cheats:
- add support R4 encrypted cheats base; cheats (winport): - fix GUI bugs; - add boxcheck in export dialog; - add convert internal cheats to AR; - add select R4 cheats base format (Path Settings); - cheats base file moved to cheat folder (CHEAT.DAT/USRCHEAT.DAT);
This commit is contained in:
parent
10f649e843
commit
13ae3664ab
|
@ -1,4 +1,4 @@
|
|||
/* Copyright 2009-2011 DeSmuME team
|
||||
/* Copyright (C) 2009-2011 DeSmuME team
|
||||
|
||||
This file is part of DeSmuME
|
||||
|
||||
|
@ -127,11 +127,11 @@ void CHEATS::ARparser(CHEATS_LIST& list)
|
|||
//manual hook
|
||||
}
|
||||
else
|
||||
if ((hi==0x0000AA99) && (lo==0))
|
||||
if ((hi==0x0000AA99) && (lo==0)) // 0000AA99 00000000 parameter bytes 9..10 for above code (padded with 00s)
|
||||
{
|
||||
//parameter bytes 9..10 for above code (padded with 00s)
|
||||
}
|
||||
else
|
||||
else // 0XXXXXXX YYYYYYYY word[XXXXXXX+offset] = YYYYYYYY
|
||||
{
|
||||
addr = hi + offset;
|
||||
_MMU_write32<ARMCPU_ARM9,MMU_AT_DEBUG>(addr, lo);
|
||||
|
@ -139,17 +139,17 @@ void CHEATS::ARparser(CHEATS_LIST& list)
|
|||
}
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
case 0x01: // 1XXXXXXX 0000YYYY half[XXXXXXX+offset] = YYYY
|
||||
addr = hi + offset;
|
||||
_MMU_write16<ARMCPU_ARM9,MMU_AT_DEBUG>(addr, lo & 0x0000FFFF);
|
||||
_MMU_write16<ARMCPU_ARM9,MMU_AT_DEBUG>(addr, lo);
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
case 0x02: // 2XXXXXXX 000000YY byte[XXXXXXX+offset] = YY
|
||||
addr = hi + offset;
|
||||
_MMU_write08<ARMCPU_ARM9,MMU_AT_DEBUG>(addr, lo & 0x000000FF);
|
||||
_MMU_write08<ARMCPU_ARM9,MMU_AT_DEBUG>(addr, lo);
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
case 0x03: // 3XXXXXXX YYYYYYYY IF YYYYYYYY > word[XXXXXXX] ;unsigned
|
||||
if (hi == 0) hi = offset; // V1.54+
|
||||
val = _MMU_read32<ARMCPU_ARM9,MMU_AT_DEBUG>(hi);
|
||||
if ( lo > val )
|
||||
|
@ -162,7 +162,11 @@ void CHEATS::ARparser(CHEATS_LIST& list)
|
|||
}
|
||||
break;
|
||||
|
||||
case 0x04:
|
||||
case 0x04: // 4XXXXXXX YYYYYYYY IF YYYYYYYY < word[XXXXXXX] ;unsigned
|
||||
if ((hi == 0x04332211) && (lo == 88776655)) //44332211 88776655 parameter bytes 1..8 for above code (example)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (hi == 0) hi = offset; // V1.54+
|
||||
val = _MMU_read32<ARMCPU_ARM9,MMU_AT_DEBUG>(hi);
|
||||
if ( lo < val )
|
||||
|
@ -175,7 +179,7 @@ void CHEATS::ARparser(CHEATS_LIST& list)
|
|||
}
|
||||
break;
|
||||
|
||||
case 0x05:
|
||||
case 0x05: // 5XXXXXXX YYYYYYYY IF YYYYYYYY = word[XXXXXXX]
|
||||
if (hi == 0) hi = offset; // V1.54+
|
||||
val = _MMU_read32<ARMCPU_ARM9,MMU_AT_DEBUG>(hi);
|
||||
if ( lo == val )
|
||||
|
@ -188,7 +192,7 @@ void CHEATS::ARparser(CHEATS_LIST& list)
|
|||
}
|
||||
break;
|
||||
|
||||
case 0x06:
|
||||
case 0x06: // 6XXXXXXX YYYYYYYY IF YYYYYYYY <> word[XXXXXXX]
|
||||
if (hi == 0) hi = offset; // V1.54+
|
||||
val = _MMU_read32<ARMCPU_ARM9,MMU_AT_DEBUG>(hi);
|
||||
if ( lo != val )
|
||||
|
@ -201,7 +205,7 @@ void CHEATS::ARparser(CHEATS_LIST& list)
|
|||
}
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
case 0x07: // 7XXXXXXX ZZZZYYYY IF YYYY > ((not ZZZZ) AND half[XXXXXXX])
|
||||
if (hi == 0) hi = offset; // V1.54+
|
||||
val = _MMU_read16<ARMCPU_ARM9,MMU_AT_DEBUG>(hi);
|
||||
if ( (lo & 0xFFFF) > ( (~(lo >> 16)) & val) )
|
||||
|
@ -214,7 +218,7 @@ void CHEATS::ARparser(CHEATS_LIST& list)
|
|||
}
|
||||
break;
|
||||
|
||||
case 0x08:
|
||||
case 0x08: // 8XXXXXXX ZZZZYYYY IF YYYY < ((not ZZZZ) AND half[XXXXXXX])
|
||||
if (hi == 0) hi = offset; // V1.54+
|
||||
val = _MMU_read16<ARMCPU_ARM9,MMU_AT_DEBUG>(hi);
|
||||
if ( (lo & 0xFFFF) < ( (~(lo >> 16)) & val) )
|
||||
|
@ -227,7 +231,7 @@ void CHEATS::ARparser(CHEATS_LIST& list)
|
|||
}
|
||||
break;
|
||||
|
||||
case 0x09:
|
||||
case 0x09: // 9XXXXXXX ZZZZYYYY IF YYYY = ((not ZZZZ) AND half[XXXXXXX])
|
||||
if (hi == 0) hi = offset; // V1.54+
|
||||
val = _MMU_read16<ARMCPU_ARM9,MMU_AT_DEBUG>(hi);
|
||||
if ( (lo & 0xFFFF) == ( (~(lo >> 16)) & val) )
|
||||
|
@ -240,7 +244,7 @@ void CHEATS::ARparser(CHEATS_LIST& list)
|
|||
}
|
||||
break;
|
||||
|
||||
case 0x0A:
|
||||
case 0x0A: // AXXXXXXX ZZZZYYYY IF YYYY <> ((not ZZZZ) AND half[XXXXXXX])
|
||||
if (hi == 0) hi = offset; // V1.54+
|
||||
val = _MMU_read16<ARMCPU_ARM9,MMU_AT_DEBUG>(hi);
|
||||
if ( (lo & 0xFFFF) != ( (~(lo >> 16)) & val) )
|
||||
|
@ -253,15 +257,15 @@ void CHEATS::ARparser(CHEATS_LIST& list)
|
|||
}
|
||||
break;
|
||||
|
||||
case 0x0B:
|
||||
case 0x0B: // BXXXXXXX 00000000 offset = word[XXXXXXX+offset]
|
||||
addr = hi + offset;
|
||||
offset = _MMU_read32<ARMCPU_ARM9,MMU_AT_DEBUG>(addr);
|
||||
offset = _MMU_read32<ARMCPU_ARM9,MMU_AT_DEBUG>(addr);;
|
||||
break;
|
||||
|
||||
case 0x0C:
|
||||
switch (subtype)
|
||||
{
|
||||
case 0x0:
|
||||
case 0x0: // C0000000 YYYYYYYY FOR loopcount=0 to YYYYYYYY ;execute Y+1 times
|
||||
if (loopcount < (lo+1))
|
||||
loop_flag = 1;
|
||||
else
|
||||
|
@ -270,10 +274,11 @@ void CHEATS::ARparser(CHEATS_LIST& list)
|
|||
loopbackline = i;
|
||||
break;
|
||||
|
||||
case 0x4:
|
||||
case 0x4: // C4000000 00000000 offset = address of the C4000000 code ; V1.54
|
||||
printf("AR: untested code C4\n");
|
||||
break;
|
||||
|
||||
case 0x5:
|
||||
case 0x5: // C5000000 XXXXYYYY counter=counter+1, IF (counter AND YYYY) = XXXX ; V1.54
|
||||
counter++;
|
||||
if ( (counter & (lo & 0xFFFF)) == ((lo >> 8) & 0xFFFF) )
|
||||
{
|
||||
|
@ -285,8 +290,8 @@ void CHEATS::ARparser(CHEATS_LIST& list)
|
|||
}
|
||||
break;
|
||||
|
||||
case 0x6:
|
||||
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][lo>>20], lo & MMU.MMU_MASK[ARMCPU_ARM9][lo>>20], offset);
|
||||
case 0x6: // C6000000 XXXXXXXX [XXXXXXXX]=offset ; V1.54
|
||||
_MMU_write32<ARMCPU_ARM9,MMU_AT_DEBUG>(lo, offset);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -295,15 +300,15 @@ void CHEATS::ARparser(CHEATS_LIST& list)
|
|||
{
|
||||
switch (subtype)
|
||||
{
|
||||
case 0x0:
|
||||
case 0x0: // D0000000 00000000 ENDIF
|
||||
break;
|
||||
|
||||
case 0x1:
|
||||
case 0x1: // D1000000 00000000 NEXT loopcount
|
||||
if (loop_flag)
|
||||
i = (loopbackline-1);
|
||||
break;
|
||||
|
||||
case 0x2:
|
||||
case 0x2: // D2000000 00000000 NEXT loopcount, and then FLUSH everything
|
||||
if (loop_flag)
|
||||
i = (loopbackline-1);
|
||||
else
|
||||
|
@ -317,59 +322,59 @@ void CHEATS::ARparser(CHEATS_LIST& list)
|
|||
}
|
||||
break;
|
||||
|
||||
case 0x3:
|
||||
case 0x3: // D3000000 XXXXXXXX offset = XXXXXXXX
|
||||
offset = lo;
|
||||
break;
|
||||
|
||||
case 0x4:
|
||||
case 0x4: // D4000000 XXXXXXXX datareg = datareg + XXXXXXXX
|
||||
datareg += lo;
|
||||
break;
|
||||
|
||||
case 0x5:
|
||||
case 0x5: // D5000000 XXXXXXXX datareg = XXXXXXXX
|
||||
datareg = lo;
|
||||
break;
|
||||
|
||||
case 0x6:
|
||||
case 0x6: // D6000000 XXXXXXXX word[XXXXXXXX+offset]=datareg, offset=offset+4
|
||||
addr = lo + offset;
|
||||
_MMU_write32<ARMCPU_ARM9,MMU_AT_DEBUG>(addr, datareg);
|
||||
offset += 4;
|
||||
break;
|
||||
|
||||
case 0x7:
|
||||
case 0x7: // D7000000 XXXXXXXX half[XXXXXXXX+offset]=datareg, offset=offset+2
|
||||
addr = lo + offset;
|
||||
_MMU_write16<ARMCPU_ARM9,MMU_AT_DEBUG>(addr,datareg & 0x0000FFFF);
|
||||
_MMU_write16<ARMCPU_ARM9,MMU_AT_DEBUG>(addr, datareg);
|
||||
offset += 2;
|
||||
break;
|
||||
|
||||
case 0x8:
|
||||
case 0x8: // D8000000 XXXXXXXX byte[XXXXXXXX+offset]=datareg, offset=offset+1
|
||||
addr = lo + offset;
|
||||
_MMU_write08<ARMCPU_ARM9,MMU_AT_DEBUG>(addr,datareg & 0x000000FF);
|
||||
_MMU_write08<ARMCPU_ARM9,MMU_AT_DEBUG>(addr, datareg);
|
||||
offset += 1;
|
||||
break;
|
||||
|
||||
case 0x9:
|
||||
case 0x9: // D9000000 XXXXXXXX datareg = word[XXXXXXXX+offset]
|
||||
addr = lo + offset;
|
||||
datareg = _MMU_read32<ARMCPU_ARM9,MMU_AT_DEBUG>(addr);
|
||||
break;
|
||||
|
||||
case 0xA:
|
||||
case 0xA: // DA000000 XXXXXXXX datareg = half[XXXXXXXX+offset]
|
||||
addr = lo + offset;
|
||||
datareg = _MMU_read16<ARMCPU_ARM9,MMU_AT_DEBUG>(addr);
|
||||
break;
|
||||
|
||||
case 0xB:
|
||||
case 0xB: // DB000000 XXXXXXXX datareg = byte[XXXXXXXX+offset] ;bugged on pre-v1.54
|
||||
addr = lo + offset;
|
||||
datareg = _MMU_read08<ARMCPU_ARM9,MMU_AT_DEBUG>(addr);
|
||||
break;
|
||||
|
||||
case 0xC:
|
||||
case 0xC: // DC000000 XXXXXXXX offset = offset + XXXXXXXX
|
||||
offset += lo;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xE:
|
||||
case 0xE: // EXXXXXXX YYYYYYYY Copy YYYYYYYY parameter bytes to [XXXXXXXX+offset...]
|
||||
{
|
||||
u8 *tmp_code = (u8*)(list.code[i+1]);
|
||||
u32 addr = hi+offset;
|
||||
|
@ -384,14 +389,14 @@ void CHEATS::ARparser(CHEATS_LIST& list)
|
|||
}
|
||||
break;
|
||||
|
||||
case 0xF:
|
||||
case 0xF: // FXXXXXXX YYYYYYYY Copy YYYYYYYY bytes from [offset..] to [XXXXXXX...]
|
||||
for (u32 t = 0; t < lo; t++)
|
||||
{
|
||||
u8 tmp = _MMU_read08<ARMCPU_ARM9,MMU_AT_DEBUG>(offset+t);
|
||||
_MMU_write08<ARMCPU_ARM9,MMU_AT_DEBUG>(hi+t, tmp);
|
||||
}
|
||||
break;
|
||||
//default: INFO("AR: ERROR uknown command 0x%2X at %08X:%08X\n", type, hi, lo); break;
|
||||
default: PROGINFO("AR: ERROR uknown command 0x%2X at %08X:%08X\n", type, hi, lo); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -727,7 +732,7 @@ void CHEATS::process()
|
|||
|
||||
switch (list[i].type)
|
||||
{
|
||||
case 0: // internal list system
|
||||
case 0: // internal cheat system
|
||||
{
|
||||
//INFO("list at 0x02|%06X value %i (size %i)\n",list[i].code[0], list[i].lo[0], list[i].size);
|
||||
u32 addr = list[i].code[0][0] | 0x02000000;
|
||||
|
@ -753,7 +758,7 @@ void CHEATS::process()
|
|||
break;
|
||||
}
|
||||
break;
|
||||
} //end case 0 internal list system
|
||||
} //end case 0 internal cheat system
|
||||
|
||||
case 1: // Action Replay
|
||||
ARparser(list[i]);
|
||||
|
@ -1066,28 +1071,97 @@ void CHEATSEARCH::getListReset()
|
|||
}
|
||||
|
||||
// ========================================================================= Export
|
||||
void CHEATSEXPORT::R4decrypt(u8 *buf, u32 len, u32 n)
|
||||
{
|
||||
size_t r = 0;
|
||||
while (r < len)
|
||||
{
|
||||
size_t i ;
|
||||
u16 key = n ^ 0x484A;
|
||||
for (i = 0 ; i < 512 && i < len - r ; i ++)
|
||||
{
|
||||
u8 _xor = 0;
|
||||
if (key & 0x4000) _xor |= 0x80;
|
||||
if (key & 0x1000) _xor |= 0x40;
|
||||
if (key & 0x0800) _xor |= 0x20;
|
||||
if (key & 0x0200) _xor |= 0x10;
|
||||
if (key & 0x0080) _xor |= 0x08;
|
||||
if (key & 0x0040) _xor |= 0x04;
|
||||
if (key & 0x0002) _xor |= 0x02;
|
||||
if (key & 0x0001) _xor |= 0x01;
|
||||
|
||||
u32 k = ((buf[i] << 8) ^ key) << 16;
|
||||
u32 x = k;
|
||||
for (u8 j = 1; j < 32; j ++)
|
||||
x ^= k >> j;
|
||||
key = 0x0000;
|
||||
if (BIT_N(x, 23)) key |= 0x8000;
|
||||
if (BIT_N(k, 22)) key |= 0x4000;
|
||||
if (BIT_N(k, 21)) key |= 0x2000;
|
||||
if (BIT_N(k, 20)) key |= 0x1000;
|
||||
if (BIT_N(k, 19)) key |= 0x0800;
|
||||
if (BIT_N(k, 18)) key |= 0x0400;
|
||||
if (BIT_N(k, 17) != BIT_N(x, 31)) key |= 0x0200;
|
||||
if (BIT_N(k, 16) != BIT_N(x, 30)) key |= 0x0100;
|
||||
if (BIT_N(k, 30) != BIT_N(k, 29)) key |= 0x0080;
|
||||
if (BIT_N(k, 29) != BIT_N(k, 28)) key |= 0x0040;
|
||||
if (BIT_N(k, 28) != BIT_N(k, 27)) key |= 0x0020;
|
||||
if (BIT_N(k, 27) != BIT_N(k, 26)) key |= 0x0010;
|
||||
if (BIT_N(k, 26) != BIT_N(k, 25)) key |= 0x0008;
|
||||
if (BIT_N(k, 25) != BIT_N(k, 24)) key |= 0x0004;
|
||||
if (BIT_N(k, 25) != BIT_N(x, 26)) key |= 0x0002;
|
||||
if (BIT_N(k, 24) != BIT_N(x, 25)) key |= 0x0001;
|
||||
buf[i] ^= _xor;
|
||||
}
|
||||
|
||||
buf+= 512;
|
||||
r += 512;
|
||||
n += 1;
|
||||
}
|
||||
}
|
||||
|
||||
bool CHEATSEXPORT::load(char *path)
|
||||
{
|
||||
error = 0;
|
||||
|
||||
fp = fopen(path, "rb");
|
||||
if (!fp)
|
||||
{
|
||||
printf("Error open database\n");
|
||||
error = 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
char *headerID = "R4 CheatCode";
|
||||
char buf[255] = {0};
|
||||
fread(buf, 1, strlen(headerID), fp);
|
||||
if (strncmp(buf, headerID, strlen(headerID)) != 0)
|
||||
{
|
||||
// check encrypted
|
||||
R4decrypt((u8 *)buf, strlen(headerID), 0);
|
||||
if (strcmp(buf, headerID) != 0)
|
||||
{
|
||||
error = 2;
|
||||
return false;
|
||||
}
|
||||
encrypted = true;
|
||||
}
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
fsize = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
if (!search())
|
||||
{
|
||||
printf("ERROR: cheat in database not founded\n");
|
||||
printf("ERROR: cheat in database not found\n");
|
||||
error = 3;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!getCodes())
|
||||
{
|
||||
printf("ERROR: export cheats failed\n");
|
||||
error = 4;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1104,43 +1178,71 @@ void CHEATSEXPORT::close()
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: decrypting database
|
||||
bool CHEATSEXPORT::search()
|
||||
{
|
||||
if (!fp) return false;
|
||||
|
||||
u32 pos = 0x0100;
|
||||
FAT_R4 fat_empty;
|
||||
FAT_R4 fat_tmp = {0};
|
||||
u8 buf[512] = {0};
|
||||
|
||||
memset(&fat, 0, sizeof(FAT_R4));
|
||||
memset(&fat_empty, 0, sizeof(FAT_R4));
|
||||
|
||||
fseek(fp, pos, SEEK_SET);
|
||||
while (pos < fsize)
|
||||
CRC = 0;
|
||||
encOffset = 0;
|
||||
u32 t = 0;
|
||||
memset(date, 0, sizeof(date));
|
||||
if (encrypted)
|
||||
{
|
||||
fread(&fat, sizeof(FAT_R4), 1, fp);
|
||||
if (memcmp(&fat, &fat_empty, sizeof(FAT_R4)) == 0) break;
|
||||
if (memcmp(gameInfo.header.gameCode, &fat.serial[0], 4) == 0)
|
||||
{
|
||||
FAT_R4 fat_tmp;
|
||||
|
||||
memset(&fat_tmp, 0, sizeof(FAT_R4));
|
||||
fread(&fat_tmp, sizeof(FAT_R4), 1, fp);
|
||||
if (memcmp(&fat_tmp, &fat_empty, sizeof(FAT_R4)) == 0)
|
||||
{
|
||||
// TODO
|
||||
dataSize = 0;
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
fread(&buf[0], 1, 512, fp);
|
||||
R4decrypt((u8 *)&buf[0], 512, 0);
|
||||
memcpy(&date[0], &buf[0x10], 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
dataSize = (fat_tmp.addr - fat.addr);
|
||||
fseek(fp, 0x10, SEEK_SET);
|
||||
fread(&date, 16, 1, fp);
|
||||
fseek(fp, pos, SEEK_SET);
|
||||
fread(&fat_tmp, sizeof(fat), 1, fp);
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (encrypted)
|
||||
{
|
||||
memcpy(&fat, &buf[pos % 512], sizeof(fat));
|
||||
pos += sizeof(fat);
|
||||
if ((pos>>9) > t)
|
||||
{
|
||||
t++;
|
||||
fread(&buf[0], 1, 512, fp);
|
||||
R4decrypt((u8 *)&buf[0], 512, t);
|
||||
}
|
||||
memcpy(&fat_tmp, &buf[pos % 512], sizeof(fat_tmp)); // next
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&fat, &fat_tmp, sizeof(fat));
|
||||
fread(&fat_tmp, sizeof(fat_tmp), 1, fp);
|
||||
|
||||
}
|
||||
//printf("serial: %s, offset %08X\n", fat.serial, fat.addr);
|
||||
if (memcmp(gameInfo.header.gameCode, &fat.serial[0], 4) == 0)
|
||||
{
|
||||
dataSize = fat_tmp.addr?(fat_tmp.addr - fat.addr):0;
|
||||
if (encrypted)
|
||||
{
|
||||
encOffset = fat.addr % 512;
|
||||
dataSize += encOffset;
|
||||
}
|
||||
if (!dataSize) return false;
|
||||
CRC = fat.CRC;
|
||||
char buf[5] = {0};
|
||||
memcpy(&buf, &fat.serial[0], 4);
|
||||
printf("Found %s CRC %08X at 0x%08llX (size %i)\n", buf, fat.CRC, fat.addr, dataSize);
|
||||
printf("Cheats: found %s CRC %08X at 0x%08llX, size %i byte(s)\n", buf, fat.CRC, fat.addr, dataSize - encOffset);
|
||||
return true;
|
||||
}
|
||||
pos += sizeof(FAT_R4);
|
||||
|
||||
if (fat.addr == 0) break;
|
||||
}
|
||||
|
||||
memset(&fat, 0, sizeof(FAT_R4));
|
||||
|
@ -1158,7 +1260,7 @@ bool CHEATSEXPORT::getCodes()
|
|||
if (!data) return false;
|
||||
memset(data, 0, dataSize+8);
|
||||
|
||||
fseek(fp, fat.addr, SEEK_SET);
|
||||
fseek(fp, fat.addr - encOffset, SEEK_SET);
|
||||
|
||||
if (fread(data, 1, dataSize, fp) != dataSize)
|
||||
{
|
||||
|
@ -1167,8 +1269,11 @@ bool CHEATSEXPORT::getCodes()
|
|||
return false;
|
||||
}
|
||||
|
||||
u8 *title = data;
|
||||
u32 *cmd = (u32 *)(((intptr_t)title + strlen((char*)title) + 4) & 0xFFFFFFFC);
|
||||
if (encrypted)
|
||||
R4decrypt(data, dataSize, fat.addr >> 9);
|
||||
|
||||
gametitle = data + encOffset;
|
||||
u32 *cmd = (u32 *)(((intptr_t)gametitle + strlen((char*)gametitle) + 4) & 0xFFFFFFFC);
|
||||
numCheats = (*cmd) & (~0xF0000000);
|
||||
cmd += 9;
|
||||
cheats = new CHEATS_LIST[numCheats];
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2009-2010 DeSmuME team
|
||||
/* Copyright (C) 2009-2011 DeSmuME team
|
||||
|
||||
This file is part of DeSmuME
|
||||
|
||||
|
@ -37,6 +37,10 @@ struct CHEATS_LIST
|
|||
// 1 - Action Replay
|
||||
// 2 - Codebreakers
|
||||
BOOL enabled;
|
||||
// TODO
|
||||
u8 freezeType; // 0 - normal freeze
|
||||
// 1 - can decrease
|
||||
// 2 - can increase
|
||||
u32 code[MAX_XX_CODE][2];
|
||||
char description[255];
|
||||
int num;
|
||||
|
@ -127,32 +131,51 @@ class CHEATSEXPORT
|
|||
{
|
||||
private:
|
||||
CHEATS_DB_TYPE type;
|
||||
bool encrypted;
|
||||
FILE *fp;
|
||||
u32 fsize;
|
||||
u32 dataSize;
|
||||
u32 encOffset;
|
||||
FAT_R4 fat;
|
||||
bool search();
|
||||
bool getCodes();
|
||||
void R4decrypt(u8 *buf, u32 len, u32 n);
|
||||
|
||||
u32 numCheats;
|
||||
CHEATS_LIST *cheats;
|
||||
|
||||
u8 error; // 0 - no errors
|
||||
// 1 - open failed/file not found
|
||||
// 2 - file format is wrong (no valid header ID)
|
||||
// 3 - cheat not found in database
|
||||
// 4 - export error from database
|
||||
|
||||
public:
|
||||
CHEATSEXPORT() :
|
||||
fp(NULL),
|
||||
fsize(0),
|
||||
dataSize(0),
|
||||
encOffset(0),
|
||||
type(CHEATS_DB_R4),
|
||||
encrypted(false),
|
||||
numCheats(0),
|
||||
cheats(0)
|
||||
{}
|
||||
cheats(0),
|
||||
CRC(0),
|
||||
error(0)
|
||||
{
|
||||
memset(date, 0, sizeof(date));
|
||||
}
|
||||
~CHEATSEXPORT()
|
||||
{}
|
||||
|
||||
u8 *gametitle;
|
||||
u8 date[17];
|
||||
u32 CRC;
|
||||
bool load(char *path);
|
||||
void close();
|
||||
CHEATS_LIST *getCheats();
|
||||
u32 getCheatsNum();
|
||||
u8 getErrorCode() { return error; }
|
||||
};
|
||||
|
||||
extern CHEATS *cheats;
|
||||
|
|
|
@ -95,6 +95,7 @@ public:
|
|||
#define SCREENSHOTKEY "Screenshots"
|
||||
#define AVIKEY "AviFiles"
|
||||
#define CHEATKEY "Cheats"
|
||||
#define R4FORMATKEY "R4format"
|
||||
#define SOUNDKEY "SoundSamples"
|
||||
#define FIRMWAREKEY "Firmware"
|
||||
#define FORMATKEY "format"
|
||||
|
@ -221,6 +222,7 @@ public:
|
|||
GetPrivateProfileString(SECTION, FORMATKEY, "%f_%s_%r", screenshotFormat, MAX_FORMAT, IniName);
|
||||
savelastromvisit = GetPrivateProfileBool(SECTION, LASTVISITKEY, true, IniName);
|
||||
currentimageformat = (ImageFormat)GetPrivateProfileInt(SECTION, DEFAULTFORMATKEY, PNG, IniName);
|
||||
r4Format = (R4Format)GetPrivateProfileInt(SECTION, R4FORMATKEY, R4_CHEAT_DAT, IniName);
|
||||
#endif
|
||||
/*
|
||||
needsSaving = GetPrivateProfileInt(SECTION, NEEDSSAVINGKEY, TRUE, IniName);
|
||||
|
@ -412,6 +414,18 @@ public:
|
|||
strncpy(output, file.c_str(), MAX_PATH);
|
||||
}
|
||||
|
||||
enum R4Format
|
||||
{
|
||||
#if defined(_WINDOWS) && !defined(WXPORT)
|
||||
R4_CHEAT_DAT = IDC_R4TYPE1,
|
||||
R4_USRCHEAT_DAT = IDC_R4TYPE2
|
||||
#else
|
||||
R4_CHEAT_DAT,
|
||||
R4_USRCHEAT_DAT
|
||||
#endif
|
||||
};
|
||||
R4Format r4Format;
|
||||
|
||||
enum ImageFormat
|
||||
{
|
||||
#if defined(_WINDOWS) && !defined(WXPORT)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright 2009-2010 DeSmuME team
|
||||
/* Copyright (C) 2009-2011 DeSmuME team
|
||||
|
||||
This file is part of DeSmuME
|
||||
|
||||
|
@ -24,7 +24,13 @@
|
|||
#include "../debug.h"
|
||||
#include "../utils/xstring.h"
|
||||
#include "../path.h"
|
||||
#include "../NDSSystem.h"
|
||||
#include "../version.h"
|
||||
|
||||
extern u8 CheatsR4Type = 0;
|
||||
|
||||
static const char *HEX_Valid = "Oo0123456789ABCDEFabcdef";
|
||||
static const char *DEC_Valid = "Oo0123456789";
|
||||
static u8 searchType = 0;
|
||||
static u8 searchSize = 0;
|
||||
static u8 searchSign = 0;
|
||||
|
@ -80,7 +86,16 @@ u32 searchRange[4][2] = {
|
|||
|
||||
//========================================= Export
|
||||
static CHEATSEXPORT *cheatsExport = NULL;
|
||||
void CheatsExportDialog(HWND hwnd);
|
||||
bool CheatsExportDialog(HWND hwnd);
|
||||
|
||||
void generateAR(HWND dialog, u32 addr, u32 val, u8 size)
|
||||
{
|
||||
// Action Replay code generate
|
||||
if (size > 3) size = 3;
|
||||
char buf[17] = {0};
|
||||
sprintf(buf, "%X%07X %08X", 3-size, addr | 0x02000000, val);
|
||||
SetWindowText(GetDlgItem(dialog, IDC_AR_CODE), buf);
|
||||
}
|
||||
|
||||
LONG_PTR CALLBACK EditValueProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
|
@ -88,21 +103,6 @@ LONG_PTR CALLBACK EditValueProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
|
|||
{
|
||||
switch (wParam)
|
||||
{
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
break;
|
||||
case 'o':
|
||||
case 'O':
|
||||
wParam = '0';
|
||||
break;
|
||||
case '-':
|
||||
{
|
||||
u32 pos = 0;
|
||||
|
@ -120,6 +120,11 @@ LONG_PTR CALLBACK EditValueProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
|
|||
cheatAddPasteCheck = true;
|
||||
break;
|
||||
default:
|
||||
if (strchr(DEC_Valid, wParam))
|
||||
{
|
||||
if(wParam=='o' || wParam=='O') wParam='0';
|
||||
break;
|
||||
}
|
||||
wParam = 0;
|
||||
break;
|
||||
}
|
||||
|
@ -135,35 +140,6 @@ LONG_PTR CALLBACK EditValueHEXProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP
|
|||
{
|
||||
switch (wParam)
|
||||
{
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case 'A':
|
||||
case 'B':
|
||||
case 'C':
|
||||
case 'D':
|
||||
case 'E':
|
||||
case 'F':
|
||||
break;
|
||||
case 'a':
|
||||
case 'b':
|
||||
case 'c':
|
||||
case 'd':
|
||||
case 'e':
|
||||
case 'f':
|
||||
wParam -= 32;
|
||||
break;
|
||||
case 'o':
|
||||
case 'O':
|
||||
wParam = '0';
|
||||
break;
|
||||
case VK_BACK:
|
||||
case 0x3: // ^C
|
||||
case 0x18: // ^X
|
||||
|
@ -173,6 +149,11 @@ LONG_PTR CALLBACK EditValueHEXProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP
|
|||
cheatAddPasteCheck = true;
|
||||
break;
|
||||
default:
|
||||
if (strchr(HEX_Valid, wParam))
|
||||
{
|
||||
if(wParam=='o' || wParam=='O') wParam='0';
|
||||
break;
|
||||
}
|
||||
wParam = 0;
|
||||
break;
|
||||
}
|
||||
|
@ -190,6 +171,8 @@ INT_PTR CALLBACK CheatsAddProc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lparam
|
|||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
memset(editBuf, 0, sizeof(editBuf));
|
||||
memset(&tempCheat, 0, sizeof(tempCheat));
|
||||
saveOldEditProc = oldEditProc;
|
||||
SendMessage(GetDlgItem(dialog, IDC_EDIT1), EM_SETLIMITTEXT, 6, 0);
|
||||
SendMessage(GetDlgItem(dialog, IDC_EDIT2), EM_SETLIMITTEXT, 11, 0);
|
||||
|
@ -241,6 +224,8 @@ INT_PTR CALLBACK CheatsAddProc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lparam
|
|||
SetFocus(GetDlgItem(dialog, IDC_EDIT2));
|
||||
SendMessage(GetDlgItem(dialog, IDC_EDIT2), EM_SETSEL, 0, -1);
|
||||
}
|
||||
|
||||
CheatAddVerify(dialog,editBuf[0],editBuf[1],searchAddSize);
|
||||
}
|
||||
return searchAddMode != 2;
|
||||
|
||||
|
@ -380,6 +365,8 @@ INT_PTR CALLBACK CheatsEditProc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lpara
|
|||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
memset(editBuf, 0, sizeof(editBuf));
|
||||
memset(&tempCheat, 0, sizeof(tempCheat));
|
||||
saveOldEditProc = oldEditProc;
|
||||
SendMessage(GetDlgItem(dialog, IDC_EDIT1), EM_SETLIMITTEXT, 6, 0);
|
||||
SendMessage(GetDlgItem(dialog, IDC_EDIT2), EM_SETLIMITTEXT, 10, 0);
|
||||
|
@ -406,6 +393,8 @@ INT_PTR CALLBACK CheatsEditProc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lpara
|
|||
CheckDlgButton(dialog, IDC_CHECK1, tempCheat.enabled?BST_CHECKED:BST_UNCHECKED);
|
||||
CheckRadioButton(dialog, searchSizeIDDs[0], searchSizeIDDs[ARRAY_SIZE(searchSizeIDDs) - 1], searchSizeIDDs[tempCheat.size]);
|
||||
SetWindowText(GetDlgItem(dialog, IDOK), "Update");
|
||||
|
||||
generateAR(dialog, tempCheat.code[0][0], tempCheat.code[0][1], searchSizeIDDs[tempCheat.size]);
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
|
@ -519,12 +508,14 @@ INT_PTR CALLBACK CheatsAdd_XX_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lp
|
|||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
memset(editBuf, 0, sizeof(editBuf));
|
||||
SendMessage(GetDlgItem(dialog, IDC_EDIT2), EM_FMTLINES, (WPARAM)TRUE, (LPARAM)0);
|
||||
|
||||
if (cheatXXtype == 0)
|
||||
{
|
||||
if (cheatXXaction == 0) // add
|
||||
{
|
||||
memset(&tempCheat, 0, sizeof(tempCheat));
|
||||
SetWindowText(dialog, "Add Action Replay code");
|
||||
tempCheat.enabled = TRUE;
|
||||
}
|
||||
|
@ -537,6 +528,7 @@ INT_PTR CALLBACK CheatsAdd_XX_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lp
|
|||
{
|
||||
if (cheatXXaction == 0) // add
|
||||
{
|
||||
memset(&tempCheat, 0, sizeof(tempCheat));
|
||||
SetWindowText(dialog, "Add Codebreaker code");
|
||||
tempCheat.enabled = TRUE;
|
||||
}
|
||||
|
@ -669,23 +661,23 @@ INT_PTR CALLBACK CheatsListBox_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM l
|
|||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
// TODO: Codebreaker
|
||||
ShowWindow(GetDlgItem(dialog, IDC_BADD_CB), SW_HIDE);// hide button
|
||||
|
||||
LV_COLUMN lvColumn;
|
||||
u32 address = 0;
|
||||
u32 val = 0;
|
||||
|
||||
cheatListView = GetDlgItem(dialog, IDC_LIST1);
|
||||
|
||||
//ListView_SetExtendedListViewStyle(GetDlgItem(hDlg, IDC_CHEAT_LIST), LVS_EX_FULLROWSELECT|LVS_EX_CHECKBOXES);
|
||||
ListView_SetExtendedListViewStyle(cheatListView, LVS_EX_FULLROWSELECT | LVS_EX_TWOCLICKACTIVATE | LVS_EX_CHECKBOXES);
|
||||
|
||||
memset(&lvColumn,0,sizeof(LV_COLUMN));
|
||||
lvColumn.mask=LVCF_FMT|LVCF_WIDTH|LVCF_TEXT;
|
||||
|
||||
lvColumn.fmt=LVCFMT_CENTER;
|
||||
lvColumn.cx=20;
|
||||
lvColumn.pszText="";
|
||||
ListView_InsertColumn(cheatListView, 0, &lvColumn);
|
||||
|
||||
lvColumn.fmt=LVCFMT_LEFT;
|
||||
lvColumn.cx=84;
|
||||
lvColumn.pszText="Address";
|
||||
|
@ -748,8 +740,8 @@ INT_PTR CALLBACK CheatsListBox_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM l
|
|||
|
||||
EnableWindow(GetDlgItem(dialog, IDOK), FALSE);
|
||||
|
||||
ListView_SetItemState(searchListView,0, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
|
||||
SetFocus(searchListView);
|
||||
ListView_SetItemState(cheatListView,0, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
|
||||
SetFocus(cheatListView);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -759,6 +751,10 @@ INT_PTR CALLBACK CheatsListBox_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM l
|
|||
LPNMHDR tmp_msg = (LPNMHDR)lparam;
|
||||
switch (tmp_msg->code)
|
||||
{
|
||||
case LVN_ITEMACTIVATE:
|
||||
SendMessage(dialog, WM_COMMAND, IDC_BEDIT, 0);
|
||||
break;
|
||||
|
||||
case LVN_ITEMCHANGED:
|
||||
{
|
||||
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)lparam;
|
||||
|
@ -813,9 +809,7 @@ INT_PTR CALLBACK CheatsListBox_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM l
|
|||
{
|
||||
case IDOK:
|
||||
if (cheats->save())
|
||||
{
|
||||
EndDialog(dialog, TRUE);
|
||||
}
|
||||
else
|
||||
MessageBox(dialog, "Can't save cheats to file.\nCheck your path (Menu->Config->Path Settings->\"Cheats\")","Error",MB_OK);
|
||||
return TRUE;
|
||||
|
@ -845,7 +839,6 @@ INT_PTR CALLBACK CheatsListBox_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM l
|
|||
ListView_SetItemText(cheatListView, row, 2, buf);
|
||||
ListView_SetItemText(cheatListView, row, 3, editBuf[2]);
|
||||
ListView_SetCheckState(cheatListView, row, searchAddFreeze);
|
||||
|
||||
EnableWindow(GetDlgItem(dialog, IDOK), TRUE);
|
||||
}
|
||||
}
|
||||
|
@ -854,14 +847,10 @@ INT_PTR CALLBACK CheatsListBox_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM l
|
|||
case IDC_BADD_AR:
|
||||
{
|
||||
if (LOWORD(wparam) == IDC_BADD_AR)
|
||||
{
|
||||
cheatXXtype = 0;
|
||||
}
|
||||
else
|
||||
if (LOWORD(wparam) == IDC_BADD_CB)
|
||||
{
|
||||
cheatXXtype = 1;
|
||||
}
|
||||
else
|
||||
return TRUE;
|
||||
cheatXXaction = 0; // 0 = add
|
||||
|
@ -899,7 +888,6 @@ INT_PTR CALLBACK CheatsListBox_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM l
|
|||
if (cheatEditPos > cheats->getSize()) return TRUE;
|
||||
|
||||
cheats->get(&tempCheat, cheatEditPos);
|
||||
|
||||
switch (tempCheat.type)
|
||||
{
|
||||
case 0: // internal
|
||||
|
@ -955,20 +943,18 @@ INT_PTR CALLBACK CheatsListBox_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM l
|
|||
{
|
||||
int tmp_pos = ListView_GetNextItem(cheatListView, -1, LVNI_ALL | LVNI_SELECTED);
|
||||
if (tmp_pos == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (cheats->remove(tmp_pos))
|
||||
{
|
||||
ListView_DeleteItem(cheatListView, tmp_pos);
|
||||
}
|
||||
}
|
||||
EnableWindow(GetDlgItem(dialog, IDOK), TRUE);
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
case IDC_EXPORT:
|
||||
CheatsExportDialog(dialog);
|
||||
if (CheatsExportDialog(dialog))
|
||||
EnableWindow(GetDlgItem(dialog, IDOK), TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
|
@ -1039,7 +1025,7 @@ INT_PTR CALLBACK CheatsSearchExactWnd(HWND dialog, UINT msg,WPARAM wparam,LPARAM
|
|||
ltoa(searchNumberResults, buf, 10);
|
||||
SetWindowText(GetDlgItem(dialog, IDC_SNUMBER), buf);
|
||||
SetFocus(GetDlgItem(dialog, IDC_EVALUE));
|
||||
break;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
case WM_COMMAND:
|
||||
|
@ -1382,6 +1368,8 @@ void CheatAddVerify(HWND dialog,char* addre, char* valu,u8 size)
|
|||
}
|
||||
else
|
||||
EnableWindow(GetDlgItem(dialog, IDOK), TRUE);
|
||||
|
||||
generateAR(dialog, fix, fix2, size);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1392,9 +1380,18 @@ INT_PTR CALLBACK CheatsExportProc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lpa
|
|||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
SetWindowText(GetDlgItem(dialog, IDC_CDATE), (LPCSTR)cheatsExport->date);
|
||||
if ((char*)cheatsExport->gametitle != "")
|
||||
{
|
||||
char buf[512] = {0};
|
||||
GetWindowText(dialog, &buf[0], sizeof(buf));
|
||||
strcat(buf, ": ");
|
||||
strcat(buf, (char*)cheatsExport->gametitle);
|
||||
SetWindowText(dialog, (LPCSTR)buf);
|
||||
}
|
||||
LV_COLUMN lvColumn;
|
||||
exportListView = GetDlgItem(dialog, IDC_LIST_CHEATS);
|
||||
ListView_SetExtendedListViewStyle(exportListView, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
|
||||
ListView_SetExtendedListViewStyle(exportListView, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_CHECKBOXES);
|
||||
|
||||
memset(&lvColumn,0,sizeof(LV_COLUMN));
|
||||
lvColumn.mask=LVCF_FMT|LVCF_TEXT|LVCF_WIDTH;
|
||||
|
@ -1415,6 +1412,10 @@ INT_PTR CALLBACK CheatsExportProc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lpa
|
|||
lvi.pszText= tmp[i].description;
|
||||
SendMessage(exportListView, LVM_INSERTITEM, 0, (LPARAM)&lvi);
|
||||
}
|
||||
if (gameInfo.crc != cheatsExport->CRC)
|
||||
{
|
||||
//MessageBox(dialog, "WARNING!\n Checksums not matching.",EMU_DESMUME_NAME_AND_VERSION(), MB_OK);// | MB_ICON_ERROR);
|
||||
}
|
||||
SendMessage(exportListView, WM_SETREDRAW, (WPARAM)TRUE,0);
|
||||
ListView_SetItemState(exportListView,0, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
|
||||
SetFocus(exportListView);
|
||||
|
@ -1426,14 +1427,15 @@ INT_PTR CALLBACK CheatsExportProc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lpa
|
|||
{
|
||||
case IDOK:
|
||||
{
|
||||
u32 count = ListView_GetSelectedCount(exportListView);
|
||||
u32 count = ListView_GetItemCount(exportListView);
|
||||
if (count > 0)
|
||||
{
|
||||
u32 prev = ListView_GetNextItem(exportListView, -1, LVIS_SELECTED);
|
||||
bool done = false;
|
||||
CHEATS_LIST *tmp = (CHEATS_LIST*)cheatsExport->getCheats();
|
||||
for (u32 i = 0; i < count; i++)
|
||||
{
|
||||
CHEATS_LIST *tmp = (CHEATS_LIST*)cheatsExport->getCheats();
|
||||
cheats->add_AR_Direct(tmp[prev]);
|
||||
if (!ListView_GetCheckState(exportListView, i)) continue;
|
||||
cheats->add_AR_Direct(tmp[i]);
|
||||
|
||||
LVITEM lvi;
|
||||
|
||||
|
@ -1444,11 +1446,10 @@ INT_PTR CALLBACK CheatsExportProc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lpa
|
|||
u32 row = ListView_InsertItem(cheatListView, &lvi);
|
||||
ListView_SetItemText(cheatListView, row, 1, "Action");
|
||||
ListView_SetItemText(cheatListView, row, 2, "Replay");
|
||||
ListView_SetItemText(cheatListView, row, 3, tmp[prev].description);
|
||||
|
||||
prev = ListView_GetNextItem(exportListView, prev, LVIS_SELECTED);
|
||||
ListView_SetItemText(cheatListView, row, 3, tmp[i].description);
|
||||
done = true;
|
||||
}
|
||||
EndDialog(dialog, TRUE);
|
||||
if (done) EndDialog(dialog, TRUE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1463,32 +1464,50 @@ INT_PTR CALLBACK CheatsExportProc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lpa
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
void CheatsExportDialog(HWND hwnd)
|
||||
bool CheatsExportDialog(HWND hwnd)
|
||||
{
|
||||
bool res = false;
|
||||
cheatsExport = new CHEATSEXPORT();
|
||||
if (!cheatsExport) return;
|
||||
if (!cheatsExport) return false;
|
||||
|
||||
char buf[MAX_PATH] = {0};
|
||||
PathInfo path;
|
||||
path.init("USRCHEAT.DAT");
|
||||
path.getpathnoext(path.MODULE, &buf[0]);
|
||||
strcat(buf, ".DAT");
|
||||
// TODO: select file
|
||||
strcpy(buf, path.getpath(path.CHEATS).c_str());
|
||||
if (path.r4Format == path.R4_CHEAT_DAT)
|
||||
strcat(buf,"cheat.dat");
|
||||
else
|
||||
if (path.r4Format == path.R4_USRCHEAT_DAT)
|
||||
strcat(buf,"usrcheat.dat");
|
||||
else return false;
|
||||
if (cheatsExport->load(buf))
|
||||
{
|
||||
if (cheatsExport->getCheatsNum() > 0)
|
||||
{
|
||||
DialogBoxW(hAppInst, MAKEINTRESOURCEW(IDD_CHEAT_EXPORT), hwnd, (DLGPROC) CheatsExportProc);
|
||||
}
|
||||
res = DialogBoxW(hAppInst, MAKEINTRESOURCEW(IDD_CHEAT_EXPORT), hwnd, (DLGPROC) CheatsExportProc);
|
||||
else
|
||||
{
|
||||
MessageBox(hwnd, "Cheats for this game in database not founded.", "DeSmuME", MB_OK | MB_ICONERROR);
|
||||
}
|
||||
}
|
||||
else
|
||||
MessageBox(hwnd, "Error loading cheat database.", "DeSmuME", MB_OK | MB_ICONERROR);
|
||||
{
|
||||
char buf2[512] = {0};
|
||||
if (cheatsExport->getErrorCode() == 1)
|
||||
sprintf(buf2, "Error loading cheats database. File not found\n\"%s\"\nCheck your path (Menu->Config->Path Settings->\"Cheats\")\n\nYou can download it from http://cheats.gbatemp.net/", buf);
|
||||
else
|
||||
if (cheatsExport->getErrorCode() == 2)
|
||||
sprintf(buf2, "File \"%s\" is not R4 cheats database.\nWrong file format!", buf);
|
||||
else
|
||||
if (cheatsExport->getErrorCode() == 3)
|
||||
sprintf(buf2, "Serial \"%s\" not found in database.", gameInfo.ROMserial);
|
||||
else
|
||||
if (cheatsExport->getErrorCode() == 4)
|
||||
sprintf(buf2, "Error export from database");
|
||||
else
|
||||
sprintf(buf2, "Unknown error!!!");
|
||||
MessageBox(hwnd, buf2, "DeSmuME", MB_OK | MB_ICONERROR);
|
||||
}
|
||||
|
||||
cheatsExport->close();
|
||||
delete cheatsExport;
|
||||
cheatsExport = NULL;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright 2009 DeSmuME team
|
||||
/* Copyright (C) 2009-2011 DeSmuME team
|
||||
|
||||
This file is part of DeSmuME
|
||||
|
||||
|
|
|
@ -389,12 +389,16 @@
|
|||
#define IDC_EXPORT 1038
|
||||
#define IDC_RFOLDER 1039
|
||||
#define IDC_2012 1039
|
||||
#define IDC_EXPORT2 1039
|
||||
#define IDC_BBROWSE2 1040
|
||||
#define IDC_PATHDESMUME 1041
|
||||
#define IDC_CDATE 1041
|
||||
#define IDC_BRESTART 1042
|
||||
#define IDC_BVIEW 1043
|
||||
#define IDC_R4TYPE1 1043
|
||||
#define IDC_BSEARCH 1044
|
||||
#define IDC_PIANO_F 1044
|
||||
#define IDC_R4TYPE2 1044
|
||||
#define IDC_RADIO1 1045
|
||||
#define IDC_PIANO_FS 1045
|
||||
#define IDC_RADIO2 1046
|
||||
|
@ -405,6 +409,7 @@
|
|||
#define IDC_PIANO_A 1048
|
||||
#define IDC_RADIO5 1049
|
||||
#define IDC_PIANO_AS 1049
|
||||
#define IDC_AR_CODE 1049
|
||||
#define IDC_RADIO6 1050
|
||||
#define IDC_PIANO_G 1050
|
||||
#define IDC_RADIO7 1051
|
||||
|
@ -972,7 +977,7 @@
|
|||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 125
|
||||
#define _APS_NEXT_COMMAND_VALUE 40094
|
||||
#define _APS_NEXT_CONTROL_VALUE 1041
|
||||
#define _APS_NEXT_CONTROL_VALUE 1050
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue