Merge pull request #302 from retro-wertz/libretro

Libretro: Add GB/GBC cheat support and wram/vram access using retro_get_memory api
This commit is contained in:
Zach Bacon 2018-08-19 11:49:31 -04:00 committed by GitHub
commit b4dd06a148
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 68 additions and 59 deletions

View File

@ -35,7 +35,7 @@ endif
ifeq ($(platform), unix) ifeq ($(platform), unix)
TARGET := $(TARGET_NAME)_libretro.so TARGET := $(TARGET_NAME)_libretro.so
fpic := -fPIC fpic := -fPIC
SHARED := -shared SHARED := -shared -Wl,-no-undefined -Wl,--version-script=link.T
TILED_RENDERING = 1 TILED_RENDERING = 1
else ifeq ($(platform), osx) else ifeq ($(platform), osx)
TARGET := $(TARGET_NAME)_libretro.dylib TARGET := $(TARGET_NAME)_libretro.dylib

View File

@ -229,10 +229,8 @@ static void* wram_ptr(void)
{ {
if (type == IMAGE_GBA) if (type == IMAGE_GBA)
return workRAM; return workRAM;
if (type == IMAGE_GB) { if (type == IMAGE_GB)
// this does not work with retro_get_memory_data/size return gbMemoryMap[0x0c];
// with its current memory mapping
}
return 0; return 0;
} }
@ -240,13 +238,19 @@ static size_t wram_size(void)
{ {
if (type == IMAGE_GBA) if (type == IMAGE_GBA)
return 0x40000; return 0x40000;
return 0; if (type == IMAGE_GB)
// only use 1st bank of wram, libretro doesnt seem to handle
// the switching bank properly in GBC mode. This is to avoid possible incorrect reads.
// For cheevos purposes, this bank is accessed using retro_memory_descriptor instead.
return gbCgbMode ? 0x1000 : 0x2000;
} }
static void* vram_ptr(void) static void* vram_ptr(void)
{ {
if (type == IMAGE_GBA) if (type == IMAGE_GBA)
return vram; return vram;
if (type == IMAGE_GB)
return gbMemoryMap[0x08] ;
return 0; return 0;
} }
@ -254,6 +258,8 @@ static size_t vram_size(void)
{ {
if (type == IMAGE_GBA) if (type == IMAGE_GBA)
return 0x20000; return 0x20000;
if (type == IMAGE_GB)
return 0x2000;;
return 0; return 0;
} }
@ -984,8 +990,8 @@ static void update_variables(void)
if ((type == IMAGE_GB) && (oldval != ((gbBorderOn << 1) | gbBorderAutomatic))) { if ((type == IMAGE_GB) && (oldval != ((gbBorderOn << 1) | gbBorderAutomatic))) {
if (gbBorderOn) { if (gbBorderOn) {
gbSgbRenderBorder();
systemGbBorderOn(); systemGbBorderOn();
gbSgbRenderBorder();
} }
else else
systemGbBorderOff(); systemGbBorderOff();
@ -1071,10 +1077,11 @@ bool retro_unserialize(const void* data, size_t size)
void retro_cheat_reset(void) void retro_cheat_reset(void)
{ {
if (type == IMAGE_GBA) { cheatsEnabled = 1;
cheatsEnabled = 1; if (type == IMAGE_GBA)
cheatsDeleteAll(false); cheatsDeleteAll(false);
} else if (type == IMAGE_GB)
gbCheatRemoveAll();
} }
void retro_cheat_set(unsigned index, bool enabled, const char* code) void retro_cheat_set(unsigned index, bool enabled, const char* code)
@ -1120,57 +1127,59 @@ void retro_cheat_set(unsigned index, bool enabled, const char* code)
} while (*c++); } while (*c++);
*/ */
// TODO: Add cheat code support for GB/GBC std::string codeLine = code;
if (type != IMAGE_GBA) std::string name = "cheat_" + index;
return; int matchLength = 0;
std::vector<std::string> codeParts;
int cursor;
std::string codeLine=code; if (type == IMAGE_GBA) {
std::string name="cheat_"+index; //Break the code into Parts
int matchLength=0; for (cursor = 0;; cursor++) {
std::vector<std::string> codeParts; if (ISHEXDEC)
int cursor; matchLength++;
else {
//Break the code into Parts if (matchLength) {
for (cursor=0;;cursor++) if (matchLength > 8) {
{ codeParts.push_back(codeLine.substr(cursor - matchLength, 8));
if (ISHEXDEC){ codeParts.push_back(codeLine.substr(cursor - matchLength + 8, matchLength - 8));
matchLength++; } else
} else { codeParts.push_back(codeLine.substr(cursor - matchLength, matchLength));
if (matchLength){ matchLength = 0;
if (matchLength>8){ }
codeParts.push_back(codeLine.substr(cursor-matchLength,8));
codeParts.push_back(codeLine.substr(cursor-matchLength+8,matchLength-8));
} else {
codeParts.push_back(codeLine.substr(cursor-matchLength,matchLength));
} }
matchLength=0; if (!codeLine[cursor])
} break;
} }
if (!codeLine[cursor]){
break; //Add to core
} for (cursor = 0; cursor < codeParts.size(); cursor += 2) {
std::string codeString;
codeString += codeParts[cursor];
if (codeParts[cursor + 1].length() == 8) {
codeString += codeParts[cursor + 1];
cheatsAddGSACode(codeString.c_str(), name.c_str(), true);
} else if (codeParts[cursor + 1].length() == 4) {
codeString += " ";
codeString += codeParts[cursor + 1];
cheatsAddCBACode(codeString.c_str(), name.c_str());
} else {
codeString += " ";
codeString += codeParts[cursor + 1];
log_cb(RETRO_LOG_ERROR, "Invalid cheat code '%s'\n", codeString.c_str());
}
log_cb(RETRO_LOG_INFO, "Cheat code added: '%s'\n", codeString.c_str());
}
} else if (type == IMAGE_GB) {
if (codeLine.find("-") != std::string::npos) {
if (gbAddGgCheat(code, ""))
log_cb(RETRO_LOG_INFO, "Cheat code added: '%s'\n", codeLine.c_str());
} else {
if (gbAddGsCheat(code, ""))
log_cb(RETRO_LOG_INFO, "Cheat code added: '%s'\n", codeLine.c_str());
}
} }
//Add to core
for (cursor=0;cursor<codeParts.size();cursor+=2){
std::string codeString;
codeString+=codeParts[cursor];
if (codeParts[cursor+1].length()==8){
codeString+=codeParts[cursor+1];
cheatsAddGSACode(codeString.c_str(),name.c_str(),true);
} else if (codeParts[cursor+1].length()==4) {
codeString+=" ";
codeString+=codeParts[cursor+1];
cheatsAddCBACode(codeString.c_str(),name.c_str());
} else {
codeString+=" ";
codeString+=codeParts[cursor+1];
log_cb(RETRO_LOG_ERROR, "[VBA] Invalid cheat code '%s'\n", codeString.c_str());
}
log_cb(RETRO_LOG_INFO, "[VBA] Cheat code added: '%s'\n", codeString.c_str());
}
} }
static void update_input_descriptors(void) static void update_input_descriptors(void)