cheatfile done

This commit is contained in:
Robin Jones 2017-10-18 13:55:40 +01:00
parent 00f4e5b69b
commit bb14fcd8c8
1 changed files with 178 additions and 164 deletions

View File

@ -1724,7 +1724,9 @@ int saveTypeToSd(display_context_t disp, char *rom_name, int stype)
if (result == FR_OK) if (result == FR_OK)
{ {
//for savegame //for savegame
uint8_t cartsave_data[size] = {0}; uint8_t cartsave_data[size]; //TODO: bring back old initialisation if this doesn't work
TRACEF(disp, "cartsave_data=%p", &cartsave_data); TRACEF(disp, "cartsave_data=%p", &cartsave_data);
@ -2015,173 +2017,185 @@ int readCheatFile(char *filename, u32 *cheat_lists[2])
yaml_parser_initialize(&parser); yaml_parser_initialize(&parser);
FatRecord rec_tmpf;
if (fatFindRecord(filename, &rec_tmpf, 0) != 0) FRESULT result;
FIL file;
UINT bytesread;
result = f_open(&file, filename, FA_READ);
if (result == FR_OK)
{ {
return -1; //err file not found int fsize = f_size(&file);
}
u8 resp = 0; char *cheatfile = malloc(fsize);
resp = fatOpenFileByName(filename, 0); if (!cheatfile)
//filesize of the opend file -> is the readfile / 512
int fsize = file.sec_available * 512;
char *cheatfile = malloc(fsize);
if (!cheatfile)
{
return -2; // Out of memory
}
/*
* Size of the cheat list can never be more than half the size of the YAML
* Minimum YAML example:
* A:-80001234 FFFF
* Which is exactly 16 bytes.
* The cheat list in this case fits into exactly 8 bytes (2 words):
* 0x80001234, 0x0000FFFF
*/
list1 = calloc(1, fsize + 2 * sizeof(u32)); // Plus 2 words to be safe
if (!list1)
{
// Free
free(cheatfile);
return -2; // Out of memory
}
list2 = &list1[fsize / sizeof(u32) / 2];
cheat_lists[0] = list1;
cheat_lists[1] = list2;
resp = fatReadFile(cheatfile, fsize / 512); //1 cluster
yaml_parser_set_input_string(&parser, cheatfile, strlen(cheatfile));
do
{
if (!yaml_parser_parse(&parser, &event))
{ {
// Free return -2; // Out of memory
yaml_parser_delete(&parser);
yaml_event_delete(&event);
free(cheatfile);
free(cheat_lists[0]);
cheat_lists[0] = 0;
cheat_lists[1] = 0;
return -3; // Parse error
} }
// Process YAML /*
switch (event.type) * Size of the cheat list can never be more than half the size of the YAML
* Minimum YAML example:
* A:-80001234 FFFF
* Which is exactly 16 bytes.
* The cheat list in this case fits into exactly 8 bytes (2 words):
* 0x80001234, 0x0000FFFF
*/
list1 = calloc(1, fsize + 2 * sizeof(u32)); // Plus 2 words to be safe
if (!list1)
{ {
case YAML_MAPPING_START_EVENT: // Free
// Begin code block free(cheatfile);
is_code = 0; return -2; // Out of memory
break; }
list2 = &list1[fsize / sizeof(u32) / 2];
cheat_lists[0] = list1;
cheat_lists[1] = list2;
case YAML_SEQUENCE_START_EVENT: result =
// Begin code lines f_read (
is_code = 1; &file, /* [IN] File object */
code_on = (event.data.sequence_start.tag ? !!strcasecmp(event.data.sequence_start.tag, "!off") : 1); &cheatfile, /* [OUT] Buffer to store read data */
break; fsize, /* [IN] Number of bytes to read */
&bytesread /* [OUT] Number of bytes read */
);
case YAML_SEQUENCE_END_EVENT: result = f_close(&file);
// End code lines
is_code = 0;
code_on = 1;
repeater = 0;
break;
case YAML_SCALAR_EVENT: yaml_parser_set_input_string(&parser, cheatfile, strlen(cheatfile));
// Code line
if (!is_code || !code_on) do
{ {
break; if (!yaml_parser_parse(&parser, &event))
}
address = strtoul(event.data.scalar.value, &next, 16);
value = strtoul(next, NULL, 16);
// Do not check code types within "repeater data"
if (repeater)
{
repeater--;
*list2++ = address;
*list2++ = value;
break;
}
// Determine destination cheat_list for the code type
switch (address >> 24)
{
// Uncessary code types
case 0x20: // Clear code list
case 0xCC: // Exception Handler Selection
case 0xDE: // Entry Point
break;
// Boot-time cheats
case 0xEE: // Disable Expansion Pak
case 0xF0: // 8-bit Boot-Time Write
case 0xF1: // 16-bit Boot-Time Write
case 0xFF: // Cheat Engine Location
*list1++ = address;
*list1++ = value;
break;
// In-game cheats
case 0x50: // Repeater/Patch
// Validate repeater count
if (address & 0x0000FF00)
{ {
repeater = 1; // Free
*list2++ = address; yaml_parser_delete(&parser);
*list2++ = value; yaml_event_delete(&event);
free(cheatfile);
free(cheat_lists[0]);
cheat_lists[0] = 0;
cheat_lists[1] = 0;
return -3; // Parse error
} }
break;
// Everything else // Process YAML
default: switch (event.type)
if (!address)
{ {
// TODO: Support special code types! :) case YAML_MAPPING_START_EVENT:
} // Begin code block
// Fall-through! is_code = 0;
break;
case 0xD0: // 8-bit Equal-To Conditional case YAML_SEQUENCE_START_EVENT:
case 0xD1: // 16-bit Equal-To Conditional // Begin code lines
case 0xD2: // 8-bit Not-Equal-To Conditional is_code = 1;
case 0xD3: // 16-bit Not-Equal-To Conditional code_on = (event.data.sequence_start.tag ? !!strcasecmp(event.data.sequence_start.tag, "!off") : 1);
// Validate 16-bit codes break;
if ((address & 0x01000001) == 0x01000001)
{ case YAML_SEQUENCE_END_EVENT:
// End code lines
is_code = 0;
code_on = 1;
repeater = 0;
break;
case YAML_SCALAR_EVENT:
// Code line
if (!is_code || !code_on)
{
break;
}
address = strtoul(event.data.scalar.value, &next, 16);
value = strtoul(next, NULL, 16);
// Do not check code types within "repeater data"
if (repeater)
{
repeater--;
*list2++ = address;
*list2++ = value;
break;
}
// Determine destination cheat_list for the code type
switch (address >> 24)
{
// Uncessary code types
case 0x20: // Clear code list
case 0xCC: // Exception Handler Selection
case 0xDE: // Entry Point
break;
// Boot-time cheats
case 0xEE: // Disable Expansion Pak
case 0xF0: // 8-bit Boot-Time Write
case 0xF1: // 16-bit Boot-Time Write
case 0xFF: // Cheat Engine Location
*list1++ = address;
*list1++ = value;
break;
// In-game cheats
case 0x50: // Repeater/Patch
// Validate repeater count
if (address & 0x0000FF00)
{
repeater = 1;
*list2++ = address;
*list2++ = value;
}
break;
// Everything else
default:
if (!address)
{
// TODO: Support special code types! :)
}
// Fall-through!
case 0xD0: // 8-bit Equal-To Conditional
case 0xD1: // 16-bit Equal-To Conditional
case 0xD2: // 8-bit Not-Equal-To Conditional
case 0xD3: // 16-bit Not-Equal-To Conditional
// Validate 16-bit codes
if ((address & 0x01000001) == 0x01000001)
{
break;
}
*list2++ = address;
*list2++ = value;
break;
}
break;
case YAML_STREAM_END_EVENT:
// And we're outta here!
done = 1;
break;
default:
break; break;
} }
*list2++ = address; yaml_event_delete(&event);
*list2++ = value; } while (!done);
break;
}
break;
case YAML_STREAM_END_EVENT: // Free
// And we're outta here! yaml_parser_delete(&parser);
done = 1; free(cheatfile);
break;
default: return repeater; // Ok or repeater error
break;
}
yaml_event_delete(&event); }
} while (!done); else
{
// Free return -1; //err file not found
yaml_parser_delete(&parser); }
free(cheatfile);
return repeater; // Ok or repeater error
} }
//TODO: UNUSED CODE, WHAT IS IS FOR? BattleTanx??? but where to insert it??? //TODO: UNUSED CODE, WHAT IS IS FOR? BattleTanx??? but where to insert it???