diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index daa2f7cc8..b0777e6b3 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -127,6 +127,9 @@ int NDS_Init( void) { TSCal.scr.width = (TSCal.scr.x2 - TSCal.scr.x1); TSCal.scr.height = (TSCal.scr.y2 - TSCal.scr.y1); + cheats = new CHEATS(); + cheatSearch = new CHEATSEARCH(); + return 0; } @@ -140,7 +143,11 @@ void NDS_DeInit(void) { gpu3D->NDS_3D_Close(); WIFI_DeInit(); - cheatsSearchClose(); + if (cheats) + delete cheats; + if (cheatSearch) + delete cheatSearch; + } BOOL NDS_SetROM(u8 * rom, u32 mask) @@ -376,7 +383,8 @@ int NDS_LoadROM(const char *filename, const char *logicalFilename) } #endif - cheatsSearchClose(); + if (cheatSearch) + cheatSearch->close(); FCEUI_StopMovie(); MMU_unsetRom(); @@ -396,7 +404,7 @@ int NDS_LoadROM(const char *filename, const char *logicalFilename) path.getpathnoext(path.CHEATS, buf); strcat(buf, ".dct"); // DeSmuME cheat :) - cheatsInit(buf); + cheats->init(buf); gameInfo.populate(); gameInfo.crc = crc32(0,(u8*)gameInfo.romdata,gameInfo.romsize); @@ -495,7 +503,8 @@ int NDS_LoadROM(const char *filename, const char *logicalFilename) #endif - cheatsSearchClose(); + if (cheatSearch) + cheatSearch->close(); MMU_unsetRom(); NDS_SetROM(data, mask); NDS_Reset(); @@ -1813,7 +1822,8 @@ void NDS_exec(s32 nb) lagframecounter = 0; } currFrameCounter++; - cheatsProcess(); + if (cheats) + cheats->process(); } void execHardware_interrupts() @@ -2004,7 +2014,7 @@ void NDS_Reset() armcpu_init(&NDS_ARM7, header->ARM7exe); armcpu_init(&NDS_ARM9, header->ARM9exe); } - + nds.wifiCycle = 0; memset(nds.timerCycle, 0, sizeof(u64) * 2 * 4); nds.VCount = 0; diff --git a/desmume/src/cheatSystem.cpp b/desmume/src/cheatSystem.cpp index 9c2571eed..7983024df 100644 --- a/desmume/src/cheatSystem.cpp +++ b/desmume/src/cheatSystem.cpp @@ -28,63 +28,57 @@ #include "MMU.h" #include "debug.h" -static CHEATS_LIST cheats[MAX_CHEAT_LIST]; -static u16 cheatsNum = 0; -static u8 cheatFilename[MAX_PATH]; -static u32 cheatsCurrentGet = 0; +CHEATS *cheats = NULL; +CHEATSEARCH *cheatSearch = NULL; -static u8 *cheatsStack = NULL; -static u16 cheatsNumStack = 0; -static bool cheatsDisabled = false; - -static void cheatsClear() +void CHEATS::clear() { - memset(cheats, 0, sizeof(cheats)); + memset(list, 0, sizeof(list)); for (int i = 0; i < MAX_CHEAT_LIST; i++) - cheats[i].type = 0xFF; - cheatsNum = 0; - cheatsCurrentGet = 0; + list[i].type = 0xFF; + num = 0; + currentGet = 0; } -void cheatsInit(char *path) +void CHEATS::init(char *path) { - cheatsClear(); - strcpy((char *)cheatFilename, path); + clear(); + strcpy((char *)filename, path); - if (cheatsStack) delete [] cheatsStack; - cheatsStack = NULL; + if (stack) delete [] stack; + stack = NULL; - cheatsLoad(); + load(); } -BOOL cheatsAdd(u8 size, u32 address, u32 val, char *description, BOOL enabled) +BOOL CHEATS::add(u8 size, u32 address, u32 val, char *description, BOOL enabled) { - if (cheatsNum == MAX_CHEAT_LIST) return FALSE; - cheats[cheatsNum].hi[0] = address & 0x00FFFFFF; - cheats[cheatsNum].lo[0] = val; - cheats[cheatsNum].num = 1; - cheats[cheatsNum].type = 0; - cheats[cheatsNum].size = size; - strcpy(cheats[cheatsNum].description, description); - cheats[cheatsNum].enabled = enabled; - cheatsNum++; + if (num == MAX_CHEAT_LIST) return FALSE; + list[num].hi[0] = address & 0x00FFFFFF; + list[num].lo[0] = val; + list[num].num = 1; + list[num].type = 0; + list[num].size = size; + strcpy(list[num].description, description); + list[num].enabled = enabled; + num++; return TRUE; } -BOOL cheatsUpdate(u8 size, u32 address, u32 val, char *description, BOOL enabled, u32 pos) +BOOL CHEATS::update(u8 size, u32 address, u32 val, char *description, BOOL enabled, u32 pos) { - if (pos > cheatsNum) return FALSE; - cheats[pos].hi[0] = address & 0x00FFFFFF; - cheats[pos].lo[0] = val; - cheats[pos].num = 1; - cheats[pos].type = 0; - cheats[pos].size = size; - strcpy(cheats[pos].description, description); - cheats[pos].enabled = enabled; + if (pos > num) return FALSE; + list[pos].hi[0] = address & 0x00FFFFFF; + list[pos].lo[0] = val; + list[pos].num = 1; + list[pos].type = 0; + list[pos].size = size; + strcpy(list[pos].description, description); + list[pos].enabled = enabled; return TRUE; } -static void cheats_ARparser(CHEATS_LIST cheat) +void CHEATS::ARparser(CHEATS_LIST list) { u8 type = 0; u8 subtype = 0; @@ -101,13 +95,13 @@ static void cheats_ARparser(CHEATS_LIST cheat) s32 loopbackline = 0; u32 loop_flag = 0; - for (int i=0; i < cheat.num; i++) + for (int i=0; i < list.num; i++) { - type = cheat.hi[i] >> 28; - subtype = (cheat.hi[i] >> 24) & 0x0F; + type = list.hi[i] >> 28; + subtype = (list.hi[i] >> 24) & 0x0F; - hi = cheat.hi[i] & 0x0FFFFFFF; - lo = cheat.lo[i]; + hi = list.hi[i] & 0x0FFFFFFF; + lo = list.lo[i]; if (if_flag > 0) { @@ -373,11 +367,10 @@ static void cheats_ARparser(CHEATS_LIST cheat) break; case 0xE: - for (u32 t = 0; t < lo; t++) - { - u8 tmp = T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM9][(hi+t)>>20], (hi+t) & MMU.MMU_MASK[ARMCPU_ARM9][(hi+t)>>20]); - T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM9][(offset+t)>>20], (offset+t) & MMU.MMU_MASK[ARMCPU_ARM9][(offset+t)>>20], tmp); - } + { + // TODO + i += (lo / 8); + } break; case 0xF: @@ -392,11 +385,11 @@ static void cheats_ARparser(CHEATS_LIST cheat) } } -static BOOL cheatsXXcodePreparser(CHEATS_LIST *cheat, char *code) +BOOL CHEATS::XXcodePreParser(CHEATS_LIST *list, char *code) { int count = 0; u16 t = 0; - char tmp_buf[sizeof(cheat->hi)+sizeof(cheat->lo)]; + char tmp_buf[sizeof(list->hi)+sizeof(list->lo)]; memset(tmp_buf, 0, sizeof(tmp_buf)); // remove wrong chars @@ -441,304 +434,315 @@ static BOOL cheatsXXcodePreparser(CHEATS_LIST *cheat, char *code) { char buf[8] = {0}; strncpy(buf, tmp_buf+(i*16), 8); - sscanf_s(buf, "%x", &cheat->hi[i]); + sscanf_s(buf, "%x", &list->hi[i]); strncpy(buf, tmp_buf+(i*16) + 8, 8); - sscanf_s(buf, "%x", &cheat->lo[i]); + sscanf_s(buf, "%x", &list->lo[i]); } - cheat->num = count; - cheat->size = 0; + list->num = count; + list->size = 0; return TRUE; } -BOOL cheatsAdd_AR(char *code, char *description, BOOL enabled) +BOOL CHEATS::add_AR(char *code, char *description, BOOL enabled) { - if (cheatsNum == MAX_CHEAT_LIST) return FALSE; + if (num == MAX_CHEAT_LIST) return FALSE; - if (!cheatsXXcodePreparser(&cheats[cheatsNum], code)) return FALSE; + if (!XXcodePreParser(&list[num], code)) return FALSE; - cheats[cheatsNum].type = 1; + list[num].type = 1; - strcpy(cheats[cheatsNum].description, description); - cheats[cheatsNum].enabled = enabled; - cheatsNum++; + strcpy(list[num].description, description); + list[num].enabled = enabled; + num++; return TRUE; } -BOOL cheatsUpdate_AR(char *code, char *description, BOOL enabled, u32 pos) +BOOL CHEATS::update_AR(char *code, char *description, BOOL enabled, u32 pos) { - if (pos > cheatsNum) return FALSE; + if (pos > num) return FALSE; if (code != NULL) { - if (!cheatsXXcodePreparser(&cheats[pos], code)) return FALSE; - strcpy(cheats[pos].description, description); - cheats[pos].type = 1; + if (!XXcodePreParser(&list[pos], code)) return FALSE; + strcpy(list[pos].description, description); + list[pos].type = 1; } - cheats[pos].enabled = enabled; + list[pos].enabled = enabled; return TRUE; } -BOOL cheatsAdd_CB(char *code, char *description, BOOL enabled) +BOOL CHEATS::add_CB(char *code, char *description, BOOL enabled) { - if (cheatsNum == MAX_CHEAT_LIST) return FALSE; + if (num == MAX_CHEAT_LIST) return FALSE; - if (!cheatsXXcodePreparser(&cheats[cheatsNum], code)) return FALSE; + if (!XXcodePreParser(&list[num], code)) return FALSE; - cheats[cheatsNum].type = 2; + list[num].type = 2; - strcpy(cheats[cheatsNum].description, description); - cheats[cheatsNum].enabled = enabled; - cheatsNum++; + strcpy(list[num].description, description); + list[num].enabled = enabled; + num++; return TRUE; } -BOOL cheatsUpdate_CB(char *code, char *description, BOOL enabled, u32 pos) +BOOL CHEATS::update_CB(char *code, char *description, BOOL enabled, u32 pos) { - if (pos > cheatsNum) return FALSE; + if (pos > num) return FALSE; if (code != NULL) { - if (!cheatsXXcodePreparser(&cheats[pos], code)) return FALSE; - cheats[pos].type = 2; - strcpy(cheats[pos].description, description); + if (!XXcodePreParser(&list[pos], code)) return FALSE; + list[pos].type = 2; + strcpy(list[pos].description, description); } - cheats[pos].enabled = enabled; + list[pos].enabled = enabled; return TRUE; } -BOOL cheatsRemove(u32 pos) +BOOL CHEATS::remove(u32 pos) { - if (pos > cheatsNum) return FALSE; - if (cheatsNum == 0) return FALSE; + if (pos > num) return FALSE; + if (num == 0) return FALSE; - for (int i = pos; i < cheatsNum; i++) - memcpy(&cheats[i], &cheats[i+1], sizeof(CHEATS_LIST)); + for (int i = pos; i < num; i++) + memcpy(&list[i], &list[i+1], sizeof(CHEATS_LIST)); - memset(&cheats[cheatsNum], 0, sizeof(CHEATS_LIST)); + memset(&list[num], 0, sizeof(CHEATS_LIST)); - cheatsNum--; + num--; return TRUE; } -void cheatsGetListReset() +void CHEATS::getListReset() { - cheatsCurrentGet = 0; + currentGet = 0; return; } -BOOL cheatsGetList(CHEATS_LIST *cheat) +BOOL CHEATS::getList(CHEATS_LIST *cheat) { - if (cheatsCurrentGet > cheatsNum) + if (currentGet > num) { - cheatsCurrentGet = 0; + currentGet = 0; return FALSE; } - memcpy(cheat, &cheats[cheatsCurrentGet++], sizeof(CHEATS_LIST)); - if (cheatsCurrentGet > cheatsNum) + memcpy(cheat, &list[currentGet++], sizeof(CHEATS_LIST)); + if (currentGet > num) { - cheatsCurrentGet = 0; + currentGet = 0; return FALSE; } return TRUE; } -BOOL cheatsGet(CHEATS_LIST *cheat, u32 pos) +BOOL CHEATS::get(CHEATS_LIST *cheat, u32 pos) { - if (pos > cheatsNum) return FALSE; - memcpy(cheat, &cheats[pos], sizeof(CHEATS_LIST)); + if (pos > num) return FALSE; + memcpy(cheat, &list[pos], sizeof(CHEATS_LIST)); return TRUE; } -u32 cheatsGetSize() +u32 CHEATS::getSize() { - return cheatsNum; + return num; } -BOOL cheatsSave() +BOOL CHEATS::save() { - FILE *fcheat = fopen((char *)cheatFilename, "w"); + char *types[] = {"DS", "AR", "CB"}; + char buf[(sizeof(list[0].hi)+sizeof(list[0].lo)) * 2 + 200] = { 0 }; + FILE *flist = fopen((char *)filename, "w"); - if (fcheat) + if (flist) { - fprintf(fcheat, "; DeSmuME cheat file. VERSION %i.%03i\n", CHEAT_VERSION_MAJOR, CHEAT_VERSION_MINOR); - fprintf(fcheat, "Name=%s\n", gameInfo.ROMserial); - fputs("; cheats list\n", fcheat); - for (int i = 0; i < cheatsNum; i++) + fprintf(flist, "; DeSmuME cheats file. VERSION %i.%03i\n", CHEAT_VERSION_MAJOR, CHEAT_VERSION_MINOR); + fprintf(flist, "Name=%s\n", gameInfo.ROMserial); + fputs("; lists list\n", flist); + for (int i = 0; i < num; i++) { - fprintf(fcheat, "Desc=%s\n", cheats[i].description); - fprintf(fcheat, "Info=%i,%i,%i,%i\n", cheats[i].type, cheats[i].num, cheats[i].enabled, cheats[i].size); - - if (cheats[i].num > 0) + if (list[i].num == 0) continue; + memset(buf, 0, sizeof(buf)); + sprintf(buf, "%s %c ", types[list[i].type], list[i].enabled?'1':'0'); + for (int t = 0; t < list[i].num; t++) { - fprintf(fcheat, "Data="); - for (int t = 0; t < cheats[i].num; t++) - { - fprintf(fcheat, "%08X%08X", cheats[i].hi[t], cheats[i].lo[t]); - if (t < (cheats[i].num - 1)) fputs(",", fcheat); - } - fputs("\n", fcheat); + char buf2[10] = { 0 }; + sprintf(buf2, "%08X", list[i].hi[t]); + strcat(buf, buf2); + sprintf(buf2, "%08X", list[i].lo[t]); + strcat(buf, buf2); + if (t < (list[i].num - 1)) + strcat(buf, ","); } - fputs("\n", fcheat); + strcat(buf, " ;"); + strcat(buf, trim(list[i].description)); + fprintf(flist, "%s\n", buf); } - - fclose(fcheat); + fputs("\n", flist); + fclose(flist); return TRUE; } return FALSE; } -BOOL cheatsLoad() +char *CHEATS::clearCode(char *s) { - FILE *fcheat = fopen((char *)cheatFilename, "r"); - char buf[1024]; - int last=0; - if (fcheat) + char *buf = s; + if (!s) return NULL; + if (!*s) return s; + + for (int i = 0; i < strlen(s); i++) { - cheatsClear(); - memset(buf, 0, 1024); - - while (!feof(fcheat)) + if (s[i] == ';') break; + if (strchr(hexValid, s[i])) { - fgets(buf, 1024, fcheat); - if (buf[0] == ';') continue; - removeCR((char *)&buf); - if (!strlen_ws(buf)) continue; - if ( (buf[0] == 'D') && - (buf[1] == 'e') && - (buf[2] == 's') && - (buf[3] == 'c') && - (buf[4] == '=') ) // new cheat block - { - strncpy((char *)cheats[last].description, (char *)buf+5, strlen(buf)-5); - fgets(buf, 1024, fcheat); - if ( (buf[0] == 'I') && - (buf[1] == 'n') && - (buf[2] == 'f') && - (buf[3] == 'o') && - (buf[4] == '=') ) // Info cheat - { - u32 dstart = 5; - u32 dsize = 0; - char bf[4] = { 0 }; + *buf = s[i]; + buf++; + } + } + *buf = 0; + return s; +} - while ( (buf[dstart+dsize] != ',') && (buf[dstart+dsize]!=0)) { dsize++; }; - if (buf[dstart+dsize]==0) continue; // error - strncpy(bf, (char*)buf+dstart, dsize); - cheats[last].type=atoi(bf); - dstart += (dsize+1); dsize=0; - while ( (buf[dstart+dsize] != ',') && (buf[dstart+dsize]!=0)) { dsize++; }; - if (buf[dstart+dsize]==0) continue; // error - strncpy(bf, (char*)buf+dstart, dsize); - dstart += (dsize+1); dsize=0; - cheats[last].num=atoi(bf); - while ( (buf[dstart+dsize] != ',') && (buf[dstart+dsize]!=0)) { dsize++; }; - if (buf[dstart+dsize]==0) continue; // error - strncpy(bf, (char*)(buf+dstart), dsize); - dstart += (dsize+1); dsize=0; - cheats[last].enabled=atoi(bf); - while ( (buf[dstart+dsize] != ',') && (buf[dstart+dsize]!=0)) { dsize++; }; - strncpy(bf, (char*)buf+dstart, dsize); - cheats[last].size=atoi(bf); - fgets(buf, 1024, fcheat); - if ( (buf[0] == 'D') && - (buf[1] == 'a') && - (buf[2] == 't') && - (buf[3] == 'a') && - (buf[4] == '=') ) // Data cheat - { - int offs = 5; - char tmp_buf[9]; - memset(tmp_buf, 0, 9); +BOOL CHEATS::load() +{ + FILE *flist = fopen((char *)filename, "r"); + char buf[(sizeof(list[0].hi)+sizeof(list[0].lo)) * 2 + 200] = { 0 }; + u32 last = 0; + CHEATS_LIST tmp_cht = { 0 }; + char tmp_code[(sizeof(list[0].hi)+sizeof(list[0].lo)) * 2] = { 0 }; + u32 line = 0; - for (int j=0; j(strchr((char*)buf, ';') - buf, 0)); + if (descr_pos != 0) + strcpy(tmp_cht.description, (buf + descr_pos + 1)); + +#if 1 + // TODO: remove later (its old) + tmp_cht.num = strlen(tmp_code) / 16; + for (int i = 0; i < tmp_cht.num; i++) + { + char tmp_buf[9] = {0}; + + strncpy(tmp_buf, (char*)(tmp_code + (i*16)), 8); + sscanf_s(tmp_buf, "%x", &tmp_cht.hi[i]); + + strncpy(tmp_buf, (char*)(tmp_code + (i*16) + 8), 8); + sscanf_s(tmp_buf, "%x", &tmp_cht.lo[i]); + } +#endif + + memcpy(&list[last], &tmp_cht, sizeof(tmp_cht)); + last++; } - fclose(fcheat); - //INFO("Loaded %i cheats\n", last); - cheatsNum = last; + fclose(flist); + num = last; + INFO("Added %i list codes\n", num); return TRUE; } return FALSE; } -BOOL cheatsPush() +BOOL CHEATS::push() { - if (cheatsStack) return FALSE; - cheatsStack = new u8 [sizeof(cheats)]; - memcpy(cheatsStack, cheats, sizeof(cheats)); - cheatsNumStack = cheatsNum; + if (stack) return FALSE; + stack = new u8 [sizeof(list)]; + memcpy(stack, list, sizeof(list)); + numStack = num; return TRUE; } -BOOL cheatsPop() +BOOL CHEATS::pop() { - if (!cheatsStack) return FALSE; - memcpy(cheats, cheatsStack, sizeof(cheats)); - cheatsNum = cheatsNumStack; - delete [] cheatsStack; - cheatsStack = NULL; + if (!stack) return FALSE; + memcpy(list, stack, sizeof(list)); + num = numStack; + delete [] stack; + stack = NULL; return TRUE; } -void cheatsStackClear() +void CHEATS::stackClear() { - if (!cheatsStack) return; - delete [] cheatsStack; - cheatsStack = NULL; + if (!stack) return; + delete [] stack; + stack = NULL; } -void cheatsProcess() +void CHEATS::process() { - if (cheatsDisabled) return; - if (!cheatsNum) return; - for (int i = 0; i < cheatsNum; i++) + if (disabled) return; + if (!num) return; + for (int i = 0; i < num; i++) { - if (!cheats[i].enabled) continue; + if (!list[i].enabled) continue; - switch (cheats[i].type) + switch (list[i].type) { - case 0: // internal cheat system - //INFO("cheat at 0x02|%06X value %i (size %i)\n",cheats[i].hi[0], cheats[i].lo[0], cheats[i].size); - switch (cheats[i].size) + case 0: // internal list system + //INFO("list at 0x02|%06X value %i (size %i)\n",list[i].hi[0], list[i].lo[0], list[i].size); + switch (list[i].size) { - case 0: T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM9][0x20], cheats[i].hi[0], cheats[i].lo[0]); break; - case 1: T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x20], cheats[i].hi[0], cheats[i].lo[0]); break; + case 0: T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM9][0x20], list[i].hi[0], list[i].lo[0]); break; + case 1: T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x20], list[i].hi[0], list[i].lo[0]); break; case 2: { - u32 tmp = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x20], cheats[i].hi[0]); + u32 tmp = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x20], list[i].hi[0]); tmp &= 0xFF000000; - tmp |= (cheats[i].lo[0] & 0x00FFFFFF); - T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x20], cheats[i].hi[0], tmp); + tmp |= (list[i].lo[0] & 0x00FFFFFF); + T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x20], list[i].hi[0], tmp); break; } - case 3: T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x20], cheats[i].hi[0], cheats[i].lo[0]); break; + case 3: T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x20], list[i].hi[0], list[i].lo[0]); break; } break; case 1: // Action Replay - cheats_ARparser(cheats[i]); + ARparser(list[i]); break; case 2: // Codebreaker break; @@ -747,88 +751,87 @@ void cheatsProcess() } } -void cheatGetXXcodeString(CHEATS_LIST cheat, char *res_buf) +void CHEATS::getXXcodeString(CHEATS_LIST list, char *res_buf) { char buf[50] = { 0 }; - for (int i=0; i < cheat.num; i++) + for (int i=0; i < list.num; i++) { - sprintf(buf, "%08X %08X\n", cheat.hi[i], cheat.lo[i]); + sprintf(buf, "%08X %08X\n", list.hi[i], list.lo[i]); strcat(res_buf, buf); } } -void cheatsDisable(bool disable) +void CHEATS::disable(bool disable) { - cheatsDisabled = disable; + disabled = disable; } // ========================================== search -u8 *searchStatMem = NULL; -u8 *searchMem = NULL; -u32 searchNumber = 0; -u32 searchLastRecord = 0; - -u32 searchType = 0; -u32 searchSize = 0; -u32 searchSign = 0; - -void cheatsSearchInit(u8 type, u8 size, u8 sign) +BOOL CHEATSEARCH::start(u8 type, u8 size, u8 sign) { - if (searchStatMem) return; - if (searchMem) return; + if (statMem) return FALSE; + if (mem) return FALSE; - searchStatMem = new u8 [ ( 4 * 1024 * 1024 ) / 8 ]; + statMem = new u8 [ ( 4 * 1024 * 1024 ) / 8 ]; - memset(searchStatMem, 0xFF, ( 4 * 1024 * 1024 ) / 8); + memset(statMem, 0xFF, ( 4 * 1024 * 1024 ) / 8); if (type == 1) // comparative search type (need 8Mb RAM !!! (4+4)) { - searchMem = new u8 [ ( 4 * 1024 * 1024 ) ]; - memcpy(searchMem, MMU.MMU_MEM[0][0x20], ( 4 * 1024 * 1024 ) ); + mem = new u8 [ ( 4 * 1024 * 1024 ) ]; + memcpy(mem, MMU.MMU_MEM[0][0x20], ( 4 * 1024 * 1024 ) ); } - searchType = type; - searchSize = size; - searchSign = sign; - searchNumber = 0; - searchLastRecord = 0; + _type = type; + _size = size; + _sign = sign; + amount = 0; + lastRecord = 0; //INFO("Cheat search system is inited (type %s)\n", type?"comparative":"exact"); + return TRUE; } -void cheatsSearchClose() +BOOL CHEATSEARCH::close() { - if (searchStatMem) delete [] searchStatMem; - searchStatMem = NULL; + if (statMem) + { + delete [] statMem; + statMem = NULL; + } - if (searchMem) delete [] searchMem; - searchMem = NULL; - searchNumber = 0; - searchLastRecord = 0; + if (mem) + { + delete [] mem; + mem = NULL; + } + amount = 0; + lastRecord = 0; //INFO("Cheat search system is closed\n"); + return FALSE; } -u32 cheatsSearchValue(u32 val) +u32 CHEATSEARCH::search(u32 val) { - searchNumber = 0; + amount = 0; - switch (searchSize) + switch (_size) { case 0: // 1 byte for (u32 i = 0; i < (4 * 1024 * 1024); i++) { u32 addr = (i >> 3); u32 offs = (i % 8); - if (searchStatMem[addr] & (1<> 3); u32 offs = (i % 8); - if (searchStatMem[addr] & (3<> 3); u32 offs = (i % 8); - if (searchStatMem[addr] & (0x7<> 3); u32 offs = (i % 8); - if (searchStatMem[addr] & (0xF<> 3); u32 offs = (i % 8); - if (searchStatMem[addr] & (1< T1ReadByte(searchMem, i)); break; - case 1: res=(T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) < T1ReadByte(searchMem, i)); break; - case 2: res=(T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) == T1ReadByte(searchMem, i)); break; - case 3: res=(T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) != T1ReadByte(searchMem, i)); break; + case 0: res=(T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) > T1ReadByte(mem, i)); break; + case 1: res=(T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) < T1ReadByte(mem, i)); break; + case 2: res=(T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) == T1ReadByte(mem, i)); break; + case 3: res=(T1ReadByte(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) != T1ReadByte(mem, i)); break; default: res = FALSE; break; } if ( res ) { - searchStatMem[addr] |= (1<> 3); u32 offs = (i % 8); - if (searchStatMem[addr] & (3< T1ReadWord(searchMem, i)); break; - case 1: res=(T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) < T1ReadWord(searchMem, i)); break; - case 2: res=(T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) == T1ReadWord(searchMem, i)); break; - case 3: res=(T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) != T1ReadWord(searchMem, i)); break; + case 0: res=(T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) > T1ReadWord(mem, i)); break; + case 1: res=(T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) < T1ReadWord(mem, i)); break; + case 2: res=(T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) == T1ReadWord(mem, i)); break; + case 3: res=(T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) != T1ReadWord(mem, i)); break; default: res = FALSE; break; } if ( res ) { - searchStatMem[addr] |= (3<> 3); u32 offs = (i % 8); - if (searchStatMem[addr] & (7< (T1ReadLong(searchMem, i) & 0x00FFFFFF) ); break; - case 1: res=((T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) & 0x00FFFFFF) < (T1ReadLong(searchMem, i) & 0x00FFFFFF) ); break; - case 2: res=((T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) & 0x00FFFFFF) == (T1ReadLong(searchMem, i) & 0x00FFFFFF) ); break; - case 3: res=((T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) & 0x00FFFFFF) != (T1ReadLong(searchMem, i) & 0x00FFFFFF) ); break; + case 0: res=((T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) & 0x00FFFFFF) > (T1ReadLong(mem, i) & 0x00FFFFFF) ); break; + case 1: res=((T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) & 0x00FFFFFF) < (T1ReadLong(mem, i) & 0x00FFFFFF) ); break; + case 2: res=((T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) & 0x00FFFFFF) == (T1ReadLong(mem, i) & 0x00FFFFFF) ); break; + case 3: res=((T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) & 0x00FFFFFF) != (T1ReadLong(mem, i) & 0x00FFFFFF) ); break; default: res = FALSE; break; } if ( res ) { - searchStatMem[addr] |= (7<> 3); u32 offs = (i % 8); - if (searchStatMem[addr] & (0xF< T1ReadLong(searchMem, i)); break; - case 1: res=(T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) < T1ReadLong(searchMem, i)); break; - case 2: res=(T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) == T1ReadLong(searchMem, i)); break; - case 3: res=(T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) != T1ReadLong(searchMem, i)); break; + case 0: res=(T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) > T1ReadLong(mem, i)); break; + case 1: res=(T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) < T1ReadLong(mem, i)); break; + case 2: res=(T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) == T1ReadLong(mem, i)); break; + case 3: res=(T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x20], i) != T1ReadLong(mem, i)); break; default: res = FALSE; break; } if ( res ) { - searchStatMem[addr] |= (0xF<> 3); u32 offs = (i % 8); - if (searchStatMem[addr] & (stepMem<0; i--) - { - if (buf[i]!=32) return (i-1); // space - } - return 0; + char *ptr = NULL; + if (!s) return NULL; + if (!*s) return s; + + for (ptr = s + strlen(s) - 1; (ptr >= s) && isspace(*ptr); ptr--); + ptr[1] = '\0'; + return s; } diff --git a/desmume/src/common.h b/desmume/src/common.h index 818f73ab4..b968f4a01 100644 --- a/desmume/src/common.h +++ b/desmume/src/common.h @@ -34,7 +34,7 @@ extern u8 logo_data[156]; #include #include - + #define CLASSNAME "DeSmuME" @@ -56,8 +56,7 @@ extern u8 logo_data[156]; #endif extern u8 reverseBitsInByte(u8 x); -extern void removeCR(char *buf); -extern u32 strlen_ws(char *buf); +extern char *trim(char *s); #endif diff --git a/desmume/src/gtk/cheatsGTK.cpp b/desmume/src/gtk/cheatsGTK.cpp index 3ab4838c7..bdccbd1d3 100644 --- a/desmume/src/gtk/cheatsGTK.cpp +++ b/desmume/src/gtk/cheatsGTK.cpp @@ -87,9 +87,9 @@ enabled_toggled(GtkCellRendererToggle * cell, path1 = gtk_tree_model_get_path (model, &iter); ii = gtk_tree_path_get_indices (path)[0]; - cheatsGet(&cheat, ii); + cheats->get(&cheat, ii); - cheatsUpdate(cheat.size, cheat.hi[0], cheat.lo[0], cheat.description, + cheats->update(cheat.size, cheat.hi[0], cheat.lo[0], cheat.description, enabled, ii); gtk_list_store_set(GTK_LIST_STORE(model), &iter, COLUMN_ENABLED, enabled, -1); @@ -118,7 +118,7 @@ static void cheat_list_modify_cheat(GtkCellRendererText * cell, path1 = gtk_tree_model_get_path (model, &iter); ii = gtk_tree_path_get_indices (path)[0]; - cheatsGet(&cheat, ii); + cheats->get(&cheat, ii); gtk_tree_path_free (path1); @@ -127,22 +127,22 @@ static void cheat_list_modify_cheat(GtkCellRendererText * cell, u32 v = atoi(new_text); switch (column) { case COLUMN_SIZE: - cheatsUpdate(v-1, cheat.hi[0], cheat.lo[0], + cheats->update(v-1, cheat.hi[0], cheat.lo[0], cheat.description, cheat.enabled, ii); break; case COLUMN_HI: - cheatsUpdate(cheat.size, v, cheat.lo[0], cheat.description, + cheats->update(cheat.size, v, cheat.lo[0], cheat.description, cheat.enabled, ii); break; case COLUMN_LO: - cheatsUpdate(cheat.size, cheat.hi[0], v, cheat.description, + cheats->update(cheat.size, cheat.hi[0], v, cheat.description, cheat.enabled, ii); break; } gtk_list_store_set(GTK_LIST_STORE(model), &iter, column, atoi(new_text), -1); } else if (column == COLUMN_DESC){ - cheatsUpdate(cheat.size, cheat.hi[0], cheat.lo[0], + cheats->update(cheat.size, cheat.hi[0], cheat.lo[0], g_strdup(new_text), cheat.enabled, ii); gtk_list_store_set(GTK_LIST_STORE(model), &iter, column, g_strdup(new_text), -1); @@ -166,7 +166,7 @@ static void cheat_list_remove_cheat(GtkWidget * widget, gpointer data) ii = gtk_tree_path_get_indices (path)[0]; gtk_list_store_remove(GTK_LIST_STORE(model), &iter); - cheatsRemove(ii); + cheats->remove(ii); gtk_tree_path_free (path); } @@ -177,7 +177,7 @@ static void cheat_list_add_cheat(GtkWidget * widget, gpointer data) #define NEW_DESC "New cheat" GtkListStore *store = (GtkListStore *) data; GtkTreeIter iter; - cheatsAdd(1, 0, 0, g_strdup(NEW_DESC), FALSE); + cheats->add(1, 0, 0, g_strdup(NEW_DESC), FALSE); gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, COLUMN_ENABLED, FALSE, @@ -271,7 +271,7 @@ static void cheat_list_add_columns(GtkTreeView * tree, GtkListStore * store) static void cheatListEnd() { - cheatsSave(); + cheats->save(); if(shouldBeRunning) Launch(); } @@ -282,10 +282,10 @@ static GtkListStore *cheat_list_populate() G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_STRING); CHEATS_LIST cheat; - u32 chsize = cheatsGetSize(); + u32 chsize = cheats->getSize(); for(u32 ii = 0; ii < chsize; ii++){ GtkTreeIter iter; - cheatsGet(&cheat, ii); + cheats->get(&cheat, ii); gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, COLUMN_ENABLED, cheat.enabled, diff --git a/desmume/src/types.h b/desmume/src/types.h index 3daeaaf07..79c44a45d 100644 --- a/desmume/src/types.h +++ b/desmume/src/types.h @@ -415,4 +415,6 @@ char (*BLAHBLAHBLAH( UNALIGNED T (&)[N] ))[N]; #define CTASSERT(x) typedef char __assert ## y[(x) ? 1 : -1] #endif +static const char hexValid[23] = {"0123456789ABCDEFabcdef"}; + #endif diff --git a/desmume/src/windows/cheatsWin.cpp b/desmume/src/windows/cheatsWin.cpp index 1f7782332..d800eead3 100644 --- a/desmume/src/windows/cheatsWin.cpp +++ b/desmume/src/windows/cheatsWin.cpp @@ -246,9 +246,9 @@ INT_PTR CALLBACK CheatsAddProc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lparam u32 tmp_addr = 0; sscanf_s(editBuf[0], "%x", &tmp_addr); - if (cheatsAdd(searchAddSize, tmp_addr, atol(editBuf[1]), editBuf[2], searchAddFreeze)) + if (cheats->add(searchAddSize, tmp_addr, atol(editBuf[1]), editBuf[2], searchAddFreeze)) { - if ((searchAddMode == 0) || (cheatsSave() && (searchAddMode == 1 || searchAddMode == 2))) + if ((searchAddMode == 0) || (cheats->save() && (searchAddMode == 1 || searchAddMode == 2))) { oldEditProc = saveOldEditProc; searchAddAddress = tmp_addr; @@ -388,7 +388,7 @@ INT_PTR CALLBACK CheatsEditProc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lpara oldEditProcHEX = SetWindowLongPtr(GetDlgItem(dialog, IDC_EDIT1), GWLP_WNDPROC, (LONG_PTR)EditValueHEXProc); oldEditProc = SetWindowLongPtr(GetDlgItem(dialog, IDC_EDIT2), GWLP_WNDPROC, (LONG_PTR)EditValueProc); - cheatsGet(&tempCheat, cheatEditPos); + cheats->get(&tempCheat, cheatEditPos); memset(buf, 0, 100); memset(buf2, 0, 100); @@ -413,7 +413,7 @@ INT_PTR CALLBACK CheatsEditProc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lpara { case IDOK: { - if (cheatsUpdate(tempCheat.size, tempCheat.hi[0], tempCheat.lo[0], tempCheat.description, tempCheat.enabled, cheatEditPos)) + if (cheats->update(tempCheat.size, tempCheat.hi[0], tempCheat.lo[0], tempCheat.description, tempCheat.enabled, cheatEditPos)) { oldEditProc = saveOldEditProc; EndDialog(dialog, TRUE); @@ -559,10 +559,10 @@ INT_PTR CALLBACK CheatsAdd_XX_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lp if (cheatXXaction != 0) { - char buf[sizeof(tempCheat.hi)+sizeof(tempCheat.lo)] = { 0 }; + char buf[(sizeof(tempCheat.hi)+sizeof(tempCheat.lo)) * 2] = { 0 }; memset(buf, 0, sizeof(buf)); - cheatGetXXcodeString(tempCheat, buf); + cheats->getXXcodeString(tempCheat, buf); SetWindowText(GetDlgItem(dialog, IDC_EDIT2), buf); SetWindowText(GetDlgItem(dialog, IDC_EDIT3), tempCheat.description); @@ -571,7 +571,7 @@ INT_PTR CALLBACK CheatsAdd_XX_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lp } CheckDlgButton(dialog, IDC_CHECK1, tempCheat.enabled?BST_CHECKED:BST_UNCHECKED); - SendMessage(GetDlgItem(dialog, IDC_EDIT2), EM_SETLIMITTEXT, sizeof(tempCheat.hi)+sizeof(tempCheat.lo), 0); + SendMessage(GetDlgItem(dialog, IDC_EDIT2), EM_SETLIMITTEXT, (sizeof(tempCheat.hi)+sizeof(tempCheat.lo)) * 2, 0); SendMessage(GetDlgItem(dialog, IDC_EDIT3), EM_SETLIMITTEXT, sizeof(tempCheat.description), 0); } return TRUE; @@ -582,7 +582,7 @@ INT_PTR CALLBACK CheatsAdd_XX_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lp { case IDOK: { - char buf[sizeof(tempCheat.hi)+sizeof(tempCheat.lo)] = { 0 }; + char buf[(sizeof(tempCheat.hi)+sizeof(tempCheat.lo)) * 2] = { 0 }; memset(buf, 0, sizeof(buf)); GetWindowText(GetDlgItem(dialog, IDC_EDIT2), buf, sizeof(buf)); @@ -591,7 +591,7 @@ INT_PTR CALLBACK CheatsAdd_XX_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lp { if (cheatXXaction == 0) // add { - if (!cheatsAdd_AR(buf, tempCheat.description, tempCheat.enabled)) + if (!cheats->add_AR(buf, tempCheat.description, tempCheat.enabled)) { MessageBox(dialog, "Syntax error in Action Replay code.\nTry again", "DeSmuME", MB_OK | MB_ICONERROR); @@ -600,7 +600,7 @@ INT_PTR CALLBACK CheatsAdd_XX_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lp } else // edit { - if (!cheatsUpdate_AR(buf, tempCheat.description, tempCheat.enabled, cheatEditPos)) + if (!cheats->update_AR(buf, tempCheat.description, tempCheat.enabled, cheatEditPos)) { MessageBox(dialog, "Syntax error in Action Replay code.\nTry again", "DeSmuME", MB_OK | MB_ICONERROR); @@ -612,7 +612,7 @@ INT_PTR CALLBACK CheatsAdd_XX_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lp { if (cheatXXaction == 0) // add { - if (!cheatsAdd_CB(buf, tempCheat.description, tempCheat.enabled)) + if (!cheats->add_CB(buf, tempCheat.description, tempCheat.enabled)) { MessageBox(dialog, "Syntax error in Codebreaker code.\nTry again", "DeSmuME", MB_OK | MB_ICONERROR); @@ -621,7 +621,7 @@ INT_PTR CALLBACK CheatsAdd_XX_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lp } else // edit { - if (!cheatsUpdate_CB(buf, tempCheat.description, tempCheat.enabled, cheatEditPos)) + if (!cheats->update_CB(buf, tempCheat.description, tempCheat.enabled, cheatEditPos)) { MessageBox(dialog, "Syntax error in Codebreaker code.\nTry again", "DeSmuME", MB_OK | MB_ICONERROR); @@ -640,7 +640,7 @@ INT_PTR CALLBACK CheatsAdd_XX_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lp case IDC_EDIT2: // code if (HIWORD(wparam) == EN_UPDATE) { - char buf[sizeof(tempCheat.hi)+sizeof(tempCheat.lo)] = { 0 }; + char buf[(sizeof(tempCheat.hi)+sizeof(tempCheat.lo)) * 2] = { 0 }; memset(buf, 0, sizeof(buf)); GetWindowText(GetDlgItem(dialog, IDC_EDIT2), buf, sizeof(buf)); @@ -712,9 +712,9 @@ INT_PTR CALLBACK CheatsListBox_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM l lvi.mask = LVIF_TEXT|LVIF_STATE; lvi.iItem = INT_MAX; - cheatsGetListReset(); + cheats->getListReset(); SendMessage(cheatListView, WM_SETREDRAW, (WPARAM)FALSE,0); - while (cheatsGetList(&tempCheat)) + while (cheats->getList(&tempCheat)) { char buf[256]; if (tempCheat.enabled) @@ -767,20 +767,20 @@ INT_PTR CALLBACK CheatsListBox_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM l if ( tmp_msg->code == LVN_ITEMACTIVATE ) { cheatEditPos = ListView_GetNextItem(cheatListView, -1, LVNI_SELECTED|LVNI_FOCUSED); - cheatsGet(&tempCheat, cheatEditPos); + cheats->get(&tempCheat, cheatEditPos); tempCheat.enabled = !tempCheat.enabled; switch (tempCheat.type) { case 0: // internal - cheatsUpdate(tempCheat.size, tempCheat.hi[0], tempCheat.lo[0], tempCheat.description, tempCheat.enabled, cheatEditPos); + cheats->update(tempCheat.size, tempCheat.hi[0], tempCheat.lo[0], tempCheat.description, tempCheat.enabled, cheatEditPos); break; case 1: // Action Replay - cheatsUpdate_AR(NULL, NULL, tempCheat.enabled, cheatEditPos); + cheats->update_AR(NULL, NULL, tempCheat.enabled, cheatEditPos); break; case 2: // Codebreaker - cheatsUpdate_CB(NULL, NULL, tempCheat.enabled, cheatEditPos); + cheats->update_CB(NULL, NULL, tempCheat.enabled, cheatEditPos); break; } @@ -815,7 +815,7 @@ INT_PTR CALLBACK CheatsListBox_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM l switch (LOWORD(wparam)) { case IDOK: - if (cheatsSave()) + if (cheats->save()) { EndDialog(dialog, TRUE); } @@ -905,9 +905,9 @@ INT_PTR CALLBACK CheatsListBox_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM l case IDC_BEDIT: { cheatEditPos = ListView_GetNextItem(cheatListView, -1, LVNI_SELECTED|LVNI_FOCUSED); - if (cheatEditPos > cheatsGetSize()) return TRUE; + if (cheatEditPos > cheats->getSize()) return TRUE; - cheatsGet(&tempCheat, cheatEditPos); + cheats->get(&tempCheat, cheatEditPos); switch (tempCheat.type) { @@ -915,7 +915,7 @@ INT_PTR CALLBACK CheatsListBox_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM l if (DialogBoxW(hAppInst, MAKEINTRESOURCEW(IDD_CHEAT_ADD), dialog, (DLGPROC) CheatsEditProc)) { char buf[256]; - cheatsGet(&tempCheat, cheatEditPos); + cheats->get(&tempCheat, cheatEditPos); if (tempCheat.enabled) ListView_SetItemText(cheatListView, cheatEditPos, 0, "X"); wsprintf(buf, "0x02%06X", tempCheat.hi[0]); @@ -937,7 +937,7 @@ INT_PTR CALLBACK CheatsListBox_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM l if (DialogBoxW(hAppInst, MAKEINTRESOURCEW(IDD_CHEAT_ADD_XX_CODE), dialog, (DLGPROC) CheatsAdd_XX_Proc)) { - cheatsGet(&tempCheat, cheatEditPos); + cheats->get(&tempCheat, cheatEditPos); if (tempCheat.enabled) ListView_SetItemText(cheatListView, cheatEditPos, 0, "X"); @@ -965,7 +965,7 @@ INT_PTR CALLBACK CheatsListBox_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM l int tmp_pos = ListView_GetNextItem(cheatListView, -1, LVNI_SELECTED|LVNI_FOCUSED); if (tmp_pos != -1) { - if (cheatsRemove(tmp_pos)) + if (cheats->remove(tmp_pos)) { ListView_DeleteItem(cheatListView, tmp_pos); EnableWindow(GetDlgItem(dialog, IDOK), TRUE); @@ -983,17 +983,17 @@ INT_PTR CALLBACK CheatsListBox_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM l void CheatsListDialog(HWND hwnd) { - if (!cheatsPush()) return; - memset(&tempCheat, 0, sizeof(CHEATS_LIST)); + if (!cheats->push()) return; + memset(&tempCheat, 0, sizeof(tempCheat)); u32 res=DialogBoxW(hAppInst, MAKEINTRESOURCEW(IDD_CHEAT_LIST), hwnd, (DLGPROC) CheatsListBox_Proc); if (res) { - cheatsSave(); - cheatsStackClear(); + cheats->save(); + cheats->stackClear(); } else { - cheatsPop(); + cheats->pop(); } } @@ -1012,7 +1012,7 @@ void CheatsAddDialog(HWND parentHwnd, u32 address, u32 value, u8 size, const cha //CheatsListDialog(listParentHwnd); // //char buf[256]; - //cheatsGet(&tempCheat, cheatEditPos); + //cheats->get(&tempCheat, cheatEditPos); //if (tempCheat.enabled) // ListView_SetItemText(cheatListView, cheatEditPos, 0, "X"); //wsprintf(buf, "0x02%06X", tempCheat.hi[0]); @@ -1169,9 +1169,9 @@ INT_PTR CALLBACK CheatsSearchViewWnd(HWND dialog, UINT msg,WPARAM wparam,LPARAM lvi.mask = LVIF_TEXT|LVIF_STATE; lvi.iItem = INT_MAX; - cheatSearchGetListReset(); + cheatSearch->getListReset(); SendMessage(searchListView, WM_SETREDRAW, (WPARAM)FALSE,0); - while (cheatSearchGetList(&address, &val)) + while (cheatSearch->getList(&address, &val)) { char buf[256]; wsprintf(buf, "0x02%06X", address); @@ -1312,16 +1312,16 @@ INT_PTR CALLBACK CheatsSearchProc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lpa case IDC_BSEARCH: if (searchStep == 0) - cheatsSearchInit(searchType, searchSize, searchSign); + cheatSearch->start(searchType, searchSize, searchSign); if (searchType == 0) { if (searchStep == 1) - searchNumberResults = cheatsSearchValue(exactVal); + searchNumberResults = cheatSearch->search((u32)exactVal); } else { if (searchStep == 2) - searchNumberResults = cheatsSearchComp(searchComp); + searchNumberResults = cheatSearch->search((u8)searchComp); } searchStep++; @@ -1340,7 +1340,7 @@ INT_PTR CALLBACK CheatsSearchProc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lpa return TRUE; case IDC_BRESTART: - cheatsSearchClose(); + cheatSearch->close(); searchStep = 0; searchNumberResults = 0; if (searchWnd) DestroyWindow(searchWnd); diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp index 0ce2d5c09..43135d773 100644 --- a/desmume/src/windows/main.cpp +++ b/desmume/src/windows/main.cpp @@ -4655,7 +4655,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM case IDM_CHEATS_DISABLE: _cheatsDisabled = !_cheatsDisabled; - cheatsDisable(_cheatsDisabled); + cheats->disable(_cheatsDisabled); MainWindow->checkMenu(IDM_CHEATS_DISABLE, _cheatsDisabled ); return 0; diff --git a/tools/cheatsConverter/cheatsConverter_VS2008.sln b/tools/cheatsConverter/cheatsConverter_VS2008.sln new file mode 100644 index 000000000..14cac1324 --- /dev/null +++ b/tools/cheatsConverter/cheatsConverter_VS2008.sln @@ -0,0 +1,17 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cheatsConverter_VS2008", "cheatsConverter_VS2008.vcproj", "{6D076DD4-4000-4249-BDEA-F7AB407C813D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6D076DD4-4000-4249-BDEA-F7AB407C813D}.Release|Win32.ActiveCfg = Release|Win32 + {6D076DD4-4000-4249-BDEA-F7AB407C813D}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/tools/cheatsConverter/cheatsConverter_VS2008.vcproj b/tools/cheatsConverter/cheatsConverter_VS2008.vcproj new file mode 100644 index 000000000..5a18d894a --- /dev/null +++ b/tools/cheatsConverter/cheatsConverter_VS2008.vcproj @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/cheatsConverter/src/common.h b/tools/cheatsConverter/src/common.h new file mode 100644 index 000000000..ae0b299da --- /dev/null +++ b/tools/cheatsConverter/src/common.h @@ -0,0 +1,70 @@ +/* Cheats converter + + Copyright 2009 DeSmuME team + + This file is part of DeSmuME + + DeSmuME is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DeSmuME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DeSmuME; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _COMMON_H__ +#define _COMMON_H__ + +#ifdef _MSC_VER +#pragma warning(disable: 4995) +#pragma warning(disable: 4996) +#endif + +#ifdef _WIN32 +#include +#endif + +#include +#include + + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +typedef unsigned __int64 u64; +typedef signed char s8; +typedef signed short s16; +typedef signed int s32; +typedef __int64 s64; + +static char *trim(char *s) +{ + char *ptr = NULL; + if (!s) return NULL; + if (!*s) return s; + + for (ptr = s + strlen(s) - 1; (ptr >= s) && isspace(*ptr); ptr--); + ptr[1] = '\0'; + return s; +} + +#ifdef _WIN32 +char __forceinline *error() +{ + LPVOID lpMsgBuf = NULL; + + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 512, NULL); + + return strdup((char*)lpMsgBuf); +} +#endif + +#endif diff --git a/tools/cheatsConverter/src/convert.cpp b/tools/cheatsConverter/src/convert.cpp new file mode 100644 index 000000000..901ce6108 --- /dev/null +++ b/tools/cheatsConverter/src/convert.cpp @@ -0,0 +1,301 @@ +/* Cheats converter + + Copyright 2009 DeSmuME team + + This file is part of DeSmuME + + DeSmuME is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DeSmuME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DeSmuME; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include +#include +#include +#include "convert.h" + +CHEATS_LIST list[MAX_CHEAT_LIST] = {0}; +u32 num = 0; +char ROMserial[50] = {0}; + +static void cheatsClear() +{ + memset(list, 0, sizeof(list)); + for (int i = 0; i < MAX_CHEAT_LIST; i++) + list[i].type = 0xFF; + num = 0; +} + +bool save(char *filename) +{ + char *types[] = {"DS", "AR", "CB"}; + char buf[(sizeof(list[0].hi)+sizeof(list[0].lo)) * 2 + 200] = { 0 }; + + FILE *flist = fopen(filename, "w"); + + if (flist) + { + fprintf(flist, "; DeSmuME cheat file. VERSION %i.%03i\n", CHEAT_VERSION_MAJOR, CHEAT_VERSION_MINOR); + fprintf(flist, "Name=%s\n", ROMserial); + fputs("; lists list\n", flist); + for (unsigned int i = 0; i < num; i++) + { + if (list[i].num == 0) continue; + memset(buf, 0, sizeof(buf)); + sprintf(buf, "%s %c ", types[list[i].type], list[i].enabled?'1':'0'); + for (int t = 0; t < list[i].num; t++) + { + char buf2[10] = { 0 }; + sprintf(buf2, "%08X", list[i].hi[t]); + strcat(buf, buf2); + sprintf(buf2, "%08X", list[i].lo[t]); + strcat(buf, buf2); + if (t < (list[i].num - 1)) + strcat(buf, ","); + } + strcat(buf, " ;"); + strcat(buf, trim(list[i].description)); + fprintf(flist, "%s\n", buf); + } + fputs("\n", flist); + fclose(flist); + return true; + } + + return false; +} + +//==================================================================================== Loads +bool load_1_0(char *fname) +{ +#ifdef WIN32 + char buf[200] = {0}; + num = GetPrivateProfileInt("General", "NumberOfCheats", 0, fname); + if (num == 0) return false; + if (num > MAX_CHEAT_LIST) num = MAX_CHEAT_LIST; + for (unsigned int i = 0; i < num; i++) + { + wsprintf(buf, "Desc%04i", i); + GetPrivateProfileString("Cheats", buf, "", list[i].description, 75, fname); + wsprintf(buf, "Type%04i", i); + list[i].type = GetPrivateProfileInt("Cheats", buf, 0xFF, fname); + wsprintf(buf, "Num_%04i", i); + list[i].num = GetPrivateProfileInt("Cheats", buf, 0, fname); + wsprintf(buf, "Enab%04i", i); + list[i].enabled = GetPrivateProfileInt("Cheats", buf, 0, fname)==1?true:false; + wsprintf(buf, "Size%04i", i); + list[i].size = GetPrivateProfileInt("Cheats", buf, 0, fname); + for (int t = 0; t < list[i].num; t++) + { + char tmp_buf[10] = { 0 }; + wsprintf(buf, "H%03i%04i", i, t); + GetPrivateProfileString("Cheats", buf, "0", tmp_buf, 10, fname); + sscanf_s(tmp_buf, "%x", &list[i].hi[t]); + wsprintf(buf, "L%03i%04i", i, t); + list[i].lo[t] = GetPrivateProfileInt("Cheats", buf, 0, fname); + } + } +#endif + return true; +} + +bool load_1_3(char *fname) +{ + FILE *fcheat = fopen(fname, "r"); + char buf[4096] = {0}; + int last=0; + + if (fcheat) + { + cheatsClear(); + memset(buf, 0, sizeof(buf)); + + while (!feof(fcheat)) + { + fgets(buf, sizeof(buf), fcheat); + if (buf[0] == ';') continue; + strcpy(buf, trim(buf)); + if (strlen(buf) == 0) continue; + if ( (buf[0] == 'D') && + (buf[1] == 'e') && + (buf[2] == 's') && + (buf[3] == 'c') && + (buf[4] == '=') ) // new cheat block + { + strncpy((char *)list[last].description, (char *)buf+5, strlen(buf)-5); + fgets(buf, sizeof(buf), fcheat); + if ( (buf[0] == 'I') && + (buf[1] == 'n') && + (buf[2] == 'f') && + (buf[3] == 'o') && + (buf[4] == '=') ) // Info cheat + { + u32 dstart = 5; + u32 dsize = 0; + char bf[4] = { 0 }; + + while ( (buf[dstart+dsize] != ',') && (buf[dstart+dsize]!=0)) { dsize++; }; + if (buf[dstart+dsize]==0) continue; // error + strncpy(bf, (char*)buf+dstart, dsize); + list[last].type=atoi(bf); + dstart += (dsize+1); dsize=0; + while ( (buf[dstart+dsize] != ',') && (buf[dstart+dsize]!=0)) { dsize++; }; + if (buf[dstart+dsize]==0) continue; // error + strncpy(bf, (char*)buf+dstart, dsize); + dstart += (dsize+1); dsize=0; + list[last].num=atoi(bf); + while ( (buf[dstart+dsize] != ',') && (buf[dstart+dsize]!=0)) { dsize++; }; + if (buf[dstart+dsize]==0) continue; // error + strncpy(bf, (char*)(buf+dstart), dsize); + dstart += (dsize+1); dsize=0; + list[last].enabled=atoi(bf)==1?true:false; + while ( (buf[dstart+dsize] != ',') && (buf[dstart+dsize]!=0)) { dsize++; }; + strncpy(bf, (char*)buf+dstart, dsize); + list[last].size=atoi(bf); + fgets(buf, sizeof(buf), fcheat); + if ( (buf[0] == 'D') && + (buf[1] == 'a') && + (buf[2] == 't') && + (buf[3] == 'a') && + (buf[4] == '=') ) // Data cheat + { + int offs = 5; + char tmp_buf[9]; + memset(tmp_buf, 0, 9); + + for (int j=0; j