From b497bd7ed6b918366a108298058a598c33bee983 Mon Sep 17 00:00:00 2001 From: Ilari Liusvaara Date: Sat, 5 Nov 2011 20:46:18 +0200 Subject: [PATCH] Wxwidgets graphics plugin As opposed to SDL graphics plugin, this has full GUI. --- Makefile | 10 +- generic/coroutine.cpp | 141 ++ generic/coroutine.hpp | 59 + manual.lyx | 108 +- platform/wxwidgets/main-wxwidgets.cpp | 71 + platform/wxwidgets/src/authorseditor.cpp | 81 ++ platform/wxwidgets/src/authorseditor.hpp | 24 + platform/wxwidgets/src/axeseditor.cpp | 222 +++ platform/wxwidgets/src/axeseditor.hpp | 41 + platform/wxwidgets/src/callrom.cpp | 195 +++ platform/wxwidgets/src/callrom.hpp | 26 + platform/wxwidgets/src/common.cpp | 17 + platform/wxwidgets/src/common.hpp | 45 + platform/wxwidgets/src/emufn.cpp | 1604 ++++++++++++++++++++++ platform/wxwidgets/src/emufn.hpp | 10 + platform/wxwidgets/src/filenamebox.cpp | 138 ++ platform/wxwidgets/src/filenamebox.hpp | 44 + platform/wxwidgets/src/keyentry.cpp | 148 ++ platform/wxwidgets/src/keyentry.hpp | 35 + platform/wxwidgets/src/labelcombobox.cpp | 48 + platform/wxwidgets/src/labelcombobox.hpp | 31 + platform/wxwidgets/src/messages_window.cpp | 143 ++ platform/wxwidgets/src/messages_window.hpp | 30 + platform/wxwidgets/src/project_select_window.cpp | 252 ++++ platform/wxwidgets/src/project_select_window.hpp | 43 + platform/wxwidgets/src/rom_patch_window.cpp | 159 +++ platform/wxwidgets/src/rom_patch_window.hpp | 31 + platform/wxwidgets/src/rom_select_window.cpp | 139 ++ platform/wxwidgets/src/rom_select_window.hpp | 37 + platform/wxwidgets/src/settingseditor.cpp | 147 ++ platform/wxwidgets/src/settingseditor.hpp | 56 + platform/wxwidgets/src/status_window.cpp | 75 + platform/wxwidgets/src/status_window.hpp | 24 + 33 files changed, 4184 insertions(+), 50 deletions(-) create mode 100644 generic/coroutine.cpp create mode 100644 generic/coroutine.hpp create mode 100644 platform/wxwidgets/main-wxwidgets.cpp create mode 100644 platform/wxwidgets/src/authorseditor.cpp create mode 100644 platform/wxwidgets/src/authorseditor.hpp create mode 100644 platform/wxwidgets/src/axeseditor.cpp create mode 100644 platform/wxwidgets/src/axeseditor.hpp create mode 100644 platform/wxwidgets/src/callrom.cpp create mode 100644 platform/wxwidgets/src/callrom.hpp create mode 100644 platform/wxwidgets/src/common.cpp create mode 100644 platform/wxwidgets/src/common.hpp create mode 100644 platform/wxwidgets/src/emufn.cpp create mode 100644 platform/wxwidgets/src/emufn.hpp create mode 100644 platform/wxwidgets/src/filenamebox.cpp create mode 100644 platform/wxwidgets/src/filenamebox.hpp create mode 100644 platform/wxwidgets/src/keyentry.cpp create mode 100644 platform/wxwidgets/src/keyentry.hpp create mode 100644 platform/wxwidgets/src/labelcombobox.cpp create mode 100644 platform/wxwidgets/src/labelcombobox.hpp create mode 100644 platform/wxwidgets/src/messages_window.cpp create mode 100644 platform/wxwidgets/src/messages_window.hpp create mode 100644 platform/wxwidgets/src/project_select_window.cpp create mode 100644 platform/wxwidgets/src/project_select_window.hpp create mode 100644 platform/wxwidgets/src/rom_patch_window.cpp create mode 100644 platform/wxwidgets/src/rom_patch_window.hpp create mode 100644 platform/wxwidgets/src/rom_select_window.cpp create mode 100644 platform/wxwidgets/src/rom_select_window.hpp create mode 100644 platform/wxwidgets/src/settingseditor.cpp create mode 100644 platform/wxwidgets/src/settingseditor.hpp create mode 100644 platform/wxwidgets/src/status_window.cpp create mode 100644 platform/wxwidgets/src/status_window.hpp diff --git a/Makefile b/Makefile index 15dd7bc4..f5e70021 100644 --- a/Makefile +++ b/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 diff --git a/generic/coroutine.cpp b/generic/coroutine.cpp new file mode 100644 index 00000000..0ad36985 --- /dev/null +++ b/generic/coroutine.cpp @@ -0,0 +1,141 @@ +#include "coroutine.hpp" +#include +#include +#include +#include +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 diff --git a/generic/coroutine.hpp b/generic/coroutine.hpp new file mode 100644 index 00000000..554791be --- /dev/null +++ b/generic/coroutine.hpp @@ -0,0 +1,59 @@ +#ifndef _coroutine__hpp__included__ +#define _coroutine__hpp__included__ + +#include +#include + +/** + * 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 \ No newline at end of file diff --git a/manual.lyx b/manual.lyx index e3d48cc2..a3142acb 100644 --- a/manual.lyx +++ b/manual.lyx @@ -814,7 +814,7 @@ Print all aliases and their expansions in effect. \end_layout \begin_layout Subsection -run-script