SaveSlot.cc

Go to the documentation of this file.
00001 /*
00002  * hack4u
00003  * Copyright (C) 2004-2008 emuWorks
00004  * http://games.technoplaza.net/
00005  *
00006  * This file is part of hack4u.
00007  *
00008  * hack4u 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  * hack4u 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 hack4u; 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.21 2008/12/16 22:12:52 jdratlif Exp $
00024 
00025 #ifdef HAVE_CONFIG_H
00026     #include <config.h>
00027 #endif
00028 
00029 #include <cstring>
00030 
00031 #include "model/ModelConstants.hh"
00032 #include "model/SaveSlot.hh"
00033 
00034 using namespace hack4u;
00035 
00036 const std::pair<int, int> hack4u::FOUND_RUNES_OFFSET[] = {
00037     std::pair<int, int>(0xD4, 4), std::pair<int, int>(0xD4, 5),
00038     std::pair<int, int>(0xD4, 6), std::pair<int, int>(0xD4, 7),
00039     std::pair<int, int>(0xD5, 0), std::pair<int, int>(0xD5, 1),
00040     std::pair<int, int>(0xD5, 2), std::pair<int, int>(0xD5, 3)
00041 };
00042 
00043 const std::pair<int, int> hack4u::FOUND_STONES_OFFSET[] = {
00044     std::pair<int, int>(0xD6, 7), std::pair<int, int>(0xD7, 0),
00045     std::pair<int, int>(0xD7, 1), std::pair<int, int>(0xD7, 2),
00046     std::pair<int, int>(0xD7, 3), std::pair<int, int>(0xD7, 4),
00047     std::pair<int, int>(0xD7, 5), std::pair<int, int>(0xD7, 6)
00048 };
00049 
00050 const std::pair<int, int> hack4u::FOUND_BELL_OFFSET(0xD6, 1);
00051 const std::pair<int, int> hack4u::FOUND_BOOK_OFFSET(0xD6, 0);
00052 const std::pair<int, int> hack4u::FOUND_CANDLE_OFFSET(0xD5, 7);
00053 const std::pair<int, int> hack4u::FOUND_FLUTE_OFFSET(0xD5, 5);
00054 const std::pair<int, int> hack4u::FOUND_HORN_OFFSET(0xD6, 3);
00055 const std::pair<int, int> hack4u::FOUND_SCALE_OFFSET(0xD5, 4);
00056 const std::pair<int, int> hack4u::FOUND_SKULL_OFFSET(0xD6, 4);
00057 
00058 const int SaveSlot::CHECKSUM_XORS[] = {
00059     0x55, 0xAA, 0x33, 0xCC,
00060     0xA5, 0x5A, 0xBB, 0x99
00061 };
00062 
00063 SaveSlot::SaveSlot(const char *data) {
00064     nvram = new unsigned char[SAVE_SIZE];
00065     std::memcpy(nvram, data, SAVE_SIZE);
00066     
00067     setModified(false);
00068 }
00069 
00070 SaveSlot::~SaveSlot() {
00071     delete nvram;
00072 }
00073 
00074 std::pair<int, int> SaveSlot::getBalloonLocation() const {
00075     return std::pair<int, int>(nvram[BALLOON_LATITUDE_OFFSET],
00076                                nvram[BALLOON_LONGITUDE_OFFSET]);
00077 }
00078 
00079 void SaveSlot::setBalloonLocation(std::pair<int, int> location) {
00080     nvram[BALLOON_LATITUDE_OFFSET] = location.first;
00081     nvram[BALLOON_LONGITUDE_OFFSET] = location.second;
00082     
00083     setModified();
00084 }
00085 
00086 wxInt16 SaveSlot::getCurrentHP(enum Character character) const {
00087     wxInt16 *ptr = reinterpret_cast<wxInt16 *>
00088         (nvram + CURRENT_HP_OFFSET + (character * 2));
00089     
00090     return wxINT16_SWAP_ON_BE(ptr[0]);
00091 }
00092 
00093 void SaveSlot::setCurrentHP(enum Character character, wxInt16 value) {
00094     wxInt16 *ptr = reinterpret_cast<wxInt16 *>
00095         (nvram + CURRENT_HP_OFFSET + (character * 2));
00096     
00097     ptr[0] = wxINT16_SWAP_ON_BE(value);
00098     setModified();
00099 }
00100 
00101 int SaveSlot::getCurrentMP(enum Character character) const {
00102     return nvram[CURRENT_MP_OFFSET + character];
00103 }
00104 
00105 void SaveSlot::setCurrentMP(enum Character character, unsigned char value) {
00106     nvram[CURRENT_MP_OFFSET + character] = value;
00107     setModified();
00108 }
00109 
00110 int SaveSlot::getDexterity(enum Character character) const {
00111     return nvram[DEXTERITY_OFFSET + character];
00112 }
00113 
00114 void SaveSlot::setDexterity(enum Character character, unsigned char value) {
00115     nvram[DEXTERITY_OFFSET + character] = value;
00116     setModified();
00117 }
00118 
00119 int SaveSlot::getEquipment(enum Character character, int slot) const {
00120     return nvram[EQUIPMENT_OFFSET + (character * 6) + slot];
00121 }
00122 
00123 void SaveSlot::setEquipment(enum Character character,
00124                             int slot, unsigned char value) {
00125     nvram[EQUIPMENT_OFFSET + (character * 6) + slot] = value;
00126     setModified();
00127 }
00128 
00129 wxInt16 SaveSlot::getExperience(enum Character character) const {
00130     wxInt16 *ptr = reinterpret_cast<wxInt16 *>
00131         (nvram + EXPERIENCE_OFFSET + (character * 2));
00132     
00133     return wxINT16_SWAP_ON_BE(ptr[0]);
00134 }
00135 
00136 void SaveSlot::setExperience(enum Character character, wxInt16 value) {
00137     wxInt16 *ptr = reinterpret_cast<wxInt16 *>
00138         (nvram + EXPERIENCE_OFFSET + (character * 2));
00139     
00140     ptr[0] = wxINT16_SWAP_ON_BE(value);
00141     setModified();
00142 }
00143 
00144 wxInt16 SaveSlot::getGold() const {
00145     wxUint16 *ptr = reinterpret_cast<wxUint16 *>(nvram + GOLD_OFFSET);
00146     
00147     return wxINT16_SWAP_ON_BE(ptr[0]);
00148 }
00149 
00150 void SaveSlot::setGold(wxInt16 gold) {
00151     wxUint16 *ptr = reinterpret_cast<wxUint16 *>(nvram + GOLD_OFFSET);
00152     
00153     ptr[0] = wxINT16_SWAP_ON_BE(gold);
00154     setModified();
00155 }
00156 
00157 int SaveSlot::getHerb(enum Herb herb) const {
00158     return nvram[HERB_OFFSET + herb];
00159 }
00160 
00161 void SaveSlot::setHerb(enum Herb herb, unsigned char value) {
00162     nvram[HERB_OFFSET + herb] = value;
00163     setModified();
00164 }
00165 
00166 wxString SaveSlot::getHerosName() const {
00167     wxString name;
00168     
00169     for (int offset = NAME_OFFSET; offset <= (NAME_OFFSET + 5); ++offset) {
00170         if (nvram[offset] == 0) {
00171             break;
00172         }
00173         
00174         char letter = fromNES(nvram[offset]);
00175         name.append(1, letter);
00176     }
00177     
00178     return name;
00179 }
00180 
00181 void SaveSlot::setHerosName(const wxString &name) {
00182     int pos;
00183     int length = name.size();
00184     
00185     for (pos = 0; pos < 5; ++pos) {
00186         if ((length - 1) < pos) {
00187             nvram[NAME_OFFSET + pos] = 0;
00188         } else {
00189             nvram[NAME_OFFSET + pos] = toNES(name.at(pos));
00190         }
00191     }
00192     
00193     setModified();
00194 }
00195 
00196 int SaveSlot::getIntelligence(enum Character character) const {
00197     return nvram[INTELLIGENCE_OFFSET + character];
00198 }
00199 
00200 void SaveSlot::setIntelligence(enum Character character, unsigned char value) {
00201     nvram[INTELLIGENCE_OFFSET + character] = value;
00202     setModified();
00203 }
00204 
00205 bool SaveSlot::hasJoined(enum Character character) const {
00206     return (nvram[JOINED_OFFSET] & (1 << character));
00207 }
00208 
00209 void SaveSlot::setJoined(enum Character character, bool value) {
00210     int mask = 1 << character;
00211     
00212     if (value) {
00213         nvram[JOINED_OFFSET] |= mask;
00214     } else {
00215         nvram[JOINED_OFFSET] &= ~mask;
00216     }
00217     
00218     setModified();
00219 }
00220 
00221 int SaveSlot::getLevel(enum Character character) const {
00222     return nvram[LEVEL_OFFSET + character];
00223 }
00224 
00225 void SaveSlot::setLevel(enum Character character, unsigned char level) {
00226     nvram[LEVEL_OFFSET + character] = level;
00227     setModified();
00228 }
00229 
00230 bool SaveSlot::hasMagic(enum Magic magic) const {
00231     int offset = MAGIC_OFFSET;
00232     int temp = magic;
00233     
00234     if (temp > 7) {
00235         offset += (temp / 8);
00236         temp %= 8;
00237     }
00238 
00239     return (nvram[offset] & (1 << temp));
00240 }
00241 
00242 void SaveSlot::setMagic(enum Magic magic, bool give) {
00243     // make sure we're not giving invalid magic
00244     wxASSERT((magic != INVALID1) && (magic != INVALID2) && (magic != INVALID3));
00245     
00246     int offset = MAGIC_OFFSET;
00247     int temp = magic;
00248     
00249     if (temp > 7) {
00250         offset += (temp / 8);
00251         temp %= 8;
00252     }
00253 
00254     int mask = 1 << temp;
00255     
00256     if (give) {
00257         nvram[offset] |= mask;
00258     } else {
00259         nvram[offset] &= ~mask;
00260     }
00261     
00262     setModified();
00263 }
00264 
00265 wxInt16 SaveSlot::getMaxHP(enum Character character) const {
00266     wxInt16 *ptr = reinterpret_cast<wxInt16 *>
00267         (nvram + MAX_HP_OFFSET + (character * 2));
00268     
00269     return wxINT16_SWAP_ON_BE(ptr[0]);
00270 }
00271 
00272 void SaveSlot::setMaxHP(enum Character character, wxInt16 value) {
00273     wxInt16 *ptr = reinterpret_cast<wxInt16 *>
00274         (nvram + MAX_HP_OFFSET + (character * 2));
00275     
00276     ptr[0] = wxINT16_SWAP_ON_BE(value);
00277     setModified();
00278 }
00279 
00280 int SaveSlot::getMaxMP(enum Character character) const {
00281     return nvram[MAX_MP_OFFSET + character];
00282 }
00283 
00284 void SaveSlot::setMaxMP(enum Character character, unsigned char value) {
00285     nvram[MAX_MP_OFFSET + character] = value;
00286     setModified();
00287 }
00288 
00289 int SaveSlot::getMember(int position) const {
00290     return (nvram[MEMBER_OFFSET + position]);
00291 }
00292 
00293 void SaveSlot::setMember(int position, int character) {
00294     nvram[MEMBER_OFFSET + position] = character;
00295     setModified();
00296 }
00297 
00298 void SaveSlot::setModified(bool modified) {
00299     this->modified = modified;
00300     
00301     if (modified) {
00302         nvram[CHECKSUM_OFFSET] = checksum();
00303     }
00304 }
00305 
00306 int SaveSlot::getPhase(enum Moon moon) const {
00307     int phase = nvram[MOON_OFFSET];
00308     
00309     if (moon == TRAMMEL) {
00310         return (phase / 3);
00311     }
00312     
00313     return (phase % 3);
00314 }
00315 
00316 void SaveSlot::setPhase(enum City trammel, int felucca) {
00317     int phase = (trammel * 3) + felucca;
00318 
00319     nvram[MOON_OFFSET] = phase;
00320     setModified();
00321 }
00322 
00323 bool SaveSlot::hasPirateShip(enum PirateShip ship) const {
00324     return (nvram[PIRATESHIP_OFFSET] & (1 << ship));
00325 }
00326 
00327 void SaveSlot::setPirateShip(enum PirateShip ship, bool give) {
00328     int mask = 1 << ship;
00329     
00330     if (give) {
00331         nvram[PIRATESHIP_OFFSET] |= mask;
00332     } else {
00333         nvram[PIRATESHIP_OFFSET] &= ~mask;
00334     }
00335     
00336     setModified();
00337 }
00338 
00339 std::pair<int, int>
00340 SaveSlot::getPirateShipLocation(enum PirateShip ship) const {
00341     return std::pair<int, int>
00342         (nvram[PIRATESHIP_LATITUDE_OFFSET + (ship << 1)],
00343          nvram[PIRATESHIP_LONGITUDE_OFFSET + (ship << 1)]);
00344 }
00345 
00346 void SaveSlot::setPirateShipLocation(enum PirateShip ship,
00347                                      std::pair<int, int> location) {
00348     nvram[PIRATESHIP_LATITUDE_OFFSET + (ship << 1)] = location.first;
00349     nvram[PIRATESHIP_LONGITUDE_OFFSET + (ship << 1)] = location.second;
00350     
00351     setModified();
00352 }
00353 
00354 bool SaveSlot::hasRune(enum Virtue rune) const {
00355     return (nvram[RUNES_OFFSET] & (1 << rune));
00356 }
00357 
00358 void SaveSlot::setRune(enum Virtue rune, bool give) {
00359     const std::pair<int, int> &found = FOUND_RUNES_OFFSET[rune];
00360     
00361     if (give) {
00362         nvram[RUNES_OFFSET] |= (1 << rune);
00363         nvram[found.first] |= (1 << found.second);
00364     } else {
00365         nvram[RUNES_OFFSET] &= ~(1 << rune);
00366         nvram[found.first] &= ~(1 << found.second);
00367     }
00368     
00369     setModified();
00370 }
00371 
00372 enum StartLocation SaveSlot::getStartLocation() const {
00373     return static_cast<enum StartLocation>(nvram[START_LOCATION]);
00374 }
00375 
00376 void SaveSlot::setStartLocation(enum StartLocation location) {
00377     nvram[START_LOCATION] = location;
00378     setModified();
00379 }
00380 
00381 bool SaveSlot::hasStone(enum Virtue stone) const {
00382     return (nvram[STONES_OFFSET] & (1 << stone));
00383 }
00384 
00385 void SaveSlot::setStone(enum Virtue stone, bool give) {
00386     const std::pair<int, int> &found = FOUND_STONES_OFFSET[stone];
00387     
00388     if (give) {
00389         nvram[STONES_OFFSET] |= (1 << stone);
00390         nvram[found.first] |= (1 << found.second);
00391     } else {
00392         nvram[STONES_OFFSET] &= ~(1 << stone);
00393         nvram[found.first] &= ~(1 << found.second);
00394     }
00395     
00396     setModified();
00397 }
00398 
00399 int SaveSlot::getStrength(enum Character character) const {
00400     return nvram[STRENGTH_OFFSET + character];
00401 }
00402 
00403 void SaveSlot::setStrength(enum Character character, unsigned char value) {
00404     nvram[STRENGTH_OFFSET + character] = value;
00405     setModified();
00406 }
00407 
00408 int SaveSlot::getTool(enum Tool tool) const {
00409     return nvram[TOOL_OFFSET + tool];
00410 }
00411 
00412 void SaveSlot::setTool(enum Tool tool, unsigned char value) {
00413     nvram[TOOL_OFFSET + tool] = value;
00414     
00415     const std::pair<int, int> *found = 0;
00416     
00417     if (tool == BELL) {
00418         found = &FOUND_BELL_OFFSET;
00419     } else if (tool == BOOK) {
00420         found = &FOUND_BOOK_OFFSET;
00421     } else if (tool == CANDLE) {
00422         found = &FOUND_CANDLE_OFFSET;
00423     } else if (tool == FLUTE) {
00424         found = &FOUND_FLUTE_OFFSET;
00425     } else if (tool == HORN) {
00426         found = &FOUND_HORN_OFFSET;
00427     } else if (tool == SCALE) {
00428         found = &FOUND_SCALE_OFFSET;
00429     } else if (tool == SKULL) {
00430         found = &FOUND_SKULL_OFFSET;
00431     }
00432     
00433     if (found) {
00434         if (value > 0) {
00435             nvram[found->first] |= (1 << found->second);
00436         } else {
00437             nvram[found->first] &= ~(1 << found->second);
00438         }
00439     }
00440     
00441     setModified();
00442 }
00443 
00444 int SaveSlot::getVirtue(enum Virtue virtue) const {
00445     return nvram[VIRTUE_OFFSET + virtue];
00446 }
00447 
00448 void SaveSlot::setVirtue(enum Virtue virtue, unsigned char value) {
00449     int mask = 1 << virtue;
00450     
00451     if (value == 100) {
00452         nvram[AVATAR_OFFSET] |= mask;
00453     } else {
00454         nvram[AVATAR_OFFSET] &= ~mask;
00455     }
00456     
00457     nvram[VIRTUE_OFFSET + virtue] = value;
00458     setModified();
00459 }
00460 
00461 char SaveSlot::fromNES(unsigned char letter) {
00462     if ((letter >= 0x91) && (letter <= 0xAA)) {
00463         return ((letter - 0x91) + 'A');
00464     } else if ((letter >= 0xD1) && (letter <= 0xEA)) {
00465         return ((letter - 0xD1) + 'a');
00466     } else if (letter == 0xD0) {
00467         return '-';
00468     } else if (letter == 0x90) {
00469         return '!';
00470     }
00471     
00472     // return  _ underscore for all else
00473     return '_';
00474 }
00475 
00476 unsigned char SaveSlot::toNES(char letter) {
00477     if ((letter >= 'A') && (letter <= 'Z')) {
00478         return (unsigned char)(0x91 + (letter - 'A'));
00479     } else if ((letter >= 'a') && (letter <= 'z')) {
00480         return (unsigned char)(0xD1 + (letter - 'a'));
00481     } else if (letter == '-') {
00482         return (unsigned char)0xD0;
00483     } else if (letter == '!') {
00484         return (unsigned char)0x90;
00485     }
00486     
00487     // return _ underscore for all else
00488     return (unsigned char)0xBC;
00489 }
00490 
00491 std::pair<int, int> SaveSlot::getWhirlpoolLocation() const {
00492     return std::pair<int, int>(nvram[WHIRLPOOL_LATITUDE_OFFSET],
00493                                nvram[WHIRLPOOL_LONGITUDE_OFFSET]);
00494 }
00495 
00496 void SaveSlot::setWhirlpoolLocation(std::pair<int, int> location) {
00497     nvram[WHIRLPOOL_LATITUDE_OFFSET] = location.first;
00498     nvram[WHIRLPOOL_LONGITUDE_OFFSET] = location.second;
00499     
00500     setModified();
00501 }
00502 
00503 unsigned char SaveSlot::checksum() const {
00504     unsigned char sum = 0;
00505     int index = 0;
00506     
00507     for (int i = 1; i < SAVE_SIZE; ++i) {
00508         sum += (nvram[i] ^ CHECKSUM_XORS[index]);
00509         
00510         ++index &= 0x7;
00511     }
00512     
00513     return sum;
00514 }
00515 

Generated on Mon Dec 29 01:19:00 2008 for hack4u by  doxygen 1.5.4