775 lines
22 KiB
C++
775 lines
22 KiB
C++
#ifndef WX_WXVBAM_H
|
|
#define WX_WXVBAM_H
|
|
|
|
#include <list>
|
|
#include <stdexcept>
|
|
#include <typeinfo>
|
|
#include <iostream>
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
#include <wx/log.h>
|
|
#include <wx/propdlg.h>
|
|
#include <wx/datetime.h>
|
|
|
|
#include "wx/joyedit.h"
|
|
#include "wx/keyedit.h"
|
|
#include "wx/sdljoy.h"
|
|
#include "wx/wxmisc.h"
|
|
#include "wxhead.h"
|
|
#ifndef NO_FFMPEG
|
|
#include "../common/ffmpeg.h"
|
|
#endif
|
|
|
|
/* yeah, they aren't needed globally, but I'm too lazy to limit where needed */
|
|
#include "../System.h"
|
|
#include "../Util.h"
|
|
#include "../gb/gb.h"
|
|
#include "../gb/gbCheats.h"
|
|
#include "../gb/gbGlobals.h"
|
|
#include "../gb/gbSound.h"
|
|
#include "../gba/Cheats.h"
|
|
#include "../gba/GBALink.h"
|
|
#include "../gba/Globals.h"
|
|
#include "../gba/Sound.h"
|
|
|
|
// make wxLogDebug work on non-debug builds of Wx, and make it use the console
|
|
// on Windows
|
|
// (this works on 2.8 too!)
|
|
#if !defined(NDEBUG) && (!wxDEBUG_LEVEL || defined(__WXMSW__))
|
|
#ifdef __WXMSW__
|
|
#define VBAM_DEBUG_STREAM stdout
|
|
#else
|
|
#define VBAM_DEBUG_STREAM stderr
|
|
#endif
|
|
#undef wxLogDebug
|
|
#define wxLogDebug(...) \
|
|
do { \
|
|
fputs(wxString::Format(wxDateTime::UNow().Format(wxT("%X")) + wxT(": Debug: ") + __VA_ARGS__).utf8_str(), VBAM_DEBUG_STREAM); \
|
|
fputc('\n', VBAM_DEBUG_STREAM); \
|
|
} while(0)
|
|
#endif
|
|
|
|
template <typename T>
|
|
void CheckPointer(T pointer)
|
|
{
|
|
if (pointer == NULL) {
|
|
std::string errormessage = "Pointer of type \"";
|
|
errormessage += typeid(pointer).name();
|
|
errormessage += "\" was not correctly created.";
|
|
throw std::runtime_error(errormessage);
|
|
}
|
|
}
|
|
|
|
/// Helper functions to convert WX's crazy string types to std::string
|
|
|
|
inline std::string ToString(wxCharBuffer aString)
|
|
{
|
|
return std::string(aString);
|
|
}
|
|
|
|
inline std::string ToString(const wxChar* aString)
|
|
{
|
|
return std::string(wxString(aString).mb_str(wxConvUTF8));
|
|
}
|
|
|
|
class MainFrame;
|
|
|
|
class wxvbamApp : public wxApp {
|
|
public:
|
|
wxvbamApp()
|
|
: wxApp()
|
|
, pending_fullscreen(false)
|
|
{
|
|
}
|
|
virtual bool OnInit();
|
|
virtual void OnInitCmdLine(wxCmdLineParser&);
|
|
virtual bool OnCmdLineParsed(wxCmdLineParser&);
|
|
wxString GetConfigurationPath();
|
|
wxString GetAbsolutePath(wxString path);
|
|
// name of a file to load at earliest opportunity
|
|
wxString pending_load;
|
|
// list of options to set after config file loaded
|
|
wxArrayString pending_optset;
|
|
// set fullscreen mode after init
|
|
bool pending_fullscreen;
|
|
#if __WXMAC__
|
|
// I suppose making this work will require tweaking the bundle
|
|
void MacOpenFile(const wxString& f)
|
|
{
|
|
pending_load = f;
|
|
};
|
|
#endif
|
|
// without this, global accels don't always work
|
|
int FilterEvent(wxEvent& event);
|
|
wxAcceleratorEntry_v accels;
|
|
|
|
// the main configuration
|
|
wxFileConfig* cfg;
|
|
// vba-over.ini
|
|
wxFileConfig* overrides;
|
|
|
|
wxFileName rom_database;
|
|
wxFileName rom_database_scene;
|
|
wxFileName rom_database_nointro;
|
|
|
|
wxString data_path;
|
|
|
|
MainFrame* frame;
|
|
// use this to get ms since program lauch
|
|
wxStopWatch timer;
|
|
// append log messages to this for the log viewer
|
|
wxString log;
|
|
// there's no way to retrieve "current" locale, so this is public
|
|
wxLocale locale;
|
|
|
|
// Handle most exceptions
|
|
virtual bool OnExceptionInMainLoop()
|
|
{
|
|
try {
|
|
throw;
|
|
} catch (const std::exception& e) {
|
|
std::cerr << "AN ERROR HAS OCCURRED: " << e.what() << std::endl;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private:
|
|
wxPathList config_path;
|
|
char* home;
|
|
};
|
|
|
|
DECLARE_APP(wxvbamApp);
|
|
|
|
// menu event handlers are declared with these macros in mainwind.cpp
|
|
// and mainwind-handlers.h, mainwind-cmd.cpp, and mainwind-evt.cpp are
|
|
// auto-generated from them
|
|
#define EVT_HANDLER(n, x) void MainFrame::On##n(wxCommandEvent& WXUNUSED(event))
|
|
// some commands are masked under some conditions
|
|
#define EVT_HANDLER_MASK(n, x, m) \
|
|
void MainFrame::On##n(wxCommandEvent& WXUNUSED(event)) \
|
|
{ \
|
|
if (!(cmd_enable & (m))) \
|
|
return; \
|
|
Do##n(); \
|
|
} \
|
|
void MainFrame::Do##n()
|
|
|
|
// here are those conditions
|
|
enum { CMDEN_GB = (1 << 0), // GB ROM loaded
|
|
CMDEN_GBA = (1 << 1), // GBA ROM loaded
|
|
// the rest imply the above, unless:
|
|
// _ANY -> does not imply either
|
|
// _GBA -> only implies GBA
|
|
CMDEN_REWIND = (1 << 2), // rewind states available
|
|
CMDEN_SREC = (1 << 3), // sound recording in progress
|
|
CMDEN_NSREC = (1 << 4), // no sound recording
|
|
CMDEN_VREC = (1 << 5), // video recording
|
|
CMDEN_NVREC = (1 << 6), // no video recording
|
|
CMDEN_GREC = (1 << 7), // game recording
|
|
CMDEN_NGREC = (1 << 8), // no game recording
|
|
CMDEN_GPLAY = (1 << 9), // game playback
|
|
CMDEN_NGPLAY = (1 << 10), // no game playback
|
|
CMDEN_SAVST = (1 << 11), // any save states
|
|
CMDEN_GDB = (1 << 12), // gdb connected
|
|
CMDEN_NGDB_GBA = (1 << 13), // gdb not connected
|
|
CMDEN_NGDB_ANY = (1 << 14), // gdb not connected
|
|
CMDEN_NREC_ANY = (1 << 15), // not a/v recording
|
|
CMDEN_LINK_ANY = (1 << 16), // link enabled
|
|
|
|
CMDEN_NEVER = (1 << 31) // never (for NOOP)
|
|
};
|
|
#define ONLOAD_CMDEN (CMDEN_NSREC | CMDEN_NVREC | CMDEN_NGREC | CMDEN_NGPLAY)
|
|
#define UNLOAD_CMDEN_KEEP (CMDEN_NGDB_ANY | CMDEN_NREC_ANY | CMDEN_LINK_ANY)
|
|
|
|
struct checkable_mi_t {
|
|
int cmd;
|
|
wxMenuItem* mi;
|
|
bool* boolopt;
|
|
int *intopt, mask, val;
|
|
};
|
|
|
|
// wxArray is only for small types
|
|
typedef std::vector<checkable_mi_t> checkable_mi_array_t;
|
|
|
|
typedef std::list<wxDialog*> dialog_list_t;
|
|
|
|
class GameArea;
|
|
|
|
class LogDialog;
|
|
|
|
// true if pause should happen at next frame
|
|
extern bool pause_next;
|
|
|
|
class MainFrame : public wxFrame {
|
|
public:
|
|
MainFrame();
|
|
~MainFrame();
|
|
|
|
bool BindControls();
|
|
void MenuOptionIntMask(const char* menuName, int& field, int mask);
|
|
void MenuOptionIntRadioValue(const char* menuName, int& field, int mask);
|
|
void MenuOptionBool(const char* menuName, bool& field);
|
|
void GetMenuOptionInt(const char* menuName, int& field, int mask);
|
|
void GetMenuOptionBool(const char* menuName, bool& field);
|
|
void SetMenuOption(const char* menuName, int value);
|
|
|
|
void SetJoystick();
|
|
|
|
GameArea* GetPanel()
|
|
{
|
|
return panel;
|
|
}
|
|
|
|
wxString GetGamePath(wxString path);
|
|
|
|
// wxMSW pauses the game for menu popups and modal dialogs, but wxGTK
|
|
// does not. It's probably desirable to pause the game. To do this for
|
|
// dialogs, use this function instead of dlg->ShowModal()
|
|
int ShowModal(wxDialog* dlg);
|
|
// and here are the wrapper functions for use when ShowModal() isn't
|
|
// possible
|
|
void StartModal();
|
|
void StopModal();
|
|
// however, adding a handler for open/close menu to do the same is unsafe.
|
|
// there is no guarantee every show will be matched by a hide.
|
|
void MenuPopped(wxMenuEvent& evt);
|
|
|
|
// flags for enabling commands
|
|
int cmd_enable;
|
|
|
|
// adjust menus based on current cmd_enable
|
|
void enable_menus();
|
|
void EnableNetworkMenu();
|
|
|
|
// adjust menus based on available save game states
|
|
void update_state_ts(bool force = false);
|
|
|
|
// retrieve oldest/newest slot
|
|
// returns lowest-numbered slot on ties
|
|
int oldest_state_slot(); // or empty slot if available
|
|
int newest_state_slot(); // or 0 if none
|
|
|
|
// system-defined accelerators
|
|
wxAcceleratorEntry_v sys_accels;
|
|
// adjust recent menu with accelerators
|
|
void SetRecentAccels();
|
|
// merge sys accels with user-defined accels (user overrides sys)
|
|
wxAcceleratorEntry_v get_accels(wxAcceleratorEntry_v user_accels);
|
|
// update menu and global accelerator table with sys+user accel defs
|
|
// probably not the quickest way to add/remove individual accels
|
|
void set_global_accels();
|
|
|
|
// 2.8 has no HasFocus(), and FindFocus() doesn't work right
|
|
bool HasFocus()
|
|
{
|
|
return focused;
|
|
}
|
|
|
|
// Returns the link mode to set according to the options
|
|
LinkMode GetConfiguredLinkMode();
|
|
|
|
void IdentifyRom();
|
|
|
|
// Start GDB listener
|
|
void GDBBreak();
|
|
|
|
// The various viewer popups; these can be popped up as often as
|
|
// desired
|
|
void Disassemble();
|
|
void IOViewer();
|
|
void MapViewer();
|
|
void MemViewer();
|
|
void OAMViewer();
|
|
void PaletteViewer();
|
|
void TileViewer();
|
|
|
|
// since they will all have to be destroyed on game unload:
|
|
dialog_list_t popups;
|
|
|
|
// this won't actually be destroyed, but it needs to be tracked so only
|
|
// one is ever up and it needs to be pinged when new messages arrive
|
|
LogDialog* logdlg;
|
|
|
|
// the cheat search dialog isn't destroyed or tracked, but it needs
|
|
// to be cleared between games
|
|
void ResetCheatSearch();
|
|
|
|
// call this to update the viewers once a frame:
|
|
void UpdateViewers();
|
|
|
|
// Check for online updates to the emulator
|
|
bool CheckForUpdates();
|
|
|
|
virtual bool MenusOpened() { return menus_opened != 0; }
|
|
|
|
virtual void SetMenusOpened(bool state);
|
|
|
|
virtual bool DialogOpened() { return dialog_opened != 0; }
|
|
|
|
// required for building from xrc
|
|
DECLARE_DYNAMIC_CLASS(MainFrame);
|
|
// required for event handling
|
|
DECLARE_EVENT_TABLE();
|
|
|
|
bool IsPaused(bool incendental = false)
|
|
{
|
|
return (paused && !pause_next && !incendental) || menus_opened || dialog_opened;
|
|
}
|
|
|
|
private:
|
|
GameArea* panel;
|
|
|
|
// the various reasons the game might be paused
|
|
bool paused;
|
|
int menus_opened, dialog_opened;
|
|
|
|
bool autoLoadMostRecent;
|
|
// copy of top-level menu bar as a context menu
|
|
wxMenu* ctx_menu;
|
|
// load/save states menu items
|
|
wxMenuItem* loadst_mi[10];
|
|
wxMenuItem* savest_mi[10];
|
|
wxDateTime state_ts[10];
|
|
// checkable menu items
|
|
checkable_mi_array_t checkable_mi;
|
|
// recent menu item accels
|
|
wxMenu* recent;
|
|
wxAcceleratorEntry recent_accel[10];
|
|
// joystick reader
|
|
wxSDLJoy joy;
|
|
|
|
// helper function for adding menu to accel editor
|
|
void add_menu_accels(wxTreeCtrl* tc, wxTreeItemId& parent, wxMenu* menu);
|
|
|
|
// for detecting window focus
|
|
void OnActivate(wxActivateEvent&);
|
|
// quicker & more accurate than FindFocus() != NULL
|
|
bool focused;
|
|
// may work, may not... if so, load dropped file
|
|
void OnDropFile(wxDropFilesEvent&);
|
|
// pop up menu in fullscreen mode
|
|
void OnMenu(wxContextMenuEvent&);
|
|
// Load a named wxDialog from the XRC file
|
|
wxDialog* LoadXRCDialog(const char* name);
|
|
// Load a named wxDialog from the XRC file
|
|
wxDialog* LoadXRCropertySheetDialog(const char* name);
|
|
|
|
void DownloadFile(wxString host, wxString url);
|
|
void UpdateFile(wxString host, wxString url);
|
|
wxString CheckForUpdates(wxString host, wxString url);
|
|
|
|
#include "cmdhandlers.h"
|
|
};
|
|
|
|
// helper class to add HiDPI awareness (mostly for Mac OS X)
|
|
class HiDPIAware {
|
|
public:
|
|
HiDPIAware() { hidpi_scale_factor = 0; }
|
|
virtual double HiDPIScaleFactor();
|
|
virtual void RequestHighResolutionOpenGLSurface();
|
|
virtual void GetRealPixelClientSize(int* x, int* y);
|
|
virtual wxWindow* GetWindow() = 0;
|
|
private:
|
|
double hidpi_scale_factor;
|
|
};
|
|
|
|
// a helper class to avoid forgetting StopModal()
|
|
class ModalPause {
|
|
public:
|
|
ModalPause()
|
|
{
|
|
wxGetApp().frame->StartModal();
|
|
}
|
|
~ModalPause()
|
|
{
|
|
wxGetApp().frame->StopModal();
|
|
}
|
|
};
|
|
|
|
enum showspeed {
|
|
// this order must match order of option enum and selector widget
|
|
SS_NONE,
|
|
SS_PERCENT,
|
|
SS_DETAILED
|
|
};
|
|
|
|
enum filtfunc {
|
|
// this order must match order of option enum and selector widget
|
|
FF_NONE,
|
|
FF_2XSAI,
|
|
FF_SUPER2XSAI,
|
|
FF_SUPEREAGLE,
|
|
FF_PIXELATE,
|
|
FF_ADVMAME,
|
|
FF_BILINEAR,
|
|
FF_BILINEARPLUS,
|
|
FF_SCANLINES,
|
|
FF_TV,
|
|
FF_HQ2X,
|
|
FF_LQ2X,
|
|
FF_SIMPLE2X,
|
|
FF_SIMPLE3X,
|
|
FF_HQ3X,
|
|
FF_SIMPLE4X,
|
|
FF_HQ4X,
|
|
FF_XBRZ2X,
|
|
FF_XBRZ3X,
|
|
FF_XBRZ4X,
|
|
FF_XBRZ5X,
|
|
FF_XBRZ6X,
|
|
FF_PLUGIN // plugin must always be last
|
|
};
|
|
#define builtin_ff_scale(x) \
|
|
((x == FF_XBRZ6X) ? 6 : (x == FF_XBRZ5X) \
|
|
? 5 \
|
|
: (x == FF_XBRZ4X || x == FF_HQ4X || x == FF_SIMPLE4X) \
|
|
? 4 \
|
|
: (x == FF_XBRZ3X || x == FF_HQ3X || x == FF_SIMPLE3X) \
|
|
? 3 \
|
|
: x == FF_PLUGIN ? 0 : x == FF_NONE ? 1 : 2)
|
|
|
|
enum ifbfunc {
|
|
// this order must match order of option enum and selector widget
|
|
IFB_NONE,
|
|
IFB_SMART,
|
|
IFB_MOTION_BLUR
|
|
};
|
|
|
|
// make sure and keep this in sync with opts.cpp!
|
|
enum renderer {
|
|
RND_SIMPLE,
|
|
RND_OPENGL,
|
|
RND_CAIRO,
|
|
RND_DIRECT3D,
|
|
RND_QUARTZ2D,
|
|
};
|
|
|
|
// likewise
|
|
enum audioapi { AUD_SDL,
|
|
AUD_OPENAL,
|
|
AUD_DIRECTSOUND,
|
|
AUD_XAUDIO2 };
|
|
|
|
// an unfortunate legacy default; should have a non-digit preceding %d
|
|
// the only reason to keep it is that user can set slotdir to old dir
|
|
// otoh, we already make some name changes (double ext strip), and
|
|
// rename is not that hard (esp. under UNIX), so I'm going ahead with a new
|
|
// name.
|
|
//#define SAVESLOT_FMT wxT("%s%d.sgm")
|
|
#define SAVESLOT_FMT wxT("%s-%02d.sgm")
|
|
|
|
// display time, in ms
|
|
#define OSD_TIME 3000
|
|
|
|
class DrawingPanelBase;
|
|
|
|
class GameArea : public wxPanel, public HiDPIAware {
|
|
public:
|
|
GameArea();
|
|
virtual ~GameArea();
|
|
|
|
virtual void SetMainFrame(MainFrame* parent) { main_frame = parent; }
|
|
|
|
// set to game title + link info
|
|
void SetFrameTitle();
|
|
|
|
void LoadGame(const wxString& name);
|
|
void UnloadGame(bool destruct = false);
|
|
|
|
IMAGE_TYPE game_type()
|
|
{
|
|
return loaded;
|
|
}
|
|
uint32_t game_size()
|
|
{
|
|
return rom_size;
|
|
}
|
|
wxString game_dir()
|
|
{
|
|
return loaded_game.GetPath();
|
|
}
|
|
wxString game_name()
|
|
{
|
|
return loaded_game.GetFullName();
|
|
}
|
|
wxString bat_dir()
|
|
{
|
|
return batdir;
|
|
}
|
|
wxString state_dir()
|
|
{
|
|
return statedir;
|
|
}
|
|
void recompute_dirs();
|
|
|
|
bool LoadState();
|
|
bool LoadState(int slot);
|
|
bool LoadState(const wxFileName& fname);
|
|
|
|
bool SaveState();
|
|
bool SaveState(int slot);
|
|
bool SaveState(const wxFileName& fname);
|
|
|
|
// save to default location
|
|
void SaveBattery(bool quiet = false);
|
|
|
|
// true if file at default location may not match memory
|
|
bool cheats_dirty;
|
|
|
|
static const int GBWidth = 160, GBHeight = 144, SGBWidth = 256, SGBHeight = 224,
|
|
GBAWidth = 240, GBAHeight = 160;
|
|
void AddBorder();
|
|
void DelBorder();
|
|
// Delete() & set to NULL to force reinit
|
|
DrawingPanelBase* panel;
|
|
struct EmulatedSystem* emusys;
|
|
|
|
// pause game or signal a long operation, similar to pausing
|
|
void Pause();
|
|
void Resume();
|
|
|
|
// true if paused since last reset of flag
|
|
bool was_paused;
|
|
|
|
// osdstat is always displayed at top-left of screen
|
|
wxString osdstat;
|
|
|
|
// osdtext is displayed for 3 seconds after osdtime, and then cleared
|
|
wxString osdtext;
|
|
uint32_t osdtime;
|
|
|
|
// Rewind: count down to 0 and rewind
|
|
uint32_t rewind_time;
|
|
// Rewind: flag to OnIdle to do a rewind
|
|
bool do_rewind;
|
|
// Rewind: rewind states
|
|
char* rewind_mem; // should be uint8_t, really
|
|
int num_rewind_states;
|
|
int next_rewind_state;
|
|
|
|
// Loaded rom information
|
|
IMAGE_TYPE loaded;
|
|
wxFileName loaded_game;
|
|
uint32_t rom_crc32;
|
|
wxString rom_name;
|
|
wxString rom_scene_rls;
|
|
wxString rom_scene_rls_name;
|
|
uint32_t rom_size;
|
|
|
|
// FIXME: size this properly
|
|
#define NUM_REWINDS 8
|
|
#define REWIND_SIZE 1024 * 512 * NUM_REWINDS
|
|
// FIXME: make this a config option
|
|
|
|
void ShowFullScreen(bool full);
|
|
bool IsFullScreen()
|
|
{
|
|
return fullscreen;
|
|
}
|
|
// set size of frame & panel to scaled screen size
|
|
void AdjustSize(bool force);
|
|
#ifndef NO_FFMPEG
|
|
void StartSoundRecording(const wxString& fname);
|
|
void StopSoundRecording();
|
|
void StartVidRecording(const wxString& fname);
|
|
void StopVidRecording();
|
|
void AddFrame(const uint8_t* data); // video
|
|
void AddFrame(const uint16_t* data, int length); // audio
|
|
bool IsRecording()
|
|
{
|
|
return snd_rec.IsRecording() || vid_rec.IsRecording();
|
|
}
|
|
#endif
|
|
void StartGameRecording(const wxString& fname);
|
|
void StopGameRecording();
|
|
void StartGamePlayback(const wxString& fname);
|
|
void StopGamePlayback();
|
|
|
|
virtual wxWindow* GetWindow() { return this; }
|
|
|
|
protected:
|
|
MainFrame* main_frame;
|
|
|
|
// set minsize of frame & panel to unscaled screen size
|
|
void LowerMinSize();
|
|
// set minsize of frame & panel to scaled screen size
|
|
void AdjustMinSize();
|
|
|
|
wxString batdir, statedir;
|
|
|
|
int basic_width, basic_height;
|
|
bool fullscreen;
|
|
|
|
bool paused;
|
|
void OnIdle(wxIdleEvent&);
|
|
void OnKeyDown(wxKeyEvent& ev);
|
|
void OnKeyUp(wxKeyEvent& ev);
|
|
void OnSDLJoy(wxSDLJoyEvent& ev);
|
|
void PaintEv(wxPaintEvent& ev);
|
|
void EraseBackground(wxEraseEvent& ev);
|
|
void OnSize(wxSizeEvent& ev);
|
|
|
|
#ifndef NO_FFMPEG
|
|
MediaRecorder snd_rec, vid_rec;
|
|
#endif
|
|
|
|
public:
|
|
void ShowPointer();
|
|
void HidePointer();
|
|
|
|
protected:
|
|
void MouseEvent(wxMouseEvent&)
|
|
{
|
|
ShowPointer();
|
|
}
|
|
bool pointer_blanked;
|
|
uint32_t mouse_active_time;
|
|
|
|
DECLARE_DYNAMIC_CLASS(GameArea)
|
|
DECLARE_EVENT_TABLE()
|
|
};
|
|
|
|
// wxString version of OSD message
|
|
void systemScreenMessage(const wxString& msg);
|
|
|
|
// List of all commands with their descriptions
|
|
// sorted by cmd field for binary searching
|
|
// filled in by copy-events.cmake
|
|
extern struct cmditem {
|
|
const wxChar *cmd, *name;
|
|
int cmd_id;
|
|
int mask_flags; // if non-0, one of the flags must be turned on in win
|
|
// to enable this command
|
|
wxMenuItem* mi; // the menu item to invoke command, if present
|
|
} cmdtab[];
|
|
extern const int ncmds;
|
|
// for binary search
|
|
extern bool cmditem_lt(const struct cmditem& cmd1, const struct cmditem& cmd2);
|
|
|
|
#include "rpi.h"
|
|
#include <wx/dynlib.h>
|
|
|
|
class FilterThread;
|
|
|
|
class DrawingPanelBase : public HiDPIAware {
|
|
public:
|
|
DrawingPanelBase(int _width, int _height);
|
|
~DrawingPanelBase();
|
|
void DrawArea(uint8_t** pixels);
|
|
|
|
virtual void PaintEv(wxPaintEvent& ev);
|
|
virtual void EraseBackground(wxEraseEvent& ev);
|
|
virtual void OnSize(wxSizeEvent& ev);
|
|
wxWindow* GetWindow() { return dynamic_cast<wxWindow*>(this); }
|
|
virtual bool Destroy() { return GetWindow()->Destroy(); }
|
|
protected:
|
|
virtual void DrawArea(wxWindowDC&) = 0;
|
|
virtual void DrawOSD(wxWindowDC&);
|
|
int width, height;
|
|
double scale;
|
|
virtual void DrawingPanelInit();
|
|
bool did_init;
|
|
uint8_t* todraw;
|
|
uint8_t *pixbuf1, *pixbuf2;
|
|
FilterThread* threads;
|
|
int nthreads;
|
|
wxSemaphore filt_done;
|
|
wxDynamicLibrary filt_plugin;
|
|
const RENDER_PLUGIN_INFO* rpi; // also flag indicating plugin loaded
|
|
// largest buffer required is 32-bit * (max width + 1) * (max height + 2)
|
|
uint8_t delta[257 * 4 * 226];
|
|
};
|
|
|
|
// base class with a wxPanel when a subclass (such as wxGLCanvas) is not being used
|
|
class DrawingPanel : public DrawingPanelBase, public wxPanel {
|
|
public:
|
|
DrawingPanel(wxWindow* parent, int _width, int _height);
|
|
};
|
|
|
|
class LogDialog : public wxDialog {
|
|
public:
|
|
LogDialog();
|
|
void Update();
|
|
|
|
private:
|
|
wxTextCtrl* log;
|
|
void Save(wxCommandEvent& ev);
|
|
void Clear(wxCommandEvent& ev);
|
|
|
|
DECLARE_EVENT_TABLE()
|
|
};
|
|
|
|
#include "opts.h"
|
|
|
|
class SoundDriver;
|
|
extern SoundDriver* newOpenAL();
|
|
// I should add this to SoundDriver, but wxArrayString is wx-specific
|
|
// I suppose I could make subclass wxSoundDriver. maybe later.
|
|
extern bool GetOALDevices(wxArrayString& names, wxArrayString& ids);
|
|
#ifdef __WXMSW__
|
|
extern SoundDriver* newDirectSound();
|
|
extern bool GetDSDevices(wxArrayString& names, wxArrayString& ids);
|
|
extern SoundDriver* newXAudio2_Output();
|
|
extern bool GetXA2Devices(wxArrayString& names, wxArrayString& ids);
|
|
#endif
|
|
|
|
extern bool debugger;
|
|
extern void (*dbgMain)();
|
|
extern void (*dbgSignal)(int, int);
|
|
extern void (*dbgOutput)(const char*, uint32_t);
|
|
extern void remoteStubMain();
|
|
extern void remoteCleanUp();
|
|
extern void remoteStubSignal(int, int);
|
|
extern void remoteOutput(const char*, uint32_t);
|
|
|
|
extern bool debugOpenPty();
|
|
extern const wxString& debugGetSlavePty();
|
|
extern bool debugWaitPty();
|
|
extern bool debugStartListen(int port);
|
|
extern bool debugWaitSocket();
|
|
|
|
// perhaps these functions should not be called systemXXX
|
|
// perhaps they should move to panel.cpp/GameArea
|
|
// but they must integrate with systemReadJoypad
|
|
void systemStartGameRecording(const wxString& fname);
|
|
void systemStopGameRecording();
|
|
void systemStartGamePlayback(const wxString& fname);
|
|
void systemStopGamePlayback();
|
|
|
|
// true if turbo mode (like pressing turbo button constantly)
|
|
extern bool turbo;
|
|
|
|
// mask of key press flags; see below
|
|
extern int joypress[4], autofire;
|
|
|
|
// FIXME: these defines should be global to project and used instead of raw numbers
|
|
#define KEYM_A (1 << 0)
|
|
#define KEYM_B (1 << 1)
|
|
#define KEYM_SELECT (1 << 2)
|
|
#define KEYM_START (1 << 3)
|
|
#define KEYM_RIGHT (1 << 4)
|
|
#define KEYM_LEFT (1 << 5)
|
|
#define KEYM_UP (1 << 6)
|
|
#define KEYM_DOWN (1 << 7)
|
|
#define KEYM_R (1 << 8)
|
|
#define KEYM_L (1 << 9)
|
|
#define KEYM_SPEED (1 << 10)
|
|
#define KEYM_CAPTURE (1 << 11)
|
|
#define KEYM_GS (1 << 12)
|
|
|
|
// actually, the wx port adds the following, which could be local:
|
|
#define REALKEY_MASK ((1 << 13) - 1)
|
|
|
|
#define KEYM_AUTO_A (1 << 13)
|
|
#define KEYM_AUTO_B (1 << 14)
|
|
#define KEYM_MOTION_UP (1 << 15)
|
|
#define KEYM_MOTION_DOWN (1 << 16)
|
|
#define KEYM_MOTION_LEFT (1 << 17)
|
|
#define KEYM_MOTION_RIGHT (1 << 18)
|
|
#define KEYM_MOTION_IN (1 << 19)
|
|
#define KEYM_MOTION_OUT (1 << 20)
|
|
|
|
#include "filters.h"
|
|
|
|
#endif /* WX_WXVBAM_H */
|