phase 1 of new movie system
we can now round trip a text movie format
This commit is contained in:
parent
91733a146a
commit
1e539ad681
|
@ -18,6 +18,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
|
11
src/driver.h
11
src/driver.h
|
@ -2,6 +2,7 @@
|
|||
#define __DRIVER_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
#include "types.h"
|
||||
#include "git.h"
|
||||
|
@ -191,18 +192,16 @@ typedef struct
|
|||
int movie_version; // version of the movie format in the file
|
||||
uint32 num_frames;
|
||||
uint32 rerecord_count;
|
||||
uint8 flags;
|
||||
bool poweron, reset, pal, nosynchack;
|
||||
int read_only;
|
||||
uint32 emu_version_used; // 9813 = 0.98.13
|
||||
char* metadata; // caller-supplied buffer to store metadata. can be NULL.
|
||||
int metadata_size; // size of the buffer pointed to by metadata
|
||||
uint8 md5_of_rom_used[16];
|
||||
int 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.
|
||||
int name_of_rom_used_size; // size of the buffer pointer to by name_of_rom_used
|
||||
MD5DATA md5_of_rom_used;
|
||||
bool md5_of_rom_used_present; // v1 movies don't have md5 info available
|
||||
std::string name_of_rom_used;
|
||||
} MOVIE_INFO;
|
||||
|
||||
int FCEUI_SelectMovie(int, int);
|
||||
void FCEUI_SaveMovie(char *fname, uint8 flags, const char* metadata);
|
||||
void FCEUI_LoadMovie(char *fname, int read_only, int _stopframe);
|
||||
void FCEUI_StopMovie(void);
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include "../../types.h"
|
||||
#include "../../driver.h"
|
||||
#include "../../utils/xstring.h"
|
||||
#include "config.h"
|
||||
|
||||
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)
|
||||
{
|
||||
int x=0;
|
||||
|
@ -364,7 +294,8 @@ void cfg_NewToOld(CFGSTRUCT *cfgst)
|
|||
if(cfgst[x].len)
|
||||
{
|
||||
//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
|
||||
{
|
||||
|
|
|
@ -14,7 +14,6 @@ static int ReplayDialogStopFrame = 0;
|
|||
|
||||
static int movieHackType = 3;
|
||||
|
||||
char *md5_asciistr(uint8 digest[16]);
|
||||
void RefreshThrottleFPS();
|
||||
|
||||
static char* GetReplayPath(HWND hwndDlg)
|
||||
|
@ -114,21 +113,15 @@ void UpdateReplayDialog(HWND hwndDlg)
|
|||
if(fn)
|
||||
{
|
||||
MOVIE_INFO info;
|
||||
char metadata[MOVIE_MAX_METADATA];
|
||||
char rom_name[MAX_PATH];
|
||||
|
||||
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))
|
||||
{
|
||||
#define MOVIE_FLAG_NOSYNCHACK (1<<4) // set in newer version, used for old movie compatibility
|
||||
extern int resetDMCacc;
|
||||
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_FROM),justAutoConverted || noNoSyncHack);
|
||||
if(justAutoConverted)
|
||||
|
@ -206,28 +199,30 @@ void UpdateReplayDialog(HWND hwndDlg)
|
|||
SetWindowTextA(GetDlgItem(hwndDlg,IDC_LABEL_LENGTH), tmp); // length
|
||||
|
||||
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
|
||||
WCHAR wszMeta[MOVIE_MAX_METADATA];
|
||||
if(MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, metadata, -1, wszMeta, MOVIE_MAX_METADATA))
|
||||
{
|
||||
if(wszMeta[0])
|
||||
SetWindowTextW(GetDlgItem(hwndDlg,IDC_LABEL_AUTHORINFO), wszMeta); // metadata
|
||||
else
|
||||
SetWindowTextW(GetDlgItem(hwndDlg,IDC_LABEL_AUTHORINFO), L"(this movie has no author info)"); // metadata
|
||||
}
|
||||
//// convert utf8 metadata to windows widechar
|
||||
//WCHAR wszMeta[MOVIE_MAX_METADATA];
|
||||
//if(MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, metadata, -1, wszMeta, MOVIE_MAX_METADATA))
|
||||
//{
|
||||
// if(wszMeta[0])
|
||||
// SetWindowTextW(GetDlgItem(hwndDlg,IDC_LABEL_AUTHORINFO), wszMeta); // metadata
|
||||
// else
|
||||
// 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
|
||||
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)
|
||||
{
|
||||
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));
|
||||
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)" : "");
|
||||
|
@ -283,7 +278,7 @@ void UpdateReplayDialog(HWND hwndDlg)
|
|||
{
|
||||
SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_LENGTH),"");
|
||||
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_ROMUSED),"");
|
||||
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];
|
||||
|
||||
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];
|
||||
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()
|
||||
{
|
||||
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))
|
||||
{
|
||||
|
|
Binary file not shown.
|
@ -18,6 +18,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -374,7 +375,6 @@ FCEUGI *FCEUI_LoadGame(const char *name, int OverwriteVidMode)
|
|||
PowerNES();
|
||||
|
||||
FCEUSS_CheckStates();
|
||||
FCEUMOV_CheckMovies();
|
||||
|
||||
if(GameInfo->type!=GIT_NSF)
|
||||
{
|
||||
|
|
|
@ -615,10 +615,6 @@ void FCEUI_SetDirOverride(int which, char *n)
|
|||
{
|
||||
FCEUSS_CheckStates();
|
||||
}
|
||||
else if(which == FCEUIOD_MISC)
|
||||
{
|
||||
FCEUMOV_CheckMovies();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,9 @@
|
|||
#define GIV_NTSC 0 /* NTSC emulation. */
|
||||
#define GIV_PAL 1 /* PAL emulation. */
|
||||
#define GIV_USER 2 /* What was set by FCEUI_SetVidSys(). */
|
||||
|
||||
|
||||
#include "utils/md5.h"
|
||||
|
||||
typedef struct {
|
||||
uint8 *name; /* Game name, UTF8 encoding */
|
||||
|
||||
|
@ -22,7 +24,7 @@ typedef struct {
|
|||
int cspecial; /* Special cart expansion: DIP switches, barcode
|
||||
reader, etc.
|
||||
*/
|
||||
uint8 MD5[16];
|
||||
MD5DATA MD5;
|
||||
int soundrate; /* For Ogg Vorbis expansion sound wacky support. 0 for default. */
|
||||
int soundchan; /* Number of sound channels. */
|
||||
} FCEUGI;
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
|
||||
#include "types.h"
|
||||
|
@ -749,42 +751,16 @@ static void CommandStateLoad(void)
|
|||
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)
|
||||
{
|
||||
if(execcmd >= EMUCMD_MOVIE_RECORD_SLOT_0 && execcmd <= EMUCMD_MOVIE_RECORD_SLOT_9)
|
||||
{
|
||||
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);
|
||||
FCEUI_SaveMovie(0, 0, 0);
|
||||
}
|
||||
|
||||
static void CommandMovieReplay(void)
|
||||
{
|
||||
if(execcmd >= EMUCMD_MOVIE_REPLAY_SLOT_0 && execcmd <= EMUCMD_MOVIE_REPLAY_SLOT_9)
|
||||
{
|
||||
int oldslot=FCEUI_SelectMovie(execcmd-EMUCMD_MOVIE_REPLAY_SLOT_0, 0);
|
||||
FCEUI_LoadMovie(0, 0);
|
||||
FCEUI_SelectMovie(oldslot, 0);
|
||||
}
|
||||
else
|
||||
FCEUI_LoadMovie(0, 0);
|
||||
FCEUI_LoadMovie(0, 0, 0);
|
||||
}
|
||||
*/
|
||||
|
||||
static void CommandSoundAdjust(void)
|
||||
{
|
||||
int n;
|
||||
|
|
2142
src/movie.cpp
2142
src/movie.cpp
File diff suppressed because it is too large
Load Diff
|
@ -2,12 +2,11 @@
|
|||
#define __MOVIE_H_
|
||||
|
||||
void FCEUMOV_AddJoy(uint8 *, int SkipFlush);
|
||||
void FCEUMOV_CheckMovies(void);
|
||||
void FCEUMOV_AddCommand(int cmd);
|
||||
void FCEU_DrawMovies(uint8 *);
|
||||
int FCEUMOV_IsPlaying(void);
|
||||
int FCEUMOV_IsRecording(void);
|
||||
int FCEUMOV_ShouldPause(void);
|
||||
bool FCEUMOV_ShouldPause(void);
|
||||
int FCEUMOV_GetFrame(void);
|
||||
|
||||
int FCEUMOV_WriteState(FILE* st);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
/* TODO: Add (better) file io error checking */
|
||||
/* TODO: Change save state file format. */
|
||||
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -490,11 +491,12 @@ int FCEUSS_Load(char *fname)
|
|||
FILE *st;
|
||||
char *fn;
|
||||
|
||||
//this fixes read-only toggle problems
|
||||
if(FCEUMOV_IsRecording()) {
|
||||
FCEUMOV_AddCommand(0);
|
||||
MovieFlushHeader();
|
||||
}
|
||||
//mbg movie - this needs to be overhauled
|
||||
////this fixes read-only toggle problems
|
||||
//if(FCEUMOV_IsRecording()) {
|
||||
// FCEUMOV_AddCommand(0);
|
||||
// MovieFlushHeader();
|
||||
//}
|
||||
|
||||
if(geniestage==1)
|
||||
{
|
||||
|
@ -621,8 +623,7 @@ int FCEUI_SelectState(int w, int show)
|
|||
{
|
||||
int oldstate=CurrentState;
|
||||
if(w == -1) { StateShow = 0; return 0; } //mbg merge 7/17/06 had to make return a value
|
||||
FCEUI_SelectMovie(-1,0);
|
||||
|
||||
|
||||
CurrentState=w;
|
||||
if(show)
|
||||
{
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define FCEU_VERSION_NUMERIC 9816
|
||||
#define FCEU_VERSION_NUMERIC 19901
|
||||
#define FCEU_NAME "FCE Ultra"
|
||||
#define FCEU_VERSION_STRING "1.9.9"
|
||||
#define FCEU_NAME_AND_VERSION FCEU_NAME " " FCEU_VERSION_STRING
|
||||
|
@ -54,6 +54,7 @@ typedef signed int int32;
|
|||
#define mkdir _mkdir
|
||||
#define alloca _alloca
|
||||
#define snprintf _snprintf
|
||||
#define vsnprintf _vsnprintf
|
||||
#define W_OK 2
|
||||
#define R_OK 2
|
||||
#define X_OK 1
|
||||
|
|
|
@ -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. */
|
||||
char *md5_asciistr(uint8 digest[16])
|
||||
char *md5_asciistr(MD5DATA& md5)
|
||||
{
|
||||
uint8* digest = md5.data;
|
||||
static char str[33];
|
||||
static char trans[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
|
||||
int x;
|
||||
|
|
|
@ -8,11 +8,22 @@ struct md5_context
|
|||
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_update( struct md5_context *ctx, uint8 *input, uint32 length );
|
||||
void md5_finish( struct md5_context *ctx, uint8 digest[16] );
|
||||
|
||||
/* 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 */
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
/// \brief various string manipulation utilities
|
||||
|
||||
#include "xstring.h"
|
||||
#include <string>
|
||||
|
||||
///Upper case routine. Returns number of characters modified
|
||||
int str_ucase(char *str) {
|
||||
|
@ -189,3 +190,122 @@ int str_replace(char *str, char *search, char *replace) {
|
|||
free(astr);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -17,9 +17,11 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <vector>
|
||||
|
||||
|
||||
//definitions for str_strip() flags
|
||||
#define STRIP_SP 0x01 /* space */
|
||||
|
@ -35,3 +37,9 @@ int str_rtrim(char *str, int flags);
|
|||
int str_strip(char *str, int flags);
|
||||
int chr_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);
|
|
@ -342,8 +342,9 @@ void FCEU_DispMessage(char *format, ...)
|
|||
|
||||
howlong=180;
|
||||
|
||||
extern int movcounter;
|
||||
movcounter=0;
|
||||
//mbg movie 5/23/08
|
||||
//extern int movcounter;
|
||||
//movcounter=0;
|
||||
}
|
||||
|
||||
void FCEU_ResetMessages(void)
|
||||
|
|
|
@ -748,6 +748,7 @@
|
|||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
GeneratePreprocessedFile="0"
|
||||
ObjectFile="$(IntDir)\$(InputName)2.obj"
|
||||
XMLDocumentationFileName="$(IntDir)\$(InputName)2.xdc"
|
||||
/>
|
||||
|
@ -2170,6 +2171,14 @@
|
|||
<File
|
||||
RelativePath="..\src\cheat.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
GeneratePreprocessedFile="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\conddebug.cpp"
|
||||
|
|
Loading…
Reference in New Issue