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