From 4c9bb20270cb2bf148bf6812397ea24faf70aa43 Mon Sep 17 00:00:00 2001 From: Ilari Liusvaara Date: Sat, 23 Jul 2016 11:16:34 +0300 Subject: [PATCH] Fix crash if mouse_x or mouse_y are hooked Turns out framebuffer draw recalibrates mouse_x and mouse_y, which then calls into hook. Which is no-no, because framebuffer draw runs in GUI thread, and hooks must run in game thread. --- include/core/framebuffer.hpp | 4 +++- src/core/framebuffer.cpp | 19 +++++++++++-------- src/core/instance.cpp | 3 ++- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/include/core/framebuffer.hpp b/include/core/framebuffer.hpp index 9cd79fde..cb7cc953 100644 --- a/include/core/framebuffer.hpp +++ b/include/core/framebuffer.hpp @@ -2,6 +2,7 @@ #define _framebuffer__hpp__included__ #include "core/window.hpp" +#include "core/queue.hpp" #include "library/command.hpp" #include "library/framebuffer.hpp" #include "library/triplebuffer.hpp" @@ -31,7 +32,7 @@ class emu_framebuffer public: emu_framebuffer(subtitle_commentary& _subtitles, settingvar::group& _settings, memwatch_set& _mwatch, keyboard::keyboard& _keyboard, emulator_dispatch& _dispatch, lua_state& _lua2, loaded_rom& _rom, - status_updater& _supdater, command::group& _cmd); + status_updater& _supdater, command::group& _cmd, input_queue& _iqueue); /** * The main framebuffer. */ @@ -110,6 +111,7 @@ private: loaded_rom& rom; status_updater& supdater; command::group& cmd; + input_queue& iqueue; command::_fnptr screenshot; }; diff --git a/src/core/framebuffer.cpp b/src/core/framebuffer.cpp index 45c50e5c..922a2260 100644 --- a/src/core/framebuffer.cpp +++ b/src/core/framebuffer.cpp @@ -90,10 +90,10 @@ 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, lua_state& _lua2, loaded_rom& _rom, - status_updater& _supdater, command::group& _cmd) + status_updater& _supdater, command::group& _cmd, input_queue& _iqueue) : buffering(buffer1, buffer2, buffer3), subtitles(_subtitles), settings(_settings), mwatch(_mwatch), keyboard(_keyboard), edispatch(_dispatch), lua2(_lua2), rom(_rom), supdater(_supdater), cmd(_cmd), - screenshot(cmd, CFRAMEBUF::ss, [this](command::arg_filename a) { this->do_screenshot(a); }) + iqueue(_iqueue), screenshot(cmd, CFRAMEBUF::ss, [this](command::arg_filename a) { this->do_screenshot(a); }) { last_redraw_no_lua = false; } @@ -186,16 +186,19 @@ void emu_framebuffer::render_framebuffer() main_screen.copy_from(ri.fbuf, ri.hscl, ri.vscl); ri.rq.run(main_screen); //We would want divide by 2, but we'll do it ourselves in order to do mouse. - keyboard::key* mouse_x = keyboard.try_lookup_key("mouse_x"); - keyboard::key* mouse_y = keyboard.try_lookup_key("mouse_y"); keyboard::mouse_calibration xcal; keyboard::mouse_calibration ycal; xcal.offset = ri.lgap; ycal.offset = ri.tgap; - if(mouse_x && mouse_x->get_type() == keyboard::KBD_KEYTYPE_MOUSE) - mouse_x->cast_mouse()->set_calibration(xcal); - if(mouse_y && mouse_y->get_type() == keyboard::KBD_KEYTYPE_MOUSE) - mouse_y->cast_mouse()->set_calibration(ycal); + auto kbd = &keyboard; + iqueue.run_async([kbd, xcal, ycal]() { + keyboard::key* mouse_x = kbd->try_lookup_key("mouse_x"); + keyboard::key* mouse_y = kbd->try_lookup_key("mouse_y"); + if(mouse_x && mouse_x->get_type() == keyboard::KBD_KEYTYPE_MOUSE) + mouse_x->cast_mouse()->set_calibration(xcal); + if(mouse_y && mouse_y->get_type() == keyboard::KBD_KEYTYPE_MOUSE) + mouse_y->cast_mouse()->set_calibration(ycal); + }, [](std::exception& e){}); buffering.put_read(); } diff --git a/src/core/instance.cpp b/src/core/instance.cpp index 0d1db414..1836f476 100644 --- a/src/core/instance.cpp +++ b/src/core/instance.cpp @@ -98,7 +98,8 @@ emulator_instance::emulator_instance() D.init(keyboard); D.init(mapper, *keyboard, *command); D.init(rom); - D.init(fbuf, *subtitles, *settings, *mwatch, *keyboard, *dispatch, *lua2, *rom, *supdater, *command); + D.init(fbuf, *subtitles, *settings, *mwatch, *keyboard, *dispatch, *lua2, *rom, *supdater, *command, + *iqueue); D.init(buttons, *controls, *mapper, *keyboard, *fbuf, *dispatch, *lua2, *command); D.init(mteditor, *mlogic, *controls, *dispatch, *supdater, *buttons, *command); D.init(status_A);