Merge branch 'finalburnneo-master'

This commit is contained in:
barbudreadmon 2024-11-15 11:29:11 +01:00
commit c4adb97a41
13 changed files with 365 additions and 104 deletions

View File

@ -102,7 +102,7 @@ drvsrc = d_akkaarrh.o d_arcadecl.o d_atarig1.o d_badlands.o d_batman.o d_blstro
d_spectrum.o
depobj = burn.o burn_bitmap.o burn_gun.o burn_led.o burn_shift.o burn_memory.o burn_pal.o burn_sound.o burn_sound_c.o cheat.o debug_track.o hiscore.o \
load.o tilemap_generic.o tiles_generic.o timer.o vector.o \
load.o burn_sha1.o tilemap_generic.o tiles_generic.o timer.o vector.o \
\
6821pia.o 6840ptm.o 8255ppi.o 8257dma.o c169.o atariic.o atarijsa.o atarimo.o atarirle.o atarivad.o avgdvg.o bsmt2000.o decobsmt.o ds2404.o dtimer.o earom.o eeprom.o epic12.o gaelco_crypt.o i4x00.o intelfsh.o \
joyprocess.o nb1414m4.o nb1414m4_8bit.o nmk004.o nmk112.o k1ge.o kaneko_hit.o kaneko_tmap.o mathbox.o mb87078.o mermaid.o midcsd.o midsat.o midsg.o midcvsd.o midssio.o midtcs.o \

View File

@ -464,6 +464,11 @@ extern bool bDoIpsPatch;
void IpsApplyPatches(UINT8* base, char* rom_name, UINT32 rom_crc, bool readonly = false);
// ---------------------------------------------------------------------------
// MISC Helper / utility functions, etc
int BurnComputeSHA1(const UINT8 *buffer, int buffer_size, char *hash_str);
//int BurnComputeSHA1(const char *filename, char *hash_str);
// ---------------------------------------------------------------------------
// Flags used with the Burndriver structure

166
src/burn/burn_sha1.cpp Normal file
View File

@ -0,0 +1,166 @@
#include "burnint.h"
#include <stdint.h>
#define SHA1_BLOCK_SIZE 64
#define SHA1_HASH_SIZE 20
struct sha1_state {
UINT32 state[5];
UINT64 bitcount;
UINT8 buffer[SHA1_BLOCK_SIZE];
};
#define ROTLEFT(a, b) (((a) << (b)) | ((a) >> (32 - (b))))
#define F0(b, c, d) ((b & c) | (~b & d))
#define F1(b, c, d) (b ^ c ^ d)
#define F2(b, c, d) ((b & c) | (b & d) | (c & d))
#define F3(b, c, d) (b ^ c ^ d)
void SHA1_Transform(sha1_state *ctx, const UINT8 *data) {
UINT32 a, b, c, d, e, i, t;
UINT32 m[80];
for (i = 0; i < 16; i++) {
m[i] = (data[i * 4] << 24) | (data[i * 4 + 1] << 16) |
(data[i * 4 + 2] << 8) | (data[i * 4 + 3]);
}
for (i = 16; i < 80; i++) {
m[i] = ROTLEFT(m[i - 3] ^ m[i - 8] ^ m[i - 14] ^ m[i - 16], 1);
}
a = ctx->state[0];
b = ctx->state[1];
c = ctx->state[2];
d = ctx->state[3];
e = ctx->state[4];
for (i = 0; i < 80; i++) {
if (i < 20) {
t = ROTLEFT(a, 5) + F0(b, c, d) + e + m[i] + 0x5A827999;
} else if (i < 40) {
t = ROTLEFT(a, 5) + F1(b, c, d) + e + m[i] + 0x6ED9EBA1;
} else if (i < 60) {
t = ROTLEFT(a, 5) + F2(b, c, d) + e + m[i] + 0x8F1BBCDC;
} else {
t = ROTLEFT(a, 5) + F3(b, c, d) + e + m[i] + 0xCA62C1D6;
}
e = d;
d = c;
c = ROTLEFT(b, 30);
b = a;
a = t;
}
ctx->state[0] += a;
ctx->state[1] += b;
ctx->state[2] += c;
ctx->state[3] += d;
ctx->state[4] += e;
}
void SHA1_Init(sha1_state *ctx) {
ctx->state[0] = 0x67452301;
ctx->state[1] = 0xEFCDAB89;
ctx->state[2] = 0x98BADCFE;
ctx->state[3] = 0x10325476;
ctx->state[4] = 0xC3D2E1F0;
ctx->bitcount = 0;
memset(ctx->buffer, 0, SHA1_BLOCK_SIZE);
}
void SHA1_Update(sha1_state *ctx, const UINT8 *data, INT32 len) {
INT32 i;
for (i = 0; i < len; i++) {
ctx->buffer[ctx->bitcount / 8 % SHA1_BLOCK_SIZE] = data[i];
ctx->bitcount += 8;
if ((ctx->bitcount / 8 % SHA1_BLOCK_SIZE) == 0) {
SHA1_Transform(ctx, ctx->buffer);
}
}
}
void SHA1_Final(UINT8 *hash, sha1_state *ctx) {
INT32 i = ctx->bitcount / 8 % SHA1_BLOCK_SIZE;
ctx->buffer[i++] = 0x80;
if (i > SHA1_BLOCK_SIZE - 8) {
while (i < SHA1_BLOCK_SIZE) {
ctx->buffer[i++] = 0;
}
SHA1_Transform(ctx, ctx->buffer);
i = 0;
}
while (i < SHA1_BLOCK_SIZE - 8) {
ctx->buffer[i++] = 0;
}
for (int j = 0; j < 8; j++) {
ctx->buffer[SHA1_BLOCK_SIZE - 1 - j] = ctx->bitcount >> (j * 8);
}
SHA1_Transform(ctx, ctx->buffer);
for (i = 0; i < 5; i++) {
hash[i * 4 + 0] = (ctx->state[i] >> 24) & 0xff;
hash[i * 4 + 1] = (ctx->state[i] >> 16) & 0xff;
hash[i * 4 + 2] = (ctx->state[i] >> 8) & 0xff;
hash[i * 4 + 3] = (ctx->state[i]) & 0xff;
}
}
int BurnComputeSHA1(const UINT8 *buffer, int buffer_size, char *hash_str) {
sha1_state ctx;
UINT8 hash[SHA1_HASH_SIZE];
SHA1_Init(&ctx);
SHA1_Update(&ctx, buffer, buffer_size);
SHA1_Final(hash, &ctx);
for (int i = 0; i < SHA1_HASH_SIZE; i++) {
char temp[128];
sprintf(temp, "%02x", hash[i]);
hash_str[i*2 + 0] = temp[0];
hash_str[i*2 + 1] = temp[1];
}
hash_str[SHA1_HASH_SIZE*2] = 0;
return 0;
}
int BurnComputeSHA1(const char *filename, char *hash_str) {
sha1_state ctx;
UINT8 hash[SHA1_HASH_SIZE];
const int filebuf_size = 1024 * 1024;
UINT8 *buffer;
FILE *file = fopen(filename, "rb");
if (!file) {
return 1;
}
buffer = (UINT8*)malloc(filebuf_size);
if (!buffer) return 2;
SHA1_Init(&ctx);
INT32 bytes_read;
while ((bytes_read = fread(buffer, 1, filebuf_size, file)) > 0) {
SHA1_Update(&ctx, buffer, bytes_read);
}
fclose(file);
free(buffer);
SHA1_Final(hash, &ctx);
for (int i = 0; i < SHA1_HASH_SIZE; i++) {
char temp[128];
sprintf(temp, "%02x", hash[i]);
hash_str[i*2 + 0] = temp[0];
hash_str[i*2 + 1] = temp[1];
}
hash_str[SHA1_HASH_SIZE*2] = 0;
return 0;
}

View File

@ -5,7 +5,8 @@
#define CHEAT_MAXCPU 8 // enough?
#define HW_NES ( ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_NES) || ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_FDS) )
// any system that uses Game Genie/Pro Action Replay codes can be defined as HW_NES...
#define HW_NES ( ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_SNES) || ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_NES) || ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_FDS) )
void (*nes_add_cheat)(char *) = NULL;
void (*nes_remove_cheat)(char *) = NULL;

View File

@ -47830,6 +47830,26 @@ struct BurnDriver BurnDrvmd_btomatog = {
&bMegadriveRecalcPalette, 0x100, 320, 224, 4, 3
};
// Bishoujo Super Street Fighter II: Glamor Queen (Hack, v1.6)
// https://romhackplaza.org/romhacks/bishoujo-super-street-fighter-ii-glamor-queen-genesis/
static struct BurnRomInfo md_bssf2gqRomDesc[] = {
{ "Bishoujo Super Street Fighter II - Glamor Queen v1.6 (2024)(Yoni Arousement).bin", 0x500000, 0x87a6c750, BRF_PRG | SEGA_MD_ROM_LOAD16_WORD_SWAP | SEGA_MD_ROM_OFFS_000000 },
};
STD_ROM_PICK(md_bssf2gq)
STD_ROM_FN(md_bssf2gq)
struct BurnDriver BurnDrvmd_bssf2gq = {
"md_bssf2gq", "md_ssf2", NULL, NULL, "2024",
"Bishoujo Super Street Fighter II: Glamor Queen (Hack, v1.6)\0", NULL, "hack (Yoni Arousement)", "Sega Megadrive",
NULL, NULL, NULL, NULL,
BDF_GAME_WORKING | BDF_16BIT_ONLY | BDF_CLONE, 2, HARDWARE_SEGA_MEGADRIVE | HARDWARE_SEGA_MEGADRIVE_PCB_SSF2, GBF_VSFIGHT, 0,
MegadriveGetZipName, md_bssf2gqRomInfo, md_bssf2gqRomName, NULL, NULL, NULL, NULL, MegadriveInputInfo, MegadriveDIPInfo,
MegadriveInit, MegadriveExit, MegadriveFrame, MegadriveDraw, MegadriveScan,
&bMegadriveRecalcPalette, 0x100, 320, 224, 4, 3
};
// Cadash (Hack, Arcade Colors)
// http://www.romhacking.net/hacks/3905/
static struct BurnRomInfo md_cadashacRomDesc[] = {
@ -52547,18 +52567,18 @@ struct BurnDriver BurnDrvmd_mkae = {
&bMegadriveRecalcPalette, 0x100, 320, 224, 4, 3
};
// Mortal Kombat Arcade Edition (Hack)
// https://www.romhacking.net/reviews/9714/
// Mortal Kombat Arcade Edition (Hack, v2.1)
// https://romhackplaza.org/romhacks/mortal-kombat-arcade-edition-enhanced-genesis-2/
static struct BurnRomInfo md_mkaeeRomDesc[] = {
{ "Mortal Kombat Arcade Edition Enhanced v1.5 (2022)(Rael G.C.).bin", 4194304, 0xb884890b, BRF_PRG | SEGA_MD_ROM_LOAD16_WORD_SWAP | SEGA_MD_ROM_OFFS_000000 },
{ "Mortal Kombat Arcade Edition Enhanced v2.1 (2024)(Rael G.C.).bin", 4194304, 0x486979c5, BRF_PRG | SEGA_MD_ROM_LOAD16_WORD_SWAP | SEGA_MD_ROM_OFFS_000000 },
};
STD_ROM_PICK(md_mkaee)
STD_ROM_FN(md_mkaee)
struct BurnDriver BurnDrvmd_mkaee = {
"md_mkaee", "md_mk", NULL, NULL, "2022",
"Mortal Kombat Arcade Edition Enhanced (Hack, v1.5)\0", NULL, "Rael G.C.", "Sega Megadrive",
"md_mkaee", "md_mk", NULL, NULL, "2024",
"Mortal Kombat Arcade Edition Enhanced (Hack, v2.1)\0", NULL, "Rael G.C.", "Sega Megadrive",
NULL, NULL, NULL, NULL,
BDF_GAME_WORKING | BDF_16BIT_ONLY | BDF_CLONE | BDF_HACK, 2, HARDWARE_SEGA_MEGADRIVE, GBF_VSFIGHT, 0,
MegadriveGetZipName, md_mkaeeRomInfo, md_mkaeeRomName, NULL, NULL, NULL, NULL, MegadriveInputInfo, MegadriveDIPInfo,

View File

@ -14132,7 +14132,7 @@ struct BurnDriver BurnDrvMSX_gundamk = {
// Mokari Makka? Bochibochi Denna! (Japan)
static struct BurnRomInfo MSX_mokarimaRomDesc[] = {
{ "Mokari Makka? Bochibochi Denna! (Japan)(1986)(Leben Pro).rom", 0x08000, 0xd40f481d, BRF_PRG | BRF_ESS },
{ "Mokari Makka Bochibochi Denna! (Japan)(1986)(Leben Pro).rom", 0x08000, 0xd40f481d, BRF_PRG | BRF_ESS },
};
STDROMPICKEXT(MSX_mokarima, MSX_mokarima, msx_msx)

View File

@ -10975,7 +10975,7 @@ static INT32 gg_decode(char *gg_code, UINT16 &address, UINT8 &value, INT32 &comp
return 0;
}
const INT32 cheat_MAX = 0x100;
static const INT32 cheat_MAX = 0x100;
static INT32 cheats_active = 0;
struct cheat_struct {
@ -10987,7 +10987,7 @@ struct cheat_struct {
static cheat_struct cheats[cheat_MAX];
void nes_add_cheat(char *code) // 6/8 character game genie codes allowed
static void nes_add_cheat(char *code) // 6/8 character game genie codes allowed
{
UINT16 address;
UINT8 value;
@ -11009,7 +11009,7 @@ void nes_add_cheat(char *code) // 6/8 character game genie codes allowed
}
}
void nes_remove_cheat(char *code)
static void nes_remove_cheat(char *code)
{
cheat_struct cheat_temp[cheat_MAX];
INT32 temp_num = 0;
@ -11192,6 +11192,12 @@ static INT32 NESInit()
if (fds_load(rom, ri.nLen, ri.nCrc)) return 1;
} else {
if (BurnLoadRom(rom, 0, 1)) return 1;
// sha1 hash
char hash_potato[128] = { 0, };
BurnComputeSHA1(rom + 0x10, ri.nLen - 0x10, hash_potato);
bprintf(0, _T("sha1 hash: [%S]\n"), hash_potato);
if (cartridge_load(rom, ri.nLen, ri.nCrc)) return 1;
}
@ -28056,10 +28062,10 @@ struct BurnDriver BurnDrvnes_marioadventure = {
SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT
};
// Mario Adventure 3 (Hack, v1.9.8)
// Mario Adventure 3 (Hack, v1.9.9)
// https://marioadventure3.com/
static struct BurnRomInfo nes_marioadventure3RomDesc[] = {
{ "Mario Adventure 3 v1.9.8 (2024)(ScarlettVixen).nes", 786448, 0x494115ef, BRF_ESS | BRF_PRG },
{ "Mario Adventure 3 v1.9.9 (2024)(ScarlettVixen).nes", 786448, 0x0bf1b61c, BRF_ESS | BRF_PRG },
};
STD_ROM_PICK(nes_marioadventure3)
@ -28067,7 +28073,7 @@ STD_ROM_FN(nes_marioadventure3)
struct BurnDriver BurnDrvnes_marioadventure3 = {
"nes_marioadventure3", "nes_smb3", NULL, NULL, "2024",
"Mario Adventure 3 (Hack, v1.9.8)\0", NULL, "ScarlettVixen", "Miscellaneous",
"Mario Adventure 3 (Hack, v1.9.9)\0", NULL, "ScarlettVixen", "Miscellaneous",
NULL, NULL, NULL, NULL,
BDF_GAME_WORKING | BDF_CLONE | BDF_HACK, 1, HARDWARE_NES, GBF_PLATFORM, 0,
NESGetZipName, nes_marioadventure3RomInfo, nes_marioadventure3RomName, NULL, NULL, NULL, NULL, NESInputInfo, NESDIPInfo,
@ -28800,9 +28806,9 @@ struct BurnDriver BurnDrvnes_multidudee = {
SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT
};
// Murder in the Maze (HB)
// Murder in the Maze (HB, v1.01)
static struct BurnRomInfo nes_murdmazeRomDesc[] = {
{ "Murder in the Maze (2024)(T1LT).nes", 524304, 0xbaac5e32, BRF_ESS | BRF_PRG },
{ "Murder in the Maze v1.01 (2024)(T1LT).nes", 524304, 0xbaac5e32, BRF_ESS | BRF_PRG },
};
STD_ROM_PICK(nes_murdmaze)
@ -28810,7 +28816,7 @@ STD_ROM_FN(nes_murdmaze)
struct BurnDriver BurnDrvnes_murdmaze = {
"nes_murdmaze", NULL, NULL, NULL, "2024",
"Murder in the Maze (HB)\0", NULL, "T1LT", "Miscellaneous",
"Murder in the Maze (HB, v1.01)\0", NULL, "T1LT", "Miscellaneous",
NULL, NULL, NULL, NULL,
BDF_GAME_WORKING | BDF_HOMEBREW, 1, HARDWARE_NES, GBF_ADV | GBF_MINIGAMES, 0,
NESGetZipName, nes_murdmazeRomInfo, nes_murdmazeRomName, NULL, NULL, NULL, NULL, NESInputInfo, NESDIPInfo,

View File

@ -525,7 +525,7 @@ static INT32 DrvCommonInit(INT32 game) // 0 = gng, 1 = gnga, 2 = diamrun
{
BurnAllocMemIndex();
BurnSetRefreshRate(59.59);
BurnSetRefreshRate(59.64);
{
if (game == 0 || game == 1) {
@ -755,7 +755,7 @@ static INT32 DrvFrame()
}
INT32 nInterleave = 256;
INT32 nCyclesTotal[2] = { (INT32)(1500000 / 59.59), (INT32)(3000000 / 59.59) };
INT32 nCyclesTotal[2] = { (INT32)(1500000 / 59.637405), (INT32)(3000000 / 59.637405) };
INT32 nCyclesDone[2] = { nExtraCycles, 0 };
M6809Open(0);

View File

@ -2211,7 +2211,7 @@ static void snkwave_exit()
static void snkwave_update_waveform(UINT32 offset, UINT8 data)
{
snkwave_waveform[offset * 2] = ((data & 0x38) >> 3) << (12-CLOCK_SHIFT);
snkwave_waveform[offset * 2] = ((data & 0x70) >> 4) << (12-CLOCK_SHIFT);
snkwave_waveform[offset * 2 + 1] = ((data & 0x07) >> 0) << (12-CLOCK_SHIFT);
snkwave_waveform[SNKWAVE_WAVEFORM_LENGTH-2 - offset * 2] = ~snkwave_waveform[offset * 2 + 1];
snkwave_waveform[SNKWAVE_WAVEFORM_LENGTH-1 - offset * 2] = ~snkwave_waveform[offset * 2];
@ -2221,13 +2221,11 @@ static void snkwave_w(UINT32 offset, UINT8 data)
{
stream.update();
data &= 0x3f; // all registers are 6-bit
if (offset == 0)
snkwave_frequency = (snkwave_frequency & 0x03f) | (data << 6);
else if (offset == 1)
snkwave_frequency = (snkwave_frequency & 0xfc0) | data;
else if (offset <= 5)
if (offset == 0) // F1, high 6 bits
snkwave_frequency = (snkwave_frequency & 0x03f) | ((data & 0xfc) << 4);
else if (offset == 1) // F2, low 6 bits
snkwave_frequency = (snkwave_frequency & 0xfc0) | (data & 0x3f);
else if (offset <= 5) // W3 thru W6, low 3 bits of each nybble
snkwave_update_waveform(offset - 2, data);
}

View File

@ -4164,7 +4164,7 @@ static void draw_screen(INT32 which)
BurnTransferClear(0);
if (!system32_displayenable[0]) {
if (!system32_displayenable[which]) {
return;
}

View File

@ -181,11 +181,13 @@ static struct BurnDIPInfo SNESMouseP1MouseP2GamepadDIPList[] =
{0x01, 0xff, 0xff, 0x01, NULL },
};
#if 0
static struct BurnDIPInfo SNESMouseP1GamepadP2MouseDIPList[] =
{
{0x00, 0xff, 0xff, 0x00, NULL },
{0x01, 0xff, 0xff, 0x02, NULL },
};
#endif
static struct BurnDIPInfo SNESMouseP1MouseP2MouseDIPList[] =
{
@ -195,7 +197,7 @@ static struct BurnDIPInfo SNESMouseP1MouseP2MouseDIPList[] =
STDDIPINFOEXT(SNESMouse, SNESMouseP1GamepadP2Gamepad, SNESMouseBase) // zoop
STDDIPINFOEXT(SNESMouseP1, SNESMouseP1MouseP2Gamepad, SNESMouseBase) // zoop
STDDIPINFOEXT(SNESMouseP2, SNESMouseP1GamepadP2Mouse, SNESMouseBase) // zoop
//STDDIPINFOEXT(SNESMouseP2, SNESMouseP1GamepadP2Mouse, SNESMouseBase) // zoop
STDDIPINFOEXT(SNESMouseP1P2, SNESMouseP1MouseP2Mouse, SNESMouseBase) // zoop
static UINT32 CheckControllerPlug()
@ -2727,10 +2729,10 @@ struct BurnDriver BurnDrvsnes_Bahalagoonte = {
512, 448, 4, 3
};
// Bahamut Lagoon (Hack, Spanish v1.03a)
// Bahamut Lagoon (Hack, Spanish v1.03c)
// https://crackowia.com/bahamuts.html
static struct BurnRomInfo snes_BahalagoontsRomDesc[] = {
{ "Bahamut Lagoon T-Spa v1.03a (2022)(Rod Merida).sfc", 8388608, 0x04a290fa, BRF_ESS | BRF_PRG },
{ "Bahamut Lagoon T-Spa v1.03c (2022)(Rod Merida).sfc", 8388608, 0xf24350ec, BRF_ESS | BRF_PRG },
};
STD_ROM_PICK(snes_Bahalagoonts)
@ -2738,7 +2740,7 @@ STD_ROM_FN(snes_Bahalagoonts)
struct BurnDriver BurnDrvsnes_Bahalagoonts = {
"snes_bahalagoonts", "snes_bahalagoonte", NULL, NULL, "2022",
"Bahamut Lagoon (Hack, Spanish v1.03a)\0", NULL, "Rod Merida", "Nintendo",
"Bahamut Lagoon (Hack, Spanish v1.03c)\0", NULL, "Rod Merida", "Nintendo",
NULL, NULL, NULL, NULL,
BDF_GAME_WORKING | BDF_CLONE | BDF_HACK, 1, HARDWARE_SNES, GBF_RPG | GBF_STRATEGY, 0,
SNESGetZipName, snes_BahalagoontsRomInfo, snes_BahalagoontsRomName, NULL, NULL, NULL, NULL, SNESInputInfo, SNESDIPInfo,
@ -6473,7 +6475,7 @@ struct BurnDriver BurnDrvsnes_Dezaemonj = {
// Dezaemon (Hack, English)
// https://www.romhacking.net/translations/3749/
static struct BurnRomInfo snes_DezaemonteRomDesc[] = {
{ "Dezaemon T-Eng (2018)(Aeon Genesis)..sfc", 524288, 0x32f9c958, BRF_ESS | BRF_PRG },
{ "Dezaemon T-Eng (2018)(Aeon Genesis).sfc", 524288, 0x32f9c958, BRF_ESS | BRF_PRG },
};
STD_ROM_PICK(snes_Dezaemonte)
@ -29676,25 +29678,6 @@ struct BurnDriver BurnDrvsnes_2048 = {
512, 448, 4, 3
};
// 4096 (HB)
static struct BurnRomInfo snes_4096RomDesc[] = {
{ "4096 (2015)(e-nost).sfc", 262144, 0xdd073c4b, BRF_ESS | BRF_PRG },
};
STD_ROM_PICK(snes_4096)
STD_ROM_FN(snes_4096)
struct BurnDriver BurnDrvsnes_4096 = {
"snes_4096", NULL, NULL, NULL, "2015",
"4096 (HB)\0", NULL, "e-nost", "Nintendo",
NULL, NULL, NULL, NULL,
BDF_GAME_WORKING | BDF_HOMEBREW, 1, HARDWARE_SNES, GBF_PUZZLE, 0,
SNESGetZipName, snes_4096RomInfo, snes_4096RomName, NULL, NULL, NULL, NULL, SNESInputInfo, SNESDIPInfo,
DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x8000,
512, 448, 4, 3
};
// Alien Cat 2 Enhanced Edition (HB, v1.1)
static struct BurnRomInfo snes_Aliencat2RomDesc[] = {
@ -30152,10 +30135,10 @@ struct BurnDriver BurnDrvsnes_Ff5rte = {
512, 448, 4, 3
};
// Final Fantasy VI Reimagined (Hack)
// Final Fantasy VI Reimagined (Hack) - 2024-10-30
// https://www.ff6hacking.com/forums/thread-4416.html
static struct BurnRomInfo snes_Ff6rmdRomDesc[] = {
{ "Final Fantasy VI Reimagined (2024)(DrakeyC).sfc", 4194304, 0xb1148ddf, BRF_ESS | BRF_PRG },
{ "Final Fantasy VI Reimagined (2024)(DrakeyC).sfc", 4194304, 0x60aff03d, BRF_ESS | BRF_PRG },
};
STD_ROM_PICK(snes_Ff6rmd)
@ -30513,10 +30496,10 @@ struct BurnDriver BurnDrvsnes_Jimpoweree = {
512, 448, 4, 3
};
// Legend of Zelda, The - 18 Hours Past (Hack, v1.11)
// Legend of Zelda, The - 18 Hours Past (Hack, v1.12)
// https://www.romhacking.net/hacks/7732/
static struct BurnRomInfo snes_Legendofzelda18hpRomDesc[] = {
{ "Legend of Zelda, The - 18 Hours Past v1.11 (2024)(Letterbomb).sfc", 2097152, 0x45d6950f, BRF_ESS | BRF_PRG },
{ "Legend of Zelda, The - 18 Hours Past v1.12 (2024)(Letterbomb).sfc", 2097152, 0xc2dc7b83, BRF_ESS | BRF_PRG },
};
STD_ROM_PICK(snes_Legendofzelda18hp)
@ -30524,7 +30507,7 @@ STD_ROM_FN(snes_Legendofzelda18hp)
struct BurnDriver BurnDrvsnes_Legendofzelda18hp = {
"snes_legendofzelda18hp", "snes_legendofzelda", NULL, NULL, "2024",
"Legend of Zelda, The - 18 Hours Past (Hack, v1.11)\0", NULL, "Letterbomb", "Nintendo",
"Legend of Zelda, The - 18 Hours Past (Hack, v1.12)\0", NULL, "Letterbomb", "Nintendo",
NULL, NULL, NULL, NULL,
BDF_GAME_WORKING | BDF_CLONE | BDF_HACK, 1, HARDWARE_SNES, GBF_ACTION | GBF_ADV, 0,
SNESGetZipName, snes_Legendofzelda18hpRomInfo, snes_Legendofzelda18hpRomName, NULL, NULL, NULL, NULL, SNESInputInfo, SNESDIPInfo,
@ -31007,10 +30990,10 @@ struct BurnDriver BurnDrvsnes_Racedrivinsa1o = {
512, 448, 4, 3
};
// Ranma 1/2 - Chougi Ranbu Hen (Japan)
// Ranma 1/2 - Chougi Ranbu Hen (Hack, Framerate Imp. v1.4)
// https://romhackplaza.org/romhacks/ranma-1-2-chougi-ranbu-hen-big-framerate-improvement-snes/
static struct BurnRomInfo snes_Ranmahb2jfrRomDesc[] = {
{ "Ranma 1-2 - Chougi Ranbu Hen frameratehack v1.3 (2024)(Upsilandre).sfc", 4194304, 0x71aaff40, BRF_ESS | BRF_PRG },
{ "Ranma 1-2 - Chougi Ranbu Hen frameratehack v1.4 (2024)(Upsilandre).sfc", 4194304, 0x1705415f, BRF_ESS | BRF_PRG },
};
STD_ROM_PICK(snes_Ranmahb2jfr)
@ -31018,7 +31001,7 @@ STD_ROM_FN(snes_Ranmahb2jfr)
struct BurnDriver BurnDrvsnes_Ranmahb2jfr = {
"snes_ranmahb2jfr", "snes_ranmahb2te", NULL, NULL, "2024",
"Ranma 1/2 - Chougi Ranbu Hen (Hack, Framerate Imp. v1.3)\0", NULL, "Upsilandre", "Nintendo",
"Ranma 1/2 - Chougi Ranbu Hen (Hack, Framerate Imp. v1.4)\0", NULL, "Upsilandre", "Nintendo",
NULL, NULL, NULL, NULL,
BDF_GAME_WORKING | BDF_CLONE | BDF_HACK, 2, HARDWARE_SNES, GBF_VSFIGHT, 0,
SNESGetZipName, snes_Ranmahb2jfrRomInfo, snes_Ranmahb2jfrRomName, NULL, NULL, NULL, NULL, SNESInputInfo, SNESDIPInfo,
@ -31026,11 +31009,11 @@ struct BurnDriver BurnDrvsnes_Ranmahb2jfr = {
512, 448, 4, 3
};
// Ranma 1/2 - Hard Battle II - Super Move Hustle (Hack, English v1.10 + Framerate Imp. v1.3)
// Ranma 1/2 - Hard Battle II - Super Move Hustle (Hack, English v1.10 + Framerate Imp. v1.4)
// https://www.romhacking.net/translations/3516/
// https://romhackplaza.org/romhacks/ranma-1-2-chougi-ranbu-hen-big-framerate-improvement-snes/
static struct BurnRomInfo snes_Ranmahb2tefrRomDesc[] = {
{ "Ranma 1-2 - Hard Battle II - Super Move Hustle T-Eng + frameratehack v1.3 (2024)(Upsilandre).sfc", 4194304, 0x4401b68c, BRF_ESS | BRF_PRG },
{ "Ranma 1-2 - Hard Battle II - Super Move Hustle T-Eng + frameratehack v1.4 (2024)(Upsilandre).sfc", 4194304, 0x22ae0893, BRF_ESS | BRF_PRG },
};
STD_ROM_PICK(snes_Ranmahb2tefr)
@ -31038,7 +31021,7 @@ STD_ROM_FN(snes_Ranmahb2tefr)
struct BurnDriver BurnDrvsnes_Ranmahb2tefr = {
"snes_ranmahb2tefr", "snes_ranmahb2te", NULL, NULL, "2024",
"Ranma 1/2 - Hard Battle II - Super Move Hustle (Hack, English v1.10 + Framerate Imp. v1.3)\0", NULL, "Dynamic-Designs - Upsilandre", "Nintendo",
"Ranma 1/2 - Hard Battle II - Super Move Hustle (Hack, English v1.10 + Framerate Imp. v1.4)\0", NULL, "Dynamic-Designs - Upsilandre", "Nintendo",
NULL, NULL, NULL, NULL,
BDF_GAME_WORKING | BDF_CLONE | BDF_HACK, 2, HARDWARE_SNES, GBF_VSFIGHT, 0,
SNESGetZipName, snes_Ranmahb2tefrRomInfo, snes_Ranmahb2tefrRomName, NULL, NULL, NULL, NULL, SNESInputInfo, SNESDIPInfo,
@ -31217,25 +31200,6 @@ struct BurnDriver BurnDrvsnes_Spacegulls = {
512, 448, 4, 3
};
// Star Keeper (HB)
static struct BurnRomInfo snes_StarkeeperRomDesc[] = {
{ "Star Keeper (2018)(87Arts).sfc", 524288, 0xd925182f, BRF_ESS | BRF_PRG },
};
STD_ROM_PICK(snes_Starkeeper)
STD_ROM_FN(snes_Starkeeper)
struct BurnDriver BurnDrvsnes_Starkeeper = {
"snes_starkeeper", NULL, NULL, NULL, "2018",
"Star Keeper (HB)\0", NULL, "87Arts", "Nintendo",
NULL, NULL, NULL, NULL,
BDF_GAME_WORKING | BDF_HOMEBREW, 1, HARDWARE_SNES, GBF_HORSHOOT, 0,
SNESGetZipName, snes_StarkeeperRomInfo, snes_StarkeeperRomName, NULL, NULL, NULL, NULL, SNESInputInfo, SNESDIPInfo,
DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x8000,
512, 448, 4, 3
};
// Steel Talons - Fastrom fix (Hack)
// https://www.patreon.com/posts/steel-talons-fix-79800713
static struct BurnRomInfo snes_SteeltalonsffRomDesc[] = {
@ -31559,25 +31523,6 @@ struct BurnDriver BurnDrvsnes_Supsudoku = {
512, 448, 4, 3
};
// Super Xoxol vs. Pigdog (HB)
static struct BurnRomInfo snes_SupxoxolRomDesc[] = {
{ "Super Xoxol vs. Pigdog (2023)(Sergey Cyka).sfc", 1048576, 0xed786ffe, BRF_ESS | BRF_PRG },
};
STD_ROM_PICK(snes_Supxoxol)
STD_ROM_FN(snes_Supxoxol)
struct BurnDriver BurnDrvsnes_Supxoxol = {
"snes_supxoxol", NULL, NULL, NULL, "2023",
"Super Xoxol vs. Pigdog (HB)\0", NULL, "Sergey Cyka", "Nintendo",
NULL, NULL, NULL, NULL,
BDF_GAME_WORKING | BDF_HOMEBREW, 2, HARDWARE_SNES, GBF_SCRFIGHT, 0,
SNESGetZipName, snes_SupxoxolRomInfo, snes_SupxoxolRomName, NULL, NULL, NULL, NULL, SNESInputInfo, SNESDIPInfo,
DrvInit, DrvExit, DrvFrame, DrvDraw, DrvScan, &DrvRecalc, 0x8000,
512, 448, 4, 3
};
// Sure Instinct Mini-Edition (HB, v1.0.2)
static struct BurnRomInfo snes_SureinstinctRomDesc[] = {

View File

@ -27,6 +27,7 @@ static uint8_t snes_rread(Snes* snes, uint32_t adr); // wrapped by read, to set
static int snes_getAccessTime(Snes* snes, uint32_t adr);
static void build_accesstime(Snes* snes);
static void free_accesstime();
static void snes_init_fbn_cheat_subsys();
static uint8_t *access_time;
@ -41,6 +42,8 @@ Snes* snes_init(void) {
snes->input2 = input_init(snes, 2);
snes->palTiming = false;
snes_init_fbn_cheat_subsys();
return snes;
}
@ -649,9 +652,126 @@ static void free_accesstime() {
BurnFree(access_time);
}
// game genie/par cheat system
static UINT8 gg_nibble(UINT8 g)
{
const UINT8 gg_str[] = "DF4709156BC8A23E";
for (UINT8 i = 0; i < 0x10; i++) {
if (g == gg_str[i]) {
return i;
}
}
return 0;
}
static INT32 gg_decode(char *gg_code, UINT32 &address, UINT8 &value)
{
UINT32 type = strlen(gg_code);
UINT32 temp = 0;
if (type != 8 && type != 9) {
// bad code!
return 1;
}
switch (type) {
case 8: { // Pro Action Replay (PAR)
temp = (UINT32)strtoul(gg_code, NULL, 16);
address = (temp >> 8) & 0xffffff;
value = temp & 0xff;
break;
}
case 9: { // Game Genie
for (int i = 0; i < 9; i++) {
if (i != 4) temp = (temp << 4) | gg_nibble(gg_code[i]);
}
value = (temp >> 24) & 0xff;
address = (temp >> 10) & 0xf;
address = (address << 4) | ((temp >> 2) & 0xf);
address = (address << 4) | ((temp >> 20) & 0xf);
address = (address << 4) | ((temp << 2) & 0xc) | ((temp >> 14) & 0x3);
address = (address << 4) | ((temp >> 16) & 0xf);
address = (address << 4) | ((temp >> 6) & 0xf);
break;
}
}
return 0;
}
static const INT32 cheat_MAX = 0x100;
static INT32 cheats_active = 0;
struct cheat_struct {
char code[0x10]; // gamegenie, par code
UINT32 address;
UINT8 value;
};
static cheat_struct cheats[cheat_MAX];
static void snes_add_cheat(char *code)
{
UINT32 address;
UINT8 value;
if (!gg_decode(code, address, value) && cheats_active < (cheat_MAX-1)) {
strncpy(cheats[cheats_active].code, code, 9);
cheats[cheats_active].code[9] = '\0';
cheats[cheats_active].address = address;
cheats[cheats_active].value = value;
bprintf(0, _T("cheat #%d (%S) added. (%x, %x)\n"), cheats_active, cheats[cheats_active].code, address, value);
cheats_active++;
} else {
if (cheats_active < (cheat_MAX-1)) {
bprintf(0, _T("snes cheat engine: bad GameGenie code %S\n"), code);
} else {
bprintf(0, _T("snes cheat engine: too many active!\n"));
}
}
}
static void snes_remove_cheat(char *code)
{
cheat_struct cheat_temp[cheat_MAX];
INT32 temp_num = 0;
for (INT32 i = 0; i < cheats_active; i++) {
if (strcmp(code, cheats[i].code) != 0) {
memcpy(&cheat_temp[temp_num], &cheats[i], sizeof(cheat_struct));
temp_num++;
} else {
bprintf(0, _T("cheat %S disabled.\n"), cheats[i].code);
}
}
memcpy(cheats, cheat_temp, sizeof(cheats));
cheats_active = temp_num;
}
static void snes_init_fbn_cheat_subsys()
{
cheats_active = 0;
nes_init_cheat_functions(snes_add_cheat, snes_remove_cheat);
}
static inline UINT8 cheat_check(UINT32 address, UINT8 value)
{
for (INT32 i = 0; i < cheats_active; i++) {
if (cheats[i].address == address) {
//bprintf(0, _T("."));
return cheats[i].value;
}
}
return value;
}
uint8_t snes_read(Snes* snes, uint32_t adr) {
snes->adrBus = adr;
uint8_t val = snes_rread(snes, adr);
const uint8_t val = cheat_check(adr, snes_rread(snes, adr));
snes->openBus = val;
return val;
}

View File

@ -1,6 +1,6 @@
#include "burner.h"
#define HW_NES ( ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_NES) || ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_FDS) )
#define HW_NES ( ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_SNES) || ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_NES) || ((BurnDrvGetHardwareCode() & HARDWARE_PUBLIC_MASK) == HARDWARE_FDS) )
static bool SkipComma(TCHAR** s)
{
@ -237,7 +237,7 @@ static INT32 ConfigParseFile(TCHAR* pszFilename)
for (INT32 z = 0; z < strlen(t); z++) {
#endif
char c = toupper((char)*s);
if (c >= 'A' && c <= 'Z' && newlen < 10)
if ( ((c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || (c == '-' || c == ':')) && newlen < 10)
pCurrentCheat->pOption[n]->AddressInfo[nCurrentAddress].szGenieCode[newlen++] = c;
s++;
if (*s == _T(',')) break;