Merge remote-tracking branch 'refs/remotes/snes9xgit/master'

This commit is contained in:
Nelson Garcia 2017-02-17 19:33:36 -08:00
commit ac9e3f2094
47 changed files with 2215 additions and 451 deletions

View File

@ -190,6 +190,7 @@
#include <math.h>
#include "snes9x.h"
#include "apu.h"
#include "msu1.h"
#include "snapshot.h"
#include "display.h"
#include "hermite_resampler.h"
@ -239,6 +240,13 @@ namespace spc
static uint32 ratio_denominator = APU_DENOMINATOR_NTSC;
}
namespace msu
{
static int buffer_size;
static uint8 *landing_buffer = NULL;
static Resampler *resampler = NULL;
}
static void EightBitize (uint8 *, int);
static void DeStereo (uint8 *, int);
static void ReverseStereo (uint8 *, int);
@ -311,6 +319,9 @@ bool8 S9xMixSamples (uint8 *buffer, int sample_count)
memset(dest, 0, sample_count << 1);
spc::resampler->clear();
if(Settings.MSU1)
msu::resampler->clear();
return (FALSE);
}
else
@ -320,6 +331,17 @@ bool8 S9xMixSamples (uint8 *buffer, int sample_count)
spc::resampler->read((short *) dest, sample_count);
if (spc::lag == spc::lag_master)
spc::lag = 0;
if (Settings.MSU1)
{
if (msu::resampler->avail() >= sample_count)
{
uint8 *msu_sample = new uint8[sample_count * 2];
msu::resampler->read((short *)msu_sample, sample_count);
for (uint32 i = 0; i < sample_count; ++i)
*((int16*)(dest+(i * 2))) += *((int16*)(msu_sample+(i * 2)));
}
}
}
else
{
@ -361,7 +383,19 @@ void S9xFinalizeSamples (void)
{
if (!Settings.Mute)
{
if (!spc::resampler->push((short *) spc::landing_buffer, SNES::dsp.spc_dsp.sample_count ()))
if (Settings.MSU1)
{
S9xMSU1Generate(SNES::dsp.spc_dsp.sample_count());
if (!msu::resampler->push((short *)msu::landing_buffer, S9xMSU1Samples()))
{
//spc::sound_in_sync = FALSE;
//if (Settings.SoundSync && !Settings.TurboMode)
//return;
}
}
if (!spc::resampler->push((short *)spc::landing_buffer, SNES::dsp.spc_dsp.sample_count()))
{
/* We weren't able to process the entire buffer. Potential overrun. */
spc::sound_in_sync = FALSE;
@ -371,6 +405,7 @@ void S9xFinalizeSamples (void)
}
}
if (!Settings.SoundSync || Settings.TurboMode || Settings.Mute)
spc::sound_in_sync = TRUE;
else
@ -380,6 +415,9 @@ void S9xFinalizeSamples (void)
spc::sound_in_sync = FALSE;
SNES::dsp.spc_dsp.set_output((SNES::SPC_DSP::sample_t *) spc::landing_buffer, spc::buffer_size);
if (Settings.MSU1)
S9xMSU1SetOutput((int16 *)msu::landing_buffer, msu::buffer_size);
}
void S9xLandSamples (void)
@ -393,6 +431,8 @@ void S9xLandSamples (void)
void S9xClearSamples (void)
{
spc::resampler->clear();
if (Settings.MSU1)
msu::resampler->clear();
spc::lag = spc::lag_master;
}
@ -419,6 +459,12 @@ static void UpdatePlaybackRate (void)
double time_ratio = (double) Settings.SoundInputRate * spc::timing_hack_numerator / (Settings.SoundPlaybackRate * spc::timing_hack_denominator);
spc::resampler->time_ratio(time_ratio);
if (Settings.MSU1)
{
time_ratio = (44100.0 / Settings.SoundPlaybackRate) * (Settings.SoundInputRate / 32040);
msu::resampler->time_ratio(time_ratio);
}
}
bool8 S9xInitSound (int buffer_ms, int lag_ms)
@ -426,8 +472,8 @@ bool8 S9xInitSound (int buffer_ms, int lag_ms)
// buffer_ms : buffer size given in millisecond
// lag_ms : allowable time-lag given in millisecond
int sample_count = buffer_ms * 32000 / 1000;
int lag_sample_count = lag_ms * 32000 / 1000;
int sample_count = buffer_ms * 32040 / 1000;
int lag_sample_count = lag_ms * 32040 / 1000;
spc::lag_master = lag_sample_count;
if (Settings.Stereo)
@ -442,6 +488,7 @@ bool8 S9xInitSound (int buffer_ms, int lag_ms)
spc::buffer_size <<= 1;
if (Settings.SixteenBitSound)
spc::buffer_size <<= 1;
msu::buffer_size = ((buffer_ms * 44100 / 1000) * 44100 / 32040) << 2; // Always 16-bit, Stereo
printf("Sound buffer size: %d (%d samples)\n", spc::buffer_size, sample_count);
@ -450,6 +497,11 @@ bool8 S9xInitSound (int buffer_ms, int lag_ms)
spc::landing_buffer = new uint8[spc::buffer_size * 2];
if (!spc::landing_buffer)
return (FALSE);
if (msu::landing_buffer)
delete[] msu::landing_buffer;
msu::landing_buffer = new uint8[msu::buffer_size * 2];
if (!msu::landing_buffer)
return (FALSE);
/* The resampler and spc unit use samples (16-bit short) as
arguments. Use 2x in the resampler for buffer leveling with SoundSync */
@ -465,6 +517,20 @@ bool8 S9xInitSound (int buffer_ms, int lag_ms)
else
spc::resampler->resize(spc::buffer_size >> (Settings.SoundSync ? 0 : 1));
if (!msu::resampler)
{
msu::resampler = new HermiteResampler(msu::buffer_size);
if (!msu::resampler)
{
delete[] msu::landing_buffer;
return (FALSE);
}
}
else
msu::resampler->resize(msu::buffer_size);
SNES::dsp.spc_dsp.set_output ((SNES::SPC_DSP::sample_t *) spc::landing_buffer, spc::buffer_size);
UpdatePlaybackRate();
@ -503,6 +569,7 @@ bool8 S9xInitAPU (void)
spc::landing_buffer = NULL;
spc::shrink_buffer = NULL;
spc::resampler = NULL;
msu::resampler = NULL;
return (TRUE);
}
@ -526,6 +593,18 @@ void S9xDeinitAPU (void)
delete[] spc::shrink_buffer;
spc::shrink_buffer = NULL;
}
if (msu::resampler)
{
delete msu::resampler;
msu::resampler = NULL;
}
if (msu::landing_buffer)
{
delete[] msu::landing_buffer;
msu::landing_buffer = NULL;
}
}
static inline int S9xAPUGetClock (int32 cpucycles)
@ -603,6 +682,9 @@ void S9xResetAPU (void)
SNES::dsp.spc_dsp.set_spc_snapshot_callback(SPCSnapshotCallback);
spc::resampler->clear();
if (Settings.MSU1)
msu::resampler->clear();
}
void S9xSoftResetAPU (void)
@ -615,6 +697,9 @@ void S9xSoftResetAPU (void)
SNES::dsp.spc_dsp.set_output ((SNES::SPC_DSP::sample_t *) spc::landing_buffer, spc::buffer_size >> 1);
spc::resampler->clear();
if (Settings.MSU1)
msu::resampler->clear();
}
void S9xAPUSaveState (uint8 *block)

View File

@ -4,6 +4,7 @@
#define __HERMITE_RESAMPLER_H
#include "resampler.h"
#include <assert.h>
#undef CLAMP
#undef SHORT_CLAMP
@ -66,6 +67,7 @@ class HermiteResampler : public Resampler
void
read (short *data, int num_samples)
{
assert((num_samples & 1) == 0); // resampler always processes both stereo samples
int i_position = start >> 1;
int max_samples = buffer_size >> 1;
short *internal_buffer = (short *) buffer;

505
bsx.cpp
View File

@ -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();
}

5
bsx.h
View File

@ -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;

View File

@ -197,7 +197,11 @@
#include <string>
#ifdef UNZIP_SUPPORT
#include "unzip/unzip.h"
# ifdef SYSTEM_ZIP
# include <minizip/unzip.h>
# else
# include "unzip/unzip.h"
# endif
#endif
#include "snes9x.h"

View File

@ -295,6 +295,7 @@ void S9xReset (void)
S9xResetPPU();
S9xResetDMA();
S9xResetAPU();
S9xResetMSU();
if (Settings.DSP)
S9xResetDSP();
@ -312,6 +313,8 @@ void S9xReset (void)
S9xResetOBC1();
if (Settings.SRTC)
S9xResetSRTC();
if (Settings.MSU1)
S9xMSU1Init();
S9xInitCheatData();
}
@ -329,6 +332,7 @@ void S9xSoftReset (void)
S9xSoftResetPPU();
S9xResetDMA();
S9xSoftResetAPU();
S9xResetMSU();
if (Settings.DSP)
S9xResetDSP();
@ -346,6 +350,8 @@ void S9xSoftReset (void)
S9xResetOBC1();
if (Settings.SRTC)
S9xResetSRTC();
if (Settings.MSU1)
S9xMSU1Init();
S9xInitCheatData();
}

View File

@ -199,6 +199,7 @@
#include "obc1.h"
#include "seta.h"
#include "bsx.h"
#include "msu1.h"
#define addCyclesInMemoryAccess \
if (!CPU.InDMAorHDMA) \

View File

@ -232,6 +232,7 @@ struct SSPC7110Snapshot s7snap;
struct SSRTCSnapshot srtcsnap;
struct SRTCData RTCData;
struct SBSX BSX;
struct SMSU1 MSU1;
struct SMulti Multi;
struct SSettings Settings;
struct SSNESGameFixes SNESGameFixes;

View File

@ -136,6 +136,11 @@ snes9x_gtk_SOURCES += \
../apu/bapu/smp/smp.cpp \
../apu/bapu/smp/smp_state.cpp
# MSU1
snes9x_gtk_SOURCES += \
../msu1.cpp \
../msu1.h
# DSP
snes9x_gtk_SOURCES += \
../dsp.cpp \
@ -196,12 +201,16 @@ snes9x_gtk_SOURCES += \
../server.cpp
endif
# Zip support is nonconfigurable.
snes9x_gtk_SOURCES += \
../loadzip.cpp \
../loadzip.cpp
if ! SYSTEM_ZIP
snes9x_gtk_SOURCES += \
../unzip/unzip.c \
../unzip/ioapi.c \
../unzip/zip.c
endif
UNZIPDEFINES=-DUNZIP_SUPPORT
if JMA

View File

@ -138,6 +138,12 @@ AC_ARG_WITH(zlib,
[],
[with_zlib=yes])
AC_ARG_WITH(system-zip,
[AS_HELP_STRING([--with(out)-system-zip],
[Use system zip])],
[],
[system_zip=check])
AC_ARG_WITH(screenshot,
[AS_HELP_STRING([--with(out)-screenshot],
[Screenshot support through libpng if available (default: with)])],
@ -313,6 +319,25 @@ if test yes = "$with_screenshot"; then
])
fi
SYSTEM_ZIP=0
SYSTEM_ZIP_CFLAGS=""
SYSTEM_ZIP_LIBS=""
ZIP_CFLAGS="-I../unzip"
if test no != "$with_system_zip" && test yes = "$with_zlib" ; then
PKG_CHECK_MODULES([SYSTEM_ZIP],[minizip],[
ZIP_CFLAGS=""
SYSTEM_ZIP=yes
CFLAGS="$CFLAGS $SYSTEM_ZIP_CFLAGS -DSYSTEM_ZIP"
LIBS="$LIBS $SYSTEM_ZIP_LIBS"
],[
if test check = "$with_system_zip"; then
AC_MSG_WARN(Cannot find system minizip library)
else
AC_MSG_ERROR(--with-system-zip given but cannot find system minizip library)
fi
])
fi
if test yes = "$with_hq2x" ; then
HQ2X=yes
CFLAGS="$CFLAGS -DUSE_HQ2X"
@ -440,7 +465,7 @@ if test $ac_cv_my_sar_int8 = yes && \
CFLAGS="$CFLAGS -DRIGHTSHIFT_IS_SAR"
fi
CFLAGS="$CFLAGS -DUNZIP_SUPPORT -DSPC700_C -I. -I.. -I../unzip"
CFLAGS="$CFLAGS -DUNZIP_SUPPORT -DSPC700_C -I. -I.. $ZIP_CFLAGS"
CXXFLAGS="$CFLAGS"
@ -462,6 +487,7 @@ AM_CONDITIONAL(ALSA, [test yes = "$ALSA"])
AM_CONDITIONAL(PULSEAUDIO, [test yes = "$PULSEAUDIO"])
AM_CONDITIONAL(HQ2X, [test yes = "$HQ2X"])
AM_CONDITIONAL(XBRZ, [test yes = "$XBRZ"])
AM_CONDITIONAL(SYSTEM_ZIP, [test yes = "$SYSTEM_ZIP"])
AC_SUBST(NASM)
AC_SUBST(NASM_FLAGS)

View File

@ -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
};

View File

@ -208,7 +208,7 @@
#define SAVE_INFO_LOAD "Loaded"
#define SAVE_INFO_OOPS "Auto-saving 'oops' snapshot"
#define SAVE_ERR_WRONG_FORMAT "File not in Snes9x snapshot format"
#define SAVE_ERR_WRONG_VERSION "Incompatable snapshot version"
#define SAVE_ERR_WRONG_VERSION "Incompatible snapshot version"
#define SAVE_ERR_ROM_NOT_FOUND "ROM image \"%s\" for snapshot not found"
#define SAVE_ERR_SAVE_NOT_FOUND "Snapshot %s does not exist"

View File

@ -167,6 +167,8 @@ else ifneq (,$(findstring armv,$(platform)))
CXXFLAGS += -marm -mcpu=cortex-a8
else ifneq (,$(findstring cortexa9,$(platform)))
CXXFLAGS += -marm -mcpu=cortex-a9
else ifneq (,$(findstring cortexa53,$(platform)))
CXXFLAGS += -marm -mcpu=cortex-a53
endif
CXXFLAGS += -marm
ifneq (,$(findstring neon,$(platform)))
@ -180,6 +182,14 @@ else ifneq (,$(findstring armv,$(platform)))
endif
CXXFLAGS += -DARM
# Android
else ifneq (,$(findstring android,$(platform)))
TARGET := $(TARGET_NAME)_libretro_android.so
SHARED := -shared -Wl,--no-undefined -march=armv7-a -Wl,--fix-cortex-a8
fpic := -fPIC
CXXFLAGS += -marm -march=armv7-a -mfloat-abi=softfp -mfpu=neon -DANDROID -DARM
HAVE_NEON = 1
# Windows
else
TARGET := $(TARGET_NAME)_libretro.dll

View File

@ -30,11 +30,14 @@ SOURCES_CXX := $(CORE_DIR)/apu/apu.cpp \
$(CORE_DIR)/globals.cpp \
$(CORE_DIR)/logger.cpp \
$(CORE_DIR)/memmap.cpp \
$(CORE_DIR)/movie.cpp \
$(CORE_DIR)/msu1.cpp \
$(CORE_DIR)/obc1.cpp \
$(CORE_DIR)/ppu.cpp \
$(CORE_DIR)/stream.cpp \
$(CORE_DIR)/sa1.cpp \
$(CORE_DIR)/sa1cpu.cpp \
$(CORE_DIR)/screenshot.cpp \
$(CORE_DIR)/sdd1.cpp \
$(CORE_DIR)/sdd1emu.cpp \
$(CORE_DIR)/seta.cpp \

View File

@ -222,6 +222,7 @@
<ClInclude Include="..\messages.h" />
<ClInclude Include="..\missing.h" />
<ClInclude Include="..\movie.h" />
<ClInclude Include="..\msu1.h" />
<ClInclude Include="..\netplay.h" />
<ClInclude Include="..\obc1.h" />
<ClInclude Include="..\pixform.h" />
@ -274,6 +275,7 @@
<ClCompile Include="..\logger.cpp" />
<ClCompile Include="..\memmap.cpp" />
<ClCompile Include="..\movie.cpp" />
<ClCompile Include="..\msu1.cpp" />
<ClCompile Include="..\netplay.cpp" />
<ClCompile Include="..\obc1.cpp" />
<ClCompile Include="..\ppu.cpp" />

View File

@ -180,6 +180,9 @@
<ClInclude Include="libretro.h">
<Filter>libretro</Filter>
</ClInclude>
<ClInclude Include="..\msu1.h">
<Filter>s9x-source</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\bsx.cpp">
@ -338,5 +341,8 @@
<ClCompile Include="libretro.cpp">
<Filter>libretro</Filter>
</ClCompile>
<ClCompile Include="..\msu1.cpp">
<Filter>s9x-source</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -76,7 +76,7 @@ static bool rom_loaded = false;
void retro_set_environment(retro_environment_t cb)
{
environ_cb = cb;
const struct retro_variable variables[] = {
// These variable names and possible values constitute an ABI with ZMZ (ZSNES Libretro player).
// Changing "Show layer 1" is fine, but don't change "layer_1"/etc or the possible values ("Yes|No").
@ -98,7 +98,7 @@ void retro_set_environment(retro_environment_t cb)
{ "snes9x_sndchan_8", "Enable sound channel 8; Yes|No" },
{ NULL, NULL },
};
environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, (void *)variables);
const struct retro_controller_description port_1[] = {
@ -128,9 +128,9 @@ static void update_variables(void)
{
char key[256];
struct retro_variable var;
var.key=key;
int disabled_channels=0;
strcpy(key, "snes9x_sndchan_x");
for (int i=0;i<8;i++)
@ -140,7 +140,7 @@ static void update_variables(void)
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value && var.value[0]=='N') disabled_channels|=1<<i;
}
S9xSetSoundControl(disabled_channels^0xFF);
int disabled_layers=0;
strcpy(key, "snes9x_layer_x");
for (int i=0;i<5;i++)
@ -150,7 +150,7 @@ static void update_variables(void)
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value && var.value[0]=='N') disabled_layers|=1<<i;
}
Settings.BG_Forced=disabled_layers;
//for some reason, Transparency seems to control both the fixed color and the windowing registers?
var.key="snes9x_gfx_clip";
var.value=NULL;
@ -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;
}
@ -192,7 +192,7 @@ void retro_get_system_av_info(struct retro_system_av_info *info)
info->geometry.max_width = MAX_SNES_WIDTH;
info->geometry.max_height = MAX_SNES_HEIGHT;
info->geometry.aspect_ratio = 4.0f / 3.0f;
info->timing.sample_rate = 32040.5;
info->timing.sample_rate = 32040;
info->timing.fps = retro_get_region() == RETRO_REGION_NTSC ? 21477272.0 / 357366.0 : 21281370.0 / 425568.0;
}
@ -256,10 +256,10 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code)
{
uint32 address;
uint8 val;
bool8 sram;
uint8 bytes[3];//used only by GoldFinger, ignored for now
if (S9xGameGenieToRaw(code, address, val)!=NULL &&
S9xProActionReplayToRaw(code, address, val)!=NULL &&
S9xGoldFingerToRaw(code, address, sram, val, bytes)!=NULL)
@ -268,13 +268,13 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code)
}
if (index>Cheat.num_cheats) return; // cheat added in weird order, ignore
if (index==Cheat.num_cheats) Cheat.num_cheats++;
Cheat.c[index].address = address;
Cheat.c[index].byte = val;
Cheat.c[index].enabled = enabled;
Cheat.c[index].saved = FALSE; // it'll be saved next time cheats run anyways
Settings.ApplyCheats=true;
S9xApplyCheats();
}
@ -374,7 +374,7 @@ bool retro_load_game(const struct retro_game_info *game)
if (!rom_loaded && log_cb)
log_cb(RETRO_LOG_ERROR, "[libretro]: Rom loading failed...\n");
return rom_loaded;
}
@ -387,7 +387,7 @@ bool retro_load_game_special(unsigned game_type,
init_descriptors();
switch (game_type) {
case RETRO_GAME_TYPE_BSX:
if(num_info == 1) {
rom_loaded = Memory.LoadROMMem((const uint8_t*)info[0].data,info[0].size);
} else if(num_info == 2) {
@ -399,7 +399,7 @@ bool retro_load_game_special(unsigned game_type,
log_cb(RETRO_LOG_ERROR, "[libretro]: BSX ROM loading failed...\n");
break;
case RETRO_GAME_TYPE_BSX_SLOTTED:
if(num_info == 2)
@ -462,8 +462,8 @@ void retro_init()
Settings.FrameTimeNTSC = 16667;
Settings.SixteenBitSound = TRUE;
Settings.Stereo = TRUE;
Settings.SoundPlaybackRate = 32000;
Settings.SoundInputRate = 32000;
Settings.SoundPlaybackRate = 32040;
Settings.SoundInputRate = 32040;
Settings.SupportHiRes = TRUE;
Settings.Transparency = TRUE;
Settings.AutoDisplayMessages = TRUE;
@ -633,7 +633,7 @@ static void map_buttons()
}
// libretro uses relative values for analogue devices.
// libretro uses relative values for analogue devices.
// S9x seems to use absolute values, but do convert these into relative values in the core. (Why?!)
// Hack around it. :)
static int16_t snes_mouse_state[2][2] = {{0}, {0}};
@ -692,7 +692,7 @@ static void report_buttons()
for (int i = JUSTIFIER_TRIGGER; i <= JUSTIFIER_LAST; i++)
S9xReportButton(MAKE_BUTTON(2, i), input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, i));
break;
default:
if (log_cb)
log_cb(RETRO_LOG_ERROR, "[libretro]: Unknown device...\n");
@ -718,14 +718,14 @@ void retro_deinit()
Memory.Deinit();
S9xGraphicsDeinit();
S9xUnmapAllControls();
free(GFX.Screen);
}
unsigned retro_get_region()
{
return Settings.PAL ? RETRO_REGION_PAL : RETRO_REGION_NTSC;
{
return Settings.PAL ? RETRO_REGION_PAL : RETRO_REGION_NTSC;
}
void* retro_get_memory_data(unsigned type)
@ -794,7 +794,7 @@ size_t retro_serialize_size()
}
bool retro_serialize(void *data, size_t size)
{
{
if (S9xFreezeGameMem((uint8_t*)data,size) == FALSE)
return false;
@ -802,7 +802,7 @@ bool retro_serialize(void *data, size_t size)
}
bool retro_unserialize(const void* data, size_t size)
{
{
if (S9xUnfreezeGameMem((const uint8_t*)data,size) != SUCCESS)
return false;
return true;
@ -870,8 +870,8 @@ void S9xExit() {}
bool S9xPollPointer(unsigned int, short*, short*) { return false; }
const char *S9xChooseMovieFilename(unsigned char) { return NULL; }
bool8 S9xOpenSnapshotFile(const char* filepath, bool8 read_only, STREAM *file)
{
bool8 S9xOpenSnapshotFile(const char* filepath, bool8 read_only, STREAM *file)
{
if(read_only)
{
if((*file = OPEN_STREAM(filepath, "rb")) != 0)
@ -889,12 +889,12 @@ bool8 S9xOpenSnapshotFile(const char* filepath, bool8 read_only, STREAM *file)
return (FALSE);
}
void S9xCloseSnapshotFile(STREAM file)
void S9xCloseSnapshotFile(STREAM file)
{
CLOSE_STREAM(file);
}
void S9xAutoSaveSRAM()
void S9xAutoSaveSRAM()
{
return;
}

View File

@ -192,7 +192,11 @@
#include <assert.h>
#include <ctype.h>
#ifdef SYSTEM_ZIP
#include <minizip/unzip.h>
#else
#include "unzip/unzip.h"
#endif
#include "snes9x.h"
#include "memmap.h"
@ -257,7 +261,7 @@ bool8 LoadZip (const char *zipname, uint32 *TotalFileSize, uint8 *buffer)
uint8 *ptr = buffer;
bool8 more = FALSE;
unzLocateFile(file, filename, 1);
unzLocateFile(file, filename, NULL);
unzGetCurrentFileInfo(file, &info, filename, 128, NULL, 0, NULL, 0);
if (unzOpenCurrentFile(file) != UNZ_OK)
@ -279,7 +283,7 @@ bool8 LoadZip (const char *zipname, uint32 *TotalFileSize, uint8 *buffer)
return (FALSE);
}
if (l <= 0 || l != FileSize)
if (l <= 0 || l != (int) FileSize)
{
unzClose(file);
return (FALSE);
@ -317,7 +321,7 @@ bool8 LoadZip (const char *zipname, uint32 *TotalFileSize, uint8 *buffer)
if (more)
{
if (unzLocateFile(file, filename, 1) != UNZ_OK ||
if (unzLocateFile(file, filename, NULL) != UNZ_OK ||
unzGetCurrentFileInfo(file, &info, filename, 128, NULL, 0, NULL, 0) != UNZ_OK ||
unzOpenCurrentFile(file) != UNZ_OK)
break;

View File

@ -193,7 +193,11 @@
#include <assert.h>
#ifdef UNZIP_SUPPORT
#include "unzip/unzip.h"
# ifdef SYSTEM_ZIP
# include <minizip/unzip.h>
# else
# include "unzip/unzip.h"
# endif
#endif
#ifdef JMA_SUPPORT
@ -201,6 +205,7 @@
#endif
#include <ctype.h>
#include <sys/stat.h>
#include "snes9x.h"
#include "memmap.h"
@ -952,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);
@ -1238,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);
}
@ -1254,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);
@ -1861,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)
@ -1883,7 +1905,7 @@ bool8 CMemory::LoadMultiCartInt ()
memmove(ROM + Multi.cartOffsetA, ROM, Multi.cartSizeA + Multi.cartSizeB);
else if(Multi.cartOffsetB) // 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];
@ -1913,11 +1935,8 @@ bool8 CMemory::LoadMultiCartInt ()
break;
case 3:
r = LoadSameGame();
break;
case 5:
r = LoadGNEXT();
r = LoadBSCart();
break;
default:
@ -1981,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);
}
@ -2209,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)
@ -2360,6 +2410,7 @@ void CMemory::InitROM (void)
Settings.SETA = 0;
Settings.SRTC = FALSE;
Settings.BS = FALSE;
Settings.MSU1 = FALSE;
SuperFX.nRomBanks = CalculatedSize >> 15;
@ -2534,6 +2585,9 @@ void CMemory::InitROM (void)
break;
}
// MSU1
Settings.MSU1 = S9xMSU1ROMExists();
//// Map memory and calculate checksum
Map_Initialize();
@ -2551,7 +2605,7 @@ void CMemory::InitROM (void)
Map_ExtendedHiROMMap();
else
if (Multi.cartType == 3)
Map_SameGameHiROMMap();
Map_BSCartHiROMMap();
else
Map_HiROMMap();
}
@ -2569,7 +2623,7 @@ void CMemory::InitROM (void)
if (Settings.SA1)
{
if (Multi.cartType == 5)
Map_GNEXTSA1LoROMMap();
Map_BSSA1LoROMMap();
else
Map_SA1LoROMMap();
}
@ -2583,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();
@ -3254,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);
@ -3272,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();
@ -3334,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");
@ -3372,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)
@ -3486,7 +3589,7 @@ const char * CMemory::KartContents (void)
static char str[64];
static const char *contents[3] = { "ROM", "ROM+RAM", "ROM+RAM+BAT" };
char chip[16];
char chip[20];
if (ROMType == 0 && !Settings.BS)
return ("ROM");
@ -3532,6 +3635,9 @@ const char * CMemory::KartContents (void)
else
strcpy(chip, "");
if (Settings.MSU1)
sprintf(chip + strlen(chip), "+MSU-1");
sprintf(str, "%s%s", contents[(ROMType & 0xf) % 3], chip);
return (str);
@ -4128,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)
{
@ -4151,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");
@ -4169,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)
{
@ -4189,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)
{
@ -4212,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");
@ -4230,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)
{
@ -4250,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)
{
@ -4277,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)
{
@ -4313,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)
{
@ -4347,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)
{
@ -4377,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)
{
@ -4404,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)
{
@ -4438,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)
{
@ -4470,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)
{
@ -4503,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)
{
@ -4530,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)
{
@ -4566,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)
{
@ -4600,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)
{

View File

@ -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);

View File

@ -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);

490
msu1.cpp Normal file
View File

@ -0,0 +1,490 @@
/***********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
(c) Copyright 2009 - 2016 BearOso,
OV2
(c) Copyright 2011 - 2016 Hans-Kristian Arntzen,
Daniel De Matteis
(Under no circumstances will commercial rights be given)
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
C4 x86 assembler and some C emulation code
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
Nach,
zsKnight (zsknight@zsnes.com)
C4 C++ code
(c) Copyright 2003 - 2006 Brad Jorsch,
Nach
DSP-1 emulator code
(c) Copyright 1998 - 2006 _Demo_,
Andreas Naive (andreasnaive@gmail.com),
Gary Henderson,
Ivar (ivar@snes9x.com),
John Weidman,
Kris Bleakley,
Matthew Kendora,
Nach,
neviksti (neviksti@hotmail.com)
DSP-2 emulator code
(c) Copyright 2003 John Weidman,
Kris Bleakley,
Lord Nightmare (lord_nightmare@users.sourceforge.net),
Matthew Kendora,
neviksti
DSP-3 emulator code
(c) Copyright 2003 - 2006 John Weidman,
Kris Bleakley,
Lancer,
z80 gaiden
DSP-4 emulator code
(c) Copyright 2004 - 2006 Dreamer Nom,
John Weidman,
Kris Bleakley,
Nach,
z80 gaiden
OBC1 emulator code
(c) Copyright 2001 - 2004 zsKnight,
pagefault (pagefault@zsnes.com),
Kris Bleakley
Ported from x86 assembler to C by sanmaiwashi
SPC7110 and RTC C++ emulator code used in 1.39-1.51
(c) Copyright 2002 Matthew Kendora with research by
zsKnight,
John Weidman,
Dark Force
SPC7110 and RTC C++ emulator code used in 1.52+
(c) Copyright 2009 byuu,
neviksti
S-DD1 C emulator code
(c) Copyright 2003 Brad Jorsch with research by
Andreas Naive,
John Weidman
S-RTC C emulator code
(c) Copyright 2001 - 2006 byuu,
John Weidman
ST010 C++ emulator code
(c) Copyright 2003 Feather,
John Weidman,
Kris Bleakley,
Matthew Kendora
Super FX x86 assembler emulator code
(c) Copyright 1998 - 2003 _Demo_,
pagefault,
zsKnight
Super FX C emulator code
(c) Copyright 1997 - 1999 Ivar,
Gary Henderson,
John Weidman
Sound emulator code used in 1.5-1.51
(c) Copyright 1998 - 2003 Brad Martin
(c) Copyright 1998 - 2006 Charles Bilyue'
Sound emulator code used in 1.52+
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
S-SMP emulator code used in 1.54+
(c) Copyright 2016 byuu
SH assembler code partly based on x86 assembler code
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
NTSC filter
(c) Copyright 2006 - 2007 Shay Green
GTK+ GUI code
(c) Copyright 2004 - 2016 BearOso
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
(c) Copyright 2009 - 2016 OV2
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2011 zones
Libretro port
(c) Copyright 2011 - 2016 Hans-Kristian Arntzen,
Daniel De Matteis
(Under no circumstances will commercial rights be given)
MSU-1 code
(c) Copyright 2016 qwertymodo
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com/
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
warranty. In no event shall the authors be held liable for any damages
arising from the use of this software or it's derivatives.
Snes9x is freeware for PERSONAL USE only. Commercial users should
seek permission of the copyright holders first. Commercial use includes,
but is not limited to, charging money for Snes9x or software derived from
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
using Snes9x as a promotion for your commercial product.
The copyright holders request that bug fixes and improvements to the code
should be forwarded to them so everyone can benefit from the modifications
in future versions.
Super NES and Super Nintendo Entertainment System are trademarks of
Nintendo Co., Limited and its subsidiary companies.
***********************************************************************************/
#include "snes9x.h"
#include "display.h"
#include "msu1.h"
#include "apu/bapu/dsp/blargg_endian.h"
#include <fstream>
#include <sys/stat.h>
std::ifstream dataFile, audioFile;
uint32 audioLoopPos;
uint32 partial_samples;
// Sample buffer
int16 *bufPos, *bufBegin, *bufEnd;
bool AudioOpen()
{
MSU1.MSU1_STATUS |= AudioError;
if (audioFile.is_open())
audioFile.close();
char ext[_MAX_EXT];
snprintf(ext, _MAX_EXT, "-%d.pcm", MSU1.MSU1_CURRENT_TRACK);
audioFile.clear();
audioFile.open(S9xGetFilename(ext, ROMFILENAME_DIR), std::ios::in | std::ios::binary);
if (audioFile.good())
{
if (audioFile.get() != 'M')
return false;
if (audioFile.get() != 'S')
return false;
if (audioFile.get() != 'U')
return false;
if (audioFile.get() != '1')
return false;
audioFile.read((char *)&audioLoopPos, 4);
audioLoopPos = GET_LE32(&audioLoopPos);
audioLoopPos <<= 2;
audioLoopPos += 8;
MSU1.MSU1_STATUS &= ~AudioError;
return true;
}
return false;
}
bool DataOpen()
{
if (dataFile.is_open())
dataFile.close();
dataFile.clear();
dataFile.open(S9xGetFilename(".msu", ROMFILENAME_DIR), std::ios::in | std::ios::binary);
return dataFile.is_open();
}
void S9xResetMSU(void)
{
MSU1.MSU1_STATUS = 0;
MSU1.MSU1_DATA_SEEK = 0;
MSU1.MSU1_DATA_POS = 0;
MSU1.MSU1_TRACK_SEEK = 0;
MSU1.MSU1_CURRENT_TRACK = 0;
MSU1.MSU1_RESUME_TRACK = 0;
MSU1.MSU1_VOLUME = 0;
MSU1.MSU1_CONTROL = 0;
MSU1.MSU1_AUDIO_POS = 0;
MSU1.MSU1_RESUME_POS = 0;
bufPos = 0;
bufBegin = 0;
bufEnd = 0;
partial_samples = 0;
if (dataFile.is_open())
dataFile.close();
if (audioFile.is_open())
audioFile.close();
Settings.MSU1 = S9xMSU1ROMExists();
}
void S9xMSU1Init(void)
{
S9xResetMSU();
DataOpen();
}
bool S9xMSU1ROMExists(void)
{
struct stat buf;
return (stat(S9xGetFilename(".msu", ROMFILENAME_DIR), &buf) == 0);
}
void S9xMSU1Generate(int sample_count)
{
partial_samples += 44100 * sample_count;
while (((uintptr_t)bufPos < (uintptr_t)bufEnd) && (MSU1.MSU1_STATUS & AudioPlaying) && partial_samples > 32040)
{
if (audioFile.is_open())
{
int16 sample;
if (audioFile.read((char *)&sample, 2).good())
{
sample = (int16)((double)(int16)GET_LE16(&sample) * (double)MSU1.MSU1_VOLUME / 255.0);
*(bufPos++) = sample;
MSU1.MSU1_AUDIO_POS += 2;
partial_samples -= 32040;
}
else
if (audioFile.eof())
{
sample = (int16)((double)(int16)GET_LE16(&sample) * (double)MSU1.MSU1_VOLUME / 255.0);
*(bufPos++) = sample;
MSU1.MSU1_AUDIO_POS += 2;
partial_samples -= 32040;
if (MSU1.MSU1_STATUS & AudioRepeating)
{
audioFile.clear();
MSU1.MSU1_AUDIO_POS = audioLoopPos;
audioFile.seekg(MSU1.MSU1_AUDIO_POS);
}
else
{
MSU1.MSU1_STATUS &= ~(AudioPlaying | AudioRepeating);
audioFile.clear();
audioFile.seekg(8);
return;
}
}
else
{
MSU1.MSU1_STATUS &= ~(AudioPlaying | AudioRepeating);
return;
}
}
else
{
MSU1.MSU1_STATUS &= ~(AudioPlaying | AudioRepeating);
return;
}
}
}
uint8 S9xMSU1ReadPort(int port)
{
switch (port)
{
case 0:
return MSU1.MSU1_STATUS;
case 1:
if (MSU1.MSU1_STATUS & DataBusy)
return 0;
if (dataFile.fail() || dataFile.bad() || dataFile.eof())
return 0;
MSU1.MSU1_DATA_POS++;
return dataFile.get();
case 2:
return 'S';
case 3:
return '-';
case 4:
return 'M';
case 5:
return 'S';
case 6:
return 'U';
case 7:
return '1';
}
return 0;
}
void S9xMSU1WritePort(int port, uint8 byte)
{
switch (port)
{
case 0:
MSU1.MSU1_DATA_SEEK &= 0xFFFFFF00;
MSU1.MSU1_DATA_SEEK |= byte << 0;
break;
case 1:
MSU1.MSU1_DATA_SEEK &= 0xFFFF00FF;
MSU1.MSU1_DATA_SEEK |= byte << 8;
break;
case 2:
MSU1.MSU1_DATA_SEEK &= 0xFF00FFFF;
MSU1.MSU1_DATA_SEEK |= byte << 16;
break;
case 3:
MSU1.MSU1_DATA_SEEK &= 0x00FFFFFF;
MSU1.MSU1_DATA_SEEK |= byte << 24;
MSU1.MSU1_DATA_POS = MSU1.MSU1_DATA_SEEK;
if(dataFile.good())
dataFile.seekg(MSU1.MSU1_DATA_POS);
break;
case 4:
MSU1.MSU1_TRACK_SEEK &= 0xFF00;
MSU1.MSU1_TRACK_SEEK |= byte;
break;
case 5:
MSU1.MSU1_TRACK_SEEK &= 0x00FF;
MSU1.MSU1_TRACK_SEEK |= (byte << 8);
MSU1.MSU1_CURRENT_TRACK = MSU1.MSU1_TRACK_SEEK;
MSU1.MSU1_STATUS &= ~AudioPlaying;
MSU1.MSU1_STATUS &= ~AudioRepeating;
if (AudioOpen())
{
if (MSU1.MSU1_CURRENT_TRACK == MSU1.MSU1_RESUME_TRACK)
{
MSU1.MSU1_AUDIO_POS = MSU1.MSU1_RESUME_POS;
MSU1.MSU1_RESUME_POS = 0;
MSU1.MSU1_RESUME_TRACK = ~0;
}
else
{
MSU1.MSU1_AUDIO_POS = 8;
}
audioFile.seekg(MSU1.MSU1_AUDIO_POS);
}
break;
case 6:
MSU1.MSU1_VOLUME = byte;
break;
case 7:
if (MSU1.MSU1_STATUS & (AudioBusy | AudioError))
break;
MSU1.MSU1_STATUS = (MSU1.MSU1_STATUS & ~0x30) | ((byte & 0x03) << 4);
if ((byte & (Play | Resume)) == Resume)
{
MSU1.MSU1_RESUME_TRACK = MSU1.MSU1_CURRENT_TRACK;
MSU1.MSU1_RESUME_POS = MSU1.MSU1_AUDIO_POS;
}
break;
}
}
uint16 S9xMSU1Samples(void)
{
return bufPos - bufBegin;
}
void S9xMSU1SetOutput(int16 * out, int size)
{
bufPos = bufBegin = out;
bufEnd = out + size;
}
void S9xMSU1PostLoadState(void)
{
if (DataOpen())
{
dataFile.seekg(MSU1.MSU1_DATA_POS);
}
if (MSU1.MSU1_STATUS & AudioPlaying)
{
if (AudioOpen())
{
audioFile.seekg(4);
audioFile.read((char *)&audioLoopPos, 4);
audioLoopPos = GET_LE32(&audioLoopPos);
audioLoopPos <<= 2;
audioLoopPos += 8;
audioFile.seekg(MSU1.MSU1_AUDIO_POS);
}
else
{
MSU1.MSU1_STATUS &= ~(AudioPlaying | AudioRepeating);
MSU1.MSU1_STATUS |= AudioError;
}
}
bufPos = 0;
bufBegin = 0;
bufEnd = 0;
partial_samples = 0;
}

239
msu1.h Normal file
View File

@ -0,0 +1,239 @@
/***********************************************************************************
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
(c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
(c) Copyright 2009 - 2016 BearOso,
OV2
(c) Copyright 2011 - 2016 Hans-Kristian Arntzen,
Daniel De Matteis
(Under no circumstances will commercial rights be given)
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
C4 x86 assembler and some C emulation code
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
Nach,
zsKnight (zsknight@zsnes.com)
C4 C++ code
(c) Copyright 2003 - 2006 Brad Jorsch,
Nach
DSP-1 emulator code
(c) Copyright 1998 - 2006 _Demo_,
Andreas Naive (andreasnaive@gmail.com),
Gary Henderson,
Ivar (ivar@snes9x.com),
John Weidman,
Kris Bleakley,
Matthew Kendora,
Nach,
neviksti (neviksti@hotmail.com)
DSP-2 emulator code
(c) Copyright 2003 John Weidman,
Kris Bleakley,
Lord Nightmare (lord_nightmare@users.sourceforge.net),
Matthew Kendora,
neviksti
DSP-3 emulator code
(c) Copyright 2003 - 2006 John Weidman,
Kris Bleakley,
Lancer,
z80 gaiden
DSP-4 emulator code
(c) Copyright 2004 - 2006 Dreamer Nom,
John Weidman,
Kris Bleakley,
Nach,
z80 gaiden
OBC1 emulator code
(c) Copyright 2001 - 2004 zsKnight,
pagefault (pagefault@zsnes.com),
Kris Bleakley
Ported from x86 assembler to C by sanmaiwashi
SPC7110 and RTC C++ emulator code used in 1.39-1.51
(c) Copyright 2002 Matthew Kendora with research by
zsKnight,
John Weidman,
Dark Force
SPC7110 and RTC C++ emulator code used in 1.52+
(c) Copyright 2009 byuu,
neviksti
S-DD1 C emulator code
(c) Copyright 2003 Brad Jorsch with research by
Andreas Naive,
John Weidman
S-RTC C emulator code
(c) Copyright 2001 - 2006 byuu,
John Weidman
ST010 C++ emulator code
(c) Copyright 2003 Feather,
John Weidman,
Kris Bleakley,
Matthew Kendora
Super FX x86 assembler emulator code
(c) Copyright 1998 - 2003 _Demo_,
pagefault,
zsKnight
Super FX C emulator code
(c) Copyright 1997 - 1999 Ivar,
Gary Henderson,
John Weidman
Sound emulator code used in 1.5-1.51
(c) Copyright 1998 - 2003 Brad Martin
(c) Copyright 1998 - 2006 Charles Bilyue'
Sound emulator code used in 1.52+
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
S-SMP emulator code used in 1.54+
(c) Copyright 2016 byuu
SH assembler code partly based on x86 assembler code
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
NTSC filter
(c) Copyright 2006 - 2007 Shay Green
GTK+ GUI code
(c) Copyright 2004 - 2016 BearOso
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
(c) Copyright 2009 - 2016 OV2
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2011 zones
Libretro port
(c) Copyright 2011 - 2016 Hans-Kristian Arntzen,
Daniel De Matteis
(Under no circumstances will commercial rights be given)
MSU-1 code
(c) Copyright 2016 qwertymodo
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com/
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
warranty. In no event shall the authors be held liable for any damages
arising from the use of this software or it's derivatives.
Snes9x is freeware for PERSONAL USE only. Commercial users should
seek permission of the copyright holders first. Commercial use includes,
but is not limited to, charging money for Snes9x or software derived from
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
using Snes9x as a promotion for your commercial product.
The copyright holders request that bug fixes and improvements to the code
should be forwarded to them so everyone can benefit from the modifications
in future versions.
Super NES and Super Nintendo Entertainment System are trademarks of
Nintendo Co., Limited and its subsidiary companies.
***********************************************************************************/
#ifndef _MSU1_H_
#define _MSU1_H_
#include "snes9x.h"
struct SMSU1
{
uint8 MSU1_STATUS;
uint32 MSU1_DATA_SEEK;
uint32 MSU1_DATA_POS;
uint16 MSU1_TRACK_SEEK;
uint16 MSU1_CURRENT_TRACK;
uint32 MSU1_RESUME_TRACK;
uint8 MSU1_VOLUME;
uint8 MSU1_CONTROL;
uint32 MSU1_AUDIO_POS;
uint32 MSU1_RESUME_POS;
};
enum SMSU1_FLAG {
Revision = 0x02, //max: 0x07
AudioResume = 0x04,
AudioError = 0x08,
AudioPlaying = 0x10,
AudioRepeating = 0x20,
AudioBusy = 0x40,
DataBusy = 0x80
};
enum SMSU1_CMD {
Play = 0x01,
Repeat = 0x02,
Resume = 0x04
};
extern struct SMSU1 MSU1;
void S9xResetMSU(void);
void S9xMSU1Init(void);
bool S9xMSU1ROMExists(void);
void S9xMSU1Generate(int sample_count);
uint8 S9xMSU1ReadPort(int port);
void S9xMSU1WritePort(int port, uint8 byte);
uint16 S9xMSU1Samples(void);
void S9xMSU1SetOutput(int16 *out, int size);
void S9xMSU1PostLoadState(void);
#endif

2
port.h
View File

@ -325,7 +325,7 @@ void SetInfoDlgColor(unsigned char, unsigned char, unsigned char);
#endif // __WIN32_LIBSNES__
#endif // __WIN32__
#ifdef __DJGPP
#if defined(__DJGPP) || defined(__WIN32__)
#define SLASH_STR "\\"
#define SLASH_CHAR '\\'
#else

View File

@ -344,6 +344,9 @@ void S9xSetPPU (uint8 Byte, uint16 Address)
S9xTraceFormattedMessage("--- HDMA PPU %04X -> %02X", Address, Byte);
#endif
if (Settings.MSU1 && (Address & 0xfff8) == 0x2000) // MSU-1
S9xMSU1WritePort(Address & 7, Byte);
else
if ((Address & 0xffc0) == 0x2140) // APUIO0, APUIO1, APUIO2, APUIO3
// write_port will run the APU until given clock before writing value
S9xAPUWritePort(Address & 3, Byte);
@ -1095,7 +1098,9 @@ void S9xSetPPU (uint8 Byte, uint16 Address)
uint8 S9xGetPPU (uint16 Address)
{
// MAP_PPU: $2000-$3FFF
if (Settings.MSU1 && (Address & 0xfff8) == 0x2000)
return (S9xMSU1ReadPort(Address & 7));
else
if (Address < 0x2100)
return (OpenBus);

33
sa1.cpp
View File

@ -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;
}

View File

@ -1135,6 +1135,23 @@ static FreezeData SnapBSX[] =
ARRAY_ENTRY(6, test2192, 32, uint8_ARRAY_V)
};
#undef STRUCT
#define STRUCT struct SMSU1
static FreezeData SnapMSU1[] =
{
INT_ENTRY(9, MSU1_STATUS),
INT_ENTRY(9, MSU1_DATA_SEEK),
INT_ENTRY(9, MSU1_DATA_POS),
INT_ENTRY(9, MSU1_TRACK_SEEK),
INT_ENTRY(9, MSU1_CURRENT_TRACK),
INT_ENTRY(9, MSU1_RESUME_TRACK),
INT_ENTRY(9, MSU1_VOLUME),
INT_ENTRY(9, MSU1_CONTROL),
INT_ENTRY(9, MSU1_AUDIO_POS),
INT_ENTRY(9, MSU1_RESUME_POS)
};
#undef STRUCT
#define STRUCT struct SnapshotScreenshotInfo
@ -1306,8 +1323,6 @@ void S9xFreezeToStream (STREAM stream)
char buffer[1024];
uint8 *soundsnapshot = new uint8[SPC_SAVE_STATE_BLOCK_SIZE];
S9xSetSoundMute(TRUE);
sprintf(buffer, "%s:%04d\n", SNAPSHOT_MAGIC, SNAPSHOT_VERSION);
WRITE_STREAM(buffer, strlen(buffer), stream);
@ -1394,6 +1409,9 @@ void S9xFreezeToStream (STREAM stream)
if (Settings.BS)
FreezeStruct(stream, "BSX", &BSX, SnapBSX, COUNT(SnapBSX));
if (Settings.MSU1)
FreezeStruct(stream, "MSU", &MSU1, SnapMSU1, COUNT(SnapMSU1));
if (Settings.SnapshotScreenshots)
{
SnapshotScreenshotInfo *ssi = new SnapshotScreenshotInfo;
@ -1443,8 +1461,6 @@ void S9xFreezeToStream (STREAM stream)
}
}
S9xSetSoundMute(FALSE);
delete [] soundsnapshot;
}
@ -1494,6 +1510,7 @@ int S9xUnfreezeFromStream (STREAM stream)
uint8 *local_srtc = NULL;
uint8 *local_rtc_data = NULL;
uint8 *local_bsx_data = NULL;
uint8 *local_msu1_data = NULL;
uint8 *local_screenshot = NULL;
uint8 *local_movie_data = NULL;
@ -1599,6 +1616,10 @@ int S9xUnfreezeFromStream (STREAM stream)
if (result != SUCCESS && Settings.BS)
break;
result = UnfreezeStructCopy(stream, "MSU", &local_msu1_data, SnapMSU1, COUNT(SnapMSU1), version);
if (result != SUCCESS && Settings.MSU1)
break;
result = UnfreezeStructCopy(stream, "SHO", &local_screenshot, SnapScreenshot, COUNT(SnapScreenshot), version);
SnapshotMovieInfo mi;
@ -1640,8 +1661,6 @@ int S9xUnfreezeFromStream (STREAM stream)
uint32 old_flags = CPU.Flags;
uint32 sa1_old_flags = SA1.Flags;
S9xSetSoundMute(TRUE);
S9xReset();
UnfreezeStructFromCopy(&CPU, SnapCPU, COUNT(SnapCPU), local_cpu, version);
@ -1717,6 +1736,9 @@ int S9xUnfreezeFromStream (STREAM stream)
if (local_bsx_data)
UnfreezeStructFromCopy(&BSX, SnapBSX, COUNT(SnapBSX), local_bsx_data, version);
if (local_msu1_data)
UnfreezeStructFromCopy(&MSU1, SnapMSU1, COUNT(SnapMSU1), local_msu1_data, version);
if (version < SNAPSHOT_VERSION_IRQ)
{
printf("Converting old snapshot version %d to %d\n...", version, SNAPSHOT_VERSION);
@ -1798,6 +1820,9 @@ int S9xUnfreezeFromStream (STREAM stream)
if (local_bsx_data)
S9xBSXPostLoadState();
if (local_msu1_data)
S9xMSU1PostLoadState();
if (local_movie_data)
{
// restore last displayed pad_read status
@ -1867,8 +1892,6 @@ int S9xUnfreezeFromStream (STREAM stream)
for (uint32 y = 0; y < (uint32) (IMAGE_HEIGHT); y++)
memset(GFX.Screen + y * GFX.RealPPL, 0, GFX.RealPPL * 2);
}
S9xSetSoundMute(FALSE);
}
if (local_cpu) delete [] local_cpu;

View File

@ -196,7 +196,7 @@
#define SNAPSHOT_MAGIC "#!s9xsnp"
#define SNAPSHOT_VERSION_IRQ 7
#define SNAPSHOT_VERSION_BAPU 8
#define SNAPSHOT_VERSION 8
#define SNAPSHOT_VERSION 9
#define SUCCESS 1
#define WRONG_FORMAT (-1)

View File

@ -377,6 +377,7 @@ struct SSettings
bool8 BS;
bool8 BSXItself;
bool8 BSXBootup;
bool8 MSU1;
bool8 MouseMaster;
bool8 SuperScopeMaster;
bool8 JustifierMaster;

View File

@ -192,7 +192,11 @@
#include <string>
#ifdef UNZIP_SUPPORT
#include "unzip.h"
# ifdef SYSTEM_ZIP
# include <minizip/unzip.h>
# else
# include "unzip.h"
# endif
#endif
#include "snes9x.h"
#include "stream.h"

View File

@ -229,8 +229,11 @@ class fStream : public Stream
};
#ifdef UNZIP_SUPPORT
#include "unzip.h"
# ifdef SYSTEM_ZIP
# include <minizip/unzip.h>
# else
# include "unzip.h"
# endif
#define unz_BUFFSIZ 1024

View File

@ -1399,29 +1399,12 @@ extern struct SLineMatrixData LineMatrixData[240];
// We don't know how Sub(0, y) is handled.
#define DRAW_PIXEL_H2x1(N, M) \
if (Z1 > GFX.DB[Offset + 2 * N] && (M)) \
{ \
GFX.S[Offset + 2 * N] = MATH(GFX.ScreenColors[Pix], GFX.SubScreen[Offset + 2 * N], GFX.SubZBuffer[Offset + 2 * N]); \
GFX.S[Offset + 2 * N + 1] = MATH((GFX.ClipColors ? 0 : GFX.SubScreen[Offset + 2 * N + 2]), GFX.RealScreenColors[Pix], GFX.SubZBuffer[Offset + 2 * N]); \
GFX.DB[Offset + 2 * N] = GFX.DB[Offset + 2 * N + 1] = Z2; \
}
/* The logic above shifts everything one pixel to the left, thus producing a blank line on the right. The code below places the pixel on correct positions but
would incur two additional branches for the edges on every pixel.
*/
//#define DRAW_PIXEL_H2x1(N, M) \
// if (Z1 > GFX.DB[Offset + 2 * N] && (M)) \
// { \
// GFX.S[Offset + 2 * N + 1] = MATH(GFX.ScreenColors[Pix], GFX.SubScreen[Offset + 2 * N], GFX.SubZBuffer[Offset + 2 * N]); \
// if ((Offset + 2 * N ) % GFX.RealPPL != (SNES_WIDTH - 1) << 1) \
// GFX.S[Offset + 2 * N + 2] = MATH((GFX.ClipColors ? 0 : GFX.SubScreen[Offset + 2 * N + 2]), GFX.RealScreenColors[Pix], GFX.SubZBuffer[Offset + 2 * N]); \
// if ((Offset + 2 * N) % GFX.RealPPL == 0) \
// GFX.S[Offset + 2 * N] = MATH((GFX.ClipColors ? 0 : GFX.SubScreen[Offset + 2 * N]), GFX.RealScreenColors[Pix], GFX.SubZBuffer[Offset + 2 * N]); \
// GFX.DB[Offset + 2 * N] = GFX.DB[Offset + 2 * N + 1] = Z2; \
// }
if (Z1 > GFX.DB[Offset + 2 * N] && (M)) \
{ \
GFX.S[Offset + 2 * N] = MATH((GFX.ClipColors ? 0 : GFX.SubScreen[Offset + 2 * N]), GFX.RealScreenColors[Pix], GFX.SubZBuffer[Offset + 2 * N]); \
GFX.S[Offset + 2 * N + 1] = MATH(GFX.ScreenColors[Pix], GFX.SubScreen[Offset + 2 * N], GFX.SubZBuffer[Offset + 2 * N]); \
GFX.DB[Offset + 2 * N] = GFX.DB[Offset + 2 * N + 1] = Z2; \
}
#define DRAW_PIXEL(N, M) DRAW_PIXEL_H2x1(N, M)
#define NAME2 Hires

View File

@ -2,12 +2,13 @@
@S9XNETPLAY@
@S9XZIP@
@S9XJMA@
@S9X_SYSTEM_ZIP@
# Fairly good and special-char-safe descriptor of the os being built on.
OS = `uname -s -r -m|sed \"s/ /-/g\"|tr \"[A-Z]\" \"[a-z]\"|tr \"/()\" \"___\"`
BUILDDIR = .
OBJECTS = ../apu/apu.o ../apu/bapu/dsp/sdsp.o ../apu/bapu/dsp/SPC_DSP.o ../apu/bapu/smp/smp.o ../apu/bapu/smp/smp_state.o ../bsx.o ../c4.o ../c4emu.o ../cheats.o ../cheats2.o ../clip.o ../conffile.o ../controls.o ../cpu.o ../cpuexec.o ../cpuops.o ../crosshairs.o ../dma.o ../dsp.o ../dsp1.o ../dsp2.o ../dsp3.o ../dsp4.o ../fxinst.o ../fxemu.o ../gfx.o ../globals.o ../logger.o ../memmap.o ../movie.o ../obc1.o ../ppu.o ../stream.o ../sa1.o ../sa1cpu.o ../screenshot.o ../sdd1.o ../sdd1emu.o ../seta.o ../seta010.o ../seta011.o ../seta018.o ../snapshot.o ../snes9x.o ../spc7110.o ../srtc.o ../tile.o ../filter/2xsai.o ../filter/blit.o ../filter/epx.o ../filter/hq2x.o ../filter/snes_ntsc.o ../statemanager.o unix.o x11.o
OBJECTS = ../apu/apu.o ../apu/bapu/dsp/sdsp.o ../apu/bapu/dsp/SPC_DSP.o ../apu/bapu/smp/smp.o ../apu/bapu/smp/smp_state.o ../bsx.o ../c4.o ../c4emu.o ../cheats.o ../cheats2.o ../clip.o ../conffile.o ../controls.o ../cpu.o ../cpuexec.o ../cpuops.o ../crosshairs.o ../dma.o ../dsp.o ../dsp1.o ../dsp2.o ../dsp3.o ../dsp4.o ../fxinst.o ../fxemu.o ../gfx.o ../globals.o ../logger.o ../memmap.o ../msu1.o ../movie.o ../obc1.o ../ppu.o ../stream.o ../sa1.o ../sa1cpu.o ../screenshot.o ../sdd1.o ../sdd1emu.o ../seta.o ../seta010.o ../seta011.o ../seta018.o ../snapshot.o ../snes9x.o ../spc7110.o ../srtc.o ../tile.o ../filter/2xsai.o ../filter/blit.o ../filter/epx.o ../filter/hq2x.o ../filter/snes_ntsc.o ../statemanager.o unix.o x11.o
DEFS = -DMITSHM
ifdef S9XDEBUGGER
@ -19,7 +20,11 @@ OBJECTS += ../netplay.o ../server.o
endif
ifdef S9XZIP
OBJECTS += ../loadzip.o ../unzip/ioapi.o ../unzip/unzip.o
OBJECTS += ../loadzip.o
ifndef SYSTEM_ZIP
OBJECTS += ../unzip/ioapi.o ../unzip/unzip.o
INCLUDES = -I../unzip/
endif
endif
ifdef S9XJMA
@ -29,7 +34,7 @@ endif
CCC = @CXX@
CC = @CC@
GASM = @CXX@
INCLUDES = -I. -I.. -I../apu/ -I../apu/bapu -I../unzip/ -I../jma/ -I../filter/
INCLUDES += -I. -I.. -I../apu/ -I../apu/bapu -I../jma/ -I../filter/
CCFLAGS = @S9XFLGS@ @S9XDEFS@ $(DEFS)
CFLAGS = $(CCFLAGS)

290
unix/aclocal.m4 vendored Normal file
View File

@ -0,0 +1,290 @@
# generated automatically by aclocal 1.15 -*- Autoconf -*-
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
dnl serial 11 (pkg-config-0.29.1)
dnl
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
dnl
dnl This program is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
dnl the Free Software Foundation; either version 2 of the License, or
dnl (at your option) any later version.
dnl
dnl This program is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
dnl General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
dnl along with this program; if not, write to the Free Software
dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
dnl 02111-1307, USA.
dnl
dnl As a special exception to the GNU General Public License, if you
dnl distribute this file as part of a program that contains a
dnl configuration script generated by Autoconf, you may include it under
dnl the same distribution terms that you use for the rest of that
dnl program.
dnl PKG_PREREQ(MIN-VERSION)
dnl -----------------------
dnl Since: 0.29
dnl
dnl Verify that the version of the pkg-config macros are at least
dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's
dnl installed version of pkg-config, this checks the developer's version
dnl of pkg.m4 when generating configure.
dnl
dnl To ensure that this macro is defined, also add:
dnl m4_ifndef([PKG_PREREQ],
dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])])
dnl
dnl See the "Since" comment for each macro you use to see what version
dnl of the macros you require.
m4_defun([PKG_PREREQ],
[m4_define([PKG_MACROS_VERSION], [0.29.1])
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
])dnl PKG_PREREQ
dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
dnl ----------------------------------
dnl Since: 0.16
dnl
dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
dnl first found in the path. Checks that the version of pkg-config found
dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
dnl used since that's the first version where most current features of
dnl pkg-config existed.
AC_DEFUN([PKG_PROG_PKG_CONFIG],
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
fi
if test -n "$PKG_CONFIG"; then
_pkg_min_version=m4_default([$1], [0.9.0])
AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
PKG_CONFIG=""
fi
fi[]dnl
])dnl PKG_PROG_PKG_CONFIG
dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
dnl -------------------------------------------------------------------
dnl Since: 0.18
dnl
dnl Check to see whether a particular set of modules exists. Similar to
dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
dnl
dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
dnl only at the first occurence in configure.ac, so if the first place
dnl it's called might be skipped (such as if it is within an "if", you
dnl have to call PKG_CHECK_EXISTS manually
AC_DEFUN([PKG_CHECK_EXISTS],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
if test -n "$PKG_CONFIG" && \
AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
m4_default([$2], [:])
m4_ifvaln([$3], [else
$3])dnl
fi])
dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
dnl ---------------------------------------------
dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting
dnl pkg_failed based on the result.
m4_define([_PKG_CONFIG],
[if test -n "$$1"; then
pkg_cv_[]$1="$$1"
elif test -n "$PKG_CONFIG"; then
PKG_CHECK_EXISTS([$3],
[pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes ],
[pkg_failed=yes])
else
pkg_failed=untried
fi[]dnl
])dnl _PKG_CONFIG
dnl _PKG_SHORT_ERRORS_SUPPORTED
dnl ---------------------------
dnl Internal check to see if pkg-config supports short errors.
AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
_pkg_short_errors_supported=yes
else
_pkg_short_errors_supported=no
fi[]dnl
])dnl _PKG_SHORT_ERRORS_SUPPORTED
dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
dnl [ACTION-IF-NOT-FOUND])
dnl --------------------------------------------------------------
dnl Since: 0.4.0
dnl
dnl Note that if there is a possibility the first call to
dnl PKG_CHECK_MODULES might not happen, you should be sure to include an
dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
AC_DEFUN([PKG_CHECK_MODULES],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
pkg_failed=no
AC_MSG_CHECKING([for $1])
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
and $1[]_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.])
if test $pkg_failed = yes; then
AC_MSG_RESULT([no])
_PKG_SHORT_ERRORS_SUPPORTED
if test $_pkg_short_errors_supported = yes; then
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
else
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
m4_default([$4], [AC_MSG_ERROR(
[Package requirements ($2) were not met:
$$1_PKG_ERRORS
Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.
_PKG_TEXT])[]dnl
])
elif test $pkg_failed = untried; then
AC_MSG_RESULT([no])
m4_default([$4], [AC_MSG_FAILURE(
[The pkg-config script could not be found or is too old. Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full
path to pkg-config.
_PKG_TEXT
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
])
else
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
AC_MSG_RESULT([yes])
$3
fi[]dnl
])dnl PKG_CHECK_MODULES
dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
dnl [ACTION-IF-NOT-FOUND])
dnl ---------------------------------------------------------------------
dnl Since: 0.29
dnl
dnl Checks for existence of MODULES and gathers its build flags with
dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags
dnl and VARIABLE-PREFIX_LIBS from --libs.
dnl
dnl Note that if there is a possibility the first call to
dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to
dnl include an explicit call to PKG_PROG_PKG_CONFIG in your
dnl configure.ac.
AC_DEFUN([PKG_CHECK_MODULES_STATIC],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
_save_PKG_CONFIG=$PKG_CONFIG
PKG_CONFIG="$PKG_CONFIG --static"
PKG_CHECK_MODULES($@)
PKG_CONFIG=$_save_PKG_CONFIG[]dnl
])dnl PKG_CHECK_MODULES_STATIC
dnl PKG_INSTALLDIR([DIRECTORY])
dnl -------------------------
dnl Since: 0.27
dnl
dnl Substitutes the variable pkgconfigdir as the location where a module
dnl should install pkg-config .pc files. By default the directory is
dnl $libdir/pkgconfig, but the default can be changed by passing
dnl DIRECTORY. The user can override through the --with-pkgconfigdir
dnl parameter.
AC_DEFUN([PKG_INSTALLDIR],
[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
m4_pushdef([pkg_description],
[pkg-config installation directory @<:@]pkg_default[@:>@])
AC_ARG_WITH([pkgconfigdir],
[AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
[with_pkgconfigdir=]pkg_default)
AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
m4_popdef([pkg_default])
m4_popdef([pkg_description])
])dnl PKG_INSTALLDIR
dnl PKG_NOARCH_INSTALLDIR([DIRECTORY])
dnl --------------------------------
dnl Since: 0.27
dnl
dnl Substitutes the variable noarch_pkgconfigdir as the location where a
dnl module should install arch-independent pkg-config .pc files. By
dnl default the directory is $datadir/pkgconfig, but the default can be
dnl changed by passing DIRECTORY. The user can override through the
dnl --with-noarch-pkgconfigdir parameter.
AC_DEFUN([PKG_NOARCH_INSTALLDIR],
[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
m4_pushdef([pkg_description],
[pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
AC_ARG_WITH([noarch-pkgconfigdir],
[AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
[with_noarch_pkgconfigdir=]pkg_default)
AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
m4_popdef([pkg_default])
m4_popdef([pkg_description])
])dnl PKG_NOARCH_INSTALLDIR
dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
dnl -------------------------------------------
dnl Since: 0.28
dnl
dnl Retrieves the value of the pkg-config variable for the given module.
AC_DEFUN([PKG_CHECK_VAR],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
_PKG_CONFIG([$1], [variable="][$3]["], [$2])
AS_VAR_COPY([$1], [pkg_cv_][$1])
AS_VAR_IF([$1], [""], [$5], [$4])dnl
])dnl PKG_CHECK_VAR

266
unix/configure vendored
View File

@ -622,6 +622,7 @@ ac_includes_default="\
ac_subst_vars='LTLIBOBJS
LIBOBJS
S9X_SYSTEM_ZIP
S9XJMA
S9XZIP
S9XNETPLAY
@ -635,6 +636,11 @@ X_LIBS
X_PRE_LIBS
X_CFLAGS
XMKMF
SYSTEM_ZIP_LIBS
SYSTEM_ZIP_CFLAGS
PKG_CONFIG_LIBDIR
PKG_CONFIG_PATH
PKG_CONFIG
EGREP
GREP
CXXCPP
@ -708,6 +714,7 @@ enable_debugger
enable_netplay
enable_gzip
enable_zip
with_system_zip
enable_jma
enable_screenshot
with_x
@ -726,6 +733,11 @@ CXX
CXXFLAGS
CCC
CXXCPP
PKG_CONFIG
PKG_CONFIG_PATH
PKG_CONFIG_LIBDIR
SYSTEM_ZIP_CFLAGS
SYSTEM_ZIP_LIBS
XMKMF'
@ -1363,6 +1375,7 @@ Optional Features:
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--with-system-zip Use system zip (default: check)
--with-x use the X Window System
Some influential environment variables:
@ -1376,6 +1389,15 @@ Some influential environment variables:
CXX C++ compiler command
CXXFLAGS C++ compiler flags
CXXCPP C++ preprocessor
PKG_CONFIG path to pkg-config utility
PKG_CONFIG_PATH
directories to add to pkg-config's search path
PKG_CONFIG_LIBDIR
path overriding pkg-config's built-in search path
SYSTEM_ZIP_CFLAGS
C compiler flags for SYSTEM_ZIP, overriding pkg-config
SYSTEM_ZIP_LIBS
linker flags for SYSTEM_ZIP, overriding pkg-config
XMKMF Path to xmkmf, Makefile generator for X Window System
Use these variables to override the choices made by `configure' or to help
@ -4831,17 +4853,241 @@ else
fi
S9X_SYSTEM_ZIP="#SYSTEM_ZIP=1"
# Check whether --with-system-zip was given.
if test "${with_system_zip+set}" = set; then :
withval=$with_system_zip;
else
with_system_zip="check"
fi
if test "x$enable_zip" = "xyes"; then
if test "x$snes9x_cv_zlib" = "xyes"; then
S9XZIP="S9XZIP=1"
S9XDEFS="$S9XDEFS -DUNZIP_SUPPORT"
if test "x$enable_gzip" = "xno"; then
S9XLIBS="$S9XLIBS -lz"
fi
if test "x$with_system_zip" != "xno"; then
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_path_PKG_CONFIG+:} false; then :
$as_echo_n "(cached) " >&6
else
case $PKG_CONFIG in
[\\/]* | ?:[\\/]*)
ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
PKG_CONFIG=$ac_cv_path_PKG_CONFIG
if test -n "$PKG_CONFIG"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
$as_echo "$PKG_CONFIG" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
fi
if test -z "$ac_cv_path_PKG_CONFIG"; then
ac_pt_PKG_CONFIG=$PKG_CONFIG
# Extract the first word of "pkg-config", so it can be a program name with args.
set dummy pkg-config; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
$as_echo_n "(cached) " >&6
else
case $ac_pt_PKG_CONFIG in
[\\/]* | ?:[\\/]*)
ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
if test -n "$ac_pt_PKG_CONFIG"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
$as_echo "$ac_pt_PKG_CONFIG" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
if test "x$ac_pt_PKG_CONFIG" = x; then
PKG_CONFIG=""
else
case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
PKG_CONFIG=$ac_pt_PKG_CONFIG
fi
else
PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
fi
fi
if test -n "$PKG_CONFIG"; then
_pkg_min_version=0.9.0
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: zlib not found. Build without ZIP support." >&5
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
PKG_CONFIG=""
fi
fi
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SYSTEM_ZIP" >&5
$as_echo_n "checking for SYSTEM_ZIP... " >&6; }
if test -n "$SYSTEM_ZIP_CFLAGS"; then
pkg_cv_SYSTEM_ZIP_CFLAGS="$SYSTEM_ZIP_CFLAGS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"minizip\""; } >&5
($PKG_CONFIG --exists --print-errors "minizip") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_SYSTEM_ZIP_CFLAGS=`$PKG_CONFIG --cflags "minizip" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
fi
else
pkg_failed=untried
fi
if test -n "$SYSTEM_ZIP_LIBS"; then
pkg_cv_SYSTEM_ZIP_LIBS="$SYSTEM_ZIP_LIBS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"minizip\""; } >&5
($PKG_CONFIG --exists --print-errors "minizip") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_SYSTEM_ZIP_LIBS=`$PKG_CONFIG --libs "minizip" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
fi
else
pkg_failed=untried
fi
if test $pkg_failed = yes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
_pkg_short_errors_supported=yes
else
_pkg_short_errors_supported=no
fi
if test $_pkg_short_errors_supported = yes; then
SYSTEM_ZIP_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "minizip" 2>&1`
else
SYSTEM_ZIP_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "minizip" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$SYSTEM_ZIP_PKG_ERRORS" >&5
if test "x${with_system_zip}" != "xcheck"; then
as_fn_error $? "--with-system-zip requested but no proper minizip lib found." "$LINENO" 5
else
{ $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 minizip lib found." "$LINENO" 5
else
{ $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
SYSTEM_ZIP_CFLAGS=$pkg_cv_SYSTEM_ZIP_CFLAGS
SYSTEM_ZIP_LIBS=$pkg_cv_SYSTEM_ZIP_LIBS
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
S9XZIP="S9XZIP=1"
S9XDEFS="$S9XDEFS -DUNZIP_SUPPORT"
S9X_SYSTEM_ZIP="SYSTEM_ZIP=1"
S9XLIBS="$S9XLIBS $SYSTEM_ZIP_LIBS"
if test "x$enable_gzip" = "xno"; then
S9XLIBS="$S9XLIBS -lz"
fi
S9XDEFS="$S9XDEFS -DSYSTEM_ZIP"
fi
else
if test "x$snes9x_cv_zlib" = "xyes"; then
S9XZIP="S9XZIP=1"
S9XDEFS="$S9XDEFS -DUNZIP_SUPPORT"
if test "x$enable_gzip" = "xno"; then
S9XLIBS="$S9XLIBS -lz"
fi
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: zlib not found. Build without ZIP support." >&5
$as_echo "$as_me: WARNING: zlib not found. Build without ZIP support." >&2;}
enable_zip="no"
enable_zip="no"
fi
fi
fi
@ -6068,9 +6314,12 @@ S9XLIBS="$LIBS $S9XLIBS"
S9XFLGS="`echo \"$S9XFLGS\" | sed -e 's/ */ /g'`"
S9XDEFS="`echo \"$S9XDEFS\" | sed -e 's/ */ /g'`"
S9XLIBS="`echo \"$S9XLIBS\" | sed -e 's/ */ /g'`"
S9X_SYSTEM_ZIP="`echo \"$S9X_SYSTEM_ZIP\" | sed -e 's/ */ /g'`"
S9XFLGS="`echo \"$S9XFLGS\" | sed -e 's/^ *//'`"
S9XDEFS="`echo \"$S9XDEFS\" | sed -e 's/^ *//'`"
S9XLIBS="`echo \"$S9XLIBS\" | sed -e 's/^ *//'`"
S9X_SYSTEM_ZIP="`echo \"$S9X_SYSTEM_ZIP\" | sed -e 's/^ *//'`"
@ -6100,6 +6349,7 @@ netplay support...... $enable_netplay
gamepad support...... $enable_gamepad
GZIP support......... $enable_gzip
ZIP support.......... $enable_zip
SYSTEM_ZIP........... $with_system_zip
JMA support.......... $enable_jma
debugger............. $enable_debugger

View File

@ -201,16 +201,43 @@ AC_ARG_ENABLE([zip],
[enable ZIP support through zlib (default: yes)])],
[], [enable_zip="yes"])
S9X_SYSTEM_ZIP="#SYSTEM_ZIP=1"
AC_ARG_WITH([system-zip],
[AS_HELP_STRING([--with-system-zip],
[Use system zip (default: check)])],
[], [with_system_zip="check"])
if test "x$enable_zip" = "xyes"; then
if test "x$snes9x_cv_zlib" = "xyes"; then
S9XZIP="S9XZIP=1"
S9XDEFS="$S9XDEFS -DUNZIP_SUPPORT"
if test "x$enable_gzip" = "xno"; then
S9XLIBS="$S9XLIBS -lz"
fi
if test "x$with_system_zip" != "xno"; then
PKG_CHECK_MODULES(
SYSTEM_ZIP,
minizip,
S9XZIP="S9XZIP=1"
S9XDEFS="$S9XDEFS -DUNZIP_SUPPORT"
S9X_SYSTEM_ZIP="SYSTEM_ZIP=1"
S9XLIBS="$S9XLIBS $SYSTEM_ZIP_LIBS"
if test "x$enable_gzip" = "xno"; then
S9XLIBS="$S9XLIBS -lz"
fi
S9XDEFS="$S9XDEFS -DSYSTEM_ZIP",
if test "x${with_system_zip}" != "xcheck"; then
AC_MSG_ERROR([--with-system-zip requested but no proper minizip lib found.])
else
AC_MSG_WARN([minizip not found. Build without SYSTEM_ZIP support.])
fi
)
else
AC_MSG_WARN([zlib not found. Build without ZIP support.])
enable_zip="no"
if test "x$snes9x_cv_zlib" = "xyes"; then
S9XZIP="S9XZIP=1"
S9XDEFS="$S9XDEFS -DUNZIP_SUPPORT"
if test "x$enable_gzip" = "xno"; then
S9XLIBS="$S9XLIBS -lz"
fi
else
AC_MSG_WARN([zlib not found. Build without ZIP support.])
enable_zip="no"
fi
fi
fi
@ -427,9 +454,11 @@ S9XLIBS="$LIBS $S9XLIBS"
S9XFLGS="`echo \"$S9XFLGS\" | sed -e 's/ */ /g'`"
S9XDEFS="`echo \"$S9XDEFS\" | sed -e 's/ */ /g'`"
S9XLIBS="`echo \"$S9XLIBS\" | sed -e 's/ */ /g'`"
S9X_SYSTEM_ZIP="`echo \"$S9X_SYSTEM_ZIP\" | sed -e 's/ */ /g'`"
S9XFLGS="`echo \"$S9XFLGS\" | sed -e 's/^ *//'`"
S9XDEFS="`echo \"$S9XDEFS\" | sed -e 's/^ *//'`"
S9XLIBS="`echo \"$S9XLIBS\" | sed -e 's/^ *//'`"
S9X_SYSTEM_ZIP="`echo \"$S9X_SYSTEM_ZIP\" | sed -e 's/^ *//'`"
AC_SUBST(S9XFLGS)
AC_SUBST(S9XDEFS)
@ -439,6 +468,7 @@ AC_SUBST(S9XDEBUGGER)
AC_SUBST(S9XNETPLAY)
AC_SUBST(S9XZIP)
AC_SUBST(S9XJMA)
AC_SUBST(S9X_SYSTEM_ZIP)
rm config.info 2>/dev/null
@ -459,6 +489,7 @@ netplay support...... $enable_netplay
gamepad support...... $enable_gamepad
GZIP support......... $enable_gzip
ZIP support.......... $enable_zip
SYSTEM_ZIP........... $with_system_zip
JMA support.......... $enable_jma
debugger............. $enable_debugger

View File

@ -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();

View File

@ -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;
}

View File

@ -314,7 +314,8 @@ bool CDirectSound::InitSoundBuffer()
blockCount = 4;
blockTime = GUI.SoundBufferSize / blockCount;
blockSamples = (Settings.SoundPlaybackRate * blockTime * (Settings.Stereo ? 2 : 1)) / 1000;
blockSamples = (Settings.SoundPlaybackRate * blockTime) / 1000;
blockSamples *= (Settings.Stereo ? 2 : 1);
blockSize = blockSamples * (Settings.SixteenBitSound ? 2 : 1);
bufferSize = blockSize * blockCount;

View File

@ -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;
}
@ -355,7 +355,8 @@ bool CXAudio2::SetupSound()
blockCount = 8;
UINT32 blockTime = GUI.SoundBufferSize / blockCount;
singleBufferSamples = (Settings.SoundPlaybackRate * blockTime * (Settings.Stereo ? 2 : 1)) / 1000;
singleBufferSamples = (Settings.SoundPlaybackRate * blockTime) / 1000;
singleBufferSamples *= (Settings.Stereo ? 2 : 1);
singleBufferBytes = singleBufferSamples * (Settings.SixteenBitSound ? 2 : 1);
sum_bufferSize = singleBufferBytes * blockCount;

View File

@ -959,17 +959,36 @@ static LRESULT CALLBACK InputCustomWndProc(HWND hwnd, UINT msg, WPARAM wParam, L
return 1;
case WM_USER+45:
case WM_KEYDOWN:
TranslateKey(wParam,temp);
col = CheckButtonKey(wParam);
{
UINT scancode = (lParam & 0x00ff0000) >> 16;
int extended = (lParam & 0x01000000) != 0;
icp->crForeGnd = ((~col) & 0x00ffffff);
icp->crBackGnd = col;
SetWindowText(hwnd,_tFromChar(temp));
InvalidateRect(icp->hwnd, NULL, FALSE);
UpdateWindow(icp->hwnd);
SendMessage(pappy,WM_USER+43,wParam,(LPARAM)hwnd);
switch (wParam) {
case VK_SHIFT:
wParam = MapVirtualKey(scancode, MAPVK_VSC_TO_VK_EX);
break;
case VK_CONTROL:
wParam = extended ? VK_RCONTROL : VK_LCONTROL;
break;
case VK_MENU:
wParam = extended ? VK_RMENU : VK_LMENU;
break;
default:
break;
}
break;
TranslateKey(wParam, temp);
col = CheckButtonKey(wParam);
icp->crForeGnd = ((~col) & 0x00ffffff);
icp->crBackGnd = col;
SetWindowText(hwnd, _tFromChar(temp));
InvalidateRect(icp->hwnd, NULL, FALSE);
UpdateWindow(icp->hwnd);
SendMessage(pappy, WM_USER + 43, wParam, (LPARAM)hwnd);
break;
}
case WM_USER+44:
TranslateKey(wParam,temp);

View File

@ -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

View File

@ -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

View File

@ -677,6 +677,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</CustomBuild>
<ClInclude Include="..\msu1.h" />
<ClInclude Include="..\statemanager.h" />
<CustomBuild Include="..\stream.h" />
<CustomBuild Include="..\tile.h" />
@ -777,6 +778,7 @@
<ClCompile Include="..\logger.cpp" />
<ClCompile Include="..\memmap.cpp" />
<ClCompile Include="..\movie.cpp" />
<ClCompile Include="..\msu1.cpp" />
<ClCompile Include="..\netplay.cpp" />
<ClCompile Include="..\obc1.cpp" />
<ClCompile Include="..\ppu.cpp" />

View File

@ -243,6 +243,9 @@
<ClInclude Include="dxerr.h">
<Filter>GUI</Filter>
</ClInclude>
<ClInclude Include="..\msu1.h">
<Filter>APU</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\bsx.cpp">
@ -539,6 +542,9 @@
<ClCompile Include="dxerr.cpp">
<Filter>GUI</Filter>
</ClCompile>
<ClCompile Include="..\msu1.cpp">
<Filter>APU</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="rsrc\nodrop.cur">

View File

@ -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.)"

View File

@ -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"<<endl<<"zipY"<<endl<<"gzY" <<endl<<"swcN"<<endl<<"figN"<<endl;
out<<"sfcN"<<endl;
out<<"bsN"<<endl;
out<<"jmaY";
out.close();
SetFileAttributes(TEXT("Valid.Ext"), FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY);
@ -10429,7 +10441,7 @@ static void set_movieinfo(const TCHAR* path, HWND hDlg)
if(m.SyncFlags & MOVIE_SYNC_HASROMINFO)
{
_stprintf(str, MOVIE_INFO_MOVIEROM MOVIE_INFO_ROMINFO, m.ROMCRC32, _tFromChar(m.ROMName));
_stprintf(str, MOVIE_INFO_MOVIEROM MOVIE_INFO_ROMINFO, m.ROMCRC32, (TCHAR *)_tFromChar(m.ROMName));
SetWindowText(GetDlgItem(hDlg, IDC_MOVIEROMINFO), str);
}
else
@ -10439,7 +10451,7 @@ static void set_movieinfo(const TCHAR* path, HWND hDlg)
}
bool mismatch = (m.SyncFlags & MOVIE_SYNC_HASROMINFO) && m.ROMCRC32 != Memory.ROMCRC32;
_stprintf(str, MOVIE_INFO_CURRENTROM MOVIE_INFO_ROMINFO TEXT("%s"), Memory.ROMCRC32, _tFromChar(Memory.ROMName), mismatch?MOVIE_INFO_MISMATCH:TEXT(""));
_stprintf(str, MOVIE_INFO_CURRENTROM MOVIE_INFO_ROMINFO TEXT("%s"), Memory.ROMCRC32, (TCHAR *)_tFromChar(Memory.ROMName), mismatch?MOVIE_INFO_MISMATCH:TEXT(""));
SetWindowText(GetDlgItem(hDlg, IDC_CURRENTROMINFO), str);
_stprintf(str, TEXT("%s"), mismatch?MOVIE_WARNING_MISMATCH:MOVIE_WARNING_OK);
@ -10505,7 +10517,7 @@ static void set_movieinfo(const TCHAR* path, HWND hDlg)
// no movie loaded
SetWindowText(GetDlgItem(hDlg, IDC_MOVIEROMINFO), dirStr);
_stprintf(str, MOVIE_INFO_CURRENTROM MOVIE_INFO_ROMINFO, Memory.ROMCRC32, _tFromChar(Memory.ROMName));
_stprintf(str, MOVIE_INFO_CURRENTROM MOVIE_INFO_ROMINFO, Memory.ROMCRC32, (TCHAR *)_tFromChar(Memory.ROMName));
SetWindowText(GetDlgItem(hDlg, IDC_CURRENTROMINFO), str);
}