Update to bsnes v022r03 release.

Double post!

 I've uploaded a new WIP, which I'll make public (only to this forum,
please don't post about it anywhere else unless you mirror the file):







    http://byuu.org/files/bsnes_v022_wip03.zip




 This version adds all of Nach's MinGW fixes, updated libco, libui and
libfunctor, cleans up the code that detects if the main window has
focus or not (if not, ignore keyboard input), adds the new makefile
target win-mingw-lui, finally fixes all of the char* conversion
warnings with GCC 4.2.x (thanks [vEX]), and I'm sure there's more, but
I don't remember.

 The ZIP includes a Visual C++ generated binary, but it also works
with MinGW GCC4. It won't work with MinGW GCC3 because that one lacks
a C99-compliant vsnprintf function. You can hack your way around that
by editing src/lib/libstring_sprintf.cpp if you really want to use
MinGW GCC3.

 You may also need to change the CC / CPP variable names. I went with
the generic names mingw32-gcc and mingw32-g++, but the GCC4 binaries
have -sjlj or -dw2 appended to them. You'll also need to set
-I/path/to/directxheaders, or copy them all into
/path/to/mingw/include, since MinGW seems to ignore the include
environment variable.

 And finally, a bit of good news. It appears that MinGW GCC4 builds
binaries that are ~6% faster than Visual C++. That means with PGO
enabled, they should be at least ~16% faster than v0.022 official. If
I can figure out how to hide the ugly terminal window in the
background, I'll start making official releases with MinGW GCC4 from
now on.
This commit is contained in:
byuu 2007-09-08 08:41:18 +00:00
parent c57c733d7d
commit 1e130d7872
20 changed files with 297 additions and 120 deletions

BIN
bsnes.exe Normal file

Binary file not shown.

View File

@ -38,7 +38,7 @@ CC = cl
CFLAGS = /nologo /wd4996 /O2 /EHsc /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_LUI
AS = nasm
ASFLAGS = -f win32 -DWIN32
LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib
LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib kernel32.lib user32.lib gdi32.lib shell32.lib winmm.lib comdlg32.lib comctl32.lib
LIBCO = libco_x86
LIBUI = libui_win
endif
@ -49,7 +49,7 @@ CC = cl
CFLAGS = /nologo /wd4996 /O2 /GL /EHsc /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_LUI
AS = nasm
ASFLAGS = -f win32 -DWIN32
LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib
LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib kernel32.lib user32.lib gdi32.lib shell32.lib winmm.lib comdlg32.lib comctl32.lib
LINK = /link /PGD:bsnes.pgd /LTCG:PGINSTRUMENT
LIBCO = libco_x86
LIBUI = libui_win
@ -61,12 +61,23 @@ CC = cl
CFLAGS = /nologo /wd4996 /O2 /GL /EHsc /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_LUI
AS = nasm
ASFLAGS = -f win32 -DWIN32
LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib
LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib kernel32.lib user32.lib gdi32.lib shell32.lib winmm.lib comdlg32.lib comctl32.lib
LINK = /link /PGD:bsnes.pgd /LTCG:PGOPTIMIZE
LIBCO = libco_x86
LIBUI = libui_win
endif
ifeq ($(PLATFORM),win-mingw-lui)
OS = win
CC = mingw32-gcc
CFLAGS = -O3 -fomit-frame-pointer -ffast-math -DPLATFORM_WIN -DCOMPILER_GCC -DPROCESSOR_X86 -DUI_LUI
AS = nasm
ASFLAGS = -f win32 -DWIN32
LIBS = -ld3d9 -lddraw -ldsound -ldinput8 -ldxguid -luuid -lkernel32 -luser32 -lgdi32 -lshell32 -lwinmm -lcomdlg32 -lcomctl32
LIBCO = libco_x86
LIBUI = libui_win
endif
#####################################
### compiler / assembler switches ###
#####################################
@ -79,6 +90,14 @@ CARGS = -c $< -o $@
DEFINE = -D
endif
ifeq ($(CC),mingw32-gcc)
OUT = -obsnes
CPP = mingw32-g++
OBJ = o
CARGS = -c $< -o $@
DEFINE = -D
endif
ifeq ($(CC),cl)
OUT = /Febsnes
CPP = cl
@ -106,7 +125,6 @@ endif
ifeq ($(OS),win)
OUT := $(OUT).exe
RM = del
LIBS += kernel32.lib user32.lib gdi32.lib shell32.lib winmm.lib comdlg32.lib comctl32.lib
endif
####################################

View File

@ -1,4 +1,4 @@
#define BSNES_VERSION "0.022"
#define BSNES_VERSION "0.022.03"
#define BSNES_TITLE "bsnes v" BSNES_VERSION
#define MEMCORE bMemBus
@ -31,6 +31,7 @@
#error "unsupported processor"
#endif
#include "lib/libfunctor.h"
#include "lib/libsort.h"
#include "lib/libarray.h"
#include "lib/libvector.h"
@ -38,9 +39,9 @@
#include "lib/libconfig.h"
//platform-specific global functions
void alert(char*, ...);
void dprintf(char*, ...);
void dprintf(uint, char*, ...);
void alert(const char*, ...);
void dprintf(const char*, ...);
void dprintf(uint, const char*, ...);
namespace source {
enum {

View File

@ -1,5 +1,5 @@
/*
libbase : version 0.10 ~byuu (2007-06-04)
libbase : version 0.11 ~byuu (2007-09-08)
license: public domain
*/
@ -18,7 +18,7 @@
#include <new>
#if defined(_MSC_VER)
#if defined(PLATFORM_WIN)
#include <io.h>
#include <direct.h>
#include <shlobj.h>
@ -34,6 +34,10 @@
#define NOMINMAX
#define PATH_MAX _MAX_PATH
#define va_copy(dst, src) ((dst) = (src))
#endif
#if defined(PLATFORM_WIN)
#define getcwd _getcwd
#define ftruncate _chsize
#define mkdir _mkdir
@ -41,11 +45,10 @@
#define rmdir _rmdir
#define vsnprintf _vsnprintf
#define va_copy(dst, src) ((dst) = (src))
static char *realpath(const char *file_name, char *resolved_name) {
return _fullpath(resolved_name, file_name, PATH_MAX);
}
#elif defined(__GNUC__)
#elif defined(PLATFORM_X)
#define mkdir(path) (mkdir)(path, 0755);
#endif
@ -90,13 +93,13 @@ typedef int64_t int64;
//userpath(output) retrieves path to user's home folder
//output must be at least as large as PATH_MAX
#if defined(_MSC_VER)
#if defined(PLATFORM_WIN)
static char *userpath(char *output) {
strcpy(output, "."); //failsafe
SHGetFolderPath(0, CSIDL_APPDATA | CSIDL_FLAG_CREATE, 0, 0, output);
return output;
}
#elif defined(__GNUC__)
#elif defined(PLATFORM_X)
static char *userpath(char *output) {
strcpy(output, "."); //failsafe
struct passwd *userinfo = getpwuid(getuid());

View File

@ -1,14 +1,14 @@
;*****
;libco_x86 : version 0.10 ~byuu (2007-04-18)
;libco_x86 : version 0.10 ~byuu (2007-09-08)
;cross-platform x86 implementation of libco
;special thanks to Aaron Giles and Joel Yliluoma for various optimizations
;
;[ABI compatibility]
;- visual c++; windows-x86
;- mingw; windows-x86
;- gcc; osx86
;- gcc; linux-x86
;- gcc; freebsd-x86
;- visual c++; windows; x86
;- mingw; windows; x86
;- gcc; mac os x; x86
;- gcc; linux; x86
;- gcc; freebsd; x86
;
;[nonvolatile registers]
;- esp, ebp, edi, esi, ebx
@ -28,7 +28,7 @@
%define free _free
%define co_active @co_active@0
%define co_create @co_create@12
%define co_create @co_create@8
%define co_delete @co_delete@4
%define co_switch @co_switch@4
%endif
@ -76,11 +76,10 @@ co_active:
ret
;*****
;extern "C" cothread_t fastcall co_create(unsigned int heapsize, void (*coentry)(void *data), void *data);
;ecx = heapsize
;edx = coentry
;[esp+4] = data
;return = eax
;extern "C" cothread_t fastcall co_create(unsigned int heapsize, void (*coentry)());
;ecx = heapsize
;edx = coentry
;return = eax
;*****
align 16
@ -101,7 +100,7 @@ co_create:
and ecx,-16 ;force 16-byte alignment of stack heap
;store thread entry point + registers, so that first call to co_switch will execute coentry
mov dword[ecx-4],co_entrypoint ;entry point
mov dword[ecx-4],edx ;entry point
mov dword[ecx-8],0 ;ebp
mov dword[ecx-12],0 ;esi
mov dword[ecx-16],0 ;edi
@ -109,11 +108,8 @@ co_create:
sub ecx,20
;initialize context memory heap and return
mov [eax],ecx ;cothread_t[ 0- 3] = stack heap pointer (esp)
mov [eax+4],edx ;cothread_t[ 4- 7] = coentry
mov ecx,[esp+4]
mov [eax+8],ecx ;cothread_t[ 8-11] = data
ret 4 ;return allocated memory block as thread handle
mov [eax],ecx ;*cothread_t = stack heap pointer (esp)
ret ;return allocated memory block as thread handle
;*****
;extern "C" void fastcall co_delete(cothread_t cothread);
@ -150,18 +146,3 @@ co_switch:
pop ebp
ret
;*****
;void fastcall co_entrypoint();
;*****
align 16
co_entrypoint:
mov ebp,esp
.loop
mov eax,[co_active_context]
mov ecx,[eax+8] ;fastcall
push ecx ;stdcall
call [eax+4]
mov esp,ebp ;cdecl
jmp .loop

View File

@ -1,26 +1,26 @@
/*
libco_x86 : version 0.10 ~byuu (2007-06-04)
libco_x86 : version 0.10 ~byuu (2007-09-08)
license: public domain
*/
#ifndef LIBCO_H
#define LIBCO_H
#undef fastcall
#if defined(_MSC_VER)
#define fastcall __fastcall
#elif defined(__GNUC__)
#define fastcall __attribute__((fastcall))
#else
#error "fastcall undefined"
#if !defined(fastcall)
#if defined(_MSC_VER)
#define fastcall __fastcall
#elif defined(__GNUC__)
#define fastcall __attribute__((fastcall))
#else
#error "fastcall undefined"
#endif
#endif
#define cocall fastcall
typedef void (*cothread_t);
typedef void *cothread_t;
extern "C" cothread_t cocall co_active();
extern "C" cothread_t cocall co_create(unsigned int heapsize, void (cocall *coentry)(void *data), void *data);
extern "C" void cocall co_delete(cothread_t cothread);
extern "C" void cocall co_switch(cothread_t cothread);
extern "C" cothread_t fastcall co_active();
extern "C" cothread_t fastcall co_create(unsigned int heapsize, void (*coentry)());
extern "C" void fastcall co_delete(cothread_t cothread);
extern "C" void fastcall co_switch(cothread_t cothread);
#endif

View File

@ -1,12 +1,12 @@
;*****
;libco_x86_64 : version 0.10 ~byuu (2007-04-18)
;libco_x86_64 : version 0.10 ~byuu (2007-09-08)
;cross-platform x86-64 implementation of libco
;special thanks to Aaron Giles and Joel Yliluoma for various optimizations
;
;[ABI compatibility]
;- SystemV ( http://refspecs.freestandards.org/elf/x86_64-SysV-psABI.pdf )
;- gcc; linux-x86-64
;- gcc; freebsd-x86-64
;- gcc; linux; x86-64
;- gcc; freebsd; x86-64
;
;[nonvolatile registers]
;- rsp, rbp, rbx, r12, r13, r14, r15
@ -50,10 +50,9 @@ co_active:
ret
;*****
;extern "C" cothread_t co_create(unsigned int heapsize, void (*coentry)(void *data), void *data);
;extern "C" cothread_t co_create(unsigned int heapsize, void (*coentry)());
;rdi = heapsize
;rsi = coentry
;rdx = data
;return = rax
;*****
@ -63,11 +62,9 @@ co_create:
add rdi,512 ;allocate extra memory for contextual info
push rdi
push rsi
push rdx
call malloc ;rax = malloc(rdi)
pop rdx
pop rsi
pop rdi
@ -75,7 +72,7 @@ co_create:
and rdi,-16 ;force 16-byte alignment of stack heap
;store thread entry point + registers, so that first call to co_switch will execute coentry
mov qword[rdi-8],co_entrypoint ;entry point
mov qword[rdi-8],rsi ;entry point
mov qword[rdi-16],0 ;r15
mov qword[rdi-24],0 ;r14
mov qword[rdi-32],0 ;r13
@ -85,9 +82,7 @@ co_create:
sub rdi,56
;initialize context memory heap and return
mov [rax],rdi ;cothread_t[ 0- 7] = stack heap pointer (rsp)
mov [rax+8],rsi ;cothread_t[ 8-15] = coentry
mov [rax+16],rdx ;cothread_t[16-23] = data
mov [rax],rdi ;*cothread_t = stack heap pointer (rsp)
ret ;return allocated memory block as thread handle
;*****
@ -126,14 +121,3 @@ co_switch:
pop rbp
ret
;*****
;void co_entrypoint();
;*****
align 16
co_entrypoint:
mov rax,[co_active_context wrt rip]
mov rdi,[rax+16]
call [rax+8]
jmp co_entrypoint

View File

@ -1,15 +1,15 @@
/*
libco_x86_64 : version 0.10 ~byuu (2007-04-18)
libco_x86_64 : version 0.10 ~byuu (2007-09-08)
license: public domain
*/
#ifndef LIBCO_H
#define LIBCO_H
#define cocall
typedef void (*cothread_t);
typedef void *cothread_t;
extern "C" cothread_t co_active();
extern "C" cothread_t co_create(unsigned int heapsize, void (cocall *coentry)(void *data), void *data);
extern "C" cothread_t co_create(unsigned int heapsize, void (*coentry)());
extern "C" void co_delete(cothread_t cothread);
extern "C" void co_switch(cothread_t cothread);

100
src/lib/libfunctor.h Normal file
View File

@ -0,0 +1,100 @@
/*
libfunctor : version 0.05 ~byuu (2007-09-08)
license: public domain
*/
#ifndef LIBFUNCTOR_H
#define LIBFUNCTOR_H
//prologue
#define TN typename
template<typename T> class functor;
//parameters = 0
#define cat(n) n
#define TL typename R
#define PL
#define CL
#include "libfunctor_impl.h"
//parameters = 1
#define cat(n) , n
#define TL TN R, TN P1
#define PL P1 p1
#define CL p1
#include "libfunctor_impl.h"
//parameters = 2
#define cat(n) , n
#define TL TN R, TN P1, TN P2
#define PL P1 p1, P2 p2
#define CL p1, p2
#include "libfunctor_impl.h"
//parameters = 3
#define cat(n) , n
#define TL TN R, TN P1, TN P2, TN P3
#define PL P1 p1, P2 p2, P3 p3
#define CL p1, p2, p3
#include "libfunctor_impl.h"
//parameters = 4
#define cat(n) , n
#define TL TN R, TN P1, TN P2, TN P3, TN P4
#define PL P1 p1, P2 p2, P3 p3, P4 p4
#define CL p1, p2, p3, p4
#include "libfunctor_impl.h"
//parameters = 5
#define cat(n) , n
#define TL TN R, TN P1, TN P2, TN P3, TN P4, TN P5
#define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5
#define CL p1, p2, p3, p4, p5
#include "libfunctor_impl.h"
//parameters = 6
#define cat(n) , n
#define TL TN R, TN P1, TN P2, TN P3, TN P4, TN P5, TN P6
#define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6
#define CL p1, p2, p3, p4, p5, p6
#include "libfunctor_impl.h"
//parameters = 7
#define cat(n) , n
#define TL TN R, TN P1, TN P2, TN P3, TN P4, TN P5, TN P6, TN P7
#define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7
#define CL p1, p2, p3, p4, p5, p6, p7
#include "libfunctor_impl.h"
//parameters = 8
#define cat(n) , n
#define TL TN R, TN P1, TN P2, TN P3, TN P4, TN P5, TN P6, TN P7, TN P8
#define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8
#define CL p1, p2, p3, p4, p5, p6, p7, p8
#include "libfunctor_impl.h"
//epilogue
#undef TN
#endif

81
src/lib/libfunctor_impl.h Normal file
View File

@ -0,0 +1,81 @@
#ifdef LIBFUNCTOR_H
template<TL>
class functor<R (PL)> {
private:
struct base1 { virtual void func1(PL) {} };
struct base2 { virtual void func2(PL) {} };
struct derived : base1, virtual base2 {};
struct data_t {
R (*fn_call)(const data_t& cat(PL));
union {
R (*fn_global)(PL);
struct {
R (derived::*fn_member)(PL);
void *object;
};
};
} data;
static R fn_call_global(const data_t &d cat(PL)) {
return d.fn_global(CL);
}
template<typename C>
static R fn_call_member(const data_t &d cat(PL)) {
return (((C*)d.object)->*((R (C::*&)(PL))d.fn_member))(CL);
}
public:
R operator()(PL) const { return data.fn_call(data cat(CL)); }
operator bool() const { return data.fn_call; }
functor() { data.fn_call = 0; }
functor(R (*fn)(PL)) {
data.fn_call = &fn_call_global;
data.fn_global = fn;
}
template<typename C>
functor(R (C::*fn)(PL), C *obj) {
data.fn_call = &fn_call_member<C>;
(R (C::*&)(PL))data.fn_member = fn;
assert(sizeof data.fn_member >= sizeof fn);
data.object = obj;
}
template<typename C>
functor(R (C::*fn)(PL) const, C *obj) {
data.fn_call = &fn_call_member<C>;
(R (C::*&)(PL))data.fn_member = (R (C::*&)(PL))fn;
assert(sizeof data.fn_member >= sizeof fn);
data.object = obj;
}
functor &operator=(const functor &source) { memcpy(&data, &source.data, sizeof(data_t)); return *this; }
functor(const functor &source) { memcpy(&data, &source.data, sizeof(data_t)); }
};
template<TL>
functor<R (PL)> bind(R (*fn)(PL)) {
return functor<R (PL)>(fn);
}
template<typename C, TL>
functor<R (PL)> bind(R (C::*fn)(PL), C *obj) {
return functor<R (PL)>(fn, obj);
}
template<typename C, TL>
functor<R (PL)> bind(R (C::*fn)(PL) const, C *obj) {
return functor<R (PL)>(fn, obj);
}
#undef cat
#undef TL
#undef PL
#undef CL
#endif

View File

@ -1,3 +1,5 @@
#define _WIN32_IE 0x0600
#include "libui_win.h"
#include "libui_win_window.cpp"
#include "libui_win_control.cpp"

View File

@ -12,6 +12,7 @@ class SNESInterface { public:
void audio_sample(uint16 l_sample, uint16 r_sample);
functor<bool ()> input_ready;
void input_poll();
bool input_poll(uint deviceid, uint button);

View File

@ -2,10 +2,10 @@ Scheduler scheduler;
//
void cocall threadentry_cpu(void*) { r_cpu->enter(); }
void cocall threadentry_smp(void*) { r_smp->enter(); }
void cocall threadentry_ppu(void*) {} //currently unused
void cocall threadentry_dsp(void*) { r_dsp->enter(); }
void threadentry_cpu() { r_cpu->enter(); }
void threadentry_smp() { r_smp->enter(); }
void threadentry_ppu() { } //currently unused
void threadentry_dsp() { r_dsp->enter(); }
//
@ -41,10 +41,10 @@ void Scheduler::init() {
if(thread_dsp)co_delete(thread_dsp);
thread_snes = co_active();
thread_cpu = co_create(sizeof(void*) * 64 * 1024, threadentry_cpu, 0);
thread_smp = co_create(sizeof(void*) * 64 * 1024, threadentry_smp, 0);
thread_ppu = co_create(sizeof(void*) * 64 * 1024, threadentry_ppu, 0);
thread_dsp = co_create(sizeof(void*) * 64 * 1024, threadentry_dsp, 0);
thread_cpu = co_create(sizeof(void*) * 64 * 1024, threadentry_cpu);
thread_smp = co_create(sizeof(void*) * 64 * 1024, threadentry_smp);
thread_ppu = co_create(sizeof(void*) * 64 * 1024, threadentry_ppu);
thread_dsp = co_create(sizeof(void*) * 64 * 1024, threadentry_dsp);
}
//

View File

@ -1,6 +1,6 @@
Tracer tracer;
void tprintf(char *s, ...) {
void tprintf(const char *s, ...) {
if(tracer.enabled() == false) { return; }
char str[4096];

View File

@ -1,4 +1,4 @@
void tprintf(char *s, ...);
void tprintf(const char *s, ...);
class Tracer {
private:
@ -43,7 +43,7 @@ public:
Tracer();
~Tracer();
friend void tprintf(char *s, ...);
friend void tprintf(const char *s, ...);
};
extern Tracer tracer;

View File

@ -2,7 +2,7 @@ void AudioDS::sample(uint16 l_sample, uint16 r_sample) {
data.buffer[data.buffer_pos++] = (l_sample << 0) + (r_sample << 16);
if(data.buffer_pos < latency)return;
uint32 ring_pos, pos, size;
DWORD ring_pos, pos, size;
for(;;) {
dsb_b->GetCurrentPosition(&pos, 0);
ring_pos = pos / data.ring_size;
@ -30,7 +30,7 @@ void *output;
data.buffer[data.buffer_pos++] = (l_sample << 0) + (r_sample << 16);
//if(data.buffer_pos & 15)return;
uint32 ring_pos, pos, size;
DWORD ring_pos, pos, size;
dsb_b->GetCurrentPosition(&pos, 0);
ring_pos = pos / data.ring_size;
if(ring_pos == data.ring_pos)return;
@ -66,7 +66,7 @@ void AudioDS::clear_audio() {
dsb_b->Stop();
dsb_b->SetCurrentPosition(0);
uint32 size;
DWORD size;
void *output;
dsb_b->Lock(0, data.ring_size * 3, &output, &size, 0, 0, 0);
memset(output, 0, size);

View File

@ -39,12 +39,12 @@ void SNESInterface::audio_sample(uint16 l_sample, uint16 r_sample) {
//input
//allow_input() returns true only when main emulator window has focus
//TODO: draft a more elegant way to poll lui, etc platforms from here
bool allow_input(); //defined in lui/main.cpp
void SNESInterface::input_poll() {
allow_input() ? uiInput->poll() : uiInput->clear_input();
if(input_ready && input_ready() == false) {
uiInput->clear_input();
} else {
uiInput->poll();
}
input_manager.poll();
}

View File

@ -18,16 +18,7 @@ bool _term_ = false;
#include "ui.cpp"
#include "event.cpp"
bool allow_input() {
#if defined(PLATFORM_X)
//TODO: window_main.focused() does not work at all on X
return true;
#endif
//only allow input capture when main window is active
return window_main.focused() == true;
}
void alert(char *s, ...) {
void alert(const char *s, ...) {
char str[4096];
va_list args;
va_start(args, s);
@ -36,7 +27,7 @@ va_list args;
fprintf(stdout, "%s\r\n", str);
}
void dprintf(char *s, ...) {
void dprintf(const char *s, ...) {
char str[4096];
va_list args;
va_start(args, s);
@ -45,7 +36,7 @@ va_list args;
fprintf(stdout, "%s\r\n", str);
}
void dprintf(uint source, char *s, ...) {
void dprintf(uint source, const char *s, ...) {
char str[4096];
va_list args;
va_start(args, s);
@ -67,7 +58,8 @@ void run() {
snes.runtoframe();
event::update_frame_counter();
}
#if defined(_MSC_VER)
#if defined(PLATFORM_WIN)
//prevent bsnes from consuming 100% CPU resources when idle
else { Sleep(1); }
#endif

View File

@ -1,3 +1,13 @@
bool MainWindow::input_ready() {
#if defined(PLATFORM_X)
//FIXME: focused() is broken in X port
return true;
#endif
//only allow input when main window is focused
return focused() == true;
}
bool MainWindow::message(uint id, uintptr_t param) {
ui::Control *control = (ui::Control*)param;
if(id == ui::Message::Close) {
@ -102,6 +112,8 @@ ui::Control *control = (ui::Control*)param;
}
void MainWindow::setup() {
snesinterface.input_ready = bind(&MainWindow::input_ready, this);
ui::ControlGroup group;
create(ui::Window::Center, 256, 224, BSNES_TITLE);
set_background_color(0, 0, 0);
@ -169,7 +181,7 @@ ui::ControlGroup group;
group.add(menu_settings_videoframeskip_7);
group.add(menu_settings_videoframeskip_8);
group.add(menu_settings_videoframeskip_9);
menu_settings_videoframeskip_0.create(menu_settings_videoframeskip, group, "0 (off)");
menu_settings_videoframeskip_0.create(menu_settings_videoframeskip, group, "0");
menu_settings_videoframeskip_sep1.create(menu_settings_videoframeskip);
menu_settings_videoframeskip_1.create(menu_settings_videoframeskip, group, "1");
menu_settings_videoframeskip_2.create(menu_settings_videoframeskip, group, "2");

View File

@ -60,6 +60,8 @@ ui::MenuGroup menu_misc;
ui::Container view;
//
bool input_ready();
bool message(uint id, uintptr_t param = 0);
void setup();
void setup_menu();