Instancefy lua core stuff

This should fix crashes on startup on Win32
This commit is contained in:
Ilari Liusvaara 2014-06-06 15:03:16 +03:00
parent b8c72344c1
commit 14a0862342
37 changed files with 627 additions and 458 deletions

View file

@ -13,6 +13,7 @@
class master_dumper;
class dumper_factory_base;
class dumper_base;
class lua_state;
class dumper_factory_base
{
@ -203,7 +204,7 @@ public:
/**
* Ctor.
*/
master_dumper();
master_dumper(lua_state& _lua2);
/**
* Get instance for specified dumper.
*/
@ -308,6 +309,7 @@ private:
gameinfo current_gi;
std::ostream* output;
threads::rlock lock;
lua_state& lua2;
};
class dumper_base

View file

@ -11,6 +11,7 @@ struct port_controller;
struct port_type;
struct emu_framebuffer;
struct emulator_dispatch;
struct lua_state;
namespace keyboard { class invbind; }
namespace keyboard { class ctrlrkey; }
namespace keyboard { class mapper; }
@ -63,7 +64,7 @@ public:
* Ctor.
*/
button_mapping(controller_state& _controls, keyboard::mapper& mapper, keyboard::keyboard& keyboard,
emu_framebuffer& fbuf, emulator_dispatch& _dispatch);
emu_framebuffer& fbuf, emulator_dispatch& _dispatch, lua_state& _lua2);
/**
* Dtor.
*/
@ -125,6 +126,7 @@ private:
keyboard::keyboard& keyboard;
emu_framebuffer& fbuf;
emulator_dispatch& edispatch;
lua_state& lua2;
struct dispatch::target<> ncore;
};

View file

@ -10,6 +10,7 @@
class subtitle_commentary;
class memwatch_set;
class emulator_dispatch;
class lua_state;
namespace settingvar
{
class group;
@ -26,7 +27,7 @@ class emu_framebuffer
{
public:
emu_framebuffer(subtitle_commentary& _subtitles, settingvar::group& _settings, memwatch_set& _mwatch,
keyboard::keyboard& _keyboard, emulator_dispatch& _dispatch);
keyboard::keyboard& _keyboard, emulator_dispatch& _dispatch, lua_state& _lua2);
/**
* The main framebuffer.
*/
@ -100,6 +101,7 @@ private:
memwatch_set& mwatch;
keyboard::keyboard& keyboard;
emulator_dispatch& edispatch;
lua_state& lua2;
};
#endif

View file

@ -24,6 +24,7 @@ class master_dumper;
class button_mapping;
class emulator_dispatch;
class slotinfo_cache;
class lua_state;
namespace command { class group; }
namespace lua { class state; }
namespace settingvar { class group; }
@ -89,6 +90,7 @@ struct emulator_instance
movie_logic* mlogic;
memory_space* memory;
lua::state* lua;
lua_state* lua2;
memwatch_set* mwatch;
settingvar::group* settings;
settingvar::cache* setcache;

View file

@ -1,7 +1,11 @@
#ifndef _subtitles__hpp__included__
#define _subtitles__hpp__included__
#include "lua/lua.hpp"
#include <cstdint>
#include <set>
#include <string>
namespace lua { class render_context; }
class moviefile_subtiming
{

View file

@ -25,15 +25,7 @@ extern lua::class_group lua_class_memory;
extern lua::class_group lua_class_fileio;
void push_keygroup_parameters(lua::state& L, keyboard::key& p);
extern lua::render_context* lua_render_ctx;
extern controller_frame* lua_input_controllerdata;
extern bool* lua_kill_frame;
extern uint32_t* lua_hscl;
extern uint32_t* lua_vscl;
extern uint64_t lua_idle_hook_time;
extern uint64_t lua_timer_hook_time;
extern void* synchronous_paint_ctx;
void lua_renderq_run(lua::render_context* ctx, void* synchronous_paint_ctx);
uint64_t lua_get_vmabase(const std::string& vma);
uint64_t lua_get_read_address(lua::parameters& P);

View file

@ -3,52 +3,113 @@
#include <string>
#include <map>
#include <list>
#include "core/controllerframe.hpp"
#include "library/movie.hpp"
#include "library/framebuffer.hpp"
#include "library/lua-base.hpp"
#include "library/lua-framebuffer.hpp"
namespace keyboard
{
class key;
}
void init_lua() throw();
void quit_lua() 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, bool& kill_frame, uint32_t& hscl, uint32_t& vscl) 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_do_idle() throw();
void lua_callback_do_timer() throw();
void lua_callback_pre_load(const std::string& name) throw();
void lua_callback_err_load(const std::string& name) throw();
void lua_callback_post_load(const std::string& name, bool was_state) throw();
void lua_callback_pre_save(const std::string& name, bool is_state) throw();
void lua_callback_err_save(const std::string& name) throw();
void lua_callback_post_save(const std::string& name, bool is_state) throw();
void lua_callback_snoop_input(uint32_t port, uint32_t controller, uint32_t index, short value) throw();
void lua_callback_quit() throw();
void lua_callback_keyhook(const std::string& key, keyboard::key& p) throw();
void lua_callback_do_unsafe_rewind(const std::vector<char>& save, uint64_t secs, uint64_t ssecs, movie& mov, void* u);
bool lua_callback_do_button(uint32_t port, uint32_t controller, uint32_t index, const char* type);
void lua_callback_movie_lost(const char* what);
void lua_callback_do_latch(std::list<std::string>& args);
void lua_run_startup_scripts();
void lua_add_startup_script(const std::string& file);
namespace command { class group; }
namespace keyboard { class key; }
#define LUA_TIMED_HOOK_IDLE 0
#define LUA_TIMED_HOOK_TIMER 1
uint64_t lua_timed_hook(int timer) throw();
const std::map<std::string, std::u32string>& get_lua_watch_vars();
void init_lua() throw();
void quit_lua() throw();
extern bool lua_requests_repaint;
extern bool lua_requests_subframe_paint;
struct lua_state
{
lua_state(lua::state& _L, command::group& _command);
~lua_state();
lua::state::callback_list* on_paint;
lua::state::callback_list* on_video;
lua::state::callback_list* on_reset;
lua::state::callback_list* on_frame;
lua::state::callback_list* on_rewind;
lua::state::callback_list* on_idle;
lua::state::callback_list* on_timer;
lua::state::callback_list* on_frame_emulated;
lua::state::callback_list* on_readwrite;
lua::state::callback_list* on_startup;
lua::state::callback_list* on_pre_load;
lua::state::callback_list* on_post_load;
lua::state::callback_list* on_err_load;
lua::state::callback_list* on_pre_save;
lua::state::callback_list* on_post_save;
lua::state::callback_list* on_err_save;
lua::state::callback_list* on_input;
lua::state::callback_list* on_snoop;
lua::state::callback_list* on_snoop2;
lua::state::callback_list* on_button;
lua::state::callback_list* on_quit;
lua::state::callback_list* on_keyhook;
lua::state::callback_list* on_movie_lost;
lua::state::callback_list* on_pre_rewind;
lua::state::callback_list* on_post_rewind;
lua::state::callback_list* on_set_rewind;
lua::state::callback_list* on_latch;
void callback_do_paint(struct lua::render_context* ctx, bool non_synthethic) throw();
void callback_do_video(struct lua::render_context* ctx, bool& kill_frame, uint32_t& hscl, uint32_t& vscl)
throw();
void callback_do_input(controller_frame& data, bool subframe) throw();
void callback_do_reset() throw();
void callback_do_frame() throw();
void callback_do_frame_emulated() throw();
void callback_do_rewind() throw();
void callback_do_readwrite() throw();
void callback_do_idle() throw();
void callback_do_timer() throw();
void callback_pre_load(const std::string& name) throw();
void callback_err_load(const std::string& name) throw();
void callback_post_load(const std::string& name, bool was_state) throw();
void callback_pre_save(const std::string& name, bool is_state) throw();
void callback_err_save(const std::string& name) throw();
void callback_post_save(const std::string& name, bool is_state) throw();
void callback_snoop_input(uint32_t port, uint32_t controller, uint32_t index, short value) throw();
void callback_quit() throw();
void callback_keyhook(const std::string& key, keyboard::key& p) throw();
void callback_do_unsafe_rewind(const std::vector<char>& save, uint64_t secs, uint64_t ssecs, movie& mov,
void* u);
bool callback_do_button(uint32_t port, uint32_t controller, uint32_t index, const char* type);
void callback_movie_lost(const char* what);
void callback_do_latch(std::list<std::string>& args);
void run_startup_scripts();
void add_startup_script(const std::string& file);
uint64_t timed_hook(int timer) throw();
const std::map<std::string, std::u32string>& get_watch_vars();
void do_eval_lua(const std::string& c) throw(std::bad_alloc);
void do_run_lua(const std::string& c) throw(std::bad_alloc);
void run_sysrc_lua();
bool requests_repaint;
bool requests_subframe_paint;
lua::render_context* render_ctx;
controller_frame* input_controllerdata;
bool* kill_frame;
void* synchronous_paint_ctx;
uint32_t* hscl;
uint32_t* vscl;
bool* veto_flag;
std::set<std::string> hooked_keys;
uint64_t idle_hook_time;
uint64_t timer_hook_time;
std::list<std::string> startup_scripts;
std::map<std::string, std::u32string> watch_vars;
private:
void run_lua_fragment() throw(std::bad_alloc);
template<typename... T> bool run_callback(lua::state::callback_list& list, T... args);
void run_synchronous_paint(struct lua::render_context* ctx);
lua::state& L;
command::group& command;
bool recursive_flag;
char* luareader_fragment;
};
#endif

View file

@ -183,7 +183,8 @@ master_dumper::notifier::~notifier()
{
}
master_dumper::master_dumper()
master_dumper::master_dumper(lua_state& _lua2)
: lua2(_lua2)
{
current_rate_n = 48000;
current_rate_d = 1;
@ -355,7 +356,7 @@ template<bool X> bool master_dumper::render_video_hud(struct framebuffer::fb<X>&
lrc.queue = &rq;
lrc.width = source.get_width();
lrc.height = source.get_height();
lua_callback_do_video(&lrc, lua_kill_video, hscl, vscl);
lua2.callback_do_video(&lrc, lua_kill_video, hscl, vscl);
if(fn)
fn();
target.reallocate(lrc.left_gap + source.get_width() * hscl + lrc.right_gap, lrc.top_gap +

View file

@ -12,6 +12,7 @@
#include "core/project.hpp"
#include "interface/romtype.hpp"
#include "library/string.hpp"
#include "lua/lua.hpp"
#include <map>
#include <sstream>
@ -101,8 +102,9 @@ namespace
}
button_mapping::button_mapping(controller_state& _controls, keyboard::mapper& _mapper, keyboard::keyboard& _keyboard,
emu_framebuffer& _fbuf, emulator_dispatch& _dispatch)
: controls(_controls), mapper(_mapper), keyboard(_keyboard), fbuf(_fbuf), edispatch(_dispatch)
emu_framebuffer& _fbuf, emulator_dispatch& _dispatch, lua_state& _lua2)
: controls(_controls), mapper(_mapper), keyboard(_keyboard), fbuf(_fbuf), edispatch(_dispatch),
lua2(_lua2)
{
ncore.set(notify_new_core, [this]() { this->init(); });
}
@ -451,14 +453,14 @@ void button_mapping::do_button_action(const std::string& name, short newstate, i
if(mode == 1) {
//Autohold.
int16_t nstate = controls.autohold2(x.port, x.controller, x.bind.control1) ^ newstate;
if(lua_callback_do_button(x.port, x.controller, x.bind.control1, nstate ? "hold" : "unhold"))
if(lua2.callback_do_button(x.port, x.controller, x.bind.control1, nstate ? "hold" : "unhold"))
return;
controls.autohold2(x.port, x.controller, x.bind.control1, nstate);
edispatch.autohold_update(x.port, x.controller, x.bind.control1, nstate);
} else if(mode == 2) {
//Framehold.
bool nstate = controls.framehold2(x.port, x.controller, x.bind.control1) ^ newstate;
if(lua_callback_do_button(x.port, x.controller, x.bind.control1, nstate ? "type" : "untype"))
if(lua2.callback_do_button(x.port, x.controller, x.bind.control1, nstate ? "type" : "untype"))
return;
controls.framehold2(x.port, x.controller, x.bind.control1, nstate);
if(nstate)
@ -466,7 +468,7 @@ void button_mapping::do_button_action(const std::string& name, short newstate, i
else
messages << "Not holding " << name << " for the next frame" << std::endl;
} else {
if(lua_callback_do_button(x.port, x.controller, x.bind.control1, newstate ? "press" :
if(lua2.callback_do_button(x.port, x.controller, x.bind.control1, newstate ? "press" :
"release"))
return;
controls.button2(x.port, x.controller, x.bind.control1, newstate);
@ -486,9 +488,9 @@ void button_mapping::send_analog(const std::string& name, int32_t x, int32_t y)
std::cerr << name << " is not a axis." << std::endl;
return;
}
if(lua_callback_do_button(z.port, z.controller, z.bind.control1, "analog"))
if(lua2.callback_do_button(z.port, z.controller, z.bind.control1, "analog"))
return;
if(lua_callback_do_button(z.port, z.controller, z.bind.control2, "analog"))
if(lua2.callback_do_button(z.port, z.controller, z.bind.control2, "analog"))
return;
auto g2 = fbuf.get_framebuffer_size();
x = z.bind.xrel ? (x - g2.first / 2) : (x / 2);
@ -529,7 +531,7 @@ void button_mapping::do_analog_action(const std::string& a)
auto x = active_buttons[name];
if(x.bind.mode != 2)
return;
if(lua_callback_do_button(x.port, x.controller, x.bind.control1, "analog"))
if(lua2.callback_do_button(x.port, x.controller, x.bind.control1, "analog"))
return;
int rmin = x.bind.rmin;
int rmax = x.bind.rmax;
@ -567,14 +569,14 @@ void button_mapping::do_autofire_action(const std::string& a, int mode)
auto afire = controls.autofire2(z.port, z.controller, z.bind.control1);
if(mode == 1 || (mode == -1 && afire.first == 0)) {
//Turn on.
if(lua_callback_do_button(z.port, z.controller, z.bind.control1, (stringfmt() << "autofire "
if(lua2.callback_do_button(z.port, z.controller, z.bind.control1, (stringfmt() << "autofire "
<< duty << " " << cyclelen).str().c_str()))
return;
controls.autofire2(z.port, z.controller, z.bind.control1, duty, cyclelen);
edispatch.autofire_update(z.port, z.controller, z.bind.control1, duty, cyclelen);
} else if(mode == 0 || (mode == -1 && afire.first != 0)) {
//Turn off.
if(lua_callback_do_button(z.port, z.controller, z.bind.control1, "autofire"))
if(lua2.callback_do_button(z.port, z.controller, z.bind.control1, "autofire"))
return;
controls.autofire2(z.port, z.controller, z.bind.control1, 0, 1);
edispatch.autofire_update(z.port, z.controller, z.bind.control1, 0, 1);

View file

@ -98,9 +98,9 @@ namespace
framebuffer::raw emu_framebuffer::screen_corrupt;
emu_framebuffer::emu_framebuffer(subtitle_commentary& _subtitles, settingvar::group& _settings, memwatch_set& _mwatch,
keyboard::keyboard& _keyboard, emulator_dispatch& _dispatch)
keyboard::keyboard& _keyboard, emulator_dispatch& _dispatch, lua_state& _lua2)
: buffering(buffer1, buffer2, buffer3), subtitles(_subtitles), settings(_settings), mwatch(_mwatch),
keyboard(_keyboard), edispatch(_dispatch)
keyboard(_keyboard), edispatch(_dispatch), lua2(_lua2)
{
last_redraw_no_lua = false;
}
@ -151,7 +151,7 @@ void emu_framebuffer::redraw_framebuffer(framebuffer::raw& todraw, bool no_lua,
lrc.width = todraw.get_width() * hscl;
lrc.height = todraw.get_height() * vscl;
if(!no_lua) {
lua_callback_do_paint(&lrc, spontaneous);
lua2.callback_do_paint(&lrc, spontaneous);
subtitles.render(lrc);
}
ri.fbuf = todraw;

View file

@ -27,6 +27,7 @@
#include "library/lua-base.hpp"
#include "library/memoryspace.hpp"
#include "library/settingvar.hpp"
#include "lua/lua.hpp"
#include <deque>
#ifdef __linux__
@ -75,6 +76,7 @@ emulator_instance::emulator_instance()
D.init(slotcache, *mlogic);
D.init(memory);
D.init(lua);
D.init(lua2, *lua, *command);
D.init(mwatch, *memory, *project, *fbuf);
D.init(settings);
D.init(setcache, *settings);
@ -84,8 +86,8 @@ emulator_instance::emulator_instance()
D.init(controls, *project, *mlogic, *buttons, *dispatch);
D.init(keyboard);
D.init(mapper, *keyboard, *command);
D.init(fbuf, *subtitles, *settings, *mwatch, *keyboard, *dispatch);
D.init(buttons, *controls, *mapper, *keyboard, *fbuf, *dispatch);
D.init(fbuf, *subtitles, *settings, *mwatch, *keyboard, *dispatch, *lua2);
D.init(buttons, *controls, *mapper, *keyboard, *fbuf, *dispatch, *lua2);
D.init(mteditor, *mlogic, *controls, *dispatch);
D.init(status_A);
D.init(status_B);
@ -97,7 +99,7 @@ emulator_instance::emulator_instance()
D.init(project, *commentary, *mwatch, *command, *controls, *setcache, *buttons, *dispatch, *iqueue);
D.init(dbg, *dispatch);
D.init(framerate);
D.init(mdumper);
D.init(mdumper, *lua2);
status_A->valid = false;
status_B->valid = false;

View file

@ -147,7 +147,7 @@ void mainloop_signal_need_rewind(void* ptr)
controller_frame movie_logic::update_controls(bool subframe) throw(std::bad_alloc, std::runtime_error)
{
auto& core = CORE();
if(lua_requests_subframe_paint)
if(core.lua2->requests_subframe_paint)
core.fbuf->redraw_framebuffer();
if(subframe) {
@ -222,7 +222,7 @@ controller_frame movie_logic::update_controls(bool subframe) throw(std::bad_allo
platform::flush_command_queue();
controller_frame tmp = core.controls->get(core.mlogic->get_movie().get_current_frame());
our_rom.rtype->pre_emulate_frame(tmp); //Preset controls, the lua will override if needed.
lua_callback_do_input(tmp, subframe);
core.lua2->callback_do_input(tmp, subframe);
core.mteditor->process_frame(tmp);
core.controls->commit(tmp);
return tmp;
@ -406,7 +406,7 @@ void update_movie_state()
_status.inputs.push_back(_buffer);
}
//Lua variables.
_status.lvars = get_lua_watch_vars();
_status.lvars = core.lua2->get_watch_vars();
//Memory watches.
_status.mvars = core.mwatch->get_window_vars();
@ -431,9 +431,10 @@ public:
int16_t get_input(unsigned port, unsigned index, unsigned control)
{
auto& core = CORE();
int16_t x;
x = CORE().mlogic->input_poll(port, index, control);
lua_callback_snoop_input(port, index, control, x);
x = core.mlogic->input_poll(port, index, control);
core.lua2->callback_snoop_input(port, index, control, x);
return x;
}
@ -450,7 +451,7 @@ public:
void notify_latch(std::list<std::string>& args)
{
lua_callback_do_latch(args);
CORE().lua2->callback_do_latch(args);
}
void timer_tick(uint32_t increment, uint32_t per_second)
@ -490,7 +491,7 @@ public:
void output_frame(framebuffer::raw& screen, uint32_t fps_n, uint32_t fps_d)
{
auto& core = CORE();
lua_callback_do_frame_emulated();
core.lua2->callback_do_frame_emulated();
location_special = SPECIAL_FRAME_VIDEO;
core.fbuf->redraw_framebuffer(screen, false, true);
auto rate = our_rom.rtype->get_audio_rate();
@ -544,11 +545,12 @@ namespace
command::fnptr<const std::string&> test4(lsnes_cmds, "test4", "test", "test",
[](const std::string& args) throw(std::bad_alloc, std::runtime_error) {
auto& core = CORE();
std::list<std::string> _args;
std::string args2 = args;
for(auto& sym : token_iterator_foreach(args, {" ", "\t"}))
_args.push_back(sym);
lua_callback_do_latch(_args);
core.lua2->callback_do_latch(_args);
});
command::fnptr<> count_rerecords(lsnes_cmds, "count-rerecords", "Count rerecords",
"Syntax: count-rerecords\nCounts rerecords.\n",
@ -834,10 +836,10 @@ namespace
"Syntax: set-rwmode\nSwitches to recording mode\n",
[]() throw(std::bad_alloc, std::runtime_error) {
auto& core = CORE();
lua_callback_movie_lost("readwrite");
core.lua2->callback_movie_lost("readwrite");
core.mlogic->get_movie().readonly_mode(false);
core.dispatch->mode_change(false);
lua_callback_do_readwrite();
core.lua2->callback_do_readwrite();
update_movie_state();
});
@ -856,11 +858,11 @@ namespace
auto& core = CORE();
bool c = core.mlogic->get_movie().readonly_mode();
if(c)
lua_callback_movie_lost("readwrite");
core.lua2->callback_movie_lost("readwrite");
core.mlogic->get_movie().readonly_mode(!c);
core.dispatch->mode_change(!c);
if(c)
lua_callback_do_readwrite();
core.lua2->callback_do_readwrite();
update_movie_state();
});
@ -1086,7 +1088,7 @@ jumpback:
return 0;
uint64_t t = framerate_regulator::get_utime();
std::vector<char> s;
lua_callback_do_unsafe_rewind(s, 0, 0, core.mlogic->get_movie(), unsafe_rewind_obj);
core.lua2->callback_do_unsafe_rewind(s, 0, 0, core.mlogic->get_movie(), unsafe_rewind_obj);
core.dispatch->mode_change(false);
do_unsafe_rewind = false;
core.mlogic->get_mfile().is_savestate = true;
@ -1181,7 +1183,7 @@ nothing_to_do:
std::vector<char> s = our_rom.save_core_state(true);
uint64_t secs = core.mlogic->get_mfile().rtc_second;
uint64_t ssecs = core.mlogic->get_mfile().rtc_subsecond;
lua_callback_do_unsafe_rewind(s, secs, ssecs, core.mlogic->get_movie(),
core.lua2->callback_do_unsafe_rewind(s, secs, ssecs, core.mlogic->get_movie(),
NULL);
do_unsafe_rewind = false;
messages << "Rewind point set in " << (framerate_regulator::get_utime() - t)
@ -1256,7 +1258,7 @@ void main_loop(struct loaded_rom& rom, struct moviefile& initial, bool load_has_
amode = initial.start_paused ? ADVANCE_PAUSE : ADVANCE_AUTO;
stop_at_frame_active = false;
lua_run_startup_scripts();
core.lua2->run_startup_scripts();
uint64_t time_x = framerate_regulator::get_utime();
while(!is_quitting() || !queued_saves.empty()) {
@ -1324,7 +1326,7 @@ void main_loop(struct loaded_rom& rom, struct moviefile& initial, bool load_has_
if(amode == ADVANCE_AUTO)
platform::wait(core.framerate->to_wait_frame(framerate_regulator::get_utime()));
first_round = false;
lua_callback_do_frame();
core.lua2->callback_do_frame();
}
out:
core.mdumper->end_dumps();

View file

@ -219,7 +219,7 @@ void do_save_state(const std::string& filename, int binary) throw(std::bad_alloc
}
auto& target = core.mlogic->get_mfile();
std::string filename2 = translate_name_mprefix(filename, binary, 1);
lua_callback_pre_save(filename2, true);
core.lua2->callback_pre_save(filename2, true);
try {
uint64_t origtime = framerate_regulator::get_utime();
target.is_savestate = true;
@ -246,13 +246,13 @@ void do_save_state(const std::string& filename, int binary) throw(std::bad_alloc
std::string kind = (binary > 0) ? "(binary format)" : "(zip format)";
messages << "Saved state " << kind << " '" << filename2 << "' in " << took << " microseconds."
<< std::endl;
lua_callback_post_save(filename2, true);
core.lua2->callback_post_save(filename2, true);
} catch(std::bad_alloc& e) {
throw;
} catch(std::exception& e) {
platform::error_message(std::string("Save failed: ") + e.what());
messages << "Save failed: " << e.what() << std::endl;
lua_callback_err_save(filename2);
core.lua2->callback_err_save(filename2);
}
last_save = resolve_relative_path(filename2);
auto p = core.project->get();
@ -273,7 +273,7 @@ void do_save_movie(const std::string& filename, int binary) throw(std::bad_alloc
}
auto& target = core.mlogic->get_mfile();
std::string filename2 = translate_name_mprefix(filename, binary, 0);
lua_callback_pre_save(filename2, false);
core.lua2->callback_pre_save(filename2, false);
try {
uint64_t origtime = framerate_regulator::get_utime();
target.is_savestate = false;
@ -289,13 +289,13 @@ void do_save_movie(const std::string& filename, int binary) throw(std::bad_alloc
std::string kind = (binary > 0) ? "(binary format)" : "(zip format)";
messages << "Saved movie " << kind << " '" << filename2 << "' in " << took << " microseconds."
<< std::endl;
lua_callback_post_save(filename2, false);
core.lua2->callback_post_save(filename2, false);
} catch(std::bad_alloc& e) {
OOM_panic();
} catch(std::exception& e) {
platform::error_message(std::string("Save failed: ") + e.what());
messages << "Save failed: " << e.what() << std::endl;
lua_callback_err_save(filename2);
core.lua2->callback_err_save(filename2);
}
last_save = resolve_relative_path(filename2);
auto p = core.project->get();
@ -473,7 +473,7 @@ void do_load_rom() throw(std::bad_alloc, std::runtime_error)
core.mlogic->get_mfile().host_memory.clear();
core.mlogic->get_movie().reset_state();
core.fbuf->redraw_framebuffer(our_rom.rtype->draw_cover());
lua_callback_do_rewind();
core.lua2->callback_do_rewind();
} catch(std::bad_alloc& e) {
OOM_panic();
} catch(std::exception& e) {
@ -520,12 +520,12 @@ void do_load_rom() throw(std::bad_alloc, std::runtime_error)
rrd.get()->read_base(rrdata::filename(_movie.get()->projectid), true);
rrd.get()->add((*core.nrrdata)());
//Movie data is lost.
lua_callback_movie_lost("reload");
core.lua2->callback_movie_lost("reload");
try {
handle_load_core(*_movie.get(), portset2, false);
_movie.get()->gametype = &our_rom.rtype->combine_region(*our_rom.region);
core.fbuf->redraw_framebuffer(our_rom.rtype->draw_cover());
lua_callback_do_rewind();
core.lua2->callback_do_rewind();
} catch(std::bad_alloc& e) {
OOM_panic();
} catch(std::exception& e) {
@ -569,7 +569,7 @@ void do_load_rewind() throw(std::bad_alloc, std::runtime_error)
core.mlogic->get_mfile().host_memory.clear();
core.mlogic->get_movie().reset_state();
core.fbuf->redraw_framebuffer(our_rom.rtype->draw_cover());
lua_callback_do_rewind();
core.lua2->callback_do_rewind();
} catch(std::bad_alloc& e) {
OOM_panic();
} catch(std::exception& e) {
@ -753,7 +753,7 @@ void do_load_state(struct moviefile& _movie, int lmode, bool& used)
_movie.host_memory.clear();
}
lua_callback_movie_lost("load");
core.lua2->callback_movie_lost("load");
//Copy the data.
if(new_rrdata) core.mlogic->set_rrdata(*(rrd()), true);
@ -841,7 +841,7 @@ bool do_load_state(const std::string& filename, int lmode)
int tmp = -1;
std::string filename2 = translate_name_mprefix(filename, tmp, -1);
uint64_t origtime = framerate_regulator::get_utime();
lua_callback_pre_load(filename2);
core.lua2->callback_pre_load(filename2);
struct moviefile* mfile = NULL;
bool used = false;
try {
@ -853,14 +853,14 @@ bool do_load_state(const std::string& filename, int lmode)
} catch(std::exception& e) {
platform::error_message(std::string("Can't read movie/savestate: ") + e.what());
messages << "Can't read movie/savestate '" << filename2 << "': " << e.what() << std::endl;
lua_callback_err_load(filename2);
core.lua2->callback_err_load(filename2);
return false;
}
try {
do_load_state(*mfile, lmode, used);
uint64_t took = framerate_regulator::get_utime() - origtime;
messages << "Loaded '" << filename2 << "' in " << took << " microseconds." << std::endl;
lua_callback_post_load(filename2, core.mlogic->get_mfile().is_savestate);
core.lua2->callback_post_load(filename2, core.mlogic->get_mfile().is_savestate);
} catch(std::bad_alloc& e) {
OOM_panic();
} catch(std::exception& e) {
@ -868,7 +868,7 @@ bool do_load_state(const std::string& filename, int lmode)
delete mfile;
platform::error_message(std::string("Can't load movie/savestate: ") + e.what());
messages << "Can't load movie/savestate '" << filename2 << "': " << e.what() << std::endl;
lua_callback_err_load(filename2);
core.lua2->callback_err_load(filename2);
return false;
}
return true;

View file

@ -8,6 +8,7 @@
#include "core/subtitles.hpp"
#include "fonts/wrapper.hpp"
#include "library/string.hpp"
#include "lua/lua.hpp"
#include <fstream>

View file

@ -242,9 +242,10 @@ namespace
uint64_t on_timer_time;
void reload_lua_timers()
{
on_idle_time = lua_timed_hook(LUA_TIMED_HOOK_IDLE);
on_timer_time = lua_timed_hook(LUA_TIMED_HOOK_TIMER);
CORE().iqueue->queue_function_run = false;
auto& core = CORE();
on_idle_time = core.lua2->timed_hook(LUA_TIMED_HOOK_IDLE);
on_timer_time = core.lua2->timed_hook(LUA_TIMED_HOOK_TIMER);
core.iqueue->queue_function_run = false;
}
}
@ -281,11 +282,11 @@ void platform::flush_command_queue() throw()
while(true) {
uint64_t now = framerate_regulator::get_utime();
if(now >= on_timer_time) {
lua_callback_do_timer();
core.lua2->callback_do_timer();
reload_lua_timers();
}
if(run_idle) {
lua_callback_do_idle();
core.lua2->callback_do_idle();
reload_lua_timers();
run_idle = false;
}
@ -335,11 +336,11 @@ void platform::wait(uint64_t usec) throw()
while(true) {
uint64_t now = framerate_regulator::get_utime();
if(now >= on_timer_time) {
lua_callback_do_timer();
core.lua2->callback_do_timer();
reload_lua_timers();
}
if(run_idle) {
lua_callback_do_idle();
core.lua2->callback_do_idle();
run_idle = false;
reload_lua_timers();
}

View file

@ -1868,6 +1868,7 @@ again2:
void snesdbg_execute_callback(lua::state*& cb, signed r)
{
auto& core = CORE();
if(!cb)
return;
cb->pushlightuserdata(&cb);
@ -1881,9 +1882,9 @@ again2:
messages << "Can't execute debug callback" << std::endl;
cb->pop(2);
}
if(lua_requests_repaint) {
lua_requests_repaint = false;
CORE().command->invoke("repaint");
if(core.lua2->requests_repaint) {
core.lua2->requests_repaint = false;
core.command->invoke("repaint");
}
}

View file

@ -148,21 +148,23 @@ namespace
int set_idle_timeout(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
uint64_t dt;
P(dt);
lua_idle_hook_time = framerate_regulator::get_utime() + dt;
core.lua2->idle_hook_time = framerate_regulator::get_utime() + dt;
return 0;
}
int set_timer_timeout(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
uint64_t dt;
P(dt);
lua_timer_hook_time = framerate_regulator::get_utime() + dt;
core.lua2->timer_hook_time = framerate_regulator::get_utime() + dt;
return 0;
}

View file

@ -1,3 +1,4 @@
#include "core/instance.hpp"
#include "lua/internal.hpp"
#include "library/framebuffer.hpp"
#include "library/lua-framebuffer.hpp"
@ -90,19 +91,20 @@ namespace
int arrow(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
int32_t x, y;
uint32_t length, headwidth, width, headthickness;
int direction;
bool fill;
framebuffer::color color;
if(!lua_render_ctx) return 0;
if(!core.lua2->render_ctx) return 0;
P(x, y, length, headwidth, direction, P.optional(fill, false), P.optional(color, 0xFFFFFF),
P.optional(width, 1), P.optional2(headthickness, width));
lua_render_ctx->queue->create_add<render_object_arrow>(x, y, length, width, headwidth, headthickness,
direction, fill, color);
core.lua2->render_ctx->queue->create_add<render_object_arrow>(x, y, length, width, headwidth,
headthickness, direction, fill, color);
return 0;
}

View file

@ -962,18 +962,19 @@ int lua_bitmap::create(lua::state& L, lua::parameters& P)
template<bool outside, bool clip>
int lua_bitmap::draw(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
int32_t x, y;
lua::objpin<lua_bitmap> b;
lua::objpin<lua_palette> p;
if(!lua_render_ctx) return 0;
if(!core.lua2->render_ctx) return 0;
P(b, x, y, p);
int32_t x0 = 0, y0 = 0, dw = b->width, dh = b->height;
if(clip) P(x0, y0, dw, dh);
lua_render_ctx->queue->create_add<render_object_bitmap>(x, y, b, p, x0, y0, dw, dh, outside);
core.lua2->render_ctx->queue->create_add<render_object_bitmap>(x, y, b, p, x0, y0, dw, dh, outside);
return 0;
}
@ -1134,17 +1135,18 @@ int lua_dbitmap::create(lua::state& L, lua::parameters& P)
template<bool outside, bool clip>
int lua_dbitmap::draw(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
int32_t x, y;
lua::objpin<lua_dbitmap> b;
if(!lua_render_ctx) return 0;
if(!core.lua2->render_ctx) return 0;
P(b, x, y);
int32_t x0 = 0, y0 = 0, dw = b->width, dh = b->height;
if(clip) P(x0, y0, dw, dh);
lua_render_ctx->queue->create_add<render_object_bitmap>(x, y, b, x0, y0, dw, dh, outside);
core.lua2->render_ctx->queue->create_add<render_object_bitmap>(x, y, b, x0, y0, dw, dh, outside);
return 0;
}

View file

@ -1,3 +1,4 @@
#include "core/instance.hpp"
#include "lua/internal.hpp"
#include "library/framebuffer.hpp"
#include "library/range.hpp"
@ -48,16 +49,17 @@ namespace
int box(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
int32_t x, y;
uint32_t width, height, thickness;
framebuffer::color poutline1, poutline2, pfill;
if(!lua_render_ctx) return 0;
if(!core.lua2->render_ctx) return 0;
P(x, y, width, height, P.optional(thickness, 1), P.optional(poutline1, 0xFFFFFFU),
P.optional(poutline2, 0x808080U), P.optional(pfill, 0xC0C0C0U));
lua_render_ctx->queue->create_add<render_object_box>(x, y, width, height, poutline1, poutline2,
core.lua2->render_ctx->queue->create_add<render_object_box>(x, y, width, height, poutline1, poutline2,
pfill, thickness);
return 0;
}

View file

@ -1,3 +1,4 @@
#include "core/instance.hpp"
#include "lua/internal.hpp"
#include "library/framebuffer.hpp"
#include "library/range.hpp"
@ -56,15 +57,17 @@ namespace
int circle(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
int32_t x, y;
uint32_t radius, thickness;
framebuffer::color poutline, pfill;
if(!lua_render_ctx) return 0;
if(!core.lua2->render_ctx) return 0;
P(x, y, radius, P.optional(thickness, 1), P.optional(poutline, 0xFFFFFFU), P.optional(pfill, -1));
lua_render_ctx->queue->create_add<render_object_circle>(x, y, radius, poutline, pfill, thickness);
core.lua2->render_ctx->queue->create_add<render_object_circle>(x, y, radius, poutline, pfill,
thickness);
return 0;
}

View file

@ -1,4 +1,5 @@
#include "lua/internal.hpp"
#include "core/instance.hpp"
#include "core/window.hpp"
#include "library/minmax.hpp"
@ -6,46 +7,46 @@ void update_movie_state();
namespace
{
std::map<std::string, std::u32string> lua_watch_vars;
template<uint32_t lua::render_context::*gap, bool delta>
int lua_gui_set_gap(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
int32_t g;
if(!lua_render_ctx)
if(!core.lua2->render_ctx)
return 0;
P(g);
if(lua_render_ctx->*gap == std::numeric_limits<uint32_t>::max())
lua_render_ctx->*gap = 0; //Handle default gap of render queue.
if(delta) g += lua_render_ctx->*gap;
if(core.lua2->render_ctx->*gap == std::numeric_limits<uint32_t>::max())
core.lua2->render_ctx->*gap = 0; //Handle default gap of render queue.
if(delta) g += core.lua2->render_ctx->*gap;
if(g < 0 || g > 8192)
return 0; //Ignore ridiculous gap.
uint32_t old = lua_render_ctx->*gap;
lua_render_ctx->*gap = g;
uint32_t old = core.lua2->render_ctx->*gap;
core.lua2->render_ctx->*gap = g;
L.pushnumber(old);
return 1;
}
int resolution(lua::state& L, lua::parameters& P)
{
if(!lua_render_ctx)
auto& core = CORE();
if(!core.lua2->render_ctx)
return 0;
L.pushnumber(lua_render_ctx->width);
L.pushnumber(lua_render_ctx->height);
L.pushnumber(core.lua2->render_ctx->width);
L.pushnumber(core.lua2->render_ctx->height);
return 2;
}
int repaint(lua::state& L, lua::parameters& P)
{
lua_requests_repaint = true;
CORE().lua2->requests_repaint = true;
return 0;
}
int subframe_update(lua::state& L, lua::parameters& P)
{
P(lua_requests_subframe_paint);
P(CORE().lua2->requests_subframe_paint);
return 0;
}
@ -70,14 +71,15 @@ namespace
int status(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
std::string name, value;
P(name, value);
if(value == "")
lua_watch_vars.erase(name);
core.lua2->watch_vars.erase(name);
else
lua_watch_vars[name] = utf8::to32(value);
core.lua2->watch_vars[name] = utf8::to32(value);
update_movie_state();
return 1;
}
@ -99,20 +101,22 @@ namespace
int kill_frame(lua::state& L, lua::parameters& P)
{
if(lua_kill_frame)
*lua_kill_frame = true;
auto& core = CORE();
if(core.lua2->kill_frame)
*core.lua2->kill_frame = true;
return 0;
}
int set_video_scale(lua::state& L, lua::parameters& P)
{
if(lua_hscl && lua_vscl) {
auto& core = CORE();
if(core.lua2->hscl && core.lua2->vscl) {
uint32_t h, v;
P(h, v);
*lua_hscl = h;
*lua_vscl = v;
*core.lua2->hscl = h;
*core.lua2->vscl = v;
}
return 0;
}
@ -136,8 +140,3 @@ namespace
{"set_video_scale", set_video_scale},
});
}
const std::map<std::string, std::u32string>& get_lua_watch_vars()
{
return lua_watch_vars;
}

View file

@ -1,3 +1,4 @@
#include "core/instance.hpp"
#include "lua/internal.hpp"
#include "library/framebuffer.hpp"
#include "library/lua-framebuffer.hpp"
@ -35,15 +36,16 @@ namespace
int crosshair(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
int32_t x, y;
uint32_t length;
framebuffer::color pcolor;
if(!lua_render_ctx) return 0;
if(!core.lua2->render_ctx) return 0;
P(x, y, P.optional(length, 10), P.optional(pcolor, 0xFFFFFFU));
lua_render_ctx->queue->create_add<render_object_crosshair>(x, y, pcolor, length);
core.lua2->render_ctx->queue->create_add<render_object_crosshair>(x, y, pcolor, length);
return 0;
}

View file

@ -1,3 +1,4 @@
#include "core/instance.hpp"
#include "lua/internal.hpp"
#include "library/framebuffer.hpp"
#include "library/lua-framebuffer.hpp"
@ -91,14 +92,15 @@ nodraw2:
int line(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
int32_t x1, y1, x2, y2;
framebuffer::color pcolor;
if(!lua_render_ctx) return 0;
if(!core.lua2->render_ctx) return 0;
P(x1, y1, x2, y2, P.optional(pcolor, 0xFFFFFFU));
lua_render_ctx->queue->create_add<render_object_line>(x1, x2, y1, y2, pcolor);
core.lua2->render_ctx->queue->create_add<render_object_line>(x1, x2, y1, y2, pcolor);
return 0;
}

View file

@ -1,3 +1,4 @@
#include "core/instance.hpp"
#include "lua/internal.hpp"
#include "library/framebuffer.hpp"
#include "library/lua-framebuffer.hpp"
@ -30,14 +31,15 @@ namespace
int pixel(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
int32_t x, y;
framebuffer::color pcolor;
if(!lua_render_ctx) return 0;
if(!core.lua2->render_ctx) return 0;
P(x, y, P.optional(pcolor, 0xFFFFFFU));
lua_render_ctx->queue->create_add<render_object_pixel>(x, y, pcolor);
core.lua2->render_ctx->queue->create_add<render_object_pixel>(x, y, pcolor);
return 0;
}

View file

@ -1,3 +1,4 @@
#include "core/instance.hpp"
#include "lua/internal.hpp"
#include "library/framebuffer.hpp"
#include "library/range.hpp"
@ -44,31 +45,34 @@ namespace
int rectangle(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
int32_t x, y;
uint32_t width, height, thickness;
framebuffer::color poutline, pfill;
if(!lua_render_ctx) return 0;
if(!core.lua2->render_ctx) return 0;
P(x, y, width, height, P.optional(thickness, 1), P.optional(poutline, 0xFFFFFFU),
P.optional(pfill, -1));
lua_render_ctx->queue->create_add<render_object_rectangle>(x, y, width, height, poutline, pfill,
thickness);
core.lua2->render_ctx->queue->create_add<render_object_rectangle>(x, y, width, height, poutline,
pfill, thickness);
return 0;
}
int srectangle(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
int32_t x, y;
uint32_t width, height;
framebuffer::color pcolor;
if(!lua_render_ctx) return 0;
if(!core.lua2->render_ctx) return 0;
P(x, y, width, height, P.optional(pcolor, 0xFFFFFFU));
lua_render_ctx->queue->create_add<render_object_rectangle>(x, y, width, height, pcolor, pcolor, 0);
core.lua2->render_ctx->queue->create_add<render_object_rectangle>(x, y, width, height, pcolor, pcolor,
0);
return 0;
}

View file

@ -24,29 +24,31 @@ namespace
static int setnull(lua::state& L, lua::parameters& P);
int run(lua::state& L, lua::parameters& P)
{
if(!lua_render_ctx) return 0;
auto& core = CORE();
if(!core.lua2->render_ctx) return 0;
lua::render_context* ptr = get();
if(ptr->top_gap != std::numeric_limits<uint32_t>::max())
lua_render_ctx->top_gap = ptr->top_gap;
core.lua2->render_ctx->top_gap = ptr->top_gap;
if(ptr->right_gap != std::numeric_limits<uint32_t>::max())
lua_render_ctx->right_gap = ptr->right_gap;
core.lua2->render_ctx->right_gap = ptr->right_gap;
if(ptr->bottom_gap != std::numeric_limits<uint32_t>::max())
lua_render_ctx->bottom_gap = ptr->bottom_gap;
core.lua2->render_ctx->bottom_gap = ptr->bottom_gap;
if(ptr->left_gap != std::numeric_limits<uint32_t>::max())
lua_render_ctx->left_gap = ptr->left_gap;
lua_render_ctx->queue->copy_from(*ptr->queue);
core.lua2->render_ctx->left_gap = ptr->left_gap;
core.lua2->render_ctx->queue->copy_from(*ptr->queue);
return 0;
}
int synchronous_repaint(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
lua::objpin<lua_renderqueue> q;
P(q);
synchronous_paint_ctx = &*q;
CORE().fbuf->redraw_framebuffer();
synchronous_paint_ctx = NULL;
core.lua2->synchronous_paint_ctx = &*q;
core.fbuf->redraw_framebuffer();
core.lua2->synchronous_paint_ctx = NULL;
return 0;
}
int clear(lua::state& L, lua::parameters& P)
@ -61,14 +63,15 @@ namespace
}
int set(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
lua::objpin<lua_renderqueue> q;
P(q);
lua::render_context* ptr = q->get();
if(!redirect || last != lua_render_ctx)
saved = lua_render_ctx;
lua_render_ctx = last = ptr;
if(!redirect || last != core.lua2->render_ctx)
saved = core.lua2->render_ctx;
core.lua2->render_ctx = last = ptr;
redirect = true;
return 0;
}
@ -128,9 +131,10 @@ namespace
int lua_renderqueue::setnull(lua::state& L, lua::parameters& P)
{
if(redirect && last == lua_render_ctx)
auto& core = CORE();
if(redirect && last == core.lua2->render_ctx)
//If there is valid redirect, undo it.
lua_render_ctx = saved;
core.lua2->render_ctx = saved;
redirect = false;
last = NULL;
saved = NULL;

View file

@ -1,3 +1,4 @@
#include "core/instance.hpp"
#include "lua/internal.hpp"
#include "lua/bitmap.hpp"
#include "fonts/wrapper.hpp"
@ -120,17 +121,18 @@ namespace
int lua_customfont::draw(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
int32_t _x, _y;
framebuffer::color fg, bg, hl;
std::string text;
lua::objpin<lua_customfont> f;
if(!lua_render_ctx)
if(!core.lua2->render_ctx)
return 0;
P(f, _x, _y, text, P.optional(fg, 0xFFFFFFU), P.optional(bg, -1), P.optional(hl, -1));
lua_render_ctx->queue->create_add<render_object_text_cf>(_x, _y, text, fg, bg, hl, f);
core.lua2->render_ctx->queue->create_add<render_object_text_cf>(_x, _y, text, fg, bg, hl, f);
return 0;
}

View file

@ -1,3 +1,4 @@
#include "core/instance.hpp"
#include "lua/internal.hpp"
#include "fonts/wrapper.hpp"
#include "library/framebuffer.hpp"
@ -31,15 +32,16 @@ namespace
template<bool hdbl, bool vdbl>
int internal_gui_text(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
int32_t x, y;
std::string text;
framebuffer::color fg, bg;
if(!lua_render_ctx) return 0;
if(!core.lua2->render_ctx) return 0;
P(x, y, text, P.optional(fg, 0xFFFFFFU), P.optional(bg, -1));
lua_render_ctx->queue->create_add<render_object_text>(x, y, text, fg, bg, hdbl, vdbl);
core.lua2->render_ctx->queue->create_add<render_object_text>(x, y, text, fg, bg, hdbl, vdbl);
return 0;
}

View file

@ -292,16 +292,17 @@ namespace
template<bool outside> int tilemap::draw(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
uint32_t x, y, w, h;
int32_t x0, y0;
lua::objpin<tilemap> t;
if(!lua_render_ctx) return 0;
if(!core.lua2->render_ctx) return 0;
P(t, x, y, P.optional(x0, 0), P.optional(y0, 0), P.optional(w, width * cwidth),
P.optional(h, height * cheight));
lua_render_ctx->queue->create_add<render_object_tilemap>(x, y, x0, y0, w, h, outside, t);
core.lua2->render_ctx->queue->create_add<render_object_tilemap>(x, y, x0, y0, w, h, outside, t);
return 0;
}

View file

@ -6,29 +6,30 @@
#include "interface/romtype.hpp"
#include <iostream>
extern bool* lua_veto_flag;
namespace
{
int input_set(lua::state& L, unsigned port, unsigned controller, unsigned index, short value)
{
if(!lua_input_controllerdata)
auto& core = CORE();
if(!core.lua2->input_controllerdata)
return 0;
lua_input_controllerdata->axis3(port, controller, index, value);
core.lua2->input_controllerdata->axis3(port, controller, index, value);
return 0;
}
int input_get(lua::state& L, unsigned port, unsigned controller, unsigned index)
{
if(!lua_input_controllerdata)
auto& core = CORE();
if(!core.lua2->input_controllerdata)
return 0;
L.pushnumber(lua_input_controllerdata->axis3(port, controller, index));
L.pushnumber(core.lua2->input_controllerdata->axis3(port, controller, index));
return 1;
}
int input_controllertype(lua::state& L, unsigned port, unsigned controller)
{
auto& m = CORE().mlogic->get_movie();
auto& core = CORE();
auto& m = core.mlogic->get_movie();
controller_frame f = m.read_subframe(m.get_current_frame(), 0);
if(port >= f.get_port_count()) {
L.pushnil();
@ -44,38 +45,40 @@ namespace
int input_seta(lua::state& L, unsigned port, unsigned controller, uint64_t base, lua::parameters& P)
{
if(!lua_input_controllerdata)
auto& core = CORE();
if(!core.lua2->input_controllerdata)
return 0;
short val;
if(port >= lua_input_controllerdata->get_port_count())
if(port >= core.lua2->input_controllerdata->get_port_count())
return 0;
const port_type& pt = lua_input_controllerdata->get_port_type(port);
const port_type& pt = core.lua2->input_controllerdata->get_port_type(port);
if(controller >= pt.controller_info->controllers.size())
return 0;
for(unsigned i = 0; i < pt.controller_info->controllers[controller].buttons.size(); i++) {
val = (base >> i) & 1;
P(P.optional(val, val));
lua_input_controllerdata->axis3(port, controller, i, val);
core.lua2->input_controllerdata->axis3(port, controller, i, val);
}
return 0;
}
int input_geta(lua::state& L, unsigned port, unsigned controller)
{
if(!lua_input_controllerdata)
auto& core = CORE();
if(!core.lua2->input_controllerdata)
return 0;
if(port >= lua_input_controllerdata->get_port_count())
if(port >= core.lua2->input_controllerdata->get_port_count())
return 0;
const port_type& pt = lua_input_controllerdata->get_port_type(port);
const port_type& pt = core.lua2->input_controllerdata->get_port_type(port);
if(controller >= pt.controller_info->controllers.size())
return 0;
uint64_t fret = 0;
for(unsigned i = 0; i < pt.controller_info->controllers[controller].buttons.size(); i++)
if(lua_input_controllerdata->axis3(port, controller, i))
if(core.lua2->input_controllerdata->axis3(port, controller, i))
fret |= (1ULL << i);
L.pushnumber(fret);
for(unsigned i = 0; i < pt.controller_info->controllers[controller].buttons.size(); i++)
L.pushnumber(lua_input_controllerdata->axis3(port, controller, i));
L.pushnumber(core.lua2->input_controllerdata->axis3(port, controller, i));
return pt.controller_info->controllers[controller].buttons.size() + 1;
}
@ -83,14 +86,15 @@ namespace
{
void on_key_event(keyboard::modifier_set& modifiers, keyboard::key& key, keyboard::event& event)
{
lua_callback_keyhook(key.get_name(), key);
auto& core = CORE();
core.lua2->callback_keyhook(key.get_name(), key);
}
} keyhook_listener;
std::set<std::string> hooked;
const port_controller_set* lookup_ps(unsigned port)
{
auto& m = CORE().mlogic->get_movie();
auto& core = CORE();
auto& m = core.mlogic->get_movie();
controller_frame f = m.read_subframe(m.get_current_frame(), 0);
const port_type& p = f.get_port_type(port);
return p.controller_info;
@ -98,13 +102,14 @@ namespace
int set(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
unsigned controller, index, value;
if(!lua_input_controllerdata) return 0;
if(!core.lua2->input_controllerdata) return 0;
P(controller, index, value);
auto _controller = lua_input_controllerdata->porttypes().legacy_pcid_to_pair(controller);
auto _controller = core.lua2->input_controllerdata->porttypes().legacy_pcid_to_pair(controller);
return input_set(L, _controller.first, _controller.second, index, value);
}
@ -120,13 +125,14 @@ namespace
int get(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
unsigned controller, index;
if(!lua_input_controllerdata) return 0;
if(!core.lua2->input_controllerdata) return 0;
P(controller, index);
auto _controller = lua_input_controllerdata->porttypes().legacy_pcid_to_pair(controller);
auto _controller = core.lua2->input_controllerdata->porttypes().legacy_pcid_to_pair(controller);
return input_get(L, _controller.first, _controller.second, index);
}
@ -141,14 +147,15 @@ namespace
int seta(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
unsigned controller;
uint64_t base;
if(!lua_input_controllerdata) return 0;
if(!core.lua2->input_controllerdata) return 0;
P(controller, base);
auto _controller = lua_input_controllerdata->porttypes().legacy_pcid_to_pair(controller);
auto _controller = core.lua2->input_controllerdata->porttypes().legacy_pcid_to_pair(controller);
return input_seta(L, _controller.first, _controller.second, base, P);
}
@ -164,13 +171,14 @@ namespace
int geta(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
unsigned controller;
if(!lua_input_controllerdata) return 0;
if(!core.lua2->input_controllerdata) return 0;
P(controller);
auto _controller = lua_input_controllerdata->porttypes().legacy_pcid_to_pair(controller);
auto _controller = core.lua2->input_controllerdata->porttypes().legacy_pcid_to_pair(controller);
return input_geta(L, _controller.first, _controller.second);
}
@ -185,11 +193,12 @@ namespace
int controllertype(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
unsigned controller;
P(controller);
auto& m = CORE().mlogic->get_movie();
auto& m = core.mlogic->get_movie();
const port_type_set& s = m.read_subframe(m.get_current_frame(), 0).porttypes();
auto _controller = s.legacy_pcid_to_pair(controller);
return input_controllertype(L, _controller.first, _controller.second);
@ -206,9 +215,10 @@ namespace
int reset(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
long cycles;
if(!lua_input_controllerdata) return 0;
if(!core.lua2->input_controllerdata) return 0;
P(P.optional(cycles, 0));
@ -216,16 +226,17 @@ namespace
return 0;
short lo = cycles % 10000;
short hi = cycles / 10000;
lua_input_controllerdata->axis3(0, 0, 1, 1);
lua_input_controllerdata->axis3(0, 0, 2, hi);
lua_input_controllerdata->axis3(0, 0, 3, lo);
core.lua2->input_controllerdata->axis3(0, 0, 1, 1);
core.lua2->input_controllerdata->axis3(0, 0, 2, hi);
core.lua2->input_controllerdata->axis3(0, 0, 3, lo);
return 0;
}
int raw(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
L.newtable();
for(auto i : CORE().keyboard->all_keys()) {
for(auto i : core.keyboard->all_keys()) {
L.pushlstring(i->get_name());
push_keygroup_parameters(L, *i);
L.settable(-3);
@ -235,22 +246,23 @@ namespace
int keyhook(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
std::string x;
bool state;
P(x, state);
keyboard::key* key = CORE().keyboard->try_lookup_key(x);
keyboard::key* key = core.keyboard->try_lookup_key(x);
if(!key)
throw std::runtime_error("Invalid key name");
bool ostate = hooked.count(x) > 0;
bool ostate = core.lua2->hooked_keys.count(x) > 0;
if(ostate == state)
return 0;
if(state) {
hooked.insert(x);
core.lua2->hooked_keys.insert(x);
key->add_listener(keyhook_listener, true);
} else {
hooked.erase(x);
core.lua2->hooked_keys.erase(x);
key->remove_listener(keyhook_listener);
}
return 0;
@ -258,17 +270,18 @@ namespace
int joyget(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
unsigned lcid;
P(lcid);
if(!lua_input_controllerdata)
if(!core.lua2->input_controllerdata)
return 0;
auto pcid = CORE().controls->lcid_to_pcid(lcid - 1);
auto pcid = core.controls->lcid_to_pcid(lcid - 1);
if(pcid.first < 0)
throw std::runtime_error("Invalid controller for input.joyget");
L.newtable();
const port_type& pt = lua_input_controllerdata->get_port_type(pcid.first);
const port_type& pt = core.lua2->input_controllerdata->get_port_type(pcid.first);
const port_controller& ctrl = pt.controller_info->controllers[pcid.second];
unsigned lcnt = ctrl.buttons.size();
for(unsigned i = 0; i < lcnt; i++) {
@ -276,9 +289,10 @@ namespace
continue;
L.pushlstring(ctrl.buttons[i].name);
if(ctrl.buttons[i].is_analog())
L.pushnumber(lua_input_controllerdata->axis3(pcid.first, pcid.second, i));
L.pushnumber(core.lua2->input_controllerdata->axis3(pcid.first, pcid.second, i));
else if(ctrl.buttons[i].type == port_controller_button::TYPE_BUTTON)
L.pushboolean(lua_input_controllerdata->axis3(pcid.first, pcid.second, i) != 0);
L.pushboolean(core.lua2->input_controllerdata->axis3(pcid.first, pcid.second, i) !=
0);
L.settable(-3);
}
return 1;
@ -286,17 +300,18 @@ namespace
int joyset(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
unsigned lcid;
int ltbl;
P(lcid, P.table(ltbl));
if(!lua_input_controllerdata)
if(!core.lua2->input_controllerdata)
return 0;
auto pcid = CORE().controls->lcid_to_pcid(lcid - 1);
auto pcid = core.controls->lcid_to_pcid(lcid - 1);
if(pcid.first < 0)
throw std::runtime_error("Invalid controller for input.joyset");
const port_type& pt = lua_input_controllerdata->get_port_type(pcid.first);
const port_type& pt = core.lua2->input_controllerdata->get_port_type(pcid.first);
const port_controller& ctrl = pt.controller_info->controllers[pcid.second];
unsigned lcnt = ctrl.buttons.size();
for(unsigned i = 0; i < lcnt; i++) {
@ -307,18 +322,18 @@ namespace
int s;
if(ctrl.buttons[i].is_analog()) {
if(L.type(-1) == LUA_TNIL)
s = lua_input_controllerdata->axis3(pcid.first, pcid.second, i);
s = core.lua2->input_controllerdata->axis3(pcid.first, pcid.second, i);
else
s = L.tonumber(-1);
} else {
if(L.type(-1) == LUA_TNIL)
s = lua_input_controllerdata->axis3(pcid.first, pcid.second, i);
s = core.lua2->input_controllerdata->axis3(pcid.first, pcid.second, i);
else if(L.type(-1) == LUA_TSTRING)
s = lua_input_controllerdata->axis3(pcid.first, pcid.second, i) ^ 1;
s = core.lua2->input_controllerdata->axis3(pcid.first, pcid.second, i) ^ 1;
else
s = L.toboolean(-1) ? 1 : 0;
}
lua_input_controllerdata->axis3(pcid.first, pcid.second, i, s);
core.lua2->input_controllerdata->axis3(pcid.first, pcid.second, i, s);
L.pop(1);
}
return 0;
@ -356,11 +371,12 @@ namespace
int lcid_to_pcid2(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
unsigned lcid;
P(lcid);
auto pcid = CORE().controls->lcid_to_pcid(lcid - 1);
auto pcid = core.controls->lcid_to_pcid(lcid - 1);
if(pcid.first < 0)
return 0;
L.pushnumber(pcid.first);
@ -370,11 +386,12 @@ namespace
int _port_type(lua::state& L, lua::parameters& P)
{
auto& core = CORE();
unsigned port;
P(port);
auto& m = CORE().mlogic->get_movie();
auto& m = core.mlogic->get_movie();
const port_type_set& s = m.read_subframe(m.get_current_frame(), 0).porttypes();
try {
const port_type& p = s.port_type(port);
@ -387,7 +404,8 @@ namespace
int veto_button(lua::state& L, lua::parameters& P)
{
if(lua_veto_flag) *lua_veto_flag = true;
auto& core = CORE();
if(core.lua2->veto_flag) *core.lua2->veto_flag = true;
return 0;
}

View file

@ -19,14 +19,7 @@ extern "C" {
#include <lualib.h>
}
uint64_t lua_idle_hook_time = 0x7EFFFFFFFFFFFFFFULL;
uint64_t lua_timer_hook_time = 0x7EFFFFFFFFFFFFFFULL;
bool* lua_veto_flag = NULL;
bool* lua_kill_frame = NULL;
uint32_t* lua_hscl = NULL;
uint32_t* lua_vscl = NULL;
extern const char* lua_sysrc_script;
void* synchronous_paint_ctx;
lua::function_group lua_func_bit;
lua::function_group lua_func_misc;
@ -43,8 +36,6 @@ lua::class_group lua_class_fileio;
namespace
{
std::list<std::string> startup_scripts;
void pushpair(lua::state& L, std::string key, double value)
{
L.pushstring(key.c_str());
@ -96,8 +87,6 @@ void push_keygroup_parameters(lua::state& L, keyboard::key& p)
}
}
lua::render_context* lua_render_ctx = NULL;
controller_frame* lua_input_controllerdata = NULL;
namespace
{
@ -107,11 +96,10 @@ namespace
return 1;
}
bool recursive_flag = false;
const char* luareader_fragment = NULL;
const char* read_lua_fragment(lua_State* L, void* dummy, size_t* size)
const char* read_lua_fragment(lua_State* L, void* fragment, size_t* size)
{
const char* luareader_fragment = reinterpret_cast<const char*>(fragment);
if(luareader_fragment) {
const char* ret = luareader_fragment;
*size = strlen(luareader_fragment);
@ -131,87 +119,6 @@ namespace
"\"Parse error in Lua statement\"); end;";
const char* run_lua_lua = "dofile(" TEMPORARY ");";
void run_lua_fragment(lua::state& L) throw(std::bad_alloc)
{
if(recursive_flag)
return;
#if LUA_VERSION_NUM == 501
int t = L.load(read_lua_fragment, NULL, "run_lua_fragment");
#endif
#if LUA_VERSION_NUM == 502
int t = L.load(read_lua_fragment, NULL, "run_lua_fragment", "t");
#endif
if(t == LUA_ERRSYNTAX) {
messages << "Can't run Lua: Internal syntax error: " << L.tostring(-1)
<< std::endl;
L.pop(1);
return;
}
if(t == LUA_ERRMEM) {
messages << "Can't run Lua: Out of memory" << std::endl;
L.pop(1);
return;
}
recursive_flag = true;
int r = L.pcall(0, 0, 0);
recursive_flag = false;
if(r == LUA_ERRRUN) {
messages << "Error running Lua hunk: " << L.tostring(-1) << std::endl;
L.pop(1);
}
if(r == LUA_ERRMEM) {
messages << "Error running Lua hunk: Out of memory" << std::endl;
L.pop(1);
}
if(r == LUA_ERRERR) {
messages << "Error running Lua hunk: Double Fault???" << std::endl;
L.pop(1);
}
lua_render_ctx = NULL;
if(lua_requests_repaint) {
lua_requests_repaint = false;
CORE().command->invoke("repaint");
}
}
void do_eval_lua(lua::state& L, const std::string& c) throw(std::bad_alloc)
{
L.pushlstring(c.c_str(), c.length());
L.setglobal(TEMPORARY);
luareader_fragment = eval_lua_lua;
run_lua_fragment(L);
}
void do_run_lua(lua::state& L, const std::string& c) throw(std::bad_alloc)
{
L.pushlstring(c.c_str(), c.length());
L.setglobal(TEMPORARY);
luareader_fragment = run_lua_lua;
run_lua_fragment(L);
}
template<typename... T> bool run_callback(lua::state::callback_list& list, T... args)
{
if(recursive_flag)
return true;
recursive_flag = true;
try {
if(!list.callback(args...)) {
recursive_flag = false;
return false;
}
} catch(std::exception& e) {
messages << e.what() << std::endl;
}
recursive_flag = false;
lua_render_ctx = NULL;
if(lua_requests_repaint) {
lua_requests_repaint = false;
CORE().command->invoke("repaint");
}
return true;
}
int system_write_error(lua_State* L)
{
lua_pushstring(L, "_SYSTEM is write-protected");
@ -245,151 +152,185 @@ namespace
L.setmetatable(-2);
L.setglobal("_SYSTEM");
}
void run_sysrc_lua(lua::state& L)
{
L.pushstring(lua_sysrc_script);
L.setglobal(TEMPORARY);
luareader_fragment = eval_sysrc_lua;
run_lua_fragment(L);
}
void run_synchronous_paint(struct lua::render_context* ctx)
{
if(!synchronous_paint_ctx)
return;
lua_renderq_run(ctx, synchronous_paint_ctx);
}
#define DEFINE_CB(X) lua::state::callback_list on_##X (*CORE().lua, #X , "on_" #X )
DEFINE_CB(paint);
DEFINE_CB(video);
DEFINE_CB(reset);
DEFINE_CB(frame);
DEFINE_CB(rewind);
DEFINE_CB(idle);
DEFINE_CB(timer);
DEFINE_CB(frame_emulated);
DEFINE_CB(readwrite);
DEFINE_CB(startup);
DEFINE_CB(pre_load);
DEFINE_CB(post_load);
DEFINE_CB(err_load);
DEFINE_CB(pre_save);
DEFINE_CB(post_save);
DEFINE_CB(err_save);
DEFINE_CB(input);
DEFINE_CB(snoop);
DEFINE_CB(snoop2);
DEFINE_CB(button);
DEFINE_CB(quit);
DEFINE_CB(keyhook);
DEFINE_CB(movie_lost);
DEFINE_CB(pre_rewind);
DEFINE_CB(post_rewind);
DEFINE_CB(set_rewind);
DEFINE_CB(latch);
}
void lua_callback_do_paint(struct lua::render_context* ctx, bool non_synthetic) throw()
lua_state::lua_state(lua::state& _L, command::group& _command)
: L(_L), command(_command)
{
requests_repaint = false;
requests_subframe_paint = false;
render_ctx = NULL;
input_controllerdata = NULL;
idle_hook_time = 0x7EFFFFFFFFFFFFFFULL;
timer_hook_time = 0x7EFFFFFFFFFFFFFFULL;
veto_flag = NULL;
kill_frame = NULL;
hscl = NULL;
vscl = NULL;
synchronous_paint_ctx = NULL;
recursive_flag = false;
luareader_fragment = NULL;
on_paint = new lua::state::callback_list(L, "paint", "on_paint");
on_video = new lua::state::callback_list(L, "video", "on_video");
on_reset = new lua::state::callback_list(L, "reset", "on_reset");
on_frame = new lua::state::callback_list(L, "frame", "on_frame");
on_rewind = new lua::state::callback_list(L, "rewind", "on_rewind");
on_idle = new lua::state::callback_list(L, "idle", "on_idle");
on_timer = new lua::state::callback_list(L, "timer", "on_timer");
on_frame_emulated = new lua::state::callback_list(L, "frame_emulated", "on_frame_emulated");
on_readwrite = new lua::state::callback_list(L, "readwrite", "on_readwrite");
on_startup = new lua::state::callback_list(L, "startup", "on_startup");
on_pre_load = new lua::state::callback_list(L, "pre_load", "on_pre_load");
on_post_load = new lua::state::callback_list(L, "post_load", "on_post_load");
on_err_load = new lua::state::callback_list(L, "err_load", "on_err_load");
on_pre_save = new lua::state::callback_list(L, "pre_save", "on_pre_save");
on_post_save = new lua::state::callback_list(L, "post_save", "on_post_save");
on_err_save = new lua::state::callback_list(L, "err_save", "on_err_save");
on_input = new lua::state::callback_list(L, "input", "on_input");
on_snoop = new lua::state::callback_list(L, "snoop", "on_snoop");
on_snoop2 = new lua::state::callback_list(L, "snoop2", "on_snoop2");
on_button = new lua::state::callback_list(L, "button", "on_button");
on_quit = new lua::state::callback_list(L, "quit", "on_quit");
on_keyhook = new lua::state::callback_list(L, "keyhook", "on_keyhook");
on_movie_lost = new lua::state::callback_list(L, "movie_lost", "on_movie_lost");
on_pre_rewind = new lua::state::callback_list(L, "pre_rewind", "on_pre_rewind");
on_post_rewind = new lua::state::callback_list(L, "post_rewind", "on_post_rewind");
on_set_rewind = new lua::state::callback_list(L, "set_rewind", "on_set_rewind");
on_latch = new lua::state::callback_list(L, "latch", "on_latch");
}
lua_state::~lua_state()
{
delete on_paint;
delete on_video;
delete on_reset;
delete on_frame;
delete on_rewind;
delete on_idle;
delete on_timer;
delete on_frame_emulated;
delete on_readwrite;
delete on_startup;
delete on_pre_load;
delete on_post_load;
delete on_err_load;
delete on_pre_save;
delete on_post_save;
delete on_err_save;
delete on_input;
delete on_snoop;
delete on_snoop2;
delete on_button;
delete on_quit;
delete on_keyhook;
delete on_movie_lost;
delete on_pre_rewind;
delete on_post_rewind;
delete on_set_rewind;
delete on_latch;
}
void lua_state::callback_do_paint(struct lua::render_context* ctx, bool non_synthetic) throw()
{
run_synchronous_paint(ctx);
run_callback(on_paint, lua::state::store_tag(lua_render_ctx, ctx), lua::state::boolean_tag(non_synthetic));
run_callback(*on_paint, lua::state::store_tag(render_ctx, ctx), lua::state::boolean_tag(non_synthetic));
}
void lua_callback_do_video(struct lua::render_context* ctx, bool& kill_frame, uint32_t& hscl, uint32_t& vscl) throw()
void lua_state::callback_do_video(struct lua::render_context* ctx, bool& _kill_frame, uint32_t& _hscl,
uint32_t& _vscl) throw()
{
run_callback(on_video, lua::state::store_tag(lua_render_ctx, ctx), lua::state::store_tag(lua_kill_frame,
&kill_frame), lua::state::store_tag(lua_hscl, &hscl), lua::state::store_tag(lua_vscl, &vscl));
run_callback(*on_video, lua::state::store_tag(render_ctx, ctx), lua::state::store_tag(kill_frame,
&_kill_frame), lua::state::store_tag(hscl, &_hscl), lua::state::store_tag(vscl, &_vscl));
}
void lua_callback_do_reset() throw()
void lua_state::callback_do_reset() throw()
{
run_callback(on_reset);
run_callback(*on_reset);
}
void lua_callback_do_frame() throw()
void lua_state::callback_do_frame() throw()
{
run_callback(on_frame);
run_callback(*on_frame);
}
void lua_callback_do_rewind() throw()
void lua_state::callback_do_rewind() throw()
{
run_callback(on_rewind);
run_callback(*on_rewind);
}
void lua_callback_do_idle() throw()
void lua_state::callback_do_idle() throw()
{
lua_idle_hook_time = 0x7EFFFFFFFFFFFFFFULL;
run_callback(on_idle);
idle_hook_time = 0x7EFFFFFFFFFFFFFFULL;
run_callback(*on_idle);
}
void lua_callback_do_timer() throw()
void lua_state::callback_do_timer() throw()
{
lua_timer_hook_time = 0x7EFFFFFFFFFFFFFFULL;
run_callback(on_timer);
timer_hook_time = 0x7EFFFFFFFFFFFFFFULL;
run_callback(*on_timer);
}
void lua_callback_do_frame_emulated() throw()
void lua_state::callback_do_frame_emulated() throw()
{
run_callback(on_frame_emulated);
run_callback(*on_frame_emulated);
}
void lua_callback_do_readwrite() throw()
void lua_state::callback_do_readwrite() throw()
{
run_callback(on_readwrite);
run_callback(*on_readwrite);
}
void lua_callback_pre_load(const std::string& name) throw()
void lua_state::callback_pre_load(const std::string& name) throw()
{
run_callback(on_pre_load, lua::state::string_tag(name));
run_callback(*on_pre_load, lua::state::string_tag(name));
}
void lua_callback_err_load(const std::string& name) throw()
void lua_state::callback_err_load(const std::string& name) throw()
{
run_callback(on_err_load, lua::state::string_tag(name));
run_callback(*on_err_load, lua::state::string_tag(name));
}
void lua_callback_post_load(const std::string& name, bool was_state) throw()
void lua_state::callback_post_load(const std::string& name, bool was_state) throw()
{
run_callback(on_post_load, lua::state::string_tag(name), lua::state::boolean_tag(was_state));
run_callback(*on_post_load, lua::state::string_tag(name), lua::state::boolean_tag(was_state));
}
void lua_callback_pre_save(const std::string& name, bool is_state) throw()
void lua_state::callback_pre_save(const std::string& name, bool is_state) throw()
{
run_callback(on_pre_save, lua::state::string_tag(name), lua::state::boolean_tag(is_state));
run_callback(*on_pre_save, lua::state::string_tag(name), lua::state::boolean_tag(is_state));
}
void lua_callback_err_save(const std::string& name) throw()
void lua_state::callback_err_save(const std::string& name) throw()
{
run_callback(on_err_save, lua::state::string_tag(name));
run_callback(*on_err_save, lua::state::string_tag(name));
}
void lua_callback_post_save(const std::string& name, bool is_state) throw()
void lua_state::callback_post_save(const std::string& name, bool is_state) throw()
{
run_callback(on_post_save, lua::state::string_tag(name), lua::state::boolean_tag(is_state));
run_callback(*on_post_save, lua::state::string_tag(name), lua::state::boolean_tag(is_state));
}
void lua_callback_do_input(controller_frame& data, bool subframe) throw()
void lua_state::callback_do_input(controller_frame& data, bool subframe) throw()
{
run_callback(on_input, lua::state::store_tag(lua_input_controllerdata, &data),
run_callback(*on_input, lua::state::store_tag(input_controllerdata, &data),
lua::state::boolean_tag(subframe));
}
void lua_callback_snoop_input(uint32_t port, uint32_t controller, uint32_t index, short value) throw()
void lua_state::callback_snoop_input(uint32_t port, uint32_t controller, uint32_t index, short value) throw()
{
if(run_callback(on_snoop2, lua::state::numeric_tag(port), lua::state::numeric_tag(controller),
if(run_callback(*on_snoop2, lua::state::numeric_tag(port), lua::state::numeric_tag(controller),
lua::state::numeric_tag(index), lua::state::numeric_tag(value)))
return;
run_callback(on_snoop, lua::state::numeric_tag(port), lua::state::numeric_tag(controller),
run_callback(*on_snoop, lua::state::numeric_tag(port), lua::state::numeric_tag(controller),
lua::state::numeric_tag(index), lua::state::numeric_tag(value));
}
bool lua_callback_do_button(uint32_t port, uint32_t controller, uint32_t index, const char* type)
bool lua_state::callback_do_button(uint32_t port, uint32_t controller, uint32_t index, const char* type)
{
bool flag = false;
run_callback(on_button, lua::state::store_tag(lua_veto_flag, &flag), lua::state::numeric_tag(port),
run_callback(*on_button, lua::state::store_tag(veto_flag, &flag), lua::state::numeric_tag(port),
lua::state::numeric_tag(controller), lua::state::numeric_tag(index), lua::state::string_tag(type));
return flag;
}
@ -401,7 +342,8 @@ namespace
[](const std::string& args) throw(std::bad_alloc, std::runtime_error) {
if(args == "")
throw std::runtime_error("Expected expression to evaluate");
do_eval_lua(*CORE().lua, args);
auto& core = CORE();
core.lua2->do_eval_lua(args);
});
command::fnptr<const std::string&> evaluate_lua2(lsnes_cmds, "L", "Evaluate expression in "
@ -409,14 +351,16 @@ namespace
[](const std::string& args) throw(std::bad_alloc, std::runtime_error) {
if(args == "")
throw std::runtime_error("Expected expression to evaluate");
do_eval_lua(*CORE().lua, args);
auto& core = CORE();
core.lua2->do_eval_lua(args);
});
command::fnptr<command::arg_filename> run_lua(lsnes_cmds, "run-lua", "Run Lua script in Lua VM",
"Syntax: run-lua <file>\nRuns <file> in Lua VM.\n",
[](command::arg_filename args) throw(std::bad_alloc, std::runtime_error)
{
do_run_lua(*CORE().lua, args);
auto& core = CORE();
core.lua2->do_run_lua(args);
});
command::fnptr<> reset_lua(lsnes_cmds, "reset-lua", "Reset the Lua VM",
@ -427,7 +371,7 @@ namespace
core.lua->reset();
luaL_openlibs(core.lua->handle());
run_sysrc_lua(*core.lua);
core.lua2->run_sysrc_lua();
copy_system_tables(*core.lua);
messages << "Lua VM reset" << std::endl;
});
@ -436,19 +380,19 @@ namespace
}, &lua_unsaferewind::print);
}
void lua_callback_quit() throw()
void lua_state::callback_quit() throw()
{
run_callback(on_quit);
run_callback(*on_quit);
}
void lua_callback_keyhook(const std::string& key, keyboard::key& p) throw()
void lua_state::callback_keyhook(const std::string& key, keyboard::key& p) throw()
{
run_callback(on_keyhook, lua::state::string_tag(key), lua::state::fnptr_tag(push_keygroup_parameters2, &p));
run_callback(*on_keyhook, lua::state::string_tag(key), lua::state::fnptr_tag(push_keygroup_parameters2, &p));
}
void init_lua() throw()
{
auto& core = CORE();
auto& core = lsnes_instance;
core.lua->set_oom_handler(OOM_panic);
try {
core.lua->reset();
@ -468,50 +412,51 @@ void init_lua() throw()
fatal_error();
}
luaL_openlibs(core.lua->handle());
run_sysrc_lua(*core.lua);
core.lua2->run_sysrc_lua();
copy_system_tables(*core.lua);
}
void quit_lua() throw()
{
CORE().lua->deinit();
lsnes_instance.lua->deinit();
}
#define LUA_TIMED_HOOK_IDLE 0
#define LUA_TIMED_HOOK_TIMER 1
uint64_t lua_timed_hook(int timer) throw()
uint64_t lua_state::timed_hook(int timer) throw()
{
switch(timer) {
case LUA_TIMED_HOOK_IDLE:
return lua_idle_hook_time;
return idle_hook_time;
case LUA_TIMED_HOOK_TIMER:
return lua_timer_hook_time;
return timer_hook_time;
}
return 0;
}
void lua_callback_do_unsafe_rewind(const std::vector<char>& save, uint64_t secs, uint64_t ssecs, movie& mov, void* u)
void lua_state::callback_do_unsafe_rewind(const std::vector<char>& save, uint64_t secs, uint64_t ssecs, movie& mov,
void* u)
{
auto& core = CORE();
if(u) {
lua_unsaferewind* u2 = reinterpret_cast<lua::objpin<lua_unsaferewind>*>(u)->object();
//Load.
try {
run_callback(on_pre_rewind);
run_callback(on_movie_lost, "unsaferewind");
run_callback(*on_pre_rewind);
run_callback(*on_movie_lost, "unsaferewind");
mainloop_restore_state(u2->state, u2->secs, u2->ssecs);
mov.fast_load(u2->frame, u2->ptr, u2->lag, u2->pollcounters);
try { core.mlogic->get_mfile().host_memory = u2->hostmemory; } catch(...) {}
run_callback(on_post_rewind);
run_callback(*on_post_rewind);
delete reinterpret_cast<lua::objpin<lua_unsaferewind>*>(u);
} catch(...) {
return;
}
} else {
//Save
run_callback(on_set_rewind, lua::state::fn_tag([&core, save, secs, ssecs, &mov](lua::state& L) ->
run_callback(*on_set_rewind, lua::state::fn_tag([&core, save, secs, ssecs, &mov](lua::state& L) ->
int {
lua_unsaferewind* u2 = lua::_class<lua_unsaferewind>::create(*core.lua);
u2->state = save;
@ -524,32 +469,130 @@ void lua_callback_do_unsafe_rewind(const std::vector<char>& save, uint64_t secs,
}
}
void lua_callback_movie_lost(const char* what)
void lua_state::callback_movie_lost(const char* what)
{
run_callback(on_movie_lost, std::string(what));
run_callback(*on_movie_lost, std::string(what));
}
void lua_callback_do_latch(std::list<std::string>& args)
void lua_state::callback_do_latch(std::list<std::string>& args)
{
run_callback(on_latch, lua::state::vararg_tag(args));
run_callback(*on_latch, lua::state::vararg_tag(args));
}
bool lua_requests_repaint = false;
bool lua_requests_subframe_paint = false;
lua_unsaferewind::lua_unsaferewind(lua::state& L)
{
}
void lua_run_startup_scripts()
void lua_state::run_startup_scripts()
{
for(auto i : startup_scripts) {
messages << "Trying to run Lua script: " << i << std::endl;
do_run_lua(*CORE().lua, i);
do_run_lua(i);
}
}
void lua_add_startup_script(const std::string& file)
void lua_state::add_startup_script(const std::string& file)
{
startup_scripts.push_back(file);
}
const std::map<std::string, std::u32string>& lua_state::get_watch_vars()
{
return watch_vars;
}
void lua_state::run_lua_fragment() throw(std::bad_alloc)
{
if(recursive_flag)
return;
#if LUA_VERSION_NUM == 501
int t = L.load(read_lua_fragment, luareader_fragment, "run_lua_fragment");
#endif
#if LUA_VERSION_NUM == 502
int t = L.load(read_lua_fragment, luareader_fragment, "run_lua_fragment", "t");
#endif
if(t == LUA_ERRSYNTAX) {
messages << "Can't run Lua: Internal syntax error: " << L.tostring(-1)
<< std::endl;
L.pop(1);
return;
}
if(t == LUA_ERRMEM) {
messages << "Can't run Lua: Out of memory" << std::endl;
L.pop(1);
return;
}
recursive_flag = true;
int r = L.pcall(0, 0, 0);
recursive_flag = false;
if(r == LUA_ERRRUN) {
messages << "Error running Lua hunk: " << L.tostring(-1) << std::endl;
L.pop(1);
}
if(r == LUA_ERRMEM) {
messages << "Error running Lua hunk: Out of memory" << std::endl;
L.pop(1);
}
if(r == LUA_ERRERR) {
messages << "Error running Lua hunk: Double Fault???" << std::endl;
L.pop(1);
}
render_ctx = NULL;
if(requests_repaint) {
requests_repaint = false;
command.invoke("repaint");
}
}
void lua_state::do_eval_lua(const std::string& c) throw(std::bad_alloc)
{
L.pushlstring(c.c_str(), c.length());
L.setglobal(TEMPORARY);
luareader_fragment = const_cast<char*>(eval_lua_lua);
run_lua_fragment();
}
void lua_state::do_run_lua(const std::string& c) throw(std::bad_alloc)
{
L.pushlstring(c.c_str(), c.length());
L.setglobal(TEMPORARY);
luareader_fragment = const_cast<char*>(run_lua_lua);
run_lua_fragment();
}
template<typename... T> bool lua_state::run_callback(lua::state::callback_list& list, T... args)
{
if(recursive_flag)
return true;
recursive_flag = true;
try {
if(!list.callback(args...)) {
recursive_flag = false;
return false;
}
} catch(std::exception& e) {
messages << e.what() << std::endl;
}
recursive_flag = false;
render_ctx = NULL;
if(requests_repaint) {
requests_repaint = false;
command.invoke("repaint");
}
return true;
}
void lua_state::run_sysrc_lua()
{
L.pushstring(lua_sysrc_script);
L.setglobal(TEMPORARY);
luareader_fragment = const_cast<char*>(eval_sysrc_lua);
run_lua_fragment();
}
void lua_state::run_synchronous_paint(struct lua::render_context* ctx)
{
if(!synchronous_paint_ctx)
return;
lua_renderq_run(ctx, synchronous_paint_ctx);
}

View file

@ -12,6 +12,7 @@
#include "library/minmax.hpp"
#include "library/string.hpp"
#include "library/utf8.hpp"
#include "lua/lua.hpp"
#include <algorithm>
#include <cstring>
@ -134,19 +135,20 @@ void wxeditor_autohold::on_checkbox(wxCommandEvent& e)
bool newstate = isaf ? t.afcheck->IsChecked() : t.check->IsChecked();
bool state = false;
inst.iqueue->run([t, newstate, &state, isaf]() {
auto& core = CORE();
if(isaf) {
auto _state = CORE().controls->autofire2(t.port, t.controller, t.index);
auto _state = core.controls->autofire2(t.port, t.controller, t.index);
state = (_state.first != 0);
if(lua_callback_do_button(t.port, t.controller, t.index, newstate ? "autofire 1 2" :
if(core.lua2->callback_do_button(t.port, t.controller, t.index, newstate ? "autofire 1 2" :
"autofire"))
return;
CORE().controls->autofire2(t.port, t.controller, t.index, newstate ? 1 : 0, newstate ? 2 : 1);
core.controls->autofire2(t.port, t.controller, t.index, newstate ? 1 : 0, newstate ? 2 : 1);
state = newstate;
} else {
state = CORE().controls->autohold2(t.port, t.controller, t.index);
if(lua_callback_do_button(t.port, t.controller, t.index, newstate ? "hold" : "unhold"))
state = core.controls->autohold2(t.port, t.controller, t.index);
if(core.lua2->callback_do_button(t.port, t.controller, t.index, newstate ? "hold" : "unhold"))
return;
CORE().controls->autohold2(t.port, t.controller, t.index, newstate);
core.controls->autohold2(t.port, t.controller, t.index, newstate);
state = newstate;
}
});
@ -175,12 +177,13 @@ void wxeditor_autohold::update_controls()
std::vector<control_triple> _autoholds;
std::vector<std::string> _controller_labels;
inst.iqueue->run([&_autoholds, &_controller_labels](){
auto& core = CORE();
std::map<std::string, unsigned> next_in_class;
controller_frame model = CORE().controls->get_blank();
controller_frame model = core.controls->get_blank();
const port_type_set& pts = model.porttypes();
unsigned cnum_g = 0;
for(unsigned i = 0;; i++) {
auto pcid = CORE().controls->lcid_to_pcid(i);
auto pcid = core.controls->lcid_to_pcid(i);
if(pcid.first < 0)
break;
const port_type& pt = pts.port_type(pcid.first);
@ -210,8 +213,8 @@ void wxeditor_autohold::update_controls()
t.port = pcid.first;
t.controller = pcid.second;
t.index = k;
t.status = CORE().controls->autohold2(pcid.first, pcid.second, k);
auto h = CORE().controls->autofire2(pcid.first, pcid.second, k);
t.status = core.controls->autohold2(pcid.first, pcid.second, k);
auto h = core.controls->autofire2(pcid.first, pcid.second, k);
t.afstatus = (h.first > 0);
t.logical = cnum_g;
t.name = pcb.name;

View file

@ -1,6 +1,8 @@
#include "core/subtitles.hpp"
#include "core/instance.hpp"
#include "core/moviedata.hpp"
#include "core/dispatch.hpp"
#include "library/string.hpp"
#include "platform/wxwidgets/platform.hpp"
@ -9,10 +11,8 @@
#include <wx/control.h>
#include <wx/combobox.h>
#include <wx/radiobut.h>
#include <cstdint>
#include "library/string.hpp"
#include "core/dispatch.hpp"
#include "core/subtitles.hpp"
namespace
{

View file

@ -544,7 +544,7 @@ bool lsnes_app::OnInit()
our_rom = rom;
mov->start_paused = start_unpaused ? !(rom.rtype && !rom.rtype->isnull()) : true;
for(auto i : c_lua)
lua_add_startup_script(i);
lsnes_instance.lua2->add_startup_script(i);
boot_emulator(lsnes_instance, rom, *mov, fullscreen_mode);
return true;
}

View file

@ -1527,14 +1527,15 @@ void wxwin_mainwindow::handle_menu_click_cancelable(wxCommandEvent& e)
case wxID_READONLY_MODE:
s = menu_ischecked(wxID_READONLY_MODE);
inst.iqueue->run([s]() {
auto& core = CORE();
if(!s)
lua_callback_movie_lost("readwrite");
if(*CORE().mlogic) CORE().mlogic->get_movie().readonly_mode(s);
CORE().dispatch->mode_change(s);
core.lua2->callback_movie_lost("readwrite");
if(*core.mlogic) core.mlogic->get_movie().readonly_mode(s);
core.dispatch->mode_change(s);
if(!s)
lua_callback_do_readwrite();
core.lua2->callback_do_readwrite();
update_movie_state();
CORE().dispatch->status_update();
core.dispatch->status_update();
});
return;
case wxID_AUTOHOLD:

View file

@ -162,7 +162,7 @@ namespace
for(auto i = cmdline.begin(); i != cmdline.end(); i++) {
std::string a = *i;
if(a.length() > 6 && a.substr(0, 6) == "--lua=") {
lua_add_startup_script(a.substr(6));
lsnes_instance.lua2->add_startup_script(a.substr(6));
}
}
}