Merge branch 'memstream'

Resolved conflicts:
	apu/SNES_SPC.h
	memmap.cpp
	port.h
	unix/Makefile.in
This commit is contained in:
OV2 2012-03-25 19:47:12 +02:00
commit 9cc05b3c12
25 changed files with 3686 additions and 355 deletions

12
bsx.cpp
View File

@ -1023,11 +1023,19 @@ static bool8 BSX_LoadBIOS (void)
return (r); return (r);
} }
static bool8 is_BSX_BIOS (const uint8 *data, uint32 size)
{
if (size == BIOS_SIZE && strncmp((char *) (data + 0x7FC0), "Satellaview BS-X ", 21) == 0)
return (TRUE);
else
return (FALSE);
}
void S9xInitBSX (void) void S9xInitBSX (void)
{ {
Settings.BS = FALSE; Settings.BS = FALSE;
if (!memcmp(&Memory.ROM[0x7FC0], "Satellaview BS-X ", 21)) if (is_BSX_BIOS(Memory.ROM,Memory.CalculatedSize))
{ {
// BS-X itself // BS-X itself
@ -1074,7 +1082,7 @@ void S9xInitBSX (void)
BSX.bootup = Settings.BSXBootup; BSX.bootup = Settings.BSXBootup;
if (!BSX_LoadBIOS()) if (!BSX_LoadBIOS() && !is_BSX_BIOS(BIOSROM,BIOS_SIZE))
{ {
BSX.bootup = FALSE; BSX.bootup = FALSE;
memset(BIOSROM, 0, BIOS_SIZE); memset(BIOSROM, 0, BIOS_SIZE);

View File

@ -209,16 +209,16 @@ void ConfigFile::Clear(void){
} }
bool ConfigFile::LoadFile(const char *filename){ bool ConfigFile::LoadFile(const char *filename){
STREAM s; FSTREAM s;
bool ret=false; bool ret=false;
const char *n, *n2; const char *n, *n2;
if((s=OPEN_STREAM(filename, "r"))){ if((s=OPEN_FSTREAM(filename, "r"))){
n=filename; n=filename;
n2=strrchr(n, '/'); if(n2!=NULL) n=n2+1; n2=strrchr(n, '/'); if(n2!=NULL) n=n2+1;
n2=strrchr(n, '\\'); if(n2!=NULL) n=n2+1; n2=strrchr(n, '\\'); if(n2!=NULL) n=n2+1;
LoadFile(new fReader(s), n); LoadFile(new fStream(s), n);
CLOSE_STREAM(s); CLOSE_FSTREAM(s);
ret = true; ret = true;
} else { } else {
fprintf(stderr, "Couldn't open conffile "); fprintf(stderr, "Couldn't open conffile ");
@ -228,7 +228,7 @@ bool ConfigFile::LoadFile(const char *filename){
} }
void ConfigFile::LoadFile(Reader *r, const char *name){ void ConfigFile::LoadFile(Stream *r, const char *name){
curConfigFile = this; curConfigFile = this;
string l, key, val; string l, key, val;
string section; string section;

View File

@ -188,7 +188,6 @@
#include "unzip/unzip.h" #include "unzip/unzip.h"
#endif #endif
#include "snes9x.h" #include "snes9x.h"
#include "reader.h"
#ifndef MAX #ifndef MAX
# define MAX(a,b) ((a) > (b)? (a) : (b)) # define MAX(a,b) ((a) > (b)? (a) : (b))
@ -203,7 +202,7 @@ class ConfigFile {
// return false on failure // return false on failure
bool LoadFile(const char *filename); bool LoadFile(const char *filename);
void LoadFile(Reader *r, const char *name=NULL); void LoadFile(Stream *r, const char *name=NULL);
// return false if key does not exist or is empty // return false if key does not exist or is empty
bool Exists(const char *key); bool Exists(const char *key);

View File

@ -159,7 +159,7 @@ snes9x_gtk_SOURCES += \
../dma.cpp \ ../dma.cpp \
../snes9x.cpp \ ../snes9x.cpp \
../globals.cpp \ ../globals.cpp \
../reader.cpp \ ../stream.cpp \
../conffile.cpp \ ../conffile.cpp \
../bsx.cpp \ ../bsx.cpp \
../logger.cpp \ ../logger.cpp \

53
libsnes/Makefile Normal file
View File

@ -0,0 +1,53 @@
ifeq ($(platform),)
platform = unix
ifeq ($(shell uname -a),)
platform = win
else ifneq ($(findstring Darwin,$(shell uname -a)),)
platform = osx
else ifneq ($(findstring MINGW,$(shell uname -a)),)
platform = win
else ifneq ($(findstring win,$(shell uname -a)),)
platform = win
endif
endif
ifeq ($(platform), unix)
TARGET := libsnes.so
fpic := -fPIC
SHARED := -shared -Wl,--version-script=link.T
else ifeq ($(platform), osx)
TARGET := libsnes.dylib
fpic := -fPIC
SHARED := -dynamiclib
else
TARGET := snes.dll
CC = gcc
CXX = g++
SHARED := -shared -static-libgcc -static-libstdc++ -s -Wl,--version-script=link.T
CXXFLAGS += -D__WIN32__ -D__WIN32_LIBSNES__
endif
OBJECTS = ../apu/apu.o ../apu/SNES_SPC.o ../apu/SNES_SPC_misc.o ../apu/SNES_SPC_state.o ../apu/SPC_DSP.o ../apu/SPC_Filter.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 libsnes.o
CXX = g++
CC = gcc
INCLUDES = -I. -I.. -I../apu/
CXXFLAGS += -O3 -fomit-frame-pointer -fno-exceptions -fno-rtti -pedantic -Wall -W -Wno-unused-parameter $(fpic)
CXXFLAGS += -DHAVE_STRINGS_H -DHAVE_STDINT_H -DRIGHTSHIFT_IS_SAR
CFLAGS = $(CXXFLAGS)
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(CXX) $(fpic) $(SHARED) $(INCLUDES) -o $@ $(OBJECTS) -lm
%.o: %.cpp
$(CXX) $(INCLUDES) $(CXXFLAGS) -c -o $@ $<
%.o: %.c
$(CC) $(INCLUDES) $(CFLAGS) -c -o $@ $<
clean:
rm -f $(OBJECTS) $(TARGET)

View File

@ -0,0 +1,786 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="libsnes-win32"
ProjectGUID="{4A2A7544-0547-4539-8B53-047FB9A15C75}"
RootNamespace="libsneswin32"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
<Platform
Name="x64"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="libsnes Debug|Win32"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../;../apu/bapu"
PreprocessorDefinitions="__WIN32__;__WIN32_LIBSNES__"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="2"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)\snes.dll"
LinkIncremental="2"
ModuleDefinitionFile="libsnes.def"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="libsnes Debug|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../;../apu/bapu"
PreprocessorDefinitions="__WIN32__;__WIN32_LIBSNES__"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="2"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)\snes.dll"
LinkIncremental="2"
ModuleDefinitionFile="libsnes.def"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="libsnes Release|Win32"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="0"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="3"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
AdditionalIncludeDirectories="../;../apu/bapu"
PreprocessorDefinitions="__WIN32__;__WIN32_LIBSNES__"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="2"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)\snes.dll"
LinkIncremental="1"
ModuleDefinitionFile="libsnes.def"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="libsnes Release|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="0"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="3"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
AdditionalIncludeDirectories="../;../apu/bapu"
PreprocessorDefinitions="__WIN32__;__WIN32_LIBSNES__"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="2"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)\snes.dll"
LinkIncremental="1"
ModuleDefinitionFile="libsnes.def"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="s9x-source"
>
<File
RelativePath="..\65c816.h"
>
</File>
<File
RelativePath="..\bsx.cpp"
>
</File>
<File
RelativePath="..\bsx.h"
>
</File>
<File
RelativePath="..\c4.cpp"
>
</File>
<File
RelativePath="..\c4.h"
>
</File>
<File
RelativePath="..\c4emu.cpp"
>
</File>
<File
RelativePath="..\cheats.cpp"
>
</File>
<File
RelativePath="..\cheats.h"
>
</File>
<File
RelativePath="..\cheats2.cpp"
>
</File>
<File
RelativePath="..\clip.cpp"
>
</File>
<File
RelativePath="..\conffile.cpp"
>
</File>
<File
RelativePath="..\conffile.h"
>
</File>
<File
RelativePath="..\controls.cpp"
>
</File>
<File
RelativePath="..\controls.h"
>
</File>
<File
RelativePath="..\cpu.cpp"
>
</File>
<File
RelativePath="..\cpuaddr.h"
>
</File>
<File
RelativePath="..\cpuexec.cpp"
>
</File>
<File
RelativePath="..\cpuexec.h"
>
</File>
<File
RelativePath="..\cpumacro.h"
>
</File>
<File
RelativePath="..\cpuops.cpp"
>
</File>
<File
RelativePath="..\cpuops.h"
>
</File>
<File
RelativePath="..\crosshairs.cpp"
>
</File>
<File
RelativePath="..\crosshairs.h"
>
</File>
<File
RelativePath="..\debug.cpp"
>
</File>
<File
RelativePath="..\debug.h"
>
</File>
<File
RelativePath="..\display.h"
>
</File>
<File
RelativePath="..\dma.cpp"
>
</File>
<File
RelativePath="..\dma.h"
>
</File>
<File
RelativePath="..\dsp.cpp"
>
</File>
<File
RelativePath="..\dsp.h"
>
</File>
<File
RelativePath="..\dsp1.cpp"
>
</File>
<File
RelativePath="..\dsp2.cpp"
>
</File>
<File
RelativePath="..\dsp3.cpp"
>
</File>
<File
RelativePath="..\dsp4.cpp"
>
</File>
<File
RelativePath="..\font.h"
>
</File>
<File
RelativePath="..\fxemu.cpp"
>
</File>
<File
RelativePath="..\fxemu.h"
>
</File>
<File
RelativePath="..\fxinst.cpp"
>
</File>
<File
RelativePath="..\fxinst.h"
>
</File>
<File
RelativePath="..\getset.h"
>
</File>
<File
RelativePath="..\gfx.cpp"
>
</File>
<File
RelativePath="..\gfx.h"
>
</File>
<File
RelativePath="..\globals.cpp"
>
</File>
<File
RelativePath="..\language.h"
>
</File>
<File
RelativePath="..\loadzip.cpp"
>
</File>
<File
RelativePath="..\logger.cpp"
>
</File>
<File
RelativePath="..\logger.h"
>
</File>
<File
RelativePath="..\memmap.cpp"
>
</File>
<File
RelativePath="..\memmap.h"
>
</File>
<File
RelativePath="..\messages.h"
>
</File>
<File
RelativePath="..\missing.h"
>
</File>
<File
RelativePath="..\movie.cpp"
>
</File>
<File
RelativePath="..\movie.h"
>
</File>
<File
RelativePath="..\netplay.cpp"
>
</File>
<File
RelativePath="..\netplay.h"
>
</File>
<File
RelativePath="..\obc1.cpp"
>
</File>
<File
RelativePath="..\obc1.h"
>
</File>
<File
RelativePath="..\pixform.h"
>
</File>
<File
RelativePath="..\port.h"
>
</File>
<File
RelativePath="..\ppu.cpp"
>
</File>
<File
RelativePath="..\ppu.h"
>
</File>
<File
RelativePath="..\sa1.cpp"
>
</File>
<File
RelativePath="..\sa1.h"
>
</File>
<File
RelativePath="..\sa1cpu.cpp"
>
</File>
<File
RelativePath="..\sar.h"
>
</File>
<File
RelativePath="..\screenshot.cpp"
>
</File>
<File
RelativePath="..\screenshot.h"
>
</File>
<File
RelativePath="..\sdd1.cpp"
>
</File>
<File
RelativePath="..\sdd1.h"
>
</File>
<File
RelativePath="..\sdd1emu.cpp"
>
</File>
<File
RelativePath="..\sdd1emu.h"
>
</File>
<File
RelativePath="..\server.cpp"
>
</File>
<File
RelativePath="..\seta.cpp"
>
</File>
<File
RelativePath="..\seta.h"
>
</File>
<File
RelativePath="..\seta010.cpp"
>
</File>
<File
RelativePath="..\seta011.cpp"
>
</File>
<File
RelativePath="..\seta018.cpp"
>
</File>
<File
RelativePath="..\snapshot.cpp"
>
</File>
<File
RelativePath="..\snapshot.h"
>
</File>
<File
RelativePath="..\snes9x.cpp"
>
</File>
<File
RelativePath="..\snes9x.h"
>
</File>
<File
RelativePath="..\spc7110.cpp"
>
</File>
<File
RelativePath="..\spc7110.h"
>
</File>
<File
RelativePath="..\srtc.cpp"
>
</File>
<File
RelativePath="..\srtc.h"
>
</File>
<File
RelativePath="..\stream.cpp"
>
</File>
<File
RelativePath="..\stream.h"
>
</File>
<File
RelativePath="..\tile.cpp"
>
</File>
<File
RelativePath="..\tile.h"
>
</File>
<Filter
Name="APU"
>
<File
RelativePath="..\apu\apu.cpp"
>
</File>
<File
RelativePath="..\apu\apu.h"
>
</File>
<File
RelativePath="..\apu\hermite_resampler.h"
>
</File>
<File
RelativePath="..\apu\resampler.h"
>
</File>
<File
RelativePath="..\apu\ring_buffer.h"
>
</File>
<Filter
Name="SMP"
>
<File
RelativePath="..\apu\bapu\smp\smp.cpp"
>
</File>
<File
RelativePath="..\apu\bapu\smp\smp_state.cpp"
>
</File>
</Filter>
<Filter
Name="DSP"
>
<File
RelativePath="..\apu\bapu\dsp\blargg_common.h"
>
</File>
<File
RelativePath="..\apu\bapu\dsp\blargg_config.h"
>
</File>
<File
RelativePath="..\apu\bapu\dsp\blargg_endian.h"
>
</File>
<File
RelativePath="..\apu\bapu\dsp\blargg_source.h"
>
</File>
<File
RelativePath="..\apu\bapu\dsp\sdsp.cpp"
>
</File>
<File
RelativePath="..\apu\bapu\dsp\sdsp.hpp"
>
</File>
<File
RelativePath="..\apu\bapu\dsp\SPC_DSP.cpp"
>
</File>
<File
RelativePath="..\apu\bapu\dsp\SPC_DSP.h"
>
</File>
</Filter>
</Filter>
</Filter>
<Filter
Name="libsnes"
>
<File
RelativePath=".\libsnes.cpp"
>
</File>
<File
RelativePath=".\libsnes.def"
>
</File>
<File
RelativePath=".\libsnes.hpp"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

790
libsnes/libsnes.cpp Normal file
View File

@ -0,0 +1,790 @@
#include "libsnes.hpp"
#include "snes9x.h"
#include "memmap.h"
#include "srtc.h"
#include "apu/apu.h"
#include "apu/bapu/snes/snes.hpp"
#include "gfx.h"
#include "snapshot.h"
#include "controls.h"
#include "cheats.h"
#include "movie.h"
#include "logger.h"
#include "display.h"
#include "conffile.h"
#include <stdio.h>
#ifndef __WIN32__
#include <unistd.h>
#endif
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
static snes_video_refresh_t s9x_video_cb = NULL;
static snes_audio_sample_t s9x_audio_cb = NULL;
static snes_input_poll_t s9x_poller_cb = NULL;
static snes_input_state_t s9x_input_state_cb = NULL;
void snes_set_video_refresh(snes_video_refresh_t cb)
{
s9x_video_cb = cb;
}
void snes_set_audio_sample(snes_audio_sample_t cb)
{
s9x_audio_cb = cb;
}
void snes_set_input_poll(snes_input_poll_t cb)
{
s9x_poller_cb = cb;
}
void snes_set_input_state(snes_input_state_t cb)
{
s9x_input_state_cb = cb;
}
static snes_environment_t environ_cb;
static bool use_overscan;
void snes_set_environment(snes_environment_t cb)
{
environ_cb = cb;
}
static void set_environ_timing()
{
if (environ_cb)
{
snes_system_timing timing;
timing.sample_rate = 32040.5;
if (!Settings.PAL)
timing.fps = 21477272.0 / 357366.0;
else
timing.fps = 21281370.0 / 425568.0;
environ_cb(SNES_ENVIRONMENT_SET_TIMING, &timing);
}
}
static void S9xAudioCallback(void*)
{
// Just pick a big buffer. We won't use it all.
static int16_t audio_buf[0x10000];
S9xFinalizeSamples();
size_t avail = S9xGetSampleCount();
S9xMixSamples((uint8*)audio_buf, avail);
for (size_t i = 0; i < avail; i+=2)
s9x_audio_cb((uint16_t)audio_buf[i], (uint16_t)audio_buf[i + 1]);
}
const char *snes_library_id()
{
return "SNES9x v" VERSION;
}
unsigned snes_library_revision_major()
{
return 1;
}
unsigned snes_library_revision_minor()
{
return 3;
}
void snes_power()
{
S9xReset();
}
void snes_reset()
{
S9xMovieUpdateOnReset();
if (S9xMoviePlaying())
{
S9xMovieStop(true);
}
S9xSoftReset();
}
static unsigned snes_devices[2];
void snes_set_controller_port_device(bool in_port, unsigned device)
{
int port = in_port == SNES_PORT_1 ? 0 : 1;
switch (device)
{
case SNES_DEVICE_JOYPAD:
S9xSetController(port, CTL_JOYPAD, 0, 0, 0, 0);
snes_devices[port] = SNES_DEVICE_JOYPAD;
break;
case SNES_DEVICE_MULTITAP:
S9xSetController(port, CTL_MP5, 1, 2, 3, 4);
snes_devices[port] = SNES_DEVICE_MULTITAP;
break;
case SNES_DEVICE_MOUSE:
S9xSetController(port, CTL_MOUSE, 0, 0, 0, 0);
snes_devices[port] = SNES_DEVICE_MOUSE;
break;
case SNES_DEVICE_SUPER_SCOPE:
S9xSetController(port, CTL_SUPERSCOPE, 0, 0, 0, 0);
snes_devices[port] = SNES_DEVICE_SUPER_SCOPE;
break;
case SNES_DEVICE_JUSTIFIER:
S9xSetController(port, CTL_JUSTIFIER, 0, 0, 0, 0);
snes_devices[port] = SNES_DEVICE_JUSTIFIER;
break;
case SNES_DEVICE_JUSTIFIERS:
S9xSetController(port, CTL_JUSTIFIER, 1, 0, 0, 0);
snes_devices[port] = SNES_DEVICE_JUSTIFIERS;
break;
default:
fprintf(stderr, "[libsnes]: Invalid device!\n");
}
}
void snes_cheat_reset()
{}
void snes_cheat_set(unsigned, bool, const char*)
{}
bool snes_load_cartridge_bsx_slotted(
const char *, const uint8_t *rom_data, unsigned rom_size,
const char *, const uint8_t *bsx_data, unsigned bsx_size
)
{
int loaded = Memory.LoadMultiCartMem(rom_data, rom_size, bsx_data, bsx_size, NULL, NULL);
if (!loaded)
{
fprintf(stderr, "[libsnes]: Sufami Turbo Rom loading failed...\n");
return false;
}
set_environ_timing();
return false;
}
bool snes_load_cartridge_bsx(
const char *rom_xml, const uint8_t *rom_data, unsigned rom_size,
const char *bsx_xml, const uint8_t *bsx_data, unsigned bsx_size
)
{
if(bsx_data==NULL)
return snes_load_cartridge_normal(rom_xml,rom_data,rom_size);
memcpy(Memory.BIOSROM,rom_data,rom_size);
return snes_load_cartridge_normal(bsx_xml,bsx_data,bsx_size);
}
bool snes_load_cartridge_sufami_turbo(
const char *, const uint8_t *rom_data, unsigned rom_size,
const char *, const uint8_t *sta_data, unsigned sta_size,
const char *, const uint8_t *stb_data, unsigned stb_size
)
{
int loaded = Memory.LoadMultiCartMem(sta_data, sta_size, stb_data, stb_size, rom_data, rom_size);
if (!loaded)
{
fprintf(stderr, "[libsnes]: Sufami Turbo Rom loading failed...\n");
return false;
}
set_environ_timing();
return true;
}
bool snes_load_cartridge_super_game_boy(
const char *, const uint8_t *, unsigned,
const char *, const uint8_t *, unsigned
)
{
return false;
}
static void map_buttons();
void snes_init()
{
if (environ_cb)
{
if (!environ_cb(SNES_ENVIRONMENT_GET_OVERSCAN, &use_overscan))
use_overscan = false;
if (use_overscan)
{
snes_geometry geom = {256, 239, 512, 512};
environ_cb(SNES_ENVIRONMENT_SET_GEOMETRY, &geom);
unsigned pitch = 1024;
environ_cb(SNES_ENVIRONMENT_SET_PITCH, &pitch);
}
}
memset(&Settings, 0, sizeof(Settings));
Settings.MouseMaster = TRUE;
Settings.SuperScopeMaster = TRUE;
Settings.JustifierMaster = TRUE;
Settings.MultiPlayer5Master = TRUE;
Settings.FrameTimePAL = 20000;
Settings.FrameTimeNTSC = 16667;
Settings.SixteenBitSound = TRUE;
Settings.Stereo = TRUE;
Settings.SoundPlaybackRate = 32000;
Settings.SoundInputRate = 32000;
Settings.SupportHiRes = TRUE;
Settings.Transparency = TRUE;
Settings.AutoDisplayMessages = TRUE;
Settings.InitialInfoStringTimeout = 120;
Settings.HDMATimingHack = 100;
Settings.BlockInvalidVRAMAccessMaster = TRUE;
Settings.StopEmulation = TRUE;
Settings.WrongMovieStateProtection = TRUE;
Settings.DumpStreamsMaxFrames = -1;
Settings.StretchScreenshots = 0;
Settings.SnapshotScreenshots = FALSE;
Settings.SkipFrames = AUTO_FRAMERATE;
Settings.TurboSkipFrames = 15;
Settings.CartAName[0] = 0;
Settings.CartBName[0] = 0;
Settings.AutoSaveDelay = 1;
CPU.Flags = 0;
if (!Memory.Init() || !S9xInitAPU())
{
Memory.Deinit();
S9xDeinitAPU();
fprintf(stderr, "[libsnes]: Failed to init Memory or APU.\n");
exit(1);
}
S9xInitSound(16, 0);
S9xSetSoundMute(FALSE);
S9xSetSamplesAvailableCallback(S9xAudioCallback, NULL);
S9xSetRenderPixelFormat(RGB555);
GFX.Pitch = use_overscan ? 1024 : 2048;
GFX.Screen = (uint16*) calloc(1, GFX.Pitch * 512 * sizeof(uint16));
S9xGraphicsInit();
S9xInitInputDevices();
for (int i = 0; i < 2; i++)
{
S9xSetController(i, CTL_JOYPAD, i, 0, 0, 0);
snes_devices[i] = SNES_DEVICE_JOYPAD;
}
S9xUnmapAllControls();
map_buttons();
}
#define MAP_BUTTON(id, name) S9xMapButton((id), S9xGetCommandT((name)), false)
#define MAKE_BUTTON(pad, btn) (((pad)<<4)|(btn))
#define PAD_1 1
#define PAD_2 2
#define PAD_3 3
#define PAD_4 4
#define PAD_5 5
#define BTN_B SNES_DEVICE_ID_JOYPAD_B
#define BTN_Y SNES_DEVICE_ID_JOYPAD_Y
#define BTN_SELECT SNES_DEVICE_ID_JOYPAD_SELECT
#define BTN_START SNES_DEVICE_ID_JOYPAD_START
#define BTN_UP SNES_DEVICE_ID_JOYPAD_UP
#define BTN_DOWN SNES_DEVICE_ID_JOYPAD_DOWN
#define BTN_LEFT SNES_DEVICE_ID_JOYPAD_LEFT
#define BTN_RIGHT SNES_DEVICE_ID_JOYPAD_RIGHT
#define BTN_A SNES_DEVICE_ID_JOYPAD_A
#define BTN_X SNES_DEVICE_ID_JOYPAD_X
#define BTN_L SNES_DEVICE_ID_JOYPAD_L
#define BTN_R SNES_DEVICE_ID_JOYPAD_R
#define BTN_FIRST BTN_B
#define BTN_LAST BTN_R
#define MOUSE_X SNES_DEVICE_ID_MOUSE_X
#define MOUSE_Y SNES_DEVICE_ID_MOUSE_Y
#define MOUSE_LEFT SNES_DEVICE_ID_MOUSE_LEFT
#define MOUSE_RIGHT SNES_DEVICE_ID_MOUSE_RIGHT
#define MOUSE_FIRST MOUSE_X
#define MOUSE_LAST MOUSE_RIGHT
#define SCOPE_X SNES_DEVICE_ID_SUPER_SCOPE_X
#define SCOPE_Y SNES_DEVICE_ID_SUPER_SCOPE_Y
#define SCOPE_TRIGGER SNES_DEVICE_ID_SUPER_SCOPE_TRIGGER
#define SCOPE_CURSOR SNES_DEVICE_ID_SUPER_SCOPE_CURSOR
#define SCOPE_TURBO SNES_DEVICE_ID_SUPER_SCOPE_TURBO
#define SCOPE_PAUSE SNES_DEVICE_ID_SUPER_SCOPE_PAUSE
#define SCOPE_FIRST SCOPE_X
#define SCOPE_LAST SCOPE_PAUSE
#define JUSTIFIER_X SNES_DEVICE_ID_JUSTIFIER_X
#define JUSTIFIER_Y SNES_DEVICE_ID_JUSTIFIER_Y
#define JUSTIFIER_TRIGGER SNES_DEVICE_ID_JUSTIFIER_TRIGGER
#define JUSTIFIER_START SNES_DEVICE_ID_JUSTIFIER_START
#define JUSTIFIER_FIRST JUSTIFIER_X
#define JUSTIFIER_LAST JUSTIFIER_START
#define BTN_POINTER (BTN_LAST + 1)
#define BTN_POINTER2 (BTN_POINTER + 1)
static void map_buttons()
{
MAP_BUTTON(MAKE_BUTTON(PAD_1, BTN_A), "Joypad1 A");
MAP_BUTTON(MAKE_BUTTON(PAD_1, BTN_B), "Joypad1 B");
MAP_BUTTON(MAKE_BUTTON(PAD_1, BTN_X), "Joypad1 X");
MAP_BUTTON(MAKE_BUTTON(PAD_1, BTN_Y), "Joypad1 Y");
MAP_BUTTON(MAKE_BUTTON(PAD_1, BTN_SELECT), "{Joypad1 Select,Mouse1 L}");
MAP_BUTTON(MAKE_BUTTON(PAD_1, BTN_START), "{Joypad1 Start,Mouse1 R}");
MAP_BUTTON(MAKE_BUTTON(PAD_1, BTN_L), "Joypad1 L");
MAP_BUTTON(MAKE_BUTTON(PAD_1, BTN_R), "Joypad1 R");
MAP_BUTTON(MAKE_BUTTON(PAD_1, BTN_LEFT), "Joypad1 Left");
MAP_BUTTON(MAKE_BUTTON(PAD_1, BTN_RIGHT), "Joypad1 Right");
MAP_BUTTON(MAKE_BUTTON(PAD_1, BTN_UP), "Joypad1 Up");
MAP_BUTTON(MAKE_BUTTON(PAD_1, BTN_DOWN), "Joypad1 Down");
S9xMapPointer((BTN_POINTER), S9xGetCommandT("Pointer Mouse1+Superscope+Justifier1"), false);
S9xMapPointer((BTN_POINTER2), S9xGetCommandT("Pointer Mouse2"), false);
MAP_BUTTON(MAKE_BUTTON(PAD_2, BTN_A), "Joypad2 A");
MAP_BUTTON(MAKE_BUTTON(PAD_2, BTN_B), "Joypad2 B");
MAP_BUTTON(MAKE_BUTTON(PAD_2, BTN_X), "Joypad2 X");
MAP_BUTTON(MAKE_BUTTON(PAD_2, BTN_Y), "Joypad2 Y");
MAP_BUTTON(MAKE_BUTTON(PAD_2, BTN_SELECT), "{Joypad2 Select,Mouse2 L,Superscope Fire,Justifier1 Trigger}");
MAP_BUTTON(MAKE_BUTTON(PAD_2, BTN_START), "{Joypad2 Start,Mouse2 R,Superscope Cursor,Justifier1 Start}");
MAP_BUTTON(MAKE_BUTTON(PAD_2, BTN_L), "Joypad2 L");
MAP_BUTTON(MAKE_BUTTON(PAD_2, BTN_R), "Joypad2 R");
MAP_BUTTON(MAKE_BUTTON(PAD_2, BTN_LEFT), "Joypad2 Left");
MAP_BUTTON(MAKE_BUTTON(PAD_2, BTN_RIGHT), "Joypad2 Right");
MAP_BUTTON(MAKE_BUTTON(PAD_2, BTN_UP), "{Joypad2 Up,Superscope ToggleTurbo}");
MAP_BUTTON(MAKE_BUTTON(PAD_2, BTN_DOWN), "{Joypad2 Down,Superscope Pause}");
MAP_BUTTON(MAKE_BUTTON(PAD_3, BTN_A), "Joypad3 A");
MAP_BUTTON(MAKE_BUTTON(PAD_3, BTN_B), "Joypad3 B");
MAP_BUTTON(MAKE_BUTTON(PAD_3, BTN_X), "Joypad3 X");
MAP_BUTTON(MAKE_BUTTON(PAD_3, BTN_Y), "Joypad3 Y");
MAP_BUTTON(MAKE_BUTTON(PAD_3, BTN_SELECT), "Joypad3 Select");
MAP_BUTTON(MAKE_BUTTON(PAD_3, BTN_START), "Joypad3 Start");
MAP_BUTTON(MAKE_BUTTON(PAD_3, BTN_L), "Joypad3 L");
MAP_BUTTON(MAKE_BUTTON(PAD_3, BTN_R), "Joypad3 R");
MAP_BUTTON(MAKE_BUTTON(PAD_3, BTN_LEFT), "Joypad3 Left");
MAP_BUTTON(MAKE_BUTTON(PAD_3, BTN_RIGHT), "Joypad3 Right");
MAP_BUTTON(MAKE_BUTTON(PAD_3, BTN_UP), "Joypad3 Up");
MAP_BUTTON(MAKE_BUTTON(PAD_3, BTN_DOWN), "Joypad3 Down");
MAP_BUTTON(MAKE_BUTTON(PAD_4, BTN_A), "Joypad4 A");
MAP_BUTTON(MAKE_BUTTON(PAD_4, BTN_B), "Joypad4 B");
MAP_BUTTON(MAKE_BUTTON(PAD_4, BTN_X), "Joypad4 X");
MAP_BUTTON(MAKE_BUTTON(PAD_4, BTN_Y), "Joypad4 Y");
MAP_BUTTON(MAKE_BUTTON(PAD_4, BTN_SELECT), "Joypad4 Select");
MAP_BUTTON(MAKE_BUTTON(PAD_4, BTN_START), "Joypad4 Start");
MAP_BUTTON(MAKE_BUTTON(PAD_4, BTN_L), "Joypad4 L");
MAP_BUTTON(MAKE_BUTTON(PAD_4, BTN_R), "Joypad4 R");
MAP_BUTTON(MAKE_BUTTON(PAD_4, BTN_LEFT), "Joypad4 Left");
MAP_BUTTON(MAKE_BUTTON(PAD_4, BTN_RIGHT), "Joypad4 Right");
MAP_BUTTON(MAKE_BUTTON(PAD_4, BTN_UP), "Joypad4 Up");
MAP_BUTTON(MAKE_BUTTON(PAD_4, BTN_DOWN), "Joypad4 Down");
MAP_BUTTON(MAKE_BUTTON(PAD_5, BTN_A), "Joypad5 A");
MAP_BUTTON(MAKE_BUTTON(PAD_5, BTN_B), "Joypad5 B");
MAP_BUTTON(MAKE_BUTTON(PAD_5, BTN_X), "Joypad5 X");
MAP_BUTTON(MAKE_BUTTON(PAD_5, BTN_Y), "Joypad5 Y");
MAP_BUTTON(MAKE_BUTTON(PAD_5, BTN_SELECT), "Joypad5 Select");
MAP_BUTTON(MAKE_BUTTON(PAD_5, BTN_START), "Joypad5 Start");
MAP_BUTTON(MAKE_BUTTON(PAD_5, BTN_L), "Joypad5 L");
MAP_BUTTON(MAKE_BUTTON(PAD_5, BTN_R), "Joypad5 R");
MAP_BUTTON(MAKE_BUTTON(PAD_5, BTN_LEFT), "Joypad5 Left");
MAP_BUTTON(MAKE_BUTTON(PAD_5, BTN_RIGHT), "Joypad5 Right");
MAP_BUTTON(MAKE_BUTTON(PAD_5, BTN_UP), "Joypad5 Up");
MAP_BUTTON(MAKE_BUTTON(PAD_5, BTN_DOWN), "Joypad5 Down");
}
// libsnes 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}};
static int16_t snes_scope_state[2] = {0};
static int16_t snes_justifier_state[2][2] = {{0}, {0}};
static void report_buttons()
{
int _x, _y;
for (int port = SNES_PORT_1; port <= SNES_PORT_2; port++)
{
switch (snes_devices[port])
{
case SNES_DEVICE_JOYPAD:
for (int i = BTN_FIRST; i <= BTN_LAST; i++)
S9xReportButton(MAKE_BUTTON(port + 1, i), s9x_input_state_cb(port == SNES_PORT_2, SNES_DEVICE_JOYPAD, 0, i));
break;
case SNES_DEVICE_MULTITAP:
for (int j = 0; j < 4; j++)
for (int i = BTN_FIRST; i <= BTN_LAST; i++)
S9xReportButton(MAKE_BUTTON(j + 2, i), s9x_input_state_cb(port == SNES_PORT_2, SNES_DEVICE_MULTITAP, j, i));
break;
case SNES_DEVICE_MOUSE:
_x = s9x_input_state_cb(port == SNES_PORT_2, SNES_DEVICE_MOUSE, 0, SNES_DEVICE_ID_MOUSE_X);
_y = s9x_input_state_cb(port == SNES_PORT_2, SNES_DEVICE_MOUSE, 0, SNES_DEVICE_ID_MOUSE_Y);
snes_mouse_state[port][0] += _x;
snes_mouse_state[port][1] += _y;
S9xReportPointer(BTN_POINTER + port, snes_mouse_state[port][0], snes_mouse_state[port][1]);
for (int i = MOUSE_LEFT; i <= MOUSE_LAST; i++)
S9xReportButton(MAKE_BUTTON(port + 1, i), s9x_input_state_cb(port == SNES_PORT_2, SNES_DEVICE_MOUSE, 0, i));
break;
case SNES_DEVICE_SUPER_SCOPE:
snes_scope_state[0] += s9x_input_state_cb(port == SNES_PORT_2, SNES_DEVICE_SUPER_SCOPE, 0, SNES_DEVICE_ID_SUPER_SCOPE_X);
snes_scope_state[1] += s9x_input_state_cb(port == SNES_PORT_2, SNES_DEVICE_SUPER_SCOPE, 0, SNES_DEVICE_ID_SUPER_SCOPE_Y);
S9xReportPointer(BTN_POINTER, snes_scope_state[0], snes_scope_state[1]);
for (int i = SCOPE_TRIGGER; i <= SCOPE_LAST; i++)
S9xReportButton(MAKE_BUTTON(port + 1, i), s9x_input_state_cb(port == SNES_PORT_2, SNES_DEVICE_SUPER_SCOPE, 0, i));
break;
case SNES_DEVICE_JUSTIFIER:
case SNES_DEVICE_JUSTIFIERS:
snes_justifier_state[0][0] += s9x_input_state_cb(port == SNES_PORT_2, SNES_DEVICE_JUSTIFIER, 0, SNES_DEVICE_ID_JUSTIFIER_X);
snes_justifier_state[0][1] += s9x_input_state_cb(port == SNES_PORT_2, SNES_DEVICE_JUSTIFIER, 0, SNES_DEVICE_ID_JUSTIFIER_Y);
S9xReportPointer(BTN_POINTER, snes_justifier_state[0][0], snes_justifier_state[0][1]);
for (int i = JUSTIFIER_TRIGGER; i <= JUSTIFIER_LAST; i++)
S9xReportButton(MAKE_BUTTON(port + 1, i), s9x_input_state_cb(port == SNES_PORT_2, SNES_DEVICE_JUSTIFIER, 0, i));
break;
default:
fprintf(stderr, "[libsnes]: Unknown device...\n");
}
}
}
bool snes_load_cartridge_normal(const char *, const uint8_t *rom_data, unsigned rom_size)
{
int loaded = Memory.LoadROMMem(rom_data,rom_size);
if (!loaded)
{
fprintf(stderr, "[libsnes]: Rom loading failed...\n");
return false;
}
set_environ_timing();
return true;
}
void snes_run()
{
s9x_poller_cb();
report_buttons();
S9xMainLoop();
}
void snes_term()
{
S9xDeinitAPU();
Memory.Deinit();
S9xGraphicsDeinit();
S9xUnmapAllControls();
}
bool snes_get_region()
{
return Settings.PAL ? SNES_REGION_PAL : SNES_REGION_NTSC;
}
uint8_t* snes_get_memory_data(unsigned type)
{
uint8_t* data;
switch(type) {
case SNES_MEMORY_SUFAMI_TURBO_A_RAM:
case SNES_MEMORY_CARTRIDGE_RAM:
data = Memory.SRAM;
break;
case SNES_MEMORY_SUFAMI_TURBO_B_RAM:
data = Multi.sramB;
break;
case SNES_MEMORY_CARTRIDGE_RTC:
data = RTCData.reg;
break;
case SNES_MEMORY_WRAM:
data = Memory.RAM;
break;
case SNES_MEMORY_APURAM:
data = SNES::smp.apuram;
break;
case SNES_MEMORY_VRAM:
data = Memory.VRAM;
break;
case SNES_MEMORY_CGRAM:
data = (uint8_t*)PPU.CGDATA;
break;
case SNES_MEMORY_OAM:
data = PPU.OAMData;
break;
default:
data = NULL;
break;
}
return data;
}
void snes_unload_cartridge()
{
}
unsigned snes_get_memory_size(unsigned type)
{
unsigned size;
switch(type) {
case SNES_MEMORY_SUFAMI_TURBO_A_RAM:
case SNES_MEMORY_CARTRIDGE_RAM:
size = (unsigned) (Memory.SRAMSize ? (1 << (Memory.SRAMSize + 3)) * 128 : 0);
if (size > 0x20000)
size = 0x20000;
break;
case SNES_MEMORY_SUFAMI_TURBO_B_RAM:
size = (unsigned) (Multi.cartType && Multi.sramSizeB ? (1 << (Multi.sramSizeB + 3)) * 128 : 0);
break;
case SNES_MEMORY_CARTRIDGE_RTC:
size = (Settings.SRTC || Settings.SPC7110RTC)?20:0;
break;
case SNES_MEMORY_WRAM:
size = 128 * 1024;
break;
case SNES_MEMORY_VRAM:
case SNES_MEMORY_APURAM:
size = 64 * 1024;
break;
case SNES_MEMORY_CGRAM:
size = 512;
break;
case SNES_MEMORY_OAM:
size = 512 + 32;
break;
default:
size = 0;
break;
}
return size;
}
void snes_set_cartridge_basename(const char*)
{}
unsigned snes_serialize_size()
{
return S9xFreezeSize();
}
bool snes_serialize(uint8_t *data, unsigned size)
{
if (S9xFreezeGameMem(data,size) == FALSE)
return false;
return true;
}
bool snes_unserialize(const uint8_t* data, unsigned size)
{
if (S9xUnfreezeGameMem(data,size) != SUCCESS)
return false;
return true;
}
// Pitch 2048 -> 1024, only done once per res-change.
static void pack_frame(uint16_t *frame, int width, int height)
{
for (int y = 1; y < height; y++)
{
uint16_t *src = frame + y * 1024;
uint16_t *dst = frame + y * 512;
memcpy(dst, src, width * sizeof(uint16_t));
}
}
// Pitch 1024 -> 2048, only done once per res-change.
static void stretch_frame(uint16_t *frame, int width, int height)
{
for (int y = height - 1; y >= 0; y--)
{
uint16_t *src = frame + y * 512;
uint16_t *dst = frame + y * 1024;
memcpy(dst, src, width * sizeof(uint16_t));
}
}
bool8 S9xDeinitUpdate(int width, int height)
{
if (use_overscan)
{
if (height == 224)
{
memmove(GFX.Screen + (GFX.Pitch / 2) * 7, GFX.Screen, GFX.Pitch * height);
memset(GFX.Screen, 0x00, GFX.Pitch * 7);
memset(GFX.Screen + (GFX.Pitch / 2) * (7 + 224), 0, GFX.Pitch * 8);
height = 239;
}
else if (height == 448)
{
memmove(GFX.Screen + (GFX.Pitch / 2) * 15, GFX.Screen, GFX.Pitch * height);
memset(GFX.Screen, 0x00, GFX.Pitch * 15);
memset(GFX.Screen + (GFX.Pitch / 2) * (15 + 224), 0x00, GFX.Pitch * 17);
height = 478;
}
}
else // libsnes classic behavior
{
if (height == 448 || height == 478)
{
if (GFX.Pitch == 2048)
pack_frame(GFX.Screen, width, height);
GFX.Pitch = 1024;
}
else
{
if (GFX.Pitch == 1024)
stretch_frame(GFX.Screen, width, height);
GFX.Pitch = 2048;
}
}
s9x_video_cb(GFX.Screen, width, height);
return TRUE;
}
bool8 S9xContinueUpdate(int width, int height)
{
return S9xDeinitUpdate(width, height);
}
// Dummy functions that should probably be implemented correctly later.
void S9xParsePortConfig(ConfigFile&, int) {}
void S9xSyncSpeed() {}
//void S9xPollPointer(int, short*, short*) {}
const char* S9xStringInput(const char* in) { return in; }
const char* S9xGetFilename(const char* in, s9x_getdirtype) { return in; }
const char* S9xGetDirectory(s9x_getdirtype) { return ""; }
void S9xInitInputDevices() {}
const char* S9xChooseFilename(unsigned char) { return ""; }
void S9xHandlePortCommand(s9xcommand_t, short, short) {}
bool S9xPollButton(unsigned int, bool*) { return false; }
void S9xToggleSoundChannel(int) {}
const char* S9xGetFilenameInc(const char* in, s9x_getdirtype) { return ""; }
const char* S9xBasename(const char* in) { return in; }
bool8 S9xInitUpdate() { return TRUE; }
void S9xExtraUsage() {}
bool8 S9xOpenSoundDevice() { return TRUE; }
void S9xMessage(int, int, const char*) {}
bool S9xPollAxis(unsigned int, short*) { return FALSE; }
void S9xSetPalette() {}
void S9xParseArg(char**, int&, int) {}
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)
{
if(read_only)
{
if((*file = OPEN_STREAM(filepath, "rb")) != 0)
{
return (TRUE);
}
}
else
{
if((*file = OPEN_STREAM(filepath, "wb")) != 0)
{
return (TRUE);
}
}
return (FALSE);
}
void S9xCloseSnapshotFile(STREAM file)
{
CLOSE_STREAM(file);
}
void S9xAutoSaveSRAM()
{
return;
}
#ifndef __WIN32__
// S9x weirdness.
void _splitpath (const char *path, char *drive, char *dir, char *fname, char *ext)
{
*drive = 0;
const char *slash = strrchr(path, SLASH_CHAR),
*dot = strrchr(path, '.');
if (dot && slash && dot < slash)
dot = NULL;
if (!slash)
{
*dir = 0;
strcpy(fname, path);
if (dot)
{
fname[dot - path] = 0;
strcpy(ext, dot + 1);
}
else
*ext = 0;
}
else
{
strcpy(dir, path);
dir[slash - path] = 0;
strcpy(fname, slash + 1);
if (dot)
{
fname[dot - slash - 1] = 0;
strcpy(ext, dot + 1);
}
else
*ext = 0;
}
}
void _makepath (char *path, const char *, const char *dir, const char *fname, const char *ext)
{
if (dir && *dir)
{
strcpy(path, dir);
strcat(path, SLASH_STR);
}
else
*path = 0;
strcat(path, fname);
if (ext && *ext)
{
strcat(path, ".");
strcat(path, ext);
}
}
#endif // __WIN32__

47
libsnes/libsnes.def Normal file
View File

@ -0,0 +1,47 @@
LIBRARY snes
EXPORTS
snes_library_id
snes_library_revision_major
snes_library_revision_minor
snes_set_video_refresh
snes_set_audio_sample
snes_set_input_poll
snes_set_input_state
snes_set_environment
snes_set_controller_port_device
snes_set_cartridge_basename
snes_init
snes_term
snes_power
snes_reset
snes_run
snes_serialize_size
snes_serialize
snes_unserialize
snes_cheat_reset
snes_cheat_set
snes_load_cartridge_normal
snes_load_cartridge_bsx_slotted
snes_load_cartridge_bsx
snes_load_cartridge_sufami_turbo
snes_load_cartridge_super_game_boy
snes_unload_cartridge
snes_get_region
snes_get_memory_data
snes_get_memory_size

1264
libsnes/libsnes.hpp Normal file

File diff suppressed because it is too large Load Diff

4
libsnes/link.T Normal file
View File

@ -0,0 +1,4 @@
{
global: snes_*;
local: *;
};

View File

@ -185,10 +185,9 @@
#include "memmap.h" #include "memmap.h"
bool8 LoadZip (const char *zipname, int32 *TotalFileSize, int32 *headers, uint8 *buffer) bool8 LoadZip (const char *zipname, uint32 *TotalFileSize, uint8 *buffer)
{ {
*TotalFileSize = 0; *TotalFileSize = 0;
*headers = 0;
unzFile file = unzOpen(zipname); unzFile file = unzOpen(zipname);
if (file == NULL) if (file == NULL)
@ -196,7 +195,7 @@ bool8 LoadZip (const char *zipname, int32 *TotalFileSize, int32 *headers, uint8
// find largest file in zip file (under MAX_ROM_SIZE) or a file with extension .1 // find largest file in zip file (under MAX_ROM_SIZE) or a file with extension .1
char filename[132]; char filename[132];
int filesize = 0; uint32 filesize = 0;
int port = unzGoToFirstFile(file); int port = unzGoToFirstFile(file);
unz_file_info info; unz_file_info info;
@ -212,7 +211,7 @@ bool8 LoadZip (const char *zipname, int32 *TotalFileSize, int32 *headers, uint8
continue; continue;
} }
if ((int) info.uncompressed_size > filesize) if (info.uncompressed_size > filesize)
{ {
strcpy(filename, name); strcpy(filename, name);
filesize = info.uncompressed_size; filesize = info.uncompressed_size;
@ -259,7 +258,7 @@ bool8 LoadZip (const char *zipname, int32 *TotalFileSize, int32 *headers, uint8
{ {
assert(info.uncompressed_size <= CMemory::MAX_ROM_SIZE + 512); assert(info.uncompressed_size <= CMemory::MAX_ROM_SIZE + 512);
int FileSize = info.uncompressed_size; uint32 FileSize = info.uncompressed_size;
int l = unzReadCurrentFile(file, ptr, FileSize); int l = unzReadCurrentFile(file, ptr, FileSize);
if (unzCloseCurrentFile(file) == UNZ_CRCERROR) if (unzCloseCurrentFile(file) == UNZ_CRCERROR)
@ -274,7 +273,7 @@ bool8 LoadZip (const char *zipname, int32 *TotalFileSize, int32 *headers, uint8
return (FALSE); return (FALSE);
} }
FileSize = (int) Memory.HeaderRemove((uint32) FileSize, *headers, ptr); FileSize = Memory.HeaderRemove(FileSize, ptr);
ptr += FileSize; ptr += FileSize;
*TotalFileSize += FileSize; *TotalFileSize += FileSize;

View File

@ -36,7 +36,7 @@
CF047D54109D0E0600FD0754 /* pixform.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061C60526CCB900A80003 /* pixform.h */; }; CF047D54109D0E0600FD0754 /* pixform.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061C60526CCB900A80003 /* pixform.h */; };
CF047D55109D0E0600FD0754 /* port.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061C70526CCB900A80003 /* port.h */; }; CF047D55109D0E0600FD0754 /* port.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061C70526CCB900A80003 /* port.h */; };
CF047D56109D0E0600FD0754 /* ppu.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061C90526CCB900A80003 /* ppu.h */; }; CF047D56109D0E0600FD0754 /* ppu.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061C90526CCB900A80003 /* ppu.h */; };
CF047D57109D0E0600FD0754 /* reader.h in Headers */ = {isa = PBXBuildFile; fileRef = EA809E9708F8D70D0072CDFB /* reader.h */; }; CF047D57109D0E0600FD0754 /* stream.h in Headers */ = {isa = PBXBuildFile; fileRef = EA809E9708F8D70D0072CDFB /* stream.h */; };
CF047D58109D0E0600FD0754 /* sa1.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061CC0526CCB900A80003 /* sa1.h */; }; CF047D58109D0E0600FD0754 /* sa1.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061CC0526CCB900A80003 /* sa1.h */; };
CF047D59109D0E0600FD0754 /* sar.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061CE0526CCB900A80003 /* sar.h */; }; CF047D59109D0E0600FD0754 /* sar.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061CE0526CCB900A80003 /* sar.h */; };
CF047D5A109D0E0600FD0754 /* screenshot.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061D00526CCB900A80003 /* screenshot.h */; }; CF047D5A109D0E0600FD0754 /* screenshot.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061D00526CCB900A80003 /* screenshot.h */; };
@ -145,7 +145,7 @@
CF047DC9109D0E0600FD0754 /* movie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EA813E9A066F50A5004F99B5 /* movie.cpp */; }; CF047DC9109D0E0600FD0754 /* movie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EA813E9A066F50A5004F99B5 /* movie.cpp */; };
CF047DCA109D0E0600FD0754 /* obc1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061C30526CCB900A80003 /* obc1.cpp */; }; CF047DCA109D0E0600FD0754 /* obc1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061C30526CCB900A80003 /* obc1.cpp */; };
CF047DCB109D0E0600FD0754 /* ppu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061C80526CCB900A80003 /* ppu.cpp */; }; CF047DCB109D0E0600FD0754 /* ppu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061C80526CCB900A80003 /* ppu.cpp */; };
CF047DCC109D0E0600FD0754 /* reader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EA809E9F08F8D7530072CDFB /* reader.cpp */; }; CF047DCC109D0E0600FD0754 /* stream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EA809E9F08F8D7530072CDFB /* stream.cpp */; };
CF047DCD109D0E0600FD0754 /* sa1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061CB0526CCB900A80003 /* sa1.cpp */; }; CF047DCD109D0E0600FD0754 /* sa1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061CB0526CCB900A80003 /* sa1.cpp */; };
CF047DCE109D0E0600FD0754 /* sa1cpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061CD0526CCB900A80003 /* sa1cpu.cpp */; }; CF047DCE109D0E0600FD0754 /* sa1cpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061CD0526CCB900A80003 /* sa1cpu.cpp */; };
CF047DCF109D0E0600FD0754 /* sdd1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061D10526CCB900A80003 /* sdd1.cpp */; }; CF047DCF109D0E0600FD0754 /* sdd1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061D10526CCB900A80003 /* sdd1.cpp */; };
@ -237,7 +237,7 @@
CF0566A90CF98E7E00C7877C /* pixform.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061C60526CCB900A80003 /* pixform.h */; }; CF0566A90CF98E7E00C7877C /* pixform.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061C60526CCB900A80003 /* pixform.h */; };
CF0566AA0CF98E7E00C7877C /* port.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061C70526CCB900A80003 /* port.h */; }; CF0566AA0CF98E7E00C7877C /* port.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061C70526CCB900A80003 /* port.h */; };
CF0566AB0CF98E7E00C7877C /* ppu.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061C90526CCB900A80003 /* ppu.h */; }; CF0566AB0CF98E7E00C7877C /* ppu.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061C90526CCB900A80003 /* ppu.h */; };
CF0566AC0CF98E7E00C7877C /* reader.h in Headers */ = {isa = PBXBuildFile; fileRef = EA809E9708F8D70D0072CDFB /* reader.h */; }; CF0566AC0CF98E7E00C7877C /* stream.h in Headers */ = {isa = PBXBuildFile; fileRef = EA809E9708F8D70D0072CDFB /* stream.h */; };
CF0566AD0CF98E7E00C7877C /* sa1.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061CC0526CCB900A80003 /* sa1.h */; }; CF0566AD0CF98E7E00C7877C /* sa1.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061CC0526CCB900A80003 /* sa1.h */; };
CF0566AE0CF98E7E00C7877C /* sar.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061CE0526CCB900A80003 /* sar.h */; }; CF0566AE0CF98E7E00C7877C /* sar.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061CE0526CCB900A80003 /* sar.h */; };
CF0566AF0CF98E7E00C7877C /* screenshot.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061D00526CCB900A80003 /* screenshot.h */; }; CF0566AF0CF98E7E00C7877C /* screenshot.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061D00526CCB900A80003 /* screenshot.h */; };
@ -333,7 +333,7 @@
CF0567180CF98E7E00C7877C /* movie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EA813E9A066F50A5004F99B5 /* movie.cpp */; }; CF0567180CF98E7E00C7877C /* movie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EA813E9A066F50A5004F99B5 /* movie.cpp */; };
CF0567190CF98E7E00C7877C /* obc1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061C30526CCB900A80003 /* obc1.cpp */; }; CF0567190CF98E7E00C7877C /* obc1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061C30526CCB900A80003 /* obc1.cpp */; };
CF05671A0CF98E7E00C7877C /* ppu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061C80526CCB900A80003 /* ppu.cpp */; }; CF05671A0CF98E7E00C7877C /* ppu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061C80526CCB900A80003 /* ppu.cpp */; };
CF05671B0CF98E7E00C7877C /* reader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EA809E9F08F8D7530072CDFB /* reader.cpp */; }; CF05671B0CF98E7E00C7877C /* stream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EA809E9F08F8D7530072CDFB /* stream.cpp */; };
CF05671C0CF98E7E00C7877C /* sa1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061CB0526CCB900A80003 /* sa1.cpp */; }; CF05671C0CF98E7E00C7877C /* sa1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061CB0526CCB900A80003 /* sa1.cpp */; };
CF05671D0CF98E7E00C7877C /* sa1cpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061CD0526CCB900A80003 /* sa1cpu.cpp */; }; CF05671D0CF98E7E00C7877C /* sa1cpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061CD0526CCB900A80003 /* sa1cpu.cpp */; };
CF05671E0CF98E7E00C7877C /* sdd1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061D10526CCB900A80003 /* sdd1.cpp */; }; CF05671E0CF98E7E00C7877C /* sdd1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061D10526CCB900A80003 /* sdd1.cpp */; };
@ -424,7 +424,7 @@
CF2F462E1095EE72007D33FA /* pixform.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061C60526CCB900A80003 /* pixform.h */; }; CF2F462E1095EE72007D33FA /* pixform.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061C60526CCB900A80003 /* pixform.h */; };
CF2F462F1095EE72007D33FA /* port.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061C70526CCB900A80003 /* port.h */; }; CF2F462F1095EE72007D33FA /* port.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061C70526CCB900A80003 /* port.h */; };
CF2F46301095EE72007D33FA /* ppu.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061C90526CCB900A80003 /* ppu.h */; }; CF2F46301095EE72007D33FA /* ppu.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061C90526CCB900A80003 /* ppu.h */; };
CF2F46311095EE72007D33FA /* reader.h in Headers */ = {isa = PBXBuildFile; fileRef = EA809E9708F8D70D0072CDFB /* reader.h */; }; CF2F46311095EE72007D33FA /* stream.h in Headers */ = {isa = PBXBuildFile; fileRef = EA809E9708F8D70D0072CDFB /* stream.h */; };
CF2F46321095EE72007D33FA /* sa1.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061CC0526CCB900A80003 /* sa1.h */; }; CF2F46321095EE72007D33FA /* sa1.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061CC0526CCB900A80003 /* sa1.h */; };
CF2F46331095EE72007D33FA /* sar.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061CE0526CCB900A80003 /* sar.h */; }; CF2F46331095EE72007D33FA /* sar.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061CE0526CCB900A80003 /* sar.h */; };
CF2F46341095EE72007D33FA /* screenshot.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061D00526CCB900A80003 /* screenshot.h */; }; CF2F46341095EE72007D33FA /* screenshot.h in Headers */ = {isa = PBXBuildFile; fileRef = EAE061D00526CCB900A80003 /* screenshot.h */; };
@ -533,7 +533,7 @@
CF2F46A31095EE72007D33FA /* movie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EA813E9A066F50A5004F99B5 /* movie.cpp */; }; CF2F46A31095EE72007D33FA /* movie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EA813E9A066F50A5004F99B5 /* movie.cpp */; };
CF2F46A41095EE72007D33FA /* obc1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061C30526CCB900A80003 /* obc1.cpp */; }; CF2F46A41095EE72007D33FA /* obc1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061C30526CCB900A80003 /* obc1.cpp */; };
CF2F46A51095EE72007D33FA /* ppu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061C80526CCB900A80003 /* ppu.cpp */; }; CF2F46A51095EE72007D33FA /* ppu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061C80526CCB900A80003 /* ppu.cpp */; };
CF2F46A61095EE72007D33FA /* reader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EA809E9F08F8D7530072CDFB /* reader.cpp */; }; CF2F46A61095EE72007D33FA /* stream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EA809E9F08F8D7530072CDFB /* stream.cpp */; };
CF2F46A71095EE72007D33FA /* sa1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061CB0526CCB900A80003 /* sa1.cpp */; }; CF2F46A71095EE72007D33FA /* sa1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061CB0526CCB900A80003 /* sa1.cpp */; };
CF2F46A81095EE72007D33FA /* sa1cpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061CD0526CCB900A80003 /* sa1cpu.cpp */; }; CF2F46A81095EE72007D33FA /* sa1cpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061CD0526CCB900A80003 /* sa1cpu.cpp */; };
CF2F46A91095EE72007D33FA /* sdd1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061D10526CCB900A80003 /* sdd1.cpp */; }; CF2F46A91095EE72007D33FA /* sdd1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EAE061D10526CCB900A80003 /* sdd1.cpp */; };
@ -817,11 +817,11 @@
EA6E6C0E08F9734500CB3555 /* debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug.h; sourceTree = "<group>"; }; EA6E6C0E08F9734500CB3555 /* debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug.h; sourceTree = "<group>"; };
EA809E9308F8D6C40072CDFB /* controls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = controls.h; sourceTree = "<group>"; }; EA809E9308F8D6C40072CDFB /* controls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = controls.h; sourceTree = "<group>"; };
EA809E9508F8D6E00072CDFB /* language.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = language.h; sourceTree = "<group>"; }; EA809E9508F8D6E00072CDFB /* language.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = language.h; sourceTree = "<group>"; };
EA809E9708F8D70D0072CDFB /* reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = reader.h; sourceTree = "<group>"; }; EA809E9708F8D70D0072CDFB /* stream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stream.h; sourceTree = "<group>"; };
EA809E9908F8D7240072CDFB /* controls.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = controls.cpp; sourceTree = "<group>"; }; EA809E9908F8D7240072CDFB /* controls.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = controls.cpp; sourceTree = "<group>"; };
EA809E9B08F8D72C0072CDFB /* crosshairs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = crosshairs.cpp; sourceTree = "<group>"; }; EA809E9B08F8D72C0072CDFB /* crosshairs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = crosshairs.cpp; sourceTree = "<group>"; };
EA809E9D08F8D73A0072CDFB /* crosshairs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = crosshairs.h; sourceTree = "<group>"; }; EA809E9D08F8D73A0072CDFB /* crosshairs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = crosshairs.h; sourceTree = "<group>"; };
EA809E9F08F8D7530072CDFB /* reader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = reader.cpp; sourceTree = "<group>"; }; EA809E9F08F8D7530072CDFB /* stream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stream.cpp; sourceTree = "<group>"; };
EA809F9D08F8F2190072CDFB /* mac-controls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = "mac-controls.h"; sourceTree = "<group>"; }; EA809F9D08F8F2190072CDFB /* mac-controls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = "mac-controls.h"; sourceTree = "<group>"; };
EA809FA108F8F2420072CDFB /* mac-controls.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = "mac-controls.cpp"; sourceTree = "<group>"; }; EA809FA108F8F2420072CDFB /* mac-controls.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = "mac-controls.cpp"; sourceTree = "<group>"; };
EA813E86066F5076004F99B5 /* movie.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = movie.h; sourceTree = "<group>"; }; EA813E86066F5076004F99B5 /* movie.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = movie.h; sourceTree = "<group>"; };
@ -1179,7 +1179,7 @@
EAE061C60526CCB900A80003 /* pixform.h */, EAE061C60526CCB900A80003 /* pixform.h */,
EAE061C70526CCB900A80003 /* port.h */, EAE061C70526CCB900A80003 /* port.h */,
EAE061C90526CCB900A80003 /* ppu.h */, EAE061C90526CCB900A80003 /* ppu.h */,
EA809E9708F8D70D0072CDFB /* reader.h */, EA809E9708F8D70D0072CDFB /* stream.h */,
EAE061CC0526CCB900A80003 /* sa1.h */, EAE061CC0526CCB900A80003 /* sa1.h */,
EAE061CE0526CCB900A80003 /* sar.h */, EAE061CE0526CCB900A80003 /* sar.h */,
EAE061D00526CCB900A80003 /* screenshot.h */, EAE061D00526CCB900A80003 /* screenshot.h */,
@ -1222,7 +1222,7 @@
EA813E9A066F50A5004F99B5 /* movie.cpp */, EA813E9A066F50A5004F99B5 /* movie.cpp */,
EAE061C30526CCB900A80003 /* obc1.cpp */, EAE061C30526CCB900A80003 /* obc1.cpp */,
EAE061C80526CCB900A80003 /* ppu.cpp */, EAE061C80526CCB900A80003 /* ppu.cpp */,
EA809E9F08F8D7530072CDFB /* reader.cpp */, EA809E9F08F8D7530072CDFB /* stream.cpp */,
EAE061CB0526CCB900A80003 /* sa1.cpp */, EAE061CB0526CCB900A80003 /* sa1.cpp */,
EAE061CD0526CCB900A80003 /* sa1cpu.cpp */, EAE061CD0526CCB900A80003 /* sa1cpu.cpp */,
EAE061D10526CCB900A80003 /* sdd1.cpp */, EAE061D10526CCB900A80003 /* sdd1.cpp */,
@ -1384,7 +1384,7 @@
CF047D54109D0E0600FD0754 /* pixform.h in Headers */, CF047D54109D0E0600FD0754 /* pixform.h in Headers */,
CF047D55109D0E0600FD0754 /* port.h in Headers */, CF047D55109D0E0600FD0754 /* port.h in Headers */,
CF047D56109D0E0600FD0754 /* ppu.h in Headers */, CF047D56109D0E0600FD0754 /* ppu.h in Headers */,
CF047D57109D0E0600FD0754 /* reader.h in Headers */, CF047D57109D0E0600FD0754 /* stream.h in Headers */,
CF047D58109D0E0600FD0754 /* sa1.h in Headers */, CF047D58109D0E0600FD0754 /* sa1.h in Headers */,
CF047D59109D0E0600FD0754 /* sar.h in Headers */, CF047D59109D0E0600FD0754 /* sar.h in Headers */,
CF047D5A109D0E0600FD0754 /* screenshot.h in Headers */, CF047D5A109D0E0600FD0754 /* screenshot.h in Headers */,
@ -1503,7 +1503,7 @@
CF0566A90CF98E7E00C7877C /* pixform.h in Headers */, CF0566A90CF98E7E00C7877C /* pixform.h in Headers */,
CF0566AA0CF98E7E00C7877C /* port.h in Headers */, CF0566AA0CF98E7E00C7877C /* port.h in Headers */,
CF0566AB0CF98E7E00C7877C /* ppu.h in Headers */, CF0566AB0CF98E7E00C7877C /* ppu.h in Headers */,
CF0566AC0CF98E7E00C7877C /* reader.h in Headers */, CF0566AC0CF98E7E00C7877C /* stream.h in Headers */,
CF0566AD0CF98E7E00C7877C /* sa1.h in Headers */, CF0566AD0CF98E7E00C7877C /* sa1.h in Headers */,
CF0566AE0CF98E7E00C7877C /* sar.h in Headers */, CF0566AE0CF98E7E00C7877C /* sar.h in Headers */,
CF0566AF0CF98E7E00C7877C /* screenshot.h in Headers */, CF0566AF0CF98E7E00C7877C /* screenshot.h in Headers */,
@ -1622,7 +1622,7 @@
CF2F462E1095EE72007D33FA /* pixform.h in Headers */, CF2F462E1095EE72007D33FA /* pixform.h in Headers */,
CF2F462F1095EE72007D33FA /* port.h in Headers */, CF2F462F1095EE72007D33FA /* port.h in Headers */,
CF2F46301095EE72007D33FA /* ppu.h in Headers */, CF2F46301095EE72007D33FA /* ppu.h in Headers */,
CF2F46311095EE72007D33FA /* reader.h in Headers */, CF2F46311095EE72007D33FA /* stream.h in Headers */,
CF2F46321095EE72007D33FA /* sa1.h in Headers */, CF2F46321095EE72007D33FA /* sa1.h in Headers */,
CF2F46331095EE72007D33FA /* sar.h in Headers */, CF2F46331095EE72007D33FA /* sar.h in Headers */,
CF2F46341095EE72007D33FA /* screenshot.h in Headers */, CF2F46341095EE72007D33FA /* screenshot.h in Headers */,
@ -1938,7 +1938,7 @@
CF047DC9109D0E0600FD0754 /* movie.cpp in Sources */, CF047DC9109D0E0600FD0754 /* movie.cpp in Sources */,
CF047DCA109D0E0600FD0754 /* obc1.cpp in Sources */, CF047DCA109D0E0600FD0754 /* obc1.cpp in Sources */,
CF047DCB109D0E0600FD0754 /* ppu.cpp in Sources */, CF047DCB109D0E0600FD0754 /* ppu.cpp in Sources */,
CF047DCC109D0E0600FD0754 /* reader.cpp in Sources */, CF047DCC109D0E0600FD0754 /* stream.cpp in Sources */,
CF047DCD109D0E0600FD0754 /* sa1.cpp in Sources */, CF047DCD109D0E0600FD0754 /* sa1.cpp in Sources */,
CF047DCE109D0E0600FD0754 /* sa1cpu.cpp in Sources */, CF047DCE109D0E0600FD0754 /* sa1cpu.cpp in Sources */,
CF047DCF109D0E0600FD0754 /* sdd1.cpp in Sources */, CF047DCF109D0E0600FD0754 /* sdd1.cpp in Sources */,
@ -2033,7 +2033,7 @@
CF0567180CF98E7E00C7877C /* movie.cpp in Sources */, CF0567180CF98E7E00C7877C /* movie.cpp in Sources */,
CF0567190CF98E7E00C7877C /* obc1.cpp in Sources */, CF0567190CF98E7E00C7877C /* obc1.cpp in Sources */,
CF05671A0CF98E7E00C7877C /* ppu.cpp in Sources */, CF05671A0CF98E7E00C7877C /* ppu.cpp in Sources */,
CF05671B0CF98E7E00C7877C /* reader.cpp in Sources */, CF05671B0CF98E7E00C7877C /* stream.cpp in Sources */,
CF05671C0CF98E7E00C7877C /* sa1.cpp in Sources */, CF05671C0CF98E7E00C7877C /* sa1.cpp in Sources */,
CF05671D0CF98E7E00C7877C /* sa1cpu.cpp in Sources */, CF05671D0CF98E7E00C7877C /* sa1cpu.cpp in Sources */,
CF05671E0CF98E7E00C7877C /* sdd1.cpp in Sources */, CF05671E0CF98E7E00C7877C /* sdd1.cpp in Sources */,
@ -2128,7 +2128,7 @@
CF2F46A31095EE72007D33FA /* movie.cpp in Sources */, CF2F46A31095EE72007D33FA /* movie.cpp in Sources */,
CF2F46A41095EE72007D33FA /* obc1.cpp in Sources */, CF2F46A41095EE72007D33FA /* obc1.cpp in Sources */,
CF2F46A51095EE72007D33FA /* ppu.cpp in Sources */, CF2F46A51095EE72007D33FA /* ppu.cpp in Sources */,
CF2F46A61095EE72007D33FA /* reader.cpp in Sources */, CF2F46A61095EE72007D33FA /* stream.cpp in Sources */,
CF2F46A71095EE72007D33FA /* sa1.cpp in Sources */, CF2F46A71095EE72007D33FA /* sa1.cpp in Sources */,
CF2F46A81095EE72007D33FA /* sa1cpu.cpp in Sources */, CF2F46A81095EE72007D33FA /* sa1cpu.cpp in Sources */,
CF2F46A91095EE72007D33FA /* sdd1.cpp in Sources */, CF2F46A91095EE72007D33FA /* sdd1.cpp in Sources */,

View File

@ -197,7 +197,6 @@
#include "controls.h" #include "controls.h"
#include "cheats.h" #include "cheats.h"
#include "movie.h" #include "movie.h"
#include "reader.h"
#include "display.h" #include "display.h"
#ifndef SET_UI_COLOR #ifndef SET_UI_COLOR
@ -937,17 +936,17 @@ static void S9xDeinterleaveType1 (int, uint8 *);
static void S9xDeinterleaveType2 (int, uint8 *); static void S9xDeinterleaveType2 (int, uint8 *);
static void S9xDeinterleaveGD24 (int, uint8 *); static void S9xDeinterleaveGD24 (int, uint8 *);
static bool8 allASCII (uint8 *, int); static bool8 allASCII (uint8 *, int);
static bool8 is_SufamiTurbo_BIOS (uint8 *, uint32); static bool8 is_SufamiTurbo_BIOS (const uint8 *, uint32);
static bool8 is_SufamiTurbo_Cart (uint8 *, uint32); static bool8 is_SufamiTurbo_Cart (const uint8 *, uint32);
static bool8 is_SameGame_BIOS (uint8 *, uint32); static bool8 is_SameGame_BIOS (const uint8 *, uint32);
static bool8 is_SameGame_Add_On (uint8 *, uint32); static bool8 is_SameGame_Add_On (const uint8 *, uint32);
static bool8 is_GNEXT_BIOS (uint8 *, uint32); static bool8 is_GNEXT_BIOS (const uint8 *, uint32);
static bool8 is_GNEXT_Add_On (uint8 *, uint32); static bool8 is_GNEXT_Add_On (const uint8 *, uint32);
static uint32 caCRC32 (uint8 *, uint32, uint32 crc32 = 0xffffffff); static uint32 caCRC32 (uint8 *, uint32, uint32 crc32 = 0xffffffff);
static uint32 ReadUPSPointer (const uint8 *, unsigned &, unsigned); static uint32 ReadUPSPointer (const uint8 *, unsigned &, unsigned);
static bool8 ReadUPSPatch (Reader *, long, int32 &); static bool8 ReadUPSPatch (Stream *, long, int32 &);
static long ReadInt (Reader *, unsigned); static long ReadInt (Stream *, unsigned);
static bool8 ReadIPSPatch (Reader *, long, int32 &); static bool8 ReadIPSPatch (Stream *, long, int32 &);
#ifdef UNZIP_SUPPORT #ifdef UNZIP_SUPPORT
static int unzFindExtension (unzFile &, const char *, bool restart = TRUE, bool print = TRUE); static int unzFindExtension (unzFile &, const char *, bool restart = TRUE, bool print = TRUE);
#endif #endif
@ -1207,7 +1206,7 @@ static bool8 allASCII (uint8 *b, int size)
return (TRUE); return (TRUE);
} }
static bool8 is_SufamiTurbo_BIOS (uint8 *data, uint32 size) static bool8 is_SufamiTurbo_BIOS (const uint8 *data, uint32 size)
{ {
if (size == 0x40000 && if (size == 0x40000 &&
strncmp((char *) data, "BANDAI SFC-ADX", 14) == 0 && strncmp((char * ) (data + 0x10), "SFC-ADX BACKUP", 14) == 0) strncmp((char *) data, "BANDAI SFC-ADX", 14) == 0 && strncmp((char * ) (data + 0x10), "SFC-ADX BACKUP", 14) == 0)
@ -1216,7 +1215,7 @@ static bool8 is_SufamiTurbo_BIOS (uint8 *data, uint32 size)
return (FALSE); return (FALSE);
} }
static bool8 is_SufamiTurbo_Cart (uint8 *data, uint32 size) static bool8 is_SufamiTurbo_Cart (const uint8 *data, uint32 size)
{ {
if (size >= 0x80000 && size <= 0x100000 && if (size >= 0x80000 && size <= 0x100000 &&
strncmp((char *) data, "BANDAI SFC-ADX", 14) == 0 && strncmp((char * ) (data + 0x10), "SFC-ADX BACKUP", 14) != 0) strncmp((char *) data, "BANDAI SFC-ADX", 14) == 0 && strncmp((char * ) (data + 0x10), "SFC-ADX BACKUP", 14) != 0)
@ -1225,7 +1224,7 @@ static bool8 is_SufamiTurbo_Cart (uint8 *data, uint32 size)
return (FALSE); return (FALSE);
} }
static bool8 is_SameGame_BIOS (uint8 *data, uint32 size) static bool8 is_SameGame_BIOS (const uint8 *data, uint32 size)
{ {
if (size == 0x100000 && strncmp((char *) (data + 0xffc0), "Same Game Tsume Game", 20) == 0) if (size == 0x100000 && strncmp((char *) (data + 0xffc0), "Same Game Tsume Game", 20) == 0)
return (TRUE); return (TRUE);
@ -1233,7 +1232,7 @@ static bool8 is_SameGame_BIOS (uint8 *data, uint32 size)
return (FALSE); return (FALSE);
} }
static bool8 is_SameGame_Add_On (uint8 *data, uint32 size) static bool8 is_SameGame_Add_On (const uint8 *data, uint32 size)
{ {
if (size == 0x80000) if (size == 0x80000)
return (TRUE); return (TRUE);
@ -1241,7 +1240,7 @@ static bool8 is_SameGame_Add_On (uint8 *data, uint32 size)
return (FALSE); return (FALSE);
} }
static bool8 is_GNEXT_BIOS (uint8 *data, uint32 size) static bool8 is_GNEXT_BIOS (const uint8 *data, uint32 size)
{ {
if (size == 0x180000 && strncmp((char *) (data + 0x7fc0), "SFC SDGUNDAMGNEXT", 17) == 0) if (size == 0x180000 && strncmp((char *) (data + 0x7fc0), "SFC SDGUNDAMGNEXT", 17) == 0)
return (TRUE); return (TRUE);
@ -1249,7 +1248,7 @@ static bool8 is_GNEXT_BIOS (uint8 *data, uint32 size)
return (FALSE); return (FALSE);
} }
static bool8 is_GNEXT_Add_On (uint8 *data, uint32 size) static bool8 is_GNEXT_Add_On (const uint8 *data, uint32 size)
{ {
if (size == 0x80000) if (size == 0x80000)
return (TRUE); return (TRUE);
@ -1352,7 +1351,7 @@ int CMemory::ScoreLoROM (bool8 skip_header, int32 romoff)
return (score); return (score);
} }
uint32 CMemory::HeaderRemove (uint32 size, int32 &headerCount, uint8 *buf) uint32 CMemory::HeaderRemove (uint32 size, uint8 *buf)
{ {
uint32 calc_size = (size / 0x2000) * 0x2000; uint32 calc_size = (size / 0x2000) * 0x2000;
@ -1373,20 +1372,20 @@ uint32 CMemory::HeaderRemove (uint32 size, int32 &headerCount, uint8 *buf)
} }
memmove(buf, buf + 512, calc_size); memmove(buf, buf + 512, calc_size);
headerCount++; HeaderCount++;
size -= 512; size -= 512;
} }
return (size); return (size);
} }
uint32 CMemory::FileLoader (uint8 *buffer, const char *filename, int32 maxsize) uint32 CMemory::FileLoader (uint8 *buffer, const char *filename, uint32 maxsize)
{ {
// <- ROM size without header // <- ROM size without header
// ** Memory.HeaderCount // ** Memory.HeaderCount
// ** Memory.ROMFilename // ** Memory.ROMFilename
int32 totalSize = 0; uint32 totalSize = 0;
char fname[PATH_MAX + 1]; char fname[PATH_MAX + 1];
char drive[_MAX_DRIVE + 1], dir[_MAX_DIR + 1], name[_MAX_FNAME + 1], exts[_MAX_EXT + 1]; char drive[_MAX_DRIVE + 1], dir[_MAX_DIR + 1], name[_MAX_FNAME + 1], exts[_MAX_EXT + 1];
char *ext; char *ext;
@ -1415,7 +1414,7 @@ uint32 CMemory::FileLoader (uint8 *buffer, const char *filename, int32 maxsize)
case FILE_ZIP: case FILE_ZIP:
{ {
#ifdef UNZIP_SUPPORT #ifdef UNZIP_SUPPORT
if (!LoadZip(fname, &totalSize, &HeaderCount, buffer)) if (!LoadZip(fname, &totalSize, buffer))
{ {
S9xMessage(S9X_ERROR, S9X_ROM_INFO, "Invalid Zip archive."); S9xMessage(S9X_ERROR, S9X_ROM_INFO, "Invalid Zip archive.");
return (0); return (0);
@ -1439,7 +1438,7 @@ uint32 CMemory::FileLoader (uint8 *buffer, const char *filename, int32 maxsize)
return (0); return (0);
} }
totalSize = HeaderRemove(size, HeaderCount, buffer); totalSize = HeaderRemove(size, buffer);
strcpy(ROMFilename, fname); strcpy(ROMFilename, fname);
#else #else
@ -1468,7 +1467,7 @@ uint32 CMemory::FileLoader (uint8 *buffer, const char *filename, int32 maxsize)
size = READ_STREAM(ptr, maxsize + 0x200 - (ptr - buffer), fp); size = READ_STREAM(ptr, maxsize + 0x200 - (ptr - buffer), fp);
CLOSE_STREAM(fp); CLOSE_STREAM(fp);
size = HeaderRemove(size, HeaderCount, ptr); size = HeaderRemove(size, ptr);
totalSize += size; totalSize += size;
ptr += size; ptr += size;
@ -1511,31 +1510,55 @@ uint32 CMemory::FileLoader (uint8 *buffer, const char *filename, int32 maxsize)
return ((uint32) totalSize); return ((uint32) totalSize);
} }
bool8 CMemory::LoadROM (const char *filename) bool8 CMemory::LoadROMMem (const uint8 *source, uint32 sourceSize)
{ {
int retry_count = 0; if(!source || sourceSize > MAX_ROM_SIZE)
return FALSE;
if (!filename || !*filename) strcpy(ROMFilename,"MemoryROM");
return (FALSE);
do
{
memset(ROM,0, MAX_ROM_SIZE); memset(ROM,0, MAX_ROM_SIZE);
memset(&Multi, 0,sizeof(Multi)); memset(&Multi, 0,sizeof(Multi));
memcpy(ROM,source,sourceSize);
}
while(!LoadROMInt(sourceSize));
again: return TRUE;
Settings.DisplayColor = BUILD_PIXEL(31, 31, 31); }
SET_UI_COLOR(255, 255, 255);
CalculatedSize = 0; bool8 CMemory::LoadROM (const char *filename)
ExtendedFormat = NOPE; {
if(!filename || !*filename)
return FALSE;
int32 totalFileSize; int32 totalFileSize;
do
{
memset(ROM,0, MAX_ROM_SIZE);
memset(&Multi, 0,sizeof(Multi));
totalFileSize = FileLoader(ROM, filename, MAX_ROM_SIZE); totalFileSize = FileLoader(ROM, filename, MAX_ROM_SIZE);
if (!totalFileSize) if (!totalFileSize)
return (FALSE); return (FALSE);
if (!Settings.NoPatch) if (!Settings.NoPatch)
CheckForAnyPatch(filename, HeaderCount != 0, totalFileSize); CheckForAnyPatch(filename, HeaderCount != 0, totalFileSize);
}
while(!LoadROMInt(totalFileSize));
return TRUE;
}
bool8 CMemory::LoadROMInt (int32 ROMfillSize)
{
Settings.DisplayColor = BUILD_PIXEL(31, 31, 31);
SET_UI_COLOR(255, 255, 255);
CalculatedSize = 0;
ExtendedFormat = NOPE;
int hi_score, lo_score; int hi_score, lo_score;
@ -1546,15 +1569,15 @@ again:
((hi_score > lo_score && ScoreHiROM(TRUE) > hi_score) || ((hi_score > lo_score && ScoreHiROM(TRUE) > hi_score) ||
(hi_score <= lo_score && ScoreLoROM(TRUE) > lo_score))) (hi_score <= lo_score && ScoreLoROM(TRUE) > lo_score)))
{ {
memmove(ROM, ROM + 512, totalFileSize - 512); memmove(ROM, ROM + 512, ROMfillSize - 512);
totalFileSize -= 512; ROMfillSize -= 512;
S9xMessage(S9X_INFO, S9X_HEADER_WARNING, "Try 'force no-header' option if the game doesn't work"); S9xMessage(S9X_INFO, S9X_HEADER_WARNING, "Try 'force no-header' option if the game doesn't work");
// modifying ROM, so we need to rescore // modifying ROM, so we need to rescore
hi_score = ScoreHiROM(FALSE); hi_score = ScoreHiROM(FALSE);
lo_score = ScoreLoROM(FALSE); lo_score = ScoreLoROM(FALSE);
} }
CalculatedSize = (totalFileSize / 0x2000) * 0x2000; CalculatedSize = (ROMfillSize / 0x2000) * 0x2000;
if (CalculatedSize > 0x400000 && if (CalculatedSize > 0x400000 &&
(ROM[0x7fd5] + (ROM[0x7fd6] << 8)) != 0x3423 && // exclude SA-1 (ROM[0x7fd5] + (ROM[0x7fd6] << 8)) != 0x3423 && // exclude SA-1
@ -1571,7 +1594,7 @@ again:
((ROM[0xfffc] + (ROM[0xfffd] << 8)) < 0x8000)) ((ROM[0xfffc] + (ROM[0xfffd] << 8)) < 0x8000))
{ {
if (!Settings.ForceInterleaved && !Settings.ForceNotInterleaved) if (!Settings.ForceInterleaved && !Settings.ForceNotInterleaved)
S9xDeinterleaveType1(totalFileSize, ROM); S9xDeinterleaveType1(ROMfillSize, ROM);
} }
// CalculatedSize is now set, so rescore // CalculatedSize is now set, so rescore
@ -1698,15 +1721,11 @@ again:
if ((HiROM && (lo_score >= hi_score || hi_score < 0)) || if ((HiROM && (lo_score >= hi_score || hi_score < 0)) ||
(LoROM && (hi_score > lo_score || lo_score < 0))) (LoROM && (hi_score > lo_score || lo_score < 0)))
{
if (retry_count == 0)
{ {
S9xMessage(S9X_INFO, S9X_ROM_CONFUSING_FORMAT_INFO, "ROM lied about its type! Trying again."); S9xMessage(S9X_INFO, S9X_ROM_CONFUSING_FORMAT_INFO, "ROM lied about its type! Trying again.");
Settings.ForceNotInterleaved = TRUE; Settings.ForceNotInterleaved = TRUE;
Settings.ForceInterleaved = FALSE; Settings.ForceInterleaved = FALSE;
retry_count++; return (FALSE);
goto again;
}
} }
} }
@ -1726,9 +1745,9 @@ again:
} }
} }
if (strncmp(LastRomFilename, filename, PATH_MAX + 1)) if (strncmp(LastRomFilename, ROMFilename, PATH_MAX + 1))
{ {
strncpy(LastRomFilename, filename, PATH_MAX + 1); strncpy(LastRomFilename, ROMFilename, PATH_MAX + 1);
LastRomFilename[PATH_MAX] = 0; LastRomFilename[PATH_MAX] = 0;
} }
@ -1747,129 +1766,109 @@ again:
return (TRUE); return (TRUE);
} }
bool8 CMemory::LoadMultiCartMem (const uint8 *sourceA, uint32 sourceASize,
const uint8 *sourceB, uint32 sourceBSize,
const uint8 *bios, uint32 biosSize)
{
uint32 offset = 0;
ZeroMemory(ROM, MAX_ROM_SIZE);
ZeroMemory(&Multi, sizeof(Multi));
if(bios) {
if(!is_SufamiTurbo_BIOS(bios,biosSize))
return FALSE;
memcpy(ROM,bios,biosSize);
offset+=biosSize;
}
if(sourceA) {
memcpy(ROM + offset,sourceA,sourceASize);
Multi.cartOffsetA = offset;
Multi.cartSizeA = sourceASize;
offset += sourceASize;
strcpy(Multi.fileNameA,"MemCartA");
}
if(sourceB) {
memcpy(ROM + offset,sourceB,sourceBSize);
Multi.cartOffsetB = offset;
Multi.cartSizeB = sourceBSize;
offset += sourceBSize;
strcpy(Multi.fileNameB,"MemCartB");
}
return LoadMultiCartInt();
}
bool8 CMemory::LoadMultiCart (const char *cartA, const char *cartB) bool8 CMemory::LoadMultiCart (const char *cartA, const char *cartB)
{ {
bool8 r = TRUE; ZeroMemory(ROM, MAX_ROM_SIZE);
ZeroMemory(&Multi, sizeof(Multi));
memset(ROM, 0, MAX_ROM_SIZE);
memset(&Multi, 0, sizeof(Multi));
Settings.DisplayColor = BUILD_PIXEL(31, 31, 31); Settings.DisplayColor = BUILD_PIXEL(31, 31, 31);
SET_UI_COLOR(255, 255, 255); SET_UI_COLOR(255, 255, 255);
CalculatedSize = 0; if (cartB && cartB[0])
ExtendedFormat = NOPE; Multi.cartSizeB = FileLoader(ROM, cartB, MAX_ROM_SIZE);
if (Multi.cartSizeB) {
strcpy(Multi.fileNameB, cartB);
if(!Settings.NoPatch)
CheckForAnyPatch(cartB, HeaderCount != 0, Multi.cartSizeB);
Multi.cartOffsetB = 0x400000;
memcpy(ROM + Multi.cartOffsetB,ROM,Multi.cartSizeB);
}
if (cartA && cartA[0]) if (cartA && cartA[0])
Multi.cartSizeA = FileLoader(ROM, cartA, MAX_ROM_SIZE); Multi.cartSizeA = FileLoader(ROM, cartA, MAX_ROM_SIZE);
if (Multi.cartSizeA == 0) if (Multi.cartSizeA) {
{ strcpy(Multi.fileNameA, cartA);
if (cartB && cartB[0])
Multi.cartSizeB = FileLoader(ROM, cartB, MAX_ROM_SIZE); if(!Settings.NoPatch)
CheckForAnyPatch(cartA, HeaderCount != 0, Multi.cartSizeA);
} }
return LoadMultiCartInt();
}
bool8 CMemory::LoadMultiCartInt ()
{
bool8 r = TRUE;
CalculatedSize = 0;
ExtendedFormat = NOPE;
if (Multi.cartSizeA) if (Multi.cartSizeA)
{ {
if (is_SufamiTurbo_Cart(ROM, Multi.cartSizeA)) if (is_SufamiTurbo_Cart(ROM + Multi.cartOffsetA, Multi.cartSizeA))
Multi.cartType = 4; Multi.cartType = 4;
else else
if (is_SameGame_BIOS(ROM, Multi.cartSizeA)) if (is_SameGame_BIOS(ROM + Multi.cartOffsetA, Multi.cartSizeA))
Multi.cartType = 3; Multi.cartType = 3;
else else
if (is_GNEXT_BIOS(ROM, Multi.cartSizeA)) if (is_GNEXT_BIOS(ROM + Multi.cartOffsetA, Multi.cartSizeA))
Multi.cartType = 5; Multi.cartType = 5;
} }
else else
if (Multi.cartSizeB) if (Multi.cartSizeB)
{ {
if (is_SufamiTurbo_Cart(ROM, Multi.cartSizeB)) if (is_SufamiTurbo_Cart(ROM + Multi.cartOffsetB, Multi.cartSizeB))
Multi.cartType = 4; Multi.cartType = 4;
} }
else else
Multi.cartType = 4; // assuming BIOS only Multi.cartType = 4; // assuming BIOS only
switch (Multi.cartType)
{
case 4:
r = LoadSufamiTurbo(cartA, cartB);
break;
case 3:
r = LoadSameGame(cartA, cartB);
break;
case 5:
r = LoadGNEXT(cartA, cartB);
break;
default:
r = FALSE;
}
if (!r)
{
memset(&Multi, 0, sizeof(Multi));
return (FALSE);
}
memset(&SNESGameFixes, 0, sizeof(SNESGameFixes));
SNESGameFixes.SRAMInitialValue = 0x60;
S9xLoadCheatFile(S9xGetFilename(".cht", CHEAT_DIR));
InitROM();
S9xInitCheatData();
S9xApplyCheats();
S9xReset();
return (TRUE);
}
bool8 CMemory::LoadSufamiTurbo (const char *cartA, const char *cartB)
{
Multi.cartOffsetA = 0x100000;
Multi.cartOffsetB = 0x200000;
Multi.sramA = SRAM;
Multi.sramB = SRAM + 0x10000;
if(Multi.cartType == 4 && Multi.cartOffsetA == 0) { // try to load bios from file
Multi.cartOffsetA = 0x40000;
if(Multi.cartSizeA) if(Multi.cartSizeA)
{ memmove(ROM + Multi.cartOffsetA,ROM,Multi.cartOffsetB - Multi.cartOffsetA);
Multi.sramSizeA = 4; // ROM[0x37]? else // clear cart A so the bios can detect that it's not present
Multi.sramMaskA = Multi.sramSizeA ? ((1 << (Multi.sramSizeA + 3)) * 128 - 1) : 0; memset(ROM,0,Multi.cartOffsetB);
if (!Settings.NoPatch)
CheckForAnyPatch(cartA, HeaderCount != 0, Multi.cartSizeA);
strcpy(Multi.fileNameA, cartA);
memcpy(ROM + Multi.cartOffsetA, ROM, Multi.cartSizeA);
}
if (Multi.cartSizeA && !Multi.cartSizeB)
{
if (cartB && cartB[0])
Multi.cartSizeB = FileLoader(ROM, cartB, MAX_ROM_SIZE);
if (Multi.cartSizeB)
{
if (!is_SufamiTurbo_Cart(ROM, Multi.cartSizeB))
Multi.cartSizeB = 0;
}
}
if (Multi.cartSizeB)
{
Multi.sramSizeB = 4; // ROM[0x37]?
Multi.sramMaskB = Multi.sramSizeB ? ((1 << (Multi.sramSizeB + 3)) * 128 - 1) : 0;
if (!Settings.NoPatch)
CheckForAnyPatch(cartB, HeaderCount != 0, Multi.cartSizeB);
strcpy(Multi.fileNameB, cartB);
memcpy(ROM + Multi.cartOffsetB, ROM, Multi.cartSizeB);
}
FILE *fp; FILE *fp;
size_t size; size_t size;
@ -1890,13 +1889,76 @@ bool8 CMemory::LoadSufamiTurbo (const char *cartA, const char *cartB)
else else
return (FALSE); return (FALSE);
strcpy(ROMFilename, path);
}
switch (Multi.cartType)
{
case 4:
r = LoadSufamiTurbo();
break;
case 3:
r = LoadSameGame();
break;
case 5:
r = LoadGNEXT();
break;
default:
r = FALSE;
}
if (!r)
{
memset(&Multi, 0, sizeof(Multi));
return (FALSE);
}
if (Multi.cartSizeA) if (Multi.cartSizeA)
strcpy(ROMFilename, Multi.fileNameA); strcpy(ROMFilename, Multi.fileNameA);
else else
if (Multi.cartSizeB) if (Multi.cartSizeB)
strcpy(ROMFilename, Multi.fileNameB); strcpy(ROMFilename, Multi.fileNameB);
else
strcpy(ROMFilename, path); ZeroMemory(&SNESGameFixes, sizeof(SNESGameFixes));
SNESGameFixes.SRAMInitialValue = 0x60;
S9xLoadCheatFile(S9xGetFilename(".cht", CHEAT_DIR));
InitROM();
S9xInitCheatData();
S9xApplyCheats();
S9xReset();
return (TRUE);
}
bool8 CMemory::LoadSufamiTurbo ()
{
Multi.sramA = SRAM;
Multi.sramB = SRAM + 0x10000;
if (Multi.cartSizeA)
{
Multi.sramSizeA = 4; // ROM[0x37]?
Multi.sramMaskA = Multi.sramSizeA ? ((1 << (Multi.sramSizeA + 3)) * 128 - 1) : 0;
}
if (Multi.cartSizeB)
{
if (!is_SufamiTurbo_Cart(ROM + Multi.cartOffsetB, Multi.cartSizeB))
Multi.cartSizeB = 0;
}
if (Multi.cartSizeB)
{
Multi.sramSizeB = 4; // ROM[0x37]?
Multi.sramMaskB = Multi.sramSizeB ? ((1 << (Multi.sramSizeB + 3)) * 128 - 1) : 0;
}
LoROM = TRUE; LoROM = TRUE;
HiROM = FALSE; HiROM = FALSE;
@ -1905,10 +1967,8 @@ bool8 CMemory::LoadSufamiTurbo (const char *cartA, const char *cartB)
return (TRUE); return (TRUE);
} }
bool8 CMemory::LoadSameGame (const char *cartA, const char *cartB) bool8 CMemory::LoadSameGame ()
{ {
Multi.cartOffsetA = 0;
Multi.cartOffsetB = 0x200000;
Multi.sramA = SRAM; Multi.sramA = SRAM;
Multi.sramB = NULL; Multi.sramB = NULL;
@ -1917,24 +1977,12 @@ bool8 CMemory::LoadSameGame (const char *cartA, const char *cartB)
Multi.sramSizeB = 0; Multi.sramSizeB = 0;
Multi.sramMaskB = 0; Multi.sramMaskB = 0;
if (!Settings.NoPatch)
CheckForAnyPatch(cartA, HeaderCount != 0, Multi.cartSizeA);
strcpy(Multi.fileNameA, cartA);
if (cartB && cartB[0])
Multi.cartSizeB = FileLoader(ROM + Multi.cartOffsetB, cartB, MAX_ROM_SIZE - Multi.cartOffsetB);
if (Multi.cartSizeB) if (Multi.cartSizeB)
{ {
if (!is_SameGame_Add_On(ROM + Multi.cartOffsetB, Multi.cartSizeB)) if (!is_SameGame_Add_On(ROM + Multi.cartOffsetB, Multi.cartSizeB))
Multi.cartSizeB = 0; Multi.cartSizeB = 0;
else
strcpy(Multi.fileNameB, cartB);
} }
strcpy(ROMFilename, Multi.fileNameA);
LoROM = FALSE; LoROM = FALSE;
HiROM = TRUE; HiROM = TRUE;
CalculatedSize = Multi.cartSizeA; CalculatedSize = Multi.cartSizeA;
@ -1942,10 +1990,8 @@ bool8 CMemory::LoadSameGame (const char *cartA, const char *cartB)
return (TRUE); return (TRUE);
} }
bool8 CMemory::LoadGNEXT (const char *cartA, const char *cartB) bool8 CMemory::LoadGNEXT ()
{ {
Multi.cartOffsetA = 0;
Multi.cartOffsetB = 0x400000;
Multi.sramA = SRAM; Multi.sramA = SRAM;
Multi.sramB = NULL; Multi.sramB = NULL;
@ -1954,24 +2000,12 @@ bool8 CMemory::LoadGNEXT (const char *cartA, const char *cartB)
Multi.sramSizeB = 0; Multi.sramSizeB = 0;
Multi.sramMaskB = 0; Multi.sramMaskB = 0;
if (!Settings.NoPatch)
CheckForAnyPatch(cartA, HeaderCount != 0, Multi.cartSizeA);
strcpy(Multi.fileNameA, cartA);
if (cartB && cartB[0])
Multi.cartSizeB = FileLoader(ROM + Multi.cartOffsetB, cartB, MAX_ROM_SIZE - Multi.cartOffsetB);
if (Multi.cartSizeB) if (Multi.cartSizeB)
{ {
if (!is_GNEXT_Add_On(ROM + Multi.cartOffsetB, Multi.cartSizeB)) if (!is_GNEXT_Add_On(ROM + Multi.cartOffsetB, Multi.cartSizeB))
Multi.cartSizeB = 0; Multi.cartSizeB = 0;
else
strcpy(Multi.fileNameB, cartB);
} }
strcpy(ROMFilename, Multi.fileNameA);
LoROM = TRUE; LoROM = TRUE;
HiROM = FALSE; HiROM = FALSE;
CalculatedSize = Multi.cartSizeA; CalculatedSize = Multi.cartSizeA;
@ -3762,7 +3796,7 @@ static uint32 XPSdecode (const uint8 *data, unsigned &addr, unsigned size)
//no-header patching errors that result in IPS patches having a 50/50 chance of //no-header patching errors that result in IPS patches having a 50/50 chance of
//being applied correctly. //being applied correctly.
static bool8 ReadUPSPatch (Reader *r, long, int32 &rom_size) static bool8 ReadUPSPatch (Stream *r, long, int32 &rom_size)
{ {
//Reader lacks size() and rewind(), so we need to read in the file to get its size //Reader lacks size() and rewind(), so we need to read in the file to get its size
uint8 *data = new uint8[8 * 1024 * 1024]; //allocate a lot of memory, better safe than sorry ... uint8 *data = new uint8[8 * 1024 * 1024]; //allocate a lot of memory, better safe than sorry ...
@ -3844,7 +3878,7 @@ static bool8 ReadUPSPatch (Reader *r, long, int32 &rom_size)
// //
// logic taken from http://byuu.org/programming/bps and the accompanying source // logic taken from http://byuu.org/programming/bps and the accompanying source
// //
static bool8 ReadBPSPatch (Reader *r, long, int32 &rom_size) static bool8 ReadBPSPatch (Stream *r, long, int32 &rom_size)
{ {
uint8 *data = new uint8[8 * 1024 * 1024]; //allocate a lot of memory, better safe than sorry ... uint8 *data = new uint8[8 * 1024 * 1024]; //allocate a lot of memory, better safe than sorry ...
uint32 size = 0; uint32 size = 0;
@ -3935,7 +3969,7 @@ static bool8 ReadBPSPatch (Reader *r, long, int32 &rom_size)
} }
} }
static long ReadInt (Reader *r, unsigned nbytes) static long ReadInt (Stream *r, unsigned nbytes)
{ {
long v = 0; long v = 0;
@ -3950,7 +3984,7 @@ static long ReadInt (Reader *r, unsigned nbytes)
return (v); return (v);
} }
static bool8 ReadIPSPatch (Reader *r, long offset, int32 &rom_size) static bool8 ReadIPSPatch (Stream *r, long offset, int32 &rom_size)
{ {
const int32 IPS_EOF = 0x00454F46l; const int32 IPS_EOF = 0x00454F46l;
int32 ofs; int32 ofs;
@ -4069,7 +4103,7 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
if (Settings.NoPatch) if (Settings.NoPatch)
return; return;
STREAM patch_file = NULL; FSTREAM patch_file = NULL;
uint32 i; uint32 i;
long offset = header ? 512 : 0; long offset = header ? 512 : 0;
int ret; int ret;
@ -4082,12 +4116,12 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
// BPS // BPS
_makepath(fname, drive, dir, name, "bps"); _makepath(fname, drive, dir, name, "bps");
if ((patch_file = OPEN_STREAM(fname, "rb")) != NULL) if ((patch_file = OPEN_FSTREAM(fname, "rb")) != NULL)
{ {
printf("Using BPS patch %s", fname); printf("Using BPS patch %s", fname);
ret = ReadBPSPatch(new fReader(patch_file), 0, rom_size); ret = ReadBPSPatch(new fStream(patch_file), 0, rom_size);
CLOSE_STREAM(patch_file); CLOSE_FSTREAM(patch_file);
if (ret) if (ret)
{ {
@ -4109,7 +4143,7 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
{ {
printf(" in %s", rom_filename); printf(" in %s", rom_filename);
ret = ReadBPSPatch(new unzReader(file), offset, rom_size); ret = ReadBPSPatch(new unzStream(file), offset, rom_size);
unzCloseCurrentFile(file); unzCloseCurrentFile(file);
if (ret) if (ret)
@ -4123,12 +4157,12 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
n = S9xGetFilename(".bps", IPS_DIR); n = S9xGetFilename(".bps", IPS_DIR);
if ((patch_file = OPEN_STREAM(n, "rb")) != NULL) if ((patch_file = OPEN_FSTREAM(n, "rb")) != NULL)
{ {
printf("Using BPS patch %s", n); printf("Using BPS patch %s", n);
ret = ReadBPSPatch(new fReader(patch_file), 0, rom_size); ret = ReadBPSPatch(new fStream(patch_file), 0, rom_size);
CLOSE_STREAM(patch_file); CLOSE_FSTREAM(patch_file);
if (ret) if (ret)
{ {
@ -4143,12 +4177,12 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
_makepath(fname, drive, dir, name, "ups"); _makepath(fname, drive, dir, name, "ups");
if ((patch_file = OPEN_STREAM(fname, "rb")) != NULL) if ((patch_file = OPEN_FSTREAM(fname, "rb")) != NULL)
{ {
printf("Using UPS patch %s", fname); printf("Using UPS patch %s", fname);
ret = ReadUPSPatch(new fReader(patch_file), 0, rom_size); ret = ReadUPSPatch(new fStream(patch_file), 0, rom_size);
CLOSE_STREAM(patch_file); CLOSE_FSTREAM(patch_file);
if (ret) if (ret)
{ {
@ -4170,7 +4204,7 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
{ {
printf(" in %s", rom_filename); printf(" in %s", rom_filename);
ret = ReadUPSPatch(new unzReader(file), offset, rom_size); ret = ReadUPSPatch(new unzStream(file), offset, rom_size);
unzCloseCurrentFile(file); unzCloseCurrentFile(file);
if (ret) if (ret)
@ -4184,12 +4218,12 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
n = S9xGetFilename(".ups", IPS_DIR); n = S9xGetFilename(".ups", IPS_DIR);
if ((patch_file = OPEN_STREAM(n, "rb")) != NULL) if ((patch_file = OPEN_FSTREAM(n, "rb")) != NULL)
{ {
printf("Using UPS patch %s", n); printf("Using UPS patch %s", n);
ret = ReadUPSPatch(new fReader(patch_file), 0, rom_size); ret = ReadUPSPatch(new fStream(patch_file), 0, rom_size);
CLOSE_STREAM(patch_file); CLOSE_FSTREAM(patch_file);
if (ret) if (ret)
{ {
@ -4204,12 +4238,12 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
_makepath(fname, drive, dir, name, "ips"); _makepath(fname, drive, dir, name, "ips");
if ((patch_file = OPEN_STREAM(fname, "rb")) != NULL) if ((patch_file = OPEN_FSTREAM(fname, "rb")) != NULL)
{ {
printf("Using IPS patch %s", fname); printf("Using IPS patch %s", fname);
ret = ReadIPSPatch(new fReader(patch_file), offset, rom_size); ret = ReadIPSPatch(new fStream(patch_file), offset, rom_size);
CLOSE_STREAM(patch_file); CLOSE_FSTREAM(patch_file);
if (ret) if (ret)
{ {
@ -4230,13 +4264,13 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
snprintf(ips, 8, "%03d.ips", i); snprintf(ips, 8, "%03d.ips", i);
_makepath(fname, drive, dir, name, ips); _makepath(fname, drive, dir, name, ips);
if (!(patch_file = OPEN_STREAM(fname, "rb"))) if (!(patch_file = OPEN_FSTREAM(fname, "rb")))
break; break;
printf("Using IPS patch %s", fname); printf("Using IPS patch %s", fname);
ret = ReadIPSPatch(new fReader(patch_file), offset, rom_size); ret = ReadIPSPatch(new fStream(patch_file), offset, rom_size);
CLOSE_STREAM(patch_file); CLOSE_FSTREAM(patch_file);
if (ret) if (ret)
{ {
@ -4266,13 +4300,13 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
break; break;
_makepath(fname, drive, dir, name, ips); _makepath(fname, drive, dir, name, ips);
if (!(patch_file = OPEN_STREAM(fname, "rb"))) if (!(patch_file = OPEN_FSTREAM(fname, "rb")))
break; break;
printf("Using IPS patch %s", fname); printf("Using IPS patch %s", fname);
ret = ReadIPSPatch(new fReader(patch_file), offset, rom_size); ret = ReadIPSPatch(new fStream(patch_file), offset, rom_size);
CLOSE_STREAM(patch_file); CLOSE_FSTREAM(patch_file);
if (ret) if (ret)
{ {
@ -4300,13 +4334,13 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
snprintf(ips, 4, "ip%d", i); snprintf(ips, 4, "ip%d", i);
_makepath(fname, drive, dir, name, ips); _makepath(fname, drive, dir, name, ips);
if (!(patch_file = OPEN_STREAM(fname, "rb"))) if (!(patch_file = OPEN_FSTREAM(fname, "rb")))
break; break;
printf("Using IPS patch %s", fname); printf("Using IPS patch %s", fname);
ret = ReadIPSPatch(new fReader(patch_file), offset, rom_size); ret = ReadIPSPatch(new fStream(patch_file), offset, rom_size);
CLOSE_STREAM(patch_file); CLOSE_FSTREAM(patch_file);
if (ret) if (ret)
{ {
@ -4335,7 +4369,7 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
{ {
printf(" in %s", rom_filename); printf(" in %s", rom_filename);
ret = ReadIPSPatch(new unzReader(file), offset, rom_size); ret = ReadIPSPatch(new unzStream(file), offset, rom_size);
unzCloseCurrentFile(file); unzCloseCurrentFile(file);
if (ret) if (ret)
@ -4362,7 +4396,7 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
printf(" in %s", rom_filename); printf(" in %s", rom_filename);
ret = ReadIPSPatch(new unzReader(file), offset, rom_size); ret = ReadIPSPatch(new unzStream(file), offset, rom_size);
unzCloseCurrentFile(file); unzCloseCurrentFile(file);
if (ret) if (ret)
@ -4396,7 +4430,7 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
printf(" in %s", rom_filename); printf(" in %s", rom_filename);
ret = ReadIPSPatch(new unzReader(file), offset, rom_size); ret = ReadIPSPatch(new unzStream(file), offset, rom_size);
unzCloseCurrentFile(file); unzCloseCurrentFile(file);
if (ret) if (ret)
@ -4428,7 +4462,7 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
printf(" in %s", rom_filename); printf(" in %s", rom_filename);
ret = ReadIPSPatch(new unzReader(file), offset, rom_size); ret = ReadIPSPatch(new unzStream(file), offset, rom_size);
unzCloseCurrentFile(file); unzCloseCurrentFile(file);
if (ret) if (ret)
@ -4457,12 +4491,12 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
n = S9xGetFilename(".ips", IPS_DIR); n = S9xGetFilename(".ips", IPS_DIR);
if ((patch_file = OPEN_STREAM(n, "rb")) != NULL) if ((patch_file = OPEN_FSTREAM(n, "rb")) != NULL)
{ {
printf("Using IPS patch %s", n); printf("Using IPS patch %s", n);
ret = ReadIPSPatch(new fReader(patch_file), offset, rom_size); ret = ReadIPSPatch(new fStream(patch_file), offset, rom_size);
CLOSE_STREAM(patch_file); CLOSE_FSTREAM(patch_file);
if (ret) if (ret)
{ {
@ -4483,13 +4517,13 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
snprintf(ips, 9, ".%03d.ips", i); snprintf(ips, 9, ".%03d.ips", i);
n = S9xGetFilename(ips, IPS_DIR); n = S9xGetFilename(ips, IPS_DIR);
if (!(patch_file = OPEN_STREAM(n, "rb"))) if (!(patch_file = OPEN_FSTREAM(n, "rb")))
break; break;
printf("Using IPS patch %s", n); printf("Using IPS patch %s", n);
ret = ReadIPSPatch(new fReader(patch_file), offset, rom_size); ret = ReadIPSPatch(new fStream(patch_file), offset, rom_size);
CLOSE_STREAM(patch_file); CLOSE_FSTREAM(patch_file);
if (ret) if (ret)
{ {
@ -4519,13 +4553,13 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
break; break;
n = S9xGetFilename(ips, IPS_DIR); n = S9xGetFilename(ips, IPS_DIR);
if (!(patch_file = OPEN_STREAM(n, "rb"))) if (!(patch_file = OPEN_FSTREAM(n, "rb")))
break; break;
printf("Using IPS patch %s", n); printf("Using IPS patch %s", n);
ret = ReadIPSPatch(new fReader(patch_file), offset, rom_size); ret = ReadIPSPatch(new fStream(patch_file), offset, rom_size);
CLOSE_STREAM(patch_file); CLOSE_FSTREAM(patch_file);
if (ret) if (ret)
{ {
@ -4553,13 +4587,13 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
snprintf(ips, 5, ".ip%d", i); snprintf(ips, 5, ".ip%d", i);
n = S9xGetFilename(ips, IPS_DIR); n = S9xGetFilename(ips, IPS_DIR);
if (!(patch_file = OPEN_STREAM(n, "rb"))) if (!(patch_file = OPEN_FSTREAM(n, "rb")))
break; break;
printf("Using IPS patch %s", n); printf("Using IPS patch %s", n);
ret = ReadIPSPatch(new fReader(patch_file), offset, rom_size); ret = ReadIPSPatch(new fStream(patch_file), offset, rom_size);
CLOSE_STREAM(patch_file); CLOSE_FSTREAM(patch_file);
if (ret) if (ret)
{ {

View File

@ -271,13 +271,18 @@ struct CMemory
int ScoreHiROM (bool8, int32 romoff = 0); int ScoreHiROM (bool8, int32 romoff = 0);
int ScoreLoROM (bool8, int32 romoff = 0); int ScoreLoROM (bool8, int32 romoff = 0);
uint32 HeaderRemove (uint32, int32 &, uint8 *); uint32 HeaderRemove (uint32, uint8 *);
uint32 FileLoader (uint8 *, const char *, int32); uint32 FileLoader (uint8 *, const char *, uint32);
uint32 MemLoader (uint8 *, const char*, uint32);
bool8 LoadROMMem (const uint8 *, uint32);
bool8 LoadROM (const char *); bool8 LoadROM (const char *);
bool8 LoadROMInt (int32);
bool8 LoadMultiCartMem (const uint8 *, uint32, const uint8 *, uint32, const uint8 *, uint32);
bool8 LoadMultiCart (const char *, const char *); bool8 LoadMultiCart (const char *, const char *);
bool8 LoadSufamiTurbo (const char *, const char *); bool8 LoadMultiCartInt ();
bool8 LoadSameGame (const char *, const char *); bool8 LoadSufamiTurbo ();
bool8 LoadGNEXT (const char *, const char *); bool8 LoadSameGame ();
bool8 LoadGNEXT ();
bool8 LoadSRAM (const char *); bool8 LoadSRAM (const char *);
bool8 SaveSRAM (const char *); bool8 SaveSRAM (const char *);
void ClearSRAM (bool8 onlyNonSavedSRAM = 0); void ClearSRAM (bool8 onlyNonSavedSRAM = 0);
@ -361,7 +366,7 @@ extern CMemory Memory;
extern SMulti Multi; extern SMulti Multi;
void S9xAutoSaveSRAM (void); void S9xAutoSaveSRAM (void);
bool8 LoadZip(const char *, int32 *, int32 *, uint8 *); bool8 LoadZip(const char *, uint32 *, uint8 *);
enum s9xwrap_t enum s9xwrap_t
{ {

View File

@ -189,6 +189,8 @@
#include <memory.h> #include <memory.h>
#include <sys/types.h> #include <sys/types.h>
#include "snes9x.h"
#ifdef __WIN32__ #ifdef __WIN32__
#include <winsock.h> #include <winsock.h>
#include <process.h> #include <process.h>
@ -222,7 +224,6 @@
#include <semaphore.h> #include <semaphore.h>
#endif #endif
#include "snes9x.h"
#include "memmap.h" #include "memmap.h"
#include "netplay.h" #include "netplay.h"
#include "snapshot.h" #include "snapshot.h"

30
port.h
View File

@ -202,7 +202,9 @@
#define RIGHTSHIFT_int8_IS_SAR #define RIGHTSHIFT_int8_IS_SAR
#define RIGHTSHIFT_int16_IS_SAR #define RIGHTSHIFT_int16_IS_SAR
#define RIGHTSHIFT_int32_IS_SAR #define RIGHTSHIFT_int32_IS_SAR
#ifndef __WIN32_LIBSNES__
#define SNES_JOY_READ_CALLBACKS #define SNES_JOY_READ_CALLBACKS
#endif //__WIN32_LIBSNES__
#endif #endif
#ifdef __MACOSX__ #ifdef __MACOSX__
@ -227,27 +229,12 @@ typedef uint64_t uint64;
#else // HAVE_STDINT_H #else // HAVE_STDINT_H
#ifdef __WIN32__ #ifdef __WIN32__
typedef intptr_t pint; typedef intptr_t pint;
#else // __WIN32__
#ifdef PTR_NOT_INT
typedef long pint;
#else
typedef int pint;
#endif
#endif // __WIN32__
#ifdef __WIN32__
#ifdef __BORLANDC__
#include <systypes.h>
#else
typedef signed char int8; typedef signed char int8;
typedef unsigned char uint8; typedef unsigned char uint8;
typedef signed short int16; typedef signed short int16;
typedef unsigned short uint16; typedef unsigned short uint16;
#ifndef WSAAP
// winsock2.h typedefs int32 as well
typedef signed int int32; typedef signed int int32;
#endif
typedef unsigned int uint32; typedef unsigned int uint32;
#endif
typedef signed __int64 int64; typedef signed __int64 int64;
typedef unsigned __int64 uint64; typedef unsigned __int64 uint64;
typedef int8 int8_t; typedef int8 int8_t;
@ -272,6 +259,11 @@ __extension__
#endif #endif
typedef long long int64; typedef long long int64;
typedef unsigned long long uint64; typedef unsigned long long uint64;
#ifdef PTR_NOT_INT
typedef long pint;
#else // __PTR_NOT_INT
typedef int pint;
#endif // __PTR_NOT_INT
#endif // __WIN32__ #endif // __WIN32__
#endif // HAVE_STDINT_H #endif // HAVE_STDINT_H
#endif // snes9x_types_defined #endif // snes9x_types_defined
@ -305,15 +297,19 @@ typedef unsigned long long uint64;
void _splitpath (const char *, char *, char *, char *, char *); void _splitpath (const char *, char *, char *, char *, char *);
void _makepath (char *, const char *, const char *, const char *, const char *); void _makepath (char *, const char *, const char *, const char *, const char *);
#define S9xDisplayString DisplayStringFromBottom #define S9xDisplayString DisplayStringFromBottom
#else #else // __WIN32__
#define snprintf _snprintf #define snprintf _snprintf
#define strcasecmp stricmp #define strcasecmp stricmp
#define strncasecmp strnicmp #define strncasecmp strnicmp
#ifndef __WIN32_LIBSNES__
void WinDisplayStringFromBottom(const char *string, int linesFromBottom, int pixelsFromLeft, bool allowWrap); void WinDisplayStringFromBottom(const char *string, int linesFromBottom, int pixelsFromLeft, bool allowWrap);
#define S9xDisplayString WinDisplayStringFromBottom #define S9xDisplayString WinDisplayStringFromBottom
void SetInfoDlgColor(unsigned char, unsigned char, unsigned char); void SetInfoDlgColor(unsigned char, unsigned char, unsigned char);
#define SET_UI_COLOR(r,g,b) SetInfoDlgColor(r,g,b) #define SET_UI_COLOR(r,g,b) SetInfoDlgColor(r,g,b)
#endif #else // __WIN32_LIBSNES__
#define S9xDisplayString DisplayStringFromBottom
#endif // __WIN32_LIBSNES__
#endif // __WIN32__
#ifdef __DJGPP #ifdef __DJGPP
#define SLASH_STR "\\" #define SLASH_STR "\\"

View File

@ -190,6 +190,8 @@
#include <strings.h> #include <strings.h>
#endif #endif
#include "snes9x.h"
#ifdef __WIN32__ #ifdef __WIN32__
#include <winsock.h> #include <winsock.h>
@ -219,7 +221,6 @@
#endif // !__WIN32__ #endif // !__WIN32__
#include "snes9x.h"
#include "memmap.h" #include "memmap.h"
#include "snapshot.h" #include "snapshot.h"
#include "netplay.h" #include "netplay.h"

View File

@ -1169,6 +1169,21 @@ void S9xResetSaveTimer (bool8 dontsave)
t = time(NULL); t = time(NULL);
} }
uint32 S9xFreezeSize()
{
nulStream stream;
S9xFreezeToStream(&stream);
return stream.size();
}
bool8 S9xFreezeGameMem (uint8 *buf, uint32 bufSize)
{
memStream mStream(buf, bufSize);
S9xFreezeToStream(&mStream);
return (TRUE);
}
bool8 S9xFreezeGame (const char *filename) bool8 S9xFreezeGame (const char *filename)
{ {
STREAM stream = NULL; STREAM stream = NULL;
@ -1194,6 +1209,14 @@ bool8 S9xFreezeGame (const char *filename)
return (FALSE); return (FALSE);
} }
int S9xUnfreezeGameMem (const uint8 *buf, uint32 bufSize)
{
memStream stream(buf, bufSize);
int result = S9xUnfreezeFromStream(&stream);
return result;
}
bool8 S9xUnfreezeGame (const char *filename) bool8 S9xUnfreezeGame (const char *filename)
{ {
STREAM stream = NULL; STREAM stream = NULL;

View File

@ -194,7 +194,10 @@
void S9xResetSaveTimer (bool8); void S9xResetSaveTimer (bool8);
bool8 S9xFreezeGame (const char *); bool8 S9xFreezeGame (const char *);
uint32 S9xFreezeSize (void);
bool8 S9xFreezeGameMem (uint8 *,uint32);
bool8 S9xUnfreezeGame (const char *); bool8 S9xUnfreezeGame (const char *);
int S9xUnfreezeGameMem (const uint8 *,uint32);
void S9xFreezeToStream (STREAM); void S9xFreezeToStream (STREAM);
int S9xUnfreezeFromStream (STREAM); int S9xUnfreezeFromStream (STREAM);

View File

@ -315,14 +315,14 @@ static void parse_crosshair_spec (enum crosscontrols ctl, const char *spec)
static bool try_load_config_file (const char *fname, ConfigFile &conf) static bool try_load_config_file (const char *fname, ConfigFile &conf)
{ {
STREAM fp; FSTREAM fp;
fp = OPEN_STREAM(fname, "r"); fp = OPEN_FSTREAM(fname, "r");
if (fp) if (fp)
{ {
fprintf(stdout, "Reading config file %s.\n", fname); fprintf(stdout, "Reading config file %s.\n", fname);
conf.LoadFile(new fReader(fp)); conf.LoadFile(new fStream(fp));
CLOSE_STREAM(fp); CLOSE_FSTREAM(fp);
return (true); return (true);
} }

View File

@ -189,29 +189,42 @@
#ifdef ZLIB #ifdef ZLIB
#include <zlib.h> #include <zlib.h>
#define STREAM gzFile #define FSTREAM gzFile
#define READ_STREAM(p, l, s) gzread(s, p, l) #define READ_FSTREAM(p, l, s) gzread(s, p, l)
#define WRITE_STREAM(p, l, s) gzwrite(s, p, l) #define WRITE_FSTREAM(p, l, s) gzwrite(s, p, l)
#define GETS_STREAM(p, l, s) gzgets(s, p, l) #define GETS_FSTREAM(p, l, s) gzgets(s, p, l)
#define GETC_STREAM(s) gzgetc(s) #define GETC_FSTREAM(s) gzgetc(s)
#define OPEN_STREAM(f, m) gzopen(f, m) #define OPEN_FSTREAM(f, m) gzopen(f, m)
#define REOPEN_STREAM(f, m) gzdopen(f, m) #define REOPEN_FSTREAM(f, m) gzdopen(f, m)
#define FIND_STREAM(f) gztell(f) #define FIND_FSTREAM(f) gztell(f)
#define REVERT_STREAM(f, o, s) gzseek(f, o, s) #define REVERT_FSTREAM(s, o, p) gzseek(s, o, p)
#define CLOSE_STREAM(s) gzclose(s) #define CLOSE_FSTREAM(s) gzclose(s)
#else #else
#define STREAM FILE * #define FSTREAM FILE *
#define READ_STREAM(p, l, s) fread(p, 1, l, s) #define READ_FSTREAM(p, l, s) fread(p, 1, l, s)
#define WRITE_STREAM(p, l, s) fwrite(p, 1, l, s) #define WRITE_FSTREAM(p, l, s) fwrite(p, 1, l, s)
#define GETS_STREAM(p, l, s) fgets(p, l, s) #define GETS_FSTREAM(p, l, s) fgets(p, l, s)
#define GETC_STREAM(s) fgetc(s) #define GETC_FSTREAM(s) fgetc(s)
#define OPEN_STREAM(f, m) fopen(f, m) #define OPEN_FSTREAM(f, m) fopen(f, m)
#define REOPEN_STREAM(f, m) fdopen(f, m) #define REOPEN_FSTREAM(f, m) fdopen(f, m)
#define FIND_STREAM(f) ftell(f) #define FIND_FSTREAM(s) ftell(s)
#define REVERT_STREAM(f, o, s) fseek(f, o, s) #define REVERT_FSTREAM(s, o, p) fseek(s, o, p)
#define CLOSE_STREAM(s) fclose(s) #define CLOSE_FSTREAM(s) fclose(s)
#endif #endif
#include "stream.h"
#define STREAM Stream *
#define READ_STREAM(p, l, s) s->read(p,l)
#define WRITE_STREAM(p, l, s) s->write(p,l)
#define GETS_STREAM(p, l, s) s->gets(p,l)
#define GETC_STREAM(s) s->get_char()
#define OPEN_STREAM(f, m) openStreamFromFSTREAM(f, m)
#define REOPEN_STREAM(f, m) reopenStreamFromFd(f, m)
#define FIND_STREAM(s) s->pos()
#define REVERT_STREAM(s, o, p) s->revert(p, o)
#define CLOSE_STREAM(s) s->closeStream()
#define SNES_WIDTH 256 #define SNES_WIDTH 256
#define SNES_HEIGHT 224 #define SNES_HEIGHT 224
#define SNES_HEIGHT_EXTENDED 239 #define SNES_HEIGHT_EXTENDED 239

View File

@ -183,24 +183,24 @@
#include "unzip.h" #include "unzip.h"
#endif #endif
#include "snes9x.h" #include "snes9x.h"
#include "reader.h" #include "stream.h"
// Generic constructor/destructor // Generic constructor/destructor
Reader::Reader (void) Stream::Stream (void)
{ {
return; return;
} }
Reader::~Reader (void) Stream::~Stream (void)
{ {
return; return;
} }
// Generic getline function, based on gets. Reimlpement if you can do better. // Generic getline function, based on gets. Reimlpement if you can do better.
char * Reader::getline (void) char * Stream::getline (void)
{ {
bool eof; bool eof;
std::string ret; std::string ret;
@ -212,7 +212,7 @@ char * Reader::getline (void)
return (strdup(ret.c_str())); return (strdup(ret.c_str()));
} }
std::string Reader::getline (bool &eof) std::string Stream::getline (bool &eof)
{ {
char buf[1024]; char buf[1024];
std::string ret; std::string ret;
@ -235,50 +235,80 @@ std::string Reader::getline (bool &eof)
return (ret); return (ret);
} }
// snes9x.h STREAM reader // snes9x.h FSTREAM Stream
fReader::fReader (STREAM f) fStream::fStream (FSTREAM f)
{ {
fp = f; fp = f;
} }
fReader::~fReader (void) fStream::~fStream (void)
{ {
return; return;
} }
int fReader::get_char (void) int fStream::get_char (void)
{ {
return (GETC_STREAM(fp)); return (GETC_FSTREAM(fp));
} }
char * fReader::gets (char *buf, size_t len) char * fStream::gets (char *buf, size_t len)
{ {
return (GETS_STREAM(buf, len, fp)); return (GETS_FSTREAM(buf, len, fp));
} }
size_t fReader::read (char *buf, size_t len) size_t fStream::read (void *buf, size_t len)
{ {
return (READ_STREAM(buf, len, fp)); return (READ_FSTREAM(buf, len, fp));
} }
// unzip reader size_t fStream::write (void *buf, size_t len)
{
return (WRITE_FSTREAM(buf, len, fp));
}
size_t fStream::pos (void)
{
return (FIND_FSTREAM(fp));
}
size_t fStream::size (void)
{
size_t sz;
REVERT_FSTREAM(fp,0L,SEEK_END);
sz = FIND_FSTREAM(fp);
REVERT_FSTREAM(fp,0L,SEEK_SET);
return sz;
}
int fStream::revert (size_t from, size_t offset)
{
return (REVERT_FSTREAM(fp, from, offset));
}
void fStream::closeStream()
{
CLOSE_FSTREAM(fp);
delete this;
}
// unzip Stream
#ifdef UNZIP_SUPPORT #ifdef UNZIP_SUPPORT
unzReader::unzReader (unzFile &v) unzStream::unzStream (unzFile &v)
{ {
file = v; file = v;
head = NULL; head = NULL;
numbytes = 0; numbytes = 0;
} }
unzReader::~unzReader (void) unzStream::~unzStream (void)
{ {
return; return;
} }
int unzReader::get_char (void) int unzStream::get_char (void)
{ {
unsigned char c; unsigned char c;
@ -297,7 +327,7 @@ int unzReader::get_char (void)
return ((int) c); return ((int) c);
} }
char * unzReader::gets (char *buf, size_t len) char * unzStream::gets (char *buf, size_t len)
{ {
size_t i; size_t i;
int c; int c;
@ -322,7 +352,7 @@ char * unzReader::gets (char *buf, size_t len)
return (buf); return (buf);
} }
size_t unzReader::read (char *buf, size_t len) size_t unzStream::read (void *buf, size_t len)
{ {
if (len == 0) if (len == 0)
return (len); return (len);
@ -344,11 +374,219 @@ size_t unzReader::read (char *buf, size_t len)
numbytes = 0; numbytes = 0;
} }
int l = unzReadCurrentFile(file, buf + numread, len - numread); int l = unzReadCurrentFile(file, (uint8 *)buf + numread, len - numread);
if (l > 0) if (l > 0)
numread += l; numread += l;
return (numread); return (numread);
} }
// not supported
size_t unzStream::write (void *buf, size_t len)
{
return (0);
}
size_t unzStream::pos (void)
{
return (unztell(file));
}
size_t unzStream::size (void)
{
unz_file_info info;
unzGetCurrentFileInfo(file,&info,NULL,0,NULL,0,NULL,0);
return info.uncompressed_size;
}
// not supported
int unzStream::revert (size_t from, size_t offset)
{
return -1;
}
void unzStream::closeStream()
{
unzCloseCurrentFile(file);
delete this;
}
#endif #endif
// memory Stream
memStream::memStream (uint8 *source, size_t sourceSize)
{
mem = head = source;
msize = remaining = sourceSize;
readonly = false;
}
memStream::memStream (const uint8 *source, size_t sourceSize)
{
mem = head = const_cast<uint8 *>(source);
msize = remaining = sourceSize;
readonly = true;
}
memStream::~memStream (void)
{
return;
}
int memStream::get_char (void)
{
if(!remaining)
return EOF;
remaining--;
return *head++;
}
char * memStream::gets (char *buf, size_t len)
{
size_t i;
int c;
for (i = 0; i < len - 1; i++)
{
c = get_char();
if (c == EOF)
{
if (i == 0)
return (NULL);
break;
}
buf[i] = (char) c;
if (buf[i] == '\n')
break;
}
buf[i] = '\0';
return (buf);
}
size_t memStream::read (void *buf, size_t len)
{
size_t bytes = len < remaining ? len : remaining;
memcpy(buf,head,bytes);
head += bytes;
remaining -= bytes;
return bytes;
}
size_t memStream::write (void *buf, size_t len)
{
if(readonly)
return 0;
size_t bytes = len < remaining ? len : remaining;
memcpy(head,buf,bytes);
head += bytes;
remaining -= bytes;
return bytes;
}
size_t memStream::pos (void)
{
return msize - remaining;
}
size_t memStream::size (void)
{
return msize;
}
int memStream::revert (size_t from, size_t offset)
{
size_t pos = from + offset;
if(pos > msize)
return -1;
head = mem + pos;
remaining = msize - pos;
return 0;
}
void memStream::closeStream()
{
delete [] mem;
delete this;
}
// dummy Stream
nulStream::nulStream (void)
{
bytes_written = 0;
}
nulStream::~nulStream (void)
{
return;
}
int nulStream::get_char (void)
{
return 0;
}
char * nulStream::gets (char *buf, size_t len)
{
*buf = '\0';
return NULL;
}
size_t nulStream::read (void *buf, size_t len)
{
return 0;
}
size_t nulStream::write (void *buf, size_t len)
{
bytes_written += len;
return len;
}
size_t nulStream::pos (void)
{
return 0;
}
size_t nulStream::size (void)
{
return bytes_written;
}
int nulStream::revert (size_t from, size_t offset)
{
bytes_written = from + offset;
return 0;
}
void nulStream::closeStream()
{
delete this;
}
Stream *openStreamFromFSTREAM(const char* filename, const char* mode)
{
FSTREAM f = OPEN_FSTREAM(filename,mode);
if(!f)
return NULL;
return new fStream(f);
}
Stream *reopenStreamFromFd(int fd, const char* mode)
{
FSTREAM f = REOPEN_FSTREAM(fd,mode);
if(!f)
return NULL;
return new fStream(f);
}

View File

@ -176,46 +176,65 @@
***********************************************************************************/ ***********************************************************************************/
#ifndef _READER_H_ #ifndef _STREAM_H_
#define _READER_H_ #define _STREAM_H_
class Reader #include <string>
class Stream
{ {
public: public:
Reader (void); Stream (void);
virtual ~Reader (void); virtual ~Stream (void);
virtual int get_char (void) = 0; virtual int get_char (void) = 0;
virtual char * gets (char *, size_t) = 0; virtual char * gets (char *, size_t) = 0;
virtual char * getline (void); // free() when done virtual char * getline (void); // free() when done
virtual std::string getline (bool &); virtual std::string getline (bool &);
virtual size_t read (char *, size_t) = 0; virtual size_t read (void *, size_t) = 0;
virtual size_t write (void *, size_t) = 0;
virtual size_t pos (void) = 0;
virtual size_t size (void) = 0;
virtual int revert (size_t from, size_t offset) = 0;
virtual void closeStream() = 0;
}; };
class fReader : public Reader class fStream : public Stream
{ {
public: public:
fReader (STREAM); fStream (FSTREAM);
virtual ~fReader (void); virtual ~fStream (void);
virtual int get_char (void); virtual int get_char (void);
virtual char * gets (char *, size_t); virtual char * gets (char *, size_t);
virtual size_t read (char *, size_t); virtual size_t read (void *, size_t);
virtual size_t write (void *, size_t);
virtual size_t pos (void);
virtual size_t size (void);
virtual int revert (size_t from, size_t offset);
virtual void closeStream();
private: private:
STREAM fp; FSTREAM fp;
}; };
#ifdef UNZIP_SUPPORT #ifdef UNZIP_SUPPORT
#include "unzip.h"
#define unz_BUFFSIZ 1024 #define unz_BUFFSIZ 1024
class unzReader : public Reader class unzStream : public Stream
{ {
public: public:
unzReader (unzFile &); unzStream (unzFile &);
virtual ~unzReader (void); virtual ~unzStream (void);
virtual int get_char (void); virtual int get_char (void);
virtual char * gets (char *, size_t); virtual char * gets (char *, size_t);
virtual size_t read (char *, size_t); virtual size_t read (void *, size_t);
virtual size_t write (void *, size_t);
virtual size_t pos (void);
virtual size_t size (void);
virtual int revert (size_t from, size_t offset);
virtual void closeStream();
private: private:
unzFile file; unzFile file;
@ -226,4 +245,52 @@ class unzReader : public Reader
#endif #endif
class memStream : public Stream
{
public:
memStream (uint8 *,size_t);
memStream (const uint8 *,size_t);
virtual ~memStream (void);
virtual int get_char (void);
virtual char * gets (char *, size_t);
virtual size_t read (void *, size_t);
virtual size_t write (void *, size_t);
virtual size_t pos (void);
virtual size_t size (void);
virtual int revert (size_t from, size_t offset);
virtual void closeStream();
private:
uint8 *mem;
size_t msize;
size_t remaining;
uint8 *head;
bool readonly;
};
/* dummy stream that always reads 0 and writes nowhere
but counts bytes written
*/
class nulStream : public Stream
{
public:
nulStream (void);
virtual ~nulStream (void);
virtual int get_char (void);
virtual char * gets (char *, size_t);
virtual size_t read (void *, size_t);
virtual size_t write (void *, size_t);
virtual size_t pos (void);
virtual size_t size (void);
virtual int revert (size_t from, size_t offset);
virtual void closeStream();
private:
size_t bytes_written;
};
Stream *openStreamFromFSTREAM(const char* filename, const char* mode);
Stream *reopenStreamFromFd(int fd, const char* mode);
#endif #endif

View File

@ -7,7 +7,7 @@
OS = `uname -s -r -m|sed \"s/ /-/g\"|tr \"[A-Z]\" \"[a-z]\"|tr \"/()\" \"___\"` OS = `uname -s -r -m|sed \"s/ /-/g\"|tr \"[A-Z]\" \"[a-z]\"|tr \"/()\" \"___\"`
BUILDDIR = . 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 ../reader.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 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 ../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 unix.o x11.o
DEFS = -DMITSHM DEFS = -DMITSHM
ifdef S9XDEBUGGER ifdef S9XDEBUGGER

View File

@ -2082,42 +2082,6 @@
/> />
</FileConfiguration> </FileConfiguration>
</File> </File>
<File
RelativePath="..\reader.cpp"
>
</File>
<File
RelativePath="..\reader.h"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCustomBuildTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCustomBuildTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Unicode|Win32"
>
<Tool
Name="VCCustomBuildTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Unicode|x64"
>
<Tool
Name="VCCustomBuildTool"
/>
</FileConfiguration>
</File>
<File <File
RelativePath="..\sa1.cpp" RelativePath="..\sa1.cpp"
> >
@ -2902,6 +2866,42 @@
/> />
</FileConfiguration> </FileConfiguration>
</File> </File>
<File
RelativePath="..\stream.cpp"
>
</File>
<File
RelativePath="..\stream.h"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCustomBuildTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCustomBuildTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Unicode|Win32"
>
<Tool
Name="VCCustomBuildTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Unicode|x64"
>
<Tool
Name="VCCustomBuildTool"
/>
</FileConfiguration>
</File>
<File <File
RelativePath="..\tile.cpp" RelativePath="..\tile.cpp"
> >