sramfile.cc

Go to the documentation of this file.
00001 /*
00002  * Secret of Evermore SRAM Editor
00003  * Copyright (C) 2006,2008 emuWorks
00004  * http://games.technoplaza.net/
00005  *
00006  * This file is part of Secret of Evermore SRAM Editor.
00007  *
00008  * Secret of Evermore SRAM Editor is free software; you can redistribute it
00009  * and/or modify it under the terms of the GNU General Public License as
00010  * published by the Free Software Foundation; either version 2 of the License,
00011  * or (at your option) any later version.
00012  *
00013  * Secret of Evermore SRAM Editor is distributed in the hope that it will be
00014  * useful, 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 Secret of Evermore 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.27 2008/01/26 16:40:51 technoplaza Exp $
00024 
00025 #include <cstring>
00026 #include <fstream>
00027 
00028 #include <QtCore/qendian.h>
00029 
00030 #include "model/sramfile.hh"
00031 
00032 using namespace soesrame;
00033 
00034 const std::pair<int, int> SRAMFile::SRAM_ALCHEMY_OFFSETS[] =
00035     {
00036         std::pair<int, int>(0x1F7, 0x01),  // acid rain
00037         std::pair<int, int>(0x1F7, 0x02),  // atlas
00038         std::pair<int, int>(0x1F7, 0x04),  // barrier
00039         std::pair<int, int>(0x1F7, 0x08),  // call up
00040         std::pair<int, int>(0x1F7, 0x10),  // corrosion
00041         std::pair<int, int>(0x1F7, 0x20),  // crush
00042         std::pair<int, int>(0x1F7, 0x40),  // cure
00043         std::pair<int, int>(0x1F7, 0x80),  // defend
00044         
00045         std::pair<int, int>(0x1F8, 0x01),  // double drain
00046         std::pair<int, int>(0x1F8, 0x02),  // drain
00047         std::pair<int, int>(0x1F8, 0x04),  // energize
00048         std::pair<int, int>(0x1F8, 0x08),  // escape
00049         std::pair<int, int>(0x1F8, 0x10),  // explosion
00050         std::pair<int, int>(0x1F8, 0x20),  // fireball
00051         std::pair<int, int>(0x1F8, 0x40),  // fire power
00052         std::pair<int, int>(0x1F8, 0x80),  // flash
00053         
00054         std::pair<int, int>(0x1F9, 0x01),  // force field
00055         std::pair<int, int>(0x1F9, 0x02),  // hard ball
00056         std::pair<int, int>(0x1F9, 0x04),  // heal
00057         std::pair<int, int>(0x1F9, 0x08),  // lance
00058         std::pair<int, int>(0x1F9, 0x10),  // laser (dummied spell)
00059         std::pair<int, int>(0x1F9, 0x20),  // levitate
00060         std::pair<int, int>(0x1F9, 0x40),  // lightning storm
00061         std::pair<int, int>(0x1F9, 0x80),  // miracle cure
00062         
00063         std::pair<int, int>(0x1FA, 0x01),  // nitro
00064         std::pair<int, int>(0x1FA, 0x02),  // one up
00065         std::pair<int, int>(0x1FA, 0x04),  // reflect
00066         std::pair<int, int>(0x1FA, 0x08),  // regrowth
00067         std::pair<int, int>(0x1FA, 0x10),  // revealer
00068         std::pair<int, int>(0x1FA, 0x20),  // revive
00069         std::pair<int, int>(0x1FA, 0x40),  // slow burn
00070         std::pair<int, int>(0x1FA, 0x80),  // speed
00071         
00072         std::pair<int, int>(0x1FB, 0x01),  // sting
00073         std::pair<int, int>(0x1FB, 0x02),  // stop
00074         std::pair<int, int>(0x1FB, 0x04)   // super heal
00075     };
00076     
00077 const std::pair<int, int> SRAMFile::SRAM_CHARM_OFFSETS[] =
00078     {
00079         std::pair<int, int>(0x200, 0x20),   // armor polish
00080         std::pair<int, int>(0x200, 0x40),   // chocobo egg
00081         std::pair<int, int>(0x200, 0x80),   // insect incense
00082         
00083         std::pair<int, int>(0x201, 0x01),   // jade disk
00084         std::pair<int, int>(0x201, 0x02),   // jaguar ring
00085         std::pair<int, int>(0x201, 0x04),   // magic gourd
00086         std::pair<int, int>(0x201, 0x08),   // moxa stick
00087         std::pair<int, int>(0x201, 0x10),   // oracle bone
00088         std::pair<int, int>(0x201, 0x20),   // ruby heart
00089         std::pair<int, int>(0x201, 0x40),   // silver sheath
00090         std::pair<int, int>(0x201, 0x80),   // staff of life
00091         
00092         std::pair<int, int>(0x202, 0x01),   // sun stone
00093         std::pair<int, int>(0x202, 0x02),   // thug's cloak
00094         std::pair<int, int>(0x202, 0x04)    // wizard's coin
00095     };
00096     
00097 const std::pair<int, int> SRAMFile::SRAM_WEAPON_OFFSETS[] =
00098     {
00099         std::pair<int, int>(0x279, 0x02),  // bone crusher
00100         std::pair<int, int>(0x279, 0x04),  // gladiator sword
00101         std::pair<int, int>(0x279, 0x08),  // crusader sword
00102         std::pair<int, int>(0x279, 0x10),  // neutron blade
00103         
00104         std::pair<int, int>(0x279, 0x20),  // spider's claw
00105         std::pair<int, int>(0x279, 0x40),  // bronze axe
00106         std::pair<int, int>(0x279, 0x80),  // knight basher
00107         std::pair<int, int>(0x27A, 0x01),  // atom smasher
00108         
00109         std::pair<int, int>(0x27A, 0x02),  // horn spear
00110         std::pair<int, int>(0x27A, 0x04),  // bronze spear
00111         std::pair<int, int>(0x27A, 0x08),  // lance
00112         std::pair<int, int>(0x27A, 0x10),  // laser lance
00113         
00114         std::pair<int, int>(0x27A, 0x20)   // bazooka
00115     };
00116 
00117 SRAMFile::SRAMFile(const QString &filename, enum sf_region region)
00118     throw(InvalidSRAMFileException) : region(region), modified(false) {
00119     std::ifstream file(filename.toAscii().data(), 
00120                        std::ios_base::in | std::ios_base::binary);
00121     
00122     if (!file) {
00123         throw InvalidSRAMFileException(ISFE_FILENOTFOUND);
00124     }
00125     
00126     file.seekg(0, std::ios_base::end);
00127     
00128     if (file.tellg() != static_cast<std::streampos>(SRAM_FILE_SIZE)) {
00129         throw InvalidSRAMFileException(ISFE_INVALIDSIZE);
00130     }
00131     
00132     file.seekg(0, std::ios_base::beg);
00133     file.read(reinterpret_cast<char *>(sram), SRAM_FILE_SIZE);
00134     file.close();
00135     
00136     bool valid = false;
00137     std::memset(this->valid, 0, 4 * sizeof(bool));
00138     
00139     for (int game = 3; game >= 0; --game) {
00140         if (checksum(game) == getChecksum(game)) {
00141             valid = true;
00142             this->valid[game] = true;
00143             setGame(game);
00144         }
00145     }
00146     
00147     if (!valid) {
00148         throw InvalidSRAMFileException(ISFE_NOVALIDGAMES);
00149     }
00150 }
00151 
00152 quint16 SRAMFile::checksum(int game) const {
00153     quint32 checksum = ((region == REGION_UNITEDSTATES) ?
00154                         SRAM_CHECKSUM_START_US :
00155                         SRAM_CHECKSUM_START_EUROPE);
00156     unsigned char temp = checksum +
00157                          sram[SRAM_GAME_OFFSET + 2 + game * SRAM_GAME_SIZE];
00158     
00159     for (int i = 3; i < SRAM_GAME_SIZE; ++i) {
00160         checksum &= 0xFF00;
00161         checksum |= temp;
00162         checksum <<= 1;
00163         
00164         if (checksum > 0xFFFF) {
00165             checksum -= 0xFFFF;
00166         }
00167         
00168         temp = checksum + sram[SRAM_GAME_OFFSET + i + game * SRAM_GAME_SIZE];
00169     }
00170     
00171     return static_cast<quint16>(checksum);
00172 }
00173 
00174 bool SRAMFile::save(const QString &filename) {
00175     for (int game = 0; game < 4; ++game) {
00176         if (isValid(game)) {
00177             setChecksum(game, checksum(game));
00178         }
00179     }
00180     
00181     std::ofstream file(filename.toAscii().data(),
00182                        std::ios_base::out | std::ios_base::binary);
00183     
00184     if (!file) {
00185         return false;
00186     }
00187     
00188     file.write(reinterpret_cast<char *>(sram), SRAM_FILE_SIZE);
00189     
00190     if (file.tellp() != static_cast<std::streampos>(SRAM_FILE_SIZE)) {
00191         return false;
00192     }
00193     
00194     file.close();
00195     modified = false;
00196     
00197     return true;
00198 }
00199 
00200 bool SRAMFile::hasAlchemy(enum sf_alchemy alchemy) const {
00201     Q_ASSERT(isValid(getGame()));
00202     
00203     return (offset[SRAM_ALCHEMY_OFFSETS[alchemy].first] &
00204             SRAM_ALCHEMY_OFFSETS[alchemy].second);
00205 }
00206 
00207 void SRAMFile::setAlchemy(enum sf_alchemy alchemy, bool have) {
00208     Q_ASSERT(isValid(getGame()));
00209     
00210     unsigned char *data = offset + SRAM_ALCHEMY_OFFSETS[alchemy].first;
00211     
00212     if (have) {
00213         *data |= SRAM_ALCHEMY_OFFSETS[alchemy].second;
00214     } else {
00215         *data &= ~SRAM_ALCHEMY_OFFSETS[alchemy].second;
00216     }
00217     
00218     modified = true;
00219 }
00220 
00221 std::pair<int, int> SRAMFile::getAlchemyLevel(enum sf_alchemy alchemy) const {
00222     Q_ASSERT(isValid(getGame()));
00223     
00224     return std::pair<int, int>
00225         (offset[SRAM_ALCHEMYMAJORLEVELS_OFFSET + (alchemy * 2)],
00226          offset[SRAM_ALCHEMYMINORLEVELS_OFFSET + (alchemy * 2)]); 
00227 }
00228 
00229 void SRAMFile::setAlchemyLevel(enum sf_alchemy alchemy,
00230                                std::pair<int, int> level) {
00231     Q_ASSERT(isValid(getGame()));
00232     Q_ASSERT((level.first >= 0) && (level.first < 10));
00233     Q_ASSERT((level.second >= 0) && (level.second < 100));
00234     
00235     offset[SRAM_ALCHEMYMAJORLEVELS_OFFSET + (alchemy * 2)] = level.first;
00236     offset[SRAM_ALCHEMYMINORLEVELS_OFFSET + (alchemy * 2)] = level.second;
00237     
00238     modified = true;
00239 }
00240 
00241 std::pair<int, int> SRAMFile::getAttackLevel() const {
00242     Q_ASSERT(isValid(getGame()));
00243     
00244     return std::pair<int, int>
00245         (offset[SRAM_DOG_ATTACKLEVEL_OFFSET + 1],
00246          offset[SRAM_DOG_ATTACKLEVEL_OFFSET]);
00247 }
00248 
00249 void SRAMFile::setAttackLevel(std::pair<int, int> level) {
00250     Q_ASSERT(isValid(getGame()));
00251     Q_ASSERT((level.first >= 1) && (level.first < 4));
00252     Q_ASSERT((level.second >= 0) && (level.second < 256));
00253     
00254     offset[SRAM_DOG_ATTACKLEVEL_OFFSET + 1] = level.first;
00255     offset[SRAM_DOG_ATTACKLEVEL_OFFSET] = level.second;
00256     
00257     modified = true;
00258 }
00259 
00260 bool SRAMFile::hasCharm(enum sf_charm charm) const {
00261     Q_ASSERT(isValid(getGame()));
00262     
00263     return (offset[SRAM_CHARM_OFFSETS[charm].first] &
00264             SRAM_CHARM_OFFSETS[charm].second);
00265 }
00266 
00267 void SRAMFile::setCharm(enum sf_charm charm, bool have) {
00268     Q_ASSERT(isValid(getGame()));
00269     
00270     unsigned char *data = offset + SRAM_CHARM_OFFSETS[charm].first;
00271     
00272     if (have) {
00273         *data |= SRAM_CHARM_OFFSETS[charm].second;
00274     } else {
00275         *data &= ~SRAM_CHARM_OFFSETS[charm].second;
00276     }
00277     
00278     modified = true;
00279 }
00280 
00281 quint16 SRAMFile::getChecksum(int game) const {
00282     const quint16 *data =
00283         reinterpret_cast<const quint16 *>(sram + SRAM_GAME_OFFSET +
00284                                           game * SRAM_GAME_SIZE +
00285                                           SRAM_CHECKSUM_OFFSET);
00286     
00287     return qFromLittleEndian(*data);
00288 }
00289 
00290 void SRAMFile::setChecksum(int game, quint16 checksum) {
00291     quint16 *data = reinterpret_cast<quint16 *>(sram + SRAM_GAME_OFFSET +
00292                                                 game * SRAM_GAME_SIZE +
00293                                                 SRAM_CHECKSUM_OFFSET);
00294     
00295     *data = qToLittleEndian(checksum);
00296 }
00297 
00298 quint16 SRAMFile::getCurrentHP(enum sf_hero hero) const {
00299     Q_ASSERT(isValid(getGame()));
00300     
00301     const quint16 *data =
00302         reinterpret_cast<const quint16 *>(offset +
00303                                           ((hero == SF_BOY) ?
00304                                            SRAM_BOY_CURRENTHP_OFFSET :
00305                                            SRAM_DOG_CURRENTHP_OFFSET));
00306                                       
00307     return qFromLittleEndian(*data);
00308 }
00309 
00310 void SRAMFile::setCurrentHP(enum sf_hero hero, quint16 hp) {
00311     Q_ASSERT(isValid(getGame()));
00312     Q_ASSERT(hp < 1000);
00313     
00314     quint16 *data = reinterpret_cast<quint16 *>(offset +
00315                                                 ((hero == SF_BOY) ?
00316                                                  SRAM_BOY_CURRENTHP_OFFSET :
00317                                                  SRAM_DOG_CURRENTHP_OFFSET));
00318                                                  
00319     *data = qToLittleEndian(hp);
00320     modified = true;
00321 }
00322 
00323 quint32 SRAMFile::getExperience(enum sf_hero hero) const {
00324     Q_ASSERT(isValid(getGame()));
00325     
00326     const quint32 *data =
00327         reinterpret_cast<const quint32 *>(offset +
00328                                           ((hero == SF_BOY) ?
00329                                            SRAM_BOY_EXPERIENCE_OFFSET :
00330                                            SRAM_DOG_EXPERIENCE_OFFSET));
00331                                            
00332     return (qFromLittleEndian(*data) & 0xFFFFFF);
00333 }
00334 
00335 void SRAMFile::setExperience(enum sf_hero hero, quint32 experience) {
00336     Q_ASSERT(isValid(getGame()));
00337     Q_ASSERT((experience >= 0) && (experience < 16777216));
00338     
00339     unsigned char *data = offset + ((hero == SF_BOY) ?
00340                                     SRAM_BOY_EXPERIENCE_OFFSET :
00341                                     SRAM_DOG_EXPERIENCE_OFFSET);
00342     
00343     data[0] = experience;
00344     data[1] = experience >> 8;
00345     data[2] = experience >> 16;
00346     
00347     modified = true;
00348 }
00349 
00350 void SRAMFile::setGame(int game) {
00351     Q_ASSERT((game >= 0) && (game < 4));
00352     
00353     this->game = game;
00354     offset = sram + SRAM_GAME_OFFSET + (game * SRAM_GAME_SIZE);
00355 }
00356 
00357 int SRAMFile::getIngredient(enum sf_ingredient ingredient) const {
00358     Q_ASSERT(isValid(getGame()));
00359     
00360     return offset[SRAM_INGREDIENTS_OFFSET + ingredient];
00361 }
00362 
00363 void SRAMFile::setIngredient(enum sf_ingredient ingredient, int count) {
00364     Q_ASSERT(isValid(getGame()));
00365     Q_ASSERT((count >= 0) && (count < 100));
00366     
00367     offset[SRAM_INGREDIENTS_OFFSET + ingredient] = count;
00368     modified = true;
00369 }
00370 
00371 int SRAMFile::getItem(enum sf_item item) const {
00372     Q_ASSERT(isValid(getGame()));
00373     
00374     return offset[SRAM_ITEMS_OFFSET + item];
00375 }
00376 
00377 void SRAMFile::setItem(enum sf_item item, int count) {
00378     Q_ASSERT(isValid(getGame()));
00379     Q_ASSERT((count >= 0) && (count < 100));
00380     
00381     offset[SRAM_ITEMS_OFFSET + item] = count;
00382     modified = true;
00383 }
00384 
00385 int SRAMFile::getLevel(enum sf_hero hero) const {
00386     Q_ASSERT(isValid(getGame()));
00387     
00388     return offset[((hero == SF_BOY) ?
00389                    SRAM_BOY_LEVEL_OFFSET :
00390                    SRAM_DOG_LEVEL_OFFSET)];
00391 }
00392 
00393 void SRAMFile::setLevel(enum sf_hero hero, int level) {
00394     Q_ASSERT(isValid(getGame()));
00395     Q_ASSERT((level >= 1) && (level < 100));
00396     
00397     offset[((hero == SF_BOY) ?
00398             SRAM_BOY_LEVEL_OFFSET :
00399             SRAM_DOG_LEVEL_OFFSET)] = level;
00400     modified = true;
00401 }
00402 
00403 quint16 SRAMFile::getMaxHP(enum sf_hero hero) const {
00404     Q_ASSERT(isValid(getGame()));
00405     
00406     const quint16 *data =
00407         reinterpret_cast<const quint16 *>(offset +
00408                                           ((hero == SF_BOY) ?
00409                                            SRAM_BOY_MAXHP_OFFSET :
00410                                            SRAM_DOG_MAXHP_OFFSET));
00411                                       
00412     return qFromLittleEndian(*data);
00413 }
00414 
00415 void SRAMFile::setMaxHP(enum sf_hero hero, quint16 hp) {
00416     Q_ASSERT(isValid(getGame()));
00417     Q_ASSERT(hp < 1000);
00418     
00419     quint16 *data = reinterpret_cast<quint16 *>(offset +
00420                                                 ((hero == SF_BOY) ?
00421                                                  SRAM_BOY_MAXHP_OFFSET :
00422                                                  SRAM_DOG_MAXHP_OFFSET));
00423                                                  
00424     *data = qToLittleEndian(hp);
00425     modified = true;
00426 }
00427 
00428 quint32 SRAMFile::getMoney(enum sf_money money) const {
00429     Q_ASSERT(isValid(getGame()));
00430     
00431     const quint32 *data =
00432         reinterpret_cast<const quint32 *>(offset +
00433                                           SRAM_MONEY_OFFSET + (money * 3));
00434                                           
00435     return (qFromLittleEndian(*data) & 0xFFFFFF);
00436 }
00437 
00438 void SRAMFile::setMoney(enum sf_money money, quint32 count) {
00439     Q_ASSERT(isValid(getGame()));
00440     Q_ASSERT((count >= 0) && (count < 16777216));
00441     
00442     unsigned char *data = offset + SRAM_MONEY_OFFSET + (money * 3);
00443     
00444     data[0] = count;
00445     data[1] = count >> 8;
00446     data[2] = count >> 16;
00447     
00448     modified = true;
00449 }
00450 
00451 QString SRAMFile::getName(enum sf_hero hero) const {
00452     Q_ASSERT(isValid(getGame()));
00453     
00454     const char *data =
00455         reinterpret_cast<const char *>(offset +
00456                                        ((hero == SF_BOY) ?
00457                                         SRAM_BOY_NAME_OFFSET :
00458                                         SRAM_DOG_NAME_OFFSET));
00459                                         
00460     QString name = QString::fromAscii(data);
00461     
00462     if (region == REGION_GERMANY) {
00463         name.replace(QChar(0xCB), QChar(0xC4)); // fix A umlaut
00464         name.replace(QChar(0xDB), QChar(0xD6)); // fix O umlaut
00465         name.replace(QChar(0xDF), QChar(0xDC)); // fix U umlaut
00466         name.replace(QChar(0xE3), QChar(0xE4)); // fix a umlaut
00467         name.replace(QChar(0xEF), QChar(0xF6)); // fix o umlaut
00468         name.replace(QChar(0xF3), QChar(0xFC)); // fix u umlaut
00469         name.replace(QChar(0xC6), QChar(0xDF)); // fix eszett
00470     } else if (region == REGION_SPAIN) {
00471         name.replace(QChar(0xD7), QChar(0xF1)); // fix n tilde
00472     }
00473     
00474     return name;
00475 }
00476 
00477 void SRAMFile::setName(enum sf_hero hero, const QString &name) {
00478     Q_ASSERT(isValid(getGame()));
00479     Q_ASSERT(name.length() <= 15);
00480     
00481     char *data = reinterpret_cast<char *>(offset + ((hero == SF_BOY) ?
00482                                                     SRAM_BOY_NAME_OFFSET :
00483                                                     SRAM_DOG_NAME_OFFSET));
00484                                                     
00485     QString temp = name;
00486     
00487     if (region == REGION_GERMANY) {
00488         temp.replace(QChar(0xDF), QChar(0xC6)); // fix eszett
00489         temp.replace(QChar(0xFC), QChar(0xF3)); // fix u umlaut
00490         temp.replace(QChar(0xF6), QChar(0xEF)); // fix o umlaut
00491         temp.replace(QChar(0xE4), QChar(0xE3)); // fix a umlaut
00492         temp.replace(QChar(0xDC), QChar(0xDF)); // fix U umlaut
00493         temp.replace(QChar(0xD6), QChar(0xDB)); // fix O umlaut
00494         temp.replace(QChar(0xC4), QChar(0xCB)); // fix A umlaut
00495     } else if (region == REGION_SPAIN) {
00496         temp.replace(QChar(0xF1), QChar(0xD7)); // fix n tilde
00497     }
00498     
00499     std::strcpy(data, temp.left(15).toAscii().data());
00500     
00501     modified = true;
00502 }
00503 
00504 quint16 SRAMFile::getTradeGood(enum sf_tradegood tradegood) const {
00505     Q_ASSERT(isValid(getGame()));
00506     
00507     const quint16 *data =
00508         reinterpret_cast<const quint16 *>(offset + SRAM_TRADEGOODS_OFFSET);
00509     
00510     return qFromLittleEndian(data[tradegood]);
00511 }
00512 
00513 void SRAMFile::setTradeGood(enum sf_tradegood tradegood, quint16 count) {
00514     Q_ASSERT(isValid(getGame()));
00515     Q_ASSERT(count < 100);
00516     
00517     quint16 *data =
00518         reinterpret_cast<quint16 *>(offset + SRAM_TRADEGOODS_OFFSET);
00519     
00520     data[tradegood] = qToLittleEndian(count);
00521     modified = true;
00522 }
00523 
00524 bool SRAMFile::hasWeapon(enum sf_weapon weapon) const {
00525     Q_ASSERT(isValid(getGame()));
00526     
00527     return (offset[SRAM_WEAPON_OFFSETS[weapon].first] &
00528             SRAM_WEAPON_OFFSETS[weapon].second);
00529 }
00530 
00531 void SRAMFile::setWeapon(enum sf_weapon weapon, bool have) {
00532     Q_ASSERT(isValid(getGame()));
00533     
00534     unsigned char *data = offset + SRAM_WEAPON_OFFSETS[weapon].first;
00535     
00536     if (have) {
00537         *data |= SRAM_WEAPON_OFFSETS[weapon].second;
00538     } else {
00539         *data &= ~SRAM_WEAPON_OFFSETS[weapon].second;
00540     }
00541     
00542     modified = true;
00543 }
00544 
00545 std::pair<int, int> SRAMFile::getWeaponLevel(enum sf_weapon weapon) const {
00546     Q_ASSERT(isValid(getGame()));
00547     Q_ASSERT(weapon != SF_BAZOOKA);
00548     
00549     const unsigned char *data =
00550         offset + SRAM_WEAPONLEVELS_OFFSET + (weapon * 2);
00551     
00552     return std::pair<int, int>(data[1], data[0]);
00553 }
00554 
00555 void SRAMFile::setWeaponLevel(enum sf_weapon weapon,
00556                               std::pair<int, int> level) {
00557     Q_ASSERT(isValid(getGame()));
00558     Q_ASSERT(weapon != SF_BAZOOKA);
00559     Q_ASSERT((level.first >= 1) && (level.first < 4));
00560     Q_ASSERT((level.second >= 0) && (level.second < 256));
00561     
00562     unsigned char *data = offset + SRAM_WEAPONLEVELS_OFFSET + (weapon * 2);
00563     
00564     data[1] = level.first;
00565     data[0] = level.second;
00566     
00567     modified = true;
00568 }
00569 

Generated on Sun Jan 27 09:41:43 2008 for Secret of Evermore SRAM Editor by  doxygen 1.5.4