phase 1 of new movie system

we can now round trip a text movie format
This commit is contained in:
zeromus 2008-05-23 09:58:38 +00:00
parent 91733a146a
commit 1e539ad681
19 changed files with 1211 additions and 1288 deletions

View File

@ -18,6 +18,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include <string>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>

View File

@ -2,6 +2,7 @@
#define __DRIVER_H_ #define __DRIVER_H_
#include <stdio.h> #include <stdio.h>
#include <string>
#include "types.h" #include "types.h"
#include "git.h" #include "git.h"
@ -191,18 +192,16 @@ typedef struct
int movie_version; // version of the movie format in the file int movie_version; // version of the movie format in the file
uint32 num_frames; uint32 num_frames;
uint32 rerecord_count; uint32 rerecord_count;
uint8 flags; bool poweron, reset, pal, nosynchack;
int read_only; int read_only;
uint32 emu_version_used; // 9813 = 0.98.13 uint32 emu_version_used; // 9813 = 0.98.13
char* metadata; // caller-supplied buffer to store metadata. can be NULL. char* metadata; // caller-supplied buffer to store metadata. can be NULL.
int metadata_size; // size of the buffer pointed to by metadata int metadata_size; // size of the buffer pointed to by metadata
uint8 md5_of_rom_used[16]; MD5DATA md5_of_rom_used;
int md5_of_rom_used_present; // v1 movies don't have md5 info available bool md5_of_rom_used_present; // v1 movies don't have md5 info available
char* name_of_rom_used; // caller-supplied buffer to store metadata. can be NULL. std::string name_of_rom_used;
int name_of_rom_used_size; // size of the buffer pointer to by name_of_rom_used
} MOVIE_INFO; } MOVIE_INFO;
int FCEUI_SelectMovie(int, int);
void FCEUI_SaveMovie(char *fname, uint8 flags, const char* metadata); void FCEUI_SaveMovie(char *fname, uint8 flags, const char* metadata);
void FCEUI_LoadMovie(char *fname, int read_only, int _stopframe); void FCEUI_LoadMovie(char *fname, int read_only, int _stopframe);
void FCEUI_StopMovie(void); void FCEUI_StopMovie(void);

View File

@ -32,6 +32,7 @@
#include "../../types.h" #include "../../types.h"
#include "../../driver.h" #include "../../driver.h"
#include "../../utils/xstring.h"
#include "config.h" #include "config.h"
static int FReadString(FILE *fp, char *str, int n) static int FReadString(FILE *fp, char *str, int n)
@ -240,77 +241,6 @@ void LoadParse(CFGSTRUCT *cfgst, FILE *fp)
} }
static void StringToBytes(std::string& str, void* data, int len)
{
if(str.size()>2 && str[0] == '0' && toupper(str[1]) == 'X')
goto hex;
if(len==1) {
int x = atoi(str.c_str());
*(unsigned char*)data = x;
return;
} else if(len==2) {
int x = atoi(str.c_str());
*(unsigned short*)data = x;
return;
} else if(len==4) {
int x = atoi(str.c_str());
*(unsigned int*)data = x;
return;
}
//else it had better be hex
FCEUD_PrintError("Config error: no hex data found somewhere it is required");
hex:
int amt = len;
int bytesAvailable = str.size()/2;
if(bytesAvailable < amt)
amt = bytesAvailable;
const char* cstr = str.c_str()+2;
for(int i=0;i<amt;i++) {
char a = toupper(cstr[i*2]);
char b = toupper(cstr[i*2+1]);
if(a>='A') a=a-'A'+10;
else a-='0';
if(b>='A') b=b-'A'+10;
else b-='0';
unsigned char val = ((unsigned char)a<<4)|(unsigned char)b;
((unsigned char*)data)[i] = val;
}
}
static std::string BytesToString(void* data, int len)
{
char temp[16];
if(len==1) {
sprintf(temp,"%d",*(unsigned char*)data);
return temp;
} else if(len==2) {
sprintf(temp,"%d",*(unsigned short*)data);
return temp;
} else if(len==4) {
sprintf(temp,"%d",*(unsigned int*)data);
return temp;
}
std::string ret;
ret.resize(len*2+2);
char* str= (char*)ret.c_str();
str[0] = '0';
str[1] = 'x';
str += 2;
for(int i=0;i<len;i++)
{
int a = (((unsigned char*)data)[i]>>4);
int b = (((unsigned char*)data)[i])&15;
if(a>9) a += 'A'-10;
else a += '0';
if(b>9) b += 'A'-10;
else b += '0';
str[i*2] = a;
str[i*2+1] = b;
}
return ret;
}
static void cfg_OldToNew(const CFGSTRUCT *cfgst) static void cfg_OldToNew(const CFGSTRUCT *cfgst)
{ {
int x=0; int x=0;
@ -364,7 +294,8 @@ void cfg_NewToOld(CFGSTRUCT *cfgst)
if(cfgst[x].len) if(cfgst[x].len)
{ {
//binary data //binary data
StringToBytes(cfgmap[cfgst[x].name],cfgst[x].ptr,cfgst[x].len); if(!StringToBytes(cfgmap[cfgst[x].name],cfgst[x].ptr,cfgst[x].len))
FCEUD_PrintError("Config error: error parsing parameter");
} }
else else
{ {

View File

@ -14,7 +14,6 @@ static int ReplayDialogStopFrame = 0;
static int movieHackType = 3; static int movieHackType = 3;
char *md5_asciistr(uint8 digest[16]);
void RefreshThrottleFPS(); void RefreshThrottleFPS();
static char* GetReplayPath(HWND hwndDlg) static char* GetReplayPath(HWND hwndDlg)
@ -114,21 +113,15 @@ void UpdateReplayDialog(HWND hwndDlg)
if(fn) if(fn)
{ {
MOVIE_INFO info; MOVIE_INFO info;
char metadata[MOVIE_MAX_METADATA];
char rom_name[MAX_PATH];
memset(&info, 0, sizeof(info)); memset(&info, 0, sizeof(info));
info.metadata = metadata;
info.metadata_size = sizeof(metadata);
info.name_of_rom_used = rom_name;
info.name_of_rom_used_size = sizeof(rom_name);
if(FCEUI_MovieGetInfo(fn, &info)) if(FCEUI_MovieGetInfo(fn, &info))
{ {
#define MOVIE_FLAG_NOSYNCHACK (1<<4) // set in newer version, used for old movie compatibility #define MOVIE_FLAG_NOSYNCHACK (1<<4) // set in newer version, used for old movie compatibility
extern int resetDMCacc; extern int resetDMCacc;
extern int justAutoConverted; extern int justAutoConverted;
int noNoSyncHack=!(info.flags&MOVIE_FLAG_NOSYNCHACK) && resetDMCacc; int noNoSyncHack=!(info.nosynchack) && resetDMCacc;
EnableWindow(GetDlgItem(hwndDlg,IDC_EDIT_OFFSET),justAutoConverted || noNoSyncHack); EnableWindow(GetDlgItem(hwndDlg,IDC_EDIT_OFFSET),justAutoConverted || noNoSyncHack);
EnableWindow(GetDlgItem(hwndDlg,IDC_EDIT_FROM),justAutoConverted || noNoSyncHack); EnableWindow(GetDlgItem(hwndDlg,IDC_EDIT_FROM),justAutoConverted || noNoSyncHack);
if(justAutoConverted) if(justAutoConverted)
@ -206,28 +199,30 @@ void UpdateReplayDialog(HWND hwndDlg)
SetWindowTextA(GetDlgItem(hwndDlg,IDC_LABEL_LENGTH), tmp); // length SetWindowTextA(GetDlgItem(hwndDlg,IDC_LABEL_LENGTH), tmp); // length
sprintf(tmp, "%lu", info.rerecord_count); sprintf(tmp, "%lu", info.rerecord_count);
SetWindowTextA(GetDlgItem(hwndDlg,IDC_LABEL_UNDOCOUNT), tmp); // rerecord //SetWindowTextA(GetDlgItem(hwndDlg,IDC_LABEL_UNDOCOUNT), tmp); // rerecord
{ {
// convert utf8 metadata to windows widechar //// convert utf8 metadata to windows widechar
WCHAR wszMeta[MOVIE_MAX_METADATA]; //WCHAR wszMeta[MOVIE_MAX_METADATA];
if(MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, metadata, -1, wszMeta, MOVIE_MAX_METADATA)) //if(MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, metadata, -1, wszMeta, MOVIE_MAX_METADATA))
{ //{
if(wszMeta[0]) // if(wszMeta[0])
SetWindowTextW(GetDlgItem(hwndDlg,IDC_LABEL_AUTHORINFO), wszMeta); // metadata // SetWindowTextW(GetDlgItem(hwndDlg,IDC_LABEL_AUTHORINFO), wszMeta); // metadata
else // else
SetWindowTextW(GetDlgItem(hwndDlg,IDC_LABEL_AUTHORINFO), L"(this movie has no author info)"); // metadata // SetWindowTextW(GetDlgItem(hwndDlg,IDC_LABEL_AUTHORINFO), L"(this movie has no author info)"); // metadata
} //}
SetDlgItemTextW(hwndDlg,IDC_LABEL_AUTHORINFO,L"Temporarily non-functional");
} }
EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK_READONLY),(info.read_only)? FALSE : TRUE); // disable read-only checkbox if the file access is read-only EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK_READONLY),(info.read_only)? FALSE : TRUE); // disable read-only checkbox if the file access is read-only
SendDlgItemMessage(hwndDlg,IDC_CHECK_READONLY,BM_SETCHECK,info.read_only ? BST_CHECKED : (ReplayDialogReadOnlyStatus ? BST_CHECKED : BST_UNCHECKED), 0); SendDlgItemMessage(hwndDlg,IDC_CHECK_READONLY,BM_SETCHECK,info.read_only ? BST_CHECKED : (ReplayDialogReadOnlyStatus ? BST_CHECKED : BST_UNCHECKED), 0);
SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_RECORDEDFROM),(info.flags & MOVIE_FLAG_FROM_POWERON) ? "Power-On" : "Savestate"); SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_RECORDEDFROM),info.poweron ? "Power-On" : (info.reset?"Soft-Reset":"Savestate"));
if(info.movie_version > 1) if(info.movie_version > 1)
{ {
char emuStr[128]; char emuStr[128];
SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_ROMUSED),info.name_of_rom_used); SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_ROMUSED),info.name_of_rom_used.c_str());
SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_ROMCHECKSUM),md5_asciistr(info.md5_of_rom_used)); SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_ROMCHECKSUM),md5_asciistr(info.md5_of_rom_used));
if(info.emu_version_used > 64) if(info.emu_version_used > 64)
sprintf(emuStr, "FCEU %d.%02d.%02d%s", info.emu_version_used/10000, (info.emu_version_used/100)%100, (info.emu_version_used)%100, info.emu_version_used < 9813 ? " (blip)" : ""); sprintf(emuStr, "FCEU %d.%02d.%02d%s", info.emu_version_used/10000, (info.emu_version_used/100)%100, (info.emu_version_used)%100, info.emu_version_used < 9813 ? " (blip)" : "");
@ -283,7 +278,7 @@ void UpdateReplayDialog(HWND hwndDlg)
{ {
SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_LENGTH),""); SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_LENGTH),"");
SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_FRAMES),""); SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_FRAMES),"");
SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_UNDOCOUNT),""); //SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_UNDOCOUNT),"");
SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_AUTHORINFO),""); SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_AUTHORINFO),"");
SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_ROMUSED),""); SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_ROMUSED),"");
SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_ROMCHECKSUM),""); SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_ROMCHECKSUM),"");
@ -410,10 +405,6 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
char rom_name[MAX_PATH]; char rom_name[MAX_PATH];
memset(&info, 0, sizeof(info)); memset(&info, 0, sizeof(info));
info.metadata = metadata;
info.metadata_size = sizeof(metadata);
info.name_of_rom_used = rom_name;
info.name_of_rom_used_size = sizeof(rom_name);
char filename [512]; char filename [512];
sprintf(filename, "%s%s", globBase, wfd.cFileName); sprintf(filename, "%s%s", globBase, wfd.cFileName);
@ -836,7 +827,7 @@ static BOOL CALLBACK RecordDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP
void FCEUD_MovieRecordTo() void FCEUD_MovieRecordTo()
{ {
struct CreateMovieParameters p; struct CreateMovieParameters p;
p.szFilename = FCEUI_MovieGetCurrentName(0); p.szFilename = FCEU_MakeFName(FCEUMKF_MOVIE,0,0);
if(DialogBoxParam(fceu_hInstance, "IDD_RECORDINP", hAppWnd, RecordDialogProc, (LPARAM)&p)) if(DialogBoxParam(fceu_hInstance, "IDD_RECORDINP", hAppWnd, RecordDialogProc, (LPARAM)&p))
{ {

Binary file not shown.

View File

@ -18,6 +18,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include <string>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -374,7 +375,6 @@ FCEUGI *FCEUI_LoadGame(const char *name, int OverwriteVidMode)
PowerNES(); PowerNES();
FCEUSS_CheckStates(); FCEUSS_CheckStates();
FCEUMOV_CheckMovies();
if(GameInfo->type!=GIT_NSF) if(GameInfo->type!=GIT_NSF)
{ {

View File

@ -615,10 +615,6 @@ void FCEUI_SetDirOverride(int which, char *n)
{ {
FCEUSS_CheckStates(); FCEUSS_CheckStates();
} }
else if(which == FCEUIOD_MISC)
{
FCEUMOV_CheckMovies();
}
} }
} }

View File

@ -9,7 +9,9 @@
#define GIV_NTSC 0 /* NTSC emulation. */ #define GIV_NTSC 0 /* NTSC emulation. */
#define GIV_PAL 1 /* PAL emulation. */ #define GIV_PAL 1 /* PAL emulation. */
#define GIV_USER 2 /* What was set by FCEUI_SetVidSys(). */ #define GIV_USER 2 /* What was set by FCEUI_SetVidSys(). */
#include "utils/md5.h"
typedef struct { typedef struct {
uint8 *name; /* Game name, UTF8 encoding */ uint8 *name; /* Game name, UTF8 encoding */
@ -22,7 +24,7 @@ typedef struct {
int cspecial; /* Special cart expansion: DIP switches, barcode int cspecial; /* Special cart expansion: DIP switches, barcode
reader, etc. reader, etc.
*/ */
uint8 MD5[16]; MD5DATA MD5;
int soundrate; /* For Ogg Vorbis expansion sound wacky support. 0 for default. */ int soundrate; /* For Ogg Vorbis expansion sound wacky support. 0 for default. */
int soundchan; /* Number of sound channels. */ int soundchan; /* Number of sound channels. */
} FCEUGI; } FCEUGI;

View File

@ -18,6 +18,8 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include <string>
#include <string.h> #include <string.h>
#include "types.h" #include "types.h"
@ -749,42 +751,16 @@ static void CommandStateLoad(void)
FCEUI_LoadState(0); FCEUI_LoadState(0);
} }
void FCEUI_SelectMovieNext(int);
/*
static void CommandMovieSelectSlot(void)
{
if(execcmd <= EMUCMD_MOVIE_SLOT_9)
FCEUI_SelectMovie(execcmd-EMUCMD_MOVIE_SLOT_0, 1);
else if(execcmd == EMUCMD_MOVIE_SLOT_NEXT)
FCEUI_SelectMovieNext(1);
else if(execcmd == EMUCMD_MOVIE_SLOT_PREV)
FCEUI_SelectMovieNext(-1);
}
static void CommandMovieRecord(void) static void CommandMovieRecord(void)
{ {
if(execcmd >= EMUCMD_MOVIE_RECORD_SLOT_0 && execcmd <= EMUCMD_MOVIE_RECORD_SLOT_9) FCEUI_SaveMovie(0, 0, 0);
{
int oldslot=FCEUI_SelectMovie(execcmd-EMUCMD_MOVIE_RECORD_SLOT_0, 0);
FCEUI_SaveMovie(0, 0, 0);
FCEUI_SelectMovie(oldslot, 0);
}
else
FCEUI_SaveMovie(0, 0, 0);
} }
static void CommandMovieReplay(void) static void CommandMovieReplay(void)
{ {
if(execcmd >= EMUCMD_MOVIE_REPLAY_SLOT_0 && execcmd <= EMUCMD_MOVIE_REPLAY_SLOT_9) FCEUI_LoadMovie(0, 0, 0);
{
int oldslot=FCEUI_SelectMovie(execcmd-EMUCMD_MOVIE_REPLAY_SLOT_0, 0);
FCEUI_LoadMovie(0, 0);
FCEUI_SelectMovie(oldslot, 0);
}
else
FCEUI_LoadMovie(0, 0);
} }
*/
static void CommandSoundAdjust(void) static void CommandSoundAdjust(void)
{ {
int n; int n;

File diff suppressed because it is too large Load Diff

View File

@ -2,12 +2,11 @@
#define __MOVIE_H_ #define __MOVIE_H_
void FCEUMOV_AddJoy(uint8 *, int SkipFlush); void FCEUMOV_AddJoy(uint8 *, int SkipFlush);
void FCEUMOV_CheckMovies(void);
void FCEUMOV_AddCommand(int cmd); void FCEUMOV_AddCommand(int cmd);
void FCEU_DrawMovies(uint8 *); void FCEU_DrawMovies(uint8 *);
int FCEUMOV_IsPlaying(void); int FCEUMOV_IsPlaying(void);
int FCEUMOV_IsRecording(void); int FCEUMOV_IsRecording(void);
int FCEUMOV_ShouldPause(void); bool FCEUMOV_ShouldPause(void);
int FCEUMOV_GetFrame(void); int FCEUMOV_GetFrame(void);
int FCEUMOV_WriteState(FILE* st); int FCEUMOV_WriteState(FILE* st);

View File

@ -21,6 +21,7 @@
/* TODO: Add (better) file io error checking */ /* TODO: Add (better) file io error checking */
/* TODO: Change save state file format. */ /* TODO: Change save state file format. */
#include <string>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -490,11 +491,12 @@ int FCEUSS_Load(char *fname)
FILE *st; FILE *st;
char *fn; char *fn;
//this fixes read-only toggle problems //mbg movie - this needs to be overhauled
if(FCEUMOV_IsRecording()) { ////this fixes read-only toggle problems
FCEUMOV_AddCommand(0); //if(FCEUMOV_IsRecording()) {
MovieFlushHeader(); // FCEUMOV_AddCommand(0);
} // MovieFlushHeader();
//}
if(geniestage==1) if(geniestage==1)
{ {
@ -621,8 +623,7 @@ int FCEUI_SelectState(int w, int show)
{ {
int oldstate=CurrentState; int oldstate=CurrentState;
if(w == -1) { StateShow = 0; return 0; } //mbg merge 7/17/06 had to make return a value if(w == -1) { StateShow = 0; return 0; } //mbg merge 7/17/06 had to make return a value
FCEUI_SelectMovie(-1,0);
CurrentState=w; CurrentState=w;
if(show) if(show)
{ {

View File

@ -24,7 +24,7 @@
#include <stdlib.h> #include <stdlib.h>
#define FCEU_VERSION_NUMERIC 9816 #define FCEU_VERSION_NUMERIC 19901
#define FCEU_NAME "FCE Ultra" #define FCEU_NAME "FCE Ultra"
#define FCEU_VERSION_STRING "1.9.9" #define FCEU_VERSION_STRING "1.9.9"
#define FCEU_NAME_AND_VERSION FCEU_NAME " " FCEU_VERSION_STRING #define FCEU_NAME_AND_VERSION FCEU_NAME " " FCEU_VERSION_STRING
@ -54,6 +54,7 @@ typedef signed int int32;
#define mkdir _mkdir #define mkdir _mkdir
#define alloca _alloca #define alloca _alloca
#define snprintf _snprintf #define snprintf _snprintf
#define vsnprintf _vsnprintf
#define W_OK 2 #define W_OK 2
#define R_OK 2 #define R_OK 2
#define X_OK 1 #define X_OK 1

View File

@ -228,8 +228,9 @@ void md5_finish( struct md5_context *ctx, uint8 digest[16] )
/* Uses a static buffer, so beware of how it's used. */ /* Uses a static buffer, so beware of how it's used. */
char *md5_asciistr(uint8 digest[16]) char *md5_asciistr(MD5DATA& md5)
{ {
uint8* digest = md5.data;
static char str[33]; static char str[33];
static char trans[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; static char trans[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
int x; int x;

View File

@ -8,11 +8,22 @@ struct md5_context
uint8 buffer[64]; uint8 buffer[64];
}; };
template<typename T, int N>
struct ValueArray
{
T data[N];
T &operator[](int index) { return data[index]; }
static const int size = N;
};
typedef ValueArray<uint8,16> MD5DATA;
void md5_starts( struct md5_context *ctx ); void md5_starts( struct md5_context *ctx );
void md5_update( struct md5_context *ctx, uint8 *input, uint32 length ); void md5_update( struct md5_context *ctx, uint8 *input, uint32 length );
void md5_finish( struct md5_context *ctx, uint8 digest[16] ); void md5_finish( struct md5_context *ctx, uint8 digest[16] );
/* Uses a static buffer, so beware of how it's used. */ /* Uses a static buffer, so beware of how it's used. */
char *md5_asciistr(uint8 digest[16]); char *md5_asciistr(MD5DATA& md5);
#endif /* md5.h */ #endif /* md5.h */

View File

@ -22,6 +22,7 @@
/// \brief various string manipulation utilities /// \brief various string manipulation utilities
#include "xstring.h" #include "xstring.h"
#include <string>
///Upper case routine. Returns number of characters modified ///Upper case routine. Returns number of characters modified
int str_ucase(char *str) { int str_ucase(char *str) {
@ -189,3 +190,122 @@ int str_replace(char *str, char *search, char *replace) {
free(astr); free(astr);
return j; return j;
} }
///Converts the provided data to a string in a standard, user-friendly, round-trippable format
std::string BytesToString(void* data, int len)
{
char temp[16];
if(len==1) {
sprintf(temp,"%d",*(unsigned char*)data);
return temp;
} else if(len==2) {
sprintf(temp,"%d",*(unsigned short*)data);
return temp;
} else if(len==4) {
sprintf(temp,"%d",*(unsigned int*)data);
return temp;
}
std::string ret;
ret.resize(len*2+2);
char* str= (char*)ret.c_str();
str[0] = '0';
str[1] = 'x';
str += 2;
for(int i=0;i<len;i++)
{
int a = (((unsigned char*)data)[i]>>4);
int b = (((unsigned char*)data)[i])&15;
if(a>9) a += 'A'-10;
else a += '0';
if(b>9) b += 'A'-10;
else b += '0';
str[i*2] = a;
str[i*2+1] = b;
}
return ret;
}
///returns -1 if this is not a hex string
int HexStringToBytesLength(std::string& str)
{
if(str.size()>2 && str[0] == '0' && toupper(str[1]) == 'X')
return str.size()/2-1;
else return -1;
}
///parses a string in the same format as BytesToString
///returns true if success.
bool StringToBytes(std::string& str, void* data, int len)
{
if(str.size()>2 && str[0] == '0' && toupper(str[1]) == 'X')
goto hex;
if(len==1) {
int x = atoi(str.c_str());
*(unsigned char*)data = x;
return true;
} else if(len==2) {
int x = atoi(str.c_str());
*(unsigned short*)data = x;
return true;
} else if(len==4) {
int x = atoi(str.c_str());
*(unsigned int*)data = x;
return true;
}
//we can't handle it
return false;
hex:
int amt = len;
int bytesAvailable = str.size()/2;
if(bytesAvailable < amt)
amt = bytesAvailable;
const char* cstr = str.c_str()+2;
for(int i=0;i<amt;i++) {
char a = toupper(cstr[i*2]);
char b = toupper(cstr[i*2+1]);
if(a>='A') a=a-'A'+10;
else a-='0';
if(b>='A') b=b-'A'+10;
else b-='0';
unsigned char val = ((unsigned char)a<<4)|(unsigned char)b;
((unsigned char*)data)[i] = val;
}
return true;
}
#include <string>
#include <vector>
/// \brief convert input string into vector of string tokens
///
/// \note consecutive delimiters will be treated as single delimiter
/// \note delimiters are _not_ included in return data
///
/// \param input string to be parsed
/// \param delims list of delimiters.
std::vector<std::string> tokenize_str(const std::string & str,
const std::string & delims=", \t")
{
using namespace std;
// Skip delims at beginning, find start of first token
string::size_type lastPos = str.find_first_not_of(delims, 0);
// Find next delimiter @ end of token
string::size_type pos = str.find_first_of(delims, lastPos);
// output vector
vector<string> tokens;
while (string::npos != pos || string::npos != lastPos)
{
// Found a token, add it to the vector.
tokens.push_back(str.substr(lastPos, pos - lastPos));
// Skip delims. Note the "not_of". this is beginning of token
lastPos = str.find_first_not_of(delims, pos);
// Find next delimiter at end of token.
pos = str.find_first_of(delims, lastPos);
}
return tokens;
}

View File

@ -17,9 +17,11 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include <string>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <vector>
//definitions for str_strip() flags //definitions for str_strip() flags
#define STRIP_SP 0x01 /* space */ #define STRIP_SP 0x01 /* space */
@ -35,3 +37,9 @@ int str_rtrim(char *str, int flags);
int str_strip(char *str, int flags); int str_strip(char *str, int flags);
int chr_replace(char *str, char search, char replace); int chr_replace(char *str, char search, char replace);
int str_replace(char *str, char *search, char *replace); int str_replace(char *str, char *search, char *replace);
int HexStringToBytesLength(std::string& str);
std::string BytesToString(void* data, int len);
bool StringToBytes(std::string& str, void* data, int len);
std::vector<std::string> tokenize_str(const std::string & str,const std::string & delims);

View File

@ -342,8 +342,9 @@ void FCEU_DispMessage(char *format, ...)
howlong=180; howlong=180;
extern int movcounter; //mbg movie 5/23/08
movcounter=0; //extern int movcounter;
//movcounter=0;
} }
void FCEU_ResetMessages(void) void FCEU_ResetMessages(void)

View File

@ -748,6 +748,7 @@
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
GeneratePreprocessedFile="0"
ObjectFile="$(IntDir)\$(InputName)2.obj" ObjectFile="$(IntDir)\$(InputName)2.obj"
XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc" XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
/> />
@ -2170,6 +2171,14 @@
<File <File
RelativePath="..\src\cheat.cpp" RelativePath="..\src\cheat.cpp"
> >
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
GeneratePreprocessedFile="0"
/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath="..\src\conddebug.cpp" RelativePath="..\src\conddebug.cpp"