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

SaveSlot.cc

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

Generated on Wed Aug 3 22:01:53 2005 for ffse by  doxygen 1.4.4