Skip to content

Commit

Permalink
GB: Allow support for colorizer patched games
Browse files Browse the repository at this point in the history
- a new core option is provided since enabling this support
means allowing invalid access to vram and palette
- works in GBC/GBA hardware mode only
  • Loading branch information
retro-wertz committed Jul 18, 2019
1 parent 85bd86c commit 6dcf016
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 32 deletions.
72 changes: 53 additions & 19 deletions src/gb/GB.cpp
Expand Up @@ -200,6 +200,7 @@ int gbCaptureNumber = 0;
bool gbCapture = false;
bool gbCapturePrevious = false;
int gbJoymask[4] = { 0, 0, 0, 0 };
static bool allow_colorizer_hack;

uint8_t gbRamFill = 0xff;

Expand Down Expand Up @@ -776,6 +777,51 @@ static const uint16_t gbColorizationPaletteData[32][3][4] = {
#define GBSAVE_GAME_VERSION_12 12
#define GBSAVE_GAME_VERSION GBSAVE_GAME_VERSION_12

void setColorizerHack(bool value)
{
allow_colorizer_hack = value;
}

bool allowColorizerHack(void)
{
if (gbHardware & 0xA)
return (allow_colorizer_hack);
return false;
}

static inline bool gbVramReadAccessValid(void)
{
// A lot of 'ugly' checks... But only way to emulate this particular behaviour...
if (allowColorizerHack()||
((gbHardware & 0xa) && ((gbLcdModeDelayed != 3) || (((register_LY == 0) && (gbScreenOn == false) && (register_LCDC & 0x80)) && (gbLcdLYIncrementTicksDelayed == (GBLY_INCREMENT_CLOCK_TICKS - GBLCD_MODE_2_CLOCK_TICKS))))) ||
((gbHardware & 0x5) && (gbLcdModeDelayed != 3) && ((gbLcdMode != 3) || ((register_LY == 0) && ((gbScreenOn == false) && (register_LCDC & 0x80)) && (gbLcdLYIncrementTicks == (GBLY_INCREMENT_CLOCK_TICKS - GBLCD_MODE_2_CLOCK_TICKS))))))
return true;
return false;
}

static inline bool gbVramWriteAccessValid(void)
{
if (allowColorizerHack() ||
// No access to Vram during mode 3
// (used to emulate the gfx differences between GB & GBC-GBA/SP in Stunt Racer)
(gbLcdModeDelayed != 3) ||
// This part is used to emulate a small difference between hardwares
// (check 8-in-1's arrow on GBA/GBC to verify it)
((register_LY == 0) && ((gbHardware & 0xa) && (gbScreenOn == false) && (register_LCDC & 0x80)) && (gbLcdLYIncrementTicksDelayed == (GBLY_INCREMENT_CLOCK_TICKS - GBLCD_MODE_2_CLOCK_TICKS))))
return true;
return false;
}

static inline bool gbCgbPaletteAccessValid(void)
{
// No access to gbPalette during mode 3 (Color Panel Demo)
if (allowColorizerHack() ||
((gbLcdModeDelayed != 3) && (!((gbLcdMode == 0) && (gbLcdTicks >= (GBLCD_MODE_0_CLOCK_TICKS - gbSpritesTicks[299] - 1)))) && (!gbSpeed)) ||
(gbSpeed && ((gbLcdMode == 1) || (gbLcdMode == 2) || ((gbLcdMode == 3) && (gbLcdTicks > (GBLCD_MODE_3_CLOCK_TICKS - 2))) || ((gbLcdMode == 0) && (gbLcdTicks <= (GBLCD_MODE_0_CLOCK_TICKS - gbSpritesTicks[299] - 2))))))
return true;
return false;
}

int inline gbGetValue(int min, int max, int v)
{
return (int)(min + (float)(max - min) * (2.0 * (v / 31.0) - (v / 31.0) * (v / 31.0)));
Expand Down Expand Up @@ -919,12 +965,8 @@ void gbWriteMemory(uint16_t address, uint8_t value)
}

if (address < 0xa000) {
// No access to Vram during mode 3
// (used to emulate the gfx differences between GB & GBC-GBA/SP in Stunt Racer)
if ((gbLcdModeDelayed != 3) ||
// This part is used to emulate a small difference between hardwares
// (check 8-in-1's arrow on GBA/GBC to verify it)
((register_LY == 0) && ((gbHardware & 0xa) && (gbScreenOn == false) && (register_LCDC & 0x80)) && (gbLcdLYIncrementTicksDelayed == (GBLY_INCREMENT_CLOCK_TICKS - GBLCD_MODE_2_CLOCK_TICKS))))

if (gbVramWriteAccessValid())
gbMemoryMap[address >> 12][address & 0x0fff] = value;
return;
}
Expand Down Expand Up @@ -1621,8 +1663,7 @@ void gbWriteMemory(uint16_t address, uint8_t value)
int paletteIndex = (v & 0x3f) >> 1;
int paletteHiLo = (v & 0x01);

// No access to gbPalette during mode 3 (Color Panel Demo)
if (((gbLcdModeDelayed != 3) && (!((gbLcdMode == 0) && (gbLcdTicks >= (GBLCD_MODE_0_CLOCK_TICKS - gbSpritesTicks[299] - 1)))) && (!gbSpeed)) || (gbSpeed && ((gbLcdMode == 1) || (gbLcdMode == 2) || ((gbLcdMode == 3) && (gbLcdTicks > (GBLCD_MODE_3_CLOCK_TICKS - 2))) || ((gbLcdMode == 0) && (gbLcdTicks <= (GBLCD_MODE_0_CLOCK_TICKS - gbSpritesTicks[299] - 2)))))) {
if (gbCgbPaletteAccessValid()) {
gbMemory[0xff69] = value;
gbPalette[paletteIndex] = (paletteHiLo ? ((value << 8) | (gbPalette[paletteIndex] & 0xff)) : ((gbPalette[paletteIndex] & 0xff00) | (value))) & 0x7fff;
}
Expand Down Expand Up @@ -1662,8 +1703,7 @@ void gbWriteMemory(uint16_t address, uint8_t value)

paletteIndex += 32;

// No access to gbPalette during mode 3 (Color Panel Demo)
if (((gbLcdModeDelayed != 3) && (!((gbLcdMode == 0) && (gbLcdTicks >= (GBLCD_MODE_0_CLOCK_TICKS - gbSpritesTicks[299] - 1)))) && (!gbSpeed)) || (gbSpeed && ((gbLcdMode == 1) || (gbLcdMode == 2) || ((gbLcdMode == 3) && (gbLcdTicks > (GBLCD_MODE_3_CLOCK_TICKS - 2))) || ((gbLcdMode == 0) && (gbLcdTicks <= (GBLCD_MODE_0_CLOCK_TICKS - gbSpritesTicks[299] - 2)))))) {
if (gbCgbPaletteAccessValid()) {
gbMemory[0xff6b] = value;
gbPalette[paletteIndex] = (paletteHiLo ? ((value << 8) | (gbPalette[paletteIndex] & 0xff)) : ((gbPalette[paletteIndex] & 0xff00) | (value))) & 0x7fff;
}
Expand Down Expand Up @@ -1733,13 +1773,8 @@ uint8_t gbReadMemory(uint16_t address)
return gbMemoryMap[address >> 12][address & 0x0fff];

if (address < 0xa000) {
// A lot of 'ugly' checks... But only way to emulate this particular behaviour...
if (
(
(gbHardware & 0xa) && ((gbLcdModeDelayed != 3) || (((register_LY == 0) && (gbScreenOn == false) && (register_LCDC & 0x80)) && (gbLcdLYIncrementTicksDelayed == (GBLY_INCREMENT_CLOCK_TICKS - GBLCD_MODE_2_CLOCK_TICKS)))))
|| ((gbHardware & 0x5) && (gbLcdModeDelayed != 3) && ((gbLcdMode != 3) || ((register_LY == 0) && ((gbScreenOn == false) && (register_LCDC & 0x80)) && (gbLcdLYIncrementTicks == (GBLY_INCREMENT_CLOCK_TICKS - GBLCD_MODE_2_CLOCK_TICKS))))))
if (gbVramReadAccessValid())
return gbMemoryMap[address >> 12][address & 0x0fff];

return 0xff;
}

Expand Down Expand Up @@ -1981,8 +2016,7 @@ uint8_t gbReadMemory(uint16_t address)
case 0x69:
case 0x6b:
if (gbCgbMode) {
// No access to gbPalette during mode 3 (Color Panel Demo)
if (((gbLcdModeDelayed != 3) && (!((gbLcdMode == 0) && (gbLcdTicks >= (GBLCD_MODE_0_CLOCK_TICKS - gbSpritesTicks[299] - 1)))) && (!gbSpeed)) || (gbSpeed && ((gbLcdMode == 1) || (gbLcdMode == 2) || ((gbLcdMode == 3) && (gbLcdTicks > (GBLCD_MODE_3_CLOCK_TICKS - 2))) || ((gbLcdMode == 0) && (gbLcdTicks <= (GBLCD_MODE_0_CLOCK_TICKS - gbSpritesTicks[299] - 2))))))
if (gbCgbPaletteAccessValid())
return (gbMemory[address]);
else
return 0xff;
Expand Down Expand Up @@ -3275,6 +3309,7 @@ void gbInit()
{
gbGenFilter();
gbSgbInit();
setColorizerHack(false);

gbMemory = (uint8_t*)malloc(65536);

Expand Down Expand Up @@ -5425,7 +5460,6 @@ bool gbLoadRomData(const char* data, unsigned size)
bios = NULL;
}
bios = (uint8_t*)calloc(1, 0x900);

return gbUpdateSizes();
}

Expand Down
4 changes: 4 additions & 0 deletions src/gb/gb.h
Expand Up @@ -50,6 +50,10 @@ bool gbReadGSASnapshot(const char*);

bool gbLoadRomData(const char* data, unsigned size);

// Allows invalid vram/palette access needed for Colorizer hacked games in GBC/GBA hardware
void setColorizerHack(bool value);
bool allowColorizerHack(void);

extern int gbHardware;

extern struct EmulatedSystem GBSystem;
Expand Down
17 changes: 17 additions & 0 deletions src/libretro/libretro.cpp
Expand Up @@ -61,6 +61,7 @@ static unsigned height = 160;
static EmulatedSystem* core = NULL;
static IMAGE_TYPE type = IMAGE_UNKNOWN;
static unsigned current_gbPalette;
static bool opt_colorizer_hack = false;

uint16_t systemColorMap16[0x10000];
uint32_t systemColorMap32[0x10000];
Expand Down Expand Up @@ -866,6 +867,12 @@ static void gb_init(void)

gbGetHardwareType();

setColorizerHack(opt_colorizer_hack);

// Disable bios loading when using Colorizer hack
if (opt_colorizer_hack)
usebios = false;

if (usebios) {
snprintf(biosfile, sizeof(biosfile), "%s%c%s",
retro_system_directory, SLASH, biosname[gbCgbMode]);
Expand Down Expand Up @@ -1100,6 +1107,16 @@ static void update_variables(bool startup)
gbEmulatorType = 5;
}

var.key = "vbam_allowcolorizerhack";
var.value = NULL;

if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
if (strcmp(var.value, "enabled") == 0)
opt_colorizer_hack = true;
else
opt_colorizer_hack = false;
}

var.key = "vbam_turboenable";

if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
Expand Down
37 changes: 24 additions & 13 deletions src/libretro/libretro_core_options.h
Expand Up @@ -89,6 +89,24 @@ struct retro_core_option_definition option_defs_us[] = {
},
"5"
},
{
"vbam_palettes",
"(GB) Color Palette",
"Set Game Boy palettes.",
{
{ "black and white", NULL },
{ "blue sea", NULL },
{ "dark knight", NULL },
{ "green forest", NULL },
{ "hot desert", NULL },
{ "pink dreams", NULL },
{ "wierd colors", NULL },
{ "original gameboy", NULL },
{ "gba sp", NULL },
{ NULL, NULL },
},
"standard"
},
{
"vbam_gbHardware",
"(GB) Emulated Hardware",
Expand All @@ -105,22 +123,15 @@ struct retro_core_option_definition option_defs_us[] = {
"gbc"
},
{
"vbam_palettes",
"(GB) Color Palette",
"Set Game Boy palettes.",
"vbam_allowcolorizerhack",
"(GB) Enable Colorizer Hack (Needs Restart)",
"Allows Colorizer hacked GB games (e.g. DX patched games) to normally run in GBC/GBA hardware type. This also disables the use of bios file. NOT RECOMMENDED for use on non-colorized games.",
{
{ "black and white", NULL },
{ "blue sea", NULL },
{ "dark knight", NULL },
{ "green forest", NULL },
{ "hot desert", NULL },
{ "pink dreams", NULL },
{ "wierd colors", NULL },
{ "original gameboy", NULL },
{ "gba sp", NULL },
{ "disabled", NULL },
{ "enabled", NULL },
{ NULL, NULL },
},
"standard"
"disabled"
},
{
"vbam_showborders",
Expand Down

0 comments on commit 6dcf016

Please sign in to comment.