Unverified Commit 06b0aebd authored by Jean-Andre Santoni's avatar Jean-Andre Santoni Committed by GitHub
Browse files

Implement serialization callbacks (#174)

* Implement retro_serialize_size

* Implement retro_serialize

* Implement retro_unserialize

* Add example

* Prevent writing random memory to the savestate
parent e751294b
SCREEN_WIDTH = 320
SCREEN_HEIGHT = 240
RETRO_DEVICE_ID_JOYPAD_B = 1
RETRO_DEVICE_ID_JOYPAD_Y = 2
RETRO_DEVICE_ID_JOYPAD_SELECT = 3
RETRO_DEVICE_ID_JOYPAD_START = 4
RETRO_DEVICE_ID_JOYPAD_UP = 5
RETRO_DEVICE_ID_JOYPAD_DOWN = 6
RETRO_DEVICE_ID_JOYPAD_LEFT = 7
RETRO_DEVICE_ID_JOYPAD_RIGHT = 8
RETRO_DEVICE_ID_JOYPAD_A = 9
RETRO_DEVICE_ID_JOYPAD_X = 10
RETRO_DEVICE_ID_JOYPAD_L = 11
RETRO_DEVICE_ID_JOYPAD_R = 12
RETRO_DEVICE_ID_JOYPAD_L2 = 13
RETRO_DEVICE_ID_JOYPAD_R2 = 14
RETRO_DEVICE_ID_JOYPAD_L3 = 15
RETRO_DEVICE_ID_JOYPAD_R3 = 16
-- json parsing
function json_decode(msg)
local js = {}
for k,v in string.gmatch(msg,'"(%w+)":"(%w+)",') do
js[k] = v;
end
for k,v in string.gmatch(msg,'"(%w+)":"(%w+)"}') do
js[k] = v;
end
return js
end
function json_encode(map)
local msg = "{"
for k,v in pairs(map) do
msg = msg..'"'..k..'":"'..v..'",'
end
return string.sub(msg,0,-2)..'}'
end
\ No newline at end of file
require "global"
require "json"
function love.conf(t)
t.width = SCREEN_WIDTH
t.height = SCREEN_HEIGHT
end
State = {
x = 50,
y = 50
}
function love.load()
love.graphics.setBackgroundColor(0, 0, 0)
love.graphics.setDefaultFilter("nearest", "nearest")
IMG_foo = love.graphics.newImage("foo.png")
end
function love.update(dt)
State.x = State.x + 1
if State.x > SCREEN_WIDTH then State.x = 0 end
end
function love.draw()
love.graphics.draw(IMG_foo, State.x, State.y)
end
function love.reset()
print("reset from lua")
State = {
x = 50,
y = 50
}
love.load()
end
function love.serializeSize()
print("serializeSize")
return 1024
end
function love.serialize(size)
print("serialize", size)
return json_encode(State)
end
function love.unserialize(data, size)
print("unserialize", data, size)
State = json_decode(data)
end
......@@ -257,28 +257,17 @@ bool retro_load_game_special(unsigned type, const struct retro_game_info *info,
size_t retro_serialize_size(void)
{
return 0;
return lutro_serialize_size();
}
bool retro_serialize(void *data_, size_t size)
{
// if (size < game_data_size())
// return false;
// memcpy(data_, game_data(), game_data_size());
// return true;
return false;
return lutro_serialize(data_, size);
}
bool retro_unserialize(const void *data_, size_t size)
{
// if (size < game_data_size())
// return false;
// memcpy(game_data(), data_, game_data_size());
// return true;
return false;
return lutro_unserialize(data_, size);
}
void *retro_get_memory_data(unsigned id)
......@@ -287,7 +276,7 @@ void *retro_get_memory_data(unsigned id)
// return NULL;
// return game_data();
return NULL;
return NULL;
}
size_t retro_get_memory_size(unsigned id)
......@@ -296,7 +285,7 @@ size_t retro_get_memory_size(unsigned id)
// return 0;
// return game_data_size();
return 0;
return 0;
}
void retro_cheat_reset(void)
......
......@@ -643,7 +643,96 @@ void lutro_reset()
lua_pop(L, 1);
}
lua_pop(L, 3);
lua_gc(L, LUA_GCSTEP, 0);
}
size_t lutro_serialize_size()
{
size_t size = 0;
lua_pushcfunction(L, db_errorfb);
lua_getglobal(L, "lutro");
lua_getfield(L, -1, "serializeSize");
if (lua_isfunction(L, -1))
{
if (lua_pcall(L, 0, 1, 0))
{
fprintf(stderr, "%s\n", lua_tostring(L, -1));
lua_pop(L, 1);
}
if (!lua_isnumber(L, -1))
{
fprintf(stderr, "%s\n", lua_tostring(L, -1));
lua_pop(L, 1);
}
size = lua_tonumber(L, -1);
lua_pop(L, 1);
} else {
lua_pop(L, 1);
}
lua_gc(L, LUA_GCSTEP, 0);
return size;
}
bool lutro_serialize(void *data_, size_t size)
{
lua_pushcfunction(L, db_errorfb);
lua_getglobal(L, "lutro");
lua_getfield(L, -1, "serialize");
if (lua_isfunction(L, -1))
{
lua_pushnumber(L, size);
if (lua_pcall(L, 1, 1, 0))
{
fprintf(stderr, "%s\n", lua_tostring(L, -1));
lua_pop(L, 1);
return false;
}
const char* data = lua_tostring(L, -1);
lua_pop(L, 1);
memset(data_, 0, size);
memcpy(data_, data, strlen(data));
} else {
lua_pop(L, 1);
}
lua_gc(L, LUA_GCSTEP, 0);
return true;
}
bool lutro_unserialize(const void *data_, size_t size)
{
lua_pushcfunction(L, db_errorfb);
lua_getglobal(L, "lutro");
lua_getfield(L, -1, "unserialize");
if (lua_isfunction(L, -1))
{
lua_pushstring(L, data_);
lua_pushnumber(L, size);
if (lua_pcall(L, 2, 0, 0))
{
fprintf(stderr, "%s\n", lua_tostring(L, -1));
lua_pop(L, 1);
return false;
}
} else {
lua_pop(L, 1);
}
lua_gc(L, LUA_GCSTEP, 0);
return true;
}
......@@ -43,6 +43,10 @@ void lutro_run(double delta);
void lutro_reset();
size_t lutro_serialize_size();
bool lutro_serialize(void *data_, size_t size);
bool lutro_unserialize(const void *data_, size_t size);
void lutro_shutdown_game(void);
#endif // LUTRO_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment