diff --git a/bsx.cpp b/bsx.cpp index c317bd26..2b4454e3 100644 --- a/bsx.cpp +++ b/bsx.cpp @@ -199,7 +199,7 @@ //#define BSX_DEBUG #define BIOS_SIZE 0x100000 -#define FLASH_SIZE 0x200000 +#define FLASH_SIZE 0x100000 #define PSRAM_SIZE 0x80000 #define Map Memory.Map @@ -231,7 +231,7 @@ static const uint8 flashcard[20] = { 0x4D, 0x00, 0x50, 0x00, // vendor id 0x00, 0x00, // ? - 0x2B, 0x00, // 2MB Flash (1MB = 0x2A) + 0x1A, 0x00, // 2MB Flash (1MB = 0x2A) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; @@ -417,13 +417,22 @@ static void map_psram_mirror_sub (uint32 bank) { for (c = 0; c < 0x100; c += 16) { - for (i = c; i < c + 8; i++) - Map[i + bank] = &PSRAM[(c << 11) % PSRAM_SIZE]; + if ((bank & 0x7F) >= 0x40) + { + for (i = c; i < c + 8; i++) + Map[i + bank] = &PSRAM[(c << 11) % PSRAM_SIZE]; + + for (i = c; i < c + 8; i++) + { + BlockIsRAM[i + bank] = TRUE; + BlockIsROM[i + bank] = FALSE; + } + } for (i = c + 8; i < c + 16; i++) Map[i + bank] = &PSRAM[(c << 11) % PSRAM_SIZE] - 0x8000; - for (i = c; i < c + 16; i++) + for (i = c + 8; i < c + 16; i++) { BlockIsRAM[i + bank] = TRUE; BlockIsROM[i + bank] = FALSE; @@ -432,42 +441,126 @@ static void map_psram_mirror_sub (uint32 bank) } } -static void BSX_Map_PSRAM (void) +static void BSX_Map_PSRAM(void) { - int c; + int c, i; - // Banks 70->77:0000-FFFF - // FIXME: could be toggled by $03 - for (c = 0; c < 0x80; c++) + if (!BSX.MMC[0x02]) { - Map[c + 0x700] = &PSRAM[((c & 0x70) << 12) % PSRAM_SIZE]; - BlockIsRAM[c + 0x700] = TRUE; - BlockIsROM[c + 0x700] = FALSE; - } + //LoROM Mode + if (!BSX.MMC[0x05] && !BSX.MMC[0x06]) + { + //Map PSRAM to 00-0F/80-8F + if (BSX.MMC[0x03]) + map_psram_mirror_sub(0x00); - // Banks 20->3F:6000-7FFF mirrors 70->77:6000-7FFF - for (c = 0x200; c < 0x400; c += 16) + if (BSX.MMC[0x04]) + map_psram_mirror_sub(0x80); + } + else if (BSX.MMC[0x05] && !BSX.MMC[0x06]) + { + //Map PSRAM to 20-2F/A0-AF + if (BSX.MMC[0x03]) + map_psram_mirror_sub(0x20); + + if (BSX.MMC[0x04]) + map_psram_mirror_sub(0xA0); + } + else if (!BSX.MMC[0x05] && BSX.MMC[0x06]) + { + //Map PSRAM to 40-4F/C0-CF + if (BSX.MMC[0x03]) + map_psram_mirror_sub(0x40); + + if (BSX.MMC[0x04]) + map_psram_mirror_sub(0xC0); + } + else + { + //Map PSRAM to 60-6F/E0-EF + if (BSX.MMC[0x03]) + map_psram_mirror_sub(0x60); + + if (BSX.MMC[0x04]) + map_psram_mirror_sub(0xE0); + } + + //Map PSRAM to 70-7D/F0-FF + if (BSX.MMC[0x03]) + map_psram_mirror_sub(0x70); + + if (BSX.MMC[0x04]) + map_psram_mirror_sub(0xF0); + } + else { - Map[c + 6] = &PSRAM[((c & 0x70) << 12) % PSRAM_SIZE]; - Map[c + 7] = &PSRAM[((c & 0x70) << 12) % PSRAM_SIZE]; - BlockIsRAM[c + 6] = TRUE; - BlockIsRAM[c + 7] = TRUE; - BlockIsROM[c + 6] = FALSE; - BlockIsROM[c + 7] = FALSE; + //HiROM Mode + if (!BSX.MMC[0x05] && !BSX.MMC[0x06]) + { + //Map PSRAM to 40-47/C0-C7 + if (BSX.MMC[0x03]) + map_psram_mirror_sub(0x40); + + if (BSX.MMC[0x04]) + map_psram_mirror_sub(0xC0); + + } + else if (BSX.MMC[0x05] && !BSX.MMC[0x06]) + { + //Map PSRAM to 50-57/D0-D7 + if (BSX.MMC[0x03]) + map_psram_mirror_sub(0x50); + + if (BSX.MMC[0x04]) + map_psram_mirror_sub(0xD0); + } + else if (!BSX.MMC[0x05] && BSX.MMC[0x06]) + { + //Map PSRAM to 60-67/E0-E7 + if (BSX.MMC[0x03]) + map_psram_mirror_sub(0x60); + + if (BSX.MMC[0x04]) + map_psram_mirror_sub(0xE0); + } + else + { + //Map PSRAM to 70-77/F0-F7 + if (BSX.MMC[0x03]) + map_psram_mirror_sub(0x70); + + if (BSX.MMC[0x04]) + map_psram_mirror_sub(0xF0); + } + + if (BSX.MMC[0x03]) + { + //Map PSRAM to 20->3F:6000-7FFF + for (c = 0x200; c < 0x400; c += 16) + { + Map[c + 6] = &PSRAM[((c & 0x70) << 12) % PSRAM_SIZE]; + Map[c + 7] = &PSRAM[((c & 0x70) << 12) % PSRAM_SIZE]; + BlockIsRAM[c + 6] = TRUE; + BlockIsRAM[c + 7] = TRUE; + BlockIsROM[c + 6] = FALSE; + BlockIsROM[c + 7] = FALSE; + } + } + + if (BSX.MMC[0x04]) + { + //Map PSRAM to A0->BF:6000-7FFF + for (c = 0xA00; c < 0xC00; c += 16) + { + Map[c + 6] = &PSRAM[((c & 0x70) << 12) % PSRAM_SIZE]; + Map[c + 7] = &PSRAM[((c & 0x70) << 12) % PSRAM_SIZE]; + BlockIsRAM[c + 6] = TRUE; + BlockIsRAM[c + 7] = TRUE; + BlockIsROM[c + 6] = FALSE; + BlockIsROM[c + 7] = FALSE; + } + } } - - if (!BSX.MMC[0x05]) - // Banks 40->4F:0000-FFFF mirrors 70->77:0000-7FFF - map_psram_mirror_sub(0x40); - - if (!BSX.MMC[0x06]) - // Banks 50->5F:0000-FFFF mirrors 70->77:0000-7FFF - map_psram_mirror_sub(0x50); - - // FIXME - if (!BSX.MMC[0x03]) - // Banks 60->6F:0000-FFFF mirrors 70->77:0000-7FFF (?) - map_psram_mirror_sub(0x60); } static void BSX_Map_BIOS (void) @@ -562,28 +655,8 @@ static void BSX_Map (void) memcpy(BSX.prevMMC, BSX.MMC, sizeof(BSX.MMC)); - // Do a quick bank change - if (BSX.dirty2 && !BSX.dirty) - { - BSX_Map_Dirty(); - BSX_Map_BIOS(); - - BSX.dirty2 = FALSE; - - Memory.map_WriteProtectROM(); - return; - } - - if (BSX.MMC[0x01]) - { - MapROM = PSRAM; - FlashSize = PSRAM_SIZE; - } - else - { - MapROM = FlashROM; - FlashSize = FLASH_SIZE; - } + MapROM = FlashROM; + FlashSize = FLASH_SIZE; BSX_Map_SNES(); @@ -592,12 +665,12 @@ static void BSX_Map (void) else BSX_Map_LoROM(); + BSX_Map_FlashIO(); BSX_Map_PSRAM(); BSX_Map_SRAM(); BSX_Map_RAM(); BSX_Map_BIOS(); - BSX_Map_FlashIO(); BSX_Map_MMC(); // Monitor new register changes @@ -607,30 +680,24 @@ static void BSX_Map (void) Memory.map_WriteProtectROM(); } -static uint8 BSX_Get_Bypass_FlashIO (uint16 offset) +static uint8 BSX_Get_Bypass_FlashIO (uint32 offset) { + MapROM = FlashROM = Memory.ROM + Multi.cartOffsetB; + if (BSX.MMC[0x02]) - return (MapROM[offset]); + return (MapROM[offset & 0x0FFFFF]); else - { - if (offset < 0x8000) - return (MapROM[offset]); - else - return (MapROM[offset - 0x8000]); - } + return (MapROM[(offset & 0x1F0000) >> 1 | (offset & 0x7FFF)]); } -static void BSX_Set_Bypass_FlashIO (uint16 offset, uint8 byte) +static void BSX_Set_Bypass_FlashIO (uint32 offset, uint8 byte) { + MapROM = FlashROM = Memory.ROM + Multi.cartOffsetB; + if (BSX.MMC[0x02]) - MapROM[offset] = byte; + MapROM[offset & 0x0FFFFF] = MapROM[offset & 0x0FFFFF] & byte; else - { - if (offset < 0x8000) - MapROM[offset] = byte; - else - MapROM[offset - 0x8000] = byte; - } + MapROM[(offset & 0x1F0000) >> 1 | (offset & 0x7FFF)] = MapROM[(offset & 0x1F0000) >> 1 | (offset & 0x7FFF)] & byte; } uint8 S9xGetBSX (uint32 address) @@ -640,43 +707,57 @@ uint8 S9xGetBSX (uint32 address) uint8 t = 0; // MMC - if ((bank >= 0x01 && bank <= 0x0E) && (offset == 0x5000)) + if ((bank >= 0x01 && bank <= 0x0E)) return (BSX.MMC[bank]); // Flash IO - if (bank == 0xC0) + if (bank >= 0xC0) { // default: read-through mode - t = BSX_Get_Bypass_FlashIO(offset); + t = BSX_Get_Bypass_FlashIO(address); // note: may be more registers, purposes unknown switch (offset) { - case 0x0002: - if (BSX.flash_enable) - t = 0x80; // status register? - break; + case 0x0002: + case 0x8002: + if (BSX.flash_bsr) + t = 0xC0; // Page Status Register + break; - case 0x5555: - if (BSX.flash_enable) - t = 0x80; // ??? - break; + case 0x0004: + case 0x8004: + if (BSX.flash_gsr) + t = 0x82; // Global Status Register + break; - case 0xFF00: - case 0xFF02: - case 0xFF04: - case 0xFF06: - case 0xFF08: - case 0xFF0A: - case 0xFF0C: - case 0xFF0E: - case 0xFF10: - case 0xFF12: - // return flash vendor information - if (BSX.read_enable) - t = flashcard[offset - 0xFF00]; - break; + case 0x5555: + if (BSX.flash_enable) + t = 0x80; // ??? + break; + + case 0xFF00: + case 0xFF02: + case 0xFF04: + case 0xFF06: + case 0xFF08: + case 0xFF0A: + case 0xFF0C: + case 0xFF0E: + case 0xFF10: + case 0xFF12: + // return flash vendor information + if (BSX.read_enable) + t = flashcard[offset - 0xFF00]; + break; } + + if (BSX.flash_csr) + { + t = 0x80; // Compatible Status Register + BSX.flash_csr = false; + } + } return (t); @@ -688,115 +769,126 @@ void S9xSetBSX (uint8 byte, uint32 address) uint16 offset = address & 0xFFFF; // MMC - if ((bank >= 0x01 && bank <= 0x0E) && (offset == 0x5000)) + if ((bank >= 0x01 && bank <= 0x0E)) { - switch (bank) - { - case 0x01: - case 0x02: - case 0x03: - case 0x04: - case 0x05: - case 0x06: - case 0x09: - case 0x0A: - case 0x0B: - case 0x0C: - case 0x0D: - if (BSX.MMC[bank] != byte) - { - BSX.MMC[bank] = byte; - BSX.dirty = TRUE; - } - break; - - case 0x07: - case 0x08: - if (BSX.MMC[bank] != byte) - { - BSX.MMC[bank] = byte; - BSX.dirty2 = TRUE; - } - break; - - case 0x0E: - BSX.MMC[bank] = byte; - if (byte && (BSX.dirty || BSX.dirty2)) - BSX_Map(); - break; - } + BSX.MMC[bank] = byte; + if (bank == 0x0E) + BSX_Map(); } // Flash IO - if (bank == 0xC0) + if (bank >= 0xC0) { - BSX.old_write = BSX.new_write; - BSX.new_write = address; - - // ???: double writes to the desired address will bypass - // flash registers - if (BSX.old_write == BSX.new_write && BSX.write_enable) + // Write to Flash + if (BSX.write_enable) { - BSX_Set_Bypass_FlashIO(offset, byte); + BSX_Set_Bypass_FlashIO(address, byte); + //MapROM[address & 0x3FFFFF] = byte; + BSX.write_enable = false; return; } - // flash command handling - // note: incomplete - switch (offset) - { - case 0x0000: - BSX.flash_command <<= 8; - BSX.flash_command |= byte; - if ((BSX.flash_command & 0xFFFF) == 0x38D0) - { - // retrieve information about the flash card - BSX.flash_enable = TRUE; - BSX.read_enable = TRUE; - } - break; + // Flash Command Handling + if (BSX.MMC[0xC]) { + //Memory Pack Type 1 & 3 & 4 + BSX.flash_command <<= 8; + BSX.flash_command |= byte; - case 0x2AAA: - BSX.flash_command <<= 8; - BSX.flash_command |= byte; - break; + switch (BSX.flash_command & 0xFF) + { + case 0x00: + case 0xFF: + //Reset to normal + BSX.flash_enable = false; + BSX.flash_bsr = false; + BSX.flash_csr = false; + BSX.flash_gsr = false; + BSX.read_enable = false; + BSX.write_enable = false; + BSX.flash_cmd_done = true; + break; - case 0x5555: - BSX.flash_command <<= 8; - BSX.flash_command |= byte; + case 0x10: + case 0x40: + //Write Byte + BSX.flash_enable = false; + BSX.flash_bsr = false; + BSX.flash_csr = true; + BSX.flash_gsr = false; + BSX.read_enable = false; + BSX.write_enable = true; + BSX.flash_cmd_done = true; + break; - switch (BSX.flash_command & 0xFFFFFF) - { - case 0xAA55F0: - // turn off flash i/o - BSX.flash_enable = FALSE; - BSX.write_enable = FALSE; - BSX.read_enable = FALSE; - break; + case 0x50: + //Clear Status Register + BSX.flash_enable = false; + BSX.flash_bsr = false; + BSX.flash_csr = false; + BSX.flash_gsr = false; + BSX.flash_cmd_done = true; + break; - case 0xAA55A0: - // enable writing to flash - BSX.old_write = 0; - BSX.new_write = 0; - BSX.flash_enable = TRUE; - BSX.write_enable = TRUE; - BSX_Map(); - break; + case 0x70: + //Read CSR + BSX.flash_enable = false; + BSX.flash_bsr = false; + BSX.flash_csr = true; + BSX.flash_gsr = false; + BSX.read_enable = false; + BSX.write_enable = false; + BSX.flash_cmd_done = true; + break; - case 0xAA5570: - // turn on write-protection - BSX.write_enable = FALSE; - BSX_Map(); - break; + case 0x71: + //Read Extended Status Registers (Page and Global) + BSX.flash_enable = false; + BSX.flash_bsr = true; + BSX.flash_csr = false; + BSX.flash_gsr = true; + BSX.read_enable = false; + BSX.write_enable = false; + BSX.flash_cmd_done = true; + break; - case 0xAA5580: - case 0xAA5510: - // ??? - break; + case 0x75: + //Show Page Buffer / Vendor Info + BSX.flash_csr = false; + BSX.read_enable = true; + BSX.flash_cmd_done = true; + break; - } + case 0xD0: + //DO COMMAND + switch (BSX.flash_command & 0xFFFF) + { + case 0x20D0: //Block Erase + uint32 x; + for (x = 0; x < 0x10000; x++) { + //BSX_Set_Bypass_FlashIO(((address & 0xFF0000) + x), 0xFF); + if (BSX.MMC[0x02]) + MapROM[(address & 0x0F0000) + x] = 0xFF; + else + MapROM[((address & 0x1E0000) >> 1) + x] = 0xFF; + } + break; - break; + case 0xA7D0: //Chip Erase (ONLY IN TYPE 1 AND 4) + if ((flashcard[6] & 0xF0) == 0x10 || (flashcard[6] & 0xF0) == 0x40) + { + uint32 x; + for (x = 0; x < FLASH_SIZE; x++) { + //BSX_Set_Bypass_FlashIO(x, 0xFF); + MapROM[x] = 0xFF; + } + } + break; + + case 0x38D0: //Flashcart Reset + break; + } + break; + } } } } @@ -1082,7 +1174,7 @@ void S9xInitBSX (void) uint8 *header = r1 ? Memory.ROM + 0x7FC0 : Memory.ROM + 0xFFC0; FlashMode = (header[0x18] & 0xEF) == 0x20 ? FALSE : TRUE; - FlashSize = (header[0x19] & 0x20) ? PSRAM_SIZE : FLASH_SIZE; + FlashSize = FLASH_SIZE; #ifdef BSX_DEBUG for (int i = 0; i <= 0x1F; i++) @@ -1145,32 +1237,11 @@ void S9xResetBSX (void) memset(BSX.output, 0, sizeof(BSX.output)); // starting from the bios - if (BSX.bootup) - BSX.MMC[0x07] = BSX.MMC[0x08] = 0x80; - else - { - BSX.MMC[0x02] = FlashMode ? 0x80: 0; + BSX.MMC[0x02] = BSX.MMC[0x03] = BSX.MMC[0x05] = BSX.MMC[0x06] = 0x80; + BSX.MMC[0x09] = BSX.MMC[0x0B] = 0x80; - // per bios: run from psram or flash card - if (FlashSize == PSRAM_SIZE) - { - memcpy(PSRAM, FlashROM, PSRAM_SIZE); - - BSX.MMC[0x01] = 0x80; - BSX.MMC[0x03] = 0x80; - BSX.MMC[0x04] = 0x80; - BSX.MMC[0x0C] = 0x80; - BSX.MMC[0x0D] = 0x80; - } - else - { - BSX.MMC[0x03] = 0x80; - BSX.MMC[0x05] = 0x80; - BSX.MMC[0x06] = 0x80; - } - - BSX.MMC[0x0E] = 0x80; - } + BSX.MMC[0x07] = BSX.MMC[0x08] = 0x80; + BSX.MMC[0x0E] = 0x80; BSX_Map(); } diff --git a/bsx.h b/bsx.h index 5d5ea03d..ac5a2906 100644 --- a/bsx.h +++ b/bsx.h @@ -208,6 +208,11 @@ struct SBSX uint8 MMC[16]; uint8 prevMMC[16]; uint8 test2192[32]; + + bool flash_csr; + bool flash_gsr; + bool flash_bsr; + bool flash_cmd_done; }; extern struct SBSX BSX; diff --git a/gtk/configure.ac b/gtk/configure.ac index e3bab4eb..50f204f3 100644 --- a/gtk/configure.ac +++ b/gtk/configure.ac @@ -331,9 +331,9 @@ if test no != "$with_system_zip" && test yes = "$with_zlib" ; then LIBS="$LIBS $SYSTEM_ZIP_LIBS" ],[ if test check = "$with_system_zip"; then - AC_MSG_WARN(Cannot find SYSTEM_ZIP) + AC_MSG_WARN(Cannot find system minizip library) else - AC_MSG_ERROR(--with-system-zip given but cannot find proper zlib) + AC_MSG_ERROR(--with-system-zip given but cannot find system minizip library) fi ]) fi diff --git a/gtk/src/gtk_file.cpp b/gtk/src/gtk_file.cpp index 9c0e0009..b6607f75 100644 --- a/gtk/src/gtk_file.cpp +++ b/gtk/src/gtk_file.cpp @@ -422,7 +422,7 @@ S9xOpenROMDialog (void) { "*.smc", "*.SMC", "*.fig", "*.FIG", "*.sfc", "*.SFC", "*.jma", "*.JMA", "*.zip", "*.ZIP", "*.gd3", "*.GD3", - "*.swc", "*.SWC", "*.gz" , "*.GZ", + "*.swc", "*.SWC", "*.gz" , "*.GZ", "*.bs", "*.BS", NULL }; diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index 859d3f8b..38db20e4 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -178,7 +178,7 @@ void retro_get_system_info(struct retro_system_info *info) info->library_name = "Snes9x"; info->library_version = VERSION; - info->valid_extensions = "smc|sfc|swc|fig"; + info->valid_extensions = "smc|sfc|swc|fig|bs"; info->need_fullpath = false; info->block_extract = false; } diff --git a/memmap.cpp b/memmap.cpp index c964c465..d55cfad4 100644 --- a/memmap.cpp +++ b/memmap.cpp @@ -957,9 +957,9 @@ static void S9xDeinterleaveGD24 (int, uint8 *); static bool8 allASCII (uint8 *, int); 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_BSCart_BIOS (const uint8 *, uint32); static bool8 is_SameGame_Add_On (const uint8 *, uint32); -static bool8 is_GNEXT_BIOS (const uint8 *, uint32); +static bool8 is_BSCartSA1_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); @@ -1243,10 +1243,22 @@ static bool8 is_SufamiTurbo_Cart (const uint8 *data, uint32 size) return (FALSE); } -static bool8 is_SameGame_BIOS (const uint8 *data, uint32 size) +static bool8 is_BSCart_BIOS(const uint8 *data, uint32 size) { - if (size == 0x100000 && strncmp((char *) (data + 0xffc0), "Same Game Tsume Game", 20) == 0) + if ((data[0x7FB2] == 0x5A) && (data[0x7FB5] != 0x20) && (data[0x7FDA] == 0x33)) + { + Memory.LoROM = TRUE; + Memory.HiROM = FALSE; + return (TRUE); + } + else if ((data[0xFFB2] == 0x5A) && (data[0xFFB5] != 0x20) && (data[0xFFDA] == 0x33)) + { + Memory.LoROM = FALSE; + Memory.HiROM = TRUE; + + return (TRUE); + } else return (FALSE); } @@ -1259,9 +1271,14 @@ static bool8 is_SameGame_Add_On (const uint8 *data, uint32 size) return (FALSE); } -static bool8 is_GNEXT_BIOS (const uint8 *data, uint32 size) +static bool8 is_BSCartSA1_BIOS (const uint8 *data, uint32 size) { - if (size == 0x180000 && strncmp((char *) (data + 0x7fc0), "SFC SDGUNDAMGNEXT", 17) == 0) + //Same basic check as BSCart + if (!is_BSCart_BIOS(data, size)) + return (FALSE); + + //Checks if the game is Itoi's Bass Fishing No. 1 (ZBPJ) or SD Gundam G-NEXT (ZX3J) + if (strncmp((char *)(data + 0x7fb2), "ZBPJ", 4) == 0 || strncmp((char *)(data + 0x7fb2), "ZX3J", 4) == 0) return (TRUE); else return (FALSE); @@ -1866,11 +1883,11 @@ bool8 CMemory::LoadMultiCartInt () if (is_SufamiTurbo_Cart(ROM + Multi.cartOffsetA, Multi.cartSizeA)) Multi.cartType = 4; else - if (is_SameGame_BIOS(ROM + Multi.cartOffsetA, Multi.cartSizeA)) - Multi.cartType = 3; - else - if (is_GNEXT_BIOS(ROM + Multi.cartOffsetA, Multi.cartSizeA)) + if (is_BSCartSA1_BIOS(ROM + Multi.cartOffsetA, Multi.cartSizeA)) Multi.cartType = 5; + else + if (is_BSCart_BIOS(ROM + Multi.cartOffsetA, Multi.cartSizeA)) + Multi.cartType = 3; } else if (Multi.cartSizeB) @@ -1918,11 +1935,8 @@ bool8 CMemory::LoadMultiCartInt () break; case 3: - r = LoadSameGame(); - break; - case 5: - r = LoadGNEXT(); + r = LoadBSCart(); break; default: @@ -1986,26 +2000,31 @@ bool8 CMemory::LoadSufamiTurbo () return (TRUE); } -bool8 CMemory::LoadSameGame () +bool8 CMemory::LoadBSCart () { Multi.sramA = SRAM; Multi.sramB = NULL; - Multi.sramSizeA = ROM[0xffd8]; + if (LoROM) + Multi.sramSizeA = ROM[0x7fd8]; + else + Multi.sramSizeA = ROM[0xffd8]; + Multi.sramMaskA = Multi.sramSizeA ? ((1 << (Multi.sramSizeA + 3)) * 128 - 1) : 0; Multi.sramSizeB = 0; Multi.sramMaskB = 0; - if (Multi.cartSizeB) - { - if (!is_SameGame_Add_On(ROM + Multi.cartOffsetB, Multi.cartSizeB)) - Multi.cartSizeB = 0; - } - - LoROM = FALSE; - HiROM = TRUE; CalculatedSize = Multi.cartSizeA; + if (Multi.cartSizeB == 0 && Multi.cartSizeA <= (MAX_ROM_SIZE - 0x100000 - Multi.cartOffsetA)) + { + //Initialize 1MB Empty Memory Pack only if cart B is cleared + //It does not make a Memory Pack if game is loaded like a normal ROM + Multi.cartOffsetB = Multi.cartOffsetA + CalculatedSize; + Multi.cartSizeB = 0x100000; + memset(Memory.ROM + Multi.cartOffsetB, 0xFF, 0x100000); + } + return (TRUE); } @@ -2214,6 +2233,32 @@ bool8 CMemory::SaveSRAM (const char *filename) return (FALSE); } +bool8 CMemory::SaveMPAK (const char *filename) +{ + if (Settings.BS || (Multi.cartSizeB && (Multi.cartType == 3))) + { + FILE *file; + int size; + char mempakName[PATH_MAX + 1]; + + strcpy(mempakName, filename); + size = 0x100000; + if (size) + { + file = fopen(mempakName, "wb"); + if (file) + { + size_t ignore; + ignore = fwrite((char *)Memory.ROM + Multi.cartOffsetB, size, 1, file); + fclose(file); + + return (TRUE); + } + } + } + return (FALSE); +} + // initialization static uint32 caCRC32 (uint8 *array, uint32 size, uint32 crc32) @@ -2560,7 +2605,7 @@ void CMemory::InitROM (void) Map_ExtendedHiROMMap(); else if (Multi.cartType == 3) - Map_SameGameHiROMMap(); + Map_BSCartHiROMMap(); else Map_HiROMMap(); } @@ -2578,7 +2623,7 @@ void CMemory::InitROM (void) if (Settings.SA1) { if (Multi.cartType == 5) - Map_GNEXTSA1LoROMMap(); + Map_BSSA1LoROMMap(); else Map_SA1LoROMMap(); } @@ -2592,6 +2637,13 @@ void CMemory::InitROM (void) if (strncmp(ROMName, "WANDERERS FROM YS", 17) == 0) Map_NoMAD1LoROMMap(); else + if (Multi.cartType == 3) + if (strncmp(ROMName, "SOUND NOVEL-TCOOL", 17) == 0 || + strncmp(ROMName, "DERBY STALLION 96", 17) == 0) + Map_BSCartLoROMMap(1); + else + Map_BSCartLoROMMap(0); + else if (strncmp(ROMName, "SOUND NOVEL-TCOOL", 17) == 0 || strncmp(ROMName, "DERBY STALLION 96", 17) == 0) Map_ROM24MBSLoROMMap(); @@ -3263,9 +3315,9 @@ void CMemory::Map_SA1LoROMMap (void) BWRAM = SRAM; } -void CMemory::Map_GNEXTSA1LoROMMap (void) +void CMemory::Map_BSSA1LoROMMap(void) { - printf("Map_GNEXTSA1LoROMMap\n"); + printf("Map_BSSA1LoROMMap\n"); map_System(); map_lorom_offset(0x00, 0x3f, 0x8000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA); @@ -3281,9 +3333,6 @@ void CMemory::Map_GNEXTSA1LoROMMap (void) for (int c = 0x40; c < 0x80; c++) map_space(c, c, 0x0000, 0xffff, SRAM + (c & 1) * 0x10000); - // FIXME: untested! - map_hirom_offset(0x70, 0x7f, 0x0000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB); - map_WRAM(); map_WriteProtectROM(); @@ -3343,26 +3392,6 @@ void CMemory::Map_ExtendedHiROMMap (void) map_WriteProtectROM(); } -void CMemory::Map_SameGameHiROMMap (void) -{ - printf("Map_SameGameHiROMMap\n"); - map_System(); - - map_hirom_offset(0x00, 0x1f, 0x8000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA); - map_hirom_offset(0x20, 0x3f, 0x8000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB); - map_hirom_offset(0x40, 0x5f, 0x0000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA); - map_hirom_offset(0x60, 0x7f, 0x0000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB); - map_hirom_offset(0x80, 0x9f, 0x8000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA); - map_hirom_offset(0xa0, 0xbf, 0x8000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB); - map_hirom_offset(0xc0, 0xdf, 0x0000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA); - map_hirom_offset(0xe0, 0xff, 0x0000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB); - - map_HiROMSRAM(); - map_WRAM(); - - map_WriteProtectROM(); -} - void CMemory::Map_SPC7110HiROMMap (void) { printf("Map_SPC7110HiROMMap\n"); @@ -3381,6 +3410,71 @@ void CMemory::Map_SPC7110HiROMMap (void) map_WriteProtectROM(); } +void CMemory::Map_BSCartLoROMMap(uint8 mapping) +{ + printf("Map_BSCartLoROMMap\n"); + + BSX.MMC[0x02] = 0x00; + BSX.MMC[0x0C] = 0x80; + + map_System(); + + if (mapping) + { + map_lorom_offset(0x00, 0x1f, 0x8000, 0xffff, 0x100000, 0); + map_lorom_offset(0x20, 0x3f, 0x8000, 0xffff, 0x100000, 0x100000); + map_lorom_offset(0x80, 0x9f, 0x8000, 0xffff, 0x100000, 0x200000); + map_lorom_offset(0xa0, 0xbf, 0x8000, 0xffff, 0x100000, 0x100000); + } + else + { + map_lorom(0x00, 0x3f, 0x8000, 0xffff, CalculatedSize); + map_lorom(0x40, 0x7f, 0x0000, 0x7fff, CalculatedSize); + map_lorom(0x80, 0xbf, 0x8000, 0xffff, CalculatedSize); + map_lorom(0xc0, 0xff, 0x0000, 0x7fff, CalculatedSize); + } + + map_LoROMSRAM(); + map_index(0xc0, 0xef, 0x0000, 0xffff, MAP_BSX, MAP_TYPE_RAM); + map_WRAM(); + + map_WriteProtectROM(); +} + +void CMemory::Map_BSCartHiROMMap(void) +{ + printf("Map_BSCartHiROMMap\n"); + + BSX.MMC[0x02] = 0x80; + BSX.MMC[0x0C] = 0x80; + + map_System(); + map_hirom_offset(0x00, 0x1f, 0x8000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA); + map_hirom_offset(0x20, 0x3f, 0x8000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB); + map_hirom_offset(0x40, 0x5f, 0x0000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA); + map_hirom_offset(0x60, 0x7f, 0x0000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB); + map_hirom_offset(0x80, 0x9f, 0x8000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA); + map_hirom_offset(0xa0, 0xbf, 0x8000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB); + map_hirom_offset(0xc0, 0xdf, 0x0000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA); + + if ((ROM[Multi.cartOffsetB + 0xFF00] == 0x4D) + && (ROM[Multi.cartOffsetB + 0xFF02] == 0x50) + && ((ROM[Multi.cartOffsetB + 0xFF06] & 0xF0) == 0x70)) + { + //Type 7 Memory Pack detection - if detected, emulate it as Mask ROM + map_hirom_offset(0xe0, 0xff, 0x0000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB); + } + else + { + map_index(0xe0, 0xff, 0x0000, 0xffff, MAP_BSX, MAP_TYPE_RAM); + } + + map_HiROMSRAM(); + map_WRAM(); + + map_WriteProtectROM(); +} + // checksum uint16 CMemory::checksum_calc_sum (uint8 *data, uint32 length) @@ -4140,8 +4234,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r { printf("Using BPS patch %s", fname); - ret = ReadBPSPatch(new fStream(patch_file), 0, rom_size); - CLOSE_FSTREAM(patch_file); + Stream *s = new fStream(patch_file); + ret = ReadBPSPatch(s, 0, rom_size); + s->closeStream(); if (ret) { @@ -4163,8 +4258,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r { printf(" in %s", rom_filename); - ret = ReadBPSPatch(new unzStream(file), offset, rom_size); - unzCloseCurrentFile(file); + Stream *s = new unzStream(file); + ret = ReadBPSPatch(s, offset, rom_size); + s->closeStream(); if (ret) printf("!\n"); @@ -4181,8 +4277,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r { printf("Using BPS patch %s", n); - ret = ReadBPSPatch(new fStream(patch_file), 0, rom_size); - CLOSE_FSTREAM(patch_file); + Stream *s = new fStream(patch_file); + ret = ReadBPSPatch(s, 0, rom_size); + s->closeStream(); if (ret) { @@ -4201,8 +4298,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r { printf("Using UPS patch %s", fname); - ret = ReadUPSPatch(new fStream(patch_file), 0, rom_size); - CLOSE_FSTREAM(patch_file); + Stream *s = new fStream(patch_file); + ret = ReadUPSPatch(s, 0, rom_size); + s->closeStream(); if (ret) { @@ -4224,8 +4322,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r { printf(" in %s", rom_filename); - ret = ReadUPSPatch(new unzStream(file), offset, rom_size); - unzCloseCurrentFile(file); + Stream *s = new unzStream(file); + ret = ReadUPSPatch(s, offset, rom_size); + s->closeStream(); if (ret) printf("!\n"); @@ -4242,8 +4341,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r { printf("Using UPS patch %s", n); - ret = ReadUPSPatch(new fStream(patch_file), 0, rom_size); - CLOSE_FSTREAM(patch_file); + Stream *s = new fStream(patch_file); + ret = ReadUPSPatch(s, 0, rom_size); + s->closeStream(); if (ret) { @@ -4262,8 +4362,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r { printf("Using IPS patch %s", fname); - ret = ReadIPSPatch(new fStream(patch_file), offset, rom_size); - CLOSE_FSTREAM(patch_file); + Stream *s = new fStream(patch_file); + ret = ReadIPSPatch(s, offset, rom_size); + s->closeStream(); if (ret) { @@ -4289,8 +4390,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r printf("Using IPS patch %s", fname); - ret = ReadIPSPatch(new fStream(patch_file), offset, rom_size); - CLOSE_FSTREAM(patch_file); + Stream *s = new fStream(patch_file); + ret = ReadIPSPatch(s, offset, rom_size); + s->closeStream(); if (ret) { @@ -4325,8 +4427,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r printf("Using IPS patch %s", fname); - ret = ReadIPSPatch(new fStream(patch_file), offset, rom_size); - CLOSE_FSTREAM(patch_file); + Stream *s = new fStream(patch_file); + ret = ReadIPSPatch(s, offset, rom_size); + s->closeStream(); if (ret) { @@ -4359,8 +4462,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r printf("Using IPS patch %s", fname); - ret = ReadIPSPatch(new fStream(patch_file), offset, rom_size); - CLOSE_FSTREAM(patch_file); + Stream *s = new fStream(patch_file); + ret = ReadIPSPatch(s, offset, rom_size); + s->closeStream(); if (ret) { @@ -4389,8 +4493,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r { printf(" in %s", rom_filename); - ret = ReadIPSPatch(new unzStream(file), offset, rom_size); - unzCloseCurrentFile(file); + Stream *s = new unzStream(file); + ret = ReadIPSPatch(s, offset, rom_size); + s->closeStream(); if (ret) { @@ -4416,8 +4521,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r printf(" in %s", rom_filename); - ret = ReadIPSPatch(new unzStream(file), offset, rom_size); - unzCloseCurrentFile(file); + Stream *s = new unzStream(file); + ret = ReadIPSPatch(s, offset, rom_size); + s->closeStream(); if (ret) { @@ -4450,8 +4556,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r printf(" in %s", rom_filename); - ret = ReadIPSPatch(new unzStream(file), offset, rom_size); - unzCloseCurrentFile(file); + Stream *s = new unzStream(file); + ret = ReadIPSPatch(s, offset, rom_size); + s->closeStream(); if (ret) { @@ -4482,8 +4589,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r printf(" in %s", rom_filename); - ret = ReadIPSPatch(new unzStream(file), offset, rom_size); - unzCloseCurrentFile(file); + Stream *s = new unzStream(file); + ret = ReadIPSPatch(s, offset, rom_size); + s->closeStream(); if (ret) { @@ -4515,8 +4623,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r { printf("Using IPS patch %s", n); - ret = ReadIPSPatch(new fStream(patch_file), offset, rom_size); - CLOSE_FSTREAM(patch_file); + Stream *s = new fStream(patch_file); + ret = ReadIPSPatch(s, offset, rom_size); + s->closeStream(); if (ret) { @@ -4542,8 +4651,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r printf("Using IPS patch %s", n); - ret = ReadIPSPatch(new fStream(patch_file), offset, rom_size); - CLOSE_FSTREAM(patch_file); + Stream *s = new fStream(patch_file); + ret = ReadIPSPatch(s, offset, rom_size); + s->closeStream(); if (ret) { @@ -4578,8 +4688,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r printf("Using IPS patch %s", n); - ret = ReadIPSPatch(new fStream(patch_file), offset, rom_size); - CLOSE_FSTREAM(patch_file); + Stream *s = new fStream(patch_file); + ret = ReadIPSPatch(s, offset, rom_size); + s->closeStream(); if (ret) { @@ -4612,8 +4723,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r printf("Using IPS patch %s", n); - ret = ReadIPSPatch(new fStream(patch_file), offset, rom_size); - CLOSE_FSTREAM(patch_file); + Stream *s = new fStream(patch_file); + ret = ReadIPSPatch(s, offset, rom_size); + s->closeStream(); if (ret) { diff --git a/memmap.h b/memmap.h index 6db01a7f..53826a98 100644 --- a/memmap.h +++ b/memmap.h @@ -293,13 +293,14 @@ struct CMemory bool8 LoadMultiCart (const char *, const char *); bool8 LoadMultiCartInt (); bool8 LoadSufamiTurbo (); - bool8 LoadSameGame (); + bool8 LoadBSCart (); bool8 LoadGNEXT (); bool8 LoadSRAM (const char *); bool8 SaveSRAM (const char *); void ClearSRAM (bool8 onlyNonSavedSRAM = 0); bool8 LoadSRTC (void); bool8 SaveSRTC (void); + bool8 SaveMPAK (const char *); char * Safe (const char *); char * SafeANK (const char *); @@ -335,11 +336,12 @@ struct CMemory void Map_SetaDSPLoROMMap (void); void Map_SDD1LoROMMap (void); void Map_SA1LoROMMap (void); - void Map_GNEXTSA1LoROMMap (void); + void Map_BSSA1LoROMMap (void); void Map_HiROMMap (void); void Map_ExtendedHiROMMap (void); - void Map_SameGameHiROMMap (void); void Map_SPC7110HiROMMap (void); + void Map_BSCartLoROMMap(uint8); + void Map_BSCartHiROMMap(void); uint16 checksum_calc_sum (uint8 *, uint32); uint16 checksum_mirror_sum (uint8 *, uint32 &, uint32 mask = 0x800000); diff --git a/movie.cpp b/movie.cpp index af2d8b3f..87426b1f 100644 --- a/movie.cpp +++ b/movie.cpp @@ -807,7 +807,9 @@ int S9xMovieOpen (const char *filename, bool8 read_only) restore_movie_settings(); lseek(fn, Movie.SaveStateOffset, SEEK_SET); - stream = REOPEN_STREAM(fn, "rb"); + + // reopen stream to access as gzipped data + stream = REOPEN_STREAM(fn, "rb"); if (!stream) return (FILE_NOT_FOUND); @@ -820,7 +822,11 @@ int S9xMovieOpen (const char *filename, bool8 read_only) else result = S9xUnfreezeFromStream(stream); - CLOSE_STREAM(stream); + // do not close stream but close FILE * + // (msvcrt will try to close all open FILE *handles on exit - if we do CLOSE_STREAM here + // the underlying file will be closed by zlib, causing problems when msvcrt tries to do it) + delete stream; + fclose(fd); if (result != SUCCESS) return (result); diff --git a/sa1.cpp b/sa1.cpp index 16f63490..20d45946 100644 --- a/sa1.cpp +++ b/sa1.cpp @@ -313,7 +313,16 @@ static void S9xSetSA1MemMap (uint32 which1, uint8 map) for (int c = 0; c < 0x100; c += 16) { - uint8 *block = &Memory.ROM[(map & 7) * 0x100000 + (c << 12)]; + uint8 *block; + if (Multi.cartType != 5) + block = &Memory.ROM[(map & 7) * 0x100000 + (c << 12)]; + else + { + if ((map & 7) < 4) + block = Memory.ROM + Multi.cartOffsetA + ((map & 7) * 0x100000 + (c << 12)); + else + block = Memory.ROM + Multi.cartOffsetB + (((map & 7) - 4) * 0x100000 + (c << 12)); + } for (int i = c; i < c + 16; i++) Memory.Map[start + i] = SA1.Map[start + i] = block; } @@ -321,8 +330,26 @@ static void S9xSetSA1MemMap (uint32 which1, uint8 map) for (int c = 0; c < 0x200; c += 16) { // conversion to int is needed here - map is promoted but which1 is not - int32 offset = (((map & 0x80) ? map : which1) & 7) * 0x100000 + (c << 11) - 0x8000; - uint8 *block = &Memory.ROM[offset]; + int32 offset; + uint8 *block; + if (Multi.cartType != 5) + { + offset = (((map & 0x80) ? map : which1) & 7) * 0x100000 + (c << 11) - 0x8000; + block = &Memory.ROM[offset]; + } + else + { + if ((map & 7) < 4) + { + offset = (((map & 0x80) ? map : which1) & 7) * 0x100000 + (c << 11) - 0x8000; + block = Memory.ROM + Multi.cartOffsetA + offset; + } + else + { + offset = (((map & 0x80) ? (map - 4) : which1) & 7) * 0x100000 + (c << 11) - 0x8000; + block = Memory.ROM + Multi.cartOffsetB + offset; + } + } for (int i = c + 8; i < c + 16; i++) Memory.Map[start2 + i] = SA1.Map[start2 + i] = block; } diff --git a/unix/configure b/unix/configure index 699f40e6..14be08d5 100755 --- a/unix/configure +++ b/unix/configure @@ -5046,20 +5046,20 @@ fi echo "$SYSTEM_ZIP_PKG_ERRORS" >&5 if test "x${with_system_zip}" != "xcheck"; then - as_fn_error $? "--with-system-zip requested but no proper zlib found." "$LINENO" 5 + as_fn_error $? "--with-system-zip requested but no proper minizip lib found." "$LINENO" 5 else - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: zlib not found. Build without SYSTEM_ZIP support." >&5 -$as_echo "$as_me: WARNING: zlib not found. Build without SYSTEM_ZIP support." >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: minizip not found. Build without SYSTEM_ZIP support." >&5 +$as_echo "$as_me: WARNING: minizip not found. Build without SYSTEM_ZIP support." >&2;} fi elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if test "x${with_system_zip}" != "xcheck"; then - as_fn_error $? "--with-system-zip requested but no proper zlib found." "$LINENO" 5 + as_fn_error $? "--with-system-zip requested but no proper minizip lib found." "$LINENO" 5 else - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: zlib not found. Build without SYSTEM_ZIP support." >&5 -$as_echo "$as_me: WARNING: zlib not found. Build without SYSTEM_ZIP support." >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: minizip not found. Build without SYSTEM_ZIP support." >&5 +$as_echo "$as_me: WARNING: minizip not found. Build without SYSTEM_ZIP support." >&2;} fi else diff --git a/unix/configure.ac b/unix/configure.ac index 47f37808..28186c67 100644 --- a/unix/configure.ac +++ b/unix/configure.ac @@ -222,9 +222,9 @@ if test "x$enable_zip" = "xyes"; then fi S9XDEFS="$S9XDEFS -DSYSTEM_ZIP", if test "x${with_system_zip}" != "xcheck"; then - AC_MSG_ERROR([--with-system-zip requested but no proper zlib found.]) + AC_MSG_ERROR([--with-system-zip requested but no proper minizip lib found.]) else - AC_MSG_WARN([zlib not found. Build without SYSTEM_ZIP support.]) + AC_MSG_WARN([minizip not found. Build without SYSTEM_ZIP support.]) fi ) else diff --git a/win32/CD3DCG.cpp b/win32/CD3DCG.cpp index d5458cb6..95b61b5f 100644 --- a/win32/CD3DCG.cpp +++ b/win32/CD3DCG.cpp @@ -383,7 +383,7 @@ bool CD3DCG::LoadShader(const TCHAR *shaderFile) hr = pDevice->CreateVertexBuffer(sizeof(VERTEX)*4,D3DUSAGE_WRITEONLY,0,D3DPOOL_MANAGED,&pass.vertexBuffer,NULL); if(FAILED(hr)) { pass.vertexBuffer = NULL; - DXTRACE_ERR_MSGBOX(TEXT("Error creating vertex buffer"), hr); + DXTRACE_ERR_MSGBOX(L"Error creating vertex buffer", hr); return false; } @@ -449,7 +449,7 @@ void CD3DCG::ensureTextureSize(LPDIRECT3DTEXTURE9 &tex, D3DXVECTOR2 &texSize, texSize = wantedSize; if(FAILED(hr)) { - DXTRACE_ERR_MSGBOX(TEXT("Error while creating texture"), hr); + DXTRACE_ERR_MSGBOX(L"Error while creating texture", hr); return; } } @@ -860,7 +860,7 @@ void CD3DCG::setupVertexDeclaration(shaderPass &pass) LPDIRECT3DVERTEXDECLARATION9 vertexDeclaration; HRESULT hr = pDevice->CreateVertexDeclaration(vElems,&vertexDeclaration); if(FAILED(hr)) { - DXTRACE_ERR_MSGBOX(TEXT("Error creating vertex declaration"), hr); + DXTRACE_ERR_MSGBOX(L"Error creating vertex declaration", hr); } if(pass.vertexDeclaration) pass.vertexDeclaration->Release(); diff --git a/win32/CDirect3D.cpp b/win32/CDirect3D.cpp index 1c69d49d..7fd8d6eb 100644 --- a/win32/CDirect3D.cpp +++ b/win32/CDirect3D.cpp @@ -272,7 +272,7 @@ bool CDirect3D::Initialize(HWND hWnd) pD3D = Direct3DCreate9(D3D_SDK_VERSION); if(pD3D == NULL) { - DXTRACE_ERR_MSGBOX(TEXT("Error creating initial D3D9 object"), 0); + DXTRACE_ERR_MSGBOX(L"Error creating initial D3D9 object", 0); return false; } @@ -290,19 +290,19 @@ bool CDirect3D::Initialize(HWND hWnd) &dPresentParams, &pDevice); if(FAILED(hr)) { - DXTRACE_ERR_MSGBOX(TEXT("Error creating D3D9 device"), hr); + DXTRACE_ERR_MSGBOX(L"Error creating D3D9 device", hr); return false; } hr = pDevice->CreateVertexBuffer(sizeof(vertexStream),D3DUSAGE_WRITEONLY,0,D3DPOOL_MANAGED,&vertexBuffer,NULL); if(FAILED(hr)) { - DXTRACE_ERR_MSGBOX(TEXT("Error creating vertex buffer"), hr); + DXTRACE_ERR_MSGBOX(L"Error creating vertex buffer", hr); return false; } hr = pDevice->CreateVertexDeclaration(vertexElems,&vertexDeclaration); if(FAILED(hr)) { - DXTRACE_ERR_MSGBOX(TEXT("Error creating vertex declaration"), hr); + DXTRACE_ERR_MSGBOX(L"Error creating vertex declaration", hr); return false; } @@ -312,7 +312,7 @@ bool CDirect3D::Initialize(HWND hWnd) cgContext = cgCreateContext(); hr = cgD3D9SetDevice(pDevice); if(FAILED(hr)) { - DXTRACE_ERR_MSGBOX(TEXT("Error setting cg device"), hr); + DXTRACE_ERR_MSGBOX(L"Error setting cg device", hr); } cgShader = new CD3DCG(cgContext,pDevice); } @@ -650,14 +650,14 @@ void CDirect3D::Render(SSurface Src) ResetDevice(); return; default: - DXTRACE_ERR_MSGBOX( TEXT("Internal driver error"), hr); + DXTRACE_ERR_MSGBOX( L"Internal driver error", hr); return; } } //BlankTexture(drawSurface); if(FAILED(hr = drawSurface->LockRect(0, &lr, NULL, 0))) { - DXTRACE_ERR_MSGBOX( TEXT("Unable to lock texture"), hr); + DXTRACE_ERR_MSGBOX( L"Unable to lock texture", hr); return; } else { Dst.Surface = (unsigned char *)lr.pBits; @@ -757,7 +757,7 @@ void CDirect3D::CreateDrawSurface() NULL ); if(FAILED(hr)) { - DXTRACE_ERR_MSGBOX(TEXT("Error while creating texture"), hr); + DXTRACE_ERR_MSGBOX(L"Error while creating texture", hr); return; } } @@ -787,7 +787,7 @@ bool CDirect3D::BlankTexture(LPDIRECT3DTEXTURE9 texture) HRESULT hr; if(FAILED(hr = texture->LockRect(0, &lr, NULL, 0))) { - DXTRACE_ERR_MSGBOX( TEXT("Unable to lock texture"), hr); + DXTRACE_ERR_MSGBOX( L"Unable to lock texture", hr); return false; } else { memset(lr.pBits, 0, lr.Pitch * quadTextureSize); @@ -938,7 +938,7 @@ bool CDirect3D::ResetDevice() } if(FAILED(hr = pDevice->Reset(&dPresentParams))) { - DXTRACE_ERR(TEXT("Unable to reset device"), hr); + DXTRACE_ERR(L"Unable to reset device", hr); return false; } diff --git a/win32/CXAudio2.cpp b/win32/CXAudio2.cpp index 84fa533f..7bfdb6ef 100644 --- a/win32/CXAudio2.cpp +++ b/win32/CXAudio2.cpp @@ -234,7 +234,7 @@ bool CXAudio2::InitXAudio2(void) HRESULT hr; if ( FAILED(hr = XAudio2Create( &pXAudio2, 0 , XAUDIO2_DEFAULT_PROCESSOR ) ) ) { - DXTRACE_ERR_MSGBOX(TEXT("Unable to create XAudio2 object."),hr); + DXTRACE_ERR_MSGBOX(L"Unable to create XAudio2 object.",hr); MessageBox (GUI.hWnd, TEXT("\ Unable to initialize XAudio2. You will not be able to hear any\n\ sound effects or music while playing.\n\n\ @@ -257,7 +257,7 @@ bool CXAudio2::InitVoices(void) HRESULT hr; if ( FAILED(hr = pXAudio2->CreateMasteringVoice( &pMasterVoice, (Settings.Stereo?2:1), Settings.SoundPlaybackRate, 0, 0 , NULL ) ) ) { - DXTRACE_ERR_MSGBOX(TEXT("Unable to create mastering voice."),hr); + DXTRACE_ERR_MSGBOX(L"Unable to create mastering voice.",hr); return false; } @@ -272,7 +272,7 @@ bool CXAudio2::InitVoices(void) if( FAILED(hr = pXAudio2->CreateSourceVoice(&pSourceVoice, (WAVEFORMATEX*)&wfx, XAUDIO2_VOICE_NOSRC , XAUDIO2_DEFAULT_FREQ_RATIO, this, NULL, NULL ) ) ) { - DXTRACE_ERR_MSGBOX(TEXT("Unable to create source voice."),hr); + DXTRACE_ERR_MSGBOX(L"Unable to create source voice.",hr); return false; } diff --git a/win32/rsrc/resource.h b/win32/rsrc/resource.h index 0f6bf528..07ec2620 100644 --- a/win32/rsrc/resource.h +++ b/win32/rsrc/resource.h @@ -496,13 +496,14 @@ #define ID_WINDOW_SIZE_4X 40172 #define ID_DEBUG_APU_TRACE 40173 #define ID_EMULATION_BACKGROUNDINPUT 40174 +#define ID_SAVEMEMPACK 40175 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 151 -#define _APS_NEXT_COMMAND_VALUE 40175 +#define _APS_NEXT_COMMAND_VALUE 40176 #define _APS_NEXT_CONTROL_VALUE 3018 #define _APS_NEXT_SYMED_VALUE 101 #endif diff --git a/win32/rsrc/snes9x.rc b/win32/rsrc/snes9x.rc index 5c11c0a3..0629f188 100644 --- a/win32/rsrc/snes9x.rc +++ b/win32/rsrc/snes9x.rc @@ -716,14 +716,15 @@ IDB_HIDDENFOLDER BITMAP "hiddir.bmp" // remains consistent on all systems. IDI_ICON1 ICON "icon1.ico" + ///////////////////////////////////////////////////////////////////////////// // // Version // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,5,3,0 - PRODUCTVERSION 1,5,3,0 + FILEVERSION 1,5,4,1 + PRODUCTVERSION 1,5,4,1 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -822,6 +823,7 @@ BEGIN MENUITEM "S&ave SPC Data", ID_FILE_SAVE_SPC_DATA MENUITEM "Save Screenshot", ID_SAVESCREENSHOT MENUITEM "Sa&ve S-RAM Data", ID_FILE_SAVE_SRAM_DATA + MENUITEM "Save Memory Pack", ID_SAVEMEMPACK END MENUITEM "ROM Information...", IDM_ROM_INFO MENUITEM SEPARATOR diff --git a/win32/snes9xw.vcxproj.filters b/win32/snes9xw.vcxproj.filters index eb02b1ac..8020f00f 100644 --- a/win32/snes9xw.vcxproj.filters +++ b/win32/snes9xw.vcxproj.filters @@ -244,7 +244,7 @@ GUI - Emu + APU @@ -543,7 +543,7 @@ GUI - Emu + APU diff --git a/win32/wlanguage.h b/win32/wlanguage.h index 2c68bede..50735f57 100644 --- a/win32/wlanguage.h +++ b/win32/wlanguage.h @@ -597,6 +597,8 @@ Nintendo is a trade mark.") #define INFO_SAVE_SPC "Saving SPC Data." +#define MPAK_SAVE_FAILED "Failed to save Memory Pack." + #define CHEATS_INFO_ENABLED "Cheats enabled." #define CHEATS_INFO_DISABLED "Cheats disabled." #define CHEATS_INFO_ENABLED_NONE "Cheats enabled. (None are active.)" diff --git a/win32/wsnes9x.cpp b/win32/wsnes9x.cpp index 8a303486..b4de0412 100644 --- a/win32/wsnes9x.cpp +++ b/win32/wsnes9x.cpp @@ -2016,7 +2016,7 @@ LRESULT CALLBACK WinProc( { char localhostname [256]; gethostname(localhostname,256); - _stprintf(localhostmsg, TEXT("Your host name is: %s\nYour port number is: %d"), _tFromChar(localhostname), Settings.Port); + _stprintf(localhostmsg, TEXT("Your host name is: %s\nYour port number is: %d"), (TCHAR *)_tFromChar(localhostname), Settings.Port); MessageBox(GUI.hWnd,localhostmsg,TEXT("Note"),MB_OK); } } @@ -2248,6 +2248,17 @@ LRESULT CALLBACK WinProc( if(!success) S9xMessage(S9X_ERROR, S9X_FREEZE_FILE_INFO, SRM_SAVE_FAILED); } break; + case ID_SAVEMEMPACK: { + const char *filename = S9xGetFilenameInc(".bs", SRAM_DIR); + bool8 success = Memory.SaveMPAK(filename); + if (!success) + S9xMessage(S9X_ERROR, 0, MPAK_SAVE_FAILED); + else + { + sprintf(String, "Saved Memory Pack %s", filename); + S9xMessage(S9X_INFO, 0, String); + } + } break; case ID_FILE_RESET: #ifdef NETPLAY_SUPPORT if (Settings.NetPlayServer) @@ -2423,7 +2434,7 @@ LRESULT CALLBACK WinProc( { if (!LoadROM(GUI.RecentGames [i])) { - sprintf (String, ERR_ROM_NOT_FOUND, _tToChar(GUI.RecentGames [i])); + sprintf (String, ERR_ROM_NOT_FOUND, (char *)_tToChar(GUI.RecentGames [i])); S9xMessage (S9X_ERROR, S9X_ROM_NOT_FOUND, String); S9xRemoveFromRecentGames(i); } @@ -2694,7 +2705,7 @@ LRESULT CALLBACK WinProc( { TCHAR buf [NP_MAX_ACTION_LEN + 10]; - _stprintf (buf, TEXT("%s %3d%%"), _tFromChar(NetPlay.ActionMsg), (int) lParam); + _stprintf (buf, TEXT("%s %3d%%"), (TCHAR *)_tFromChar(NetPlay.ActionMsg), (int) lParam); SetWindowText (GUI.hWnd, buf); } #if 0 @@ -3693,7 +3704,7 @@ loop_exit: void FreezeUnfreeze (int slot, bool8 freeze) { - const char *filename; + char filename[_MAX_PATH +1]; char ext [_MAX_EXT + 1]; #ifdef NETPLAY_SUPPORT @@ -3706,7 +3717,7 @@ void FreezeUnfreeze (int slot, bool8 freeze) #endif snprintf(ext, _MAX_EXT, ".%03d", slot); - filename = S9xGetFilename(ext,SNAPSHOT_DIR); + strcpy(filename, S9xGetFilename(ext, SNAPSHOT_DIR)); S9xSetPause (PAUSE_FREEZE_FILE); @@ -5015,7 +5026,7 @@ INT_PTR CALLBACK DlgInfoProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { SetTextColor((HDC)wParam, GUI.InfoColor); SetBkColor((HDC)wParam, RGB(0,0,0)); - return (BOOL)GetStockObject( BLACK_BRUSH ); + return (INT_PTR)GetStockObject( BLACK_BRUSH ); } break; case WM_PAINT: @@ -5309,7 +5320,7 @@ void rominfo(const TCHAR *filename, TCHAR *namebuffer, TCHAR *sizebuffer) lstrcpy(namebuffer, ROM_ITEM_DESCNOTAVAILABLE); lstrcpy(sizebuffer, TEXT("? Mbits")); -#ifdef ZLIB +#ifdef UNZIP_SUPPORT if(IsCompressed(filename)) { unzFile uf = unzOpen(_tToChar(filename)); @@ -7006,6 +7017,7 @@ void MakeExtFile(void) out<<"smcN"<