Main Page | Namespace List | Class List | File List | Namespace Members | Class Members | File Members

source/model/SaveSlot.cc

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004 emuWorks
00003  * http://games.technoplaza.net/
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * as published by the Free Software Foundation; either version 2
00008  * of the License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018  */
00019 
00020 // $Id: SaveSlot.cc,v 1.8 2004/12/08 07:22:06 technoplaza Exp $
00021 
00022 #ifdef HAVE_CONFIG_H
00023     #include <config.h>
00024 #endif
00025 
00026 #include <wx/wxprec.h>
00027 
00028 #ifndef WX_PRECOMP
00029     #include <wx/wx.h>
00030 #endif
00031 
00032 #include <cstring>
00033 
00034 #include "SaveSlot.hh"
00035 
00036 using namespace ffse;
00037 
00038 SaveSlot::SaveSlot(const char *nvram) {
00039     this->nvram = new unsigned char[GAME_SIZE];
00040     memcpy(this->nvram, nvram, GAME_SIZE);
00041     
00042     if (checksum() == (unsigned char)nvram[CHECKSUM_OFFSET]) {
00043         valid = true;
00044         setModified(false);
00045     } else {
00046         valid = false;
00047     }
00048 }
00049 
00050 SaveSlot::~SaveSlot() {
00051     if (nvram != 0) {
00052         delete nvram;
00053     }
00054 }
00055 
00056 unsigned char SaveSlot::checksum() {
00057     unsigned char sum = 0;
00058     
00059     // clear the carry flag
00060     setCarry(false);
00061     
00062     for (int pos = 0; pos < 0x100; pos++) {
00063         if (pos != 0xFD) {
00064             sum = adc(sum, nvram[pos]);
00065         }
00066         
00067         sum = adc(sum, nvram[pos + 0x100]);
00068         sum = adc(sum, nvram[pos + 0x200]);
00069         sum = adc(sum, nvram[pos + 0x300]);
00070     }
00071     
00072     return (sum ^ 0xFF);
00073 }
00074 
00075 wxInt32 SaveSlot::getGold() {
00076     unsigned char *byte = (nvram + GOLD_OFFSET);
00077     wxInt32 value = 0;
00078 
00079     for (int i = 2; i >= 0; i--) {
00080         if (byte[i] == 0) {
00081             continue;
00082         }
00083         
00084         value <<= 8;
00085         value |= byte[i];
00086     }
00087     
00088     return value;
00089 }
00090 
00091 void SaveSlot::setGold(wxInt32 value) {
00092     for (int i = 0; i < 3; i++) {
00093         unsigned char temp = (value & 0xFF);
00094         nvram[GOLD_OFFSET + i] = temp;
00095         value >>= 8;
00096     }
00097     
00098     setModified();
00099 }
00100 
00101 int SaveSlot::getItem(int item) {
00102     return nvram[ITEM_OFFSET + item];
00103 }
00104 
00105 void SaveSlot::setItem(int item, unsigned char value) {
00106     nvram[ITEM_OFFSET + item] = value;
00107     
00108     setModified();
00109 }
00110 
00111 wxString SaveSlot::getName(int member) {
00112     wxString name;
00113     
00114     for (int pos = 0; pos < 4; pos++) {
00115         char letter = fromNES(nvram[NAME_OFFSET + (MEMBER_GAP * member) + pos]);
00116         name.append(1, letter);
00117     }
00118     
00119     return name;
00120 }
00121 
00122 void SaveSlot::setName(int member, wxString &value) {
00123     int length = value.size();
00124     
00125     for (int pos = 0; pos < 4; pos++) {
00126         unsigned char letter;
00127         
00128         if ((length - 1) < pos) {
00129             letter = toNES(' ');
00130         } else {
00131             letter = toNES(value.at(pos));
00132         }
00133         
00134         nvram[NAME_OFFSET + (MEMBER_GAP * member) + pos] = letter;
00135     }
00136     
00137     setModified();
00138 }
00139 
00140 int SaveSlot::getClass(int member) {
00141     return nvram[CLASS_OFFSET + (MEMBER_GAP * member)];
00142 }
00143 
00144 void SaveSlot::setClass(int member, unsigned char value) {
00145     nvram[CLASS_OFFSET + (MEMBER_GAP * member)] = value;
00146     
00147     setModified();
00148 }
00149 
00150 int SaveSlot::getCondition(int member) {
00151     return nvram[CONDITION_OFFSET + (MEMBER_GAP * member)];
00152 }
00153 
00154 void SaveSlot::setCondition(int member, unsigned char value) {
00155     nvram[CONDITION_OFFSET + (MEMBER_GAP * member)] = value;
00156     
00157     setModified();
00158 }
00159 
00160 wxInt16 SaveSlot::getCurrentHP(int member) {
00161     wxInt16 *ptr = (wxInt16 *)(nvram + 
00162                                CURRENT_HP_OFFSET + (MEMBER_GAP * member));
00163                                           
00164     return wxINT16_SWAP_ON_BE(ptr[0]);
00165 }
00166 
00167 void SaveSlot::setCurrentHP(int member, wxInt16 value) {
00168     wxInt16 *ptr = (wxInt16 *)(nvram +
00169                                CURRENT_HP_OFFSET + (MEMBER_GAP * member));
00170                                           
00171     ptr[0] = wxINT16_SWAP_ON_BE(value);
00172     setModified();
00173 }
00174 
00175 wxInt16 SaveSlot::getMaxHP(int member) {
00176     wxInt16 *ptr = (wxInt16 *)(nvram + MAX_HP_OFFSET + (MEMBER_GAP * member));
00177                                           
00178     return wxINT16_SWAP_ON_BE(ptr[0]);
00179 }
00180 
00181 void SaveSlot::setMaxHP(int member, wxInt16 value) {
00182     wxInt16 *ptr = (wxInt16 *)(nvram + MAX_HP_OFFSET + (MEMBER_GAP * member));
00183                                           
00184     ptr[0] = wxINT16_SWAP_ON_BE(value);
00185     setModified();
00186 }
00187 
00188 wxInt32 SaveSlot::getExperience(int member) {
00189     unsigned char *byte = (nvram + EXPERIENCE_OFFSET + (MEMBER_GAP * member));
00190     wxInt32 value = 0;
00191 
00192     for (int i = 2; i >= 0; i--) {
00193         if (byte[i] == 0) {
00194             continue;
00195         }
00196         
00197         value <<= 8;
00198         value |= byte[i];
00199     }
00200     
00201     return value;
00202 }
00203 
00204 void SaveSlot::setExperience(int member, wxInt32 value) {
00205     int offset = EXPERIENCE_OFFSET + (MEMBER_GAP * member);
00206     
00207     for (int i = 0; i < 3; i++) {
00208         unsigned char temp = (value & 0xFF);
00209         nvram[offset + i] = temp;
00210         value >>= 8;
00211     }
00212     
00213     setModified();
00214 }
00215 
00216 int SaveSlot::getStrength(int member) {
00217     return nvram[STRENGTH_OFFSET + (MEMBER_GAP * member)];
00218 }
00219 
00220 void SaveSlot::setStrength(int member, unsigned char value) {
00221     nvram[STRENGTH_OFFSET + (MEMBER_GAP * member)] = value;
00222     
00223     setModified();
00224 }
00225 
00226 int SaveSlot::getAgility(int member) {
00227     return nvram[AGILITY_OFFSET + (MEMBER_GAP * member)];
00228 }
00229 
00230 void SaveSlot::setAgility(int member, unsigned char value) {
00231     nvram[AGILITY_OFFSET + (MEMBER_GAP * member)] = value;
00232     
00233     setModified();
00234 }
00235 
00236 int SaveSlot::getIntelligence(int member) {
00237     return nvram[INTELLIGENCE_OFFSET + (MEMBER_GAP * member)];
00238 }
00239 
00240 void SaveSlot::setIntelligence(int member, unsigned char value) {
00241     nvram[INTELLIGENCE_OFFSET + (MEMBER_GAP * member)] = value;
00242     
00243     setModified();
00244 }
00245 
00246 int SaveSlot::getVitality(int member) {
00247     return nvram[VITALITY_OFFSET + (MEMBER_GAP * member)];
00248 }
00249 
00250 void SaveSlot::setVitality(int member, unsigned char value) {
00251     nvram[VITALITY_OFFSET + (MEMBER_GAP * member)] = value;
00252     
00253     setModified();
00254 }
00255 
00256 int SaveSlot::getLuck(int member) {
00257     return nvram[LUCK_OFFSET + (MEMBER_GAP * member)];
00258 }
00259 
00260 void SaveSlot::setLuck(int member, unsigned char value) {
00261     nvram[LUCK_OFFSET + (MEMBER_GAP * member)] = value;
00262     
00263     setModified();
00264 }
00265 
00266 int SaveSlot::getDamage(int member) {
00267     return nvram[DAMAGE_OFFSET + (MEMBER_GAP * member)];
00268 }
00269 
00270 void SaveSlot::setDamage(int member, unsigned char value) {
00271     nvram[DAMAGE_OFFSET + (MEMBER_GAP * member)] = value;
00272     
00273     setModified();
00274 }
00275 
00276 int SaveSlot::getHitPercent(int member) {
00277     return nvram[HIT_PERCENT_OFFSET + (MEMBER_GAP * member)];
00278 }
00279 
00280 void SaveSlot::setHitPercent(int member, unsigned char value) {
00281     nvram[HIT_PERCENT_OFFSET + (MEMBER_GAP * member)] = value;
00282     
00283     setModified();
00284 }
00285 
00286 int SaveSlot::getWeapon(int member, int slot) {
00287     return nvram[WEAPON_OFFSET + (MEMBER_GAP * member) + slot];
00288 }
00289 
00290 void SaveSlot::setWeapon(int member, int slot, unsigned char value) {
00291     nvram[WEAPON_OFFSET + (MEMBER_GAP * member) + slot] = value;
00292     
00293     setModified();
00294 }
00295 
00296 int SaveSlot::getArmor(int member, int slot) {
00297     return nvram[ARMOR_OFFSET + (MEMBER_GAP * member) + slot];
00298 }
00299 
00300 void SaveSlot::setArmor(int member, int slot, unsigned char value) {
00301     nvram[ARMOR_OFFSET + (MEMBER_GAP * member) + slot] = value;
00302     
00303     setModified();
00304 }
00305 
00306 int SaveSlot::getCurrentMagic(int member, int level) {
00307     return nvram[CURRENT_MAGIC_OFFSET + (MEMBER_GAP * member) + level];
00308 }
00309 
00310 void SaveSlot::setCurrentMagic(int member, int level, unsigned char value) {
00311     nvram[CURRENT_MAGIC_OFFSET + (MEMBER_GAP * member) + level] = value;
00312     
00313     setModified();
00314 }
00315 
00316 int SaveSlot::getMaxMagic(int member, int level) {
00317     return nvram[MAX_MAGIC_OFFSET + (MEMBER_GAP * member) + level];
00318 }
00319 
00320 void SaveSlot::setMaxMagic(int member, int level, unsigned char value) {
00321     nvram[MAX_MAGIC_OFFSET + (MEMBER_GAP * member) + level] = value;
00322     
00323     setModified();
00324 }
00325 
00326 int SaveSlot::getMagic(int member, int level, int slot) {
00327     int offset = MAGIC_OFFSET + (MEMBER_GAP * member) + 
00328                  (level * 3) + level + slot;
00329 
00330     return nvram[offset];
00331 }
00332 
00333 void SaveSlot::setMagic(int member, int level, int slot, unsigned char value) {
00334     int offset = MAGIC_OFFSET + (MEMBER_GAP * member) + 
00335                  (level * 3) + level + slot;
00336     
00337     nvram[offset] = value;
00338     setModified();
00339 }
00340 
00341 unsigned char SaveSlot::adc(unsigned char current, unsigned char value) {
00342     int n = (int)current;
00343     
00344     if (carry == 1) {
00345         n++;
00346         carry = 0;
00347     }
00348     
00349     n += (int)value;
00350     
00351     if ((n >> 8) == 1) {
00352         carry = 1;
00353     }
00354     
00355     return (unsigned char)(n & 0xFF);
00356 }
00357 
00358 void SaveSlot::setModified(bool modified) {
00359     this->modified = modified;
00360     
00361     if (modified) {
00362         nvram[CHECKSUM_OFFSET] = checksum();
00363     }
00364 }
00365 
00366 unsigned char SaveSlot::toNES(char letter) {
00367     if ((letter >= '0') && (letter <= '9')) {
00368         return (unsigned char)(0x80 + (letter - '0'));
00369     } else if ((letter >= 'A') && (letter <= 'Z')) {
00370         return (unsigned char)(0x8A + (letter - 'A'));
00371     } else if ((letter >= 'a') && (letter <= 'z')) {
00372         return (unsigned char)(0xA4 + (letter - 'a'));
00373     } else if (letter == '\'') {
00374         return (unsigned char)0xBE;
00375     } else if (letter == ',') {
00376         return (unsigned char)0xBF;
00377     } else if (letter == '.') {
00378         return (unsigned char)0xC0;
00379     } else if (letter == '-') {
00380         return (unsigned char)0xC2;
00381     } else if (letter == ':') {
00382         return (unsigned char)0xC3;
00383     } else if (letter == '!') {
00384         return (unsigned char)0xC4;
00385     } else if (letter == '?') {
00386         return (unsigned char)0xC5;
00387     }
00388     
00389     return (unsigned char)0xFF;
00390 }
00391 
00392 char SaveSlot::fromNES(unsigned char letter) {
00393     if ((letter >= 0x80) && (letter < 0x8A)) {
00394         return (char)('0' + (letter - 0x80));
00395     } else if ((letter >= 0x8A) && (letter < 0xA4)) {
00396         return (char)('A' + (letter - 0x8A));
00397     } else if ((letter >= 0xA4) && (letter < 0xBE)) {
00398         return (char)('a' + (letter - 0xA4));
00399     } else if (letter == 0xBE) {
00400         return (char)'\'';
00401     } else if (letter == 0xBF) {
00402         return (char)',';
00403     } else if (letter == 0xC0) {
00404         return (char)'.';
00405     } else if (letter == 0xC2) {
00406         return (char)'-';
00407     } else if (letter == 0xC3) {
00408         return (char)':';
00409     } else if (letter == 0xC4) {
00410         return (char)'!';
00411     } else if (letter == 0xC5) {
00412         return (char)'?';
00413     }
00414     
00415     return (char)' ';
00416 }
00417 

Generated on Wed Dec 8 03:21:44 2004 for Final Fantasy SRAM Editor by  doxygen 1.3.9.1