Add multicart memory function, add sufami turbo to libsnes

This commit is contained in:
OV2 2012-01-06 20:13:16 +01:00
parent dee8895db2
commit 3368fd6883
3 changed files with 183 additions and 133 deletions

View File

@ -53,6 +53,21 @@ void snes_set_environment(snes_environment_t cb)
environ_cb = cb;
}
static void set_environ_timing()
{
if (environ_cb)
{
snes_system_timing timing;
timing.sample_rate = 32040.5;
if (!Settings.PAL)
timing.fps = 21477272.0 / 357366.0;
else
timing.fps = 21281370.0 / 425568.0;
environ_cb(SNES_ENVIRONMENT_SET_TIMING, &timing);
}
}
static void S9xAudioCallback(void*)
{
// Just pick a big buffer. We won't use it all.
@ -137,10 +152,20 @@ void snes_cheat_set(unsigned, bool, const char*)
{}
bool snes_load_cartridge_bsx_slotted(
const char *, const uint8_t *, unsigned,
const char *, const uint8_t *, unsigned
const char *, const uint8_t *rom_data, unsigned rom_size,
const char *, const uint8_t *bsx_data, unsigned bsx_size
)
{
int loaded = Memory.LoadMultiCartMem(rom_data, rom_size, bsx_data, bsx_size, NULL, NULL);
if (!loaded)
{
fprintf(stderr, "[libsnes]: Sufami Turbo Rom loading failed...\n");
return false;
}
set_environ_timing();
return false;
}
@ -153,12 +178,22 @@ bool snes_load_cartridge_bsx(
}
bool snes_load_cartridge_sufami_turbo(
const char *, const uint8_t *, unsigned,
const char *, const uint8_t *, unsigned,
const char *, const uint8_t *, unsigned
const char *, const uint8_t *rom_data, unsigned rom_size,
const char *, const uint8_t *sta_data, unsigned sta_size,
const char *, const uint8_t *stb_data, unsigned stb_size
)
{
return false;
int loaded = Memory.LoadMultiCartMem(sta_data, sta_size, stb_data, stb_size, rom_data, rom_size);
if (!loaded)
{
fprintf(stderr, "[libsnes]: Sufami Turbo Rom loading failed...\n");
return false;
}
set_environ_timing();
return true;
}
bool snes_load_cartridge_super_game_boy(
@ -435,17 +470,7 @@ bool snes_load_cartridge_normal(const char *, const uint8_t *rom_data, unsigned
return false;
}
if (environ_cb)
{
snes_system_timing timing;
timing.sample_rate = 32040.5;
if (!Settings.PAL)
timing.fps = 21477272.0 / 357366.0;
else
timing.fps = 21281370.0 / 425568.0;
environ_cb(SNES_ENVIRONMENT_SET_TIMING, &timing);
}
set_environ_timing();
return true;
}
@ -476,9 +501,13 @@ uint8_t* snes_get_memory_data(unsigned type)
uint8_t* data;
switch(type) {
case SNES_MEMORY_SUFAMI_TURBO_A_RAM:
case SNES_MEMORY_CARTRIDGE_RAM:
data = Memory.SRAM;
break;
case SNES_MEMORY_SUFAMI_TURBO_B_RAM:
data = Multi.sramB;
break;
case SNES_MEMORY_CARTRIDGE_RTC:
data = RTCData.reg;
break;
@ -515,11 +544,15 @@ unsigned snes_get_memory_size(unsigned type)
unsigned size;
switch(type) {
case SNES_MEMORY_SUFAMI_TURBO_A_RAM:
case SNES_MEMORY_CARTRIDGE_RAM:
size = (unsigned) (Memory.SRAMSize ? (1 << (Memory.SRAMSize + 3)) * 128 : 0);
if (size > 0x20000)
size = 0x20000;
break;
case SNES_MEMORY_SUFAMI_TURBO_B_RAM:
size = (unsigned) (Multi.cartType && Multi.sramSizeB ? (1 << (Multi.sramSizeB + 3)) * 128 : 0);
break;
case SNES_MEMORY_CARTRIDGE_RTC:
size = (Settings.SRTC || Settings.SPC7110RTC)?20:0;
break;

View File

@ -936,12 +936,12 @@ static void S9xDeinterleaveType1 (int, uint8 *);
static void S9xDeinterleaveType2 (int, uint8 *);
static void S9xDeinterleaveGD24 (int, uint8 *);
static bool8 allASCII (uint8 *, int);
static bool8 is_SufamiTurbo_BIOS (uint8 *, uint32);
static bool8 is_SufamiTurbo_Cart (uint8 *, uint32);
static bool8 is_SameGame_BIOS (uint8 *, uint32);
static bool8 is_SameGame_Add_On (uint8 *, uint32);
static bool8 is_GNEXT_BIOS (uint8 *, uint32);
static bool8 is_GNEXT_Add_On (uint8 *, uint32);
static bool8 is_SufamiTurbo_BIOS (const uint8 *, uint32);
static bool8 is_SufamiTurbo_Cart (const uint8 *, uint32);
static bool8 is_SameGame_BIOS (const uint8 *, uint32);
static bool8 is_SameGame_Add_On (const uint8 *, uint32);
static bool8 is_GNEXT_BIOS (const uint8 *, uint32);
static bool8 is_GNEXT_Add_On (const uint8 *, uint32);
static uint32 caCRC32 (uint8 *, uint32, uint32 crc32 = 0xffffffff);
static uint32 ReadUPSPointer (const uint8 *, unsigned &, unsigned);
static bool8 ReadUPSPatch (Stream *, long, int32 &);
@ -1206,7 +1206,7 @@ static bool8 allASCII (uint8 *b, int size)
return (TRUE);
}
static bool8 is_SufamiTurbo_BIOS (uint8 *data, uint32 size)
static bool8 is_SufamiTurbo_BIOS (const uint8 *data, uint32 size)
{
if (size == 0x40000 &&
strncmp((char *) data, "BANDAI SFC-ADX", 14) == 0 && strncmp((char * ) (data + 0x10), "SFC-ADX BACKUP", 14) == 0)
@ -1215,7 +1215,7 @@ static bool8 is_SufamiTurbo_BIOS (uint8 *data, uint32 size)
return (FALSE);
}
static bool8 is_SufamiTurbo_Cart (uint8 *data, uint32 size)
static bool8 is_SufamiTurbo_Cart (const uint8 *data, uint32 size)
{
if (size >= 0x80000 && size <= 0x100000 &&
strncmp((char *) data, "BANDAI SFC-ADX", 14) == 0 && strncmp((char * ) (data + 0x10), "SFC-ADX BACKUP", 14) != 0)
@ -1224,7 +1224,7 @@ static bool8 is_SufamiTurbo_Cart (uint8 *data, uint32 size)
return (FALSE);
}
static bool8 is_SameGame_BIOS (uint8 *data, uint32 size)
static bool8 is_SameGame_BIOS (const uint8 *data, uint32 size)
{
if (size == 0x100000 && strncmp((char *) (data + 0xffc0), "Same Game Tsume Game", 20) == 0)
return (TRUE);
@ -1232,7 +1232,7 @@ static bool8 is_SameGame_BIOS (uint8 *data, uint32 size)
return (FALSE);
}
static bool8 is_SameGame_Add_On (uint8 *data, uint32 size)
static bool8 is_SameGame_Add_On (const uint8 *data, uint32 size)
{
if (size == 0x80000)
return (TRUE);
@ -1240,7 +1240,7 @@ static bool8 is_SameGame_Add_On (uint8 *data, uint32 size)
return (FALSE);
}
static bool8 is_GNEXT_BIOS (uint8 *data, uint32 size)
static bool8 is_GNEXT_BIOS (const uint8 *data, uint32 size)
{
if (size == 0x180000 && strncmp((char *) (data + 0x7fc0), "SFC SDGUNDAMGNEXT", 17) == 0)
return (TRUE);
@ -1248,7 +1248,7 @@ static bool8 is_GNEXT_BIOS (uint8 *data, uint32 size)
return (FALSE);
}
static bool8 is_GNEXT_Add_On (uint8 *data, uint32 size)
static bool8 is_GNEXT_Add_On (const uint8 *data, uint32 size)
{
if (size == 0x80000)
return (TRUE);
@ -1543,6 +1543,9 @@ bool8 CMemory::LoadROM (const char *filename)
if (!totalFileSize)
return (FALSE);
if (!Settings.NoPatch)
CheckForAnyPatch(filename, HeaderCount != 0, totalFileSize);
}
while(!LoadROMInt(totalFileSize));
@ -1557,9 +1560,6 @@ bool8 CMemory::LoadROMInt (int32 ROMfillSize)
CalculatedSize = 0;
ExtendedFormat = NOPE;
if (!Settings.NoPatch)
CheckForAnyPatch(ROMFilename, HeaderCount != 0, ROMfillSize);
int hi_score, lo_score;
hi_score = ScoreHiROM(FALSE);
@ -1766,60 +1766,144 @@ bool8 CMemory::LoadROMInt (int32 ROMfillSize)
return (TRUE);
}
bool8 CMemory::LoadMultiCartMem (const uint8 *sourceA, uint32 sourceASize,
const uint8 *sourceB, uint32 sourceBSize,
const uint8 *bios, uint32 biosSize)
{
uint32 offset = 0;
ZeroMemory(ROM, MAX_ROM_SIZE);
ZeroMemory(&Multi, sizeof(Multi));
if(bios) {
if(!is_SufamiTurbo_BIOS(bios,biosSize))
return FALSE;
memcpy(ROM,bios,biosSize);
offset+=biosSize;
}
if(sourceA) {
memcpy(ROM + offset,sourceA,sourceASize);
Multi.cartOffsetA = offset;
Multi.cartSizeA = sourceASize;
offset += sourceASize;
strcpy(Multi.fileNameA,"MemCartA");
}
if(sourceB) {
memcpy(ROM + offset,sourceB,sourceBSize);
Multi.cartOffsetB = offset;
Multi.cartSizeB = sourceBSize;
offset += sourceBSize;
strcpy(Multi.fileNameB,"MemCartB");
}
return LoadMultiCartInt();
}
bool8 CMemory::LoadMultiCart (const char *cartA, const char *cartB)
{
bool8 r = TRUE;
ZeroMemory(ROM, MAX_ROM_SIZE);
ZeroMemory(ROM, MAX_ROM_SIZE);
ZeroMemory(&Multi, sizeof(Multi));
Settings.DisplayColor = BUILD_PIXEL(31, 31, 31);
SET_UI_COLOR(255, 255, 255);
CalculatedSize = 0;
ExtendedFormat = NOPE;
if (cartB && cartB[0])
Multi.cartSizeB = FileLoader(ROM, cartB, MAX_ROM_SIZE);
if (Multi.cartSizeB) {
strcpy(Multi.fileNameB, cartB);
if(!Settings.NoPatch)
CheckForAnyPatch(cartB, HeaderCount != 0, Multi.cartSizeB);
Multi.cartOffsetB = 0x400000;
memcpy(ROM + Multi.cartOffsetB,ROM,Multi.cartSizeB);
}
if (cartA && cartA[0])
Multi.cartSizeA = FileLoader(ROM, cartA, MAX_ROM_SIZE);
if (Multi.cartSizeA == 0)
{
if (cartB && cartB[0])
Multi.cartSizeB = FileLoader(ROM, cartB, MAX_ROM_SIZE);
}
if (Multi.cartSizeA) {
strcpy(Multi.fileNameA, cartA);
if(!Settings.NoPatch)
CheckForAnyPatch(cartA, HeaderCount != 0, Multi.cartSizeA);
}
return LoadMultiCartInt();
}
bool8 CMemory::LoadMultiCartInt ()
{
bool8 r = TRUE;
CalculatedSize = 0;
ExtendedFormat = NOPE;
if (Multi.cartSizeA)
{
if (is_SufamiTurbo_Cart(ROM, Multi.cartSizeA))
if (is_SufamiTurbo_Cart(ROM + Multi.cartOffsetA, Multi.cartSizeA))
Multi.cartType = 4;
else
if (is_SameGame_BIOS(ROM, Multi.cartSizeA))
if (is_SameGame_BIOS(ROM + Multi.cartOffsetA, Multi.cartSizeA))
Multi.cartType = 3;
else
if (is_GNEXT_BIOS(ROM, Multi.cartSizeA))
if (is_GNEXT_BIOS(ROM + Multi.cartOffsetA, Multi.cartSizeA))
Multi.cartType = 5;
}
else
if (Multi.cartSizeB)
{
if (is_SufamiTurbo_Cart(ROM, Multi.cartSizeB))
if (is_SufamiTurbo_Cart(ROM + Multi.cartOffsetB, Multi.cartSizeB))
Multi.cartType = 4;
}
else
Multi.cartType = 4; // assuming BIOS only
if(Multi.cartType == 4 && Multi.cartOffsetA == 0) { // try to load bios from file
Multi.cartOffsetA = 0x40000;
if(Multi.cartSizeA)
memmove(ROM + Multi.cartOffsetA,ROM,Multi.cartOffsetB - Multi.cartOffsetA);
else // clear cart A so the bios can detect that it's not present
memset(ROM,0,Multi.cartOffsetB);
FILE *fp;
size_t size;
char path[PATH_MAX + 1];
strcpy(path, S9xGetDirectory(BIOS_DIR));
strcat(path, SLASH_STR);
strcat(path, "STBIOS.bin");
fp = fopen(path, "rb");
if (fp)
{
size = fread((void *) ROM, 1, 0x40000, fp);
fclose(fp);
if (!is_SufamiTurbo_BIOS(ROM, size))
return (FALSE);
}
else
return (FALSE);
strcpy(ROMFilename, path);
}
switch (Multi.cartType)
{
case 4:
r = LoadSufamiTurbo(cartA, cartB);
r = LoadSufamiTurbo();
break;
case 3:
r = LoadSameGame(cartA, cartB);
r = LoadSameGame();
break;
case 5:
r = LoadGNEXT(cartA, cartB);
r = LoadGNEXT();
break;
default:
@ -1832,6 +1916,12 @@ bool8 CMemory::LoadMultiCart (const char *cartA, const char *cartB)
return (FALSE);
}
if (Multi.cartSizeA)
strcpy(ROMFilename, Multi.fileNameA);
else
if (Multi.cartSizeB)
strcpy(ROMFilename, Multi.fileNameB);
ZeroMemory(&SNESGameFixes, sizeof(SNESGameFixes));
SNESGameFixes.SRAMInitialValue = 0x60;
@ -1847,10 +1937,8 @@ bool8 CMemory::LoadMultiCart (const char *cartA, const char *cartB)
return (TRUE);
}
bool8 CMemory::LoadSufamiTurbo (const char *cartA, const char *cartB)
bool8 CMemory::LoadSufamiTurbo ()
{
Multi.cartOffsetA = 0x100000;
Multi.cartOffsetB = 0x200000;
Multi.sramA = SRAM;
Multi.sramB = SRAM + 0x10000;
@ -1858,65 +1946,20 @@ bool8 CMemory::LoadSufamiTurbo (const char *cartA, const char *cartB)
{
Multi.sramSizeA = 4; // ROM[0x37]?
Multi.sramMaskA = Multi.sramSizeA ? ((1 << (Multi.sramSizeA + 3)) * 128 - 1) : 0;
if (!Settings.NoPatch)
CheckForAnyPatch(cartA, HeaderCount != 0, Multi.cartSizeA);
strcpy(Multi.fileNameA, cartA);
memcpy(ROM + Multi.cartOffsetA, ROM, Multi.cartSizeA);
}
if (Multi.cartSizeA && !Multi.cartSizeB)
if (Multi.cartSizeB)
{
if (cartB && cartB[0])
Multi.cartSizeB = FileLoader(ROM, cartB, MAX_ROM_SIZE);
if (Multi.cartSizeB)
{
if (!is_SufamiTurbo_Cart(ROM, Multi.cartSizeB))
Multi.cartSizeB = 0;
}
if (!is_SufamiTurbo_Cart(ROM + Multi.cartOffsetB, Multi.cartSizeB))
Multi.cartSizeB = 0;
}
if (Multi.cartSizeB)
{
Multi.sramSizeB = 4; // ROM[0x37]?
Multi.sramMaskB = Multi.sramSizeB ? ((1 << (Multi.sramSizeB + 3)) * 128 - 1) : 0;
if (!Settings.NoPatch)
CheckForAnyPatch(cartB, HeaderCount != 0, Multi.cartSizeB);
strcpy(Multi.fileNameB, cartB);
memcpy(ROM + Multi.cartOffsetB, ROM, Multi.cartSizeB);
}
FILE *fp;
size_t size;
char path[PATH_MAX + 1];
strcpy(path, S9xGetDirectory(BIOS_DIR));
strcat(path, SLASH_STR);
strcat(path, "STBIOS.bin");
fp = fopen(path, "rb");
if (fp)
{
size = fread((void *) ROM, 1, 0x40000, fp);
fclose(fp);
if (!is_SufamiTurbo_BIOS(ROM, size))
return (FALSE);
}
else
return (FALSE);
if (Multi.cartSizeA)
strcpy(ROMFilename, Multi.fileNameA);
else
if (Multi.cartSizeB)
strcpy(ROMFilename, Multi.fileNameB);
else
strcpy(ROMFilename, path);
LoROM = TRUE;
HiROM = FALSE;
CalculatedSize = 0x40000;
@ -1924,10 +1967,8 @@ bool8 CMemory::LoadSufamiTurbo (const char *cartA, const char *cartB)
return (TRUE);
}
bool8 CMemory::LoadSameGame (const char *cartA, const char *cartB)
bool8 CMemory::LoadSameGame ()
{
Multi.cartOffsetA = 0;
Multi.cartOffsetB = 0x200000;
Multi.sramA = SRAM;
Multi.sramB = NULL;
@ -1936,24 +1977,12 @@ bool8 CMemory::LoadSameGame (const char *cartA, const char *cartB)
Multi.sramSizeB = 0;
Multi.sramMaskB = 0;
if (!Settings.NoPatch)
CheckForAnyPatch(cartA, HeaderCount != 0, Multi.cartSizeA);
strcpy(Multi.fileNameA, cartA);
if (cartB && cartB[0])
Multi.cartSizeB = FileLoader(ROM + Multi.cartOffsetB, cartB, MAX_ROM_SIZE - Multi.cartOffsetB);
if (Multi.cartSizeB)
{
if (!is_SameGame_Add_On(ROM + Multi.cartOffsetB, Multi.cartSizeB))
Multi.cartSizeB = 0;
else
strcpy(Multi.fileNameB, cartB);
}
strcpy(ROMFilename, Multi.fileNameA);
LoROM = FALSE;
HiROM = TRUE;
CalculatedSize = Multi.cartSizeA;
@ -1961,10 +1990,8 @@ bool8 CMemory::LoadSameGame (const char *cartA, const char *cartB)
return (TRUE);
}
bool8 CMemory::LoadGNEXT (const char *cartA, const char *cartB)
bool8 CMemory::LoadGNEXT ()
{
Multi.cartOffsetA = 0;
Multi.cartOffsetB = 0x400000;
Multi.sramA = SRAM;
Multi.sramB = NULL;
@ -1973,24 +2000,12 @@ bool8 CMemory::LoadGNEXT (const char *cartA, const char *cartB)
Multi.sramSizeB = 0;
Multi.sramMaskB = 0;
if (!Settings.NoPatch)
CheckForAnyPatch(cartA, HeaderCount != 0, Multi.cartSizeA);
strcpy(Multi.fileNameA, cartA);
if (cartB && cartB[0])
Multi.cartSizeB = FileLoader(ROM + Multi.cartOffsetB, cartB, MAX_ROM_SIZE - Multi.cartOffsetB);
if (Multi.cartSizeB)
{
if (!is_GNEXT_Add_On(ROM + Multi.cartOffsetB, Multi.cartSizeB))
Multi.cartSizeB = 0;
else
strcpy(Multi.fileNameB, cartB);
}
strcpy(ROMFilename, Multi.fileNameA);
LoROM = TRUE;
HiROM = FALSE;
CalculatedSize = Multi.cartSizeA;

View File

@ -277,10 +277,12 @@ struct CMemory
bool8 LoadROMMem (const uint8 *, uint32);
bool8 LoadROM (const char *);
bool8 LoadROMInt (int32);
bool8 LoadMultiCartMem (const uint8 *, uint32, const uint8 *, uint32, const uint8 *, uint32);
bool8 LoadMultiCart (const char *, const char *);
bool8 LoadSufamiTurbo (const char *, const char *);
bool8 LoadSameGame (const char *, const char *);
bool8 LoadGNEXT (const char *, const char *);
bool8 LoadMultiCartInt ();
bool8 LoadSufamiTurbo ();
bool8 LoadSameGame ();
bool8 LoadGNEXT ();
bool8 LoadSRAM (const char *);
bool8 SaveSRAM (const char *);
void ClearSRAM (bool8 onlyNonSavedSRAM = 0);