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 #ifdef HAVE_CONFIG_H
00026 #include <config.h>
00027 #endif
00028
00029 #include <cstring>
00030 #include <fstream>
00031
00032 #include "model/SRAMFile.hh"
00033
00034 using namespace smse;
00035
00036 const std::pair<int, unsigned char> SRAMFile::SRAM_OFFSET[] =
00037 {
00038
00039 std::pair<int, unsigned char>(0x20, 0),
00040 std::pair<int, unsigned char>(0x22, 0),
00041
00042
00043 std::pair<int, unsigned char>(0x34, 0),
00044 std::pair<int, unsigned char>(0x32, 0),
00045
00046
00047 std::pair<int, unsigned char>(0x24, 0),
00048 std::pair<int, unsigned char>(0x26, 0),
00049
00050
00051 std::pair<int, unsigned char>(0x28, 0),
00052 std::pair<int, unsigned char>(0x2A, 0),
00053
00054
00055 std::pair<int, unsigned char>(0x2C, 0),
00056 std::pair<int, unsigned char>(0x2E, 0),
00057
00058
00059 std::pair<int, unsigned char>(0xB3, 0x4),
00060 std::pair<int, unsigned char>(0x2, 0x4),
00061 std::pair<int, unsigned char>(0x0, 0x4),
00062
00063
00064 std::pair<int, unsigned char>(0xB0, 0x80),
00065 std::pair<int, unsigned char>(0x3, 0x10),
00066 std::pair<int, unsigned char>(0x1, 0x10),
00067
00068
00069 std::pair<int, unsigned char>(0xC2, 0x40),
00070 std::pair<int, unsigned char>(0x2, 0x2),
00071 std::pair<int, unsigned char>(0x0, 0x2),
00072
00073
00074 std::pair<int, unsigned char>(0xB6, 0x20),
00075 std::pair<int, unsigned char>(0x3, 0x1),
00076 std::pair<int, unsigned char>(0x1, 0x1),
00077
00078
00079 std::pair<int, unsigned char>(0xB6, 0x1),
00080 std::pair<int, unsigned char>(0x2, 0x1),
00081 std::pair<int, unsigned char>(0x0, 0x1),
00082
00083
00084 std::pair<int, unsigned char>(0xC0, 0x80),
00085 std::pair<int, unsigned char>(0x2, 0x20),
00086 std::pair<int, unsigned char>(0x0, 0x20),
00087
00088
00089 std::pair<int, unsigned char>(0xB8, 0x4),
00090 std::pair<int, unsigned char>(0x3, 0x20),
00091 std::pair<int, unsigned char>(0x1, 0x20),
00092
00093
00094 std::pair<int, unsigned char>(0xC3, 0x4),
00095 std::pair<int, unsigned char>(0x3, 0x2),
00096 std::pair<int, unsigned char>(0x1, 0x2),
00097
00098
00099 std::pair<int, unsigned char>(0xB9, 0x80),
00100 std::pair<int, unsigned char>(0x2, 0x8),
00101 std::pair<int, unsigned char>(0x0, 0x8),
00102
00103
00104 std::pair<int, unsigned char>(0xB2, 0x80),
00105 std::pair<int, unsigned char>(0x7, 0x10),
00106 std::pair<int, unsigned char>(0x5, 0x10),
00107
00108
00109 std::pair<int, unsigned char>(0xB6, 0x4),
00110 std::pair<int, unsigned char>(0x6, 0x2),
00111 std::pair<int, unsigned char>(0x4, 0x2),
00112
00113
00114 std::pair<int, unsigned char>(0xB8, 0x10),
00115 std::pair<int, unsigned char>(0x6, 0x1),
00116 std::pair<int, unsigned char>(0x4, 0x1),
00117
00118
00119 std::pair<int, unsigned char>(0xB5, 0x4),
00120 std::pair<int, unsigned char>(0x6, 0x4),
00121 std::pair<int, unsigned char>(0x4, 0x4),
00122
00123
00124 std::pair<int, unsigned char>(0xC1, 0x80),
00125 std::pair<int, unsigned char>(0x6, 0x8),
00126 std::pair<int, unsigned char>(0x4, 0x8),
00127
00128
00129 std::pair<int, unsigned char>(0xB7, 0x10),
00130 std::pair<int, unsigned char>(0x3, 0x40),
00131 std::pair<int, unsigned char>(0x1, 0x40),
00132
00133
00134 std::pair<int, unsigned char>(0xB4, 0x40),
00135 std::pair<int, unsigned char>(0x3, 0x80),
00136 std::pair<int, unsigned char>(0x1, 0x80),
00137
00138
00139 std::pair<int, unsigned char>(0x68, 0x4),
00140
00141
00142 std::pair<int, unsigned char>(0x69, 0x2),
00143
00144
00145 std::pair<int, unsigned char>(0x69, 0x1),
00146 std::pair<int, unsigned char>(0x61, 0x2),
00147
00148
00149 std::pair<int, unsigned char>(0x6B, 0x1),
00150 std::pair<int, unsigned char>(0x60, 0x40),
00151
00152
00153 std::pair<int, unsigned char>(0x6C, 0x2),
00154
00155
00156 std::pair<int, unsigned char>(0x6C, 0x1),
00157 std::pair<int, unsigned char>(0x61, 0x1),
00158
00159
00160 std::pair<int, unsigned char>(0x6A, 0x2),
00161
00162
00163 std::pair<int, unsigned char>(0x6A, 0x4),
00164
00165
00166 std::pair<int, unsigned char>(0x6A, 0x1),
00167 std::pair<int, unsigned char>(0x60, 0x80),
00168
00169
00170 std::pair<int, unsigned char>(0x62, 0x1),
00171 std::pair<int, unsigned char>(0x62, 0x2),
00172 std::pair<int, unsigned char>(0x62, 0x4),
00173 std::pair<int, unsigned char>(0x62, 0x8),
00174
00175
00176 std::pair<int, unsigned char>(0x60, 0x3),
00177
00178
00179 std::pair<int, unsigned char>(0x61, 0x4),
00180
00181
00182 std::pair<int, unsigned char>(0x61, 0x8),
00183
00184
00185 std::pair<int, unsigned char>(0x61, 0x80),
00186
00187
00188 std::pair<int, unsigned char>(0xB0, 0x2),
00189 std::pair<int, unsigned char>(0xB0, 0x4),
00190 std::pair<int, unsigned char>(0xB0, 0x8),
00191 std::pair<int, unsigned char>(0xB0, 0x10),
00192 std::pair<int, unsigned char>(0xB0, 0x40),
00193 std::pair<int, unsigned char>(0xB1, 0x2),
00194 std::pair<int, unsigned char>(0xB1, 0x4),
00195 std::pair<int, unsigned char>(0xB1, 0x10),
00196
00197
00198 std::pair<int, unsigned char>(0xB1, 0x80),
00199 std::pair<int, unsigned char>(0xB2, 0x4),
00200 std::pair<int, unsigned char>(0xB2, 0x8),
00201 std::pair<int, unsigned char>(0xB2, 0x20),
00202 std::pair<int, unsigned char>(0xB2, 0x40),
00203 std::pair<int, unsigned char>(0xB3, 0x2),
00204 std::pair<int, unsigned char>(0xB3, 0x10),
00205 std::pair<int, unsigned char>(0xB4, 0x4),
00206 std::pair<int, unsigned char>(0xB4, 0x10),
00207 std::pair<int, unsigned char>(0xB4, 0x20),
00208 std::pair<int, unsigned char>(0xB5, 0x2),
00209 std::pair<int, unsigned char>(0xB5, 0x10),
00210
00211
00212 std::pair<int, unsigned char>(0xB6, 0x2),
00213 std::pair<int, unsigned char>(0xB6, 0x8),
00214 std::pair<int, unsigned char>(0xB6, 0x40),
00215 std::pair<int, unsigned char>(0xB6, 0x80),
00216 std::pair<int, unsigned char>(0xB7, 0x4),
00217 std::pair<int, unsigned char>(0xB7, 0x8),
00218 std::pair<int, unsigned char>(0xB7, 0x40),
00219 std::pair<int, unsigned char>(0xB7, 0x80),
00220 std::pair<int, unsigned char>(0xB8, 0x1),
00221 std::pair<int, unsigned char>(0xB8, 0x2),
00222 std::pair<int, unsigned char>(0xB8, 0x8),
00223 std::pair<int, unsigned char>(0xB8, 0x40),
00224 std::pair<int, unsigned char>(0xB9, 0x2),
00225 std::pair<int, unsigned char>(0xB9, 0x4),
00226 std::pair<int, unsigned char>(0xB9, 0x20),
00227
00228
00229 std::pair<int, unsigned char>(0xC0, 0x1),
00230 std::pair<int, unsigned char>(0xC0, 0x4),
00231 std::pair<int, unsigned char>(0xC0, 0x8),
00232
00233
00234 std::pair<int, unsigned char>(0xC1, 0x1),
00235 std::pair<int, unsigned char>(0xC1, 0x8),
00236 std::pair<int, unsigned char>(0xC1, 0x20),
00237 std::pair<int, unsigned char>(0xC1, 0x40),
00238 std::pair<int, unsigned char>(0xC2, 0x1),
00239 std::pair<int, unsigned char>(0xC2, 0x4),
00240 std::pair<int, unsigned char>(0xC2, 0x10),
00241 std::pair<int, unsigned char>(0xC2, 0x80),
00242
00243
00244 std::pair<int, unsigned char>(0xB1, 0x8),
00245
00246
00247 std::pair<int, unsigned char>(0xB1, 0x40),
00248 std::pair<int, unsigned char>(0xB2, 0x1),
00249 std::pair<int, unsigned char>(0xB3, 0x80),
00250
00251
00252 std::pair<int, unsigned char>(0xB8, 0x80),
00253
00254
00255 std::pair<int, unsigned char>(0xC0, 0x20),
00256 std::pair<int, unsigned char>(0xC0, 0x40),
00257
00258
00259 std::pair<int, unsigned char>(0xC1, 0x2),
00260 std::pair<int, unsigned char>(0xC1, 0x10),
00261 std::pair<int, unsigned char>(0xC2, 0x20),
00262
00263
00264 std::pair<int, unsigned char>(0xB0, 0x1),
00265
00266
00267 std::pair<int, unsigned char>(0xB1, 0x20),
00268 std::pair<int, unsigned char>(0xB3, 0x1),
00269 std::pair<int, unsigned char>(0xB3, 0x8),
00270 std::pair<int, unsigned char>(0xB4, 0x80),
00271 std::pair<int, unsigned char>(0xB5, 0x1),
00272
00273
00274 std::pair<int, unsigned char>(0xB7, 0x2),
00275 std::pair<int, unsigned char>(0xB9, 0x8),
00276 std::pair<int, unsigned char>(0xB9, 0x10),
00277
00278
00279 std::pair<int, unsigned char>(0xC2, 0x8),
00280
00281
00282 std::pair<int, unsigned char>(0xB0, 0x20),
00283 std::pair<int, unsigned char>(0xB1, 0x1),
00284
00285
00286 std::pair<int, unsigned char>(0xB3, 0x20),
00287 std::pair<int, unsigned char>(0xB3, 0x40),
00288 std::pair<int, unsigned char>(0xB4, 0x2),
00289 std::pair<int, unsigned char>(0xB4, 0x8),
00290 std::pair<int, unsigned char>(0xB5, 0x8),
00291
00292
00293 std::pair<int, unsigned char>(0xB6, 0x10),
00294 std::pair<int, unsigned char>(0xB7, 0x1),
00295 std::pair<int, unsigned char>(0xB9, 0x40),
00296 std::pair<int, unsigned char>(0xBA, 0x1),
00297
00298
00299 std::pair<int, unsigned char>(0xC0, 0x10),
00300
00301
00302 std::pair<int, unsigned char>(0xC1, 0x4),
00303 std::pair<int, unsigned char>(0xC3, 0x1),
00304
00305
00306 std::pair<int, unsigned char>(0xB2, 0x2),
00307
00308
00309 std::pair<int, unsigned char>(0xB7, 0x20),
00310
00311
00312 std::pair<int, unsigned char>(0xC0, 0x2),
00313
00314
00315 std::pair<int, unsigned char>(0xC2, 0x2),
00316
00317
00318 std::pair<int, unsigned char>(0xF0, 0x20),
00319 std::pair<int, unsigned char>(0xF3, 0x20),
00320 std::pair<int, unsigned char>(0xF3, 0x40),
00321
00322
00323 std::pair<int, unsigned char>(0xF3, 0x80),
00324 std::pair<int, unsigned char>(0xF4, 0x1),
00325 std::pair<int, unsigned char>(0xF4, 0x2),
00326 std::pair<int, unsigned char>(0xF4, 0x4),
00327 std::pair<int, unsigned char>(0xF4, 0x8),
00328 std::pair<int, unsigned char>(0xF4, 0x40),
00329 std::pair<int, unsigned char>(0xF5, 0x4),
00330 std::pair<int, unsigned char>(0xF5, 0x8),
00331 std::pair<int, unsigned char>(0xF6, 0x4),
00332 std::pair<int, unsigned char>(0xF7, 0x4),
00333
00334
00335 std::pair<int, unsigned char>(0xF9, 0x4),
00336 std::pair<int, unsigned char>(0xF9, 0x20),
00337 std::pair<int, unsigned char>(0xFA, 0x2),
00338 std::pair<int, unsigned char>(0xFA, 0x4),
00339 std::pair<int, unsigned char>(0xFA, 0x20),
00340 std::pair<int, unsigned char>(0xFA, 0x40),
00341 std::pair<int, unsigned char>(0xFA, 0x80),
00342
00343
00344 std::pair<int, unsigned char>(0x101, 0x8),
00345
00346
00347 std::pair<int, unsigned char>(0x101, 0x10),
00348 std::pair<int, unsigned char>(0x101, 0x20),
00349 std::pair<int, unsigned char>(0x101, 0x40),
00350 std::pair<int, unsigned char>(0x102, 0x1),
00351 std::pair<int, unsigned char>(0x102, 0x4),
00352 std::pair<int, unsigned char>(0x102, 0x40),
00353 std::pair<int, unsigned char>(0x103, 0x1),
00354
00355
00356 std::pair<int, unsigned char>(0x104, 0x80),
00357 std::pair<int, unsigned char>(0x105, 0x2),
00358
00359
00360 std::pair<int, unsigned char>(0xF0, 0x1),
00361 std::pair<int, unsigned char>(0xF1, 0x10),
00362
00363
00364 std::pair<int, unsigned char>(0xF5, 0x2),
00365 std::pair<int, unsigned char>(0xF5, 0x40),
00366 std::pair<int, unsigned char>(0xF6, 0x8),
00367 std::pair<int, unsigned char>(0xF6, 0x10),
00368 std::pair<int, unsigned char>(0xF6, 0x20),
00369 std::pair<int, unsigned char>(0xF7, 0x1),
00370 std::pair<int, unsigned char>(0xF7, 0x8),
00371 std::pair<int, unsigned char>(0xF7, 0x20),
00372 std::pair<int, unsigned char>(0xF7, 0x80),
00373 std::pair<int, unsigned char>(0xF8, 0x10),
00374
00375
00376 std::pair<int, unsigned char>(0xF9, 0x2),
00377 std::pair<int, unsigned char>(0xF9, 0x8),
00378 std::pair<int, unsigned char>(0xF9, 0x40),
00379 std::pair<int, unsigned char>(0xFA, 0x8),
00380 std::pair<int, unsigned char>(0xFA, 0x10),
00381 std::pair<int, unsigned char>(0xFB, 0x80),
00382
00383
00384 std::pair<int, unsigned char>(0x100, 0x10),
00385
00386
00387 std::pair<int, unsigned char>(0x101, 0x80),
00388 std::pair<int, unsigned char>(0x102, 0x10),
00389 std::pair<int, unsigned char>(0x102, 0x20),
00390 std::pair<int, unsigned char>(0x103, 0x4),
00391
00392
00393 std::pair<int, unsigned char>(0xF0, 0x2),
00394 std::pair<int, unsigned char>(0xF1, 0x20),
00395 std::pair<int, unsigned char>(0xF1, 0x40),
00396 std::pair<int, unsigned char>(0xF1, 0x80),
00397 std::pair<int, unsigned char>(0xF2, 0x1),
00398 std::pair<int, unsigned char>(0xF2, 0x8),
00399
00400
00401 std::pair<int, unsigned char>(0xF5, 0x1),
00402 std::pair<int, unsigned char>(0xF6, 0x1),
00403 std::pair<int, unsigned char>(0xF7, 0x2),
00404 std::pair<int, unsigned char>(0xF7, 0x10),
00405
00406
00407 std::pair<int, unsigned char>(0xF9, 0x10),
00408 std::pair<int, unsigned char>(0xFB, 0x1),
00409 std::pair<int, unsigned char>(0xFB, 0x40),
00410
00411
00412 std::pair<int, unsigned char>(0xF3, 0x8),
00413
00414
00415 std::pair<int, unsigned char>(0xF3, 0x2),
00416 std::pair<int, unsigned char>(0xF3, 0x4),
00417 std::pair<int, unsigned char>(0xF4, 0x20),
00418 std::pair<int, unsigned char>(0xF5, 0x10),
00419 std::pair<int, unsigned char>(0xF5, 0x20),
00420 std::pair<int, unsigned char>(0xF5, 0x80),
00421 std::pair<int, unsigned char>(0xF6, 0x2),
00422 std::pair<int, unsigned char>(0xF6, 0x40),
00423 std::pair<int, unsigned char>(0xF6, 0x80),
00424 std::pair<int, unsigned char>(0xF7, 0x40),
00425 std::pair<int, unsigned char>(0xF8, 0x1),
00426 std::pair<int, unsigned char>(0xF8, 0x2),
00427 std::pair<int, unsigned char>(0xF8, 0x4),
00428 std::pair<int, unsigned char>(0xF8, 0x8),
00429 std::pair<int, unsigned char>(0xF8, 0x40),
00430 std::pair<int, unsigned char>(0xF8, 0x80),
00431
00432
00433 std::pair<int, unsigned char>(0xF9, 0x80),
00434 std::pair<int, unsigned char>(0xFA, 0x1),
00435 std::pair<int, unsigned char>(0xFB, 0x2),
00436 std::pair<int, unsigned char>(0xFB, 0x4),
00437 std::pair<int, unsigned char>(0xFB, 0x8),
00438 std::pair<int, unsigned char>(0xFC, 0x1),
00439
00440
00441 std::pair<int, unsigned char>(0x100, 0x8),
00442 std::pair<int, unsigned char>(0x100, 0x40),
00443 std::pair<int, unsigned char>(0x101, 0x1),
00444 std::pair<int, unsigned char>(0x101, 0x2),
00445 std::pair<int, unsigned char>(0x101, 0x4),
00446
00447
00448 std::pair<int, unsigned char>(0x102, 0x2),
00449 std::pair<int, unsigned char>(0x102, 0x8),
00450 std::pair<int, unsigned char>(0x102, 0x80),
00451 std::pair<int, unsigned char>(0x103, 0x10),
00452 std::pair<int, unsigned char>(0x103, 0x20),
00453 std::pair<int, unsigned char>(0x103, 0x40),
00454 std::pair<int, unsigned char>(0x103, 0x80),
00455
00456
00457 std::pair<int, unsigned char>(0x104, 0x1),
00458 std::pair<int, unsigned char>(0x104, 0x2),
00459 std::pair<int, unsigned char>(0x104, 0x4),
00460 std::pair<int, unsigned char>(0x104, 0x8),
00461 std::pair<int, unsigned char>(0x104, 0x20),
00462
00463
00464 std::pair<int, unsigned char>(0xF8, 0x20),
00465
00466
00467 std::pair<int, unsigned char>(0xFB, 0x10),
00468
00469
00470 std::pair<int, unsigned char>(0x100, 0x20),
00471
00472
00473 std::pair<int, unsigned char>(0x103, 0x8),
00474
00475
00476 std::pair<int, unsigned char>(0x105, 0x1),
00477
00478
00479 std::pair<int, unsigned char>(0x148, 0xFF),
00480
00481
00482 std::pair<int, unsigned char>(0x149, 0xFF),
00483
00484
00485 std::pair<int, unsigned char>(0x14A, 0xFF),
00486
00487
00488 std::pair<int, unsigned char>(0x14B, 0xFF),
00489
00490
00491 std::pair<int, unsigned char>(0x14C, 0xFF),
00492
00493
00494 std::pair<int, unsigned char>(0x14D, 0xFF),
00495
00496
00497 std::pair<int, unsigned char>(0x158, 0),
00498 std::pair<int, unsigned char>(0x156, 0),
00499
00500
00501 std::pair<int, unsigned char>(0x3E, 0xFF),
00502
00503
00504 std::pair<int, unsigned char>(0x3C, 0xFF),
00505
00506
00507 std::pair<int, unsigned char>(0x10, 0),
00508
00509
00510 std::pair<int, unsigned char>(0x12, 0),
00511
00512
00513 std::pair<int, unsigned char>(0x14, 0),
00514
00515
00516 std::pair<int, unsigned char>(0x16, 0),
00517
00518
00519 std::pair<int, unsigned char>(0x18, 0),
00520
00521
00522 std::pair<int, unsigned char>(0x1A, 0),
00523
00524
00525 std::pair<int, unsigned char>(0x1C, 0),
00526
00527
00528 std::pair<int, unsigned char>(0x40, 0x1),
00529
00530
00531 std::pair<int, unsigned char>(0x42, 0x1),
00532
00533
00534 std::pair<int, unsigned char>(0x48, 0x1)
00535 };
00536
00537 const std::pair<unsigned char, unsigned char> SRAMFile::BUTTON_VALUE[] =
00538 {
00539 std::pair<unsigned char, unsigned char>(0x80, 0x0),
00540 std::pair<unsigned char, unsigned char>(0x0, 0x80),
00541 std::pair<unsigned char, unsigned char>(0x40, 0x0),
00542 std::pair<unsigned char, unsigned char>(0x0, 0x40),
00543 std::pair<unsigned char, unsigned char>(0x20, 0x0),
00544 std::pair<unsigned char, unsigned char>(0x10, 0x0),
00545 std::pair<unsigned char, unsigned char>(0x0, 0x20)
00546 };
00547
00548 SRAMFile::SRAMFile(const wxString &filename) throw (InvalidSRAMFileException) :
00549 game(sram + GAME_OFFSET), modified(false) {
00550 this->filename = filename;
00551
00552 try {
00553 read();
00554 } catch (FileIOException &e) {
00555 throw InvalidSRAMFileException(e.what());
00556 }
00557
00558 if (!hasValidGame()) {
00559 throw InvalidSRAMFileException("No save games found");
00560 }
00561 }
00562
00563 void SRAMFile::setBit(const std::pair<int, unsigned char> &bit,
00564 bool on) {
00565 if (on) {
00566 game[bit.first] |= bit.second;
00567 } else {
00568 game[bit.first] &= ~bit.second;
00569 }
00570
00571 modified = true;
00572 }
00573
00574 enum Button SRAMFile::getButton(enum Action action) const
00575 throw(InvalidButtonException){
00576 const std::pair<int, unsigned char> &offset =
00577 SRAM_OFFSET[action + SO_SHOTBUTTON];
00578
00579 unsigned char high = game[offset.first];
00580 unsigned char low = game[offset.first + 1];
00581
00582 for (int i = BUTTON_A; i <= BUTTON_SELECT; ++i) {
00583 enum Button button = static_cast<enum Button>(i);
00584
00585 if ((high == BUTTON_VALUE[button].first) &&
00586 (low == BUTTON_VALUE[button].second)) {
00587 return button;
00588 }
00589 }
00590
00591
00592 throw InvalidButtonException();
00593 }
00594
00595 void SRAMFile::setButton(enum Action action, enum Button button) {
00596 const std::pair<int, unsigned char> &offset =
00597 SRAM_OFFSET[action + SO_SHOTBUTTON];
00598
00599 game[offset.first] = BUTTON_VALUE[button].first;
00600 game[offset.first + 1] = BUTTON_VALUE[button].second;
00601
00602 modified = true;
00603 }
00604
00605 std::pair<unsigned char,
00606 unsigned char> SRAMFile::getChecksum(int game, bool redundant) const {
00607
00608 wxASSERT((game >= 0) && (game <= 2));
00609
00610 int offset = CHECKSUM_OFFSET;
00611
00612 if (redundant) {
00613 offset = CHECKSUM_OFFSET2;
00614 }
00615
00616 return std::pair<unsigned char,
00617 unsigned char>(sram[offset + (game * 2)],
00618 sram[offset + (game * 2) + 1]);
00619 }
00620
00621 std::pair<unsigned char,
00622 unsigned char> SRAMFile::getCompliment(int game,
00623 bool redundant) const {
00624
00625 wxASSERT((game >= 0) && (game <= 2));
00626
00627 int offset = COMPLIMENT_OFFSET;
00628
00629 if (redundant) {
00630 offset = COMPLIMENT_OFFSET2;
00631 }
00632
00633 return std::pair<unsigned char,
00634 unsigned char>(sram[offset + (game * 2)],
00635 sram[offset + (game * 2) + 1]);
00636 }
00637
00638 bool SRAMFile::getDoor(int door) const {
00639
00640 wxASSERT((door >= SO_CRDOORS) && (door <= SO_TEDOOR));
00641
00642 return getBit(SRAM_OFFSET[door]);
00643 }
00644
00645 void SRAMFile::setDoor(int door, bool open) {
00646
00647 wxASSERT((door >= SO_CRDOORS) && (door <= SO_TEDOOR));
00648
00649 setBit(SRAM_OFFSET[door], open);
00650 }
00651
00652 wxUint16 SRAMFile::getEnergy() const {
00653 const std::pair<int, unsigned char> &offset =
00654 SRAM_OFFSET[SO_CURRENTENERGY];
00655 wxUint16 *ptr = reinterpret_cast<wxUint16 *>(game + offset.first);
00656
00657 return wxUINT16_SWAP_ON_BE(*ptr);
00658 }
00659
00660 void SRAMFile::setEnergy(wxUint16 energy) {
00661 const std::pair<int, unsigned char> &offset =
00662 SRAM_OFFSET[SO_CURRENTENERGY];
00663 wxUint16 *ptr = reinterpret_cast<wxUint16 *>(game + offset.first);
00664 wxUint16 max = getMaxEnergy();
00665
00666 if (energy > max) {
00667 energy = max;
00668 }
00669
00670 *ptr = wxUINT16_SWAP_ON_BE(energy);
00671
00672 modified = true;
00673 }
00674
00675 bool SRAMFile::hasEnergyTank(int tank) const {
00676
00677 wxASSERT((tank >= SO_CETANKS) && (tank < SO_BSRTANK));
00678
00679 return getBit(SRAM_OFFSET[tank]);
00680 }
00681
00682 void SRAMFile::setEnergyTank(int tank, bool give) {
00683
00684 wxASSERT((tank >= SO_CETANKS) && (tank < SO_BSRTANK));
00685
00686 if (!hasEnergyTank(tank) && give) {
00687 setMaxEnergy(getMaxEnergy() + 100);
00688 } else if (hasEnergyTank(tank) && !give) {
00689 setMaxEnergy(getMaxEnergy() - 100);
00690 setEnergy(getEnergy());
00691 }
00692
00693 setBit(SRAM_OFFSET[tank], give);
00694 }
00695
00696 void SRAMFile::setGame(int game) {
00697
00698 wxASSERT((game >= 0) && (game <= 2));
00699
00700
00701 wxASSERT(valid[game]);
00702
00703 this->game = (sram + GAME_OFFSET + (GAME_SIZE * game));
00704 }
00705
00706 unsigned char SRAMFile::getGameHours() const {
00707 std::pair<int, unsigned char> offset = SRAM_OFFSET[SO_GAMEHOURS];
00708
00709 return game[offset.first];
00710 }
00711
00712 void SRAMFile::setGameHours(unsigned char hours) {
00713
00714 wxASSERT(hours < 100);
00715
00716 const std::pair<int, unsigned char> &offset = SRAM_OFFSET[SO_GAMEHOURS];
00717
00718 game[offset.first] = hours;
00719
00720 modified = true;
00721 }
00722
00723 unsigned char SRAMFile::getGameMinutes() const {
00724 std::pair<int, unsigned char> offset = SRAM_OFFSET[SO_GAMEMINUTES];
00725
00726 return game[offset.first];
00727 }
00728
00729 void SRAMFile::setGameMinutes(unsigned char minutes) {
00730
00731 wxASSERT(minutes < 60);
00732
00733 const std::pair<int, unsigned char> &offset = SRAM_OFFSET[SO_GAMEMINUTES];
00734
00735 game[offset.first] = minutes;
00736
00737 modified = true;
00738 }
00739
00740 bool SRAMFile::hasItem(enum Item item) const {
00741 return (getBit(SRAM_OFFSET[item]) && getBit(SRAM_OFFSET[item + 1]));
00742 }
00743
00744 void SRAMFile::setItem(enum Item item, bool have) {
00745 setBit(SRAM_OFFSET[item], have);
00746 setBit(SRAM_OFFSET[item + 1], have);
00747 }
00748
00749 wxUint16 SRAMFile::getMaxEnergy() const {
00750 const std::pair<int, unsigned char> &offset =
00751 SRAM_OFFSET[SO_MAXENERGY];
00752 wxUint16 *ptr = reinterpret_cast<wxUint16 *>(game + offset.first);
00753
00754 return wxUINT16_SWAP_ON_BE(*ptr);
00755 }
00756
00757 void SRAMFile::setMaxEnergy(wxUint16 energy) {
00758 const std::pair<int, unsigned char> &offset =
00759 SRAM_OFFSET[SO_MAXENERGY];
00760 wxUint16 *ptr = reinterpret_cast<wxUint16 *>(game + offset.first);
00761
00762 *ptr = wxUINT16_SWAP_ON_BE(energy);
00763
00764 modified = true;
00765 }
00766
00767 unsigned char SRAMFile::getMaxMissiles() const{
00768 const std::pair<int, unsigned char> &offset =
00769 SRAM_OFFSET[SO_MAXMISSILES];
00770
00771 return game[offset.first];
00772 }
00773
00774 void SRAMFile::setMaxMissiles(unsigned char missiles) {
00775 const std::pair<int, unsigned char> &offset =
00776 SRAM_OFFSET[SO_MAXMISSILES];
00777
00778 game[offset.first] = missiles;
00779
00780 modified = true;
00781 }
00782
00783 unsigned char SRAMFile::getMaxPowerBombs() const {
00784 const std::pair<int, unsigned char> &offset =
00785 SRAM_OFFSET[SO_MAXPBOMBS];
00786
00787 return game[offset.first];
00788 }
00789
00790 void SRAMFile::setMaxPowerBombs(unsigned char bombs) {
00791 const std::pair<int, unsigned char> &offset =
00792 SRAM_OFFSET[SO_MAXPBOMBS];
00793
00794 game[offset.first] = bombs;
00795
00796 modified = true;
00797 }
00798
00799 wxUint16 SRAMFile::getMaxReserveEnergy() const {
00800 const std::pair<int, unsigned char> &offset =
00801 SRAM_OFFSET[SO_MAXRESERVE];
00802 wxUint16 *ptr = reinterpret_cast<wxUint16 *>(game + offset.first);
00803
00804 return wxUINT16_SWAP_ON_BE(*ptr);
00805 }
00806
00807 void SRAMFile::setMaxReserveEnergy(wxUint16 energy) {
00808 const std::pair<int, unsigned char> &offset =
00809 SRAM_OFFSET[SO_MAXRESERVE];
00810 wxUint16 *ptr = reinterpret_cast<wxUint16 *>(game + offset.first);
00811
00812 *ptr = wxUINT16_SWAP_ON_BE(energy);
00813
00814 modified = true;
00815 }
00816
00817 unsigned char SRAMFile::getMaxSuperMissiles() const {
00818 const std::pair<int, unsigned char> &offset =
00819 SRAM_OFFSET[SO_MAXSMISSILES];
00820
00821 return game[offset.first];
00822 }
00823
00824 void SRAMFile::setMaxSuperMissiles(unsigned char missiles) {
00825 const std::pair<int, unsigned char> &offset =
00826 SRAM_OFFSET[SO_MAXSMISSILES];
00827
00828 game[offset.first] = missiles;
00829
00830 modified = true;
00831 }
00832
00833 bool SRAMFile::hasMissilePack(int pack) const {
00834
00835 wxASSERT((pack >= SO_CMISSILEPACKS) && (pack < SO_CSMISSILEPACKS));
00836
00837 return getBit(SRAM_OFFSET[pack]);
00838 }
00839
00840 void SRAMFile::setMissilePack(int pack, bool give) {
00841
00842 wxASSERT((pack >= SO_CMISSILEPACKS) && (pack < SO_CSMISSILEPACKS));
00843
00844 if (!hasMissilePack(pack) && give) {
00845 setMaxMissiles(getMaxMissiles() + 5);
00846 } else if (hasMissilePack(pack) && !give) {
00847 setMaxMissiles(getMaxMissiles() - 5);
00848 setMissiles(getMissiles());
00849 }
00850
00851 setBit(SRAM_OFFSET[pack], give);
00852 }
00853
00854 unsigned char SRAMFile::getMissiles() const {
00855 const std::pair<int, unsigned char> &offset =
00856 SRAM_OFFSET[SO_CURRENTMISSILES];
00857
00858 return game[offset.first];
00859 }
00860
00861 void SRAMFile::setMissiles(unsigned char missiles) {
00862 const std::pair<int, unsigned char> &offset =
00863 SRAM_OFFSET[SO_CURRENTMISSILES];
00864 unsigned char max = getMaxMissiles();
00865
00866 if (missiles > max) {
00867 missiles = max;
00868 }
00869
00870 game[offset.first] = missiles;
00871
00872 modified = true;
00873 }
00874
00875 bool SRAMFile::hasPowerBombPack(int pack) const {
00876
00877 wxASSERT((pack >= SO_CPBOMBPACKS) && (pack < SO_CETANKS));
00878
00879 return getBit(SRAM_OFFSET[pack]);
00880 }
00881
00882 void SRAMFile::setPowerBombPack(int pack, bool give) {
00883
00884 wxASSERT((pack >= SO_CPBOMBPACKS) && (pack < SO_CETANKS));
00885
00886 if (!hasPowerBombPack(pack) && give) {
00887 setMaxPowerBombs(getMaxPowerBombs() + 5);
00888 } else if (hasPowerBombPack(pack) && !give) {
00889 setMaxPowerBombs(getMaxPowerBombs() - 5);
00890 setPowerBombs(getPowerBombs());
00891 }
00892
00893 setBit(SRAM_OFFSET[pack], give);
00894 }
00895
00896 unsigned char SRAMFile::getPowerBombs() const {
00897 const std::pair<int, unsigned char> &offset =
00898 SRAM_OFFSET[SO_CURRENTPBOMBS];
00899
00900 return game[offset.first];
00901 }
00902
00903 void SRAMFile::setPowerBombs(unsigned char bombs) {
00904 const std::pair<int, unsigned char> &offset =
00905 SRAM_OFFSET[SO_CURRENTPBOMBS];
00906 unsigned char max = getMaxPowerBombs();
00907
00908 if (bombs > max) {
00909 bombs = max;
00910 }
00911
00912 game[offset.first] = bombs;
00913
00914 modified = true;
00915 }
00916
00917 wxUint16 SRAMFile::getReserveEnergy() const {
00918 const std::pair<int, unsigned char> &offset =
00919 SRAM_OFFSET[SO_CURRENTRESERVE];
00920 wxUint16 *ptr = reinterpret_cast<wxUint16 *>(game + offset.first);
00921
00922 return wxUINT16_SWAP_ON_BE(*ptr);
00923 }
00924
00925 void SRAMFile::setReserveEnergy(wxUint16 energy) {
00926 const std::pair<int, unsigned char> &offset =
00927 SRAM_OFFSET[SO_CURRENTRESERVE];
00928 wxUint16 *ptr = reinterpret_cast<wxUint16 *>(game + offset.first);
00929 wxUint16 max = getMaxReserveEnergy();
00930
00931 if (energy > max) {
00932 energy = max;
00933 }
00934
00935 *ptr = wxUINT16_SWAP_ON_BE(energy);
00936
00937 modified = true;
00938 }
00939
00940 bool SRAMFile::hasReserveTank(int tank) const {
00941
00942 wxASSERT((tank >= SO_BSRTANK) && (tank <= SO_MRTANK));
00943
00944 return getBit(SRAM_OFFSET[tank]);
00945 }
00946
00947 void SRAMFile::setReserveTank(int tank, bool give) {
00948
00949 wxASSERT((tank >= SO_BSRTANK) && (tank <= SO_MRTANK));
00950
00951 if (!hasReserveTank(tank) && give) {
00952 setMaxReserveEnergy(getMaxReserveEnergy() + 100);
00953 } else if (hasReserveTank(tank) && !give) {
00954 setMaxReserveEnergy(getMaxReserveEnergy() - 100);
00955 setReserveEnergy(getReserveEnergy());
00956 }
00957
00958 setBit(SRAM_OFFSET[tank], give);
00959 }
00960
00961 std::pair<enum Area, int> SRAMFile::getSavePoint() const {
00962 const std::pair<int, unsigned char> &area = SRAM_OFFSET[SO_SAVEAREA];
00963 const std::pair<int, unsigned char> &point = SRAM_OFFSET[SO_SAVEPOINT];
00964
00965 return std::pair<enum Area, int>(static_cast<enum Area>(game[area.first]),
00966 game[point.first]);
00967 }
00968
00969 void SRAMFile::setSavePoint(enum Area area, int point) {
00970
00971 wxASSERT((point >= 0) &&
00972 (((area == AREA_C) && (point < C_SAVEPOINTS)) ||
00973 ((area == AREA_BS) && (point < BS_SAVEPOINTS)) ||
00974 ((area == AREA_NF) && (point < NF_SAVEPOINTS)) ||
00975 ((area == AREA_WS) && (point < WS_SAVEPOINTS)) ||
00976 ((area == AREA_M) && (point < M_SAVEPOINTS)) ||
00977 ((area == AREA_T) && (point < T_SAVEPOINTS))));
00978
00979 const std::pair<int, unsigned char> &high = SRAM_OFFSET[SO_SAVEAREA];
00980 const std::pair<int, unsigned char> &low = SRAM_OFFSET[SO_SAVEPOINT];
00981
00982 game[high.first] = area;
00983 game[low.first] = point;
00984
00985 modified = true;
00986 }
00987
00988 bool SRAMFile::hasSuperMissilePack(int pack) const {
00989
00990 wxASSERT((pack >= SO_CSMISSILEPACKS) && (pack < SO_CPBOMBPACKS));
00991
00992 return getBit(SRAM_OFFSET[pack]);
00993 }
00994
00995 void SRAMFile::setSuperMissilePack(int pack, bool give) {
00996
00997 wxASSERT((pack >= SO_CSMISSILEPACKS) && (pack < SO_CPBOMBPACKS));
00998
00999 if (!hasSuperMissilePack(pack) && give) {
01000 setMaxSuperMissiles(getMaxSuperMissiles() + 5);
01001 } else if (hasSuperMissilePack(pack) && !give) {
01002 setMaxSuperMissiles(getMaxSuperMissiles() - 5);
01003 setSuperMissiles(getSuperMissiles());
01004 }
01005
01006 setBit(SRAM_OFFSET[pack], give);
01007 }
01008
01009 unsigned char SRAMFile::getSuperMissiles() const {
01010 const std::pair<int, unsigned char> &offset =
01011 SRAM_OFFSET[SO_CURRENTSMISSILES];
01012
01013 return game[offset.first];
01014 }
01015
01016 void SRAMFile::setSuperMissiles(unsigned char missiles) {
01017 const std::pair<int, unsigned char> &offset =
01018 SRAM_OFFSET[SO_CURRENTSMISSILES];
01019 unsigned char max = getMaxSuperMissiles();
01020
01021 if (missiles > max) {
01022 missiles = max;
01023 }
01024
01025 game[offset.first] = missiles;
01026
01027 modified = true;
01028 }
01029
01030 bool SRAMFile::isValidGame(int game) const {
01031
01032 wxASSERT((game >= 0) && (game <= 2));
01033
01034 return valid[game];
01035 }
01036
01037 int SRAMFile::getZebetites() const {
01038 const std::pair<int, unsigned char> &offset =
01039 SRAM_OFFSET[SO_ZEBETITES];
01040
01041 return ((game[offset.first] & 0x38) >> offset.second);
01042 }
01043
01044 void SRAMFile::setZebetites(int count) {
01045
01046 wxASSERT((count >= 0) && (count <= 4));
01047
01048 const std::pair<int, unsigned char> &offset =
01049 SRAM_OFFSET[SO_ZEBETITES];
01050 count <<= offset.second;
01051
01052 game[offset.first] &= ~0x38;
01053 game[offset.first] |= count;
01054
01055 modified = true;
01056 }
01057
01058 std::pair<unsigned char,
01059 unsigned char> SRAMFile::checksum(int game) const {
01060
01061 wxASSERT((game >= 0) && (game <= 2));
01062
01063 const char *ptr = (sram + GAME_OFFSET + (GAME_SIZE * game));
01064 short high = 0, low = 0;
01065 unsigned char value;
01066
01067 for (unsigned int i = 0; i < GAME_SIZE; ++i) {
01068 value = ptr[i];
01069
01070 if ((high += value) > 255) {
01071 high &= 0xFF;
01072 ++low;
01073 }
01074
01075 value = ptr[++i];
01076
01077 if ((low += value) > 255) {
01078 low &= 0xFF;
01079 }
01080 }
01081
01082 return std::pair<unsigned char,
01083 unsigned char>(static_cast<unsigned char>(high),
01084 static_cast<unsigned char>(low));
01085 }
01086
01087 void SRAMFile::checksum() {
01088 for (unsigned int game = 0; game < GAMES; ++game) {
01089 if (valid[game]) {
01090 std::pair<unsigned char, unsigned char> pair = checksum(game);
01091 std::pair<unsigned char, unsigned char> comp = compliment(pair);
01092
01093 sram[CHECKSUM_OFFSET + (game * 2)] = pair.first;
01094 sram[CHECKSUM_OFFSET + (game * 2) + 1] = pair.second;
01095
01096 sram[COMPLIMENT_OFFSET + (game * 2)] = comp.first;
01097 sram[COMPLIMENT_OFFSET + (game * 2) + 1] = comp.second;
01098
01099 sram[CHECKSUM_OFFSET2 + (game * 2)] = pair.first;
01100 sram[CHECKSUM_OFFSET2 + (game * 2) + 1] = pair.second;
01101
01102 sram[COMPLIMENT_OFFSET2 + (game * 2)] = comp.first;
01103 sram[COMPLIMENT_OFFSET2 + (game * 2) + 1] = comp.second;
01104 }
01105 }
01106 }
01107
01108 void SRAMFile::clear(int game) {
01109
01110 wxASSERT((game >= 0) && (game < GAMES));
01111
01112 if (valid[game]) {
01113
01114 std::memset((sram + GAME_OFFSET + (game * GAME_SIZE)), 0, GAME_SIZE);
01115
01116
01117 sram[CHECKSUM_OFFSET + (game * 2)] = 0xFF;
01118 sram[CHECKSUM_OFFSET2 + (game * 2)] = 0xFF;
01119
01120
01121 valid[game] = false;
01122
01123 modified = true;
01124 }
01125 }
01126
01127 void SRAMFile::copy(int src, int dest) {
01128
01129 wxASSERT((src >= 0) && (src < GAMES));
01130 wxASSERT((dest >= 0) && (dest < GAMES));
01131 wxASSERT(src != dest);
01132
01133
01134 wxASSERT(valid[src]);
01135
01136
01137 std::memcpy((sram + GAME_OFFSET + (dest * GAME_SIZE)),
01138 (sram + GAME_OFFSET + (src * GAME_SIZE)),
01139 GAME_SIZE);
01140
01141
01142 valid[dest] = true;
01143
01144 modified = true;
01145 }
01146
01147 std::pair<unsigned char, unsigned char>
01148 SRAMFile::compliment(std::pair<unsigned char,
01149 unsigned char> checksum) const {
01150 return std::pair<unsigned char, unsigned char>((checksum.first ^ 0xFF),
01151 (checksum.second ^ 0xFF));
01152 }
01153
01154 bool SRAMFile::hasValidGame() {
01155 bool valid = false;
01156
01157 for (unsigned int game = 0; game < GAMES; ++game) {
01158 std::pair<unsigned char, unsigned char> schecksum = getChecksum(game);
01159 std::pair<unsigned char,
01160 unsigned char> scompliment = getCompliment(game);
01161
01162 std::pair<unsigned char, unsigned char> rchecksum =
01163 getChecksum(game, true);
01164 std::pair<unsigned char, unsigned char> rcompliment =
01165 getCompliment(game, true);
01166
01167 std::pair<unsigned char, unsigned char> lchecksum = checksum(game);
01168 std::pair<unsigned char,
01169 unsigned char> lcompliment = compliment(lchecksum);
01170
01171 if ((schecksum == lchecksum) && (scompliment == lcompliment) &&
01172 (rchecksum == lchecksum) && (rcompliment == lcompliment)) {
01173 this->valid[game] = true;
01174 valid = true;
01175 } else {
01176 this->valid[game] = false;
01177 }
01178 }
01179
01180 return valid;
01181 }
01182
01183 void SRAMFile::read() throw(FileIOException, InvalidSRAMFileException) {
01184 std::fstream in(filename.mb_str(),
01185 std::ios_base::in | std::ios_base::binary);
01186
01187 if (!in) {
01188 throw FileIOException("Unable to open file for reading!");
01189 }
01190
01191 in.read(sram, SRAM_SIZE);
01192
01193 if (in.gcount() != static_cast<std::streamsize>(SRAM_SIZE)) {
01194 throw FileIOException("Unable to read SRAM data!");
01195 }
01196
01197 char ch;
01198
01199 if (in.get(ch)) {
01200 throw InvalidSRAMFileException("Not a valid SRAM file");
01201 }
01202
01203 in.close();
01204 }
01205
01206 void SRAMFile::save(const wxString &filename) throw(FileIOException) {
01207 if (filename != wxEmptyString) {
01208 this->filename = filename;
01209 }
01210
01211 checksum();
01212 write();
01213
01214 modified = false;
01215 }
01216
01217 void SRAMFile::write() throw(FileIOException) {
01218 std::fstream out(filename.mb_str(),
01219 std::ios_base::out | std::ios_base::binary);
01220
01221 if (!out) {
01222 throw FileIOException("Unable to open file for writing!");
01223 }
01224
01225 out.write(sram, SRAM_SIZE);
01226
01227 if (out.tellp() != static_cast<std::streampos>(SRAM_SIZE)) {
01228 throw FileIOException("Unable to write SRAM data!");
01229 }
01230
01231 out.close();
01232 }
01233