diff --git a/include/core/framebuffer.hpp b/include/core/framebuffer.hpp index 951107bf..c0eae92a 100644 --- a/include/core/framebuffer.hpp +++ b/include/core/framebuffer.hpp @@ -76,7 +76,7 @@ void init_special_screens() throw(std::bad_alloc); /** * Copy framebuffer to backing store, running Lua hooks if any. */ -void redraw_framebuffer(lcscreen& torender, bool no_lua = false); +void redraw_framebuffer(lcscreen& torender, bool no_lua = false, bool spontaneous = false); /** * Redraw the framebuffer, reusing contents from last redraw. Runs lua hooks if last redraw ran them. */ diff --git a/include/core/lua.hpp b/include/core/lua.hpp index 318ee155..95b9f42e 100644 --- a/include/core/lua.hpp +++ b/include/core/lua.hpp @@ -68,11 +68,13 @@ struct lua_render_context void init_lua() throw(); void quit_lua() throw(); -void lua_callback_do_paint(struct lua_render_context* ctx) throw(); +void lua_callback_do_paint(struct lua_render_context* ctx, bool non_synthethic) throw(); void lua_callback_do_video(struct lua_render_context* ctx) throw(); void lua_callback_do_input(controller_frame& data, bool subframe) throw(); void lua_callback_do_reset() throw(); void lua_callback_do_frame() throw(); +void lua_callback_do_frame_emulated() throw(); +void lua_callback_do_rewind() throw(); void lua_callback_do_readwrite() throw(); void lua_callback_startup() throw(); void lua_callback_pre_load(const std::string& name) throw(); diff --git a/src/core/framebuffer.cpp b/src/core/framebuffer.cpp index fe7a195b..84032f94 100644 --- a/src/core/framebuffer.cpp +++ b/src/core/framebuffer.cpp @@ -168,7 +168,7 @@ void init_special_screens() throw(std::bad_alloc) screen_corrupt = lcscreen(&buf[0], 512, 448); } -void redraw_framebuffer(lcscreen& todraw, bool no_lua) +void redraw_framebuffer(lcscreen& todraw, bool no_lua, bool spontaneous) { uint32_t hscl, vscl; auto g = get_scale_factors(todraw.width, todraw.height); @@ -185,7 +185,7 @@ void redraw_framebuffer(lcscreen& todraw, bool no_lua) lrc.width = todraw.width * hscl; lrc.height = todraw.height * vscl; if(!no_lua) - lua_callback_do_paint(&lrc); + lua_callback_do_paint(&lrc, spontaneous); ri.fbuf = todraw; ri.hscl = hscl; ri.vscl = vscl; @@ -203,7 +203,8 @@ void redraw_framebuffer() render_info& ri = get_read_buffer(); lcscreen copy = ri.fbuf; buffering.end_read(); - redraw_framebuffer(copy, last_redraw_no_lua); + //Redraws are never spontaneous + redraw_framebuffer(copy, last_redraw_no_lua, false); } diff --git a/src/core/lua.cpp b/src/core/lua.cpp index c5c4938b..a919e12a 100644 --- a/src/core/lua.cpp +++ b/src/core/lua.cpp @@ -4,11 +4,13 @@ struct lua_State { int x; }; lua_function::lua_function(const std::string& name) throw(std::bad_alloc) {} lua_function::~lua_function() throw() {} -void lua_callback_do_paint(struct lua_render_context* ctx) throw() {} +void lua_callback_do_paint(struct lua_render_context* ctx, bool non_synthetic) throw() {} void lua_callback_do_video(struct lua_render_context* ctx) throw() {} void lua_callback_do_input(controller_frame& data, bool subframe) throw() {} void lua_callback_do_reset() throw() {} void lua_callback_do_frame() throw() {} +void lua_callback_do_rewind() throw() {} +void lua_callback_do_frame_emulated() throw() {} void lua_callback_do_readwrite() throw() {} void lua_callback_startup() throw() {} void lua_callback_pre_load(const std::string& name) throw() {} @@ -362,12 +364,13 @@ namespace } } -void lua_callback_do_paint(struct lua_render_context* ctx) throw() +void lua_callback_do_paint(struct lua_render_context* ctx, bool non_synthetic) throw() { if(!callback_exists("on_paint")) return; lua_render_ctx = ctx; - run_lua_cb(0); + push_boolean(non_synthetic); + run_lua_cb(1); lua_render_ctx = NULL; } @@ -394,6 +397,20 @@ void lua_callback_do_frame() throw() run_lua_cb(0); } +void lua_callback_do_rewind() throw() +{ + if(!callback_exists("on_rewind")) + return; + run_lua_cb(0); +} + +void lua_callback_do_frame_emulated() throw() +{ + if(!callback_exists("on_frame_emulated")) + return; + run_lua_cb(0); +} + void lua_callback_do_readwrite() throw() { if(!callback_exists("on_readwrite")) diff --git a/src/core/mainloop.cpp b/src/core/mainloop.cpp index 2d434edf..d8b3db48 100644 --- a/src/core/mainloop.cpp +++ b/src/core/mainloop.cpp @@ -335,6 +335,7 @@ class my_interface : public SNES::Interface if(stepping_into_save) messages << "Got video refresh in runtosave, expect desyncs!" << std::endl; video_refresh_done = true; + lua_callback_do_frame_emulated(); bool region = (SNES::system.region() == SNES::System::Region::PAL); information_dispatch::do_raw_frame(data, hires, interlace, overscan, region ? VIDEO_REGION_PAL : VIDEO_REGION_NTSC); @@ -345,7 +346,7 @@ class my_interface : public SNES::Interface lcscreen ls(data, hires, interlace, overscan, region); location_special = SPECIAL_FRAME_VIDEO; update_movie_state(); - redraw_framebuffer(ls); + redraw_framebuffer(ls, false, true); uint32_t fps_n, fps_d; uint32_t fclocks; if(region) diff --git a/src/core/moviedata.cpp b/src/core/moviedata.cpp index 7b81af44..54ee1c41 100644 --- a/src/core/moviedata.cpp +++ b/src/core/moviedata.cpp @@ -277,6 +277,7 @@ void do_load_beginning() throw(std::bad_alloc, std::runtime_error) our_movie.rtc_second = our_movie.movie_rtc_second; our_movie.rtc_subsecond = our_movie.movie_rtc_subsecond; redraw_framebuffer(screen_nosignal); + lua_callback_do_rewind(); } catch(std::bad_alloc& e) { OOM_panic(); } catch(std::exception& e) {