Wxwidgets graphics plugin
As opposed to SDL graphics plugin, this has full GUI.
This commit is contained in:
parent
7b3fc13b22
commit
b497bd7ed6
33 changed files with 4184 additions and 50 deletions
10
Makefile
10
Makefile
|
@ -104,8 +104,16 @@ endif
|
|||
platform/SDL/%.$(OBJECT_SUFFIX): platform/SDL/%.cpp
|
||||
$(REALCC) -I. -Igeneric -g -std=gnu++0x -I$(BSNES_PATH) -c -o $@ $< $(CFLAGS) $(PLATFORM_CFLAGS)
|
||||
else
|
||||
ifeq ($(GRAPHICS), WXWIDGETS)
|
||||
PLATFORM_OBJECTS += platform/wxwidgets/main-wxwidgets.$(OBJECT_SUFFIX) $(patsubst %.cpp,%.$(OBJECT_SUFFIX),$(wildcard platform/wxwidgets/src/*.cpp))
|
||||
PLATFORM_CFLAGS += $(shell $(CROSS_PREFIX)wx-config --cxxflags) $(shell $(CROSS_PREFIX)pkg-config libswscale --cflags)
|
||||
PLATFORM_LDFLAGS += $(shell $(CROSS_PREFIX)wx-config --libs) $(shell $(CROSS_PREFIX)pkg-config libswscale --libs)
|
||||
platform/wxwidgets/%.$(OBJECT_SUFFIX): platform/wxwidgets/%.cpp
|
||||
$(REALCC) -I. -Igeneric -g -std=gnu++0x -I$(BSNES_PATH) -c -o $@ $< $(CFLAGS) $(PLATFORM_CFLAGS)
|
||||
else
|
||||
$(error "Unsupported graphics type")
|
||||
endif
|
||||
endif
|
||||
|
||||
.PRECIOUS: %.$(EXECUTABLE_SUFFIX) %.$(OBJECT_SUFFIX)
|
||||
|
||||
|
@ -129,4 +137,4 @@ fonts/parsehexfont.$(EXECUTABLE_SUFFIX): fonts/parsehexfont.cpp
|
|||
$(HOSTCC) -std=gnu++0x $(HOSTCCFLAGS) -o $@ $^
|
||||
|
||||
clean:
|
||||
rm -f $(PROGRAMS) $(patsubst %.$(EXECUTABLE_SUFFIX),%.$(OBJECT_SUFFIX),$(PROGRAMS)) platform/*/*.$(OBJECT_SUFFIX) avidump/*.$(OBJECT_SUFFIX) generic/*.$(OBJECT_SUFFIX) lua/*.$(OBJECT_SUFFIX) fonts/font.o fonts/font.cpp
|
||||
rm -f $(PROGRAMS) $(patsubst %.$(EXECUTABLE_SUFFIX),%.$(OBJECT_SUFFIX),$(PROGRAMS)) platform/*/*.$(OBJECT_SUFFIX) platform/*/src/*.$(OBJECT_SUFFIX) avidump/*.$(OBJECT_SUFFIX) generic/*.$(OBJECT_SUFFIX) lua/*.$(OBJECT_SUFFIX) fonts/font.o fonts/font.cpp
|
||||
|
|
141
generic/coroutine.cpp
Normal file
141
generic/coroutine.cpp
Normal file
|
@ -0,0 +1,141 @@
|
|||
#include "coroutine.hpp"
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
namespace
|
||||
{
|
||||
#if defined(__amd64__)
|
||||
void trampoline_fn(void (*fn)(void* arg), void* arg) __attribute__((sysv_abi));
|
||||
#else
|
||||
#if defined(__i386__)
|
||||
void trampoline_fn(void (*fn)(void* arg), void* arg) __attribute__((stdcall));
|
||||
#else
|
||||
#error "This CPU is not supported"
|
||||
#endif
|
||||
#endif
|
||||
void trampoline_fn(void (*fn)(void* arg), void* arg)
|
||||
{
|
||||
fn(arg);
|
||||
coroutine::cexit();
|
||||
}
|
||||
|
||||
#ifdef __amd64__
|
||||
bool stacks_grow_down = true;
|
||||
void switch_stacks(void (*fn)(void* arg), void* arg, void* new_esp)
|
||||
{
|
||||
__asm__ __volatile__("movq %%rax,%%rsp; call *%%rdx" :: "D"(fn), "S"(arg), "a"(new_esp), "d"(trampoline_fn));
|
||||
}
|
||||
#else
|
||||
#ifdef __i386__
|
||||
bool stacks_grow_down = true;
|
||||
void switch_stacks(void (*fn)(void* arg), void* arg, void* new_esp)
|
||||
{
|
||||
__asm__ __volatile__("movl %%eax,%%esp; pushl %%esi; push %%edi ; call *%%edx" :: "D"(fn), "S"(arg),
|
||||
"a"(new_esp), "d"(trampoline_fn));
|
||||
}
|
||||
#else
|
||||
#error "This CPU is not supported"
|
||||
#endif
|
||||
#endif
|
||||
jmp_buf main_saved_env;
|
||||
coroutine* executing_coroutine = NULL;
|
||||
}
|
||||
|
||||
coroutine::coroutine(void (*fn)(void* arg), void* arg, size_t stacksize)
|
||||
{
|
||||
dead = false;
|
||||
if(executing_coroutine) {
|
||||
std::cerr << "FATAL: Coroutine create only allowed from main coroutine!" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
executing_coroutine = this;
|
||||
if(setjmp(main_saved_env)) {
|
||||
executing_coroutine = NULL;
|
||||
return;
|
||||
}
|
||||
stackblock = new unsigned char[stacksize];
|
||||
unsigned char* esp = stackblock;
|
||||
if(stacks_grow_down)
|
||||
esp = esp + stacksize;
|
||||
switch_stacks(fn, arg, esp);
|
||||
}
|
||||
|
||||
coroutine::~coroutine() throw()
|
||||
{
|
||||
if(!dead) {
|
||||
std::cerr << "FATAL: Trying to delete a live coroutine!" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
delete[] stackblock;
|
||||
}
|
||||
|
||||
void coroutine::resume()
|
||||
{
|
||||
if(executing_coroutine) {
|
||||
std::cerr << "FATAL: Coroutine resume only allowed from main coroutine!" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
if(dead)
|
||||
return;
|
||||
executing_coroutine = this;
|
||||
if(setjmp(main_saved_env)) {
|
||||
executing_coroutine = NULL;
|
||||
return;
|
||||
}
|
||||
longjmp(saved_env, 1);
|
||||
}
|
||||
|
||||
void coroutine::yield()
|
||||
{
|
||||
if(!executing_coroutine) {
|
||||
std::cerr << "FATAL: Coroutine yield not allowed from main coroutine!" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
if(setjmp(executing_coroutine->saved_env))
|
||||
return;
|
||||
longjmp(main_saved_env, 1);
|
||||
}
|
||||
|
||||
bool coroutine::is_dead()
|
||||
{
|
||||
return dead;
|
||||
}
|
||||
|
||||
void coroutine::cexit()
|
||||
{
|
||||
if(!executing_coroutine) {
|
||||
std::cerr << "FATAL: Main coroutine can't exit!" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
executing_coroutine->dead = true;
|
||||
yield();
|
||||
}
|
||||
|
||||
#ifdef TEST_COROUTINES
|
||||
|
||||
void fn(void* arg)
|
||||
{
|
||||
std::cout << "Print #1 from coroutine (" << arg << ")" << std::endl;
|
||||
coroutine::yield();
|
||||
std::cout << "Print #2 from coroutine (" << arg << ")" << std::endl;
|
||||
coroutine::yield();
|
||||
std::cout << "Print #3 from coroutine (" << arg << ")" << std::endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int x;
|
||||
coroutine c(fn, &x, 8 * 1024 * 1024);
|
||||
std::cout << "Back to main thread" << std::endl;
|
||||
std::cout << "Coroutine dead flag is " << c.is_dead() << std::endl;
|
||||
c.resume();
|
||||
std::cout << "Back to main thread" << std::endl;
|
||||
std::cout << "Coroutine dead flag is " << c.is_dead() << std::endl;
|
||||
c.resume();
|
||||
std::cout << "Back to main thread" << std::endl;
|
||||
std::cout << "Coroutine dead flag is " << c.is_dead() << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
59
generic/coroutine.hpp
Normal file
59
generic/coroutine.hpp
Normal file
|
@ -0,0 +1,59 @@
|
|||
#ifndef _coroutine__hpp__included__
|
||||
#define _coroutine__hpp__included__
|
||||
|
||||
#include <cstdlib>
|
||||
#include <csetjmp>
|
||||
|
||||
/**
|
||||
* A coroutine.
|
||||
*/
|
||||
class coroutine
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Create a new coroutine with specified starting function and stack size. The coroutine created will run until it
|
||||
* yields for the first time.
|
||||
*
|
||||
* This can only be called from outside any coroutine.
|
||||
*
|
||||
* parameter fn: The function to call.
|
||||
* parameter arg: Argument to pass to the function.
|
||||
* parameter stacksize: Size of stack to allocate for function.
|
||||
* throws std::bad:alloc: Not enough memory.
|
||||
*/
|
||||
coroutine(void (*fn)(void* arg), void* arg, size_t stacksize);
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~coroutine() throw();
|
||||
/**
|
||||
* Resume yielded coroutine.
|
||||
*
|
||||
* This can only be called from outside any coroutine.
|
||||
*/
|
||||
void resume();
|
||||
/**
|
||||
* Yield execution, causing coroutine::resume() or coroutine::coroutine() that called this coroutine to return.
|
||||
*
|
||||
* This can only be called from coroutine.
|
||||
*/
|
||||
static void yield();
|
||||
|
||||
/**
|
||||
* Is the coroutine dead (has returned?)
|
||||
*/
|
||||
bool is_dead();
|
||||
|
||||
/**
|
||||
* Exit the coroutine (yield and mark it dead).
|
||||
*/
|
||||
static void cexit();
|
||||
private:
|
||||
jmp_buf saved_env;
|
||||
bool dead;
|
||||
unsigned char* stackblock;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
108
manual.lyx
108
manual.lyx
|
@ -814,7 +814,7 @@ Print all aliases and their expansions in effect.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsection
|
||||
run-script <script>
|
||||
run-script <script> (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1076,7 +1076,7 @@ These commands are not available in lsnesrc, but are available after ROM
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
quit-emulator [/y]
|
||||
quit-emulator [/y] (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1085,7 +1085,7 @@ Quits the emulator (asking for confirmation).
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
pause-emulator
|
||||
pause-emulator (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1093,7 +1093,7 @@ Toggle paused/unpaused
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
+advance-frame
|
||||
+advance-frame (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1103,7 +1103,7 @@ Advance frame.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
+advance-poll
|
||||
+advance-poll (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1113,7 +1113,7 @@ Advance subframe.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
advance-skiplag
|
||||
advance-skiplag (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1121,7 +1121,7 @@ Skip to first poll in frame after current.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
reset
|
||||
reset (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1129,7 +1129,7 @@ Reset the SNES after this frame.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
load <filename>
|
||||
load <filename> (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1137,7 +1137,7 @@ Load savestate <filename> in current mode.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
load-state <filename>
|
||||
load-state <filename> (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1145,7 +1145,7 @@ Load savestate <filename> in readwrite mode.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
load-readonly <filename>
|
||||
load-readonly <filename> (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1153,7 +1153,7 @@ Load savestate <filename> in readonly mode.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
load-preserve <filename>
|
||||
load-preserve <filename> (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1161,7 +1161,7 @@ Load savestate <filename> in readonly mode, preserving current events.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
load-movie <filename>
|
||||
load-movie <filename> (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1169,7 +1169,7 @@ Load savestate <filename>, ignoring save part in readonly mode.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
save-state <filename>
|
||||
save-state <filename> (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1177,7 +1177,7 @@ Save system state to <filename> as soon as possible.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
save-movie <filename>
|
||||
save-movie <filename> (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1185,7 +1185,7 @@ Save movie to <filename>.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
set-rwmode
|
||||
set-rwmode (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1193,7 +1193,7 @@ Set read-write mode.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
set-romode
|
||||
set-romode (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1201,7 +1201,7 @@ Set read-only mode
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
toggle-rwmode
|
||||
toggle-rwmode (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1209,7 +1209,7 @@ Toggle between read-only and read-write modes.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
set-gamename <name>
|
||||
set-gamename <name> (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1217,7 +1217,7 @@ Set name of the game to <name>
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
get-gamename
|
||||
get-gamename (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1225,7 +1225,7 @@ Print the name of the game.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
add-author <author>
|
||||
add-author <author> (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1235,7 +1235,7 @@ Adds new author <author>.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
edit-author <num> <author>
|
||||
edit-author <num> <author> (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1244,7 +1244,7 @@ Edit the author in slot <num> (0-based) to be <author> (see add-author for
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
remove-author <num>
|
||||
remove-author <num> (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1252,7 +1252,7 @@ Remove author in slot <num>
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
print-authors
|
||||
print-authors (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1260,7 +1260,7 @@ Print authors.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
test-1, test-2, test-3
|
||||
test-1, test-2, test-3 (N/A for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1269,7 +1269,7 @@ Internal test commands.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
take-screenshot <filename>
|
||||
take-screenshot <filename> (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1277,7 +1277,7 @@ Save screenshot to <filename>.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
+controller<num><button>
|
||||
+controller<num><button> (N/A for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1360,6 +1360,7 @@ Hold/unhold button <button> on controller <num> (1-8).
|
|||
|
||||
\begin_layout Subsubsection
|
||||
autofire (<pattern>|-)...
|
||||
(N/A for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1370,7 +1371,7 @@ Set autofire pattern.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
repaint
|
||||
repaint (N/A for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1378,11 +1379,11 @@ Force a repaint.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsection
|
||||
Save jukebox
|
||||
Save jukebox (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
cycle-jukebox-backward
|
||||
cycle-jukebox-backward (N/A for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1390,7 +1391,7 @@ Cycle save jukebox backwards.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
cycle-jukebox-forward
|
||||
cycle-jukebox-forward (N/A for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1398,7 +1399,7 @@ Cycle save jukebox forwards
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
add-jukebox-save <filename>
|
||||
add-jukebox-save <filename> (N/A for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1406,7 +1407,7 @@ Add <filename> to jukebox saves.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
load-jukebox
|
||||
load-jukebox (N/A for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1414,7 +1415,7 @@ Do load from jukebox (current mode).
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
save-jukebox
|
||||
save-jukebox (N/A for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1422,7 +1423,7 @@ Do state save to jukebox.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsection
|
||||
Lua
|
||||
Lua (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1430,7 +1431,8 @@ Only available if lua support is compiled in.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
evaluate-lua <luacode>
|
||||
<<<<<<< HEADevaluate-lua <luacode>=======eval-lua <luacode> (implemented
|
||||
for wxwidgets)>>>>>>> Wxwidgets Graphics plugin WIP
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1438,7 +1440,7 @@ Run Lua code <luacode> using built-in Lua interpretter.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
run-lua <script>
|
||||
run-lua <script> (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1466,11 +1468,11 @@ Remove a watch.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsection
|
||||
Sound
|
||||
Sound (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
enable-sound <on/off>
|
||||
enable-sound <on/off> (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1478,7 +1480,7 @@ Enable/Disable sound.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
set-sound-device <device>
|
||||
set-sound-device <device> (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1486,7 +1488,7 @@ Set sound device to <device>
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
show-sound-status
|
||||
show-sound-status (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1494,7 +1496,7 @@ Show status of sound system.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
show-sound-devices
|
||||
show-sound-devices (N/A for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1502,7 +1504,7 @@ Show all available devices.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsection
|
||||
SDL Platform commands
|
||||
SDL Platform commands (implemented for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1510,7 +1512,7 @@ The following are valid on SDL platform.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
identify-key
|
||||
identify-key (N/A for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1518,7 +1520,7 @@ Asks to press a key and then identifies that (pseudo-)key.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
toggle-console
|
||||
toggle-console (N/A for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1526,7 +1528,7 @@ Toggle between windowed/fullscreen console.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
scroll-fullup
|
||||
scroll-fullup (N/A for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1534,7 +1536,7 @@ Scroll messages window as far back as it goes.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
scroll-fulldown
|
||||
scroll-fulldown (N/A for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1542,7 +1544,7 @@ Scroll messages window as far forward as it goes.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
scroll-up
|
||||
scroll-up (N/A for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -1550,7 +1552,7 @@ Scroll messages window back one screenful.
|
|||
\end_layout
|
||||
|
||||
\begin_layout Subsubsection
|
||||
scroll-down
|
||||
scroll-down (N/A for wxwidgets)
|
||||
\end_layout
|
||||
|
||||
\begin_layout Standard
|
||||
|
@ -3773,12 +3775,20 @@ GRAPHICS=<plat>
|
|||
|
||||
\begin_layout Standard
|
||||
Set graphics platform.
|
||||
Currently available choice is
|
||||
Currently available choices are
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
SDL
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
and
|
||||
\begin_inset Quotes eld
|
||||
\end_inset
|
||||
|
||||
WXWIDGETS
|
||||
\begin_inset Quotes erd
|
||||
\end_inset
|
||||
|
||||
.
|
||||
|
|
71
platform/wxwidgets/main-wxwidgets.cpp
Normal file
71
platform/wxwidgets/main-wxwidgets.cpp
Normal file
|
@ -0,0 +1,71 @@
|
|||
#include "lsnes.hpp"
|
||||
#include <snes/snes.hpp>
|
||||
#include <ui-libsnes/libsnes.hpp>
|
||||
#include <wx/wx.h>
|
||||
#include <wx/event.h>
|
||||
#include <wx/control.h>
|
||||
#include <wx/combobox.h>
|
||||
#include <cassert>
|
||||
#include "rom.hpp"
|
||||
#include "avsnoop.hpp"
|
||||
#include "rrdata.hpp"
|
||||
#include "framerate.hpp"
|
||||
#include "zip.hpp"
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include "misc.hpp"
|
||||
#include "window.hpp"
|
||||
#include "lua.hpp"
|
||||
#include "src/rom_select_window.hpp"
|
||||
#include "src/messages_window.hpp"
|
||||
#include "src/status_window.hpp"
|
||||
|
||||
class lsnes_app : public wxApp
|
||||
{
|
||||
public:
|
||||
virtual bool OnInit();
|
||||
virtual int OnExit();
|
||||
};
|
||||
|
||||
IMPLEMENT_APP(lsnes_app)
|
||||
|
||||
bool lsnes_app::OnInit()
|
||||
{
|
||||
set_random_seed();
|
||||
|
||||
{
|
||||
std::ostringstream x;
|
||||
x << snes_library_id() << " (" << SNES::Info::Profile << " core)";
|
||||
bsnes_core_version = x.str();
|
||||
}
|
||||
window::init();
|
||||
init_lua();
|
||||
|
||||
messages << "BSNES version: " << bsnes_core_version << std::endl;
|
||||
messages << "lsnes version: lsnes rr" << lsnes_version << std::endl;
|
||||
|
||||
std::string cfgpath = get_config_path();
|
||||
messages << "Saving per-user data to: " << get_config_path() << std::endl;
|
||||
|
||||
wx_messages_window* msgs = new wx_messages_window();
|
||||
window1 = msgs;
|
||||
msgs->Show();
|
||||
|
||||
wx_rom_select_window* romwin = new wx_rom_select_window();
|
||||
romwin->Show();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int lsnes_app::OnExit()
|
||||
{
|
||||
av_snooper::_end();
|
||||
rrdata::close();
|
||||
window::quit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void window::notify_message() throw(std::bad_alloc, std::runtime_error)
|
||||
{
|
||||
if(wx_messages_window::ptr)
|
||||
wx_messages_window::ptr->notify_message();
|
||||
}
|
81
platform/wxwidgets/src/authorseditor.cpp
Normal file
81
platform/wxwidgets/src/authorseditor.cpp
Normal file
|
@ -0,0 +1,81 @@
|
|||
#include "authorseditor.hpp"
|
||||
#include "common.hpp"
|
||||
#include "moviedata.hpp"
|
||||
|
||||
wx_authors_editor::wx_authors_editor(wxWindow* parent)
|
||||
: wxDialog(parent, wxID_ANY, wxT("lsnes: Edit game name & authors"), wxDefaultPosition, wxSize(-1, -1))
|
||||
{
|
||||
Centre();
|
||||
wxFlexGridSizer* top_s = new wxFlexGridSizer(4, 1, 0, 0);
|
||||
SetSizer(top_s);
|
||||
|
||||
wxFlexGridSizer* c_s = new wxFlexGridSizer(1, 2, 0, 0);
|
||||
c_s->Add(new wxStaticText(this, wxID_ANY, wxT("Game name:")), 0, wxGROW);
|
||||
c_s->Add(projectname = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxSize(400, -1)), 1, wxGROW);
|
||||
top_s->Add(c_s);
|
||||
|
||||
top_s->Add(new wxStaticText(this, wxID_ANY, wxT("Authors (one per line):")), 0, wxGROW);
|
||||
top_s->Add(authors = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize,
|
||||
wxTE_MULTILINE), 0, wxGROW);
|
||||
authors->Connect(wxEVT_COMMAND_TEXT_UPDATED,
|
||||
wxCommandEventHandler(wx_authors_editor::on_authors_change), NULL, this);
|
||||
|
||||
wxBoxSizer* pbutton_s = new wxBoxSizer(wxHORIZONTAL);
|
||||
pbutton_s->AddStretchSpacer();
|
||||
pbutton_s->Add(okbutton = new wxButton(this, wxID_OK, wxT("OK")), 0, wxGROW);
|
||||
pbutton_s->Add(cancel = new wxButton(this, wxID_CANCEL, wxT("Cancel")), 0, wxGROW);
|
||||
okbutton->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
wxCommandEventHandler(wx_authors_editor::on_ok), NULL, this);
|
||||
cancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
wxCommandEventHandler(wx_authors_editor::on_cancel), NULL, this);
|
||||
top_s->Add(pbutton_s, 0, wxGROW);
|
||||
|
||||
c_s->SetSizeHints(this);
|
||||
top_s->SetSizeHints(this);
|
||||
Fit();
|
||||
|
||||
projectname->SetValue(towxstring(our_movie.gamename));
|
||||
std::string x;
|
||||
for(auto i : our_movie.authors)
|
||||
x = x + i.first + "|" + i.second + "\n";
|
||||
authors->SetValue(towxstring(x));
|
||||
}
|
||||
|
||||
bool wx_authors_editor::ShouldPreventAppExit() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void wx_authors_editor::on_authors_change(wxCommandEvent& e)
|
||||
{
|
||||
try {
|
||||
size_t lines = authors->GetNumberOfLines();
|
||||
for(size_t i = 0; i < lines; i++) {
|
||||
std::string l = tostdstring(authors->GetLineText(i));
|
||||
if(l == "|")
|
||||
throw 43;
|
||||
}
|
||||
okbutton->Enable();
|
||||
} catch(...) {
|
||||
okbutton->Disable();
|
||||
}
|
||||
}
|
||||
|
||||
void wx_authors_editor::on_cancel(wxCommandEvent& e)
|
||||
{
|
||||
EndModal(wxID_CANCEL);
|
||||
}
|
||||
|
||||
void wx_authors_editor::on_ok(wxCommandEvent& e)
|
||||
{
|
||||
our_movie.gamename = tostdstring(projectname->GetValue());
|
||||
std::vector<std::pair<std::string, std::string>> newauthors;
|
||||
size_t lines = authors->GetNumberOfLines();
|
||||
for(size_t i = 0; i < lines; i++) {
|
||||
std::string l = tostdstring(authors->GetLineText(i));
|
||||
if(l != "" && l != "|")
|
||||
newauthors.push_back(split_author(l));
|
||||
}
|
||||
our_movie.authors = newauthors;
|
||||
EndModal(wxID_OK);
|
||||
}
|
24
platform/wxwidgets/src/authorseditor.hpp
Normal file
24
platform/wxwidgets/src/authorseditor.hpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
#ifndef _wxwidgets_authorseditor__hpp__included__
|
||||
#define _wxwidgets_authorseditor__hpp__included__
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/event.h>
|
||||
#include <wx/control.h>
|
||||
#include <wx/combobox.h>
|
||||
|
||||
class wx_authors_editor : public wxDialog
|
||||
{
|
||||
public:
|
||||
wx_authors_editor(wxWindow* parent);
|
||||
bool ShouldPreventAppExit() const;
|
||||
void on_authors_change(wxCommandEvent& e);
|
||||
void on_cancel(wxCommandEvent& e);
|
||||
void on_ok(wxCommandEvent& e);
|
||||
private:
|
||||
wxTextCtrl* projectname;
|
||||
wxTextCtrl* authors;
|
||||
wxButton* okbutton;
|
||||
wxButton* cancel;
|
||||
};
|
||||
|
||||
#endif
|
222
platform/wxwidgets/src/axeseditor.cpp
Normal file
222
platform/wxwidgets/src/axeseditor.cpp
Normal file
|
@ -0,0 +1,222 @@
|
|||
#include "axeseditor.hpp"
|
||||
#include "keymapper.hpp"
|
||||
#include "common.hpp"
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <sstream>
|
||||
|
||||
#define AMODE_DISABLED "Disabled"
|
||||
#define AMODE_AXIS_PAIR "Axis"
|
||||
#define AMODE_AXIS_PAIR_INVERSE "Axis (inverted)"
|
||||
#define AMODE_PRESSURE_M0 "Pressure - to 0"
|
||||
#define AMODE_PRESSURE_MP "Pressure - to +"
|
||||
#define AMODE_PRESSURE_0M "Pressure 0 to -"
|
||||
#define AMODE_PRESSURE_0P "Pressure 0 to +"
|
||||
#define AMODE_PRESSURE_PM "Pressure + to -"
|
||||
#define AMODE_PRESSURE_P0 "Pressure + to 0"
|
||||
|
||||
wx_axes_editor_axis::wx_axes_editor_axis(wxSizer* sizer, wxWindow* window, const std::string& name)
|
||||
{
|
||||
wxString choices[9];
|
||||
choices[0] = wxT(AMODE_DISABLED);
|
||||
choices[1] = wxT(AMODE_AXIS_PAIR);
|
||||
choices[2] = wxT(AMODE_AXIS_PAIR_INVERSE);
|
||||
choices[3] = wxT(AMODE_PRESSURE_M0);
|
||||
choices[4] = wxT(AMODE_PRESSURE_MP);
|
||||
choices[5] = wxT(AMODE_PRESSURE_0M);
|
||||
choices[6] = wxT(AMODE_PRESSURE_0P);
|
||||
choices[7] = wxT(AMODE_PRESSURE_PM);
|
||||
choices[8] = wxT(AMODE_PRESSURE_P0);
|
||||
size_t defaultidx = 0;
|
||||
std::string low;
|
||||
std::string mid;
|
||||
std::string high;
|
||||
std::string tolerance;
|
||||
keygroup* k = keygroup::lookup_by_name(name);
|
||||
if(!k)
|
||||
return;
|
||||
struct keygroup::parameters p = k->get_parameters();
|
||||
{
|
||||
switch(p.ktype) {
|
||||
case keygroup::KT_DISABLED: defaultidx = 0; break;
|
||||
case keygroup::KT_AXIS_PAIR: defaultidx = 1; break;
|
||||
case keygroup::KT_AXIS_PAIR_INVERSE: defaultidx = 2; break;
|
||||
case keygroup::KT_PRESSURE_M0: defaultidx = 3; break;
|
||||
case keygroup::KT_PRESSURE_MP: defaultidx = 4; break;
|
||||
case keygroup::KT_PRESSURE_0M: defaultidx = 5; break;
|
||||
case keygroup::KT_PRESSURE_0P: defaultidx = 6; break;
|
||||
case keygroup::KT_PRESSURE_PM: defaultidx = 7; break;
|
||||
case keygroup::KT_PRESSURE_P0: defaultidx = 8; break;
|
||||
};
|
||||
std::ostringstream x1;
|
||||
std::ostringstream x2;
|
||||
std::ostringstream x3;
|
||||
std::ostringstream x4;
|
||||
x1 << p.cal_left;
|
||||
x2 << p.cal_center;
|
||||
x3 << p.cal_right;
|
||||
x4 << p.cal_tolerance;
|
||||
low = x1.str();
|
||||
mid = x2.str();
|
||||
high = x3.str();
|
||||
tolerance = x4.str();
|
||||
}
|
||||
|
||||
a_name = name;
|
||||
sizer->Add(new wxStaticText(window, wxID_ANY, towxstring(name)), 0, wxGROW);
|
||||
sizer->Add(a_type = new wxComboBox(window, wxID_ANY, choices[defaultidx], wxDefaultPosition, wxDefaultSize,
|
||||
9, choices, wxCB_READONLY), 0, wxGROW);
|
||||
sizer->Add(a_low = new wxTextCtrl(window, wxID_ANY, towxstring(low)), 0, wxGROW);
|
||||
sizer->Add(a_mid = new wxTextCtrl(window, wxID_ANY, towxstring(mid)), 0, wxGROW);
|
||||
sizer->Add(a_high = new wxTextCtrl(window, wxID_ANY, towxstring(high)), 0, wxGROW);
|
||||
sizer->Add(a_tolerance = new wxTextCtrl(window, wxID_ANY, towxstring(tolerance)), 0, wxGROW);
|
||||
a_low->Connect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(wx_axes_editor::on_value_change), NULL,
|
||||
window);
|
||||
a_mid->Connect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(wx_axes_editor::on_value_change), NULL,
|
||||
window);
|
||||
a_high->Connect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(wx_axes_editor::on_value_change), NULL,
|
||||
window);
|
||||
a_tolerance->Connect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(wx_axes_editor::on_value_change), NULL,
|
||||
window);
|
||||
}
|
||||
|
||||
bool wx_axes_editor_axis::is_ok()
|
||||
{
|
||||
int32_t low, mid, high;
|
||||
double tolerance;
|
||||
|
||||
try {
|
||||
low = boost::lexical_cast<int32_t>(tostdstring(a_low->GetValue()));
|
||||
mid = boost::lexical_cast<int32_t>(tostdstring(a_mid->GetValue()));
|
||||
high = boost::lexical_cast<int32_t>(tostdstring(a_high->GetValue()));
|
||||
tolerance = boost::lexical_cast<double>(tostdstring(a_tolerance->GetValue()));
|
||||
} catch(...) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(low < -32768 || low > 32767 || low > mid)
|
||||
return false;
|
||||
if(mid < -32768 || mid > 32767 || mid > high)
|
||||
return false;
|
||||
if(high < -32768 || high > 32767)
|
||||
return false;
|
||||
if(tolerance <= 0 || tolerance >= 1)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void wx_axes_editor_axis::apply()
|
||||
{
|
||||
keygroup* k = keygroup::lookup_by_name(a_name);
|
||||
if(!k)
|
||||
return;
|
||||
|
||||
int32_t low, mid, high;
|
||||
double tolerance;
|
||||
enum keygroup::type ntype;
|
||||
enum keygroup::type ctype = k->get_parameters().ktype;;
|
||||
|
||||
std::string amode = tostdstring(a_type->GetValue());
|
||||
if(amode == AMODE_AXIS_PAIR)
|
||||
ntype = keygroup::KT_AXIS_PAIR;
|
||||
if(amode == AMODE_AXIS_PAIR_INVERSE)
|
||||
ntype = keygroup::KT_AXIS_PAIR_INVERSE;
|
||||
if(amode == AMODE_DISABLED)
|
||||
ntype = keygroup::KT_DISABLED;
|
||||
if(amode == AMODE_PRESSURE_0M)
|
||||
ntype = keygroup::KT_PRESSURE_0M;
|
||||
if(amode == AMODE_PRESSURE_0P)
|
||||
ntype = keygroup::KT_PRESSURE_0P;
|
||||
if(amode == AMODE_PRESSURE_M0)
|
||||
ntype = keygroup::KT_PRESSURE_M0;
|
||||
if(amode == AMODE_PRESSURE_MP)
|
||||
ntype = keygroup::KT_PRESSURE_MP;
|
||||
if(amode == AMODE_PRESSURE_PM)
|
||||
ntype = keygroup::KT_PRESSURE_PM;
|
||||
if(amode == AMODE_PRESSURE_P0)
|
||||
ntype = keygroup::KT_PRESSURE_P0;
|
||||
try {
|
||||
low = boost::lexical_cast<int32_t>(tostdstring(a_low->GetValue()));
|
||||
mid = boost::lexical_cast<int32_t>(tostdstring(a_mid->GetValue()));
|
||||
high = boost::lexical_cast<int32_t>(tostdstring(a_high->GetValue()));
|
||||
tolerance = boost::lexical_cast<double>(tostdstring(a_tolerance->GetValue()));
|
||||
} catch(...) {
|
||||
return;
|
||||
}
|
||||
if(low < -32768 || low > 32767 || low > mid)
|
||||
return;
|
||||
if(mid < -32768 || mid > 32767 || mid > high)
|
||||
return;
|
||||
if(high < -32768 || high > 32767)
|
||||
return;
|
||||
if(tolerance <= 0 || tolerance >= 1)
|
||||
return;
|
||||
if(ctype != ntype)
|
||||
k->change_type(ntype);
|
||||
k->change_calibration(low, mid, high, tolerance);
|
||||
}
|
||||
|
||||
wx_axes_editor::wx_axes_editor(wxWindow* parent)
|
||||
: wxDialog(parent, wxID_ANY, wxT("lsnes: Edit axes"), wxDefaultPosition, wxSize(-1, -1))
|
||||
{
|
||||
std::set<std::string> axisnames = keygroup::get_axis_set();
|
||||
|
||||
Centre();
|
||||
wxFlexGridSizer* top_s = new wxFlexGridSizer(2, 1, 0, 0);
|
||||
SetSizer(top_s);
|
||||
|
||||
wxFlexGridSizer* t_s = new wxFlexGridSizer(axisnames.size() + 1, 6, 0, 0);
|
||||
t_s->Add(new wxStaticText(this, wxID_ANY, wxT("Name")), 0, wxGROW);
|
||||
t_s->Add(new wxStaticText(this, wxID_ANY, wxT("Type")), 0, wxGROW);
|
||||
t_s->Add(new wxStaticText(this, wxID_ANY, wxT("Low")), 0, wxGROW);
|
||||
t_s->Add(new wxStaticText(this, wxID_ANY, wxT("Mid")), 0, wxGROW);
|
||||
t_s->Add(new wxStaticText(this, wxID_ANY, wxT("High")), 0, wxGROW);
|
||||
t_s->Add(new wxStaticText(this, wxID_ANY, wxT("Tolerance")), 0, wxGROW);
|
||||
for(auto i : axisnames)
|
||||
axes.push_back(new wx_axes_editor_axis(t_s, this, i));
|
||||
top_s->Add(t_s);
|
||||
|
||||
wxBoxSizer* pbutton_s = new wxBoxSizer(wxHORIZONTAL);
|
||||
pbutton_s->AddStretchSpacer();
|
||||
pbutton_s->Add(okbutton = new wxButton(this, wxID_OK, wxT("OK")), 0, wxGROW);
|
||||
pbutton_s->Add(cancel = new wxButton(this, wxID_CANCEL, wxT("Cancel")), 0, wxGROW);
|
||||
okbutton->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
wxCommandEventHandler(wx_axes_editor::on_ok), NULL, this);
|
||||
cancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
wxCommandEventHandler(wx_axes_editor::on_cancel), NULL, this);
|
||||
top_s->Add(pbutton_s, 0, wxGROW);
|
||||
|
||||
t_s->SetSizeHints(this);
|
||||
top_s->SetSizeHints(this);
|
||||
Fit();
|
||||
}
|
||||
|
||||
wx_axes_editor::~wx_axes_editor()
|
||||
{
|
||||
for(auto i : axes)
|
||||
delete i;
|
||||
}
|
||||
|
||||
bool wx_axes_editor::ShouldPreventAppExit() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void wx_axes_editor::on_value_change(wxCommandEvent& e)
|
||||
{
|
||||
bool all_ok = true;
|
||||
for(auto i : axes)
|
||||
all_ok = all_ok && i->is_ok();
|
||||
okbutton->Enable(all_ok);
|
||||
}
|
||||
|
||||
void wx_axes_editor::on_cancel(wxCommandEvent& e)
|
||||
{
|
||||
EndModal(wxID_CANCEL);
|
||||
}
|
||||
|
||||
void wx_axes_editor::on_ok(wxCommandEvent& e)
|
||||
{
|
||||
for(auto i : axes)
|
||||
i->apply();
|
||||
EndModal(wxID_OK);
|
||||
}
|
41
platform/wxwidgets/src/axeseditor.hpp
Normal file
41
platform/wxwidgets/src/axeseditor.hpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
#ifndef _wxwidgets_axeseditor__hpp__included__
|
||||
#define _wxwidgets_axeseditor__hpp__included__
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/event.h>
|
||||
#include <wx/control.h>
|
||||
#include <wx/combobox.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
class wx_axes_editor_axis
|
||||
{
|
||||
public:
|
||||
wx_axes_editor_axis(wxSizer* sizer, wxWindow* window, const std::string& name);
|
||||
bool is_ok();
|
||||
void apply();
|
||||
private:
|
||||
std::string a_name;
|
||||
wxComboBox* a_type;
|
||||
wxTextCtrl* a_low;
|
||||
wxTextCtrl* a_mid;
|
||||
wxTextCtrl* a_high;
|
||||
wxTextCtrl* a_tolerance;
|
||||
};
|
||||
|
||||
class wx_axes_editor : public wxDialog
|
||||
{
|
||||
public:
|
||||
wx_axes_editor(wxWindow* parent);
|
||||
~wx_axes_editor();
|
||||
bool ShouldPreventAppExit() const;
|
||||
void on_value_change(wxCommandEvent& e);
|
||||
void on_cancel(wxCommandEvent& e);
|
||||
void on_ok(wxCommandEvent& e);
|
||||
private:
|
||||
std::vector<wx_axes_editor_axis*> axes;
|
||||
wxButton* okbutton;
|
||||
wxButton* cancel;
|
||||
};
|
||||
|
||||
#endif
|
195
platform/wxwidgets/src/callrom.cpp
Normal file
195
platform/wxwidgets/src/callrom.cpp
Normal file
|
@ -0,0 +1,195 @@
|
|||
#include "callrom.hpp"
|
||||
#include "common.hpp"
|
||||
|
||||
#define TNAME_SNES "SNES"
|
||||
#define TNAME_BSX_NS "BS-X (non-slotted)"
|
||||
#define TNAME_BSX_S "BS-X (slotted)"
|
||||
#define TNAME_SUFAMITURBO "Sufami Turbo"
|
||||
#define TNAME_SGB "SGB"
|
||||
#define RNAME_AUTO "Autodetect"
|
||||
#define RNAME_NTSC "NTSC"
|
||||
#define RNAME_PAL "PAL"
|
||||
#define WNAME_SNES_MAIN "ROM"
|
||||
#define WNAME_SNES_MAIN_XML "ROM XML"
|
||||
#define WNAME_BS_MAIN "BS-X BIOS"
|
||||
#define WNAME_BS_MAIN_XML "BS-X BIOS XML"
|
||||
#define WNAME_BS_SLOTA "BS FLASH"
|
||||
#define WNAME_BS_SLOTA_XML "BS FLASH XML"
|
||||
#define WNAME_ST_MAIN "ST BIOS"
|
||||
#define WNAME_ST_MAIN_XML "ST BIOS XML"
|
||||
#define WNAME_ST_SLOTA "SLOT A ROM"
|
||||
#define WNAME_ST_SLOTA_XML "SLOT A XML"
|
||||
#define WNAME_ST_SLOTB "SLOT B ROM"
|
||||
#define WNAME_ST_SLOTB_XML "SLOT B XML"
|
||||
#define WNAME_SGB_MAIN "SGB BIOS"
|
||||
#define WNAME_SGB_MAIN_XML "SGB BIOS XML"
|
||||
#define WNAME_SGB_SLOTA "DMG ROM"
|
||||
#define WNAME_SGB_SLOTA_XML "BMG XML"
|
||||
|
||||
|
||||
enum rom_type romtype_from_string(const std::string& str)
|
||||
{
|
||||
if(str == TNAME_SNES)
|
||||
return ROMTYPE_SNES;
|
||||
if(str == TNAME_BSX_NS)
|
||||
return ROMTYPE_BSX;
|
||||
if(str == TNAME_BSX_S)
|
||||
return ROMTYPE_BSXSLOTTED;
|
||||
if(str == TNAME_SUFAMITURBO)
|
||||
return ROMTYPE_SUFAMITURBO;
|
||||
if(str == TNAME_SGB)
|
||||
return ROMTYPE_SGB;
|
||||
return ROMTYPE_NONE;
|
||||
}
|
||||
|
||||
enum rom_type romtype_from_string(const wxString& str)
|
||||
{
|
||||
return romtype_from_string(tostdstring(str));
|
||||
}
|
||||
|
||||
wxString romname_wxs(enum rom_type rtype, unsigned index)
|
||||
{
|
||||
return towxstring(romname_stds(rtype, index));
|
||||
}
|
||||
|
||||
std::string romname_stds(enum rom_type rtype, unsigned index)
|
||||
{
|
||||
switch(rtype) {
|
||||
case ROMTYPE_SNES:
|
||||
switch(index) {
|
||||
case 0: return WNAME_SNES_MAIN;
|
||||
case 1: return WNAME_SNES_MAIN_XML;
|
||||
};
|
||||
break;
|
||||
case ROMTYPE_BSX:
|
||||
case ROMTYPE_BSXSLOTTED:
|
||||
switch(index) {
|
||||
case 0: return WNAME_BS_MAIN;
|
||||
case 1: return WNAME_BS_MAIN_XML;
|
||||
case 2: return WNAME_BS_SLOTA;
|
||||
case 3: return WNAME_BS_SLOTA_XML;
|
||||
};
|
||||
break;
|
||||
case ROMTYPE_SUFAMITURBO:
|
||||
switch(index) {
|
||||
case 0: return WNAME_ST_MAIN;
|
||||
case 1: return WNAME_ST_MAIN_XML;
|
||||
case 2: return WNAME_ST_SLOTA;
|
||||
case 3: return WNAME_ST_SLOTA_XML;
|
||||
case 4: return WNAME_ST_SLOTB;
|
||||
case 5: return WNAME_ST_SLOTB_XML;
|
||||
};
|
||||
break;
|
||||
case ROMTYPE_SGB:
|
||||
switch(index) {
|
||||
case 0: return WNAME_SGB_MAIN;
|
||||
case 1: return WNAME_SGB_MAIN_XML;
|
||||
case 2: return WNAME_SGB_SLOTA;
|
||||
case 3: return WNAME_SGB_SLOTA_XML;
|
||||
};
|
||||
break;
|
||||
case ROMTYPE_NONE:
|
||||
if(index == 0) return "dummy";
|
||||
break;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
unsigned fill_rom_names(enum rom_type rtype, wxString* array)
|
||||
{
|
||||
unsigned r = 0;
|
||||
for(unsigned i = 0; i < 6; i++) {
|
||||
wxString s = romname_wxs(rtype, i);
|
||||
if(s.Length())
|
||||
array[r++] = s;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
unsigned romname_to_index(enum rom_type rtype, const wxString& name)
|
||||
{
|
||||
std::string s = tostdstring(name);
|
||||
for(unsigned i = 0; i < 6; i++)
|
||||
if(romname_stds(rtype, i) == s)
|
||||
return i;
|
||||
return 6;
|
||||
|
||||
}
|
||||
|
||||
struct loaded_slot& get_rom_slot(struct loaded_rom& rom, unsigned index)
|
||||
{
|
||||
switch(index) {
|
||||
case 0: return rom.rom;
|
||||
case 1: return rom.rom_xml;
|
||||
case 2: return rom.slota;
|
||||
case 3: return rom.slota_xml;
|
||||
case 4: return rom.slotb;
|
||||
case 5: return rom.slotb_xml;
|
||||
}
|
||||
return rom.rom;
|
||||
}
|
||||
|
||||
enum rom_region region_from_string(const std::string& str)
|
||||
{
|
||||
if(str == RNAME_NTSC)
|
||||
return REGION_NTSC;
|
||||
if(str == RNAME_PAL)
|
||||
return REGION_PAL;
|
||||
return REGION_AUTO;
|
||||
}
|
||||
|
||||
enum rom_region region_from_string(const wxString& str)
|
||||
{
|
||||
return region_from_string(tostdstring(str));
|
||||
}
|
||||
|
||||
bool has_forced_region(enum rom_type rtype)
|
||||
{
|
||||
return (rtype != ROMTYPE_SNES && rtype != ROMTYPE_SGB);
|
||||
}
|
||||
|
||||
bool has_forced_region(const std::string& str)
|
||||
{
|
||||
return has_forced_region(romtype_from_string(str));
|
||||
}
|
||||
|
||||
bool has_forced_region(const wxString& str)
|
||||
{
|
||||
return has_forced_region(romtype_from_string(str));
|
||||
}
|
||||
|
||||
wxString forced_region_for_romtype(enum rom_type rtype)
|
||||
{
|
||||
if(has_forced_region(rtype))
|
||||
return wxT(RNAME_NTSC);
|
||||
else
|
||||
return wxT("");
|
||||
}
|
||||
|
||||
wxString forced_region_for_romtype(const std::string& str)
|
||||
{
|
||||
return forced_region_for_romtype(romtype_from_string(str));
|
||||
}
|
||||
|
||||
wxString forced_region_for_romtype(const wxString& str)
|
||||
{
|
||||
return forced_region_for_romtype(romtype_from_string(str));
|
||||
}
|
||||
|
||||
unsigned populate_region_choices(wxString* array)
|
||||
{
|
||||
array[0] = wxT(RNAME_AUTO);
|
||||
array[1] = wxT(RNAME_NTSC);
|
||||
array[2] = wxT(RNAME_PAL);
|
||||
return 3;
|
||||
}
|
||||
|
||||
unsigned populate_system_choices(wxString* array)
|
||||
{
|
||||
array[0] = wxT(TNAME_SNES);
|
||||
array[1] = wxT(TNAME_BSX_NS);
|
||||
array[2] = wxT(TNAME_BSX_S);
|
||||
array[3] = wxT(TNAME_SUFAMITURBO);
|
||||
array[4] = wxT(TNAME_SGB);
|
||||
return 5;
|
||||
}
|
26
platform/wxwidgets/src/callrom.hpp
Normal file
26
platform/wxwidgets/src/callrom.hpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef _wxwidgets_callrom__hpp__included__
|
||||
#define _wxwidgets_callrom__hpp__included__
|
||||
|
||||
#include "rom.hpp"
|
||||
#include <wx/string.h>
|
||||
#include <string>
|
||||
|
||||
enum rom_type romtype_from_string(const std::string& str);
|
||||
enum rom_type romtype_from_string(const wxString& str);
|
||||
wxString romname_wxs(enum rom_type rtype, unsigned index);
|
||||
std::string romname_stds(enum rom_type rtype, unsigned index);
|
||||
unsigned fill_rom_names(enum rom_type rtype, wxString* array);
|
||||
unsigned romname_to_index(enum rom_type rtype, const wxString& name);
|
||||
struct loaded_slot& get_rom_slot(struct loaded_rom& rom, unsigned index);
|
||||
enum rom_region region_from_string(const std::string& str);
|
||||
enum rom_region region_from_string(const wxString& str);
|
||||
bool has_forced_region(enum rom_type rtype);
|
||||
bool has_forced_region(const std::string& str);
|
||||
bool has_forced_region(const wxString& str);
|
||||
wxString forced_region_for_romtype(enum rom_type rtype);
|
||||
wxString forced_region_for_romtype(const std::string& str);
|
||||
wxString forced_region_for_romtype(const wxString& str);
|
||||
unsigned populate_region_choices(wxString* array);
|
||||
unsigned populate_system_choices(wxString* array);
|
||||
|
||||
#endif
|
17
platform/wxwidgets/src/common.cpp
Normal file
17
platform/wxwidgets/src/common.cpp
Normal file
|
@ -0,0 +1,17 @@
|
|||
#include "common.hpp"
|
||||
|
||||
wxString towxstring(const std::string& str)
|
||||
{
|
||||
return wxString(str.c_str(), wxConvUTF8);
|
||||
}
|
||||
|
||||
std::string tostdstring(const wxString& str)
|
||||
{
|
||||
return std::string(str.mb_str(wxConvUTF8));
|
||||
}
|
||||
|
||||
long primary_window_style = wxMINIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION | wxCLIP_CHILDREN | wxCLOSE_BOX;
|
||||
long secondary_window_style = wxMINIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION | wxCLIP_CHILDREN;
|
||||
|
||||
wxFrame* window1;
|
||||
wxFrame* window2;
|
45
platform/wxwidgets/src/common.hpp
Normal file
45
platform/wxwidgets/src/common.hpp
Normal file
|
@ -0,0 +1,45 @@
|
|||
#ifndef _wxwidgets_common__hpp__included__
|
||||
#define _wxwidgets_common__hpp__included__
|
||||
|
||||
#include <wx/string.h>
|
||||
#include <wx/wx.h>
|
||||
|
||||
wxString towxstring(const std::string& str);
|
||||
std::string tostdstring(const wxString& str);
|
||||
extern long primary_window_style;
|
||||
extern long secondary_window_style;
|
||||
typedef wxStaticText* wxStaticText_ptr;
|
||||
|
||||
extern wxFrame* window1;
|
||||
extern wxFrame* window2;
|
||||
|
||||
template<class T>
|
||||
void cmdbutton_action(T* target, wxButton* button, void (T::*fptr)(wxCommandEvent& e))
|
||||
{
|
||||
button->Connect(wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction)(wxEventFunction)
|
||||
static_cast<wxCommandEventFunction>(fptr), NULL, target);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void menu_action(T* target, int id, void (T::*fptr)(wxCommandEvent& e))
|
||||
{
|
||||
target->Connect(id, wxEVT_COMMAND_MENU_SELECTED, (wxObjectEventFunction)(wxEventFunction)
|
||||
static_cast<wxCommandEventFunction>(fptr), NULL, target);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void menu_action(T* target, int id, void (T::*fptr)(wxCommandEvent& e), std::string subcmd)
|
||||
{
|
||||
target->Connect(id, wxEVT_COMMAND_MENU_SELECTED, (wxObjectEventFunction)(wxEventFunction)
|
||||
static_cast<wxCommandEventFunction>(fptr), NULL, target);
|
||||
}
|
||||
|
||||
#define CNAME_NONE "None"
|
||||
#define CNAME_GAMEPAD "Gamepad"
|
||||
#define CNAME_MULTITAP "Multitap"
|
||||
#define CNAME_MOUSE "Mouse"
|
||||
#define CNAME_SUPERSCOPE "Superscope"
|
||||
#define CNAME_JUSTIFIER "Justifier"
|
||||
#define CNAME_JUSTIFIERS "2 Justifiers"
|
||||
|
||||
#endif
|
1604
platform/wxwidgets/src/emufn.cpp
Normal file
1604
platform/wxwidgets/src/emufn.cpp
Normal file
File diff suppressed because it is too large
Load diff
10
platform/wxwidgets/src/emufn.hpp
Normal file
10
platform/wxwidgets/src/emufn.hpp
Normal file
|
@ -0,0 +1,10 @@
|
|||
#ifndef _wxwdigets_emufn__hpp__included__
|
||||
#define _wxwdigets_emufn__hpp__included__
|
||||
|
||||
#include "rom.hpp"
|
||||
#include "moviefile.hpp"
|
||||
|
||||
void boot_emulator(loaded_rom& rom, moviefile& movie);
|
||||
void exec_command(const std::string& cmd);
|
||||
|
||||
#endif
|
138
platform/wxwidgets/src/filenamebox.cpp
Normal file
138
platform/wxwidgets/src/filenamebox.cpp
Normal file
|
@ -0,0 +1,138 @@
|
|||
#include "filenamebox.hpp"
|
||||
#include "common.hpp"
|
||||
#include "zip.hpp"
|
||||
#include <wx/wx.h>
|
||||
#include <wx/event.h>
|
||||
#include <wx/control.h>
|
||||
#include <wx/combobox.h>
|
||||
|
||||
filenamebox::filenamebox(wxSizer* sizer, wxWindow* parent, const std::string& initial_label, int flags,
|
||||
wxEvtHandler* dispatch_to, wxObjectEventFunction on_fn_change)
|
||||
{
|
||||
wxSizer* inner = sizer;
|
||||
if(flags & FNBF_OI)
|
||||
inner = new wxFlexGridSizer(1, 3, 0, 0);
|
||||
given_flags = flags;
|
||||
last_label = initial_label;
|
||||
label = new wxStaticText(parent, wxID_ANY, towxstring(last_label));
|
||||
filename = new wxTextCtrl(parent, wxID_ANY, wxT(""), wxDefaultPosition, wxSize(500, -1));
|
||||
file_select = new wxButton(parent, wxID_ANY, wxT("..."));
|
||||
inner->Add(label, 0, wxGROW);
|
||||
inner->Add(filename, 1, wxGROW);
|
||||
inner->Add(file_select, 0, wxGROW);
|
||||
if((flags & FNBF_NN) == 0)
|
||||
filename->Connect(wxEVT_COMMAND_TEXT_UPDATED, on_fn_change, NULL, dispatch_to);
|
||||
file_select->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(filenamebox::on_file_select), NULL,
|
||||
this);
|
||||
if(flags & FNBF_SD)
|
||||
disable();
|
||||
if(flags & FNBF_OI) {
|
||||
inner->SetSizeHints(parent);
|
||||
sizer->Add(inner, 0, wxGROW);
|
||||
}
|
||||
pwindow = parent;
|
||||
enabled = ((flags & FNBF_SD) == 0);
|
||||
}
|
||||
|
||||
filenamebox::~filenamebox()
|
||||
{
|
||||
//Wxwidgets destroys the subwidgets.
|
||||
}
|
||||
|
||||
|
||||
void filenamebox::on_file_select(wxCommandEvent& e)
|
||||
{
|
||||
std::string fname;
|
||||
wxFileDialog* d = new wxFileDialog(pwindow, towxstring("Choose " + last_label), wxT("."));
|
||||
if(d->ShowModal() == wxID_CANCEL) {
|
||||
d->Destroy();
|
||||
return;
|
||||
}
|
||||
fname = tostdstring(d->GetPath());
|
||||
d->Destroy();
|
||||
if(given_flags & FNBF_PZ) {
|
||||
//Did we pick a .zip file?
|
||||
try {
|
||||
zip_reader zr(fname);
|
||||
std::vector<wxString> files;
|
||||
for(auto i : zr)
|
||||
files.push_back(towxstring(i));
|
||||
wxSingleChoiceDialog* d2 = new wxSingleChoiceDialog(pwindow, wxT("Select file within .zip"),
|
||||
wxT("Select member"), files.size(), &files[0]);
|
||||
if(d2->ShowModal() == wxID_CANCEL) {
|
||||
d2->Destroy();
|
||||
return;
|
||||
}
|
||||
fname = fname + "/" + tostdstring(d2->GetStringSelection());
|
||||
d2->Destroy();
|
||||
} catch(...) {
|
||||
//Ignore error.
|
||||
}
|
||||
}
|
||||
filename->SetValue(towxstring(fname));
|
||||
}
|
||||
|
||||
std::string filenamebox::get_file()
|
||||
{
|
||||
if(!enabled)
|
||||
return "";
|
||||
else
|
||||
return tostdstring(filename->GetValue());
|
||||
}
|
||||
|
||||
bool filenamebox::is_enabled()
|
||||
{
|
||||
return enabled;
|
||||
}
|
||||
|
||||
void filenamebox::enable(const std::string& new_label)
|
||||
{
|
||||
change_label(new_label);
|
||||
enable();
|
||||
}
|
||||
|
||||
void filenamebox::change_label(const std::string& new_label)
|
||||
{
|
||||
last_label = new_label;
|
||||
if(enabled || (given_flags & FNBF_PL))
|
||||
label->SetLabel(towxstring(last_label));
|
||||
}
|
||||
|
||||
void filenamebox::disable()
|
||||
{
|
||||
label->Disable();
|
||||
filename->Disable();
|
||||
file_select->Disable();
|
||||
if((given_flags & FNBF_PL) == 0)
|
||||
label->SetLabel(wxT(""));
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
void filenamebox::enable()
|
||||
{
|
||||
if((given_flags & FNBF_PL) == 0)
|
||||
label->SetLabel(towxstring(last_label));
|
||||
label->Enable();
|
||||
filename->Enable();
|
||||
file_select->Enable();
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
bool filenamebox::is_nonblank()
|
||||
{
|
||||
if(!enabled)
|
||||
return false;
|
||||
return (filename->GetValue().Length() != 0);
|
||||
}
|
||||
|
||||
bool filenamebox::is_nonblank_or_disabled()
|
||||
{
|
||||
if(!enabled)
|
||||
return true;
|
||||
return (filename->GetValue().Length() != 0);
|
||||
}
|
||||
|
||||
void filenamebox::clear()
|
||||
{
|
||||
filename->SetValue(wxT(""));
|
||||
}
|
44
platform/wxwidgets/src/filenamebox.hpp
Normal file
44
platform/wxwidgets/src/filenamebox.hpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
#ifndef _wxwidgets_filenamebox__hpp__included__
|
||||
#define _wxwidgets_filenamebox__hpp__included__
|
||||
|
||||
//Permanent label.
|
||||
#define FNBF_PL 1
|
||||
//Start disabled.
|
||||
#define FNBF_SD 2
|
||||
//No notification on filename change.
|
||||
#define FNBF_NN 4
|
||||
//Insert as one item.
|
||||
#define FNBF_OI 8
|
||||
//Peek inside .zip files.
|
||||
#define FNBF_PZ 16
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/event.h>
|
||||
|
||||
class filenamebox : public wxEvtHandler
|
||||
{
|
||||
public:
|
||||
filenamebox(wxSizer* sizer, wxWindow* parent, const std::string& initial_label, int flags,
|
||||
wxEvtHandler* dispatch_to, wxObjectEventFunction on_fn_change);
|
||||
~filenamebox();
|
||||
void disable();
|
||||
void enable();
|
||||
void change_label(const std::string& new_label);
|
||||
void enable(const std::string& new_label);
|
||||
bool is_enabled();
|
||||
std::string get_file();
|
||||
void on_file_select(wxCommandEvent& e);
|
||||
bool is_nonblank();
|
||||
bool is_nonblank_or_disabled();
|
||||
void clear();
|
||||
private:
|
||||
int given_flags;
|
||||
std::string last_label;
|
||||
bool enabled;
|
||||
wxStaticText* label;
|
||||
wxTextCtrl* filename;
|
||||
wxButton* file_select;
|
||||
wxWindow* pwindow;
|
||||
};
|
||||
|
||||
#endif
|
148
platform/wxwidgets/src/keyentry.cpp
Normal file
148
platform/wxwidgets/src/keyentry.cpp
Normal file
|
@ -0,0 +1,148 @@
|
|||
#include "keyentry.hpp"
|
||||
#include "common.hpp"
|
||||
#include "keymapper.hpp"
|
||||
|
||||
#define S_DONT_CARE "Ignore"
|
||||
#define S_RELEASED "Released"
|
||||
#define S_PRESSED "Pressed"
|
||||
|
||||
wx_key_entry::wx_key_entry(wxWindow* parent)
|
||||
: wxDialog(parent, wxID_ANY, wxT("Specify key"), wxDefaultPosition, wxSize(-1, -1))
|
||||
{
|
||||
std::vector<wxString> keych;
|
||||
|
||||
std::set<std::string> mods = modifier::get_set();
|
||||
std::set<std::string> keys = keygroup::get_keys();
|
||||
Centre();
|
||||
wxFlexGridSizer* top_s = new wxFlexGridSizer(2, 1, 0, 0);
|
||||
SetSizer(top_s);
|
||||
|
||||
wxFlexGridSizer* t_s = new wxFlexGridSizer(mods.size() + 1, 3, 0, 0);
|
||||
for(auto i : mods) {
|
||||
t_s->Add(new wxStaticText(this, wxID_ANY, towxstring(i)), 0, wxGROW);
|
||||
keyentry_mod_data m;
|
||||
t_s->Add(m.pressed = new wxCheckBox(this, wxID_ANY, wxT("Pressed")), 0, wxGROW);
|
||||
t_s->Add(m.unmasked = new wxCheckBox(this, wxID_ANY, wxT("Unmasked")), 0, wxGROW);
|
||||
m.pressed->Disable();
|
||||
modifiers[i] = m;
|
||||
m.pressed->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
|
||||
wxCommandEventHandler(wx_key_entry::on_change_setting), NULL, this);
|
||||
m.unmasked->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED,
|
||||
wxCommandEventHandler(wx_key_entry::on_change_setting), NULL, this);
|
||||
}
|
||||
for(auto i : keys)
|
||||
keych.push_back(towxstring(i));
|
||||
mainkey = new labeledcombobox(t_s, this, "Key", &keych[0], keych.size(), 0, true, this,
|
||||
(wxObjectEventFunction)(&wx_key_entry::on_change_setting));
|
||||
t_s->Add(new wxStaticText(this, wxID_ANY, wxT("")), 0, wxGROW);
|
||||
top_s->Add(t_s);
|
||||
|
||||
wxBoxSizer* pbutton_s = new wxBoxSizer(wxHORIZONTAL);
|
||||
pbutton_s->AddStretchSpacer();
|
||||
pbutton_s->Add(ok = new wxButton(this, wxID_OK, wxT("OK")), 0, wxGROW);
|
||||
pbutton_s->Add(cancel = new wxButton(this, wxID_CANCEL, wxT("Cancel")), 0, wxGROW);
|
||||
ok->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
wxCommandEventHandler(wx_key_entry::on_ok), NULL, this);
|
||||
cancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
wxCommandEventHandler(wx_key_entry::on_cancel), NULL, this);
|
||||
top_s->Add(pbutton_s, 0, wxGROW);
|
||||
|
||||
t_s->SetSizeHints(this);
|
||||
top_s->SetSizeHints(this);
|
||||
Fit();
|
||||
}
|
||||
|
||||
#define TMPFLAG_UNMASKED 65
|
||||
#define TMPFLAG_UNMASKED_LINK_CHILD 2
|
||||
#define TMPFLAG_UNMASKED_LINK_PARENT 68
|
||||
#define TMPFLAG_PRESSED 8
|
||||
#define TMPFLAG_PRESSED_LINK_CHILD 16
|
||||
#define TMPFLAG_PRESSED_LINK_PARENT 32
|
||||
|
||||
void wx_key_entry::on_change_setting(wxCommandEvent& e)
|
||||
{
|
||||
for(auto& i : modifiers)
|
||||
i.second.tmpflags = 0;
|
||||
for(auto& i : modifiers) {
|
||||
modifier* m = NULL;
|
||||
try {
|
||||
m = &modifier::lookup(i.first);
|
||||
} catch(...) {
|
||||
i.second.pressed->Disable();
|
||||
i.second.unmasked->Disable();
|
||||
continue;
|
||||
}
|
||||
std::string j = m->linked_name();
|
||||
if(i.second.unmasked->GetValue())
|
||||
i.second.tmpflags |= TMPFLAG_UNMASKED;
|
||||
if(j != "") {
|
||||
if(modifiers[j].unmasked->GetValue())
|
||||
i.second.tmpflags |= TMPFLAG_UNMASKED_LINK_PARENT;
|
||||
if(i.second.unmasked->GetValue())
|
||||
modifiers[j].tmpflags |= TMPFLAG_UNMASKED_LINK_CHILD;
|
||||
}
|
||||
if(i.second.pressed->GetValue())
|
||||
i.second.tmpflags |= TMPFLAG_PRESSED;
|
||||
if(j != "") {
|
||||
if(modifiers[j].pressed->GetValue())
|
||||
i.second.tmpflags |= TMPFLAG_PRESSED_LINK_PARENT;
|
||||
if(i.second.pressed->GetValue())
|
||||
modifiers[j].tmpflags |= TMPFLAG_PRESSED_LINK_CHILD;
|
||||
}
|
||||
}
|
||||
for(auto& i : modifiers) {
|
||||
//Unmasked is to be enabled if neither unmasked link flag is set.
|
||||
if(i.second.tmpflags & ((TMPFLAG_UNMASKED_LINK_CHILD | TMPFLAG_UNMASKED_LINK_PARENT) & ~64)) {
|
||||
i.second.unmasked->SetValue(false);
|
||||
i.second.unmasked->Disable();
|
||||
} else
|
||||
i.second.unmasked->Enable();
|
||||
//Pressed is to be enabled if:
|
||||
//- This modifier is unmasked or parent is unmasked.
|
||||
//- Parent nor child is not pressed.
|
||||
if(((i.second.tmpflags & (TMPFLAG_UNMASKED | TMPFLAG_UNMASKED_LINK_PARENT | TMPFLAG_PRESSED_LINK_CHILD |
|
||||
TMPFLAG_PRESSED_LINK_PARENT)) & 112) == 64)
|
||||
i.second.pressed->Enable();
|
||||
else {
|
||||
i.second.pressed->SetValue(false);
|
||||
i.second.pressed->Disable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wx_key_entry::on_ok(wxCommandEvent& e)
|
||||
{
|
||||
EndModal(wxID_OK);
|
||||
}
|
||||
|
||||
void wx_key_entry::on_cancel(wxCommandEvent& e)
|
||||
{
|
||||
EndModal(wxID_CANCEL);
|
||||
}
|
||||
|
||||
std::string wx_key_entry::getkey()
|
||||
{
|
||||
std::string x;
|
||||
bool f;
|
||||
f = true;
|
||||
for(auto i : modifiers) {
|
||||
if(i.second.pressed->GetValue()) {
|
||||
if(!f)
|
||||
x = x + ",";
|
||||
f = false;
|
||||
x = x + i.first;
|
||||
}
|
||||
}
|
||||
x = x + "/";
|
||||
f = true;
|
||||
for(auto i : modifiers) {
|
||||
if(i.second.unmasked->GetValue()) {
|
||||
if(!f)
|
||||
x = x + ",";
|
||||
f = false;
|
||||
x = x + i.first;
|
||||
}
|
||||
}
|
||||
x = x + "|" + mainkey->get_choice();
|
||||
return x;
|
||||
}
|
35
platform/wxwidgets/src/keyentry.hpp
Normal file
35
platform/wxwidgets/src/keyentry.hpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
#ifndef _wxwidgets_keyentry__hpp__included__
|
||||
#define _wxwidgets_keyentry__hpp__included__
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/event.h>
|
||||
#include <wx/control.h>
|
||||
#include <wx/combobox.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "window.hpp"
|
||||
#include "labelcombobox.hpp"
|
||||
|
||||
struct keyentry_mod_data
|
||||
{
|
||||
wxCheckBox* pressed;
|
||||
wxCheckBox* unmasked;
|
||||
unsigned tmpflags;
|
||||
};
|
||||
|
||||
class wx_key_entry : public wxDialog
|
||||
{
|
||||
public:
|
||||
wx_key_entry(wxWindow* parent);
|
||||
void on_change_setting(wxCommandEvent& e);
|
||||
void on_ok(wxCommandEvent& e);
|
||||
void on_cancel(wxCommandEvent& e);
|
||||
std::string getkey();
|
||||
private:
|
||||
std::map<std::string, keyentry_mod_data> modifiers;
|
||||
labeledcombobox* mainkey;
|
||||
wxButton* ok;
|
||||
wxButton* cancel;
|
||||
};
|
||||
|
||||
#endif
|
48
platform/wxwidgets/src/labelcombobox.cpp
Normal file
48
platform/wxwidgets/src/labelcombobox.cpp
Normal file
|
@ -0,0 +1,48 @@
|
|||
#include "labelcombobox.hpp"
|
||||
#include "command.hpp"
|
||||
|
||||
labeledcombobox::labeledcombobox(wxSizer* sizer, wxWindow* parent, const std::string& label, wxString* choices,
|
||||
size_t choice_count, size_t defaultidx, bool start_enabled, wxEvtHandler* dispatch_to,
|
||||
wxObjectEventFunction on_fn_change)
|
||||
{
|
||||
sizer->Add(new wxStaticText(parent, wxID_ANY, towxstring(label)), 0, wxGROW);
|
||||
sizer->Add(combo = new wxComboBox(parent, wxID_ANY, choices[defaultidx], wxDefaultPosition, wxDefaultSize,
|
||||
choice_count, choices, wxCB_READONLY), 0, wxGROW);
|
||||
if(dispatch_to)
|
||||
combo->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, on_fn_change, NULL, dispatch_to);
|
||||
combo->Enable(start_enabled);
|
||||
enabled = start_enabled;
|
||||
forced = false;
|
||||
}
|
||||
|
||||
std::string labeledcombobox::get_choice()
|
||||
{
|
||||
return tostdstring(combo->GetValue());
|
||||
}
|
||||
|
||||
void labeledcombobox::enable()
|
||||
{
|
||||
if(forced && !enabled)
|
||||
combo->SetValue(remembered);
|
||||
combo->Enable();
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
void labeledcombobox::disable(const wxString& choice)
|
||||
{
|
||||
combo->Disable();
|
||||
if(enabled)
|
||||
remembered = combo->GetValue();
|
||||
combo->SetValue(choice);
|
||||
enabled = false;
|
||||
forced = true;
|
||||
}
|
||||
|
||||
void labeledcombobox::disable()
|
||||
{
|
||||
combo->Disable();
|
||||
if(enabled)
|
||||
remembered = combo->GetValue();
|
||||
enabled = false;
|
||||
forced = false;
|
||||
}
|
31
platform/wxwidgets/src/labelcombobox.hpp
Normal file
31
platform/wxwidgets/src/labelcombobox.hpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef _labelcombobox__hpp__included__
|
||||
#define _labelcombobox__hpp__included__
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/event.h>
|
||||
#include <wx/control.h>
|
||||
#include <wx/combobox.h>
|
||||
#include <wx/string.h>
|
||||
#include "filenamebox.hpp"
|
||||
#include "common.hpp"
|
||||
#include <string>
|
||||
|
||||
class labeledcombobox
|
||||
{
|
||||
public:
|
||||
labeledcombobox(wxSizer* sizer, wxWindow* parent, const std::string& label, wxString* choices,
|
||||
size_t choice_count, size_t defaultidx, bool start_enabled, wxEvtHandler* dispatch_to,
|
||||
wxObjectEventFunction on_fn_change);
|
||||
std::string get_choice();
|
||||
void enable();
|
||||
void disable(const wxString& choice);
|
||||
void disable();
|
||||
private:
|
||||
wxStaticText* label;
|
||||
wxComboBox* combo;
|
||||
wxString remembered;
|
||||
bool enabled;
|
||||
bool forced;
|
||||
};
|
||||
|
||||
#endif
|
143
platform/wxwidgets/src/messages_window.cpp
Normal file
143
platform/wxwidgets/src/messages_window.cpp
Normal file
|
@ -0,0 +1,143 @@
|
|||
#include "messages_window.hpp"
|
||||
#include "window.hpp"
|
||||
#include "emufn.hpp"
|
||||
|
||||
|
||||
#define MAXMESSAGES 20
|
||||
|
||||
class wx_message_panel : public wxPanel
|
||||
{
|
||||
public:
|
||||
wx_message_panel(unsigned lines);
|
||||
void on_paint(wxPaintEvent& e);
|
||||
};
|
||||
|
||||
wx_messages_window* wx_messages_window::ptr;
|
||||
|
||||
wx_message_panel::wx_message_panel(unsigned lines)
|
||||
: wxPanel(wx_messages_window::ptr)
|
||||
{
|
||||
wxMemoryDC d;
|
||||
wxSize s = d.GetTextExtent(wxT("MMMMMM"));
|
||||
SetMinSize(wxSize(12 * s.x, lines * s.y));
|
||||
this->Connect(wxEVT_PAINT, wxPaintEventHandler(wx_message_panel::on_paint), NULL, this);
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
wx_message_panel* mpanel;
|
||||
}
|
||||
|
||||
wx_messages_window::wx_messages_window()
|
||||
: wxFrame(NULL, wxID_ANY, wxT("lsnes: Messages"), wxDefaultPosition, wxSize(-1, -1), secondary_window_style)
|
||||
{
|
||||
ptr = this;
|
||||
wxFlexGridSizer* top_s = new wxFlexGridSizer(3, 1, 0, 0);
|
||||
top_s->Add(mpanel = new wx_message_panel(MAXMESSAGES));
|
||||
window::msgbuf.set_max_window_size(MAXMESSAGES);
|
||||
|
||||
wxFlexGridSizer* buttons_s = new wxFlexGridSizer(1, 6, 0, 0);
|
||||
wxButton* beginning, * pageup, * lineup, * linedown, * pagedown, * end;
|
||||
buttons_s->Add(beginning = new wxButton(this, wxID_ANY, wxT("Beginning")), 1, wxGROW);
|
||||
buttons_s->Add(pageup = new wxButton(this, wxID_ANY, wxT("Page Up")), 1, wxGROW);
|
||||
buttons_s->Add(lineup = new wxButton(this, wxID_ANY, wxT("Line Up")), 1, wxGROW);
|
||||
buttons_s->Add(linedown = new wxButton(this, wxID_ANY, wxT("Line Down")), 1, wxGROW);
|
||||
buttons_s->Add(pagedown = new wxButton(this, wxID_ANY, wxT("Page Down")), 1, wxGROW);
|
||||
buttons_s->Add(end = new wxButton(this, wxID_ANY, wxT("End")), 1, wxGROW);
|
||||
beginning->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(wx_messages_window::on_scroll_home),
|
||||
NULL, this);
|
||||
pageup->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(wx_messages_window::on_scroll_pageup),
|
||||
NULL, this);
|
||||
lineup->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(wx_messages_window::on_scroll_lineup),
|
||||
NULL, this);
|
||||
linedown->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(wx_messages_window::on_scroll_linedown),
|
||||
NULL, this);
|
||||
pagedown->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(wx_messages_window::on_scroll_pagedown),
|
||||
NULL, this);
|
||||
end->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(wx_messages_window::on_scroll_end),
|
||||
NULL, this);
|
||||
top_s->Add(buttons_s, 0, wxGROW);
|
||||
|
||||
wxBoxSizer* cmd_s = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxButton* execute;
|
||||
cmd_s->Add(command = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize,
|
||||
wxTE_PROCESS_ENTER), 1, wxEXPAND);
|
||||
cmd_s->Add(execute = new wxButton(this, wxID_ANY, wxT("Execute")), 0, wxGROW);
|
||||
command->Connect(wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(wx_messages_window::on_execute),
|
||||
NULL, this);
|
||||
execute->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(wx_messages_window::on_execute),
|
||||
NULL, this);
|
||||
cmd_s->SetSizeHints(this);
|
||||
top_s->Add(cmd_s, 0, wxGROW);
|
||||
|
||||
top_s->SetSizeHints(this);
|
||||
SetSizer(top_s);
|
||||
Fit();
|
||||
}
|
||||
|
||||
wx_messages_window::~wx_messages_window()
|
||||
{
|
||||
ptr = NULL;
|
||||
}
|
||||
|
||||
void wx_message_panel::on_paint(wxPaintEvent& e)
|
||||
{
|
||||
wxPaintDC dc(this);
|
||||
dc.Clear();
|
||||
int y = 0;
|
||||
size_t lines = window::msgbuf.get_visible_count();
|
||||
size_t first = window::msgbuf.get_visible_first();
|
||||
for(size_t i = 0; i < lines; i++) {
|
||||
wxSize s = dc.GetTextExtent(towxstring(window::msgbuf.get_message(first + i)));
|
||||
dc.DrawText(towxstring(window::msgbuf.get_message(first + i)), 0, y);
|
||||
y += s.y;
|
||||
}
|
||||
}
|
||||
|
||||
void wx_messages_window::on_scroll_home(wxCommandEvent& e)
|
||||
{
|
||||
window::msgbuf.scroll_beginning();
|
||||
}
|
||||
|
||||
void wx_messages_window::on_scroll_pageup(wxCommandEvent& e)
|
||||
{
|
||||
window::msgbuf.scroll_up_page();
|
||||
}
|
||||
|
||||
void wx_messages_window::on_scroll_lineup(wxCommandEvent& e)
|
||||
{
|
||||
window::msgbuf.scroll_up_line();
|
||||
}
|
||||
|
||||
void wx_messages_window::on_scroll_linedown(wxCommandEvent& e)
|
||||
{
|
||||
window::msgbuf.scroll_down_line();
|
||||
}
|
||||
|
||||
void wx_messages_window::on_scroll_pagedown(wxCommandEvent& e)
|
||||
{
|
||||
window::msgbuf.scroll_down_page();
|
||||
}
|
||||
|
||||
void wx_messages_window::on_scroll_end(wxCommandEvent& e)
|
||||
{
|
||||
window::msgbuf.scroll_end();
|
||||
}
|
||||
|
||||
void wx_messages_window::on_execute(wxCommandEvent& e)
|
||||
{
|
||||
std::string cmd = tostdstring(command->GetValue());
|
||||
if(cmd == "")
|
||||
return;
|
||||
exec_command(cmd);
|
||||
}
|
||||
|
||||
void wx_messages_window::notify_message()
|
||||
{
|
||||
mpanel->Refresh();
|
||||
}
|
||||
|
||||
bool wx_messages_window::ShouldPreventAppExit() const
|
||||
{
|
||||
return false;
|
||||
}
|
30
platform/wxwidgets/src/messages_window.hpp
Normal file
30
platform/wxwidgets/src/messages_window.hpp
Normal file
|
@ -0,0 +1,30 @@
|
|||
#ifndef _wxwidgets_messages_window__hpp__included__
|
||||
#define _wxwidgets_messages_window__hpp__included__
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/event.h>
|
||||
#include <wx/control.h>
|
||||
#include <wx/combobox.h>
|
||||
#include "filenamebox.hpp"
|
||||
#include "common.hpp"
|
||||
|
||||
class wx_messages_window : public wxFrame
|
||||
{
|
||||
public:
|
||||
wx_messages_window();
|
||||
~wx_messages_window();
|
||||
bool ShouldPreventAppExit() const;
|
||||
static wx_messages_window* ptr;
|
||||
void notify_message();
|
||||
void on_scroll_home(wxCommandEvent& e);
|
||||
void on_scroll_pageup(wxCommandEvent& e);
|
||||
void on_scroll_lineup(wxCommandEvent& e);
|
||||
void on_scroll_linedown(wxCommandEvent& e);
|
||||
void on_scroll_pagedown(wxCommandEvent& e);
|
||||
void on_scroll_end(wxCommandEvent& e);
|
||||
void on_execute(wxCommandEvent& e);
|
||||
private:
|
||||
wxTextCtrl* command;
|
||||
};
|
||||
|
||||
#endif
|
252
platform/wxwidgets/src/project_select_window.cpp
Normal file
252
platform/wxwidgets/src/project_select_window.cpp
Normal file
|
@ -0,0 +1,252 @@
|
|||
#include "lsnes.hpp"
|
||||
#include <snes/snes.hpp>
|
||||
#include <ui-libsnes/libsnes.hpp>
|
||||
#include "project_select_window.hpp"
|
||||
#include "common.hpp"
|
||||
#include "zip.hpp"
|
||||
#include "moviedata.hpp"
|
||||
#include "emufn.hpp"
|
||||
#include <stdexcept>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
std::string sram_name(const nall::string& _id, SNES::Cartridge::Slot slotname)
|
||||
{
|
||||
std::string id(_id, _id.length());
|
||||
if(slotname == SNES::Cartridge::Slot::SufamiTurboA)
|
||||
return "slota." + id.substr(1);
|
||||
if(slotname == SNES::Cartridge::Slot::SufamiTurboB)
|
||||
return "slotb." + id.substr(1);
|
||||
return id.substr(1);
|
||||
}
|
||||
|
||||
porttype_t get_controller_type(const std::string& s)
|
||||
{
|
||||
if(s == CNAME_NONE)
|
||||
return PT_NONE;
|
||||
if(s == CNAME_GAMEPAD)
|
||||
return PT_GAMEPAD;
|
||||
if(s == CNAME_MULTITAP)
|
||||
return PT_MULTITAP;
|
||||
if(s == CNAME_MOUSE)
|
||||
return PT_MOUSE;
|
||||
if(s == CNAME_SUPERSCOPE)
|
||||
return PT_SUPERSCOPE;
|
||||
if(s == CNAME_JUSTIFIER)
|
||||
return PT_JUSTIFIER;
|
||||
if(s == CNAME_JUSTIFIERS)
|
||||
return PT_JUSTIFIERS;
|
||||
return PT_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
wx_project_select_window::wx_project_select_window(loaded_rom& rom)
|
||||
: wxFrame(NULL, wxID_ANY, wxT("Project settings"), wxDefaultPosition, wxSize(-1, -1),
|
||||
primary_window_style)
|
||||
{
|
||||
our_rom = &rom;
|
||||
wxString cchoices[7];
|
||||
cchoices[0] = wxT(CNAME_NONE);
|
||||
cchoices[1] = wxT(CNAME_GAMEPAD);
|
||||
cchoices[2] = wxT(CNAME_MULTITAP);
|
||||
cchoices[3] = wxT(CNAME_MOUSE);
|
||||
cchoices[4] = wxT(CNAME_SUPERSCOPE);
|
||||
cchoices[5] = wxT(CNAME_JUSTIFIER);
|
||||
cchoices[6] = wxT(CNAME_JUSTIFIERS);
|
||||
|
||||
std::set<std::string> sram_set = get_sram_set();
|
||||
|
||||
Centre();
|
||||
wxFlexGridSizer* top_s = new wxFlexGridSizer(7 + sram_set.size(), 1, 0, 0);
|
||||
SetSizer(top_s);
|
||||
|
||||
wxRadioButton* file = new wxRadioButton(this, wxID_ANY, wxT("Load movie/savestate"), wxDefaultPosition,
|
||||
wxDefaultSize, wxRB_GROUP);
|
||||
wxRadioButton* newp = new wxRadioButton(this, wxID_ANY, wxT("New project"));
|
||||
file->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
|
||||
wxCommandEventHandler(wx_project_select_window::on_file_select), NULL, this);
|
||||
newp->Connect(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
|
||||
wxCommandEventHandler(wx_project_select_window::on_new_select), NULL, this);
|
||||
top_s->Add(file, 0, wxGROW);
|
||||
top_s->Add(newp, 0, wxGROW);
|
||||
load_file = true;
|
||||
|
||||
filename = new filenamebox(top_s, this, "Movie/Savestate", FNBF_PL | FNBF_OI, this,
|
||||
wxCommandEventHandler(wx_project_select_window::on_filename_change));
|
||||
|
||||
wxFlexGridSizer* c_s = new wxFlexGridSizer(4, 2, 0, 0);
|
||||
controller1type = new labeledcombobox(c_s, this, "Controller 1 type:", cchoices, 4, 1, false, this,
|
||||
wxCommandEventHandler(wx_project_select_window::on_filename_change));
|
||||
controller2type = new labeledcombobox(c_s, this, "Controller 2 type:", cchoices, 7, 0, false, this,
|
||||
wxCommandEventHandler(wx_project_select_window::on_filename_change));
|
||||
c_s->Add(new wxStaticText(this, wxID_ANY, wxT("Initial RTC:")), 0, wxGROW);
|
||||
wxFlexGridSizer* t_s = new wxFlexGridSizer(1, 3, 0, 0);
|
||||
t_s->Add(rtc_sec = new wxTextCtrl(this, wxID_ANY, wxT("1000000000"), wxDefaultPosition, wxSize(150, -1)), 1,
|
||||
wxGROW);
|
||||
t_s->Add(new wxStaticText(this, wxID_ANY, wxT(":")), 0, wxGROW);
|
||||
t_s->Add(rtc_subsec = new wxTextCtrl(this, wxID_ANY, wxT("0"), wxDefaultPosition, wxSize(120, -1)), 0, wxGROW);
|
||||
rtc_sec->Connect(wxEVT_COMMAND_TEXT_UPDATED,
|
||||
wxCommandEventHandler(wx_project_select_window::on_filename_change), NULL, this);
|
||||
rtc_subsec->Connect(wxEVT_COMMAND_TEXT_UPDATED,
|
||||
wxCommandEventHandler(wx_project_select_window::on_filename_change), NULL, this);
|
||||
c_s->Add(t_s, 0, wxGROW);
|
||||
top_s->Add(c_s, 0, wxGROW);
|
||||
c_s->Add(new wxStaticText(this, wxID_ANY, wxT("Game name:")), 0, wxGROW);
|
||||
c_s->Add(projectname = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxSize(400, -1)), 1, wxGROW);
|
||||
|
||||
top_s->Add(new wxStaticText(this, wxID_ANY, wxT("Authors (one per line):")), 0, wxGROW);
|
||||
top_s->Add(authors = new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize,
|
||||
wxTE_MULTILINE), 0, wxGROW);
|
||||
authors->Connect(wxEVT_COMMAND_TEXT_UPDATED,
|
||||
wxCommandEventHandler(wx_project_select_window::on_filename_change), NULL, this);
|
||||
|
||||
for(auto i : sram_set)
|
||||
srams[i] = new filenamebox(top_s, this, "SRAM " + i + ":" , FNBF_PL | FNBF_OI, this,
|
||||
wxCommandEventHandler(wx_project_select_window::on_filename_change));
|
||||
|
||||
wxBoxSizer* pbutton_s = new wxBoxSizer(wxHORIZONTAL);
|
||||
pbutton_s->AddStretchSpacer();
|
||||
pbutton_s->Add(load = new wxButton(this, wxID_ANY, wxT("Load")), 0, wxGROW);
|
||||
pbutton_s->Add(quit = new wxButton(this, wxID_EXIT, wxT("Quit")), 0, wxGROW);
|
||||
load->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
wxCommandEventHandler(wx_project_select_window::on_load), NULL, this);
|
||||
quit->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
wxCommandEventHandler(wx_project_select_window::on_quit), NULL, this);
|
||||
top_s->Add(pbutton_s, 0, wxGROW);
|
||||
|
||||
wxCommandEvent e;
|
||||
on_file_select(e);
|
||||
|
||||
t_s->SetSizeHints(this);
|
||||
c_s->SetSizeHints(this);
|
||||
top_s->SetSizeHints(this);
|
||||
Fit();
|
||||
}
|
||||
|
||||
wx_project_select_window::~wx_project_select_window()
|
||||
{
|
||||
delete controller1type;
|
||||
delete controller2type;
|
||||
delete filename;
|
||||
}
|
||||
|
||||
void wx_project_select_window::on_file_select(wxCommandEvent& e)
|
||||
{
|
||||
filename->enable();
|
||||
controller1type->disable();
|
||||
controller2type->disable();
|
||||
rtc_sec->Disable();
|
||||
rtc_subsec->Disable();
|
||||
projectname->Disable();
|
||||
authors->Disable();
|
||||
load->SetLabel(wxT("Load"));
|
||||
on_filename_change(e);
|
||||
load_file = true;
|
||||
for(auto i : srams)
|
||||
i.second->disable();
|
||||
}
|
||||
|
||||
void wx_project_select_window::on_new_select(wxCommandEvent& e)
|
||||
{
|
||||
filename->disable();
|
||||
controller1type->enable();
|
||||
controller2type->enable();
|
||||
rtc_sec->Enable();
|
||||
rtc_subsec->Enable();
|
||||
projectname->Enable();
|
||||
authors->Enable();
|
||||
load->SetLabel(wxT("Start"));
|
||||
on_filename_change(e);
|
||||
load_file = false;
|
||||
for(auto i : srams)
|
||||
i.second->enable();
|
||||
}
|
||||
|
||||
void wx_project_select_window::on_filename_change(wxCommandEvent& e)
|
||||
{
|
||||
if(filename->is_enabled()) {
|
||||
load->Enable(filename->is_nonblank());
|
||||
} else {
|
||||
try {
|
||||
boost::lexical_cast<int64_t>(tostdstring(rtc_sec->GetValue()));
|
||||
if(boost::lexical_cast<int64_t>(tostdstring(rtc_subsec->GetValue())) < 0)
|
||||
throw 42;
|
||||
size_t lines = authors->GetNumberOfLines();
|
||||
for(size_t i = 0; i < lines; i++) {
|
||||
std::string l = tostdstring(authors->GetLineText(i));
|
||||
if(l == "|")
|
||||
throw 43;
|
||||
}
|
||||
load->Enable();
|
||||
} catch(...) {
|
||||
load->Disable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wx_project_select_window::on_quit(wxCommandEvent& e)
|
||||
{
|
||||
Close(true);
|
||||
}
|
||||
|
||||
void wx_project_select_window::on_load(wxCommandEvent& e)
|
||||
{
|
||||
try {
|
||||
if(load_file) {
|
||||
boot_emulator(*our_rom, *new moviefile(filename->get_file()));
|
||||
} else {
|
||||
boot_emulator(*our_rom, *new moviefile(make_movie()));
|
||||
}
|
||||
Destroy();
|
||||
} catch(std::exception& e) {
|
||||
wxMessageDialog* d = new wxMessageDialog(this, towxstring(e.what()),
|
||||
wxT("Error loading movie"), wxOK | wxICON_EXCLAMATION);
|
||||
d->ShowModal();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::set<std::string> wx_project_select_window::get_sram_set()
|
||||
{
|
||||
std::set<std::string> r;
|
||||
for(unsigned i = 0; i < SNES::cartridge.nvram.size(); i++) {
|
||||
SNES::Cartridge::NonVolatileRAM& s = SNES::cartridge.nvram[i];
|
||||
r.insert(sram_name(s.id, s.slot));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
struct moviefile wx_project_select_window::make_movie()
|
||||
{
|
||||
moviefile f;
|
||||
f.force_corrupt = false;
|
||||
f.gametype = gtype::togametype(our_rom->rtype, our_rom->region);
|
||||
f.port1 = get_controller_type(controller1type->get_choice());
|
||||
f.port2 = get_controller_type(controller2type->get_choice());
|
||||
f.coreversion = bsnes_core_version;
|
||||
f.gamename = tostdstring(projectname->GetValue());
|
||||
f.projectid = get_random_hexstring(40);
|
||||
f.rerecords = "0";
|
||||
f.rom_sha256 = our_rom->rom.sha256;
|
||||
f.romxml_sha256 = our_rom->rom_xml.sha256;
|
||||
f.slota_sha256 = our_rom->slota.sha256;
|
||||
f.slotaxml_sha256 = our_rom->slota_xml.sha256;
|
||||
f.slotb_sha256 = our_rom->slotb.sha256;
|
||||
f.slotbxml_sha256 = our_rom->slotb_xml.sha256;
|
||||
size_t lines = authors->GetNumberOfLines();
|
||||
for(size_t i = 0; i < lines; i++) {
|
||||
std::string l = tostdstring(authors->GetLineText(i));
|
||||
if(l != "" && l != "|")
|
||||
f.authors.push_back(split_author(l));
|
||||
}
|
||||
for(auto i : srams)
|
||||
if(i.second->get_file() != "")
|
||||
f.movie_sram[i.first] = read_file_relative(i.second->get_file(), "");
|
||||
f.is_savestate = false;
|
||||
f.movie_rtc_second = f.rtc_second = boost::lexical_cast<int64_t>(tostdstring(rtc_sec->GetValue()));
|
||||
f.movie_rtc_subsecond = f.rtc_subsecond = boost::lexical_cast<int64_t>(tostdstring(rtc_subsec->GetValue()));
|
||||
if(f.movie_rtc_subsecond < 0)
|
||||
throw std::runtime_error("RTC subsecond must be positive");
|
||||
return f;
|
||||
}
|
43
platform/wxwidgets/src/project_select_window.hpp
Normal file
43
platform/wxwidgets/src/project_select_window.hpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
#ifndef _wxwidgets_project_select_window__hpp__included__
|
||||
#define _wxwidgets_project_select_window__hpp__included__
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/event.h>
|
||||
#include <wx/control.h>
|
||||
#include <wx/combobox.h>
|
||||
#include "filenamebox.hpp"
|
||||
#include "rom.hpp"
|
||||
#include "moviefile.hpp"
|
||||
#include "labelcombobox.hpp"
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
class wx_project_select_window : public wxFrame
|
||||
{
|
||||
public:
|
||||
wx_project_select_window(loaded_rom& rom);
|
||||
~wx_project_select_window();
|
||||
void on_file_select(wxCommandEvent& e);
|
||||
void on_new_select(wxCommandEvent& e);
|
||||
void on_filename_change(wxCommandEvent& e);
|
||||
void on_quit(wxCommandEvent& e);
|
||||
void on_load(wxCommandEvent& e);
|
||||
loaded_rom* our_rom;
|
||||
private:
|
||||
bool load_file;
|
||||
std::set<std::string> get_sram_set();
|
||||
struct moviefile make_movie();
|
||||
filenamebox* filename;
|
||||
std::map<std::string, filenamebox*> srams;
|
||||
labeledcombobox* controller1type;
|
||||
labeledcombobox* controller2type;
|
||||
wxTextCtrl* projectname;
|
||||
wxTextCtrl* rtc_sec;
|
||||
wxTextCtrl* rtc_subsec;
|
||||
wxTextCtrl* authors;
|
||||
wxButton* load;
|
||||
wxButton* quit;
|
||||
};
|
||||
|
||||
#endif
|
159
platform/wxwidgets/src/rom_patch_window.cpp
Normal file
159
platform/wxwidgets/src/rom_patch_window.cpp
Normal file
|
@ -0,0 +1,159 @@
|
|||
#include "lsnes.hpp"
|
||||
#include <snes/snes.hpp>
|
||||
#include <ui-libsnes/libsnes.hpp>
|
||||
#include "rom_patch_window.hpp"
|
||||
#include "project_select_window.hpp"
|
||||
#include "callrom.hpp"
|
||||
#include "zip.hpp"
|
||||
#include "framerate.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
class my_interfaced : public SNES::Interface
|
||||
{
|
||||
string path(SNES::Cartridge::Slot slot, const string &hint)
|
||||
{
|
||||
return "./";
|
||||
}
|
||||
} simple_interface;
|
||||
}
|
||||
|
||||
wx_rom_patch_window::wx_rom_patch_window(loaded_rom& rom)
|
||||
: wxFrame(NULL, wxID_ANY, wxT("Patch ROM"), wxDefaultPosition, wxSize(-1, -1),
|
||||
primary_window_style)
|
||||
{
|
||||
our_rom = &rom;
|
||||
size_t target_count = fill_rom_names(rom.rtype, targets);
|
||||
|
||||
Centre();
|
||||
wxFlexGridSizer* top_s = new wxFlexGridSizer(5, 1, 0, 0);
|
||||
SetSizer(top_s);
|
||||
|
||||
wxFlexGridSizer* checksums_s = new wxFlexGridSizer(target_count, 2, 0, 0);
|
||||
for(unsigned i = 0; i < 6; i++)
|
||||
checksums[i] = NULL;
|
||||
for(unsigned i = 0; i < target_count; i++) {
|
||||
checksums_s->Add(new wxStaticText(this, wxID_ANY, targets[i]), 0, wxGROW);
|
||||
checksums_s->Add(checksums[i] = new wxStaticText(this, wxID_ANY,
|
||||
towxstring(get_rom_slot(*our_rom, i).sha256)), 0, wxGROW);
|
||||
}
|
||||
top_s->Add(checksums_s, 0, wxGROW);
|
||||
|
||||
wxFlexGridSizer* pwhat_s = new wxFlexGridSizer(1, 2, 0, 0);
|
||||
pwhat_s->Add(new wxStaticText(this, wxID_ANY, wxT("Patch what:")), 0, wxGROW);
|
||||
pwhat_s->Add(patch_what = new wxComboBox(this, wxID_ANY, targets[0], wxDefaultPosition, wxDefaultSize,
|
||||
target_count, targets, wxCB_READONLY), 0, wxGROW);
|
||||
top_s->Add(pwhat_s, 0, wxGROW);
|
||||
|
||||
patchfile = new filenamebox(top_s, this, "Patch file", FNBF_PL | FNBF_OI | FNBF_PZ, this,
|
||||
wxCommandEventHandler(wx_rom_patch_window::on_patchfile_change));
|
||||
|
||||
wxFlexGridSizer* poffset_s = new wxFlexGridSizer(1, 2, 0, 0);
|
||||
pwhat_s->Add(new wxStaticText(this, wxID_ANY, wxT("Patch offset:")), 0, wxGROW);
|
||||
pwhat_s->Add(patch_offset = new wxTextCtrl(this, wxID_ANY, wxT("")), 0, wxGROW);
|
||||
patch_offset->Connect(wxEVT_COMMAND_TEXT_UPDATED,
|
||||
wxCommandEventHandler(wx_rom_patch_window::on_patchfile_change), NULL, this);
|
||||
top_s->Add(poffset_s, 0, wxGROW);
|
||||
|
||||
wxBoxSizer* pbutton_s = new wxBoxSizer(wxHORIZONTAL);
|
||||
pbutton_s->AddStretchSpacer();
|
||||
wxButton* thats_enough = new wxButton(this, wxID_ANY, wxT("Enough"));
|
||||
pbutton_s->Add(thats_enough, 0, wxGROW);
|
||||
thats_enough->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
wxCommandEventHandler(wx_rom_patch_window::on_done), NULL, this);
|
||||
dopatch = new wxButton(this, wxID_ANY, wxT("Patch"));
|
||||
pbutton_s->Add(dopatch, 0, wxGROW);
|
||||
dopatch->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
wxCommandEventHandler(wx_rom_patch_window::on_do_patch), NULL, this);
|
||||
dopatch->Disable();
|
||||
wxButton* quitbutton = new wxButton(this, wxID_EXIT, wxT("Quit"));
|
||||
pbutton_s->Add(quitbutton, 0, wxGROW);
|
||||
quitbutton->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
wxCommandEventHandler(wx_rom_patch_window::on_quit), NULL, this);
|
||||
top_s->Add(pbutton_s, 0, wxGROW);
|
||||
|
||||
patch_offset->SetValue(wxT("0"));
|
||||
|
||||
checksums_s->SetSizeHints(this);
|
||||
pwhat_s->SetSizeHints(this);
|
||||
pbutton_s->SetSizeHints(this);
|
||||
top_s->SetSizeHints(this);
|
||||
Fit();
|
||||
}
|
||||
|
||||
wx_rom_patch_window::~wx_rom_patch_window()
|
||||
{
|
||||
delete patchfile;
|
||||
}
|
||||
|
||||
void wx_rom_patch_window::on_patchfile_change(wxCommandEvent& e)
|
||||
{
|
||||
//std::cerr << "wx_rom_patch_window::on_patchfile_change" << std::endl;
|
||||
bool ok = true;
|
||||
//std::cerr << "wx_rom_patch_window::on_patchfile_change: #1: ok=" << ok << std::endl;
|
||||
ok = ok && patchfile->is_nonblank();
|
||||
//std::cerr << "wx_rom_patch_window::on_patchfile_change: #2: ok=" << ok << std::endl;
|
||||
std::string offsetv = tostdstring(patch_offset->GetValue());
|
||||
try {
|
||||
int32_t offset = boost::lexical_cast<int32_t>(offsetv);
|
||||
} catch(...) {
|
||||
ok = false;
|
||||
}
|
||||
//std::cerr << "wx_rom_patch_window::on_patchfile_change: #3: ok=" << ok << std::endl;
|
||||
if(dopatch) {
|
||||
//std::cerr << "wx_rom_patch_window::on_patchfile_change: #4: ok=" << ok << std::endl;
|
||||
dopatch->Enable(ok);
|
||||
}
|
||||
//std::cerr << "wx_rom_patch_window::on_patchfile_change: #5: ok=" << ok << std::endl;
|
||||
}
|
||||
|
||||
void wx_rom_patch_window::on_do_patch(wxCommandEvent& e)
|
||||
{
|
||||
try {
|
||||
auto patch_contents = read_file_relative(patchfile->get_file(), "");
|
||||
size_t patch_index = romname_to_index(our_rom->rtype, patch_what->GetValue());
|
||||
if(patch_index == 6)
|
||||
throw std::runtime_error("Internal error: Patch WHAT?");
|
||||
loaded_slot& s = get_rom_slot(*our_rom, patch_index);
|
||||
std::string offsetv = tostdstring(patch_offset->GetValue());
|
||||
int32_t offset = boost::lexical_cast<int32_t>(offsetv);
|
||||
s.patch(patch_contents, offset);
|
||||
checksums[patch_index]->SetLabel(towxstring(s.sha256));
|
||||
} catch(std::exception& e) {
|
||||
wxMessageDialog* d = new wxMessageDialog(this, towxstring(e.what()),
|
||||
wxT("Error patching ROM"), wxOK | wxICON_EXCLAMATION);
|
||||
d->ShowModal();
|
||||
return;
|
||||
}
|
||||
patchfile->clear();
|
||||
}
|
||||
|
||||
void wx_rom_patch_window::on_quit(wxCommandEvent& e)
|
||||
{
|
||||
Close(true);
|
||||
}
|
||||
|
||||
void wx_rom_patch_window::on_done(wxCommandEvent& e)
|
||||
{
|
||||
try {
|
||||
SNES::interface = &simple_interface;
|
||||
our_rom->load();
|
||||
} catch(std::exception& e) {
|
||||
wxMessageDialog* d = new wxMessageDialog(this, towxstring(e.what()),
|
||||
wxT("Error loading ROM"), wxOK | wxICON_EXCLAMATION);
|
||||
d->ShowModal();
|
||||
return;
|
||||
}
|
||||
messages << "Detected region: " << gtype::tostring(our_rom->rtype, our_rom->region) << std::endl;
|
||||
if(our_rom->region == REGION_PAL)
|
||||
set_nominal_framerate(322445.0/6448.0);
|
||||
else if(our_rom->region == REGION_NTSC)
|
||||
set_nominal_framerate(10738636.0/178683.0);
|
||||
|
||||
messages << "--- Internal memory mappings ---" << std::endl;
|
||||
dump_region_map();
|
||||
messages << "--- End of Startup --- " << std::endl;
|
||||
wx_project_select_window* projwin = new wx_project_select_window(*our_rom);
|
||||
projwin->Show();
|
||||
Destroy();
|
||||
}
|
31
platform/wxwidgets/src/rom_patch_window.hpp
Normal file
31
platform/wxwidgets/src/rom_patch_window.hpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef _wxwidgets_rom_patch_window__hpp__included__
|
||||
#define _wxwidgets_rom_patch_window__hpp__included__
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/event.h>
|
||||
#include <wx/control.h>
|
||||
#include <wx/combobox.h>
|
||||
#include "filenamebox.hpp"
|
||||
#include "rom.hpp"
|
||||
#include "common.hpp"
|
||||
|
||||
class wx_rom_patch_window : public wxFrame
|
||||
{
|
||||
public:
|
||||
wx_rom_patch_window(loaded_rom& rom);
|
||||
~wx_rom_patch_window();
|
||||
void on_patchfile_change(wxCommandEvent& e);
|
||||
void on_do_patch(wxCommandEvent& e);
|
||||
void on_quit(wxCommandEvent& e);
|
||||
void on_done(wxCommandEvent& e);
|
||||
loaded_rom* our_rom;
|
||||
private:
|
||||
filenamebox* patchfile;
|
||||
wxComboBox* patch_what;
|
||||
wxButton* dopatch;
|
||||
wxTextCtrl* patch_offset;
|
||||
wxStaticText_ptr checksums[6];
|
||||
wxString targets[6];
|
||||
};
|
||||
|
||||
#endif
|
139
platform/wxwidgets/src/rom_select_window.cpp
Normal file
139
platform/wxwidgets/src/rom_select_window.cpp
Normal file
|
@ -0,0 +1,139 @@
|
|||
#include "rom_select_window.hpp"
|
||||
#include "rom_patch_window.hpp"
|
||||
#include "callrom.hpp"
|
||||
|
||||
wx_rom_select_window::wx_rom_select_window()
|
||||
: wxFrame(NULL, wxID_ANY, wxT("Select ROM"), wxDefaultPosition, wxSize(-1, -1),
|
||||
primary_window_style)
|
||||
{
|
||||
wxString rtchoices[5];
|
||||
wxString rrchoices[3];
|
||||
size_t systems = populate_system_choices(rtchoices);
|
||||
size_t regions = populate_region_choices(rrchoices);
|
||||
|
||||
Centre();
|
||||
wxFlexGridSizer* top_s = new wxFlexGridSizer(3, 1, 0, 0);
|
||||
SetSizer(top_s);
|
||||
|
||||
wxBoxSizer* selects_s = new wxBoxSizer(wxHORIZONTAL);
|
||||
rtypec = new labeledcombobox(selects_s, this, "ROM type:", rtchoices, systems, 0, true, this,
|
||||
wxCommandEventHandler(wx_rom_select_window::on_romtype_change));
|
||||
regionc = new labeledcombobox(selects_s, this, "Region:", rrchoices, regions, 0, true, this,
|
||||
wxCommandEventHandler(wx_rom_select_window::on_romtype_change));
|
||||
top_s->Add(selects_s, 0, wxGROW);
|
||||
|
||||
//The XMLs don't matter, so don't notify those.
|
||||
wxFlexGridSizer* romgrid_s = new wxFlexGridSizer(6, 3, 0, 0);
|
||||
main_rom = new filenamebox(romgrid_s, this, "ROM", FNBF_PZ, this,
|
||||
wxCommandEventHandler(wx_rom_select_window::on_filename_change));
|
||||
main_xml = new filenamebox(romgrid_s, this, "ROM XML", FNBF_NN | FNBF_PZ, this,
|
||||
wxCommandEventHandler(wx_rom_select_window::on_filename_change));
|
||||
slota_rom = new filenamebox(romgrid_s, this, "SLOT A ROM", FNBF_PZ, this,
|
||||
wxCommandEventHandler(wx_rom_select_window::on_filename_change));
|
||||
slota_xml = new filenamebox(romgrid_s, this, "SLOT A XML", FNBF_NN | FNBF_PZ, this,
|
||||
wxCommandEventHandler(wx_rom_select_window::on_filename_change));
|
||||
slotb_rom = new filenamebox(romgrid_s, this, "SLOT A ROM", FNBF_PZ, this,
|
||||
wxCommandEventHandler(wx_rom_select_window::on_filename_change));
|
||||
slotb_xml = new filenamebox(romgrid_s, this, "SLOT A XML", FNBF_NN | FNBF_PZ, this,
|
||||
wxCommandEventHandler(wx_rom_select_window::on_filename_change));
|
||||
|
||||
top_s->Add(romgrid_s, 1, wxGROW);
|
||||
wxBoxSizer* button_s = new wxBoxSizer(wxHORIZONTAL);
|
||||
button_s->AddStretchSpacer();
|
||||
button_s->Add(open_rom = new wxButton(this, wxID_OPEN, wxT("Open ROM")), 0, wxALIGN_RIGHT);
|
||||
button_s->Add(quit_button = new wxButton(this, wxID_EXIT, wxT("Quit")), 0, wxALIGN_RIGHT);
|
||||
open_rom->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
wxCommandEventHandler(wx_rom_select_window::on_open_rom), NULL, this);
|
||||
open_rom->Disable();
|
||||
quit_button->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
wxCommandEventHandler(wx_rom_select_window::on_quit), NULL, this);
|
||||
top_s->Add(button_s, 1, wxGROW);
|
||||
|
||||
set_rtype("");
|
||||
|
||||
top_s->SetSizeHints(this);
|
||||
Fit();
|
||||
}
|
||||
|
||||
wx_rom_select_window::~wx_rom_select_window()
|
||||
{
|
||||
delete rtypec;
|
||||
delete regionc;
|
||||
delete main_rom;
|
||||
delete main_xml;
|
||||
delete slota_rom;
|
||||
delete slota_xml;
|
||||
delete slotb_rom;
|
||||
delete slotb_xml;
|
||||
}
|
||||
|
||||
|
||||
void wx_rom_select_window::set_rtype(std::string rtype)
|
||||
{
|
||||
bool no_rtype = (current_rtype == "");
|
||||
if(rtype == "")
|
||||
rtype = rtypec->get_choice();
|
||||
if(rtype == current_rtype)
|
||||
return;
|
||||
if(has_forced_region(rtype))
|
||||
regionc->disable(forced_region_for_romtype(rtype));
|
||||
else
|
||||
regionc->enable();
|
||||
wxString tmp[6];
|
||||
unsigned c = fill_rom_names(romtype_from_string(rtype), tmp);
|
||||
if(c > 0) main_rom->enable(tostdstring(tmp[0])); else main_rom->disable();
|
||||
if(c > 1) main_xml->enable(tostdstring(tmp[1])); else main_xml->disable();
|
||||
if(c > 2) slota_rom->enable(tostdstring(tmp[2])); else slota_rom->disable();
|
||||
if(c > 3) slota_xml->enable(tostdstring(tmp[3])); else slota_xml->disable();
|
||||
if(c > 4) slotb_rom->enable(tostdstring(tmp[4])); else slotb_rom->disable();
|
||||
if(c > 5) slotb_xml->enable(tostdstring(tmp[5])); else slotb_xml->disable();
|
||||
current_rtype = rtype;
|
||||
Fit();
|
||||
}
|
||||
|
||||
void wx_rom_select_window::on_filename_change(wxCommandEvent& e)
|
||||
{
|
||||
bool ok = true;
|
||||
enum rom_type rtype = romtype_from_string(rtypec->get_choice());
|
||||
ok = ok && main_rom->is_nonblank();
|
||||
if(rtype == ROMTYPE_BSX || rtype == ROMTYPE_BSXSLOTTED || rtype == ROMTYPE_SGB)
|
||||
ok = ok && slota_rom->is_nonblank();
|
||||
if(rtype == ROMTYPE_SUFAMITURBO)
|
||||
ok = ok && (slota_rom->is_nonblank() || slotb_rom->is_nonblank());
|
||||
open_rom->Enable(ok);
|
||||
}
|
||||
|
||||
void wx_rom_select_window::on_romtype_change(wxCommandEvent& e)
|
||||
{
|
||||
set_rtype(rtypec->get_choice());
|
||||
on_filename_change(e);
|
||||
}
|
||||
|
||||
void wx_rom_select_window::on_quit(wxCommandEvent& e)
|
||||
{
|
||||
Close(true);
|
||||
}
|
||||
|
||||
void wx_rom_select_window::on_open_rom(wxCommandEvent& e)
|
||||
{
|
||||
rom_files rfiles;
|
||||
rfiles.base_file = "";
|
||||
rfiles.rtype = romtype_from_string(rtypec->get_choice());
|
||||
rfiles.region = region_from_string(regionc->get_choice());
|
||||
rfiles.rom = main_rom->get_file();
|
||||
rfiles.rom_xml = main_xml->get_file();
|
||||
rfiles.slota = slota_rom->get_file();
|
||||
rfiles.slota_xml = slota_xml->get_file();
|
||||
rfiles.slotb = slotb_rom->get_file();
|
||||
rfiles.slotb_xml = slotb_xml->get_file();
|
||||
try {
|
||||
our_rom = new loaded_rom(rfiles);
|
||||
} catch(std::exception& e) {
|
||||
wxMessageDialog* d = new wxMessageDialog(this, towxstring(e.what()),
|
||||
wxT("Error loading ROM"), wxOK | wxICON_EXCLAMATION);
|
||||
d->ShowModal();
|
||||
}
|
||||
wx_rom_patch_window* projwin = new wx_rom_patch_window(*our_rom);
|
||||
projwin->Show();
|
||||
Destroy();
|
||||
}
|
37
platform/wxwidgets/src/rom_select_window.hpp
Normal file
37
platform/wxwidgets/src/rom_select_window.hpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
#ifndef _wxwidgets_rom_select_window__hpp__included__
|
||||
#define _wxwidgets_rom_select_window__hpp__included__
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/event.h>
|
||||
#include <wx/control.h>
|
||||
#include <wx/combobox.h>
|
||||
#include "filenamebox.hpp"
|
||||
#include "rom.hpp"
|
||||
#include "labelcombobox.hpp"
|
||||
|
||||
class wx_rom_select_window : public wxFrame
|
||||
{
|
||||
public:
|
||||
wx_rom_select_window();
|
||||
~wx_rom_select_window();
|
||||
void on_filename_change(wxCommandEvent& e);
|
||||
void on_romtype_change(wxCommandEvent& e);
|
||||
void on_quit(wxCommandEvent& e);
|
||||
void on_open_rom(wxCommandEvent& e);
|
||||
loaded_rom* our_rom;
|
||||
private:
|
||||
labeledcombobox* rtypec;
|
||||
labeledcombobox* regionc;
|
||||
filenamebox* main_rom;
|
||||
filenamebox* main_xml;
|
||||
filenamebox* slota_rom;
|
||||
filenamebox* slota_xml;
|
||||
filenamebox* slotb_rom;
|
||||
filenamebox* slotb_xml;
|
||||
wxButton* open_rom;
|
||||
wxButton* quit_button;
|
||||
std::string current_rtype;
|
||||
void set_rtype(std::string rtype);
|
||||
};
|
||||
|
||||
#endif
|
147
platform/wxwidgets/src/settingseditor.cpp
Normal file
147
platform/wxwidgets/src/settingseditor.cpp
Normal file
|
@ -0,0 +1,147 @@
|
|||
#include "settingseditor.hpp"
|
||||
#include "settings.hpp"
|
||||
#include "common.hpp"
|
||||
#include "window.hpp"
|
||||
#include <stdexcept>
|
||||
|
||||
wx_settings_editor_setting::wx_settings_editor_setting(wxSizer* sizer, wxWindow* window, const std::string& name)
|
||||
{
|
||||
a_name = name;
|
||||
parent = window;
|
||||
std::string pvalue = "<unknown>";
|
||||
try {
|
||||
if(!setting::is_set(a_name))
|
||||
pvalue = "<unset>";
|
||||
else
|
||||
pvalue = setting::get(a_name);
|
||||
} catch(...) {
|
||||
}
|
||||
sizer->Add(new wxStaticText(window, wxID_ANY, towxstring(name)), 0, wxGROW);
|
||||
sizer->Add(label = new wxStaticText(window, wxID_ANY, towxstring(pvalue)), 0, wxGROW);
|
||||
sizer->Add(edit = new wxButton(window, wxID_ANY, wxT("Edit")), 0, wxGROW);
|
||||
sizer->Add(clear = new wxButton(window, wxID_ANY, wxT("Clear")), 0, wxGROW);
|
||||
edit->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
wxCommandEventHandler(wx_settings_editor_setting::on_edit_click), NULL, this);
|
||||
clear->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
wxCommandEventHandler(wx_settings_editor_setting::on_clear_click), NULL, this);
|
||||
}
|
||||
|
||||
void wx_settings_editor_setting::on_clear_click(wxCommandEvent& e)
|
||||
{
|
||||
try {
|
||||
setting::blank(a_name);
|
||||
}catch(std::exception& e) {
|
||||
wxMessageDialog* d = new wxMessageDialog(parent, towxstring(std::string("Can't clear setting: ") +
|
||||
e.what()), wxT("Error"), wxOK | wxICON_EXCLAMATION);
|
||||
d->ShowModal();
|
||||
d->Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
void wx_settings_editor_setting::on_edit_click(wxCommandEvent& e)
|
||||
{
|
||||
try {
|
||||
std::string newsetting;
|
||||
std::string oldvalue = setting::get(a_name);
|
||||
wxTextEntryDialog* d = new wxTextEntryDialog(parent, towxstring("Enter new value for " + a_name),
|
||||
wxT("Enter new value for setting"), towxstring(oldvalue));
|
||||
if(d->ShowModal() == wxID_CANCEL) {
|
||||
d->Destroy();
|
||||
return;
|
||||
}
|
||||
newsetting = tostdstring(d->GetValue());
|
||||
setting::set(a_name, newsetting);
|
||||
} catch(std::exception& e) {
|
||||
wxMessageDialog* d = new wxMessageDialog(parent, towxstring(std::string("Can't set setting: ") +
|
||||
e.what()), wxT("Error"), wxOK | wxICON_EXCLAMATION);
|
||||
d->ShowModal();
|
||||
d->Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
void wx_settings_editor_setting::change_setting(const std::string& _setting, const std::string& value)
|
||||
{
|
||||
if(_setting != a_name)
|
||||
return;
|
||||
label->SetLabel(towxstring(value));
|
||||
}
|
||||
|
||||
void wx_settings_editor_setting::clear_setting(const std::string& _setting)
|
||||
{
|
||||
if(_setting != a_name)
|
||||
return;
|
||||
label->SetLabel(wxT("<unset>"));
|
||||
}
|
||||
|
||||
wx_settings_editor::wx_settings_editor(wxWindow* parent)
|
||||
: wxDialog(parent, wxID_ANY, wxT("lsnes: Edit settings"), wxDefaultPosition, wxSize(-1, -1)), listener(this)
|
||||
{
|
||||
std::set<std::string> settings_set = setting::get_settings_set();
|
||||
|
||||
Centre();
|
||||
wxFlexGridSizer* top_s = new wxFlexGridSizer(2, 1, 0, 0);
|
||||
SetSizer(top_s);
|
||||
|
||||
wxFlexGridSizer* t_s = new wxFlexGridSizer(settings_set.size(), 4, 0, 0);
|
||||
for(auto i : settings_set)
|
||||
esettings.push_back(new wx_settings_editor_setting(t_s, this, i));
|
||||
top_s->Add(t_s);
|
||||
|
||||
wxBoxSizer* pbutton_s = new wxBoxSizer(wxHORIZONTAL);
|
||||
pbutton_s->AddStretchSpacer();
|
||||
pbutton_s->Add(close = new wxButton(this, wxID_CANCEL, wxT("Close")), 0, wxGROW);
|
||||
close->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
wxCommandEventHandler(wx_settings_editor::on_close), NULL, this);
|
||||
top_s->Add(pbutton_s, 0, wxGROW);
|
||||
|
||||
t_s->SetSizeHints(this);
|
||||
top_s->SetSizeHints(this);
|
||||
Fit();
|
||||
}
|
||||
|
||||
wx_settings_editor::~wx_settings_editor()
|
||||
{
|
||||
for(auto i : esettings)
|
||||
delete i;
|
||||
}
|
||||
|
||||
bool wx_settings_editor::ShouldPreventAppExit() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void wx_settings_editor::on_close(wxCommandEvent& e)
|
||||
{
|
||||
EndModal(wxID_OK);
|
||||
}
|
||||
|
||||
void wx_settings_editor::change_setting(const std::string& _setting, const std::string& value)
|
||||
{
|
||||
for(auto i : esettings)
|
||||
i->change_setting(_setting, value);
|
||||
}
|
||||
|
||||
void wx_settings_editor::clear_setting(const std::string& _setting)
|
||||
{
|
||||
for(auto i : esettings)
|
||||
i->clear_setting(_setting);
|
||||
}
|
||||
|
||||
wx_settings_editor_listener::wx_settings_editor_listener(wx_settings_editor* _editor)
|
||||
{
|
||||
editor = _editor;
|
||||
}
|
||||
|
||||
wx_settings_editor_listener::~wx_settings_editor_listener() throw()
|
||||
{
|
||||
}
|
||||
|
||||
void wx_settings_editor_listener::on_setting_change(const std::string& _setting, const std::string& value)
|
||||
{
|
||||
editor->change_setting(_setting, value);
|
||||
}
|
||||
|
||||
void wx_settings_editor_listener::on_setting_clear(const std::string& _setting)
|
||||
{
|
||||
editor->clear_setting(_setting);
|
||||
}
|
56
platform/wxwidgets/src/settingseditor.hpp
Normal file
56
platform/wxwidgets/src/settingseditor.hpp
Normal file
|
@ -0,0 +1,56 @@
|
|||
#ifndef _wxwidgets_settingseditor__hpp__included__
|
||||
#define _wxwidgets_settingseditor__hpp__included__
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/event.h>
|
||||
#include <wx/control.h>
|
||||
#include <wx/combobox.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "window.hpp"
|
||||
|
||||
class wx_settings_editor_setting : public wxEvtHandler
|
||||
{
|
||||
public:
|
||||
wx_settings_editor_setting(wxSizer* sizer, wxWindow* window, const std::string& name);
|
||||
void on_clear_click(wxCommandEvent& e);
|
||||
void on_edit_click(wxCommandEvent& e);
|
||||
void change_setting(const std::string& setting, const std::string& value);
|
||||
void clear_setting(const std::string& setting);
|
||||
private:
|
||||
std::string a_name;
|
||||
wxWindow* parent;
|
||||
wxStaticText* label;
|
||||
wxButton* clear;
|
||||
wxButton* edit;
|
||||
};
|
||||
|
||||
class wx_settings_editor;
|
||||
|
||||
class wx_settings_editor_listener : public window_callback
|
||||
{
|
||||
public:
|
||||
wx_settings_editor_listener(wx_settings_editor* _editor);
|
||||
~wx_settings_editor_listener() throw();
|
||||
void on_setting_change(const std::string& setting, const std::string& value);
|
||||
void on_setting_clear(const std::string& setting);
|
||||
private:
|
||||
wx_settings_editor* editor;
|
||||
};
|
||||
|
||||
class wx_settings_editor : public wxDialog
|
||||
{
|
||||
public:
|
||||
wx_settings_editor(wxWindow* parent);
|
||||
~wx_settings_editor();
|
||||
bool ShouldPreventAppExit() const;
|
||||
void on_close(wxCommandEvent& e);
|
||||
void change_setting(const std::string& setting, const std::string& value);
|
||||
void clear_setting(const std::string& setting);
|
||||
private:
|
||||
wx_settings_editor_listener listener;
|
||||
std::vector<wx_settings_editor_setting*> esettings;
|
||||
wxButton* close;
|
||||
};
|
||||
|
||||
#endif
|
75
platform/wxwidgets/src/status_window.cpp
Normal file
75
platform/wxwidgets/src/status_window.cpp
Normal file
|
@ -0,0 +1,75 @@
|
|||
#include "status_window.hpp"
|
||||
#include "window.hpp"
|
||||
#include "emufn.hpp"
|
||||
|
||||
|
||||
#define MAXSTATUS 30
|
||||
|
||||
class wx_status_panel : public wxPanel
|
||||
{
|
||||
public:
|
||||
wx_status_panel(unsigned lines);
|
||||
void on_paint(wxPaintEvent& e);
|
||||
bool dirty;
|
||||
};
|
||||
|
||||
wx_status_window* wx_status_window::ptr;
|
||||
|
||||
wx_status_panel::wx_status_panel(unsigned lines)
|
||||
: wxPanel(wx_status_window::ptr)
|
||||
{
|
||||
dirty = false;
|
||||
wxMemoryDC d;
|
||||
wxSize s = d.GetTextExtent(wxT("MMMMMM"));
|
||||
SetMinSize(wxSize(6 * s.x, lines * s.y));
|
||||
this->Connect(wxEVT_PAINT, wxPaintEventHandler(wx_status_panel::on_paint), NULL, this);
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
wx_status_panel* spanel;
|
||||
}
|
||||
|
||||
wx_status_window::wx_status_window()
|
||||
: wxFrame(NULL, wxID_ANY, wxT("lsnes: Status"), wxDefaultPosition, wxSize(-1, -1), secondary_window_style)
|
||||
{
|
||||
ptr = this;
|
||||
wxFlexGridSizer* top_s = new wxFlexGridSizer(1, 1, 0, 0);
|
||||
top_s->Add(spanel = new wx_status_panel(MAXSTATUS));
|
||||
top_s->SetSizeHints(this);
|
||||
SetSizer(top_s);
|
||||
Fit();
|
||||
}
|
||||
|
||||
wx_status_window::~wx_status_window()
|
||||
{
|
||||
ptr = NULL;
|
||||
}
|
||||
|
||||
void wx_status_panel::on_paint(wxPaintEvent& e)
|
||||
{
|
||||
wxPaintDC dc(this);
|
||||
dc.Clear();
|
||||
int y = 0;
|
||||
auto& status = window::get_emustatus();
|
||||
for(auto i : status) {
|
||||
std::string pstr = i.first + ": " + i.second;
|
||||
wxSize s = dc.GetTextExtent(towxstring(pstr));
|
||||
dc.DrawText(towxstring(pstr), 0, y);
|
||||
y += s.y;
|
||||
}
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
void wx_status_window::notify_status_change()
|
||||
{
|
||||
if(!spanel || spanel->dirty)
|
||||
return;
|
||||
spanel->dirty = true;
|
||||
spanel->Refresh();
|
||||
}
|
||||
|
||||
bool wx_status_window::ShouldPreventAppExit() const
|
||||
{
|
||||
return false;
|
||||
}
|
24
platform/wxwidgets/src/status_window.hpp
Normal file
24
platform/wxwidgets/src/status_window.hpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
#ifndef _wxwidgets_status_window__hpp__included__
|
||||
#define _wxwidgets_status_window__hpp__included__
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/event.h>
|
||||
#include <wx/control.h>
|
||||
#include <wx/combobox.h>
|
||||
#include "common.hpp"
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
class wx_status_window : public wxFrame
|
||||
{
|
||||
public:
|
||||
wx_status_window();
|
||||
~wx_status_window();
|
||||
bool ShouldPreventAppExit() const;
|
||||
static wx_status_window* ptr;
|
||||
void notify_status_change();
|
||||
};
|
||||
|
||||
void repaint_status_window();
|
||||
|
||||
#endif
|
Loading…
Add table
Reference in a new issue