Merge branch 'rr1-maint'

Conflicts:
	include/core/rom.hpp
	src/core/rom.cpp
This commit is contained in:
Ilari Liusvaara 2012-05-20 13:35:55 +03:00
commit 591770ffa9
19 changed files with 333 additions and 13 deletions

View file

@ -13,5 +13,14 @@ void main_loop(struct loaded_rom& rom, struct moviefile& settings, bool load_has
std::vector<std::string> get_jukebox_names(); std::vector<std::string> get_jukebox_names();
void set_jukebox_names(const std::vector<std::string>& newj); void set_jukebox_names(const std::vector<std::string>& newj);
void update_movie_state(); void update_movie_state();
extern std::string msu1_base_path;
/**
* Signal that fast rewind operation is needed.
*
* Parameter ptr: If NULL, saves a state and calls lua_callback_do_unsafe_rewind() with quicksave, movie and NULL.
* If non-NULL, calls lua_callback_do_unsafe_rewind() with movie and this parameter, but without quicksave.
*/
void mainloop_signal_need_rewind(void* ptr);
#endif #endif

View file

@ -230,6 +230,15 @@ public:
* movie, reads all released. * movie, reads all released.
*/ */
controller_frame read_subframe(uint64_t frame, uint64_t subframe) throw(); controller_frame read_subframe(uint64_t frame, uint64_t subframe) throw();
/**
* Fast save.
*/
void fast_save(uint64_t& _frame, uint64_t& _ptr, uint64_t& _lagc, std::vector<uint32_t>& counters);
/**
* Fast load.
*/
void fast_load(uint64_t& _frame, uint64_t& _ptr, uint64_t& _lagc, std::vector<uint32_t>& counters);
private: private:
//TRUE if readonly mode is active. //TRUE if readonly mode is active.
bool readonly; bool readonly;

View file

@ -33,4 +33,14 @@ std::string translate_name_mprefix(std::string original, bool forio = false);
extern std::string last_save; extern std::string last_save;
extern movie_logic movb; extern movie_logic movb;
/**
* Restore the actual core state from quicksave. Only call in rewind callback.
*
* Parameter state: The state to restore.
* Parameter secs: The seconds counter.
* Parameter ssecs: The subsecond counter.
*/
void mainloop_restore_state(const std::vector<char>& state, uint64_t secs, uint64_t ssecs);
#endif #endif

View file

@ -176,7 +176,11 @@ struct loaded_rom
*/ */
std::vector<loaded_slot> markup_slots; std::vector<loaded_slot> markup_slots;
/** /**
* Patch the ROMs. * MSU-1 base.
*/
std::string msu1_base;
/**
* Patch the ROM.
* *
* parameter cmdline: The command line. * parameter cmdline: The command line.
* throws std::bad_alloc: Not enough memory. * throws std::bad_alloc: Not enough memory.
@ -222,7 +226,27 @@ std::map<std::string, std::vector<char>> load_sram_commandline(const std::vector
throw(std::bad_alloc, std::runtime_error); throw(std::bad_alloc, std::runtime_error);
/** /**
<<<<<<< HEAD
* Given commandline arguments, load a ROM. * Given commandline arguments, load a ROM.
=======
* Saves core state into buffer. WARNING: This takes emulated time.
*
* returns: The saved state.
* throws std::bad_alloc: Not enough memory.
*/
std::vector<char> save_core_state(bool nochecksum = false) throw(std::bad_alloc);
/**
* Loads core state from buffer.
*
* parameter buf: The buffer containing the state.
* throws std::runtime_error: Loading state failed.
*/
void load_core_state(const std::vector<char>& buf, bool nochecksum = false) throw(std::runtime_error);
/**
* Read index of ROMs and add ROMs found to content-searchable storage.
>>>>>>> rr1-maint
* *
* parameter cmdline: The command line. * parameter cmdline: The command line.
* returns: The loaded ROM set. * returns: The loaded ROM set.

View file

@ -89,8 +89,8 @@ struct sram_slot_structure* emucore_sram_slot(size_t index);
size_t emucore_vma_slots(); size_t emucore_vma_slots();
struct vma_structure* emucore_vma_slot(size_t index); struct vma_structure* emucore_vma_slot(size_t index);
void emucore_refresh_cart(); void emucore_refresh_cart();
std::vector<char> emucore_serialize(); std::vector<char> emucore_serialize(bool nochecksum = false);
void emucore_unserialize(const std::vector<char>& data); void emucore_unserialize(const std::vector<char>& data, bool nochecksum = false);
void emucore_load_rom(systype_info_structure* rtype, region_info_structure* region, void emucore_load_rom(systype_info_structure* rtype, region_info_structure* region,
const std::vector<std::vector<char>>& romslots, const std::vector<std::vector<char>>& markslots); const std::vector<std::vector<char>>& romslots, const std::vector<std::vector<char>>& markslots);
struct region_info_structure* emucore_current_region(); struct region_info_structure* emucore_current_region();

View file

@ -4,6 +4,7 @@
#include "core/controllerframe.hpp" #include "core/controllerframe.hpp"
#include "core/keymapper.hpp" #include "core/keymapper.hpp"
#include "core/render.hpp" #include "core/render.hpp"
#include "core/movie.hpp"
struct lua_State; struct lua_State;
@ -88,6 +89,7 @@ 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_snoop_input(uint32_t port, uint32_t controller, uint32_t index, short value) throw();
void lua_callback_quit() throw(); void lua_callback_quit() throw();
void lua_callback_keyhook(const std::string& key, const struct keygroup::parameters& p) throw(); void lua_callback_keyhook(const std::string& key, const struct keygroup::parameters& p) throw();
void lua_callback_do_unsafe_rewind(const std::vector<char>& save, uint64_t secs, uint64_t ssecs, movie& mov, void* u);
#define LUA_TIMED_HOOK_IDLE 0 #define LUA_TIMED_HOOK_IDLE 0
#define LUA_TIMED_HOOK_TIMER 1 #define LUA_TIMED_HOOK_TIMER 1

View file

@ -0,0 +1,15 @@
#ifndef _lua__unsaferewind__hpp__included__
#define _lua__unsaferewind__hpp__included__
struct lua_unsaferewind
{
std::vector<char> state;
uint64_t frame;
uint64_t lag;
uint64_t ptr;
uint64_t secs;
uint64_t ssecs;
std::vector<uint32_t> pollcounters;
};
#endif

View file

@ -2918,6 +2918,51 @@ Read specifed subframe in specified frame and return data as array (100
elements, numbered 0-99 currently). elements, numbered 0-99 currently).
\end_layout \end_layout
\begin_layout Subsubsection
movie.unsafe_rewind([UNSAFEREWIND state])
\end_layout
\begin_layout Standard
Start setting point for unsafe rewind or jump to point of unsafe rewind.
\end_layout
\begin_layout Itemize
If called without argument, causes emulator to start process of setting
unsafe rewind point.
When this has finished, callback on_set_rewind occurs, passing the rewind
state to lua script.
\end_layout
\begin_layout Itemize
If called with argument, causes emulator rewind to passed rewind point as
soon as possible.
Readwrite mode is implicitly activated.
\end_layout
\begin_layout Standard
The following warnings apply to unsafe rewinding:
\end_layout
\begin_layout Itemize
There are no safety checks against misuse (that's what
\begin_inset Quotes eld
\end_inset
unsafe
\begin_inset Quotes erd
\end_inset
comes from)!
\end_layout
\begin_layout Itemize
Only call rewind from timeline rewind point was set from.
\end_layout
\begin_layout Itemize
Only call rewind from after the rewind point was set.
\end_layout
\begin_layout Subsection \begin_layout Subsection
Table settings Table settings
\end_layout \end_layout
@ -3341,6 +3386,30 @@ Called when requested by set_idle_timeout() and the timeout has expired
(regardless if emulator is waiting). (regardless if emulator is waiting).
\end_layout \end_layout
\begin_layout Subsubsection
Callback: on_set_rewind(UNSAFEREWIND r)
\end_layout
\begin_layout Standard
Called when unsafe rewind object has been constructed.
\end_layout
\begin_layout Subsubsection
Callback: on_pre_rewind()
\end_layout
\begin_layout Standard
Called just before unsafe rewind is about to occur.
\end_layout
\begin_layout Subsubsection
Callback: on_post_rewind()
\end_layout
\begin_layout Standard
Called just after unsafe rewind has occured.
\end_layout
\begin_layout Section \begin_layout Section
Memory watch expression syntax Memory watch expression syntax
\end_layout \end_layout

View file

@ -1476,6 +1476,28 @@ Count number of subframes in specified frame (frame numbers are
Read specifed subframe in specified frame and return data as Read specifed subframe in specified frame and return data as
array (100 elements, numbered 0-99 currently). array (100 elements, numbered 0-99 currently).
8.6.7 movie.unsafe_rewind([UNSAFEREWIND state])
Start setting point for unsafe rewind or jump to point of unsafe
rewind.
• If called without argument, causes emulator to start process of
setting unsafe rewind point. When this has finished, callback
on_set_rewind occurs, passing the rewind state to lua script.
• If called with argument, causes emulator rewind to passed
rewind point as soon as possible. Readwrite mode is implicitly
activated.
The following warnings apply to unsafe rewinding:
• There are no safety checks against misuse (that's what “unsafe”
comes from)!
• Only call rewind from timeline rewind point was set from.
• Only call rewind from after the rewind point was set.
8.7 Table settings 8.7 Table settings
Routines for settings manipulation Routines for settings manipulation
@ -1712,6 +1734,18 @@ expired and emulator is waiting.
Called when requested by set_idle_timeout() and the timeout has Called when requested by set_idle_timeout() and the timeout has
expired (regardless if emulator is waiting). expired (regardless if emulator is waiting).
8.10.21 Callback: on_set_rewind(UNSAFEREWIND r)
Called when unsafe rewind object has been constructed.
8.10.22 Callback: on_pre_rewind()
Called just before unsafe rewind is about to occur.
8.10.23 Callback: on_post_rewind()
Called just after unsafe rewind has occured.
9 Memory watch expression syntax 9 Memory watch expression syntax
Memory watch expressions are in RPN (Reverse Polish Notation). At Memory watch expressions are in RPN (Reverse Polish Notation). At

View file

@ -80,6 +80,11 @@ namespace
//Delay reset. //Delay reset.
unsigned long long delayreset_cycles_run; unsigned long long delayreset_cycles_run;
unsigned long long delayreset_cycles_target; unsigned long long delayreset_cycles_target;
//Unsafe rewind.
bool do_unsafe_rewind = false;
void* unsafe_rewind_obj = NULL;
enum advance_mode old_mode;
bool delayreset_fn() bool delayreset_fn()
{ {
@ -97,6 +102,16 @@ namespace
path_setting firmwarepath_setting("firmwarepath"); path_setting firmwarepath_setting("firmwarepath");
void mainloop_signal_need_rewind(void* ptr)
{
if(ptr) {
old_mode = amode;
amode = ADVANCE_LOAD;
}
do_unsafe_rewind = true;
unsafe_rewind_obj = ptr;
}
controller_frame movie_logic::update_controls(bool subframe) throw(std::bad_alloc, std::runtime_error) controller_frame movie_logic::update_controls(bool subframe) throw(std::bad_alloc, std::runtime_error)
{ {
if(lua_requests_subframe_paint) if(lua_requests_subframe_paint)
@ -165,7 +180,6 @@ controller_frame movie_logic::update_controls(bool subframe) throw(std::bad_allo
namespace namespace
{ {
enum advance_mode old_mode;
//Do pending load (automatically unpauses). //Do pending load (automatically unpauses).
void mark_pending_load(const std::string& filename, int lmode) void mark_pending_load(const std::string& filename, int lmode)
@ -286,7 +300,7 @@ void update_movie_state()
uint64_t audio_irq_time; uint64_t audio_irq_time;
uint64_t controller_irq_time; uint64_t controller_irq_time;
uint64_t frame_irq_time; uint64_t frame_irq_time;
std::string msu1_base_path;
class my_interface : public SNES::Interface class my_interface : public SNES::Interface
{ {
@ -295,6 +309,23 @@ class my_interface : public SNES::Interface
const char* _hint = hint; const char* _hint = hint;
std::string _hint2 = _hint; std::string _hint2 = _hint;
std::string fwp = firmwarepath_setting; std::string fwp = firmwarepath_setting;
regex_results r;
std::string msubase = msu1_base_path;
if(regex_match(".*\\.sfc", msu1_base_path))
msubase = msu1_base_path.substr(0, msu1_base_path.length() - 4);
if(_hint2 == "msu1.rom" || _hint2 == ".msu") {
//MSU-1 main ROM.
std::string x = msubase + ".msu";
messages << "MSU main data file: " << x << std::endl;
return x.c_str();
}
if(r = regex("(track)?(-([0-9])+\\.pcm)", _hint2)) {
//MSU track.
std::string x = msubase + r[2];
messages << "MSU track " << r[3] << "': " << x << std::endl;
return x.c_str();
}
std::string finalpath = fwp + "/" + _hint2; std::string finalpath = fwp + "/" + _hint2;
return finalpath.c_str(); return finalpath.c_str();
} }
@ -736,6 +767,18 @@ namespace
//failing. //failing.
int handle_load() int handle_load()
{ {
if(do_unsafe_rewind && unsafe_rewind_obj) {
uint64_t t = get_utime();
std::vector<char> s;
lua_callback_do_unsafe_rewind(s, 0, 0, movb.get_movie(), unsafe_rewind_obj);
information_dispatch::do_mode_change(false);
do_unsafe_rewind = false;
our_movie.is_savestate = true;
location_special = SPECIAL_SAVEPOINT;
update_movie_state();
messages << "Rewind done in " << (get_utime() - t) << " usec." << std::endl;
return 1;
}
if(pending_load != "") { if(pending_load != "") {
system_corrupt = false; system_corrupt = false;
if(loadmode != LOAD_STATE_BEGINNING && !do_load_state(pending_load, loadmode)) { if(loadmode != LOAD_STATE_BEGINNING && !do_load_state(pending_load, loadmode)) {
@ -763,12 +806,21 @@ namespace
//If there are pending saves, perform them. //If there are pending saves, perform them.
void handle_saves() void handle_saves()
{ {
if(!queued_saves.empty()) { if(!queued_saves.empty() || (do_unsafe_rewind && !unsafe_rewind_obj)) {
stepping_into_save = true; stepping_into_save = true;
SNES::system.runtosave(); SNES::system.runtosave();
stepping_into_save = false; stepping_into_save = false;
for(auto i : queued_saves) for(auto i : queued_saves)
do_save_state(i); do_save_state(i);
if(do_unsafe_rewind && !unsafe_rewind_obj) {
uint64_t t = get_utime();
std::vector<char> s = emucore_serialize(true);
uint64_t secs = our_movie.rtc_second;
uint64_t ssecs = our_movie.rtc_subsecond;
lua_callback_do_unsafe_rewind(s, secs, ssecs, movb.get_movie(), NULL);
do_unsafe_rewind = false;
messages << "Rewind point set in " << (get_utime() - t) << " usec." << std::endl;
}
} }
queued_saves.clear(); queued_saves.clear();
} }

View file

@ -459,6 +459,25 @@ void movie::reset_state() throw()
clear_caches(); clear_caches();
} }
void movie::fast_save(uint64_t& _frame, uint64_t& _ptr, uint64_t& _lagc, std::vector<uint32_t>& _counters)
{
pollcounters.save_state(_counters);
_frame = current_frame;
_ptr = current_frame_first_subframe;
_lagc = lag_frames;
}
void movie::fast_load(uint64_t& _frame, uint64_t& _ptr, uint64_t& _lagc, std::vector<uint32_t>& _counters)
{
readonly = true;
current_frame = _frame;
current_frame_first_subframe = (_ptr <= movie_data.size()) ? _ptr : movie_data.size();
lag_frames = _lagc;
pollcounters.load_state(_counters);
readonly_mode(false);
}
movie_logic::movie_logic() throw() movie_logic::movie_logic() throw()
{ {
} }

View file

@ -291,6 +291,7 @@ void do_load_beginning() throw(std::bad_alloc, std::runtime_error)
redraw_framebuffer(screen_corrupt, true); redraw_framebuffer(screen_corrupt, true);
throw; throw;
} }
information_dispatch::do_mode_change(movb.get_movie().readonly_mode());
our_movie.is_savestate = false; our_movie.is_savestate = false;
our_movie.host_memory.clear(); our_movie.host_memory.clear();
messages << "Movie rewound to beginning." << std::endl; messages << "Movie rewound to beginning." << std::endl;
@ -469,3 +470,11 @@ bool do_load_state(const std::string& filename, int lmode)
} }
return true; return true;
} }
void mainloop_restore_state(const std::vector<char>& state, uint64_t secs, uint64_t ssecs)
{
rrdata::add_internal();
our_movie.rtc_second = secs;
our_movie.rtc_subsecond = ssecs;
emucore_unserialize(state, true);
}

View file

@ -1,6 +1,7 @@
#include "core/command.hpp" #include "core/command.hpp"
#include "core/dispatch.hpp" #include "core/dispatch.hpp"
#include "core/framerate.hpp" #include "core/framerate.hpp"
#include "core/mainloop.hpp"
#include "core/memorymanip.hpp" #include "core/memorymanip.hpp"
#include "core/misc.hpp" #include "core/misc.hpp"
#include "core/rom.hpp" #include "core/rom.hpp"
@ -210,6 +211,10 @@ loaded_rom::loaded_rom(const rom_files& files) throw(std::bad_alloc, std::runtim
markup_slots[i] = loaded_slot(files.markup_slots[i], files.base_file, *rtype->rom_slot(i), markup_slots[i] = loaded_slot(files.markup_slots[i], files.base_file, *rtype->rom_slot(i),
true); true);
orig_region = region = files.region; orig_region = region = files.region;
if(main_slots.size() > 1)
msu1_base = resolve_file_relative(files.main_slots[1], files.base_file);
else
msu1_base = resolve_file_relative(files.main_slots[0], files.base_file);
} }
void loaded_rom::load() throw(std::bad_alloc, std::runtime_error) void loaded_rom::load() throw(std::bad_alloc, std::runtime_error)
@ -234,6 +239,7 @@ void loaded_rom::load() throw(std::bad_alloc, std::runtime_error)
auto soundrate = emucore_get_audio_rate(); auto soundrate = emucore_get_audio_rate();
set_nominal_framerate(1.0 * framerate.first / framerate.second); set_nominal_framerate(1.0 * framerate.first / framerate.second);
information_dispatch::do_sound_rate(soundrate.first, soundrate.second); information_dispatch::do_sound_rate(soundrate.first, soundrate.second);
msu1_base_path = msu1_base;
refresh_cart_mappings(); refresh_cart_mappings();
} }

View file

@ -446,12 +446,14 @@ void emucore_refresh_cart()
delete i; delete i;
} }
std::vector<char> emucore_serialize() std::vector<char> emucore_serialize(bool nochecksum)
{ {
std::vector<char> ret; std::vector<char> ret;
serializer s = SNES::system.serialize(); serializer s = SNES::system.serialize();
ret.resize(s.size()); ret.resize(s.size());
memcpy(&ret[0], s.data(), s.size()); memcpy(&ret[0], s.data(), s.size());
if(nochecksum)
return ret;
size_t offset = ret.size(); size_t offset = ret.size();
unsigned char tmp[32]; unsigned char tmp[32];
sha256::hash(tmp, ret); sha256::hash(tmp, ret);
@ -460,8 +462,14 @@ std::vector<char> emucore_serialize()
return ret; return ret;
} }
void emucore_unserialize(const std::vector<char>& buf) void emucore_unserialize(const std::vector<char>& buf, bool nochecksum)
{ {
if(nochecksum) {
serializer s(reinterpret_cast<const uint8_t*>(&buf[0]), buf.size());
if(!SNES::system.unserialize(s))
throw std::runtime_error("SNES core rejected savestate");
return;
}
if(buf.size() < 32) if(buf.size() < 32)
throw std::runtime_error("Savestate corrupt"); throw std::runtime_error("Savestate corrupt");
unsigned char tmp[32]; unsigned char tmp[32];

View file

@ -27,6 +27,8 @@ void lua_callback_keyhook(const std::string& key, const struct keygroup::paramet
void init_lua() throw() {} void init_lua() throw() {}
void quit_lua() throw() {} void quit_lua() throw() {}
uint64_t lua_timed_hook(int timer) throw() { return 0x7EFFFFFFFFFFFFFFULL; } uint64_t lua_timed_hook(int timer) throw() { return 0x7EFFFFFFFFFFFFFFULL; }
void lua_callback_do_unsafe_rewind(const std::vector<char>& save, movie& mov, void* u) {}
bool lua_requests_repaint = false; bool lua_requests_repaint = false;
bool lua_requests_subframe_paint = false; bool lua_requests_subframe_paint = false;

View file

@ -2,8 +2,10 @@
#include "core/globalwrap.hpp" #include "core/globalwrap.hpp"
#include "lua/internal.hpp" #include "lua/internal.hpp"
#include "lua/lua.hpp" #include "lua/lua.hpp"
#include "lua/unsaferewind.hpp"
#include "core/mainloop.hpp" #include "core/mainloop.hpp"
#include "core/memorymanip.hpp" #include "core/memorymanip.hpp"
#include "core/moviedata.hpp"
#include "core/misc.hpp" #include "core/misc.hpp"
#include <map> #include <map>
@ -555,7 +557,38 @@ uint64_t lua_timed_hook(int timer) throw()
} }
} }
void lua_callback_do_unsafe_rewind(const std::vector<char>& save, uint64_t secs, uint64_t ssecs, movie& mov, void* u)
{
if(u) {
lua_unsaferewind* u2 = reinterpret_cast<lua_obj_pin<lua_unsaferewind>*>(u)->object();
//Load.
try {
if(callback_exists("on_pre_rewind"))
run_lua_cb(0);
mainloop_restore_state(u2->state, u2->secs, u2->ssecs);
mov.fast_load(u2->frame, u2->ptr, u2->lag, u2->pollcounters);
if(callback_exists("on_post_rewind"))
run_lua_cb(0);
} catch(...) {
return;
}
} else {
//Save
if(callback_exists("on_set_rewind")) {
lua_unsaferewind* u2 = lua_class<lua_unsaferewind>::create(L);
u2->state = save;
u2->secs = secs,
u2->ssecs = ssecs;
mov.fast_save(u2->frame, u2->ptr, u2->lag, u2->pollcounters);
run_lua_cb(1);
}
}
}
bool lua_requests_repaint = false; bool lua_requests_repaint = false;
bool lua_requests_subframe_paint = false; bool lua_requests_subframe_paint = false;
bool lua_supported = true; bool lua_supported = true;
DECLARE_LUACLASS(lua_unsaferewind, "UNSAFEREWIND");

View file

@ -1,6 +1,8 @@
#include "lua/internal.hpp" #include "lua/internal.hpp"
#include "lua/unsaferewind.hpp"
#include "core/movie.hpp" #include "core/movie.hpp"
#include "core/moviedata.hpp" #include "core/moviedata.hpp"
#include "core/mainloop.hpp"
namespace namespace
{ {
@ -68,4 +70,20 @@ namespace
lua_pushnumber(LS, our_movie.rtc_subsecond); lua_pushnumber(LS, our_movie.rtc_subsecond);
return 2; return 2;
}); });
function_ptr_luafun musv("movie.unsafe_rewind", [](lua_State* LS, const std::string& fname) -> int {
if(lua_isnoneornil(LS, 1)) {
//Start process to mark save.
mainloop_signal_need_rewind(NULL);
} else if(lua_class<lua_unsaferewind>::is(LS, 1)) {
//Load the save.
lua_obj_pin<lua_unsaferewind>* u = lua_class<lua_unsaferewind>::pin(LS, 1, fname.c_str());
mainloop_signal_need_rewind(u);
} else {
lua_pushstring(LS, "movie.unsafe_rewind: Expected nil or UNSAFEREWIND as 1st argument");
lua_error(LS);
return 0;
} }
});
}

View file

@ -473,7 +473,7 @@ void boot_emulator(loaded_rom& rom, moviefile& movie)
} }
wxwin_mainwindow::panel::panel(wxWindow* win) wxwin_mainwindow::panel::panel(wxWindow* win)
: wxPanel(win) : wxPanel(win, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS)
{ {
this->Connect(wxEVT_PAINT, wxPaintEventHandler(panel::on_paint), NULL, this); this->Connect(wxEVT_PAINT, wxPaintEventHandler(panel::on_paint), NULL, this);
this->Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler(panel::on_erase), NULL, this); this->Connect(wxEVT_ERASE_BACKGROUND, wxEraseEventHandler(panel::on_erase), NULL, this);

View file

@ -100,11 +100,11 @@ namespace
int horiz_padding = 60; int horiz_padding = 60;
wxdialog_pressbutton::wxdialog_pressbutton(wxWindow* parent, const std::string& title) wxdialog_pressbutton::wxdialog_pressbutton(wxWindow* parent, const std::string& title)
: wxDialog(parent, wxID_ANY, towxstring(title), wxDefaultPosition, wxSize(-1, -1)) : wxDialog(parent, wxID_ANY, towxstring(title))
{ {
wxStaticText* t; wxStaticText* t;
wxBoxSizer* s2 = new wxBoxSizer(wxVERTICAL); wxBoxSizer* s2 = new wxBoxSizer(wxVERTICAL);
wxPanel* p = new wxPanel(this, wxID_ANY); wxPanel* p = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, -1), wxWANTS_CHARS);
s2->Add(p, 1, wxGROW); s2->Add(p, 1, wxGROW);
lastkbdkey = -1; lastkbdkey = -1;
mouseflag = 0; mouseflag = 0;
@ -116,7 +116,8 @@ namespace
s->Add(0, 0); s->Add(0, 0);
s->Add(0, 0); s->Add(0, 0);
s->Add(0, 0); s->Add(0, 0);
s->Add(t = new wxStaticText(p, wxID_ANY, wxT("Press the key to assign")), 1, wxGROW); s->Add(t = new wxStaticText(p, wxID_ANY, wxT("Press the key to assign"), wxDefaultPosition,
wxSize(-1, -1), wxWANTS_CHARS), 1, wxGROW);
s->Add(0, 0); s->Add(0, 0);
s->Add(0, 0); s->Add(0, 0);
s->Add(0, 0); s->Add(0, 0);