decoder.cc

Go to the documentation of this file.
00001 /*
00002  * Game Genie Encoder/Decoder
00003  * Copyright (C) 2004-2006,2008 emuWorks
00004  * http://games.technoplaza.net/
00005  *
00006  * This file is part of Game Genie Encoder/Decoder.
00007  *
00008  * Game Genie Encoder/Decoder 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  * Game Genie Encoder/Decoder 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 Game Genie Encoder/Decoder; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00021  */
00022  
00023 // $Id: decoder.cc,v 1.9 2008/12/18 03:23:30 jdratlif Exp $
00024 
00025 #include <QString>
00026 
00027 #include "exceptions/invalidgamegeniecode.hh"
00028 
00029 #include "model/gbgggamegeniecode.hh"
00030 #include "model/gbggrawcode.hh"
00031 #include "model/genesisgamegeniecode.hh"
00032 #include "model/genesisrawcode.hh"
00033 #include "model/nesgamegeniecode.hh"
00034 #include "model/nesrawcode.hh"
00035 #include "model/snesgamegeniecode.hh"
00036 #include "model/snesrawcode.hh"
00037 
00038 #include "tools/decoder.hh"
00039 
00040 using namespace ggencoder;
00041 
00042 GBGGRawCode Decoder::decodeGBGG(const GameGenieCode &code) {
00043     QString ggcode = code.getCode();
00044     int length = ggcode.length();
00045     
00046     if (!GBGGGameGenieCode::isValidCode(ggcode)) {
00047         throw InvalidGameGenieCodeException();
00048     }
00049     
00050     qint64 bitstring = 0;
00051     
00052     for (int i = 0; i < length; i++) {
00053         if ((i == 3) || (i == 7)) {
00054             continue;
00055         }
00056         
00057         QChar ch = ggcode[i];
00058         
00059         bitstring <<= 4;
00060         bitstring |= code.toHex(ch.toAscii());
00061     }
00062     
00063     int value;
00064     int address;
00065     int temp;
00066     
00067     if (length == 7) {
00068         bitstring <<= 12;
00069     }
00070     
00071     value = (int)(bitstring >> 28);
00072     
00073     temp = (int)((bitstring >> 12) & 0xF);
00074     temp = (~temp & 0xF) << 12;
00075     address = (int)((bitstring >> 16) & 0xFFF) | temp;
00076     
00077     if (length == 7) {
00078         return GBGGRawCode(address, value);
00079     }
00080     
00081     temp = (int)(((bitstring >> 4) & 0xF0) | (bitstring & 0xF));
00082     temp = (temp >> 2) | ((temp << 6) & 0xFC);
00083     
00084     int compare = temp ^ 0xBA;
00085     
00086     return GBGGRawCode(address, value, compare);
00087 }
00088 
00089 GenesisRawCode Decoder::decodeGenesis(const GameGenieCode &code) {
00090     QString ggcode = code.getCode();
00091     int length = ggcode.length();
00092     
00093     if (!GenesisGameGenieCode::isValidCode(ggcode)) {
00094         throw InvalidGameGenieCodeException();
00095     }
00096     
00097     qint64 bitstring = 0;
00098     
00099     for (int i = 0; i < length; i++) {
00100         if (i == 4) {
00101             continue;
00102         }
00103         
00104         QChar ch = ggcode[i];
00105         
00106         bitstring <<= 5;
00107         bitstring |= code.toHex(ch.toAscii());
00108     }
00109     
00110     int value;
00111     int address;
00112     int temp;
00113     
00114     // position abcd
00115     value = (int)(((bitstring >> 7) & 0xE) | ((bitstring >> 15) & 0x1));
00116     
00117     // position efgh
00118     temp = (int)(((bitstring >> 11) & 0xE) | ((bitstring >> 11) & 0x1));
00119     value <<= 4;
00120     value |= temp;
00121     
00122     // position ijklmnop
00123     temp = (int)(bitstring >> 32);
00124     value <<= 8;
00125     value |= temp;
00126     
00127     // a-p = value, a-x = addy
00128     // ijkl mnop IJKL MNOP ABCD EFGH defg habc QRST UVWX
00129     // position ABCDEFGH
00130     address = (int)((bitstring >> 16) & 0xFF);
00131     
00132     // position IJKLMNOP
00133     temp = (int)((bitstring >> 24) & 0xFF);
00134     address <<= 8;
00135     address |= temp;
00136     
00137     // position QRSTUVWX
00138     temp = (int)(bitstring & 0xFF);
00139     address <<= 8;
00140     address |= temp;
00141     
00142     return GenesisRawCode(address, value);
00143 }
00144 
00145 NESRawCode Decoder::decodeNES(const GameGenieCode &code) {
00146     QString ggcode = code.getCode();
00147     int length = ggcode.length();
00148     
00149     if (!NESGameGenieCode::isValidCode(ggcode)) {
00150         throw InvalidGameGenieCodeException();
00151     }
00152     
00153     int bitstring = 0;
00154     
00155     for (int i = 0; i < length; i++) {
00156         QChar ch = ggcode[i];
00157         
00158         bitstring <<= 4;        
00159         bitstring |= code.toHex(ch.toAscii());
00160     }
00161     
00162     int value;
00163     int address;
00164     int temp;
00165     
00166     if (length == 6) {
00167         bitstring <<= 8;
00168     }
00169     
00170     // position 1234
00171     value = ((bitstring >> 28) & 0x8) | ((bitstring >> 24) & 0x7);
00172     
00173     if (length == 6) {
00174         temp = (bitstring & 0x800) >> 8;
00175     } else {
00176         temp = bitstring & 0x8;
00177     }
00178     
00179     temp |= ((bitstring >> 28) & 0x7);
00180     
00181     value <<= 4;
00182     value |= temp;
00183     
00184     // position -ABC
00185     address = (bitstring & 0x70000) >> 16;
00186     
00187     // position DEFG
00188     temp = ((bitstring & 0x8000) >> 12) | ((bitstring & 0x700) >> 8);
00189     address <<= 4;
00190     address |= temp;
00191     
00192     // position HIJK
00193     temp = ((bitstring & 0x8000000) >> 24) | ((bitstring & 0x700000) >> 20);
00194     address <<= 4;
00195     address |= temp;
00196 
00197     // position LMNO
00198     temp = ((bitstring & 0x80000) >> 16) | ((bitstring & 0x7000) >> 12);
00199     address <<= 4;
00200     address |= temp;
00201     
00202     if (length == 6) {
00203         return NESRawCode(address, value);
00204     }
00205     
00206     int compare;
00207     
00208     // position abcd
00209     compare = ((bitstring & 0x80) >> 4) | (bitstring & 0x7);
00210     
00211     // position efgh
00212     temp = ((bitstring & 0x800) >> 8) | ((bitstring & 0x70) >> 4);
00213     compare <<= 4;
00214     compare |= temp;
00215     
00216     return NESRawCode(address, value, compare);
00217 }
00218 
00219 SNESRawCode Decoder::decodeSNES(const GameGenieCode &code) {
00220     QString ggcode = code.getCode();
00221     int length = ggcode.length();
00222     
00223     if (!SNESGameGenieCode::isValidCode(ggcode)) {
00224         throw InvalidGameGenieCodeException();
00225     }
00226     
00227     int bitstring = 0;
00228     
00229     for (int i = 0; i < length; i++) {
00230         if (i == 4) {
00231             continue;
00232         }
00233         
00234         QChar ch = ggcode[i];
00235         
00236         bitstring <<= 4;
00237         bitstring |= code.toHex(ch.toAscii());
00238     }
00239     
00240     int value;
00241     int address;
00242     int temp;
00243     
00244     // position 12345678
00245     value = (bitstring >> 24) & 0xFF;
00246     
00247     // position ABCD
00248     address = ((bitstring >> 10) & 0xC) | ((bitstring >> 10) & 0x3);
00249     
00250     // position EFGH
00251     temp = ((bitstring >> 2) & 0xC) | ((bitstring >> 2) & 0x3);
00252     address <<= 4;
00253     address |= temp;
00254     
00255     // position IJKL
00256     temp = (bitstring >> 20) & 0xF;
00257     address <<= 4;
00258     address |= temp;
00259     
00260     // position MNOP
00261     temp = ((bitstring << 2) & 0xC) | ((bitstring >> 14) & 0x3);
00262     address <<= 4;
00263     address |= temp;
00264     
00265     // position QRST
00266     temp = (bitstring >> 16) & 0xF;
00267     address <<= 4;
00268     address |= temp;
00269     
00270     // position UVWX
00271     temp = ((bitstring >> 6) & 0xC) | ((bitstring >> 6) & 0x3);
00272     address <<= 4;
00273     address |= temp;
00274     
00275     return SNESRawCode(address, value);
00276 }
00277 

Generated on Thu Dec 18 01:01:24 2008 for Game Genie Encoder/Decoder by  doxygen 1.5.4