faster compiles (mappers include 1/3 as much code now)

fix some memory leaks by changing the path generation APIs to return std::string.. but it still gets strdupped by a lot of clients. 
switch over more movie and savestate code to use iostreams instead of stdio
remove the temporary savestate stuff for more tasing speed hopefully
This commit is contained in:
zeromus 2008-06-17 06:55:07 +00:00
parent 1a725b5850
commit e0a14909f0
46 changed files with 3764 additions and 3861 deletions

View File

@ -8,4 +8,3 @@
#include "../cart.h"
#include "../cheat.h"
#include "../unif.h"
#include <string.h>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,7 @@
#include "types.h"
#include "fceu.h"
#include "driver.h"
static char *aboutString = 0;

View File

@ -386,14 +386,14 @@ int getValue(int type)
case 'A': return _A;
case 'X': return _X;
case 'Y': return _Y;
case 'N': return _P & N_FLAG ? 1 : 0;
case 'V': return _P & V_FLAG ? 1 : 0;
case 'U': return _P & U_FLAG ? 1 : 0;
case 'B': return _P & B_FLAG ? 1 : 0;
case 'D': return _P & D_FLAG ? 1 : 0;
case 'I': return _P & I_FLAG ? 1 : 0;
case 'Z': return _P & Z_FLAG ? 1 : 0;
case 'C': return _P & C_FLAG ? 1 : 0;
case 'N': return __P & N_FLAG ? 1 : 0;
case 'V': return __P & V_FLAG ? 1 : 0;
case 'U': return __P & U_FLAG ? 1 : 0;
case 'B': return __P & B_FLAG ? 1 : 0;
case 'D': return __P & D_FLAG ? 1 : 0;
case 'I': return __P & I_FLAG ? 1 : 0;
case 'Z': return __P & Z_FLAG ? 1 : 0;
case 'C': return __P & C_FLAG ? 1 : 0;
case 'P': return _PC;
}

View File

@ -3,6 +3,7 @@
#include "drawing.h"
#include "video.h"
#include "movie.h"
#include "driver.h"
static uint8 Font6x5[594] =
{

View File

@ -3,13 +3,15 @@
#include <stdio.h>
#include <string>
#include <fstream>
#include <iosfwd>
#include "types.h"
#include "git.h"
FILE *FCEUD_UTF8fopen(const char *fn, const char *mode);
inline FILE *FCEUD_UTF8fopen(const std::string &n, const char *mode) { return FCEUD_UTF8fopen(n.c_str(),mode); }
std::fstream* FCEUD_UTF8_fstream(const char *n, const char *m);
inline std::fstream* FCEUD_UTF8_fstream(const std::string &n, const char *m) { return FCEUD_UTF8_fstream(n.c_str(),m); }
//mbg 7/23/06
@ -188,7 +190,7 @@ void FCEUI_LoadMovie(char *fname, bool read_only, int _stopframe);
void FCEUI_MoviePlayFromBeginning(void);
void FCEUI_StopMovie(void);
//int FCEUI_IsMovieActive(void);
bool FCEUI_MovieGetInfo(const char* fname, MOVIE_INFO* /* [in, out] */ info, bool skipFrameCount = false);
bool FCEUI_MovieGetInfo(const std::string& fname, MOVIE_INFO* /* [in, out] */ info, bool skipFrameCount = false);
char* FCEUI_MovieGetCurrentName(int addSlotNumber);
void FCEUI_MovieToggleReadOnly(void);
bool FCEUI_GetMovieToggleReadOnly();

View File

@ -2029,7 +2029,8 @@ static bool SaveBasicBot()
ofn.lpstrFile=nameo;
ofn.nMaxFile=256;
ofn.Flags=OFN_EXPLORER|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT;
ofn.lpstrInitialDir=FCEU_GetPath(FCEUMKF_BBOT);
std::string initdir = FCEU_GetPath(FCEUMKF_BBOT);
ofn.lpstrInitialDir=initdir.c_str();
if(GetSaveFileName(&ofn))
{
/*
@ -2107,11 +2108,11 @@ static bool SaveBasicBotFile(char fn[])
error(1005);
return false;
}
/**
* Loads a previously saved file
* todo: need to add ensurance that saved file has the same BOT_MAXCODE value
* as currently set, or offer some kind of support for this "problem"
**/
// Loads a previously saved file
// todo: need to add ensurance that saved file has the same BOT_MAXCODE value
// as currently set, or offer some kind of support for this "problem"
//
static bool LoadBasicBot()
{
const char filter[]="Basic Bot (*.bot)\0*.bot\0";
@ -2126,7 +2127,8 @@ static bool LoadBasicBot()
ofn.lpstrFile=nameo;
ofn.nMaxFile=256;
ofn.Flags=OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;
ofn.lpstrInitialDir=FCEU_GetPath(FCEUMKF_BBOT);
std::string initdir = FCEU_GetPath(FCEUMKF_BBOT);
ofn.lpstrInitialDir=initdir.c_str();
if(GetOpenFileName(&ofn))
{

View File

@ -1460,7 +1460,8 @@ static void PresetExport(int preset)
ofn.lpstrFile=nameo;
ofn.nMaxFile=256;
ofn.Flags=OFN_EXPLORER|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT;
ofn.lpstrInitialDir=FCEU_GetPath(FCEUMKF_INPUT);
std::string initdir = FCEU_GetPath(FCEUMKF_INPUT).c_str();
ofn.lpstrInitialDir=initdir.c_str();
if(GetSaveFileName(&ofn))
{
int i;
@ -1517,7 +1518,8 @@ static void PresetImport(int preset)
ofn.lpstrFile=nameo;
ofn.nMaxFile=256;
ofn.Flags=OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;
ofn.lpstrInitialDir=FCEU_GetPath(FCEUMKF_INPUT);
std::string initdir = FCEU_GetPath(FCEUMKF_INPUT);
ofn.lpstrInitialDir=initdir.c_str();
if(GetOpenFileName(&ofn))
{

View File

@ -32,6 +32,8 @@
#include <shlobj.h> // For directories configuration dialog.
#undef uint8
#include <fstream>
#include "../../types.h"
#include "../../fceu.h"
#include "../../state.h"

View File

@ -363,7 +363,8 @@ static void SaveMemWatch()
ofn.lpstrFile=memwLastFilename;
ofn.nMaxFile=256;
ofn.Flags=OFN_EXPLORER|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT;
ofn.lpstrInitialDir=FCEU_GetPath(FCEUMKF_MEMW);
std::string initdir = FCEU_GetPath(FCEUMKF_MEMW);
ofn.lpstrInitialDir=initdir.c_str();
if(GetSaveFileName(&ofn))
{
int i;
@ -478,7 +479,8 @@ static void LoadMemWatch()
ofn.lpstrFile=memwLastFilename;
ofn.nMaxFile=256;
ofn.Flags=OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;
ofn.lpstrInitialDir=FCEU_GetPath(FCEUMKF_MEMW);
std::string initdir = FCEU_GetPath(FCEUMKF_MEMW);
ofn.lpstrInitialDir=initdir.c_str();
if(GetOpenFileName(&ofn))
{

View File

@ -44,7 +44,7 @@ static char* GetReplayPath(HWND hwndDlg)
_splitpath(szChoice, szDrive, szDirectory, szFilename, szExt);
if(szDrive[0]=='\0' && szDirectory[0]=='\0')
fn=FCEU_MakePath(FCEUMKF_MOVIE, szChoice); // need to make a full path
fn=strdup(FCEU_MakePath(FCEUMKF_MOVIE, szChoice).c_str()); // need to make a full path
else
fn=strdup(szChoice); // given a full path
}
@ -66,7 +66,7 @@ static char* GetRecordPath(HWND hwndDlg)
_splitpath(szChoice, szDrive, szDirectory, szFilename, szExt);
if(szDrive[0]=='\0' && szDirectory[0]=='\0')
fn=FCEU_MakePath(FCEUMKF_MOVIE, szChoice); // need to make a full path
fn=strdup(FCEU_MakePath(FCEUMKF_MOVIE, szChoice).c_str()); // need to make a full path
else
fn=strdup(szChoice); // given a full path
@ -89,7 +89,7 @@ static char* GetSavePath(HWND hwndDlg)
_splitpath(fn, szDrive, szDirectory, szFilename, szExt);
if(szDrive[0]=='\0' && szDirectory[0]=='\0')
{
char* newfn=FCEU_MakePath(FCEUMKF_STATE, fn); // need to make a full path
char* newfn=strdup(FCEU_MakePath(FCEUMKF_STATE, fn).c_str()); // need to make a full path
free(fn);
fn=newfn;
}
@ -255,11 +255,8 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
SendDlgItemMessage(hwndDlg, IDC_CHECK_READONLY, BM_SETCHECK, replayReadOnlySetting?BST_CHECKED:BST_UNCHECKED, 0);
SendDlgItemMessage(hwndDlg, IDC_CHECK_STOPMOVIE,BM_SETCHECK, BST_UNCHECKED, 0);
char* findGlob[2] = {FCEU_MakeFName(FCEUMKF_MOVIEGLOB, 0, 0),
FCEU_MakeFName(FCEUMKF_MOVIEGLOB2, 0, 0)};
extern int suppress_scan_chunks;
suppress_scan_chunks=1;
char* findGlob[2] = {strdup(FCEU_MakeFName(FCEUMKF_MOVIEGLOB, 0, 0).c_str()),
strdup(FCEU_MakeFName(FCEUMKF_MOVIEGLOB2, 0, 0).c_str())};
int i=0, j=0;
@ -372,8 +369,6 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
}
}
suppress_scan_chunks=0;
free(findGlob[0]);
free(findGlob[1]);
@ -427,7 +422,7 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
if(lIndex == lCount-1)
{
// pop open a file browser...
char *pn=FCEU_GetPath(FCEUMKF_MOVIE);
char *pn=strdup(FCEU_GetPath(FCEUMKF_MOVIE).c_str());
char szFile[MAX_PATH]={0};
OPENFILENAME ofn;
//int nRet; //mbg merge 7/17/06 removed
@ -564,7 +559,7 @@ static void UpdateRecordDialog(HWND hwndDlg)
static void UpdateRecordDialogPath(HWND hwndDlg, const char* fname)
{
char* baseMovieDir = FCEU_GetPath(FCEUMKF_MOVIE);
char* baseMovieDir = strdup(FCEU_GetPath(FCEUMKF_MOVIE).c_str());
char* fn=0;
// display a shortened filename if the file exists in the base movie directory
@ -603,7 +598,7 @@ static BOOL CALLBACK RecordDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP
// Populate the "record from..." dialog
{
char* findGlob=FCEU_MakeFName(FCEUMKF_STATEGLOB, 0, 0);
char* findGlob=strdup(FCEU_MakeFName(FCEUMKF_STATEGLOB, 0, 0).c_str());
WIN32_FIND_DATA wfd;
HANDLE hFind;
int i=0;
@ -731,7 +726,7 @@ static BOOL CALLBACK RecordDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP
void FCEUD_MovieRecordTo()
{
struct CreateMovieParameters p;
p.szFilename = FCEU_MakeFName(FCEUMKF_MOVIE,0,0);
p.szFilename = strdup(FCEU_MakeFName(FCEUMKF_MOVIE,0,0).c_str());
if(DialogBoxParam(fceu_hInstance, "IDD_RECORDINP", hAppWnd, RecordDialogProc, (LPARAM)&p))
{

View File

@ -1,4 +1,5 @@
#include <set>
#include <fstream>
#include "common.h"
#include "tasedit.h"
@ -305,7 +306,8 @@ static void Export()
ofn.lpstrFilter=filter;
ofn.lpstrFile=fname;
ofn.nMaxFile=256;
ofn.lpstrInitialDir=FCEU_GetPath(FCEUMKF_MOVIE);
std::string initdir = FCEU_GetPath(FCEUMKF_MOVIE);
ofn.lpstrInitialDir=initdir.c_str();
if(GetSaveFileName(&ofn))
{
fstream* osRecordingMovie = FCEUD_UTF8_fstream(ofn.lpstrFile, "wb");

View File

@ -21,6 +21,7 @@
#include "../../types.h"
#include "../../fceu.h"
#include "windows.h"
#include "driver.h"
static uint64 tmethod,tfreq;
static uint64 desiredfps;

View File

@ -504,7 +504,8 @@ void LoadNewGamey(HWND hParent, const char *initialdir)
ofn.lpstrFile=nameo;
ofn.nMaxFile=256;
ofn.Flags=OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY; //OFN_EXPLORER|OFN_ENABLETEMPLATE|OFN_ENABLEHOOK;
ofn.lpstrInitialDir = initialdir ? initialdir : FCEU_GetPath(FCEUMKF_ROMS);
std::string stdinitdir =FCEU_GetPath(FCEUMKF_ROMS);
ofn.lpstrInitialDir = initialdir ? initialdir : stdinitdir.c_str();
// Show the Open File dialog
if(GetOpenFileName(&ofn))

View File

@ -316,7 +316,7 @@ FCEUGI *FCEUI_LoadGame(const char *name, int OverwriteVidMode)
FCEU_printf("Loading %s...\n\n",name);
GetFileBase(name);
ipsfn=FCEU_MakeFName(FCEUMKF_IPS,0,0);
ipsfn=strdup(FCEU_MakeFName(FCEUMKF_IPS,0,0).c_str());
fp=FCEU_fopen(name,ipsfn,"rb",0);
free(ipsfn);
@ -817,7 +817,7 @@ void UpdateRewind(void)
if(RewindCounter == 0)
{
RewindIndex = (RewindIndex + 1) % 4;
f = FCEU_MakeFName(FCEUMKF_REWINDSTATE,RewindIndex,0);
f = strdup(FCEU_MakeFName(FCEUMKF_REWINDSTATE,RewindIndex,0).c_str());
FCEUSS_Save(f);
free(f);
RewindStatus[RewindIndex] = 1;
@ -832,7 +832,7 @@ void FCEUI_Rewind(void)
if(RewindStatus[RewindIndex] == 1)
{
char * f;
f = FCEU_MakeFName(FCEUMKF_REWINDSTATE,RewindIndex,0);
f = strdup(FCEU_MakeFName(FCEUMKF_REWINDSTATE,RewindIndex,0).c_str());
FCEUSS_Load(f);
free(f);

View File

@ -1,9 +1,6 @@
#ifndef _FCEUH
#define _FCEUH
#include <iostream>
#include <sstream>
extern int fceuindbg;
void ResetGameLoaded(void);
@ -65,7 +62,7 @@ extern int GameAttributes;
extern uint8 PAL;
#include "driver.h"
//#include "driver.h"
typedef struct {
int PAL;

File diff suppressed because it is too large Load Diff

View File

@ -635,92 +635,93 @@ void FCEUI_SetDirOverride(int which, char *n)
}
#endif
char* FCEU_GetPath(int type)
std::string FCEU_GetPath(int type)
{
char *ret=0;
char ret[FILENAME_MAX];
switch(type)
{
case FCEUMKF_STATE:
if(odirs[FCEUIOD_STATES])
ret=strdup(odirs[FCEUIOD_STATES]);
return (odirs[FCEUIOD_STATES]);
else
asprintf(&ret,"%s"PSS"fcs",BaseDirectory);
sprintf(ret,"%s"PSS"fcs",BaseDirectory);
break;
case FCEUMKF_MOVIE:
if(odirs[FCEUIOD_MOVIES])
ret=strdup(odirs[FCEUIOD_MOVIES]);
return (odirs[FCEUIOD_MOVIES]);
else
asprintf(&ret,"%s"PSS"movies",BaseDirectory);
sprintf(ret,"%s"PSS"movies",BaseDirectory);
break;
case FCEUMKF_MEMW:
if(odirs[FCEUIOD_MEMW])
ret=strdup(odirs[FCEUIOD_MEMW]);
return (odirs[FCEUIOD_MEMW]);
else
asprintf(&ret,"%s"PSS"tools",BaseDirectory);
sprintf(ret,"%s"PSS"tools",BaseDirectory);
break;
case FCEUMKF_BBOT:
if(odirs[FCEUIOD_BBOT])
ret=strdup(odirs[FCEUIOD_BBOT]);
return (odirs[FCEUIOD_BBOT]);
else
asprintf(&ret,"%s"PSS"tools",BaseDirectory);
sprintf(ret,"%s"PSS"tools",BaseDirectory);
break;
case FCEUMKF_ROMS:
if(odirs[FCEUIOD_ROMS])
ret=strdup(odirs[FCEUIOD_ROMS]);
return (odirs[FCEUIOD_ROMS]);
else
asprintf(&ret,"%s",BaseDirectory);
sprintf(ret,"%s",BaseDirectory);
break;
case FCEUMKF_INPUT:
if(odirs[FCEUIOD_INPUT])
ret=strdup(odirs[FCEUIOD_INPUT]);
return (odirs[FCEUIOD_INPUT]);
else
asprintf(&ret,"%s"PSS"tools",BaseDirectory);
sprintf(ret,"%s"PSS"tools",BaseDirectory);
break;
case FCEUMKF_LUA:
if(odirs[FCEUIOD_LUA])
ret=strdup(odirs[FCEUIOD_LUA]);
return (odirs[FCEUIOD_LUA]);
else
asprintf(&ret,"%s"PSS"tools",BaseDirectory);
sprintf(ret,"%s"PSS"tools",BaseDirectory);
break;
}
return(ret);
return ret;
}
char *FCEU_MakePath(int type, const char* filebase)
std::string FCEU_MakePath(int type, const char* filebase)
{
char *ret=0;
char ret[FILENAME_MAX];
switch(type)
{
case FCEUMKF_MOVIE:
if(odirs[FCEUIOD_MOVIES])
asprintf(&ret,"%s"PSS"%s",odirs[FCEUIOD_MOVIES],filebase);
sprintf(ret,"%s"PSS"%s",odirs[FCEUIOD_MOVIES],filebase);
else
asprintf(&ret,"%s"PSS"movies"PSS"%s",BaseDirectory,filebase);
sprintf(ret,"%s"PSS"movies"PSS"%s",BaseDirectory,filebase);
break;
case FCEUMKF_STATE:
if(odirs[FCEUIOD_STATES])
asprintf(&ret,"%s"PSS"%s",odirs[FCEUIOD_STATES],filebase);
sprintf(ret,"%s"PSS"%s",odirs[FCEUIOD_STATES],filebase);
else
asprintf(&ret,"%s"PSS"fcs"PSS"%s",BaseDirectory,filebase);
sprintf(ret,"%s"PSS"fcs"PSS"%s",BaseDirectory,filebase);
break;
}
return(ret);
return ret;
}
char *FCEU_MakeFName(int type, int id1, char *cd1)
std::string FCEU_MakeFName(int type, int id1, char *cd1)
{
char *ret=0;
char ret[FILENAME_MAX];
struct stat tmpstat;
switch(type)
{
case FCEUMKF_NPTEMP: asprintf(&ret,"%s"PSS"m590plqd94fo.tmp",BaseDirectory);break;
case FCEUMKF_NPTEMP: sprintf(ret,"%s"PSS"m590plqd94fo.tmp",BaseDirectory);break;
case FCEUMKF_MOVIE:
if(odirs[FCEUIOD_MOVIES])
asprintf(&ret,"%s"PSS"%s.fm2",odirs[FCEUIOD_MOVIES],FileBase);
sprintf(ret,"%s"PSS"%s.fm2",odirs[FCEUIOD_MOVIES],FileBase);
else
asprintf(&ret,"%s"PSS"movies"PSS"%s.fm2",BaseDirectory,FileBase);
sprintf(ret,"%s"PSS"movies"PSS"%s.fm2",BaseDirectory,FileBase);
break;
case FCEUMKF_STATE:
{
@ -736,21 +737,21 @@ char *FCEU_MakeFName(int type, int id1, char *cd1)
if(odirs[FCEUIOD_STATES])
{
asprintf(&ret,"%s"PSS"%s%s.fc%d",odirs[FCEUIOD_STATES],FileBase,mfn,id1);
sprintf(ret,"%s"PSS"%s%s.fc%d",odirs[FCEUIOD_STATES],FileBase,mfn,id1);
}
else
{
asprintf(&ret,"%s"PSS"fcs"PSS"%s%s.fc%d",BaseDirectory,FileBase,mfn,id1);
sprintf(ret,"%s"PSS"fcs"PSS"%s%s.fc%d",BaseDirectory,FileBase,mfn,id1);
}
if(stat(ret,&tmpstat)==-1)
{
if(odirs[FCEUIOD_STATES])
{
asprintf(&ret,"%s"PSS"%s%s.fc%d",odirs[FCEUIOD_STATES],FileBase,mfn,id1);
sprintf(ret,"%s"PSS"%s%s.fc%d",odirs[FCEUIOD_STATES],FileBase,mfn,id1);
}
else
{
asprintf(&ret,"%s"PSS"fcs"PSS"%s%s.fc%d",BaseDirectory,FileBase,mfn,id1);
sprintf(ret,"%s"PSS"fcs"PSS"%s%s.fc%d",BaseDirectory,FileBase,mfn,id1);
}
}
}
@ -759,89 +760,90 @@ char *FCEU_MakeFName(int type, int id1, char *cd1)
if(FSettings.SnapName)
{
if(odirs[FCEUIOD_SNAPS])
asprintf(&ret,"%s"PSS"%s-%d.%s",odirs[FCEUIOD_SNAPS],FileBase,id1,cd1);
sprintf(ret,"%s"PSS"%s-%d.%s",odirs[FCEUIOD_SNAPS],FileBase,id1,cd1);
else
asprintf(&ret,"%s"PSS"snaps"PSS"%s-%d.%s",BaseDirectory,FileBase,id1,cd1);
sprintf(ret,"%s"PSS"snaps"PSS"%s-%d.%s",BaseDirectory,FileBase,id1,cd1);
}
else
{
if(odirs[FCEUIOD_SNAPS])
asprintf(&ret,"%s"PSS"%d.%s",odirs[FCEUIOD_SNAPS],id1,cd1);
sprintf(ret,"%s"PSS"%d.%s",odirs[FCEUIOD_SNAPS],id1,cd1);
else
asprintf(&ret,"%s"PSS"snaps"PSS"%d.%s",BaseDirectory,id1,cd1);
sprintf(ret,"%s"PSS"snaps"PSS"%d.%s",BaseDirectory,id1,cd1);
}
break;
case FCEUMKF_FDS:
if(odirs[FCEUIOD_NV])
asprintf(&ret,"%s"PSS"%s.fds",odirs[FCEUIOD_NV],FileBase);
sprintf(ret,"%s"PSS"%s.fds",odirs[FCEUIOD_NV],FileBase);
else
asprintf(&ret,"%s"PSS"sav"PSS"%s.fds",BaseDirectory,FileBase);
sprintf(ret,"%s"PSS"sav"PSS"%s.fds",BaseDirectory,FileBase);
break;
case FCEUMKF_SAV:
if(odirs[FCEUIOD_NV])
asprintf(&ret,"%s"PSS"%s.%s",odirs[FCEUIOD_NV],FileBase,cd1);
sprintf(ret,"%s"PSS"%s.%s",odirs[FCEUIOD_NV],FileBase,cd1);
else
asprintf(&ret,"%s"PSS"sav"PSS"%s.%s",BaseDirectory,FileBase,cd1);
sprintf(ret,"%s"PSS"sav"PSS"%s.%s",BaseDirectory,FileBase,cd1);
if(stat(ret,&tmpstat)==-1)
{
if(odirs[FCEUIOD_NV])
asprintf(&ret,"%s"PSS"%s.%s",odirs[FCEUIOD_NV],FileBase,cd1);
sprintf(ret,"%s"PSS"%s.%s",odirs[FCEUIOD_NV],FileBase,cd1);
else
asprintf(&ret,"%s"PSS"sav"PSS"%s.%s",BaseDirectory,FileBase,cd1);
sprintf(ret,"%s"PSS"sav"PSS"%s.%s",BaseDirectory,FileBase,cd1);
}
break;
case FCEUMKF_REWINDSTATE:
if(odirs[FCEUIOD_STATES])
{
asprintf(&ret,"%s"PSS"rewind%d.fcs",odirs[FCEUIOD_STATES],id1);
sprintf(ret,"%s"PSS"rewind%d.fcs",odirs[FCEUIOD_STATES],id1);
}
else
{
asprintf(&ret,"%s"PSS"fcs"PSS"rewind%d.fcs",BaseDirectory,id1);
sprintf(ret,"%s"PSS"fcs"PSS"rewind%d.fcs",BaseDirectory,id1);
}
if(stat(ret,&tmpstat)==-1)
{
if(odirs[FCEUIOD_STATES])
{
asprintf(&ret,"%s"PSS"rewind%d.fcs",odirs[FCEUIOD_STATES],id1);
sprintf(ret,"%s"PSS"rewind%d.fcs",odirs[FCEUIOD_STATES],id1);
}
else
{
asprintf(&ret,"%s"PSS"fcs"PSS"rewind%d.fcs",BaseDirectory,id1);
sprintf(ret,"%s"PSS"fcs"PSS"rewind%d.fcs",BaseDirectory,id1);
}
}
break;
case FCEUMKF_CHEAT:
if(odirs[FCEUIOD_CHEATS])
asprintf(&ret,"%s"PSS"%s.cht",odirs[FCEUIOD_CHEATS],FileBase);
sprintf(ret,"%s"PSS"%s.cht",odirs[FCEUIOD_CHEATS],FileBase);
else
asprintf(&ret,"%s"PSS"cheats"PSS"%s.cht",BaseDirectory,FileBase);
sprintf(ret,"%s"PSS"cheats"PSS"%s.cht",BaseDirectory,FileBase);
break;
case FCEUMKF_IPS:asprintf(&ret,"%s"PSS"%s%s.ips",FileBaseDirectory,FileBase,FileExt);break;
case FCEUMKF_GGROM:asprintf(&ret,"%s"PSS"gg.rom",BaseDirectory);break;
case FCEUMKF_IPS:sprintf(ret,"%s"PSS"%s%s.ips",FileBaseDirectory,FileBase,FileExt);break;
case FCEUMKF_GGROM:sprintf(ret,"%s"PSS"gg.rom",BaseDirectory);break;
case FCEUMKF_FDSROM:
if(odirs[FCEUIOD_FDSROM])
asprintf(&ret,"%s"PSS"disksys.rom",odirs[FCEUIOD_FDSROM]);
sprintf(ret,"%s"PSS"disksys.rom",odirs[FCEUIOD_FDSROM]);
else
asprintf(&ret,"%s"PSS"disksys.rom",BaseDirectory);
sprintf(ret,"%s"PSS"disksys.rom",BaseDirectory);
break;
case FCEUMKF_PALETTE:asprintf(&ret,"%s"PSS"%s.pal",BaseDirectory,FileBase);break;
case FCEUMKF_PALETTE:sprintf(ret,"%s"PSS"%s.pal",BaseDirectory,FileBase);break;
case FCEUMKF_MOVIEGLOB:
//these globs use ??? because we can load multiple formats
if(odirs[FCEUIOD_MOVIES])
asprintf(&ret,"%s"PSS"*.???",odirs[FCEUIOD_MOVIES]);
sprintf(ret,"%s"PSS"*.???",odirs[FCEUIOD_MOVIES]);
else
asprintf(&ret,"%s"PSS"movies"PSS"*.???",BaseDirectory);
sprintf(ret,"%s"PSS"movies"PSS"*.???",BaseDirectory);
break;
case FCEUMKF_MOVIEGLOB2:asprintf(&ret,"%s"PSS"*.???",BaseDirectory);break;
case FCEUMKF_MOVIEGLOB2:sprintf(ret,"%s"PSS"*.???",BaseDirectory);break;
case FCEUMKF_STATEGLOB:
if(odirs[FCEUIOD_STATES])
asprintf(&ret,"%s"PSS"%s*.fc?",odirs[FCEUIOD_STATES],FileBase);
sprintf(ret,"%s"PSS"%s*.fc?",odirs[FCEUIOD_STATES],FileBase);
else
asprintf(&ret,"%s"PSS"fcs"PSS"%s*.fc?",BaseDirectory,FileBase);
sprintf(ret,"%s"PSS"fcs"PSS"%s*.fc?",BaseDirectory,FileBase);
break;
}
return(ret);
return ret;
}
void GetFileBase(const char *f)

View File

@ -1,6 +1,8 @@
#ifndef _FCEU_FILE_H_
#define _FCEU_FILE_H_
#include <string>
typedef struct {
void *fp; // FILE* or ptr to ZIPWRAP
uint32 type; // 0=normal file, 1=gzip, 2=zip
@ -22,9 +24,9 @@ int FCEU_fisarchive(FCEUFILE*);
void GetFileBase(const char *f);
char* FCEU_GetPath(int type);
char *FCEU_MakePath(int type, const char* filebase);
char *FCEU_MakeFName(int type, int id1, char *cd1);
std::string FCEU_GetPath(int type);
std::string FCEU_MakePath(int type, const char* filebase);
std::string FCEU_MakeFName(int type, int id1, char *cd1);
#define FCEUMKF_STATE 1
#define FCEUMKF_SNAP 2

View File

@ -44,6 +44,7 @@
#include "utils/md5.h"
#include "cheat.h"
#include "vsuni.h"
#include "driver.h"
extern SFORMAT FCEUVSUNI_STATEINFO[];

View File

@ -37,6 +37,7 @@
#include "input.h"
#include "vsuni.h"
#include "fds.h"
#include "driver.h"
// qfox: For UpdateExternalButton(), called when the
// botmode state changes, to update a label in gui.

View File

@ -4,6 +4,7 @@
#include <assert.h>
#include <zlib.h>
#include <iomanip>
#include <fstream>
#ifdef WIN32
#include <windows.h>
@ -19,6 +20,7 @@
#include "file.h"
#include "video.h"
#include "movie.h"
#include "utils/guid.h"
#include "utils/memory.h"
#include "utils/memorystream.h"
#include "utils/xstring.h"
@ -338,7 +340,7 @@ bool FCEUMOV_Mode(int modemask)
}
//yuck... another custom text parser.
void LoadFM2(MovieData& movieData, std::istream* fp, bool stopAfterHeader = false)
static void LoadFM2(MovieData& movieData, std::istream* fp, int size=-1, bool stopAfterHeader = false)
{
std::string key,value;
enum {
@ -348,6 +350,7 @@ void LoadFM2(MovieData& movieData, std::istream* fp, bool stopAfterHeader = fals
for(;;)
{
bool iswhitespace, isrecchar, isnewline;
if(size--==0) goto bail;
int c = fp->get();
if(c == -1)
goto bail;
@ -506,15 +509,8 @@ void FCEUMOV_ExitTasEdit()
bool MovieData::loadSavestateFrom(std::vector<char>* buf)
{
//dump the savestate to disk
FILE* fp = tmpfile();
fwrite(&(*buf)[0],1,buf->size(),fp);
fseek(fp,0,SEEK_SET);
//and load the state
bool success = FCEUSS_LoadFP(fp,SSLOADPARAM_BACKUP);
fclose(fp);
return success;
memorystream ms(buf);
return FCEUSS_LoadFP(&ms,SSLOADPARAM_BACKUP);
}
void MovieData::dumpSavestateTo(std::vector<char>* buf, int compressionLevel)
@ -780,22 +776,22 @@ int FCEUMOV_WriteState(std::ostream* os)
static bool load_successful;
bool FCEUMOV_ReadState(FILE* st, uint32 size)
bool FCEUMOV_ReadState(std::istream* is, uint32 size)
{
load_successful = false;
//write the state to disk so we can reload
std::vector<char> buf(size);
fread(&buf[0],1,size,st);
//---------
//(debug)
//FILE* wtf = fopen("d:\\wtf.txt","wb");
//fwrite(&buf[0],1,size,wtf);
//fclose(wtf);
//---------
memorystream mstemp(&buf);
////write the state to disk so we can reload
//std::vector<char> buf(size);
//fread(&buf[0],1,size,st);
////---------
////(debug)
////FILE* wtf = fopen("d:\\wtf.txt","wb");
////fwrite(&buf[0],1,size,wtf);
////fclose(wtf);
////---------
//memorystream mstemp(&buf);
MovieData tempMovieData = MovieData();
LoadFM2(tempMovieData, &mstemp);
LoadFM2(tempMovieData, is);
//complex TAS logic for when a savestate is loaded:
//----------------
@ -934,7 +930,7 @@ void FCEUI_MoviePlayFromBeginning(void)
}
bool FCEUI_MovieGetInfo(const char* fname, MOVIE_INFO* info, bool skipFrameCount)
bool FCEUI_MovieGetInfo(const std::string& fname, MOVIE_INFO* info, bool skipFrameCount)
{
memset(info,0,sizeof(MOVIE_INFO));

View File

@ -7,6 +7,7 @@
#include <ostream>
#include "input/zapper.h"
#include "utils/guid.h"
void FCEUMOV_AddInputState();
void FCEUMOV_AddCommand(int cmd);
@ -33,7 +34,7 @@ bool FCEUMOV_ShouldPause(void);
int FCEUMOV_GetFrame(void);
int FCEUMOV_WriteState(std::ostream* os);
bool FCEUMOV_ReadState(FILE* st, uint32 size);
bool FCEUMOV_ReadState(std::istream* is, uint32 size);
void FCEUMOV_PreLoad();
bool FCEUMOV_PostLoad();

View File

@ -1,22 +1,22 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2002 Xodnizel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
*
* Copyright notice for this file:
* Copyright (C) 2002 Xodnizel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
@ -35,44 +35,43 @@
#include "state.h"
#include "cheat.h"
#include "input.h"
#include "driver.h"
int FCEUnetplay=0;
static uint8 netjoy[4]; /* Controller cache. */
static uint8 netjoy[4]; // Controller cache.
static int numlocal;
static int netdivisor;
static int netdcount;
/* NetError should only be called after a FCEUD_*Data function returned 0, in the function
that called FCEUD_*Data, to prevent it from being called twice.
*/
//NetError should only be called after a FCEUD_*Data function returned 0, in the function
//that called FCEUD_*Data, to prevent it from being called twice.
static void NetError(void)
{
FCEU_DispMessage("Network error/connection lost!");
FCEUD_NetworkClose();
FCEU_DispMessage("Network error/connection lost!");
FCEUD_NetworkClose();
}
void FCEUI_NetplayStop(void)
{
if(FCEUnetplay)
{
FCEUnetplay = 0;
FCEU_FlushGameCheats(0,1); /* Don't save netplay cheats. */
FCEU_LoadGameCheats(0); /* Reload our original cheats. */
FCEUnetplay = 0;
FCEU_FlushGameCheats(0,1); //Don't save netplay cheats.
FCEU_LoadGameCheats(0); //Reload our original cheats.
}
else puts("Check your code!");
}
int FCEUI_NetplayStart(int nlocal, int divisor)
{
FCEU_FlushGameCheats(0, 0); /* Save our pre-netplay cheats. */
FCEU_LoadGameCheats(0); /* Load them again, for pre-multiplayer
action.
*/
FCEU_FlushGameCheats(0, 0); //Save our pre-netplay cheats.
FCEU_LoadGameCheats(0); // Load them again, for pre-multiplayer action.
FCEUnetplay = 1;
memset(netjoy,0,sizeof(netjoy));
numlocal = nlocal;
memset(netjoy,0,sizeof(netjoy));
numlocal = nlocal;
netdivisor = divisor;
netdcount = 0;
return(1);
@ -80,249 +79,252 @@ int FCEUI_NetplayStart(int nlocal, int divisor)
int FCEUNET_SendCommand(uint8 cmd, uint32 len)
{
//mbg merge 7/17/06 changed to alloca
//uint8 buf[numlocal + 1 + 4];
uint8 *buf = (uint8*)alloca(numlocal+1+4);
//mbg merge 7/17/06 changed to alloca
//uint8 buf[numlocal + 1 + 4];
uint8 *buf = (uint8*)alloca(numlocal+1+4);
buf[0] = 0xFF;
FCEU_en32lsb(&buf[numlocal], len);
buf[numlocal + 4] = cmd;
if(!FCEUD_SendData(buf,numlocal + 1 + 4))
{
NetError();
return(0);
}
return(1);
buf[0] = 0xFF;
FCEU_en32lsb(&buf[numlocal], len);
buf[numlocal + 4] = cmd;
if(!FCEUD_SendData(buf,numlocal + 1 + 4))
{
NetError();
return(0);
}
return(1);
}
void FCEUI_NetplayText(uint8 *text)
{
uint32 len;
uint32 len;
len = strlen((char*)text); //mbg merge 7/17/06 added cast
len = strlen((char*)text); //mbg merge 7/17/06 added cast
if(!FCEUNET_SendCommand(FCEUNPCMD_TEXT,len)) return;
if(!FCEUNET_SendCommand(FCEUNPCMD_TEXT,len)) return;
if(!FCEUD_SendData(text,len))
NetError();
if(!FCEUD_SendData(text,len))
NetError();
}
int FCEUNET_SendFile(uint8 cmd, char *fn)
{
uint32 len;
uLongf clen;
char *buf, *cbuf;
FILE *fp;
struct stat sb;
uint32 len;
uLongf clen;
char *buf, *cbuf;
FILE *fp;
struct stat sb;
if(!(fp=FCEUD_UTF8fopen(fn,"rb"))) return(0);
if(!(fp=FCEUD_UTF8fopen(fn,"rb"))) return(0);
fstat(fileno(fp),&sb);
len = sb.st_size;
buf = (char*)malloc(len); //mbg merge 7/17/06 added cast
fread(buf, 1, len, fp);
fclose(fp);
fstat(fileno(fp),&sb);
len = sb.st_size;
buf = (char*)malloc(len); //mbg merge 7/17/06 added cast
fread(buf, 1, len, fp);
fclose(fp);
cbuf = (char*)malloc(4 + len + len / 1000 + 12); //mbg merge 7/17/06 added cast
FCEU_en32lsb((uint8*)cbuf, len); //mbg merge 7/17/06 added cast
compress2((uint8*)cbuf + 4, &clen, (uint8*)buf, len, 7); //mbg merge 7/17/06 added casts
free(buf);
cbuf = (char*)malloc(4 + len + len / 1000 + 12); //mbg merge 7/17/06 added cast
FCEU_en32lsb((uint8*)cbuf, len); //mbg merge 7/17/06 added cast
compress2((uint8*)cbuf + 4, &clen, (uint8*)buf, len, 7); //mbg merge 7/17/06 added casts
free(buf);
//printf("Sending file: %s, %d, %d\n",fn,len,clen);
//printf("Sending file: %s, %d, %d\n",fn,len,clen);
len = clen + 4;
len = clen + 4;
if(!FCEUNET_SendCommand(cmd,len))
{
free(cbuf);
return(0);
}
if(!FCEUD_SendData(cbuf, len))
{
NetError();
free(cbuf);
return(0);
}
free(cbuf);
if(!FCEUNET_SendCommand(cmd,len))
{
free(cbuf);
return(0);
}
if(!FCEUD_SendData(cbuf, len))
{
NetError();
free(cbuf);
return(0);
}
free(cbuf);
return(1);
return(1);
}
static FILE *FetchFile(uint32 remlen)
{
uint32 clen = remlen;
char *cbuf;
uLongf len;
char *buf;
FILE *fp;
char *fn;
if(clen > 500000) // Sanity check
{
NetError();
return(0);
}
uint32 clen = remlen;
char *cbuf;
uLongf len;
char *buf;
FILE *fp;
char *fn;
//printf("Receiving file: %d...\n",clen);
fn = FCEU_MakeFName(FCEUMKF_NPTEMP,0,0);
if((fp = fopen(fn,"w+b")))
{
cbuf = (char *)malloc(clen); //mbg merge 7/17/06 added cast
if(!FCEUD_RecvData(cbuf, clen))
{
NetError();
unlink(fn);
fclose(fp);
free(cbuf);
free(fn);
return(0);
}
len = FCEU_de32lsb((uint8*)cbuf); //mbg merge 7/17/06 added cast
if(len > 500000) // Another sanity check
{
NetError();
unlink(fn);
fclose(fp);
free(cbuf);
free(fn);
return(0);
}
buf = (char *)malloc(len); //mbg merge 7/17/06 added cast
uncompress((uint8*)buf, &len, (uint8*)cbuf + 4, clen - 4); //mbg merge 7/17/06 added casts
fwrite(buf, 1, len, fp);
free(buf);
fseek(fp, 0, SEEK_SET);
unlink(fn);
free(fn);
return(fp);
}
free(fn);
return(0);
if(clen > 500000) // Sanity check
{
NetError();
return(0);
}
//printf("Receiving file: %d...\n",clen);
fn = strdup(FCEU_MakeFName(FCEUMKF_NPTEMP,0,0).c_str());
if((fp = fopen(fn,"w+b")))
{
cbuf = (char *)malloc(clen); //mbg merge 7/17/06 added cast
if(!FCEUD_RecvData(cbuf, clen))
{
NetError();
unlink(fn);
fclose(fp);
free(cbuf);
free(fn);
return(0);
}
len = FCEU_de32lsb((uint8*)cbuf); //mbg merge 7/17/06 added cast
if(len > 500000) // Another sanity check
{
NetError();
unlink(fn);
fclose(fp);
free(cbuf);
free(fn);
return(0);
}
buf = (char *)malloc(len); //mbg merge 7/17/06 added cast
uncompress((uint8*)buf, &len, (uint8*)cbuf + 4, clen - 4); //mbg merge 7/17/06 added casts
fwrite(buf, 1, len, fp);
free(buf);
fseek(fp, 0, SEEK_SET);
unlink(fn);
free(fn);
return(fp);
}
free(fn);
return(0);
}
void NetplayUpdate(uint8 *joyp)
{
static uint8 buf[5]; /* 4 play states, + command/extra byte */
static uint8 joypb[4];
static uint8 buf[5]; /* 4 play states, + command/extra byte */
static uint8 joypb[4];
memcpy(joypb,joyp,4);
memcpy(joypb,joyp,4);
/* This shouldn't happen, but just in case. 0xFF is used as a command escape elsewhere. */
if(joypb[0] == 0xFF)
joypb[0] = 0xF;
if(!netdcount)
if(!FCEUD_SendData(joypb,numlocal))
{
NetError();
return;
}
/* This shouldn't happen, but just in case. 0xFF is used as a command escape elsewhere. */
if(joypb[0] == 0xFF)
joypb[0] = 0xF;
if(!netdcount)
if(!FCEUD_SendData(joypb,numlocal))
{
NetError();
return;
}
if(!netdcount)
do
{
if(!FCEUD_RecvData(buf,5))
{
NetError();
return;
}
switch(buf[4])
{
default: FCEU_DoSimpleCommand(buf[4]);break;
case FCEUNPCMD_TEXT:
{
uint8 *tbuf;
uint32 len = FCEU_de32lsb(buf);
if(len > 100000) // Insanity check!
if(!netdcount)
{
do
{
if(!FCEUD_RecvData(buf,5))
{
NetError();
return;
NetError();
return;
}
tbuf = (uint8*)malloc(len + 1); //mbg merge 7/17/06 added cast
tbuf[len] = 0;
if(!FCEUD_RecvData(tbuf, len))
{
NetError();
free(tbuf);
return;
}
FCEUD_NetplayText(tbuf);
free(tbuf);
}
break;
case FCEUNPCMD_SAVESTATE:
{
char *fn;
FILE *fp;
/* Send the cheats first, then the save state, since
there might be a frame or two in between the two sendfile
commands on the server side.
*/
fn = FCEU_MakeFName(FCEUMKF_CHEAT,0,0);
//if(!
FCEUNET_SendFile(FCEUNPCMD_LOADCHEATS,fn);
// {
// free(fn);
// return;
// }
free(fn);
if(!FCEUnetplay) return;
fn = FCEU_MakeFName(FCEUMKF_NPTEMP,0,0);
fp = fopen(fn, "wb");
if(FCEUSS_SaveFP(fp,Z_BEST_COMPRESSION))
{
fclose(fp);
if(!FCEUNET_SendFile(FCEUNPCMD_LOADSTATE, fn))
{
unlink(fn);
free(fn);
return;
}
unlink(fn);
free(fn);
}
else
{
fclose(fp);
FCEUD_PrintError("File error. (K)ill, (M)aim, (D)estroy? Now!");
unlink(fn);
free(fn);
return;
}
}
break;
case FCEUNPCMD_LOADCHEATS:
switch(buf[4])
{
default: FCEU_DoSimpleCommand(buf[4]);break;
case FCEUNPCMD_TEXT:
{
FILE *fp = FetchFile(FCEU_de32lsb(buf));
if(!fp) return;
FCEU_FlushGameCheats(0,1);
FCEU_LoadGameCheats(fp);
uint8 *tbuf;
uint32 len = FCEU_de32lsb(buf);
if(len > 100000) // Insanity check!
{
NetError();
return;
}
tbuf = (uint8*)malloc(len + 1); //mbg merge 7/17/06 added cast
tbuf[len] = 0;
if(!FCEUD_RecvData(tbuf, len))
{
NetError();
free(tbuf);
return;
}
FCEUD_NetplayText(tbuf);
free(tbuf);
}
break;
case FCEUNPCMD_LOADSTATE:
break;
case FCEUNPCMD_SAVESTATE:
{
FILE *fp = FetchFile(FCEU_de32lsb(buf));
if(!fp) return;
if(FCEUSS_LoadFP(fp,SSLOADPARAM_BACKUP))
{
fclose(fp);
FCEU_DispMessage("Remote state loaded.");
} else FCEUD_PrintError("File error. (K)ill, (M)aim, (D)estroy?");
}
break;
}
} while(buf[4]);
char *fn;
FILE *fp;
netdcount=(netdcount+1)%netdivisor;
/* Send the cheats first, then the save state, since
there might be a frame or two in between the two sendfile
commands on the server side.
*/
fn = strdup(FCEU_MakeFName(FCEUMKF_CHEAT,0,0).c_str());
//if(!
FCEUNET_SendFile(FCEUNPCMD_LOADCHEATS,fn);
memcpy(netjoy,buf,4);
*(uint32 *)joyp=*(uint32 *)netjoy;
// {
// free(fn);
// return;
// }
free(fn);
if(!FCEUnetplay) return;
fn = strdup(FCEU_MakeFName(FCEUMKF_NPTEMP,0,0).c_str());
fp = fopen(fn, "wb");
if(FCEUSS_SaveFP(fp,Z_BEST_COMPRESSION))
{
fclose(fp);
if(!FCEUNET_SendFile(FCEUNPCMD_LOADSTATE, fn))
{
unlink(fn);
free(fn);
return;
}
unlink(fn);
free(fn);
}
else
{
fclose(fp);
FCEUD_PrintError("File error. (K)ill, (M)aim, (D)estroy? Now!");
unlink(fn);
free(fn);
return;
}
}
break;
case FCEUNPCMD_LOADCHEATS:
{
FILE *fp = FetchFile(FCEU_de32lsb(buf));
if(!fp) return;
FCEU_FlushGameCheats(0,1);
FCEU_LoadGameCheats(fp);
}
break;
//mbg 6/16/08 - netplay doesnt work right now anyway
/*case FCEUNPCMD_LOADSTATE:
{
FILE *fp = FetchFile(FCEU_de32lsb(buf));
if(!fp) return;
if(FCEUSS_LoadFP(fp,SSLOADPARAM_BACKUP))
{
fclose(fp);
FCEU_DispMessage("Remote state loaded.");
} else FCEUD_PrintError("File error. (K)ill, (M)aim, (D)estroy?");
}
break;*/
}
} while(buf[4]);
netdcount=(netdcount+1)%netdivisor;
memcpy(netjoy,buf,4);
*(uint32 *)joyp=*(uint32 *)netjoy;
}
}

View File

@ -1,22 +1,22 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2002 Xodnizel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
*
* Copyright notice for this file:
* Copyright (C) 2002 Xodnizel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/// \file
/// \brief implements a built-in NSF player. This is a perk--not a part of the emu core
@ -38,6 +38,7 @@
#include "fds.h"
#include "cart.h"
#include "input.h"
#include "driver.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
@ -74,33 +75,33 @@ static int vismode=1;
*/
static uint8 NSFROM[0x30+6]=
{
/* 0x00 - NMI */
0x8D,0xF4,0x3F, /* Stop play routine NMIs. */
0xA2,0xFF,0x9A, /* Initialize the stack pointer. */
0xAD,0xF0,0x3F, /* See if we need to init. */
0xF0,0x09, /* If 0, go to play routine playing. */
/* 0x00 - NMI */
0x8D,0xF4,0x3F, /* Stop play routine NMIs. */
0xA2,0xFF,0x9A, /* Initialize the stack pointer. */
0xAD,0xF0,0x3F, /* See if we need to init. */
0xF0,0x09, /* If 0, go to play routine playing. */
0xAD,0xF1,0x3F, /* Confirm and load A */
0xAE,0xF3,0x3F, /* Load X with PAL/NTSC byte */
0xAD,0xF1,0x3F, /* Confirm and load A */
0xAE,0xF3,0x3F, /* Load X with PAL/NTSC byte */
0x20,0x00,0x00, /* JSR to init routine */
0x20,0x00,0x00, /* JSR to init routine */
0xA9,0x00,
0xAA,
0xA8,
0x20,0x00,0x00, /* JSR to play routine */
0x8D,0xF5,0x3F, /* Start play routine NMIs. */
0x90,0xFE, /* Loopie time. */
0xA9,0x00,
0xAA,
0xA8,
0x20,0x00,0x00, /* JSR to play routine */
0x8D,0xF5,0x3F, /* Start play routine NMIs. */
0x90,0xFE, /* Loopie time. */
/* 0x20 */
0x8D,0xF3,0x3F, /* Init init NMIs */
0x18,
0x90,0xFE /* Loopie time. */
/* 0x20 */
0x8D,0xF3,0x3F, /* Init init NMIs */
0x18,
0x90,0xFE /* Loopie time. */
};
static DECLFR(NSFROMRead)
{
return (NSFROM-0x3800)[A];
return (NSFROM-0x3800)[A];
}
static int doreset=0;
@ -121,148 +122,148 @@ static uint8 *ExWRAM=0;
void NSFGI(int h)
{
switch(h)
{
case GI_CLOSE:
if(NSFDATA) {free(NSFDATA);NSFDATA=0;}
if(ExWRAM) {free(ExWRAM);ExWRAM=0;}
if(NSFHeader.SoundChip&1) {
// NSFVRC6_Init();
} else if(NSFHeader.SoundChip&2) {
// NSFVRC7_Init();
} else if(NSFHeader.SoundChip&4) {
// FDSSoundReset();
} else if(NSFHeader.SoundChip&8) {
NSFMMC5_Close();
} else if(NSFHeader.SoundChip&0x10) {
// NSFN106_Init();
} else if(NSFHeader.SoundChip&0x20) {
// NSFAY_Init();
}
break;
case GI_RESETM2:
case GI_POWER: NSF_init();break;
}
switch(h)
{
case GI_CLOSE:
if(NSFDATA) {free(NSFDATA);NSFDATA=0;}
if(ExWRAM) {free(ExWRAM);ExWRAM=0;}
if(NSFHeader.SoundChip&1) {
// NSFVRC6_Init();
} else if(NSFHeader.SoundChip&2) {
// NSFVRC7_Init();
} else if(NSFHeader.SoundChip&4) {
// FDSSoundReset();
} else if(NSFHeader.SoundChip&8) {
NSFMMC5_Close();
} else if(NSFHeader.SoundChip&0x10) {
// NSFN106_Init();
} else if(NSFHeader.SoundChip&0x20) {
// NSFAY_Init();
}
break;
case GI_RESETM2:
case GI_POWER: NSF_init();break;
}
}
// First 32KB is reserved for sound chip emulation in the iNES mapper code.
static INLINE void BANKSET(uint32 A, uint32 bank)
{
bank&=NSFMaxBank;
if(NSFHeader.SoundChip&4)
memcpy(ExWRAM+(A-0x6000),NSFDATA+(bank<<12),4096);
else
setprg4(A,bank);
bank&=NSFMaxBank;
if(NSFHeader.SoundChip&4)
memcpy(ExWRAM+(A-0x6000),NSFDATA+(bank<<12),4096);
else
setprg4(A,bank);
}
int NSFLoad(FCEUFILE *fp)
{
int x;
int x;
FCEU_fseek(fp,0,SEEK_SET);
FCEU_fread(&NSFHeader,1,0x80,fp);
if(memcmp(NSFHeader.ID,"NESM\x1a",5))
return 0;
NSFHeader.SongName[31]=NSFHeader.Artist[31]=NSFHeader.Copyright[31]=0;
FCEU_fseek(fp,0,SEEK_SET);
FCEU_fread(&NSFHeader,1,0x80,fp);
if(memcmp(NSFHeader.ID,"NESM\x1a",5))
return 0;
NSFHeader.SongName[31]=NSFHeader.Artist[31]=NSFHeader.Copyright[31]=0;
LoadAddr=NSFHeader.LoadAddressLow;
LoadAddr|=NSFHeader.LoadAddressHigh<<8;
LoadAddr=NSFHeader.LoadAddressLow;
LoadAddr|=NSFHeader.LoadAddressHigh<<8;
if(LoadAddr<0x6000)
{
FCEUD_PrintError("Invalid load address.");
return(0);
}
InitAddr=NSFHeader.InitAddressLow;
InitAddr|=NSFHeader.InitAddressHigh<<8;
if(LoadAddr<0x6000)
{
FCEUD_PrintError("Invalid load address.");
return(0);
}
InitAddr=NSFHeader.InitAddressLow;
InitAddr|=NSFHeader.InitAddressHigh<<8;
PlayAddr=NSFHeader.PlayAddressLow;
PlayAddr|=NSFHeader.PlayAddressHigh<<8;
PlayAddr=NSFHeader.PlayAddressLow;
PlayAddr|=NSFHeader.PlayAddressHigh<<8;
NSFSize=FCEU_fgetsize(fp)-0x80;
NSFSize=FCEU_fgetsize(fp)-0x80;
NSFMaxBank=((NSFSize+(LoadAddr&0xfff)+4095)/4096);
NSFMaxBank=uppow2(NSFMaxBank);
NSFMaxBank=((NSFSize+(LoadAddr&0xfff)+4095)/4096);
NSFMaxBank=uppow2(NSFMaxBank);
if(!(NSFDATA=(uint8 *)FCEU_malloc(NSFMaxBank*4096)))
return 0;
if(!(NSFDATA=(uint8 *)FCEU_malloc(NSFMaxBank*4096)))
return 0;
FCEU_fseek(fp,0x80,SEEK_SET);
memset(NSFDATA,0x00,NSFMaxBank*4096);
FCEU_fread(NSFDATA+(LoadAddr&0xfff),1,NSFSize,fp);
NSFMaxBank--;
FCEU_fseek(fp,0x80,SEEK_SET);
memset(NSFDATA,0x00,NSFMaxBank*4096);
FCEU_fread(NSFDATA+(LoadAddr&0xfff),1,NSFSize,fp);
BSon=0;
for(x=0;x<8;x++)
BSon|=NSFHeader.BankSwitch[x];
NSFMaxBank--;
GameInfo->type=GIT_NSF;
GameInfo->input[0]=GameInfo->input[1]=SI_GAMEPAD;
GameInfo->cspecial=SIS_NSF;
BSon=0;
for(x=0;x<8;x++)
BSon|=NSFHeader.BankSwitch[x];
for(x=0;;x++)
{
if(NSFROM[x]==0x20)
{
NSFROM[x+1]=InitAddr&0xFF;
NSFROM[x+2]=InitAddr>>8;
NSFROM[x+8]=PlayAddr&0xFF;
NSFROM[x+9]=PlayAddr>>8;
break;
}
}
GameInfo->type=GIT_NSF;
GameInfo->input[0]=GameInfo->input[1]=SI_GAMEPAD;
GameInfo->cspecial=SIS_NSF;
if(NSFHeader.VideoSystem==0)
GameInfo->vidsys=GIV_NTSC;
else if(NSFHeader.VideoSystem==1)
GameInfo->vidsys=GIV_PAL;
for(x=0;;x++)
{
if(NSFROM[x]==0x20)
{
NSFROM[x+1]=InitAddr&0xFF;
NSFROM[x+2]=InitAddr>>8;
NSFROM[x+8]=PlayAddr&0xFF;
NSFROM[x+9]=PlayAddr>>8;
break;
}
}
GameInterface=NSFGI;
if(NSFHeader.VideoSystem==0)
GameInfo->vidsys=GIV_NTSC;
else if(NSFHeader.VideoSystem==1)
GameInfo->vidsys=GIV_PAL;
FCEU_printf("NSF Loaded. File information:\n\n");
FCEU_printf(" Name: %s\n Artist: %s\n Copyright: %s\n\n",NSFHeader.SongName,NSFHeader.Artist,NSFHeader.Copyright);
if(NSFHeader.SoundChip)
{
static char *tab[6]={"Konami VRCVI","Konami VRCVII","Nintendo FDS","Nintendo MMC5","Namco 106","Sunsoft FME-07"};
GameInterface=NSFGI;
for(x=0;x<6;x++)
if(NSFHeader.SoundChip&(1<<x))
{
FCEU_printf(" Expansion hardware: %s\n",tab[x]);
NSFHeader.SoundChip=1<<x; /* Prevent confusing weirdness if more than one bit is set. */
break;
}
}
if(BSon)
FCEU_printf(" Bank-switched.\n");
FCEU_printf(" Load address: $%04x\n Init address: $%04x\n Play address: $%04x\n",LoadAddr,InitAddr,PlayAddr);
FCEU_printf(" %s\n",(NSFHeader.VideoSystem&1)?"PAL":"NTSC");
FCEU_printf(" Starting song: %d / %d\n\n",NSFHeader.StartingSong,NSFHeader.TotalSongs);
FCEU_printf("NSF Loaded. File information:\n\n");
FCEU_printf(" Name: %s\n Artist: %s\n Copyright: %s\n\n",NSFHeader.SongName,NSFHeader.Artist,NSFHeader.Copyright);
if(NSFHeader.SoundChip)
{
static char *tab[6]={"Konami VRCVI","Konami VRCVII","Nintendo FDS","Nintendo MMC5","Namco 106","Sunsoft FME-07"};
if(NSFHeader.SoundChip&4)
ExWRAM=(uint8*)FCEU_gmalloc(32768+8192); //mbg merge 7/17/06 added cast
else
ExWRAM=(uint8*)FCEU_gmalloc(8192); //mbg merge 7/17/06 added cast
for(x=0;x<6;x++)
if(NSFHeader.SoundChip&(1<<x))
{
FCEU_printf(" Expansion hardware: %s\n",tab[x]);
NSFHeader.SoundChip=1<<x; /* Prevent confusing weirdness if more than one bit is set. */
break;
}
}
if(BSon)
FCEU_printf(" Bank-switched.\n");
FCEU_printf(" Load address: $%04x\n Init address: $%04x\n Play address: $%04x\n",LoadAddr,InitAddr,PlayAddr);
FCEU_printf(" %s\n",(NSFHeader.VideoSystem&1)?"PAL":"NTSC");
FCEU_printf(" Starting song: %d / %d\n\n",NSFHeader.StartingSong,NSFHeader.TotalSongs);
FCEUI_SetVidSystem(NSFHeader.VideoSystem);
if(NSFHeader.SoundChip&4)
ExWRAM=(uint8*)FCEU_gmalloc(32768+8192); //mbg merge 7/17/06 added cast
else
ExWRAM=(uint8*)FCEU_gmalloc(8192); //mbg merge 7/17/06 added cast
return 1;
FCEUI_SetVidSystem(NSFHeader.VideoSystem);
return 1;
}
static DECLFR(NSFVectorRead)
{
if(((NSFNMIFlags&1) && SongReload) || (NSFNMIFlags&2) || doreset)
{
if(A==0xFFFA) return(0x00);
else if(A==0xFFFB) return(0x38);
else if(A==0xFFFC) return(0x20);
else if(A==0xFFFD) {doreset=0;return(0x38);}
return(X.DB);
}
else
return(CartBR(A));
if(((NSFNMIFlags&1) && SongReload) || (NSFNMIFlags&2) || doreset)
{
if(A==0xFFFA) return(0x00);
else if(A==0xFFFB) return(0x38);
else if(A==0xFFFC) return(0x20);
else if(A==0xFFFD) {doreset=0;return(0x38);}
return(X.DB);
}
else
return(CartBR(A));
}
void NSFVRC6_Init(void);
@ -273,145 +274,145 @@ void NSFAY_Init(void);
void NSF_init(void)
{
doreset=1;
doreset=1;
ResetCartMapping();
if(NSFHeader.SoundChip&4)
{
SetupCartPRGMapping(0,ExWRAM,32768+8192,1);
setprg32(0x6000,0);
setprg8(0xE000,4);
memset(ExWRAM,0x00,32768+8192);
SetWriteHandler(0x6000,0xDFFF,CartBW);
SetReadHandler(0x6000,0xFFFF,CartBR);
}
else
{
memset(ExWRAM,0x00,8192);
SetReadHandler(0x6000,0x7FFF,CartBR);
SetWriteHandler(0x6000,0x7FFF,CartBW);
SetupCartPRGMapping(0,NSFDATA,((NSFMaxBank+1)*4096),0);
SetupCartPRGMapping(1,ExWRAM,8192,1);
setprg8r(1,0x6000,0);
SetReadHandler(0x8000,0xFFFF,CartBR);
}
ResetCartMapping();
if(NSFHeader.SoundChip&4)
{
SetupCartPRGMapping(0,ExWRAM,32768+8192,1);
setprg32(0x6000,0);
setprg8(0xE000,4);
memset(ExWRAM,0x00,32768+8192);
SetWriteHandler(0x6000,0xDFFF,CartBW);
SetReadHandler(0x6000,0xFFFF,CartBR);
}
else
{
memset(ExWRAM,0x00,8192);
SetReadHandler(0x6000,0x7FFF,CartBR);
SetWriteHandler(0x6000,0x7FFF,CartBW);
SetupCartPRGMapping(0,NSFDATA,((NSFMaxBank+1)*4096),0);
SetupCartPRGMapping(1,ExWRAM,8192,1);
setprg8r(1,0x6000,0);
SetReadHandler(0x8000,0xFFFF,CartBR);
}
if(BSon)
{
int32 x;
for(x=0;x<8;x++)
{
if(NSFHeader.SoundChip&4 && x>=6)
BANKSET(0x6000+(x-6)*4096,NSFHeader.BankSwitch[x]);
BANKSET(0x8000+x*4096,NSFHeader.BankSwitch[x]);
}
}
else
{
int32 x;
for(x=(LoadAddr&0xF000);x<0x10000;x+=0x1000)
BANKSET(x,((x-(LoadAddr&0x7000))>>12));
}
if(BSon)
{
int32 x;
for(x=0;x<8;x++)
{
if(NSFHeader.SoundChip&4 && x>=6)
BANKSET(0x6000+(x-6)*4096,NSFHeader.BankSwitch[x]);
BANKSET(0x8000+x*4096,NSFHeader.BankSwitch[x]);
}
}
else
{
int32 x;
for(x=(LoadAddr&0xF000);x<0x10000;x+=0x1000)
BANKSET(x,((x-(LoadAddr&0x7000))>>12));
}
SetReadHandler(0xFFFA,0xFFFD,NSFVectorRead);
SetReadHandler(0xFFFA,0xFFFD,NSFVectorRead);
SetWriteHandler(0x2000,0x3fff,0);
SetReadHandler(0x2000,0x37ff,0);
SetReadHandler(0x3836,0x3FFF,0);
SetReadHandler(0x3800,0x3835,NSFROMRead);
SetWriteHandler(0x2000,0x3fff,0);
SetReadHandler(0x2000,0x37ff,0);
SetReadHandler(0x3836,0x3FFF,0);
SetReadHandler(0x3800,0x3835,NSFROMRead);
SetWriteHandler(0x5ff6,0x5fff,NSF_write);
SetWriteHandler(0x5ff6,0x5fff,NSF_write);
SetWriteHandler(0x3ff0,0x3fff,NSF_write);
SetReadHandler(0x3ff0,0x3fff,NSF_read);
SetWriteHandler(0x3ff0,0x3fff,NSF_write);
SetReadHandler(0x3ff0,0x3fff,NSF_read);
if(NSFHeader.SoundChip&1) {
NSFVRC6_Init();
} else if(NSFHeader.SoundChip&2) {
NSFVRC7_Init();
} else if(NSFHeader.SoundChip&4) {
FDSSoundReset();
} else if(NSFHeader.SoundChip&8) {
NSFMMC5_Init();
} else if(NSFHeader.SoundChip&0x10) {
NSFN106_Init();
} else if(NSFHeader.SoundChip&0x20) {
NSFAY_Init();
}
CurrentSong=NSFHeader.StartingSong;
SongReload=0xFF;
NSFNMIFlags=0;
if(NSFHeader.SoundChip&1) {
NSFVRC6_Init();
} else if(NSFHeader.SoundChip&2) {
NSFVRC7_Init();
} else if(NSFHeader.SoundChip&4) {
FDSSoundReset();
} else if(NSFHeader.SoundChip&8) {
NSFMMC5_Init();
} else if(NSFHeader.SoundChip&0x10) {
NSFN106_Init();
} else if(NSFHeader.SoundChip&0x20) {
NSFAY_Init();
}
CurrentSong=NSFHeader.StartingSong;
SongReload=0xFF;
NSFNMIFlags=0;
}
static DECLFW(NSF_write)
{
switch(A)
{
case 0x3FF3:NSFNMIFlags|=1;break;
case 0x3FF4:NSFNMIFlags&=~2;break;
case 0x3FF5:NSFNMIFlags|=2;break;
switch(A)
{
case 0x3FF3:NSFNMIFlags|=1;break;
case 0x3FF4:NSFNMIFlags&=~2;break;
case 0x3FF5:NSFNMIFlags|=2;break;
case 0x5FF6:
case 0x5FF7:if(!(NSFHeader.SoundChip&4)) return;
case 0x5FF8:
case 0x5FF9:
case 0x5FFA:
case 0x5FFB:
case 0x5FFC:
case 0x5FFD:
case 0x5FFE:
case 0x5FFF:if(!BSon) return;
A&=0xF;
BANKSET((A*4096),V);
break;
}
case 0x5FF6:
case 0x5FF7:if(!(NSFHeader.SoundChip&4)) return;
case 0x5FF8:
case 0x5FF9:
case 0x5FFA:
case 0x5FFB:
case 0x5FFC:
case 0x5FFD:
case 0x5FFE:
case 0x5FFF:if(!BSon) return;
A&=0xF;
BANKSET((A*4096),V);
break;
}
}
static DECLFR(NSF_read)
{
int x;
int x;
switch(A)
{
case 0x3ff0:x=SongReload;
if(!fceuindbg)
SongReload=0;
return x;
case 0x3ff1:
if(!fceuindbg)
{
memset(RAM,0x00,0x800);
switch(A)
{
case 0x3ff0:x=SongReload;
if(!fceuindbg)
SongReload=0;
return x;
case 0x3ff1:
if(!fceuindbg)
{
memset(RAM,0x00,0x800);
BWrite[0x4015](0x4015,0x0);
for(x=0;x<0x14;x++)
BWrite[0x4000+x](0x4000+x,0);
BWrite[0x4015](0x4015,0xF);
BWrite[0x4015](0x4015,0x0);
for(x=0;x<0x14;x++)
BWrite[0x4000+x](0x4000+x,0);
BWrite[0x4015](0x4015,0xF);
if(NSFHeader.SoundChip&4)
{
BWrite[0x4017](0x4017,0xC0); /* FDS BIOS writes $C0 */
BWrite[0x4089](0x4089,0x80);
BWrite[0x408A](0x408A,0xE8);
}
else
{
memset(ExWRAM,0x00,8192);
BWrite[0x4017](0x4017,0xC0);
BWrite[0x4017](0x4017,0xC0);
BWrite[0x4017](0x4017,0x40);
}
if(NSFHeader.SoundChip&4)
{
BWrite[0x4017](0x4017,0xC0); /* FDS BIOS writes $C0 */
BWrite[0x4089](0x4089,0x80);
BWrite[0x408A](0x408A,0xE8);
}
else
{
memset(ExWRAM,0x00,8192);
BWrite[0x4017](0x4017,0xC0);
BWrite[0x4017](0x4017,0xC0);
BWrite[0x4017](0x4017,0x40);
}
if(BSon)
{
for(x=0;x<8;x++)
BANKSET(0x8000+x*4096,NSFHeader.BankSwitch[x]);
}
return (CurrentSong-1);
}
case 0x3FF3:return PAL;
}
return 0;
if(BSon)
{
for(x=0;x<8;x++)
BANKSET(0x8000+x*4096,NSFHeader.BankSwitch[x]);
}
return (CurrentSong-1);
}
case 0x3FF3:return PAL;
}
return 0;
}
uint8 FCEU_GetJoyJoy(void);
@ -420,173 +421,173 @@ static int special=0;
void DrawNSF(uint8 *XBuf)
{
char snbuf[16];
int x;
char snbuf[16];
int x;
if(vismode==0) return;
if(vismode==0) return;
memset(XBuf,0,256*240);
memset(XBuf,0,256*240);
{
int32 *Bufpl;
int32 mul=0;
{
int32 *Bufpl;
int32 mul=0;
int l;
l=GetSoundBuffer(&Bufpl);
int l;
l=GetSoundBuffer(&Bufpl);
if(special==0)
{
if(FSettings.SoundVolume)
mul=8192*240/(16384*FSettings.SoundVolume/50);
for(x=0;x<256;x++)
{
uint32 y;
y=142+((Bufpl[(x*l)>>8]*mul)>>14);
if(y<240)
XBuf[x+y*256]=3;
}
}
else if(special==1)
{
if(FSettings.SoundVolume)
mul=8192*240/(8192*FSettings.SoundVolume/50);
for(x=0;x<256;x++)
{
double r;
uint32 xp,yp;
if(special==0)
{
if(FSettings.SoundVolume)
mul=8192*240/(16384*FSettings.SoundVolume/50);
for(x=0;x<256;x++)
{
uint32 y;
y=142+((Bufpl[(x*l)>>8]*mul)>>14);
if(y<240)
XBuf[x+y*256]=3;
}
}
else if(special==1)
{
if(FSettings.SoundVolume)
mul=8192*240/(8192*FSettings.SoundVolume/50);
for(x=0;x<256;x++)
{
double r;
uint32 xp,yp;
r=(Bufpl[(x*l)>>8]*mul)>>14;
xp=128+r*cos(x*M_PI*2/256);
yp=120+r*sin(x*M_PI*2/256);
xp&=255;
yp%=240;
XBuf[xp+yp*256]=3;
}
}
else if(special==2)
{
static double theta=0;
if(FSettings.SoundVolume)
mul=8192*240/(16384*FSettings.SoundVolume/50);
for(x=0;x<128;x++)
{
double xc,yc;
double r,t;
uint32 m,n;
xc=(double)128-x;
yc=0-((double)( ((Bufpl[(x*l)>>8]) *mul)>>14));
t=M_PI+atan(yc/xc);
r=sqrt(xc*xc+yc*yc);
t+=theta;
m=128+r*cos(t);
n=120+r*sin(t);
if(m<256 && n<240)
XBuf[m+n*256]=3;
r=(Bufpl[(x*l)>>8]*mul)>>14;
xp=128+r*cos(x*M_PI*2/256);
yp=120+r*sin(x*M_PI*2/256);
xp&=255;
yp%=240;
XBuf[xp+yp*256]=3;
}
}
else if(special==2)
{
static double theta=0;
if(FSettings.SoundVolume)
mul=8192*240/(16384*FSettings.SoundVolume/50);
for(x=0;x<128;x++)
{
double xc,yc;
double r,t;
uint32 m,n;
}
for(x=128;x<256;x++)
{
double xc,yc;
double r,t;
uint32 m,n;
xc=(double)128-x;
yc=0-((double)( ((Bufpl[(x*l)>>8]) *mul)>>14));
t=M_PI+atan(yc/xc);
r=sqrt(xc*xc+yc*yc);
xc=(double)x-128;
yc=(double)((Bufpl[(x*l)>>8]*mul)>>14);
t=atan(yc/xc);
r=sqrt(xc*xc+yc*yc);
t+=theta;
m=128+r*cos(t);
n=120+r*sin(t);
if(m<256 && n<240)
XBuf[m+n*256]=3;
t+=theta;
m=128+r*cos(t);
n=120+r*sin(t);
}
theta+=(double)M_PI/256;
}
}
if(m<256 && n<240)
XBuf[m+n*256]=3;
DrawTextTrans(XBuf+10*256+4+(((31-strlen((char*)NSFHeader.SongName))<<2)), 256, NSFHeader.SongName, 6);
DrawTextTrans(XBuf+26*256+4+(((31-strlen((char*)NSFHeader.Artist))<<2)), 256,NSFHeader.Artist, 6);
DrawTextTrans(XBuf+42*256+4+(((31-strlen((char*)NSFHeader.Copyright))<<2)), 256,NSFHeader.Copyright, 6);
DrawTextTrans(XBuf+70*256+4+(((31-strlen("Song:"))<<2)), 256, (uint8*)"Song:", 6);
sprintf(snbuf,"<%d/%d>",CurrentSong,NSFHeader.TotalSongs);
DrawTextTrans(XBuf+82*256+4+(((31-strlen(snbuf))<<2)), 256, (uint8*)snbuf, 6);
}
for(x=128;x<256;x++)
{
double xc,yc;
double r,t;
uint32 m,n;
{
static uint8 last=0;
uint8 tmp;
tmp=FCEU_GetJoyJoy();
if((tmp&JOY_RIGHT) && !(last&JOY_RIGHT))
{
if(CurrentSong<NSFHeader.TotalSongs)
{
CurrentSong++;
SongReload=0xFF;
}
}
else if((tmp&JOY_LEFT) && !(last&JOY_LEFT))
{
if(CurrentSong>1)
{
CurrentSong--;
SongReload=0xFF;
}
}
else if((tmp&JOY_UP) && !(last&JOY_UP))
{
CurrentSong+=10;
if(CurrentSong>NSFHeader.TotalSongs) CurrentSong=NSFHeader.TotalSongs;
SongReload=0xFF;
}
else if((tmp&JOY_DOWN) && !(last&JOY_DOWN))
{
CurrentSong-=10;
if(CurrentSong<1) CurrentSong=1;
SongReload=0xFF;
}
else if((tmp&JOY_START) && !(last&JOY_START))
SongReload=0xFF;
else if((tmp&JOY_A) && !(last&JOY_A))
{
special=(special+1)%3;
}
last=tmp;
}
xc=(double)x-128;
yc=(double)((Bufpl[(x*l)>>8]*mul)>>14);
t=atan(yc/xc);
r=sqrt(xc*xc+yc*yc);
t+=theta;
m=128+r*cos(t);
n=120+r*sin(t);
if(m<256 && n<240)
XBuf[m+n*256]=3;
}
theta+=(double)M_PI/256;
}
}
DrawTextTrans(XBuf+10*256+4+(((31-strlen((char*)NSFHeader.SongName))<<2)), 256, NSFHeader.SongName, 6);
DrawTextTrans(XBuf+26*256+4+(((31-strlen((char*)NSFHeader.Artist))<<2)), 256,NSFHeader.Artist, 6);
DrawTextTrans(XBuf+42*256+4+(((31-strlen((char*)NSFHeader.Copyright))<<2)), 256,NSFHeader.Copyright, 6);
DrawTextTrans(XBuf+70*256+4+(((31-strlen("Song:"))<<2)), 256, (uint8*)"Song:", 6);
sprintf(snbuf,"<%d/%d>",CurrentSong,NSFHeader.TotalSongs);
DrawTextTrans(XBuf+82*256+4+(((31-strlen(snbuf))<<2)), 256, (uint8*)snbuf, 6);
{
static uint8 last=0;
uint8 tmp;
tmp=FCEU_GetJoyJoy();
if((tmp&JOY_RIGHT) && !(last&JOY_RIGHT))
{
if(CurrentSong<NSFHeader.TotalSongs)
{
CurrentSong++;
SongReload=0xFF;
}
}
else if((tmp&JOY_LEFT) && !(last&JOY_LEFT))
{
if(CurrentSong>1)
{
CurrentSong--;
SongReload=0xFF;
}
}
else if((tmp&JOY_UP) && !(last&JOY_UP))
{
CurrentSong+=10;
if(CurrentSong>NSFHeader.TotalSongs) CurrentSong=NSFHeader.TotalSongs;
SongReload=0xFF;
}
else if((tmp&JOY_DOWN) && !(last&JOY_DOWN))
{
CurrentSong-=10;
if(CurrentSong<1) CurrentSong=1;
SongReload=0xFF;
}
else if((tmp&JOY_START) && !(last&JOY_START))
SongReload=0xFF;
else if((tmp&JOY_A) && !(last&JOY_A))
{
special=(special+1)%3;
}
last=tmp;
}
}
void DoNSFFrame(void)
{
if(((NSFNMIFlags&1) && SongReload) || (NSFNMIFlags&2))
TriggerNMI();
if(((NSFNMIFlags&1) && SongReload) || (NSFNMIFlags&2))
TriggerNMI();
}
void FCEUI_NSFSetVis(int mode)
{
vismode=mode;
vismode=mode;
}
int FCEUI_NSFChange(int amount)
{
CurrentSong+=amount;
if(CurrentSong<1) CurrentSong=1;
else if(CurrentSong>NSFHeader.TotalSongs) CurrentSong=NSFHeader.TotalSongs;
SongReload=0xFF;
CurrentSong+=amount;
if(CurrentSong<1) CurrentSong=1;
else if(CurrentSong>NSFHeader.TotalSongs) CurrentSong=NSFHeader.TotalSongs;
SongReload=0xFF;
return(CurrentSong);
return(CurrentSong);
}
/* Returns total songs */
//Returns total songs
int FCEUI_NSFGetInfo(uint8 *name, uint8 *artist, uint8 *copyright, int maxlen)
{
strncpy((char*)name,(char*)NSFHeader.SongName,maxlen); //mbg merge 7/17/06 added casts
strncpy((char*)artist,(char*)NSFHeader.Artist,maxlen); //mbg merge 7/17/06 added casts
strncpy((char*)copyright,(char*)NSFHeader.Copyright,maxlen); //mbg merge 7/17/06 added casts
return(NSFHeader.TotalSongs);
strncpy((char*)name,(char*)NSFHeader.SongName,maxlen); //mbg merge 7/17/06 added casts
strncpy((char*)artist,(char*)NSFHeader.Artist,maxlen); //mbg merge 7/17/06 added casts
strncpy((char*)copyright,(char*)NSFHeader.Copyright,maxlen); //mbg merge 7/17/06 added casts
return(NSFHeader.TotalSongs);
}

View File

@ -22,17 +22,17 @@ case 0x00: /* BRK */
_PC++;
PUSH(_PC>>8);
PUSH(_PC);
PUSH(_P|U_FLAG|B_FLAG);
_P|=I_FLAG;
PUSH(__P|U_FLAG|B_FLAG);
__P|=I_FLAG;
_PI|=I_FLAG;
_PC=RdMem(0xFFFE);
_PC|=RdMem(0xFFFF)<<8;
break;
case 0x40: /* RTI */
_P=POP();
__P=POP();
/* _PI=_P; This is probably incorrect, so it's commented out. */
_PI = _P;
_PI = __P;
_PC=POP();
_PC|=POP()<<8;
break;
@ -47,14 +47,14 @@ case 0x48: /* PHA */
PUSH(_A);
break;
case 0x08: /* PHP */
PUSH(_P|U_FLAG|B_FLAG);
PUSH(__P|U_FLAG|B_FLAG);
break;
case 0x68: /* PLA */
_A=POP();
X_ZN(_A);
break;
case 0x28: /* PLP */
_P=POP();
__P=POP();
break;
case 0x4C:
{
@ -107,11 +107,11 @@ case 0x98: /* TYA */
break;
case 0xBA: /* TSX */
_X=_S;
_X=__S;
X_ZN(_X);
break;
case 0x9A: /* TXS */
_S=_X;
__S=_X;
break;
case 0xCA: /* DEX */
@ -133,26 +133,26 @@ case 0xC8: /* INY */
break;
case 0x18: /* CLC */
_P&=~C_FLAG;
__P&=~C_FLAG;
break;
case 0xD8: /* CLD */
_P&=~D_FLAG;
__P&=~D_FLAG;
break;
case 0x58: /* CLI */
_P&=~I_FLAG;
__P&=~I_FLAG;
break;
case 0xB8: /* CLV */
_P&=~V_FLAG;
__P&=~V_FLAG;
break;
case 0x38: /* SEC */
_P|=C_FLAG;
__P|=C_FLAG;
break;
case 0xF8: /* SED */
_P|=D_FLAG;
__P|=D_FLAG;
break;
case 0x78: /* SEI */
_P|=I_FLAG;
__P|=I_FLAG;
break;
case 0xEA: /* NOP */
@ -296,28 +296,28 @@ case 0x94: ST_ZPX(_Y);
case 0x8C: ST_AB(_Y);
/* BCC */
case 0x90: JR(!(_P&C_FLAG)); break;
case 0x90: JR(!(__P&C_FLAG)); break;
/* BCS */
case 0xB0: JR(_P&C_FLAG); break;
case 0xB0: JR(__P&C_FLAG); break;
/* BEQ */
case 0xF0: JR(_P&Z_FLAG); break;
case 0xF0: JR(__P&Z_FLAG); break;
/* BNE */
case 0xD0: JR(!(_P&Z_FLAG)); break;
case 0xD0: JR(!(__P&Z_FLAG)); break;
/* BMI */
case 0x30: JR(_P&N_FLAG); break;
case 0x30: JR(__P&N_FLAG); break;
/* BPL */
case 0x10: JR(!(_P&N_FLAG)); break;
case 0x10: JR(!(__P&N_FLAG)); break;
/* BVC */
case 0x50: JR(!(_P&V_FLAG)); break;
case 0x50: JR(!(__P&V_FLAG)); break;
/* BVS */
case 0x70: JR(_P&V_FLAG); break;
case 0x70: JR(__P&V_FLAG); break;
//default: printf("Bad %02x at $%04x\n",b1,X.PC);break;
//ifdef moo
@ -327,7 +327,7 @@ case 0x70: JR(_P&V_FLAG); break;
/* AAC */
case 0x2B:
case 0x0B: LD_IM(AND;_P&=~C_FLAG;_P|=_A>>7);
case 0x0B: LD_IM(AND;__P&=~C_FLAG;__P|=_A>>7);
/* AAX */
case 0x87: ST_ZP(_A&_X);
@ -338,7 +338,7 @@ case 0x83: ST_IX(_A&_X);
/* ARR - ARGH, MATEY! */
case 0x6B: {
uint8 arrtmp;
LD_IM(AND;_P&=~V_FLAG;_P|=(_A^(_A>>1))&0x40;arrtmp=_A>>7;_A>>=1;_A|=(_P&C_FLAG)<<7;_P&=~C_FLAG;_P|=arrtmp;X_ZN(_A));
LD_IM(AND;__P&=~V_FLAG;__P|=(_A^(_A>>1))&0x40;arrtmp=_A>>7;_A>>=1;_A|=(__P&C_FLAG)<<7;__P&=~C_FLAG;__P|=arrtmp;X_ZN(_A));
}
/* ASR */
case 0x4B: LD_IM(AND;LSRA);
@ -404,7 +404,7 @@ case 0xF2:ADDCYC(0xFF);
break;
/* LAR */
case 0xBB: RMW_ABY(_S&=x;_A=_X=_S;X_ZN(_X));
case 0xBB: RMW_ABY(__S&=x;_A=_X=__S;X_ZN(_X));
/* LAX */
case 0xA7: LD_ZP(LDA;LDX);
@ -469,7 +469,7 @@ case 0x9C: ST_ABX(_Y&(((A-_X)>>8)+1));
case 0x9E: ST_ABY(_X&(((A-_Y)>>8)+1));
/* XAS */
case 0x9B: _S=_A&_X;ST_ABY(_S& (((A-_Y)>>8)+1) );
case 0x9B: __S=_A&_X;ST_ABY(__S& (((A-_Y)>>8)+1) );
/* TOP */
case 0x0C: LD_AB(;);

View File

@ -1,22 +1,22 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2002,2003 Xodnizel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
*
* Copyright notice for this file:
* Copyright (C) 2002,2003 Xodnizel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <stdlib.h>
@ -50,219 +50,219 @@ uint8 pale=0;
pal *palo;
static pal *palpoint[8]=
{
palette,
rp2c04001,
rp2c04002,
rp2c04003,
rp2c05004,
};
{
palette,
rp2c04001,
rp2c04002,
rp2c04003,
rp2c05004,
};
void FCEUI_SetPaletteArray(uint8 *pal)
{
if(!pal)
palpoint[0]=palette;
else
{
int x;
palpoint[0]=palettec;
for(x=0;x<64;x++)
{
palpoint[0][x].r=*((uint8 *)pal+x+x+x);
palpoint[0][x].g=*((uint8 *)pal+x+x+x+1);
palpoint[0][x].b=*((uint8 *)pal+x+x+x+2);
}
}
FCEU_ResetPalette();
if(!pal)
palpoint[0]=palette;
else
{
int x;
palpoint[0]=palettec;
for(x=0;x<64;x++)
{
palpoint[0][x].r=*((uint8 *)pal+x+x+x);
palpoint[0][x].g=*((uint8 *)pal+x+x+x+1);
palpoint[0][x].b=*((uint8 *)pal+x+x+x+2);
}
}
FCEU_ResetPalette();
}
void FCEUI_SetNTSCTH(int n, int tint, int hue)
{
ntsctint=tint;
ntschue=hue;
ntsccol=n;
FCEU_ResetPalette();
ntsctint=tint;
ntschue=hue;
ntsccol=n;
FCEU_ResetPalette();
}
static uint8 lastd=0;
void SetNESDeemph(uint8 d, int force)
{
static uint16 rtmul[7]={32768*1.239,32768*.794,32768*1.019,32768*.905,32768*1.023,32768*.741,32768*.75};
static uint16 gtmul[7]={32768*.915,32768*1.086,32768*.98,32768*1.026,32768*.908,32768*.987,32768*.75};
static uint16 btmul[7]={32768*.743,32768*.882,32768*.653,32768*1.277,32768*.979,32768*.101,32768*.75};
uint32 r,g,b;
int x;
static uint16 rtmul[7]={32768*1.239,32768*.794,32768*1.019,32768*.905,32768*1.023,32768*.741,32768*.75};
static uint16 gtmul[7]={32768*.915,32768*1.086,32768*.98,32768*1.026,32768*.908,32768*.987,32768*.75};
static uint16 btmul[7]={32768*.743,32768*.882,32768*.653,32768*1.277,32768*.979,32768*.101,32768*.75};
uint32 r,g,b;
int x;
/* If it's not forced(only forced when the palette changes),
don't waste cpu time if the same deemphasis bits are set as the last call.
*/
if(!force)
{
if(d==lastd)
return;
}
else /* Only set this when palette has changed. */
{
r=rtmul[6];
g=rtmul[6];
b=rtmul[6];
/* If it's not forced(only forced when the palette changes),
don't waste cpu time if the same deemphasis bits are set as the last call.
*/
if(!force)
{
if(d==lastd)
return;
}
else /* Only set this when palette has changed. */
{
r=rtmul[6];
g=rtmul[6];
b=rtmul[6];
for(x=0;x<0x40;x++)
{
uint32 m,n,o;
m=palo[x].r;
n=palo[x].g;
o=palo[x].b;
m=(m*r)>>15;
n=(n*g)>>15;
o=(o*b)>>15;
if(m>0xff) m=0xff;
if(n>0xff) n=0xff;
if(o>0xff) o=0xff;
FCEUD_SetPalette(x|0xC0,m,n,o);
}
}
if(!d) return; /* No deemphasis, so return. */
for(x=0;x<0x40;x++)
{
uint32 m,n,o;
m=palo[x].r;
n=palo[x].g;
o=palo[x].b;
m=(m*r)>>15;
n=(n*g)>>15;
o=(o*b)>>15;
if(m>0xff) m=0xff;
if(n>0xff) n=0xff;
if(o>0xff) o=0xff;
FCEUD_SetPalette(x|0xC0,m,n,o);
}
}
if(!d) return; /* No deemphasis, so return. */
r=rtmul[d-1];
g=gtmul[d-1];
b=btmul[d-1];
r=rtmul[d-1];
g=gtmul[d-1];
b=btmul[d-1];
for(x=0;x<0x40;x++)
{
uint32 m,n,o;
m=palo[x].r;
n=palo[x].g;
o=palo[x].b;
m=(m*r)>>15;
n=(n*g)>>15;
o=(o*b)>>15;
if(m>0xff) m=0xff;
if(n>0xff) n=0xff;
if(o>0xff) o=0xff;
FCEUD_SetPalette(x|0x40,m,n,o);
}
lastd=d;
for(x=0;x<0x40;x++)
{
uint32 m,n,o;
m=palo[x].r;
n=palo[x].g;
o=palo[x].b;
m=(m*r)>>15;
n=(n*g)>>15;
o=(o*b)>>15;
if(m>0xff) m=0xff;
if(n>0xff) n=0xff;
if(o>0xff) o=0xff;
FCEUD_SetPalette(x|0x40,m,n,o);
}
lastd=d;
}
/* Converted from Kevin Horton's qbasic palette generator. */
static void CalculatePalette(void)
{
int x,z;
int r,g,b;
double s,luma,theta;
static uint8 cols[16]={0,24,21,18,15,12,9,6,3,0,33,30,27,0,0,0};
static uint8 br1[4]={6,9,12,12};
static double br2[4]={.29,.45,.73,.9};
static double br3[4]={0,.24,.47,.77};
for(x=0;x<=3;x++)
for(z=0;z<16;z++)
{
s=(double)ntsctint/128;
luma=br2[x];
if(z==0) {s=0;luma=((double)br1[x])/12;}
if(z>=13)
{
s=luma=0;
if(z==13)
luma=br3[x];
}
theta=(double)M_PI*(double)(((double)cols[z]*10+ (((double)ntschue/2)+300) )/(double)180);
r=(int)((luma+s*sin(theta))*256);
g=(int)((luma-(double)27/53*s*sin(theta)+(double)10/53*s*cos(theta))*256);
b=(int)((luma-s*cos(theta))*256);
if(r>255) r=255;
if(g>255) g=255;
if(b>255) b=255;
if(r<0) r=0;
if(g<0) g=0;
if(b<0) b=0;
paletten[(x<<4)+z].r=r;
paletten[(x<<4)+z].g=g;
paletten[(x<<4)+z].b=b;
}
WritePalette();
int x,z;
int r,g,b;
double s,luma,theta;
static uint8 cols[16]={0,24,21,18,15,12,9,6,3,0,33,30,27,0,0,0};
static uint8 br1[4]={6,9,12,12};
static double br2[4]={.29,.45,.73,.9};
static double br3[4]={0,.24,.47,.77};
for(x=0;x<=3;x++)
for(z=0;z<16;z++)
{
s=(double)ntsctint/128;
luma=br2[x];
if(z==0) {s=0;luma=((double)br1[x])/12;}
if(z>=13)
{
s=luma=0;
if(z==13)
luma=br3[x];
}
theta=(double)M_PI*(double)(((double)cols[z]*10+ (((double)ntschue/2)+300) )/(double)180);
r=(int)((luma+s*sin(theta))*256);
g=(int)((luma-(double)27/53*s*sin(theta)+(double)10/53*s*cos(theta))*256);
b=(int)((luma-s*cos(theta))*256);
if(r>255) r=255;
if(g>255) g=255;
if(b>255) b=255;
if(r<0) r=0;
if(g<0) g=0;
if(b<0) b=0;
paletten[(x<<4)+z].r=r;
paletten[(x<<4)+z].g=g;
paletten[(x<<4)+z].b=b;
}
WritePalette();
}
static int ipalette=0;
void FCEU_LoadGamePalette(void)
{
uint8 ptmp[192];
FILE *fp;
char *fn;
uint8 ptmp[192];
FILE *fp;
char *fn;
ipalette=0;
ipalette=0;
fn=FCEU_MakeFName(FCEUMKF_PALETTE,0,0);
fn=strdup(FCEU_MakeFName(FCEUMKF_PALETTE,0,0).c_str());
if((fp=FCEUD_UTF8fopen(fn,"rb")))
{
int x;
fread(ptmp,1,192,fp);
fclose(fp);
for(x=0;x<64;x++)
{
palettei[x].r=ptmp[x+x+x];
palettei[x].g=ptmp[x+x+x+1];
palettei[x].b=ptmp[x+x+x+2];
}
ipalette=1;
}
free(fn);
if((fp=FCEUD_UTF8fopen(fn,"rb")))
{
int x;
fread(ptmp,1,192,fp);
fclose(fp);
for(x=0;x<64;x++)
{
palettei[x].r=ptmp[x+x+x];
palettei[x].g=ptmp[x+x+x+1];
palettei[x].b=ptmp[x+x+x+2];
}
ipalette=1;
}
free(fn);
}
void FCEU_ResetPalette(void)
{
if(GameInfo)
{
ChoosePalette();
WritePalette();
}
if(GameInfo)
{
ChoosePalette();
WritePalette();
}
}
static void ChoosePalette(void)
{
if(GameInfo->type==GIT_NSF)
palo=0;
else if(ipalette)
palo=palettei;
else if(ntsccol && !PAL && GameInfo->type!=GIT_VSUNI)
{
palo=paletten;
CalculatePalette();
}
else
palo=palpoint[pale];
if(GameInfo->type==GIT_NSF)
palo=0;
else if(ipalette)
palo=palettei;
else if(ntsccol && !PAL && GameInfo->type!=GIT_VSUNI)
{
palo=paletten;
CalculatePalette();
}
else
palo=palpoint[pale];
}
void WritePalette(void)
{
int x;
for(x=0;x<7;x++)
FCEUD_SetPalette(x,unvpalette[x].r,unvpalette[x].g,unvpalette[x].b);
if(GameInfo->type==GIT_NSF)
{
//for(x=0;x<128;x++)
// FCEUD_SetPalette(x,x,0,x);
}
else
{
for(x=0;x<64;x++)
FCEUD_SetPalette(128+x,palo[x].r,palo[x].g,palo[x].b);
SetNESDeemph(lastd,1);
}
int x;
for(x=0;x<7;x++)
FCEUD_SetPalette(x,unvpalette[x].r,unvpalette[x].g,unvpalette[x].b);
if(GameInfo->type==GIT_NSF)
{
//for(x=0;x<128;x++)
// FCEUD_SetPalette(x,x,0,x);
}
else
{
for(x=0;x<64;x++)
FCEUD_SetPalette(128+x,palo[x].r,palo[x].g,palo[x].b);
SetNESDeemph(lastd,1);
}
}
void FCEUI_GetNTSCTH(int *tint, int *hue)
@ -277,90 +277,90 @@ static int controllength=0;
void FCEUI_NTSCDEC(void)
{
if(ntsccol && GameInfo->type!=GIT_VSUNI &&!PAL && GameInfo->type!=GIT_NSF)
{
int which;
if(controlselect)
{
if(controllength)
{
which=controlselect==1?ntschue:ntsctint;
which--;
if(which<0) which=0;
if(controlselect==1)
ntschue=which;
else ntsctint=which;
CalculatePalette();
}
controllength=360;
}
{
int which;
if(controlselect)
{
if(controllength)
{
which=controlselect==1?ntschue:ntsctint;
which--;
if(which<0) which=0;
if(controlselect==1)
ntschue=which;
else ntsctint=which;
CalculatePalette();
}
controllength=360;
}
}
}
void FCEUI_NTSCINC(void)
{
if(ntsccol && GameInfo->type!=GIT_VSUNI && !PAL && GameInfo->type!=GIT_NSF)
if(controlselect)
{
if(controllength)
{
switch(controlselect)
{
case 1:ntschue++;
if(ntschue>128) ntschue=128;
CalculatePalette();
break;
case 2:ntsctint++;
if(ntsctint>128) ntsctint=128;
CalculatePalette();
break;
}
}
controllength=360;
}
if(ntsccol && GameInfo->type!=GIT_VSUNI && !PAL && GameInfo->type!=GIT_NSF)
if(controlselect)
{
if(controllength)
{
switch(controlselect)
{
case 1:ntschue++;
if(ntschue>128) ntschue=128;
CalculatePalette();
break;
case 2:ntsctint++;
if(ntsctint>128) ntsctint=128;
CalculatePalette();
break;
}
}
controllength=360;
}
}
void FCEUI_NTSCSELHUE(void)
{
if(ntsccol && GameInfo->type!=GIT_VSUNI && !PAL && GameInfo->type!=GIT_NSF){controlselect=1;controllength=360;}
if(ntsccol && GameInfo->type!=GIT_VSUNI && !PAL && GameInfo->type!=GIT_NSF){controlselect=1;controllength=360;}
}
void FCEUI_NTSCSELTINT(void)
{
if(ntsccol && GameInfo->type!=GIT_VSUNI && !PAL && GameInfo->type!=GIT_NSF){controlselect=2;controllength=360;}
if(ntsccol && GameInfo->type!=GIT_VSUNI && !PAL && GameInfo->type!=GIT_NSF){controlselect=2;controllength=360;}
}
void FCEU_DrawNTSCControlBars(uint8 *XBuf)
{
uint8 *XBaf;
int which=0;
int x,x2;
uint8 *XBaf;
int which=0;
int x,x2;
if(!controllength) return;
controllength--;
if(!XBuf) return;
if(!controllength) return;
controllength--;
if(!XBuf) return;
if(controlselect==1)
{
DrawTextTrans(XBuf+128-12+180*256, 256, (uint8 *)"Hue", 0x85);
which=ntschue<<1;
}
else if(controlselect==2)
{
DrawTextTrans(XBuf+128-16+180*256, 256, (uint8 *)"Tint", 0x85);
which=ntsctint<<1;
}
if(controlselect==1)
{
DrawTextTrans(XBuf+128-12+180*256, 256, (uint8 *)"Hue", 0x85);
which=ntschue<<1;
}
else if(controlselect==2)
{
DrawTextTrans(XBuf+128-16+180*256, 256, (uint8 *)"Tint", 0x85);
which=ntsctint<<1;
}
XBaf=XBuf+200*256;
for(x=0;x<which;x+=2)
{
for(x2=6;x2>=-6;x2--)
{
XBaf[x-256*x2]=0x85;
}
}
for(;x<256;x+=2)
{
for(x2=2;x2>=-2;x2--)
XBaf[x-256*x2]=0x85;
}
XBaf=XBuf+200*256;
for(x=0;x<which;x+=2)
{
for(x2=6;x2>=-6;x2--)
{
XBaf[x-256*x2]=0x85;
}
}
for(;x<256;x+=2)
{
for(x2=2;x2>=-2;x2--)
XBaf[x-256*x2]=0x85;
}
}

View File

@ -38,6 +38,7 @@
#include "state.h"
#include "video.h"
#include "input.h"
#include "driver.h"
#define VBlankON (PPU[0]&0x80) /* Generate VBlank NMI */
#define Sprite16 (PPU[0]&0x20) /* Sprites 8x16/8x8 */

File diff suppressed because it is too large Load Diff

View File

@ -24,17 +24,16 @@ enum ENUM_SSLOADPARAMS
{
SSLOADPARAM_NOBACKUP,
SSLOADPARAM_BACKUP,
SSLOADPARAM_DUMMY
};
void FCEUSS_Save(char *);
int FCEUSS_Load(char *);
bool FCEUSS_Load(char *);
//zlib values: 0 (none) through 9 (max) or -1 (default)
bool FCEUSS_SaveMS(std::ostream* outstream, int compressionLevel);
bool FCEUSS_SaveFP(FILE* fp, int compressionLevel);
bool FCEUSS_LoadFP(FILE *, ENUM_SSLOADPARAMS);
bool FCEUSS_LoadFP(std::istream* is, ENUM_SSLOADPARAMS params);
extern int CurrentState;
void FCEUSS_CheckStates(void);

View File

@ -22,8 +22,8 @@
#ifndef __FCEU_TYPES
#define __FCEU_TYPES
#include <string>
#include <stdlib.h>
#include <iosfwd>
#define FCEU_VERSION_NUMERIC 19901
#define FCEU_NAME "FCE Ultra"
@ -134,73 +134,6 @@ typedef uint32_t uint32;
typedef void (*writefunc)(uint32 A, uint8 V);
typedef uint8 (*readfunc)(uint32 A);
template<typename T, int N>
struct ValueArray
{
T data[N];
T &operator[](int index) { return data[index]; }
static const int size = N;
bool operator!=(ValueArray<T,N> &other) { return !operator==(other); }
bool operator==(ValueArray<T,N> &other)
{
for(int i=0;i<size;i++)
if(data[i] != other[i])
return false;
return true;
}
};
#include "utils/endian.h"
struct FCEU_Guid : public ValueArray<uint8,16>
{
void newGuid()
{
for(int i=0;i<size;i++)
data[i] = rand();
}
std::string toString()
{
char buf[37];
sprintf(buf,"%08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X",
FCEU_de32lsb(data),FCEU_de16lsb(data+4),FCEU_de16lsb(data+6),FCEU_de16lsb(data+8),data[10],data[11],data[12],data[13],data[14],data[15]);
return std::string(buf);
}
static FCEU_Guid fromString(std::string str)
{
FCEU_Guid ret;
ret.scan(str);
return ret;
}
static uint8 hexToByte(char** ptrptr)
{
char a = toupper(**ptrptr);
(*ptrptr)++;
char b = toupper(**ptrptr);
(*ptrptr)++;
if(a>='A') a=a-'A'+10;
else a-='0';
if(b>='A') b=b-'A'+10;
else b-='0';
return ((unsigned char)a<<4)|(unsigned char)b;
}
void scan(std::string str)
{
char* endptr = (char*)str.c_str();
FCEU_en32lsb(data,strtoul(endptr,&endptr,16));
FCEU_en16lsb(data+4,strtoul(endptr+1,&endptr,16));
FCEU_en16lsb(data+6,strtoul(endptr+1,&endptr,16));
FCEU_en16lsb(data+8,strtoul(endptr+1,&endptr,16));
endptr++;
for(int i=0;i<6;i++)
data[10+i] = hexToByte(&endptr);
}
};
#endif

View File

@ -1,22 +1,22 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2002 Xodnizel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
*
* Copyright notice for this file:
* Copyright (C) 2002 Xodnizel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* TODO: Battery backup file saving, mirror force */
/* **INCOMPLETE** */
@ -27,32 +27,33 @@
#include <string.h>
#include "types.h"
#include "fceu.h"
#include "cart.h"
#include "unif.h"
#include "ines.h"
#include "utils/endian.h"
#include "utils/memory.h"
#include "utils/md5.h"
#include "state.h"
#include "file.h"
#include "input.h"
#include "types.h"
#include "fceu.h"
#include "cart.h"
#include "unif.h"
#include "ines.h"
#include "utils/endian.h"
#include "utils/memory.h"
#include "utils/md5.h"
#include "state.h"
#include "file.h"
#include "input.h"
#include "driver.h"
typedef struct {
char ID[4];
uint32 info;
char ID[4];
uint32 info;
} UNIF_HEADER;
typedef struct {
char *name;
void (*init)(CartInfo *);
int flags;
char *name;
void (*init)(CartInfo *);
int flags;
} BMAPPING;
typedef struct {
char *name;
int (*init)(FCEUFILE *fp);
char *name;
int (*init)(FCEUFILE *fp);
} BFMAPPING;
static CartInfo UNIFCart;
@ -74,238 +75,238 @@ static uint32 mallocedsizes[32];
static int FixRomSize(uint32 size, uint32 minimum)
{
uint32 x=1; //mbg merge 7/17/06 made uint
uint32 x=1; //mbg merge 7/17/06 made uint
if(size<minimum)
return minimum;
while(x<size)
x<<=1;
return x;
if(size<minimum)
return minimum;
while(x<size)
x<<=1;
return x;
}
static void FreeUNIF(void)
{
int x;
if(UNIFchrrama)
{free(UNIFchrrama);UNIFchrrama=0;}
if(boardname)
{free(boardname);boardname=0;}
for(x=0;x<32;x++)
{
if(malloced[x])
{free(malloced[x]);malloced[x]=0;}
}
int x;
if(UNIFchrrama)
{free(UNIFchrrama);UNIFchrrama=0;}
if(boardname)
{free(boardname);boardname=0;}
for(x=0;x<32;x++)
{
if(malloced[x])
{free(malloced[x]);malloced[x]=0;}
}
}
static void ResetUNIF(void)
{
int x;
for(x=0;x<32;x++)
malloced[x]=0;
vramo=0;
boardname=0;
mirrortodo=0;
memset(&UNIFCart,0,sizeof(UNIFCart));
UNIFchrrama=0;
int x;
for(x=0;x<32;x++)
malloced[x]=0;
vramo=0;
boardname=0;
mirrortodo=0;
memset(&UNIFCart,0,sizeof(UNIFCart));
UNIFchrrama=0;
}
static uint8 exntar[2048];
static void MooMirroring(void)
{
if(mirrortodo<0x4)
SetupCartMirroring(mirrortodo,1,0);
else if(mirrortodo==0x4)
{
SetupCartMirroring(4,1,exntar);
AddExState(exntar, 2048, 0,"EXNR");
}
else
SetupCartMirroring(0,0,0);
if(mirrortodo<0x4)
SetupCartMirroring(mirrortodo,1,0);
else if(mirrortodo==0x4)
{
SetupCartMirroring(4,1,exntar);
AddExState(exntar, 2048, 0,"EXNR");
}
else
SetupCartMirroring(0,0,0);
}
static int DoMirroring(FCEUFILE *fp)
{
uint8 t;
t=FCEU_fgetc(fp);
mirrortodo=t;
uint8 t;
t=FCEU_fgetc(fp);
mirrortodo=t;
{
static char *stuffo[6]={"Horizontal","Vertical","$2000","$2400","\"Four-screen\"","Controlled by Mapper Hardware"};
if(t<6)
FCEU_printf(" Name/Attribute Table Mirroring: %s\n",stuffo[t]);
}
return(1);
{
static char *stuffo[6]={"Horizontal","Vertical","$2000","$2400","\"Four-screen\"","Controlled by Mapper Hardware"};
if(t<6)
FCEU_printf(" Name/Attribute Table Mirroring: %s\n",stuffo[t]);
}
return(1);
}
static int NAME(FCEUFILE *fp)
{
char namebuf[100];
int index;
int t;
char namebuf[100];
int index;
int t;
FCEU_printf(" Name: ");
index=0;
FCEU_printf(" Name: ");
index=0;
while((t=FCEU_fgetc(fp))>0)
if(index<99)
namebuf[index++]=t;
while((t=FCEU_fgetc(fp))>0)
if(index<99)
namebuf[index++]=t;
namebuf[index]=0;
FCEU_printf("%s\n",namebuf);
namebuf[index]=0;
FCEU_printf("%s\n",namebuf);
if(!GameInfo->name)
{
GameInfo->name=(uint8*)malloc(strlen(namebuf)+1); //mbg merge 7/17/06 added cast
strcpy((char*)GameInfo->name,namebuf); //mbg merge 7/17/06 added cast
}
return(1);
if(!GameInfo->name)
{
GameInfo->name=(uint8*)malloc(strlen(namebuf)+1); //mbg merge 7/17/06 added cast
strcpy((char*)GameInfo->name,namebuf); //mbg merge 7/17/06 added cast
}
return(1);
}
static int DINF(FCEUFILE *fp)
{
char name[100], method[100];
uint8 d, m;
uint16 y;
int t;
char name[100], method[100];
uint8 d, m;
uint16 y;
int t;
if(FCEU_fread(name,1,100,fp)!=100)
return(0);
if((t=FCEU_fgetc(fp))==EOF) return(0);
d=t;
if((t=FCEU_fgetc(fp))==EOF) return(0);
m=t;
if((t=FCEU_fgetc(fp))==EOF) return(0);
y=t;
if((t=FCEU_fgetc(fp))==EOF) return(0);
y|=t<<8;
if(FCEU_fread(method,1,100,fp)!=100)
return(0);
name[99]=method[99]=0;
FCEU_printf(" Dumped by: %s\n",name);
FCEU_printf(" Dumped with: %s\n",method);
{
char *months[12]={"January","February","March","April","May","June","July",
"August","September","October","November","December"};
FCEU_printf(" Dumped on: %s %d, %d\n",months[(m-1)%12],d,y);
}
return(1);
if(FCEU_fread(name,1,100,fp)!=100)
return(0);
if((t=FCEU_fgetc(fp))==EOF) return(0);
d=t;
if((t=FCEU_fgetc(fp))==EOF) return(0);
m=t;
if((t=FCEU_fgetc(fp))==EOF) return(0);
y=t;
if((t=FCEU_fgetc(fp))==EOF) return(0);
y|=t<<8;
if(FCEU_fread(method,1,100,fp)!=100)
return(0);
name[99]=method[99]=0;
FCEU_printf(" Dumped by: %s\n",name);
FCEU_printf(" Dumped with: %s\n",method);
{
char *months[12]={"January","February","March","April","May","June","July",
"August","September","October","November","December"};
FCEU_printf(" Dumped on: %s %d, %d\n",months[(m-1)%12],d,y);
}
return(1);
}
static int CTRL(FCEUFILE *fp)
{
int t;
int t;
if((t=FCEU_fgetc(fp))==EOF)
return(0);
/* The information stored in this byte isn't very helpful, but it's
better than nothing...maybe.
*/
if((t=FCEU_fgetc(fp))==EOF)
return(0);
/* The information stored in this byte isn't very helpful, but it's
better than nothing...maybe.
*/
if(t&1) GameInfo->input[0]=GameInfo->input[1]=SI_GAMEPAD;
else GameInfo->input[0]=GameInfo->input[1]=SI_NONE;
if(t&1) GameInfo->input[0]=GameInfo->input[1]=SI_GAMEPAD;
else GameInfo->input[0]=GameInfo->input[1]=SI_NONE;
if(t&2) GameInfo->input[1]=SI_ZAPPER;
//else if(t&0x10) GameInfo->input[1]=SI_POWERPAD;
if(t&2) GameInfo->input[1]=SI_ZAPPER;
//else if(t&0x10) GameInfo->input[1]=SI_POWERPAD;
return(1);
return(1);
}
static int TVCI(FCEUFILE *fp)
{
int t;
if( (t=FCEU_fgetc(fp)) ==EOF)
return(0);
if(t<=2)
{
char *stuffo[3]={"NTSC","PAL","NTSC and PAL"};
if(t==0)
{
GameInfo->vidsys=GIV_NTSC;
FCEUI_SetVidSystem(0);
}
else if(t==1)
{
GameInfo->vidsys=GIV_PAL;
FCEUI_SetVidSystem(1);
}
FCEU_printf(" TV Standard Compatibility: %s\n",stuffo[t]);
}
return(1);
int t;
if( (t=FCEU_fgetc(fp)) ==EOF)
return(0);
if(t<=2)
{
char *stuffo[3]={"NTSC","PAL","NTSC and PAL"};
if(t==0)
{
GameInfo->vidsys=GIV_NTSC;
FCEUI_SetVidSystem(0);
}
else if(t==1)
{
GameInfo->vidsys=GIV_PAL;
FCEUI_SetVidSystem(1);
}
FCEU_printf(" TV Standard Compatibility: %s\n",stuffo[t]);
}
return(1);
}
static int EnableBattery(FCEUFILE *fp)
{
FCEU_printf(" Battery-backed.\n");
if(FCEU_fgetc(fp)==EOF)
return(0);
UNIFCart.battery=1;
return(1);
FCEU_printf(" Battery-backed.\n");
if(FCEU_fgetc(fp)==EOF)
return(0);
UNIFCart.battery=1;
return(1);
}
static int LoadPRG(FCEUFILE *fp)
{
int z,t;
z=uchead.ID[3]-'0';
int z,t;
z=uchead.ID[3]-'0';
if(z<0 || z>15)
return(0);
FCEU_printf(" PRG ROM %d size: %d",z,(int) uchead.info);
if(malloced[z])
free(malloced[z]);
t=FixRomSize(uchead.info,2048);
if(!(malloced[z]=(uint8 *)FCEU_malloc(t)))
return(0);
mallocedsizes[z]=t;
memset(malloced[z]+uchead.info,0xFF,t-uchead.info);
if(FCEU_fread(malloced[z],1,uchead.info,fp)!=uchead.info)
{
FCEU_printf("Read Error!\n");
return(0);
}
else
FCEU_printf("\n");
if(z<0 || z>15)
return(0);
FCEU_printf(" PRG ROM %d size: %d",z,(int) uchead.info);
if(malloced[z])
free(malloced[z]);
t=FixRomSize(uchead.info,2048);
if(!(malloced[z]=(uint8 *)FCEU_malloc(t)))
return(0);
mallocedsizes[z]=t;
memset(malloced[z]+uchead.info,0xFF,t-uchead.info);
if(FCEU_fread(malloced[z],1,uchead.info,fp)!=uchead.info)
{
FCEU_printf("Read Error!\n");
return(0);
}
else
FCEU_printf("\n");
SetupCartPRGMapping(z,malloced[z],t,0);
return(1);
SetupCartPRGMapping(z,malloced[z],t,0);
return(1);
}
static int SetBoardName(FCEUFILE *fp)
{
if(!(boardname=(uint8 *)FCEU_malloc(uchead.info+1)))
return(0);
FCEU_fread(boardname,1,uchead.info,fp);
boardname[uchead.info]=0;
FCEU_printf(" Board name: %s\n",boardname);
sboardname=boardname;
if(!memcmp(boardname,"NES-",4) || !memcmp(boardname,"UNL-",4) || !memcmp(boardname,"HVC-",4) || !memcmp(boardname,"BTL-",4) || !memcmp(boardname,"BMC-",4))
sboardname+=4;
return(1);
if(!(boardname=(uint8 *)FCEU_malloc(uchead.info+1)))
return(0);
FCEU_fread(boardname,1,uchead.info,fp);
boardname[uchead.info]=0;
FCEU_printf(" Board name: %s\n",boardname);
sboardname=boardname;
if(!memcmp(boardname,"NES-",4) || !memcmp(boardname,"UNL-",4) || !memcmp(boardname,"HVC-",4) || !memcmp(boardname,"BTL-",4) || !memcmp(boardname,"BMC-",4))
sboardname+=4;
return(1);
}
static int LoadCHR(FCEUFILE *fp)
{
int z,t;
z=uchead.ID[3]-'0';
if(z<0 || z>15)
return(0);
FCEU_printf(" CHR ROM %d size: %d",z,(int) uchead.info);
if(malloced[16+z])
free(malloced[16+z]);
t=FixRomSize(uchead.info,8192);
if(!(malloced[16+z]=(uint8 *)FCEU_malloc(t)))
return(0);
mallocedsizes[16+z]=t;
memset(malloced[16+z]+uchead.info,0xFF,t-uchead.info);
if(FCEU_fread(malloced[16+z],1,uchead.info,fp)!=uchead.info)
{
FCEU_printf("Read Error!\n");
return(0);
}
else
FCEU_printf("\n");
int z,t;
z=uchead.ID[3]-'0';
if(z<0 || z>15)
return(0);
FCEU_printf(" CHR ROM %d size: %d",z,(int) uchead.info);
if(malloced[16+z])
free(malloced[16+z]);
t=FixRomSize(uchead.info,8192);
if(!(malloced[16+z]=(uint8 *)FCEU_malloc(t)))
return(0);
mallocedsizes[16+z]=t;
memset(malloced[16+z]+uchead.info,0xFF,t-uchead.info);
if(FCEU_fread(malloced[16+z],1,uchead.info,fp)!=uchead.info)
{
FCEU_printf("Read Error!\n");
return(0);
}
else
FCEU_printf("\n");
SetupCartCHRMapping(z,malloced[16+z],t,0);
return(1);
SetupCartCHRMapping(z,malloced[16+z],t,0);
return(1);
}
@ -315,257 +316,257 @@ static int LoadCHR(FCEUFILE *fp)
static BMAPPING bmap[] = {
/* Sachen Carts */
{ "TC-U01-1.5M", TCU01_Init,0},
{ "Sachen-8259A", S8259A_Init,0},
{ "Sachen-8259B", S8259B_Init,0},
{ "Sachen-8259C", S8259C_Init,0},
{ "Sachen-8259D", S8259D_Init,0},
{ "Sachen-74LS374N", S74LS374N_Init,0},
{ "Sachen-74LS374NA", S74LS374NA_Init,0}, //seems to be custom mapper
{ "SA-016-1M", SA0161M_Init,0},
{ "SA-72007", SA72007_Init,0},
{ "SA-72008", SA72008_Init,0},
{ "SA-0036", SA0036_Init,0},
{ "SA-0037", SA0037_Init,0},
{ "SA-NROM", TCA01_Init,0},
/* Sachen Carts */
{ "TC-U01-1.5M", TCU01_Init,0},
{ "Sachen-8259A", S8259A_Init,0},
{ "Sachen-8259B", S8259B_Init,0},
{ "Sachen-8259C", S8259C_Init,0},
{ "Sachen-8259D", S8259D_Init,0},
{ "Sachen-74LS374N", S74LS374N_Init,0},
{ "Sachen-74LS374NA", S74LS374NA_Init,0}, //seems to be custom mapper
{ "SA-016-1M", SA0161M_Init,0},
{ "SA-72007", SA72007_Init,0},
{ "SA-72008", SA72008_Init,0},
{ "SA-0036", SA0036_Init,0},
{ "SA-0037", SA0037_Init,0},
{ "SA-NROM", TCA01_Init,0},
// /* AVE carts. */
// { "MB-91", MB91_Init,0}, // DeathBots
// { "NINA-06", NINA06_Init,0}, // F-15 City War
// { "NINA-03", NINA03_Init,0}, // Tiles of Fate
// { "NINA-001", NINA001_Init,0}, // Impossible Mission 2
// /* AVE carts. */
// { "MB-91", MB91_Init,0}, // DeathBots
// { "NINA-06", NINA06_Init,0}, // F-15 City War
// { "NINA-03", NINA03_Init,0}, // Tiles of Fate
// { "NINA-001", NINA001_Init,0}, // Impossible Mission 2
{ "ANROM", ANROM_Init,0},
{ "ANROM", ANROM_Init,0},
{ "HKROM", HKROM_Init,0},
{ "HKROM", HKROM_Init,0},
{ "EWROM", EWROM_Init,0},
{ "EKROM", EKROM_Init,0},
{ "ELROM", ELROM_Init,0},
{ "ETROM", ETROM_Init,0},
{ "EWROM", EWROM_Init,0},
{ "EKROM", EKROM_Init,0},
{ "ELROM", ELROM_Init,0},
{ "ETROM", ETROM_Init,0},
{ "SAROM", SAROM_Init,0},
{ "SBROM", SBROM_Init,0},
{ "SCROM", SCROM_Init,0},
{ "SEROM", SEROM_Init,0},
{ "SGROM", SGROM_Init,0},
{ "SKROM", SKROM_Init,0},
{ "SLROM", SLROM_Init,0},
{ "SL1ROM", SL1ROM_Init,0},
{ "SNROM", SNROM_Init,0},
{ "SOROM", SOROM_Init,0},
{ "SAROM", SAROM_Init,0},
{ "SBROM", SBROM_Init,0},
{ "SCROM", SCROM_Init,0},
{ "SEROM", SEROM_Init,0},
{ "SGROM", SGROM_Init,0},
{ "SKROM", SKROM_Init,0},
{ "SLROM", SLROM_Init,0},
{ "SL1ROM", SL1ROM_Init,0},
{ "SNROM", SNROM_Init,0},
{ "SOROM", SOROM_Init,0},
{ "TGROM", TGROM_Init,0},
{ "TR1ROM", TFROM_Init,BMCFLAG_FORCE4},
{ "TGROM", TGROM_Init,0},
{ "TR1ROM", TFROM_Init,BMCFLAG_FORCE4},
{ "TEROM", TEROM_Init,0},
{ "TFROM", TFROM_Init,0},
{ "TLROM", TLROM_Init,0},
{ "TKROM", TKROM_Init,0},
{ "TSROM", TSROM_Init,0},
{ "TEROM", TEROM_Init,0},
{ "TFROM", TFROM_Init,0},
{ "TLROM", TLROM_Init,0},
{ "TKROM", TKROM_Init,0},
{ "TSROM", TSROM_Init,0},
{ "TLSROM", TLSROM_Init,0},
{ "TKSROM", TKSROM_Init,0},
{ "TQROM", TQROM_Init,0},
{ "TVROM", TLROM_Init,BMCFLAG_FORCE4},
{ "TLSROM", TLSROM_Init,0},
{ "TKSROM", TKSROM_Init,0},
{ "TQROM", TQROM_Init,0},
{ "TVROM", TLROM_Init,BMCFLAG_FORCE4},
{ "CPROM", CPROM_Init,BMCFLAG_16KCHRR},
{ "CNROM", CNROM_Init,0},
{ "NROM", NROM_Init,0 }, //NROM256_Init,0 },
{ "NROM-128", NROM_Init,0 }, //NROM128_Init,0 },
{ "NROM-256", NROM_Init,0 }, //NROM256_Init,0 },
{ "RROM", NROM_Init,0 }, //NROM128_Init,0 },
{ "RROM-128", NROM_Init,0 }, //NROM128_Init,0 },
{ "MHROM", MHROM_Init,0},
{ "UNROM", UNROM_Init,0},
{ "SUNSOFT_UNROM", SUNSOFT_UNROM_Init,0},
{ "MARIO1-MALEE2", MALEE_Init,0},
{ "CPROM", CPROM_Init,BMCFLAG_16KCHRR},
{ "CNROM", CNROM_Init,0},
{ "NROM", NROM_Init,0 }, //NROM256_Init,0 },
{ "NROM-128", NROM_Init,0 }, //NROM128_Init,0 },
{ "NROM-256", NROM_Init,0 }, //NROM256_Init,0 },
{ "RROM", NROM_Init,0 }, //NROM128_Init,0 },
{ "RROM-128", NROM_Init,0 }, //NROM128_Init,0 },
{ "MHROM", MHROM_Init,0},
{ "UNROM", UNROM_Init,0},
{ "SUNSOFT_UNROM", SUNSOFT_UNROM_Init,0},
{ "MARIO1-MALEE2", MALEE_Init,0},
{ "CC-21", UNLCC21_Init,0},
{ "CC-21", UNLCC21_Init,0},
{ "H2288", UNLH2288_Init,0},
{ "KOF97", UNLKOF97_Init,0},
{ "SL1632", UNLSL1632_Init,0},
{ "SHERO", UNLSHeroes_Init,0},
{ "8237", UNL8237_Init,0},
{ "8157", UNL8157_Init,0},
{ "T-262", BMCT262_Init,0},
{ "FK23C", BMCFK23C_Init,0},
{ "A65AS", BMCA65AS_Init,0},
{ "C-N22M", UNLCN22M_Init,0},
{ "EDU2000", UNLEDU2000_Init,0},
{ "603-5052", UNL6035052_Init,0},
{ "Supervision16in1", Supervision16_Init,0},
{ "NovelDiamond9999999in1", Novel_Init,0},
{ "Super24in1SC03", Super24_Init,0},
{ "42in1ResetSwitch", BMC42in1r_Init, 0},
{ "64in1NoRepeat", BMC64in1nr_Init, 0},
{ "13in1JY110", BMC13in1JY110_Init, 0},
{ "70in1", BMC70in1_Init, 0},
{ "70in1B", BMC70in1B_Init, 0},
{ "D1038", BMCD1038_Init, 0},
{ "GK-192", BMCGK192_Init, 0},
{ "SuperHIK8in1", Mapper45_Init,0},
{ "22211", UNL22211_Init,0},
{ "H2288", UNLH2288_Init,0},
{ "KOF97", UNLKOF97_Init,0},
{ "SL1632", UNLSL1632_Init,0},
{ "SHERO", UNLSHeroes_Init,0},
{ "8237", UNL8237_Init,0},
{ "8157", UNL8157_Init,0},
{ "T-262", BMCT262_Init,0},
{ "FK23C", BMCFK23C_Init,0},
{ "A65AS", BMCA65AS_Init,0},
{ "C-N22M", UNLCN22M_Init,0},
{ "EDU2000", UNLEDU2000_Init,0},
{ "603-5052", UNL6035052_Init,0},
{ "Supervision16in1", Supervision16_Init,0},
{ "NovelDiamond9999999in1", Novel_Init,0},
{ "Super24in1SC03", Super24_Init,0},
{ "42in1ResetSwitch", BMC42in1r_Init, 0},
{ "64in1NoRepeat", BMC64in1nr_Init, 0},
{ "13in1JY110", BMC13in1JY110_Init, 0},
{ "70in1", BMC70in1_Init, 0},
{ "70in1B", BMC70in1B_Init, 0},
{ "D1038", BMCD1038_Init, 0},
{ "GK-192", BMCGK192_Init, 0},
{ "SuperHIK8in1", Mapper45_Init,0},
{ "22211", UNL22211_Init,0},
{ "DREAMTECH01", DreamTech01_Init,0},
{ "KONAMI-QTAI", Mapper190_Init,0},
{ "DREAMTECH01", DreamTech01_Init,0},
{ "KONAMI-QTAI", Mapper190_Init,0},
{ "TEK90", Mapper90_Init,0},
{ "TEK90", Mapper90_Init,0},
{0,0,0}
{0,0,0}
};
static BFMAPPING bfunc[] = {
{ "CTRL", CTRL },
{ "TVCI", TVCI },
{ "BATR", EnableBattery },
{ "MIRR", DoMirroring },
{ "PRG", LoadPRG },
{ "CHR", LoadCHR },
{ "NAME", NAME },
{ "MAPR", SetBoardName },
{ "DINF", DINF },
{ 0, 0 }
{ "CTRL", CTRL },
{ "TVCI", TVCI },
{ "BATR", EnableBattery },
{ "MIRR", DoMirroring },
{ "PRG", LoadPRG },
{ "CHR", LoadCHR },
{ "NAME", NAME },
{ "MAPR", SetBoardName },
{ "DINF", DINF },
{ 0, 0 }
};
int LoadUNIFChunks(FCEUFILE *fp)
{
int x;
int t;
for(;;)
{
t=FCEU_fread(&uchead,1,4,fp);
if(t<4)
{
if(t>0)
return 0;
return 1;
}
if(!(FCEU_read32le(&uchead.info,fp)))
return 0;
t=0;
x=0;
//printf("Funky: %s\n",((uint8 *)&uchead));
while(bfunc[x].name)
{
if(!memcmp(&uchead,bfunc[x].name,strlen(bfunc[x].name)))
{
if(!bfunc[x].init(fp))
return 0;
t=1;
break;
}
x++;
}
if(!t)
if(FCEU_fseek(fp,uchead.info,SEEK_CUR))
return(0);
}
int x;
int t;
for(;;)
{
t=FCEU_fread(&uchead,1,4,fp);
if(t<4)
{
if(t>0)
return 0;
return 1;
}
if(!(FCEU_read32le(&uchead.info,fp)))
return 0;
t=0;
x=0;
//printf("Funky: %s\n",((uint8 *)&uchead));
while(bfunc[x].name)
{
if(!memcmp(&uchead,bfunc[x].name,strlen(bfunc[x].name)))
{
if(!bfunc[x].init(fp))
return 0;
t=1;
break;
}
x++;
}
if(!t)
if(FCEU_fseek(fp,uchead.info,SEEK_CUR))
return(0);
}
}
static int InitializeBoard(void)
{
int x=0;
int x=0;
if(!sboardname) return(0);
if(!sboardname) return(0);
while(bmap[x].name)
{
if(!strcmp((char *)sboardname,(char *)bmap[x].name))
{
if(!malloced[16])
{
if(bmap[x].flags & BMCFLAG_16KCHRR)
CHRRAMSize = 16384;
else
CHRRAMSize = 8192;
if((UNIFchrrama=(uint8 *)FCEU_malloc(CHRRAMSize)))
{
SetupCartCHRMapping(0,UNIFchrrama,CHRRAMSize,1);
AddExState(UNIFchrrama, CHRRAMSize, 0,"CHRR");
}
else
return(-1);
}
if(bmap[x].flags&BMCFLAG_FORCE4)
mirrortodo=4;
MooMirroring();
bmap[x].init(&UNIFCart);
return(1);
}
x++;
}
FCEU_PrintError("Board type not supported.");
return(0);
while(bmap[x].name)
{
if(!strcmp((char *)sboardname,(char *)bmap[x].name))
{
if(!malloced[16])
{
if(bmap[x].flags & BMCFLAG_16KCHRR)
CHRRAMSize = 16384;
else
CHRRAMSize = 8192;
if((UNIFchrrama=(uint8 *)FCEU_malloc(CHRRAMSize)))
{
SetupCartCHRMapping(0,UNIFchrrama,CHRRAMSize,1);
AddExState(UNIFchrrama, CHRRAMSize, 0,"CHRR");
}
else
return(-1);
}
if(bmap[x].flags&BMCFLAG_FORCE4)
mirrortodo=4;
MooMirroring();
bmap[x].init(&UNIFCart);
return(1);
}
x++;
}
FCEU_PrintError("Board type not supported.");
return(0);
}
static void UNIFGI(int h)
{
switch(h)
{
case GI_RESETM2:
if(UNIFCart.Reset)
UNIFCart.Reset();
switch(h)
{
case GI_RESETM2:
if(UNIFCart.Reset)
UNIFCart.Reset();
break;
case GI_POWER:
if(UNIFCart.Power)
UNIFCart.Power();
case GI_POWER:
if(UNIFCart.Power)
UNIFCart.Power();
if(UNIFchrrama) memset(UNIFchrrama,0,8192);
break;
case GI_CLOSE:
FCEU_SaveGameSave(&UNIFCart);
case GI_CLOSE:
FCEU_SaveGameSave(&UNIFCart);
if(UNIFCart.Close)
UNIFCart.Close();
FreeUNIF();
break;
}
UNIFCart.Close();
FreeUNIF();
break;
}
}
int UNIFLoad(const char *name, FCEUFILE *fp)
{
FCEU_fseek(fp,0,SEEK_SET);
FCEU_fread(&unhead,1,4,fp);
if(memcmp(&unhead,"UNIF",4))
return 0;
FCEU_fseek(fp,0,SEEK_SET);
FCEU_fread(&unhead,1,4,fp);
if(memcmp(&unhead,"UNIF",4))
return 0;
ResetCartMapping();
ResetExState(0,0);
ResetUNIF();
if(!FCEU_read32le(&unhead.info,fp))
goto aborto;
if(FCEU_fseek(fp,0x20,SEEK_SET)<0)
goto aborto;
if(!LoadUNIFChunks(fp))
goto aborto;
ResetExState(0,0);
ResetUNIF();
if(!FCEU_read32le(&unhead.info,fp))
goto aborto;
if(FCEU_fseek(fp,0x20,SEEK_SET)<0)
goto aborto;
if(!LoadUNIFChunks(fp))
goto aborto;
{
int x;
struct md5_context md5;
md5_starts(&md5);
int x;
struct md5_context md5;
for(x=0;x<32;x++)
if(malloced[x])
{
md5_update(&md5,malloced[x],mallocedsizes[x]);
}
md5_finish(&md5,UNIFCart.MD5);
FCEU_printf(" ROM MD5: 0x");
for(x=0;x<16;x++)
FCEU_printf("%02x",UNIFCart.MD5[x]);
FCEU_printf("\n");
memcpy(&GameInfo->MD5,&UNIFCart.MD5,sizeof(UNIFCart.MD5));
md5_starts(&md5);
for(x=0;x<32;x++)
if(malloced[x])
{
md5_update(&md5,malloced[x],mallocedsizes[x]);
}
md5_finish(&md5,UNIFCart.MD5);
FCEU_printf(" ROM MD5: 0x");
for(x=0;x<16;x++)
FCEU_printf("%02x",UNIFCart.MD5[x]);
FCEU_printf("\n");
memcpy(&GameInfo->MD5,&UNIFCart.MD5,sizeof(UNIFCart.MD5));
}
if(!InitializeBoard())
goto aborto;
if(!InitializeBoard())
goto aborto;
FCEU_LoadGameSave(&UNIFCart);
GameInterface=UNIFGI;
return 1;
aborto:
GameInterface=UNIFGI;
return 1;
aborto:
FreeUNIF();
ResetUNIF();

View File

@ -23,6 +23,7 @@
#include <stdio.h>
#include <ostream>
#include <fstream>
#include "../types.h"
#include "endian.h"
@ -91,6 +92,19 @@ int read32le(uint32 *Bufo, FILE *fp)
return 1;
}
int read32le(uint32 *Bufo, std::istream *is)
{
uint32 buf;
if(is->readsome((char*)&buf,4) != 4)
return 0;
#ifdef LSB_FIRST
*(uint32*)Bufo=buf;
#else
*(uint32*)Bufo=((buf&0xFF)<<24)|((buf&0xFF00)<<8)|((buf&0xFF0000)>>8)|((buf&0xFF000000)>>24);
#endif
return 1;
}
///reads a little endian 16bit value from the specified file
int read16le(char *d, FILE *fp)
{

View File

@ -1,9 +1,14 @@
#ifndef __FCEU_ENDIAN
#define __FCEU_ENDIAN
//#include <iosfwd>
#include <stdio.h>
int write16le(uint16 b, FILE *fp);
int write32le(uint32 b, FILE *fp);
int write32le(uint32 b, std::ostream* os);
int read32le(uint32 *Bufo, std::istream *is);
int read32le(uint32 *Bufo, FILE *fp);
void FlipByteOrder(uint8 *src, uint32 count);

47
src/utils/guid.cpp Normal file
View File

@ -0,0 +1,47 @@
#include "guid.h"
void FCEU_Guid::newGuid()
{
for(int i=0;i<size;i++)
data[i] = rand();
}
std::string FCEU_Guid::toString()
{
char buf[37];
sprintf(buf,"%08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X",
FCEU_de32lsb(data),FCEU_de16lsb(data+4),FCEU_de16lsb(data+6),FCEU_de16lsb(data+8),data[10],data[11],data[12],data[13],data[14],data[15]);
return std::string(buf);
}
FCEU_Guid FCEU_Guid::fromString(std::string str)
{
FCEU_Guid ret;
ret.scan(str);
return ret;
}
uint8 FCEU_Guid::hexToByte(char** ptrptr)
{
char a = toupper(**ptrptr);
(*ptrptr)++;
char b = toupper(**ptrptr);
(*ptrptr)++;
if(a>='A') a=a-'A'+10;
else a-='0';
if(b>='A') b=b-'A'+10;
else b-='0';
return ((unsigned char)a<<4)|(unsigned char)b;
}
void FCEU_Guid::scan(std::string& str)
{
char* endptr = (char*)str.c_str();
FCEU_en32lsb(data,strtoul(endptr,&endptr,16));
FCEU_en16lsb(data+4,strtoul(endptr+1,&endptr,16));
FCEU_en16lsb(data+6,strtoul(endptr+1,&endptr,16));
FCEU_en16lsb(data+8,strtoul(endptr+1,&endptr,16));
endptr++;
for(int i=0;i<6;i++)
data[10+i] = hexToByte(&endptr);
}

18
src/utils/guid.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef _guid_h_
#define _guid_h_
#include <string>
#include "types.h"
#include "valuearray.h"
struct FCEU_Guid : public ValueArray<uint8,16>
{
void newGuid();
std::string toString();
static FCEU_Guid fromString(std::string str);
static uint8 hexToByte(char** ptrptr);
void scan(std::string& str);
};
#endif

View File

@ -2,6 +2,7 @@
#define _MD5_H
#include "../types.h"
#include "valuearray.h"
struct md5_context
{

20
src/utils/valuearray.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef _VALUEARRAY_H_
#define _VALUEARRAY_H_
template<typename T, int N>
struct ValueArray
{
T data[N];
T &operator[](int index) { return data[index]; }
static const int size = N;
bool operator!=(ValueArray<T,N> &other) { return !operator==(other); }
bool operator==(ValueArray<T,N> &other)
{
for(int i=0;i<size;i++)
if(data[i] != other[i])
return false;
return true;
}
};
#endif

View File

@ -477,4 +477,10 @@ unsigned int uintDecFromIstream(std::istream* is)
}
is->unget();
return ret;
}
std::string stditoa(int n)
{
char tempbuf[16];
return itoa(n,tempbuf,10);
}

View File

@ -55,5 +55,7 @@ char *U8ToDecStr(uint8 a);
char *U8ToHexStr(uint8 a);
char *U16ToHexStr(uint16 a);
std::string stditoa(int n);
//extracts a decimal uint from an istream
unsigned int uintDecFromIstream(std::istream* is);

View File

@ -1,22 +1,22 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2002 Xodnizel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
*
* Copyright notice for this file:
* Copyright (C) 2002 Xodnizel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef WIN32
#include <stdint.h>
@ -64,22 +64,22 @@ HANDLE mapXBuf;
void FCEU_KillVirtualVideo(void)
{
//mbg merge TODO 7/17/06 temporarily removed
//if(xbsave)
//{
// free(xbsave);
// xbsave=0;
//}
//if(XBuf)
//{
//if(xbsave)
//{
// free(xbsave);
// xbsave=0;
//}
//if(XBuf)
//{
//UnmapViewOfFile(XBuf);
//CloseHandle(mapXBuf);
//mapXBuf=NULL;
//}
//if(XBackBuf)
//{
// free(XBackBuf);
// XBackBuf=0;
//}
//}
//if(XBackBuf)
//{
// free(XBackBuf);
// XBackBuf=0;
//}
}
/**
@ -90,13 +90,13 @@ void FCEU_KillVirtualVideo(void)
int FCEU_InitVirtualVideo(void)
{
if(!XBuf) /* Some driver code may allocate XBuf externally. */
/* 256 bytes per scanline, * 240 scanline maximum, +16 for alignment,
*/
/* 256 bytes per scanline, * 240 scanline maximum, +16 for alignment,
*/
#ifdef _USE_SHARED_MEMORY_
mapXBuf = CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE, 0, 256 * 256 + 16, "fceu.XBuf");
mapXBuf = CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,PAGE_READWRITE, 0, 256 * 256 + 16, "fceu.XBuf");
if(mapXBuf == NULL || GetLastError() == ERROR_ALREADY_EXISTS)
{
CloseHandle(mapXBuf);
@ -114,30 +114,30 @@ int FCEU_InitVirtualVideo(void)
{
return 0;
}
#else
if(!(XBuf= (uint8*) (FCEU_malloc(256 * 256 + 16))) ||
!(XBackBuf= (uint8*) (FCEU_malloc(256 * 256 + 16))))
{
return 0;
}
if(!(XBuf= (uint8*) (FCEU_malloc(256 * 256 + 16))) ||
!(XBackBuf= (uint8*) (FCEU_malloc(256 * 256 + 16))))
{
return 0;
}
#endif //_USE_SHARED_MEMORY_
xbsave = XBuf;
xbsave = XBuf;
if( sizeof(uint8*) == 4 )
{
uintptr_t m = (uintptr_t)XBuf;
m = ( 8 - m) & 7;
XBuf+=m;
}
memset(XBuf,128,256*256); //*240);
memset(XBackBuf,128,256*256);
return 1;
if( sizeof(uint8*) == 4 )
{
uintptr_t m = (uintptr_t)XBuf;
m = ( 8 - m) & 7;
XBuf+=m;
}
memset(XBuf,128,256*256); //*240);
memset(XBackBuf,128,256*256);
return 1;
}
@ -147,23 +147,23 @@ int FCEU_InitVirtualVideo(void)
void ShowFPS(void);
void FCEU_PutImageDummy(void)
{
#ifdef SHOWFPS
ShowFPS();
#endif
if(GameInfo->type!=GIT_NSF)
{
FCEU_DrawNTSCControlBars(XBuf);
FCEU_DrawSaveStates(XBuf);
FCEU_DrawMovies(XBuf);
}
if(guiMessage.howlong) guiMessage.howlong--; /* DrawMessage() */
#ifdef SHOWFPS
ShowFPS();
#endif
if(GameInfo->type!=GIT_NSF)
{
FCEU_DrawNTSCControlBars(XBuf);
FCEU_DrawSaveStates(XBuf);
FCEU_DrawMovies(XBuf);
}
if(guiMessage.howlong) guiMessage.howlong--; /* DrawMessage() */
}
#endif
static int dosnapsave=0;
void FCEUI_SaveSnapshot(void)
{
dosnapsave=1;
dosnapsave=1;
}
@ -182,11 +182,11 @@ void FCEU_PutImage(void)
#ifdef SHOWFPS
ShowFPS();
#endif
if(GameInfo->type==GIT_NSF)
{
DrawNSF(XBuf);
//Save snapshot after NSF screen is drawn. Why would we want to do it before?
if(dosnapsave)
{
@ -203,7 +203,7 @@ void FCEU_PutImage(void)
//Update AVI before overlay stuff is written
if(!FCEUI_EmulationPaused())
FCEUI_AviVideoUpdate(XBuf);
//Save backbuffer before overlay stuff is written.
if(!FCEUI_EmulationPaused())
memcpy(XBackBuf, XBuf, 256*256);
@ -222,7 +222,7 @@ void FCEU_PutImage(void)
FCEU_DrawNTSCControlBars(XBuf);
FCEU_DrawRecordingStatus(XBuf);
}
DrawMessage(false);
if(FCEUD_ShouldDrawInputAids())
@ -354,140 +354,140 @@ void FCEU_ResetMessages()
static int WritePNGChunk(FILE *fp, uint32 size, char *type, uint8 *data)
{
uint32 crc;
uint32 crc;
uint8 tempo[4];
uint8 tempo[4];
tempo[0]=size>>24;
tempo[1]=size>>16;
tempo[2]=size>>8;
tempo[3]=size;
tempo[0]=size>>24;
tempo[1]=size>>16;
tempo[2]=size>>8;
tempo[3]=size;
if(fwrite(tempo,4,1,fp)!=1)
return 0;
if(fwrite(type,4,1,fp)!=1)
return 0;
if(fwrite(tempo,4,1,fp)!=1)
return 0;
if(fwrite(type,4,1,fp)!=1)
return 0;
if(size)
if(fwrite(data,1,size,fp)!=size)
return 0;
if(size)
if(fwrite(data,1,size,fp)!=size)
return 0;
crc=CalcCRC32(0,(uint8 *)type,4);
if(size)
crc=CalcCRC32(crc,data,size);
crc=CalcCRC32(0,(uint8 *)type,4);
if(size)
crc=CalcCRC32(crc,data,size);
tempo[0]=crc>>24;
tempo[1]=crc>>16;
tempo[2]=crc>>8;
tempo[3]=crc;
tempo[0]=crc>>24;
tempo[1]=crc>>16;
tempo[2]=crc>>8;
tempo[3]=crc;
if(fwrite(tempo,4,1,fp)!=1)
return 0;
return 1;
if(fwrite(tempo,4,1,fp)!=1)
return 0;
return 1;
}
int SaveSnapshot(void)
{
static unsigned int lastu=0;
static unsigned int lastu=0;
char *fn=0;
int totallines=FSettings.LastSLine-FSettings.FirstSLine+1;
int x,u,y;
FILE *pp=NULL;
uint8 *compmem=NULL;
uLongf compmemsize=totallines*263+12;
char *fn=0;
int totallines=FSettings.LastSLine-FSettings.FirstSLine+1;
int x,u,y;
FILE *pp=NULL;
uint8 *compmem=NULL;
uLongf compmemsize=totallines*263+12;
if(!(compmem=(uint8 *)FCEU_malloc(compmemsize)))
return 0;
if(!(compmem=(uint8 *)FCEU_malloc(compmemsize)))
return 0;
for(u=lastu;u<99999;u++)
{
pp=FCEUD_UTF8fopen((fn=FCEU_MakeFName(FCEUMKF_SNAP,u,"png")),"rb");
if(pp==NULL) break;
fclose(pp);
}
for(u=lastu;u<99999;u++)
{
pp=FCEUD_UTF8fopen((fn=strdup(FCEU_MakeFName(FCEUMKF_SNAP,u,"png").c_str())),"rb");
if(pp==NULL) break;
fclose(pp);
}
lastu=u;
lastu=u;
if(!(pp=FCEUD_UTF8fopen(fn,"wb")))
{
free(fn);
return 0;
}
free(fn);
{
static uint8 header[8]={137,80,78,71,13,10,26,10};
if(fwrite(header,8,1,pp)!=1)
goto PNGerr;
}
if(!(pp=FCEUD_UTF8fopen(fn,"wb")))
{
free(fn);
return 0;
}
free(fn);
{
static uint8 header[8]={137,80,78,71,13,10,26,10};
if(fwrite(header,8,1,pp)!=1)
goto PNGerr;
}
{
uint8 chunko[13];
{
uint8 chunko[13];
chunko[0]=chunko[1]=chunko[3]=0;
chunko[2]=0x1; // Width of 256
chunko[0]=chunko[1]=chunko[3]=0;
chunko[2]=0x1; // Width of 256
chunko[4]=chunko[5]=chunko[6]=0;
chunko[7]=totallines; // Height
chunko[4]=chunko[5]=chunko[6]=0;
chunko[7]=totallines; // Height
chunko[8]=8; // bit depth
chunko[9]=3; // Color type; indexed 8-bit
chunko[10]=0; // compression: deflate
chunko[11]=0; // Basic adapative filter set(though none are used).
chunko[12]=0; // No interlace.
chunko[8]=8; // bit depth
chunko[9]=3; // Color type; indexed 8-bit
chunko[10]=0; // compression: deflate
chunko[11]=0; // Basic adapative filter set(though none are used).
chunko[12]=0; // No interlace.
if(!WritePNGChunk(pp,13,"IHDR",chunko))
goto PNGerr;
}
if(!WritePNGChunk(pp,13,"IHDR",chunko))
goto PNGerr;
}
{
uint8 pdata[256*3];
for(x=0;x<256;x++)
FCEUD_GetPalette(x,pdata+x*3,pdata+x*3+1,pdata+x*3+2);
if(!WritePNGChunk(pp,256*3,"PLTE",pdata))
goto PNGerr;
}
{
uint8 pdata[256*3];
for(x=0;x<256;x++)
FCEUD_GetPalette(x,pdata+x*3,pdata+x*3+1,pdata+x*3+2);
if(!WritePNGChunk(pp,256*3,"PLTE",pdata))
goto PNGerr;
}
{
uint8 *tmp=XBuf+FSettings.FirstSLine*256;
uint8 *dest,*mal,*mork;
{
uint8 *tmp=XBuf+FSettings.FirstSLine*256;
uint8 *dest,*mal,*mork;
if(!(mal=mork=dest=(uint8 *)malloc((totallines<<8)+totallines)))
goto PNGerr;
// mork=dest=XBuf;
if(!(mal=mork=dest=(uint8 *)malloc((totallines<<8)+totallines)))
goto PNGerr;
// mork=dest=XBuf;
for(y=0;y<totallines;y++)
{
*dest=0; // No filter.
dest++;
for(x=256;x;x--,tmp++,dest++)
*dest=*tmp;
}
for(y=0;y<totallines;y++)
{
*dest=0; // No filter.
dest++;
for(x=256;x;x--,tmp++,dest++)
*dest=*tmp;
}
if(compress(compmem,&compmemsize,mork,(totallines<<8)+totallines)!=Z_OK)
{
if(mal) free(mal);
goto PNGerr;
}
if(mal) free(mal);
if(!WritePNGChunk(pp,compmemsize,"IDAT",compmem))
goto PNGerr;
}
if(!WritePNGChunk(pp,0,"IEND",0))
goto PNGerr;
if(compress(compmem,&compmemsize,mork,(totallines<<8)+totallines)!=Z_OK)
{
if(mal) free(mal);
goto PNGerr;
}
if(mal) free(mal);
if(!WritePNGChunk(pp,compmemsize,"IDAT",compmem))
goto PNGerr;
}
if(!WritePNGChunk(pp,0,"IEND",0))
goto PNGerr;
free(compmem);
fclose(pp);
free(compmem);
fclose(pp);
return u+1;
return u+1;
PNGerr:
if(compmem)
free(compmem);
if(pp)
fclose(pp);
return(0);
PNGerr:
if(compmem)
free(compmem);
if(pp)
fclose(pp);
return(0);
}
//TODO mbg - this needs to be implemented in a better way
#ifdef SHOWFPS
@ -499,14 +499,14 @@ static int boopcount = 0;
void ShowFPS(void)
{
uint64 da = FCEUD_GetTime() - boop[boopcount];
char fpsmsg[16];
int booplimit = PAL?50:60;
boop[boopcount] = FCEUD_GetTime();
uint64 da = FCEUD_GetTime() - boop[boopcount];
char fpsmsg[16];
int booplimit = PAL?50:60;
boop[boopcount] = FCEUD_GetTime();
sprintf(fpsmsg, "%8.1f",(double)booplimit / ((double)da / FCEUD_GetTimeFreq()));
DrawTextTrans(XBuf + (256-8-8*8) + (FSettings.FirstSLine+4)*256,256,fpsmsg,4);
// It's not averaging FPS over exactly 1 second, but it's close enough.
boopcount = (boopcount + 1) % booplimit;
sprintf(fpsmsg, "%8.1f",(double)booplimit / ((double)da / FCEUD_GetTimeFreq()));
DrawTextTrans(XBuf + (256-8-8*8) + (FSettings.FirstSLine+4)*256,256,fpsmsg,4);
// It's not averaging FPS over exactly 1 second, but it's close enough.
boopcount = (boopcount + 1) % booplimit;
}
#endif

View File

@ -28,6 +28,7 @@
#include "netplay.h"
#include "vsuni.h"
#include "state.h"
#include "driver.h"
#define IOPTION_GUN 0x1
#define IOPTION_SWAPDIRAB 0x2

View File

@ -76,18 +76,18 @@ void X6502_DMW(uint32 A, uint8 V)
#define PUSH(V) \
{ \
uint8 VTMP=V; \
WrRAM(0x100+_S,VTMP); \
_S--; \
WrRAM(0x100+__S,VTMP); \
__S--; \
}
#define POP() RdRAM(0x100+(++_S))
#define POP() RdRAM(0x100+(++__S))
static uint8 ZNTable[256];
/* Some of these operations will only make sense if you know what the flag
constants are. */
#define X_ZN(zort) _P&=~(Z_FLAG|N_FLAG);_P|=ZNTable[zort]
#define X_ZNT(zort) _P|=ZNTable[zort]
#define X_ZN(zort) __P&=~(Z_FLAG|N_FLAG);__P|=ZNTable[zort]
#define X_ZNT(zort) __P|=ZNTable[zort]
#define JR(cond); \
{ \
@ -113,24 +113,24 @@ static uint8 ZNTable[256];
/* All of the freaky arithmetic operations. */
#define AND _A&=x;X_ZN(_A)
#define BIT _P&=~(Z_FLAG|V_FLAG|N_FLAG);_P|=ZNTable[x&_A]&Z_FLAG;_P|=x&(V_FLAG|N_FLAG)
#define BIT __P&=~(Z_FLAG|V_FLAG|N_FLAG);__P|=ZNTable[x&_A]&Z_FLAG;__P|=x&(V_FLAG|N_FLAG)
#define EOR _A^=x;X_ZN(_A)
#define ORA _A|=x;X_ZN(_A)
#define ADC { \
uint32 l=_A+x+(_P&1); \
_P&=~(Z_FLAG|C_FLAG|N_FLAG|V_FLAG); \
_P|=((((_A^x)&0x80)^0x80) & ((_A^l)&0x80))>>1; \
_P|=(l>>8)&C_FLAG; \
uint32 l=_A+x+(__P&1); \
__P&=~(Z_FLAG|C_FLAG|N_FLAG|V_FLAG); \
__P|=((((_A^x)&0x80)^0x80) & ((_A^l)&0x80))>>1; \
__P|=(l>>8)&C_FLAG; \
_A=l; \
X_ZNT(_A); \
}
#define SBC { \
uint32 l=_A-x-((_P&1)^1); \
_P&=~(Z_FLAG|C_FLAG|N_FLAG|V_FLAG); \
_P|=((_A^l)&(_A^x)&0x80)>>1; \
_P|=((l>>8)&C_FLAG)^C_FLAG; \
uint32 l=_A-x-((__P&1)^1); \
__P&=~(Z_FLAG|C_FLAG|N_FLAG|V_FLAG); \
__P|=((_A^l)&(_A^x)&0x80)>>1; \
__P|=((l>>8)&C_FLAG)^C_FLAG; \
_A=l; \
X_ZNT(_A); \
}
@ -138,16 +138,16 @@ static uint8 ZNTable[256];
#define CMPL(a1,a2) { \
uint32 t=a1-a2; \
X_ZN(t&0xFF); \
_P&=~C_FLAG; \
_P|=((t>>8)&C_FLAG)^C_FLAG; \
__P&=~C_FLAG; \
__P|=((t>>8)&C_FLAG)^C_FLAG; \
}
/* Special undocumented operation. Very similar to CMP. */
#define AXS { \
uint32 t=(_A&_X)-x; \
X_ZN(t&0xFF); \
_P&=~C_FLAG; \
_P|=((t>>8)&C_FLAG)^C_FLAG; \
__P&=~C_FLAG; \
__P|=((t>>8)&C_FLAG)^C_FLAG; \
_X=t; \
}
@ -159,26 +159,26 @@ static uint8 ZNTable[256];
#define DEC x--;X_ZN(x)
#define INC x++;X_ZN(x)
#define ASL _P&=~C_FLAG;_P|=x>>7;x<<=1;X_ZN(x)
#define LSR _P&=~(C_FLAG|N_FLAG|Z_FLAG);_P|=x&1;x>>=1;X_ZNT(x)
#define ASL __P&=~C_FLAG;__P|=x>>7;x<<=1;X_ZN(x)
#define LSR __P&=~(C_FLAG|N_FLAG|Z_FLAG);__P|=x&1;x>>=1;X_ZNT(x)
/* For undocumented instructions, maybe for other things later... */
#define LSRA _P&=~(C_FLAG|N_FLAG|Z_FLAG);_P|=_A&1;_A>>=1;X_ZNT(_A)
#define LSRA __P&=~(C_FLAG|N_FLAG|Z_FLAG);__P|=_A&1;_A>>=1;X_ZNT(_A)
#define ROL { \
uint8 l=x>>7; \
x<<=1; \
x|=_P&C_FLAG; \
_P&=~(Z_FLAG|N_FLAG|C_FLAG); \
_P|=l; \
x|=__P&C_FLAG; \
__P&=~(Z_FLAG|N_FLAG|C_FLAG); \
__P|=l; \
X_ZNT(x); \
}
#define ROR { \
uint8 l=x&1; \
x>>=1; \
x|=(_P&C_FLAG)<<7; \
_P&=~(Z_FLAG|N_FLAG|C_FLAG); \
_P|=l; \
x|=(__P&C_FLAG)<<7; \
__P&=~(Z_FLAG|N_FLAG|C_FLAG); \
__P|=l; \
X_ZNT(x); \
}
@ -392,7 +392,7 @@ void X6502_Init(void)
void X6502_Power(void)
{
_count=_tcount=_IRQlow=_PC=_A=_X=_Y=_S=_P=_PI=_DB=_jammed=0;
_count=_tcount=_IRQlow=_PC=_A=_X=_Y=__S=__P=_PI=_DB=_jammed=0;
timestamp=0;
X6502_Reset();
}
@ -419,7 +419,7 @@ void X6502_Run(int32 cycles)
_PC=RdMem(0xFFFC);
_PC|=RdMem(0xFFFD)<<8;
_jammed=0;
_PI=_P=I_FLAG;
_PI=__P=I_FLAG;
_IRQlow&=~FCEU_IQRESET;
}
else if(_IRQlow&FCEU_IQNMI2)
@ -434,8 +434,8 @@ void X6502_Run(int32 cycles)
ADDCYC(7);
PUSH(_PC>>8);
PUSH(_PC);
PUSH((_P&~B_FLAG)|(U_FLAG));
_P|=I_FLAG;
PUSH((__P&~B_FLAG)|(U_FLAG));
__P|=I_FLAG;
DEBUG( if(debug_loggingCD) LogCDVectors(1) );
_PC=RdMem(0xFFFA);
_PC|=RdMem(0xFFFB)<<8;
@ -449,8 +449,8 @@ void X6502_Run(int32 cycles)
ADDCYC(7);
PUSH(_PC>>8);
PUSH(_PC);
PUSH((_P&~B_FLAG)|(U_FLAG));
_P|=I_FLAG;
PUSH((__P&~B_FLAG)|(U_FLAG));
__P|=I_FLAG;
DEBUG( if(debug_loggingCD) LogCDVectors(1) );
_PC=RdMem(0xFFFE);
_PC|=RdMem(0xFFFF)<<8;
@ -459,7 +459,7 @@ void X6502_Run(int32 cycles)
_IRQlow&=~(FCEU_IQTEMP);
if(_count<=0)
{
_PI=_P;
_PI=__P;
return;
} //Should increase accuracy without a
//major speed hit.
@ -468,7 +468,7 @@ void X6502_Run(int32 cycles)
//will probably cause a major speed decrease on low-end systems
DEBUG( DebugCycle() );
_PI=_P;
_PI=__P;
b1=RdMem(_PC);
ADDCYC(CycTable[b1]);

View File

@ -27,8 +27,8 @@ extern X6502 X;
#define _A X.A
#define _X X.X
#define _Y X.Y
#define _S X.S
#define _P X.P
#define __S X.S
#define __P X.P
#define _PI X.mooPI
#define _DB X.DB
#define _count X.count

View File

@ -358,6 +358,14 @@
<File
RelativePath="..\src\boards\01-222.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
GeneratePreprocessedFile="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\boards\112.cpp"
@ -2156,6 +2164,14 @@
RelativePath="..\src\utils\general.h"
>
</File>
<File
RelativePath="..\src\utils\guid.cpp"
>
</File>
<File
RelativePath="..\src\utils\guid.h"
>
</File>
<File
RelativePath="..\src\utils\md5.cpp"
>
@ -2184,6 +2200,10 @@
RelativePath="..\src\utils\unzip.h"
>
</File>
<File
RelativePath="..\src\utils\valuearray.h"
>
</File>
<File
RelativePath="..\src\utils\xstring.cpp"
>