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