00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "model/gbgggamegeniecode.hh"
00026 #include "model/gbggrawcode.hh"
00027 #include "model/genesisgamegeniecode.hh"
00028 #include "model/genesisrawcode.hh"
00029 #include "model/nesgamegeniecode.hh"
00030 #include "model/nesrawcode.hh"
00031 #include "model/snesgamegeniecode.hh"
00032 #include "model/snesrawcode.hh"
00033
00034 #include "tools/encoder.hh"
00035
00036 using namespace ggencoder;
00037
00038 GBGGGameGenieCode Encoder::encode(const GBGGRawCode &code) {
00039 int temp, address = code.getAddress(), value = code.getValue();
00040 qint64 genie;
00041
00042
00043 genie = value;
00044
00045 temp = (address & 0xF000) >> 12;
00046 temp = (~temp & 0xF);
00047 temp |= (address & 0xFFF) << 4;
00048 genie <<= 16;
00049 genie |= temp;
00050
00051 if (code.hasCompare()) {
00052 int compare = code.getCompare();
00053
00054 compare ^= 0xBA;
00055 compare = (compare << 2) | (compare >> 6);
00056 temp = (compare & 0xF0) >> 4;
00057 genie <<= 4;
00058 genie |= temp;
00059
00060 temp ^= 8;
00061 genie <<= 4;
00062 genie |= temp;
00063
00064 temp = (compare & 0xF);
00065 genie <<= 4;
00066 genie |= temp;
00067 }
00068
00069 QString ggcode;
00070 const char *alphabet = GBGGGameGenieCode::ALPHABET;
00071
00072 for (int i = 0; i < (code.hasCompare() ? 9 : 6); i++) {
00073 if ((i == 3) || (i == 6)) {
00074 ggcode.insert(0, '-');
00075 }
00076
00077 ggcode.insert(0, alphabet[(int)((genie >> (i * 4)) & 0xF)]);
00078 }
00079
00080 return GBGGGameGenieCode::create(ggcode);
00081 }
00082
00083 GenesisGameGenieCode Encoder::encode(const GenesisRawCode &code) {
00084 int temp;
00085 qint64 genie;
00086 int value = code.getValue();
00087 int address = code.getAddress();
00088
00089
00090 genie = (value & 0xF0) >> 4;
00091
00092
00093 temp = (value & 0xF);
00094 genie <<= 4;
00095 genie |= temp;
00096
00097
00098 temp = (address & 0xF000) >> 12;
00099 genie <<= 4;
00100 genie |= temp;
00101
00102
00103 temp = (address & 0xF00) >> 8;
00104 genie <<= 4;
00105 genie |= temp;
00106
00107
00108 temp = (address & 0xF00000) >> 20;
00109 genie <<= 4;
00110 genie |= temp;
00111
00112
00113 temp = (address & 0xF0000) >> 16;
00114 genie <<= 4;
00115 genie |= temp;
00116
00117
00118 temp = ((value & 0x1000) >> 9) | ((value & 0xE00) >> 9);
00119 genie <<= 4;
00120 genie |= temp;
00121
00122
00123 temp = ((value & 0x100) >> 5) | ((value & 0xE000) >> 13);
00124 genie <<= 4;
00125 genie |= temp;
00126
00127
00128 temp = (address & 0xF0) >> 4;
00129 genie <<= 4;
00130 genie |= temp;
00131
00132
00133 temp = (address & 0xF);
00134 genie <<= 4;
00135 genie |= temp;
00136
00137 QString ggcode;
00138 const char *alphabet = GenesisGameGenieCode::ALPHABET;
00139
00140 for (int i = 0; i < 8; i++) {
00141 if (i == 4) {
00142 ggcode.insert(0, "-");
00143 }
00144
00145 ggcode.insert(0, alphabet[(int)((genie >> (i * 5)) & 0x1F)]);
00146 }
00147
00148 return GenesisGameGenieCode::create(ggcode);
00149 }
00150
00151 NESGameGenieCode Encoder::encode(const NESRawCode &code) {
00152 int genie;
00153 int temp = 0;
00154 int value = code.getValue();
00155 int address = code.getAddress();
00156
00157
00158 genie = ((value & 0x80) >> 4) | (value & 0x7);
00159
00160
00161 temp = ((address & 0x80) >> 4) | ((value & 0x70) >> 4);
00162 genie <<= 4;
00163 genie |= temp;
00164
00165
00166 temp = (address & 0x70) >> 4;
00167
00168 if (code.hasCompare()) {
00169 temp |= 0x8;
00170 }
00171
00172 genie <<= 4;
00173 genie |= temp;
00174
00175
00176 temp = (address & 0x8) | ((address & 0x7000) >> 12);
00177 genie <<= 4;
00178 genie |= temp;
00179
00180
00181 temp = ((address & 0x800) >> 8) | (address & 0x7);
00182 genie <<= 4;
00183 genie |= temp;
00184
00185 if (code.hasCompare()) {
00186 int compare = code.getCompare();
00187
00188
00189 temp = (compare & 0x8) | ((address & 0x700) >> 8);
00190 genie <<= 4;
00191 genie |= temp;
00192
00193
00194 temp = ((compare & 0x80) >> 4) | (compare & 0x7);
00195 genie <<= 4;
00196 genie |= temp;
00197
00198
00199 temp = (value & 0x8) | ((compare & 0x70) >> 4);
00200 genie <<= 4;
00201 genie |= temp;
00202 } else {
00203
00204 temp = (value & 0x8) | ((address & 0x700) >> 8);
00205 genie <<= 4;
00206 genie |= temp;
00207 }
00208
00209 QString ggcode;
00210 const char *alphabet = NESGameGenieCode::ALPHABET;
00211
00212 for (int i = 0; i < (code.hasCompare() ? 8 : 6); i++) {
00213 ggcode.insert(0, alphabet[(genie >> (i * 4)) & 0xF]);
00214 }
00215
00216 return NESGameGenieCode::create(ggcode);
00217 }
00218
00219 SNESGameGenieCode Encoder::encode(const SNESRawCode &code) {
00220 int genie;
00221 int temp;
00222 int value = code.getValue();
00223 int address = code.getAddress();
00224
00225
00226 genie = value;
00227
00228
00229 temp = (address & 0xF000) >> 12;
00230 genie <<= 4;
00231 genie |= temp;
00232
00233
00234 temp = (address & 0xF0) >> 4;
00235 genie <<= 4;
00236 genie |= temp;
00237
00238
00239 temp = ((address & 0x300) >> 6) | (address >> 22);
00240 genie <<= 4;
00241 genie |= temp;
00242
00243
00244 temp = ((address & 0x300000) >> 18) | ((address & 0xC) >> 2);
00245 genie <<= 4;
00246 genie |= temp;
00247
00248
00249 temp = ((address & 0x3) << 2) | ((address & 0xC0000) >> 18);
00250 genie <<= 4;
00251 genie |= temp;
00252
00253
00254 temp = ((address & 0x30000) >> 14) | ((address & 0xC00) >> 10);
00255 genie <<= 4;
00256 genie |= temp;
00257
00258 QString ggcode;
00259 const char *alphabet = SNESGameGenieCode::ALPHABET;
00260
00261 for (int i = 0; i < 8; i++) {
00262 if (i == 4) {
00263 ggcode.insert(0, '-');
00264 }
00265
00266 ggcode.insert(0, alphabet[(genie >> (i * 4)) & 0xF]);
00267 }
00268
00269 return SNESGameGenieCode::create(ggcode);
00270 }
00271