libretro: Use GB RTC data when available
- Save GB RTC data using retro_get_memory/size and only init using localtime when its unavailable (check is done in retro_run)
This commit is contained in:
parent
b3744b3bd5
commit
03184dd513
|
@ -195,6 +195,7 @@ int gbSynchronizeTicks = GBSYNCHRONIZE_CLOCK_TICKS;
|
|||
// emulator features
|
||||
int gbBattery = 0;
|
||||
int gbRumble = 0;
|
||||
int gbRTCPresent = 0;
|
||||
bool gbBatteryError = false;
|
||||
int gbCaptureNumber = 0;
|
||||
bool gbCapture = false;
|
||||
|
@ -4360,8 +4361,6 @@ bool gbUpdateSizes()
|
|||
memset(gbRam, gbRamFill, gbRamSize);
|
||||
}
|
||||
|
||||
gbBattery = gbRumble = 0;
|
||||
|
||||
switch (gbRomType) {
|
||||
case 0x03:
|
||||
case 0x06:
|
||||
|
@ -4377,6 +4376,9 @@ bool gbUpdateSizes()
|
|||
case 0xff:
|
||||
gbBattery = 1;
|
||||
break;
|
||||
default:
|
||||
gbBattery = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (gbRomType) {
|
||||
|
@ -4384,6 +4386,21 @@ bool gbUpdateSizes()
|
|||
case 0x1d:
|
||||
case 0x1e:
|
||||
gbRumble = 1;
|
||||
break;
|
||||
default:
|
||||
gbRumble = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (gbRomType) {
|
||||
case 0x0f:
|
||||
case 0x10: // mbc3
|
||||
case 0xfd: // tama5
|
||||
gbRTCPresent = 1;
|
||||
break;
|
||||
default:
|
||||
gbRTCPresent = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
gbInit();
|
||||
|
|
|
@ -62,6 +62,7 @@ bool allowColorizerHack(void);
|
|||
extern int gbHardware;
|
||||
extern int gbRomType; // gets type from header 0x147
|
||||
extern int gbBattery; // enabled when gbRamSize != 0
|
||||
extern int gbRTCPresent; // gbROM has RTC support
|
||||
|
||||
extern struct EmulatedSystem GBSystem;
|
||||
|
||||
|
|
|
@ -216,99 +216,76 @@ static void set_gbPalette(void)
|
|||
}
|
||||
}
|
||||
|
||||
static bool gb_hasrtc(void)
|
||||
static void* gb_rtcdata_prt(void)
|
||||
{
|
||||
switch (gbRomType) {
|
||||
case 0x0f:
|
||||
case 0x10: // MBC3 + extended
|
||||
case 0x13:
|
||||
return &gbDataMBC3.mapperSeconds;
|
||||
case 0xfd: // TAMA5 + extended
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void* gb_rtcdata_prt(void)
|
||||
{
|
||||
if (gb_hasrtc()) {
|
||||
switch (gbRomType) {
|
||||
case 0x0f:
|
||||
case 0x10: // MBC3 + extended
|
||||
return &gbDataMBC3.mapperSeconds;
|
||||
case 0x13:
|
||||
case 0xfd: // TAMA5 + extended
|
||||
return &gbDataTAMA5.mapperSeconds;
|
||||
}
|
||||
return &gbDataTAMA5.mapperSeconds;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static size_t gb_rtcdata_size(void)
|
||||
{
|
||||
if (gb_hasrtc()) {
|
||||
switch (gbRomType) {
|
||||
case 0x0f:
|
||||
case 0x10: // MBC3 + extended
|
||||
return MBC3_RTC_DATA_SIZE;
|
||||
break;
|
||||
case 0x13:
|
||||
case 0xfd: // TAMA5 + extended
|
||||
return TAMA5_RTC_DATA_SIZE;
|
||||
break;
|
||||
}
|
||||
switch (gbRomType) {
|
||||
case 0x0f:
|
||||
case 0x10: // MBC3 + extended
|
||||
return MBC3_RTC_DATA_SIZE;
|
||||
case 0xfd: // TAMA5 + extended
|
||||
return TAMA5_RTC_DATA_SIZE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gbUpdateRTC(void)
|
||||
static void gbInitRTC(void)
|
||||
{
|
||||
if (gb_hasrtc()) {
|
||||
struct tm* lt;
|
||||
time_t rawtime;
|
||||
time(&rawtime);
|
||||
lt = localtime(&rawtime);
|
||||
struct tm* lt;
|
||||
time_t rawtime;
|
||||
time(&rawtime);
|
||||
lt = localtime(&rawtime);
|
||||
|
||||
switch (gbRomType) {
|
||||
case 0x0f:
|
||||
case 0x10: {
|
||||
gbDataMBC3.mapperSeconds = lt->tm_sec;
|
||||
gbDataMBC3.mapperMinutes = lt->tm_min;
|
||||
gbDataMBC3.mapperHours = lt->tm_hour;
|
||||
gbDataMBC3.mapperDays = lt->tm_yday & 255;
|
||||
gbDataMBC3.mapperControl = (gbDataMBC3.mapperControl & 0xfe) | (lt->tm_yday > 255 ? 1 : 0);
|
||||
gbDataMBC3.mapperLastTime = rawtime;
|
||||
}
|
||||
break;
|
||||
case 0xfd: {
|
||||
uint8_t gbDaysinMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
gbDataTAMA5.mapperSeconds = lt->tm_sec;
|
||||
gbDataTAMA5.mapperMinutes = lt->tm_min;
|
||||
gbDataTAMA5.mapperHours = lt->tm_hour;
|
||||
gbDataTAMA5.mapperDays = 1;
|
||||
gbDataTAMA5.mapperMonths = 1;
|
||||
gbDataTAMA5.mapperYears = 1970;
|
||||
gbDataTAMA5.mapperLastTime = rawtime;
|
||||
int days = lt->tm_yday + 365 * 3;
|
||||
while (days) {
|
||||
gbDataTAMA5.mapperDays++;
|
||||
days--;
|
||||
if (gbDataTAMA5.mapperDays > gbDaysinMonth[gbDataTAMA5.mapperMonths - 1]) {
|
||||
gbDataTAMA5.mapperDays = 1;
|
||||
gbDataTAMA5.mapperMonths++;
|
||||
if (gbDataTAMA5.mapperMonths > 12) {
|
||||
gbDataTAMA5.mapperMonths = 1;
|
||||
gbDataTAMA5.mapperYears++;
|
||||
if ((gbDataTAMA5.mapperYears & 3) == 0)
|
||||
gbDaysinMonth[1] = 29;
|
||||
else
|
||||
gbDaysinMonth[1] = 28;
|
||||
}
|
||||
switch (gbRomType) {
|
||||
case 0x0f:
|
||||
case 0x10:
|
||||
gbDataMBC3.mapperSeconds = lt->tm_sec;
|
||||
gbDataMBC3.mapperMinutes = lt->tm_min;
|
||||
gbDataMBC3.mapperHours = lt->tm_hour;
|
||||
gbDataMBC3.mapperDays = lt->tm_yday & 255;
|
||||
gbDataMBC3.mapperControl = (gbDataMBC3.mapperControl & 0xfe) | (lt->tm_yday > 255 ? 1 : 0);
|
||||
gbDataMBC3.mapperLastTime = rawtime;
|
||||
break;
|
||||
case 0xfd: {
|
||||
uint8_t gbDaysinMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
int days = lt->tm_yday + 365 * 3;
|
||||
gbDataTAMA5.mapperSeconds = lt->tm_sec;
|
||||
gbDataTAMA5.mapperMinutes = lt->tm_min;
|
||||
gbDataTAMA5.mapperHours = lt->tm_hour;
|
||||
gbDataTAMA5.mapperDays = 1;
|
||||
gbDataTAMA5.mapperMonths = 1;
|
||||
gbDataTAMA5.mapperYears = 1970;
|
||||
gbDataTAMA5.mapperLastTime = rawtime;
|
||||
while (days) {
|
||||
gbDataTAMA5.mapperDays++;
|
||||
days--;
|
||||
if (gbDataTAMA5.mapperDays > gbDaysinMonth[gbDataTAMA5.mapperMonths - 1]) {
|
||||
gbDataTAMA5.mapperDays = 1;
|
||||
gbDataTAMA5.mapperMonths++;
|
||||
if (gbDataTAMA5.mapperMonths > 12) {
|
||||
gbDataTAMA5.mapperMonths = 1;
|
||||
gbDataTAMA5.mapperYears++;
|
||||
if ((gbDataTAMA5.mapperYears & 3) == 0)
|
||||
gbDaysinMonth[1] = 29;
|
||||
else
|
||||
gbDaysinMonth[1] = 28;
|
||||
}
|
||||
}
|
||||
gbDataTAMA5.mapperControl = (gbDataTAMA5.mapperControl & 0xfe) | (lt->tm_yday > 255 ? 1 : 0);
|
||||
}
|
||||
break;
|
||||
gbDataTAMA5.mapperControl = (gbDataTAMA5.mapperControl & 0xfe) | (lt->tm_yday > 255 ? 1 : 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -343,70 +320,91 @@ static void SetGBBorder(unsigned val)
|
|||
|
||||
void* retro_get_memory_data(unsigned id)
|
||||
{
|
||||
if (type == IMAGE_GBA) {
|
||||
void *data = NULL;
|
||||
|
||||
switch (type) {
|
||||
case IMAGE_GBA:
|
||||
switch (id) {
|
||||
case RETRO_MEMORY_SAVE_RAM:
|
||||
if ((saveType == GBA_SAVE_EEPROM) | (saveType == GBA_SAVE_EEPROM_SENSOR))
|
||||
return eepromData;
|
||||
if ((saveType == GBA_SAVE_SRAM) | (saveType == GBA_SAVE_FLASH))
|
||||
return flashSaveMemory;
|
||||
return NULL;
|
||||
data = eepromData;
|
||||
else if ((saveType == GBA_SAVE_SRAM) | (saveType == GBA_SAVE_FLASH))
|
||||
data = flashSaveMemory;
|
||||
break;
|
||||
case RETRO_MEMORY_SYSTEM_RAM:
|
||||
return workRAM;
|
||||
data = workRAM;
|
||||
break;
|
||||
case RETRO_MEMORY_VIDEO_RAM:
|
||||
return vram;
|
||||
data = vram;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (type == IMAGE_GB) {
|
||||
case IMAGE_GB:
|
||||
switch (id) {
|
||||
case RETRO_MEMORY_SAVE_RAM:
|
||||
if (gbBattery)
|
||||
return gbRam;
|
||||
return NULL;
|
||||
data = gbRam;
|
||||
break;
|
||||
case RETRO_MEMORY_SYSTEM_RAM:
|
||||
return (gbCgbMode ? gbWram : (gbMemory + 0xC000));
|
||||
data = (gbCgbMode ? gbWram : (gbMemory + 0xC000));
|
||||
break;
|
||||
case RETRO_MEMORY_VIDEO_RAM:
|
||||
return (gbCgbMode ? gbVram : (gbMemory + 0x8000));
|
||||
data = (gbCgbMode ? gbVram : (gbMemory + 0x8000));
|
||||
break;
|
||||
case RETRO_MEMORY_RTC:
|
||||
if (gbBattery && gbRTCPresent)
|
||||
data = gb_rtcdata_prt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
default: break;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
size_t retro_get_memory_size(unsigned id)
|
||||
{
|
||||
if (type == IMAGE_GBA) {
|
||||
size_t size = 0;
|
||||
|
||||
switch (type) {
|
||||
case IMAGE_GBA:
|
||||
switch (id) {
|
||||
case RETRO_MEMORY_SAVE_RAM:
|
||||
if ((saveType == GBA_SAVE_EEPROM) | (saveType == GBA_SAVE_EEPROM_SENSOR))
|
||||
return eepromSize;
|
||||
if (saveType == GBA_SAVE_FLASH)
|
||||
return flashSize;
|
||||
if (saveType == GBA_SAVE_SRAM)
|
||||
return SIZE_SRAM;
|
||||
return 0;
|
||||
size = eepromSize;
|
||||
else if (saveType == GBA_SAVE_FLASH)
|
||||
size = flashSize;
|
||||
else if (saveType == GBA_SAVE_SRAM)
|
||||
size = SIZE_SRAM;
|
||||
break;
|
||||
case RETRO_MEMORY_SYSTEM_RAM:
|
||||
return SIZE_WRAM;
|
||||
size = SIZE_WRAM;
|
||||
break;
|
||||
case RETRO_MEMORY_VIDEO_RAM:
|
||||
return SIZE_VRAM - 0x2000; // usuable vram is only 0x18000
|
||||
size = SIZE_VRAM - 0x2000; // usuable vram is only 0x18000
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (type == IMAGE_GB) {
|
||||
case IMAGE_GB:
|
||||
switch (id) {
|
||||
case RETRO_MEMORY_SAVE_RAM:
|
||||
if (gbBattery)
|
||||
return gbRamSize;
|
||||
return 0;
|
||||
size = gbRamSize;
|
||||
break;
|
||||
case RETRO_MEMORY_SYSTEM_RAM:
|
||||
return gbCgbMode ? 0x8000 : 0x2000;
|
||||
size = gbCgbMode ? 0x8000 : 0x2000;
|
||||
break;
|
||||
case RETRO_MEMORY_VIDEO_RAM:
|
||||
return gbCgbMode ? 0x4000 : 0x2000;
|
||||
size = gbCgbMode ? 0x4000 : 0x2000;
|
||||
break;
|
||||
case RETRO_MEMORY_RTC:
|
||||
size = gb_rtcdata_size();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
default: break;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
unsigned retro_api_version(void)
|
||||
|
@ -932,10 +930,6 @@ static void gb_init(void)
|
|||
gbReset(); // also resets sound;
|
||||
set_gbPalette();
|
||||
|
||||
// VBA-M always updates time based on current time and not in-game time.
|
||||
// No need to add RTC data to RETRO_MEMORY_RTC, so its safe to place this here.
|
||||
gbUpdateRTC();
|
||||
|
||||
log("Rom size : %02x (%dK)\n", gbRom[0x148], (romSize + 1023) / 1024);
|
||||
log("Cartridge type : %02x (%s)\n", gbRom[0x147], gbGetCartridgeType());
|
||||
log("Ram size : %02x (%s)\n", gbRom[0x149], gbGetSaveRamSize());
|
||||
|
@ -1368,12 +1362,37 @@ void updateInput_SolarSensor(void)
|
|||
}
|
||||
}
|
||||
|
||||
static bool firstrun = true;
|
||||
static unsigned has_frame;
|
||||
|
||||
void retro_run(void)
|
||||
{
|
||||
bool updated = false;
|
||||
|
||||
if (firstrun) {
|
||||
bool initRTC = false;
|
||||
firstrun = false;
|
||||
/* Check if GB game has RTC data. Has to be check here since this is where the data will be
|
||||
* available when using libretro api. */
|
||||
if ((type == IMAGE_GB) && gbRTCPresent) {
|
||||
switch (gbRomType) {
|
||||
case 0x0f:
|
||||
case 0x10:
|
||||
/* Check if any RTC has been loaded, zero value means nothing has been loaded. */
|
||||
if (!gbDataMBC3.mapperSeconds && !gbDataMBC3.mapperLSeconds && !gbDataMBC3.mapperLastTime)
|
||||
initRTC = true;
|
||||
break;
|
||||
case 0xfd:
|
||||
if (!gbDataTAMA5.mapperSeconds && !gbDataTAMA5.mapperLSeconds && !gbDataTAMA5.mapperLastTime)
|
||||
initRTC = true;
|
||||
break;
|
||||
}
|
||||
/* Initialize RTC using local time if needed */
|
||||
if (initRTC)
|
||||
gbInitRTC();
|
||||
}
|
||||
}
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated)
|
||||
update_variables(false);
|
||||
|
||||
|
@ -1384,9 +1403,8 @@ void retro_run(void)
|
|||
|
||||
has_frame = 0;
|
||||
|
||||
do {
|
||||
while (!has_frame)
|
||||
core->emuMain(core->emuCount);
|
||||
} while (!has_frame);
|
||||
}
|
||||
|
||||
static unsigned serialize_size = 0;
|
||||
|
|
Loading…
Reference in New Issue