diff --git a/src/wx/CMakeLists.txt b/src/wx/CMakeLists.txt index 9821028a5..b700729df 100644 --- a/src/wx/CMakeLists.txt +++ b/src/wx/CMakeLists.txt @@ -247,8 +247,12 @@ if(APPLE) SET(MACOSX_BUNDLE_ICON_FILE ${VBAM_ICON}) SET_SOURCE_FILES_PROPERTIES(${VBAM_ICON_PATH} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) - ADD_CUSTOM_COMMAND(TARGET visualboyadvance-m POST_BUILD - COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tools/osx/third_party_libs_tool "$/../..") + # budle dylibs and relink them for releasing .app + # but only in Release mode + IF(CMAKE_BUILD_TYPE STREQUAL "Release") + ADD_CUSTOM_COMMAND(TARGET visualboyadvance-m POST_BUILD + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tools/osx/third_party_libs_tool "$/../..") + ENDIF() endif(APPLE) SET(WX_EXE_NAME visualboyadvance-m-wx${CMAKE_EXECUTABLE_SUFFIX}) diff --git a/src/wx/drawing.h b/src/wx/drawing.h index 7c63ab010..f595b5de2 100644 --- a/src/wx/drawing.h +++ b/src/wx/drawing.h @@ -8,14 +8,9 @@ class BasicDrawingPanel : public DrawingPanel, public wxPanel { BasicDrawingPanel(wxWindow* parent, int _width, int _height); protected: - void PaintEv2(wxPaintEvent& ev) - { - PaintEv(ev); - } void DrawArea(wxWindowDC& dc); DECLARE_CLASS() - DECLARE_EVENT_TABLE() }; #ifndef NO_OGL @@ -27,10 +22,6 @@ class GLDrawingPanel : public DrawingPanel, public wxGLCanvas { virtual ~GLDrawingPanel(); protected: - void PaintEv2(wxPaintEvent& ev) - { - PaintEv(ev); - } void DrawArea(wxWindowDC& dc); #if wxCHECK_VERSION(2, 9, 0) wxGLContext* ctx; @@ -40,7 +31,6 @@ class GLDrawingPanel : public DrawingPanel, public wxGLCanvas { int texsize; DECLARE_CLASS() - DECLARE_EVENT_TABLE() }; #endif @@ -50,15 +40,10 @@ class DXDrawingPanel : public DrawingPanel, public wxPanel { DXDrawingPanel(wxWindow* parent, int _width, int _height); protected: - void PaintEv2(wxPaintEvent& ev) - { - PaintEv(ev); - } void DrawArea(wxWindowDC&); void DrawingPanelInit(); DECLARE_CLASS() - DECLARE_EVENT_TABLE() }; #endif @@ -71,15 +56,10 @@ class CairoDrawingPanel : public DrawingPanel, public wxPanel { ~CairoDrawingPanel(); protected: - void PaintEv2(wxPaintEvent& ev) - { - PaintEv(ev); - } void DrawArea(wxWindowDC&); cairo_surface_t* conv_surf; DECLARE_CLASS() - DECLARE_EVENT_TABLE() }; #endif diff --git a/src/wx/opts.cpp b/src/wx/opts.cpp index e47becf93..3dad7a739 100644 --- a/src/wx/opts.cpp +++ b/src/wx/opts.cpp @@ -293,7 +293,10 @@ opts_t::opts_t() if (max_threads < 0) max_threads = 2; - audio_buffers = 5; + // 10 fixes stuttering on mac with openal, as opposed to 5 + // also should be better for modern hardware in general + audio_buffers = 10; + sound_en = 0x30f; sound_vol = 100; sound_qual = 1; diff --git a/src/wx/panel.cpp b/src/wx/panel.cpp index f70c7d18a..4726ee175 100644 --- a/src/wx/panel.cpp +++ b/src/wx/panel.cpp @@ -1029,7 +1029,6 @@ void GameArea::OnIdle(wxIdleEvent& event) wxWindow* w = panel->GetWindow(); w->SetBackgroundStyle(wxBG_STYLE_CUSTOM); - w->Enable(false); // never give it the keyboard focus w->SetSize(wxSize(basic_width, basic_height)); if (maxScale) @@ -1045,6 +1044,13 @@ void GameArea::OnIdle(wxIdleEvent& event) // if user changed Display/Scale config, this needs to run AdjustMinSize(); AdjustSize(false); + + // set focus to panel + w->SetFocus(); + + // capture keyboard events + w->Connect(wxEVT_CHAR_HOOK, wxKeyEventHandler(GameArea::OnKeyDown), NULL, this); + w->Connect(wxEVT_KEY_UP, wxKeyEventHandler(GameArea::OnKeyUp), NULL, this); } if (!paused && (!pauseWhenInactive || wxGetApp().frame->HasFocus())) { @@ -1125,8 +1131,10 @@ static uint32_t bmask[NUM_KEYS] = { static wxJoyKeyBinding_v keys_pressed; -static void process_key_press(bool down, int key, int mod, int joy = 0) +static bool process_key_press(bool down, int key, int mod, int joy = 0) { + static bool in_game_key = false; + // check if key is already pressed int kpno; @@ -1137,14 +1145,14 @@ static void process_key_press(bool down, int key, int mod, int joy = 0) if (kpno < keys_pressed.size()) { // double press is noop if (down) - return; + return in_game_key; // otherwise forget it keys_pressed.erase(keys_pressed.begin() + kpno); } else { // double release is noop if (!down) - return; + return in_game_key; // otherwise remember it // c++0x @@ -1153,6 +1161,8 @@ static void process_key_press(bool down, int key, int mod, int joy = 0) keys_pressed.push_back(jb); } + bool matched_game_key = false; + // find all game keys this is bound to for (int i = 0; i < 4; i++) for (int j = 0; j < NUM_KEYS; j++) { @@ -1160,8 +1170,10 @@ static void process_key_press(bool down, int key, int mod, int joy = 0) for (int k = 0; k < b.size(); k++) if (b[k].key == key && b[k].mod == mod && b[k].joy == joy) { - if (down) + if (down) { joypress[i] |= bmask[j]; + matched_game_key = true; + } else { // only release if no others pressed int k2; @@ -1178,25 +1190,29 @@ static void process_key_press(bool down, int key, int mod, int joy = 0) break; } - if (k2 == b.size()) + if (k2 == b.size()) { joypress[i] &= ~bmask[j]; + matched_game_key = true; + } } break; } } + + in_game_key = matched_game_key; + + return in_game_key; } void GameArea::OnKeyDown(wxKeyEvent& ev) { - process_key_press(true, ev.GetKeyCode(), 0 /* ev.GetModifiers() */); - ev.Skip(); // process accelerators + ev.Skip(!process_key_press(true, ev.GetKeyCode(), 0 /* ev.GetModifiers() */)); } void GameArea::OnKeyUp(wxKeyEvent& ev) { - process_key_press(false, ev.GetKeyCode(), 0 /* ev.GetModifiers() */); - ev.Skip(); // process accelerators + ev.Skip(!process_key_press(false, ev.GetKeyCode(), 0 /* ev.GetModifiers() */)); } void GameArea::OnSDLJoy(wxSDLJoyEvent& ev) @@ -1378,6 +1394,11 @@ DrawingPanel::DrawingPanel(int _width, int _height) void DrawingPanel::DrawingPanelInit() { + wxWindow* w = dynamic_cast(this); + + // this is not 2.8 compatible, sorry + w->Bind(wxEVT_PAINT, &DrawingPanel::PaintEv, this); + did_init = true; } @@ -1894,13 +1915,9 @@ DrawingPanel::~DrawingPanel() IMPLEMENT_CLASS2(BasicDrawingPanel, DrawingPanel, wxPanel) -BEGIN_EVENT_TABLE(BasicDrawingPanel, wxPanel) -EVT_PAINT(BasicDrawingPanel::PaintEv2) -END_EVENT_TABLE() - BasicDrawingPanel::BasicDrawingPanel(wxWindow* parent, int _width, int _height) : wxPanel(parent, wxID_ANY, wxPoint(0, 0), parent->GetSize(), - wxFULL_REPAINT_ON_RESIZE) + wxFULL_REPAINT_ON_RESIZE | wxWANTS_CHARS) , DrawingPanel(_width, _height) { // wxImage is 24-bit RGB, so 24-bit is preferred. Filters require @@ -1980,11 +1997,6 @@ void BasicDrawingPanel::DrawArea(wxWindowDC& dc) IMPLEMENT_CLASS2(GLDrawingPanel, DrawingPanel, wxGLCanvas) -// this would be easier in 2.9 -BEGIN_EVENT_TABLE(GLDrawingPanel, wxGLCanvas) -EVT_PAINT(GLDrawingPanel::PaintEv2) -END_EVENT_TABLE() - // This is supposed to be the default, but DOUBLEBUFFER doesn't seem to be // turned on by default for wxGTK. static int glopts[] = { @@ -2001,7 +2013,7 @@ static int glopts[] = { GLDrawingPanel::GLDrawingPanel(wxWindow* parent, int _width, int _height) : glc(parent, wxID_ANY, glopts, wxPoint(0, 0), parent->GetSize(), - wxFULL_REPAINT_ON_RESIZE) + wxFULL_REPAINT_ON_RESIZE | wxWANTS_CHARS) , DrawingPanel(_width, _height) { #ifdef __WXMAC__ @@ -2166,13 +2178,9 @@ void GLDrawingPanel::DrawArea(wxWindowDC& dc) IMPLEMENT_CLASS(CairoDrawingPanel, DrawingPanel) -BEGIN_EVENT_TABLE(CairoDrawingPanel, wxPanel) -EVT_PAINT(CairoDrawingPanel::PaintEv2) -END_EVENT_TABLE() - CairoDrawingPanel::CairoDrawingPanel(wxWindow* parent, int _width, int _height) : wxPanel(parent, wxID_ANY, wxPoint(0, 0), parent->GetSize(), - wxFULL_REPAINT_ON_RESIZE) + wxFULL_REPAINT_ON_RESIZE | wxWANTS_CHARS) , DrawingPanel(_width, _height) { conv_surf = NULL; @@ -2295,13 +2303,9 @@ void CairoDrawingPanel::DrawArea(wxWindowDC& dc) IMPLEMENT_CLASS(DXDrawingPanel, DrawingPanel) -BEGIN_EVENT_TABLE(DXDrawingPanel, wxPanel) -EVT_PAINT(DXDrawingPanel::PaintEv2) -END_EVENT_TABLE() - DXDrawingPanel::DXDrawingPanel(wxWindow* parent, int _width, int _height) : wxPanel(parent, wxID_ANY, wxPoint(0, 0), parent->GetSize(), - wxFULL_REPAINT_ON_RESIZE) + wxFULL_REPAINT_ON_RESIZE | wxWANTS_CHARS) , DrawingPanel(_width, _height) { // FIXME: implement diff --git a/src/wx/wxvbam.cpp b/src/wx/wxvbam.cpp index 738d2aca3..6443b8799 100644 --- a/src/wx/wxvbam.cpp +++ b/src/wx/wxvbam.cpp @@ -71,13 +71,19 @@ static void get_config_path(wxPathList& path, bool exists = true) path.Add(s); \ } while (0) - vbamDebug("GetUserLocalDataDir(): %s", static_cast(stdp.GetUserLocalDataDir().utf8_str())); - vbamDebug("GetUserDataDir(): %s", static_cast(stdp.GetUserDataDir().utf8_str())); - vbamDebug("GetLocalizedResourcesDir(wxGetApp().locale.GetCanonicalName()): %s", static_cast(stdp.GetLocalizedResourcesDir(wxGetApp().locale.GetCanonicalName()).utf8_str())); - vbamDebug("GetResourcesDir(): %s", static_cast(stdp.GetResourcesDir().utf8_str())); - vbamDebug("GetDataDir(): %s", static_cast(stdp.GetDataDir().utf8_str())); - vbamDebug("GetLocalDataDir(): %s", static_cast(stdp.GetLocalDataDir().utf8_str())); - vbamDebug("GetPluginsDir(): %s", static_cast(stdp.GetPluginsDir().utf8_str())); + static bool debug_dumped = false; + + if (!debug_dumped) { + vbamDebug("GetUserLocalDataDir(): %s", static_cast(stdp.GetUserLocalDataDir().utf8_str())); + vbamDebug("GetUserDataDir(): %s", static_cast(stdp.GetUserDataDir().utf8_str())); + vbamDebug("GetLocalizedResourcesDir(wxGetApp().locale.GetCanonicalName()): %s", static_cast(stdp.GetLocalizedResourcesDir(wxGetApp().locale.GetCanonicalName()).utf8_str())); + vbamDebug("GetResourcesDir(): %s", static_cast(stdp.GetResourcesDir().utf8_str())); + vbamDebug("GetDataDir(): %s", static_cast(stdp.GetDataDir().utf8_str())); + vbamDebug("GetLocalDataDir(): %s", static_cast(stdp.GetLocalDataDir().utf8_str())); + vbamDebug("GetPluginsDir(): %s", static_cast(stdp.GetPluginsDir().utf8_str())); + + debug_dumped = true; + } // NOTE: this does not support XDG (freedesktop.org) paths add_path(GetUserLocalDataDir()); @@ -591,10 +597,16 @@ EVT_CONTEXT_MENU(MainFrame::OnMenu) EVT_ACTIVATE(MainFrame::OnActivate) // requires DragAcceptFiles(true); even then may not do anything EVT_DROP_FILES(MainFrame::OnDropFile) + // pause game if menu pops up +// +// this causes problems with keyboard game keys on mac, disable for now +#ifndef __WXMAC__ EVT_MENU_OPEN(MainFrame::MenuPopped) EVT_MENU_CLOSE(MainFrame::MenuPopped) EVT_MENU_HIGHLIGHT_ALL(MainFrame::MenuPopped) +#endif + END_EVENT_TABLE() void MainFrame::OnActivate(wxActivateEvent& event) diff --git a/src/wx/wxvbam.h b/src/wx/wxvbam.h index 40c2d1d95..50f96669b 100644 --- a/src/wx/wxvbam.h +++ b/src/wx/wxvbam.h @@ -630,10 +630,10 @@ class DrawingPanel : public wxObject, public HiDPIAware { void DrawArea(uint8_t** pixels); // using dynamic_cast<> to not force trivial reimplementation in concrete classes - // TODO: figure something out for PaintEv as well virtual wxWindow* GetWindow() { return dynamic_cast(this); } virtual void Delete() { (dynamic_cast(this))->Destroy(); } + void PaintEv(wxPaintEvent& ev); protected: virtual void DrawArea(wxWindowDC&) = 0; virtual void DrawOSD(wxWindowDC&); @@ -651,13 +651,6 @@ class DrawingPanel : public wxObject, public HiDPIAware { // largest buffer required is 32-bit * (max width + 1) * (max height + 2) uint8_t delta[257 * 4 * 226]; - // following can't work in 2.8 as intended - // inheriting from wxEvtHandler is required, but also breaks subclasses - // due to lack of virtual inheritance (2.9 drops wxEvtHandler req) - // so each child must have a paint event handler (not override of this, - // but it's not virtual anyway, so that won't happen) that calls this - void PaintEv(wxPaintEvent& ev); - DECLARE_ABSTRACT_CLASS() };