patch from bisquit to make savestates more efficient
also worked on the build system to accomidate for lua
This commit is contained in:
parent
71c98f6600
commit
cbb5c8bc90
|
@ -48,6 +48,9 @@ else:
|
||||||
if not conf.CheckLib('z', autoadd=1):
|
if not conf.CheckLib('z', autoadd=1):
|
||||||
print 'Did not find libz or z.lib, exiting!'
|
print 'Did not find libz or z.lib, exiting!'
|
||||||
Exit(1)
|
Exit(1)
|
||||||
|
if not conf.CheckLib('lua5.1', autoadd=1):
|
||||||
|
print 'Did not find liblua5.1 or lua5.1.lib, exiting!'
|
||||||
|
Exit(1)
|
||||||
if conf.CheckFunc('asprintf'):
|
if conf.CheckFunc('asprintf'):
|
||||||
conf.env.Append(CCFLAGS = " -DHAVE_ASPRINTF")
|
conf.env.Append(CCFLAGS = " -DHAVE_ASPRINTF")
|
||||||
if env['OPENGL'] and conf.CheckLibWithHeader('GL', 'GL/gl.h', 'c++', autoadd=1):
|
if env['OPENGL'] and conf.CheckLibWithHeader('GL', 'GL/gl.h', 'c++', autoadd=1):
|
||||||
|
@ -55,13 +58,14 @@ else:
|
||||||
conf.env.Append(CPPDEFINES = ['PSS_STYLE=1'])
|
conf.env.Append(CPPDEFINES = ['PSS_STYLE=1'])
|
||||||
# parse SDL cflags/libs
|
# parse SDL cflags/libs
|
||||||
env.ParseConfig('sdl-config --cflags --libs')
|
env.ParseConfig('sdl-config --cflags --libs')
|
||||||
|
env.ParseConfig('echo "-I/usr/include/lua5.1/ -llua5.1"')
|
||||||
env = conf.Finish()
|
env = conf.Finish()
|
||||||
|
|
||||||
# Build for this system's endianness, if not overriden
|
# Build for this system's endianness, if not overriden
|
||||||
#if env.has_key('LSB_FIRST'):
|
#if env.has_key('LSB_FIRST'):
|
||||||
# if env['LSB_FIRST']:
|
# if env['LSB_FIRST']:
|
||||||
# env.Append(CPPDEFINES = ['LSB_FIRST'])
|
# env.Append(CPPDEFINES = ['LSB_FIRST'])
|
||||||
elif sys.byteorder == 'little' or env['PLATFORM'] == 'win32':
|
if sys.byteorder == 'little' or env['PLATFORM'] == 'win32':
|
||||||
env.Append(CPPDEFINES = ['LSB_FIRST'])
|
env.Append(CPPDEFINES = ['LSB_FIRST'])
|
||||||
|
|
||||||
if env['FRAMESKIP']:
|
if env['FRAMESKIP']:
|
||||||
|
|
|
@ -12,6 +12,7 @@ file.cpp
|
||||||
filter.cpp
|
filter.cpp
|
||||||
ines.cpp
|
ines.cpp
|
||||||
input.cpp
|
input.cpp
|
||||||
|
lua-engine.cpp
|
||||||
netplay.cpp
|
netplay.cpp
|
||||||
nsf.cpp
|
nsf.cpp
|
||||||
palette.cpp
|
palette.cpp
|
||||||
|
|
|
@ -343,11 +343,12 @@ void MovieData::installValue(std::string& key, std::string& val)
|
||||||
comments.push_back(val);
|
comments.push_back(val);
|
||||||
else if(key == "savestate")
|
else if(key == "savestate")
|
||||||
{
|
{
|
||||||
int len = HexStringToBytesLength(val);
|
int len = Base64StringToBytesLength(val);
|
||||||
|
if(len == -1) len = HexStringToBytesLength(val); // wasn't base64, try hex
|
||||||
if(len >= 1)
|
if(len >= 1)
|
||||||
{
|
{
|
||||||
savestate.resize(len);
|
savestate.resize(len);
|
||||||
StringToBytes(val,&savestate[0],len);
|
StringToBytes(val,&savestate[0],len); // decodes either base64 or hex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,54 +191,153 @@ int str_replace(char *str, char *search, char *replace) {
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct Base64Table
|
||||||
|
{
|
||||||
|
Base64Table()
|
||||||
|
{
|
||||||
|
size_t a=0;
|
||||||
|
for(a=0; a<256; ++a) data[a] = 0xFF; // mark everything as invalid by default
|
||||||
|
// create value->ascii mapping
|
||||||
|
a=0;
|
||||||
|
for(unsigned char c='A'; c<='Z'; ++c) data[a++] = c; // 0..25
|
||||||
|
for(unsigned char c='a'; c<='z'; ++c) data[a++] = c; // 26..51
|
||||||
|
for(unsigned char c='0'; c<='9'; ++c) data[a++] = c; // 52..61
|
||||||
|
data[62] = '+'; // 62
|
||||||
|
data[63] = '/'; // 63
|
||||||
|
// create ascii->value mapping (but due to overlap, write it to highbit region)
|
||||||
|
for(a=0; a<64; ++a) data[data[a]^0x80] = a; //
|
||||||
|
data[((unsigned char)'=') ^ 0x80] = 0;
|
||||||
|
}
|
||||||
|
unsigned char operator[] (size_t pos) const { return data[pos]; }
|
||||||
|
private:
|
||||||
|
unsigned char data[256];
|
||||||
|
} Base64Table;
|
||||||
|
|
||||||
///Converts the provided data to a string in a standard, user-friendly, round-trippable format
|
///Converts the provided data to a string in a standard, user-friendly, round-trippable format
|
||||||
std::string BytesToString(void* data, int len)
|
std::string BytesToString(const void* data, int len)
|
||||||
{
|
{
|
||||||
char temp[16];
|
char temp[16];
|
||||||
if(len==1) {
|
if(len==1) {
|
||||||
sprintf(temp,"%d",*(unsigned char*)data);
|
sprintf(temp,"%d",*(const unsigned char*)data);
|
||||||
return temp;
|
return temp;
|
||||||
} else if(len==2) {
|
} else if(len==2) {
|
||||||
sprintf(temp,"%d",*(unsigned short*)data);
|
sprintf(temp,"%d",*(const unsigned short*)data);
|
||||||
return temp;
|
return temp;
|
||||||
} else if(len==4) {
|
} else if(len==4) {
|
||||||
sprintf(temp,"%d",*(unsigned int*)data);
|
sprintf(temp,"%d",*(const unsigned int*)data);
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ret;
|
std::string ret;
|
||||||
ret.resize(len*2+2);
|
if(1) // use base64
|
||||||
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);
|
const unsigned char* src = (const unsigned char*)data;
|
||||||
int b = (((unsigned char*)data)[i])&15;
|
ret = "base64:";
|
||||||
if(a>9) a += 'A'-10;
|
for(int n; len > 0; len -= n)
|
||||||
else a += '0';
|
{
|
||||||
if(b>9) b += 'A'-10;
|
unsigned char input[3] = {0,0,0};
|
||||||
else b += '0';
|
for(n=0; n<3 && n<len; ++n)
|
||||||
str[i*2] = a;
|
input[n] = *src++;
|
||||||
str[i*2+1] = b;
|
unsigned char output[4] =
|
||||||
|
{
|
||||||
|
Base64Table[ input[0] >> 2 ],
|
||||||
|
Base64Table[ ((input[0] & 0x03) << 4) | (input[1] >> 4) ],
|
||||||
|
n<2 ? '=' : Base64Table[ ((input[1] & 0x0F) << 2) | (input[2] >> 6) ],
|
||||||
|
n<3 ? '=' : Base64Table[ input[2] & 0x3F ]
|
||||||
|
};
|
||||||
|
ret.append(output, output+4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // use hex
|
||||||
|
{
|
||||||
|
ret.resize(len*2+2);
|
||||||
|
ret[0] = '0';
|
||||||
|
ret[1] = 'x';
|
||||||
|
for(int i=0;i<len;i++)
|
||||||
|
{
|
||||||
|
int a = (((const unsigned char*)data)[i]>>4);
|
||||||
|
int b = (((const unsigned char*)data)[i])&15;
|
||||||
|
if(a>9) a += 'A'-10;
|
||||||
|
else a += '0';
|
||||||
|
if(b>9) b += 'A'-10;
|
||||||
|
else b += '0';
|
||||||
|
ret[2+i*2] = a;
|
||||||
|
ret[2+i*2+1] = b;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
///returns -1 if this is not a hex string
|
///returns -1 if this is not a hex string
|
||||||
int HexStringToBytesLength(std::string& str)
|
int HexStringToBytesLength(const std::string& str)
|
||||||
{
|
{
|
||||||
if(str.size()>2 && str[0] == '0' && toupper(str[1]) == 'X')
|
if(str.size()>2 && str[0] == '0' && toupper(str[1]) == 'X')
|
||||||
return str.size()/2-1;
|
return str.size()/2-1;
|
||||||
else return -1;
|
else return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Base64StringToBytesLength(const std::string& str)
|
||||||
|
{
|
||||||
|
if(str.size() < 7 || (str.size()-7) % 4 || str.substr(0,7) != "base64:") return -1;
|
||||||
|
|
||||||
|
size_t c = (str.size() - 7) / 4;
|
||||||
|
if(str[str.size()-1] == '=') { --c;
|
||||||
|
if(str[str.size()-2] == '=') --c; }
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
///parses a string in the same format as BytesToString
|
///parses a string in the same format as BytesToString
|
||||||
///returns true if success.
|
///returns true if success.
|
||||||
bool StringToBytes(std::string& str, void* data, int len)
|
bool StringToBytes(const std::string& str, void* data, int len)
|
||||||
{
|
{
|
||||||
|
if(str.substr(0,7) == "base64:")
|
||||||
|
{
|
||||||
|
// base64
|
||||||
|
unsigned char* tgt = (unsigned char*)data;
|
||||||
|
int pos = 7, remain = str.size() - pos;
|
||||||
|
while(remain > 0 && len > 0)
|
||||||
|
{
|
||||||
|
unsigned char input[4], converted[4];
|
||||||
|
for(int i=0; i<4; ++i)
|
||||||
|
{
|
||||||
|
if(pos >= remain && i > 0) return false; // invalid data
|
||||||
|
input[i] = str[pos++];
|
||||||
|
if(input[i] & 0x80) return false; // illegal character
|
||||||
|
converted[i] = Base64Table[input[i]^0x80];
|
||||||
|
if(converted[i] & 0x80) return false; // illegal character
|
||||||
|
}
|
||||||
|
unsigned char outpacket[3] =
|
||||||
|
{
|
||||||
|
(converted[0] << 2) | (converted[1] >> 4),
|
||||||
|
(converted[1] << 4) | (converted[2] >> 2),
|
||||||
|
(converted[2] << 6) | (converted[3])
|
||||||
|
};
|
||||||
|
int outlen = (input[2] == '=') ? 1 : (input[3] == '=' ? 2 : 3);
|
||||||
|
if(outlen > len) outlen = len;
|
||||||
|
memcpy(tgt, outpacket, outlen);
|
||||||
|
tgt += outlen;
|
||||||
|
}
|
||||||
|
}
|
||||||
if(str.size()>2 && str[0] == '0' && toupper(str[1]) == 'X')
|
if(str.size()>2 && str[0] == '0' && toupper(str[1]) == 'X')
|
||||||
goto hex;
|
{
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
if(len==1) {
|
if(len==1) {
|
||||||
int x = atoi(str.c_str());
|
int x = atoi(str.c_str());
|
||||||
|
@ -255,24 +354,6 @@ bool StringToBytes(std::string& str, void* data, int len)
|
||||||
}
|
}
|
||||||
//we can't handle it
|
//we can't handle it
|
||||||
return false;
|
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 <string>
|
||||||
|
@ -482,4 +563,4 @@ std::string readNullTerminatedAscii(std::istream* is)
|
||||||
else ret += (char)c;
|
else ret += (char)c;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,9 +44,10 @@ 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);
|
int HexStringToBytesLength(const std::string& str);
|
||||||
std::string BytesToString(void* data, int len);
|
int Base64StringToBytesLength(const std::string& str);
|
||||||
bool StringToBytes(std::string& str, void* data, int len);
|
std::string BytesToString(const void* data, int len);
|
||||||
|
bool StringToBytes(const std::string& str, void* data, int len);
|
||||||
|
|
||||||
std::vector<std::string> tokenize_str(const std::string & str,const std::string & delims);
|
std::vector<std::string> tokenize_str(const std::string & str,const std::string & delims);
|
||||||
void splitpath(const char* path, char* drv, char* dir, char* name, char* ext);
|
void splitpath(const char* path, char* drv, char* dir, char* name, char* ext);
|
||||||
|
|
Loading…
Reference in New Issue