X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=platform%2Flibretro%2Flibretro.c;h=a1cf22c88dae1e0d194bc1856af36bfebc9c981b;hb=fa55ee51c9c1d86311fbd90f055a575e4991ac70;hp=332cf65150c68afcbb8f584f7c61ca11fea11d8c;hpb=f0a3d0dc4bd9060eb6bfdb16fb20dbb80a9e6ae9;p=picodrive.git diff --git a/platform/libretro/libretro.c b/platform/libretro/libretro.c index 332cf65..a1cf22c 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" @@ -691,13 +692,84 @@ bool retro_unserialize(const void *data, size_t size) return ret == 0; } -/* cheats - TODO */ +typedef struct patch +{ + unsigned int addr; + unsigned short data; + unsigned char comp; +} 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) { + 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) { + patch pt; + int array_len = PicoPatchCount; + char codeCopy[256]; + char *buff; + + if (code=='\0') return; + strcpy(codeCopy,code); + buff = strtok(codeCopy,"+"); + + while (buff != NULL) + { + decode(buff, &pt); + if (pt.addr == (uint32_t) -1 || pt.data == (uint16_t) -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].active = enabled; + PicoPatches[PicoPatchCount].addr = pt.addr; + PicoPatches[PicoPatchCount].data = pt.data; + PicoPatches[PicoPatchCount].comp = pt.comp; + if (PicoPatches[PicoPatchCount].addr < Pico.romsize) + PicoPatches[PicoPatchCount].data_old = *(uint16_t *)(Pico.rom + PicoPatches[PicoPatchCount].addr); + else + PicoPatches[PicoPatchCount].data_old = (uint16_t) m68k_read16(PicoPatches[PicoPatchCount].addr); + PicoPatchCount++; + + buff = strtok(NULL,"+"); + } } /* multidisk support */ @@ -1270,6 +1342,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,