Skip to content

Commit

Permalink
Libretro: Add GB/GBC core
Browse files Browse the repository at this point in the history
Gb,gbc and sgb enhanced version of roms and savestates working. Bios loading for gb/gbc works too. No save ram / battery handling yet.

Fix offset and pitch issues with vba rendering and when borders are enabled.
  • Loading branch information
retro-wertz committed Jul 16, 2018
1 parent f05a05e commit bf447bf
Show file tree
Hide file tree
Showing 12 changed files with 685 additions and 64 deletions.
379 changes: 378 additions & 1 deletion src/gb/GB.cpp

Large diffs are not rendered by default.

11 changes: 9 additions & 2 deletions src/gb/gb.h
Expand Up @@ -31,18 +31,25 @@ void gbGetHardwareType();
void gbReset();
void gbCleanUp();
void gbCPUInit(const char*, bool);
#ifdef __LIBRETRO__
unsigned int gbWriteSaveState(uint8_t*, unsigned);
bool gbReadSaveState(const uint8_t*, unsigned);
#else
bool gbWriteSaveState(const char*);
bool gbReadSaveState(const char*);
#endif
bool gbWriteBatteryFile(const char*);
bool gbWriteBatteryFile(const char*, bool);
bool gbReadBatteryFile(const char*);
bool gbWriteSaveState(const char*);
bool gbWriteMemSaveState(char*, int, long&);
bool gbReadSaveState(const char*);
bool gbReadMemSaveState(char*, int);
void gbSgbRenderBorder();
bool gbWritePNGFile(const char*);
bool gbWriteBMPFile(const char*);
bool gbReadGSASnapshot(const char*);

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

extern int gbHardware;

extern struct EmulatedSystem GBSystem;
Expand Down
2 changes: 2 additions & 0 deletions src/gb/gbCheats.cpp
Expand Up @@ -30,6 +30,7 @@ void gbCheatUpdateMap()
}
}

#ifndef __LIBRETRO__
void gbCheatsSaveGame(gzFile gzFile)
{
utilWriteInt(gzFile, gbCheatNumber);
Expand Down Expand Up @@ -98,6 +99,7 @@ void gbCheatsReadGameSkip(gzFile gzFile, int version)
}
}
}
#endif

void gbCheatsSaveCheatList(const char* file)
{
Expand Down
2 changes: 2 additions & 0 deletions src/gb/gbCheats.h
Expand Up @@ -19,9 +19,11 @@ struct gbCheat {
bool enabled;
};

#ifndef __LIBRETRO__
void gbCheatsSaveGame(gzFile);
void gbCheatsReadGame(gzFile, int);
void gbCheatsReadGameSkip(gzFile, int);
#endif
void gbCheatsSaveCheatList(const char*);
bool gbCheatsLoadCheatList(const char*);
bool gbCheatReadGSCodeFile(const char*);
Expand Down
54 changes: 53 additions & 1 deletion src/gb/gbSGB.cpp
Expand Up @@ -113,7 +113,11 @@ void gbSgbFillScreen(uint16_t color)
switch (systemColorDepth) {
case 16: {
for (int y = 0; y < 144; y++) {
#ifdef __LIBRETRO__
int yLine = (y + gbBorderRowSkip) * gbBorderLineSkip + gbBorderColumnSkip;
#else
int yLine = (y + gbBorderRowSkip + 1) * (gbBorderLineSkip + 2) + gbBorderColumnSkip;
#endif
uint16_t* dest = (uint16_t*)pix + yLine;
for (register int x = 0; x < 160; x++)
gbSgbDraw16Bit(dest++, color);
Expand All @@ -131,7 +135,11 @@ void gbSgbFillScreen(uint16_t color)
} break;
case 32: {
for (int y = 0; y < 144; y++) {
#ifdef __LIBRETRO__
int yLine = (y + gbBorderRowSkip) * gbBorderLineSkip + gbBorderColumnSkip;
#else
int yLine = (y + gbBorderRowSkip + 1) * (gbBorderLineSkip + 1) + gbBorderColumnSkip;
#endif
uint32_t* dest = (uint32_t*)pix + yLine;
for (register int x = 0; x < 160; x++) {
gbSgbDraw32Bit(dest++, color);
Expand Down Expand Up @@ -181,9 +189,14 @@ void gbSgbRenderScreenToBuffer()

void gbSgbDrawBorderTile(int x, int y, int tile, int attr)
{
#ifdef __LIBRETRO__
uint16_t* dest = (uint16_t*)pix + (y * 256) + x;
uint32_t* dest32 = (uint32_t*)pix + (y * 256) + x;
#else
uint16_t* dest = (uint16_t*)pix + ((y + 1) * (256 + 2)) + x;
uint32_t* dest32 = (uint32_t*)pix + ((y + 1) * 256 + 1) + x;
#endif
uint8_t* dest8 = (uint8_t*)pix + ((y * 256) + x) * 3;
uint32_t* dest32 = (uint32_t*)pix + ((y + 1) * 257) + x;

uint8_t* tileAddress = &gbSgbBorderChar[tile * 32];
uint8_t* tileAddress2 = &gbSgbBorderChar[tile * 32 + 16];
Expand Down Expand Up @@ -245,13 +258,21 @@ void gbSgbDrawBorderTile(int x, int y, int tile, int attr)

switch (systemColorDepth) {
case 16:
#ifdef __LIBRETRO__
gbSgbDraw16Bit(dest + yyy * 256 + xxx, cc);
#else
gbSgbDraw16Bit(dest + yyy * (256 + 2) + xxx, cc);
#endif
break;
case 24:
gbSgbDraw24Bit(dest8 + (yyy * 256 + xxx) * 3, cc);
break;
case 32:
#ifdef __LIBRETRO__
gbSgbDraw32Bit(dest32 + yyy * 256 + xxx, cc);
#else
gbSgbDraw32Bit(dest32 + yyy * (256 + 1) + xxx, cc);
#endif
break;
}
}
Expand Down Expand Up @@ -860,6 +881,36 @@ variable_desc gbSgbSaveStructV3[] = {
{ NULL, 0 }
};

#ifdef __LIBRETRO__
void gbSgbSaveGame(uint8_t*& data)
{
utilWriteDataMem(data, gbSgbSaveStructV3);

utilWriteMem(data, gbSgbBorder, 2048);
utilWriteMem(data, gbSgbBorderChar, 32 * 256);

utilWriteMem(data, gbSgbPacket, 16 * 7);

utilWriteMem(data, gbSgbSCPPalette, 4 * 512 * sizeof(uint16_t));
utilWriteMem(data, gbSgbATF, 20 * 18);
utilWriteMem(data, gbSgbATFList, 45 * 20 * 18);
}

void gbSgbReadGame(const uint8_t*& data, int version)
{
utilReadDataMem(data, gbSgbSaveStructV3);

utilReadMem(gbSgbBorder, data, 2048);
utilReadMem(gbSgbBorderChar, data, 32 * 256);

utilReadMem(gbSgbPacket, data, 16 * 7);

utilReadMem(gbSgbSCPPalette, data, 4 * 512 * sizeof(uint16_t));
utilReadMem(gbSgbATF, data, 20 * 18);
utilReadMem(gbSgbATFList, data, 45 * 20 * 18);
}

#else // !__LIBRETRO__
void gbSgbSaveGame(gzFile gzFile)
{
utilWriteData(gzFile, gbSgbSaveStructV3);
Expand Down Expand Up @@ -894,3 +945,4 @@ void gbSgbReadGame(gzFile gzFile, int version)
utilGzRead(gzFile, gbSgbATF, 20 * 18);
utilGzRead(gzFile, gbSgbATFList, 45 * 20 * 18);
}
#endif // !__LIBRETRO__
7 changes: 6 additions & 1 deletion src/gb/gbSGB.h
Expand Up @@ -7,9 +7,14 @@ void gbSgbCommand();
void gbSgbResetPacketState();
void gbSgbReset();
void gbSgbDoBitTransfer(uint8_t);
void gbSgbRenderBorder();
#ifdef __LIBRETRO__
void gbSgbSaveGame(uint8_t*&);
void gbSgbReadGame(const uint8_t*&, int);
#else
void gbSgbSaveGame(gzFile);
void gbSgbReadGame(gzFile, int version);
void gbSgbRenderBorder();
#endif

extern uint8_t gbSgbATF[20 * 18];
extern int gbSgbMode;
Expand Down
18 changes: 18 additions & 0 deletions src/gb/gbSound.cpp
Expand Up @@ -358,6 +358,7 @@ enum {
nr52
};

#ifndef __LIBRETRO__
static void gbSoundReadGameOld(int version, gzFile gzFile)
{
if (version == 11) {
Expand Down Expand Up @@ -395,6 +396,7 @@ static void gbSoundReadGameOld(int version, gzFile gzFile)

memcpy(&s.regs[0x20], &gbMemory[0xFF30], 0x10); // wave
}
#endif

// New state format

Expand Down Expand Up @@ -430,27 +432,43 @@ static variable_desc gb_state[] = {
{ NULL, 0 }
};

#ifdef __LIBRETRO__
void gbSoundSaveGame(uint8_t*& out)
#else
void gbSoundSaveGame(gzFile out)
#endif
{
gb_apu->save_state(&state.apu);

// Be sure areas for expansion get written as zero
memset(dummy_state, 0, sizeof dummy_state);

state.version = 1;
#ifdef __LIBRETRO__
utilWriteDataMem(out, gb_state);
#else
utilWriteData(out, gb_state);
#endif
}

#ifdef __LIBRETRO__
void gbSoundReadGame(const uint8_t*& in, int version)
#else
void gbSoundReadGame(int version, gzFile in)
#endif
{
// Prepare APU and default state
reset_apu();
gb_apu->save_state(&state.apu);

if (version > 11)
#ifdef __LIBRETRO__
utilReadDataMem(in, gb_state);
#else
utilReadData(in, gb_state);
else
gbSoundReadGameOld(version, in);
#endif

gb_apu->load_state(state.apu);
}
5 changes: 5 additions & 0 deletions src/gb/gbSound.h
Expand Up @@ -68,7 +68,12 @@ extern int SOUND_CLOCK_TICKS; // Number of 16.8 MHz clocks between calls to gbSo
extern int soundTicks; // Number of 16.8 MHz clocks until gbSoundTick() will be called

// Saves/loads emulator state
#ifdef __LIBRETRO__
void gbSoundSaveGame(uint8_t*&);
void gbSoundReadGame(const uint8_t*&, int);
#else
void gbSoundSaveGame(gzFile out);
void gbSoundReadGame(int version, gzFile in);
#endif

#endif // GBSOUND_H
2 changes: 1 addition & 1 deletion src/libretro/Makefile
@@ -1,6 +1,6 @@
TILED_RENDERING=0
STATIC_LINKING=0
FRONTEND_SUPPORTS_RGB565=0
FRONTEND_SUPPORTS_RGB565=1

SPACE :=
SPACE := $(SPACE) $(SPACE)
Expand Down
38 changes: 27 additions & 11 deletions src/libretro/Makefile.common
@@ -1,6 +1,22 @@
INCFLAGS := -I$(CORE_DIR)
SOURCES_CXX :=

SOURCES_CXX := $(CORE_DIR)/gba/GBA-thumb.cpp \
SOURCES_CXX += \
$(CORE_DIR)/libretro/libretro.cpp \
$(CORE_DIR)/libretro/UtilRetro.cpp \
$(CORE_DIR)/libretro/SoundRetro.cpp \
$(CORE_DIR)/libretro/scrc32.cpp

SOURCES_CXX += \
$(CORE_DIR)/apu/Gb_Oscs.cpp \
$(CORE_DIR)/apu/Gb_Apu_State.cpp \
$(CORE_DIR)/apu/Blip_Buffer.cpp \
$(CORE_DIR)/apu/Multi_Buffer.cpp \
$(CORE_DIR)/apu/Effects_Buffer.cpp \
$(CORE_DIR)/apu/Gb_Apu.cpp

SOURCES_CXX += \
$(CORE_DIR)/gba/GBA-thumb.cpp \
$(CORE_DIR)/gba/Sound.cpp \
$(CORE_DIR)/gba/Mode1.cpp \
$(CORE_DIR)/gba/CheatSearch.cpp \
Expand All @@ -20,13 +36,13 @@ SOURCES_CXX := $(CORE_DIR)/gba/GBA-thumb.cpp \
$(CORE_DIR)/gba/GBA.cpp \
$(CORE_DIR)/gba/EEprom.cpp \
$(CORE_DIR)/gba/RTC.cpp \
$(CORE_DIR)/gba/Sram.cpp \
$(CORE_DIR)/apu/Gb_Oscs.cpp \
$(CORE_DIR)/apu/Gb_Apu_State.cpp \
$(CORE_DIR)/apu/Blip_Buffer.cpp \
$(CORE_DIR)/apu/Multi_Buffer.cpp \
$(CORE_DIR)/apu/Gb_Apu.cpp \
$(CORE_DIR)/libretro/libretro.cpp \
$(CORE_DIR)/libretro/UtilRetro.cpp \
$(CORE_DIR)/libretro/SoundRetro.cpp \
$(CORE_DIR)/libretro/scrc32.cpp
$(CORE_DIR)/gba/Sram.cpp

SOURCES_CXX += \
$(CORE_DIR)/gb/gbCheats.cpp \
$(CORE_DIR)/gb/GB.cpp \
$(CORE_DIR)/gb/gbGfx.cpp \
$(CORE_DIR)/gb/gbGlobals.cpp \
$(CORE_DIR)/gb/gbMemory.cpp \
$(CORE_DIR)/gb/gbSGB.cpp \
$(CORE_DIR)/gb/gbSound.cpp
15 changes: 15 additions & 0 deletions src/libretro/UtilRetro.cpp
Expand Up @@ -108,6 +108,7 @@ bool utilIsGBAImage(const char* file)

bool utilIsGBImage(const char* file)
{
/*
FILE *fp;
bool ret = false;
char buffer[47];
Expand All @@ -121,6 +122,20 @@ bool utilIsGBImage(const char* file)
}
fclose (fp);
return ret;
*/
if (strlen(file) > 4) {
const char *p = strrchr(file, '.');

if (p != NULL) {
if ((_stricmp(p, ".dmg") == 0) || (_stricmp(p, ".gb") == 0)
|| (_stricmp(p, ".gbc") == 0) || (_stricmp(p, ".cgb") == 0)
|| (_stricmp(p, ".sgb") == 0)) {
return true;
}
}
}

return false;
}

// strip .gz or .z off end
Expand Down

0 comments on commit bf447bf

Please sign in to comment.