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):
|
||||
print 'Did not find libz or z.lib, exiting!'
|
||||
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'):
|
||||
conf.env.Append(CCFLAGS = " -DHAVE_ASPRINTF")
|
||||
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'])
|
||||
# parse SDL cflags/libs
|
||||
env.ParseConfig('sdl-config --cflags --libs')
|
||||
env.ParseConfig('echo "-I/usr/include/lua5.1/ -llua5.1"')
|
||||
env = conf.Finish()
|
||||
|
||||
# Build for this system's endianness, if not overriden
|
||||
#if env.has_key('LSB_FIRST'):
|
||||
# if env['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'])
|
||||
|
||||
if env['FRAMESKIP']:
|
||||
|
|
|
@ -12,6 +12,7 @@ file.cpp
|
|||
filter.cpp
|
||||
ines.cpp
|
||||
input.cpp
|
||||
lua-engine.cpp
|
||||
netplay.cpp
|
||||
nsf.cpp
|
||||
palette.cpp
|
||||
|
|
|
@ -343,11 +343,12 @@ void MovieData::installValue(std::string& key, std::string& val)
|
|||
comments.push_back(val);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
std::string BytesToString(void* data, int len)
|
||||
std::string BytesToString(const void* data, int len)
|
||||
{
|
||||
char temp[16];
|
||||
if(len==1) {
|
||||
sprintf(temp,"%d",*(unsigned char*)data);
|
||||
sprintf(temp,"%d",*(const unsigned char*)data);
|
||||
return temp;
|
||||
} else if(len==2) {
|
||||
sprintf(temp,"%d",*(unsigned short*)data);
|
||||
sprintf(temp,"%d",*(const unsigned short*)data);
|
||||
return temp;
|
||||
} else if(len==4) {
|
||||
sprintf(temp,"%d",*(unsigned int*)data);
|
||||
sprintf(temp,"%d",*(const 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++)
|
||||
if(1) // use base64
|
||||
{
|
||||
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;
|
||||
const unsigned char* src = (const unsigned char*)data;
|
||||
ret = "base64:";
|
||||
for(int n; len > 0; len -= n)
|
||||
{
|
||||
unsigned char input[3] = {0,0,0};
|
||||
for(n=0; n<3 && n<len; ++n)
|
||||
input[n] = *src++;
|
||||
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;
|
||||
}
|
||||
|
||||
///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')
|
||||
return str.size()/2-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
|
||||
///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')
|
||||
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) {
|
||||
int x = atoi(str.c_str());
|
||||
|
@ -255,24 +354,6 @@ bool StringToBytes(std::string& str, void* data, int len)
|
|||
}
|
||||
//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>
|
||||
|
@ -482,4 +563,4 @@ std::string readNullTerminatedAscii(std::istream* is)
|
|||
else ret += (char)c;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,9 +44,10 @@ 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);
|
||||
int HexStringToBytesLength(const std::string& str);
|
||||
int Base64StringToBytesLength(const std::string& str);
|
||||
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);
|
||||
void splitpath(const char* path, char* drv, char* dir, char* name, char* ext);
|
||||
|
|
Loading…
Reference in New Issue