SRAMFile.cc

Go to the documentation of this file.
00001 /*
00002  * Super Metroid SRAM Editor
00003  * Copyright (C) 2005,2007-2008 emuWorks
00004  * http://games.technoplaza.net/
00005  *
00006  * This file is part of Super Metroid SRAM Editor.
00007  *
00008  * Super Metroid SRAM Editor is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * Super Metroid SRAM Editor is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with Super Metroid SRAM Editor; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00021  */
00022  
00023 // $Id: SRAMFile.cc,v 1.36 2008/12/17 04:14:15 jdratlif Exp $
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         // Energy (Current/Max) [0]
00039         std::pair<int, unsigned char>(0x20, 0),
00040         std::pair<int, unsigned char>(0x22, 0),
00041         
00042         // Reserve Energy (Current/Max) [2]
00043         std::pair<int, unsigned char>(0x34, 0),
00044         std::pair<int, unsigned char>(0x32, 0),
00045         
00046         // Missiles (Current/Max) [4]
00047         std::pair<int, unsigned char>(0x24, 0),
00048         std::pair<int, unsigned char>(0x26, 0),
00049         
00050         // Super Missiles (Current/Max) [6]
00051         std::pair<int, unsigned char>(0x28, 0),
00052         std::pair<int, unsigned char>(0x2A, 0),
00053         
00054         // Power Bombs (Current/Max) [8]
00055         std::pair<int, unsigned char>(0x2C, 0),
00056         std::pair<int, unsigned char>(0x2E, 0),
00057         
00058         // Morphing Ball [10]
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         // Bombs [13]
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         // Spring Ball [16]
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         // High Jump Boots [19]
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         // Varia Suit [22]
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         // Gravity Suit [25]
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         // Speed Booster [28]
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         // Space Jump [31]
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         // Screw Attack [34]
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         // Charge Beam [37]
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         // Ice Beam [40]
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         // Wave Beam [43]
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         // Spazer [46]
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         // Plasma Beam [49]
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         // Grappling Beam [52]
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         // X-Ray Scope [55]
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         // Silver Torizo [58]
00139         std::pair<int, unsigned char>(0x68, 0x4),
00140         
00141         // Spore Spawn [59]
00142         std::pair<int, unsigned char>(0x69, 0x2),
00143         
00144         // Kraid [60]
00145         std::pair<int, unsigned char>(0x69, 0x1),
00146         std::pair<int, unsigned char>(0x61, 0x2),
00147         
00148         // Phantoon [62]
00149         std::pair<int, unsigned char>(0x6B, 0x1),
00150         std::pair<int, unsigned char>(0x60, 0x40),
00151         
00152         // Botwoon [64]
00153         std::pair<int, unsigned char>(0x6C, 0x2),
00154         
00155         // Draygon [65]
00156         std::pair<int, unsigned char>(0x6C, 0x1),
00157         std::pair<int, unsigned char>(0x61, 0x1),
00158         
00159         // Crocomire [67]
00160         std::pair<int, unsigned char>(0x6A, 0x2),
00161         
00162         // Golden Torizo [68]
00163         std::pair<int, unsigned char>(0x6A, 0x4),
00164         
00165         // Ridley [69]
00166         std::pair<int, unsigned char>(0x6A, 0x1),
00167         std::pair<int, unsigned char>(0x60, 0x80),
00168         
00169         // Metroid Rooms [71]
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         // Zebetites [75]
00176         std::pair<int, unsigned char>(0x60, 0x3),
00177         
00178         // Tourian Elevator [76]
00179         std::pair<int, unsigned char>(0x61, 0x4),
00180         
00181         // Maridia Glass Tube Broken [77]
00182         std::pair<int, unsigned char>(0x61, 0x8),
00183         
00184         // Rescued Animals [78]
00185         std::pair<int, unsigned char>(0x61, 0x80),
00186         
00187         // Crateria Missile Packs (8) [79]
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         // Brinstar Missile Packs (12) [87]
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         // Norfair Missile Packs (15) [99]
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         // Wrecked Ship Missile Packs (3) [114]
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         // Maridia Missile Packs (8) [117]
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         // Crateria Super Missile Packs (1) [125]
00244         std::pair<int, unsigned char>(0xB1, 0x8),
00245         
00246         // Brinstar Super Missile Packs (3) [126]
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         // Norfair Super Missile Packs (1) [129]
00252         std::pair<int, unsigned char>(0xB8, 0x80),
00253         
00254         // Wrecked Ship Super Missile Packs (2) [130]
00255         std::pair<int, unsigned char>(0xC0, 0x20),
00256         std::pair<int, unsigned char>(0xC0, 0x40),
00257         
00258         // Maridia Super Missile Packs (3) [132]
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         // Crateria Power Bomb Packs (1) [135]
00264         std::pair<int, unsigned char>(0xB0, 0x1),
00265         
00266         // Brinstar Power Bomb Packs (5) [136]
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         // Norfair Power Bomb Packs (3) [141]
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         // Maridia Power Bomb Packs (1) [144]
00279         std::pair<int, unsigned char>(0xC2, 0x8),
00280         
00281         // Crateria Energy Tanks (2) [145]
00282         std::pair<int, unsigned char>(0xB0, 0x20),
00283         std::pair<int, unsigned char>(0xB1, 0x1),
00284         
00285         // Brinstar Energy Tanks (5) [147]
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         // Norfair Energy Tanks (4) [152]
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         // Wrecked Ship Energy Tanks (1)  [156]
00299         std::pair<int, unsigned char>(0xC0, 0x10),
00300         
00301         // Maridia Energy Tanks (2) [157]
00302         std::pair<int, unsigned char>(0xC1, 0x4),
00303         std::pair<int, unsigned char>(0xC3, 0x1),
00304         
00305         // Brinstar Reserve Tank [159]
00306         std::pair<int, unsigned char>(0xB2, 0x2),
00307         
00308         // Norfair Reserve Tank [160]
00309         std::pair<int, unsigned char>(0xB7, 0x20),
00310         
00311         // Wrecked Ship Reserve Tank [161]
00312         std::pair<int, unsigned char>(0xC0, 0x2),
00313         
00314         // Maridia Reserve Tank [162]
00315         std::pair<int, unsigned char>(0xC2, 0x2),
00316         
00317         // Crateria Red Doors (3) [163]
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         // Brinstar Red Doors (10) [166]
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         // Norfair Red Doors (7) [176]
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         // Wrecked Ship Red Doors (1) [183]
00344         std::pair<int, unsigned char>(0x101, 0x8),
00345         
00346         // Maridia Red Doors (8) [184]
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         // Tourian Red Doors (2) [191]
00356         std::pair<int, unsigned char>(0x104, 0x80),
00357         std::pair<int, unsigned char>(0x105, 0x2),
00358         
00359         // Crateria Green Doors (2) [193]
00360         std::pair<int, unsigned char>(0xF0, 0x1),
00361         std::pair<int, unsigned char>(0xF1, 0x10),
00362         
00363         // Brinstar Green Doors (10) [195]
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         // Norfair Green Doors (6) [205]
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         // Wrecked Ship Green Doors (1) [211]
00384         std::pair<int, unsigned char>(0x100, 0x10),
00385         
00386         // Maridia Green Doors (4) [212]
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         // Crateria Yellow Doors (6) [216]
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         // Brinstar Yellow Doors (4) [222]
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         // Norfair Yellow Doors (3) [226]
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         // Crateria Metal Doors (1) [229]
00412         std::pair<int, unsigned char>(0xF3, 0x8),
00413         
00414         // Brinstar Metal Doors (16) [230]
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         // Norfair Metal Doors (6) [246]
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         // Wrecked Ship Metal Doors (5) [252]
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         // Maridia Metal Doors (7) [257]
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         // Tourian Metal Doors (5) [264]
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         // Brinstar Eye Door (Kraid) [269]
00464         std::pair<int, unsigned char>(0xF8, 0x20),
00465         
00466         // Norfair Eye Door (Ridley) [270]
00467         std::pair<int, unsigned char>(0xFB, 0x10),
00468         
00469         // Wrecked Ship Eye Door (Phantoon) [271]
00470         std::pair<int, unsigned char>(0x100, 0x20),
00471         
00472         // Maridia Eye Door (Draygon) [272]
00473         std::pair<int, unsigned char>(0x103, 0x8),
00474         
00475         // Tourian Eye Door [273]
00476         std::pair<int, unsigned char>(0x105, 0x1),
00477         
00478         // Crateria Map [274]
00479         std::pair<int, unsigned char>(0x148, 0xFF),
00480         
00481         // Brinstar Map [275]
00482         std::pair<int, unsigned char>(0x149, 0xFF),
00483         
00484         // Norfair Map [276]
00485         std::pair<int, unsigned char>(0x14A, 0xFF),
00486         
00487         // Wrecked Ship Map [277]
00488         std::pair<int, unsigned char>(0x14B, 0xFF),
00489         
00490         // Maridia Map [278]
00491         std::pair<int, unsigned char>(0x14C, 0xFF),
00492         
00493         // Tourian Map [279]
00494         std::pair<int, unsigned char>(0x14D, 0xFF),
00495         
00496         // Save Spot (Area, Point) [280]
00497         std::pair<int, unsigned char>(0x158, 0),
00498         std::pair<int, unsigned char>(0x156, 0),
00499         
00500         // Game Hours [282]
00501         std::pair<int, unsigned char>(0x3E, 0xFF),
00502         
00503         // Game Minutes [283]
00504         std::pair<int, unsigned char>(0x3C, 0xFF),
00505         
00506         // Shot Button [284]
00507         std::pair<int, unsigned char>(0x10, 0),
00508         
00509         // Jump Button [285]
00510         std::pair<int, unsigned char>(0x12, 0),
00511         
00512         // Dash Button [286]
00513         std::pair<int, unsigned char>(0x14, 0),
00514         
00515         // Item Cancel Button [287]
00516         std::pair<int, unsigned char>(0x16, 0),
00517         
00518         // Item Select Button [288]
00519         std::pair<int, unsigned char>(0x18, 0),
00520         
00521         // Angle Down Button [289]
00522         std::pair<int, unsigned char>(0x1A, 0),
00523         
00524         // Angle Up Button [290]
00525         std::pair<int, unsigned char>(0x1C, 0),
00526         
00527         // Language (English or Japanese) [291]
00528         std::pair<int, unsigned char>(0x40, 0x1),
00529         
00530         // Moon Walk (Off or On) [292]
00531         std::pair<int, unsigned char>(0x42, 0x1),
00532         
00533         // Icon Cancel (Manual or Automatic) [293]
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),     // A
00540         std::pair<unsigned char, unsigned char>(0x0, 0x80),     // B
00541         std::pair<unsigned char, unsigned char>(0x40, 0x0),     // X
00542         std::pair<unsigned char, unsigned char>(0x0, 0x40),     // Y
00543         std::pair<unsigned char, unsigned char>(0x20, 0x0),     // L
00544         std::pair<unsigned char, unsigned char>(0x10, 0x0),     // R
00545         std::pair<unsigned char, unsigned char>(0x0, 0x20)     // Select
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     // we should NEVER reach here
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     // ensure we have a valid game
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     // ensure we have a valid game
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     // ensure we have a valid door
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     // ensure we have a valid door
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     // ensure we have a valid energy tank
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     // ensure we have a valid energy tank
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     // ensure we have a valid game
00698     wxASSERT((game >= 0) && (game <= 2));
00699     
00700     // ensure we are choosing a valid game
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     // ensure we have a valid number of hours
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     // ensure we have a valid number of minutes
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     // ensure we have a valid missile pack number
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     // ensure we have a valid missile pack number
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     // ensure we have a valid power bomb pack
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     // ensure we have a valid power bomb pack
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     // ensure we have a valid reserve tank
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     // ensure we have a valid reserve tank
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     // ensure we have a valid save point
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     // ensure we have a valid super missile pack
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     // ensure we have a valid super missile pack
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     // ensure we have a valid game
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     // ensure a valid number of dead zebetites
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     // ensure we have a valid game
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     // ensure we have a valid game
01110     wxASSERT((game >= 0) && (game < GAMES));
01111     
01112     if (valid[game]) {
01113         // clear the game data
01114         std::memset((sram + GAME_OFFSET + (game * GAME_SIZE)), 0, GAME_SIZE);
01115         
01116         // invalidate the checksum
01117         sram[CHECKSUM_OFFSET + (game * 2)] = 0xFF;
01118         sram[CHECKSUM_OFFSET2 + (game * 2)] = 0xFF;
01119         
01120         // the game is no longer valid
01121         valid[game] = false;
01122         
01123         modified = true;
01124     }
01125 }
01126 
01127 void SRAMFile::copy(int src, int dest) {
01128     // ensure we have valid games
01129     wxASSERT((src >= 0) && (src < GAMES));
01130     wxASSERT((dest >= 0) && (dest < GAMES));
01131     wxASSERT(src != dest);
01132     
01133     // ensure our source is a valid game to duplicate
01134     wxASSERT(valid[src]);
01135     
01136     // copy the game data
01137     std::memcpy((sram + GAME_OFFSET + (dest * GAME_SIZE)),
01138                 (sram + GAME_OFFSET + (src * GAME_SIZE)),
01139                 GAME_SIZE);
01140                 
01141     // the destination is now a valid game
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 

Generated on Mon Dec 29 01:15:52 2008 for Super Metroid SRAM Editor by  doxygen 1.5.4