mirror of https://github.com/bsnes-emu/bsnes.git
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:
parent
c57c733d7d
commit
1e130d7872
26
src/Makefile
26
src/Makefile
|
@ -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
|
||||
|
||||
####################################
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -1,3 +1,5 @@
|
|||
#define _WIN32_IE 0x0600
|
||||
|
||||
#include "libui_win.h"
|
||||
#include "libui_win_window.cpp"
|
||||
#include "libui_win_control.cpp"
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
Tracer tracer;
|
||||
|
||||
void tprintf(char *s, ...) {
|
||||
void tprintf(const char *s, ...) {
|
||||
if(tracer.enabled() == false) { return; }
|
||||
|
||||
char str[4096];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue