Take out some unneeded stuff

This commit is contained in:
TwinAphex51224 2012-09-24 05:50:17 +02:00
parent 9621b27e53
commit 7c0f21e8e3
5 changed files with 50 additions and 752 deletions

View File

@ -28,8 +28,8 @@ else ifeq ($(platform), osx)
FLAGS += -pthread -DHAVE_MKDIR FLAGS += -pthread -DHAVE_MKDIR
else else
TARGET := retro.dll TARGET := retro.dll
CC = gcc CC = i686-pc-mingw32-gcc
CXX = g++ CXX = i686-pc-mingw32-g++
SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T
LDFLAGS += -static-libgcc -static-libstdc++ -lwinmm LDFLAGS += -static-libgcc -static-libstdc++ -lwinmm
ENDIANNESS_DEFINES := -DLSB_FIRST ENDIANNESS_DEFINES := -DLSB_FIRST
@ -66,16 +66,13 @@ MEDNAFEN_SOURCES := $(MEDNAFEN_DIR)/cdrom/cdromif.cpp \
$(MEDNAFEN_DIR)/error.cpp \ $(MEDNAFEN_DIR)/error.cpp \
$(MEDNAFEN_DIR)/math_ops.cpp \ $(MEDNAFEN_DIR)/math_ops.cpp \
$(MEDNAFEN_DIR)/settings.cpp \ $(MEDNAFEN_DIR)/settings.cpp \
$(MEDNAFEN_DIR)/netplay.cpp \
$(MEDNAFEN_DIR)/general.cpp \ $(MEDNAFEN_DIR)/general.cpp \
$(MEDNAFEN_DIR)/player.cpp \ $(MEDNAFEN_DIR)/player.cpp \
$(MEDNAFEN_LIBRETRO_DIR)/cdplay.cpp \ $(MEDNAFEN_LIBRETRO_DIR)/cdplay.cpp \
$(MEDNAFEN_DIR)/FileWrapper.cpp \ $(MEDNAFEN_DIR)/FileWrapper.cpp \
$(MEDNAFEN_DIR)/state.cpp \ $(MEDNAFEN_DIR)/state.cpp \
$(MEDNAFEN_DIR)/tests.cpp \ $(MEDNAFEN_DIR)/tests.cpp \
$(MEDNAFEN_DIR)/movie.cpp \
$(MEDNAFEN_DIR)/endian.cpp \ $(MEDNAFEN_DIR)/endian.cpp \
$(MEDNAFEN_DIR)/qtrecord.cpp \
$(MEDNAFEN_DIR)/cdrom/CDAccess.cpp \ $(MEDNAFEN_DIR)/cdrom/CDAccess.cpp \
$(MEDNAFEN_DIR)/cdrom/CDAccess_Image.cpp \ $(MEDNAFEN_DIR)/cdrom/CDAccess_Image.cpp \
$(MEDNAFEN_DIR)/cdrom/CDUtility.cpp \ $(MEDNAFEN_DIR)/cdrom/CDUtility.cpp \
@ -94,7 +91,6 @@ MEDNAFEN_SOURCES := $(MEDNAFEN_DIR)/cdrom/cdromif.cpp \
$(MEDNAFEN_DIR)/video/text.cpp \ $(MEDNAFEN_DIR)/video/text.cpp \
$(MEDNAFEN_DIR)/video/font-data.cpp \ $(MEDNAFEN_DIR)/video/font-data.cpp \
$(MEDNAFEN_DIR)/video/tblur.cpp \ $(MEDNAFEN_DIR)/video/tblur.cpp \
$(MEDNAFEN_DIR)/video/png.cpp \
$(MEDNAFEN_DIR)/video/Deinterlacer.cpp \ $(MEDNAFEN_DIR)/video/Deinterlacer.cpp \
$(MEDNAFEN_DIR)/video/surface.cpp \ $(MEDNAFEN_DIR)/video/surface.cpp \
$(MEDNAFEN_DIR)/video/resize.cpp \ $(MEDNAFEN_DIR)/video/resize.cpp \
@ -125,8 +121,7 @@ SOURCES_C := $(MEDNAFEN_DIR)/trio/trio.c \
$(MEDNAFEN_DIR)/compress/unzip.c \ $(MEDNAFEN_DIR)/compress/unzip.c \
$(MEDNAFEN_DIR)/compress/minilzo.c \ $(MEDNAFEN_DIR)/compress/minilzo.c \
$(MEDNAFEN_DIR)/compress/quicklz.c \ $(MEDNAFEN_DIR)/compress/quicklz.c \
$(MEDNAFEN_DIR)/compress/ioapi.c \ $(MEDNAFEN_DIR)/compress/ioapi.c
$(MEDNAFEN_DIR)/resampler/resample.c
SOURCES := $(LIBRETRO_SOURCES) $(PSX_SOURCES) $(MEDNAFEN_SOURCES) SOURCES := $(LIBRETRO_SOURCES) $(PSX_SOURCES) $(MEDNAFEN_SOURCES)
OBJECTS := $(SOURCES:.cpp=.o) $(SOURCES_C:.c=.o) OBJECTS := $(SOURCES:.cpp=.o) $(SOURCES_C:.c=.o)

View File

@ -27,8 +27,6 @@
#include <list> #include <list>
#include <algorithm> #include <algorithm>
#include "netplay.h"
#include "netplay-driver.h"
#include "general.h" #include "general.h"
#include "state.h" #include "state.h"
@ -42,7 +40,6 @@
#include "compress/minilzo.h" #include "compress/minilzo.h"
#include "tests.h" #include "tests.h"
#include "video/tblur.h" #include "video/tblur.h"
#include "qtrecord.h"
#include "md5.h" #include "md5.h"
#include "clamp.h" #include "clamp.h"
#include "Fir_Resampler.h" #include "Fir_Resampler.h"
@ -67,20 +64,6 @@ static MDFNSetting_EnumList CompressorList[] =
{ NULL, 0 }, { NULL, 0 },
}; };
static MDFNSetting_EnumList VCodec_List[] =
{
{ "raw", (int)QTRecord::VCODEC_RAW, "Raw",
gettext_noop("A fast codec, computationally, but will cause enormous file size and may exceed your storage medium's sustained write rate.") },
{ "cscd", (int)QTRecord::VCODEC_CSCD, "CamStudio Screen Codec",
gettext_noop("A good balance between performance and compression ratio.") },
{ "png", (int)QTRecord::VCODEC_PNG, "PNG",
gettext_noop("Has a better compression ratio than \"cscd\", but is much more CPU intensive. Use for compatibility with official QuickTime in cases where you have insufficient disk space for \"raw\".") },
{ NULL, 0 },
};
static const char *fname_extra = gettext_noop("See fname_format.txt for more information. Edit at your own risk."); static const char *fname_extra = gettext_noop("See fname_format.txt for more information. Edit at your own risk.");
static MDFNSetting MednafenSettings[] = static MDFNSetting MednafenSettings[] =
@ -112,7 +95,6 @@ static MDFNSetting MednafenSettings[] =
{ "qtrecord.w_double_threshold", MDFNSF_NOFLAGS, gettext_noop("Double the raw image's width if it's below this threshold."), NULL, MDFNST_UINT, "384", "0", "1073741824" }, { "qtrecord.w_double_threshold", MDFNSF_NOFLAGS, gettext_noop("Double the raw image's width if it's below this threshold."), NULL, MDFNST_UINT, "384", "0", "1073741824" },
{ "qtrecord.h_double_threshold", MDFNSF_NOFLAGS, gettext_noop("Double the raw image's height if it's below this threshold."), NULL, MDFNST_UINT, "256", "0", "1073741824" }, { "qtrecord.h_double_threshold", MDFNSF_NOFLAGS, gettext_noop("Double the raw image's height if it's below this threshold."), NULL, MDFNST_UINT, "256", "0", "1073741824" },
{ "qtrecord.vcodec", MDFNSF_NOFLAGS, gettext_noop("Video codec to use."), NULL, MDFNST_ENUM, "cscd", NULL, NULL, NULL, NULL, VCodec_List },
{ NULL } { NULL }
}; };
@ -150,7 +132,6 @@ static MDFNSetting RenamedSettings[] =
MDFNGI *MDFNGameInfo = NULL; MDFNGI *MDFNGameInfo = NULL;
static QTRecord *qtrecorder = NULL;
static WAVRecord *wavrecorder = NULL; static WAVRecord *wavrecorder = NULL;
static Fir_Resampler<16> ff_resampler; static Fir_Resampler<16> ff_resampler;
static double LastSoundMultiplier; static double LastSoundMultiplier;
@ -182,56 +163,11 @@ bool MDFNI_StartWAVRecord(const char *path, double SoundRate)
bool MDFNI_StartAVRecord(const char *path, double SoundRate) bool MDFNI_StartAVRecord(const char *path, double SoundRate)
{ {
try
{
QTRecord::VideoSpec spec;
memset(&spec, 0, sizeof(spec));
spec.SoundRate = SoundRate;
spec.SoundChan = MDFNGameInfo->soundchan;
spec.VideoWidth = MDFNGameInfo->lcm_width;
spec.VideoHeight = MDFNGameInfo->lcm_height;
spec.VideoCodec = MDFN_GetSettingI("qtrecord.vcodec");
if(spec.VideoWidth < MDFN_GetSettingUI("qtrecord.w_double_threshold"))
spec.VideoWidth *= 2;
if(spec.VideoHeight < MDFN_GetSettingUI("qtrecord.h_double_threshold"))
spec.VideoHeight *= 2;
spec.AspectXAdjust = ((double)MDFNGameInfo->nominal_width * 2) / spec.VideoWidth;
spec.AspectYAdjust = ((double)MDFNGameInfo->nominal_height * 2) / spec.VideoHeight;
MDFN_printf("\n");
MDFN_printf(_("Starting QuickTime recording to file \"%s\":\n"), path);
MDFN_indent(1);
MDFN_printf(_("Video width: %u\n"), spec.VideoWidth);
MDFN_printf(_("Video height: %u\n"), spec.VideoHeight);
MDFN_printf(_("Video codec: %s\n"), MDFN_GetSettingS("qtrecord.vcodec").c_str());
MDFN_printf(_("Sound rate: %u\n"), spec.SoundRate);
MDFN_printf(_("Sound channels: %u\n"), spec.SoundChan);
MDFN_indent(-1);
MDFN_printf("\n");
qtrecorder = new QTRecord(path, spec);
}
catch(std::exception &e)
{
MDFND_PrintError(e.what());
return(false); return(false);
}
return(true);
} }
void MDFNI_StopAVRecord(void) void MDFNI_StopAVRecord(void)
{ {
if(qtrecorder)
{
delete qtrecorder;
qtrecorder = NULL;
}
} }
void MDFNI_StopWAVRecord(void) void MDFNI_StopWAVRecord(void)
@ -247,11 +183,6 @@ void MDFNI_CloseGame(void)
{ {
if(MDFNGameInfo) if(MDFNGameInfo)
{ {
if(MDFNnetplay)
MDFNI_NetplayStop();
MDFNMOV_Stop();
if(MDFNGameInfo->GameType != GMT_PLAYER) if(MDFNGameInfo->GameType != GMT_PLAYER)
MDFN_FlushGameCheats(0); MDFN_FlushGameCheats(0);
@ -264,7 +195,6 @@ void MDFNI_CloseGame(void)
MDFNMP_Kill(); MDFNMP_Kill();
MDFNGameInfo = NULL; MDFNGameInfo = NULL;
MDFN_StateEvilEnd();
for(unsigned i = 0; i < CDInterfaces.size(); i++) for(unsigned i = 0; i < CDInterfaces.size(); i++)
delete CDInterfaces[i]; delete CDInterfaces[i];
@ -584,13 +514,9 @@ MDFNGI *MDFNI_LoadCD(const char *force_module, const char *devicename)
#endif #endif
MDFNSS_CheckStates(); MDFNSS_CheckStates();
MDFNMOV_CheckMovies();
MDFN_ResetMessages(); // Save state, status messages, etc. MDFN_ResetMessages(); // Save state, status messages, etc.
MDFN_StateEvilBegin();
if(MDFNGameInfo->GameType != GMT_PLAYER) if(MDFNGameInfo->GameType != GMT_PLAYER)
{ {
MDFN_LoadGameCheats(NULL); MDFN_LoadGameCheats(NULL);
@ -787,7 +713,6 @@ MDFNGI *MDFNI_LoadGame(const char *force_module, const char *name)
#endif #endif
MDFNSS_CheckStates(); MDFNSS_CheckStates();
MDFNMOV_CheckMovies();
MDFN_ResetMessages(); // Save state, status messages, etc. MDFN_ResetMessages(); // Save state, status messages, etc.
@ -812,9 +737,6 @@ MDFNGI *MDFNI_LoadGame(const char *force_module, const char *name)
PrevInterlaced = false; PrevInterlaced = false;
deint.ClearState(); deint.ClearState();
MDFN_StateEvilBegin();
last_sound_rate = -1; last_sound_rate = -1;
memset(&last_pixel_format, 0, sizeof(MDFN_PixelFormat)); memset(&last_pixel_format, 0, sizeof(MDFN_PixelFormat));
@ -1251,25 +1173,6 @@ void MDFNI_Emulate(EmulateSpecStruct *espec)
espec->skip = 0; espec->skip = 0;
if(espec->NeedRewind)
{
if(MDFNMOV_IsPlaying())
{
espec->NeedRewind = 0;
MDFN_DispMessage(_("Can't rewind during movie playback."));
}
else if(MDFNnetplay)
{
espec->NeedRewind = 0;
MDFN_DispMessage(_("Can't rewind during netplay."));
}
else if(MDFNGameInfo->GameType == GMT_PLAYER)
{
espec->NeedRewind = 0;
MDFN_DispMessage(_("Music player rewinding is unsupported."));
}
}
// Don't even save states with state rewinding if netplay is enabled, it will degrade netplay performance, and can cause // Don't even save states with state rewinding if netplay is enabled, it will degrade netplay performance, and can cause
// desynchs with some emulation(IE SNES based on bsnes). // desynchs with some emulation(IE SNES based on bsnes).
@ -1417,16 +1320,7 @@ void MDFN_DoSimpleCommand(int cmd)
void MDFN_QSimpleCommand(int cmd) void MDFN_QSimpleCommand(int cmd)
{ {
if(MDFNnetplay)
NetplaySendCommand(cmd, 0);
else
{
if(!MDFNMOV_IsPlaying())
{
MDFN_DoSimpleCommand(cmd); MDFN_DoSimpleCommand(cmd);
MDFNMOV_AddCommand(cmd);
}
}
} }
void MDFNI_Power(void) void MDFNI_Power(void)

View File

@ -20,23 +20,24 @@
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#ifndef _WIN32
#include <unistd.h> #include <unistd.h>
#endif
#include <time.h> #include <time.h>
#include <trio/trio.h> #include "include/trio/trio.h"
#include "driver.h" #include "driver.h"
#include "general.h" #include "general.h"
#include "state.h" #include "state.h"
#include "movie.h"
#include "netplay.h"
#include "video.h" #include "video.h"
#include "video/resize.h"
static int SaveStateStatus[10]; static int SaveStateStatus[10];
#define RLSB MDFNSTATE_RLSB //0x80000000 #define RLSB MDFNSTATE_RLSB //0x80000000
int32 smem_read(StateMem *st, void *buffer, uint32 len) static int32 smem_read(StateMem *st, void *buffer, uint32 len)
{ {
if((len + st->loc) > st->len) if((len + st->loc) > st->len)
return(0); return(0);
@ -47,7 +48,7 @@ int32 smem_read(StateMem *st, void *buffer, uint32 len)
return(len); return(len);
} }
int32 smem_write(StateMem *st, void *buffer, uint32 len) static int32 smem_write(StateMem *st, void *buffer, uint32 len)
{ {
if((len + st->loc) > st->malloced) if((len + st->loc) > st->malloced)
{ {
@ -66,7 +67,7 @@ int32 smem_write(StateMem *st, void *buffer, uint32 len)
return(len); return(len);
} }
int32 smem_putc(StateMem *st, int value) static int32 smem_putc(StateMem *st, int value)
{ {
uint8 tmpval = value; uint8 tmpval = value;
if(smem_write(st, &tmpval, 1) != 1) if(smem_write(st, &tmpval, 1) != 1)
@ -74,12 +75,12 @@ int32 smem_putc(StateMem *st, int value)
return(1); return(1);
} }
int32 smem_tell(StateMem *st) static int32 smem_tell(StateMem *st)
{ {
return(st->loc); return(st->loc);
} }
int32 smem_seek(StateMem *st, uint32 offset, int whence) static int32 smem_seek(StateMem *st, uint32 offset, int whence)
{ {
switch(whence) switch(whence)
{ {
@ -103,7 +104,7 @@ int32 smem_seek(StateMem *st, uint32 offset, int whence)
return(0); return(0);
} }
int smem_write32le(StateMem *st, uint32 b) static int smem_write32le(StateMem *st, uint32 b)
{ {
uint8 s[4]; uint8 s[4];
s[0]=b; s[0]=b;
@ -113,7 +114,7 @@ int smem_write32le(StateMem *st, uint32 b)
return((smem_write(st, s, 4)<4)?0:4); return((smem_write(st, s, 4)<4)?0:4);
} }
int smem_read32le(StateMem *st, uint32 *b) static int smem_read32le(StateMem *st, uint32 *b)
{ {
uint8 s[4]; uint8 s[4];
@ -125,7 +126,6 @@ int smem_read32le(StateMem *st, uint32 *b)
return(4); return(4);
} }
static bool ValidateSFStructure(SFORMAT *sf) static bool ValidateSFStructure(SFORMAT *sf)
{ {
SFORMAT *saved_sf = sf; SFORMAT *saved_sf = sf;
@ -153,8 +153,6 @@ static bool ValidateSFStructure(SFORMAT *sf)
static bool SubWrite(StateMem *st, SFORMAT *sf, int data_only, const char *name_prefix = NULL) static bool SubWrite(StateMem *st, SFORMAT *sf, int data_only, const char *name_prefix = NULL)
{ {
// FIXME? It's kind of slow, and we definitely don't want it on with state rewinding...
if(!data_only)
ValidateSFStructure(sf); ValidateSFStructure(sf);
while(sf->size || sf->name) // Size can sometimes be zero, so also check for the text name. These two should both be zero only at the end of a struct. while(sf->size || sf->name) // Size can sometimes be zero, so also check for the text name. These two should both be zero only at the end of a struct.
@ -167,7 +165,7 @@ static bool SubWrite(StateMem *st, SFORMAT *sf, int data_only, const char *name_
if(sf->size == (uint32)~0) /* Link to another struct. */ if(sf->size == (uint32)~0) /* Link to another struct. */
{ {
if(!SubWrite(st, (SFORMAT *)sf->v, data_only, name_prefix)) if(!SubWrite(st, (SFORMAT *)sf->v, 0, name_prefix))
return(0); return(0);
sf++; sf++;
@ -176,15 +174,6 @@ static bool SubWrite(StateMem *st, SFORMAT *sf, int data_only, const char *name_
int32 bytesize = sf->size; int32 bytesize = sf->size;
// If we're only saving the raw data, and we come across a bool type, we save it as it is in memory, rather than converting it to
// 1-byte. In the SFORMAT structure, the size member for bool entries is the number of bool elements, not the total in-memory size,
// so we adjust it here.
if(data_only && (sf->flags & MDFNSTATE_BOOL))
{
bytesize *= sizeof(bool);
}
if(!data_only)
{ {
char nameo[1 + 256]; char nameo[1 + 256];
int slen; int slen;
@ -218,7 +207,7 @@ static bool SubWrite(StateMem *st, SFORMAT *sf, int data_only, const char *name_
// Special case for the evil bool type, to convert bool to 1-byte elements. // Special case for the evil bool type, to convert bool to 1-byte elements.
// Don't do it if we're only saving the raw data. // Don't do it if we're only saving the raw data.
if((sf->flags & MDFNSTATE_BOOL) && !data_only) if((sf->flags & MDFNSTATE_BOOL))
{ {
for(int32 bool_monster = 0; bool_monster < bytesize; bool_monster++) for(int32 bool_monster = 0; bool_monster < bytesize; bool_monster++)
{ {
@ -230,7 +219,6 @@ static bool SubWrite(StateMem *st, SFORMAT *sf, int data_only, const char *name_
else else
smem_write(st, (uint8 *)sf->v, bytesize); smem_write(st, (uint8 *)sf->v, bytesize);
if(!data_only)
{ {
/* Now restore the original byte order. */ /* Now restore the original byte order. */
if(sf->flags & MDFNSTATE_BOOL) if(sf->flags & MDFNSTATE_BOOL)
@ -257,7 +245,6 @@ static int WriteStateChunk(StateMem *st, const char *sname, SFORMAT *sf, int dat
int32 data_start_pos; int32 data_start_pos;
int32 end_pos; int32 end_pos;
if(!data_only)
{ {
uint8 sname_tmp[32]; uint8 sname_tmp[32];
@ -274,12 +261,11 @@ static int WriteStateChunk(StateMem *st, const char *sname, SFORMAT *sf, int dat
data_start_pos = smem_tell(st); data_start_pos = smem_tell(st);
if(!SubWrite(st, sf, data_only)) if(!SubWrite(st, sf, 0))
return(0); return(0);
end_pos = smem_tell(st); end_pos = smem_tell(st);
if(!data_only)
{ {
smem_seek(st, data_start_pos - 4, SEEK_SET); smem_seek(st, data_start_pos - 4, SEEK_SET);
smem_write32le(st, end_pos - data_start_pos); smem_write32le(st, end_pos - data_start_pos);
@ -325,47 +311,10 @@ static void MakeSFMap(SFORMAT *sf, SFMap_t &sfmap)
} }
} }
// Fast raw chunk reader
static void DOReadChunk(StateMem *st, SFORMAT *sf)
{
while(sf->size || sf->name) // Size can sometimes be zero, so also check for the text name.
// These two should both be zero only at the end of a struct.
{
if(!sf->size || !sf->v)
{
sf++;
continue;
}
if(sf->size == (uint32) ~0) // Link to another SFORMAT struct
{
DOReadChunk(st, (SFORMAT *)sf->v);
sf++;
continue;
}
int32 bytesize = sf->size;
// Loading raw data, bool types are stored as they appear in memory, not as single bytes in the full state format.
// In the SFORMAT structure, the size member for bool entries is the number of bool elements, not the total in-memory size,
// so we adjust it here.
if(sf->flags & MDFNSTATE_BOOL)
bytesize *= sizeof(bool);
smem_read(st, (uint8 *)sf->v, bytesize);
sf++;
}
}
static int ReadStateChunk(StateMem *st, SFORMAT *sf, int size, int data_only) static int ReadStateChunk(StateMem *st, SFORMAT *sf, int size, int data_only)
{ {
int temp; int temp;
if(data_only)
{
DOReadChunk(st, sf);
}
else
{ {
SFMap_t sfmap; SFMap_t sfmap;
SFMap_t sfmap_found; // Used for identifying variables that are missing in the save state. SFMap_t sfmap_found; // Used for identifying variables that are missing in the save state.
@ -470,14 +419,6 @@ int MDFNSS_StateAction(StateMem *st, int load, int data_only, std::vector <SSDes
if(load) if(load)
{ {
if(data_only)
{
for(section = sections.begin(); section != sections.end(); section++)
{
ReadStateChunk(st, section->sf, ~0, 1);
}
}
else
{ {
char sname[32]; char sname[32];
@ -507,7 +448,6 @@ int MDFNSS_StateAction(StateMem *st, int load, int data_only, std::vector <SSDes
} }
else else
{ {
// puts("SEEK");
if(smem_seek(st, tmp_size, SEEK_CUR) < 0) if(smem_seek(st, tmp_size, SEEK_CUR) < 0)
{ {
puts("Chunk seek failure"); puts("Chunk seek failure");
@ -532,7 +472,7 @@ int MDFNSS_StateAction(StateMem *st, int load, int data_only, std::vector <SSDes
{ {
for(section = sections.begin(); section != sections.end(); section++) for(section = sections.begin(); section != sections.end(); section++)
{ {
if(!WriteStateChunk(st, section->name, section->sf, data_only)) if(!WriteStateChunk(st, section->name, section->sf, 0))
return(0); return(0);
} }
} }
@ -545,116 +485,34 @@ int MDFNSS_StateAction(StateMem *st, int load, int data_only, SFORMAT *sf, const
std::vector <SSDescriptor> love; std::vector <SSDescriptor> love;
love.push_back(SSDescriptor(sf, name, optional)); love.push_back(SSDescriptor(sf, name, optional));
return(MDFNSS_StateAction(st, load, data_only, love)); return(MDFNSS_StateAction(st, load, 0, love));
} }
int MDFNSS_SaveSM(StateMem *st, int wantpreview_and_ts, int data_only, const MDFN_Surface *surface, const MDFN_Rect *DisplayRect, const MDFN_Rect *LineWidths) int MDFNSS_SaveSM(StateMem *st)
{ {
static const char *header_magic = "MDFNSVST"; static const char *header_magic = "MDFNSVST";
uint8 header[32]; uint8 header[32];
int neowidth = 0, neoheight = 0; int neowidth = 0, neoheight = 0;
memset(header, 0, sizeof(header)); memset(header, 0, sizeof(header));
memcpy(header, header_magic, 8);
if(wantpreview_and_ts) MDFN_en32lsb(header + 16, MEDNAFEN_VERSION_NUMERIC);
{ MDFN_en32lsb(header + 24, neowidth);
bool is_multires = FALSE; MDFN_en32lsb(header + 28, neoheight);
smem_write(st, header, 32);
// We'll want to use the nominal width if the source rectangle is > 25% off on either axis, or the source image has if(!MDFNGameInfo->StateAction(st, 0, 0))
// multiple horizontal resolutions.
neowidth = MDFNGameInfo->nominal_width;
neoheight = MDFNGameInfo->nominal_height;
if(LineWidths[0].w != ~0)
{
uint32 first_w = LineWidths[DisplayRect->y].w;
for(int y = 0; y < DisplayRect->h; y++)
if(LineWidths[DisplayRect->y + y].w != first_w)
{
puts("Multires!");
is_multires = TRUE;
}
}
if(!is_multires)
{
if(((double)DisplayRect->w / MDFNGameInfo->nominal_width) > 0.75 && ((double)DisplayRect->w / MDFNGameInfo->nominal_width) < 1.25)
neowidth = DisplayRect->w;
if(((double)DisplayRect->h / MDFNGameInfo->nominal_height) > 0.75 && ((double)DisplayRect->h / MDFNGameInfo->nominal_height) < 1.25)
neoheight = DisplayRect->h;
}
}
if(!data_only)
{
memcpy(header, header_magic, 8);
if(wantpreview_and_ts)
MDFN_en64lsb(header + 8, time(NULL));
MDFN_en32lsb(header + 16, MEDNAFEN_VERSION_NUMERIC);
MDFN_en32lsb(header + 24, neowidth);
MDFN_en32lsb(header + 28, neoheight);
smem_write(st, header, 32);
}
if(wantpreview_and_ts)
{
uint8 *previewbuffer = (uint8 *)malloc(4 * neowidth * neoheight);
MDFN_Surface *dest_surface = new MDFN_Surface((uint32 *)previewbuffer, neowidth, neoheight, neowidth, surface->format);
MDFN_Rect dest_rect;
dest_rect.x = 0;
dest_rect.y = 0;
dest_rect.w = neowidth;
dest_rect.h = neoheight;
MDFN_ResizeSurface(surface, DisplayRect, (LineWidths[0].w != ~0) ? LineWidths : NULL, dest_surface, &dest_rect);
{
uint32 a, b = 0;
for(a = 0; a < neowidth * neoheight * 4; a+=4)
{
uint32 c = *(uint32 *)&previewbuffer[a];
int nr, ng, nb;
surface->DecodeColor(c, nr, ng, nb);
previewbuffer[b + 0] = nr;
previewbuffer[b + 1] = ng;
previewbuffer[b + 2] = nb;
b += 3;
}
}
smem_write(st, previewbuffer, 3 * neowidth * neoheight);
free(previewbuffer);
delete dest_surface;
}
// State rewinding code path hack, FIXME
if(data_only)
{
if(!MDFN_RawInputStateAction(st, 0, data_only))
return(0);
}
if(!MDFNGameInfo->StateAction(st, 0, data_only))
return(0); return(0);
if(!data_only) uint32 sizy = smem_tell(st);
{ smem_seek(st, 16 + 4, SEEK_SET);
uint32 sizy = smem_tell(st); smem_write32le(st, sizy);
smem_seek(st, 16 + 4, SEEK_SET);
smem_write32le(st, sizy);
}
return(1); return(1);
} }
int MDFNSS_Save(const char *fname, const char *suffix, const MDFN_Surface *surface, const MDFN_Rect *DisplayRect, const MDFN_Rect *LineWidths) static int MDFNSS_Save(const char *fname, const char *suffix)
{ {
StateMem st; StateMem st;
@ -667,7 +525,7 @@ int MDFNSS_Save(const char *fname, const char *suffix, const MDFN_Surface *surfa
return(0); return(0);
} }
if(!MDFNSS_SaveSM(&st, (DisplayRect && LineWidths), 0, surface, DisplayRect, LineWidths)) if(!MDFNSS_SaveSM(&st))
{ {
if(st.data) if(st.data)
free(st.data); free(st.data);
@ -698,74 +556,22 @@ int MDFNSS_Save(const char *fname, const char *suffix, const MDFN_Surface *surfa
return(1); return(1);
} }
// Convenience function for movie.cpp int MDFNSS_LoadSM(StateMem *st)
int MDFNSS_SaveFP(gzFile fp, const MDFN_Surface *surface, const MDFN_Rect *DisplayRect, const MDFN_Rect *LineWidths)
{ {
StateMem st; uint8 header[32];
uint32 stateversion;
memset(&st, 0, sizeof(StateMem)); smem_read(st, header, 32);
if(!MDFNSS_SaveSM(&st, (DisplayRect && LineWidths), 0, surface, DisplayRect, LineWidths)) if(memcmp(header, "MEDNAFENSVESTATE", 16) && memcmp(header, "MDFNSVST", 8))
{
if(st.data)
free(st.data);
return(0); return(0);
}
if(gzwrite(fp, st.data, st.len) != (int32)st.len) stateversion = MDFN_de32lsb(header + 16);
{
if(st.data)
free(st.data);
return(0);
}
if(st.data) return(MDFNGameInfo->StateAction(st, stateversion, 0));
free(st.data);
return(1);
} }
static int MDFNSS_LoadFP(gzFile fp)
int MDFNSS_LoadSM(StateMem *st, int haspreview, int data_only)
{
uint8 header[32];
uint32 stateversion;
if(data_only)
{
stateversion = MEDNAFEN_VERSION_NUMERIC;
}
else
{
smem_read(st, header, 32);
if(memcmp(header, "MEDNAFENSVESTATE", 16) && memcmp(header, "MDFNSVST", 8))
return(0);
stateversion = MDFN_de32lsb(header + 16);
}
if(haspreview)
{
uint32 width = MDFN_de32lsb(header + 24);
uint32 height = MDFN_de32lsb(header + 28);
uint32 psize;
psize = width * height * 3;
smem_seek(st, psize, SEEK_CUR); // Skip preview
}
// State rewinding code path hack, FIXME
if(data_only)
{
if(!MDFN_RawInputStateAction(st, stateversion, data_only))
return(0);
}
return(MDFNGameInfo->StateAction(st, stateversion, data_only));
}
int MDFNSS_LoadFP(gzFile fp)
{ {
uint8 header[32]; uint8 header[32];
StateMem st; StateMem st;
@ -790,7 +596,7 @@ int MDFNSS_LoadFP(gzFile fp)
free(st.data); free(st.data);
return(0); return(0);
} }
if(!MDFNSS_LoadSM(&st, 1, 0)) if(!MDFNSS_LoadSM(&st))
{ {
free(st.data); free(st.data);
return(0); return(0);
@ -799,7 +605,7 @@ int MDFNSS_LoadFP(gzFile fp)
return(1); return(1);
} }
int MDFNSS_Load(const char *fname, const char *suffix) static int MDFNSS_Load(const char *fname, const char *suffix)
{ {
gzFile st; gzFile st;
@ -859,7 +665,7 @@ void MDFNSS_CheckStates(void)
struct stat stat_buf; struct stat stat_buf;
SaveStateStatus[ssel] = 0; SaveStateStatus[ssel] = 0;
//printf("%s\n", MDFN_MakeFName(MDFNMKF_STATE, ssel, 0).c_str());
if(stat(MDFN_MakeFName(MDFNMKF_STATE, ssel, 0).c_str(), &stat_buf) == 0) if(stat(MDFN_MakeFName(MDFNMKF_STATE, ssel, 0).c_str(), &stat_buf) == 0)
{ {
SaveStateStatus[ssel] = 1; SaveStateStatus[ssel] = 1;
@ -878,9 +684,6 @@ void MDFNSS_CheckStates(void)
void MDFNSS_GetStateInfo(const char *filename, StateStatusStruct *status) void MDFNSS_GetStateInfo(const char *filename, StateStatusStruct *status)
{ {
gzFile fp; gzFile fp;
uint32 StateShowPBWidth;
uint32 StateShowPBHeight;
uint8 *previewbuffer = NULL;
fp = gzopen(filename, "rb"); fp = gzopen(filename, "rb");
if(fp) if(fp)
@ -888,35 +691,12 @@ void MDFNSS_GetStateInfo(const char *filename, StateStatusStruct *status)
uint8 header[32]; uint8 header[32];
gzread(fp, header, 32); gzread(fp, header, 32);
uint32 width = MDFN_de32lsb(header + 24);
uint32 height = MDFN_de32lsb(header + 28);
if(width > 1024) width = 1024;
if(height > 1024) height = 1024;
if(!(previewbuffer = (uint8 *)MDFN_malloc(3 * width * height, _("Save state preview buffer"))))
{
StateShowPBWidth = 0;
StateShowPBHeight = 0;
}
else
{
gzread(fp, previewbuffer, 3 * width * height);
StateShowPBWidth = width;
StateShowPBHeight = height;
}
gzclose(fp); gzclose(fp);
} }
else else
{ {
StateShowPBWidth = MDFNGameInfo->nominal_width;
StateShowPBHeight = MDFNGameInfo->nominal_height;
} }
status->gfx = previewbuffer;
status->w = StateShowPBWidth;
status->h = StateShowPBHeight;
} }
void MDFNI_SelectState(int w) void MDFNI_SelectState(int w)
@ -930,7 +710,6 @@ void MDFNI_SelectState(int w)
MDFND_SetStateStatus(NULL); MDFND_SetStateStatus(NULL);
return; return;
} }
MDFNI_SelectMovie(-1);
if(w == 666 + 1) if(w == 666 + 1)
CurrentState = (CurrentState + 1) % 10; CurrentState = (CurrentState + 1) % 10;
@ -957,21 +736,13 @@ void MDFNI_SelectState(int w)
MDFND_SetStateStatus(status); MDFND_SetStateStatus(status);
} }
void MDFNI_SaveState(const char *fname, const char *suffix, const MDFN_Surface *surface, const MDFN_Rect *DisplayRect, const MDFN_Rect *LineWidths) void MDFNI_SaveState(const char *fname, const char *suffix)
{ {
if(!MDFNGameInfo->StateAction) if(!MDFNGameInfo->StateAction)
return; return;
if(MDFNnetplay && (MDFNGameInfo->SaveStateAltersState == true))
{
char sb[256];
trio_snprintf(sb, sizeof(sb), _("Module %s is not compatible with manual state saving during netplay."), MDFNGameInfo->shortname);
MDFND_NetplayText((const uint8*)sb, false);
return;
}
MDFND_SetStateStatus(NULL); MDFND_SetStateStatus(NULL);
MDFNSS_Save(fname, suffix, surface, DisplayRect, LineWidths); MDFNSS_Save(fname, suffix);
} }
void MDFNI_LoadState(const char *fname, const char *suffix) void MDFNI_LoadState(const char *fname, const char *suffix)
@ -981,296 +752,5 @@ void MDFNI_LoadState(const char *fname, const char *suffix)
MDFND_SetStateStatus(NULL); MDFND_SetStateStatus(NULL);
/* For network play and movies, be load the state locally, and then save the state to a temporary buffer, MDFNSS_Load(fname, suffix);
and send or record that. This ensures that if an older state is loaded that is missing some
information expected in newer save states, desynchronization won't occur(at least not
from this ;)).
*/
if(MDFNSS_Load(fname, suffix))
{
if(MDFNnetplay)
{
NetplaySendState();
}
if(MDFNMOV_IsRecording())
MDFNMOV_RecordState();
}
}
#include "compress/minilzo.h"
#include "compress/quicklz.h"
#include "compress/blz.h"
static union
{
char qlz_scratch_compress[/*QLZ_*/SCRATCH_COMPRESS];
char qlz_scratch_decompress[/*QLZ_*/SCRATCH_DECOMPRESS];
};
enum
{
SRW_COMPRESSOR_MINILZO = 0,
SRW_COMPRESSOR_QUICKLZ,
SRW_COMPRESSOR_BLZ
};
struct StateMemPacket
{
uint8 *data;
uint32 compressed_len;
uint32 uncompressed_len;
StateMem MovieLove;
};
static int SRW_NUM = 600;
static int SRWCompressor;
static int EvilEnabled = 0;
static StateMemPacket *bcs;
static int32 bcspos;
void MDFN_StateEvilBegin(void)
{
int x;
std::string srwcompstring;
if(!EvilEnabled)
return;
SRW_NUM = MDFN_GetSettingUI("srwframes");
SRWCompressor = SRW_COMPRESSOR_MINILZO;
srwcompstring = MDFN_GetSettingS("srwcompressor");
if(srwcompstring == "minilzo")
SRWCompressor = SRW_COMPRESSOR_MINILZO;
else if(srwcompstring == "quicklz")
SRWCompressor = SRW_COMPRESSOR_QUICKLZ;
else if(srwcompstring == "blz")
SRWCompressor = SRW_COMPRESSOR_BLZ;
bcs = (StateMemPacket *)calloc(SRW_NUM, sizeof(StateMemPacket));
bcspos = 0;
for(x=0;x<SRW_NUM;x++)
{
bcs[x].data = NULL;
bcs[x].compressed_len = 0;
bcs[x].uncompressed_len = 0;
memset(&bcs[x].MovieLove, 0, sizeof(StateMem));
}
}
bool MDFN_StateEvilIsRunning(void)
{
return(EvilEnabled);
}
void MDFN_StateEvilEnd(void)
{
int x;
if(!EvilEnabled)
return;
if(bcs)
{
if(MDFNMOV_IsRecording())
MDFN_StateEvilFlushMovieLove();
for(x = 0;x < SRW_NUM; x++)
{
if(bcs[x].data)
free(bcs[x].data);
bcs[x].data = NULL;
bcs[x].compressed_len = 0;
}
free(bcs);
}
}
void MDFN_StateEvilFlushMovieLove(void)
{
int bahpos = (bcspos + 1) % SRW_NUM;
for(int x = 0; x < SRW_NUM; x++)
{
if(bcs[bahpos].MovieLove.data)
{
if(bcs[x].data)
MDFNMOV_ForceRecord(&bcs[bahpos].MovieLove);
free(bcs[bahpos].MovieLove.data);
bcs[bahpos].MovieLove.data = NULL;
}
bahpos = (bahpos + 1) % SRW_NUM;
}
}
int MDFN_StateEvil(int rewind)
{
if(!EvilEnabled)
return(0);
if(rewind)
{
int32 next_bcspos = bcspos;
bool NeedDataFlush = FALSE;
bcspos--;
if(bcspos < 0) bcspos += SRW_NUM;
if(!bcs[bcspos].data)
bcspos = (bcspos + 1) % SRW_NUM;
else
NeedDataFlush = TRUE;
if(bcs[bcspos].compressed_len)
{
uint8 *tmp_buf;
lzo_uint dst_len = bcs[bcspos].uncompressed_len;
tmp_buf = (uint8 *)malloc(bcs[bcspos].uncompressed_len);
if(SRWCompressor == SRW_COMPRESSOR_QUICKLZ)
dst_len = qlz_decompress((char*)bcs[bcspos].data, tmp_buf, qlz_scratch_decompress);
else if(SRWCompressor == SRW_COMPRESSOR_MINILZO)
lzo1x_decompress(bcs[bcspos].data, bcs[bcspos].compressed_len, tmp_buf, &dst_len, NULL);
else if(SRWCompressor == SRW_COMPRESSOR_BLZ)
{
dst_len = blz_unpack(bcs[bcspos].data, tmp_buf);
}
for(uint32 x = 0; x < bcs[bcspos].uncompressed_len && x < bcs[next_bcspos].uncompressed_len; x++)
tmp_buf[x] ^= bcs[next_bcspos].data[x];
free(bcs[bcspos].data);
bcs[bcspos].data = tmp_buf;
bcs[bcspos].compressed_len = 0;
}
if(NeedDataFlush)
{
if(bcs[next_bcspos].MovieLove.data)
{
free(bcs[next_bcspos].MovieLove.data);
bcs[next_bcspos].MovieLove.data = NULL;
}
free(bcs[next_bcspos].data);
bcs[next_bcspos].data = NULL;
bcs[next_bcspos].compressed_len = 0;
bcs[next_bcspos].uncompressed_len = 0;
}
if(bcs[bcspos].uncompressed_len)
{
StateMem sm;
sm.data = bcs[bcspos].data;
sm.loc = 0;
sm.initial_malloc = 0;
sm.malloced = sm.len = bcs[bcspos].uncompressed_len;
MDFNSS_LoadSM(&sm, 0, 1);
free(MDFNMOV_GrabRewindJoy().data);
return(1);
}
}
else
{
StateMem sm;
int32 prev_bcspos = bcspos;
bcspos = (bcspos + 1) % SRW_NUM;
if(MDFNMOV_IsRecording())
{
if(bcs[bcspos].data && bcs[bcspos].MovieLove.data)
{
//printf("Force: %d\n", bcspos);
MDFNMOV_ForceRecord(&bcs[bcspos].MovieLove);
free(bcs[bcspos].MovieLove.data);
bcs[bcspos].MovieLove.data = NULL;
}
}
if(bcs[bcspos].data)
{
free(bcs[bcspos].data);
bcs[bcspos].data = NULL;
}
if(bcs[bcspos].MovieLove.data)
{
free(bcs[bcspos].MovieLove.data);
bcs[bcspos].MovieLove.data = NULL;
}
memset(&sm, 0, sizeof(sm));
MDFNSS_SaveSM(&sm, 0, 1);
bcs[bcspos].data = sm.data;
bcs[bcspos].compressed_len = 0;
bcs[bcspos].uncompressed_len = sm.len;
// Compress the previous save state.
if(bcs[prev_bcspos].data)
{
for(uint32 x = 0; x < bcs[prev_bcspos].uncompressed_len && x < sm.len; x++)
bcs[prev_bcspos].data[x] ^= sm.data[x];
if(SRWCompressor == SRW_COMPRESSOR_QUICKLZ)
{
uint32 dst_len;
uint8 *tmp_buf = (uint8 *)malloc(bcs[prev_bcspos].uncompressed_len + 400);
dst_len = qlz_compress(bcs[prev_bcspos].data, (char*)tmp_buf, bcs[prev_bcspos].uncompressed_len, qlz_scratch_compress);
free(bcs[prev_bcspos].data);
bcs[prev_bcspos].data = (uint8 *)realloc(tmp_buf, dst_len);
bcs[prev_bcspos].compressed_len = dst_len;
}
else if(SRWCompressor == SRW_COMPRESSOR_MINILZO)
{
uint8 workmem[LZO1X_1_MEM_COMPRESS];
uint8 * tmp_buf = (uint8 *)malloc((size_t)(1.10 * bcs[prev_bcspos].uncompressed_len));
lzo_uint dst_len = (lzo_uint)(1.10 * bcs[prev_bcspos].uncompressed_len);
lzo1x_1_compress(bcs[prev_bcspos].data, bcs[prev_bcspos].uncompressed_len, tmp_buf, &dst_len, workmem);
free(bcs[prev_bcspos].data);
bcs[prev_bcspos].data = (uint8 *)realloc(tmp_buf, dst_len);
bcs[prev_bcspos].compressed_len = dst_len;
}
else if(SRWCompressor == SRW_COMPRESSOR_BLZ)
{
blz_pack_t workmem;
uint8 * tmp_buf = (uint8 *)malloc((size_t)(bcs[prev_bcspos].uncompressed_len + blz_pack_extra));
uint32 dst_len = bcs[prev_bcspos].uncompressed_len + blz_pack_extra;
dst_len = blz_pack(bcs[prev_bcspos].data, bcs[prev_bcspos].uncompressed_len, tmp_buf, &workmem);
free(bcs[prev_bcspos].data);
bcs[prev_bcspos].data = (uint8 *)realloc(tmp_buf, dst_len);
bcs[prev_bcspos].compressed_len = dst_len;
}
}
if(MDFNMOV_IsRecording())
bcs[bcspos].MovieLove = MDFNMOV_GrabRewindJoy();
}
return(0);
}
void MDFNI_EnableStateRewind(int enable)
{
if(!MDFNGameInfo->StateAction)
return;
MDFN_StateEvilEnd();
EvilEnabled = enable;
MDFN_StateEvilBegin();
} }

View File

@ -1,18 +1,13 @@
#ifndef _STATE_H #ifndef _STATE_H
#define _STATE_H #define _STATE_H
#include <zlib.h> #include "zlib.h"
#include "video.h" #include "video.h"
#include "state-common.h" #include "state-common.h"
void MDFNSS_GetStateInfo(const char *filename, StateStatusStruct *status); void MDFNSS_GetStateInfo(const char *filename, StateStatusStruct *status);
int MDFNSS_Save(const char *, const char *suffix, const MDFN_Surface *surface = (MDFN_Surface *)NULL, const MDFN_Rect *DisplayRect = (MDFN_Rect*)NULL, const MDFN_Rect *LineWidths = (MDFN_Rect *)NULL);
int MDFNSS_Load(const char *, const char *suffix);
int MDFNSS_SaveFP(gzFile fp, const MDFN_Surface *surface = (MDFN_Surface *)NULL, const MDFN_Rect *DisplayRect = (MDFN_Rect*)NULL, const MDFN_Rect *LineWidths = (MDFN_Rect *)NULL);
int MDFNSS_LoadFP(gzFile fp);
typedef struct typedef struct
{ {
uint8 *data; uint8 *data;
@ -24,19 +19,6 @@ typedef struct
uint32 initial_malloc; // A setting! uint32 initial_malloc; // A setting!
} StateMem; } StateMem;
// Eh, we abuse the smem_* in-memory stream code
// in a few other places. :)
int32 smem_read(StateMem *st, void *buffer, uint32 len);
int32 smem_write(StateMem *st, void *buffer, uint32 len);
int32 smem_putc(StateMem *st, int value);
int32 smem_tell(StateMem *st);
int32 smem_seek(StateMem *st, uint32 offset, int whence);
int smem_write32le(StateMem *st, uint32 b);
int smem_read32le(StateMem *st, uint32 *b);
int MDFNSS_SaveSM(StateMem *st, int wantpreview_and_ts, int data_only, const MDFN_Surface *surface = (MDFN_Surface *)NULL, const MDFN_Rect *DisplayRect = (MDFN_Rect*)NULL, const MDFN_Rect *LineWidths = (MDFN_Rect *)NULL);
int MDFNSS_LoadSM(StateMem *st, int haspreview, int data_only);
void MDFNSS_CheckStates(void); void MDFNSS_CheckStates(void);
// Flag for a single, >= 1 byte native-endian variable // Flag for a single, >= 1 byte native-endian variable
@ -138,10 +120,7 @@ class SSDescriptor
int MDFNSS_StateAction(StateMem *st, int load, int data_only, std::vector <SSDescriptor> &sections); int MDFNSS_StateAction(StateMem *st, int load, int data_only, std::vector <SSDescriptor> &sections);
int MDFNSS_StateAction(StateMem *st, int load, int data_only, SFORMAT *sf, const char *name, bool optional = 0); int MDFNSS_StateAction(StateMem *st, int load, int data_only, SFORMAT *sf, const char *name, bool optional = 0);
void MDFN_StateEvilFlushMovieLove(void); int MDFNSS_SaveSM(StateMem *st);
bool MDFN_StateEvilIsRunning(void); int MDFNSS_LoadSM(StateMem *st);
void MDFN_StateEvilBegin(void);
void MDFN_StateEvilEnd(void);
int MDFN_StateEvil(int);
#endif #endif

View File

@ -29,56 +29,6 @@
void MDFNI_SaveSnapshot(const MDFN_Surface *src, const MDFN_Rect *rect, const MDFN_Rect *LineWidths) void MDFNI_SaveSnapshot(const MDFN_Surface *src, const MDFN_Rect *rect, const MDFN_Rect *LineWidths)
{ {
FileWrapper *pp = NULL;
try
{
std::string fn;
int u = 0;
try
{
pp = new FileWrapper(MDFN_MakeFName(MDFNMKF_SNAP_DAT, 0, NULL).c_str(), FileWrapper::MODE_READ);
}
catch(std::exception &e)
{
}
if(pp)
{
if(pp->scanf("%d", &u) != 1)
u = 0;
delete pp;
pp = NULL;
}
pp = new FileWrapper(MDFN_MakeFName(MDFNMKF_SNAP_DAT, 0, NULL).c_str(), FileWrapper::MODE_WRITE);
pp->seek(0, SEEK_SET);
pp->printf("%d\n", u + 1);
delete pp;
pp = NULL;
fn = MDFN_MakeFName(MDFNMKF_SNAP, u, "png");
PNGWrite(fn.c_str(), src, *rect, LineWidths);
MDFN_DispMessage(_("Screen snapshot %d saved."), u);
}
catch(std::exception &e)
{
if(pp)
{
delete pp;
pp = NULL;
}
MDFN_PrintError(_("Error saving screen snapshot: %s"), e.what());
MDFN_DispMessage(_("Error saving screen snapshot: %s"), e.what());
}
} }
void MDFN_DispMessage(const char *format, ...) throw() void MDFN_DispMessage(const char *format, ...) throw()