From 20563b60d0b9526c133289ca9c7b1ba255991916 Mon Sep 17 00:00:00 2001 From: iLag Date: Wed, 22 Mar 2017 14:19:35 -0700 Subject: [PATCH 1/6] Add support for single-line cheats and PAR codes. --- pico/patch.c | 14 +++++++-- platform/libretro/libretro.c | 59 +++++++++++++++++++++++++++++++++++- 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/pico/patch.c b/pico/patch.c index b961e802..0240cb0d 100644 --- a/pico/patch.c +++ b/pico/patch.c @@ -142,7 +142,7 @@ static void hex_decode(const char *code, struct patch *result) /* THIS is the function you call from the MegaDrive or whatever. This figures * out whether it's a genie or hex code, depunctuates it, and calls the proper * decoder. */ -static void decode(const char* code, struct patch* result) +void decode(const char* code, struct patch* result) { int len = strlen(code), i, j; char code_to_pass[16], *x; @@ -299,6 +299,8 @@ void PicoPatchPrepare(void) PicoPatches[i].addr &= ~1; if (PicoPatches[i].addr < Pico.romsize) PicoPatches[i].data_old = *(unsigned short *)(Pico.rom + PicoPatches[i].addr); + else + PicoPatches[i].data_old = (unsigned short) m68k_read16(PicoPatches[i].addr); if (strstr(PicoPatches[i].name, "AUTO")) PicoPatches[i].active = 1; } @@ -328,7 +330,15 @@ void PicoPatchApply(void) } else { - /* TODO? */ + if (PicoPatches[i].active) + m68k_write16(PicoPatches[i].addr,PicoPatches[i].data); + else { + // if current addr is not patched by older patch, write back original val + for (u = 0; u < i; u++) + if (PicoPatches[u].addr == addr) break; + if (u == i) + m68k_write16(PicoPatches[i].addr,PicoPatches[i].data_old); + } } } } diff --git a/platform/libretro/libretro.c b/platform/libretro/libretro.c index 332cf651..73733fdb 100644 --- a/platform/libretro/libretro.c +++ b/platform/libretro/libretro.c @@ -53,6 +53,7 @@ int _newlib_vm_size_user = 1 << TARGET_SIZE_2; #include #include +#include #include "../common/input_pico.h" #include "../common/version.h" #include "libretro.h" @@ -692,12 +693,67 @@ bool retro_unserialize(const void *data, size_t size) } /* cheats - TODO */ + void retro_cheat_reset(void) { + int i=0; + unsigned int addr; + + for (i = 0; i < PicoPatchCount; i++) + { + addr = PicoPatches[i].addr; + if (addr < Pico.romsize) + if (PicoPatches[i].active) + *(unsigned short *)(Pico.rom + addr) = PicoPatches[i].data_old; + else + if (PicoPatches[i].active) + m68k_write16(PicoPatches[i].addr,PicoPatches[i].data_old); + } + + PicoPatchUnload(); } -void retro_cheat_set(unsigned index, bool enabled, const char *code) +void retro_cheat_set(unsigned index, bool enabled, const char *buff) { + struct patch + { + unsigned int addr; + unsigned short data; + } pt; + int array_len = 0; + + //TODO: Split multi-line codes properly + + decode(buff, &pt); + if (pt.addr == (unsigned int)-1 || pt.data == (unsigned short)-1){ + log_cb(RETRO_LOG_ERROR,"CHEATS: Invalid code: %s\n",buff); + return; + } + + /* code was good, add it */ + if (array_len < PicoPatchCount + 1) + { + void *ptr; + array_len *= 2; + array_len++; + ptr = realloc(PicoPatches, array_len * sizeof(PicoPatches[0])); + if (ptr == NULL) { + log_cb(RETRO_LOG_ERROR,"CHEATS: Failed to allocate memory for: %s\n",buff); + return; + } + PicoPatches = ptr; + } + strcpy(PicoPatches[PicoPatchCount].code, buff); + + PicoPatches[PicoPatchCount].name[51] = ""; + PicoPatches[PicoPatchCount].active = enabled; + PicoPatches[PicoPatchCount].addr = pt.addr; + PicoPatches[PicoPatchCount].data = pt.data; + if (PicoPatches[PicoPatchCount].addr < Pico.romsize) + PicoPatches[PicoPatchCount].data_old = *(unsigned short *)(Pico.rom + PicoPatches[PicoPatchCount].addr); + else + PicoPatches[PicoPatchCount].data_old = (unsigned short) m68k_read16(PicoPatches[PicoPatchCount].addr); + PicoPatchCount++; } /* multidisk support */ @@ -1270,6 +1326,7 @@ void retro_run(void) if (input_state_cb(pad, RETRO_DEVICE_JOYPAD, 0, i)) PicoPad[pad] |= retro_pico_map[i]; + PicoPatchApply(); PicoFrame(); video_cb((short *)vout_buf + vout_offset, From 6cf45534d325cc4a2e93910e57f5f1eff7443a88 Mon Sep 17 00:00:00 2001 From: iLag Date: Wed, 22 Mar 2017 14:37:18 -0700 Subject: [PATCH 2/6] Support multiline codes --- platform/libretro/libretro.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/platform/libretro/libretro.c b/platform/libretro/libretro.c index 73733fdb..1b914d54 100644 --- a/platform/libretro/libretro.c +++ b/platform/libretro/libretro.c @@ -713,7 +713,7 @@ void retro_cheat_reset(void) PicoPatchUnload(); } -void retro_cheat_set(unsigned index, bool enabled, const char *buff) +void retro_cheat_set(unsigned index, bool enabled, const char *code) { struct patch { @@ -721,11 +721,16 @@ void retro_cheat_set(unsigned index, bool enabled, const char *buff) unsigned short data; } pt; int array_len = 0; + char *buff; //TODO: Split multi-line codes properly + buff = strtok(code,"+"); + while (buff) + { decode(buff, &pt); - if (pt.addr == (unsigned int)-1 || pt.data == (unsigned short)-1){ + if (pt.addr == (unsigned int)-1 || pt.data == (unsigned short)-1) + { log_cb(RETRO_LOG_ERROR,"CHEATS: Invalid code: %s\n",buff); return; } @@ -754,6 +759,7 @@ void retro_cheat_set(unsigned index, bool enabled, const char *buff) else PicoPatches[PicoPatchCount].data_old = (unsigned short) m68k_read16(PicoPatches[PicoPatchCount].addr); PicoPatchCount++; + } } /* multidisk support */ From d4089d9b8e132e796dca0382bd237b8efeeeac3d Mon Sep 17 00:00:00 2001 From: iLag Date: Wed, 22 Mar 2017 14:45:23 -0700 Subject: [PATCH 3/6] Fix multiline support --- platform/libretro/libretro.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/platform/libretro/libretro.c b/platform/libretro/libretro.c index 1b914d54..0f060e6b 100644 --- a/platform/libretro/libretro.c +++ b/platform/libretro/libretro.c @@ -722,11 +722,17 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code) } pt; int array_len = 0; char *buff; + bool multiline=0; //TODO: Split multi-line codes properly - buff = strtok(code,"+"); + if (strstr(code,"+")){ + multiline=1; + buff = strtok(code,"+"); + } else { + buff=code; + } - while (buff) + while (buff != NULL) { decode(buff, &pt); if (pt.addr == (unsigned int)-1 || pt.data == (unsigned short)-1) @@ -759,6 +765,9 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code) else PicoPatches[PicoPatchCount].data_old = (unsigned short) m68k_read16(PicoPatches[PicoPatchCount].addr); PicoPatchCount++; + + if (!multiline) + break; } } From daae6156b46bd32529d9c6908600409d036b6932 Mon Sep 17 00:00:00 2001 From: iLag Date: Wed, 22 Mar 2017 15:01:58 -0700 Subject: [PATCH 4/6] Fix variable types, silence warnings. --- pico/patch.c | 3 ++- platform/libretro/libretro.c | 36 +++++++++++++++++++++--------------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/pico/patch.c b/pico/patch.c index 0240cb0d..558658c3 100644 --- a/pico/patch.c +++ b/pico/patch.c @@ -211,7 +211,8 @@ bad_code: unsigned int PicoRead16(unsigned int a); void PicoWrite16(unsigned int a, unsigned short d); - +extern unsigned short m68k_read16(unsigned int a); +extern void m68k_write16(int a, unsigned short d); void PicoPatchUnload(void) { diff --git a/platform/libretro/libretro.c b/platform/libretro/libretro.c index 0f060e6b..8e1bed35 100644 --- a/platform/libretro/libretro.c +++ b/platform/libretro/libretro.c @@ -692,7 +692,15 @@ bool retro_unserialize(const void *data, size_t size) return ret == 0; } -/* cheats - TODO */ +typedef struct patch +{ + unsigned int addr; + unsigned short data; +} patch; + +extern void decode(char *buff, patch *dest); +extern uint16_t m68k_read16(uint32_t a); +extern void m68k_write16(uint32_t a, uint16_t d); void retro_cheat_reset(void) { @@ -702,12 +710,13 @@ void retro_cheat_reset(void) for (i = 0; i < PicoPatchCount; i++) { addr = PicoPatches[i].addr; - if (addr < Pico.romsize) + if (addr < Pico.romsize) { if (PicoPatches[i].active) *(unsigned short *)(Pico.rom + addr) = PicoPatches[i].data_old; - else + } else { if (PicoPatches[i].active) m68k_write16(PicoPatches[i].addr,PicoPatches[i].data_old); + } } PicoPatchUnload(); @@ -715,27 +724,25 @@ void retro_cheat_reset(void) void retro_cheat_set(unsigned index, bool enabled, const char *code) { - struct patch - { - unsigned int addr; - unsigned short data; - } pt; + patch pt; int array_len = 0; + char codeCopy[256]; char *buff; bool multiline=0; - //TODO: Split multi-line codes properly + strcpy(codeCopy,code); + if (strstr(code,"+")){ multiline=1; - buff = strtok(code,"+"); + buff = strtok(codeCopy,"+"); } else { - buff=code; + buff=codeCopy; } while (buff != NULL) { decode(buff, &pt); - if (pt.addr == (unsigned int)-1 || pt.data == (unsigned short)-1) + if (pt.addr == (uint32_t) -1 || pt.data == (uint16_t) -1) { log_cb(RETRO_LOG_ERROR,"CHEATS: Invalid code: %s\n",buff); return; @@ -756,14 +763,13 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code) } strcpy(PicoPatches[PicoPatchCount].code, buff); - PicoPatches[PicoPatchCount].name[51] = ""; PicoPatches[PicoPatchCount].active = enabled; PicoPatches[PicoPatchCount].addr = pt.addr; PicoPatches[PicoPatchCount].data = pt.data; if (PicoPatches[PicoPatchCount].addr < Pico.romsize) - PicoPatches[PicoPatchCount].data_old = *(unsigned short *)(Pico.rom + PicoPatches[PicoPatchCount].addr); + PicoPatches[PicoPatchCount].data_old = *(uint16_t *)(Pico.rom + PicoPatches[PicoPatchCount].addr); else - PicoPatches[PicoPatchCount].data_old = (unsigned short) m68k_read16(PicoPatches[PicoPatchCount].addr); + PicoPatches[PicoPatchCount].data_old = (uint16_t) m68k_read16(PicoPatches[PicoPatchCount].addr); PicoPatchCount++; if (!multiline) From e5326b1a0e5fe59e95db275c52acffd4bd50e7da Mon Sep 17 00:00:00 2001 From: iLag Date: Thu, 23 Mar 2017 11:13:56 -0700 Subject: [PATCH 5/6] Fix memory management so the emulator won't crash with multiple cheats in a file. --- platform/libretro/libretro.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/libretro/libretro.c b/platform/libretro/libretro.c index 8e1bed35..a4bc0a1b 100644 --- a/platform/libretro/libretro.c +++ b/platform/libretro/libretro.c @@ -725,7 +725,7 @@ void retro_cheat_reset(void) void retro_cheat_set(unsigned index, bool enabled, const char *code) { patch pt; - int array_len = 0; + int array_len = PicoPatchCount; char codeCopy[256]; char *buff; bool multiline=0; @@ -741,6 +741,7 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code) while (buff != NULL) { + log_cb(RETRO_LOG_INFO,"Buff: %s\n",buff); decode(buff, &pt); if (pt.addr == (uint32_t) -1 || pt.data == (uint16_t) -1) { @@ -774,6 +775,7 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code) if (!multiline) break; + buff = strtok(NULL,"+"); } } From cb5021471da11969696c474d922fdaac05e2eb83 Mon Sep 17 00:00:00 2001 From: iLag Date: Thu, 23 Mar 2017 11:16:37 -0700 Subject: [PATCH 6/6] Remove temporary debug print line --- platform/libretro/libretro.c | 1 - 1 file changed, 1 deletion(-) diff --git a/platform/libretro/libretro.c b/platform/libretro/libretro.c index a4bc0a1b..f11b5dae 100644 --- a/platform/libretro/libretro.c +++ b/platform/libretro/libretro.c @@ -741,7 +741,6 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code) while (buff != NULL) { - log_cb(RETRO_LOG_INFO,"Buff: %s\n",buff); decode(buff, &pt); if (pt.addr == (uint32_t) -1 || pt.data == (uint16_t) -1) {