00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef _SMSE_SRAMFILE_HH_
00026 #define _SMSE_SRAMFILE_HH_
00027
00028 #include <utility>
00029
00030 #include <wx/string.h>
00031
00032 #include "AppConstants.hh"
00033 #include "exceptions/FileIOException.hh"
00034 #include "exceptions/InvalidButtonException.hh"
00035 #include "exceptions/InvalidSRAMFileException.hh"
00036
00037 namespace smse {
00038
00039 enum {
00040
00041 SO_CURRENTENERGY, SO_MAXENERGY, SO_CURRENTRESERVE, SO_MAXRESERVE,
00042 SO_CURRENTMISSILES, SO_MAXMISSILES, SO_CURRENTSMISSILES,
00043 SO_MAXSMISSILES, SO_CURRENTPBOMBS, SO_MAXPBOMBS,
00044
00045
00046 SO_MORPHINGBALL, SO_BOMBS = 13, SO_SPRINGBALL = 16,
00047 SO_HIGHJUMPBOOTS = 19, SO_VARIASUIT = 22, SO_GRAVITYSUIT = 25,
00048 SO_SPEEDBOOSTER = 28, SO_SPACEJUMP = 31, SO_SCREWATTACK = 34,
00049 SO_CHARGEBEAM = 37, SO_ICEBEAM = 40, SO_WAVEBEAM = 43, SO_SPAZER = 46,
00050 SO_PLASMABEAM = 49, SO_GRAPPLINGBEAM = 52, SO_XRAYSCOPE = 55,
00051
00052
00053 SO_SILVERTORIZO = 58, SO_SPORESPAWN, SO_KRAID, SO_PHANTOON = 62,
00054 SO_BOTWOON = 64, SO_DRAYGON, SO_CROCOMIRE = 67, SO_GOLDENTORIZO,
00055 SO_RIDLEY, SO_METROIDROOMS = 71, SO_ZEBETITES = 75,
00056
00057
00058 SO_TOURIANELEVATOR, SO_MARIDIATUBEBROKEN, SO_RESCUEDANIMALS,
00059
00060
00061 SO_CMISSILEPACKS, SO_BSMISSILEPACKS = 87, SO_NFMISSILEPACKS = 99,
00062 SO_WSMISSILEPACKS = 114, SO_MMISSILEPACKS = 117,
00063
00064
00065 SO_CSMISSILEPACKS = 125, SO_BSSMISSILEPACKS, SO_NFSMISSILEPACKS = 129,
00066 SO_WSSMISSILEPACKS, SO_MSMISSILEPACKS = 132,
00067
00068
00069 SO_CPBOMBPACKS = 135, SO_BSPBOMBPACKS, SO_NFPBOMBPACKS = 141,
00070 SO_MPBOMBPACKS = 144,
00071
00072
00073 SO_CETANKS, SO_BSETANKS = 147, SO_NFETANKS = 152, SO_WSETANKS = 156,
00074 SO_METANKS, SO_BSRTANK = 159, SO_NFRTANK, SO_WSRTANK, SO_MRTANK,
00075
00076
00077 SO_CRDOORS, SO_BSRDOORS = 166, SO_NFRDOORS = 176, SO_WSRDOORS = 183,
00078 SO_MRDOORS, SO_TRDOORS = 191,
00079
00080
00081 SO_CGDOORS = 193, SO_BSGDOORS = 195, SO_NFGDOORS = 205,
00082 SO_WSGDOORS = 211, SO_MGDOORS,
00083
00084
00085 SO_CYDOORS = 216, SO_BSYDOORS = 222, SO_NFYDOORS = 226,
00086
00087
00088 SO_CMDOORS = 229, SO_BSMDOORS, SO_NFMDOORS = 246,
00089 SO_WSMDOORS = 252, SO_MMDOORS = 257, SO_TMDOORS = 264,
00090
00091
00092 SO_BSEDOOR = 269, SO_NFEDOOR, SO_WSEDOOR, SO_MEDOOR, SO_TEDOOR,
00093
00094
00095 SO_CMAP, SO_BSMAP, SO_NFMAP, SO_WSMAP, SO_MMAP, SO_TMAP,
00096
00097
00098 SO_SAVEAREA, SO_SAVEPOINT, SO_GAMEHOURS, SO_GAMEMINUTES,
00099
00100
00101 SO_SHOTBUTTON, SO_JUMPBUTTON, SO_DASHBUTTON, SO_ITEMCANCELBUTTON,
00102 SO_ITEMSELECTBUTTON, SO_ANGLEDOWNBUTTON, SO_ANGLEUPBUTTON, SO_LANGUAGE,
00103 SO_MOONWALK, SO_ICONCANCEL
00104 };
00105
00106
00107 enum Action {
00108 ACTION_SHOT, ACTION_JUMP, ACTION_DASH, ACTION_ITEMCANCEL,
00109 ACTION_ITEMSELECT, ACTION_ANGLEDOWN, ACTION_ANGLEUP
00110 };
00111
00112
00113 enum Area {
00114 AREA_C, AREA_BS, AREA_NF, AREA_WS, AREA_M, AREA_T
00115 };
00116
00117
00118 enum Boss {
00119 BOSS_SILVERTORIZO = 58, BOSS_SPORESPAWN, BOSS_KRAID, BOSS_PHANTOON = 62,
00120 BOSS_BOTWOON = 64, BOSS_DRAYGON, BOSS_CROCOMIRE = 67, BOSS_GOLDENTORIZO,
00121 BOSS_RIDLEY
00122 };
00123
00124
00125 enum Button {
00126 BUTTON_A, BUTTON_B, BUTTON_X, BUTTON_Y,
00127 BUTTON_L, BUTTON_R, BUTTON_SELECT
00128 };
00129
00130
00131 enum Door {
00132
00133 RD_C_MAP = 163, RD_C_BOMBS, RD_C_TELEVATOR,
00134
00135
00136 RD_BS1, RD_BS_MAP, RD_BS2, RD_BS3, RD_BS4, RD_BS_RTANK,
00137 RD_BS_SPORESPAWN, RD_BS5, RD_BS6, RD_BS_XRAYSCOPE,
00138
00139
00140 RD_NF1, RD_NF_HJBOOTS, RD_NF2, RD_NF3,
00141 RD_NF_SPEEDBOOSTER, RD_NF4, RD_NF_WAVEBEAM,
00142
00143
00144 RD_WS_RTANK,
00145
00146
00147 RD_M1, RD_M2, RD_M3, RD_M_MAP, RD_M4, RD_M5, RD_M6,
00148
00149
00150 RD_T1, RD_T_MB,
00151
00152
00153 GD_C1, GD_C_WS,
00154
00155
00156 GD_BS1, GD_BS_SPORESPAWNEXIT, GD_BS2, GD_BS3, GD_BS4,
00157 GD_BS5, GD_BS6, GD_BS7, GD_BS_SPAZER, GD_BS8,
00158
00159
00160 GD_NF1, GD_NF_ICEBEAM, GD_NF2, GD_NF3, GD_NF_SPEEDBOOSTER, GD_NF4,
00161
00162
00163 GD_WS,
00164
00165
00166 GD_M1, GD_M2, GD_M3, GD_M_DRAYGON,
00167
00168
00169 YD_C1, YD_C2, YD_C3, YD_C4, YD_C5, YD_C6,
00170
00171
00172 YD_BS1, YD_BS2, YD_BS_XRAYSCOPE, YD_BS3,
00173
00174
00175 YD_NF_MAP, YD_NF1, YD_NF2,
00176
00177
00178 MD_C_BOMBSEXIT,
00179
00180
00181 MD_BS_OLDTRIGHT, MD_BS_OLDTLEFT, MD_BS_MAPEXIT, MD_BS1, MD_BS2, MD_BS3,
00182 MD_BS4, MD_BS5, MD_BS6, MD_BS7, MD_BS8, MD_BS9, MD_BS_MINIKRAIDRIGHT,
00183 MD_BS_MINIKRAIDLEFT, MD_BS_VARIASUIT, MD_BS_KRAIDEXIT,
00184
00185
00186 MD_NF_CROCOMIREEXIT, MD_NF_HJBOOTSEXIT, MD_NF_SCREWATTACK,
00187 MD_NF_RIDLEYEXIT, MD_NF_RIDLEYLEFT, MD_NF_GOLDSPACEPIRATES,
00188
00189
00190 MD_WS1, MD_WS_PHANTOONEXIT, MD_WS2, MD_WS3, MD_WS4,
00191
00192
00193 MD_M_PLASMAEXIT, MD_M_PLASMA, MD_M1, MD_M2,
00194 MD_M_BOTWOONEXIT, MD_M_DRAYGONEXIT, MD_M_SPACEJUMP,
00195
00196
00197 MD_T1, MD_T2, MD_T3, MD_T4, MD_T5,
00198
00199
00200 ED_KRAID, ED_RIDLEY, ED_PHANTOON, ED_DRAYGON, ED_T
00201 };
00202
00203
00204 enum Item {
00205 ITEM_MORPHINGBALL = 10, ITEM_BOMBS = 13, ITEM_SPRINGBALL = 16,
00206 ITEM_HJBOOTS = 19, ITEM_VARIASUIT = 22, ITEM_GRAVITYSUIT = 25,
00207 ITEM_SPEEDBOOSTER = 28, ITEM_SPACEJUMP = 31, ITEM_SCREWATTACK = 34,
00208 ITEM_CHARGEBEAM = 37, ITEM_ICEBEAM = 40, ITEM_WAVEBEAM = 43,
00209 ITEM_SPAZER = 46, ITEM_PLASMA = 49, ITEM_GRAPPLINGBEAM = 52,
00210 ITEM_XRAYSCOPE = 55
00211 };
00212
00213
00214 enum MiscBit {
00215 MB_TELEVATOR = 76, MB_MTUBEBROKEN, MB_RESCUEDANIMALS,
00216 MB_LANGUAGE = 291, MB_MOONWALK, MB_ICONCANCEL
00217 };
00218
00219
00220 enum MetroidRoom {
00221 MR1, MR2, MR3, MR4
00222 };
00223
00224
00225 enum Statue {
00226 STATUE_KRAID = 61, STATUE_PHANTOON = 63,
00227 STATUE_DRAYGON = 66, STATUE_RIDLEY = 70
00228 };
00229
00230
00231 const int C_SAVEPOINTS = 2;
00232
00233
00234 const int BS_SAVEPOINTS = 5;
00235
00236
00237 const int NF_SAVEPOINTS = 6;
00238
00239
00240 const int WS_SAVEPOINTS = 1;
00241
00242
00243 const int M_SAVEPOINTS = 4;
00244
00245
00246 const int T_SAVEPOINTS = 2;
00247
00248
00249 class SRAMFile {
00250 public:
00251
00252 static const unsigned int SRAM_SIZE = 0x2000;
00253
00254
00255 static const unsigned int GAMES = 3;
00256
00257
00258 static const unsigned int GAME_SIZE = 0x65C;
00259
00260
00261 static const int GAME_OFFSET = 0x10;
00262
00263
00264 static const int CHECKSUM_OFFSET = 0;
00265
00266
00267 static const int CHECKSUM_OFFSET2 = 0x1FF0;
00268
00269
00270 static const int COMPLIMENT_OFFSET = 0x8;
00271
00272
00273 static const int COMPLIMENT_OFFSET2 = 0x1FF8;
00274
00275 private:
00276
00277 static const std::pair<int, unsigned char> SRAM_OFFSET[];
00278
00279
00280 static const std::pair<unsigned char, unsigned char> BUTTON_VALUE[];
00281
00282 wxString filename;
00283 char sram[SRAM_SIZE];
00284 char *game;
00285 bool valid[3], modified;
00286
00287
00288
00289
00290
00291
00292
00293
00294 bool getBit(const std::pair<int, unsigned char> &bit) const;
00295
00296
00297
00298
00299
00300
00301
00302 void setBit(const std::pair<int, unsigned char> &bit, bool on = true);
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 std::pair<unsigned char,
00313 unsigned char> getChecksum(int game,
00314 bool redundant = false) const;
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324 std::pair<unsigned char,
00325 unsigned char> getCompliment(int game,
00326 bool redundant = false) const;
00327
00328
00329
00330
00331
00332
00333 void setMaxEnergy(wxUint16 energy = 0x5DB);
00334
00335
00336
00337
00338
00339
00340 void setMaxMissiles(unsigned char missiles = 0xE6);
00341
00342
00343
00344
00345
00346
00347 void setMaxPowerBombs(unsigned char bombs = 0x32);
00348
00349
00350
00351
00352
00353
00354 void setMaxReserveEnergy(wxUint16 energy = 0x190);
00355
00356
00357
00358
00359
00360
00361 void setMaxSuperMissiles(unsigned char missiles = 0x32);
00362
00363
00364
00365
00366
00367
00368 std::pair<unsigned char,
00369 unsigned char> checksum(int game) const;
00370
00371
00372
00373
00374 void checksum();
00375
00376
00377
00378
00379
00380
00381
00382
00383 std::pair<unsigned char, unsigned char>
00384 compliment(std::pair<unsigned char, unsigned char> checksum) const;
00385
00386
00387
00388
00389
00390
00391 bool hasValidGame();
00392
00393
00394
00395
00396
00397
00398
00399 void read() throw(FileIOException, InvalidSRAMFileException);
00400
00401
00402
00403
00404
00405
00406 void write() throw(FileIOException);
00407
00408 public:
00409
00410
00411
00412
00413
00414
00415
00416
00417 SRAMFile(const wxString &filename) throw(InvalidSRAMFileException);
00418
00419
00420
00421
00422
00423
00424
00425
00426 bool getBoss(enum Boss boss) const;
00427
00428
00429
00430
00431
00432
00433
00434 void setBoss(enum Boss boss, bool dead = true);
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446 enum Button getButton(enum Action action) const
00447 throw(InvalidButtonException);
00448
00449
00450
00451
00452
00453
00454
00455 void setButton(enum Action action, enum Button button);
00456
00457
00458
00459
00460
00461
00462
00463
00464 bool getDoor(int door) const;
00465
00466
00467
00468
00469
00470
00471
00472 void setDoor(int door, bool open = true);
00473
00474
00475
00476
00477
00478
00479 wxUint16 getEnergy() const;
00480
00481
00482
00483
00484
00485
00486 void setEnergy(wxUint16 energy = 0x5DB);
00487
00488
00489
00490
00491
00492
00493
00494
00495 bool hasEnergyTank(int tank) const;
00496
00497
00498
00499
00500
00501
00502
00503 void setEnergyTank(int tank, bool give = true);
00504
00505
00506
00507
00508
00509
00510 int getGame() const;
00511
00512
00513
00514
00515
00516
00517 void setGame(int game = 0);
00518
00519
00520
00521
00522
00523
00524 unsigned char getGameHours() const;
00525
00526
00527
00528
00529
00530
00531 void setGameHours(unsigned char hours = 0);
00532
00533
00534
00535
00536
00537
00538 unsigned char getGameMinutes() const;
00539
00540
00541
00542
00543
00544
00545 void setGameMinutes(unsigned char minutes = 0);
00546
00547
00548
00549
00550
00551
00552
00553
00554 bool hasItem(enum Item item) const;
00555
00556
00557
00558
00559
00560
00561
00562 void setItem(enum Item item, bool have = true);
00563
00564
00565
00566
00567
00568
00569
00570
00571 bool isItemEquipped(enum Item item) const;
00572
00573
00574
00575
00576
00577
00578
00579 void setItemEquipped(enum Item item, bool equipped = true);
00580
00581
00582
00583
00584
00585
00586
00587
00588 bool hasMap(enum Area area) const;
00589
00590
00591
00592
00593
00594
00595
00596 void setMap(enum Area area, bool give = true);
00597
00598
00599
00600
00601
00602
00603 wxUint16 getMaxEnergy() const;
00604
00605
00606
00607
00608
00609
00610 unsigned char getMaxMissiles() const;
00611
00612
00613
00614
00615
00616
00617 unsigned char getMaxPowerBombs() const;
00618
00619
00620
00621
00622
00623
00624 wxUint16 getMaxReserveEnergy() const;
00625
00626
00627
00628
00629
00630
00631 unsigned char getMaxSuperMissiles() const;
00632
00633
00634
00635
00636
00637
00638
00639
00640 bool getMetroidRoom(enum MetroidRoom room) const;
00641
00642
00643
00644
00645
00646
00647
00648 void setMetroidRoom(enum MetroidRoom room, bool clear = true);
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658 bool getMiscBit(enum MiscBit bit) const;
00659
00660
00661
00662
00663
00664
00665
00666
00667 void setMiscBit(enum MiscBit bit, bool on = true);
00668
00669
00670
00671
00672
00673
00674
00675
00676 bool hasMissilePack(int pack) const;
00677
00678
00679
00680
00681
00682
00683
00684 void setMissilePack(int pack, bool give = true);
00685
00686
00687
00688
00689
00690
00691 unsigned char getMissiles() const;
00692
00693
00694
00695
00696
00697
00698 void setMissiles(unsigned char missiles = 0xE6);
00699
00700
00701
00702
00703
00704
00705 bool isModified() const;
00706
00707
00708
00709
00710
00711
00712
00713
00714 bool hasPowerBombPack(int pack) const;
00715
00716
00717
00718
00719
00720
00721
00722 void setPowerBombPack(int pack, bool give = true);
00723
00724
00725
00726
00727
00728
00729 unsigned char getPowerBombs() const;
00730
00731
00732
00733
00734
00735
00736 void setPowerBombs(unsigned char bombs = 0x32);
00737
00738
00739
00740
00741
00742
00743 wxUint16 getReserveEnergy() const;
00744
00745
00746
00747
00748
00749
00750 void setReserveEnergy(wxUint16 energy = 0x190);
00751
00752
00753
00754
00755
00756
00757
00758
00759 bool hasReserveTank(int tank) const;
00760
00761
00762
00763
00764
00765
00766
00767 void setReserveTank(int tank, bool give = true);
00768
00769
00770
00771
00772
00773
00774
00775 std::pair<enum Area, int> getSavePoint() const;
00776
00777
00778
00779
00780
00781
00782
00783 void setSavePoint(enum Area area, int point = 0);
00784
00785
00786
00787
00788
00789
00790
00791
00792 bool getStatue(enum Statue statue) const;
00793
00794
00795
00796
00797
00798
00799
00800 void setStatue(enum Statue statue, bool active = true);
00801
00802
00803
00804
00805
00806
00807
00808
00809 bool hasSuperMissilePack(int pack) const;
00810
00811
00812
00813
00814
00815
00816
00817 void setSuperMissilePack(int pack, bool give = true);
00818
00819
00820
00821
00822
00823
00824 unsigned char getSuperMissiles() const;
00825
00826
00827
00828
00829
00830
00831 void setSuperMissiles(unsigned char missiles = 0x32);
00832
00833
00834
00835
00836
00837
00838
00839
00840 bool isValidGame(int game = 0) const;
00841
00842
00843
00844
00845
00846
00847 int getZebetites() const;
00848
00849
00850
00851
00852
00853
00854 void setZebetites(int count = 4);
00855
00856
00857
00858
00859
00860
00861 void clear(int game);
00862
00863
00864
00865
00866
00867
00868
00869 void copy(int src, int dest);
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879 void save(const wxString &filename = wxEmptyString)
00880 throw(FileIOException);
00881 };
00882
00883 inline bool SRAMFile::getBit(const std::pair<int, unsigned char> &bit) const
00884 { return (game[bit.first] & bit.second); }
00885
00886 inline bool SRAMFile::getBoss(enum Boss boss) const
00887 { return getBit(SRAM_OFFSET[boss]); }
00888
00889 inline void SRAMFile::setBoss(enum Boss boss, bool dead)
00890 { setBit(SRAM_OFFSET[boss], dead); }
00891
00892 inline int SRAMFile::getGame() const
00893 { return (static_cast<int>(game - sram - GAME_OFFSET) / GAME_SIZE); }
00894
00895 inline bool SRAMFile::isItemEquipped(enum Item item) const
00896 { return getBit(SRAM_OFFSET[item + 2]); }
00897
00898 inline void SRAMFile::setItemEquipped(enum Item item, bool equipped)
00899 { setBit(SRAM_OFFSET[item + 2], equipped); }
00900
00901 inline bool SRAMFile::hasMap(enum Area area) const
00902 { return getBit(SRAM_OFFSET[area + SO_CMAP]); }
00903
00904 inline void SRAMFile::setMap(enum Area area, bool give)
00905 { setBit(SRAM_OFFSET[area + SO_CMAP], give); }
00906
00907 inline bool SRAMFile::getMetroidRoom(enum MetroidRoom room) const
00908 { return getBit(SRAM_OFFSET[SO_METROIDROOMS + room]); }
00909
00910 inline void SRAMFile::setMetroidRoom(enum MetroidRoom room, bool clear)
00911 { setBit(SRAM_OFFSET[SO_METROIDROOMS + room], clear); }
00912
00913 inline bool SRAMFile::getMiscBit(enum MiscBit bit) const
00914 { return getBit(SRAM_OFFSET[bit]); }
00915
00916 inline void SRAMFile::setMiscBit(enum MiscBit bit, bool on)
00917 { setBit(SRAM_OFFSET[bit], on); }
00918
00919 inline bool SRAMFile::isModified() const { return modified; }
00920
00921 inline bool SRAMFile::getStatue(enum Statue statue) const
00922 { return getBit(SRAM_OFFSET[statue]); }
00923
00924 inline void SRAMFile::setStatue(enum Statue statue, bool active)
00925 { setBit(SRAM_OFFSET[statue], active); }
00926 }
00927
00928 #endif
00929