From 7919071a25449e9dce8d781037f7d1dbf5e58aae Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Fri, 19 Jun 2020 23:58:12 -0400 Subject: [PATCH 001/100] =?UTF-8?q?Cleaned=20up=20gcc=20compiler=20warning?= =?UTF-8?q?=20:=20ISO=20C++=20forbids=20converting=20a=20string=20constant?= =?UTF-8?q?=20to=20=E2=80=98char*=E2=80=99=20[-Wwrite-strings]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cheat.h | 4 ++-- src/driver.h | 4 ++-- src/drivers/common/cheat.cpp | 6 +++--- src/drivers/sdl/config.cpp | 2 +- src/drivers/sdl/input.cpp | 2 +- src/drivers/sdl/sdl.cpp | 6 +++--- src/drivers/sdl/unix-netplay.cpp | 2 +- src/fceu.cpp | 6 ++++-- src/fceu.h | 8 ++++---- src/file.cpp | 2 +- src/file.h | 2 +- src/ines.cpp | 6 +++--- src/ines.h | 2 +- src/input.h | 2 +- src/lua-engine.cpp | 8 +++++--- src/movie.cpp | 2 +- src/movie.h | 2 +- src/nsf.cpp | 2 +- src/state.cpp | 8 ++++---- src/state.h | 4 ++-- src/unif.cpp | 10 +++++----- src/utils/xstring.cpp | 2 +- src/utils/xstring.h | 4 ++-- src/video.cpp | 6 +++--- src/vsuni.cpp | 2 +- 25 files changed, 54 insertions(+), 50 deletions(-) diff --git a/src/cheat.h b/src/cheat.h index 4ea6f12c..9f3dbe2b 100644 --- a/src/cheat.h +++ b/src/cheat.h @@ -40,7 +40,7 @@ typedef struct { struct CHEATF { struct CHEATF *next; - char *name = ""; + char *name; uint16 addr; uint8 val; int compare; /* -1 for no compare. */ @@ -65,4 +65,4 @@ struct SEARCHPOSSIBLE { #define FCEU_SEARCH_NEWVAL_GT_KNOWN 7 #define FCEU_SEARCH_NEWVAL_LT_KNOWN 8 -#endif \ No newline at end of file +#endif diff --git a/src/driver.h b/src/driver.h index 496ab636..d3f1f020 100644 --- a/src/driver.h +++ b/src/driver.h @@ -23,7 +23,7 @@ ArchiveScanRecord FCEUD_ScanArchive(std::string fname); const char *FCEUD_GetCompilerString(); //This makes me feel dirty for some reason. -void FCEU_printf(char *format, ...); +void FCEU_printf(const char *format, ...); #define FCEUI_printf FCEU_printf //Video interface @@ -183,7 +183,7 @@ void FCEUD_LuaRunFrom(void); int32 FCEUI_GetDesiredFPS(void); void FCEUI_SaveSnapshot(void); void FCEUI_SaveSnapshotAs(void); -void FCEU_DispMessage(char *format, int disppos, ...); +void FCEU_DispMessage(const char *format, int disppos, ...); #define FCEUI_DispMessage FCEU_DispMessage int FCEUI_DecodePAR(const char *code, int *a, int *v, int *c, int *type); diff --git a/src/drivers/common/cheat.cpp b/src/drivers/common/cheat.cpp index b03edad9..f985876e 100644 --- a/src/drivers/common/cheat.cpp +++ b/src/drivers/common/cheat.cpp @@ -176,7 +176,7 @@ int AddToList(char *text, uint32 id) **/ typedef struct MENU { - char *text; + const char *text; void *action; int type; // 0 for menu, 1 for function. } MENU; @@ -392,7 +392,7 @@ static void ShowRes(void) } } -static int ShowShortList(char *moe[], int n, int def) +static int ShowShortList(const char *moe[], int n, int def) { int x,c; int baa; //mbg merge 7/17/06 made to normal int @@ -430,7 +430,7 @@ static void DoSearch(void) { static int v1=0,v2=0; static int method=0; - char *m[9]={"O==V1 && C==V2", + const char *m[9]={"O==V1 && C==V2", "O==V1 && |O-C|==V2", "|O-C|==V2", "O!=C", diff --git a/src/drivers/sdl/config.cpp b/src/drivers/sdl/config.cpp index 9774e0d0..4856cbb2 100644 --- a/src/drivers/sdl/config.cpp +++ b/src/drivers/sdl/config.cpp @@ -102,7 +102,7 @@ LoadCPalette(const std::string &file) static void CreateDirs(const std::string &dir) { - char *subs[8]={"fcs","snaps","gameinfo","sav","cheats","movies","cfg.d"}; + const char *subs[8]={"fcs","snaps","gameinfo","sav","cheats","movies","cfg.d"}; std::string subdir; int x; diff --git a/src/drivers/sdl/input.cpp b/src/drivers/sdl/input.cpp index f4246e96..9e7280c9 100644 --- a/src/drivers/sdl/input.cpp +++ b/src/drivers/sdl/input.cpp @@ -1808,7 +1808,7 @@ void ConfigDevice (int which, int arg) char buf[256]; int x; std::string prefix; - char *str[10] = + const char *str[10] = { "A", "B", "SELECT", "START", "UP", "DOWN", "LEFT", "RIGHT", "Rapid A", "Rapid B" }; diff --git a/src/drivers/sdl/sdl.cpp b/src/drivers/sdl/sdl.cpp index fb421832..dd3d1c83 100644 --- a/src/drivers/sdl/sdl.cpp +++ b/src/drivers/sdl/sdl.cpp @@ -493,12 +493,12 @@ FILE *FCEUD_UTF8fopen(const char *fn, const char *mode) return(fopen(fn,mode)); } -static char *s_linuxCompilerString = "g++ " __VERSION__; +static const char *s_linuxCompilerString = "g++ " __VERSION__; /** * Returns the compiler string. */ const char *FCEUD_GetCompilerString() { - return (const char *)s_linuxCompilerString; + return s_linuxCompilerString; } /** @@ -590,7 +590,7 @@ int main(int argc, char *argv[]) else if(strcmp(argv[i], "--nogui") == 0) { noGui = 1; - argv[i] = ""; + //argv[i] = ""; } #endif } diff --git a/src/drivers/sdl/unix-netplay.cpp b/src/drivers/sdl/unix-netplay.cpp index 66f8a687..b1d732a6 100644 --- a/src/drivers/sdl/unix-netplay.cpp +++ b/src/drivers/sdl/unix-netplay.cpp @@ -117,7 +117,7 @@ FCEUD_NetworkConnect(void) TSocket = socket(AF_INET, SOCK_STREAM, 0); if(TSocket < 0) { - char* s = "Error creating stream socket."; + const char* s = "Error creating stream socket."; puts(s); FCEU_DispMessage(s,0); FCEUD_NetworkClose(); diff --git a/src/fceu.cpp b/src/fceu.cpp index f97595d4..90e295bd 100644 --- a/src/fceu.cpp +++ b/src/fceu.cpp @@ -980,7 +980,8 @@ void FCEU_ResetVidSys(void) { FCEUS FSettings; -void FCEU_printf(char *format, ...) { +void FCEU_printf(const char *format, ...) +{ char temp[2048]; va_list ap; @@ -999,7 +1000,8 @@ void FCEU_printf(char *format, ...) { va_end(ap); } -void FCEU_PrintError(char *format, ...) { +void FCEU_PrintError(const char *format, ...) +{ char temp[2048]; va_list ap; diff --git a/src/fceu.h b/src/fceu.h index a15da070..a9075f4f 100644 --- a/src/fceu.h +++ b/src/fceu.h @@ -133,10 +133,10 @@ extern FCEUS FSettings; bool CheckFileExists(const char* filename); //Receives a filename (fullpath) and checks to see if that file exists -void FCEU_PrintError(char *format, ...); -void FCEU_printf(char *format, ...); -void FCEU_DispMessage(char *format, int disppos, ...); -void FCEU_DispMessageOnMovie(char *format, ...); +void FCEU_PrintError(const char *format, ...); +void FCEU_printf(const char *format, ...); +void FCEU_DispMessage(const char *format, int disppos, ...); +void FCEU_DispMessageOnMovie(const char *format, ...); void FCEU_TogglePPU(); void SetNESDeemph_OldHacky(uint8 d, int force); diff --git a/src/file.cpp b/src/file.cpp index dfbba02e..0aeb6ae2 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -260,7 +260,7 @@ zpfail: return 0; } -FCEUFILE * FCEU_fopen(const char *path, const char *ipsfn, char *mode, char *ext, int index, const char** extensions, int* userCancel) +FCEUFILE * FCEU_fopen(const char *path, const char *ipsfn, const char *mode, char *ext, int index, const char** extensions, int* userCancel) { FILE *ipsfile=0; FCEUFILE *fceufp=0; diff --git a/src/file.h b/src/file.h index f5dcf426..84235f70 100644 --- a/src/file.h +++ b/src/file.h @@ -122,7 +122,7 @@ struct ArchiveScanRecord }; -FCEUFILE *FCEU_fopen(const char *path, const char *ipsfn, char *mode, char *ext, int index=-1, const char** extensions = 0, int* userCancel = 0); +FCEUFILE *FCEU_fopen(const char *path, const char *ipsfn, const char *mode, char *ext, int index=-1, const char** extensions = 0, int* userCancel = 0); bool FCEU_isFileInArchive(const char *path); int FCEU_fclose(FCEUFILE*); uint64 FCEU_fread(void *ptr, size_t size, size_t nmemb, FCEUFILE*); diff --git a/src/ines.cpp b/src/ines.cpp index 48f00b61..1b75ae07 100644 --- a/src/ines.cpp +++ b/src/ines.cpp @@ -233,7 +233,7 @@ static void SetInput(void) { struct BADINF { uint64 md5partial; - char *name; + const char *name; uint32 type; }; @@ -417,7 +417,7 @@ static void CheckHInfo(void) { if (tofix & 1) sprintf(gigastr + strlen(gigastr), "The mapper number should be set to %d. ", MapperNo); if (tofix & 2) { - char *mstr[3] = { "Horizontal", "Vertical", "Four-screen" }; + const char *mstr[3] = { "Horizontal", "Vertical", "Four-screen" }; sprintf(gigastr + strlen(gigastr), "Mirroring should be set to \"%s\". ", mstr[Mirroring & 3]); } if (tofix & 4) @@ -839,7 +839,7 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) { FCEU_printf("\n"); } - char* mappername = "Not Listed"; + const char* mappername = "Not Listed"; for (int mappertest = 0; mappertest < (sizeof bmap / sizeof bmap[0]) - 1; mappertest++) { if (bmap[mappertest].number == MapperNo) { diff --git a/src/ines.h b/src/ines.h index f82f7a86..6ad2657b 100644 --- a/src/ines.h +++ b/src/ines.h @@ -270,7 +270,7 @@ void Mapper254_Init(CartInfo *); void Mapper406_Init(CartInfo *); typedef struct { - char *name; + const char *name; int32 number; void (*init)(CartInfo *); } BMAPPINGLocal; diff --git a/src/input.h b/src/input.h index b3c4199a..d2eb2053 100644 --- a/src/input.h +++ b/src/input.h @@ -295,7 +295,7 @@ struct EMUCMDTABLE EMUCMDFN* fn_on; EMUCMDFN* fn_off; int state; - char* name; + const char* name; int flags; //EMUCMDFLAG }; diff --git a/src/lua-engine.cpp b/src/lua-engine.cpp index 76f99cb3..645eaf31 100644 --- a/src/lua-engine.cpp +++ b/src/lua-engine.cpp @@ -515,6 +515,7 @@ static int emu_getdir(lua_State *L) { return 1; #endif + return 0; } @@ -545,6 +546,7 @@ static int emu_loadrom(lua_State *L) { return 1; } #endif + return 1; } @@ -5227,7 +5229,7 @@ static int doPopup(lua_State *L, const char* deftype, const char* deficon) { return 1; #else - char *t; + const char *t; #ifdef __linux int pid; // appease compiler @@ -5285,9 +5287,9 @@ static int doPopup(lua_State *L, const char* deftype, const char* deficon) { // I'm gonna be dead in a matter of microseconds anyways, so wasted memory doesn't matter to me. // Go ahead and abuse strdup. - char * parameters[] = {"xmessage", "-buttons", t, strdup(str), NULL}; + const char * parameters[] = {"xmessage", "-buttons", t, strdup(str), NULL}; - execvp("xmessage", parameters); + execvp("xmessage", (char* const*)parameters); // Aw shitty perror("exec xmessage"); diff --git a/src/movie.cpp b/src/movie.cpp index 4ba7e29c..0a33f5f0 100644 --- a/src/movie.cpp +++ b/src/movie.cpp @@ -2000,7 +2000,7 @@ void ProcessSubtitles(void) } } -void FCEU_DisplaySubtitles(char *format, ...) +void FCEU_DisplaySubtitles(const char *format, ...) { va_list ap; diff --git a/src/movie.h b/src/movie.h index 0824db17..10b7979a 100644 --- a/src/movie.h +++ b/src/movie.h @@ -309,7 +309,7 @@ void FCEUI_ToggleInputDisplay(void); void LoadSubtitles(MovieData &); void ProcessSubtitles(void); -void FCEU_DisplaySubtitles(char *format, ...); +void FCEU_DisplaySubtitles(const char *format, ...); void poweron(bool shouldDisableBatteryLoading); diff --git a/src/nsf.cpp b/src/nsf.cpp index 453e4fa9..129e045d 100644 --- a/src/nsf.cpp +++ b/src/nsf.cpp @@ -262,7 +262,7 @@ int NSFLoad(const char *name, FCEUFILE *fp) FCEU_printf(" Name: %s\n Artist: %s\n Copyright: %s\n\n",NSFHeader.SongName,NSFHeader.Artist,NSFHeader.Copyright); if(NSFHeader.SoundChip) { - static char *tab[6]={"Konami VRCVI","Konami VRCVII","Nintendo FDS","Nintendo MMC5","Namco 106","Sunsoft FME-07"}; + static const char *tab[6]={"Konami VRCVI","Konami VRCVII","Nintendo FDS","Nintendo MMC5","Namco 106","Sunsoft FME-07"}; for(x=0;x<6;x++) if(NSFHeader.SoundChip&(1<vidsys = GIV_NTSC; FCEUI_SetVidSystem(0); diff --git a/src/utils/xstring.cpp b/src/utils/xstring.cpp index 831aebd9..8f8b66d3 100644 --- a/src/utils/xstring.cpp +++ b/src/utils/xstring.cpp @@ -157,7 +157,7 @@ int chr_replace(char *str, char search, char replace) { ///Replaces all instances of 'search' with 'replace' ///Returns number of sub-strings modified, or -1 on error -int str_replace(char *str, char *search, char *replace) { +int str_replace(char *str, const char *search, const char *replace) { unsigned int i=0,j=0; //mbg merge 7/17/06 changed to unsigned int int searchlen,replacelen; char *astr; diff --git a/src/utils/xstring.h b/src/utils/xstring.h index b42aec12..9d860486 100644 --- a/src/utils/xstring.h +++ b/src/utils/xstring.h @@ -43,7 +43,7 @@ int str_ltrim(char *str, int flags); int str_rtrim(char *str, int flags); int str_strip(char *str, int flags); int chr_replace(char *str, char search, char replace); -int str_replace(char *str, char *search, char *replace); +int str_replace(char *str, const char *search, const char *replace); int HexStringToBytesLength(const std::string& str); int Base64StringToBytesLength(const std::string& str); @@ -129,4 +129,4 @@ std::string wcstombs(std::wstring str); std::string getExtension(const char* input); std::string StripExtension(std::string filename); -std::string StripPath(std::string filename); \ No newline at end of file +std::string StripPath(std::string filename); diff --git a/src/video.cpp b/src/video.cpp index d9654c96..3c43d7bd 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -398,7 +398,7 @@ void snapAVI() FCEUI_AviVideoUpdate(XBuf); } -void FCEU_DispMessageOnMovie(char *format, ...) +void FCEU_DispMessageOnMovie(const char *format, ...) { va_list ap; @@ -414,7 +414,7 @@ void FCEU_DispMessageOnMovie(char *format, ...) guiMessage.howlong = 0; } -void FCEU_DispMessage(char *format, int disppos=0, ...) +void FCEU_DispMessage(const char *format, int disppos=0, ...) { va_list ap; @@ -455,7 +455,7 @@ void FCEU_ResetMessages() } -static int WritePNGChunk(FILE *fp, uint32 size, char *type, uint8 *data) +static int WritePNGChunk(FILE *fp, uint32 size, const char *type, uint8 *data) { uint32 crc; diff --git a/src/vsuni.cpp b/src/vsuni.cpp index 26e6ab62..c2e64766 100644 --- a/src/vsuni.cpp +++ b/src/vsuni.cpp @@ -35,7 +35,7 @@ #define IOPTION_PREDIP 0x10 typedef struct { - char *name; + const char *name; uint64 md5partial; int mapper; int mirroring; From cc15338ebbc2cbbafea4edbc0ed362dbe36340e0 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 20 Jun 2020 00:06:47 -0400 Subject: [PATCH 002/100] Cast const char * to char * to get past winbuild.... this is not the best way to go, but it works. --- CMakeLists.txt | 7 + pipelines/linux_build.sh | 8 +- src/CMakeLists.txt | 347 +++++++++++++++++++++++++++++++++++ src/drivers/win/mapinput.cpp | 2 +- 4 files changed, 361 insertions(+), 3 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 src/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..1cbc07cf --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,7 @@ + +cmake_minimum_required(VERSION 2.8) + +project(fceux) + +add_subdirectory( src ) + diff --git a/pipelines/linux_build.sh b/pipelines/linux_build.sh index bf6c1c9b..92d29394 100755 --- a/pipelines/linux_build.sh +++ b/pipelines/linux_build.sh @@ -81,8 +81,12 @@ echo '**************************' echo '*** Building Project ***' echo '**************************' mkdir -p $INSTALL_PREFIX/usr; -scons --clean -scons GTK3=1 SYSTEM_LUA=1 SYSTEM_MINIZIP=1 CREATE_AVI=1 install --prefix=$INSTALL_PREFIX/usr +#scons --clean +#scons GTK3=1 SYSTEM_LUA=1 SYSTEM_MINIZIP=1 CREATE_AVI=1 install --prefix=$INSTALL_PREFIX/usr +mkdir build; cd build; +cmake .. +make -j `nproc` +#DESTDIR=$INSTALL_PREFIX make -j `nproc` install # Debug via ssh if necessary if [ ! -z $APPVEYOR_SSH_BLOCK ]; then diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 00000000..149ca68b --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,347 @@ + +if(WIN32) + set(SOURCES ${SRC_CORE} ${SRC_DRIVERS_COMMON} ${SRC_DRIVERS_WIN}) + include_directories( ${CMAKE_SOURCE_DIR}/src/drivers/win/directx ${CMAKE_SOURCE_DIR}/src/drivers/win/zlib ) + add_definitions( + -DWIN32 + -DFCEUDEF_DEBUGGER + -D_USE_SHARED_MEMORY_ + -DPSS_STYLE=2 + -DNOMINMAX + -D_S9XLUA_H + ) + link_directories( ${CMAKE_SOURCE_DIR}/src/drivers/win/directx ) +else(WIN32) + # Non Windows System + # Use the package PkgConfig to detect headers/library files + find_package(PkgConfig REQUIRED) + + # Check for GTK+3 + pkg_check_modules(GTK3 REQUIRED gtk+-3.0) + + if ( ${GTK3_FOUND} ) + add_definitions( -D_GTK ${GTK3_CFLAGS} ) + endif() + + # Check for X11 + pkg_check_modules( X11 x11 ) + + if ( ${X11_FOUND} ) + add_definitions( ${X11_CFLAGS} ) + endif() + + # Check for OpenGL + pkg_check_modules( GL REQUIRED gl) + + if ( ${GL_FOUND} ) + add_definitions( -DOPENGL ${GL_CFLAGS} ) + endif() + + # Check for libminizip + pkg_check_modules( MINIZIP REQUIRED minizip) + + if ( ${MINIZIP_FOUND} ) + add_definitions( -D_SYSTEM_MINIZIP ${MINIZIP_CFLAGS} ) + endif() + + # Check for SDL2 + pkg_check_modules( SDL2 REQUIRED sdl2) + + if ( ${SDL2_FOUND} ) + add_definitions( ${SDL2_CFLAGS} ) + endif() + + # Check for LUA + pkg_check_modules( LUA lua-5.1) + + if ( ${LUA_FOUND} ) + add_definitions( -D_S9XLUA_H ${LUA_CFLAGS} ) + set( LUA_ENGINE_SOURCE lua-engine.cpp ) + endif() + + add_definitions( -DHAVE_ASPRINTF ) # What system wouldn't have this? + + set( SYS_LIBS -lrt -lpthread ) + +endif(WIN32) + +if(APPLE) + add_definitions( -DPSS_STYLE=4 ) +else(APPLE) + if(UNIX) + add_definitions( -DPSS_STYLE=1 ) + endif(UNIX) +endif(APPLE) + +set(SRC_CORE + ${CMAKE_CURRENT_SOURCE_DIR}/asm.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/cart.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/cheat.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/conddebug.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/config.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/debug.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drawing.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/fceu.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/fds.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/file.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/emufile.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/filter.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/ines.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/input.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/movie.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/netplay.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/nsf.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/oldmovie.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/palette.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/ppu.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/sound.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/state.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/unif.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/video.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/vsuni.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/wave.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/x6502.cpp + ${LUA_ENGINE_SOURCE} + ${CMAKE_CURRENT_SOURCE_DIR}/boards/01-222.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/09-034a.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/103.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/106.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/108.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/112.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/116.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/117.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/120.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/121.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/12in1.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/151.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/156.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/158B.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/15.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/164.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/168.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/170.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/175.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/176.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/177.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/178.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/183.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/185.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/186.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/187.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/189.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/18.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/190.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/193.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/199.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/206.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/208.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/222.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/225.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/228.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/230.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/232.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/234.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/235.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/244.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/246.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/252.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/253.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/28.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/32.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/33.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/34.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/36.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/3d-block.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/40.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/411120-c.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/41.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/42.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/43.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/46.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/50.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/51.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/57.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/603-5052.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/62.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/65.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/67.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/68.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/69.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/71.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/72.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/77.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/79.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/80013-B.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/80.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/8157.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/8237.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/82.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/830118C.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/88.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/8in1.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/90.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/91.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/96.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/99.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/a9746.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/ac-08.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/addrlatch.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/ax5705.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/bandai.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/bb.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/bmc13in1jy110.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/bmc42in1r.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/bmc64in1nr.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/bmc70in1.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/BMW8544.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/bonza.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/bs-5.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/cheapocabra.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/cityfighter.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/coolboy.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/dance2000.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/datalatch.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/dream.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/__dummy_mapper.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/edu2000.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/eh8813a.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/emu2413.c + ${CMAKE_CURRENT_SOURCE_DIR}/boards/et-100.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/et-4320.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/F-15.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/famicombox.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/ffe.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/fk23c.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/fns.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/ghostbusters63in1.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/gs-2004.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/gs-2013.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/h2288.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/hp10xx_hp20xx.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/hp898f.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/inlnsf.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/karaoke.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/kof97.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/ks7010.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/ks7012.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/ks7013.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/ks7016.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/ks7017.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/ks7030.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/ks7031.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/ks7032.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/ks7037.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/ks7057.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/le05.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/lh32.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/lh53.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/malee.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/mihunche.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/mmc1.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/mmc2and4.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/mmc3.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/mmc5.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/n106.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/n625092.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/novel.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/onebus.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/pec-586.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/rt-01.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/sa-9602b.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/sachen.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/sb-2000.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/sc-127.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/sheroes.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/sl1632.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/subor.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/super24.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/supervision.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/t-227-1.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/t-262.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/tengen.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/tf-1201.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/transformer.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/unrom512.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/vrc1.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/vrc2and4.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/vrc3.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/vrc5.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/vrc6.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/vrc7.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/vrc7p.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/boards/yoko.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/input/arkanoid.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/input/bworld.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/input/cursor.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/input/fkb.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/input/fns.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/input/ftrainer.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/input/hypershot.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/input/mahjong.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/input/mouse.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/input/oekakids.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/input/pec586kb.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/input/powerpad.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/input/quiz.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/input/shadow.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/input/snesmouse.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/input/suborkb.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/input/toprider.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/input/virtualboy.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/input/zapper.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/utils/backward.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/utils/ConvertUTF.c + ${CMAKE_CURRENT_SOURCE_DIR}/utils/xstring.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/utils/crc32.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/utils/endian.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/utils/general.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/utils/guid.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/utils/md5.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/utils/memory.cpp +) + + +set(SRC_DRIVERS_COMMON + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/args.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/cheat.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/config.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/configSys.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/hq2x.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/hq3x.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/scale2x.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/scale3x.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/scalebit.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/vidblit.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/nes_ntsc.c +) + +set(SRC_DRIVERS_SDL + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/config.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/input.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/gui.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/cheat.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/debugger.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/memview.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/ramwatch.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/sdl.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/sdl-joystick.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/sdl-sound.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/sdl-throttle.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/sdl-video.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/glxwin.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/unix-netplay.cpp +) + +set(SOURCES ${SRC_CORE} ${SRC_DRIVERS_COMMON} ${SRC_DRIVERS_SDL}) + +add_executable( fceux ${SOURCES} ) + +target_link_libraries( fceux + ${GTK3_LDFLAGS} + ${X11_LDFLAGS} + ${GL_LDFLAGS} + ${SDL2_LDFLAGS} + ${MINIZIP_LDFLAGS} + ${LUA_LDFLAGS} + ${SYS_LIBS} +) diff --git a/src/drivers/win/mapinput.cpp b/src/drivers/win/mapinput.cpp index aca19ad1..662fa969 100644 --- a/src/drivers/win/mapinput.cpp +++ b/src/drivers/win/mapinput.cpp @@ -543,7 +543,7 @@ void PopulateMappingDisplay(HWND hwndDlg) lvi.mask = LVIF_TEXT; lvi.iItem = idx; lvi.iSubItem = 1; - lvi.pszText = FCEUI_CommandTable[i].name; + lvi.pszText = (char*)FCEUI_CommandTable[i].name; SendMessage(hwndListView, LVM_SETITEM, (WPARAM)0, (LPARAM)&lvi); From 36b9cf3fb35ec97fad52e161d27e83f914d6c249 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 20 Jun 2020 00:13:08 -0400 Subject: [PATCH 003/100] Fixed references to print error function in win tas editor. --- src/drivers/win/taseditor/taseditor_project.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/win/taseditor/taseditor_project.cpp b/src/drivers/win/taseditor/taseditor_project.cpp index c3b09fa1..4baad00b 100644 --- a/src/drivers/win/taseditor/taseditor_project.cpp +++ b/src/drivers/win/taseditor/taseditor_project.cpp @@ -35,7 +35,7 @@ extern SPLICER splicer; extern FCEUGI *GameInfo; -extern void FCEU_PrintError(char *format, ...); +extern void FCEU_PrintError(const char *format, ...); extern bool saveProject(bool save_compact = false); extern bool saveProjectAs(bool save_compact = false); extern int getInputType(MovieData& md); From 714e7bbfb253d02ab6251522588750cd30c7dcdd Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 20 Jun 2020 00:20:58 -0400 Subject: [PATCH 004/100] Added logic to make cmake output verbose. --- pipelines/linux_build.sh | 5 ++++- src/CMakeLists.txt | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/pipelines/linux_build.sh b/pipelines/linux_build.sh index 92d29394..834fa0d3 100755 --- a/pipelines/linux_build.sh +++ b/pipelines/linux_build.sh @@ -84,7 +84,10 @@ mkdir -p $INSTALL_PREFIX/usr; #scons --clean #scons GTK3=1 SYSTEM_LUA=1 SYSTEM_MINIZIP=1 CREATE_AVI=1 install --prefix=$INSTALL_PREFIX/usr mkdir build; cd build; -cmake .. +cmake \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ + .. make -j `nproc` #DESTDIR=$INSTALL_PREFIX make -j `nproc` install diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 149ca68b..d0a85653 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -44,6 +44,8 @@ else(WIN32) add_definitions( -D_SYSTEM_MINIZIP ${MINIZIP_CFLAGS} ) endif() + #pkg_check_modules( ZLIB REQUIRED zlib) + # Check for SDL2 pkg_check_modules( SDL2 REQUIRED sdl2) From 6271d63ba6cfa72b91b677449148028d0db2175b Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 20 Jun 2020 00:36:43 -0400 Subject: [PATCH 005/100] Added cmake package check for zlib --- pipelines/linux_build.sh | 1 + src/CMakeLists.txt | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/pipelines/linux_build.sh b/pipelines/linux_build.sh index 834fa0d3..e48bacb1 100755 --- a/pipelines/linux_build.sh +++ b/pipelines/linux_build.sh @@ -83,6 +83,7 @@ echo '**************************' mkdir -p $INSTALL_PREFIX/usr; #scons --clean #scons GTK3=1 SYSTEM_LUA=1 SYSTEM_MINIZIP=1 CREATE_AVI=1 install --prefix=$INSTALL_PREFIX/usr +echo "Num CPU: `nproc`"; mkdir build; cd build; cmake \ -DCMAKE_BUILD_TYPE=Release \ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d0a85653..fb877146 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -44,7 +44,12 @@ else(WIN32) add_definitions( -D_SYSTEM_MINIZIP ${MINIZIP_CFLAGS} ) endif() - #pkg_check_modules( ZLIB REQUIRED zlib) + pkg_check_modules( ZLIB REQUIRED zlib) + + # Check for zlib + if ( ${ZLIB_FOUND} ) + add_definitions( ${ZLIB_CFLAGS} ) + endif() # Check for SDL2 pkg_check_modules( SDL2 REQUIRED sdl2) @@ -343,7 +348,7 @@ target_link_libraries( fceux ${X11_LDFLAGS} ${GL_LDFLAGS} ${SDL2_LDFLAGS} - ${MINIZIP_LDFLAGS} + ${MINIZIP_LDFLAGS} ${ZLIB_LDFLAGS} ${LUA_LDFLAGS} ${SYS_LIBS} ) From 9a30cce9218e669e16b91ce6e1c9163a5b8fb3fb Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 20 Jun 2020 00:39:44 -0400 Subject: [PATCH 006/100] Fixed compiler warning for unchecked fgets return value. --- src/drivers/sdl/unix-netplay.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/drivers/sdl/unix-netplay.cpp b/src/drivers/sdl/unix-netplay.cpp index b1d732a6..1150fcdc 100644 --- a/src/drivers/sdl/unix-netplay.cpp +++ b/src/drivers/sdl/unix-netplay.cpp @@ -252,9 +252,14 @@ FCEUD_SendData(void *data, if(!error && check) { char buf[1024]; char *f; - fgets(buf, 1024, stdin); - if((f=strrchr(buf,'\n'))) { - *f = 0; + + buf[0] = 0; + + if ( fgets(buf, 1024, stdin) ) + { + if((f=strrchr(buf,'\n'))) { + *f = 0; + } } FCEUI_NetplayText((uint8 *)buf); } From 70a77cbe41c5dd2c4af639e30c0cce3cd5106be9 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 20 Jun 2020 00:53:18 -0400 Subject: [PATCH 007/100] Added install target to cmake. --- pipelines/linux_build.sh | 3 ++- src/CMakeLists.txt | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pipelines/linux_build.sh b/pipelines/linux_build.sh index e48bacb1..f4a979ab 100755 --- a/pipelines/linux_build.sh +++ b/pipelines/linux_build.sh @@ -87,10 +87,11 @@ echo "Num CPU: `nproc`"; mkdir build; cd build; cmake \ -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX/usr \ -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ .. make -j `nproc` -#DESTDIR=$INSTALL_PREFIX make -j `nproc` install +make install # Debug via ssh if necessary if [ ! -z $APPVEYOR_SSH_BLOCK ]; then diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fb877146..46c677c6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -352,3 +352,6 @@ target_link_libraries( fceux ${LUA_LDFLAGS} ${SYS_LIBS} ) + +install( TARGETS fceux + RUNTIME bin ) From fb9ee25800133e4c301b8176dc748082cd6d27a9 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 20 Jun 2020 00:54:26 -0400 Subject: [PATCH 008/100] Bug fix for cmake install target. --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 46c677c6..c1a07e18 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -354,4 +354,4 @@ target_link_libraries( fceux ) install( TARGETS fceux - RUNTIME bin ) + RUNTIME DESTINATION bin ) From be4c650238857e0827498dd40d9518434c0bc2c9 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Tue, 23 Jun 2020 20:40:43 -0400 Subject: [PATCH 009/100] Starting new QT gui. --- src/drivers/Qt/.qmake.stash | 22 + src/drivers/Qt/GameApp.cpp | 88 ++ src/drivers/Qt/GameApp.h | 50 + src/drivers/Qt/GameViewer.cpp | 64 + src/drivers/Qt/GameViewer.h | 26 + src/drivers/Qt/config.cpp | 485 +++++++ src/drivers/Qt/config.h | 28 + src/drivers/Qt/dface.h | 37 + src/drivers/Qt/fceuWrapper.cpp | 300 ++++ src/drivers/Qt/fceuWrapper.h | 23 + src/drivers/Qt/gl_win.cpp | 54 + src/drivers/Qt/gl_win.h | 68 + src/drivers/Qt/input.cpp | 2355 +++++++++++++++++++++++++++++++ src/drivers/Qt/input.h | 62 + src/drivers/Qt/keyscan.h | 44 + src/drivers/Qt/main.cpp | 15 + src/drivers/Qt/main.h | 100 ++ src/drivers/Qt/sdl-joystick.cpp | 123 ++ src/drivers/Qt/sdl-sound.cpp | 280 ++++ src/drivers/Qt/sdl-throttle.cpp | 154 ++ src/drivers/Qt/sdl-video.cpp | 464 ++++++ src/drivers/Qt/sdl-video.h | 17 + src/drivers/Qt/sdl.h | 32 + src/drivers/Qt/throttle.h | 2 + src/drivers/Qt/unix-netplay.cpp | 366 +++++ src/drivers/Qt/unix-netplay.h | 6 + src/fceux.pro | 305 ++++ 27 files changed, 5570 insertions(+) create mode 100644 src/drivers/Qt/.qmake.stash create mode 100644 src/drivers/Qt/GameApp.cpp create mode 100644 src/drivers/Qt/GameApp.h create mode 100644 src/drivers/Qt/GameViewer.cpp create mode 100644 src/drivers/Qt/GameViewer.h create mode 100644 src/drivers/Qt/config.cpp create mode 100644 src/drivers/Qt/config.h create mode 100644 src/drivers/Qt/dface.h create mode 100644 src/drivers/Qt/fceuWrapper.cpp create mode 100644 src/drivers/Qt/fceuWrapper.h create mode 100644 src/drivers/Qt/gl_win.cpp create mode 100644 src/drivers/Qt/gl_win.h create mode 100644 src/drivers/Qt/input.cpp create mode 100644 src/drivers/Qt/input.h create mode 100644 src/drivers/Qt/keyscan.h create mode 100644 src/drivers/Qt/main.cpp create mode 100644 src/drivers/Qt/main.h create mode 100644 src/drivers/Qt/sdl-joystick.cpp create mode 100644 src/drivers/Qt/sdl-sound.cpp create mode 100644 src/drivers/Qt/sdl-throttle.cpp create mode 100644 src/drivers/Qt/sdl-video.cpp create mode 100644 src/drivers/Qt/sdl-video.h create mode 100644 src/drivers/Qt/sdl.h create mode 100644 src/drivers/Qt/throttle.h create mode 100644 src/drivers/Qt/unix-netplay.cpp create mode 100644 src/drivers/Qt/unix-netplay.h create mode 100644 src/fceux.pro diff --git a/src/drivers/Qt/.qmake.stash b/src/drivers/Qt/.qmake.stash new file mode 100644 index 00000000..c753fda7 --- /dev/null +++ b/src/drivers/Qt/.qmake.stash @@ -0,0 +1,22 @@ +QMAKE_CXX.INCDIRS = \ + /usr/include/c++/8 \ + /usr/include/c++/8/x86_64-redhat-linux \ + /usr/include/c++/8/backward \ + /usr/lib/gcc/x86_64-redhat-linux/8/include \ + /usr/local/include \ + /usr/include +QMAKE_CXX.LIBDIRS = \ + /usr/lib/gcc/x86_64-redhat-linux/8 \ + /usr/lib64 \ + /lib64 \ + /usr/lib \ + /lib +QMAKE_CXX.QT_COMPILER_STDCXX = 201402L +QMAKE_CXX.QMAKE_GCC_MAJOR_VERSION = 8 +QMAKE_CXX.QMAKE_GCC_MINOR_VERSION = 3 +QMAKE_CXX.QMAKE_GCC_PATCH_VERSION = 1 +QMAKE_CXX.COMPILER_MACROS = \ + QT_COMPILER_STDCXX \ + QMAKE_GCC_MAJOR_VERSION \ + QMAKE_GCC_MINOR_VERSION \ + QMAKE_GCC_PATCH_VERSION diff --git a/src/drivers/Qt/GameApp.cpp b/src/drivers/Qt/GameApp.cpp new file mode 100644 index 00000000..de15835f --- /dev/null +++ b/src/drivers/Qt/GameApp.cpp @@ -0,0 +1,88 @@ +// GameApp.cpp +// +#include "GameApp.h" + +gameWin_t::gameWin_t(QWidget *parent) + : QMainWindow( parent ) +{ + QWidget *widget = new QWidget( this ); + + setCentralWidget(widget); + + QVBoxLayout *layout = new QVBoxLayout; + layout->setMargin(5); + + createMainMenu(); + + viewport = new gameView_t(); + //viewport.resize( 200, 200 ); + + layout->addWidget(viewport); + + widget->setLayout(layout); + + gameTimer = new QTimer( this ); + + connect( gameTimer, &QTimer::timeout, this, &gameWin_t::runGameFrame ); + + gameTimer->setTimerType( Qt::PreciseTimer ); + gameTimer->start( 10 ); +} + +gameWin_t::~gameWin_t(void) +{ + delete viewport; +} + +void gameWin_t::createMainMenu(void) +{ + menuBar()->setNativeMenuBar(false); + fileMenu = menuBar()->addMenu(tr("&File")); + + openAct = new QAction(tr("&Open"), this); + openAct->setShortcuts(QKeySequence::Open); + openAct->setStatusTip(tr("Open an Existing File")); + connect(openAct, SIGNAL(triggered()), this, SLOT(openFile(void)) ); + + fileMenu->addAction(openAct); + + quitAct = new QAction(tr("&Quit"), this); + quitAct->setStatusTip(tr("Quit the Application")); + connect(quitAct, SIGNAL(triggered()), qApp, SLOT(quit())); + + fileMenu->addAction(quitAct); + + helpMenu = menuBar()->addMenu(tr("&Help")); + + aboutAct = new QAction(tr("&About"), this); + aboutAct->setStatusTip(tr("About Qplot")); + connect(aboutAct, SIGNAL(triggered()), this, SLOT(aboutQPlot(void)) ); + + helpMenu->addAction(aboutAct); +}; + +void gameWin_t::openFile(void) +{ + printf("Open File\n"); + return; +} +void gameWin_t::aboutQPlot(void) +{ + printf("About QPlot\n"); + return; +} + +void gameWin_t::runGameFrame(void) +{ + struct timespec ts; + double t; + + clock_gettime( CLOCK_REALTIME, &ts ); + + t = (double)ts.tv_sec + (double)(ts.tv_nsec * 1.0e-9); + //printf("Run Frame %f\n", t); + // + viewport->repaint(); + + return; +} diff --git a/src/drivers/Qt/GameApp.h b/src/drivers/Qt/GameApp.h new file mode 100644 index 00000000..44f9529c --- /dev/null +++ b/src/drivers/Qt/GameApp.h @@ -0,0 +1,50 @@ + +// + +#ifndef __GameAppH__ +#define __GameAppH__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "GameViewer.h" + +class gameWin_t : public QMainWindow +{ + Q_OBJECT + + public: + gameWin_t(QWidget *parent = 0); + ~gameWin_t(void); + + gameView_t *viewport; + //QPushButton hello( "Hello world!", 0 ); + // + + QMenu *fileMenu; + QMenu *helpMenu; + + QAction *openAct; + QAction *quitAct; + QAction *aboutAct; + + QTimer *gameTimer; + + private: + void createMainMenu(void); + + private slots: + void openFile(void); + void aboutQPlot(void); + void runGameFrame(void); + +}; + +#endif diff --git a/src/drivers/Qt/GameViewer.cpp b/src/drivers/Qt/GameViewer.cpp new file mode 100644 index 00000000..ef32e331 --- /dev/null +++ b/src/drivers/Qt/GameViewer.cpp @@ -0,0 +1,64 @@ +// GameViewer.cpp +// +#include + +#include "GameViewer.h" + +gameView_t::gameView_t(QWidget *parent) + : QOpenGLWidget( parent ) +{ + +} + +gameView_t::~gameView_t(void) +{ + // Make sure the context is current and then explicitly + // destroy all underlying OpenGL resources. + makeCurrent(); + + // Free GL texture + + doneCurrent(); +} + +void gameView_t::initializeGL(void) +{ + initializeOpenGLFunctions(); + // Set up the rendering context, load shaders and other resources, etc.: + //QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions(); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + + printf("GL Init!\n"); +} + +void gameView_t::resizeGL(int w, int h) +{ + printf("GL Resize: %i x %i \n", w, h ); + glViewport(0, 0, w, h); + +} + +void gameView_t::paintGL(void) +{ + float x1, y1, x2, y2; + + angle += (2.0 * 3.14 * 0.01); + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + + x1 = cos( angle ); + y1 = sin( angle ); + + x2 = -x1; + y2 = -y1; + + glColor4f( 1.0, 1.0, 1.0, 1.0 ); + glLineWidth(5.0); + + glBegin(GL_LINES); + glVertex2f( x1, y1 ); + glVertex2f( x2, y2 ); + glEnd(); + + //printf("Paint GL!\n"); +} diff --git a/src/drivers/Qt/GameViewer.h b/src/drivers/Qt/GameViewer.h new file mode 100644 index 00000000..655eb9de --- /dev/null +++ b/src/drivers/Qt/GameViewer.h @@ -0,0 +1,26 @@ +// GameViewer.h +// + +#pragma once + +#include +#include + +class gameView_t : public QOpenGLWidget, protected QOpenGLFunctions +{ + Q_OBJECT + + public: + gameView_t(QWidget *parent = 0); + ~gameView_t(void); + + float angle; + + protected: + void initializeGL(void); + void resizeGL(int w, int h); + void paintGL(void); + + private slots: +}; + diff --git a/src/drivers/Qt/config.cpp b/src/drivers/Qt/config.cpp new file mode 100644 index 00000000..4856cbb2 --- /dev/null +++ b/src/drivers/Qt/config.cpp @@ -0,0 +1,485 @@ +#include "main.h" +#include "throttle.h" +#include "config.h" + +#include "../common/cheat.h" + +#include "input.h" +#include "dface.h" + +#include "sdl.h" +#include "sdl-video.h" +#include "unix-netplay.h" + +#ifdef WIN32 +#include +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static const char* HotkeyStrings[HK_MAX] = { + "CheatMenu", + "BindState", + "LoadLua", + "ToggleBG", + "SaveState", + "FDSSelect", + "LoadState", + "FDSEject", + "VSInsertCoin", + "VSToggleDip", + "MovieToggleFrameDisplay", + "SubtitleDisplay", + "Reset", + "Screenshot", + "Pause", + "DecreaseSpeed", + "IncreaseSpeed", + "FrameAdvance", + "Turbo", + "ToggleInputDisplay", + "ToggleMovieRW", + "MuteCapture", + "Quit", + "FrameAdvanceLagSkip", + "LagCounterDisplay", + "SelectState0", "SelectState1", "SelectState2", "SelectState3", + "SelectState4", "SelectState5", "SelectState6", "SelectState7", + "SelectState8", "SelectState9", "SelectStateNext", "SelectStatePrev", + "VolumeDown", "VolumeUp" }; + +const char *getHotkeyString( int i ) +{ + if ( (i>=0) && (iaddOption('s', "sound", "SDL.Sound", 1); + config->addOption("volume", "SDL.Sound.Volume", 150); + config->addOption("trianglevol", "SDL.Sound.TriangleVolume", 256); + config->addOption("square1vol", "SDL.Sound.Square1Volume", 256); + config->addOption("square2vol", "SDL.Sound.Square2Volume", 256); + config->addOption("noisevol", "SDL.Sound.NoiseVolume", 256); + config->addOption("pcmvol", "SDL.Sound.PCMVolume", 256); + config->addOption("soundrate", "SDL.Sound.Rate", 44100); + config->addOption("soundq", "SDL.Sound.Quality", 1); + config->addOption("soundrecord", "SDL.Sound.RecordFile", ""); + config->addOption("soundbufsize", "SDL.Sound.BufSize", 128); + config->addOption("lowpass", "SDL.Sound.LowPass", 0); + + config->addOption('g', "gamegenie", "SDL.GameGenie", 0); + config->addOption("pal", "SDL.PAL", 0); + config->addOption("frameskip", "SDL.Frameskip", 0); + config->addOption("clipsides", "SDL.ClipSides", 0); + config->addOption("nospritelim", "SDL.DisableSpriteLimit", 1); + config->addOption("swapduty", "SDL.SwapDuty", 0); + + // color control + config->addOption('p', "palette", "SDL.Palette", ""); + config->addOption("tint", "SDL.Tint", 56); + config->addOption("hue", "SDL.Hue", 72); + config->addOption("ntsccolor", "SDL.NTSCpalette", 0); + + // scanline settings + config->addOption("slstart", "SDL.ScanLineStart", 0); + config->addOption("slend", "SDL.ScanLineEnd", 239); + + // video controls + config->addOption('f', "fullscreen", "SDL.Fullscreen", 0); + + // set x/y res to 0 for automatic fullscreen resolution detection (no change) + config->addOption('x', "xres", "SDL.XResolution", 0); + config->addOption('y', "yres", "SDL.YResolution", 0); + config->addOption("SDL.LastXRes", 0); + config->addOption("SDL.LastYRes", 0); + config->addOption('b', "bpp", "SDL.BitsPerPixel", 32); + config->addOption("doublebuf", "SDL.DoubleBuffering", 1); + config->addOption("autoscale", "SDL.AutoScale", 1); + config->addOption("keepratio", "SDL.KeepRatio", 1); + config->addOption("xscale", "SDL.XScale", 1.0); + config->addOption("yscale", "SDL.YScale", 1.0); + config->addOption("xstretch", "SDL.XStretch", 0); + config->addOption("ystretch", "SDL.YStretch", 0); + config->addOption("noframe", "SDL.NoFrame", 0); + config->addOption("special", "SDL.SpecialFilter", 0); + config->addOption("showfps", "SDL.ShowFPS", 0); + config->addOption("togglemenu", "SDL.ToggleMenu", 0); + + // OpenGL options + config->addOption("opengl", "SDL.OpenGL", 1); + config->addOption("openglip", "SDL.OpenGLip", 1); + config->addOption("SDL.SpecialFilter", 0); + config->addOption("SDL.SpecialFX", 0); + config->addOption("SDL.Vsync", 1); + + // network play options - netplay is broken + config->addOption("server", "SDL.NetworkIsServer", 0); + config->addOption('n', "net", "SDL.NetworkIP", ""); + config->addOption('u', "user", "SDL.NetworkUsername", ""); + config->addOption('w', "pass", "SDL.NetworkPassword", ""); + config->addOption('k', "netkey", "SDL.NetworkGameKey", ""); + config->addOption("port", "SDL.NetworkPort", 4046); + config->addOption("players", "SDL.NetworkPlayers", 1); + + // input configuration options + config->addOption("input1", "SDL.Input.0", "GamePad.0"); + config->addOption("input2", "SDL.Input.1", "GamePad.1"); + config->addOption("input3", "SDL.Input.2", "Gamepad.2"); + config->addOption("input4", "SDL.Input.3", "Gamepad.3"); + + // allow for input configuration + config->addOption('i', "inputcfg", "SDL.InputCfg", InputCfg); + + // display input + config->addOption("inputdisplay", "SDL.InputDisplay", 0); + + // enable / disable opposite directionals (left + right or up + down simultaneously) + config->addOption("opposite-directionals", "SDL.Input.EnableOppositeDirectionals", 1); + + // pause movie playback at frame x + config->addOption("pauseframe", "SDL.PauseFrame", 0); + config->addOption("recordhud", "SDL.RecordHUD", 1); + config->addOption("moviemsg", "SDL.MovieMsg", 1); + + // overwrite the config file? + config->addOption("no-config", "SDL.NoConfig", 0); + + config->addOption("autoresume", "SDL.AutoResume", 0); + + // video playback + config->addOption("playmov", "SDL.Movie", ""); + config->addOption("subtitles", "SDL.SubtitleDisplay", 1); + config->addOption("movielength", "SDL.MovieLength", 0); + + config->addOption("fourscore", "SDL.FourScore", 0); + + config->addOption("nofscursor", "SDL.NoFullscreenCursor", 1); + + #ifdef _S9XLUA_H + // load lua script + config->addOption("loadlua", "SDL.LuaScript", ""); + #endif + + #ifdef CREATE_AVI + config->addOption("videolog", "SDL.VideoLog", ""); + config->addOption("mute", "SDL.MuteCapture", 0); + #endif + + // auto load/save on gameload/close + config->addOption("loadstate", "SDL.AutoLoadState", INVALID_STATE); + config->addOption("savestate", "SDL.AutoSaveState", INVALID_STATE); + + //TODO implement this + config->addOption("periodicsaves", "SDL.PeriodicSaves", 0); + + + #ifdef _GTK + char* home_dir = getenv("HOME"); + // prefixed with _ because they are internal (not cli options) + config->addOption("_lastopenfile", "SDL.LastOpenFile", home_dir); + config->addOption("_laststatefrom", "SDL.LastLoadStateFrom", home_dir); + config->addOption("_lastopennsf", "SDL.LastOpenNSF", home_dir); + config->addOption("_lastsavestateas", "SDL.LastSaveStateAs", home_dir); + config->addOption("_lastloadlua", "SDL.LastLoadLua", ""); + #endif + + // fcm -> fm2 conversion + config->addOption("fcmconvert", "SDL.FCMConvert", ""); + + // fm2 -> srt conversion + config->addOption("ripsubs", "SDL.RipSubs", ""); + + // enable new PPU core + config->addOption("newppu", "SDL.NewPPU", 0); + + // quit when a+b+select+start is pressed + config->addOption("4buttonexit", "SDL.ABStartSelectExit", 0); + + // GamePad 0 - 3 + for(unsigned int i = 0; i < GAMEPAD_NUM_DEVICES; i++) + { + char buf[64]; + snprintf(buf, sizeof(buf)-1, "SDL.Input.GamePad.%u.", i); + prefix = buf; + + config->addOption(prefix + "DeviceType", DefaultGamePadDevice[i]); + config->addOption(prefix + "DeviceNum", 0); + for(unsigned int j = 0; j < GAMEPAD_NUM_BUTTONS; j++) { + config->addOption(prefix + GamePadNames[j], DefaultGamePad[i][j]); + } + } + + // PowerPad 0 - 1 + for(unsigned int i = 0; i < POWERPAD_NUM_DEVICES; i++) { + char buf[64]; + snprintf(buf, sizeof(buf)-1, "SDL.Input.PowerPad.%u.", i); + prefix = buf; + + config->addOption(prefix + "DeviceType", DefaultPowerPadDevice[i]); + config->addOption(prefix + "DeviceNum", 0); + for(unsigned int j = 0; j < POWERPAD_NUM_BUTTONS; j++) { + config->addOption(prefix +PowerPadNames[j], DefaultPowerPad[i][j]); + } + } + + // QuizKing + prefix = "SDL.Input.QuizKing."; + config->addOption(prefix + "DeviceType", DefaultQuizKingDevice); + config->addOption(prefix + "DeviceNum", 0); + for(unsigned int j = 0; j < QUIZKING_NUM_BUTTONS; j++) { + config->addOption(prefix + QuizKingNames[j], DefaultQuizKing[j]); + } + + // HyperShot + prefix = "SDL.Input.HyperShot."; + config->addOption(prefix + "DeviceType", DefaultHyperShotDevice); + config->addOption(prefix + "DeviceNum", 0); + for(unsigned int j = 0; j < HYPERSHOT_NUM_BUTTONS; j++) { + config->addOption(prefix + HyperShotNames[j], DefaultHyperShot[j]); + } + + // Mahjong + prefix = "SDL.Input.Mahjong."; + config->addOption(prefix + "DeviceType", DefaultMahjongDevice); + config->addOption(prefix + "DeviceNum", 0); + for(unsigned int j = 0; j < MAHJONG_NUM_BUTTONS; j++) { + config->addOption(prefix + MahjongNames[j], DefaultMahjong[j]); + } + + // TopRider + prefix = "SDL.Input.TopRider."; + config->addOption(prefix + "DeviceType", DefaultTopRiderDevice); + config->addOption(prefix + "DeviceNum", 0); + for(unsigned int j = 0; j < TOPRIDER_NUM_BUTTONS; j++) { + config->addOption(prefix + TopRiderNames[j], DefaultTopRider[j]); + } + + // FTrainer + prefix = "SDL.Input.FTrainer."; + config->addOption(prefix + "DeviceType", DefaultFTrainerDevice); + config->addOption(prefix + "DeviceNum", 0); + for(unsigned int j = 0; j < FTRAINER_NUM_BUTTONS; j++) { + config->addOption(prefix + FTrainerNames[j], DefaultFTrainer[j]); + } + + // FamilyKeyBoard + prefix = "SDL.Input.FamilyKeyBoard."; + config->addOption(prefix + "DeviceType", DefaultFamilyKeyBoardDevice); + config->addOption(prefix + "DeviceNum", 0); + for(unsigned int j = 0; j < FAMILYKEYBOARD_NUM_BUTTONS; j++) { + config->addOption(prefix + FamilyKeyBoardNames[j], + DefaultFamilyKeyBoard[j]); + } + + // for FAMICOM microphone in pad 2 pad 1 didn't have it + // Takeshi no Chousenjou uses it for example. + prefix = "SDL.Input.FamicomPad2."; + config->addOption("rp2mic", prefix + "EnableMic", 0); + + // TODO: use a better data structure to store the hotkeys or something + // improve this code overall in the future to make it + // easier to maintain + const int Hotkeys[HK_MAX] = { + SDLK_F1, // cheat menu + SDLK_F2, // bind state + SDLK_F3, // load lua + SDLK_F4, // toggleBG + SDLK_F5, // save state + SDLK_F6, // fds select + SDLK_F7, // load state + SDLK_F8, // fds eject + SDLK_F6, // VS insert coin + SDLK_F8, // VS toggle dipswitch + SDLK_PERIOD, // toggle frame display + SDLK_F10, // toggle subtitle + SDLK_F11, // reset + SDLK_F12, // screenshot + SDLK_PAUSE, // pause + SDLK_MINUS, // speed++ + SDLK_EQUALS, // speed-- + SDLK_BACKSLASH, //frame advnace + SDLK_TAB, // turbo + SDLK_COMMA, // toggle input display + SDLK_q, // toggle movie RW + SDLK_QUOTE, // toggle mute capture + 0, // quit // edit 10/11/11 - don't map to escape, it causes ugly things to happen to sdl. can be manually appended to config + SDLK_DELETE, // frame advance lag skip + SDLK_SLASH, // lag counter display + SDLK_0, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5, + SDLK_6, SDLK_7, SDLK_8, SDLK_9, + SDLK_PAGEUP, // select state next + SDLK_PAGEDOWN}; // select state prev + + prefix = "SDL.Hotkeys."; + for(int i=0; i < HK_MAX; i++) + config->addOption(prefix + HotkeyStrings[i], Hotkeys[i]); + // All mouse devices + config->addOption("SDL.OekaKids.0.DeviceType", "Mouse"); + config->addOption("SDL.OekaKids.0.DeviceNum", 0); + + config->addOption("SDL.Arkanoid.0.DeviceType", "Mouse"); + config->addOption("SDL.Arkanoid.0.DeviceNum", 0); + + config->addOption("SDL.Shadow.0.DeviceType", "Mouse"); + config->addOption("SDL.Shadow.0.DeviceNum", 0); + + config->addOption("SDL.Zapper.0.DeviceType", "Mouse"); + config->addOption("SDL.Zapper.0.DeviceNum", 0); + + return config; +} + +void +UpdateEMUCore(Config *config) +{ + int ntsccol, ntsctint, ntschue, flag, region, start, end; + std::string cpalette; + + config->getOption("SDL.NTSCpalette", &ntsccol); + config->getOption("SDL.Tint", &ntsctint); + config->getOption("SDL.Hue", &ntschue); + FCEUI_SetNTSCTH(ntsccol, ntsctint, ntschue); + + config->getOption("SDL.Palette", &cpalette); + if(cpalette.size()) { + LoadCPalette(cpalette); + } + + config->getOption("SDL.PAL", ®ion); + FCEUI_SetRegion(region); + + config->getOption("SDL.GameGenie", &flag); + FCEUI_SetGameGenie(flag ? 1 : 0); + + config->getOption("SDL.Sound.LowPass", &flag); + FCEUI_SetLowPass(flag ? 1 : 0); + + config->getOption("SDL.DisableSpriteLimit", &flag); + FCEUI_DisableSpriteLimitation(flag ? 1 : 0); + + config->getOption("SDL.ScanLineStart", &start); + config->getOption("SDL.ScanLineEnd", &end); + +#if DOING_SCANLINE_CHECKS + for(int i = 0; i < 2; x++) { + if(srendlinev[x]<0 || srendlinev[x]>239) srendlinev[x]=0; + if(erendlinev[x]239) erendlinev[x]=239; + } +#endif + + FCEUI_SetRenderedLines(start + 8, end - 8, start, end); +} + diff --git a/src/drivers/Qt/config.h b/src/drivers/Qt/config.h new file mode 100644 index 00000000..dbf6a0b6 --- /dev/null +++ b/src/drivers/Qt/config.h @@ -0,0 +1,28 @@ +#ifndef CONFIG_H_HF128 +#define CONFIG_H_HF128 + +#include "../common/configSys.h" + +Config *InitConfig(void); +void UpdateEMUCore(Config *); +int LoadCPalette(const std::string &file); + +// hotkey definitions +// TODO: encapsulate this in an improved data structure +enum HOTKEY { HK_CHEAT_MENU=0, HK_BIND_STATE, HK_LOAD_LUA, HK_TOGGLE_BG, + HK_SAVE_STATE, HK_FDS_SELECT, HK_LOAD_STATE, HK_FDS_EJECT , + HK_VS_INSERT_COIN, HK_VS_TOGGLE_DIPSWITCH, + HK_TOGGLE_FRAME_DISPLAY, HK_TOGGLE_SUBTITLE, HK_RESET, HK_SCREENSHOT, + HK_PAUSE, HK_DECREASE_SPEED, HK_INCREASE_SPEED, HK_FRAME_ADVANCE, HK_TURBO, + HK_TOGGLE_INPUT_DISPLAY, HK_MOVIE_TOGGLE_RW, HK_MUTE_CAPTURE, HK_QUIT, + HK_FA_LAG_SKIP, HK_LAG_COUNTER_DISPLAY, + HK_SELECT_STATE_0, HK_SELECT_STATE_1, HK_SELECT_STATE_2, HK_SELECT_STATE_3, + HK_SELECT_STATE_4, HK_SELECT_STATE_5, HK_SELECT_STATE_6, HK_SELECT_STATE_7, + HK_SELECT_STATE_8, HK_SELECT_STATE_9, + HK_SELECT_STATE_NEXT, HK_SELECT_STATE_PREV, HK_VOLUME_DOWN, HK_VOLUME_UP, + HK_MAX}; + +const char *getHotkeyString( int i ); + +#endif + diff --git a/src/drivers/Qt/dface.h b/src/drivers/Qt/dface.h new file mode 100644 index 00000000..f753f3ca --- /dev/null +++ b/src/drivers/Qt/dface.h @@ -0,0 +1,37 @@ +#include "../common/args.h" +#include "../common/config.h" + +#include "input.h" + +extern CFGSTRUCT DriverConfig[]; +extern ARGPSTRUCT DriverArgs[]; + +void DoDriverArgs(void); + +int InitSound(); +void WriteSound(int32 *Buffer, int Count); +int KillSound(void); +uint32 GetMaxSound(void); +uint32 GetWriteSound(void); + +void SilenceSound(int s); /* DOS and SDL */ + +int InitJoysticks(void); +int KillJoysticks(void); +uint32 *GetJSOr(void); + +int InitVideo(FCEUGI *gi); +int KillVideo(void); +void BlitScreen(uint8 *XBuf); +void LockConsole(void); +void UnlockConsole(void); +void ToggleFS(); /* SDL */ + +int LoadGame(const char *path); +//int CloseGame(void); + +void Giggles(int); +void DoFun(void); + +int FCEUD_NetworkConnect(void); + diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp new file mode 100644 index 00000000..61d7812b --- /dev/null +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -0,0 +1,300 @@ +// fceuWrapper.cpp +// +#include +#include + +#include "main.h" +#include "throttle.h" +#include "config.h" +#include "dface.h" +#include "fceuWrapper.h" +#include "input.h" +#include "sdl-video.h" +#include "unix-netplay.h" + +#include "../common/cheat.h" +#include "../../fceu.h" +#include "../../movie.h" +#include "../../version.h" + +#ifdef _S9XLUA_H +#include "../../fceulua.h" +#endif + +#include "../common/configSys.h" +#include "../../oldmovie.h" +#include "../../types.h" + +#ifdef CREATE_AVI +#include "../videolog/nesvideos-piece.h" +#endif + +//***************************************************************** +// Define Global Variables to be shared with FCEU Core +//***************************************************************** +int dendy = 0; +int eoptions=0; +int isloaded=0; +int pal_emulation=0; +int gametype = 0; +int closeFinishedMovie = 0; +int KillFCEUXonFrame = 0; + +bool swapDuty = 0; +bool turbo = false; +unsigned int gui_draw_area_width = 256; +unsigned int gui_draw_area_height = 256; + +// global configuration object +Config *g_config = NULL; + +static int inited = 0; +static int noconfig=0; + +//***************************************************************** +// Define Global Functions to be shared with FCEU Core +//***************************************************************** +// + +/** +* Prints a textual message without adding a newline at the end. +* +* @param text The text of the message. +* +* TODO: This function should have a better name. +**/ +void FCEUD_Message(const char *text) +{ + fputs(text, stdout); +} + +/** +* Shows an error message in a message box. +* (For now: prints to stderr.) +* +* If running in GTK mode, display a dialog message box of the error. +* +* @param errormsg Text of the error message. +**/ +void FCEUD_PrintError(const char *errormsg) +{ + fprintf(stderr, "%s\n", errormsg); +} + +/** + * Opens a file, C++ style, to be read a byte at a time. + */ +FILE *FCEUD_UTF8fopen(const char *fn, const char *mode) +{ + return(fopen(fn,mode)); +} + +/** + * Opens a file to be read a byte at a time. + */ +EMUFILE_FILE* FCEUD_UTF8_fstream(const char *fn, const char *m) +{ + std::ios_base::openmode mode = std::ios_base::binary; + if(!strcmp(m,"r") || !strcmp(m,"rb")) + mode |= std::ios_base::in; + else if(!strcmp(m,"w") || !strcmp(m,"wb")) + mode |= std::ios_base::out | std::ios_base::trunc; + else if(!strcmp(m,"a") || !strcmp(m,"ab")) + mode |= std::ios_base::out | std::ios_base::app; + else if(!strcmp(m,"r+") || !strcmp(m,"r+b")) + mode |= std::ios_base::in | std::ios_base::out; + else if(!strcmp(m,"w+") || !strcmp(m,"w+b")) + mode |= std::ios_base::in | std::ios_base::out | std::ios_base::trunc; + else if(!strcmp(m,"a+") || !strcmp(m,"a+b")) + mode |= std::ios_base::in | std::ios_base::out | std::ios_base::app; + return new EMUFILE_FILE(fn, m); + //return new std::fstream(fn,mode); +} + +static const char *s_linuxCompilerString = "g++ " __VERSION__; +/** + * Returns the compiler string. + */ +const char *FCEUD_GetCompilerString(void) +{ + return s_linuxCompilerString; +} + +/** + * Get the time in ticks. + */ +uint64 +FCEUD_GetTime(void) +{ + return SDL_GetTicks(); +} + +/** + * Get the tick frequency in Hz. + */ +uint64 +FCEUD_GetTimeFreq(void) +{ + // SDL_GetTicks() is in milliseconds + return 1000; +} + +void FCEUD_DebugBreakpoint( int addr ) +{ + // TODO +} + +/** + * Initialize all of the subsystem drivers: video, audio, and joystick. + */ +static int +DriverInitialize(FCEUGI *gi) +{ + if(InitVideo(gi) < 0) return 0; + inited|=4; + + if(InitSound()) + inited|=1; + + if(InitJoysticks()) + inited|=2; + + int fourscore=0; + g_config->getOption("SDL.FourScore", &fourscore); + eoptions &= ~EO_FOURSCORE; + if(fourscore) + eoptions |= EO_FOURSCORE; + + InitInputInterface(); + return 1; +} + +/** + * Shut down all of the subsystem drivers: video, audio, and joystick. + */ +static void +DriverKill() +{ + if (!noconfig) + g_config->save(); + + if(inited&2) + KillJoysticks(); + if(inited&4) + KillVideo(); + if(inited&1) + KillSound(); + inited=0; +} + +/** + * Loads a game, given a full path/filename. The driver code must be + * initialized after the game is loaded, because the emulator code + * provides data necessary for the driver code(number of scanlines to + * render, what virtual input devices to use, etc.). + */ +int LoadGame(const char *path) +{ + if (isloaded){ + CloseGame(); + } + if(!FCEUI_LoadGame(path, 1)) { + return 0; + } + + int state_to_load; + g_config->getOption("SDL.AutoLoadState", &state_to_load); + if (state_to_load >= 0 && state_to_load < 10){ + FCEUI_SelectState(state_to_load, 0); + FCEUI_LoadState(NULL, false); + } + + ParseGIInput(GameInfo); + RefreshThrottleFPS(); + + if(!DriverInitialize(GameInfo)) { + return(0); + } + + // set pal/ntsc + int id; + g_config->getOption("SDL.PAL", &id); + FCEUI_SetRegion(id); + + g_config->getOption("SDL.SwapDuty", &id); + swapDuty = id; + + std::string filename; + g_config->getOption("SDL.Sound.RecordFile", &filename); + if(filename.size()) { + if(!FCEUI_BeginWaveRecord(filename.c_str())) { + g_config->setOption("SDL.Sound.RecordFile", ""); + } + } + isloaded = 1; + + FCEUD_NetworkConnect(); + return 1; +} + +/** + * Closes a game. Frees memory, and deinitializes the drivers. + */ +int +CloseGame(void) +{ + std::string filename; + + if(!isloaded) { + return(0); + } + + int state_to_save; + g_config->getOption("SDL.AutoSaveState", &state_to_save); + if (state_to_save < 10 && state_to_save >= 0){ + FCEUI_SelectState(state_to_save, 0); + FCEUI_SaveState(NULL, false); + } + FCEUI_CloseGame(); + + DriverKill(); + isloaded = 0; + GameInfo = 0; + + g_config->getOption("SDL.Sound.RecordFile", &filename); + if(filename.size()) { + FCEUI_EndWaveRecord(); + } + + InputUserActiveFix(); + return(1); +} + +// dummy functions + +#define DUMMY(__f) \ + void __f(void) {\ + printf("%s\n", #__f);\ + FCEU_DispMessage("Not implemented.",0);\ + } +DUMMY(FCEUD_HideMenuToggle) +DUMMY(FCEUD_MovieReplayFrom) +DUMMY(FCEUD_ToggleStatusIcon) +DUMMY(FCEUD_AviRecordTo) +DUMMY(FCEUD_AviStop) +void FCEUI_AviVideoUpdate(const unsigned char* buffer) { } +int FCEUD_ShowStatusIcon(void) {return 0;} +bool FCEUI_AviIsRecording(void) {return false;} +void FCEUI_UseInputPreset(int preset) { } +bool FCEUD_PauseAfterPlayback() { return false; } + +void FCEUD_TurboOn (void) { /* TODO */ }; +void FCEUD_TurboOff (void) { /* TODO */ }; +void FCEUD_TurboToggle(void) { /* TODO */ }; + +FCEUFILE* FCEUD_OpenArchiveIndex(ArchiveScanRecord& asr, std::string &fname, int innerIndex) { return 0; } +FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::string* innerFilename) { return 0; } +FCEUFILE* FCEUD_OpenArchiveIndex(ArchiveScanRecord& asr, std::string &fname, int innerIndex, int* userCancel) { return 0; } +FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::string* innerFilename, int* userCancel) { return 0; } +ArchiveScanRecord FCEUD_ScanArchive(std::string fname) { return ArchiveScanRecord(); } + diff --git a/src/drivers/Qt/fceuWrapper.h b/src/drivers/Qt/fceuWrapper.h new file mode 100644 index 00000000..0c279144 --- /dev/null +++ b/src/drivers/Qt/fceuWrapper.h @@ -0,0 +1,23 @@ +// fceuWrapper.h +// +#include "config.h" + +//***************************************************************** +// Define Global Variables to be shared with FCEU Core +//***************************************************************** +extern int dendy; +extern int eoptions; +extern int isLoaded; +extern int pal_emulation; +extern int gametype; +extern int closeFinishedMovie; +extern bool turbo; +extern bool swapDuty; +extern unsigned int gui_draw_area_width; +extern unsigned int gui_draw_area_height; + +// global configuration object +extern Config *g_config; + +int LoadGame(const char *path); +int CloseGame(void); diff --git a/src/drivers/Qt/gl_win.cpp b/src/drivers/Qt/gl_win.cpp new file mode 100644 index 00000000..111e7fb6 --- /dev/null +++ b/src/drivers/Qt/gl_win.cpp @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gl_win.h" + +gl_win_shm_t *gl_shm = NULL; + +//************************************************************************ +gl_win_shm_t *open_video_shm(void) +{ + int shmId; + gl_win_shm_t *vaddr; + struct shmid_ds ds; + + shmId = shmget( IPC_PRIVATE, sizeof(struct gl_win_shm_t), IPC_CREAT | S_IRWXU | S_IRWXG ); + + if ( shmId == -1 ) + { + perror("Error: GL shmget Failed:"); + return NULL; + } + printf("Created ShmID: %i \n", shmId ); + + vaddr = (gl_win_shm_t*)shmat( shmId, NULL, 0); + + if ( vaddr == (gl_win_shm_t*)-1 ) + { + perror("Error: GLX shmat Failed:"); + return NULL; + } + memset( vaddr, 0, sizeof(struct gl_win_shm_t)); + + if ( shmctl( shmId, IPC_RMID, &ds ) != 0 ) + { + perror("Error: GLX shmctl IPC_RMID Failed:"); + } + + //sem_init( &vaddr->sem, 1, 1 ); + + vaddr->ncol = 256; + vaddr->nrow = 256; + vaddr->pitch = 256 * 4; + + return vaddr; +} +//************************************************************************ diff --git a/src/drivers/Qt/gl_win.h b/src/drivers/Qt/gl_win.h new file mode 100644 index 00000000..552c70a9 --- /dev/null +++ b/src/drivers/Qt/gl_win.h @@ -0,0 +1,68 @@ +// glxwin.cpp +// + +#ifndef __GLXWIN_H__ +#define __GLXWIN_H__ + +#include + +#define GL_WIN_PIXEL_LINEAR_FILTER 0x0001 +#define GL_WIN_DOUBLE_BUFFER 0x0002 + +#define GL_NES_WIDTH 256 +#define GL_NES_HEIGHT 256 + +struct gl_win_shm_t +{ + int pid; + int run; + uint32_t render_count; + uint32_t blit_count; + + int ncol; + int nrow; + int pitch; + + // Pass Key Events back to QT Gui + struct + { + int head; + int tail; + + struct { + int type; + int keycode; + int state; + } data[64]; + + } keyEventBuf; + + // Gui Command Event Queue + struct + { + int head; + int tail; + + struct { + int id; + + union { + int i32[4]; + float f32[4]; + } param; + } cmd[64]; + } guiEvent; + + uint32_t pixbuf[65536]; // 256 x 256 + + void clear_pixbuf(void) + { + memset( pixbuf, 0, sizeof(pixbuf) ); + } +}; + +extern gl_win_shm_t *gl_shm; + +gl_win_shm_t *open_video_shm(void); + +#endif diff --git a/src/drivers/Qt/input.cpp b/src/drivers/Qt/input.cpp new file mode 100644 index 00000000..d384136f --- /dev/null +++ b/src/drivers/Qt/input.cpp @@ -0,0 +1,2355 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2002 Xodnizel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "main.h" +#include "dface.h" +#include "input.h" +#include "config.h" + + +#include "sdl-video.h" +#include "sdl.h" + +#include "../common/cheat.h" +#include "../../movie.h" +#include "../../fceu.h" +#include "../../driver.h" +#include "../../state.h" +#include "../../utils/xstring.h" +#ifdef _S9XLUA_H +#include "../../fceulua.h" +#endif + +#include +#include + +/** GLOBALS **/ +int NoWaiting = 0; +extern Config *g_config; +extern bool bindSavestate, frameAdvanceLagSkip, lagCounterDisplay; + + +/* UsrInputType[] is user-specified. CurInputType[] is current + (game loading can override user settings) +*/ +static int UsrInputType[NUM_INPUT_DEVICES]; +static int CurInputType[NUM_INPUT_DEVICES]; +static int cspec = 0; + +extern int gametype; + +/** + * Necessary for proper GUI functioning (configuring when a game isn't loaded). + */ +void +InputUserActiveFix () +{ + int x; + for (x = 0; x < 3; x++) + { + CurInputType[x] = UsrInputType[x]; + } +} + +/** + * Parse game information and configure the input devices accordingly. + */ +void +ParseGIInput (FCEUGI * gi) +{ + gametype = gi->type; + + CurInputType[0] = UsrInputType[0]; + CurInputType[1] = UsrInputType[1]; + CurInputType[2] = UsrInputType[2]; + + if (gi->input[0] >= 0) + { + CurInputType[0] = gi->input[0]; + } + if (gi->input[1] >= 0) + { + CurInputType[1] = gi->input[1]; + } + if (gi->inputfc >= 0) + { + CurInputType[2] = gi->inputfc; + } + cspec = gi->cspecial; +} + + +static uint8 QuizKingData = 0; +static uint8 HyperShotData = 0; +static uint32 MahjongData = 0; +static uint32 FTrainerData = 0; +static uint8 TopRiderData = 0; +static uint8 BWorldData[1 + 13 + 1]; + +static void UpdateFKB (void); +static void UpdateGamepad (void); +static void UpdateQuizKing (void); +static void UpdateHyperShot (void); +static void UpdateMahjong (void); +static void UpdateFTrainer (void); +static void UpdateTopRider (void); + +static uint32 JSreturn = 0; + +/** + * Configure cheat devices (game genie, etc.). Restarts the keyboard + * and video subsystems. + */ +static void +DoCheatSeq () +{ + SilenceSound (1); + KillVideo (); + + DoConsoleCheatConfig (); + InitVideo (GameInfo); + SilenceSound (0); +} + +#include "keyscan.h" +static uint8 g_keyState[SDL_NUM_SCANCODES]; +static int DIPS = 0; + +static uint8 keyonce[SDL_NUM_SCANCODES]; +#define KEY(__a) g_keyState[MKK(__a)] + +int getKeyState( int k ) +{ + if ( (k >= 0) && (k < SDL_NUM_SCANCODES) ) + { + return g_keyState[k]; + } + return 0; +} + +static int +_keyonly (int a) +{ + int sc; + + if ( a < 0 ) + { + return 0; + } + + sc = SDL_GetScancodeFromKey(a); + + // check for valid key + if (sc >= SDL_NUM_SCANCODES || sc < 0) + { + return 0; + } + + if (g_keyState[sc]) + { + if (!keyonce[sc]) + { + keyonce[sc] = 1; + return 1; + } + } + else + { + keyonce[sc] = 0; + } + return 0; +} + +#define keyonly(__a) _keyonly(MKK(__a)) + +static int g_fkbEnabled = 0; + +// this function loads the sdl hotkeys from the config file into the +// global scope. this elimates the need for accessing the config file + +int Hotkeys[HK_MAX] = { 0 }; + +// on every cycle of keyboardinput() +void +setHotKeys (void) +{ + std::string prefix = "SDL.Hotkeys."; + for (int i = 0; i < HK_MAX; i++) + { + g_config->getOption (prefix + getHotkeyString(i), &Hotkeys[i]); + } + return; +} + +/*** + * This function is a wrapper for FCEUI_ToggleEmulationPause that handles + * releasing/capturing mouse pointer during pause toggles + * */ +void +TogglePause () +{ + FCEUI_ToggleEmulationPause (); + + int no_cursor; + g_config->getOption("SDL.NoFullscreenCursor", &no_cursor); + int fullscreen; + g_config->getOption ("SDL.Fullscreen", &fullscreen); + + return; +} + +/*** + * This function opens a file chooser dialog and returns the filename the + * user selected. + * */ +std::string GetFilename (const char *title, bool save, const char *filter) +{ + if (FCEUI_EmulationPaused () == 0) + FCEUI_ToggleEmulationPause (); + std::string fname = ""; + +#ifdef WIN32 + OPENFILENAME ofn; // common dialog box structure + char szFile[260]; // buffer for file name + HWND hwnd; // owner window + HANDLE hf; // file handle + + // Initialize OPENFILENAME + memset (&ofn, 0, sizeof (ofn)); + ofn.lStructSize = sizeof (ofn); + ofn.hwndOwner = hwnd; + ofn.lpstrFile = szFile; + // Set lpstrFile[0] to '\0' so that GetOpenFileName does not + // use the contents of szFile to initialize itself. + ofn.lpstrFile[0] = '\0'; + ofn.nMaxFile = sizeof (szFile); + ofn.lpstrFilter = "All\0*.*\0"; + ofn.nFilterIndex = 1; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = NULL; + ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; + + // Display the Open dialog box. + fname = GetOpenFileName (&ofn); + +#endif +#ifdef _GTK + int fullscreen = 0; + g_config->getOption ("SDL.Fullscreen", &fullscreen); + if (fullscreen) + ToggleFS (); + + GtkWidget *fileChooser; + + GtkFileFilter *filterX; + GtkFileFilter *filterAll; + + filterX = gtk_file_filter_new (); + gtk_file_filter_add_pattern (filterX, filter); + gtk_file_filter_set_name (filterX, filter); + + + filterAll = gtk_file_filter_new (); + gtk_file_filter_add_pattern (filterAll, "*"); + gtk_file_filter_set_name (filterAll, "All Files"); + + if (save) + fileChooser = gtk_file_chooser_dialog_new ("Save as", NULL, + GTK_FILE_CHOOSER_ACTION_SAVE, + "_Cancel", + GTK_RESPONSE_CANCEL, + "_Save", + GTK_RESPONSE_ACCEPT, NULL); + else + fileChooser = gtk_file_chooser_dialog_new ("Open", NULL, + GTK_FILE_CHOOSER_ACTION_OPEN, + "_Cancel", + GTK_RESPONSE_CANCEL, + "_Open", + GTK_RESPONSE_ACCEPT, NULL); + + // TODO: make file filters case insensitive + //gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterX); + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (fileChooser), filterAll); + int response = gtk_dialog_run (GTK_DIALOG (fileChooser)); + + // flush gtk events + while (gtk_events_pending ()) + gtk_main_iteration_do (TRUE); + + if (response == GTK_RESPONSE_ACCEPT) + fname = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fileChooser)); + + gtk_widget_destroy (fileChooser); + + while (gtk_events_pending ()) + gtk_main_iteration_do (TRUE); +#endif + FCEUI_ToggleEmulationPause (); + return fname; +} + +/** + * This function opens a text entry dialog and returns the user's input + */ +std::string GetUserText (const char *title) +{ +#ifdef _GTK +/* prg318 - 10/13/11 - this is broken in recent build and causes + * segfaults/very weird behavior i'd rather remove it for now than it cause + * accidental segfaults + * TODO fix it +*/ +#if 0 + + GtkWidget* d; + GtkWidget* entry; + + d = gtk_dialog_new_with_buttons(title, NULL, GTK_DIALOG_MODAL, GTK_STOCK_OK, GTK_RESPONSE_OK); + + entry = gtk_entry_new(); + + GtkWidget* vbox = gtk_dialog_get_content_area(GTK_DIALOG(d)); + + gtk_container_add(GTK_CONTAINER(vbox), entry); + + gtk_widget_show_all(d); + + gtk_dialog_run(GTK_DIALOG(d)); + + // flush gtk events + while(gtk_events_pending()) + gtk_main_iteration_do(TRUE); + + std::string input = gtk_entry_get_text(GTK_ENTRY(entry)); + + if (FCEUI_EmulationPaused() == 0) + FCEUI_ToggleEmulationPause(); // pause emulation + + int fullscreen = 0; + g_config->getOption("SDL.Fullscreen", &fullscreen); + if(fullscreen) + ToggleFS(); // disable fullscreen emulation + + FILE *fpipe; + std::string command = "zenity --entry --title=\""; + command.append(title); + command.append("\" --text=\""); + command.append(title); + command.append(":\""); + + if (!(fpipe = (FILE*)popen(command.c_str(),"r"))) // If fpipe is NULL + FCEUD_PrintError("Pipe error on opening zenity"); + int c; + std::string input; + while((c = fgetc(fpipe))) + { + if (c == EOF || c == '\n') + break; + input += c; + } + pclose(fpipe); + gtk_widget_destroy(d); + + + while(gtk_events_pending()) + gtk_main_iteration_do(TRUE); + + FCEUI_ToggleEmulationPause(); // unpause emulation + return input; +#endif // #if 0 +#endif + return ""; +} + + +/** +* Lets the user start a new .fm2 movie file +**/ +void FCEUD_MovieRecordTo () +{ + std::string fname = GetFilename ("Save FM2 movie for recording", true, "FM2 movies|*.fm2"); + if (!fname.size ()) + return; // no filename selected, quit the whole thing + std::wstring author = mbstowcs (GetUserText ("Author name")); // the author can be empty, so no need to check here + + FCEUI_SaveMovie (fname.c_str (), MOVIE_FLAG_FROM_POWERON, author); +} + + +/** +* Lets the user save a savestate to a specific file +**/ +void FCEUD_SaveStateAs () +{ + std::string fname = GetFilename ("Save savestate as...", true, "Savestates|*.fc0"); + if (!fname.size ()) + return; // no filename selected, quit the whole thing + + FCEUI_SaveState (fname.c_str ()); +} + +/** +* Lets the user load a savestate from a specific file +*/ +void FCEUD_LoadStateFrom () +{ + std::string fname = GetFilename ("Load savestate from...", false, "Savestates|*.fc?"); + if (!fname.size ()) + return; // no filename selected, quit the whole thing + + FCEUI_LoadState (fname.c_str ()); +} + +/** +* Hook for transformer board +*/ +unsigned int *GetKeyboard(void) +{ + int size = 256; + + Uint8* keystate = (Uint8*)SDL_GetKeyboardState(&size); + + return (unsigned int*)(keystate); +} + +/** + * Parse keyboard commands and execute accordingly. + */ +static void KeyboardCommands (void) +{ + int is_shift, is_alt; + + // get the keyboard input + + // check if the family keyboard is enabled + if (CurInputType[2] == SIFC_FKB) + { + if ( g_keyState[SDL_SCANCODE_SCROLLLOCK] ) + { + g_fkbEnabled ^= 1; + FCEUI_DispMessage ("Family Keyboard %sabled.", 0, + g_fkbEnabled ? "en" : "dis"); + } + if (g_fkbEnabled) + { + return; + } + } + + if (g_keyState[SDL_SCANCODE_LSHIFT] || g_keyState[SDL_SCANCODE_RSHIFT]) + { + is_shift = 1; + } + else + { + is_shift = 0; + } + + if (g_keyState[SDL_SCANCODE_LALT] || g_keyState[SDL_SCANCODE_RALT]) + { + is_alt = 1; + } + else + { + is_alt = 0; + } + + + if (_keyonly (Hotkeys[HK_TOGGLE_BG])) + { + if (is_shift) + { + FCEUI_SetRenderPlanes (true, false); + } + else + { + FCEUI_SetRenderPlanes (true, true); + } + } + + // Alt-Enter to toggle full-screen + // This is already handled by GTK Accelerator + //if (keyonly (ENTER) && is_alt) + //{ + // ToggleFS (); + //} + // + + // Alt-M to toggle Main Menu Visibility + //if ( is_alt ) + //{ + // if (keyonly (M)) + // { + // toggleMenuVis(); // TODO + // } + //} + + // Toggle Movie auto-backup + if ( is_shift ) + { + if (keyonly (M)) + { + autoMovieBackup ^= 1; + FCEUI_DispMessage ("Automatic movie backup %sabled.", 0, + autoMovieBackup ? "en" : "dis"); + } + } + + if ( is_alt ) + { + // Start recording an FM2 movie on Alt+R + if (keyonly (R)) + { + FCEUD_MovieRecordTo (); + } + // Save a state from a file + if (keyonly (S)) + { + FCEUD_SaveStateAs (); + } + // Load a state from a file + if (keyonly (L)) + { + FCEUD_LoadStateFrom (); + } + } + + // Famicom disk-system games + if (gametype == GIT_FDS) + { + if (_keyonly (Hotkeys[HK_FDS_SELECT])) + { + FCEUI_FDSSelect (); + } + if (_keyonly (Hotkeys[HK_FDS_EJECT])) + { + FCEUI_FDSInsert (); + } + } + + if (_keyonly (Hotkeys[HK_SCREENSHOT])) + { + FCEUI_SaveSnapshot (); + } + + // if not NES Sound Format + if (gametype != GIT_NSF) + { + if (_keyonly (Hotkeys[HK_CHEAT_MENU])) + { + DoCheatSeq (); + } + + // f5 (default) save key, hold shift to save movie + if (_keyonly (Hotkeys[HK_SAVE_STATE])) + { + if (is_shift) + { + std::string movie_fname = FCEU_MakeFName (FCEUMKF_MOVIE, 0, 0); + FCEUI_printf ("Recording movie to %s\n", movie_fname.c_str() ); + FCEUI_SaveMovie(movie_fname.c_str() , MOVIE_FLAG_NONE, L""); + } + else + { + FCEUI_SaveState (NULL); + } + } + + // f7 to load state, Shift-f7 to load movie + if (_keyonly (Hotkeys[HK_LOAD_STATE])) + { + if (is_shift) + { + FCEUI_StopMovie (); + std::string fname; + fname = + GetFilename ("Open FM2 movie for playback...", false, + "FM2 movies|*.fm2"); + if (fname != "") + { + if (fname.find (".fm2") != std::string::npos + || fname.find (".fm3") != std::string::npos) + { + FCEUI_printf ("Playing back movie located at %s\n", + fname.c_str ()); + FCEUI_LoadMovie (fname.c_str (), false, false); + } + else + { + FCEUI_printf + ("Only .fm2 and .fm3 movies are supported.\n"); + } + } + } + else + { + FCEUI_LoadState(NULL); + } + } + } + + + if (_keyonly (Hotkeys[HK_DECREASE_SPEED])) + { + DecreaseEmulationSpeed (); + } + + if (_keyonly (Hotkeys[HK_INCREASE_SPEED])) + { + IncreaseEmulationSpeed (); + } + + if (_keyonly (Hotkeys[HK_TOGGLE_FRAME_DISPLAY])) + { + FCEUI_MovieToggleFrameDisplay (); + } + + if (_keyonly (Hotkeys[HK_TOGGLE_INPUT_DISPLAY])) + { + FCEUI_ToggleInputDisplay (); + extern int input_display; + g_config->setOption ("SDL.InputDisplay", input_display); + } + + if (_keyonly (Hotkeys[HK_MOVIE_TOGGLE_RW])) + { + FCEUI_SetMovieToggleReadOnly (!FCEUI_GetMovieToggleReadOnly ()); + } + +#ifdef CREATE_AVI + if (_keyonly (Hotkeys[HK_MUTE_CAPTURE])) + { + extern int mutecapture; + mutecapture ^= 1; + } +#endif + + if (_keyonly (Hotkeys[HK_PAUSE])) + { + //FCEUI_ToggleEmulationPause(); + // use the wrapper function instead of the fceui function directly + // so we can handle cursor grabbage + TogglePause (); + } + + // Toggle throttling + if ( _keyonly(Hotkeys[HK_TURBO]) ) + { + NoWaiting ^= 1; + //printf("NoWaiting: 0x%04x\n", NoWaiting ); + } + + static bool frameAdvancing = false; + if ( _keyonly(Hotkeys[HK_FRAME_ADVANCE])) + { + if (frameAdvancing == false) + { + FCEUI_FrameAdvance (); + frameAdvancing = true; + } + } + else + { + if (frameAdvancing) + { + FCEUI_FrameAdvanceEnd (); + frameAdvancing = false; + } + } + + if (_keyonly (Hotkeys[HK_RESET])) + { + FCEUI_ResetNES (); + } + //if(_keyonly(Hotkeys[HK_POWER])) { + // FCEUI_PowerNES(); + //} + if (_keyonly (Hotkeys[HK_QUIT])) + { + CloseGame(); + FCEUI_Kill(); + SDL_Quit(); + exit(0); + } + else +#ifdef _S9XLUA_H + if (_keyonly (Hotkeys[HK_LOAD_LUA])) + { + std::string fname; + fname = GetFilename ("Open LUA script...", false, "Lua scripts|*.lua"); + if (fname != "") + FCEU_LoadLuaCode (fname.c_str ()); + } +#endif + + for (int i = 0; i < 10; i++) + { + if (_keyonly (Hotkeys[HK_SELECT_STATE_0 + i])) + { +#ifdef _GTK + setStateMenuItem(i); +#endif + FCEUI_SelectState (i, 1); + } + } + + if (_keyonly (Hotkeys[HK_SELECT_STATE_NEXT])) + { + FCEUI_SelectStateNext (1); +#ifdef _GTK + setStateMenuItem( CurrentState ); +#endif + } + + if (_keyonly (Hotkeys[HK_SELECT_STATE_PREV])) + { + FCEUI_SelectStateNext (-1); +#ifdef _GTK + setStateMenuItem( CurrentState ); +#endif + } + + if (_keyonly (Hotkeys[HK_BIND_STATE])) + { + bindSavestate ^= 1; + FCEUI_DispMessage ("Savestate binding to movie %sabled.", 0, + bindSavestate ? "en" : "dis"); + } + + if (_keyonly (Hotkeys[HK_FA_LAG_SKIP])) + { + frameAdvanceLagSkip ^= 1; + FCEUI_DispMessage ("Skipping lag in Frame Advance %sabled.", 0, + frameAdvanceLagSkip ? "en" : "dis"); + } + + if (_keyonly (Hotkeys[HK_LAG_COUNTER_DISPLAY])) + { + lagCounterDisplay ^= 1; + } + + if (_keyonly (Hotkeys[HK_TOGGLE_SUBTITLE])) + { + extern int movieSubtitles; + movieSubtitles ^= 1; + FCEUI_DispMessage ("Movie subtitles o%s.", 0, + movieSubtitles ? "n" : "ff"); + } + + if (_keyonly (Hotkeys[HK_VOLUME_DOWN])) + { + FCEUD_SoundVolumeAdjust(-1); + } + + if (_keyonly (Hotkeys[HK_VOLUME_UP])) + { + FCEUD_SoundVolumeAdjust(1); + } + + // VS Unisystem games + if (gametype == GIT_VSUNI) + { + // insert coin + if (_keyonly (Hotkeys[HK_VS_INSERT_COIN])) + FCEUI_VSUniCoin (); + + // toggle dipswitch display + if (_keyonly (Hotkeys[HK_VS_TOGGLE_DIPSWITCH])) + { + DIPS ^= 1; + FCEUI_VSUniToggleDIPView (); + } + if (!(DIPS & 1)) + goto DIPSless; + + // toggle the various dipswitches + for(int i=1; i<=8;i++) + { + if(keyonly(i)) + FCEUI_VSUniToggleDIP(i-1); + } + } + else + { + static uint8 bbuf[32]; + static int bbuft; + static int barcoder = 0; + + if (keyonly (H)) + FCEUI_NTSCSELHUE (); + if (keyonly (T)) + FCEUI_NTSCSELTINT (); + + if (_keyonly (Hotkeys[HK_DECREASE_SPEED])) + FCEUI_NTSCDEC (); + if (_keyonly (Hotkeys[HK_INCREASE_SPEED])) + FCEUI_NTSCINC (); + + if ((CurInputType[2] == SIFC_BWORLD) || (cspec == SIS_DATACH)) + { + if (keyonly (F8)) + { + barcoder ^= 1; + if (!barcoder) + { + if (CurInputType[2] == SIFC_BWORLD) + { + strcpy ((char *) &BWorldData[1], (char *) bbuf); + BWorldData[0] = 1; + } + else + { + FCEUI_DatachSet (bbuf); + } + FCEUI_DispMessage ("Barcode Entered", 0); + } + else + { + bbuft = 0; + FCEUI_DispMessage ("Enter Barcode", 0); + } + } + } + else + { + barcoder = 0; + } + +#define SSM(x) \ +do { \ + if(barcoder) { \ + if(bbuft < 13) { \ + bbuf[bbuft++] = '0' + x; \ + bbuf[bbuft] = 0; \ + } \ + FCEUI_DispMessage("Barcode: %s",0, bbuf); \ + } \ +} while(0) + + DIPSless: + for(int i=0; i<10;i++) + { + if (keyonly (i)) + SSM (i); + } +#undef SSM + } +} + +/** + * Return the state of the mouse buttons. Input 'd' is an array of 3 + * integers that store . + */ +void // removed static for a call in lua-engine.cpp +GetMouseData (uint32 (&d)[3]) +{ + int x, y; + uint32 t; + + // retrieve the state of the mouse from SDL + t = SDL_GetMouseState (&x, &y); + + d[2] = 0; + if (t & SDL_BUTTON (1)) + { + d[2] |= 0x1; + } + if (t & SDL_BUTTON (3)) + { + d[2] |= 0x2; + } + + // get the mouse position from the SDL video driver + t = PtoV (x, y); + d[0] = t & 0xFFFF; + d[1] = (t >> 16) & 0xFFFF; + // debug print + // printf("mouse %d %d %d\n", d[0], d[1], d[2]); +} + +void GetMouseRelative (int32 (&d)[3]) +{ + // converts absolute mouse positions to relative ones for input devices that require this + + // The windows version additionally in fullscreen will constantly return the mouse to center screen + // after reading it, so that the user can endlessly keep moving the mouse. + // The same should eventually be implemented here, but this version should minimally provide + // the necessary relative input, piggybacking on the already implemented GetMouseData. + + static int cx = -1; + static int cy = -1; + + uint32 md[3]; + GetMouseData (md); + + if (cx < 0 || cy < 0) + { + cx = md[0]; + cy = md[1]; + } + + int dx = md[0] - cx; + int dy = md[1] - cy; + + d[0] = dx; + d[1] = dy; + d[2] = md[2]; // buttons +} + +//static void checkKeyBoardState( int scanCode ) +//{ +// printf("Key State is: %i \n", g_keyState[ scanCode ] ); +//} +/** + * Handles outstanding SDL events. + */ +static void +UpdatePhysicalInput () +{ + SDL_Event event; + + // loop, handling all pending events + while (SDL_PollEvent (&event)) + { + switch (event.type) + { + case SDL_QUIT: + CloseGame (); + puts ("Quit"); + break; + case SDL_FCEU_HOTKEY_EVENT: + switch (event.user.code) + { + case HK_PAUSE: + TogglePause (); + break; + default: + FCEU_printf ("Warning: unknown hotkey event %d\n", + event.user.code); + } + break; + case SDL_KEYDOWN: + case SDL_KEYUP: + //printf("SDL_Event.type: %i Keysym: %i ScanCode: %i\n", + // event.type, event.key.keysym.sym, event.key.keysym.scancode ); + + g_keyState[ event.key.keysym.scancode ] = (event.type == SDL_KEYDOWN) ? 1 : 0; + //checkKeyBoardState( event.key.keysym.scancode ); + break; + default: + break; + } + } + //SDL_PumpEvents(); +} + + +static int bcpv, bcpj; + +/** + * Begin configuring the buttons by placing the video and joystick + * subsystems into a well-known state. Button configuration really + * needs to be cleaned up after the new config system is in place. + */ +int ButtonConfigBegin () +{ + // shut down the joystick subsystems + //SDL_Surface *screen; + + bcpj = KillJoysticks (); + + // XXX soules - why did we shut this down? + // initialize the joystick subsystem + InitJoysticks (); + + return 1; +} + +/** + * Finish configuring the buttons by reverting the video and joystick + * subsystems to their previous state. Button configuration really + * needs to be cleaned up after the new config system is in place. + */ +void +ButtonConfigEnd () +{ + // shutdown the joystick and video subsystems + KillJoysticks (); + //SDL_QuitSubSystem(SDL_INIT_VIDEO); + + // re-initialize joystick and video subsystems if they were active before + /*if(!bcpv) { + InitVideo(GameInfo); + } */ + if (!bcpj) + { + InitJoysticks (); + } +} + +/** + * Tests to see if a specified button is currently pressed. + */ +static int +DTestButton (ButtConfig * bc) +{ + int x; + + for (x = 0; x < bc->NumC; x++) + { + if (bc->ButtType[x] == BUTTC_KEYBOARD) + { + if (g_keyState[SDL_GetScancodeFromKey (bc->ButtonNum[x])]) + { + return 1; + } + } + else if (bc->ButtType[x] == BUTTC_JOYSTICK) + { + if (DTestButtonJoy (bc)) + { + return 1; + } + } + } + return 0; +} + + +#define MK(x) {{BUTTC_KEYBOARD},{0},{MKK(x)},1} +#define MK2(x1,x2) {{BUTTC_KEYBOARD},{0},{MKK(x1),MKK(x2)},2} +#define MKZ() {{0},{0},{0},0} +#define GPZ() {MKZ(), MKZ(), MKZ(), MKZ()} + +ButtConfig GamePadConfig[4][10] = { +/* Gamepad 1 */ + {MK (KP_3), MK (KP_2), MK (SLASH), MK (ENTER), + MK (W), MK (Z), MK (A), MK (S), MKZ (), MKZ ()}, + + /* Gamepad 2 */ + GPZ (), + + /* Gamepad 3 */ + GPZ (), + + /* Gamepad 4 */ + GPZ () +}; + +/** + * Update the status of the gamepad input devices. + */ +static void +UpdateGamepad(void) +{ + // don't update during movie playback + if (FCEUMOV_Mode (MOVIEMODE_PLAY)) + { + return; + } + + static int rapid = 0; + uint32 JS = 0; + int x; + int wg; + + rapid ^= 1; + + int opposite_dirs; + g_config->getOption("SDL.Input.EnableOppositeDirectionals", &opposite_dirs); + + // go through each of the four game pads + for (wg = 0; wg < 4; wg++) + { + bool left = false; + bool up = false; + // a, b, select, start, up, down, left, right + for (x = 0; x < 8; x++) + { + if (DTestButton (&GamePadConfig[wg][x])) + { + //printf("GamePad%i Button Hit: %i \n", wg, x ); + if(opposite_dirs == 0) + { + // test for left+right and up+down + if(x == 4){ + up = true; + } + if((x == 5) && (up == true)){ + continue; + } + if(x == 6){ + left = true; + } + if((x == 7) && (left == true)){ + continue; + } + } + JS |= (1 << x) << (wg << 3); + } + } + + int four_button_exit; + g_config->getOption("SDL.ABStartSelectExit", &four_button_exit); + // if a+b+start+select is pressed, exit + if (four_button_exit && JS == 15) { + FCEUI_printf("all buttons pressed, exiting\n"); + CloseGame(); + FCEUI_Kill(); + exit(0); + } + + // rapid-fire a, rapid-fire b + if (rapid) + { + for (x = 0; x < 2; x++) + { + if (DTestButton (&GamePadConfig[wg][8 + x])) + { + JS |= (1 << x) << (wg << 3); + } + } + } + } + +// for(x=0;x<32;x+=8) /* Now, test to see if anything weird(up+down at same time) +// is happening, and correct */ +// { +// if((JS & (0xC0<ButtType[which]) + { + case BUTTC_KEYBOARD: + return SDL_GetKeyName (bc->ButtonNum[which]); + break; + case BUTTC_JOYSTICK: + { + int joyNum, inputNum; + const char *inputType, *inputDirection; + + joyNum = bc->DeviceNum[which]; + + if (bc->ButtonNum[which] & 0x8000) + { + inputType = "Axis"; + inputNum = bc->ButtonNum[which] & 0x3FFF; + inputDirection = bc->ButtonNum[which] & 0x4000 ? "-" : "+"; + } + else if (bc->ButtonNum[which] & 0x2000) + { + int inputValue; + char direction[128] = ""; + + inputType = "Hat"; + inputNum = (bc->ButtonNum[which] >> 8) & 0x1F; + inputValue = bc->ButtonNum[which] & 0xF; + + if (inputValue & SDL_HAT_UP) + strncat (direction, "Up ", sizeof (direction)-1); + if (inputValue & SDL_HAT_DOWN) + strncat (direction, "Down ", sizeof (direction)-1); + if (inputValue & SDL_HAT_LEFT) + strncat (direction, "Left ", sizeof (direction)-1); + if (inputValue & SDL_HAT_RIGHT) + strncat (direction, "Right ", sizeof (direction)-1); + + if (direction[0]) + inputDirection = direction; + else + inputDirection = "Center"; + } + else + { + inputType = "Button"; + inputNum = bc->ButtonNum[which]; + inputDirection = ""; + } + sprintf( name, "js%i:%s%i%s", joyNum, inputType, inputNum, inputDirection ); + } + break; + } + + return name; +} + +/** + * Waits for a button input and returns the information as to which + * button was pressed. Used in button configuration. + */ +int DWaitButton (const uint8 * text, ButtConfig * bc, int wb, int *buttonConfigStatus ) +{ + SDL_Event event; + static int32 LastAx[64][64]; + int x, y; + + if (text) + { + std::string title = "Press a key for "; + title += (const char *) text; + // TODO - SDL2 + //SDL_WM_SetCaption (title.c_str (), 0); + puts ((const char *) text); + } + + for (x = 0; x < 64; x++) + { + for (y = 0; y < 64; y++) + { + LastAx[x][y] = 0x100000; + } + } + + while (1) + { + int done = 0; +#ifdef _GTK + while (gtk_events_pending ()) + gtk_main_iteration_do (FALSE); +#endif + while (SDL_PollEvent (&event)) + { + done++; + switch (event.type) + { + case SDL_KEYDOWN: + bc->ButtType[wb] = BUTTC_KEYBOARD; + bc->DeviceNum[wb] = 0; + bc->ButtonNum[wb] = event.key.keysym.sym; + return (1); + case SDL_JOYBUTTONDOWN: + bc->ButtType[wb] = BUTTC_JOYSTICK; + bc->DeviceNum[wb] = event.jbutton.which; + bc->ButtonNum[wb] = event.jbutton.button; + return (1); + case SDL_JOYHATMOTION: + if (event.jhat.value == SDL_HAT_CENTERED) + done--; + else + { + bc->ButtType[wb] = BUTTC_JOYSTICK; + bc->DeviceNum[wb] = event.jhat.which; + bc->ButtonNum[wb] = + (0x2000 | ((event.jhat.hat & 0x1F) << 8) | event. + jhat.value); + return (1); + } + break; + case SDL_JOYAXISMOTION: + if (LastAx[event.jaxis.which][event.jaxis.axis] == 0x100000) + { + if (abs (event.jaxis.value) < 1000) + { + LastAx[event.jaxis.which][event.jaxis.axis] = + event.jaxis.value; + } + done--; + } + else + { + if (abs + (LastAx[event.jaxis.which][event.jaxis.axis] - + event.jaxis.value) >= 8192) + { + bc->ButtType[wb] = BUTTC_JOYSTICK; + bc->DeviceNum[wb] = event.jaxis.which; + bc->ButtonNum[wb] = (0x8000 | event.jaxis.axis | + ((event.jaxis.value < 0) + ? 0x4000 : 0)); + return (1); + } + else + done--; + } + break; + default: + done--; + } + } + if (done) + break; + + // If the button config window is Closed, + // get out of loop. + if ( buttonConfigStatus != NULL ) + { + if ( *buttonConfigStatus == 0 ) + { + break; + } + } + } + + return (0); +} + +/** + * This function takes in button inputs until either it sees two of + * the same button presses in a row or gets four inputs and then saves + * the total number of button presses. Each of the keys pressed is + * used as input for the specified button, thus allowing up to four + * possible settings for each input button. + */ + void +ConfigButton (char *text, ButtConfig * bc) +{ + uint8 buf[256]; + int wc; + + for (wc = 0; wc < MAXBUTTCONFIG; wc++) + { + sprintf ((char *) buf, "%s (%d)", text, wc + 1); + DWaitButton (buf, bc, wc, NULL); + + if (wc && + bc->ButtType[wc] == bc->ButtType[wc - 1] && + bc->DeviceNum[wc] == bc->DeviceNum[wc - 1] && + bc->ButtonNum[wc] == bc->ButtonNum[wc - 1]) + { + break; + } + } + bc->NumC = wc; +} + +/** + * Update the button configuration for a specified device. + */ +extern Config *g_config; + +void ConfigDevice (int which, int arg) +{ + char buf[256]; + int x; + std::string prefix; + const char *str[10] = + { "A", "B", "SELECT", "START", "UP", "DOWN", "LEFT", "RIGHT", "Rapid A", + "Rapid B" + }; + + // XXX soules - set the configuration options so that later calls + // don't override these. This is a temp hack until I + // can clean up this file. + + ButtonConfigBegin (); + switch (which) + { + case FCFGD_QUIZKING: + prefix = "SDL.Input.QuizKing."; + for (x = 0; x < 6; x++) + { + sprintf (buf, "Quiz King Buzzer #%d", x + 1); + ConfigButton (buf, &QuizKingButtons[x]); + + g_config->setOption (prefix + QuizKingNames[x], + QuizKingButtons[x].ButtonNum[0]); + } + + if (QuizKingButtons[0].ButtType[0] == BUTTC_KEYBOARD) + { + g_config->setOption (prefix + "DeviceType", "Keyboard"); + } + else if (QuizKingButtons[0].ButtType[0] == BUTTC_JOYSTICK) + { + g_config->setOption (prefix + "DeviceType", "Joystick"); + } + else + { + g_config->setOption (prefix + "DeviceType", "Unknown"); + } + g_config->setOption (prefix + "DeviceNum", + QuizKingButtons[0].DeviceNum[0]); + break; + case FCFGD_HYPERSHOT: + prefix = "SDL.Input.HyperShot."; + for (x = 0; x < 4; x++) + { + sprintf (buf, "Hyper Shot %d: %s", + ((x & 2) >> 1) + 1, (x & 1) ? "JUMP" : "RUN"); + ConfigButton (buf, &HyperShotButtons[x]); + + g_config->setOption (prefix + HyperShotNames[x], + HyperShotButtons[x].ButtonNum[0]); + } + + if (HyperShotButtons[0].ButtType[0] == BUTTC_KEYBOARD) + { + g_config->setOption (prefix + "DeviceType", "Keyboard"); + } + else if (HyperShotButtons[0].ButtType[0] == BUTTC_JOYSTICK) + { + g_config->setOption (prefix + "DeviceType", "Joystick"); + } + else + { + g_config->setOption (prefix + "DeviceType", "Unknown"); + } + g_config->setOption (prefix + "DeviceNum", + HyperShotButtons[0].DeviceNum[0]); + break; + case FCFGD_POWERPAD: + snprintf (buf, 256, "SDL.Input.PowerPad.%d", (arg & 1)); + prefix = buf; + for (x = 0; x < 12; x++) + { + sprintf (buf, "PowerPad %d: %d", (arg & 1) + 1, x + 11); + ConfigButton (buf, &powerpadsc[arg & 1][x]); + + g_config->setOption (prefix + PowerPadNames[x], + powerpadsc[arg & 1][x].ButtonNum[0]); + } + + if (powerpadsc[arg & 1][0].ButtType[0] == BUTTC_KEYBOARD) + { + g_config->setOption (prefix + "DeviceType", "Keyboard"); + } + else if (powerpadsc[arg & 1][0].ButtType[0] == BUTTC_JOYSTICK) + { + g_config->setOption (prefix + "DeviceType", "Joystick"); + } + else + { + g_config->setOption (prefix + "DeviceType", "Unknown"); + } + g_config->setOption (prefix + "DeviceNum", + powerpadsc[arg & 1][0].DeviceNum[0]); + break; + + case FCFGD_GAMEPAD: + snprintf (buf, 256, "SDL.Input.GamePad.%d", arg); + prefix = buf; + for (x = 0; x < 10; x++) + { + sprintf (buf, "GamePad #%d: %s", arg + 1, str[x]); + ConfigButton (buf, &GamePadConfig[arg][x]); + + g_config->setOption (prefix + GamePadNames[x], + GamePadConfig[arg][x].ButtonNum[0]); + } + + if (GamePadConfig[arg][0].ButtType[0] == BUTTC_KEYBOARD) + { + g_config->setOption (prefix + "DeviceType", "Keyboard"); + } + else if (GamePadConfig[arg][0].ButtType[0] == BUTTC_JOYSTICK) + { + g_config->setOption (prefix + "DeviceType", "Joystick"); + } + else + { + g_config->setOption (prefix + "DeviceType", "Unknown"); + } + g_config->setOption (prefix + "DeviceNum", + GamePadConfig[arg][0].DeviceNum[0]); + break; + } + + ButtonConfigEnd (); +} + + +/** + * Update the button configuration for a device, specified by a text string. + */ +void InputCfg (const std::string & text) +{ + +// if (noGui) +// { +// if (text.find ("gamepad") != std::string::npos) +// { +// int device = (text[strlen ("gamepad")] - '1'); +// if (device < 0 || device > 3) +// { +// FCEUD_PrintError +// ("Invalid gamepad device specified; must be one of gamepad1 through gamepad4"); +// exit (-1); +// } +// ConfigDevice (FCFGD_GAMEPAD, device); +// } +// else if (text.find ("powerpad") != std::string::npos) +// { +// int device = (text[strlen ("powerpad")] - '1'); +// if (device < 0 || device > 1) +// { +// FCEUD_PrintError +// ("Invalid powerpad device specified; must be powerpad1 or powerpad2"); +// exit (-1); +// } +// ConfigDevice (FCFGD_POWERPAD, device); +// } +// else if (text.find ("hypershot") != std::string::npos) +// { +// ConfigDevice (FCFGD_HYPERSHOT, 0); +// } +// else if (text.find ("quizking") != std::string::npos) +// { +// ConfigDevice (FCFGD_QUIZKING, 0); +// } +// } +// else +// printf ("Please run \"fceux --nogui\" before using --inputcfg\n"); + +} + + +/** + * Hack to map the new configuration onto the existing button + * configuration management. Will probably want to change this in the + * future - soules. + */ + void +UpdateInput (Config * config) +{ + char buf[64]; + std::string device, prefix; + + for (unsigned int i = 0; i < 3; i++) + { + snprintf (buf, 64, "SDL.Input.%u", i); + config->getOption (buf, &device); + + if (device == "None") + { + UsrInputType[i] = SI_NONE; + } + else if (device.find ("GamePad") != std::string::npos) + { + UsrInputType[i] = (i < 2) ? (int) SI_GAMEPAD : (int) SIFC_NONE; + } + else if (device.find ("PowerPad.0") != std::string::npos) + { + UsrInputType[i] = (i < 2) ? (int) SI_POWERPADA : (int) SIFC_NONE; + } + else if (device.find ("PowerPad.1") != std::string::npos) + { + UsrInputType[i] = (i < 2) ? (int) SI_POWERPADB : (int) SIFC_NONE; + } + else if (device.find ("QuizKing") != std::string::npos) + { + UsrInputType[i] = (i < 2) ? (int) SI_NONE : (int) SIFC_QUIZKING; + } + else if (device.find ("HyperShot") != std::string::npos) + { + UsrInputType[i] = (i < 2) ? (int) SI_NONE : (int) SIFC_HYPERSHOT; + } + else if (device.find ("Mahjong") != std::string::npos) + { + UsrInputType[i] = (i < 2) ? (int) SI_NONE : (int) SIFC_MAHJONG; + } + else if (device.find ("TopRider") != std::string::npos) + { + UsrInputType[i] = (i < 2) ? (int) SI_NONE : (int) SIFC_TOPRIDER; + } + else if (device.find ("FTrainer") != std::string::npos) + { + UsrInputType[i] = (i < 2) ? (int) SI_NONE : (int) SIFC_FTRAINERA; + } + else if (device.find ("FamilyKeyBoard") != std::string::npos) + { + UsrInputType[i] = (i < 2) ? (int) SI_NONE : (int) SIFC_FKB; + } + else if (device.find ("OekaKids") != std::string::npos) + { + UsrInputType[i] = (i < 2) ? (int) SI_NONE : (int) SIFC_OEKAKIDS; + } + else if (device.find ("Arkanoid") != std::string::npos) + { + UsrInputType[i] = (i < 2) ? (int) SI_ARKANOID : (int) SIFC_ARKANOID; + } + else if (device.find ("Shadow") != std::string::npos) + { + UsrInputType[i] = (i < 2) ? (int) SI_NONE : (int) SIFC_SHADOW; + } + else if (device.find ("Zapper") != std::string::npos) + { + UsrInputType[i] = (i < 2) ? (int) SI_ZAPPER : (int) SIFC_NONE; + } + else if (device.find ("BWorld") != std::string::npos) + { + UsrInputType[i] = (i < 2) ? (int) SI_NONE : (int) SIFC_BWORLD; + } + else if (device.find ("4Player") != std::string::npos) + { + UsrInputType[i] = (i < 2) ? (int) SI_NONE : (int) SIFC_4PLAYER; + } + else + { + // Unknown device + UsrInputType[i] = SI_NONE; + } + } + + // update each of the devices' configuration structure + // XXX soules - this is temporary until this file is cleaned up to + // simplify the interface between configuration and + // structure data. This will likely include the + // removal of multiple input buttons for a single + // input device key. + int type, devnum, button; + + // gamepad 0 - 3 + for (unsigned int i = 0; i < GAMEPAD_NUM_DEVICES; i++) + { + char buf[64]; + snprintf (buf, sizeof(buf)-1, "SDL.Input.GamePad.%u.", i); + prefix = buf; + + config->getOption (prefix + "DeviceType", &device); + if (device.find ("Keyboard") != std::string::npos) + { + type = BUTTC_KEYBOARD; + } + else if (device.find ("Joystick") != std::string::npos) + { + type = BUTTC_JOYSTICK; + } + else + { + type = 0; + } + + config->getOption (prefix + "DeviceNum", &devnum); + for (unsigned int j = 0; j < GAMEPAD_NUM_BUTTONS; j++) + { + config->getOption (prefix + GamePadNames[j], &button); + + GamePadConfig[i][j].ButtType[0] = type; + GamePadConfig[i][j].DeviceNum[0] = devnum; + GamePadConfig[i][j].ButtonNum[0] = button; + GamePadConfig[i][j].NumC = 1; + } + } + + // PowerPad 0 - 1 + for (unsigned int i = 0; i < POWERPAD_NUM_DEVICES; i++) + { + char buf[64]; + snprintf (buf, 32, "SDL.Input.PowerPad.%u.", i); + prefix = buf; + + config->getOption (prefix + "DeviceType", &device); + if (device.find ("Keyboard") != std::string::npos) + { + type = BUTTC_KEYBOARD; + } + else if (device.find ("Joystick") != std::string::npos) + { + type = BUTTC_JOYSTICK; + } + else + { + type = 0; + } + + config->getOption (prefix + "DeviceNum", &devnum); + for (unsigned int j = 0; j < POWERPAD_NUM_BUTTONS; j++) + { + config->getOption (prefix + PowerPadNames[j], &button); + + powerpadsc[i][j].ButtType[0] = type; + powerpadsc[i][j].DeviceNum[0] = devnum; + powerpadsc[i][j].ButtonNum[0] = button; + powerpadsc[i][j].NumC = 1; + } + } + + // QuizKing + prefix = "SDL.Input.QuizKing."; + config->getOption (prefix + "DeviceType", &device); + if (device.find ("Keyboard") != std::string::npos) + { + type = BUTTC_KEYBOARD; + } + else if (device.find ("Joystick") != std::string::npos) + { + type = BUTTC_JOYSTICK; + } + else + { + type = 0; + } + config->getOption (prefix + "DeviceNum", &devnum); + for (unsigned int j = 0; j < QUIZKING_NUM_BUTTONS; j++) + { + config->getOption (prefix + QuizKingNames[j], &button); + + QuizKingButtons[j].ButtType[0] = type; + QuizKingButtons[j].DeviceNum[0] = devnum; + QuizKingButtons[j].ButtonNum[0] = button; + QuizKingButtons[j].NumC = 1; + } + + // HyperShot + prefix = "SDL.Input.HyperShot."; + config->getOption (prefix + "DeviceType", &device); + if (device.find ("Keyboard") != std::string::npos) + { + type = BUTTC_KEYBOARD; + } + else if (device.find ("Joystick") != std::string::npos) + { + type = BUTTC_JOYSTICK; + } + else + { + type = 0; + } + config->getOption (prefix + "DeviceNum", &devnum); + for (unsigned int j = 0; j < HYPERSHOT_NUM_BUTTONS; j++) + { + config->getOption (prefix + HyperShotNames[j], &button); + + HyperShotButtons[j].ButtType[0] = type; + HyperShotButtons[j].DeviceNum[0] = devnum; + HyperShotButtons[j].ButtonNum[0] = button; + HyperShotButtons[j].NumC = 1; + } + + // Mahjong + prefix = "SDL.Input.Mahjong."; + config->getOption (prefix + "DeviceType", &device); + if (device.find ("Keyboard") != std::string::npos) + { + type = BUTTC_KEYBOARD; + } + else if (device.find ("Joystick") != std::string::npos) + { + type = BUTTC_JOYSTICK; + } + else + { + type = 0; + } + config->getOption (prefix + "DeviceNum", &devnum); + for (unsigned int j = 0; j < MAHJONG_NUM_BUTTONS; j++) + { + config->getOption (prefix + MahjongNames[j], &button); + + MahjongButtons[j].ButtType[0] = type; + MahjongButtons[j].DeviceNum[0] = devnum; + MahjongButtons[j].ButtonNum[0] = button; + MahjongButtons[j].NumC = 1; + } + + // TopRider + prefix = "SDL.Input.TopRider."; + config->getOption (prefix + "DeviceType", &device); + if (device.find ("Keyboard") != std::string::npos) + { + type = BUTTC_KEYBOARD; + } + else if (device.find ("Joystick") != std::string::npos) + { + type = BUTTC_JOYSTICK; + } + else + { + type = 0; + } + config->getOption (prefix + "DeviceNum", &devnum); + for (unsigned int j = 0; j < TOPRIDER_NUM_BUTTONS; j++) + { + config->getOption (prefix + TopRiderNames[j], &button); + + TopRiderButtons[j].ButtType[0] = type; + TopRiderButtons[j].DeviceNum[0] = devnum; + TopRiderButtons[j].ButtonNum[0] = button; + TopRiderButtons[j].NumC = 1; + } + + // FTrainer + prefix = "SDL.Input.FTrainer."; + config->getOption (prefix + "DeviceType", &device); + if (device.find ("Keyboard") != std::string::npos) + { + type = BUTTC_KEYBOARD; + } + else if (device.find ("Joystick") != std::string::npos) + { + type = BUTTC_JOYSTICK; + } + else + { + type = 0; + } + config->getOption (prefix + "DeviceNum", &devnum); + for (unsigned int j = 0; j < FTRAINER_NUM_BUTTONS; j++) + { + config->getOption (prefix + FTrainerNames[j], &button); + + FTrainerButtons[j].ButtType[0] = type; + FTrainerButtons[j].DeviceNum[0] = devnum; + FTrainerButtons[j].ButtonNum[0] = button; + FTrainerButtons[j].NumC = 1; + } + + // FamilyKeyBoard + prefix = "SDL.Input.FamilyKeyBoard."; + config->getOption (prefix + "DeviceType", &device); + if (device.find ("Keyboard") != std::string::npos) + { + type = BUTTC_KEYBOARD; + } + else if (device.find ("Joystick") != std::string::npos) + { + type = BUTTC_JOYSTICK; + } + else + { + type = 0; + } + config->getOption (prefix + "DeviceNum", &devnum); + for (unsigned int j = 0; j < FAMILYKEYBOARD_NUM_BUTTONS; j++) + { + config->getOption (prefix + FamilyKeyBoardNames[j], &button); + + fkbmap[j].ButtType[0] = type; + fkbmap[j].DeviceNum[0] = devnum; + fkbmap[j].ButtonNum[0] = button; + fkbmap[j].NumC = 1; + } +} + +// Definitions from main.h: +// GamePad defaults +const char *GamePadNames[GAMEPAD_NUM_BUTTONS] = { "A", "B", "Select", "Start", + "Up", "Down", "Left", "Right", "TurboA", "TurboB" +}; +const char *DefaultGamePadDevice[GAMEPAD_NUM_DEVICES] = +{ "Keyboard", "None", "None", "None" }; +const int DefaultGamePad[GAMEPAD_NUM_DEVICES][GAMEPAD_NUM_BUTTONS] = +{ {SDLK_F, SDLK_D, SDLK_S, SDLK_RETURN, + SDLK_UP, SDLK_DOWN, SDLK_LEFT, SDLK_RIGHT, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +// PowerPad defaults +const char *PowerPadNames[POWERPAD_NUM_BUTTONS] = +{ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B" }; +const char *DefaultPowerPadDevice[POWERPAD_NUM_DEVICES] = +{ "Keyboard", "None" }; +const int DefaultPowerPad[POWERPAD_NUM_DEVICES][POWERPAD_NUM_BUTTONS] = +{ {SDLK_o, SDLK_p, SDLK_LEFTBRACKET, SDLK_RIGHTBRACKET, + SDLK_k, SDLK_l, SDLK_SEMICOLON, SDLK_QUOTE, + SDLK_m, SDLK_COMMA, SDLK_PERIOD, SDLK_SLASH}, +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + +// QuizKing defaults +const char *QuizKingNames[QUIZKING_NUM_BUTTONS] = +{ "0", "1", "2", "3", "4", "5" }; +const char *DefaultQuizKingDevice = "Keyboard"; +const int DefaultQuizKing[QUIZKING_NUM_BUTTONS] = +{ SDLK_q, SDLK_w, SDLK_e, SDLK_r, SDLK_t, SDLK_y }; + +// HyperShot defaults +const char *HyperShotNames[HYPERSHOT_NUM_BUTTONS] = { "0", "1", "2", "3" }; + +const char *DefaultHyperShotDevice = "Keyboard"; +const int DefaultHyperShot[HYPERSHOT_NUM_BUTTONS] = +{ SDLK_q, SDLK_w, SDLK_e, SDLK_r }; + +// Mahjong defaults +const char *MahjongNames[MAHJONG_NUM_BUTTONS] = +{ "00", "01", "02", "03", "04", "05", "06", "07", + "08", "09", "10", "11", "12", "13", "14", "15", + "16", "17", "18", "19", "20" +}; + +const char *DefaultMahjongDevice = "Keyboard"; +const int DefaultMahjong[MAHJONG_NUM_BUTTONS] = +{ SDLK_q, SDLK_w, SDLK_e, SDLK_r, SDLK_t, SDLK_a, SDLK_s, SDLK_d, + SDLK_f, SDLK_g, SDLK_h, SDLK_j, SDLK_k, SDLK_l, SDLK_z, SDLK_x, + SDLK_c, SDLK_v, SDLK_b, SDLK_n, SDLK_m +}; + +// TopRider defaults +const char *TopRiderNames[TOPRIDER_NUM_BUTTONS] = +{ "0", "1", "2", "3", "4", "5", "6", "7" }; +const char *DefaultTopRiderDevice = "Keyboard"; +const int DefaultTopRider[TOPRIDER_NUM_BUTTONS] = +{ SDLK_q, SDLK_w, SDLK_e, SDLK_r, SDLK_t, SDLK_y, SDLK_u, SDLK_i }; + +// FTrainer defaults +const char *FTrainerNames[FTRAINER_NUM_BUTTONS] = +{ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B" }; +const char *DefaultFTrainerDevice = "Keyboard"; +const int DefaultFTrainer[FTRAINER_NUM_BUTTONS] = +{ SDLK_o, SDLK_p, SDLK_LEFTBRACKET, SDLK_RIGHTBRACKET, + SDLK_k, SDLK_l, SDLK_SEMICOLON, SDLK_QUOTE, + SDLK_m, SDLK_COMMA, SDLK_PERIOD, SDLK_SLASH +}; + +// FamilyKeyBoard defaults +const char *FamilyKeyBoardNames[FAMILYKEYBOARD_NUM_BUTTONS] = +{ "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", + "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", + "MINUS", "EQUAL", "BACKSLASH", "BACKSPACE", + "ESCAPE", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", + "P", "GRAVE", "BRACKET_LEFT", "ENTER", + "LEFTCONTROL", "A", "S", "D", "F", "G", "H", "J", "K", + "L", "SEMICOLON", "APOSTROPHE", "BRACKET_RIGHT", "INSERT", + "LEFTSHIFT", "Z", "X", "C", "V", "B", "N", "M", "COMMA", + "PERIOD", "SLASH", "RIGHTALT", "RIGHTSHIFT", "LEFTALT", "SPACE", + "DELETE", "END", "PAGEDOWN", + "CURSORUP", "CURSORLEFT", "CURSORRIGHT", "CURSORDOWN" +}; + +const char *DefaultFamilyKeyBoardDevice = "Keyboard"; +const int DefaultFamilyKeyBoard[FAMILYKEYBOARD_NUM_BUTTONS] = +{ SDLK_F1, SDLK_F2, SDLK_F3, SDLK_F4, SDLK_F5, SDLK_F6, SDLK_F7, SDLK_F8, + SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5, + SDLK_6, SDLK_7, SDLK_8, SDLK_9, SDLK_0, + SDLK_MINUS, SDLK_EQUALS, SDLK_BACKSLASH, SDLK_BACKSPACE, + SDLK_ESCAPE, SDLK_q, SDLK_w, SDLK_e, SDLK_r, SDLK_t, SDLK_y, SDLK_u, + SDLK_i, SDLK_o, SDLK_p, SDLK_BACKQUOTE, SDLK_LEFTBRACKET, SDLK_RETURN, + SDLK_LCTRL, SDLK_a, SDLK_s, SDLK_d, SDLK_f, SDLK_g, SDLK_h, SDLK_j, + SDLK_k, SDLK_l, SDLK_SEMICOLON, SDLK_QUOTE, SDLK_RIGHTBRACKET, + SDLK_INSERT, SDLK_LSHIFT, SDLK_z, SDLK_x, SDLK_c, SDLK_v, SDLK_b, + SDLK_n, SDLK_m, SDLK_COMMA, SDLK_PERIOD, SDLK_SLASH, SDLK_RALT, + SDLK_RSHIFT, SDLK_LALT, SDLK_SPACE, SDLK_DELETE, SDLK_END, SDLK_PAGEDOWN, + SDLK_UP, SDLK_LEFT, SDLK_RIGHT, SDLK_DOWN +}; diff --git a/src/drivers/Qt/input.h b/src/drivers/Qt/input.h new file mode 100644 index 00000000..2a1a2d85 --- /dev/null +++ b/src/drivers/Qt/input.h @@ -0,0 +1,62 @@ +#ifndef _aosdfjk02fmasf +#define _aosdfjk02fmasf + +#include "../common/configSys.h" + +#define MAXBUTTCONFIG 4 +typedef struct { + uint8 ButtType[MAXBUTTCONFIG]; + uint8 DeviceNum[MAXBUTTCONFIG]; + //uint16 ButtonNum[MAXBUTTCONFIG]; + int ButtonNum[MAXBUTTCONFIG]; + uint32 NumC; + //uint64 DeviceID[MAXBUTTCONFIG]; /* TODO */ +} ButtConfig; + + +extern int NoWaiting; +extern CFGSTRUCT InputConfig[]; +extern ARGPSTRUCT InputArgs[]; +extern int Hotkeys[]; +void ParseGIInput(FCEUGI *GI); +void setHotKeys(); +int getKeyState( int k ); +int ButtonConfigBegin(); +void ButtonConfigEnd(); +void ConfigButton(char *text, ButtConfig *bc); +int DWaitButton(const uint8 *text, ButtConfig *bc, int wb, int *buttonConfigStatus = NULL); + +#define BUTTC_KEYBOARD 0x00 +#define BUTTC_JOYSTICK 0x01 +#define BUTTC_MOUSE 0x02 + +#define FCFGD_GAMEPAD 1 +#define FCFGD_POWERPAD 2 +#define FCFGD_HYPERSHOT 3 +#define FCFGD_QUIZKING 4 + +#define SDL_FCEU_HOTKEY_EVENT SDL_USEREVENT + +void InitInputInterface(void); +void InputUserActiveFix(void); + +extern bool replaceP2StartWithMicrophone; +extern ButtConfig GamePadConfig[4][10]; +//extern ButtConfig powerpadsc[2][12]; +//extern ButtConfig QuizKingButtons[6]; +//extern ButtConfig FTrainerButtons[12]; + +void IncreaseEmulationSpeed(void); +void DecreaseEmulationSpeed(void); + +int DTestButtonJoy(ButtConfig *bc); + +void FCEUD_UpdateInput(void); + +void UpdateInput(Config *config); +void InputCfg(const std::string &); + +std::string GetUserText(const char* title); +const char* ButtonName(const ButtConfig* bc, int which); +#endif + diff --git a/src/drivers/Qt/keyscan.h b/src/drivers/Qt/keyscan.h new file mode 100644 index 00000000..b3973c20 --- /dev/null +++ b/src/drivers/Qt/keyscan.h @@ -0,0 +1,44 @@ +#define SDLK_A SDLK_a +#define SDLK_B SDLK_b +#define SDLK_C SDLK_c +#define SDLK_D SDLK_d +#define SDLK_E SDLK_e +#define SDLK_F SDLK_f +#define SDLK_G SDLK_g +#define SDLK_H SDLK_h +#define SDLK_I SDLK_i +#define SDLK_J SDLK_j +#define SDLK_K SDLK_k +#define SDLK_L SDLK_l +#define SDLK_M SDLK_m +#define SDLK_N SDLK_n +#define SDLK_O SDLK_o +#define SDLK_P SDLK_p +#define SDLK_Q SDLK_q +#define SDLK_R SDLK_r +#define SDLK_S SDLK_s +#define SDLK_T SDLK_t +#define SDLK_U SDLK_u +#define SDLK_V SDLK_v +#define SDLK_W SDLK_w +#define SDLK_X SDLK_x +#define SDLK_Y SDLK_y +#define SDLK_Z SDLK_z +#define SDLK_LEFTCONTROL SDLK_LCTRL +#define SDLK_RIGHTCONTROL SDLK_RCTRL +#define SDLK_LEFTALT SDLK_LALT +#define SDLK_RIGHTALT SDLK_RALT +#define SDLK_LEFTSHIFT SDLK_LSHIFT +#define SDLK_RIGHTSHIFT SDLK_RSHIFT +#define SDLK_CURSORDOWN SDLK_DOWN +#define SDLK_CURSORUP SDLK_UP +#define SDLK_CURSORLEFT SDLK_LEFT +#define SDLK_CURSORRIGHT SDLK_RIGHT +#define SDLK_ENTER SDLK_RETURN +#define SDLK_EQUAL SDLK_EQUALS +#define SDLK_APOSTROPHE SDLK_QUOTE +#define SDLK_BRACKET_LEFT SDLK_LEFTBRACKET +#define SDLK_BRACKET_RIGHT SDLK_RIGHTBRACKET +#define SDLK_SCROLLLOCK SDLK_SCROLLOCK /* I guess the SDL people don't like lots of Ls... */ +#define SDLK_GRAVE SDLK_BACKQUOTE +#define MKK(k) SDLK_##k diff --git a/src/drivers/Qt/main.cpp b/src/drivers/Qt/main.cpp new file mode 100644 index 00000000..14864529 --- /dev/null +++ b/src/drivers/Qt/main.cpp @@ -0,0 +1,15 @@ +#include + +#include "GameApp.h" + +int main( int argc, char *argv[] ) +{ + QApplication app(argc, argv); + gameWin_t win; + + win.resize( 200, 200 ); + win.show(); + + return app.exec(); +} + diff --git a/src/drivers/Qt/main.h b/src/drivers/Qt/main.h new file mode 100644 index 00000000..9b6963e1 --- /dev/null +++ b/src/drivers/Qt/main.h @@ -0,0 +1,100 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2002 Xodnizel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef __FCEU_SDL_MAIN_H +#define __FCEU_SDL_MAIN_H + +#include "../../driver.h" +#include "../common/config.h" +#include "../common/args.h" + +extern int eoptions; +#define EO_NO8LIM 1 +#define EO_SUBASE 2 +#define EO_CLIPSIDES 8 +#define EO_SNAPNAME 16 +#define EO_FOURSCORE 32 +#define EO_NOTHROTTLE 64 +#define EO_GAMEGENIE 128 +#define EO_PAL 256 +#define EO_LOWPASS 512 +#define EO_AUTOHIDE 1024 + +extern int _sound; +extern long soundrate; +extern long soundbufsize; + +extern int pal_emulation; + +int CLImain(int argc, char *argv[]); + +// Device management defaults +#define NUM_INPUT_DEVICES 3 + +// GamePad defaults +#define GAMEPAD_NUM_DEVICES 4 +#define GAMEPAD_NUM_BUTTONS 10 +extern const char *GamePadNames[GAMEPAD_NUM_BUTTONS]; +extern const char *DefaultGamePadDevice[GAMEPAD_NUM_DEVICES]; +extern const int DefaultGamePad[GAMEPAD_NUM_DEVICES][GAMEPAD_NUM_BUTTONS]; + +// PowerPad defaults +#define POWERPAD_NUM_DEVICES 2 +#define POWERPAD_NUM_BUTTONS 12 +extern const char *PowerPadNames[POWERPAD_NUM_BUTTONS]; +extern const char *DefaultPowerPadDevice[POWERPAD_NUM_DEVICES]; +extern const int DefaultPowerPad[POWERPAD_NUM_DEVICES][POWERPAD_NUM_BUTTONS]; + +// QuizKing defaults +#define QUIZKING_NUM_BUTTONS 6 +extern const char *QuizKingNames[QUIZKING_NUM_BUTTONS]; +extern const char *DefaultQuizKingDevice; +extern const int DefaultQuizKing[QUIZKING_NUM_BUTTONS]; + +// HyperShot defaults +#define HYPERSHOT_NUM_BUTTONS 4 +extern const char *HyperShotNames[HYPERSHOT_NUM_BUTTONS]; +extern const char *DefaultHyperShotDevice; +extern const int DefaultHyperShot[HYPERSHOT_NUM_BUTTONS]; + +// Mahjong defaults +#define MAHJONG_NUM_BUTTONS 21 +extern const char *MahjongNames[MAHJONG_NUM_BUTTONS]; +extern const char *DefaultMahjongDevice; +extern const int DefaultMahjong[MAHJONG_NUM_BUTTONS]; + +// TopRider defaults +#define TOPRIDER_NUM_BUTTONS 8 +extern const char *TopRiderNames[TOPRIDER_NUM_BUTTONS]; +extern const char *DefaultTopRiderDevice; +extern const int DefaultTopRider[TOPRIDER_NUM_BUTTONS]; + +// FTrainer defaults +#define FTRAINER_NUM_BUTTONS 12 +extern const char *FTrainerNames[FTRAINER_NUM_BUTTONS]; +extern const char *DefaultFTrainerDevice; +extern const int DefaultFTrainer[FTRAINER_NUM_BUTTONS]; + +// FamilyKeyBoard defaults +#define FAMILYKEYBOARD_NUM_BUTTONS 0x48 +extern const char *FamilyKeyBoardNames[FAMILYKEYBOARD_NUM_BUTTONS]; +extern const char *DefaultFamilyKeyBoardDevice; +extern const int DefaultFamilyKeyBoard[FAMILYKEYBOARD_NUM_BUTTONS]; + +#endif diff --git a/src/drivers/Qt/sdl-joystick.cpp b/src/drivers/Qt/sdl-joystick.cpp new file mode 100644 index 00000000..690b012b --- /dev/null +++ b/src/drivers/Qt/sdl-joystick.cpp @@ -0,0 +1,123 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2002 Xodnizel + * Copyright (C) 2002 Paul Kuliniewicz + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/// \file +/// \brief Handles joystick input using the SDL. + +#include "sdl.h" + +#include +#include +#include +#include + +#define MAX_JOYSTICKS 32 +static SDL_Joystick *s_Joysticks[MAX_JOYSTICKS] = {NULL}; + +static int s_jinited = 0; + + +/** + * Tests if the given button is active on the joystick. + */ +int +DTestButtonJoy(ButtConfig *bc) +{ + int x; + + for(x = 0; x < bc->NumC; x++) + { + if(bc->ButtonNum[x] & 0x2000) + { + /* Hat "button" */ + if(SDL_JoystickGetHat(s_Joysticks[bc->DeviceNum[x]], + ((bc->ButtonNum[x] >> 8) & 0x1F)) & + (bc->ButtonNum[x]&0xFF)) + return 1; + } + else if(bc->ButtonNum[x] & 0x8000) + { + /* Axis "button" */ + int pos; + pos = SDL_JoystickGetAxis(s_Joysticks[bc->DeviceNum[x]], + bc->ButtonNum[x] & 16383); + if ((bc->ButtonNum[x] & 0x4000) && pos <= -16383) { + return 1; + } else if (!(bc->ButtonNum[x] & 0x4000) && pos >= 16363) { + return 1; + } + } + else if(SDL_JoystickGetButton(s_Joysticks[bc->DeviceNum[x]], + bc->ButtonNum[x])) + return 1; + } + return 0; +} + +/** + * Shutdown the SDL joystick subsystem. + */ +int +KillJoysticks() +{ + int n; /* joystick index */ + + if(!s_jinited) { + return -1; + } + + for(n = 0; n < MAX_JOYSTICKS; n++) { + if (s_Joysticks[n] != 0) { + SDL_JoystickClose(s_Joysticks[n]); + } + s_Joysticks[n]=0; + } + SDL_QuitSubSystem(SDL_INIT_JOYSTICK); + return 0; +} + +/** + * Initialize the SDL joystick subsystem. + */ +int +InitJoysticks() +{ + int n; /* joystick index */ + int total; + + SDL_InitSubSystem(SDL_INIT_JOYSTICK); + + total = SDL_NumJoysticks(); + if(total>MAX_JOYSTICKS) { + total = MAX_JOYSTICKS; + } + + for(n = 0; n < total; n++) { + /* Open the joystick under SDL. */ + s_Joysticks[n] = SDL_JoystickOpen(n); + //printf("Could not open joystick %d: %s.\n", + //joy[n] - 1, SDL_GetError()); + continue; + } + + s_jinited = 1; + return 1; +} diff --git a/src/drivers/Qt/sdl-sound.cpp b/src/drivers/Qt/sdl-sound.cpp new file mode 100644 index 00000000..00b7c9a6 --- /dev/null +++ b/src/drivers/Qt/sdl-sound.cpp @@ -0,0 +1,280 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2002 Xodnizel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/// \file +/// \brief Handles sound emulation using the SDL. + +#include "sdl.h" + +#include "../common/configSys.h" +#include "../../utils/memory.h" + +#include +#include +#include + +extern Config *g_config; + +static volatile int *s_Buffer = 0; +static unsigned int s_BufferSize; +static unsigned int s_BufferRead; +static unsigned int s_BufferWrite; +static volatile unsigned int s_BufferIn; + +static int s_mute = 0; + + +/** + * Callback from the SDL to get and play audio data. + */ +static void +fillaudio(void *udata, + uint8 *stream, + int len) +{ + int16 *tmps = (int16*)stream; + len >>= 1; + while(len) { + int16 sample = 0; + if(s_BufferIn) { + sample = s_Buffer[s_BufferRead]; + s_BufferRead = (s_BufferRead + 1) % s_BufferSize; + s_BufferIn--; + } else { + sample = 0; + } + + *tmps = sample; + tmps++; + len--; + } +} + +/** + * Initialize the audio subsystem. + */ +int +InitSound() +{ + int sound, soundrate, soundbufsize, soundvolume, soundtrianglevolume, soundsquare1volume, soundsquare2volume, soundnoisevolume, soundpcmvolume, soundq; + SDL_AudioSpec spec; + const char *driverName; + + g_config->getOption("SDL.Sound", &sound); + if (!sound) + { + return 0; + } + + memset(&spec, 0, sizeof(spec)); + if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) + { + puts(SDL_GetError()); + KillSound(); + return 0; + } + + // load configuration variables + g_config->getOption("SDL.Sound.Rate", &soundrate); + g_config->getOption("SDL.Sound.BufSize", &soundbufsize); + g_config->getOption("SDL.Sound.Volume", &soundvolume); + g_config->getOption("SDL.Sound.Quality", &soundq); + g_config->getOption("SDL.Sound.TriangleVolume", &soundtrianglevolume); + g_config->getOption("SDL.Sound.Square1Volume", &soundsquare1volume); + g_config->getOption("SDL.Sound.Square2Volume", &soundsquare2volume); + g_config->getOption("SDL.Sound.NoiseVolume", &soundnoisevolume); + g_config->getOption("SDL.Sound.PCMVolume", &soundpcmvolume); + + spec.freq = soundrate; + spec.format = AUDIO_S16SYS; + spec.channels = 1; + spec.samples = 512; + spec.callback = fillaudio; + spec.userdata = 0; + + s_BufferSize = soundbufsize * soundrate / 1000; + + // For safety, set a bare minimum: + if (s_BufferSize < spec.samples * 2) + { + s_BufferSize = spec.samples * 2; + } + + s_Buffer = (int *)FCEU_dmalloc(sizeof(int) * s_BufferSize); + + if (!s_Buffer) + { + return 0; + } + s_BufferRead = s_BufferWrite = s_BufferIn = 0; + + if (SDL_OpenAudio(&spec, 0) < 0) + { + puts(SDL_GetError()); + KillSound(); + return 0; + } + SDL_PauseAudio(0); + + driverName = SDL_GetCurrentAudioDriver(); + + if ( driverName ) + { + fprintf(stderr, "Loading SDL sound with %s driver...\n", driverName); + } + + FCEUI_SetSoundVolume(soundvolume); + FCEUI_SetSoundQuality(soundq); + FCEUI_Sound(soundrate); + FCEUI_SetTriangleVolume(soundtrianglevolume); + FCEUI_SetSquare1Volume(soundsquare1volume); + FCEUI_SetSquare2Volume(soundsquare2volume); + FCEUI_SetNoiseVolume(soundnoisevolume); + FCEUI_SetPCMVolume(soundpcmvolume); + return 1; +} + + +/** + * Returns the size of the audio buffer. + */ +uint32 +GetMaxSound(void) +{ + return(s_BufferSize); +} + +/** + * Returns the amount of free space in the audio buffer. + */ +uint32 +GetWriteSound(void) +{ + return(s_BufferSize - s_BufferIn); +} + +/** + * Send a sound clip to the audio subsystem. + */ +void +WriteSound(int32 *buf, + int Count) +{ + extern int EmulationPaused; + if (EmulationPaused == 0) + while(Count) + { + while(s_BufferIn == s_BufferSize) + { + SDL_Delay(1); + } + + s_Buffer[s_BufferWrite] = *buf; + Count--; + s_BufferWrite = (s_BufferWrite + 1) % s_BufferSize; + + SDL_LockAudio(); + s_BufferIn++; + SDL_UnlockAudio(); + + buf++; + } +} + +/** + * Pause (1) or unpause (0) the audio output. + */ +void +SilenceSound(int n) +{ + SDL_PauseAudio(n); +} + +/** + * Shut down the audio subsystem. + */ +int +KillSound(void) +{ + FCEUI_Sound(0); + SDL_CloseAudio(); + SDL_QuitSubSystem(SDL_INIT_AUDIO); + if(s_Buffer) { + free((void *)s_Buffer); + s_Buffer = 0; + } + return 0; +} + + +/** + * Adjust the volume either down (-1), up (1), or to the default (0). + * Unmutes if mute was active before. + */ +void +FCEUD_SoundVolumeAdjust(int n) +{ + int soundvolume; + g_config->getOption("SDL.Sound.Volume", &soundvolume); + + switch(n) { + case -1: + soundvolume -= 10; + if(soundvolume < 0) { + soundvolume = 0; + } + break; + case 0: + soundvolume = 100; + break; + case 1: + soundvolume += 10; + if(soundvolume > 150) { + soundvolume = 150; + } + break; + } + + s_mute = 0; + FCEUI_SetSoundVolume(soundvolume); + g_config->setOption("SDL.Sound.Volume", soundvolume); + + FCEU_DispMessage("Sound volume %d.",0, soundvolume); +} + +/** + * Toggles the sound on or off. + */ +void +FCEUD_SoundToggle(void) +{ + if(s_mute) { + int soundvolume; + g_config->getOption("SDL.SoundVolume", &soundvolume); + + s_mute = 0; + FCEUI_SetSoundVolume(soundvolume); + FCEU_DispMessage("Sound mute off.",0); + } else { + s_mute = 1; + FCEUI_SetSoundVolume(0); + FCEU_DispMessage("Sound mute on.",0); + } +} diff --git a/src/drivers/Qt/sdl-throttle.cpp b/src/drivers/Qt/sdl-throttle.cpp new file mode 100644 index 00000000..498d4fe7 --- /dev/null +++ b/src/drivers/Qt/sdl-throttle.cpp @@ -0,0 +1,154 @@ +/// \file +/// \brief Handles emulation speed throttling using the SDL timing functions. + +#include "sdl.h" +#include "throttle.h" + +static const double Slowest = 0.015625; // 1/64x speed (around 1 fps on NTSC) +static const double Fastest = 32; // 32x speed (around 1920 fps on NTSC) +static const double Normal = 1.0; // 1x speed (around 60 fps on NTSC) + +static uint64 Lasttime, Nexttime; +static long double desired_frametime; +static int InFrame; +double g_fpsScale = Normal; // used by sdl.cpp +bool MaxSpeed = false; + +/* LOGMUL = exp(log(2) / 3) + * + * This gives us a value such that if we do x*=LOGMUL three times, + * then after that, x is twice the value it was before. + * + * This gives us three speed steps per order of magnitude. + * + */ +#define LOGMUL 1.259921049894873 + +/** + * Refreshes the FPS throttling variables. + */ +void +RefreshThrottleFPS() +{ + uint64 fps = FCEUI_GetDesiredFPS(); // Do >> 24 to get in Hz + desired_frametime = 16777216.0l / (fps * g_fpsScale); + + Lasttime=0; + Nexttime=0; + InFrame=0; +} + +/** + * Perform FPS speed throttling by delaying until the next time slot. + */ +int +SpeedThrottle() +{ + if(g_fpsScale >= 32) + { + return 0; /* Done waiting */ + } + uint64 time_left; + uint64 cur_time; + + if(!Lasttime) + Lasttime = SDL_GetTicks(); + + if(!InFrame) + { + InFrame = 1; + Nexttime = Lasttime + desired_frametime * 1000; + } + + cur_time = SDL_GetTicks(); + if(cur_time >= Nexttime) + time_left = 0; + else + time_left = Nexttime - cur_time; + + if(time_left > 50) + { + time_left = 50; + /* In order to keep input responsive, don't wait too long at once */ + /* 50 ms wait gives us a 20 Hz responsetime which is nice. */ + } + else + InFrame = 0; + + //fprintf(stderr, "attempting to sleep %Ld ms, frame complete=%s\n", + // time_left, InFrame?"no":"yes"); + + if ( time_left > 0 ) + { + SDL_Delay(time_left); + } + + if(!InFrame) + { + Lasttime = SDL_GetTicks(); + return 0; /* Done waiting */ + } + return 1; /* Must still wait some more */ +} + +/** + * Set the emulation speed throttling to the next entry in the speed table. + */ +void IncreaseEmulationSpeed(void) +{ + g_fpsScale *= LOGMUL; + + if(g_fpsScale > Fastest) g_fpsScale = Fastest; + + RefreshThrottleFPS(); + + FCEU_DispMessage("Emulation speed %.1f%%",0, g_fpsScale*100.0); +} + +/** + * Set the emulation speed throttling to the previous entry in the speed table. + */ +void DecreaseEmulationSpeed(void) +{ + g_fpsScale /= LOGMUL; + if(g_fpsScale < Slowest) + g_fpsScale = Slowest; + + RefreshThrottleFPS(); + + FCEU_DispMessage("Emulation speed %.1f%%",0, g_fpsScale*100.0); +} + +/** + * Set the emulation speed throttling to a specific value. + */ +void +FCEUD_SetEmulationSpeed(int cmd) +{ + MaxSpeed = false; + + switch(cmd) { + case EMUSPEED_SLOWEST: + g_fpsScale = Slowest; + break; + case EMUSPEED_SLOWER: + DecreaseEmulationSpeed(); + break; + case EMUSPEED_NORMAL: + g_fpsScale = Normal; + break; + case EMUSPEED_FASTER: + IncreaseEmulationSpeed(); + break; + case EMUSPEED_FASTEST: + g_fpsScale = Fastest; + MaxSpeed = true; + break; + default: + return; + } + + RefreshThrottleFPS(); + + FCEU_DispMessage("Emulation speed %.1f%%",0, g_fpsScale*100.0); +} diff --git a/src/drivers/Qt/sdl-video.cpp b/src/drivers/Qt/sdl-video.cpp new file mode 100644 index 00000000..98f59009 --- /dev/null +++ b/src/drivers/Qt/sdl-video.cpp @@ -0,0 +1,464 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2002 Xodnizel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/// \file +/// \brief Handles the graphical game display for the SDL implementation. + +#include "sdl.h" +#include "gl_win.h" +#include "../common/vidblit.h" +#include "../../fceu.h" +#include "../../version.h" +#include "../../video.h" + +#include "../../utils/memory.h" + +//#include "sdl-icon.h" +#include "dface.h" + +#include "../common/configSys.h" +#include "sdl-video.h" +#include "fceuWrapper.h" + +#ifdef CREATE_AVI +#include "../videolog/nesvideos-piece.h" +#endif + +#include +#include +#include + +// GLOBALS +extern Config *g_config; + +// STATIC GLOBALS +static int s_curbpp = 0; +static int s_srendline, s_erendline; +static int s_tlines; +static int s_inited = 0; + +//#ifdef OPENGL +//static int s_useOpenGL = 0; +//#endif +static double s_exs = 1.0, s_eys = 1.0; +static int s_eefx = 0; +static int s_clipSides = 0; +static int s_fullscreen = 0; +static int noframe = 0; +static int initBlitToHighDone = 0; + +#define NWIDTH (256 - (s_clipSides ? 16 : 0)) +#define NOFFSET (s_clipSides ? 8 : 0) + +static int s_paletterefresh = 1; + +extern bool MaxSpeed; + +/** + * Attempts to destroy the graphical video display. Returns 0 on + * success, -1 on failure. + */ + +//draw input aids if we are fullscreen +bool FCEUD_ShouldDrawInputAids() +{ + return s_fullscreen!=0; +} + +int +KillVideo() +{ + //printf("Killing Video\n"); + + if ( gl_shm != NULL ) + { + gl_shm->clear_pixbuf(); + } + + //destroy_gui_video(); + + // return failure if the video system was not initialized + if (s_inited == 0) + return -1; + + // if the rest of the system has been initialized, shut it down +// // shut down the system that converts from 8 to 16/32 bpp +// if (s_curbpp > 8) +// { +// KillBlitToHigh(); +// } + + // SDL Video system is not used. + // shut down the SDL video sub-system + //SDL_QuitSubSystem(SDL_INIT_VIDEO); + + s_inited = 0; + return 0; +} + + +// this variable contains information about the special scaling filters +static int s_sponge = 0; + +/** + * These functions determine an appropriate scale factor for fullscreen/ + */ +inline double GetXScale(int xres) +{ + return ((double)xres) / NWIDTH; +} +inline double GetYScale(int yres) +{ + return ((double)yres) / s_tlines; +} +void FCEUD_VideoChanged() +{ + int buf; + g_config->getOption("SDL.PAL", &buf); + if(buf == 1) + PAL = 1; + else + PAL = 0; // NTSC and Dendy +} + +int InitVideo(FCEUGI *gi) +{ + int doublebuf, xstretch, ystretch, xres, yres, show_fps; + + FCEUI_printf("Initializing video..."); + + // load the relevant configuration variables + g_config->getOption("SDL.Fullscreen", &s_fullscreen); + g_config->getOption("SDL.DoubleBuffering", &doublebuf); +//#ifdef OPENGL +// g_config->getOption("SDL.OpenGL", &s_useOpenGL); +//#endif + //g_config->getOption("SDL.SpecialFilter", &s_sponge); + g_config->getOption("SDL.XStretch", &xstretch); + g_config->getOption("SDL.YStretch", &ystretch); + //g_config->getOption("SDL.LastXRes", &xres); + //g_config->getOption("SDL.LastYRes", &yres); + g_config->getOption("SDL.ClipSides", &s_clipSides); + g_config->getOption("SDL.NoFrame", &noframe); + g_config->getOption("SDL.ShowFPS", &show_fps); + //g_config->getOption("SDL.XScale", &s_exs); + //g_config->getOption("SDL.YScale", &s_eys); + uint32_t rmask, gmask, bmask; + + s_sponge = 0; + s_exs = 1.0; + s_eys = 1.0; + xres = gui_draw_area_width; + yres = gui_draw_area_height; + // check the starting, ending, and total scan lines + + FCEUI_GetCurrentVidSystem(&s_srendline, &s_erendline); + s_tlines = s_erendline - s_srendline + 1; + + //init_gui_video( s_useOpenGL ); + + s_inited = 1; + + // check to see if we are showing FPS + FCEUI_SetShowFPS(show_fps); + +#ifdef LSB_FIRST + rmask = 0x000000FF; + gmask = 0x0000FF00; + bmask = 0x00FF0000; +#else + rmask = 0x00FF0000; + gmask = 0x0000FF00; + bmask = 0x000000FF; +#endif + + s_curbpp = 32; // Bits per pixel is always 32 + + FCEU_printf(" Video Mode: %d x %d x %d bpp %s\n", + xres, yres, s_curbpp, + s_fullscreen ? "full screen" : ""); + + if (s_curbpp != 8 && s_curbpp != 16 && s_curbpp != 24 && s_curbpp != 32) + { + FCEU_printf(" Sorry, %dbpp modes are not supported by FCE Ultra. Supported bit depths are 8bpp, 16bpp, and 32bpp.\n", s_curbpp); + KillVideo(); + return -1; + } + +#ifdef OPENGL + if(s_exs <= 0.01) { + FCEUD_PrintError("xscale out of bounds."); + KillVideo(); + return -1; + } + if(s_eys <= 0.01) { + FCEUD_PrintError("yscale out of bounds."); + KillVideo(); + return -1; + } + //if(s_sponge && s_useOpenGL) { + // FCEUD_PrintError("scalers not compatible with openGL mode."); + // KillVideo(); + // return -1; + //} +#endif + + if ( !initBlitToHighDone ) + { + InitBlitToHigh(s_curbpp >> 3, + rmask, + gmask, + bmask, + s_eefx, s_sponge, 0); + + initBlitToHighDone = 1; + } + + return 0; +} + +/** + * Toggles the full-screen display. + */ +void ToggleFS(void) +{ + // pause while we we are making the switch + bool paused = FCEUI_EmulationPaused(); + if(!paused) + FCEUI_ToggleEmulationPause(); + + int error, fullscreen = s_fullscreen; + + // shut down the current video system + KillVideo(); + + // flip the fullscreen flag + g_config->setOption("SDL.Fullscreen", !fullscreen); +#ifdef _GTK + if(noGui == 0) + { + if(!fullscreen) + showGui(0); + else + showGui(1); + } +#endif + // try to initialize the video + error = InitVideo(GameInfo); + if(error) { + // if we fail, just continue with what worked before + g_config->setOption("SDL.Fullscreen", fullscreen); + InitVideo(GameInfo); + } + // if we paused to make the switch; unpause + if(!paused) + FCEUI_ToggleEmulationPause(); +} + +static SDL_Color s_psdl[256]; + +/** + * Sets the color for a particular index in the palette. + */ +void +FCEUD_SetPalette(uint8 index, + uint8 r, + uint8 g, + uint8 b) +{ + s_psdl[index].r = r; + s_psdl[index].g = g; + s_psdl[index].b = b; + + s_paletterefresh = 1; +} + +/** + * Gets the color for a particular index in the palette. + */ +void +FCEUD_GetPalette(uint8 index, + uint8 *r, + uint8 *g, + uint8 *b) +{ + *r = s_psdl[index].r; + *g = s_psdl[index].g; + *b = s_psdl[index].b; +} + +/** + * Pushes the palette structure into the underlying video subsystem. + */ +static void RedoPalette() +{ + if (s_curbpp > 8) + { + SetPaletteBlitToHigh((uint8*)s_psdl); + } +} +// XXX soules - console lock/unlock unimplemented? + +///Currently unimplemented. +void LockConsole(){} + +///Currently unimplemented. +void UnlockConsole(){} + +/** + * Pushes the given buffer of bits to the screen. + */ +void +BlitScreen(uint8 *XBuf) +{ + uint8 *dest; + int w, h, pitch; + + // refresh the palette if required + if (s_paletterefresh) + { + RedoPalette(); + s_paletterefresh = 0; + } + + // XXX soules - not entirely sure why this is being done yet + XBuf += s_srendline * 256; + + dest = (uint8*)gl_shm->pixbuf; + w = GL_NES_WIDTH; + h = GL_NES_HEIGHT; + pitch = w*4; + + gl_shm->ncol = NWIDTH; + gl_shm->nrow = s_tlines; + gl_shm->pitch = pitch; + + if ( dest == NULL ) return; + + Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines, pitch, 1, 1); + + //guiPixelBufferReDraw(); + +#ifdef CREATE_AVI + { int fps = FCEUI_GetDesiredFPS(); + static unsigned char* result = NULL; + static unsigned resultsize = 0; + int width = NWIDTH, height = s_tlines; + if(!result || resultsize != width*height*3*2) + { + if(result) free(result); + result = (unsigned char*) FCEU_dmalloc(resultsize = width*height*3*2); + } + switch(s_curbpp) + { + #if 0 + case 24: case 32: case 15: case 16: + /* Convert to I420 if possible, because our I420 conversion is optimized + * and it'll produce less network traffic, hence faster throughput than + * anything else. And H.264 eats only I420, so it'd be converted sooner + * or later anyway if we didn't do it. Win-win situation. + */ + switch(s_curbpp) + { + case 32: Convert32To_I420Frame(s_screen->pixels, &result[0], width*height, width); break; + case 24: Convert24To_I420Frame(s_screen->pixels, &result[0], width*height, width); break; + case 15: Convert15To_I420Frame(s_screen->pixels, &result[0], width*height, width); break; + case 16: Convert16To_I420Frame(s_screen->pixels, &result[0], width*height, width); break; + } + NESVideoLoggingVideo(&result[0], width,height, fps, 12); + break; + #endif + default: + NESVideoLoggingVideo( dest, width,height, fps, s_curbpp); + } + } +#endif // CREATE_AVI + +#if REALTIME_LOGGING + { + static struct timeval last_time; + static int first_time=1; + extern long soundrate; + + struct timeval cur_time; + gettimeofday(&cur_time, NULL); + + double timediff = + (cur_time.tv_sec *1e6 + cur_time.tv_usec + - (last_time.tv_sec *1e6 + last_time.tv_usec)) / 1e6; + + int nframes = timediff * 60 - 1; + if(first_time) + first_time = 0; + else while(nframes > 0) + { + static const unsigned char Buf[800*4] = {0}; + NESVideoLoggingVideo(screen->pixels, 256,tlines, FCEUI_GetDesiredFPS(), s_curbpp); + NESVideoLoggingAudio(Buf, soundrate,16,1, soundrate/60.0); + --nframes; + } + memcpy(&last_time, &cur_time, sizeof(last_time)); + } +#endif // REALTIME_LOGGING + +} + +/** + * Converts an x-y coordinate in the window manager into an x-y + * coordinate on FCEU's screen. + */ +uint32 +PtoV(uint16 x, + uint16 y) +{ + y = (uint16)((double)y / s_eys); + x = (uint16)((double)x / s_exs); + if(s_clipSides) { + x += 8; + } + y += s_srendline; + return (x | (y << 16)); +} + +bool enableHUDrecording = false; +bool FCEUI_AviEnableHUDrecording() +{ + if (enableHUDrecording) + return true; + + return false; +} +void FCEUI_SetAviEnableHUDrecording(bool enable) +{ + enableHUDrecording = enable; +} + +bool disableMovieMessages = false; +bool FCEUI_AviDisableMovieMessages() +{ + if (disableMovieMessages) + return true; + + return false; +} +void FCEUI_SetAviDisableMovieMessages(bool disable) +{ + disableMovieMessages = disable; +} diff --git a/src/drivers/Qt/sdl-video.h b/src/drivers/Qt/sdl-video.h new file mode 100644 index 00000000..82ac15f7 --- /dev/null +++ b/src/drivers/Qt/sdl-video.h @@ -0,0 +1,17 @@ +#ifndef __FCEU_SDL_VIDEO_H +#define __FCEU_SDL_VIDEO_H +#ifdef _SDL2 +#include +#else +#include +#endif + +uint32 PtoV(uint16 x, uint16 y); +bool FCEUD_ShouldDrawInputAids(); +bool FCEUI_AviDisableMovieMessages(); +bool FCEUI_AviEnableHUDrecording(); +void FCEUI_SetAviEnableHUDrecording(bool enable); +bool FCEUI_AviDisableMovieMessages(); +void FCEUI_SetAviDisableMovieMessages(bool disable); +#endif + diff --git a/src/drivers/Qt/sdl.h b/src/drivers/Qt/sdl.h new file mode 100644 index 00000000..91c6414d --- /dev/null +++ b/src/drivers/Qt/sdl.h @@ -0,0 +1,32 @@ +#ifndef __FCEU_SDL_H +#define __FCEU_SDL_H + +#if _SDL2 +#include +#else +#include +#endif + +#include "main.h" +#include "dface.h" +#include "input.h" + +// I'm using this as a #define so the compiler can optimize the +// modulo operation +#define PERIODIC_SAVE_INTERVAL 5000 // milliseconds + +const int INVALID_STATE = 99; + +extern int noGui; +extern int isloaded; + +extern int dendy; +extern int pal_emulation; +extern bool swapDuty; + +int LoadGame(const char *path); +int CloseGame(void); +void FCEUD_Update(uint8 *XBuf, int32 *Buffer, int Count); +uint64 FCEUD_GetTime(); + +#endif diff --git a/src/drivers/Qt/throttle.h b/src/drivers/Qt/throttle.h new file mode 100644 index 00000000..5709c88a --- /dev/null +++ b/src/drivers/Qt/throttle.h @@ -0,0 +1,2 @@ +void RefreshThrottleFPS(); +int SpeedThrottle(void); diff --git a/src/drivers/Qt/unix-netplay.cpp b/src/drivers/Qt/unix-netplay.cpp new file mode 100644 index 00000000..37fcba12 --- /dev/null +++ b/src/drivers/Qt/unix-netplay.cpp @@ -0,0 +1,366 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2002 Xodnizel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +//todo - ensure that #ifdef WIN32 makes sense +//consider changing this to use sdl net stuff? + +//#include "main.h" +//#include "input.h" +//#include "dface.h" +#include "unix-netplay.h" + +#include "../../fceu.h" +#include "../../driver.h" +#include "../../utils/md5.h" +#include "../../utils/memory.h" + +#include +#include "../common/configSys.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef WIN32 +#include +#else +#include +#include +#include +#include +#include +#include +#endif + +extern Config *g_config; + +#ifndef socklen_t +#define socklen_t int +#endif + +#ifndef SOL_TCP +#define SOL_TCP IPPROTO_TCP +#endif + +int FCEUDnetplay=0; + +static int s_Socket = -1; + +static void +en32(uint8 *buf, + uint32 morp) +{ + buf[0] = morp; + buf[1] = morp >> 8; + buf[2] = morp >> 16; + buf[3] = morp >> 24; +} + +/* +static uint32 de32(uint8 *morp) +{ + return(morp[0]|(morp[1]<<8)|(morp[2]<<16)|(morp[3]<<24)); +} +*/ + +int +FCEUD_NetworkConnect(void) +{ + struct sockaddr_in sockin; + struct hostent *phostentb; + unsigned long hadr; + int TSocket, tcpopt, error; + int netdivisor; + + // get any required configuration variables + int port, localPlayers; + std::string server, username, password, key; + g_config->getOption("SDL.NetworkIP", &server); + g_config->getOption("SDL.NetworkUsername", &username); + g_config->getOption("SDL.NetworkPassword", &password); + g_config->getOption("SDL.NetworkGameKey", &key); + g_config->getOption("SDL.NetworkPort", &port); + g_config->getOption("SDL.NetworkPlayers", &localPlayers); + + + g_config->setOption("SDL.NetworkIP", ""); + g_config->setOption("SDL.NetworkPassword", ""); + g_config->setOption("SDL.NetworkGameKey", ""); + + + + // only initialize if remote server is specified + if(!server.size()) { + return 0; + } + + TSocket = socket(AF_INET, SOCK_STREAM, 0); + if(TSocket < 0) { + const char* s = "Error creating stream socket."; + puts(s); + FCEU_DispMessage(s,0); + FCEUD_NetworkClose(); + return 0; + } + + // try to setup TCP_NODELAY to avoid network jitters + tcpopt = 1; +#ifdef BEOS + error = setsockopt(TSocket, SOL_SOCKET, TCP_NODELAY, &tcpopt, sizeof(int)); +#elif WIN32 + error = setsockopt(TSocket, SOL_TCP, TCP_NODELAY, + (char*)&tcpopt, sizeof(int)); +#else + error = setsockopt(TSocket, SOL_TCP, TCP_NODELAY, &tcpopt, sizeof(int)); +#endif + if(error) { + puts("Nodelay fail"); + } + + memset(&sockin, 0, sizeof(sockin)); + sockin.sin_family = AF_INET; + hadr = inet_addr(server.c_str()); + if(hadr != INADDR_NONE) { + sockin.sin_addr.s_addr = hadr; + } else { + puts("*** Looking up host name..."); + phostentb = gethostbyname(server.c_str()); + if(!phostentb) { + puts("Error getting host network information."); + FCEU_DispMessage("Error getting host info",0); + close(TSocket); + FCEUD_NetworkClose(); + return(0); + } + memcpy(&sockin.sin_addr, phostentb->h_addr, phostentb->h_length); + } + + sockin.sin_port = htons(port); + puts("*** Connecting to remote host..."); + error = connect(TSocket, (struct sockaddr *)&sockin, sizeof(sockin)); + if(error < 0) { + puts("Error connecting to remote host."); + FCEU_DispMessage("Error connecting to server",0); + close(TSocket); + FCEUD_NetworkClose(); + return 0; + } + + s_Socket = TSocket; + + puts("*** Sending initialization data to server..."); + uint8 *sendbuf; + uint8 buf[5]; + uint32 sblen; + + sblen = 4 + 16 + 16 + 64 + 1 + username.size(); + sendbuf = (uint8 *)FCEU_dmalloc(sblen); + memset(sendbuf, 0, sblen); + + // XXX soules - should use htons instead of en32() from above! + //uint32 data = htons(sblen - 4); + //memcpy(sendbuf, &data, sizeof(data)); + en32(sendbuf, sblen - 4); + + if(key.size()) + { + struct md5_context md5; + uint8 md5out[16]; + + md5_starts(&md5); + md5_update(&md5, (uint8*)&GameInfo->MD5.data, 16); + md5_update(&md5, (uint8 *)key.c_str(), key.size()); + md5_finish(&md5, md5out); + memcpy(sendbuf + 4, md5out, 16); + } else + { + memcpy(sendbuf + 4, (uint8*)&GameInfo->MD5.data, 16); + } + + if(password.size()) { + struct md5_context md5; + uint8 md5out[16]; + + md5_starts(&md5); + md5_update(&md5, (uint8 *)password.c_str(), password.size()); + md5_finish(&md5, md5out); + memcpy(sendbuf + 4 + 16, md5out, 16); + } + + memset(sendbuf + 4 + 16 + 16, 0, 64); + + sendbuf[4 + 16 + 16 + 64] = (uint8)localPlayers; + + if(username.size()) { + memcpy(sendbuf + 4 + 16 + 16 + 64 + 1, + username.c_str(), username.size()); + } + +#ifdef WIN32 + send(s_Socket, (char*)sendbuf, sblen, 0); +#else + send(s_Socket, sendbuf, sblen, 0); +#endif + FCEU_dfree(sendbuf); + +#ifdef WIN32 + recv(s_Socket, (char*)buf, 1, 0); +#else + recv(s_Socket, buf, 1, MSG_WAITALL); +#endif + netdivisor = buf[0]; + + puts("*** Connection established."); + FCEU_DispMessage("Connection established.",0); + + FCEUDnetplay = 1; + FCEUI_NetplayStart(localPlayers, netdivisor); + + return 1; +} + + +int +FCEUD_SendData(void *data, + uint32 len) +{ + int check = 0, error = 0; +#ifndef WIN32 + error = ioctl(fileno(stdin), FIONREAD, &check); +#endif + if(!error && check) { + char buf[1024]; + char *f; + + buf[0] = 0; + + if ( fgets(buf, 1024, stdin) ) + { + if((f=strrchr(buf,'\n'))) { + *f = 0; + } + } + FCEUI_NetplayText((uint8 *)buf); + } + +#ifdef WIN32 + send(s_Socket, (char*)data, len ,0); +#else + send(s_Socket, data, len ,0); +#endif + return 1; +} + +int +FCEUD_RecvData(void *data, + uint32 len) +{ + int size; + //NoWaiting &= ~2; + + for(;;) + { + fd_set funfun; + struct timeval popeye; + + popeye.tv_sec=0; + popeye.tv_usec=100000; + + FD_ZERO(&funfun); + FD_SET(s_Socket, &funfun); + + switch(select(s_Socket + 1,&funfun,0,0,&popeye)) { + case 0: continue; + case -1:return 0; + } + + if(FD_ISSET(s_Socket,&funfun)) { +#ifdef WIN32 + size = recv(s_Socket, (char*)data, len, 0); +#else + size = recv(s_Socket, data, len, MSG_WAITALL); +#endif + + if(size == len) { + //unsigned long beefie; + + FD_ZERO(&funfun); + FD_SET(s_Socket, &funfun); + + popeye.tv_sec = popeye.tv_usec = 0; + if(select(s_Socket + 1, &funfun, 0, 0, &popeye) == 1) + //if(!ioctl(s_Socket,FIONREAD,&beefie)) + // if(beefie) + { + //NoWaiting|=2; + } + return 1; + } else { + return 0; + } + } + } + + return 0; +} + +void +FCEUD_NetworkClose(void) +{ + if(s_Socket > 0) { +#ifdef BEOS + closesocket(s_Socket); +#else + close(s_Socket); +#endif + } + s_Socket = -1; + + if(FCEUDnetplay) { + FCEUI_NetplayStop(); + } + FCEUDnetplay = 0; +} + + +void +FCEUD_NetplayText(uint8 *text) +{ + char *tot = (char *)FCEU_dmalloc(strlen((const char *)text) + 1); + char *tmp; + if (!tot) + return; + strcpy(tot, (const char *)text); + tmp = tot; + + while(*tmp) { + if(*tmp < 0x20) { + *tmp = ' '; + } + tmp++; + } + puts(tot); + FCEU_dfree(tot); +} diff --git a/src/drivers/Qt/unix-netplay.h b/src/drivers/Qt/unix-netplay.h new file mode 100644 index 00000000..27b1de43 --- /dev/null +++ b/src/drivers/Qt/unix-netplay.h @@ -0,0 +1,6 @@ +extern char *netplaynick; +extern char *netplayhost; +extern char *netpassword; +extern char *netgamekey; +extern int tport; +extern int netlocalplayers; diff --git a/src/fceux.pro b/src/fceux.pro new file mode 100644 index 00000000..24cf00c0 --- /dev/null +++ b/src/fceux.pro @@ -0,0 +1,305 @@ +###################################################################### +# Automatically generated by qmake (3.1) Sat Jun 20 21:20:47 2020 +###################################################################### + +TEMPLATE = app +TARGET = fceux +INCLUDEPATH += . + +# The following define makes your compiler warn you if you use any +# feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +QT += widgets + +CONFIG += object_parallel_to_source + +unix { + QT_CONFIG -= no-pkg-config + CONFIG += link_pkgconfig + + QMAKE_CXXFLAGS += -DPSS_STYLE=1 -DHAVE_ASPRINTF + + packagesExist(minizip){ + PKGCONFIG += minizip + QMAKE_CXXFLAGS += -D_SYSTEM_MINIZIP + } + + packagesExist(zlib){ + PKGCONFIG += zlib + } + + PKGCONFIG += sdl2 + + packagesExist(lua-5.1){ + PKGCONFIG += lua-5.1 + QMAKE_CXXFLAGS += -D_S9XLUA_H + } + + QMAKE_CXXFLAGS += -Wall -Wno-write-strings -Wno-sign-compare -Wno-parentheses -Wno-unused-local-typedefs +} + +# Input +SOURCES += asm.cpp +SOURCES += cart.cpp +SOURCES += cheat.cpp +SOURCES += conddebug.cpp +SOURCES += config.cpp +SOURCES += debug.cpp +SOURCES += drawing.cpp +SOURCES += fceu.cpp +SOURCES += fds.cpp +SOURCES += file.cpp +SOURCES += emufile.cpp +SOURCES += filter.cpp +SOURCES += ines.cpp +SOURCES += input.cpp +SOURCES += movie.cpp +SOURCES += netplay.cpp +SOURCES += nsf.cpp +SOURCES += oldmovie.cpp +SOURCES += palette.cpp +SOURCES += ppu.cpp +SOURCES += sound.cpp +SOURCES += state.cpp +SOURCES += unif.cpp +SOURCES += video.cpp +SOURCES += vsuni.cpp +SOURCES += wave.cpp +SOURCES += x6502.cpp + +unix { + packagesExist(lua-5.1){ + SOURCES += lua-engine.cpp + } +} +SOURCES += boards/01-222.cpp +SOURCES += boards/09-034a.cpp +SOURCES += boards/103.cpp +SOURCES += boards/106.cpp +SOURCES += boards/108.cpp +SOURCES += boards/112.cpp +SOURCES += boards/116.cpp +SOURCES += boards/117.cpp +SOURCES += boards/120.cpp +SOURCES += boards/121.cpp +SOURCES += boards/12in1.cpp +SOURCES += boards/151.cpp +SOURCES += boards/156.cpp +SOURCES += boards/158B.cpp +SOURCES += boards/15.cpp +SOURCES += boards/164.cpp +SOURCES += boards/168.cpp +SOURCES += boards/170.cpp +SOURCES += boards/175.cpp +SOURCES += boards/176.cpp +SOURCES += boards/177.cpp +SOURCES += boards/178.cpp +SOURCES += boards/183.cpp +SOURCES += boards/185.cpp +SOURCES += boards/186.cpp +SOURCES += boards/187.cpp +SOURCES += boards/189.cpp +SOURCES += boards/18.cpp +SOURCES += boards/190.cpp +SOURCES += boards/193.cpp +SOURCES += boards/199.cpp +SOURCES += boards/206.cpp +SOURCES += boards/208.cpp +SOURCES += boards/222.cpp +SOURCES += boards/225.cpp +SOURCES += boards/228.cpp +SOURCES += boards/230.cpp +SOURCES += boards/232.cpp +SOURCES += boards/234.cpp +SOURCES += boards/235.cpp +SOURCES += boards/244.cpp +SOURCES += boards/246.cpp +SOURCES += boards/252.cpp +SOURCES += boards/253.cpp +SOURCES += boards/28.cpp +SOURCES += boards/32.cpp +SOURCES += boards/33.cpp +SOURCES += boards/34.cpp +SOURCES += boards/36.cpp +SOURCES += boards/3d-block.cpp +SOURCES += boards/40.cpp +SOURCES += boards/411120-c.cpp +SOURCES += boards/41.cpp +SOURCES += boards/42.cpp +SOURCES += boards/43.cpp +SOURCES += boards/46.cpp +SOURCES += boards/50.cpp +SOURCES += boards/51.cpp +SOURCES += boards/57.cpp +SOURCES += boards/603-5052.cpp +SOURCES += boards/62.cpp +SOURCES += boards/65.cpp +SOURCES += boards/67.cpp +SOURCES += boards/68.cpp +SOURCES += boards/69.cpp +SOURCES += boards/71.cpp +SOURCES += boards/72.cpp +SOURCES += boards/77.cpp +SOURCES += boards/79.cpp +SOURCES += boards/80013-B.cpp +SOURCES += boards/80.cpp +SOURCES += boards/8157.cpp +SOURCES += boards/8237.cpp +SOURCES += boards/82.cpp +SOURCES += boards/830118C.cpp +SOURCES += boards/88.cpp +SOURCES += boards/8in1.cpp +SOURCES += boards/90.cpp +SOURCES += boards/91.cpp +SOURCES += boards/96.cpp +SOURCES += boards/99.cpp +SOURCES += boards/a9746.cpp +SOURCES += boards/ac-08.cpp +SOURCES += boards/addrlatch.cpp +SOURCES += boards/ax5705.cpp +SOURCES += boards/bandai.cpp +SOURCES += boards/bb.cpp +SOURCES += boards/bmc13in1jy110.cpp +SOURCES += boards/bmc42in1r.cpp +SOURCES += boards/bmc64in1nr.cpp +SOURCES += boards/bmc70in1.cpp +SOURCES += boards/BMW8544.cpp +SOURCES += boards/bonza.cpp +SOURCES += boards/bs-5.cpp +SOURCES += boards/cheapocabra.cpp +SOURCES += boards/cityfighter.cpp +SOURCES += boards/coolboy.cpp +SOURCES += boards/dance2000.cpp +SOURCES += boards/datalatch.cpp +SOURCES += boards/dream.cpp +SOURCES += boards/__dummy_mapper.cpp +SOURCES += boards/edu2000.cpp +SOURCES += boards/eh8813a.cpp +SOURCES += boards/emu2413.c +SOURCES += boards/et-100.cpp +SOURCES += boards/et-4320.cpp +SOURCES += boards/F-15.cpp +SOURCES += boards/famicombox.cpp +SOURCES += boards/ffe.cpp +SOURCES += boards/fk23c.cpp +SOURCES += boards/fns.cpp +SOURCES += boards/ghostbusters63in1.cpp +SOURCES += boards/gs-2004.cpp +SOURCES += boards/gs-2013.cpp +SOURCES += boards/h2288.cpp +SOURCES += boards/hp10xx_hp20xx.cpp +SOURCES += boards/hp898f.cpp +SOURCES += boards/inlnsf.cpp +SOURCES += boards/karaoke.cpp +SOURCES += boards/kof97.cpp +SOURCES += boards/ks7010.cpp +SOURCES += boards/ks7012.cpp +SOURCES += boards/ks7013.cpp +SOURCES += boards/ks7016.cpp +SOURCES += boards/ks7017.cpp +SOURCES += boards/ks7030.cpp +SOURCES += boards/ks7031.cpp +SOURCES += boards/ks7032.cpp +SOURCES += boards/ks7037.cpp +SOURCES += boards/ks7057.cpp +SOURCES += boards/le05.cpp +SOURCES += boards/lh32.cpp +SOURCES += boards/lh53.cpp +SOURCES += boards/malee.cpp +SOURCES += boards/mihunche.cpp +SOURCES += boards/mmc1.cpp +SOURCES += boards/mmc2and4.cpp +SOURCES += boards/mmc3.cpp +SOURCES += boards/mmc5.cpp +SOURCES += boards/n106.cpp +SOURCES += boards/n625092.cpp +SOURCES += boards/novel.cpp +SOURCES += boards/onebus.cpp +SOURCES += boards/pec-586.cpp +SOURCES += boards/rt-01.cpp +SOURCES += boards/sa-9602b.cpp +SOURCES += boards/sachen.cpp +SOURCES += boards/sb-2000.cpp +SOURCES += boards/sc-127.cpp +SOURCES += boards/sheroes.cpp +SOURCES += boards/sl1632.cpp +SOURCES += boards/subor.cpp +SOURCES += boards/super24.cpp +SOURCES += boards/supervision.cpp +SOURCES += boards/t-227-1.cpp +SOURCES += boards/t-262.cpp +SOURCES += boards/tengen.cpp +SOURCES += boards/tf-1201.cpp +SOURCES += boards/transformer.cpp +SOURCES += boards/unrom512.cpp +SOURCES += boards/vrc1.cpp +SOURCES += boards/vrc2and4.cpp +SOURCES += boards/vrc3.cpp +SOURCES += boards/vrc5.cpp +SOURCES += boards/vrc6.cpp +SOURCES += boards/vrc7.cpp +SOURCES += boards/vrc7p.cpp +SOURCES += boards/yoko.cpp +SOURCES += input/arkanoid.cpp +SOURCES += input/bworld.cpp +SOURCES += input/cursor.cpp +SOURCES += input/fkb.cpp +SOURCES += input/fns.cpp +SOURCES += input/ftrainer.cpp +SOURCES += input/hypershot.cpp +SOURCES += input/mahjong.cpp +SOURCES += input/mouse.cpp +SOURCES += input/oekakids.cpp +SOURCES += input/pec586kb.cpp +SOURCES += input/powerpad.cpp +SOURCES += input/quiz.cpp +SOURCES += input/shadow.cpp +SOURCES += input/snesmouse.cpp +SOURCES += input/suborkb.cpp +SOURCES += input/toprider.cpp +SOURCES += input/virtualboy.cpp +SOURCES += input/zapper.cpp +SOURCES += utils/backward.cpp +SOURCES += utils/ConvertUTF.c +SOURCES += utils/xstring.cpp +SOURCES += utils/crc32.cpp +SOURCES += utils/endian.cpp +SOURCES += utils/general.cpp +SOURCES += utils/guid.cpp +SOURCES += utils/md5.cpp +SOURCES += utils/memory.cpp +SOURCES += drivers/common/args.cpp +SOURCES += drivers/common/cheat.cpp +SOURCES += drivers/common/config.cpp +SOURCES += drivers/common/configSys.cpp +SOURCES += drivers/common/hq2x.cpp +SOURCES += drivers/common/hq3x.cpp +SOURCES += drivers/common/scale2x.cpp +SOURCES += drivers/common/scale3x.cpp +SOURCES += drivers/common/scalebit.cpp +SOURCES += drivers/common/vidblit.cpp +SOURCES += drivers/common/nes_ntsc.c + +HEADERS += drivers/Qt/GameApp.h +HEADERS += drivers/Qt/GameViewer.h +SOURCES += drivers/Qt/main.cpp +SOURCES += drivers/Qt/GameApp.cpp +SOURCES += drivers/Qt/GameViewer.cpp +SOURCES += drivers/Qt/fceuWrapper.cpp +SOURCES += drivers/Qt/config.cpp +SOURCES += drivers/Qt/input.cpp +SOURCES += drivers/Qt/gl_win.cpp +SOURCES += drivers/Qt/sdl-sound.cpp +SOURCES += drivers/Qt/sdl-video.cpp +SOURCES += drivers/Qt/sdl-joystick.cpp +SOURCES += drivers/Qt/sdl-throttle.cpp +SOURCES += drivers/Qt/unix-netplay.cpp + From 0352483a19b63eac78db0525f695a01b4bfaa041 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Tue, 23 Jun 2020 22:51:10 -0400 Subject: [PATCH 010/100] Successful display of video in QT gui. --- src/drivers/Qt/GameApp.cpp | 5 +- src/drivers/Qt/GameViewer.cpp | 158 ++++++++++- src/drivers/Qt/GameViewer.h | 4 + src/drivers/Qt/fceuWrapper.cpp | 505 +++++++++++++++++++++++++++++++++ src/drivers/Qt/fceuWrapper.h | 5 + src/drivers/Qt/main.cpp | 5 +- src/drivers/Qt/sdl-video.cpp | 28 +- src/fceux.pro | 4 +- 8 files changed, 697 insertions(+), 17 deletions(-) diff --git a/src/drivers/Qt/GameApp.cpp b/src/drivers/Qt/GameApp.cpp index de15835f..8602a26d 100644 --- a/src/drivers/Qt/GameApp.cpp +++ b/src/drivers/Qt/GameApp.cpp @@ -1,6 +1,7 @@ // GameApp.cpp // #include "GameApp.h" +#include "fceuWrapper.h" gameWin_t::gameWin_t(QWidget *parent) : QMainWindow( parent ) @@ -81,7 +82,9 @@ void gameWin_t::runGameFrame(void) t = (double)ts.tv_sec + (double)(ts.tv_nsec * 1.0e-9); //printf("Run Frame %f\n", t); - // + + fceuWrapperUpdate(); + viewport->repaint(); return; diff --git a/src/drivers/Qt/GameViewer.cpp b/src/drivers/Qt/GameViewer.cpp index ef32e331..718cd743 100644 --- a/src/drivers/Qt/GameViewer.cpp +++ b/src/drivers/Qt/GameViewer.cpp @@ -1,13 +1,39 @@ // GameViewer.cpp // +#include +#include +#include #include +#include "gl_win.h" #include "GameViewer.h" +extern unsigned int gui_draw_area_width; +extern unsigned int gui_draw_area_height; + gameView_t::gameView_t(QWidget *parent) : QOpenGLWidget( parent ) { + view_width = 0; + view_height = 0; + gltexture = 0; + QSurfaceFormat fmt = QSurfaceFormat::defaultFormat(); + + fmt.setRedBufferSize(8); + fmt.setGreenBufferSize(8); + fmt.setBlueBufferSize(8); + fmt.setAlphaBufferSize(8); + fmt.setDepthBufferSize( 24 ); + setTextureFormat(GL_RGBA8); + + printf("R: %i \n", fmt.redBufferSize() ); + printf("G: %i \n", fmt.greenBufferSize() ); + printf("B: %i \n", fmt.blueBufferSize() ); + printf("A: %i \n", fmt.alphaBufferSize() ); + printf("SW: %i \n", fmt.swapBehavior() ); + + setFormat( fmt ); } gameView_t::~gameView_t(void) @@ -17,18 +43,45 @@ gameView_t::~gameView_t(void) makeCurrent(); // Free GL texture + if (gltexture) + { + printf("Destroying GLX Texture\n"); + glDeleteTextures(1, &gltexture); + gltexture=0; + } doneCurrent(); } void gameView_t::initializeGL(void) { + int ipolate = 0; + initializeOpenGLFunctions(); // Set up the rendering context, load shaders and other resources, etc.: //QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions(); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); printf("GL Init!\n"); + + glEnable(GL_TEXTURE_2D); + + if ( gltexture ) + { + printf("GL Texture already exists\n"); + } + else + { + glGenTextures(1, &gltexture); + } + printf("Linear Interpolation on GL Texture: %s \n", ipolate ? "Enabled" : "Disabled"); + + glBindTexture(GL_TEXTURE_2D, gltexture); + + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,ipolate?GL_LINEAR:GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,ipolate?GL_LINEAR:GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP); } void gameView_t::resizeGL(int w, int h) @@ -36,29 +89,108 @@ void gameView_t::resizeGL(int w, int h) printf("GL Resize: %i x %i \n", w, h ); glViewport(0, 0, w, h); + view_width = w; + view_height = h; + + gui_draw_area_width = w; + gui_draw_area_height = h; } void gameView_t::paintGL(void) { - float x1, y1, x2, y2; + int l=0, r=gl_shm->ncol; + int t=0, b=gl_shm->nrow; - angle += (2.0 * 3.14 * 0.01); - - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + float xscale = (float)view_width / (float)gl_shm->ncol; + float yscale = (float)view_height / (float)gl_shm->nrow; - x1 = cos( angle ); - y1 = sin( angle ); + if (xscale < yscale ) + { + yscale = xscale; + } + else + { + xscale = yscale; + } + int rw=(int)((r-l)*xscale); + int rh=(int)((b-t)*yscale); + int sx=(view_width-rw)/2; + int sy=(view_height-rh)/2; - x2 = -x1; - y2 = -y1; + glViewport(sx, sy, rw, rh); + //glViewport( 0, 0, screen_width, screen_height); - glColor4f( 1.0, 1.0, 1.0, 1.0 ); - glLineWidth(5.0); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0); - glBegin(GL_LINES); - glVertex2f( x1, y1 ); - glVertex2f( x2, y2 ); + glDisable(GL_DEPTH_TEST); + glClearColor( 0.0, 0.0f, 0.0f, 0.0f); // Background color to black. + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_LINE_SMOOTH); + glEnable(GL_TEXTURE_2D); + //glBindTexture(GL_TEXTURE_2D, gltexture); + glBindTexture(GL_TEXTURE_2D, gltexture); + + //print_pixbuf(); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, + GL_RGBA, GL_UNSIGNED_BYTE, gl_shm->pixbuf ); + + glBegin(GL_QUADS); + glTexCoord2f(1.0f*l/256, 1.0f*b/256); // Bottom left of picture. + glVertex2f(-1.0f, -1.0f); // Bottom left of target. + + glTexCoord2f(1.0f*r/256, 1.0f*b/256);// Bottom right of picture. + glVertex2f( 1.0f, -1.0f); // Bottom right of target. + + glTexCoord2f(1.0f*r/256, 1.0f*t/256); // Top right of our picture. + glVertex2f( 1.0f, 1.0f); // Top right of target. + + glTexCoord2f(1.0f*l/256, 1.0f*t/256); // Top left of our picture. + glVertex2f(-1.0f, 1.0f); // Top left of target. glEnd(); + glDisable(GL_TEXTURE_2D); + + //glColor4f( 1.0, 1.0, 1.0, 1.0 ); + //glLineWidth(5.0); + //glBegin(GL_LINES); + //glVertex2f(-1.0f, -1.0f); // Bottom left of target. + //glVertex2f( 1.0f, 1.0f); // Top right of target. + //glEnd(); + + context()->swapBuffers( context()->surface() ); + //if ( double_buffer_ena ) + //{ + // glXSwapBuffers( dpy, win ); + //} + //else + //{ + // glFlush(); + //} + glFlush(); + + //float x1, y1, x2, y2; + + //angle += (2.0 * 3.14 * 0.01); + // + //glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + + //x1 = cos( angle ); + //y1 = sin( angle ); + + //x2 = -x1; + //y2 = -y1; + + //glColor4f( 1.0, 1.0, 1.0, 1.0 ); + //glLineWidth(5.0); + + //glBegin(GL_LINES); + // glVertex2f( x1, y1 ); + // glVertex2f( x2, y2 ); + //glEnd(); + //printf("Paint GL!\n"); } diff --git a/src/drivers/Qt/GameViewer.h b/src/drivers/Qt/GameViewer.h index 655eb9de..edc0524a 100644 --- a/src/drivers/Qt/GameViewer.h +++ b/src/drivers/Qt/GameViewer.h @@ -21,6 +21,10 @@ class gameView_t : public QOpenGLWidget, protected QOpenGLFunctions void resizeGL(int w, int h); void paintGL(void); + int view_width; + int view_height; + GLuint gltexture; + private slots: }; diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp index 61d7812b..c8402f7c 100644 --- a/src/drivers/Qt/fceuWrapper.cpp +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -2,6 +2,7 @@ // #include #include +#include #include "main.h" #include "throttle.h" @@ -9,7 +10,9 @@ #include "dface.h" #include "fceuWrapper.h" #include "input.h" +#include "sdl.h" #include "sdl-video.h" +#include "gl_win.h" #include "unix-netplay.h" #include "../common/cheat.h" @@ -50,7 +53,10 @@ Config *g_config = NULL; static int inited = 0; static int noconfig=0; +static int frameskip=0; +static int periodic_saves = 0; +extern double g_fpsScale; //***************************************************************** // Define Global Functions to be shared with FCEU Core //***************************************************************** @@ -270,6 +276,505 @@ CloseGame(void) return(1); } +int fceuWrapperInit( int argc, char *argv[] ) +{ + int error; + + FCEUD_Message("Starting " FCEU_NAME_AND_VERSION "...\n"); + + // Initialize the configuration system + g_config = InitConfig(); + + if ( !g_config ) + { + printf("Error: Could not initialize configuration system\n"); + exit(-1); + } + + // initialize the infrastructure + error = FCEUI_Initialize(); + + if (error != 1) + { + printf("Error: Initializing FCEUI\n"); + //ShowUsage(argv[0]); + //SDL_Quit(); + return -1; + } + + int romIndex = g_config->parse(argc, argv); + + // This is here so that a default fceux.cfg will be created on first + // run, even without a valid ROM to play. + // Unless, of course, there's actually --no-config given + // mbg 8/23/2008 - this is also here so that the inputcfg routines can have + // a chance to dump the new inputcfg to the fceux.cfg in case you didnt + // specify a rom filename + g_config->getOption("SDL.NoConfig", &noconfig); + + if (!noconfig) + { + g_config->save(); + } + + std::string s; + + g_config->getOption("SDL.InputCfg", &s); + + if (s.size() != 0) + { + InitVideo(GameInfo); + InputCfg(s); + } + + // update the input devices + UpdateInput(g_config); + + // check for a .fcm file to convert to .fm2 + g_config->getOption ("SDL.FCMConvert", &s); + g_config->setOption ("SDL.FCMConvert", ""); + if (!s.empty()) + { + int okcount = 0; + std::string infname = s.c_str(); + // produce output filename + std::string outname; + size_t dot = infname.find_last_of ("."); + if (dot == std::string::npos) + outname = infname + ".fm2"; + else + outname = infname.substr(0,dot) + ".fm2"; + + MovieData md; + EFCM_CONVERTRESULT result = convert_fcm (md, infname); + + if (result == FCM_CONVERTRESULT_SUCCESS) { + okcount++; + // *outf = new EMUFILE; + EMUFILE_FILE* outf = FCEUD_UTF8_fstream (outname, "wb"); + md.dump (outf,false); + delete outf; + FCEUD_Message ("Your file has been converted to FM2.\n"); + } + else { + FCEUD_Message ("Something went wrong while converting your file...\n"); + } + + DriverKill(); + SDL_Quit(); + return 0; + } + // If x/y res set to 0, store current display res in SDL.LastX/YRes + int yres, xres; + g_config->getOption("SDL.XResolution", &xres); + g_config->getOption("SDL.YResolution", &yres); + + int autoResume; + g_config->getOption("SDL.AutoResume", &autoResume); + if(autoResume) + { + AutoResumePlay = true; + } + else + { + AutoResumePlay = false; + } + + // check to see if recording HUD to AVI is enabled + int rh; + g_config->getOption("SDL.RecordHUD", &rh); + if( rh == 0) + FCEUI_SetAviEnableHUDrecording(true); + else + FCEUI_SetAviEnableHUDrecording(false); + + // check to see if movie messages are disabled + int mm; + g_config->getOption("SDL.MovieMsg", &mm); + if( mm == 0) + FCEUI_SetAviDisableMovieMessages(true); + else + FCEUI_SetAviDisableMovieMessages(false); + + // check for a .fm2 file to rip the subtitles + g_config->getOption("SDL.RipSubs", &s); + g_config->setOption("SDL.RipSubs", ""); + if (!s.empty()) + { + MovieData md; + std::string infname; + infname = s.c_str(); + FCEUFILE *fp = FCEU_fopen(s.c_str(), 0, "rb", 0); + + // load the movie and and subtitles + extern bool LoadFM2(MovieData&, EMUFILE*, int, bool); + LoadFM2(md, fp->stream, INT_MAX, false); + LoadSubtitles(md); // fill subtitleFrames and subtitleMessages + delete fp; + + // produce .srt file's name and open it for writing + std::string outname; + size_t dot = infname.find_last_of ("."); + if (dot == std::string::npos) + outname = infname + ".srt"; + else + outname = infname.substr(0,dot) + ".srt"; + FILE *srtfile; + srtfile = fopen(outname.c_str(), "w"); + + if (srtfile != NULL) + { + extern std::vector subtitleFrames; + extern std::vector subtitleMessages; + float fps = (md.palFlag == 0 ? 60.0988 : 50.0069); // NTSC vs PAL + float subduration = 3; // seconds for the subtitles to be displayed + for (int i = 0; i < subtitleFrames.size(); i++) + { + fprintf(srtfile, "%i\n", i+1); // starts with 1, not 0 + double seconds, ms, endseconds, endms; + seconds = subtitleFrames[i]/fps; + if (i+1 < subtitleFrames.size()) // there's another subtitle coming after this one + { + if (subtitleFrames[i+1]-subtitleFrames[i] < subduration*fps) // avoid two subtitles at the same time + { + endseconds = (subtitleFrames[i+1]-1)/fps; // frame x: subtitle1; frame x+1 subtitle2 + } else { + endseconds = seconds+subduration; + } + } else { + endseconds = seconds+subduration; + } + ms = modf(seconds, &seconds); + endms = modf(endseconds, &endseconds); + // this is just beyond ugly, don't show it to your kids + fprintf(srtfile, + "%02.0f:%02d:%02d,%03d --> %02.0f:%02d:%02d,%03d\n", // hh:mm:ss,ms --> hh:mm:ss,ms + floor(seconds/3600), (int)floor(seconds/60 ) % 60, (int)floor(seconds) % 60, (int)(ms*1000), + floor(endseconds/3600), (int)floor(endseconds/60) % 60, (int)floor(endseconds) % 60, (int)(endms*1000)); + fprintf(srtfile, "%s\n\n", subtitleMessages[i].c_str()); // new line for every subtitle + } + fclose(srtfile); + printf("%d subtitles have been ripped.\n", (int)subtitleFrames.size()); + } else { + FCEUD_Message("Couldn't create output srt file...\n"); + } + + DriverKill(); + SDL_Quit(); + return 0; + } + + gl_shm = open_video_shm(); + + if ( gl_shm == NULL ) + { + printf("Error: Failed to open video Shared memory\n"); + return -1; + } + + // update the emu core + UpdateEMUCore(g_config); + + #ifdef CREATE_AVI + g_config->getOption("SDL.VideoLog", &s); + g_config->setOption("SDL.VideoLog", ""); + if(!s.empty()) + { + NESVideoSetVideoCmd(s.c_str()); + LoggingEnabled = 1; + g_config->getOption("SDL.MuteCapture", &mutecapture); + } else { + mutecapture = 0; + } + #endif + + { + int id; + g_config->getOption("SDL.InputDisplay", &id); + extern int input_display; + input_display = id; + // not exactly an id as an true/false switch; still better than creating another int for that + g_config->getOption("SDL.SubtitleDisplay", &id); + extern int movieSubtitles; + movieSubtitles = id; + } + + // load the hotkeys from the config life + setHotKeys(); + + if (romIndex >= 0) + { + // load the specified game + error = LoadGame(argv[romIndex]); + if (error != 1) + { + DriverKill(); + SDL_Quit(); + return -1; + } + g_config->setOption("SDL.LastOpenFile", argv[romIndex]); + g_config->save(); + } + + // movie playback + g_config->getOption("SDL.Movie", &s); + g_config->setOption("SDL.Movie", ""); + if (s != "") + { + if(s.find(".fm2") != std::string::npos || s.find(".fm3") != std::string::npos) + { + static int pauseframe; + g_config->getOption("SDL.PauseFrame", &pauseframe); + g_config->setOption("SDL.PauseFrame", 0); + FCEUI_printf("Playing back movie located at %s\n", s.c_str()); + FCEUI_LoadMovie(s.c_str(), false, pauseframe ? pauseframe : false); + } + else + { + FCEUI_printf("Sorry, I don't know how to play back %s\n", s.c_str()); + } + g_config->getOption("SDL.MovieLength",&KillFCEUXonFrame); + printf("KillFCEUXonFrame %d\n",KillFCEUXonFrame); + } + + int save_state; + g_config->getOption("SDL.PeriodicSaves", &periodic_saves); + g_config->getOption("SDL.AutoSaveState", &save_state); + if(periodic_saves && save_state < 10 && save_state >= 0){ + FCEUI_SelectState(save_state, 0); + } else { + periodic_saves = 0; + } + +#ifdef _S9XLUA_H + // load lua script if option passed + g_config->getOption("SDL.LuaScript", &s); + g_config->setOption("SDL.LuaScript", ""); + if (s != "") + { +#ifdef __linux + // Resolve absolute path to file + char fullpath[2048]; + if ( realpath( s.c_str(), fullpath ) != NULL ) + { + //printf("Fullpath: '%s'\n", fullpath ); + s.assign( fullpath ); + } +#endif + FCEU_LoadLuaCode(s.c_str()); + } +#endif + + { + int id; + g_config->getOption("SDL.NewPPU", &id); + if (id) + newppu = 1; + } + + g_config->getOption("SDL.Frameskip", &frameskip); + + return 0; +} + +int fceuWrapperClose( void ) +{ + CloseGame(); + + // exit the infrastructure + FCEUI_Kill(); + SDL_Quit(); + + return 0; +} + +/** + * Update the video, audio, and input subsystems with the provided + * video (XBuf) and audio (Buffer) information. + */ +void +FCEUD_Update(uint8 *XBuf, + int32 *Buffer, + int Count) +{ + int blitDone = 0; + extern int FCEUDnetplay; + + #ifdef CREATE_AVI + if(LoggingEnabled == 2 || (eoptions&EO_NOTHROTTLE)) + { + if(LoggingEnabled == 2) + { + int16* MonoBuf = new int16[Count]; + int n; + for(n=0; n GetWriteSound()) Count = GetWriteSound(); + if (!mutecapture) + if(Count > 0 && Buffer) WriteSound(Buffer,Count); + } + if(inited & 2) + FCEUD_UpdateInput(); + if(XBuf && (inited & 4)) BlitScreen(XBuf); + + //SpeedThrottle(); + return; + } + #endif + + int ocount = Count; + // apply frame scaling to Count + Count = (int)(Count / g_fpsScale); + if (Count) + { + int32 can=GetWriteSound(); + static int uflow=0; + int32 tmpcan; + + // don't underflow when scaling fps + if(can >= GetMaxSound() && g_fpsScale==1.0) uflow=1; /* Go into massive underflow mode. */ + + if(can > Count) can=Count; + else uflow=0; + + #ifdef CREATE_AVI + if (!mutecapture) + #endif + WriteSound(Buffer,can); + + //if(uflow) puts("Underflow"); + tmpcan = GetWriteSound(); + // don't underflow when scaling fps + if (g_fpsScale>1.0 || ((tmpcan < Count*0.90) && !uflow)) + { + if (XBuf && (inited&4) && !(NoWaiting & 2)) + { + BlitScreen(XBuf); blitDone = 1; + } + Buffer+=can; + Count-=can; + if(Count) + { + if(NoWaiting) + { + can=GetWriteSound(); + if(Count>can) Count=can; + #ifdef CREATE_AVI + if (!mutecapture) + #endif + WriteSound(Buffer,Count); + } + else + { + while(Count>0) + { + #ifdef CREATE_AVI + if (!mutecapture) + #endif + WriteSound(Buffer,(Count= (Count * 1.8))) + { + if (Count > tmpcan) Count=tmpcan; + while(tmpcan > 0) + { + // printf("Overwrite: %d\n", (Count <= tmpcan)?Count : tmpcan); + #ifdef CREATE_AVI + if (!mutecapture) + #endif + WriteSound(Buffer, (Count <= tmpcan)?Count : tmpcan); + tmpcan -= Count; + } + } + } + else + { + if (!NoWaiting && (!(eoptions&EO_NOTHROTTLE) || FCEUI_EmulationPaused())) + { + while (SpeedThrottle()) + { + FCEUD_UpdateInput(); + } + } + if (XBuf && (inited&4)) + { + BlitScreen(XBuf); blitDone = 1; + } + } + if ( !blitDone ) + { + if (XBuf && (inited&4)) + { + BlitScreen(XBuf); blitDone = 1; + } + } + FCEUD_UpdateInput(); + //if(!Count && !NoWaiting && !(eoptions&EO_NOTHROTTLE)) + // SpeedThrottle(); + //if(XBuf && (inited&4)) + //{ + // BlitScreen(XBuf); + //} + //if(Count) + // WriteSound(Buffer,Count,NoWaiting); + //FCEUD_UpdateInput(); +} + +static void DoFun(int frameskip, int periodic_saves) +{ + uint8 *gfx; + int32 *sound; + int32 ssize; + static int fskipc = 0; + static int opause = 0; + + //TODO peroidic saves, working on it right now + if (periodic_saves && FCEUD_GetTime() % PERIODIC_SAVE_INTERVAL < 30){ + FCEUI_SaveState(NULL, false); + } +#ifdef FRAMESKIP + fskipc = (fskipc + 1) % (frameskip + 1); +#endif + + if (NoWaiting) + { + gfx = 0; + } + FCEUI_Emulate(&gfx, &sound, &ssize, fskipc); + FCEUD_Update(gfx, sound, ssize); + + if(opause!=FCEUI_EmulationPaused()) + { + opause=FCEUI_EmulationPaused(); + SilenceSound(opause); + } +} + +int fceuWrapperUpdate( void ) +{ + if (GameInfo) + { + DoFun(frameskip, periodic_saves); + } + + return 0; +} + // dummy functions #define DUMMY(__f) \ diff --git a/src/drivers/Qt/fceuWrapper.h b/src/drivers/Qt/fceuWrapper.h index 0c279144..804e8bb8 100644 --- a/src/drivers/Qt/fceuWrapper.h +++ b/src/drivers/Qt/fceuWrapper.h @@ -21,3 +21,8 @@ extern Config *g_config; int LoadGame(const char *path); int CloseGame(void); + +int fceuWrapperInit( int argc, char *argv[] ); +int fceuWrapperClose( void ); +int fceuWrapperUpdate( void ); + diff --git a/src/drivers/Qt/main.cpp b/src/drivers/Qt/main.cpp index 14864529..807ae5d8 100644 --- a/src/drivers/Qt/main.cpp +++ b/src/drivers/Qt/main.cpp @@ -1,13 +1,16 @@ #include #include "GameApp.h" +#include "fceuWrapper.h" int main( int argc, char *argv[] ) { QApplication app(argc, argv); gameWin_t win; - win.resize( 200, 200 ); + fceuWrapperInit( argc, argv ); + + win.resize( 512, 512 ); win.show(); return app.exec(); diff --git a/src/drivers/Qt/sdl-video.cpp b/src/drivers/Qt/sdl-video.cpp index 98f59009..4e70a08c 100644 --- a/src/drivers/Qt/sdl-video.cpp +++ b/src/drivers/Qt/sdl-video.cpp @@ -45,6 +45,10 @@ #include #include +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define LSB_FIRST +#endif + // GLOBALS extern Config *g_config; @@ -322,6 +326,21 @@ void LockConsole(){} ///Currently unimplemented. void UnlockConsole(){} +static int testPattern = 0; + +static void WriteTestPattern(void) +{ + int i, j, k; + + k=0; + for (i=0; ipixbuf[k] = 0xffffffff; k++; + } + } +} /** * Pushes the given buffer of bits to the screen. */ @@ -352,7 +371,14 @@ BlitScreen(uint8 *XBuf) if ( dest == NULL ) return; - Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines, pitch, 1, 1); + if ( testPattern ) + { + WriteTestPattern(); + } + else + { + Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines, pitch, 1, 1); + } //guiPixelBufferReDraw(); diff --git a/src/fceux.pro b/src/fceux.pro index 24cf00c0..04dbcd67 100644 --- a/src/fceux.pro +++ b/src/fceux.pro @@ -43,7 +43,9 @@ unix { QMAKE_CXXFLAGS += -D_S9XLUA_H } - QMAKE_CXXFLAGS += -Wall -Wno-write-strings -Wno-sign-compare -Wno-parentheses -Wno-unused-local-typedefs + QMAKE_CXXFLAGS -= -O2 + QMAKE_CXXFLAGS += -O0 -g3 -Wall -Wno-write-strings -Wno-sign-compare -Wno-parentheses -Wno-unused-local-typedefs + QMAKE_CXXFLAGS_RELEASE -= -O2 } # Input From 095415790cfd6031feab8e1d2187c25b9f65db55 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Tue, 23 Jun 2020 22:55:48 -0400 Subject: [PATCH 011/100] Cleaned up unnecessary test code. --- src/drivers/Qt/GameViewer.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/drivers/Qt/GameViewer.cpp b/src/drivers/Qt/GameViewer.cpp index 718cd743..3814fb73 100644 --- a/src/drivers/Qt/GameViewer.cpp +++ b/src/drivers/Qt/GameViewer.cpp @@ -18,22 +18,22 @@ gameView_t::gameView_t(QWidget *parent) view_height = 0; gltexture = 0; - QSurfaceFormat fmt = QSurfaceFormat::defaultFormat(); + //QSurfaceFormat fmt = QSurfaceFormat::defaultFormat(); - fmt.setRedBufferSize(8); - fmt.setGreenBufferSize(8); - fmt.setBlueBufferSize(8); - fmt.setAlphaBufferSize(8); - fmt.setDepthBufferSize( 24 ); - setTextureFormat(GL_RGBA8); + //fmt.setRedBufferSize(8); + //fmt.setGreenBufferSize(8); + //fmt.setBlueBufferSize(8); + //fmt.setAlphaBufferSize(8); + //fmt.setDepthBufferSize( 24 ); + //setTextureFormat(GL_RGBA8); - printf("R: %i \n", fmt.redBufferSize() ); - printf("G: %i \n", fmt.greenBufferSize() ); - printf("B: %i \n", fmt.blueBufferSize() ); - printf("A: %i \n", fmt.alphaBufferSize() ); - printf("SW: %i \n", fmt.swapBehavior() ); + ////printf("R: %i \n", fmt.redBufferSize() ); + ////printf("G: %i \n", fmt.greenBufferSize() ); + ////printf("B: %i \n", fmt.blueBufferSize() ); + ////printf("A: %i \n", fmt.alphaBufferSize() ); + ////printf("SW: %i \n", fmt.swapBehavior() ); - setFormat( fmt ); + //setFormat( fmt ); } gameView_t::~gameView_t(void) @@ -161,7 +161,7 @@ void gameView_t::paintGL(void) //glVertex2f( 1.0f, 1.0f); // Top right of target. //glEnd(); - context()->swapBuffers( context()->surface() ); + //context()->swapBuffers( context()->surface() ); //if ( double_buffer_ena ) //{ // glXSwapBuffers( dpy, win ); @@ -170,7 +170,7 @@ void gameView_t::paintGL(void) //{ // glFlush(); //} - glFlush(); + //glFlush(); //float x1, y1, x2, y2; From f53bbc8cde1f782142c759a336f6357ee6912302 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Tue, 23 Jun 2020 23:04:10 -0400 Subject: [PATCH 012/100] Added logic to close game and shutdown FCEU system on window close. --- src/drivers/Qt/GameApp.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/drivers/Qt/GameApp.cpp b/src/drivers/Qt/GameApp.cpp index 8602a26d..229c9c11 100644 --- a/src/drivers/Qt/GameApp.cpp +++ b/src/drivers/Qt/GameApp.cpp @@ -32,6 +32,8 @@ gameWin_t::gameWin_t(QWidget *parent) gameWin_t::~gameWin_t(void) { + fceuWrapperClose(); + delete viewport; } From d6ff002af04e20c70fcba8f915878a33beb987c1 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Wed, 24 Jun 2020 21:57:43 -0400 Subject: [PATCH 013/100] Added keyboard QT to SDL2 key conversion functionality. --- fceux.pro | 308 +++++++++++ src/drivers/Qt/GameApp.cpp | 13 + src/drivers/Qt/GameApp.h | 5 + src/drivers/Qt/fceuWrapper.cpp | 7 + src/drivers/Qt/input.cpp | 4 +- src/drivers/Qt/keyscan.cpp | 985 +++++++++++++++++++++++++++++++++ src/drivers/Qt/keyscan.h | 12 +- src/fceux.pro | 307 ---------- 8 files changed, 1331 insertions(+), 310 deletions(-) create mode 100644 fceux.pro create mode 100644 src/drivers/Qt/keyscan.cpp delete mode 100644 src/fceux.pro diff --git a/fceux.pro b/fceux.pro new file mode 100644 index 00000000..615bf636 --- /dev/null +++ b/fceux.pro @@ -0,0 +1,308 @@ +###################################################################### +# Automatically generated by qmake (3.1) Sat Jun 20 21:20:47 2020 +###################################################################### + +TEMPLATE = app +TARGET = fceux +INCLUDEPATH += . + +# The following define makes your compiler warn you if you use any +# feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +QT += widgets + +CONFIG += object_parallel_to_source + +unix { + QT_CONFIG -= no-pkg-config + CONFIG += link_pkgconfig + + QMAKE_CXXFLAGS += -DPSS_STYLE=1 -DHAVE_ASPRINTF + + packagesExist(minizip){ + PKGCONFIG += minizip + QMAKE_CXXFLAGS += -D_SYSTEM_MINIZIP + } + + packagesExist(zlib){ + PKGCONFIG += zlib + } + + PKGCONFIG += sdl2 + + packagesExist(lua-5.1){ + PKGCONFIG += lua-5.1 + QMAKE_CXXFLAGS += -D_S9XLUA_H + } + + QMAKE_CXXFLAGS -= -O2 + QMAKE_CXXFLAGS += -O0 -g3 -Wall -Wno-write-strings -Wno-sign-compare -Wno-parentheses -Wno-unused-local-typedefs + QMAKE_CXXFLAGS_RELEASE -= -O2 +} + +# Input +SOURCES += src/asm.cpp +SOURCES += src/cart.cpp +SOURCES += src/cheat.cpp +SOURCES += src/conddebug.cpp +SOURCES += src/config.cpp +SOURCES += src/debug.cpp +SOURCES += src/drawing.cpp +SOURCES += src/fceu.cpp +SOURCES += src/fds.cpp +SOURCES += src/file.cpp +SOURCES += src/emufile.cpp +SOURCES += src/filter.cpp +SOURCES += src/ines.cpp +SOURCES += src/input.cpp +SOURCES += src/movie.cpp +SOURCES += src/netplay.cpp +SOURCES += src/nsf.cpp +SOURCES += src/oldmovie.cpp +SOURCES += src/palette.cpp +SOURCES += src/ppu.cpp +SOURCES += src/sound.cpp +SOURCES += src/state.cpp +SOURCES += src/unif.cpp +SOURCES += src/video.cpp +SOURCES += src/vsuni.cpp +SOURCES += src/wave.cpp +SOURCES += src/x6502.cpp + +unix { + packagesExist(lua-5.1){ + SOURCES += src/lua-engine.cpp + } +} +SOURCES += src/boards/01-222.cpp +SOURCES += src/boards/09-034a.cpp +SOURCES += src/boards/103.cpp +SOURCES += src/boards/106.cpp +SOURCES += src/boards/108.cpp +SOURCES += src/boards/112.cpp +SOURCES += src/boards/116.cpp +SOURCES += src/boards/117.cpp +SOURCES += src/boards/120.cpp +SOURCES += src/boards/121.cpp +SOURCES += src/boards/12in1.cpp +SOURCES += src/boards/151.cpp +SOURCES += src/boards/156.cpp +SOURCES += src/boards/158B.cpp +SOURCES += src/boards/15.cpp +SOURCES += src/boards/164.cpp +SOURCES += src/boards/168.cpp +SOURCES += src/boards/170.cpp +SOURCES += src/boards/175.cpp +SOURCES += src/boards/176.cpp +SOURCES += src/boards/177.cpp +SOURCES += src/boards/178.cpp +SOURCES += src/boards/183.cpp +SOURCES += src/boards/185.cpp +SOURCES += src/boards/186.cpp +SOURCES += src/boards/187.cpp +SOURCES += src/boards/189.cpp +SOURCES += src/boards/18.cpp +SOURCES += src/boards/190.cpp +SOURCES += src/boards/193.cpp +SOURCES += src/boards/199.cpp +SOURCES += src/boards/206.cpp +SOURCES += src/boards/208.cpp +SOURCES += src/boards/222.cpp +SOURCES += src/boards/225.cpp +SOURCES += src/boards/228.cpp +SOURCES += src/boards/230.cpp +SOURCES += src/boards/232.cpp +SOURCES += src/boards/234.cpp +SOURCES += src/boards/235.cpp +SOURCES += src/boards/244.cpp +SOURCES += src/boards/246.cpp +SOURCES += src/boards/252.cpp +SOURCES += src/boards/253.cpp +SOURCES += src/boards/28.cpp +SOURCES += src/boards/32.cpp +SOURCES += src/boards/33.cpp +SOURCES += src/boards/34.cpp +SOURCES += src/boards/36.cpp +SOURCES += src/boards/3d-block.cpp +SOURCES += src/boards/40.cpp +SOURCES += src/boards/411120-c.cpp +SOURCES += src/boards/41.cpp +SOURCES += src/boards/42.cpp +SOURCES += src/boards/43.cpp +SOURCES += src/boards/46.cpp +SOURCES += src/boards/50.cpp +SOURCES += src/boards/51.cpp +SOURCES += src/boards/57.cpp +SOURCES += src/boards/603-5052.cpp +SOURCES += src/boards/62.cpp +SOURCES += src/boards/65.cpp +SOURCES += src/boards/67.cpp +SOURCES += src/boards/68.cpp +SOURCES += src/boards/69.cpp +SOURCES += src/boards/71.cpp +SOURCES += src/boards/72.cpp +SOURCES += src/boards/77.cpp +SOURCES += src/boards/79.cpp +SOURCES += src/boards/80013-B.cpp +SOURCES += src/boards/80.cpp +SOURCES += src/boards/8157.cpp +SOURCES += src/boards/8237.cpp +SOURCES += src/boards/82.cpp +SOURCES += src/boards/830118C.cpp +SOURCES += src/boards/88.cpp +SOURCES += src/boards/8in1.cpp +SOURCES += src/boards/90.cpp +SOURCES += src/boards/91.cpp +SOURCES += src/boards/96.cpp +SOURCES += src/boards/99.cpp +SOURCES += src/boards/a9746.cpp +SOURCES += src/boards/ac-08.cpp +SOURCES += src/boards/addrlatch.cpp +SOURCES += src/boards/ax5705.cpp +SOURCES += src/boards/bandai.cpp +SOURCES += src/boards/bb.cpp +SOURCES += src/boards/bmc13in1jy110.cpp +SOURCES += src/boards/bmc42in1r.cpp +SOURCES += src/boards/bmc64in1nr.cpp +SOURCES += src/boards/bmc70in1.cpp +SOURCES += src/boards/BMW8544.cpp +SOURCES += src/boards/bonza.cpp +SOURCES += src/boards/bs-5.cpp +SOURCES += src/boards/cheapocabra.cpp +SOURCES += src/boards/cityfighter.cpp +SOURCES += src/boards/coolboy.cpp +SOURCES += src/boards/dance2000.cpp +SOURCES += src/boards/datalatch.cpp +SOURCES += src/boards/dream.cpp +SOURCES += src/boards/__dummy_mapper.cpp +SOURCES += src/boards/edu2000.cpp +SOURCES += src/boards/eh8813a.cpp +SOURCES += src/boards/emu2413.c +SOURCES += src/boards/et-100.cpp +SOURCES += src/boards/et-4320.cpp +SOURCES += src/boards/F-15.cpp +SOURCES += src/boards/famicombox.cpp +SOURCES += src/boards/ffe.cpp +SOURCES += src/boards/fk23c.cpp +SOURCES += src/boards/fns.cpp +SOURCES += src/boards/ghostbusters63in1.cpp +SOURCES += src/boards/gs-2004.cpp +SOURCES += src/boards/gs-2013.cpp +SOURCES += src/boards/h2288.cpp +SOURCES += src/boards/hp10xx_hp20xx.cpp +SOURCES += src/boards/hp898f.cpp +SOURCES += src/boards/inlnsf.cpp +SOURCES += src/boards/karaoke.cpp +SOURCES += src/boards/kof97.cpp +SOURCES += src/boards/ks7010.cpp +SOURCES += src/boards/ks7012.cpp +SOURCES += src/boards/ks7013.cpp +SOURCES += src/boards/ks7016.cpp +SOURCES += src/boards/ks7017.cpp +SOURCES += src/boards/ks7030.cpp +SOURCES += src/boards/ks7031.cpp +SOURCES += src/boards/ks7032.cpp +SOURCES += src/boards/ks7037.cpp +SOURCES += src/boards/ks7057.cpp +SOURCES += src/boards/le05.cpp +SOURCES += src/boards/lh32.cpp +SOURCES += src/boards/lh53.cpp +SOURCES += src/boards/malee.cpp +SOURCES += src/boards/mihunche.cpp +SOURCES += src/boards/mmc1.cpp +SOURCES += src/boards/mmc2and4.cpp +SOURCES += src/boards/mmc3.cpp +SOURCES += src/boards/mmc5.cpp +SOURCES += src/boards/n106.cpp +SOURCES += src/boards/n625092.cpp +SOURCES += src/boards/novel.cpp +SOURCES += src/boards/onebus.cpp +SOURCES += src/boards/pec-586.cpp +SOURCES += src/boards/rt-01.cpp +SOURCES += src/boards/sa-9602b.cpp +SOURCES += src/boards/sachen.cpp +SOURCES += src/boards/sb-2000.cpp +SOURCES += src/boards/sc-127.cpp +SOURCES += src/boards/sheroes.cpp +SOURCES += src/boards/sl1632.cpp +SOURCES += src/boards/subor.cpp +SOURCES += src/boards/super24.cpp +SOURCES += src/boards/supervision.cpp +SOURCES += src/boards/t-227-1.cpp +SOURCES += src/boards/t-262.cpp +SOURCES += src/boards/tengen.cpp +SOURCES += src/boards/tf-1201.cpp +SOURCES += src/boards/transformer.cpp +SOURCES += src/boards/unrom512.cpp +SOURCES += src/boards/vrc1.cpp +SOURCES += src/boards/vrc2and4.cpp +SOURCES += src/boards/vrc3.cpp +SOURCES += src/boards/vrc5.cpp +SOURCES += src/boards/vrc6.cpp +SOURCES += src/boards/vrc7.cpp +SOURCES += src/boards/vrc7p.cpp +SOURCES += src/boards/yoko.cpp +SOURCES += src/input/arkanoid.cpp +SOURCES += src/input/bworld.cpp +SOURCES += src/input/cursor.cpp +SOURCES += src/input/fkb.cpp +SOURCES += src/input/fns.cpp +SOURCES += src/input/ftrainer.cpp +SOURCES += src/input/hypershot.cpp +SOURCES += src/input/mahjong.cpp +SOURCES += src/input/mouse.cpp +SOURCES += src/input/oekakids.cpp +SOURCES += src/input/pec586kb.cpp +SOURCES += src/input/powerpad.cpp +SOURCES += src/input/quiz.cpp +SOURCES += src/input/shadow.cpp +SOURCES += src/input/snesmouse.cpp +SOURCES += src/input/suborkb.cpp +SOURCES += src/input/toprider.cpp +SOURCES += src/input/virtualboy.cpp +SOURCES += src/input/zapper.cpp +SOURCES += src/utils/backward.cpp +SOURCES += src/utils/ConvertUTF.c +SOURCES += src/utils/xstring.cpp +SOURCES += src/utils/crc32.cpp +SOURCES += src/utils/endian.cpp +SOURCES += src/utils/general.cpp +SOURCES += src/utils/guid.cpp +SOURCES += src/utils/md5.cpp +SOURCES += src/utils/memory.cpp +SOURCES += src/drivers/common/args.cpp +SOURCES += src/drivers/common/cheat.cpp +SOURCES += src/drivers/common/config.cpp +SOURCES += src/drivers/common/configSys.cpp +SOURCES += src/drivers/common/hq2x.cpp +SOURCES += src/drivers/common/hq3x.cpp +SOURCES += src/drivers/common/scale2x.cpp +SOURCES += src/drivers/common/scale3x.cpp +SOURCES += src/drivers/common/scalebit.cpp +SOURCES += src/drivers/common/vidblit.cpp +SOURCES += src/drivers/common/nes_ntsc.c + +HEADERS += src/drivers/Qt/GameApp.h +HEADERS += src/drivers/Qt/GameViewer.h +SOURCES += src/drivers/Qt/main.cpp +SOURCES += src/drivers/Qt/GameApp.cpp +SOURCES += src/drivers/Qt/GameViewer.cpp +SOURCES += src/drivers/Qt/fceuWrapper.cpp +SOURCES += src/drivers/Qt/config.cpp +SOURCES += src/drivers/Qt/input.cpp +SOURCES += src/drivers/Qt/gl_win.cpp +SOURCES += src/drivers/Qt/keyscan.cpp +SOURCES += src/drivers/Qt/sdl-sound.cpp +SOURCES += src/drivers/Qt/sdl-video.cpp +SOURCES += src/drivers/Qt/sdl-joystick.cpp +SOURCES += src/drivers/Qt/sdl-throttle.cpp +SOURCES += src/drivers/Qt/unix-netplay.cpp + diff --git a/src/drivers/Qt/GameApp.cpp b/src/drivers/Qt/GameApp.cpp index 229c9c11..c7e7078e 100644 --- a/src/drivers/Qt/GameApp.cpp +++ b/src/drivers/Qt/GameApp.cpp @@ -2,6 +2,7 @@ // #include "GameApp.h" #include "fceuWrapper.h" +#include "keyscan.h" gameWin_t::gameWin_t(QWidget *parent) : QMainWindow( parent ) @@ -37,6 +38,18 @@ gameWin_t::~gameWin_t(void) delete viewport; } +void gameWin_t::keyPressEvent(QKeyEvent *event) +{ + //printf("Key Press: 0x%x \n", event->key() ); + pushKeyEvent( event, 1 ); +} + +void gameWin_t::keyReleaseEvent(QKeyEvent *event) +{ + //printf("Key Release: 0x%x \n", event->key() ); + pushKeyEvent( event, 0 ); +} + void gameWin_t::createMainMenu(void) { menuBar()->setNativeMenuBar(false); diff --git a/src/drivers/Qt/GameApp.h b/src/drivers/Qt/GameApp.h index 44f9529c..579fe782 100644 --- a/src/drivers/Qt/GameApp.h +++ b/src/drivers/Qt/GameApp.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include "GameViewer.h" @@ -37,6 +38,10 @@ class gameWin_t : public QMainWindow QTimer *gameTimer; + protected: + void keyPressEvent(QKeyEvent *event); + void keyReleaseEvent(QKeyEvent *event); + private: void createMainMenu(void); diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp index c8402f7c..a340dfc8 100644 --- a/src/drivers/Qt/fceuWrapper.cpp +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -282,6 +282,13 @@ int fceuWrapperInit( int argc, char *argv[] ) FCEUD_Message("Starting " FCEU_NAME_AND_VERSION "...\n"); + /* SDL_INIT_VIDEO Needed for (joystick config) event processing? */ + if (SDL_Init(SDL_INIT_VIDEO)) + { + printf("Could not initialize SDL: %s.\n", SDL_GetError()); + return(-1); + } + // Initialize the configuration system g_config = InitConfig(); diff --git a/src/drivers/Qt/input.cpp b/src/drivers/Qt/input.cpp index d384136f..0dc2f1af 100644 --- a/src/drivers/Qt/input.cpp +++ b/src/drivers/Qt/input.cpp @@ -1043,7 +1043,7 @@ DTestButton (ButtConfig * bc) ButtConfig GamePadConfig[4][10] = { /* Gamepad 1 */ {MK (KP_3), MK (KP_2), MK (SLASH), MK (ENTER), - MK (W), MK (Z), MK (A), MK (S), MKZ (), MKZ ()}, + MK (w), MK (z), MK (a), MK (s), MKZ (), MKZ ()}, /* Gamepad 2 */ GPZ (), @@ -2259,7 +2259,7 @@ const char *GamePadNames[GAMEPAD_NUM_BUTTONS] = { "A", "B", "Select", "Start", const char *DefaultGamePadDevice[GAMEPAD_NUM_DEVICES] = { "Keyboard", "None", "None", "None" }; const int DefaultGamePad[GAMEPAD_NUM_DEVICES][GAMEPAD_NUM_BUTTONS] = -{ {SDLK_F, SDLK_D, SDLK_S, SDLK_RETURN, +{ {SDLK_f, SDLK_d, SDLK_s, SDLK_RETURN, SDLK_UP, SDLK_DOWN, SDLK_LEFT, SDLK_RIGHT, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, diff --git a/src/drivers/Qt/keyscan.cpp b/src/drivers/Qt/keyscan.cpp new file mode 100644 index 00000000..2b3361c5 --- /dev/null +++ b/src/drivers/Qt/keyscan.cpp @@ -0,0 +1,985 @@ +// keyscan.cpp +// + +#include +#include + +#include "keyscan.h" + +using namespace Qt; + +SDL_Scancode convQtKey2SDLScanCode( Qt::Key q ) +{ + SDL_Scancode s = SDL_SCANCODE_UNKNOWN; + + switch (q) + { + case Key_Escape: + s = SDL_SCANCODE_ESCAPE; + break; + case Key_Tab: + case Key_Backtab: + s = SDL_SCANCODE_TAB; + break; + case Key_Backspace: + s = SDL_SCANCODE_BACKSPACE; + break; + case Key_Return: + s = SDL_SCANCODE_RETURN; + break; + case Key_Enter: + s = SDL_SCANCODE_RETURN; + break; + case Key_Insert: + s = SDL_SCANCODE_INSERT; + break; + case Key_Delete: + s = SDL_SCANCODE_DELETE; + break; + case Key_Pause: + s = SDL_SCANCODE_PAUSE; + break; + case Key_Print: + case Key_SysReq: + s = SDL_SCANCODE_PRINTSCREEN; + break; + case Key_Clear: + s = SDL_SCANCODE_CLEAR; + break; + case Key_Home: + s = SDL_SCANCODE_HOME; + break; + case Key_End: + s = SDL_SCANCODE_END; + break; + case Key_Left: + s = SDL_SCANCODE_LEFT; + break; + case Key_Up: + s = SDL_SCANCODE_UP; + break; + case Key_Right: + s = SDL_SCANCODE_RIGHT; + break; + case Key_Down: + s = SDL_SCANCODE_DOWN; + break; + case Key_PageUp: + s = SDL_SCANCODE_PAGEUP; + break; + case Key_PageDown: + s = SDL_SCANCODE_PAGEDOWN; + break; + case Key_Shift: + s = SDL_SCANCODE_LSHIFT; + break; + case Key_Control: + s = SDL_SCANCODE_LCTRL; + break; + case Key_Meta: + s = SDL_SCANCODE_LGUI; + break; + case Key_Alt: + s = SDL_SCANCODE_LALT; + break; + case Key_CapsLock: + s = SDL_SCANCODE_CAPSLOCK; + break; + case Key_NumLock: + s = SDL_SCANCODE_NUMLOCKCLEAR; + break; + case Key_ScrollLock: + s = SDL_SCANCODE_SCROLLLOCK; + break; + case Key_F1: + s = SDL_SCANCODE_F1; + break; + case Key_F2: + s = SDL_SCANCODE_F2; + break; + case Key_F3: + s = SDL_SCANCODE_F3; + break; + case Key_F4: + s = SDL_SCANCODE_F4; + break; + case Key_F5: + s = SDL_SCANCODE_F5; + break; + case Key_F6: + s = SDL_SCANCODE_F6; + break; + case Key_F7: + s = SDL_SCANCODE_F7; + break; + case Key_F8: + s = SDL_SCANCODE_F8; + break; + case Key_F9: + s = SDL_SCANCODE_F9; + break; + case Key_F10: + s = SDL_SCANCODE_F10; + break; + case Key_F11: + s = SDL_SCANCODE_F11; + break; + case Key_F12: + s = SDL_SCANCODE_F12; + break; + case Key_F13: + s = SDL_SCANCODE_F13; + break; + case Key_F14: + s = SDL_SCANCODE_F14; + break; + case Key_F15: + s = SDL_SCANCODE_F15; + break; + case Key_F16: + s = SDL_SCANCODE_F16; + break; + case Key_F17: + s = SDL_SCANCODE_F17; + break; + case Key_F18: + s = SDL_SCANCODE_F18; + break; + case Key_F19: + s = SDL_SCANCODE_F19; + break; + case Key_F20: + s = SDL_SCANCODE_F20; + break; + case Key_F21: + s = SDL_SCANCODE_F21; + break; + case Key_F22: + s = SDL_SCANCODE_F22; + break; + case Key_F23: + s = SDL_SCANCODE_F23; + break; + case Key_F24: + s = SDL_SCANCODE_F24; + break; + //case Key_F25: // F25 .. F35 only on X11 + //case Key_F26: + //case Key_F27: + //case Key_F28: + //case Key_F29: + //case Key_F30: + //case Key_F31: + //case Key_F32: + //case Key_F33: + //case Key_F34: + //case Key_F35: + // s = SDL_SCANCODE_UNKNOWN; + //break; + case Key_Super_L: + case Key_Super_R: + s = SDL_SCANCODE_UNKNOWN; + break; + case Key_Menu: + s = SDL_SCANCODE_MENU; + break; + case Key_Hyper_L: + case Key_Hyper_R: + s = SDL_SCANCODE_UNKNOWN; + break; + case Key_Help: + s = SDL_SCANCODE_HELP; + break; + case Key_Direction_L: + case Key_Direction_R: + s = SDL_SCANCODE_UNKNOWN; + break; + + case Key_Space: + //case Key_Any: + s = SDL_SCANCODE_SPACE; + break; + + case Key_Exclam: + s = SDL_SCANCODE_1; + break; + case Key_QuoteDbl: + s = SDL_SCANCODE_APOSTROPHE; + break; + case Key_NumberSign: + s = SDL_SCANCODE_3; + break; + case Key_Dollar: + s = SDL_SCANCODE_4; + break; + case Key_Percent: + s = SDL_SCANCODE_5; + break; + case Key_Ampersand: + s = SDL_SCANCODE_7; + break; + case Key_Apostrophe: + s = SDL_SCANCODE_APOSTROPHE; + break; + case Key_ParenLeft: + s = SDL_SCANCODE_9; + break; + case Key_ParenRight: + s = SDL_SCANCODE_0; + break; + case Key_Asterisk: + s = SDL_SCANCODE_8; + break; + case Key_Plus: + s = SDL_SCANCODE_EQUALS; + break; + case Key_Comma: + s = SDL_SCANCODE_COMMA; + break; + case Key_Minus: + s = SDL_SCANCODE_MINUS; + break; + case Key_Period: + s = SDL_SCANCODE_PERIOD; + break; + case Key_Slash: + s = SDL_SCANCODE_SLASH; + break; + case Key_0: + s = SDL_SCANCODE_0; + break; + case Key_1: + s = SDL_SCANCODE_1; + break; + case Key_2: + s = SDL_SCANCODE_2; + break; + case Key_3: + s = SDL_SCANCODE_3; + break; + case Key_4: + s = SDL_SCANCODE_4; + break; + case Key_5: + s = SDL_SCANCODE_5; + break; + case Key_6: + s = SDL_SCANCODE_6; + break; + case Key_7: + s = SDL_SCANCODE_7; + break; + case Key_8: + s = SDL_SCANCODE_8; + break; + case Key_9: + s = SDL_SCANCODE_9; + break; + case Key_Colon: + case Key_Semicolon: + s = SDL_SCANCODE_SEMICOLON; + break; + case Key_Less: + s = SDL_SCANCODE_COMMA; + break; + case Key_Equal: + s = SDL_SCANCODE_EQUALS; + break; + case Key_Greater: + s = SDL_SCANCODE_PERIOD; + break; + case Key_Question: + s = SDL_SCANCODE_SLASH; + break; + case Key_At: + s = SDL_SCANCODE_2; + break; + break; + case Key_A: + s = SDL_SCANCODE_A; + break; + case Key_B: + s = SDL_SCANCODE_B; + break; + case Key_C: + s = SDL_SCANCODE_C; + break; + case Key_D: + s = SDL_SCANCODE_D; + break; + case Key_E: + s = SDL_SCANCODE_E; + break; + case Key_F: + s = SDL_SCANCODE_F; + break; + case Key_G: + s = SDL_SCANCODE_G; + break; + case Key_H: + s = SDL_SCANCODE_H; + break; + case Key_I: + s = SDL_SCANCODE_I; + break; + case Key_J: + s = SDL_SCANCODE_J; + break; + case Key_K: + s = SDL_SCANCODE_K; + break; + case Key_L: + s = SDL_SCANCODE_L; + break; + case Key_M: + s = SDL_SCANCODE_M; + break; + case Key_N: + s = SDL_SCANCODE_N; + break; + case Key_O: + s = SDL_SCANCODE_O; + break; + case Key_P: + s = SDL_SCANCODE_P; + break; + case Key_Q: + s = SDL_SCANCODE_Q; + break; + case Key_R: + s = SDL_SCANCODE_R; + break; + case Key_S: + s = SDL_SCANCODE_S; + break; + case Key_T: + s = SDL_SCANCODE_T; + break; + case Key_U: + s = SDL_SCANCODE_U; + break; + case Key_V: + s = SDL_SCANCODE_V; + break; + case Key_W: + s = SDL_SCANCODE_W; + break; + case Key_X: + s = SDL_SCANCODE_X; + break; + case Key_Y: + s = SDL_SCANCODE_Y; + break; + case Key_Z: + s = SDL_SCANCODE_Z; + break; + case Key_BracketLeft: + s = SDL_SCANCODE_LEFTBRACKET; + break; + case Key_Backslash: + s = SDL_SCANCODE_BACKSLASH; + break; + case Key_BracketRight: + s = SDL_SCANCODE_RIGHTBRACKET; + break; + //case Key_AsciiCircum: + // s = SDL_SCANCODE_UNKNOWN; + //break; + case Key_Underscore: + s = SDL_SCANCODE_MINUS; + break; + case Key_QuoteLeft: + s = SDL_SCANCODE_GRAVE; + break; + case Key_BraceLeft: + s = SDL_SCANCODE_LEFTBRACKET; + break; + case Key_Bar: + s = SDL_SCANCODE_BACKSLASH; + break; + case Key_BraceRight: + s = SDL_SCANCODE_RIGHTBRACKET; + break; + case Key_AsciiTilde: + s = SDL_SCANCODE_GRAVE; + break; + + //case Key_nobreakspace: + //case Key_exclamdown: + //case Key_cent: + //case Key_sterling: + //case Key_currency: + //case Key_yen: + //case Key_brokenbar: + //case Key_section: + //case Key_diaeresis: + //case Key_copyright: + //case Key_ordfeminine: + //case Key_guillemotleft: + //case Key_notsign: + //case Key_hyphen: + //case Key_registered: + //case Key_macron: + //case Key_degree: + //case Key_plusminus: + //case Key_twosuperior: + //case Key_threesuperior: + //case Key_acute: + //case Key_mu: + //case Key_paragraph: + //case Key_periodcentered: + //case Key_cedilla: + //case Key_onesuperior: + //case Key_masculine: + //case Key_guillemotright: + //case Key_onequarter: + //case Key_onehalf: + //case Key_threequarters: + //case Key_questiondown: + //case Key_Agrave: + //case Key_Aacute: + //case Key_Acircumflex: + //case Key_Atilde: + //case Key_Adiaeresis: + //case Key_Aring: + //case Key_AE: + //case Key_Ccedilla: + //case Key_Egrave: + //case Key_Eacute: + //case Key_Ecircumflex: + //case Key_Ediaeresis: + //case Key_Igrave: + //case Key_Iacute: + //case Key_Icircumflex: + //case Key_Idiaeresis: + //case Key_ETH: + //case Key_Ntilde: + //case Key_Ograve: + //case Key_Oacute: + //case Key_Ocircumflex: + //case Key_Otilde: + //case Key_Odiaeresis: + //case Key_multiply: + //case Key_Ooblique: + //case Key_Ugrave: + //case Key_Uacute: + //case Key_Ucircumflex: + //case Key_Udiaeresis: + //case Key_Yacute: + //case Key_THORN: + //case Key_ssharp: + //case Key_division: + //case Key_ydiaeresis: + // s = SDL_SCANCODE_UNKNOWN; + //break; + default: + s = SDL_SCANCODE_UNKNOWN; + break; + } + return s; +} + +SDL_Keycode convQtKey2SDLKeyCode( Qt::Key q ) +{ + SDL_Keycode s = SDLK_UNKNOWN; + + switch (q) + { + case Key_Escape: + s = SDLK_ESCAPE; + break; + case Key_Tab: + case Key_Backtab: + s = SDLK_TAB; + break; + case Key_Backspace: + s = SDLK_BACKSPACE; + break; + case Key_Return: + s = SDLK_RETURN; + break; + case Key_Enter: + s = SDLK_KP_ENTER; + break; + case Key_Insert: + s = SDLK_INSERT; + break; + case Key_Delete: + s = SDLK_DELETE; + break; + case Key_Pause: + s = SDLK_PAUSE; + break; + case Key_Print: + s = SDLK_PRINTSCREEN; + break; + case Key_SysReq: + s = SDLK_SYSREQ; + break; + case Key_Clear: + s = SDLK_CLEAR; + break; + case Key_Home: + s = SDLK_HOME; + break; + case Key_End: + s = SDLK_END; + break; + case Key_Left: + s = SDLK_LEFT; + break; + case Key_Up: + s = SDLK_UP; + break; + case Key_Right: + s = SDLK_RIGHT; + break; + case Key_Down: + s = SDLK_DOWN; + break; + case Key_PageUp: + s = SDLK_PAGEUP; + break; + case Key_PageDown: + s = SDLK_PAGEDOWN; + break; + case Key_Shift: + s = SDLK_LSHIFT; + break; + case Key_Control: + s = SDLK_LCTRL; + break; + case Key_Meta: + s = SDLK_LGUI; + break; + case Key_Alt: + s = SDL_SCANCODE_LALT; + break; + case Key_CapsLock: + s = SDLK_LALT; + break; + case Key_NumLock: + s = SDLK_NUMLOCKCLEAR; + break; + case Key_ScrollLock: + s = SDLK_SCROLLLOCK; + break; + case Key_F1: + s = SDLK_F1; + break; + case Key_F2: + s = SDLK_F2; + break; + case Key_F3: + s = SDLK_F3; + break; + case Key_F4: + s = SDLK_F4; + break; + case Key_F5: + s = SDLK_F5; + break; + case Key_F6: + s = SDLK_F6; + break; + case Key_F7: + s = SDLK_F7; + break; + case Key_F8: + s = SDLK_F8; + break; + case Key_F9: + s = SDLK_F9; + break; + case Key_F10: + s = SDLK_F10; + break; + case Key_F11: + s = SDLK_F11; + break; + case Key_F12: + s = SDLK_F12; + break; + case Key_F13: + s = SDLK_F13; + break; + case Key_F14: + s = SDLK_F14; + break; + case Key_F15: + s = SDLK_F15; + break; + case Key_F16: + s = SDLK_F16; + break; + case Key_F17: + s = SDLK_F17; + break; + case Key_F18: + s = SDLK_F18; + break; + case Key_F19: + s = SDLK_F19; + break; + case Key_F20: + s = SDLK_F20; + break; + case Key_F21: + s = SDLK_F21; + break; + case Key_F22: + s = SDLK_F22; + break; + case Key_F23: + s = SDLK_F23; + break; + case Key_F24: + s = SDLK_F24; + break; + //case Key_F25: // F25 .. F35 only on X11 + //case Key_F26: + //case Key_F27: + //case Key_F28: + //case Key_F29: + //case Key_F30: + //case Key_F31: + //case Key_F32: + //case Key_F33: + //case Key_F34: + //case Key_F35: + // s = SDL_SCANCODE_UNKNOWN; + //break; + case Key_Super_L: + case Key_Super_R: + s = SDLK_UNKNOWN; + break; + case Key_Menu: + s = SDLK_MENU; + break; + case Key_Hyper_L: + case Key_Hyper_R: + s = SDLK_UNKNOWN; + break; + case Key_Help: + s = SDLK_HELP; + break; + case Key_Direction_L: + case Key_Direction_R: + s = SDLK_UNKNOWN; + break; + + case Key_Space: + //case Key_Any: + s = SDLK_SPACE; + break; + + case Key_Exclam: + s = SDLK_EXCLAIM; + break; + case Key_QuoteDbl: + s = SDLK_QUOTEDBL; + break; + case Key_NumberSign: + s = SDLK_HASH; + break; + case Key_Dollar: + s = SDLK_DOLLAR; + break; + case Key_Percent: + s = SDLK_PERCENT; + break; + case Key_Ampersand: + s = SDLK_AMPERSAND; + break; + case Key_Apostrophe: + s = SDLK_QUOTE; + break; + case Key_ParenLeft: + s = SDLK_LEFTPAREN; + break; + case Key_ParenRight: + s = SDLK_RIGHTPAREN; + break; + case Key_Asterisk: + s = SDLK_ASTERISK; + break; + case Key_Plus: + s = SDLK_PLUS; + break; + case Key_Comma: + s = SDLK_COMMA; + break; + case Key_Minus: + s = SDLK_MINUS; + break; + case Key_Period: + s = SDLK_PERIOD; + break; + case Key_Slash: + s = SDLK_SLASH; + break; + case Key_0: + s = SDLK_0; + break; + case Key_1: + s = SDLK_1; + break; + case Key_2: + s = SDLK_2; + break; + case Key_3: + s = SDLK_3; + break; + case Key_4: + s = SDLK_4; + break; + case Key_5: + s = SDLK_5; + break; + case Key_6: + s = SDLK_6; + break; + case Key_7: + s = SDLK_7; + break; + case Key_8: + s = SDLK_8; + break; + case Key_9: + s = SDLK_9; + break; + case Key_Colon: + s = SDLK_COLON; + break; + case Key_Semicolon: + s = SDLK_SEMICOLON; + break; + case Key_Less: + s = SDLK_LESS; + break; + case Key_Equal: + s = SDLK_LESS; + break; + case Key_Greater: + s = SDLK_GREATER; + break; + case Key_Question: + s = SDLK_QUESTION; + break; + case Key_At: + s = SDLK_AT; + break; + break; + case Key_A: + s = SDLK_a; + break; + case Key_B: + s = SDLK_b; + break; + case Key_C: + s = SDLK_c; + break; + case Key_D: + s = SDLK_d; + break; + case Key_E: + s = SDLK_e; + break; + case Key_F: + s = SDLK_f; + break; + case Key_G: + s = SDLK_g; + break; + case Key_H: + s = SDLK_h; + break; + case Key_I: + s = SDLK_i; + break; + case Key_J: + s = SDLK_j; + break; + case Key_K: + s = SDLK_k; + break; + case Key_L: + s = SDLK_l; + break; + case Key_M: + s = SDLK_m; + break; + case Key_N: + s = SDLK_n; + break; + case Key_O: + s = SDLK_o; + break; + case Key_P: + s = SDLK_p; + break; + case Key_Q: + s = SDLK_q; + break; + case Key_R: + s = SDLK_r; + break; + case Key_S: + s = SDLK_s; + break; + case Key_T: + s = SDLK_t; + break; + case Key_U: + s = SDLK_u; + break; + case Key_V: + s = SDLK_v; + break; + case Key_W: + s = SDLK_w; + break; + case Key_X: + s = SDLK_x; + break; + case Key_Y: + s = SDLK_y; + break; + case Key_Z: + s = SDLK_z; + break; + case Key_BracketLeft: + s = SDLK_LEFTBRACKET; + break; + case Key_Backslash: + s = SDLK_BACKSLASH; + break; + case Key_BracketRight: + s = SDLK_RIGHTBRACKET; + break; + //case Key_AsciiCircum: + // s = SDLK_CARET; + //break; + case Key_Underscore: + s = SDLK_UNDERSCORE; + break; + case Key_QuoteLeft: + s = SDLK_BACKQUOTE; + break; + case Key_BraceLeft: + s = SDLK_LEFTBRACKET; + break; + case Key_Bar: + s = SDLK_BACKSLASH; + break; + case Key_BraceRight: + s = SDLK_RIGHTBRACKET; + break; + case Key_AsciiTilde: + s = SDLK_BACKQUOTE; + break; + + //case Key_nobreakspace: + //case Key_exclamdown: + //case Key_cent: + //case Key_sterling: + //case Key_currency: + //case Key_yen: + //case Key_brokenbar: + //case Key_section: + //case Key_diaeresis: + //case Key_copyright: + //case Key_ordfeminine: + //case Key_guillemotleft: + //case Key_notsign: + //case Key_hyphen: + //case Key_registered: + //case Key_macron: + //case Key_degree: + //case Key_plusminus: + //case Key_twosuperior: + //case Key_threesuperior: + //case Key_acute: + //case Key_mu: + //case Key_paragraph: + //case Key_periodcentered: + //case Key_cedilla: + //case Key_onesuperior: + //case Key_masculine: + //case Key_guillemotright: + //case Key_onequarter: + //case Key_onehalf: + //case Key_threequarters: + //case Key_questiondown: + //case Key_Agrave: + //case Key_Aacute: + //case Key_Acircumflex: + //case Key_Atilde: + //case Key_Adiaeresis: + //case Key_Aring: + //case Key_AE: + //case Key_Ccedilla: + //case Key_Egrave: + //case Key_Eacute: + //case Key_Ecircumflex: + //case Key_Ediaeresis: + //case Key_Igrave: + //case Key_Iacute: + //case Key_Icircumflex: + //case Key_Idiaeresis: + //case Key_ETH: + //case Key_Ntilde: + //case Key_Ograve: + //case Key_Oacute: + //case Key_Ocircumflex: + //case Key_Otilde: + //case Key_Odiaeresis: + //case Key_multiply: + //case Key_Ooblique: + //case Key_Ugrave: + //case Key_Uacute: + //case Key_Ucircumflex: + //case Key_Udiaeresis: + //case Key_Yacute: + //case Key_THORN: + //case Key_ssharp: + //case Key_division: + //case Key_ydiaeresis: + // s = SDL_SCANCODE_UNKNOWN; + //break; + default: + s = SDLK_UNKNOWN; + break; + } + return s; +} + +int pushKeyEvent( QKeyEvent *event, int pressDown ) +{ + SDL_Event sdlev; + + if ( pressDown ) + { + sdlev.type = SDL_KEYDOWN; + sdlev.key.state = SDL_PRESSED; + } + else + { + sdlev.type = SDL_KEYUP; + sdlev.key.state = SDL_RELEASED; + } + + sdlev.key.keysym.sym = convQtKey2SDLKeyCode( (Qt::Key)event->key() ); + + sdlev.key.keysym.scancode = SDL_GetScancodeFromKey( sdlev.key.keysym.sym ); + + sdlev.key.keysym.mod = 0; + sdlev.key.repeat = 0; + + if (sdlev.key.keysym.scancode != SDL_SCANCODE_UNKNOWN) + { + SDL_PushEvent (&sdlev); + } + + return 0; +} diff --git a/src/drivers/Qt/keyscan.h b/src/drivers/Qt/keyscan.h index b3973c20..0273471c 100644 --- a/src/drivers/Qt/keyscan.h +++ b/src/drivers/Qt/keyscan.h @@ -39,6 +39,16 @@ #define SDLK_APOSTROPHE SDLK_QUOTE #define SDLK_BRACKET_LEFT SDLK_LEFTBRACKET #define SDLK_BRACKET_RIGHT SDLK_RIGHTBRACKET -#define SDLK_SCROLLLOCK SDLK_SCROLLOCK /* I guess the SDL people don't like lots of Ls... */ +//#define SDLK_SCROLLLOCK SDLK_SCROLLOCK /* I guess the SDL people don't like lots of Ls... */ #define SDLK_GRAVE SDLK_BACKQUOTE #define MKK(k) SDLK_##k + +#include +#include +#include + +SDL_Keycode convQtKey2SDLKeyCode( Qt::Key q ); + +SDL_Scancode convQtKey2SDLScanCode( Qt::Key q ); + +int pushKeyEvent( QKeyEvent *event, int pressDown ); diff --git a/src/fceux.pro b/src/fceux.pro deleted file mode 100644 index 04dbcd67..00000000 --- a/src/fceux.pro +++ /dev/null @@ -1,307 +0,0 @@ -###################################################################### -# Automatically generated by qmake (3.1) Sat Jun 20 21:20:47 2020 -###################################################################### - -TEMPLATE = app -TARGET = fceux -INCLUDEPATH += . - -# The following define makes your compiler warn you if you use any -# feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. -DEFINES += QT_DEPRECATED_WARNINGS - -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - -QT += widgets - -CONFIG += object_parallel_to_source - -unix { - QT_CONFIG -= no-pkg-config - CONFIG += link_pkgconfig - - QMAKE_CXXFLAGS += -DPSS_STYLE=1 -DHAVE_ASPRINTF - - packagesExist(minizip){ - PKGCONFIG += minizip - QMAKE_CXXFLAGS += -D_SYSTEM_MINIZIP - } - - packagesExist(zlib){ - PKGCONFIG += zlib - } - - PKGCONFIG += sdl2 - - packagesExist(lua-5.1){ - PKGCONFIG += lua-5.1 - QMAKE_CXXFLAGS += -D_S9XLUA_H - } - - QMAKE_CXXFLAGS -= -O2 - QMAKE_CXXFLAGS += -O0 -g3 -Wall -Wno-write-strings -Wno-sign-compare -Wno-parentheses -Wno-unused-local-typedefs - QMAKE_CXXFLAGS_RELEASE -= -O2 -} - -# Input -SOURCES += asm.cpp -SOURCES += cart.cpp -SOURCES += cheat.cpp -SOURCES += conddebug.cpp -SOURCES += config.cpp -SOURCES += debug.cpp -SOURCES += drawing.cpp -SOURCES += fceu.cpp -SOURCES += fds.cpp -SOURCES += file.cpp -SOURCES += emufile.cpp -SOURCES += filter.cpp -SOURCES += ines.cpp -SOURCES += input.cpp -SOURCES += movie.cpp -SOURCES += netplay.cpp -SOURCES += nsf.cpp -SOURCES += oldmovie.cpp -SOURCES += palette.cpp -SOURCES += ppu.cpp -SOURCES += sound.cpp -SOURCES += state.cpp -SOURCES += unif.cpp -SOURCES += video.cpp -SOURCES += vsuni.cpp -SOURCES += wave.cpp -SOURCES += x6502.cpp - -unix { - packagesExist(lua-5.1){ - SOURCES += lua-engine.cpp - } -} -SOURCES += boards/01-222.cpp -SOURCES += boards/09-034a.cpp -SOURCES += boards/103.cpp -SOURCES += boards/106.cpp -SOURCES += boards/108.cpp -SOURCES += boards/112.cpp -SOURCES += boards/116.cpp -SOURCES += boards/117.cpp -SOURCES += boards/120.cpp -SOURCES += boards/121.cpp -SOURCES += boards/12in1.cpp -SOURCES += boards/151.cpp -SOURCES += boards/156.cpp -SOURCES += boards/158B.cpp -SOURCES += boards/15.cpp -SOURCES += boards/164.cpp -SOURCES += boards/168.cpp -SOURCES += boards/170.cpp -SOURCES += boards/175.cpp -SOURCES += boards/176.cpp -SOURCES += boards/177.cpp -SOURCES += boards/178.cpp -SOURCES += boards/183.cpp -SOURCES += boards/185.cpp -SOURCES += boards/186.cpp -SOURCES += boards/187.cpp -SOURCES += boards/189.cpp -SOURCES += boards/18.cpp -SOURCES += boards/190.cpp -SOURCES += boards/193.cpp -SOURCES += boards/199.cpp -SOURCES += boards/206.cpp -SOURCES += boards/208.cpp -SOURCES += boards/222.cpp -SOURCES += boards/225.cpp -SOURCES += boards/228.cpp -SOURCES += boards/230.cpp -SOURCES += boards/232.cpp -SOURCES += boards/234.cpp -SOURCES += boards/235.cpp -SOURCES += boards/244.cpp -SOURCES += boards/246.cpp -SOURCES += boards/252.cpp -SOURCES += boards/253.cpp -SOURCES += boards/28.cpp -SOURCES += boards/32.cpp -SOURCES += boards/33.cpp -SOURCES += boards/34.cpp -SOURCES += boards/36.cpp -SOURCES += boards/3d-block.cpp -SOURCES += boards/40.cpp -SOURCES += boards/411120-c.cpp -SOURCES += boards/41.cpp -SOURCES += boards/42.cpp -SOURCES += boards/43.cpp -SOURCES += boards/46.cpp -SOURCES += boards/50.cpp -SOURCES += boards/51.cpp -SOURCES += boards/57.cpp -SOURCES += boards/603-5052.cpp -SOURCES += boards/62.cpp -SOURCES += boards/65.cpp -SOURCES += boards/67.cpp -SOURCES += boards/68.cpp -SOURCES += boards/69.cpp -SOURCES += boards/71.cpp -SOURCES += boards/72.cpp -SOURCES += boards/77.cpp -SOURCES += boards/79.cpp -SOURCES += boards/80013-B.cpp -SOURCES += boards/80.cpp -SOURCES += boards/8157.cpp -SOURCES += boards/8237.cpp -SOURCES += boards/82.cpp -SOURCES += boards/830118C.cpp -SOURCES += boards/88.cpp -SOURCES += boards/8in1.cpp -SOURCES += boards/90.cpp -SOURCES += boards/91.cpp -SOURCES += boards/96.cpp -SOURCES += boards/99.cpp -SOURCES += boards/a9746.cpp -SOURCES += boards/ac-08.cpp -SOURCES += boards/addrlatch.cpp -SOURCES += boards/ax5705.cpp -SOURCES += boards/bandai.cpp -SOURCES += boards/bb.cpp -SOURCES += boards/bmc13in1jy110.cpp -SOURCES += boards/bmc42in1r.cpp -SOURCES += boards/bmc64in1nr.cpp -SOURCES += boards/bmc70in1.cpp -SOURCES += boards/BMW8544.cpp -SOURCES += boards/bonza.cpp -SOURCES += boards/bs-5.cpp -SOURCES += boards/cheapocabra.cpp -SOURCES += boards/cityfighter.cpp -SOURCES += boards/coolboy.cpp -SOURCES += boards/dance2000.cpp -SOURCES += boards/datalatch.cpp -SOURCES += boards/dream.cpp -SOURCES += boards/__dummy_mapper.cpp -SOURCES += boards/edu2000.cpp -SOURCES += boards/eh8813a.cpp -SOURCES += boards/emu2413.c -SOURCES += boards/et-100.cpp -SOURCES += boards/et-4320.cpp -SOURCES += boards/F-15.cpp -SOURCES += boards/famicombox.cpp -SOURCES += boards/ffe.cpp -SOURCES += boards/fk23c.cpp -SOURCES += boards/fns.cpp -SOURCES += boards/ghostbusters63in1.cpp -SOURCES += boards/gs-2004.cpp -SOURCES += boards/gs-2013.cpp -SOURCES += boards/h2288.cpp -SOURCES += boards/hp10xx_hp20xx.cpp -SOURCES += boards/hp898f.cpp -SOURCES += boards/inlnsf.cpp -SOURCES += boards/karaoke.cpp -SOURCES += boards/kof97.cpp -SOURCES += boards/ks7010.cpp -SOURCES += boards/ks7012.cpp -SOURCES += boards/ks7013.cpp -SOURCES += boards/ks7016.cpp -SOURCES += boards/ks7017.cpp -SOURCES += boards/ks7030.cpp -SOURCES += boards/ks7031.cpp -SOURCES += boards/ks7032.cpp -SOURCES += boards/ks7037.cpp -SOURCES += boards/ks7057.cpp -SOURCES += boards/le05.cpp -SOURCES += boards/lh32.cpp -SOURCES += boards/lh53.cpp -SOURCES += boards/malee.cpp -SOURCES += boards/mihunche.cpp -SOURCES += boards/mmc1.cpp -SOURCES += boards/mmc2and4.cpp -SOURCES += boards/mmc3.cpp -SOURCES += boards/mmc5.cpp -SOURCES += boards/n106.cpp -SOURCES += boards/n625092.cpp -SOURCES += boards/novel.cpp -SOURCES += boards/onebus.cpp -SOURCES += boards/pec-586.cpp -SOURCES += boards/rt-01.cpp -SOURCES += boards/sa-9602b.cpp -SOURCES += boards/sachen.cpp -SOURCES += boards/sb-2000.cpp -SOURCES += boards/sc-127.cpp -SOURCES += boards/sheroes.cpp -SOURCES += boards/sl1632.cpp -SOURCES += boards/subor.cpp -SOURCES += boards/super24.cpp -SOURCES += boards/supervision.cpp -SOURCES += boards/t-227-1.cpp -SOURCES += boards/t-262.cpp -SOURCES += boards/tengen.cpp -SOURCES += boards/tf-1201.cpp -SOURCES += boards/transformer.cpp -SOURCES += boards/unrom512.cpp -SOURCES += boards/vrc1.cpp -SOURCES += boards/vrc2and4.cpp -SOURCES += boards/vrc3.cpp -SOURCES += boards/vrc5.cpp -SOURCES += boards/vrc6.cpp -SOURCES += boards/vrc7.cpp -SOURCES += boards/vrc7p.cpp -SOURCES += boards/yoko.cpp -SOURCES += input/arkanoid.cpp -SOURCES += input/bworld.cpp -SOURCES += input/cursor.cpp -SOURCES += input/fkb.cpp -SOURCES += input/fns.cpp -SOURCES += input/ftrainer.cpp -SOURCES += input/hypershot.cpp -SOURCES += input/mahjong.cpp -SOURCES += input/mouse.cpp -SOURCES += input/oekakids.cpp -SOURCES += input/pec586kb.cpp -SOURCES += input/powerpad.cpp -SOURCES += input/quiz.cpp -SOURCES += input/shadow.cpp -SOURCES += input/snesmouse.cpp -SOURCES += input/suborkb.cpp -SOURCES += input/toprider.cpp -SOURCES += input/virtualboy.cpp -SOURCES += input/zapper.cpp -SOURCES += utils/backward.cpp -SOURCES += utils/ConvertUTF.c -SOURCES += utils/xstring.cpp -SOURCES += utils/crc32.cpp -SOURCES += utils/endian.cpp -SOURCES += utils/general.cpp -SOURCES += utils/guid.cpp -SOURCES += utils/md5.cpp -SOURCES += utils/memory.cpp -SOURCES += drivers/common/args.cpp -SOURCES += drivers/common/cheat.cpp -SOURCES += drivers/common/config.cpp -SOURCES += drivers/common/configSys.cpp -SOURCES += drivers/common/hq2x.cpp -SOURCES += drivers/common/hq3x.cpp -SOURCES += drivers/common/scale2x.cpp -SOURCES += drivers/common/scale3x.cpp -SOURCES += drivers/common/scalebit.cpp -SOURCES += drivers/common/vidblit.cpp -SOURCES += drivers/common/nes_ntsc.c - -HEADERS += drivers/Qt/GameApp.h -HEADERS += drivers/Qt/GameViewer.h -SOURCES += drivers/Qt/main.cpp -SOURCES += drivers/Qt/GameApp.cpp -SOURCES += drivers/Qt/GameViewer.cpp -SOURCES += drivers/Qt/fceuWrapper.cpp -SOURCES += drivers/Qt/config.cpp -SOURCES += drivers/Qt/input.cpp -SOURCES += drivers/Qt/gl_win.cpp -SOURCES += drivers/Qt/sdl-sound.cpp -SOURCES += drivers/Qt/sdl-video.cpp -SOURCES += drivers/Qt/sdl-joystick.cpp -SOURCES += drivers/Qt/sdl-throttle.cpp -SOURCES += drivers/Qt/unix-netplay.cpp - From f1153bfc6bf0701f35045f6f411de94b97e553cb Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Fri, 26 Jun 2020 09:29:47 -0400 Subject: [PATCH 014/100] Successful test of loading ROM via QFileDialog, changed logic to not use native gnome file dialog as it is very lagged. --- src/drivers/Qt/GameApp.cpp | 58 ++++++++-- src/drivers/Qt/GameApp.h | 4 +- src/drivers/Qt/input.cpp | 224 ++++++++++++++++++------------------- 3 files changed, 165 insertions(+), 121 deletions(-) diff --git a/src/drivers/Qt/GameApp.cpp b/src/drivers/Qt/GameApp.cpp index c7e7078e..e2b40b9e 100644 --- a/src/drivers/Qt/GameApp.cpp +++ b/src/drivers/Qt/GameApp.cpp @@ -1,5 +1,7 @@ // GameApp.cpp // +#include + #include "GameApp.h" #include "fceuWrapper.h" #include "keyscan.h" @@ -55,12 +57,12 @@ void gameWin_t::createMainMenu(void) menuBar()->setNativeMenuBar(false); fileMenu = menuBar()->addMenu(tr("&File")); - openAct = new QAction(tr("&Open"), this); - openAct->setShortcuts(QKeySequence::Open); - openAct->setStatusTip(tr("Open an Existing File")); - connect(openAct, SIGNAL(triggered()), this, SLOT(openFile(void)) ); + openROM = new QAction(tr("&Open ROM"), this); + openROM->setShortcuts(QKeySequence::Open); + openROM->setStatusTip(tr("Open ROM File")); + connect(openROM, SIGNAL(triggered()), this, SLOT(openROMFile(void)) ); - fileMenu->addAction(openAct); + fileMenu->addAction(openROM); quitAct = new QAction(tr("&Quit"), this); quitAct->setStatusTip(tr("Quit the Application")); @@ -77,9 +79,51 @@ void gameWin_t::createMainMenu(void) helpMenu->addAction(aboutAct); }; -void gameWin_t::openFile(void) +void gameWin_t::openROMFile(void) { - printf("Open File\n"); + int ret; + QString filename; + QFileDialog dialog(this); + + dialog.setFileMode(QFileDialog::ExistingFile); + + dialog.setNameFilter(tr("All files (*.*) ;; NES files (*.nes)")); + + dialog.setViewMode(QFileDialog::List); + + // the gnome default file dialog is not playing nice with QT. + // TODO make this a config option to use native file dialog. + dialog.setOption(QFileDialog::DontUseNativeDialog, true); + + dialog.show(); + ret = dialog.exec(); + + if ( ret ) + { + QStringList fileList; + fileList = dialog.selectedFiles(); + + if ( fileList.size() > 0 ) + { + filename = fileList[0]; + } + } + + //filename = QFileDialog::getOpenFileName( this, + // "Open ROM File", + // QDir::currentPath(), + // "All files (*.*) ;; NES files (*.nes)"); + + if ( filename.isNull() ) + { + return; + } + qDebug() << "selected file path : " << filename.toUtf8(); + + g_config->setOption ("SDL.LastOpenFile", filename.toStdString().c_str() ); + CloseGame (); + LoadGame ( filename.toStdString().c_str() ); + return; } void gameWin_t::aboutQPlot(void) diff --git a/src/drivers/Qt/GameApp.h b/src/drivers/Qt/GameApp.h index 579fe782..3ec3d6f9 100644 --- a/src/drivers/Qt/GameApp.h +++ b/src/drivers/Qt/GameApp.h @@ -32,7 +32,7 @@ class gameWin_t : public QMainWindow QMenu *fileMenu; QMenu *helpMenu; - QAction *openAct; + QAction *openROM; QAction *quitAct; QAction *aboutAct; @@ -46,7 +46,7 @@ class gameWin_t : public QMainWindow void createMainMenu(void); private slots: - void openFile(void); + void openROMFile(void); void aboutQPlot(void); void runGameFrame(void); diff --git a/src/drivers/Qt/input.cpp b/src/drivers/Qt/input.cpp index 0dc2f1af..701e9e0b 100644 --- a/src/drivers/Qt/input.cpp +++ b/src/drivers/Qt/input.cpp @@ -251,58 +251,58 @@ std::string GetFilename (const char *title, bool save, const char *filter) fname = GetOpenFileName (&ofn); #endif -#ifdef _GTK - int fullscreen = 0; - g_config->getOption ("SDL.Fullscreen", &fullscreen); - if (fullscreen) - ToggleFS (); - - GtkWidget *fileChooser; - - GtkFileFilter *filterX; - GtkFileFilter *filterAll; - - filterX = gtk_file_filter_new (); - gtk_file_filter_add_pattern (filterX, filter); - gtk_file_filter_set_name (filterX, filter); - - - filterAll = gtk_file_filter_new (); - gtk_file_filter_add_pattern (filterAll, "*"); - gtk_file_filter_set_name (filterAll, "All Files"); - - if (save) - fileChooser = gtk_file_chooser_dialog_new ("Save as", NULL, - GTK_FILE_CHOOSER_ACTION_SAVE, - "_Cancel", - GTK_RESPONSE_CANCEL, - "_Save", - GTK_RESPONSE_ACCEPT, NULL); - else - fileChooser = gtk_file_chooser_dialog_new ("Open", NULL, - GTK_FILE_CHOOSER_ACTION_OPEN, - "_Cancel", - GTK_RESPONSE_CANCEL, - "_Open", - GTK_RESPONSE_ACCEPT, NULL); - - // TODO: make file filters case insensitive - //gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterX); - gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (fileChooser), filterAll); - int response = gtk_dialog_run (GTK_DIALOG (fileChooser)); - - // flush gtk events - while (gtk_events_pending ()) - gtk_main_iteration_do (TRUE); - - if (response == GTK_RESPONSE_ACCEPT) - fname = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fileChooser)); - - gtk_widget_destroy (fileChooser); - - while (gtk_events_pending ()) - gtk_main_iteration_do (TRUE); -#endif +//#ifdef _GTK +// int fullscreen = 0; +// g_config->getOption ("SDL.Fullscreen", &fullscreen); +// if (fullscreen) +// ToggleFS (); +// +// GtkWidget *fileChooser; +// +// GtkFileFilter *filterX; +// GtkFileFilter *filterAll; +// +// filterX = gtk_file_filter_new (); +// gtk_file_filter_add_pattern (filterX, filter); +// gtk_file_filter_set_name (filterX, filter); +// +// +// filterAll = gtk_file_filter_new (); +// gtk_file_filter_add_pattern (filterAll, "*"); +// gtk_file_filter_set_name (filterAll, "All Files"); +// +// if (save) +// fileChooser = gtk_file_chooser_dialog_new ("Save as", NULL, +// GTK_FILE_CHOOSER_ACTION_SAVE, +// "_Cancel", +// GTK_RESPONSE_CANCEL, +// "_Save", +// GTK_RESPONSE_ACCEPT, NULL); +// else +// fileChooser = gtk_file_chooser_dialog_new ("Open", NULL, +// GTK_FILE_CHOOSER_ACTION_OPEN, +// "_Cancel", +// GTK_RESPONSE_CANCEL, +// "_Open", +// GTK_RESPONSE_ACCEPT, NULL); +// +// // TODO: make file filters case insensitive +// //gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser), filterX); +// gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (fileChooser), filterAll); +// int response = gtk_dialog_run (GTK_DIALOG (fileChooser)); +// +// // flush gtk events +// while (gtk_events_pending ()) +// gtk_main_iteration_do (TRUE); +// +// if (response == GTK_RESPONSE_ACCEPT) +// fname = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fileChooser)); +// +// gtk_widget_destroy (fileChooser); +// +// while (gtk_events_pending ()) +// gtk_main_iteration_do (TRUE); +//#endif FCEUI_ToggleEmulationPause (); return fname; } @@ -319,62 +319,62 @@ std::string GetUserText (const char *title) * TODO fix it */ #if 0 - - GtkWidget* d; - GtkWidget* entry; - - d = gtk_dialog_new_with_buttons(title, NULL, GTK_DIALOG_MODAL, GTK_STOCK_OK, GTK_RESPONSE_OK); - - entry = gtk_entry_new(); - - GtkWidget* vbox = gtk_dialog_get_content_area(GTK_DIALOG(d)); - - gtk_container_add(GTK_CONTAINER(vbox), entry); - - gtk_widget_show_all(d); - - gtk_dialog_run(GTK_DIALOG(d)); - - // flush gtk events - while(gtk_events_pending()) - gtk_main_iteration_do(TRUE); - - std::string input = gtk_entry_get_text(GTK_ENTRY(entry)); - - if (FCEUI_EmulationPaused() == 0) - FCEUI_ToggleEmulationPause(); // pause emulation - - int fullscreen = 0; - g_config->getOption("SDL.Fullscreen", &fullscreen); - if(fullscreen) - ToggleFS(); // disable fullscreen emulation - - FILE *fpipe; - std::string command = "zenity --entry --title=\""; - command.append(title); - command.append("\" --text=\""); - command.append(title); - command.append(":\""); - - if (!(fpipe = (FILE*)popen(command.c_str(),"r"))) // If fpipe is NULL - FCEUD_PrintError("Pipe error on opening zenity"); - int c; - std::string input; - while((c = fgetc(fpipe))) - { - if (c == EOF || c == '\n') - break; - input += c; - } - pclose(fpipe); - gtk_widget_destroy(d); - - - while(gtk_events_pending()) - gtk_main_iteration_do(TRUE); - - FCEUI_ToggleEmulationPause(); // unpause emulation - return input; +// +// GtkWidget* d; +// GtkWidget* entry; +// +// d = gtk_dialog_new_with_buttons(title, NULL, GTK_DIALOG_MODAL, GTK_STOCK_OK, GTK_RESPONSE_OK); +// +// entry = gtk_entry_new(); +// +// GtkWidget* vbox = gtk_dialog_get_content_area(GTK_DIALOG(d)); +// +// gtk_container_add(GTK_CONTAINER(vbox), entry); +// +// gtk_widget_show_all(d); +// +// gtk_dialog_run(GTK_DIALOG(d)); +// +// // flush gtk events +// while(gtk_events_pending()) +// gtk_main_iteration_do(TRUE); +// +// std::string input = gtk_entry_get_text(GTK_ENTRY(entry)); +// +// if (FCEUI_EmulationPaused() == 0) +// FCEUI_ToggleEmulationPause(); // pause emulation +// +// int fullscreen = 0; +// g_config->getOption("SDL.Fullscreen", &fullscreen); +// if(fullscreen) +// ToggleFS(); // disable fullscreen emulation +// +// FILE *fpipe; +// std::string command = "zenity --entry --title=\""; +// command.append(title); +// command.append("\" --text=\""); +// command.append(title); +// command.append(":\""); +// +// if (!(fpipe = (FILE*)popen(command.c_str(),"r"))) // If fpipe is NULL +// FCEUD_PrintError("Pipe error on opening zenity"); +// int c; +// std::string input; +// while((c = fgetc(fpipe))) +// { +// if (c == EOF || c == '\n') +// break; +// input += c; +// } +// pclose(fpipe); +// gtk_widget_destroy(d); +// +// +// while(gtk_events_pending()) +// gtk_main_iteration_do(TRUE); +// +// FCEUI_ToggleEmulationPause(); // unpause emulation +// return input; #endif // #if 0 #endif return ""; @@ -1643,10 +1643,10 @@ int DWaitButton (const uint8 * text, ButtConfig * bc, int wb, int *buttonConfigS while (1) { int done = 0; -#ifdef _GTK - while (gtk_events_pending ()) - gtk_main_iteration_do (FALSE); -#endif +//#ifdef _GTK +// while (gtk_events_pending ()) +// gtk_main_iteration_do (FALSE); +//#endif while (SDL_PollEvent (&event)) { done++; From ee02883ac7e9a0c2c379d58ed59660f7e947d156 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Fri, 26 Jun 2020 12:46:48 -0400 Subject: [PATCH 015/100] QT gamepad window in work. --- fceux.pro | 2 ++ src/drivers/Qt/GameApp.cpp | 45 +++++++++++++++++++++++++++++++++- src/drivers/Qt/GameApp.h | 5 ++++ src/drivers/Qt/GamePadConf.cpp | 40 ++++++++++++++++++++++++++++++ src/drivers/Qt/GamePadConf.h | 28 +++++++++++++++++++++ 5 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 src/drivers/Qt/GamePadConf.cpp create mode 100644 src/drivers/Qt/GamePadConf.h diff --git a/fceux.pro b/fceux.pro index 615bf636..ab80964c 100644 --- a/fceux.pro +++ b/fceux.pro @@ -292,9 +292,11 @@ SOURCES += src/drivers/common/nes_ntsc.c HEADERS += src/drivers/Qt/GameApp.h HEADERS += src/drivers/Qt/GameViewer.h +HEADERS += src/drivers/Qt/GamePadConf.h SOURCES += src/drivers/Qt/main.cpp SOURCES += src/drivers/Qt/GameApp.cpp SOURCES += src/drivers/Qt/GameViewer.cpp +SOURCES += src/drivers/Qt/GamePadConf.cpp SOURCES += src/drivers/Qt/fceuWrapper.cpp SOURCES += src/drivers/Qt/config.cpp SOURCES += src/drivers/Qt/input.cpp diff --git a/src/drivers/Qt/GameApp.cpp b/src/drivers/Qt/GameApp.cpp index e2b40b9e..25d2e07a 100644 --- a/src/drivers/Qt/GameApp.cpp +++ b/src/drivers/Qt/GameApp.cpp @@ -3,6 +3,7 @@ #include #include "GameApp.h" +#include "GamePadConf.h" #include "fceuWrapper.h" #include "keyscan.h" @@ -54,9 +55,14 @@ void gameWin_t::keyReleaseEvent(QKeyEvent *event) void gameWin_t::createMainMenu(void) { + // This is needed for menu bar to show up on MacOS menuBar()->setNativeMenuBar(false); + + //----------------------------------------------------------------------- + // File fileMenu = menuBar()->addMenu(tr("&File")); + // File -> Open ROM openROM = new QAction(tr("&Open ROM"), this); openROM->setShortcuts(QKeySequence::Open); openROM->setStatusTip(tr("Open ROM File")); @@ -64,12 +70,37 @@ void gameWin_t::createMainMenu(void) fileMenu->addAction(openROM); + // File -> Close ROM + closeROM = new QAction(tr("&Close ROM"), this); + closeROM->setShortcut( QKeySequence(tr("Ctrl+C"))); + closeROM->setStatusTip(tr("Close Loaded ROM")); + connect(closeROM, SIGNAL(triggered()), this, SLOT(closeROMCB(void)) ); + + fileMenu->addAction(closeROM); + + fileMenu->addSeparator(); + + // File -> Quit quitAct = new QAction(tr("&Quit"), this); quitAct->setStatusTip(tr("Quit the Application")); connect(quitAct, SIGNAL(triggered()), qApp, SLOT(quit())); fileMenu->addAction(quitAct); + //----------------------------------------------------------------------- + // Options + optMenu = menuBar()->addMenu(tr("&Options")); + + // Options -> GamePad Config + gamePadConfig = new QAction(tr("&GamePad Config"), this); + //gamePadConfig->setShortcut( QKeySequence(tr("Ctrl+C"))); + gamePadConfig->setStatusTip(tr("GamePad Configure")); + connect(gamePadConfig, SIGNAL(triggered()), this, SLOT(openGamePadConfWin(void)) ); + + optMenu->addAction(gamePadConfig); + + //----------------------------------------------------------------------- + // Help helpMenu = menuBar()->addMenu(tr("&Help")); aboutAct = new QAction(tr("&About"), this); @@ -83,7 +114,7 @@ void gameWin_t::openROMFile(void) { int ret; QString filename; - QFileDialog dialog(this); + QFileDialog dialog(this, "Open ROM File"); dialog.setFileMode(QFileDialog::ExistingFile); @@ -126,6 +157,18 @@ void gameWin_t::openROMFile(void) return; } + +void gameWin_t::closeROMCB(void) +{ + CloseGame(); +} + +void gameWin_t::openGamePadConfWin(void) +{ + printf("Open GamePad Config Window\n"); + GamePadConfDialog_t gpConf(this); +} + void gameWin_t::aboutQPlot(void) { printf("About QPlot\n"); diff --git a/src/drivers/Qt/GameApp.h b/src/drivers/Qt/GameApp.h index 3ec3d6f9..5dafcfff 100644 --- a/src/drivers/Qt/GameApp.h +++ b/src/drivers/Qt/GameApp.h @@ -30,10 +30,13 @@ class gameWin_t : public QMainWindow // QMenu *fileMenu; + QMenu *optMenu; QMenu *helpMenu; QAction *openROM; + QAction *closeROM; QAction *quitAct; + QAction *gamePadConfig; QAction *aboutAct; QTimer *gameTimer; @@ -47,7 +50,9 @@ class gameWin_t : public QMainWindow private slots: void openROMFile(void); + void closeROMCB(void); void aboutQPlot(void); + void openGamePadConfWin(void); void runGameFrame(void); }; diff --git a/src/drivers/Qt/GamePadConf.cpp b/src/drivers/Qt/GamePadConf.cpp new file mode 100644 index 00000000..c056e137 --- /dev/null +++ b/src/drivers/Qt/GamePadConf.cpp @@ -0,0 +1,40 @@ +// GamePadConf.cpp +// +#include "GamePadConf.h" + +//---------------------------------------------------- +GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) + : QDialog( parent ) +{ + QHBoxLayout *hbox1, *hbox2; + QCheckBox *efs_chkbox; + + hbox1 = new QHBoxLayout(); + + QLabel *label = new QLabel(tr("Port:")); + portSel = new QComboBox(); + hbox1->addWidget( label ); + hbox1->addWidget( portSel ); + + hbox2 = new QHBoxLayout(); + efs_chkbox = new QCheckBox("Enable Four Score"); + hbox2->addWidget( efs_chkbox ); + + QVBoxLayout *mainLayout = new QVBoxLayout(); + + mainLayout->addLayout( hbox1 ); + mainLayout->addWidget( efs_chkbox ); + //mainLayout->addLayout( hbox2 ); + + setLayout( mainLayout ); + + show(); + exec(); +} + +//---------------------------------------------------- +GamePadConfDialog_t::~GamePadConfDialog_t(void) +{ + +} +//---------------------------------------------------- diff --git a/src/drivers/Qt/GamePadConf.h b/src/drivers/Qt/GamePadConf.h new file mode 100644 index 00000000..62962b3d --- /dev/null +++ b/src/drivers/Qt/GamePadConf.h @@ -0,0 +1,28 @@ +// GamePadConf.h +// + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +class GamePadConfDialog_t : public QDialog +{ + public: + GamePadConfDialog_t(QWidget *parent = 0); + ~GamePadConfDialog_t(void); + + protected: + QComboBox *portSel; + + + + private slots: + +}; From 002e9e0f34819dc89b013b62c7fab8c4fbf0f57d Mon Sep 17 00:00:00 2001 From: mjbudd77 Date: Fri, 26 Jun 2020 16:35:41 -0400 Subject: [PATCH 016/100] Added logic to configure gamepad buttons. Still needs more testing. --- src/drivers/Qt/GameApp.cpp | 43 +++++-- src/drivers/Qt/GameApp.h | 4 + src/drivers/Qt/GamePadConf.cpp | 206 +++++++++++++++++++++++++++++++-- src/drivers/Qt/GamePadConf.h | 24 ++++ src/drivers/Qt/input.cpp | 22 +++- 5 files changed, 283 insertions(+), 16 deletions(-) diff --git a/src/drivers/Qt/GameApp.cpp b/src/drivers/Qt/GameApp.cpp index 25d2e07a..3b05e458 100644 --- a/src/drivers/Qt/GameApp.cpp +++ b/src/drivers/Qt/GameApp.cpp @@ -32,24 +32,41 @@ gameWin_t::gameWin_t(QWidget *parent) gameTimer->setTimerType( Qt::PreciseTimer ); gameTimer->start( 10 ); + + gamePadConfWin = NULL; } gameWin_t::~gameWin_t(void) { + if ( gamePadConfWin != NULL ) + { + gamePadConfWin->closeWindow(); + } fceuWrapperClose(); delete viewport; } +void gameWin_t::closeEvent(QCloseEvent *event) +{ + printf("Main Window Close Event\n"); + if ( gamePadConfWin != NULL ) + { + printf("Command Game Pad Close\n"); + gamePadConfWin->closeWindow(); + } + event->accept(); +} + void gameWin_t::keyPressEvent(QKeyEvent *event) { - //printf("Key Press: 0x%x \n", event->key() ); + printf("Key Press: 0x%x \n", event->key() ); pushKeyEvent( event, 1 ); } void gameWin_t::keyReleaseEvent(QKeyEvent *event) { - //printf("Key Release: 0x%x \n", event->key() ); + printf("Key Release: 0x%x \n", event->key() ); pushKeyEvent( event, 0 ); } @@ -165,8 +182,20 @@ void gameWin_t::closeROMCB(void) void gameWin_t::openGamePadConfWin(void) { + if ( gamePadConfWin != NULL ) + { + printf("GamePad Config Window Already Open\n"); + return; + } printf("Open GamePad Config Window\n"); - GamePadConfDialog_t gpConf(this); + gamePadConfWin = new GamePadConfDialog_t(this); + + gamePadConfWin->show(); + gamePadConfWin->exec(); + + delete gamePadConfWin; + gamePadConfWin = NULL; + printf("GamePad Config Window Destroyed\n"); } void gameWin_t::aboutQPlot(void) @@ -177,12 +206,12 @@ void gameWin_t::aboutQPlot(void) void gameWin_t::runGameFrame(void) { - struct timespec ts; - double t; + //struct timespec ts; + //double t; - clock_gettime( CLOCK_REALTIME, &ts ); + //clock_gettime( CLOCK_REALTIME, &ts ); - t = (double)ts.tv_sec + (double)(ts.tv_nsec * 1.0e-9); + //t = (double)ts.tv_sec + (double)(ts.tv_nsec * 1.0e-9); //printf("Run Frame %f\n", t); fceuWrapperUpdate(); diff --git a/src/drivers/Qt/GameApp.h b/src/drivers/Qt/GameApp.h index 5dafcfff..258bfa77 100644 --- a/src/drivers/Qt/GameApp.h +++ b/src/drivers/Qt/GameApp.h @@ -16,6 +16,7 @@ #include #include "GameViewer.h" +#include "GamePadConf.h" class gameWin_t : public QMainWindow { @@ -41,7 +42,10 @@ class gameWin_t : public QMainWindow QTimer *gameTimer; + GamePadConfDialog_t *gamePadConfWin; + protected: + void closeEvent(QCloseEvent *event); void keyPressEvent(QKeyEvent *event); void keyReleaseEvent(QKeyEvent *event); diff --git a/src/drivers/Qt/GamePadConf.cpp b/src/drivers/Qt/GamePadConf.cpp index c056e137..9d155df0 100644 --- a/src/drivers/Qt/GamePadConf.cpp +++ b/src/drivers/Qt/GamePadConf.cpp @@ -1,13 +1,26 @@ // GamePadConf.cpp // #include "GamePadConf.h" +#include "main.h" +#include "input.h" +#include "config.h" +#include "keyscan.h" +#include "fceuWrapper.h" //---------------------------------------------------- GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) : QDialog( parent ) { - QHBoxLayout *hbox1, *hbox2; - QCheckBox *efs_chkbox; + QHBoxLayout *hbox1; + QGridLayout *grid; + QCheckBox *efs_chkbox, *udlr_chkbox; + QGroupBox *frame; + QPushButton *closebutton; + + portNum = 0; + buttonConfigStatus = 1; + + setWindowTitle("GamePad Config"); hbox1 = new QHBoxLayout(); @@ -16,25 +29,202 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) hbox1->addWidget( label ); hbox1->addWidget( portSel ); - hbox2 = new QHBoxLayout(); - efs_chkbox = new QCheckBox("Enable Four Score"); - hbox2->addWidget( efs_chkbox ); + portSel->addItem( tr("1"), 0 ); + portSel->addItem( tr("2"), 1 ); + portSel->addItem( tr("3"), 2 ); + portSel->addItem( tr("4"), 3 ); + + efs_chkbox = new QCheckBox("Enable Four Score"); + udlr_chkbox = new QCheckBox("Allow Up+Down/Left+Right"); + + frame = new QGroupBox(tr("Buttons:")); + grid = new QGridLayout(); + + grid-> setHorizontalSpacing(50); + + //frame->setFrameStyle( QFrame::Box ); + frame->setLayout( grid ); + + for (int i=0; i<10; i++) + { + char text[64]; + const char *keyNameStr; + QLabel *buttonName; + + sprintf( text, "%s:", GamePadNames[i] ); + + //hbox2 = new QHBoxLayout(); + + //hbox2->setAlignment(Qt::AlignCenter); + + keyNameStr = ButtonName( &GamePadConfig[portNum][i], portNum ); + + buttonName = new QLabel(tr(text)); + keyName[i] = new QLabel(tr(keyNameStr)); + button[i] = new QPushButton(tr("Change")); + + grid->addWidget( buttonName, i, 0, Qt::AlignCenter ); + grid->addWidget( keyName[i], i, 1, Qt::AlignCenter ); + grid->addWidget( button[i] , i, 2, Qt::AlignCenter ); + } + closebutton = new QPushButton(tr("Close")); + + connect(button[0], SIGNAL(clicked()), this, SLOT(changeButton0(void)) ); + connect(button[1], SIGNAL(clicked()), this, SLOT(changeButton1(void)) ); + connect(button[2], SIGNAL(clicked()), this, SLOT(changeButton2(void)) ); + connect(button[3], SIGNAL(clicked()), this, SLOT(changeButton3(void)) ); + connect(button[4], SIGNAL(clicked()), this, SLOT(changeButton4(void)) ); + connect(button[5], SIGNAL(clicked()), this, SLOT(changeButton5(void)) ); + connect(button[6], SIGNAL(clicked()), this, SLOT(changeButton6(void)) ); + connect(button[7], SIGNAL(clicked()), this, SLOT(changeButton7(void)) ); + connect(button[8], SIGNAL(clicked()), this, SLOT(changeButton8(void)) ); + connect(button[9], SIGNAL(clicked()), this, SLOT(changeButton9(void)) ); + connect(closebutton, SIGNAL(clicked()), this, SLOT(closeWindow(void)) ); QVBoxLayout *mainLayout = new QVBoxLayout(); mainLayout->addLayout( hbox1 ); mainLayout->addWidget( efs_chkbox ); - //mainLayout->addLayout( hbox2 ); + mainLayout->addWidget( udlr_chkbox ); + mainLayout->addWidget( frame ); + mainLayout->addWidget( closebutton, Qt::AlignRight ); setLayout( mainLayout ); - show(); - exec(); + //show(); + //exec(); + } //---------------------------------------------------- GamePadConfDialog_t::~GamePadConfDialog_t(void) { + buttonConfigStatus = 0; +} +void GamePadConfDialog_t::keyPressEvent(QKeyEvent *event) +{ + //printf("Key Press: 0x%x \n", event->key() ); + pushKeyEvent( event, 1 ); +} +void GamePadConfDialog_t::keyReleaseEvent(QKeyEvent *event) +{ + //printf("Key Release: 0x%x \n", event->key() ); + pushKeyEvent( event, 0 ); +} +//---------------------------------------------------- +void GamePadConfDialog_t::changeButton(int padNo, int x) +{ + int configNo = 0; + char buf[256]; + std::string prefix; + const char *keyNameStr; + + if ( buttonConfigStatus == 2 ) + { + buttonConfigStatus = 0; + return; + } + buttonConfigStatus = 2; + + ButtonConfigBegin (); + + button[x]->setText("Waiting" ); + + snprintf (buf, sizeof(buf)-1, "SDL.Input.GamePad.%d.", padNo); + prefix = buf; + DWaitButton (NULL, &GamePadConfig[padNo][x], configNo, &buttonConfigStatus ); + + g_config->setOption (prefix + GamePadNames[x], + GamePadConfig[padNo][x].ButtonNum[configNo]); + + if (GamePadConfig[padNo][x].ButtType[0] == BUTTC_KEYBOARD) + { + g_config->setOption (prefix + "DeviceType", "Keyboard"); + } + else if (GamePadConfig[padNo][x].ButtType[0] == BUTTC_JOYSTICK) + { + g_config->setOption (prefix + "DeviceType", "Joystick"); + } + else + { + g_config->setOption (prefix + "DeviceType", "Unknown"); + } + g_config->setOption (prefix + "DeviceNum", + GamePadConfig[padNo][x].DeviceNum[configNo]); + + keyNameStr = ButtonName( &GamePadConfig[padNo][x], padNo ); + + keyName[x]->setText( keyNameStr ); + button[x]->setText("Change"); + + ButtonConfigEnd (); + + buttonConfigStatus = 1; +} +//---------------------------------------------------- +void GamePadConfDialog_t::closeEvent(QCloseEvent *event) +{ + printf("GamePad Close Window Event\n"); + buttonConfigStatus = 0; + done(0); + event->accept(); +} +//---------------------------------------------------- +void GamePadConfDialog_t::closeWindow(void) +{ + printf("Close Window\n"); + buttonConfigStatus = 0; + done(0); +} +//---------------------------------------------------- +void GamePadConfDialog_t::changeButton0(void) +{ + changeButton( portNum, 0 ); +} +//---------------------------------------------------- +void GamePadConfDialog_t::changeButton1(void) +{ + changeButton( portNum, 1 ); +} +//---------------------------------------------------- +void GamePadConfDialog_t::changeButton2(void) +{ + changeButton( portNum, 2 ); +} +//---------------------------------------------------- +void GamePadConfDialog_t::changeButton3(void) +{ + changeButton( portNum, 3 ); +} +//---------------------------------------------------- +void GamePadConfDialog_t::changeButton4(void) +{ + changeButton( portNum, 4 ); +} +//---------------------------------------------------- +void GamePadConfDialog_t::changeButton5(void) +{ + changeButton( portNum, 5 ); +} +//---------------------------------------------------- +void GamePadConfDialog_t::changeButton6(void) +{ + changeButton( portNum, 6 ); +} +//---------------------------------------------------- +void GamePadConfDialog_t::changeButton7(void) +{ + changeButton( portNum, 7 ); +} +//---------------------------------------------------- +void GamePadConfDialog_t::changeButton8(void) +{ + changeButton( portNum, 8 ); +} +//---------------------------------------------------- +void GamePadConfDialog_t::changeButton9(void) +{ + changeButton( portNum, 9 ); } //---------------------------------------------------- diff --git a/src/drivers/Qt/GamePadConf.h b/src/drivers/Qt/GamePadConf.h index 62962b3d..e7dd6cc5 100644 --- a/src/drivers/Qt/GamePadConf.h +++ b/src/drivers/Qt/GamePadConf.h @@ -11,18 +11,42 @@ #include #include #include +#include +#include class GamePadConfDialog_t : public QDialog { + Q_OBJECT + public: GamePadConfDialog_t(QWidget *parent = 0); ~GamePadConfDialog_t(void); protected: QComboBox *portSel; + QPushButton *button[10]; + QLabel *keyName[10]; + int portNum; + int buttonConfigStatus; + void changeButton( int port, int button ); + void keyPressEvent(QKeyEvent *event); + void keyReleaseEvent(QKeyEvent *event); + void closeEvent(QCloseEvent *bar); + public slots: + void closeWindow(void); private slots: + void changeButton0(void); + void changeButton1(void); + void changeButton2(void); + void changeButton3(void); + void changeButton4(void); + void changeButton5(void); + void changeButton6(void); + void changeButton7(void); + void changeButton8(void); + void changeButton9(void); }; diff --git a/src/drivers/Qt/input.cpp b/src/drivers/Qt/input.cpp index 701e9e0b..a95bec6f 100644 --- a/src/drivers/Qt/input.cpp +++ b/src/drivers/Qt/input.cpp @@ -52,6 +52,7 @@ extern bool bindSavestate, frameAdvanceLagSkip, lagCounterDisplay; static int UsrInputType[NUM_INPUT_DEVICES]; static int CurInputType[NUM_INPUT_DEVICES]; static int cspec = 0; +static int buttonConfigInProgress = 0; extern int gametype; @@ -963,7 +964,7 @@ UpdatePhysicalInput () } -static int bcpv, bcpj; +static int bcpv=0, bcpj=0; /** * Begin configuring the buttons by placing the video and joystick @@ -981,6 +982,8 @@ int ButtonConfigBegin () // initialize the joystick subsystem InitJoysticks (); + buttonConfigInProgress = 1; + return 1; } @@ -1004,6 +1007,7 @@ ButtonConfigEnd () { InitJoysticks (); } + buttonConfigInProgress = 0; } /** @@ -1197,6 +1201,10 @@ void FCEUD_UpdateInput () int x; int t = 0; + if ( buttonConfigInProgress ) + { + return; + } UpdatePhysicalInput (); KeyboardCommands (); @@ -1622,6 +1630,7 @@ int DWaitButton (const uint8 * text, ButtConfig * bc, int wb, int *buttonConfigS SDL_Event event; static int32 LastAx[64][64]; int x, y; + int timeout_ms = 10000; if (text) { @@ -1643,6 +1652,16 @@ int DWaitButton (const uint8 * text, ButtConfig * bc, int wb, int *buttonConfigS while (1) { int done = 0; + + usleep(10000); + timeout_ms -= 10; + + if ( timeout_ms <= 0 ) + { + break; + } + + QCoreApplication::processEvents(); //#ifdef _GTK // while (gtk_events_pending ()) // gtk_main_iteration_do (FALSE); @@ -1653,6 +1672,7 @@ int DWaitButton (const uint8 * text, ButtConfig * bc, int wb, int *buttonConfigS switch (event.type) { case SDL_KEYDOWN: + //printf("SDL KeyDown:%i \n", event.key.keysym.sym ); bc->ButtType[wb] = BUTTC_KEYBOARD; bc->DeviceNum[wb] = 0; bc->ButtonNum[wb] = event.key.keysym.sym; From 950004503bda26f0827cbcf604b4877e0748d171 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Fri, 26 Jun 2020 20:27:20 -0400 Subject: [PATCH 017/100] Hooked up checkboxes on gamepad config page. --- src/drivers/Qt/GameApp.cpp | 12 ++++---- src/drivers/Qt/GamePadConf.cpp | 56 +++++++++++++++++++++++++++++----- src/drivers/Qt/GamePadConf.h | 16 +++++++++- 3 files changed, 69 insertions(+), 15 deletions(-) diff --git a/src/drivers/Qt/GameApp.cpp b/src/drivers/Qt/GameApp.cpp index 3b05e458..2c291ce9 100644 --- a/src/drivers/Qt/GameApp.cpp +++ b/src/drivers/Qt/GameApp.cpp @@ -49,10 +49,10 @@ gameWin_t::~gameWin_t(void) void gameWin_t::closeEvent(QCloseEvent *event) { - printf("Main Window Close Event\n"); + //printf("Main Window Close Event\n"); if ( gamePadConfWin != NULL ) { - printf("Command Game Pad Close\n"); + //printf("Command Game Pad Close\n"); gamePadConfWin->closeWindow(); } event->accept(); @@ -60,13 +60,13 @@ void gameWin_t::closeEvent(QCloseEvent *event) void gameWin_t::keyPressEvent(QKeyEvent *event) { - printf("Key Press: 0x%x \n", event->key() ); + //printf("Key Press: 0x%x \n", event->key() ); pushKeyEvent( event, 1 ); } void gameWin_t::keyReleaseEvent(QKeyEvent *event) { - printf("Key Release: 0x%x \n", event->key() ); + //printf("Key Release: 0x%x \n", event->key() ); pushKeyEvent( event, 0 ); } @@ -187,7 +187,7 @@ void gameWin_t::openGamePadConfWin(void) printf("GamePad Config Window Already Open\n"); return; } - printf("Open GamePad Config Window\n"); + //printf("Open GamePad Config Window\n"); gamePadConfWin = new GamePadConfDialog_t(this); gamePadConfWin->show(); @@ -195,7 +195,7 @@ void gameWin_t::openGamePadConfWin(void) delete gamePadConfWin; gamePadConfWin = NULL; - printf("GamePad Config Window Destroyed\n"); + //printf("GamePad Config Window Destroyed\n"); } void gameWin_t::aboutQPlot(void) diff --git a/src/drivers/Qt/GamePadConf.cpp b/src/drivers/Qt/GamePadConf.cpp index 9d155df0..f112b29c 100644 --- a/src/drivers/Qt/GamePadConf.cpp +++ b/src/drivers/Qt/GamePadConf.cpp @@ -37,6 +37,14 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) efs_chkbox = new QCheckBox("Enable Four Score"); udlr_chkbox = new QCheckBox("Allow Up+Down/Left+Right"); + int fourScore; + g_config->getOption("SDL.FourScore", &fourScore); + efs_chkbox->setChecked( fourScore ); + + int opposite_dirs; + g_config->getOption("SDL.Input.EnableOppositeDirectionals", &opposite_dirs); + udlr_chkbox->setChecked( opposite_dirs ); + frame = new QGroupBox(tr("Buttons:")); grid = new QGridLayout(); @@ -61,7 +69,7 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) buttonName = new QLabel(tr(text)); keyName[i] = new QLabel(tr(keyNameStr)); - button[i] = new QPushButton(tr("Change")); + button[i] = new GamePadConfigButton_t(i); grid->addWidget( buttonName, i, 0, Qt::AlignCenter ); grid->addWidget( keyName[i], i, 1, Qt::AlignCenter ); @@ -81,6 +89,9 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) connect(button[9], SIGNAL(clicked()), this, SLOT(changeButton9(void)) ); connect(closebutton, SIGNAL(clicked()), this, SLOT(closeWindow(void)) ); + connect(efs_chkbox , SIGNAL(stateChanged(int)), this, SLOT(ena4score(int)) ); + connect(udlr_chkbox, SIGNAL(stateChanged(int)), this, SLOT(oppDirEna(int)) ); + QVBoxLayout *mainLayout = new QVBoxLayout(); mainLayout->addLayout( hbox1 ); @@ -91,9 +102,6 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) setLayout( mainLayout ); - //show(); - //exec(); - } //---------------------------------------------------- @@ -103,16 +111,30 @@ GamePadConfDialog_t::~GamePadConfDialog_t(void) } void GamePadConfDialog_t::keyPressEvent(QKeyEvent *event) { - //printf("Key Press: 0x%x \n", event->key() ); + //printf("GamePad Window Key Press: 0x%x \n", event->key() ); pushKeyEvent( event, 1 ); } void GamePadConfDialog_t::keyReleaseEvent(QKeyEvent *event) { - //printf("Key Release: 0x%x \n", event->key() ); + //printf("GamePad Window Key Release: 0x%x \n", event->key() ); pushKeyEvent( event, 0 ); } //---------------------------------------------------- +void GamePadConfDialog_t::ena4score(int state) +{ + int value = (state == Qt::Unchecked) ? 0 : 1; + printf("Set 'SDL.FourScore' = %i\n", value); + g_config->setOption("SDL.FourScore", value); +} +//---------------------------------------------------- +void GamePadConfDialog_t::oppDirEna(int state) +{ + int value = (state == Qt::Unchecked) ? 0 : 1; + //printf("Set 'SDL.Input.EnableOppositeDirectionals' = %i\n", value); + g_config->setOption("SDL.Input.EnableOppositeDirectionals", value); +} +//---------------------------------------------------- void GamePadConfDialog_t::changeButton(int padNo, int x) { int configNo = 0; @@ -165,7 +187,7 @@ void GamePadConfDialog_t::changeButton(int padNo, int x) //---------------------------------------------------- void GamePadConfDialog_t::closeEvent(QCloseEvent *event) { - printf("GamePad Close Window Event\n"); + //printf("GamePad Close Window Event\n"); buttonConfigStatus = 0; done(0); event->accept(); @@ -173,7 +195,7 @@ void GamePadConfDialog_t::closeEvent(QCloseEvent *event) //---------------------------------------------------- void GamePadConfDialog_t::closeWindow(void) { - printf("Close Window\n"); + //printf("Close Window\n"); buttonConfigStatus = 0; done(0); } @@ -228,3 +250,21 @@ void GamePadConfDialog_t::changeButton9(void) changeButton( portNum, 9 ); } //---------------------------------------------------- +GamePadConfigButton_t::GamePadConfigButton_t(int i) +{ + idx = i; + setText("Change"); +} +//---------------------------------------------------- +void GamePadConfigButton_t::keyPressEvent(QKeyEvent *event) +{ + //printf("GamePad Button Key Press: 0x%x \n", event->key() ); + pushKeyEvent( event, 1 ); +} + +void GamePadConfigButton_t::keyReleaseEvent(QKeyEvent *event) +{ + //printf("GamePad Button Key Release: 0x%x \n", event->key() ); + pushKeyEvent( event, 0 ); +} +//---------------------------------------------------- diff --git a/src/drivers/Qt/GamePadConf.h b/src/drivers/Qt/GamePadConf.h index e7dd6cc5..f13cdd5d 100644 --- a/src/drivers/Qt/GamePadConf.h +++ b/src/drivers/Qt/GamePadConf.h @@ -14,6 +14,18 @@ #include #include +class GamePadConfigButton_t : public QPushButton +{ + public: + GamePadConfigButton_t(int i); + + protected: + void keyPressEvent(QKeyEvent *event); + void keyReleaseEvent(QKeyEvent *event); + + int idx; +}; + class GamePadConfDialog_t : public QDialog { Q_OBJECT @@ -24,8 +36,8 @@ class GamePadConfDialog_t : public QDialog protected: QComboBox *portSel; - QPushButton *button[10]; QLabel *keyName[10]; + GamePadConfigButton_t *button[10]; int portNum; int buttonConfigStatus; @@ -48,5 +60,7 @@ class GamePadConfDialog_t : public QDialog void changeButton7(void); void changeButton8(void); void changeButton9(void); + void ena4score(int state); + void oppDirEna(int state); }; From cb664b44a013c6360b6711cb134376c0d0fe9af1 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Fri, 26 Jun 2020 20:32:44 -0400 Subject: [PATCH 018/100] commented out debug print statement. --- src/drivers/Qt/GamePadConf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/Qt/GamePadConf.cpp b/src/drivers/Qt/GamePadConf.cpp index f112b29c..979258d8 100644 --- a/src/drivers/Qt/GamePadConf.cpp +++ b/src/drivers/Qt/GamePadConf.cpp @@ -124,7 +124,7 @@ void GamePadConfDialog_t::keyReleaseEvent(QKeyEvent *event) void GamePadConfDialog_t::ena4score(int state) { int value = (state == Qt::Unchecked) ? 0 : 1; - printf("Set 'SDL.FourScore' = %i\n", value); + //printf("Set 'SDL.FourScore' = %i\n", value); g_config->setOption("SDL.FourScore", value); } //---------------------------------------------------- From 1980dd8c5b88ec1e0e826e07786d0ba11b98d912 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Fri, 26 Jun 2020 21:56:26 -0400 Subject: [PATCH 019/100] Game Pad calibration page still in work. --- src/drivers/Qt/GameApp.cpp | 20 +++++++++++++++++- src/drivers/Qt/GameApp.h | 1 + src/drivers/Qt/GamePadConf.cpp | 38 ++++++++++++++++++++++++++++------ src/drivers/Qt/GamePadConf.h | 4 ++++ src/drivers/Qt/input.cpp | 14 +++++++++---- 5 files changed, 66 insertions(+), 11 deletions(-) diff --git a/src/drivers/Qt/GameApp.cpp b/src/drivers/Qt/GameApp.cpp index 2c291ce9..188b77c5 100644 --- a/src/drivers/Qt/GameApp.cpp +++ b/src/drivers/Qt/GameApp.cpp @@ -56,6 +56,8 @@ void gameWin_t::closeEvent(QCloseEvent *event) gamePadConfWin->closeWindow(); } event->accept(); + + closeApp(); } void gameWin_t::keyPressEvent(QKeyEvent *event) @@ -70,6 +72,7 @@ void gameWin_t::keyReleaseEvent(QKeyEvent *event) pushKeyEvent( event, 0 ); } +//--------------------------------------------------------------------------- void gameWin_t::createMainMenu(void) { // This is needed for menu bar to show up on MacOS @@ -100,7 +103,7 @@ void gameWin_t::createMainMenu(void) // File -> Quit quitAct = new QAction(tr("&Quit"), this); quitAct->setStatusTip(tr("Quit the Application")); - connect(quitAct, SIGNAL(triggered()), qApp, SLOT(quit())); + connect(quitAct, SIGNAL(triggered()), this, SLOT(closeApp())); fileMenu->addAction(quitAct); @@ -126,6 +129,21 @@ void gameWin_t::createMainMenu(void) helpMenu->addAction(aboutAct); }; +//--------------------------------------------------------------------------- +void gameWin_t::closeApp(void) +{ + fceuWrapperClose(); + + // LoadGame() checks for an IP and if it finds one begins a network session + // clear the NetworkIP field so this doesn't happen unintentionally + g_config->setOption ("SDL.NetworkIP", ""); + g_config->save (); + //SDL_Quit (); // Already called by fceuWrapperClose + + //qApp::quit(); + qApp->quit(); +} +//--------------------------------------------------------------------------- void gameWin_t::openROMFile(void) { diff --git a/src/drivers/Qt/GameApp.h b/src/drivers/Qt/GameApp.h index 258bfa77..2f295259 100644 --- a/src/drivers/Qt/GameApp.h +++ b/src/drivers/Qt/GameApp.h @@ -53,6 +53,7 @@ class gameWin_t : public QMainWindow void createMainMenu(void); private slots: + void closeApp(void); void openROMFile(void); void closeROMCB(void); void aboutQPlot(void); diff --git a/src/drivers/Qt/GamePadConf.cpp b/src/drivers/Qt/GamePadConf.cpp index 979258d8..a7e9a89b 100644 --- a/src/drivers/Qt/GamePadConf.cpp +++ b/src/drivers/Qt/GamePadConf.cpp @@ -18,6 +18,7 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) QPushButton *closebutton; portNum = 0; + configNo = 0; buttonConfigStatus = 1; setWindowTitle("GamePad Config"); @@ -56,7 +57,6 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) for (int i=0; i<10; i++) { char text[64]; - const char *keyNameStr; QLabel *buttonName; sprintf( text, "%s:", GamePadNames[i] ); @@ -65,16 +65,16 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) //hbox2->setAlignment(Qt::AlignCenter); - keyNameStr = ButtonName( &GamePadConfig[portNum][i], portNum ); - buttonName = new QLabel(tr(text)); - keyName[i] = new QLabel(tr(keyNameStr)); + keyName[i] = new QLabel(); button[i] = new GamePadConfigButton_t(i); grid->addWidget( buttonName, i, 0, Qt::AlignCenter ); grid->addWidget( keyName[i], i, 1, Qt::AlignCenter ); grid->addWidget( button[i] , i, 2, Qt::AlignCenter ); } + updateCntrlrDpy(); + closebutton = new QPushButton(tr("Close")); connect(button[0], SIGNAL(clicked()), this, SLOT(changeButton0(void)) ); @@ -89,6 +89,7 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) connect(button[9], SIGNAL(clicked()), this, SLOT(changeButton9(void)) ); connect(closebutton, SIGNAL(clicked()), this, SLOT(closeWindow(void)) ); + connect(portSel , SIGNAL(activated(int)), this, SLOT(controllerSelect(int)) ); connect(efs_chkbox , SIGNAL(stateChanged(int)), this, SLOT(ena4score(int)) ); connect(udlr_chkbox, SIGNAL(stateChanged(int)), this, SLOT(oppDirEna(int)) ); @@ -121,6 +122,32 @@ void GamePadConfDialog_t::keyReleaseEvent(QKeyEvent *event) pushKeyEvent( event, 0 ); } //---------------------------------------------------- +void GamePadConfDialog_t::updateCntrlrDpy(void) +{ + char keyNameStr[128]; + + for (int i=0; i<10; i++) + { + if (GamePadConfig[portNum][i].ButtType[configNo] == BUTTC_KEYBOARD) + { + snprintf( keyNameStr, sizeof (keyNameStr), "%s", + SDL_GetKeyName (GamePadConfig[portNum][i].ButtonNum[configNo])); + } + else + { + strcpy( keyNameStr, ButtonName( &GamePadConfig[portNum][i], configNo ) ); + } + keyName[i]->setText( tr(keyNameStr) ); + } +} +//---------------------------------------------------- +void GamePadConfDialog_t::controllerSelect(int index) +{ + printf("Port Number:%i \n", index); + portNum = index; + updateCntrlrDpy(); +} +//---------------------------------------------------- void GamePadConfDialog_t::ena4score(int state) { int value = (state == Qt::Unchecked) ? 0 : 1; @@ -137,7 +164,6 @@ void GamePadConfDialog_t::oppDirEna(int state) //---------------------------------------------------- void GamePadConfDialog_t::changeButton(int padNo, int x) { - int configNo = 0; char buf[256]; std::string prefix; const char *keyNameStr; @@ -175,7 +201,7 @@ void GamePadConfDialog_t::changeButton(int padNo, int x) g_config->setOption (prefix + "DeviceNum", GamePadConfig[padNo][x].DeviceNum[configNo]); - keyNameStr = ButtonName( &GamePadConfig[padNo][x], padNo ); + keyNameStr = ButtonName( &GamePadConfig[padNo][x], configNo ); keyName[x]->setText( keyNameStr ); button[x]->setText("Change"); diff --git a/src/drivers/Qt/GamePadConf.h b/src/drivers/Qt/GamePadConf.h index f13cdd5d..34e5b42d 100644 --- a/src/drivers/Qt/GamePadConf.h +++ b/src/drivers/Qt/GamePadConf.h @@ -40,12 +40,15 @@ class GamePadConfDialog_t : public QDialog GamePadConfigButton_t *button[10]; int portNum; + int configNo; int buttonConfigStatus; void changeButton( int port, int button ); void keyPressEvent(QKeyEvent *event); void keyReleaseEvent(QKeyEvent *event); void closeEvent(QCloseEvent *bar); + private: + void updateCntrlrDpy(void); public slots: void closeWindow(void); @@ -62,5 +65,6 @@ class GamePadConfDialog_t : public QDialog void changeButton9(void); void ena4score(int state); void oppDirEna(int state); + void controllerSelect(int index); }; diff --git a/src/drivers/Qt/input.cpp b/src/drivers/Qt/input.cpp index a95bec6f..fe1b4ec7 100644 --- a/src/drivers/Qt/input.cpp +++ b/src/drivers/Qt/input.cpp @@ -1566,6 +1566,8 @@ const char * ButtonName (const ButtConfig * bc, int which) { static char name[256]; + name[0] = 0; + switch (bc->ButtType[which]) { case BUTTC_KEYBOARD: @@ -1649,6 +1651,13 @@ int DWaitButton (const uint8 * text, ButtConfig * bc, int wb, int *buttonConfigS } } + // Purge all pending events, so that this next button press + // will be the one we want. + while (SDL_PollEvent (&event)) + { + + } + while (1) { int done = 0; @@ -1662,10 +1671,7 @@ int DWaitButton (const uint8 * text, ButtConfig * bc, int wb, int *buttonConfigS } QCoreApplication::processEvents(); -//#ifdef _GTK -// while (gtk_events_pending ()) -// gtk_main_iteration_do (FALSE); -//#endif + while (SDL_PollEvent (&event)) { done++; From 7ba7ef4b8228d899a75483d29daf705cbafd8515 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 27 Jun 2020 20:07:24 -0400 Subject: [PATCH 020/100] Include path fixes for qmake incorrectly marking sdl folder for heading includes. --- fceux.pro | 4 +++- src/drivers/Qt/GameApp.cpp | 8 ++++---- src/drivers/Qt/GameApp.h | 4 ++-- src/drivers/Qt/GamePadConf.cpp | 12 ++++++------ src/drivers/Qt/GameViewer.cpp | 4 ++-- src/drivers/Qt/config.cpp | 16 ++++++++-------- src/drivers/Qt/config.h | 2 +- src/drivers/Qt/dface.h | 6 +++--- src/drivers/Qt/fceuWrapper.cpp | 24 ++++++++++++------------ src/drivers/Qt/fceuWrapper.h | 2 +- src/drivers/Qt/gl_win.cpp | 2 +- src/drivers/Qt/gl_win.h | 6 +++--- src/drivers/Qt/input.cpp | 14 +++++++------- src/drivers/Qt/input.h | 2 +- src/drivers/Qt/keyscan.cpp | 2 +- src/drivers/Qt/main.cpp | 4 ++-- src/drivers/Qt/main.h | 4 ++-- src/drivers/Qt/sdl-joystick.cpp | 2 +- src/drivers/Qt/sdl-sound.cpp | 4 ++-- src/drivers/Qt/sdl-throttle.cpp | 4 ++-- src/drivers/Qt/sdl-video.cpp | 16 ++++++++-------- src/drivers/Qt/sdl.h | 6 +++--- src/drivers/Qt/unix-netplay.cpp | 14 +++++++------- src/fceu.cpp | 4 ++++ 24 files changed, 86 insertions(+), 80 deletions(-) diff --git a/fceux.pro b/fceux.pro index ab80964c..aa43cddb 100644 --- a/fceux.pro +++ b/fceux.pro @@ -21,6 +21,8 @@ QT += widgets CONFIG += object_parallel_to_source +INCLUDEPATH = src src/drivers + unix { QT_CONFIG -= no-pkg-config CONFIG += link_pkgconfig @@ -44,7 +46,7 @@ unix { } QMAKE_CXXFLAGS -= -O2 - QMAKE_CXXFLAGS += -O0 -g3 -Wall -Wno-write-strings -Wno-sign-compare -Wno-parentheses -Wno-unused-local-typedefs + QMAKE_CXXFLAGS += -D__QT_DRIVER__ -O0 -g3 -Wall -Wno-write-strings -Wno-sign-compare -Wno-parentheses -Wno-unused-local-typedefs QMAKE_CXXFLAGS_RELEASE -= -O2 } diff --git a/src/drivers/Qt/GameApp.cpp b/src/drivers/Qt/GameApp.cpp index 188b77c5..83966b8f 100644 --- a/src/drivers/Qt/GameApp.cpp +++ b/src/drivers/Qt/GameApp.cpp @@ -2,10 +2,10 @@ // #include -#include "GameApp.h" -#include "GamePadConf.h" -#include "fceuWrapper.h" -#include "keyscan.h" +#include "Qt/GameApp.h" +#include "Qt/GamePadConf.h" +#include "Qt/fceuWrapper.h" +#include "Qt/keyscan.h" gameWin_t::gameWin_t(QWidget *parent) : QMainWindow( parent ) diff --git a/src/drivers/Qt/GameApp.h b/src/drivers/Qt/GameApp.h index 2f295259..c813f3bf 100644 --- a/src/drivers/Qt/GameApp.h +++ b/src/drivers/Qt/GameApp.h @@ -15,8 +15,8 @@ #include #include -#include "GameViewer.h" -#include "GamePadConf.h" +#include "Qt/GameViewer.h" +#include "Qt/GamePadConf.h" class gameWin_t : public QMainWindow { diff --git a/src/drivers/Qt/GamePadConf.cpp b/src/drivers/Qt/GamePadConf.cpp index a7e9a89b..102a006d 100644 --- a/src/drivers/Qt/GamePadConf.cpp +++ b/src/drivers/Qt/GamePadConf.cpp @@ -1,11 +1,11 @@ // GamePadConf.cpp // -#include "GamePadConf.h" -#include "main.h" -#include "input.h" -#include "config.h" -#include "keyscan.h" -#include "fceuWrapper.h" +#include "Qt/GamePadConf.h" +#include "Qt/main.h" +#include "Qt/input.h" +#include "Qt/config.h" +#include "Qt/keyscan.h" +#include "Qt/fceuWrapper.h" //---------------------------------------------------- GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) diff --git a/src/drivers/Qt/GameViewer.cpp b/src/drivers/Qt/GameViewer.cpp index 3814fb73..aa34a9bf 100644 --- a/src/drivers/Qt/GameViewer.cpp +++ b/src/drivers/Qt/GameViewer.cpp @@ -5,8 +5,8 @@ #include #include -#include "gl_win.h" -#include "GameViewer.h" +#include "Qt/gl_win.h" +#include "Qt/GameViewer.h" extern unsigned int gui_draw_area_width; extern unsigned int gui_draw_area_height; diff --git a/src/drivers/Qt/config.cpp b/src/drivers/Qt/config.cpp index 4856cbb2..305439f0 100644 --- a/src/drivers/Qt/config.cpp +++ b/src/drivers/Qt/config.cpp @@ -1,15 +1,15 @@ -#include "main.h" -#include "throttle.h" -#include "config.h" +#include "Qt/main.h" +#include "Qt/throttle.h" +#include "Qt/config.h" #include "../common/cheat.h" -#include "input.h" -#include "dface.h" +#include "Qt/input.h" +#include "Qt/dface.h" -#include "sdl.h" -#include "sdl-video.h" -#include "unix-netplay.h" +#include "Qt/sdl.h" +#include "Qt/sdl-video.h" +#include "Qt/unix-netplay.h" #ifdef WIN32 #include diff --git a/src/drivers/Qt/config.h b/src/drivers/Qt/config.h index dbf6a0b6..c413a259 100644 --- a/src/drivers/Qt/config.h +++ b/src/drivers/Qt/config.h @@ -1,7 +1,7 @@ #ifndef CONFIG_H_HF128 #define CONFIG_H_HF128 -#include "../common/configSys.h" +#include "common/configSys.h" Config *InitConfig(void); void UpdateEMUCore(Config *); diff --git a/src/drivers/Qt/dface.h b/src/drivers/Qt/dface.h index f753f3ca..2f3890ec 100644 --- a/src/drivers/Qt/dface.h +++ b/src/drivers/Qt/dface.h @@ -1,7 +1,7 @@ -#include "../common/args.h" -#include "../common/config.h" +#include "common/args.h" +#include "common/config.h" -#include "input.h" +#include "Qt/input.h" extern CFGSTRUCT DriverConfig[]; extern ARGPSTRUCT DriverArgs[]; diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp index a340dfc8..b077a140 100644 --- a/src/drivers/Qt/fceuWrapper.cpp +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -4,18 +4,18 @@ #include #include -#include "main.h" -#include "throttle.h" -#include "config.h" -#include "dface.h" -#include "fceuWrapper.h" -#include "input.h" -#include "sdl.h" -#include "sdl-video.h" -#include "gl_win.h" -#include "unix-netplay.h" +#include "Qt/main.h" +#include "Qt/throttle.h" +#include "Qt/config.h" +#include "Qt/dface.h" +#include "Qt/fceuWrapper.h" +#include "Qt/input.h" +#include "Qt/sdl.h" +#include "Qt/sdl-video.h" +#include "Qt/gl_win.h" +#include "Qt/unix-netplay.h" -#include "../common/cheat.h" +#include "common/cheat.h" #include "../../fceu.h" #include "../../movie.h" #include "../../version.h" @@ -24,7 +24,7 @@ #include "../../fceulua.h" #endif -#include "../common/configSys.h" +#include "common/configSys.h" #include "../../oldmovie.h" #include "../../types.h" diff --git a/src/drivers/Qt/fceuWrapper.h b/src/drivers/Qt/fceuWrapper.h index 804e8bb8..2d4a1ff7 100644 --- a/src/drivers/Qt/fceuWrapper.h +++ b/src/drivers/Qt/fceuWrapper.h @@ -1,6 +1,6 @@ // fceuWrapper.h // -#include "config.h" +#include "Qt/config.h" //***************************************************************** // Define Global Variables to be shared with FCEU Core diff --git a/src/drivers/Qt/gl_win.cpp b/src/drivers/Qt/gl_win.cpp index 111e7fb6..a3fe766e 100644 --- a/src/drivers/Qt/gl_win.cpp +++ b/src/drivers/Qt/gl_win.cpp @@ -9,7 +9,7 @@ #include #include -#include "gl_win.h" +#include "Qt/gl_win.h" gl_win_shm_t *gl_shm = NULL; diff --git a/src/drivers/Qt/gl_win.h b/src/drivers/Qt/gl_win.h index 552c70a9..88776ac8 100644 --- a/src/drivers/Qt/gl_win.h +++ b/src/drivers/Qt/gl_win.h @@ -1,8 +1,8 @@ -// glxwin.cpp +// gl_win.cpp // -#ifndef __GLXWIN_H__ -#define __GLXWIN_H__ +#ifndef __GL_WIN_H__ +#define __GL_WIN_H__ #include diff --git a/src/drivers/Qt/input.cpp b/src/drivers/Qt/input.cpp index fe1b4ec7..9cc4aaff 100644 --- a/src/drivers/Qt/input.cpp +++ b/src/drivers/Qt/input.cpp @@ -18,16 +18,16 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "main.h" -#include "dface.h" -#include "input.h" -#include "config.h" +#include "Qt/main.h" +#include "Qt/dface.h" +#include "Qt/input.h" +#include "Qt/config.h" -#include "sdl-video.h" -#include "sdl.h" +#include "Qt/sdl-video.h" +#include "Qt/sdl.h" -#include "../common/cheat.h" +#include "common/cheat.h" #include "../../movie.h" #include "../../fceu.h" #include "../../driver.h" diff --git a/src/drivers/Qt/input.h b/src/drivers/Qt/input.h index 2a1a2d85..a62f3233 100644 --- a/src/drivers/Qt/input.h +++ b/src/drivers/Qt/input.h @@ -1,7 +1,7 @@ #ifndef _aosdfjk02fmasf #define _aosdfjk02fmasf -#include "../common/configSys.h" +#include "common/configSys.h" #define MAXBUTTCONFIG 4 typedef struct { diff --git a/src/drivers/Qt/keyscan.cpp b/src/drivers/Qt/keyscan.cpp index 2b3361c5..3dfd1f22 100644 --- a/src/drivers/Qt/keyscan.cpp +++ b/src/drivers/Qt/keyscan.cpp @@ -4,7 +4,7 @@ #include #include -#include "keyscan.h" +#include "Qt/keyscan.h" using namespace Qt; diff --git a/src/drivers/Qt/main.cpp b/src/drivers/Qt/main.cpp index 807ae5d8..fc4b9718 100644 --- a/src/drivers/Qt/main.cpp +++ b/src/drivers/Qt/main.cpp @@ -1,7 +1,7 @@ #include -#include "GameApp.h" -#include "fceuWrapper.h" +#include "Qt/GameApp.h" +#include "Qt/fceuWrapper.h" int main( int argc, char *argv[] ) { diff --git a/src/drivers/Qt/main.h b/src/drivers/Qt/main.h index 9b6963e1..35d5026d 100644 --- a/src/drivers/Qt/main.h +++ b/src/drivers/Qt/main.h @@ -21,8 +21,8 @@ #define __FCEU_SDL_MAIN_H #include "../../driver.h" -#include "../common/config.h" -#include "../common/args.h" +#include "common/config.h" +#include "common/args.h" extern int eoptions; #define EO_NO8LIM 1 diff --git a/src/drivers/Qt/sdl-joystick.cpp b/src/drivers/Qt/sdl-joystick.cpp index 690b012b..2e6d14a6 100644 --- a/src/drivers/Qt/sdl-joystick.cpp +++ b/src/drivers/Qt/sdl-joystick.cpp @@ -22,7 +22,7 @@ /// \file /// \brief Handles joystick input using the SDL. -#include "sdl.h" +#include "Qt/sdl.h" #include #include diff --git a/src/drivers/Qt/sdl-sound.cpp b/src/drivers/Qt/sdl-sound.cpp index 00b7c9a6..af01a355 100644 --- a/src/drivers/Qt/sdl-sound.cpp +++ b/src/drivers/Qt/sdl-sound.cpp @@ -23,8 +23,8 @@ #include "sdl.h" -#include "../common/configSys.h" -#include "../../utils/memory.h" +#include "common/configSys.h" +#include "utils/memory.h" #include #include diff --git a/src/drivers/Qt/sdl-throttle.cpp b/src/drivers/Qt/sdl-throttle.cpp index 498d4fe7..7afdb07e 100644 --- a/src/drivers/Qt/sdl-throttle.cpp +++ b/src/drivers/Qt/sdl-throttle.cpp @@ -1,8 +1,8 @@ /// \file /// \brief Handles emulation speed throttling using the SDL timing functions. -#include "sdl.h" -#include "throttle.h" +#include "Qt/sdl.h" +#include "Qt/throttle.h" static const double Slowest = 0.015625; // 1/64x speed (around 1 fps on NTSC) static const double Fastest = 32; // 32x speed (around 1920 fps on NTSC) diff --git a/src/drivers/Qt/sdl-video.cpp b/src/drivers/Qt/sdl-video.cpp index 4e70a08c..47afb1f6 100644 --- a/src/drivers/Qt/sdl-video.cpp +++ b/src/drivers/Qt/sdl-video.cpp @@ -21,21 +21,21 @@ /// \file /// \brief Handles the graphical game display for the SDL implementation. -#include "sdl.h" -#include "gl_win.h" -#include "../common/vidblit.h" +#include "Qt/sdl.h" +#include "Qt/gl_win.h" +#include "common/vidblit.h" #include "../../fceu.h" #include "../../version.h" #include "../../video.h" -#include "../../utils/memory.h" +#include "utils/memory.h" //#include "sdl-icon.h" -#include "dface.h" +#include "Qt/dface.h" -#include "../common/configSys.h" -#include "sdl-video.h" -#include "fceuWrapper.h" +#include "common/configSys.h" +#include "Qt/sdl-video.h" +#include "Qt/fceuWrapper.h" #ifdef CREATE_AVI #include "../videolog/nesvideos-piece.h" diff --git a/src/drivers/Qt/sdl.h b/src/drivers/Qt/sdl.h index 91c6414d..82870040 100644 --- a/src/drivers/Qt/sdl.h +++ b/src/drivers/Qt/sdl.h @@ -7,9 +7,9 @@ #include #endif -#include "main.h" -#include "dface.h" -#include "input.h" +#include "Qt/main.h" +#include "Qt/dface.h" +#include "Qt/input.h" // I'm using this as a #define so the compiler can optimize the // modulo operation diff --git a/src/drivers/Qt/unix-netplay.cpp b/src/drivers/Qt/unix-netplay.cpp index 37fcba12..9c538d71 100644 --- a/src/drivers/Qt/unix-netplay.cpp +++ b/src/drivers/Qt/unix-netplay.cpp @@ -21,18 +21,18 @@ //todo - ensure that #ifdef WIN32 makes sense //consider changing this to use sdl net stuff? -//#include "main.h" -//#include "input.h" -//#include "dface.h" -#include "unix-netplay.h" +//#include "Qt/main.h" +//#include "Qt/input.h" +//#include "Qt/dface.h" +#include "Qt/unix-netplay.h" #include "../../fceu.h" #include "../../driver.h" -#include "../../utils/md5.h" -#include "../../utils/memory.h" +#include "utils/md5.h" +#include "utils/memory.h" #include -#include "../common/configSys.h" +#include "common/configSys.h" #include #include diff --git a/src/fceu.cpp b/src/fceu.cpp index 90e295bd..bb311c6c 100644 --- a/src/fceu.cpp +++ b/src/fceu.cpp @@ -75,8 +75,12 @@ extern void RefreshThrottleFPS(); #include "drivers/win/memwatch.h" #include "drivers/win/tracer.h" #else +#ifdef __QT_DRIVER__ +#include "drivers/Qt/sdl.h" +#else #include "drivers/sdl/sdl.h" #endif +#endif #include #include From 59462545cab578014160efa6e1bab78ba20c8830 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 27 Jun 2020 21:08:02 -0400 Subject: [PATCH 021/100] Gui controller calibration fixes and enhancements. --- src/drivers/Qt/GamePadConf.cpp | 173 +++++++++++++++++++++++++++++--- src/drivers/Qt/GamePadConf.h | 19 +++- src/drivers/Qt/input.cpp | 17 ++-- src/drivers/Qt/input.h | 19 ++-- src/drivers/Qt/sdl-joystick.cpp | 8 +- 5 files changed, 203 insertions(+), 33 deletions(-) diff --git a/src/drivers/Qt/GamePadConf.cpp b/src/drivers/Qt/GamePadConf.cpp index 102a006d..37f02f5f 100644 --- a/src/drivers/Qt/GamePadConf.cpp +++ b/src/drivers/Qt/GamePadConf.cpp @@ -11,11 +11,14 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) : QDialog( parent ) { - QHBoxLayout *hbox1; + QHBoxLayout *hbox1, *hbox2; QGridLayout *grid; QCheckBox *efs_chkbox, *udlr_chkbox; QGroupBox *frame; + QPushButton *loadDefaultButton; + QPushButton *clearAllButton; QPushButton *closebutton; + QPushButton *clearButton[GAMEPAD_NUM_BUTTONS]; portNum = 0; configNo = 0; @@ -24,6 +27,7 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) setWindowTitle("GamePad Config"); hbox1 = new QHBoxLayout(); + hbox2 = new QHBoxLayout(); QLabel *label = new QLabel(tr("Port:")); portSel = new QComboBox(); @@ -54,7 +58,7 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) //frame->setFrameStyle( QFrame::Box ); frame->setLayout( grid ); - for (int i=0; i<10; i++) + for (int i=0; isetAlignment(Qt::AlignCenter); - buttonName = new QLabel(tr(text)); - keyName[i] = new QLabel(); - button[i] = new GamePadConfigButton_t(i); + buttonName = new QLabel(tr(text)); + keyName[i] = new QLabel(); + button[i] = new GamePadConfigButton_t(i); + clearButton[i] = new QPushButton("Clear"); - grid->addWidget( buttonName, i, 0, Qt::AlignCenter ); - grid->addWidget( keyName[i], i, 1, Qt::AlignCenter ); - grid->addWidget( button[i] , i, 2, Qt::AlignCenter ); + grid->addWidget( buttonName , i, 0, Qt::AlignCenter ); + grid->addWidget( keyName[i] , i, 1, Qt::AlignCenter ); + grid->addWidget( button[i] , i, 2, Qt::AlignCenter ); + grid->addWidget( clearButton[i], i, 3, Qt::AlignCenter ); } updateCntrlrDpy(); - closebutton = new QPushButton(tr("Close")); + loadDefaultButton = new QPushButton(tr("Load Defaults")); + clearAllButton = new QPushButton(tr("Clear All")); + closebutton = new QPushButton(tr("Close")); + + hbox2->addWidget( loadDefaultButton ); + hbox2->addWidget( clearAllButton ); + hbox2->addWidget( closebutton ); connect(button[0], SIGNAL(clicked()), this, SLOT(changeButton0(void)) ); connect(button[1], SIGNAL(clicked()), this, SLOT(changeButton1(void)) ); @@ -87,7 +99,21 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) connect(button[7], SIGNAL(clicked()), this, SLOT(changeButton7(void)) ); connect(button[8], SIGNAL(clicked()), this, SLOT(changeButton8(void)) ); connect(button[9], SIGNAL(clicked()), this, SLOT(changeButton9(void)) ); - connect(closebutton, SIGNAL(clicked()), this, SLOT(closeWindow(void)) ); + + connect(clearButton[0], SIGNAL(clicked()), this, SLOT(clearButton0(void)) ); + connect(clearButton[1], SIGNAL(clicked()), this, SLOT(clearButton1(void)) ); + connect(clearButton[2], SIGNAL(clicked()), this, SLOT(clearButton2(void)) ); + connect(clearButton[3], SIGNAL(clicked()), this, SLOT(clearButton3(void)) ); + connect(clearButton[4], SIGNAL(clicked()), this, SLOT(clearButton4(void)) ); + connect(clearButton[5], SIGNAL(clicked()), this, SLOT(clearButton5(void)) ); + connect(clearButton[6], SIGNAL(clicked()), this, SLOT(clearButton6(void)) ); + connect(clearButton[7], SIGNAL(clicked()), this, SLOT(clearButton7(void)) ); + connect(clearButton[8], SIGNAL(clicked()), this, SLOT(clearButton8(void)) ); + connect(clearButton[9], SIGNAL(clicked()), this, SLOT(clearButton9(void)) ); + + connect(loadDefaultButton, SIGNAL(clicked()), this, SLOT(loadDefaults(void)) ); + connect(clearAllButton , SIGNAL(clicked()), this, SLOT(clearAllCallback(void)) ); + connect(closebutton , SIGNAL(clicked()), this, SLOT(closeWindow(void)) ); connect(portSel , SIGNAL(activated(int)), this, SLOT(controllerSelect(int)) ); connect(efs_chkbox , SIGNAL(stateChanged(int)), this, SLOT(ena4score(int)) ); @@ -99,7 +125,7 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) mainLayout->addWidget( efs_chkbox ); mainLayout->addWidget( udlr_chkbox ); mainLayout->addWidget( frame ); - mainLayout->addWidget( closebutton, Qt::AlignRight ); + mainLayout->addLayout( hbox2 ); setLayout( mainLayout ); @@ -126,7 +152,7 @@ void GamePadConfDialog_t::updateCntrlrDpy(void) { char keyNameStr[128]; - for (int i=0; i<10; i++) + for (int i=0; isetOption (prefix + GamePadNames[x], GamePadConfig[padNo][x].ButtonNum[configNo]); - if (GamePadConfig[padNo][x].ButtType[0] == BUTTC_KEYBOARD) + if (GamePadConfig[padNo][x].ButtType[configNo] == BUTTC_KEYBOARD) { g_config->setOption (prefix + "DeviceType", "Keyboard"); } - else if (GamePadConfig[padNo][x].ButtType[0] == BUTTC_JOYSTICK) + else if (GamePadConfig[padNo][x].ButtType[configNo] == BUTTC_JOYSTICK) { g_config->setOption (prefix + "DeviceType", "Joystick"); } @@ -211,6 +237,23 @@ void GamePadConfDialog_t::changeButton(int padNo, int x) buttonConfigStatus = 1; } //---------------------------------------------------- +void GamePadConfDialog_t::clearButton( int padNo, int x ) +{ + char buf[256]; + std::string prefix; + + GamePadConfig[padNo][x].ButtonNum[configNo] = -1; + + keyName[x]->setText(""); + + snprintf (buf, sizeof(buf)-1, "SDL.Input.GamePad.%d.", padNo); + prefix = buf; + + g_config->setOption (prefix + GamePadNames[x], + GamePadConfig[padNo][x].ButtonNum[configNo]); + +} +//---------------------------------------------------- void GamePadConfDialog_t::closeEvent(QCloseEvent *event) { //printf("GamePad Close Window Event\n"); @@ -276,6 +319,106 @@ void GamePadConfDialog_t::changeButton9(void) changeButton( portNum, 9 ); } //---------------------------------------------------- +void GamePadConfDialog_t::clearButton0(void) +{ + clearButton( portNum, 0 ); +} +//---------------------------------------------------- +void GamePadConfDialog_t::clearButton1(void) +{ + clearButton( portNum, 1 ); +} +//---------------------------------------------------- +void GamePadConfDialog_t::clearButton2(void) +{ + clearButton( portNum, 2 ); +} +//---------------------------------------------------- +void GamePadConfDialog_t::clearButton3(void) +{ + clearButton( portNum, 3 ); +} +//---------------------------------------------------- +void GamePadConfDialog_t::clearButton4(void) +{ + clearButton( portNum, 4 ); +} +//---------------------------------------------------- +void GamePadConfDialog_t::clearButton5(void) +{ + clearButton( portNum, 5 ); +} +//---------------------------------------------------- +void GamePadConfDialog_t::clearButton6(void) +{ + clearButton( portNum, 6 ); +} +//---------------------------------------------------- +void GamePadConfDialog_t::clearButton7(void) +{ + clearButton( portNum, 7 ); +} +//---------------------------------------------------- +void GamePadConfDialog_t::clearButton8(void) +{ + clearButton( portNum, 8 ); +} +//---------------------------------------------------- +void GamePadConfDialog_t::clearButton9(void) +{ + clearButton( portNum, 9 ); +} +//---------------------------------------------------- +void GamePadConfDialog_t::clearAllCallback(void) +{ + for (int i=0; i 0 ) + { + clearAllCallback(); + return; + } + + snprintf (buf, sizeof(buf)-1, "SDL.Input.GamePad.%d.", portNum); + prefix = buf; + + for (int x=0; xsetOption (prefix + GamePadNames[x], + GamePadConfig[portNum][x].ButtonNum[configNo]); + + if (GamePadConfig[portNum][x].ButtType[configNo] == BUTTC_KEYBOARD) + { + g_config->setOption (prefix + "DeviceType", "Keyboard"); + } + else if (GamePadConfig[portNum][x].ButtType[configNo] == BUTTC_JOYSTICK) + { + g_config->setOption (prefix + "DeviceType", "Joystick"); + } + else + { + g_config->setOption (prefix + "DeviceType", "Unknown"); + } + g_config->setOption (prefix + "DeviceNum", + GamePadConfig[portNum][x].DeviceNum[configNo]); + } + updateCntrlrDpy(); +} +//---------------------------------------------------- GamePadConfigButton_t::GamePadConfigButton_t(int i) { idx = i; diff --git a/src/drivers/Qt/GamePadConf.h b/src/drivers/Qt/GamePadConf.h index 34e5b42d..0f83000c 100644 --- a/src/drivers/Qt/GamePadConf.h +++ b/src/drivers/Qt/GamePadConf.h @@ -14,6 +14,8 @@ #include #include +#include "Qt/main.h" + class GamePadConfigButton_t : public QPushButton { public: @@ -36,14 +38,15 @@ class GamePadConfDialog_t : public QDialog protected: QComboBox *portSel; - QLabel *keyName[10]; - GamePadConfigButton_t *button[10]; + QLabel *keyName[GAMEPAD_NUM_BUTTONS]; + GamePadConfigButton_t *button[GAMEPAD_NUM_BUTTONS]; int portNum; int configNo; int buttonConfigStatus; void changeButton( int port, int button ); + void clearButton( int port, int button ); void keyPressEvent(QKeyEvent *event); void keyReleaseEvent(QKeyEvent *event); void closeEvent(QCloseEvent *bar); @@ -63,6 +66,18 @@ class GamePadConfDialog_t : public QDialog void changeButton7(void); void changeButton8(void); void changeButton9(void); + void clearButton0(void); + void clearButton1(void); + void clearButton2(void); + void clearButton3(void); + void clearButton4(void); + void clearButton5(void); + void clearButton6(void); + void clearButton7(void); + void clearButton8(void); + void clearButton9(void); + void clearAllCallback(void); + void loadDefaults(void); void ena4score(int state); void oppDirEna(int state); void controllerSelect(int index); diff --git a/src/drivers/Qt/input.cpp b/src/drivers/Qt/input.cpp index 9cc4aaff..1e2162a0 100644 --- a/src/drivers/Qt/input.cpp +++ b/src/drivers/Qt/input.cpp @@ -1041,10 +1041,11 @@ DTestButton (ButtConfig * bc) #define MK(x) {{BUTTC_KEYBOARD},{0},{MKK(x)},1} #define MK2(x1,x2) {{BUTTC_KEYBOARD},{0},{MKK(x1),MKK(x2)},2} -#define MKZ() {{0},{0},{0},0} +#define MKZ() {{0},{0},{-1},0} #define GPZ() {MKZ(), MKZ(), MKZ(), MKZ()} -ButtConfig GamePadConfig[4][10] = { +ButtConfig GamePadConfig[ GAMEPAD_NUM_DEVICES ][ GAMEPAD_NUM_BUTTONS ] = +{ /* Gamepad 1 */ {MK (KP_3), MK (KP_2), MK (SLASH), MK (ENTER), MK (w), MK (z), MK (a), MK (s), MKZ (), MKZ ()}, @@ -1568,6 +1569,10 @@ const char * ButtonName (const ButtConfig * bc, int which) name[0] = 0; + if (bc->ButtonNum[which] == -1) + { + return name; + } switch (bc->ButtType[which]) { case BUTTC_KEYBOARD: @@ -2286,10 +2291,10 @@ const char *DefaultGamePadDevice[GAMEPAD_NUM_DEVICES] = { "Keyboard", "None", "None", "None" }; const int DefaultGamePad[GAMEPAD_NUM_DEVICES][GAMEPAD_NUM_BUTTONS] = { {SDLK_f, SDLK_d, SDLK_s, SDLK_RETURN, - SDLK_UP, SDLK_DOWN, SDLK_LEFT, SDLK_RIGHT, 0, 0}, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + SDLK_UP, SDLK_DOWN, SDLK_LEFT, SDLK_RIGHT, -1, -1}, +{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, +{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, +{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1} }; // PowerPad defaults diff --git a/src/drivers/Qt/input.h b/src/drivers/Qt/input.h index a62f3233..35361f56 100644 --- a/src/drivers/Qt/input.h +++ b/src/drivers/Qt/input.h @@ -4,14 +4,20 @@ #include "common/configSys.h" #define MAXBUTTCONFIG 4 -typedef struct { - uint8 ButtType[MAXBUTTCONFIG]; - uint8 DeviceNum[MAXBUTTCONFIG]; - //uint16 ButtonNum[MAXBUTTCONFIG]; + +enum { + BUTTC_KEYBOARD = 0, + BUTTC_JOYSTICK = 1, + BUTTC_MOUSE = 2 +}; +struct ButtConfig +{ + int ButtType[MAXBUTTCONFIG]; + int DeviceNum[MAXBUTTCONFIG]; int ButtonNum[MAXBUTTCONFIG]; uint32 NumC; //uint64 DeviceID[MAXBUTTCONFIG]; /* TODO */ -} ButtConfig; +}; extern int NoWaiting; @@ -26,9 +32,6 @@ void ButtonConfigEnd(); void ConfigButton(char *text, ButtConfig *bc); int DWaitButton(const uint8 *text, ButtConfig *bc, int wb, int *buttonConfigStatus = NULL); -#define BUTTC_KEYBOARD 0x00 -#define BUTTC_JOYSTICK 0x01 -#define BUTTC_MOUSE 0x02 #define FCFGD_GAMEPAD 1 #define FCFGD_POWERPAD 2 diff --git a/src/drivers/Qt/sdl-joystick.cpp b/src/drivers/Qt/sdl-joystick.cpp index 2e6d14a6..71148b2e 100644 --- a/src/drivers/Qt/sdl-joystick.cpp +++ b/src/drivers/Qt/sdl-joystick.cpp @@ -45,7 +45,11 @@ DTestButtonJoy(ButtConfig *bc) for(x = 0; x < bc->NumC; x++) { - if(bc->ButtonNum[x] & 0x2000) + if (bc->ButtonNum[x] == -1) + { + continue; + } + if (bc->ButtonNum[x] & 0x2000) { /* Hat "button" */ if(SDL_JoystickGetHat(s_Joysticks[bc->DeviceNum[x]], @@ -53,7 +57,7 @@ DTestButtonJoy(ButtConfig *bc) (bc->ButtonNum[x]&0xFF)) return 1; } - else if(bc->ButtonNum[x] & 0x8000) + else if (bc->ButtonNum[x] & 0x8000) { /* Axis "button" */ int pos; From 970afc2bea6d9cfd17d45aae6fe6f85a19d778cc Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 28 Jun 2020 10:11:03 -0400 Subject: [PATCH 022/100] Added logic to use GL_TEXTURE_RECTANGLE instead of GL_TEXTURE_2D --- src/drivers/Qt/GameViewer.cpp | 58 +++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/src/drivers/Qt/GameViewer.cpp b/src/drivers/Qt/GameViewer.cpp index aa34a9bf..788767d0 100644 --- a/src/drivers/Qt/GameViewer.cpp +++ b/src/drivers/Qt/GameViewer.cpp @@ -64,7 +64,8 @@ void gameView_t::initializeGL(void) printf("GL Init!\n"); - glEnable(GL_TEXTURE_2D); + //glEnable(GL_TEXTURE_2D); + glEnable(GL_TEXTURE_RECTANGLE); if ( gltexture ) { @@ -76,12 +77,19 @@ void gameView_t::initializeGL(void) } printf("Linear Interpolation on GL Texture: %s \n", ipolate ? "Enabled" : "Disabled"); - glBindTexture(GL_TEXTURE_2D, gltexture); + //glBindTexture(GL_TEXTURE_2D, gltexture); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,ipolate?GL_LINEAR:GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,ipolate?GL_LINEAR:GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP); + //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,ipolate?GL_LINEAR:GL_NEAREST); + //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,ipolate?GL_LINEAR:GL_NEAREST); + //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP); + //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP); + + glBindTexture(GL_TEXTURE_RECTANGLE, gltexture); + + glTexParameteri(GL_TEXTURE_RECTANGLE,GL_TEXTURE_MAG_FILTER,ipolate?GL_LINEAR:GL_NEAREST); + glTexParameteri(GL_TEXTURE_RECTANGLE,GL_TEXTURE_MIN_FILTER,ipolate?GL_LINEAR:GL_NEAREST); + glTexParameteri(GL_TEXTURE_RECTANGLE,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_RECTANGLE,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); } void gameView_t::resizeGL(int w, int h) @@ -124,35 +132,45 @@ void gameView_t::paintGL(void) glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); - glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0); + //glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0); + glOrtho( 0.0, rw, 0.0, rh, -1.0, 1.0); glDisable(GL_DEPTH_TEST); glClearColor( 0.0, 0.0f, 0.0f, 0.0f); // Background color to black. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glEnable(GL_LINE_SMOOTH); - glEnable(GL_TEXTURE_2D); + //glEnable(GL_LINE_SMOOTH); + //glEnable(GL_TEXTURE_2D); + glEnable(GL_TEXTURE_RECTANGLE); //glBindTexture(GL_TEXTURE_2D, gltexture); - glBindTexture(GL_TEXTURE_2D, gltexture); + glBindTexture(GL_TEXTURE_RECTANGLE, gltexture); //print_pixbuf(); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, + //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, + // GL_RGBA, GL_UNSIGNED_BYTE, gl_shm->pixbuf ); + glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, gl_shm->pixbuf ); glBegin(GL_QUADS); - glTexCoord2f(1.0f*l/256, 1.0f*b/256); // Bottom left of picture. - glVertex2f(-1.0f, -1.0f); // Bottom left of target. + //glTexCoord2f(1.0f*l/256, 1.0f*b/256); // Bottom left of picture. + //glVertex2f(-1.0f, -1.0f); // Bottom left of target. + glTexCoord2f( l, b); // Bottom left of picture. + glVertex2f( 0.0, 0.0f); // Bottom left of target. - glTexCoord2f(1.0f*r/256, 1.0f*b/256);// Bottom right of picture. - glVertex2f( 1.0f, -1.0f); // Bottom right of target. + //glTexCoord2f(1.0f*r/256, 1.0f*b/256);// Bottom right of picture. + glTexCoord2f(r, b);// Bottom right of picture. + glVertex2f( rw, 0.0f); // Bottom right of target. - glTexCoord2f(1.0f*r/256, 1.0f*t/256); // Top right of our picture. - glVertex2f( 1.0f, 1.0f); // Top right of target. + //glTexCoord2f(1.0f*r/256, 1.0f*t/256); // Top right of our picture. + glTexCoord2f(r, t); // Top right of our picture. + glVertex2f( rw, rh); // Top right of target. - glTexCoord2f(1.0f*l/256, 1.0f*t/256); // Top left of our picture. - glVertex2f(-1.0f, 1.0f); // Top left of target. + //glTexCoord2f(1.0f*l/256, 1.0f*t/256); // Top left of our picture. + glTexCoord2f(l, t); // Top left of our picture. + glVertex2f( 0.0f, rh); // Top left of target. glEnd(); - glDisable(GL_TEXTURE_2D); + //glDisable(GL_TEXTURE_2D); + glDisable(GL_TEXTURE_RECTANGLE); //glColor4f( 1.0, 1.0, 1.0, 1.0 ); //glLineWidth(5.0); From 95d055da2c2bf6f556bf05c7a795067d40d91cef Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Mon, 29 Jun 2020 08:15:26 -0400 Subject: [PATCH 023/100] Renamed openGL based game viewer so to distinguish it from others that will be tested. --- fceux.pro | 4 ++-- src/drivers/Qt/GameApp.cpp | 2 +- src/drivers/Qt/GameApp.h | 6 ++---- src/drivers/Qt/{GameViewer.cpp => GameViewerGL.cpp} | 12 ++++++------ src/drivers/Qt/{GameViewer.h => GameViewerGL.h} | 8 ++++---- 5 files changed, 15 insertions(+), 17 deletions(-) rename src/drivers/Qt/{GameViewer.cpp => GameViewerGL.cpp} (96%) rename src/drivers/Qt/{GameViewer.h => GameViewerGL.h} (65%) diff --git a/fceux.pro b/fceux.pro index aa43cddb..93ad5b28 100644 --- a/fceux.pro +++ b/fceux.pro @@ -293,11 +293,11 @@ SOURCES += src/drivers/common/vidblit.cpp SOURCES += src/drivers/common/nes_ntsc.c HEADERS += src/drivers/Qt/GameApp.h -HEADERS += src/drivers/Qt/GameViewer.h +HEADERS += src/drivers/Qt/GameViewerGL.h HEADERS += src/drivers/Qt/GamePadConf.h SOURCES += src/drivers/Qt/main.cpp SOURCES += src/drivers/Qt/GameApp.cpp -SOURCES += src/drivers/Qt/GameViewer.cpp +SOURCES += src/drivers/Qt/GameViewerGL.cpp SOURCES += src/drivers/Qt/GamePadConf.cpp SOURCES += src/drivers/Qt/fceuWrapper.cpp SOURCES += src/drivers/Qt/config.cpp diff --git a/src/drivers/Qt/GameApp.cpp b/src/drivers/Qt/GameApp.cpp index 83966b8f..274a4507 100644 --- a/src/drivers/Qt/GameApp.cpp +++ b/src/drivers/Qt/GameApp.cpp @@ -19,7 +19,7 @@ gameWin_t::gameWin_t(QWidget *parent) createMainMenu(); - viewport = new gameView_t(); + viewport = new gameViewGL_t(); //viewport.resize( 200, 200 ); layout->addWidget(viewport); diff --git a/src/drivers/Qt/GameApp.h b/src/drivers/Qt/GameApp.h index c813f3bf..d2500b82 100644 --- a/src/drivers/Qt/GameApp.h +++ b/src/drivers/Qt/GameApp.h @@ -15,7 +15,7 @@ #include #include -#include "Qt/GameViewer.h" +#include "Qt/GameViewerGL.h" #include "Qt/GamePadConf.h" class gameWin_t : public QMainWindow @@ -26,9 +26,7 @@ class gameWin_t : public QMainWindow gameWin_t(QWidget *parent = 0); ~gameWin_t(void); - gameView_t *viewport; - //QPushButton hello( "Hello world!", 0 ); - // + gameViewGL_t *viewport; QMenu *fileMenu; QMenu *optMenu; diff --git a/src/drivers/Qt/GameViewer.cpp b/src/drivers/Qt/GameViewerGL.cpp similarity index 96% rename from src/drivers/Qt/GameViewer.cpp rename to src/drivers/Qt/GameViewerGL.cpp index 788767d0..0e6d295e 100644 --- a/src/drivers/Qt/GameViewer.cpp +++ b/src/drivers/Qt/GameViewerGL.cpp @@ -6,12 +6,12 @@ #include #include "Qt/gl_win.h" -#include "Qt/GameViewer.h" +#include "Qt/GameViewerGL.h" extern unsigned int gui_draw_area_width; extern unsigned int gui_draw_area_height; -gameView_t::gameView_t(QWidget *parent) +gameViewGL_t::gameViewGL_t(QWidget *parent) : QOpenGLWidget( parent ) { view_width = 0; @@ -36,7 +36,7 @@ gameView_t::gameView_t(QWidget *parent) //setFormat( fmt ); } -gameView_t::~gameView_t(void) +gameViewGL_t::~gameViewGL_t(void) { // Make sure the context is current and then explicitly // destroy all underlying OpenGL resources. @@ -53,7 +53,7 @@ gameView_t::~gameView_t(void) doneCurrent(); } -void gameView_t::initializeGL(void) +void gameViewGL_t::initializeGL(void) { int ipolate = 0; @@ -92,7 +92,7 @@ void gameView_t::initializeGL(void) glTexParameteri(GL_TEXTURE_RECTANGLE,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); } -void gameView_t::resizeGL(int w, int h) +void gameViewGL_t::resizeGL(int w, int h) { printf("GL Resize: %i x %i \n", w, h ); glViewport(0, 0, w, h); @@ -104,7 +104,7 @@ void gameView_t::resizeGL(int w, int h) gui_draw_area_height = h; } -void gameView_t::paintGL(void) +void gameViewGL_t::paintGL(void) { int l=0, r=gl_shm->ncol; int t=0, b=gl_shm->nrow; diff --git a/src/drivers/Qt/GameViewer.h b/src/drivers/Qt/GameViewerGL.h similarity index 65% rename from src/drivers/Qt/GameViewer.h rename to src/drivers/Qt/GameViewerGL.h index edc0524a..fda2ff53 100644 --- a/src/drivers/Qt/GameViewer.h +++ b/src/drivers/Qt/GameViewerGL.h @@ -1,4 +1,4 @@ -// GameViewer.h +// GameViewerGL.h // #pragma once @@ -6,13 +6,13 @@ #include #include -class gameView_t : public QOpenGLWidget, protected QOpenGLFunctions +class gameViewGL_t : public QOpenGLWidget, protected QOpenGLFunctions { Q_OBJECT public: - gameView_t(QWidget *parent = 0); - ~gameView_t(void); + gameViewGL_t(QWidget *parent = 0); + ~gameViewGL_t(void); float angle; From 53dcb48a90555c559b93b2e7bca8c0d69d44cddd Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Mon, 29 Jun 2020 10:11:02 -0400 Subject: [PATCH 024/100] Successful test of SDL video driver inside QT window. --- fceux.pro | 2 + src/drivers/Qt/GameApp.cpp | 6 +- src/drivers/Qt/GameApp.h | 5 +- src/drivers/Qt/GameViewerSDL.cpp | 151 +++++++++++++++++++++++++++++++ src/drivers/Qt/GameViewerSDL.h | 37 ++++++++ src/drivers/Qt/main.cpp | 2 + src/drivers/Qt/sdl-video.cpp | 4 +- 7 files changed, 202 insertions(+), 5 deletions(-) create mode 100644 src/drivers/Qt/GameViewerSDL.cpp create mode 100644 src/drivers/Qt/GameViewerSDL.h diff --git a/fceux.pro b/fceux.pro index 93ad5b28..46a7c2fd 100644 --- a/fceux.pro +++ b/fceux.pro @@ -294,10 +294,12 @@ SOURCES += src/drivers/common/nes_ntsc.c HEADERS += src/drivers/Qt/GameApp.h HEADERS += src/drivers/Qt/GameViewerGL.h +HEADERS += src/drivers/Qt/GameViewerSDL.h HEADERS += src/drivers/Qt/GamePadConf.h SOURCES += src/drivers/Qt/main.cpp SOURCES += src/drivers/Qt/GameApp.cpp SOURCES += src/drivers/Qt/GameViewerGL.cpp +SOURCES += src/drivers/Qt/GameViewerSDL.cpp SOURCES += src/drivers/Qt/GamePadConf.cpp SOURCES += src/drivers/Qt/fceuWrapper.cpp SOURCES += src/drivers/Qt/config.cpp diff --git a/src/drivers/Qt/GameApp.cpp b/src/drivers/Qt/GameApp.cpp index 274a4507..0a799a95 100644 --- a/src/drivers/Qt/GameApp.cpp +++ b/src/drivers/Qt/GameApp.cpp @@ -19,7 +19,8 @@ gameWin_t::gameWin_t(QWidget *parent) createMainMenu(); - viewport = new gameViewGL_t(); + //viewport = new gameViewGL_t(this); + viewport = new gameViewSDL_t(this); //viewport.resize( 200, 200 ); layout->addWidget(viewport); @@ -234,7 +235,8 @@ void gameWin_t::runGameFrame(void) fceuWrapperUpdate(); - viewport->repaint(); + //viewport->repaint(); + viewport->update(); return; } diff --git a/src/drivers/Qt/GameApp.h b/src/drivers/Qt/GameApp.h index d2500b82..98f72fe4 100644 --- a/src/drivers/Qt/GameApp.h +++ b/src/drivers/Qt/GameApp.h @@ -16,6 +16,7 @@ #include #include "Qt/GameViewerGL.h" +#include "Qt/GameViewerSDL.h" #include "Qt/GamePadConf.h" class gameWin_t : public QMainWindow @@ -26,8 +27,10 @@ class gameWin_t : public QMainWindow gameWin_t(QWidget *parent = 0); ~gameWin_t(void); - gameViewGL_t *viewport; + //gameViewGL_t *viewport; + gameViewSDL_t *viewport; + protected: QMenu *fileMenu; QMenu *optMenu; QMenu *helpMenu; diff --git a/src/drivers/Qt/GameViewerSDL.cpp b/src/drivers/Qt/GameViewerSDL.cpp new file mode 100644 index 00000000..7ec04b81 --- /dev/null +++ b/src/drivers/Qt/GameViewerSDL.cpp @@ -0,0 +1,151 @@ +// GameViewer.cpp +// +#include +#include +#include +#include +#include + +#include "Qt/gl_win.h" +#include "Qt/GameViewerSDL.h" + +extern unsigned int gui_draw_area_width; +extern unsigned int gui_draw_area_height; + +gameViewSDL_t::gameViewSDL_t(QWidget *parent) + : QWidget( parent ) +{ + view_width = GL_NES_WIDTH; + view_height = GL_NES_HEIGHT; + + sdlWindow = NULL; + sdlRenderer = NULL; + sdlTexture = NULL; + + vsyncEnabled = false; +} + +gameViewSDL_t::~gameViewSDL_t(void) +{ + +} + +int gameViewSDL_t::init(void) +{ + WId windowHandle; + + if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) + { + printf("[SDL] Failed to initialize video subsystem.\n"); + return -1; + } + else + { + printf("Initialized SDL Video Subsystem\n"); + } + + windowHandle = this->winId(); + + printf("Window Handle: %llu \n", windowHandle ); + + //sleep(1); + + sdlWindow = SDL_CreateWindowFrom( (void*)windowHandle); + if (sdlWindow == NULL) + { + printf("[SDL] Failed to create window from handle.\n"); + return -1; + } + + uint32_t baseFlags = vsyncEnabled ? SDL_RENDERER_PRESENTVSYNC : 0; + + sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, baseFlags | SDL_RENDERER_ACCELERATED); + + if (sdlRenderer == NULL) + { + printf("[SDL] Failed to create accelerated renderer.\n"); + + printf("[SDL] Attempting to create software renderer...\n"); + + sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, baseFlags | SDL_RENDERER_SOFTWARE); + + if (sdlRenderer == NULL) + { + printf("[SDL] Failed to create software renderer.\n"); + return -1; + } + } + + sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, GL_NES_WIDTH, GL_NES_HEIGHT); + + if (sdlTexture == NULL) + { + printf("[SDL] Failed to create texture: %i x %i", GL_NES_WIDTH, GL_NES_HEIGHT ); + return -1; + } + + return 0; +} + +void gameViewSDL_t::cleanup(void) +{ + if (sdlTexture) + { + SDL_DestroyTexture(sdlTexture); + sdlTexture = NULL; + } + if (sdlRenderer) + { + SDL_DestroyRenderer(sdlRenderer); + sdlRenderer = NULL; + } +} + +void gameViewSDL_t::reset(void) +{ + cleanup(); + if ( init() == 0 ) + { + //console->GetVideoRenderer()->RegisterRenderingDevice(this); + } + else + { + cleanup(); + } +} + +void gameViewSDL_t::resizeEvent(QResizeEvent *event) +{ + QSize s; + + s = event->size(); + view_width = s.width(); + view_height = s.height(); + printf("SDL Resize: %i x %i \n", view_width, view_height); + reset(); +} + +void gameViewSDL_t::update(void) +{ + if ( (sdlRenderer == NULL) || (sdlTexture == NULL) ) + { + return; + } + + SDL_RenderClear(sdlRenderer); + + uint8_t *textureBuffer; + int rowPitch; + SDL_LockTexture( sdlTexture, nullptr, (void**)&textureBuffer, &rowPitch); + { + memcpy( textureBuffer, gl_shm->pixbuf, GL_NES_HEIGHT*GL_NES_WIDTH*sizeof(uint32_t) ); + } + SDL_UnlockTexture(sdlTexture); + + SDL_Rect source = {0, 0, GL_NES_WIDTH, GL_NES_HEIGHT }; + SDL_Rect dest = {0, 0, view_width, view_height }; + SDL_RenderCopy(sdlRenderer, sdlTexture, &source, &dest); + + SDL_RenderPresent(sdlRenderer); + +} diff --git a/src/drivers/Qt/GameViewerSDL.h b/src/drivers/Qt/GameViewerSDL.h new file mode 100644 index 00000000..1377077d --- /dev/null +++ b/src/drivers/Qt/GameViewerSDL.h @@ -0,0 +1,37 @@ +// GameViewerSDL.h +// + +#pragma once + +#include +#include +#include + +class gameViewSDL_t : public QWidget +{ + Q_OBJECT + + public: + gameViewSDL_t(QWidget *parent = 0); + ~gameViewSDL_t(void); + + int init(void); + void reset(void); + void cleanup(void); + void update(void); + + protected: + + void resizeEvent(QResizeEvent *event); + int view_width; + int view_height; + + bool vsyncEnabled; + + SDL_Window *sdlWindow; + SDL_Renderer *sdlRenderer; + SDL_Texture *sdlTexture; + + private slots: +}; + diff --git a/src/drivers/Qt/main.cpp b/src/drivers/Qt/main.cpp index fc4b9718..4379b0ad 100644 --- a/src/drivers/Qt/main.cpp +++ b/src/drivers/Qt/main.cpp @@ -13,6 +13,8 @@ int main( int argc, char *argv[] ) win.resize( 512, 512 ); win.show(); + win.viewport->init(); + return app.exec(); } diff --git a/src/drivers/Qt/sdl-video.cpp b/src/drivers/Qt/sdl-video.cpp index 47afb1f6..4f784aa1 100644 --- a/src/drivers/Qt/sdl-video.cpp +++ b/src/drivers/Qt/sdl-video.cpp @@ -184,9 +184,9 @@ int InitVideo(FCEUGI *gi) FCEUI_SetShowFPS(show_fps); #ifdef LSB_FIRST - rmask = 0x000000FF; + rmask = 0x00FF0000; gmask = 0x0000FF00; - bmask = 0x00FF0000; + bmask = 0x000000FF; #else rmask = 0x00FF0000; gmask = 0x0000FF00; From 26fe3c7da5a15ed13e94510e64394463751d5dab Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Mon, 29 Jun 2020 21:13:05 -0400 Subject: [PATCH 025/100] Added logic to keep proper aspect ratio on SDL driven screen. --- src/drivers/Qt/GameApp.cpp | 11 +------- src/drivers/Qt/GameViewerSDL.cpp | 45 +++++++++++++++++++++++++++----- src/drivers/Qt/GameViewerSDL.h | 5 ++++ 3 files changed, 44 insertions(+), 17 deletions(-) diff --git a/src/drivers/Qt/GameApp.cpp b/src/drivers/Qt/GameApp.cpp index 0a799a95..5969e9ad 100644 --- a/src/drivers/Qt/GameApp.cpp +++ b/src/drivers/Qt/GameApp.cpp @@ -10,22 +10,13 @@ gameWin_t::gameWin_t(QWidget *parent) : QMainWindow( parent ) { - QWidget *widget = new QWidget( this ); - - setCentralWidget(widget); - - QVBoxLayout *layout = new QVBoxLayout; - layout->setMargin(5); createMainMenu(); //viewport = new gameViewGL_t(this); viewport = new gameViewSDL_t(this); - //viewport.resize( 200, 200 ); - layout->addWidget(viewport); - - widget->setLayout(layout); + setCentralWidget(viewport); gameTimer = new QTimer( this ); diff --git a/src/drivers/Qt/GameViewerSDL.cpp b/src/drivers/Qt/GameViewerSDL.cpp index 7ec04b81..211abb92 100644 --- a/src/drivers/Qt/GameViewerSDL.cpp +++ b/src/drivers/Qt/GameViewerSDL.cpp @@ -18,6 +18,10 @@ gameViewSDL_t::gameViewSDL_t(QWidget *parent) view_width = GL_NES_WIDTH; view_height = GL_NES_HEIGHT; + sx = sy = 0; + rw = view_width; + rh = view_height; + sdlWindow = NULL; sdlRenderer = NULL; sdlTexture = NULL; @@ -39,14 +43,14 @@ int gameViewSDL_t::init(void) printf("[SDL] Failed to initialize video subsystem.\n"); return -1; } - else - { - printf("Initialized SDL Video Subsystem\n"); - } + //else + //{ + // printf("Initialized SDL Video Subsystem\n"); + //} windowHandle = this->winId(); - printf("Window Handle: %llu \n", windowHandle ); + //printf("Window Handle: %llu \n", windowHandle ); //sleep(1); @@ -121,12 +125,39 @@ void gameViewSDL_t::resizeEvent(QResizeEvent *event) s = event->size(); view_width = s.width(); view_height = s.height(); - printf("SDL Resize: %i x %i \n", view_width, view_height); + //printf("SDL Resize: %i x %i \n", view_width, view_height); + reset(); } void gameViewSDL_t::update(void) { + int nesWidth = GL_NES_WIDTH; + int nesHeight = GL_NES_HEIGHT; + + if ( gl_shm != NULL ) + { + nesWidth = gl_shm->ncol; + nesHeight = gl_shm->nrow; + } + //printf(" %i x %i \n", nesWidth, nesHeight ); + float xscale = (float)view_width / (float)nesWidth; + float yscale = (float)view_height / (float)nesHeight; + + if (xscale < yscale ) + { + yscale = xscale; + } + else + { + xscale = yscale; + } + + rw=(int)(nesWidth*xscale); + rh=(int)(nesHeight*yscale); + sx=(view_width-rw)/2; + sy=(view_height-rh)/2; + if ( (sdlRenderer == NULL) || (sdlTexture == NULL) ) { return; @@ -143,7 +174,7 @@ void gameViewSDL_t::update(void) SDL_UnlockTexture(sdlTexture); SDL_Rect source = {0, 0, GL_NES_WIDTH, GL_NES_HEIGHT }; - SDL_Rect dest = {0, 0, view_width, view_height }; + SDL_Rect dest = { sx, sy, rw, rh }; SDL_RenderCopy(sdlRenderer, sdlTexture, &source, &dest); SDL_RenderPresent(sdlRenderer); diff --git a/src/drivers/Qt/GameViewerSDL.h b/src/drivers/Qt/GameViewerSDL.h index 1377077d..a854d9b9 100644 --- a/src/drivers/Qt/GameViewerSDL.h +++ b/src/drivers/Qt/GameViewerSDL.h @@ -26,6 +26,11 @@ class gameViewSDL_t : public QWidget int view_width; int view_height; + int rw; + int rh; + int sx; + int sy; + bool vsyncEnabled; SDL_Window *sdlWindow; From c6b46bfcc18aab77a61bfc48c2c78a094a50e281 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Mon, 29 Jun 2020 22:24:34 -0400 Subject: [PATCH 026/100] Added software pixel remapper function to openGL renderer. --- src/drivers/Qt/GameApp.cpp | 4 +- src/drivers/Qt/GameApp.h | 4 +- src/drivers/Qt/GameViewerGL.cpp | 301 ++++++++++++++++++++++++-------- src/drivers/Qt/GameViewerGL.h | 11 +- 4 files changed, 239 insertions(+), 81 deletions(-) diff --git a/src/drivers/Qt/GameApp.cpp b/src/drivers/Qt/GameApp.cpp index 5969e9ad..91356967 100644 --- a/src/drivers/Qt/GameApp.cpp +++ b/src/drivers/Qt/GameApp.cpp @@ -13,8 +13,8 @@ gameWin_t::gameWin_t(QWidget *parent) createMainMenu(); - //viewport = new gameViewGL_t(this); - viewport = new gameViewSDL_t(this); + viewport = new gameViewGL_t(this); + //viewport = new gameViewSDL_t(this); setCentralWidget(viewport); diff --git a/src/drivers/Qt/GameApp.h b/src/drivers/Qt/GameApp.h index 98f72fe4..08790225 100644 --- a/src/drivers/Qt/GameApp.h +++ b/src/drivers/Qt/GameApp.h @@ -27,8 +27,8 @@ class gameWin_t : public QMainWindow gameWin_t(QWidget *parent = 0); ~gameWin_t(void); - //gameViewGL_t *viewport; - gameViewSDL_t *viewport; + gameViewGL_t *viewport; + //gameViewSDL_t *viewport; protected: QMenu *fileMenu; diff --git a/src/drivers/Qt/GameViewerGL.cpp b/src/drivers/Qt/GameViewerGL.cpp index 0e6d295e..8434d0a2 100644 --- a/src/drivers/Qt/GameViewerGL.cpp +++ b/src/drivers/Qt/GameViewerGL.cpp @@ -17,23 +17,10 @@ gameViewGL_t::gameViewGL_t(QWidget *parent) view_width = 0; view_height = 0; gltexture = 0; + use_sw_pix_remap = 0; + remap_pixBuf = NULL; + remap_pixPtr = NULL; - //QSurfaceFormat fmt = QSurfaceFormat::defaultFormat(); - - //fmt.setRedBufferSize(8); - //fmt.setGreenBufferSize(8); - //fmt.setBlueBufferSize(8); - //fmt.setAlphaBufferSize(8); - //fmt.setDepthBufferSize( 24 ); - //setTextureFormat(GL_RGBA8); - - ////printf("R: %i \n", fmt.redBufferSize() ); - ////printf("G: %i \n", fmt.greenBufferSize() ); - ////printf("B: %i \n", fmt.blueBufferSize() ); - ////printf("A: %i \n", fmt.alphaBufferSize() ); - ////printf("SW: %i \n", fmt.swapBehavior() ); - - //setFormat( fmt ); } gameViewGL_t::~gameViewGL_t(void) @@ -51,30 +38,36 @@ gameViewGL_t::~gameViewGL_t(void) } doneCurrent(); + + if ( remap_pixBuf ) + { + ::free( remap_pixBuf ); remap_pixBuf = NULL; + } + if ( remap_pixPtr ) + { + ::free( remap_pixPtr ); remap_pixPtr = NULL; + } } -void gameViewGL_t::initializeGL(void) +int gameViewGL_t::init(void) +{ + return 0; +} + +void gameViewGL_t::buildTextures(void) { int ipolate = 0; - initializeOpenGLFunctions(); - // Set up the rendering context, load shaders and other resources, etc.: - //QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions(); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - - printf("GL Init!\n"); - - //glEnable(GL_TEXTURE_2D); + //glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_RECTANGLE); if ( gltexture ) { - printf("GL Texture already exists\n"); - } - else - { - glGenTextures(1, &gltexture); + glDeleteTextures(1, &gltexture); + gltexture=0; } + + glGenTextures(1, &gltexture); printf("Linear Interpolation on GL Texture: %s \n", ipolate ? "Enabled" : "Disabled"); //glBindTexture(GL_TEXTURE_2D, gltexture); @@ -90,6 +83,70 @@ void gameViewGL_t::initializeGL(void) glTexParameteri(GL_TEXTURE_RECTANGLE,GL_TEXTURE_MIN_FILTER,ipolate?GL_LINEAR:GL_NEAREST); glTexParameteri(GL_TEXTURE_RECTANGLE,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_RECTANGLE,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); + + if ( remap_pixBuf ) + { + ::free( remap_pixBuf ); remap_pixBuf = NULL; + } + if ( remap_pixPtr ) + { + ::free( remap_pixPtr ); remap_pixPtr = NULL; + } + + if ( use_sw_pix_remap ) + { + texture_width = view_width; + texture_height = view_height; + } + else + { + texture_width = GL_NES_WIDTH; + texture_height = GL_NES_HEIGHT; + } + if ( texture_width < GL_NES_WIDTH ) + { + texture_width = GL_NES_WIDTH; + } + if ( texture_height < GL_NES_HEIGHT ) + { + texture_height = GL_NES_HEIGHT; + } + + if ( use_sw_pix_remap ) + { + remap_pixBuf = (uint32_t*)malloc( texture_width * texture_height * sizeof(uint32_t) ); + + if ( remap_pixBuf ) + { + memset( remap_pixBuf, 0, texture_width * texture_height * sizeof(uint32_t) ); + } + + remap_pixPtr = (uint32_t**)malloc( texture_width * texture_height * sizeof(uintptr_t) ); + + if ( remap_pixPtr ) + { + memset( remap_pixPtr, 0, texture_width * texture_height * sizeof(uintptr_t) ); + } + calcPixRemap(); + } + + glTexImage2D(GL_TEXTURE_RECTANGLE, 0, + GL_RGBA8, texture_width, texture_height, 0, + GL_BGRA, GL_UNSIGNED_BYTE, 0 ); + +} + +void gameViewGL_t::initializeGL(void) +{ + + initializeOpenGLFunctions(); + // Set up the rendering context, load shaders and other resources, etc.: + //QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions(); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + + printf("GL Init!\n"); + + buildTextures(); } void gameViewGL_t::resizeGL(int w, int h) @@ -102,15 +159,17 @@ void gameViewGL_t::resizeGL(int w, int h) gui_draw_area_width = w; gui_draw_area_height = h; + + buildTextures(); } void gameViewGL_t::paintGL(void) { - int l=0, r=gl_shm->ncol; - int t=0, b=gl_shm->nrow; + int l=0, r=texture_width; + int t=0, b=texture_height; - float xscale = (float)view_width / (float)gl_shm->ncol; - float yscale = (float)view_height / (float)gl_shm->nrow; + float xscale = (float)view_width / (float)texture_width; + float yscale = (float)view_height / (float)texture_height; if (xscale < yscale ) { @@ -139,7 +198,7 @@ void gameViewGL_t::paintGL(void) glClearColor( 0.0, 0.0f, 0.0f, 0.0f); // Background color to black. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glEnable(GL_LINE_SMOOTH); - //glEnable(GL_TEXTURE_2D); + glDisable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_RECTANGLE); //glBindTexture(GL_TEXTURE_2D, gltexture); glBindTexture(GL_TEXTURE_RECTANGLE, gltexture); @@ -147,8 +206,22 @@ void gameViewGL_t::paintGL(void) //print_pixbuf(); //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, // GL_RGBA, GL_UNSIGNED_BYTE, gl_shm->pixbuf ); - glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA8, 256, 256, 0, - GL_RGBA, GL_UNSIGNED_BYTE, gl_shm->pixbuf ); + //glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA8, 256, 256, 0, + // GL_BGRA, GL_UNSIGNED_BYTE, gl_shm->pixbuf ); + if ( use_sw_pix_remap ) + { + doRemap(); + + glTexSubImage2D(GL_TEXTURE_RECTANGLE, 0, + 0, 0, texture_width, texture_height, + GL_BGRA, GL_UNSIGNED_BYTE, remap_pixBuf ); + } + else + { + glTexSubImage2D(GL_TEXTURE_RECTANGLE, 0, + 0, 0, texture_width, texture_height, + GL_BGRA, GL_UNSIGNED_BYTE, gl_shm->pixbuf ); + } glBegin(GL_QUADS); //glTexCoord2f(1.0f*l/256, 1.0f*b/256); // Bottom left of picture. @@ -169,46 +242,122 @@ void gameViewGL_t::paintGL(void) glVertex2f( 0.0f, rh); // Top left of target. glEnd(); - //glDisable(GL_TEXTURE_2D); + glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_RECTANGLE); - //glColor4f( 1.0, 1.0, 1.0, 1.0 ); - //glLineWidth(5.0); - //glBegin(GL_LINES); - //glVertex2f(-1.0f, -1.0f); // Bottom left of target. - //glVertex2f( 1.0f, 1.0f); // Top right of target. - //glEnd(); - - //context()->swapBuffers( context()->surface() ); - //if ( double_buffer_ena ) - //{ - // glXSwapBuffers( dpy, win ); - //} - //else - //{ - // glFlush(); - //} - //glFlush(); - - //float x1, y1, x2, y2; - - //angle += (2.0 * 3.14 * 0.01); - // - //glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - - //x1 = cos( angle ); - //y1 = sin( angle ); - - //x2 = -x1; - //y2 = -y1; - - //glColor4f( 1.0, 1.0, 1.0, 1.0 ); - //glLineWidth(5.0); - - //glBegin(GL_LINES); - // glVertex2f( x1, y1 ); - // glVertex2f( x2, y2 ); - //glEnd(); - //printf("Paint GL!\n"); } + +void gameViewGL_t::doRemap(void) +{ + int x,y,i; + + i=0; + for (x=0; xncol; + gh = gl_shm->nrow; + + sx = (float)w / (float)gw; + sy = (float)h / (float)gh; + + if (sx < sy ) + { + sy = sx; + } + else + { + sx = sy; + } + + sw = (int) ( (float)gw * sx ); + sh = (int) ( (float)gh * sy ); + + llx = (w - sw) / 2; + lly = (h - sh) / 2; + urx = llx + sw; + ury = lly + sh; + + i=0; + for (y=0; y ury) ) + { + for (x=0; x urx) ) + { + remap_pixPtr[i] = 0; i++; + } + else + { + nw = (float)(x - llx) / (float)sw; + nh = (float)(y - lly) / (float)sh; + + rx = (int)((float)gw * nw); + ry = (int)((float)gh * nh); + + if ( rx < 0 ) + { + rx = 0; + } + else if ( rx >= GL_NES_WIDTH ) + { + rx = GL_NES_WIDTH-1; + } + if ( ry < 0 ) + { + ry = 0; + } + else if ( ry >= GL_NES_HEIGHT ) + { + ry = GL_NES_HEIGHT-1; + } + + j = (ry * GL_NES_WIDTH) + rx; + + remap_pixPtr[i] = &gl_shm->pixbuf[j]; i++; + + //printf("Remap: (%i,%i)=%i (%i,%i)=%i \n", x,y,i, rx,ry,j ); + } + } + } + } + //numRendLines = gh; +} diff --git a/src/drivers/Qt/GameViewerGL.h b/src/drivers/Qt/GameViewerGL.h index fda2ff53..205b9681 100644 --- a/src/drivers/Qt/GameViewerGL.h +++ b/src/drivers/Qt/GameViewerGL.h @@ -14,16 +14,25 @@ class gameViewGL_t : public QOpenGLWidget, protected QOpenGLFunctions gameViewGL_t(QWidget *parent = 0); ~gameViewGL_t(void); - float angle; + int init(void); protected: void initializeGL(void); void resizeGL(int w, int h); void paintGL(void); + void buildTextures(void); + void calcPixRemap(void); + void doRemap(void); + + int texture_width; + int texture_height; int view_width; int view_height; GLuint gltexture; + bool use_sw_pix_remap; + uint32_t *remap_pixBuf; + uint32_t **remap_pixPtr; private slots: }; From 41b54b98135b274092af2c23abfa119c67d56090 Mon Sep 17 00:00:00 2001 From: mjbudd77 Date: Mon, 29 Jun 2020 23:24:41 -0400 Subject: [PATCH 027/100] Solved MAC OpenGL scaling issue. Turns out it was related to the retina screen having a 2x device to framebuffer scaling. --- src/drivers/Qt/GameViewerGL.cpp | 6 +++++- src/drivers/Qt/GameViewerGL.h | 3 ++- src/drivers/Qt/keyscan.cpp | 2 +- src/drivers/Qt/keyscan.h | 2 +- src/drivers/Qt/main.cpp | 14 ++++++++++++-- 5 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/drivers/Qt/GameViewerGL.cpp b/src/drivers/Qt/GameViewerGL.cpp index 8434d0a2..79df9e9e 100644 --- a/src/drivers/Qt/GameViewerGL.cpp +++ b/src/drivers/Qt/GameViewerGL.cpp @@ -20,6 +20,7 @@ gameViewGL_t::gameViewGL_t(QWidget *parent) use_sw_pix_remap = 0; remap_pixBuf = NULL; remap_pixPtr = NULL; + devPixRatio = 1.0f; } @@ -49,8 +50,9 @@ gameViewGL_t::~gameViewGL_t(void) } } -int gameViewGL_t::init(void) +int gameViewGL_t::init( double devPixRatioInput ) { + devPixRatio = devPixRatioInput; return 0; } @@ -151,6 +153,8 @@ void gameViewGL_t::initializeGL(void) void gameViewGL_t::resizeGL(int w, int h) { + w = (int)( devPixRatio * w ); + h = (int)( devPixRatio * h ); printf("GL Resize: %i x %i \n", w, h ); glViewport(0, 0, w, h); diff --git a/src/drivers/Qt/GameViewerGL.h b/src/drivers/Qt/GameViewerGL.h index 205b9681..45776c05 100644 --- a/src/drivers/Qt/GameViewerGL.h +++ b/src/drivers/Qt/GameViewerGL.h @@ -14,7 +14,7 @@ class gameViewGL_t : public QOpenGLWidget, protected QOpenGLFunctions gameViewGL_t(QWidget *parent = 0); ~gameViewGL_t(void); - int init(void); + int init( double devPixRatio = 1.0f ); protected: void initializeGL(void); @@ -25,6 +25,7 @@ class gameViewGL_t : public QOpenGLWidget, protected QOpenGLFunctions void calcPixRemap(void); void doRemap(void); + double devPixRatio; int texture_width; int texture_height; int view_width; diff --git a/src/drivers/Qt/keyscan.cpp b/src/drivers/Qt/keyscan.cpp index 3dfd1f22..389ac66a 100644 --- a/src/drivers/Qt/keyscan.cpp +++ b/src/drivers/Qt/keyscan.cpp @@ -2,7 +2,7 @@ // #include -#include +#include #include "Qt/keyscan.h" diff --git a/src/drivers/Qt/keyscan.h b/src/drivers/Qt/keyscan.h index 0273471c..2499709f 100644 --- a/src/drivers/Qt/keyscan.h +++ b/src/drivers/Qt/keyscan.h @@ -45,7 +45,7 @@ #include #include -#include +#include SDL_Keycode convQtKey2SDLKeyCode( Qt::Key q ); diff --git a/src/drivers/Qt/main.cpp b/src/drivers/Qt/main.cpp index 4379b0ad..ec133a41 100644 --- a/src/drivers/Qt/main.cpp +++ b/src/drivers/Qt/main.cpp @@ -1,19 +1,29 @@ #include +#include #include "Qt/GameApp.h" #include "Qt/fceuWrapper.h" int main( int argc, char *argv[] ) { + double devPixRatio = 1.0; QApplication app(argc, argv); gameWin_t win; + QScreen *screen = QGuiApplication::primaryScreen(); + + if ( screen != NULL ) + { + devPixRatio = screen->devicePixelRatio(); + printf("Ratio: %f \n", screen->devicePixelRatio() ); + } + fceuWrapperInit( argc, argv ); - win.resize( 512, 512 ); + //win.resize( 512, 512 ); win.show(); - win.viewport->init(); + win.viewport->init( devPixRatio ); return app.exec(); } From e2b853661d18eb89a3a76945b72113d43bc76145 Mon Sep 17 00:00:00 2001 From: mjbudd77 Date: Tue, 30 Jun 2020 09:22:59 -0400 Subject: [PATCH 028/100] More testing with SDL game viewer driver, keeps drawing over the menu bar on the mac os. Thinking native GL inside QT is the way to go. --- src/drivers/Qt/GameApp.cpp | 3 +-- src/drivers/Qt/GameViewerSDL.cpp | 26 ++++++++++++++++++++++---- src/drivers/Qt/GameViewerSDL.h | 9 +++++++-- src/drivers/Qt/main.cpp | 2 +- 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/drivers/Qt/GameApp.cpp b/src/drivers/Qt/GameApp.cpp index 91356967..6d402625 100644 --- a/src/drivers/Qt/GameApp.cpp +++ b/src/drivers/Qt/GameApp.cpp @@ -226,8 +226,7 @@ void gameWin_t::runGameFrame(void) fceuWrapperUpdate(); - //viewport->repaint(); - viewport->update(); + viewport->repaint(); return; } diff --git a/src/drivers/Qt/GameViewerSDL.cpp b/src/drivers/Qt/GameViewerSDL.cpp index 211abb92..8576ffac 100644 --- a/src/drivers/Qt/GameViewerSDL.cpp +++ b/src/drivers/Qt/GameViewerSDL.cpp @@ -21,7 +21,10 @@ gameViewSDL_t::gameViewSDL_t(QWidget *parent) sx = sy = 0; rw = view_width; rh = view_height; + sdlRendW = 0; + sdlRendH = 0; + devPixRatio = 1.0f; sdlWindow = NULL; sdlRenderer = NULL; sdlTexture = NULL; @@ -34,10 +37,12 @@ gameViewSDL_t::~gameViewSDL_t(void) } -int gameViewSDL_t::init(void) +int gameViewSDL_t::init( double devPixRatioIn ) { WId windowHandle; + devPixRatio = devPixRatioIn; + if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) { printf("[SDL] Failed to initialize video subsystem.\n"); @@ -80,6 +85,10 @@ int gameViewSDL_t::init(void) } } + SDL_GetRendererOutputSize( sdlRenderer, &sdlRendW, &sdlRendH ); + + printf("[SDL] Renderer Output Size: %i x %i \n", sdlRendW, sdlRendH ); + sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, GL_NES_WIDTH, GL_NES_HEIGHT); if (sdlTexture == NULL) @@ -128,9 +137,14 @@ void gameViewSDL_t::resizeEvent(QResizeEvent *event) //printf("SDL Resize: %i x %i \n", view_width, view_height); reset(); + + sdlViewport.x = sdlRendW - view_width; + sdlViewport.y = sdlRendH - view_height; + sdlViewport.w = view_width; + sdlViewport.h = view_height; } -void gameViewSDL_t::update(void) +void gameViewSDL_t::paintEvent( QPaintEvent *event ) { int nesWidth = GL_NES_WIDTH; int nesHeight = GL_NES_HEIGHT; @@ -155,14 +169,16 @@ void gameViewSDL_t::update(void) rw=(int)(nesWidth*xscale); rh=(int)(nesHeight*yscale); - sx=(view_width-rw)/2; - sy=(view_height-rh)/2; + sx=sdlViewport.x + (view_width-rw)/2; + sy=sdlViewport.y + (view_height-rh)/2; if ( (sdlRenderer == NULL) || (sdlTexture == NULL) ) { return; } + SDL_SetRenderDrawColor( sdlRenderer, 0, 0, 0, 0 ); + SDL_RenderClear(sdlRenderer); uint8_t *textureBuffer; @@ -173,6 +189,8 @@ void gameViewSDL_t::update(void) } SDL_UnlockTexture(sdlTexture); + SDL_RenderSetViewport( sdlRenderer, &sdlViewport ); + SDL_Rect source = {0, 0, GL_NES_WIDTH, GL_NES_HEIGHT }; SDL_Rect dest = { sx, sy, rw, rh }; SDL_RenderCopy(sdlRenderer, sdlTexture, &source, &dest); diff --git a/src/drivers/Qt/GameViewerSDL.h b/src/drivers/Qt/GameViewerSDL.h index a854d9b9..61f3da04 100644 --- a/src/drivers/Qt/GameViewerSDL.h +++ b/src/drivers/Qt/GameViewerSDL.h @@ -4,6 +4,7 @@ #pragma once #include +#include #include #include @@ -15,27 +16,31 @@ class gameViewSDL_t : public QWidget gameViewSDL_t(QWidget *parent = 0); ~gameViewSDL_t(void); - int init(void); + int init(double devPixRatioIn = 1.0); void reset(void); void cleanup(void); - void update(void); protected: + void paintEvent(QPaintEvent *event); void resizeEvent(QResizeEvent *event); int view_width; int view_height; + double devPixRatio; int rw; int rh; int sx; int sy; + int sdlRendW; + int sdlRendH; bool vsyncEnabled; SDL_Window *sdlWindow; SDL_Renderer *sdlRenderer; SDL_Texture *sdlTexture; + SDL_Rect sdlViewport; private slots: }; diff --git a/src/drivers/Qt/main.cpp b/src/drivers/Qt/main.cpp index ec133a41..83466f47 100644 --- a/src/drivers/Qt/main.cpp +++ b/src/drivers/Qt/main.cpp @@ -20,7 +20,7 @@ int main( int argc, char *argv[] ) fceuWrapperInit( argc, argv ); - //win.resize( 512, 512 ); + win.resize( 512, 512 ); win.show(); win.viewport->init( devPixRatio ); From 2762d5379171a94a5da3854d0039efc0a737cd22 Mon Sep 17 00:00:00 2001 From: mjbudd77 Date: Tue, 30 Jun 2020 19:53:29 -0400 Subject: [PATCH 029/100] Cleaned up game viewer GL. --- src/drivers/Qt/GameViewerGL.cpp | 257 ++++---------------------------- src/drivers/Qt/GameViewerGL.h | 26 ++-- src/drivers/Qt/main.cpp | 20 +-- 3 files changed, 47 insertions(+), 256 deletions(-) diff --git a/src/drivers/Qt/GameViewerGL.cpp b/src/drivers/Qt/GameViewerGL.cpp index 79df9e9e..851f0b96 100644 --- a/src/drivers/Qt/GameViewerGL.cpp +++ b/src/drivers/Qt/GameViewerGL.cpp @@ -5,6 +5,9 @@ #include #include +#include +#include + #include "Qt/gl_win.h" #include "Qt/GameViewerGL.h" @@ -17,11 +20,16 @@ gameViewGL_t::gameViewGL_t(QWidget *parent) view_width = 0; view_height = 0; gltexture = 0; - use_sw_pix_remap = 0; - remap_pixBuf = NULL; - remap_pixPtr = NULL; - devPixRatio = 1.0f; + devPixRatio = 1.0f; + linearFilter = false; + QScreen *screen = QGuiApplication::primaryScreen(); + + if ( screen != NULL ) + { + devPixRatio = screen->devicePixelRatio(); + //printf("Ratio: %f \n", screen->devicePixelRatio() ); + } } gameViewGL_t::~gameViewGL_t(void) @@ -33,34 +41,21 @@ gameViewGL_t::~gameViewGL_t(void) // Free GL texture if (gltexture) { - printf("Destroying GLX Texture\n"); + //printf("Destroying GL Texture\n"); glDeleteTextures(1, &gltexture); gltexture=0; } doneCurrent(); - - if ( remap_pixBuf ) - { - ::free( remap_pixBuf ); remap_pixBuf = NULL; - } - if ( remap_pixPtr ) - { - ::free( remap_pixPtr ); remap_pixPtr = NULL; - } } -int gameViewGL_t::init( double devPixRatioInput ) +int gameViewGL_t::init( void ) { - devPixRatio = devPixRatioInput; return 0; } void gameViewGL_t::buildTextures(void) { - int ipolate = 0; - - //glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_RECTANGLE); if ( gltexture ) @@ -69,71 +64,18 @@ void gameViewGL_t::buildTextures(void) gltexture=0; } - glGenTextures(1, &gltexture); - printf("Linear Interpolation on GL Texture: %s \n", ipolate ? "Enabled" : "Disabled"); + glGenTextures(1, &gltexture); + //printf("Linear Interpolation on GL Texture: %s \n", linearFilter ? "Enabled" : "Disabled"); - //glBindTexture(GL_TEXTURE_2D, gltexture); + glBindTexture( GL_TEXTURE_RECTANGLE, gltexture); - //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,ipolate?GL_LINEAR:GL_NEAREST); - //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,ipolate?GL_LINEAR:GL_NEAREST); - //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP); - //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP); + glTexParameteri( GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, linearFilter ? GL_LINEAR : GL_NEAREST ); + glTexParameteri( GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, linearFilter ? GL_LINEAR : GL_NEAREST ); + glTexParameteri( GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + glTexParameteri( GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); - glBindTexture(GL_TEXTURE_RECTANGLE, gltexture); - - glTexParameteri(GL_TEXTURE_RECTANGLE,GL_TEXTURE_MAG_FILTER,ipolate?GL_LINEAR:GL_NEAREST); - glTexParameteri(GL_TEXTURE_RECTANGLE,GL_TEXTURE_MIN_FILTER,ipolate?GL_LINEAR:GL_NEAREST); - glTexParameteri(GL_TEXTURE_RECTANGLE,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_RECTANGLE,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); - - if ( remap_pixBuf ) - { - ::free( remap_pixBuf ); remap_pixBuf = NULL; - } - if ( remap_pixPtr ) - { - ::free( remap_pixPtr ); remap_pixPtr = NULL; - } - - if ( use_sw_pix_remap ) - { - texture_width = view_width; - texture_height = view_height; - } - else - { - texture_width = GL_NES_WIDTH; - texture_height = GL_NES_HEIGHT; - } - if ( texture_width < GL_NES_WIDTH ) - { - texture_width = GL_NES_WIDTH; - } - if ( texture_height < GL_NES_HEIGHT ) - { - texture_height = GL_NES_HEIGHT; - } - - if ( use_sw_pix_remap ) - { - remap_pixBuf = (uint32_t*)malloc( texture_width * texture_height * sizeof(uint32_t) ); - - if ( remap_pixBuf ) - { - memset( remap_pixBuf, 0, texture_width * texture_height * sizeof(uint32_t) ); - } - - remap_pixPtr = (uint32_t**)malloc( texture_width * texture_height * sizeof(uintptr_t) ); - - if ( remap_pixPtr ) - { - memset( remap_pixPtr, 0, texture_width * texture_height * sizeof(uintptr_t) ); - } - calcPixRemap(); - } - - glTexImage2D(GL_TEXTURE_RECTANGLE, 0, - GL_RGBA8, texture_width, texture_height, 0, + glTexImage2D( GL_TEXTURE_RECTANGLE, 0, + GL_RGBA8, GL_NES_WIDTH, GL_NES_HEIGHT, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0 ); } @@ -146,7 +88,7 @@ void gameViewGL_t::initializeGL(void) //QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions(); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - printf("GL Init!\n"); + //printf("GL Init!\n"); buildTextures(); } @@ -155,7 +97,7 @@ void gameViewGL_t::resizeGL(int w, int h) { w = (int)( devPixRatio * w ); h = (int)( devPixRatio * h ); - printf("GL Resize: %i x %i \n", w, h ); + //printf("GL Resize: %i x %i \n", w, h ); glViewport(0, 0, w, h); view_width = w; @@ -169,6 +111,8 @@ void gameViewGL_t::resizeGL(int w, int h) void gameViewGL_t::paintGL(void) { + int texture_width = gl_shm->ncol; + int texture_height = gl_shm->nrow; int l=0, r=texture_width; int t=0, b=texture_height; @@ -189,59 +133,34 @@ void gameViewGL_t::paintGL(void) int sy=(view_height-rh)/2; glViewport(sx, sy, rw, rh); - //glViewport( 0, 0, screen_width, screen_height); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); - //glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0); glOrtho( 0.0, rw, 0.0, rh, -1.0, 1.0); glDisable(GL_DEPTH_TEST); glClearColor( 0.0, 0.0f, 0.0f, 0.0f); // Background color to black. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - //glEnable(GL_LINE_SMOOTH); glDisable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_RECTANGLE); - //glBindTexture(GL_TEXTURE_2D, gltexture); glBindTexture(GL_TEXTURE_RECTANGLE, gltexture); - //print_pixbuf(); - //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, - // GL_RGBA, GL_UNSIGNED_BYTE, gl_shm->pixbuf ); - //glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA8, 256, 256, 0, - // GL_BGRA, GL_UNSIGNED_BYTE, gl_shm->pixbuf ); - if ( use_sw_pix_remap ) - { - doRemap(); - - glTexSubImage2D(GL_TEXTURE_RECTANGLE, 0, - 0, 0, texture_width, texture_height, - GL_BGRA, GL_UNSIGNED_BYTE, remap_pixBuf ); - } - else - { - glTexSubImage2D(GL_TEXTURE_RECTANGLE, 0, - 0, 0, texture_width, texture_height, - GL_BGRA, GL_UNSIGNED_BYTE, gl_shm->pixbuf ); - } + glTexSubImage2D(GL_TEXTURE_RECTANGLE, 0, + 0, 0, GL_NES_WIDTH, GL_NES_HEIGHT, + GL_BGRA, GL_UNSIGNED_BYTE, gl_shm->pixbuf ); glBegin(GL_QUADS); - //glTexCoord2f(1.0f*l/256, 1.0f*b/256); // Bottom left of picture. - //glVertex2f(-1.0f, -1.0f); // Bottom left of target. glTexCoord2f( l, b); // Bottom left of picture. glVertex2f( 0.0, 0.0f); // Bottom left of target. - //glTexCoord2f(1.0f*r/256, 1.0f*b/256);// Bottom right of picture. glTexCoord2f(r, b);// Bottom right of picture. glVertex2f( rw, 0.0f); // Bottom right of target. - //glTexCoord2f(1.0f*r/256, 1.0f*t/256); // Top right of our picture. glTexCoord2f(r, t); // Top right of our picture. glVertex2f( rw, rh); // Top right of target. - //glTexCoord2f(1.0f*l/256, 1.0f*t/256); // Top left of our picture. glTexCoord2f(l, t); // Top left of our picture. glVertex2f( 0.0f, rh); // Top left of target. glEnd(); @@ -250,118 +169,4 @@ void gameViewGL_t::paintGL(void) glDisable(GL_TEXTURE_RECTANGLE); //printf("Paint GL!\n"); -} - -void gameViewGL_t::doRemap(void) -{ - int x,y,i; - - i=0; - for (x=0; xncol; - gh = gl_shm->nrow; - - sx = (float)w / (float)gw; - sy = (float)h / (float)gh; - - if (sx < sy ) - { - sy = sx; - } - else - { - sx = sy; - } - - sw = (int) ( (float)gw * sx ); - sh = (int) ( (float)gh * sy ); - - llx = (w - sw) / 2; - lly = (h - sh) / 2; - urx = llx + sw; - ury = lly + sh; - - i=0; - for (y=0; y ury) ) - { - for (x=0; x urx) ) - { - remap_pixPtr[i] = 0; i++; - } - else - { - nw = (float)(x - llx) / (float)sw; - nh = (float)(y - lly) / (float)sh; - - rx = (int)((float)gw * nw); - ry = (int)((float)gh * nh); - - if ( rx < 0 ) - { - rx = 0; - } - else if ( rx >= GL_NES_WIDTH ) - { - rx = GL_NES_WIDTH-1; - } - if ( ry < 0 ) - { - ry = 0; - } - else if ( ry >= GL_NES_HEIGHT ) - { - ry = GL_NES_HEIGHT-1; - } - - j = (ry * GL_NES_WIDTH) + rx; - - remap_pixPtr[i] = &gl_shm->pixbuf[j]; i++; - - //printf("Remap: (%i,%i)=%i (%i,%i)=%i \n", x,y,i, rx,ry,j ); - } - } - } - } - //numRendLines = gh; -} +} \ No newline at end of file diff --git a/src/drivers/Qt/GameViewerGL.h b/src/drivers/Qt/GameViewerGL.h index 45776c05..3494928d 100644 --- a/src/drivers/Qt/GameViewerGL.h +++ b/src/drivers/Qt/GameViewerGL.h @@ -14,26 +14,22 @@ class gameViewGL_t : public QOpenGLWidget, protected QOpenGLFunctions gameViewGL_t(QWidget *parent = 0); ~gameViewGL_t(void); - int init( double devPixRatio = 1.0f ); + int init( void ); protected: void initializeGL(void); - void resizeGL(int w, int h); - void paintGL(void); + void resizeGL(int w, int h); + void paintGL(void); - void buildTextures(void); - void calcPixRemap(void); - void doRemap(void); + void buildTextures(void); + void calcPixRemap(void); + void doRemap(void); - double devPixRatio; - int texture_width; - int texture_height; - int view_width; - int view_height; - GLuint gltexture; - bool use_sw_pix_remap; - uint32_t *remap_pixBuf; - uint32_t **remap_pixPtr; + double devPixRatio; + int view_width; + int view_height; + GLuint gltexture; + bool linearFilter; private slots: }; diff --git a/src/drivers/Qt/main.cpp b/src/drivers/Qt/main.cpp index 83466f47..6c16f142 100644 --- a/src/drivers/Qt/main.cpp +++ b/src/drivers/Qt/main.cpp @@ -1,29 +1,19 @@ #include -#include #include "Qt/GameApp.h" #include "Qt/fceuWrapper.h" int main( int argc, char *argv[] ) { - double devPixRatio = 1.0; - QApplication app(argc, argv); + QApplication app(argc, argv); gameWin_t win; - QScreen *screen = QGuiApplication::primaryScreen(); + fceuWrapperInit( argc, argv ); - if ( screen != NULL ) - { - devPixRatio = screen->devicePixelRatio(); - printf("Ratio: %f \n", screen->devicePixelRatio() ); - } + win.resize( 512, 512 ); + win.show(); - fceuWrapperInit( argc, argv ); - - win.resize( 512, 512 ); - win.show(); - - win.viewport->init( devPixRatio ); + win.viewport->init(); return app.exec(); } From d38f1b0c1ba976054c93857ac0d08261d7113725 Mon Sep 17 00:00:00 2001 From: mjbudd77 Date: Tue, 30 Jun 2020 20:00:29 -0400 Subject: [PATCH 030/100] Build fix for minizip include in MAC OS --- src/file.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/file.cpp b/src/file.cpp index 0aeb6ae2..f7f58cbd 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -33,7 +33,11 @@ #include "utils/memory.h" #include "utils/md5.h" #ifdef _SYSTEM_MINIZIP +#ifdef __linux #include +#else // Apple Most Likely +#include +#endif #else #include "utils/unzip.h" #endif From 104f7c465eb48ed43c5caa466212b3416adf85c7 Mon Sep 17 00:00:00 2001 From: mjbudd77 Date: Tue, 30 Jun 2020 20:04:17 -0400 Subject: [PATCH 031/100] Updated init call for game viewer SDL to match GL. --- src/drivers/Qt/GameViewerSDL.cpp | 4 +--- src/drivers/Qt/GameViewerSDL.h | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/drivers/Qt/GameViewerSDL.cpp b/src/drivers/Qt/GameViewerSDL.cpp index 8576ffac..50dffda1 100644 --- a/src/drivers/Qt/GameViewerSDL.cpp +++ b/src/drivers/Qt/GameViewerSDL.cpp @@ -37,12 +37,10 @@ gameViewSDL_t::~gameViewSDL_t(void) } -int gameViewSDL_t::init( double devPixRatioIn ) +int gameViewSDL_t::init(void) { WId windowHandle; - devPixRatio = devPixRatioIn; - if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) { printf("[SDL] Failed to initialize video subsystem.\n"); diff --git a/src/drivers/Qt/GameViewerSDL.h b/src/drivers/Qt/GameViewerSDL.h index 61f3da04..2a7b4b05 100644 --- a/src/drivers/Qt/GameViewerSDL.h +++ b/src/drivers/Qt/GameViewerSDL.h @@ -16,7 +16,7 @@ class gameViewSDL_t : public QWidget gameViewSDL_t(QWidget *parent = 0); ~gameViewSDL_t(void); - int init(double devPixRatioIn = 1.0); + int init(void); void reset(void); void cleanup(void); From e8d3b9da46f3a678b9090b7a9da344403d0e22a3 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Tue, 30 Jun 2020 20:20:50 -0400 Subject: [PATCH 032/100] Added macOS build script for pipeline. --- appveyor.yml | 12 ++++++++++++ pipelines/linux_build.sh | 1 + pipelines/macOS_build.sh | 24 ++++++++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 pipelines/macOS_build.sh diff --git a/appveyor.yml b/appveyor.yml index 6d0f01bf..869bf0fe 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -13,6 +13,9 @@ environment: appveyor_build_worker_image: Ubuntu2004 #appveyor_build_worker_image: Ubuntu1804 + - job_name: macOS + appveyor_build_worker_image: macos + for: - @@ -38,3 +41,12 @@ for: build_script: - sh: ./pipelines/linux_build.sh + + - + matrix: + only: + - job_name: macOS + + build_script: + - sh: ./pipelines/macOS_build.sh + diff --git a/pipelines/linux_build.sh b/pipelines/linux_build.sh index f4a979ab..e5ffe5d4 100755 --- a/pipelines/linux_build.sh +++ b/pipelines/linux_build.sh @@ -2,6 +2,7 @@ id pwd +uname -a cat /etc/os-release SCRIPT_DIR=$( cd $(dirname $BASH_SOURCE[0]); pwd ); diff --git a/pipelines/macOS_build.sh b/pipelines/macOS_build.sh new file mode 100644 index 00000000..51762734 --- /dev/null +++ b/pipelines/macOS_build.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +echo ' MacOS Build !!! ' +id +pwd +uname -a +sw_vers + +SCRIPT_DIR=$( cd $(dirname $BASH_SOURCE[0]); pwd ); + +gcc --version + +echo '****************************************' +echo "APPVEYOR_SSH_KEY=$APPVEYOR_SSH_KEY"; +echo "APPVEYOR_SSH_BLOCK=$APPVEYOR_SSH_BLOCK"; +echo '****************************************' + +brew install sdl2 +brew install qt5 + +# Debug via ssh if necessary +if [ ! -z $APPVEYOR_SSH_BLOCK ]; then + curl -sflL 'https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-ssh.sh' | bash -e - +fi From bb312d8a55f8ceff9c0e0e79ad2a003770c2ffe1 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Tue, 30 Jun 2020 20:42:16 -0400 Subject: [PATCH 033/100] Take 2 mac build --- appveyor.yml | 38 ++------------------------------------ pipelines/macOS_build.sh | 7 +++++++ 2 files changed, 9 insertions(+), 36 deletions(-) mode change 100644 => 100755 pipelines/macOS_build.sh diff --git a/appveyor.yml b/appveyor.yml index 869bf0fe..e67172b6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,17 +3,7 @@ version: 1.0.{build} environment: matrix: - - job_name: Windows 32 - appveyor_build_worker_image: Visual Studio 2019 - - - job_name: Windows 64 - appveyor_build_worker_image: Visual Studio 2019 - - - job_name: Ubuntu - appveyor_build_worker_image: Ubuntu2004 - #appveyor_build_worker_image: Ubuntu1804 - - - job_name: macOS + - job_name: MacOS appveyor_build_worker_image: macos for: @@ -21,31 +11,7 @@ for: - matrix: only: - - job_name: Windows 32 - - build_script: - - cmd: pipelines/win32_build.bat - - - - matrix: - only: - - job_name: Windows 64 - - build_script: - - cmd: pipelines/win64_build.bat - - - - matrix: - only: - - job_name: Ubuntu - - build_script: - - sh: ./pipelines/linux_build.sh - - - - matrix: - only: - - job_name: macOS + - job_name: MacOS build_script: - sh: ./pipelines/macOS_build.sh diff --git a/pipelines/macOS_build.sh b/pipelines/macOS_build.sh old mode 100644 new mode 100755 index 51762734..69705d61 --- a/pipelines/macOS_build.sh +++ b/pipelines/macOS_build.sh @@ -17,6 +17,13 @@ echo '****************************************' brew install sdl2 brew install qt5 +brew install minizip +brew install zlib + +mkdir build; +cd build; +/usr/local/Cellar/qt/5.15.0/bin/qmake .. +make # Debug via ssh if necessary if [ ! -z $APPVEYOR_SSH_BLOCK ]; then From e161869bf5e57070ad3794239de69b0cbd8e30f2 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Tue, 30 Jun 2020 20:50:11 -0400 Subject: [PATCH 034/100] Mac standalone test --- appveyor.yml | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index e67172b6..62a9c454 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,18 +1,7 @@ version: 1.0.{build} -environment: - matrix: +image: macos - - job_name: MacOS - appveyor_build_worker_image: macos - -for: - - - - matrix: - only: - - job_name: MacOS - - build_script: - - sh: ./pipelines/macOS_build.sh +build_script: +- sh: ./pipelines/macOS_build.sh From fa8b2ce810e6b66dd57cc9e3567eba8113c6634e Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Tue, 30 Jun 2020 20:53:54 -0400 Subject: [PATCH 035/100] macOS take 3 --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 62a9c454..0da6cb58 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,6 @@ version: 1.0.{build} -image: macos +image: macOS build_script: - sh: ./pipelines/macOS_build.sh From 2fbf934633becfed12e33d206800d2b56b58b4e6 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Tue, 30 Jun 2020 21:28:18 -0400 Subject: [PATCH 036/100] MacOS build take 4 --- fceux.pro | 2 ++ pipelines/macOS_build.sh | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/fceux.pro b/fceux.pro index 46a7c2fd..6961d182 100644 --- a/fceux.pro +++ b/fceux.pro @@ -48,6 +48,8 @@ unix { QMAKE_CXXFLAGS -= -O2 QMAKE_CXXFLAGS += -D__QT_DRIVER__ -O0 -g3 -Wall -Wno-write-strings -Wno-sign-compare -Wno-parentheses -Wno-unused-local-typedefs QMAKE_CXXFLAGS_RELEASE -= -O2 + + LIBS += -lz } # Input diff --git a/pipelines/macOS_build.sh b/pipelines/macOS_build.sh index 69705d61..9596f945 100755 --- a/pipelines/macOS_build.sh +++ b/pipelines/macOS_build.sh @@ -18,11 +18,15 @@ echo '****************************************' brew install sdl2 brew install qt5 brew install minizip -brew install zlib +#brew install zlib # Already installed in appveyor macOS + +export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig: + +QMAKE=`find /usr/local -name qmake`; mkdir build; cd build; -/usr/local/Cellar/qt/5.15.0/bin/qmake .. +$QMAKE .. make # Debug via ssh if necessary From 588d566b92341981976dd1292cb9ab6675633506 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Tue, 30 Jun 2020 21:37:09 -0400 Subject: [PATCH 037/100] Added comments into macOS pipeline script. Added other OSs back into pipeline. --- appveyor.yml | 51 +++++++++++++++++++++++++++++++++++++--- pipelines/macOS_build.sh | 15 ++++++++++++ 2 files changed, 63 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 0da6cb58..696e0c74 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,7 +1,52 @@ version: 1.0.{build} -image: macOS +environment: + matrix: -build_script: -- sh: ./pipelines/macOS_build.sh + - job_name: Windows 32 + appveyor_build_worker_image: Visual Studio 2019 + + - job_name: Windows 64 + appveyor_build_worker_image: Visual Studio 2019 + + - job_name: Ubuntu + appveyor_build_worker_image: Ubuntu2004 + #appveyor_build_worker_image: Ubuntu1804 + + - job_name: MacOS + appveyor_build_worker_image: macOS + +for: + + - + matrix: + only: + - job_name: Windows 32 + + build_script: + - cmd: pipelines/win32_build.bat + + - + matrix: + only: + - job_name: Windows 64 + + build_script: + - cmd: pipelines/win64_build.bat + + - + matrix: + only: + - job_name: Ubuntu + + build_script: + - sh: ./pipelines/linux_build.sh + + - + matrix: + only: + - job_name: MacOS + + build_script: + - sh: ./pipelines/macOS_build.sh diff --git a/pipelines/macOS_build.sh b/pipelines/macOS_build.sh index 9596f945..32e70a83 100755 --- a/pipelines/macOS_build.sh +++ b/pipelines/macOS_build.sh @@ -15,15 +15,30 @@ echo "APPVEYOR_SSH_KEY=$APPVEYOR_SSH_KEY"; echo "APPVEYOR_SSH_BLOCK=$APPVEYOR_SSH_BLOCK"; echo '****************************************' +echo '****************************************' +echo 'Install Dependency sdl2' +echo '****************************************' brew install sdl2 + +echo '****************************************' +echo 'Install Dependency Qt5' +echo '****************************************' brew install qt5 + +echo '****************************************' +echo 'Install Dependency minizip' +echo '****************************************' brew install minizip + #brew install zlib # Already installed in appveyor macOS export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig: QMAKE=`find /usr/local -name qmake`; +echo '**************************' +echo '*** Building Project ***' +echo '**************************' mkdir build; cd build; $QMAKE .. From 9407867e18ed479029e213968cf4ed6c987eaa90 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Tue, 30 Jun 2020 22:04:50 -0400 Subject: [PATCH 038/100] Added qmake in to linux pipeline --- pipelines/linux_build.sh | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/pipelines/linux_build.sh b/pipelines/linux_build.sh index e5ffe5d4..995d43e5 100755 --- a/pipelines/linux_build.sh +++ b/pipelines/linux_build.sh @@ -67,10 +67,10 @@ sudo apt-get --assume-yes install libgtksourceview-3.0-dev pkg-config --cflags --libs gtksourceview-3.0 # Install scons -echo '****************************************' -echo 'Install Build Dependency scons' -echo '****************************************' -sudo apt-get --assume-yes install scons +#echo '****************************************' +#echo 'Install Build Dependency scons' +#echo '****************************************' +#sudo apt-get --assume-yes install scons # Install cppcheck echo '****************************************' @@ -86,13 +86,14 @@ mkdir -p $INSTALL_PREFIX/usr; #scons GTK3=1 SYSTEM_LUA=1 SYSTEM_MINIZIP=1 CREATE_AVI=1 install --prefix=$INSTALL_PREFIX/usr echo "Num CPU: `nproc`"; mkdir build; cd build; -cmake \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX/usr \ - -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ - .. +qmake .. +#cmake \ +# -DCMAKE_BUILD_TYPE=Release \ +# -DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX/usr \ +# -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ +# .. make -j `nproc` -make install +#make install # Debug via ssh if necessary if [ ! -z $APPVEYOR_SSH_BLOCK ]; then From e748fb67f491daa89ea87adaa845d74bb55d2722 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Tue, 30 Jun 2020 22:28:02 -0400 Subject: [PATCH 039/100] Added QT5 dependency installation to the linux build --- pipelines/linux_build.sh | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/pipelines/linux_build.sh b/pipelines/linux_build.sh index 995d43e5..f95ef333 100755 --- a/pipelines/linux_build.sh +++ b/pipelines/linux_build.sh @@ -55,16 +55,22 @@ pkg-config --cflags --libs minizip # GTK+-2 is no longer needed #sudo apt-get install libgtk2.0-dev -# Install GTK+-3 -echo '****************************************' -echo 'Install Dependency libgtk-3-dev' -echo '****************************************' -sudo apt-get --assume-yes install libgtk-3-dev -pkg-config --cflags --libs gtk+-3.0 +## Install GTK+-3 +#echo '****************************************' +#echo 'Install Dependency libgtk-3-dev' +#echo '****************************************' +#sudo apt-get --assume-yes install libgtk-3-dev +#pkg-config --cflags --libs gtk+-3.0 +# +## Install GTK+-3 Sourceview +#sudo apt-get --assume-yes install libgtksourceview-3.0-dev +#pkg-config --cflags --libs gtksourceview-3.0 -# Install GTK+-3 Sourceview -sudo apt-get --assume-yes install libgtksourceview-3.0-dev -pkg-config --cflags --libs gtksourceview-3.0 +# Install QT5 +echo '****************************************' +echo 'Install Dependency Qt5' +echo '****************************************' +sudo apt-get --assume-yes install qt5-default # Install scons #echo '****************************************' @@ -93,7 +99,7 @@ qmake .. # -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ # .. make -j `nproc` -#make install +make install # Debug via ssh if necessary if [ ! -z $APPVEYOR_SSH_BLOCK ]; then From 4a52e9d374af27c148462fd6bbc718954eb2fbde Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Wed, 1 Jul 2020 20:15:34 -0400 Subject: [PATCH 040/100] Added qmake install prefix to linux build script. --- pipelines/linux_build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipelines/linux_build.sh b/pipelines/linux_build.sh index f95ef333..c6421d03 100755 --- a/pipelines/linux_build.sh +++ b/pipelines/linux_build.sh @@ -92,7 +92,7 @@ mkdir -p $INSTALL_PREFIX/usr; #scons GTK3=1 SYSTEM_LUA=1 SYSTEM_MINIZIP=1 CREATE_AVI=1 install --prefix=$INSTALL_PREFIX/usr echo "Num CPU: `nproc`"; mkdir build; cd build; -qmake .. +qmake PREFIX=$INSTALL_PREFIX/usr .. #cmake \ # -DCMAKE_BUILD_TYPE=Release \ # -DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX/usr \ From e79650845fed368a397edfa89da7117a5c5772a3 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Wed, 1 Jul 2020 20:33:32 -0400 Subject: [PATCH 041/100] Added install commands in pipeline script --- pipelines/linux_build.sh | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pipelines/linux_build.sh b/pipelines/linux_build.sh index c6421d03..7d88db3e 100755 --- a/pipelines/linux_build.sh +++ b/pipelines/linux_build.sh @@ -99,7 +99,17 @@ qmake PREFIX=$INSTALL_PREFIX/usr .. # -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ # .. make -j `nproc` -make install +#make install + +# Install Files +cd .. # cd out of build +cp -f ./build/fceux $INSTALL_PREFIX/usr/bin/. +cp -a ./output/* $INSTALL_PREFIX/usr/share/fceux/. +cp -a ./fceux.png $INSTALL_PREFIX/usr/share/pixmaps/. +cp -a ./fceux.desktop $INSTALL_PREFIX/usr/share/applications/. +cp -a ./documentation/fceux.6 $INSTALL_PREFIX/usr/man/man6/. +cp -a ./documentation/fceux-net-server.6 $INSTALL_PREFIX/usr/man/man6/. + # Debug via ssh if necessary if [ ! -z $APPVEYOR_SSH_BLOCK ]; then From ab664db06c364942ec91926e8dbd8de73edb69f8 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Wed, 1 Jul 2020 20:47:57 -0400 Subject: [PATCH 042/100] Big fix for linux build script, make directories before installing files. --- pipelines/linux_build.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pipelines/linux_build.sh b/pipelines/linux_build.sh index 7d88db3e..e7347a43 100755 --- a/pipelines/linux_build.sh +++ b/pipelines/linux_build.sh @@ -103,8 +103,15 @@ make -j `nproc` # Install Files cd .. # cd out of build +mkdir -p $INSTALL_PREFIX/usr/bin/. +mkdir -p $INSTALL_PREFIX/usr/share/fceux +mkdir -p $INSTALL_PREFIX/usr/share/pixmaps +mkdir -p $INSTALL_PREFIX/usr/share/applications +mkdir -p $INSTALL_PREFIX/usr/man/man6 + cp -f ./build/fceux $INSTALL_PREFIX/usr/bin/. cp -a ./output/* $INSTALL_PREFIX/usr/share/fceux/. +cp -a ./src/auxlib.lua $INSTALL_PREFIX/usr/share/fceux/. cp -a ./fceux.png $INSTALL_PREFIX/usr/share/pixmaps/. cp -a ./fceux.desktop $INSTALL_PREFIX/usr/share/applications/. cp -a ./documentation/fceux.6 $INSTALL_PREFIX/usr/man/man6/. From afc3a61014f73266dfb96413035ea6092927ee12 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Wed, 1 Jul 2020 22:03:59 -0400 Subject: [PATCH 043/100] Started putting together window framework for sound configuration. --- fceux.pro | 2 + src/drivers/Qt/GameApp.cpp | 25 +++++++++ src/drivers/Qt/GameApp.h | 2 + src/drivers/Qt/GameSoundConf.cpp | 90 ++++++++++++++++++++++++++++++++ src/drivers/Qt/GameSoundConf.h | 39 ++++++++++++++ 5 files changed, 158 insertions(+) create mode 100644 src/drivers/Qt/GameSoundConf.cpp create mode 100644 src/drivers/Qt/GameSoundConf.h diff --git a/fceux.pro b/fceux.pro index 6961d182..afd60019 100644 --- a/fceux.pro +++ b/fceux.pro @@ -298,11 +298,13 @@ HEADERS += src/drivers/Qt/GameApp.h HEADERS += src/drivers/Qt/GameViewerGL.h HEADERS += src/drivers/Qt/GameViewerSDL.h HEADERS += src/drivers/Qt/GamePadConf.h +HEADERS += src/drivers/Qt/GameSoundConf.h SOURCES += src/drivers/Qt/main.cpp SOURCES += src/drivers/Qt/GameApp.cpp SOURCES += src/drivers/Qt/GameViewerGL.cpp SOURCES += src/drivers/Qt/GameViewerSDL.cpp SOURCES += src/drivers/Qt/GamePadConf.cpp +SOURCES += src/drivers/Qt/GameSoundConf.cpp SOURCES += src/drivers/Qt/fceuWrapper.cpp SOURCES += src/drivers/Qt/config.cpp SOURCES += src/drivers/Qt/input.cpp diff --git a/src/drivers/Qt/GameApp.cpp b/src/drivers/Qt/GameApp.cpp index 6d402625..fad66336 100644 --- a/src/drivers/Qt/GameApp.cpp +++ b/src/drivers/Qt/GameApp.cpp @@ -4,6 +4,7 @@ #include "Qt/GameApp.h" #include "Qt/GamePadConf.h" +#include "Qt/GameSoundConf.h" #include "Qt/fceuWrapper.h" #include "Qt/keyscan.h" @@ -111,6 +112,14 @@ void gameWin_t::createMainMenu(void) optMenu->addAction(gamePadConfig); + // Options -> Sound Config + gameSoundConfig = new QAction(tr("&Sound Config"), this); + //gameSoundConfig->setShortcut( QKeySequence(tr("Ctrl+C"))); + gameSoundConfig->setStatusTip(tr("Sound Configure")); + connect(gameSoundConfig, SIGNAL(triggered()), this, SLOT(openGameSndConfWin(void)) ); + + optMenu->addAction(gameSoundConfig); + //----------------------------------------------------------------------- // Help helpMenu = menuBar()->addMenu(tr("&Help")); @@ -208,6 +217,22 @@ void gameWin_t::openGamePadConfWin(void) //printf("GamePad Config Window Destroyed\n"); } +void gameWin_t::openGameSndConfWin(void) +{ + GameSndConfDialog_t *sndConfWin; + + printf("Open Sound Config Window\n"); + + sndConfWin = new GameSndConfDialog_t(this); + + sndConfWin->show(); + sndConfWin->exec(); + + delete sndConfWin; + + printf("Sound Config Window Destroyed\n"); +} + void gameWin_t::aboutQPlot(void) { printf("About QPlot\n"); diff --git a/src/drivers/Qt/GameApp.h b/src/drivers/Qt/GameApp.h index 08790225..ddd624d1 100644 --- a/src/drivers/Qt/GameApp.h +++ b/src/drivers/Qt/GameApp.h @@ -39,6 +39,7 @@ class gameWin_t : public QMainWindow QAction *closeROM; QAction *quitAct; QAction *gamePadConfig; + QAction *gameSoundConfig; QAction *aboutAct; QTimer *gameTimer; @@ -59,6 +60,7 @@ class gameWin_t : public QMainWindow void closeROMCB(void); void aboutQPlot(void); void openGamePadConfWin(void); + void openGameSndConfWin(void); void runGameFrame(void); }; diff --git a/src/drivers/Qt/GameSoundConf.cpp b/src/drivers/Qt/GameSoundConf.cpp new file mode 100644 index 00000000..6cf0d037 --- /dev/null +++ b/src/drivers/Qt/GameSoundConf.cpp @@ -0,0 +1,90 @@ +// GameSoundConf.cpp +// +#include "Qt/GameSoundConf.h" +#include "Qt/main.h" +#include "Qt/config.h" +#include "Qt/fceuWrapper.h" + +//---------------------------------------------------- +GameSndConfDialog_t::GameSndConfDialog_t(QWidget *parent) + : QDialog( parent ) +{ + QHBoxLayout *hbox1, *hbox2; + QVBoxLayout *vbox1; + QLabel *lbl; + + setWindowTitle("Sound Config"); + + hbox1 = new QHBoxLayout(); + vbox1 = new QVBoxLayout(); + + // Enable Sound Select + enaChkbox = new QCheckBox("Enable Sound"); + // Enable Low Pass Filter Select + enaLowPass = new QCheckBox("Enable Low Pass Filter"); + + vbox1->addWidget( enaChkbox ); + vbox1->addWidget( enaLowPass ); + + // Audio Quality Select + hbox2 = new QHBoxLayout(); + + lbl = new QLabel("Quality:"); + + qualitySelect = new QComboBox(); + + qualitySelect->addItem( tr("Low") , 0 ); + qualitySelect->addItem( tr("High") , 1 ); + qualitySelect->addItem( tr("Very High"), 2 ); + + hbox2->addWidget( lbl ); + hbox2->addWidget( qualitySelect ); + + vbox1->addLayout( hbox2 ); + + // Sample Rate Select + hbox2 = new QHBoxLayout(); + + lbl = new QLabel("Rate:"); + + rateSelect = new QComboBox(); + + rateSelect->addItem( tr("11025"), 11025 ); + rateSelect->addItem( tr("22050"), 22050 ); + rateSelect->addItem( tr("44100"), 44100 ); + rateSelect->addItem( tr("48000"), 48000 ); + rateSelect->addItem( tr("96000"), 96000 ); + + hbox2->addWidget( lbl ); + hbox2->addWidget( rateSelect ); + + vbox1->addLayout( hbox2 ); + + // Buffer Size Select + // + lbl = new QLabel("Buffer Size (in ms)"); + + bufSizeSlider = new QSlider( Qt::Horizontal ); + + bufSizeSlider->setMinimum( 15); + bufSizeSlider->setMaximum(200); + bufSizeSlider->setSliderPosition(128); + + vbox1->addWidget( lbl ); + vbox1->addWidget( bufSizeSlider ); + + // Swap Duty Cycles + swapDutyChkbox = new QCheckBox("Swap Duty Cycles"); + vbox1->addWidget( swapDutyChkbox ); + + hbox1->addLayout( vbox1 ); + + // Set Final Layout + setLayout( hbox1 ); +} +//---------------------------------------------------- +GameSndConfDialog_t::~GameSndConfDialog_t(void) +{ + +} +//---------------------------------------------------- diff --git a/src/drivers/Qt/GameSoundConf.h b/src/drivers/Qt/GameSoundConf.h new file mode 100644 index 00000000..455a5009 --- /dev/null +++ b/src/drivers/Qt/GameSoundConf.h @@ -0,0 +1,39 @@ +// GameSoundConf.h +// + +#ifndef __GameSndH__ +#define __GameSndH__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class GameSndConfDialog_t : public QDialog +{ + Q_OBJECT + + public: + GameSndConfDialog_t(QWidget *parent = 0); + ~GameSndConfDialog_t(void); + + protected: + QCheckBox *enaChkbox; + QCheckBox *enaLowPass; + QCheckBox *swapDutyChkbox; + QComboBox *qualitySelect; + QComboBox *rateSelect; + QSlider *bufSizeSlider; + + private slots: + +}; + +#endif From 021452b7f0a9000c29f427f674db0afd4d681b85 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Thu, 2 Jul 2020 20:49:52 -0400 Subject: [PATCH 044/100] Sound configure window in work. --- src/drivers/Qt/GameApp.cpp | 17 +- src/drivers/Qt/GameSoundConf.cpp | 303 ++++++++++++++++++++++++++++++- src/drivers/Qt/GameSoundConf.h | 21 +++ 3 files changed, 329 insertions(+), 12 deletions(-) diff --git a/src/drivers/Qt/GameApp.cpp b/src/drivers/Qt/GameApp.cpp index fad66336..ebd0df74 100644 --- a/src/drivers/Qt/GameApp.cpp +++ b/src/drivers/Qt/GameApp.cpp @@ -76,7 +76,7 @@ void gameWin_t::createMainMenu(void) fileMenu = menuBar()->addMenu(tr("&File")); // File -> Open ROM - openROM = new QAction(tr("&Open ROM"), this); + openROM = new QAction(tr("Open ROM"), this); openROM->setShortcuts(QKeySequence::Open); openROM->setStatusTip(tr("Open ROM File")); connect(openROM, SIGNAL(triggered()), this, SLOT(openROMFile(void)) ); @@ -84,7 +84,7 @@ void gameWin_t::createMainMenu(void) fileMenu->addAction(openROM); // File -> Close ROM - closeROM = new QAction(tr("&Close ROM"), this); + closeROM = new QAction(tr("Close ROM"), this); closeROM->setShortcut( QKeySequence(tr("Ctrl+C"))); closeROM->setStatusTip(tr("Close Loaded ROM")); connect(closeROM, SIGNAL(triggered()), this, SLOT(closeROMCB(void)) ); @@ -94,7 +94,8 @@ void gameWin_t::createMainMenu(void) fileMenu->addSeparator(); // File -> Quit - quitAct = new QAction(tr("&Quit"), this); + quitAct = new QAction(tr("Quit"), this); + quitAct->setShortcut( QKeySequence(tr("Ctrl+Q"))); quitAct->setStatusTip(tr("Quit the Application")); connect(quitAct, SIGNAL(triggered()), this, SLOT(closeApp())); @@ -102,10 +103,10 @@ void gameWin_t::createMainMenu(void) //----------------------------------------------------------------------- // Options - optMenu = menuBar()->addMenu(tr("&Options")); + optMenu = menuBar()->addMenu(tr("Options")); // Options -> GamePad Config - gamePadConfig = new QAction(tr("&GamePad Config"), this); + gamePadConfig = new QAction(tr("GamePad Config"), this); //gamePadConfig->setShortcut( QKeySequence(tr("Ctrl+C"))); gamePadConfig->setStatusTip(tr("GamePad Configure")); connect(gamePadConfig, SIGNAL(triggered()), this, SLOT(openGamePadConfWin(void)) ); @@ -113,7 +114,7 @@ void gameWin_t::createMainMenu(void) optMenu->addAction(gamePadConfig); // Options -> Sound Config - gameSoundConfig = new QAction(tr("&Sound Config"), this); + gameSoundConfig = new QAction(tr("Sound Config"), this); //gameSoundConfig->setShortcut( QKeySequence(tr("Ctrl+C"))); gameSoundConfig->setStatusTip(tr("Sound Configure")); connect(gameSoundConfig, SIGNAL(triggered()), this, SLOT(openGameSndConfWin(void)) ); @@ -122,9 +123,9 @@ void gameWin_t::createMainMenu(void) //----------------------------------------------------------------------- // Help - helpMenu = menuBar()->addMenu(tr("&Help")); + helpMenu = menuBar()->addMenu(tr("Help")); - aboutAct = new QAction(tr("&About"), this); + aboutAct = new QAction(tr("About"), this); aboutAct->setStatusTip(tr("About Qplot")); connect(aboutAct, SIGNAL(triggered()), this, SLOT(aboutQPlot(void)) ); diff --git a/src/drivers/Qt/GameSoundConf.cpp b/src/drivers/Qt/GameSoundConf.cpp index 6cf0d037..0f6ac901 100644 --- a/src/drivers/Qt/GameSoundConf.cpp +++ b/src/drivers/Qt/GameSoundConf.cpp @@ -1,7 +1,10 @@ // GameSoundConf.cpp // +#include "../../fceu.h" +#include "../../driver.h" #include "Qt/GameSoundConf.h" #include "Qt/main.h" +#include "Qt/dface.h" #include "Qt/config.h" #include "Qt/fceuWrapper.h" @@ -9,9 +12,12 @@ GameSndConfDialog_t::GameSndConfDialog_t(QWidget *parent) : QDialog( parent ) { + int buf; QHBoxLayout *hbox1, *hbox2; - QVBoxLayout *vbox1; + QVBoxLayout *vbox1, *vbox2; QLabel *lbl; + QGroupBox *frame; + QSlider *vslider; setWindowTitle("Sound Config"); @@ -23,6 +29,12 @@ GameSndConfDialog_t::GameSndConfDialog_t(QWidget *parent) // Enable Low Pass Filter Select enaLowPass = new QCheckBox("Enable Low Pass Filter"); + setCheckBoxFromProperty( enaChkbox , "SDL.Sound" ); + setCheckBoxFromProperty( enaLowPass, "SDL.Sound.LowPass" ); + + connect(enaChkbox , SIGNAL(stateChanged(int)), this, SLOT(enaSoundStateChange(int)) ); + connect(enaLowPass, SIGNAL(stateChanged(int)), this, SLOT(enaSoundLowPassChange(int)) ); + vbox1->addWidget( enaChkbox ); vbox1->addWidget( enaLowPass ); @@ -37,6 +49,8 @@ GameSndConfDialog_t::GameSndConfDialog_t(QWidget *parent) qualitySelect->addItem( tr("High") , 1 ); qualitySelect->addItem( tr("Very High"), 2 ); + setComboBoxFromProperty( qualitySelect, "SDL.Sound.Quality" ); + hbox2->addWidget( lbl ); hbox2->addWidget( qualitySelect ); @@ -55,6 +69,10 @@ GameSndConfDialog_t::GameSndConfDialog_t(QWidget *parent) rateSelect->addItem( tr("48000"), 48000 ); rateSelect->addItem( tr("96000"), 96000 ); + setComboBoxFromProperty( rateSelect, "SDL.Sound.Rate" ); + + g_config->getOption ("SDL.Sound.Rate", &buf); + hbox2->addWidget( lbl ); hbox2->addWidget( rateSelect ); @@ -62,23 +80,133 @@ GameSndConfDialog_t::GameSndConfDialog_t(QWidget *parent) // Buffer Size Select // - lbl = new QLabel("Buffer Size (in ms)"); + hbox2 = new QHBoxLayout(); + lbl = new QLabel("Buffer Size (in ms):"); + + bufSizeLabel = new QLabel("128"); bufSizeSlider = new QSlider( Qt::Horizontal ); bufSizeSlider->setMinimum( 15); bufSizeSlider->setMaximum(200); - bufSizeSlider->setSliderPosition(128); + //bufSizeSlider->setSliderPosition(128); + setSliderFromProperty( bufSizeSlider, bufSizeLabel, "SDL.Sound.BufSize" ); - vbox1->addWidget( lbl ); + hbox2->addWidget( lbl ); + hbox2->addWidget( bufSizeLabel ); + + vbox1->addLayout( hbox2 ); vbox1->addWidget( bufSizeSlider ); + + connect(bufSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(bufSizeChanged(int)) ); // Swap Duty Cycles swapDutyChkbox = new QCheckBox("Swap Duty Cycles"); vbox1->addWidget( swapDutyChkbox ); + setCheckBoxFromProperty( swapDutyChkbox , "SDL.SwapDuty" ); + + connect(swapDutyChkbox , SIGNAL(stateChanged(int)), this, SLOT(swapDutyCallback(int)) ); + hbox1->addLayout( vbox1 ); + frame = new QGroupBox(tr("Mixer:")); + hbox2 = new QHBoxLayout(); + + frame->setLayout( hbox2 ); + + hbox1->addWidget( frame ); + + frame = new QGroupBox(tr("Volume")); + vbox2 = new QVBoxLayout(); + volLbl = new QLabel("150"); + vslider = new QSlider( Qt::Vertical ); + vslider->setMinimum( 0); + vslider->setMaximum(255); + setSliderFromProperty( vslider, volLbl, "SDL.Sound.Volume" ); + + vbox2->addWidget( volLbl ); + vbox2->addWidget( vslider ); + frame->setLayout( vbox2 ); + hbox2->addWidget( frame ); + + connect(vslider, SIGNAL(valueChanged(int)), this, SLOT(volumeChanged(int)) ); + + frame = new QGroupBox(tr("Triangle")); + vbox2 = new QVBoxLayout(); + triLbl = new QLabel("255"); + vslider = new QSlider( Qt::Vertical ); + vslider->setMinimum( 0); + vslider->setMaximum(255); + setSliderFromProperty( vslider, triLbl, "SDL.Sound.TriangleVolume" ); + + vbox2->addWidget( triLbl ); + vbox2->addWidget( vslider ); + frame->setLayout( vbox2 ); + hbox2->addWidget( frame ); + + connect(vslider, SIGNAL(valueChanged(int)), this, SLOT(triangleChanged(int)) ); + + frame = new QGroupBox(tr("Square1")); + vbox2 = new QVBoxLayout(); + sqr1Lbl = new QLabel("255"); + vslider = new QSlider( Qt::Vertical ); + vslider->setMinimum( 0); + vslider->setMaximum(255); + setSliderFromProperty( vslider, sqr1Lbl, "SDL.Sound.Square1Volume" ); + + vbox2->addWidget( sqr1Lbl ); + vbox2->addWidget( vslider ); + frame->setLayout( vbox2 ); + hbox2->addWidget( frame ); + + connect(vslider, SIGNAL(valueChanged(int)), this, SLOT(square1Changed(int)) ); + + frame = new QGroupBox(tr("Square2")); + vbox2 = new QVBoxLayout(); + sqr2Lbl = new QLabel("255"); + vslider = new QSlider( Qt::Vertical ); + vslider->setMinimum( 0); + vslider->setMaximum(255); + setSliderFromProperty( vslider, sqr2Lbl, "SDL.Sound.Square2Volume" ); + + vbox2->addWidget( sqr2Lbl ); + vbox2->addWidget( vslider ); + frame->setLayout( vbox2 ); + hbox2->addWidget( frame ); + + connect(vslider, SIGNAL(valueChanged(int)), this, SLOT(square2Changed(int)) ); + + frame = new QGroupBox(tr("Noise")); + vbox2 = new QVBoxLayout(); + nseLbl = new QLabel("255"); + vslider = new QSlider( Qt::Vertical ); + vslider->setMinimum( 0); + vslider->setMaximum(255); + setSliderFromProperty( vslider, nseLbl, "SDL.Sound.NoiseVolume" ); + + vbox2->addWidget( nseLbl ); + vbox2->addWidget( vslider ); + frame->setLayout( vbox2 ); + hbox2->addWidget( frame ); + + connect(vslider, SIGNAL(valueChanged(int)), this, SLOT(noiseChanged(int)) ); + + frame = new QGroupBox(tr("PCM")); + vbox2 = new QVBoxLayout(); + pcmLbl = new QLabel("255"); + vslider = new QSlider( Qt::Vertical ); + vslider->setMinimum( 0); + vslider->setMaximum(255); + setSliderFromProperty( vslider, pcmLbl, "SDL.Sound.PCMVolume" ); + + vbox2->addWidget( pcmLbl ); + vbox2->addWidget( vslider ); + frame->setLayout( vbox2 ); + hbox2->addWidget( frame ); + + connect(vslider, SIGNAL(valueChanged(int)), this, SLOT(pcmChanged(int)) ); + // Set Final Layout setLayout( hbox1 ); } @@ -88,3 +216,170 @@ GameSndConfDialog_t::~GameSndConfDialog_t(void) } //---------------------------------------------------- +void GameSndConfDialog_t::setCheckBoxFromProperty( QCheckBox *cbx, const char *property ) +{ + int pval; + g_config->getOption (property, &pval); + + cbx->setCheckState( pval ? Qt::Checked : Qt::Unchecked ); +} +//---------------------------------------------------- +void GameSndConfDialog_t::setComboBoxFromProperty( QComboBox *cbx, const char *property ) +{ + int i, pval; + g_config->getOption (property, &pval); + + for (i=0; icount(); i++) + { + if ( pval == cbx->itemData(i) ) + { + cbx->setCurrentIndex(i); break; + } + } +} +//---------------------------------------------------- +void GameSndConfDialog_t::setSliderFromProperty( QSlider *slider, QLabel *lbl, const char *property ) +{ + int pval; + char stmp[32]; + g_config->getOption (property, &pval); + slider->setValue( pval ); + sprintf( stmp, "%i", pval ); + lbl->setText( stmp ); +} +//---------------------------------------------------- +void GameSndConfDialog_t::bufSizeChanged(int value) +{ + char stmp[32]; + + sprintf( stmp, "%i", value ); + + bufSizeLabel->setText(stmp); + + g_config->setOption ("SDL.Sound.BufSize", value); + // reset sound subsystem for changes to take effect + KillSound (); + InitSound (); +} +//---------------------------------------------------- +void GameSndConfDialog_t::volumeChanged(int value) +{ + char stmp[32]; + + sprintf( stmp, "%i", value ); + + volLbl->setText(stmp); + + g_config->setOption ("SDL.Sound.Volume", value); + FCEUI_SetSoundVolume (value); +} +//---------------------------------------------------- +void GameSndConfDialog_t::triangleChanged(int value) +{ + char stmp[32]; + + sprintf( stmp, "%i", value ); + + triLbl->setText(stmp); + + g_config->setOption ("SDL.Sound.TriangleVolume", value); + FCEUI_SetTriangleVolume (value); +} +//---------------------------------------------------- +void GameSndConfDialog_t::square1Changed(int value) +{ + char stmp[32]; + + sprintf( stmp, "%i", value ); + + sqr1Lbl->setText(stmp); + + g_config->setOption ("SDL.Sound.Square1Volume", value); + FCEUI_SetSquare1Volume (value); +} +//---------------------------------------------------- +void GameSndConfDialog_t::square2Changed(int value) +{ + char stmp[32]; + + sprintf( stmp, "%i", value ); + + sqr2Lbl->setText(stmp); + + g_config->setOption ("SDL.Sound.Square2Volume", value); + FCEUI_SetSquare2Volume (value); +} +//---------------------------------------------------- +void GameSndConfDialog_t::noiseChanged(int value) +{ + char stmp[32]; + + sprintf( stmp, "%i", value ); + + nseLbl->setText(stmp); + + g_config->setOption ("SDL.Sound.NoiseVolume", value); + FCEUI_SetNoiseVolume (value); +} +//---------------------------------------------------- +void GameSndConfDialog_t::pcmChanged(int value) +{ + char stmp[32]; + + sprintf( stmp, "%i", value ); + + pcmLbl->setText(stmp); + + g_config->setOption ("SDL.Sound.PCMVolume", value); + FCEUI_SetPCMVolume (value); +} +//---------------------------------------------------- +void GameSndConfDialog_t::enaSoundStateChange(int value) +{ + if ( value ) + { + int last_soundopt; + g_config->getOption ("SDL.Sound", &last_soundopt); + g_config->setOption ("SDL.Sound", 1); + if (GameInfo && !last_soundopt) + { + InitSound (); + } + } + else + { + g_config->setOption ("SDL.Sound", 0); + KillSound (); + } +} +//---------------------------------------------------- +void GameSndConfDialog_t::enaSoundLowPassChange(int value) +{ + if (value) + { + g_config->setOption ("SDL.Sound.LowPass", 1); + FCEUI_SetLowPass (1); + } + else + { + g_config->setOption ("SDL.Sound.LowPass", 0); + FCEUI_SetLowPass (0); + } + g_config->save (); +} +//---------------------------------------------------- +void GameSndConfDialog_t::swapDutyCallback(int value) +{ + if (value) + { + g_config->setOption ("SDL.SwapDuty", 1); + swapDuty = 1; + } + else + { + g_config->setOption ("SDL.SwapDuty", 0); + swapDuty = 0; + } + g_config->save (); +} +//---------------------------------------------------- diff --git a/src/drivers/Qt/GameSoundConf.h b/src/drivers/Qt/GameSoundConf.h index 455a5009..f6a9918e 100644 --- a/src/drivers/Qt/GameSoundConf.h +++ b/src/drivers/Qt/GameSoundConf.h @@ -31,8 +31,29 @@ class GameSndConfDialog_t : public QDialog QComboBox *qualitySelect; QComboBox *rateSelect; QSlider *bufSizeSlider; + QLabel *bufSizeLabel; + QLabel *volLbl; + QLabel *triLbl; + QLabel *sqr1Lbl; + QLabel *sqr2Lbl; + QLabel *nseLbl; + QLabel *pcmLbl; + + void setCheckBoxFromProperty( QCheckBox *cbx, const char *property ); + void setComboBoxFromProperty( QComboBox *cbx, const char *property ); + void setSliderFromProperty( QSlider *slider, QLabel *lbl, const char *property ); private slots: + void bufSizeChanged(int value); + void volumeChanged(int value); + void triangleChanged(int value); + void square1Changed(int value); + void square2Changed(int value); + void noiseChanged(int value); + void pcmChanged(int value); + void enaSoundStateChange(int value); + void enaSoundLowPassChange(int value); + void swapDutyCallback(int value); }; From 91e5427258b726d68875059bfb4e9b6e92d93281 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Thu, 2 Jul 2020 21:05:08 -0400 Subject: [PATCH 045/100] Successful test of full sound config window functionality. --- src/drivers/Qt/GameSoundConf.cpp | 29 ++++++++++++++++++++++++++++- src/drivers/Qt/GameSoundConf.h | 2 ++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/drivers/Qt/GameSoundConf.cpp b/src/drivers/Qt/GameSoundConf.cpp index 0f6ac901..8ead488f 100644 --- a/src/drivers/Qt/GameSoundConf.cpp +++ b/src/drivers/Qt/GameSoundConf.cpp @@ -51,6 +51,8 @@ GameSndConfDialog_t::GameSndConfDialog_t(QWidget *parent) setComboBoxFromProperty( qualitySelect, "SDL.Sound.Quality" ); + connect(qualitySelect, SIGNAL(currentIndexChanged(int)), this, SLOT(soundQualityChanged(int)) ); + hbox2->addWidget( lbl ); hbox2->addWidget( qualitySelect ); @@ -71,6 +73,8 @@ GameSndConfDialog_t::GameSndConfDialog_t(QWidget *parent) setComboBoxFromProperty( rateSelect, "SDL.Sound.Rate" ); + connect(rateSelect, SIGNAL(currentIndexChanged(int)), this, SLOT(soundRateChanged(int)) ); + g_config->getOption ("SDL.Sound.Rate", &buf); hbox2->addWidget( lbl ); @@ -231,7 +235,7 @@ void GameSndConfDialog_t::setComboBoxFromProperty( QComboBox *cbx, const char * for (i=0; icount(); i++) { - if ( pval == cbx->itemData(i) ) + if ( pval == cbx->itemData(i).toInt() ) { cbx->setCurrentIndex(i); break; } @@ -383,3 +387,26 @@ void GameSndConfDialog_t::swapDutyCallback(int value) g_config->save (); } //---------------------------------------------------- +void GameSndConfDialog_t::soundQualityChanged(int index) +{ + //printf("Sound Quality: %i : %i \n", index, qualitySelect->itemData(index).toInt() ); + + g_config->setOption ("SDL.Sound.Quality", qualitySelect->itemData(index).toInt() ); + + // reset sound subsystem for changes to take effect + KillSound (); + InitSound (); + g_config->save (); +} +//---------------------------------------------------- +void GameSndConfDialog_t::soundRateChanged(int index) +{ + //printf("Sound Rate: %i : %i \n", index, rateSelect->itemData(index).toInt() ); + + g_config->setOption ("SDL.Sound.Rate", rateSelect->itemData(index).toInt() ); + // reset sound subsystem for changes to take effect + KillSound (); + InitSound (); + g_config->save (); +} +//---------------------------------------------------- diff --git a/src/drivers/Qt/GameSoundConf.h b/src/drivers/Qt/GameSoundConf.h index f6a9918e..ebc97649 100644 --- a/src/drivers/Qt/GameSoundConf.h +++ b/src/drivers/Qt/GameSoundConf.h @@ -54,6 +54,8 @@ class GameSndConfDialog_t : public QDialog void enaSoundStateChange(int value); void enaSoundLowPassChange(int value); void swapDutyCallback(int value); + void soundQualityChanged(int index); + void soundRateChanged(int index); }; From 7eca2978edbe6383ef78ce506c78a17e531c6d1e Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Thu, 2 Jul 2020 21:08:46 -0400 Subject: [PATCH 046/100] Minor removal of underscored F on File menu. --- src/drivers/Qt/GameApp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/Qt/GameApp.cpp b/src/drivers/Qt/GameApp.cpp index ebd0df74..dcba7508 100644 --- a/src/drivers/Qt/GameApp.cpp +++ b/src/drivers/Qt/GameApp.cpp @@ -73,7 +73,7 @@ void gameWin_t::createMainMenu(void) //----------------------------------------------------------------------- // File - fileMenu = menuBar()->addMenu(tr("&File")); + fileMenu = menuBar()->addMenu(tr("File")); // File -> Open ROM openROM = new QAction(tr("Open ROM"), this); From 72141845f0eb8a3744768bc7268a75640b9f8b86 Mon Sep 17 00:00:00 2001 From: mjbudd77 Date: Fri, 3 Jul 2020 15:58:53 -0400 Subject: [PATCH 047/100] Changed gl_shm name to nes_shm. Added audio circular buffer to shared memory. --- fceux.pro | 2 +- src/drivers/Qt/GameApp.cpp | 2 +- src/drivers/Qt/GameViewerGL.cpp | 10 ++++---- src/drivers/Qt/GameViewerSDL.cpp | 10 ++++---- src/drivers/Qt/fceuWrapper.cpp | 8 +++---- src/drivers/Qt/{gl_win.cpp => nes_shm.cpp} | 18 +++++++-------- src/drivers/Qt/{gl_win.h => nes_shm.h} | 27 +++++++++++++++++----- src/drivers/Qt/sdl-sound.cpp | 20 ++++++++++++---- src/drivers/Qt/sdl-throttle.cpp | 16 +++++++++---- src/drivers/Qt/sdl-video.cpp | 16 ++++++------- 10 files changed, 82 insertions(+), 47 deletions(-) rename src/drivers/Qt/{gl_win.cpp => nes_shm.cpp} (67%) rename src/drivers/Qt/{gl_win.h => nes_shm.h} (61%) diff --git a/fceux.pro b/fceux.pro index afd60019..37eb3f9c 100644 --- a/fceux.pro +++ b/fceux.pro @@ -308,7 +308,7 @@ SOURCES += src/drivers/Qt/GameSoundConf.cpp SOURCES += src/drivers/Qt/fceuWrapper.cpp SOURCES += src/drivers/Qt/config.cpp SOURCES += src/drivers/Qt/input.cpp -SOURCES += src/drivers/Qt/gl_win.cpp +SOURCES += src/drivers/Qt/nes_shm.cpp SOURCES += src/drivers/Qt/keyscan.cpp SOURCES += src/drivers/Qt/sdl-sound.cpp SOURCES += src/drivers/Qt/sdl-video.cpp diff --git a/src/drivers/Qt/GameApp.cpp b/src/drivers/Qt/GameApp.cpp index dcba7508..dbbbb27b 100644 --- a/src/drivers/Qt/GameApp.cpp +++ b/src/drivers/Qt/GameApp.cpp @@ -24,7 +24,7 @@ gameWin_t::gameWin_t(QWidget *parent) connect( gameTimer, &QTimer::timeout, this, &gameWin_t::runGameFrame ); gameTimer->setTimerType( Qt::PreciseTimer ); - gameTimer->start( 10 ); + gameTimer->start( 16 ); gamePadConfWin = NULL; } diff --git a/src/drivers/Qt/GameViewerGL.cpp b/src/drivers/Qt/GameViewerGL.cpp index 851f0b96..51fe20cc 100644 --- a/src/drivers/Qt/GameViewerGL.cpp +++ b/src/drivers/Qt/GameViewerGL.cpp @@ -8,7 +8,7 @@ #include #include -#include "Qt/gl_win.h" +#include "Qt/nes_shm.h" #include "Qt/GameViewerGL.h" extern unsigned int gui_draw_area_width; @@ -111,8 +111,8 @@ void gameViewGL_t::resizeGL(int w, int h) void gameViewGL_t::paintGL(void) { - int texture_width = gl_shm->ncol; - int texture_height = gl_shm->nrow; + int texture_width = nes_shm->ncol; + int texture_height = nes_shm->nrow; int l=0, r=texture_width; int t=0, b=texture_height; @@ -149,7 +149,7 @@ void gameViewGL_t::paintGL(void) glTexSubImage2D(GL_TEXTURE_RECTANGLE, 0, 0, 0, GL_NES_WIDTH, GL_NES_HEIGHT, - GL_BGRA, GL_UNSIGNED_BYTE, gl_shm->pixbuf ); + GL_BGRA, GL_UNSIGNED_BYTE, nes_shm->pixbuf ); glBegin(GL_QUADS); glTexCoord2f( l, b); // Bottom left of picture. @@ -169,4 +169,4 @@ void gameViewGL_t::paintGL(void) glDisable(GL_TEXTURE_RECTANGLE); //printf("Paint GL!\n"); -} \ No newline at end of file +} diff --git a/src/drivers/Qt/GameViewerSDL.cpp b/src/drivers/Qt/GameViewerSDL.cpp index 50dffda1..be0b7039 100644 --- a/src/drivers/Qt/GameViewerSDL.cpp +++ b/src/drivers/Qt/GameViewerSDL.cpp @@ -6,7 +6,7 @@ #include #include -#include "Qt/gl_win.h" +#include "Qt/nes_shm.h" #include "Qt/GameViewerSDL.h" extern unsigned int gui_draw_area_width; @@ -147,10 +147,10 @@ void gameViewSDL_t::paintEvent( QPaintEvent *event ) int nesWidth = GL_NES_WIDTH; int nesHeight = GL_NES_HEIGHT; - if ( gl_shm != NULL ) + if ( nes_shm != NULL ) { - nesWidth = gl_shm->ncol; - nesHeight = gl_shm->nrow; + nesWidth = nes_shm->ncol; + nesHeight = nes_shm->nrow; } //printf(" %i x %i \n", nesWidth, nesHeight ); float xscale = (float)view_width / (float)nesWidth; @@ -183,7 +183,7 @@ void gameViewSDL_t::paintEvent( QPaintEvent *event ) int rowPitch; SDL_LockTexture( sdlTexture, nullptr, (void**)&textureBuffer, &rowPitch); { - memcpy( textureBuffer, gl_shm->pixbuf, GL_NES_HEIGHT*GL_NES_WIDTH*sizeof(uint32_t) ); + memcpy( textureBuffer, nes_shm->pixbuf, GL_NES_HEIGHT*GL_NES_WIDTH*sizeof(uint32_t) ); } SDL_UnlockTexture(sdlTexture); diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp index b077a140..f2513509 100644 --- a/src/drivers/Qt/fceuWrapper.cpp +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -12,7 +12,7 @@ #include "Qt/input.h" #include "Qt/sdl.h" #include "Qt/sdl-video.h" -#include "Qt/gl_win.h" +#include "Qt/nes_shm.h" #include "Qt/unix-netplay.h" #include "common/cheat.h" @@ -471,11 +471,11 @@ int fceuWrapperInit( int argc, char *argv[] ) return 0; } - gl_shm = open_video_shm(); + nes_shm = open_nes_shm(); - if ( gl_shm == NULL ) + if ( nes_shm == NULL ) { - printf("Error: Failed to open video Shared memory\n"); + printf("Error: Failed to open NES Shared memory\n"); return -1; } diff --git a/src/drivers/Qt/gl_win.cpp b/src/drivers/Qt/nes_shm.cpp similarity index 67% rename from src/drivers/Qt/gl_win.cpp rename to src/drivers/Qt/nes_shm.cpp index a3fe766e..59d1e948 100644 --- a/src/drivers/Qt/gl_win.cpp +++ b/src/drivers/Qt/nes_shm.cpp @@ -9,18 +9,18 @@ #include #include -#include "Qt/gl_win.h" +#include "Qt/nes_shm.h" -gl_win_shm_t *gl_shm = NULL; +nes_shm_t *nes_shm = NULL; //************************************************************************ -gl_win_shm_t *open_video_shm(void) +nes_shm_t *open_nes_shm(void) { int shmId; - gl_win_shm_t *vaddr; + nes_shm_t *vaddr; struct shmid_ds ds; - shmId = shmget( IPC_PRIVATE, sizeof(struct gl_win_shm_t), IPC_CREAT | S_IRWXU | S_IRWXG ); + shmId = shmget( IPC_PRIVATE, sizeof(struct nes_shm_t), IPC_CREAT | S_IRWXU | S_IRWXG ); if ( shmId == -1 ) { @@ -29,14 +29,14 @@ gl_win_shm_t *open_video_shm(void) } printf("Created ShmID: %i \n", shmId ); - vaddr = (gl_win_shm_t*)shmat( shmId, NULL, 0); + vaddr = (nes_shm_t*)shmat( shmId, NULL, 0); - if ( vaddr == (gl_win_shm_t*)-1 ) + if ( vaddr == (nes_shm_t*)-1 ) { - perror("Error: GLX shmat Failed:"); + perror("Error: NES shmat Failed:"); return NULL; } - memset( vaddr, 0, sizeof(struct gl_win_shm_t)); + memset( vaddr, 0, sizeof(struct nes_shm_t)); if ( shmctl( shmId, IPC_RMID, &ds ) != 0 ) { diff --git a/src/drivers/Qt/gl_win.h b/src/drivers/Qt/nes_shm.h similarity index 61% rename from src/drivers/Qt/gl_win.h rename to src/drivers/Qt/nes_shm.h index 88776ac8..0cc52bd6 100644 --- a/src/drivers/Qt/gl_win.h +++ b/src/drivers/Qt/nes_shm.h @@ -1,8 +1,8 @@ -// gl_win.cpp +// nes_shm.h // -#ifndef __GL_WIN_H__ -#define __GL_WIN_H__ +#ifndef __NES_SHM_H__ +#define __NES_SHM_H__ #include @@ -11,8 +11,9 @@ #define GL_NES_WIDTH 256 #define GL_NES_HEIGHT 256 +#define NES_AUDIO_BUFLEN 480000 -struct gl_win_shm_t +struct nes_shm_t { int pid; int run; @@ -59,10 +60,24 @@ struct gl_win_shm_t { memset( pixbuf, 0, sizeof(pixbuf) ); } + + struct sndBuf_t + { + int head; + int tail; + int16_t data[NES_AUDIO_BUFLEN]; + unsigned int starveCounter; + } sndBuf; + + void push_sound_sample( int16_t sample ) + { + sndBuf.data[ sndBuf.head ] = sample; + sndBuf.head = (sndBuf.head + 1) % NES_AUDIO_BUFLEN; + } }; -extern gl_win_shm_t *gl_shm; +extern nes_shm_t *nes_shm; -gl_win_shm_t *open_video_shm(void); +nes_shm_t *open_nes_shm(void); #endif diff --git a/src/drivers/Qt/sdl-sound.cpp b/src/drivers/Qt/sdl-sound.cpp index af01a355..2133d990 100644 --- a/src/drivers/Qt/sdl-sound.cpp +++ b/src/drivers/Qt/sdl-sound.cpp @@ -25,6 +25,7 @@ #include "common/configSys.h" #include "utils/memory.h" +#include "nes_shm.h" #include #include @@ -49,18 +50,27 @@ fillaudio(void *udata, uint8 *stream, int len) { + static int16_t sample = 0; int16 *tmps = (int16*)stream; len >>= 1; - while(len) { - int16 sample = 0; - if(s_BufferIn) { + while (len) + { + //int16 sample = 0; + if (s_BufferIn) + { sample = s_Buffer[s_BufferRead]; s_BufferRead = (s_BufferRead + 1) % s_BufferSize; s_BufferIn--; } else { - sample = 0; + // Retain last known sample value, helps avoid clicking + // noise when sound system is starved of audio data. + //sample = 0; + nes_shm->sndBuf.starveCounter++; + //printf("Starve:%u\n", nes_shm->sndBuf.starveCounter ); } + nes_shm->push_sound_sample( sample ); + *tmps = sample; tmps++; len--; @@ -179,6 +189,7 @@ WriteSound(int32 *buf, { extern int EmulationPaused; if (EmulationPaused == 0) + { while(Count) { while(s_BufferIn == s_BufferSize) @@ -196,6 +207,7 @@ WriteSound(int32 *buf, buf++; } + } } /** diff --git a/src/drivers/Qt/sdl-throttle.cpp b/src/drivers/Qt/sdl-throttle.cpp index 7afdb07e..6af554fb 100644 --- a/src/drivers/Qt/sdl-throttle.cpp +++ b/src/drivers/Qt/sdl-throttle.cpp @@ -9,7 +9,7 @@ static const double Fastest = 32; // 32x speed (around 1920 fps on NTSC) static const double Normal = 1.0; // 1x speed (around 60 fps on NTSC) static uint64 Lasttime, Nexttime; -static long double desired_frametime; +static double desired_frametime = (1.0 / 60.099823); static int InFrame; double g_fpsScale = Normal; // used by sdl.cpp bool MaxSpeed = false; @@ -30,8 +30,14 @@ bool MaxSpeed = false; void RefreshThrottleFPS() { - uint64 fps = FCEUI_GetDesiredFPS(); // Do >> 24 to get in Hz - desired_frametime = 16777216.0l / (fps * g_fpsScale); + double hz; + int32_t fps = FCEUI_GetDesiredFPS(); // Do >> 24 to get in Hz + + hz = ( ((double)fps) / 16777216.0 ); + + desired_frametime = 1.0 / ( hz * g_fpsScale ); + + printf("FrameTime: %llu %llu %f %lf \n", fps, fps >> 24, hz, desired_frametime ); Lasttime=0; Nexttime=0; @@ -44,6 +50,8 @@ RefreshThrottleFPS() int SpeedThrottle() { + return 0; + if(g_fpsScale >= 32) { return 0; /* Done waiting */ @@ -66,7 +74,7 @@ SpeedThrottle() else time_left = Nexttime - cur_time; - if(time_left > 50) + if (time_left > 50) { time_left = 50; /* In order to keep input responsive, don't wait too long at once */ diff --git a/src/drivers/Qt/sdl-video.cpp b/src/drivers/Qt/sdl-video.cpp index 4f784aa1..cbc8c441 100644 --- a/src/drivers/Qt/sdl-video.cpp +++ b/src/drivers/Qt/sdl-video.cpp @@ -22,7 +22,7 @@ /// \brief Handles the graphical game display for the SDL implementation. #include "Qt/sdl.h" -#include "Qt/gl_win.h" +#include "Qt/nes_shm.h" #include "common/vidblit.h" #include "../../fceu.h" #include "../../version.h" @@ -91,9 +91,9 @@ KillVideo() { //printf("Killing Video\n"); - if ( gl_shm != NULL ) + if ( nes_shm != NULL ) { - gl_shm->clear_pixbuf(); + nes_shm->clear_pixbuf(); } //destroy_gui_video(); @@ -337,7 +337,7 @@ static void WriteTestPattern(void) { for (j=0; jpixbuf[k] = 0xffffffff; k++; + nes_shm->pixbuf[k] = 0xffffffff; k++; } } } @@ -360,14 +360,14 @@ BlitScreen(uint8 *XBuf) // XXX soules - not entirely sure why this is being done yet XBuf += s_srendline * 256; - dest = (uint8*)gl_shm->pixbuf; + dest = (uint8*)nes_shm->pixbuf; w = GL_NES_WIDTH; h = GL_NES_HEIGHT; pitch = w*4; - gl_shm->ncol = NWIDTH; - gl_shm->nrow = s_tlines; - gl_shm->pitch = pitch; + nes_shm->ncol = NWIDTH; + nes_shm->nrow = s_tlines; + nes_shm->pitch = pitch; if ( dest == NULL ) return; From c496c0f281465ac741181ab105f113a6f98a8bcf Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Fri, 3 Jul 2020 21:52:27 -0400 Subject: [PATCH 048/100] Added logic to increase/decrease emulation speed via hotkeys using QTimer system. Bug fix for = key Qt to SDL mapping. --- src/drivers/Qt/GameApp.cpp | 8 ++++++++ src/drivers/Qt/GameApp.h | 4 ++++ src/drivers/Qt/keyscan.cpp | 2 +- src/drivers/Qt/main.cpp | 13 ++++++++----- src/drivers/Qt/sdl-throttle.cpp | 12 ++++++++++-- 5 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/drivers/Qt/GameApp.cpp b/src/drivers/Qt/GameApp.cpp index dbbbb27b..bd811408 100644 --- a/src/drivers/Qt/GameApp.cpp +++ b/src/drivers/Qt/GameApp.cpp @@ -40,6 +40,14 @@ gameWin_t::~gameWin_t(void) delete viewport; } +void gameWin_t::setCyclePeriodms( int ms ) +{ + // If timer is already running, it will be restarted. + gameTimer->start( ms ); + + //printf("Period Set to: %i ms \n", ms ); +} + void gameWin_t::closeEvent(QCloseEvent *event) { //printf("Main Window Close Event\n"); diff --git a/src/drivers/Qt/GameApp.h b/src/drivers/Qt/GameApp.h index ddd624d1..570ef6e8 100644 --- a/src/drivers/Qt/GameApp.h +++ b/src/drivers/Qt/GameApp.h @@ -30,6 +30,8 @@ class gameWin_t : public QMainWindow gameViewGL_t *viewport; //gameViewSDL_t *viewport; + void setCyclePeriodms( int ms ); + protected: QMenu *fileMenu; QMenu *optMenu; @@ -65,4 +67,6 @@ class gameWin_t : public QMainWindow }; +extern gameWin_t *gameWindow; + #endif diff --git a/src/drivers/Qt/keyscan.cpp b/src/drivers/Qt/keyscan.cpp index 389ac66a..da2b4982 100644 --- a/src/drivers/Qt/keyscan.cpp +++ b/src/drivers/Qt/keyscan.cpp @@ -758,7 +758,7 @@ SDL_Keycode convQtKey2SDLKeyCode( Qt::Key q ) s = SDLK_LESS; break; case Key_Equal: - s = SDLK_LESS; + s = SDLK_EQUALS; break; case Key_Greater: s = SDLK_GREATER; diff --git a/src/drivers/Qt/main.cpp b/src/drivers/Qt/main.cpp index 6c16f142..28e4d882 100644 --- a/src/drivers/Qt/main.cpp +++ b/src/drivers/Qt/main.cpp @@ -3,18 +3,21 @@ #include "Qt/GameApp.h" #include "Qt/fceuWrapper.h" +gameWin_t *gameWindow = NULL; + int main( int argc, char *argv[] ) { QApplication app(argc, argv); - gameWin_t win; + + gameWindow = new gameWin_t(); fceuWrapperInit( argc, argv ); - win.resize( 512, 512 ); - win.show(); + gameWindow->resize( 512, 512 ); + gameWindow->show(); - win.viewport->init(); + gameWindow->viewport->init(); - return app.exec(); + return app.exec(); } diff --git a/src/drivers/Qt/sdl-throttle.cpp b/src/drivers/Qt/sdl-throttle.cpp index 6af554fb..f6a52eb3 100644 --- a/src/drivers/Qt/sdl-throttle.cpp +++ b/src/drivers/Qt/sdl-throttle.cpp @@ -3,6 +3,7 @@ #include "Qt/sdl.h" #include "Qt/throttle.h" +#include "Qt/GameApp.h" static const double Slowest = 0.015625; // 1/64x speed (around 1 fps on NTSC) static const double Fastest = 32; // 32x speed (around 1920 fps on NTSC) @@ -10,7 +11,7 @@ static const double Normal = 1.0; // 1x speed (around 60 fps on NTSC) static uint64 Lasttime, Nexttime; static double desired_frametime = (1.0 / 60.099823); -static int InFrame; +static int InFrame = 0; double g_fpsScale = Normal; // used by sdl.cpp bool MaxSpeed = false; @@ -32,12 +33,19 @@ RefreshThrottleFPS() { double hz; int32_t fps = FCEUI_GetDesiredFPS(); // Do >> 24 to get in Hz + int32_t T; hz = ( ((double)fps) / 16777216.0 ); desired_frametime = 1.0 / ( hz * g_fpsScale ); - printf("FrameTime: %llu %llu %f %lf \n", fps, fps >> 24, hz, desired_frametime ); + T = (int32_t)( desired_frametime * 1000.0 ); + + if ( T < 0 ) T = 1; + + //printf("FrameTime: %llu %llu %f %lf \n", fps, fps >> 24, hz, desired_frametime ); + + gameWindow->setCyclePeriodms( T ); Lasttime=0; Nexttime=0; From acc02ee98e74ad15f152dcfa255f6173e7784fbe Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 5 Jul 2020 16:11:53 -0400 Subject: [PATCH 049/100] Moved FCEU emulation to its own thread for better timing control. --- src/drivers/Qt/GameApp.cpp | 47 ++++++++++++++++++++-- src/drivers/Qt/GameApp.h | 16 ++++++++ src/drivers/Qt/fceuWrapper.cpp | 69 +++++++++++++++++++++++++++++---- src/drivers/Qt/fceuWrapper.h | 4 ++ src/drivers/Qt/input.cpp | 4 +- src/drivers/Qt/main.cpp | 13 +++++-- src/drivers/Qt/nes_shm.h | 2 + src/drivers/Qt/sdl-sound.cpp | 7 +++- src/drivers/Qt/sdl-throttle.cpp | 19 +++++---- 9 files changed, 157 insertions(+), 24 deletions(-) diff --git a/src/drivers/Qt/GameApp.cpp b/src/drivers/Qt/GameApp.cpp index bd811408..f4e98fd7 100644 --- a/src/drivers/Qt/GameApp.cpp +++ b/src/drivers/Qt/GameApp.cpp @@ -7,6 +7,7 @@ #include "Qt/GameSoundConf.h" #include "Qt/fceuWrapper.h" #include "Qt/keyscan.h" +#include "Qt/nes_shm.h" gameWin_t::gameWin_t(QWidget *parent) : QMainWindow( parent ) @@ -19,25 +20,45 @@ gameWin_t::gameWin_t(QWidget *parent) setCentralWidget(viewport); - gameTimer = new QTimer( this ); + gameTimer = new QTimer( this ); + gameThread = new QThread( this ); + worker = new gameWorkerThread_t(); + mutex = new QMutex( QMutex::NonRecursive ); + + worker->moveToThread(gameThread); + connect(gameThread, &QThread::finished, worker, &QObject::deleteLater); + connect(gameThread, SIGNAL (started()), worker, SLOT( runEmulator() )); + connect(worker, SIGNAL (finished()), gameThread, SLOT (quit())); + connect(worker, SIGNAL (finished()), worker, SLOT (deleteLater())); connect( gameTimer, &QTimer::timeout, this, &gameWin_t::runGameFrame ); gameTimer->setTimerType( Qt::PreciseTimer ); gameTimer->start( 16 ); + gameThread->start(); + gamePadConfWin = NULL; } gameWin_t::~gameWin_t(void) { + nes_shm->runEmulator = 0; + if ( gamePadConfWin != NULL ) { gamePadConfWin->closeWindow(); } + fceuWrapperLock(); fceuWrapperClose(); + fceuWrapperUnLock(); + + //printf("Thread Finished: %i \n", gameThread->isFinished() ); + gameThread->exit(0); + gameThread->wait(); delete viewport; + delete mutex; } void gameWin_t::setCyclePeriodms( int ms ) @@ -142,7 +163,11 @@ void gameWin_t::createMainMenu(void) //--------------------------------------------------------------------------- void gameWin_t::closeApp(void) { + nes_shm->runEmulator = 0; + + fceuWrapperLock(); fceuWrapperClose(); + fceuWrapperUnLock(); // LoadGame() checks for an IP and if it finds one begins a network session // clear the NetworkIP field so this doesn't happen unintentionally @@ -197,15 +222,20 @@ void gameWin_t::openROMFile(void) qDebug() << "selected file path : " << filename.toUtf8(); g_config->setOption ("SDL.LastOpenFile", filename.toStdString().c_str() ); + + fceuWrapperLock(); CloseGame (); LoadGame ( filename.toStdString().c_str() ); + fceuWrapperUnLock(); return; } void gameWin_t::closeROMCB(void) { + fceuWrapperLock(); CloseGame(); + fceuWrapperUnLock(); } void gameWin_t::openGamePadConfWin(void) @@ -258,9 +288,20 @@ void gameWin_t::runGameFrame(void) //t = (double)ts.tv_sec + (double)(ts.tv_nsec * 1.0e-9); //printf("Run Frame %f\n", t); - fceuWrapperUpdate(); - viewport->repaint(); return; } + +void gameWorkerThread_t::runEmulator(void) +{ + printf("Emulator Start\n"); + nes_shm->runEmulator = 1; + + while ( nes_shm->runEmulator ) + { + fceuWrapperUpdate(); + } + printf("Emulator Exit\n"); + emit finished(); +} diff --git a/src/drivers/Qt/GameApp.h b/src/drivers/Qt/GameApp.h index 570ef6e8..3cb2963e 100644 --- a/src/drivers/Qt/GameApp.h +++ b/src/drivers/Qt/GameApp.h @@ -14,11 +14,23 @@ #include #include #include +#include +#include #include "Qt/GameViewerGL.h" #include "Qt/GameViewerSDL.h" #include "Qt/GamePadConf.h" +class gameWorkerThread_t : public QObject +{ + Q_OBJECT + + public slots: + void runEmulator( void ); + signals: + void finished(); +}; + class gameWin_t : public QMainWindow { Q_OBJECT @@ -32,6 +44,8 @@ class gameWin_t : public QMainWindow void setCyclePeriodms( int ms ); + QMutex *mutex; + protected: QMenu *fileMenu; QMenu *optMenu; @@ -45,6 +59,8 @@ class gameWin_t : public QMainWindow QAction *aboutAct; QTimer *gameTimer; + QThread *gameThread; + gameWorkerThread_t *worker; GamePadConfDialog_t *gamePadConfWin; diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp index f2513509..097ace38 100644 --- a/src/drivers/Qt/fceuWrapper.cpp +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -14,6 +14,7 @@ #include "Qt/sdl-video.h" #include "Qt/nes_shm.h" #include "Qt/unix-netplay.h" +#include "Qt/GameApp.h" #include "common/cheat.h" #include "../../fceu.h" @@ -55,6 +56,7 @@ static int inited = 0; static int noconfig=0; static int frameskip=0; static int periodic_saves = 0; +static bool mutexLocked = 0; extern double g_fpsScale; //***************************************************************** @@ -711,13 +713,13 @@ FCEUD_Update(uint8 *XBuf, } else { - if (!NoWaiting && (!(eoptions&EO_NOTHROTTLE) || FCEUI_EmulationPaused())) - { - while (SpeedThrottle()) - { - FCEUD_UpdateInput(); - } - } + //if (!NoWaiting && (!(eoptions&EO_NOTHROTTLE) || FCEUI_EmulationPaused())) + //{ + // while (SpeedThrottle()) + // { + // FCEUD_UpdateInput(); + // } + //} if (XBuf && (inited&4)) { BlitScreen(XBuf); blitDone = 1; @@ -772,13 +774,64 @@ static void DoFun(int frameskip, int periodic_saves) } } +void fceuWrapperLock(void) +{ + gameWindow->mutex->lock(); + mutexLocked = 1; +} + +bool fceuWrapperTryLock(int timeout) +{ + bool lockAcq; + + lockAcq = gameWindow->mutex->tryLock( timeout ); + + if ( lockAcq ) + { + mutexLocked = 1; + } + return lockAcq; +} + +void fceuWrapperUnLock(void) +{ + if ( mutexLocked ) + { + gameWindow->mutex->unlock(); + mutexLocked = 0; + } + else + { + printf("Error: Mutex is Already UnLocked\n"); + } +} + +bool fceuWrapperIsLocked(void) +{ + return mutexLocked; +} + int fceuWrapperUpdate( void ) { + fceuWrapperLock(); + if (GameInfo) { DoFun(frameskip, periodic_saves); - } + + fceuWrapperUnLock(); + while ( SpeedThrottle() ) + { + FCEUD_UpdateInput(); + } + } + else + { + fceuWrapperUnLock(); + + usleep( 100000 ); + } return 0; } diff --git a/src/drivers/Qt/fceuWrapper.h b/src/drivers/Qt/fceuWrapper.h index 2d4a1ff7..7cd6b70c 100644 --- a/src/drivers/Qt/fceuWrapper.h +++ b/src/drivers/Qt/fceuWrapper.h @@ -25,4 +25,8 @@ int CloseGame(void); int fceuWrapperInit( int argc, char *argv[] ); int fceuWrapperClose( void ); int fceuWrapperUpdate( void ); +void fceuWrapperLock(void); +bool fceuWrapperTryLock(int timeout); +bool fceuWrapperIsLocked(void); +void fceuWrapperUnLock(void); diff --git a/src/drivers/Qt/input.cpp b/src/drivers/Qt/input.cpp index 1e2162a0..049a5a97 100644 --- a/src/drivers/Qt/input.cpp +++ b/src/drivers/Qt/input.cpp @@ -611,10 +611,10 @@ static void KeyboardCommands (void) if (_keyonly (Hotkeys[HK_DECREASE_SPEED])) { - DecreaseEmulationSpeed (); + DecreaseEmulationSpeed(); } - if (_keyonly (Hotkeys[HK_INCREASE_SPEED])) + if (_keyonly(Hotkeys[HK_INCREASE_SPEED])) { IncreaseEmulationSpeed (); } diff --git a/src/drivers/Qt/main.cpp b/src/drivers/Qt/main.cpp index 28e4d882..09caec18 100644 --- a/src/drivers/Qt/main.cpp +++ b/src/drivers/Qt/main.cpp @@ -7,17 +7,24 @@ gameWin_t *gameWindow = NULL; int main( int argc, char *argv[] ) { + int retval; QApplication app(argc, argv); - gameWindow = new gameWin_t(); - fceuWrapperInit( argc, argv ); + gameWindow = new gameWin_t(); + gameWindow->resize( 512, 512 ); gameWindow->show(); gameWindow->viewport->init(); - return app.exec(); + retval = app.exec(); + + //printf("App Return: %i \n", retval ); + + delete gameWindow; + + return retval; } diff --git a/src/drivers/Qt/nes_shm.h b/src/drivers/Qt/nes_shm.h index 0cc52bd6..d626afe4 100644 --- a/src/drivers/Qt/nes_shm.h +++ b/src/drivers/Qt/nes_shm.h @@ -24,6 +24,8 @@ struct nes_shm_t int nrow; int pitch; + char runEmulator; + // Pass Key Events back to QT Gui struct { diff --git a/src/drivers/Qt/sdl-sound.cpp b/src/drivers/Qt/sdl-sound.cpp index 2133d990..28c263ba 100644 --- a/src/drivers/Qt/sdl-sound.cpp +++ b/src/drivers/Qt/sdl-sound.cpp @@ -50,6 +50,7 @@ fillaudio(void *udata, uint8 *stream, int len) { + char bufStarveDetected = 0; static int16_t sample = 0; int16 *tmps = (int16*)stream; len >>= 1; @@ -65,8 +66,8 @@ fillaudio(void *udata, // Retain last known sample value, helps avoid clicking // noise when sound system is starved of audio data. //sample = 0; + bufStarveDetected = 1; nes_shm->sndBuf.starveCounter++; - //printf("Starve:%u\n", nes_shm->sndBuf.starveCounter ); } nes_shm->push_sound_sample( sample ); @@ -75,6 +76,10 @@ fillaudio(void *udata, tmps++; len--; } + if ( bufStarveDetected ) + { + //printf("Starve:%u\n", nes_shm->sndBuf.starveCounter ); + } } /** diff --git a/src/drivers/Qt/sdl-throttle.cpp b/src/drivers/Qt/sdl-throttle.cpp index f6a52eb3..cafaad5c 100644 --- a/src/drivers/Qt/sdl-throttle.cpp +++ b/src/drivers/Qt/sdl-throttle.cpp @@ -4,6 +4,7 @@ #include "Qt/sdl.h" #include "Qt/throttle.h" #include "Qt/GameApp.h" +#include "Qt/fceuWrapper.h" static const double Slowest = 0.015625; // 1/64x speed (around 1 fps on NTSC) static const double Fastest = 32; // 32x speed (around 1920 fps on NTSC) @@ -45,7 +46,7 @@ RefreshThrottleFPS() //printf("FrameTime: %llu %llu %f %lf \n", fps, fps >> 24, hz, desired_frametime ); - gameWindow->setCyclePeriodms( T ); + //gameWindow->setCyclePeriodms( T ); Lasttime=0; Nexttime=0; @@ -58,19 +59,19 @@ RefreshThrottleFPS() int SpeedThrottle() { - return 0; - - if(g_fpsScale >= 32) + if (g_fpsScale >= 32) { return 0; /* Done waiting */ } uint64 time_left; uint64 cur_time; - if(!Lasttime) + if (!Lasttime) + { Lasttime = SDL_GetTicks(); + } - if(!InFrame) + if (!InFrame) { InFrame = 1; Nexttime = Lasttime + desired_frametime * 1000; @@ -89,17 +90,21 @@ SpeedThrottle() /* 50 ms wait gives us a 20 Hz responsetime which is nice. */ } else + { InFrame = 0; + } //fprintf(stderr, "attempting to sleep %Ld ms, frame complete=%s\n", // time_left, InFrame?"no":"yes"); if ( time_left > 0 ) { + //fceuWrapperUnLock(); SDL_Delay(time_left); + //fceuWrapperLock(); } - if(!InFrame) + if (!InFrame) { Lasttime = SDL_GetTicks(); return 0; /* Done waiting */ From f2e7b66c616159e9828fddbf9552230bc56cd81e Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 5 Jul 2020 16:27:13 -0400 Subject: [PATCH 050/100] changed QThread setup to be a separate object from the console window. --- src/drivers/Qt/GameApp.cpp | 49 +++++++++++++++------------------- src/drivers/Qt/GameApp.h | 19 +++++++------ src/drivers/Qt/fceuWrapper.cpp | 6 ++--- src/drivers/Qt/main.cpp | 12 ++++----- 4 files changed, 40 insertions(+), 46 deletions(-) diff --git a/src/drivers/Qt/GameApp.cpp b/src/drivers/Qt/GameApp.cpp index f4e98fd7..6d149bae 100644 --- a/src/drivers/Qt/GameApp.cpp +++ b/src/drivers/Qt/GameApp.cpp @@ -9,7 +9,7 @@ #include "Qt/keyscan.h" #include "Qt/nes_shm.h" -gameWin_t::gameWin_t(QWidget *parent) +consoleWin_t::consoleWin_t(QWidget *parent) : QMainWindow( parent ) { @@ -21,27 +21,22 @@ gameWin_t::gameWin_t(QWidget *parent) setCentralWidget(viewport); gameTimer = new QTimer( this ); - gameThread = new QThread( this ); - worker = new gameWorkerThread_t(); mutex = new QMutex( QMutex::NonRecursive ); + emulatorThread = new emulatorThread_t(); - worker->moveToThread(gameThread); - connect(gameThread, &QThread::finished, worker, &QObject::deleteLater); - connect(gameThread, SIGNAL (started()), worker, SLOT( runEmulator() )); - connect(worker, SIGNAL (finished()), gameThread, SLOT (quit())); - connect(worker, SIGNAL (finished()), worker, SLOT (deleteLater())); + connect(emulatorThread, &QThread::finished, emulatorThread, &QObject::deleteLater); - connect( gameTimer, &QTimer::timeout, this, &gameWin_t::runGameFrame ); + connect( gameTimer, &QTimer::timeout, this, &consoleWin_t::updateDisplay ); gameTimer->setTimerType( Qt::PreciseTimer ); - gameTimer->start( 16 ); + gameTimer->start( 16 ); // 60hz - gameThread->start(); + emulatorThread->start(); gamePadConfWin = NULL; } -gameWin_t::~gameWin_t(void) +consoleWin_t::~consoleWin_t(void) { nes_shm->runEmulator = 0; @@ -54,14 +49,14 @@ gameWin_t::~gameWin_t(void) fceuWrapperUnLock(); //printf("Thread Finished: %i \n", gameThread->isFinished() ); - gameThread->exit(0); - gameThread->wait(); + emulatorThread->quit(); + emulatorThread->wait(); delete viewport; delete mutex; } -void gameWin_t::setCyclePeriodms( int ms ) +void consoleWin_t::setCyclePeriodms( int ms ) { // If timer is already running, it will be restarted. gameTimer->start( ms ); @@ -69,7 +64,7 @@ void gameWin_t::setCyclePeriodms( int ms ) //printf("Period Set to: %i ms \n", ms ); } -void gameWin_t::closeEvent(QCloseEvent *event) +void consoleWin_t::closeEvent(QCloseEvent *event) { //printf("Main Window Close Event\n"); if ( gamePadConfWin != NULL ) @@ -82,20 +77,20 @@ void gameWin_t::closeEvent(QCloseEvent *event) closeApp(); } -void gameWin_t::keyPressEvent(QKeyEvent *event) +void consoleWin_t::keyPressEvent(QKeyEvent *event) { //printf("Key Press: 0x%x \n", event->key() ); pushKeyEvent( event, 1 ); } -void gameWin_t::keyReleaseEvent(QKeyEvent *event) +void consoleWin_t::keyReleaseEvent(QKeyEvent *event) { //printf("Key Release: 0x%x \n", event->key() ); pushKeyEvent( event, 0 ); } //--------------------------------------------------------------------------- -void gameWin_t::createMainMenu(void) +void consoleWin_t::createMainMenu(void) { // This is needed for menu bar to show up on MacOS menuBar()->setNativeMenuBar(false); @@ -161,7 +156,7 @@ void gameWin_t::createMainMenu(void) helpMenu->addAction(aboutAct); }; //--------------------------------------------------------------------------- -void gameWin_t::closeApp(void) +void consoleWin_t::closeApp(void) { nes_shm->runEmulator = 0; @@ -180,7 +175,7 @@ void gameWin_t::closeApp(void) } //--------------------------------------------------------------------------- -void gameWin_t::openROMFile(void) +void consoleWin_t::openROMFile(void) { int ret; QString filename; @@ -231,14 +226,14 @@ void gameWin_t::openROMFile(void) return; } -void gameWin_t::closeROMCB(void) +void consoleWin_t::closeROMCB(void) { fceuWrapperLock(); CloseGame(); fceuWrapperUnLock(); } -void gameWin_t::openGamePadConfWin(void) +void consoleWin_t::openGamePadConfWin(void) { if ( gamePadConfWin != NULL ) { @@ -256,7 +251,7 @@ void gameWin_t::openGamePadConfWin(void) //printf("GamePad Config Window Destroyed\n"); } -void gameWin_t::openGameSndConfWin(void) +void consoleWin_t::openGameSndConfWin(void) { GameSndConfDialog_t *sndConfWin; @@ -272,13 +267,13 @@ void gameWin_t::openGameSndConfWin(void) printf("Sound Config Window Destroyed\n"); } -void gameWin_t::aboutQPlot(void) +void consoleWin_t::aboutQPlot(void) { printf("About QPlot\n"); return; } -void gameWin_t::runGameFrame(void) +void consoleWin_t::updateDisplay(void) { //struct timespec ts; //double t; @@ -293,7 +288,7 @@ void gameWin_t::runGameFrame(void) return; } -void gameWorkerThread_t::runEmulator(void) +void emulatorThread_t::run(void) { printf("Emulator Start\n"); nes_shm->runEmulator = 1; diff --git a/src/drivers/Qt/GameApp.h b/src/drivers/Qt/GameApp.h index 3cb2963e..a7acf1a8 100644 --- a/src/drivers/Qt/GameApp.h +++ b/src/drivers/Qt/GameApp.h @@ -21,23 +21,23 @@ #include "Qt/GameViewerSDL.h" #include "Qt/GamePadConf.h" -class gameWorkerThread_t : public QObject +class emulatorThread_t : public QThread { Q_OBJECT - public slots: - void runEmulator( void ); + //public slots: + void run( void ) override; signals: void finished(); }; -class gameWin_t : public QMainWindow +class consoleWin_t : public QMainWindow { Q_OBJECT public: - gameWin_t(QWidget *parent = 0); - ~gameWin_t(void); + consoleWin_t(QWidget *parent = 0); + ~consoleWin_t(void); gameViewGL_t *viewport; //gameViewSDL_t *viewport; @@ -59,8 +59,7 @@ class gameWin_t : public QMainWindow QAction *aboutAct; QTimer *gameTimer; - QThread *gameThread; - gameWorkerThread_t *worker; + emulatorThread_t *emulatorThread; GamePadConfDialog_t *gamePadConfWin; @@ -79,10 +78,10 @@ class gameWin_t : public QMainWindow void aboutQPlot(void); void openGamePadConfWin(void); void openGameSndConfWin(void); - void runGameFrame(void); + void updateDisplay(void); }; -extern gameWin_t *gameWindow; +extern consoleWin_t *consoleWindow; #endif diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp index 097ace38..c9b0c153 100644 --- a/src/drivers/Qt/fceuWrapper.cpp +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -776,7 +776,7 @@ static void DoFun(int frameskip, int periodic_saves) void fceuWrapperLock(void) { - gameWindow->mutex->lock(); + consoleWindow->mutex->lock(); mutexLocked = 1; } @@ -784,7 +784,7 @@ bool fceuWrapperTryLock(int timeout) { bool lockAcq; - lockAcq = gameWindow->mutex->tryLock( timeout ); + lockAcq = consoleWindow->mutex->tryLock( timeout ); if ( lockAcq ) { @@ -797,7 +797,7 @@ void fceuWrapperUnLock(void) { if ( mutexLocked ) { - gameWindow->mutex->unlock(); + consoleWindow->mutex->unlock(); mutexLocked = 0; } else diff --git a/src/drivers/Qt/main.cpp b/src/drivers/Qt/main.cpp index 09caec18..153cb60f 100644 --- a/src/drivers/Qt/main.cpp +++ b/src/drivers/Qt/main.cpp @@ -3,7 +3,7 @@ #include "Qt/GameApp.h" #include "Qt/fceuWrapper.h" -gameWin_t *gameWindow = NULL; +consoleWin_t *consoleWindow = NULL; int main( int argc, char *argv[] ) { @@ -12,18 +12,18 @@ int main( int argc, char *argv[] ) fceuWrapperInit( argc, argv ); - gameWindow = new gameWin_t(); + consoleWindow = new consoleWin_t(); - gameWindow->resize( 512, 512 ); - gameWindow->show(); + consoleWindow->resize( 512, 512 ); + consoleWindow->show(); - gameWindow->viewport->init(); + consoleWindow->viewport->init(); retval = app.exec(); //printf("App Return: %i \n", retval ); - delete gameWindow; + delete consoleWindow; return retval; } From 824bdda083c113ac6a478bfd59d032169d3eaf6e Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 5 Jul 2020 16:37:26 -0400 Subject: [PATCH 051/100] Renamed a few of the files and class objects to be more appropriate to what the actually are. --- fceux.pro | 8 ++--- ...GameSoundConf.cpp => ConsoleSoundConf.cpp} | 36 +++++++++---------- .../{GameSoundConf.h => ConsoleSoundConf.h} | 6 ++-- .../Qt/{GameApp.cpp => ConsoleWindow.cpp} | 8 ++--- src/drivers/Qt/{GameApp.h => ConsoleWindow.h} | 0 src/drivers/Qt/fceuWrapper.cpp | 2 +- src/drivers/Qt/main.cpp | 2 +- src/drivers/Qt/sdl-throttle.cpp | 6 ---- 8 files changed, 31 insertions(+), 37 deletions(-) rename src/drivers/Qt/{GameSoundConf.cpp => ConsoleSoundConf.cpp} (89%) rename src/drivers/Qt/{GameSoundConf.h => ConsoleSoundConf.h} (91%) rename src/drivers/Qt/{GameApp.cpp => ConsoleWindow.cpp} (97%) rename src/drivers/Qt/{GameApp.h => ConsoleWindow.h} (100%) diff --git a/fceux.pro b/fceux.pro index 37eb3f9c..cb3d246f 100644 --- a/fceux.pro +++ b/fceux.pro @@ -294,17 +294,17 @@ SOURCES += src/drivers/common/scalebit.cpp SOURCES += src/drivers/common/vidblit.cpp SOURCES += src/drivers/common/nes_ntsc.c -HEADERS += src/drivers/Qt/GameApp.h +HEADERS += src/drivers/Qt/ConsoleWindow.h HEADERS += src/drivers/Qt/GameViewerGL.h HEADERS += src/drivers/Qt/GameViewerSDL.h HEADERS += src/drivers/Qt/GamePadConf.h -HEADERS += src/drivers/Qt/GameSoundConf.h +HEADERS += src/drivers/Qt/ConsoleSoundConf.h SOURCES += src/drivers/Qt/main.cpp -SOURCES += src/drivers/Qt/GameApp.cpp +SOURCES += src/drivers/Qt/ConsoleWindow.cpp SOURCES += src/drivers/Qt/GameViewerGL.cpp SOURCES += src/drivers/Qt/GameViewerSDL.cpp SOURCES += src/drivers/Qt/GamePadConf.cpp -SOURCES += src/drivers/Qt/GameSoundConf.cpp +SOURCES += src/drivers/Qt/ConsoleSoundConf.cpp SOURCES += src/drivers/Qt/fceuWrapper.cpp SOURCES += src/drivers/Qt/config.cpp SOURCES += src/drivers/Qt/input.cpp diff --git a/src/drivers/Qt/GameSoundConf.cpp b/src/drivers/Qt/ConsoleSoundConf.cpp similarity index 89% rename from src/drivers/Qt/GameSoundConf.cpp rename to src/drivers/Qt/ConsoleSoundConf.cpp index 8ead488f..f5b34727 100644 --- a/src/drivers/Qt/GameSoundConf.cpp +++ b/src/drivers/Qt/ConsoleSoundConf.cpp @@ -2,14 +2,14 @@ // #include "../../fceu.h" #include "../../driver.h" -#include "Qt/GameSoundConf.h" +#include "Qt/ConsoleSoundConf.h" #include "Qt/main.h" #include "Qt/dface.h" #include "Qt/config.h" #include "Qt/fceuWrapper.h" //---------------------------------------------------- -GameSndConfDialog_t::GameSndConfDialog_t(QWidget *parent) +ConsoleSndConfDialog_t::ConsoleSndConfDialog_t(QWidget *parent) : QDialog( parent ) { int buf; @@ -215,12 +215,12 @@ GameSndConfDialog_t::GameSndConfDialog_t(QWidget *parent) setLayout( hbox1 ); } //---------------------------------------------------- -GameSndConfDialog_t::~GameSndConfDialog_t(void) +ConsoleSndConfDialog_t::~ConsoleSndConfDialog_t(void) { } //---------------------------------------------------- -void GameSndConfDialog_t::setCheckBoxFromProperty( QCheckBox *cbx, const char *property ) +void ConsoleSndConfDialog_t::setCheckBoxFromProperty( QCheckBox *cbx, const char *property ) { int pval; g_config->getOption (property, &pval); @@ -228,7 +228,7 @@ void GameSndConfDialog_t::setCheckBoxFromProperty( QCheckBox *cbx, const char * cbx->setCheckState( pval ? Qt::Checked : Qt::Unchecked ); } //---------------------------------------------------- -void GameSndConfDialog_t::setComboBoxFromProperty( QComboBox *cbx, const char *property ) +void ConsoleSndConfDialog_t::setComboBoxFromProperty( QComboBox *cbx, const char *property ) { int i, pval; g_config->getOption (property, &pval); @@ -242,7 +242,7 @@ void GameSndConfDialog_t::setComboBoxFromProperty( QComboBox *cbx, const char * } } //---------------------------------------------------- -void GameSndConfDialog_t::setSliderFromProperty( QSlider *slider, QLabel *lbl, const char *property ) +void ConsoleSndConfDialog_t::setSliderFromProperty( QSlider *slider, QLabel *lbl, const char *property ) { int pval; char stmp[32]; @@ -252,7 +252,7 @@ void GameSndConfDialog_t::setSliderFromProperty( QSlider *slider, QLabel *lbl, lbl->setText( stmp ); } //---------------------------------------------------- -void GameSndConfDialog_t::bufSizeChanged(int value) +void ConsoleSndConfDialog_t::bufSizeChanged(int value) { char stmp[32]; @@ -266,7 +266,7 @@ void GameSndConfDialog_t::bufSizeChanged(int value) InitSound (); } //---------------------------------------------------- -void GameSndConfDialog_t::volumeChanged(int value) +void ConsoleSndConfDialog_t::volumeChanged(int value) { char stmp[32]; @@ -278,7 +278,7 @@ void GameSndConfDialog_t::volumeChanged(int value) FCEUI_SetSoundVolume (value); } //---------------------------------------------------- -void GameSndConfDialog_t::triangleChanged(int value) +void ConsoleSndConfDialog_t::triangleChanged(int value) { char stmp[32]; @@ -290,7 +290,7 @@ void GameSndConfDialog_t::triangleChanged(int value) FCEUI_SetTriangleVolume (value); } //---------------------------------------------------- -void GameSndConfDialog_t::square1Changed(int value) +void ConsoleSndConfDialog_t::square1Changed(int value) { char stmp[32]; @@ -302,7 +302,7 @@ void GameSndConfDialog_t::square1Changed(int value) FCEUI_SetSquare1Volume (value); } //---------------------------------------------------- -void GameSndConfDialog_t::square2Changed(int value) +void ConsoleSndConfDialog_t::square2Changed(int value) { char stmp[32]; @@ -314,7 +314,7 @@ void GameSndConfDialog_t::square2Changed(int value) FCEUI_SetSquare2Volume (value); } //---------------------------------------------------- -void GameSndConfDialog_t::noiseChanged(int value) +void ConsoleSndConfDialog_t::noiseChanged(int value) { char stmp[32]; @@ -326,7 +326,7 @@ void GameSndConfDialog_t::noiseChanged(int value) FCEUI_SetNoiseVolume (value); } //---------------------------------------------------- -void GameSndConfDialog_t::pcmChanged(int value) +void ConsoleSndConfDialog_t::pcmChanged(int value) { char stmp[32]; @@ -338,7 +338,7 @@ void GameSndConfDialog_t::pcmChanged(int value) FCEUI_SetPCMVolume (value); } //---------------------------------------------------- -void GameSndConfDialog_t::enaSoundStateChange(int value) +void ConsoleSndConfDialog_t::enaSoundStateChange(int value) { if ( value ) { @@ -357,7 +357,7 @@ void GameSndConfDialog_t::enaSoundStateChange(int value) } } //---------------------------------------------------- -void GameSndConfDialog_t::enaSoundLowPassChange(int value) +void ConsoleSndConfDialog_t::enaSoundLowPassChange(int value) { if (value) { @@ -372,7 +372,7 @@ void GameSndConfDialog_t::enaSoundLowPassChange(int value) g_config->save (); } //---------------------------------------------------- -void GameSndConfDialog_t::swapDutyCallback(int value) +void ConsoleSndConfDialog_t::swapDutyCallback(int value) { if (value) { @@ -387,7 +387,7 @@ void GameSndConfDialog_t::swapDutyCallback(int value) g_config->save (); } //---------------------------------------------------- -void GameSndConfDialog_t::soundQualityChanged(int index) +void ConsoleSndConfDialog_t::soundQualityChanged(int index) { //printf("Sound Quality: %i : %i \n", index, qualitySelect->itemData(index).toInt() ); @@ -399,7 +399,7 @@ void GameSndConfDialog_t::soundQualityChanged(int index) g_config->save (); } //---------------------------------------------------- -void GameSndConfDialog_t::soundRateChanged(int index) +void ConsoleSndConfDialog_t::soundRateChanged(int index) { //printf("Sound Rate: %i : %i \n", index, rateSelect->itemData(index).toInt() ); diff --git a/src/drivers/Qt/GameSoundConf.h b/src/drivers/Qt/ConsoleSoundConf.h similarity index 91% rename from src/drivers/Qt/GameSoundConf.h rename to src/drivers/Qt/ConsoleSoundConf.h index ebc97649..40e86d2a 100644 --- a/src/drivers/Qt/GameSoundConf.h +++ b/src/drivers/Qt/ConsoleSoundConf.h @@ -16,13 +16,13 @@ #include #include -class GameSndConfDialog_t : public QDialog +class ConsoleSndConfDialog_t : public QDialog { Q_OBJECT public: - GameSndConfDialog_t(QWidget *parent = 0); - ~GameSndConfDialog_t(void); + ConsoleSndConfDialog_t(QWidget *parent = 0); + ~ConsoleSndConfDialog_t(void); protected: QCheckBox *enaChkbox; diff --git a/src/drivers/Qt/GameApp.cpp b/src/drivers/Qt/ConsoleWindow.cpp similarity index 97% rename from src/drivers/Qt/GameApp.cpp rename to src/drivers/Qt/ConsoleWindow.cpp index 6d149bae..b17e4e9f 100644 --- a/src/drivers/Qt/GameApp.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -2,9 +2,9 @@ // #include -#include "Qt/GameApp.h" +#include "Qt/ConsoleWindow.h" #include "Qt/GamePadConf.h" -#include "Qt/GameSoundConf.h" +#include "Qt/ConsoleSoundConf.h" #include "Qt/fceuWrapper.h" #include "Qt/keyscan.h" #include "Qt/nes_shm.h" @@ -253,11 +253,11 @@ void consoleWin_t::openGamePadConfWin(void) void consoleWin_t::openGameSndConfWin(void) { - GameSndConfDialog_t *sndConfWin; + ConsoleSndConfDialog_t *sndConfWin; printf("Open Sound Config Window\n"); - sndConfWin = new GameSndConfDialog_t(this); + sndConfWin = new ConsoleSndConfDialog_t(this); sndConfWin->show(); sndConfWin->exec(); diff --git a/src/drivers/Qt/GameApp.h b/src/drivers/Qt/ConsoleWindow.h similarity index 100% rename from src/drivers/Qt/GameApp.h rename to src/drivers/Qt/ConsoleWindow.h diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp index c9b0c153..6599d819 100644 --- a/src/drivers/Qt/fceuWrapper.cpp +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -14,7 +14,7 @@ #include "Qt/sdl-video.h" #include "Qt/nes_shm.h" #include "Qt/unix-netplay.h" -#include "Qt/GameApp.h" +#include "Qt/ConsoleWindow.h" #include "common/cheat.h" #include "../../fceu.h" diff --git a/src/drivers/Qt/main.cpp b/src/drivers/Qt/main.cpp index 153cb60f..0dc688c0 100644 --- a/src/drivers/Qt/main.cpp +++ b/src/drivers/Qt/main.cpp @@ -1,6 +1,6 @@ #include -#include "Qt/GameApp.h" +#include "Qt/ConsoleWindow.h" #include "Qt/fceuWrapper.h" consoleWin_t *consoleWindow = NULL; diff --git a/src/drivers/Qt/sdl-throttle.cpp b/src/drivers/Qt/sdl-throttle.cpp index cafaad5c..1fba8173 100644 --- a/src/drivers/Qt/sdl-throttle.cpp +++ b/src/drivers/Qt/sdl-throttle.cpp @@ -3,8 +3,6 @@ #include "Qt/sdl.h" #include "Qt/throttle.h" -#include "Qt/GameApp.h" -#include "Qt/fceuWrapper.h" static const double Slowest = 0.015625; // 1/64x speed (around 1 fps on NTSC) static const double Fastest = 32; // 32x speed (around 1920 fps on NTSC) @@ -46,8 +44,6 @@ RefreshThrottleFPS() //printf("FrameTime: %llu %llu %f %lf \n", fps, fps >> 24, hz, desired_frametime ); - //gameWindow->setCyclePeriodms( T ); - Lasttime=0; Nexttime=0; InFrame=0; @@ -99,9 +95,7 @@ SpeedThrottle() if ( time_left > 0 ) { - //fceuWrapperUnLock(); SDL_Delay(time_left); - //fceuWrapperLock(); } if (!InFrame) From ac43cc3e62ca9eeae7f0314c44849546789f7be7 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 5 Jul 2020 16:44:36 -0400 Subject: [PATCH 052/100] Renamed gameViewer to ConsoleViewer. --- fceux.pro | 8 ++++---- .../Qt/{GameViewerGL.cpp => ConsoleViewerGL.cpp} | 16 ++++++++-------- .../Qt/{GameViewerGL.h => ConsoleViewerGL.h} | 6 +++--- .../{GameViewerSDL.cpp => ConsoleViewerSDL.cpp} | 16 ++++++++-------- .../Qt/{GameViewerSDL.h => ConsoleViewerSDL.h} | 6 +++--- src/drivers/Qt/ConsoleWindow.cpp | 4 ++-- src/drivers/Qt/ConsoleWindow.h | 8 ++++---- 7 files changed, 32 insertions(+), 32 deletions(-) rename src/drivers/Qt/{GameViewerGL.cpp => ConsoleViewerGL.cpp} (92%) rename src/drivers/Qt/{GameViewerGL.h => ConsoleViewerGL.h} (75%) rename src/drivers/Qt/{GameViewerSDL.cpp => ConsoleViewerSDL.cpp} (91%) rename src/drivers/Qt/{GameViewerSDL.h => ConsoleViewerSDL.h} (84%) diff --git a/fceux.pro b/fceux.pro index cb3d246f..80711047 100644 --- a/fceux.pro +++ b/fceux.pro @@ -295,14 +295,14 @@ SOURCES += src/drivers/common/vidblit.cpp SOURCES += src/drivers/common/nes_ntsc.c HEADERS += src/drivers/Qt/ConsoleWindow.h -HEADERS += src/drivers/Qt/GameViewerGL.h -HEADERS += src/drivers/Qt/GameViewerSDL.h +HEADERS += src/drivers/Qt/ConsoleViewerGL.h +HEADERS += src/drivers/Qt/ConsoleViewerSDL.h HEADERS += src/drivers/Qt/GamePadConf.h HEADERS += src/drivers/Qt/ConsoleSoundConf.h SOURCES += src/drivers/Qt/main.cpp SOURCES += src/drivers/Qt/ConsoleWindow.cpp -SOURCES += src/drivers/Qt/GameViewerGL.cpp -SOURCES += src/drivers/Qt/GameViewerSDL.cpp +SOURCES += src/drivers/Qt/ConsoleViewerGL.cpp +SOURCES += src/drivers/Qt/ConsoleViewerSDL.cpp SOURCES += src/drivers/Qt/GamePadConf.cpp SOURCES += src/drivers/Qt/ConsoleSoundConf.cpp SOURCES += src/drivers/Qt/fceuWrapper.cpp diff --git a/src/drivers/Qt/GameViewerGL.cpp b/src/drivers/Qt/ConsoleViewerGL.cpp similarity index 92% rename from src/drivers/Qt/GameViewerGL.cpp rename to src/drivers/Qt/ConsoleViewerGL.cpp index 51fe20cc..d271ac98 100644 --- a/src/drivers/Qt/GameViewerGL.cpp +++ b/src/drivers/Qt/ConsoleViewerGL.cpp @@ -9,12 +9,12 @@ #include #include "Qt/nes_shm.h" -#include "Qt/GameViewerGL.h" +#include "Qt/ConsoleViewerGL.h" extern unsigned int gui_draw_area_width; extern unsigned int gui_draw_area_height; -gameViewGL_t::gameViewGL_t(QWidget *parent) +ConsoleViewGL_t::ConsoleViewGL_t(QWidget *parent) : QOpenGLWidget( parent ) { view_width = 0; @@ -32,7 +32,7 @@ gameViewGL_t::gameViewGL_t(QWidget *parent) } } -gameViewGL_t::~gameViewGL_t(void) +ConsoleViewGL_t::~ConsoleViewGL_t(void) { // Make sure the context is current and then explicitly // destroy all underlying OpenGL resources. @@ -49,12 +49,12 @@ gameViewGL_t::~gameViewGL_t(void) doneCurrent(); } -int gameViewGL_t::init( void ) +int ConsoleViewGL_t::init( void ) { return 0; } -void gameViewGL_t::buildTextures(void) +void ConsoleViewGL_t::buildTextures(void) { glEnable(GL_TEXTURE_RECTANGLE); @@ -80,7 +80,7 @@ void gameViewGL_t::buildTextures(void) } -void gameViewGL_t::initializeGL(void) +void ConsoleViewGL_t::initializeGL(void) { initializeOpenGLFunctions(); @@ -93,7 +93,7 @@ void gameViewGL_t::initializeGL(void) buildTextures(); } -void gameViewGL_t::resizeGL(int w, int h) +void ConsoleViewGL_t::resizeGL(int w, int h) { w = (int)( devPixRatio * w ); h = (int)( devPixRatio * h ); @@ -109,7 +109,7 @@ void gameViewGL_t::resizeGL(int w, int h) buildTextures(); } -void gameViewGL_t::paintGL(void) +void ConsoleViewGL_t::paintGL(void) { int texture_width = nes_shm->ncol; int texture_height = nes_shm->nrow; diff --git a/src/drivers/Qt/GameViewerGL.h b/src/drivers/Qt/ConsoleViewerGL.h similarity index 75% rename from src/drivers/Qt/GameViewerGL.h rename to src/drivers/Qt/ConsoleViewerGL.h index 3494928d..8d8e9270 100644 --- a/src/drivers/Qt/GameViewerGL.h +++ b/src/drivers/Qt/ConsoleViewerGL.h @@ -6,13 +6,13 @@ #include #include -class gameViewGL_t : public QOpenGLWidget, protected QOpenGLFunctions +class ConsoleViewGL_t : public QOpenGLWidget, protected QOpenGLFunctions { Q_OBJECT public: - gameViewGL_t(QWidget *parent = 0); - ~gameViewGL_t(void); + ConsoleViewGL_t(QWidget *parent = 0); + ~ConsoleViewGL_t(void); int init( void ); diff --git a/src/drivers/Qt/GameViewerSDL.cpp b/src/drivers/Qt/ConsoleViewerSDL.cpp similarity index 91% rename from src/drivers/Qt/GameViewerSDL.cpp rename to src/drivers/Qt/ConsoleViewerSDL.cpp index be0b7039..18867777 100644 --- a/src/drivers/Qt/GameViewerSDL.cpp +++ b/src/drivers/Qt/ConsoleViewerSDL.cpp @@ -7,12 +7,12 @@ #include #include "Qt/nes_shm.h" -#include "Qt/GameViewerSDL.h" +#include "Qt/ConsoleViewerSDL.h" extern unsigned int gui_draw_area_width; extern unsigned int gui_draw_area_height; -gameViewSDL_t::gameViewSDL_t(QWidget *parent) +ConsoleViewSDL_t::ConsoleViewSDL_t(QWidget *parent) : QWidget( parent ) { view_width = GL_NES_WIDTH; @@ -32,12 +32,12 @@ gameViewSDL_t::gameViewSDL_t(QWidget *parent) vsyncEnabled = false; } -gameViewSDL_t::~gameViewSDL_t(void) +ConsoleViewSDL_t::~ConsoleViewSDL_t(void) { } -int gameViewSDL_t::init(void) +int ConsoleViewSDL_t::init(void) { WId windowHandle; @@ -98,7 +98,7 @@ int gameViewSDL_t::init(void) return 0; } -void gameViewSDL_t::cleanup(void) +void ConsoleViewSDL_t::cleanup(void) { if (sdlTexture) { @@ -112,7 +112,7 @@ void gameViewSDL_t::cleanup(void) } } -void gameViewSDL_t::reset(void) +void ConsoleViewSDL_t::reset(void) { cleanup(); if ( init() == 0 ) @@ -125,7 +125,7 @@ void gameViewSDL_t::reset(void) } } -void gameViewSDL_t::resizeEvent(QResizeEvent *event) +void ConsoleViewSDL_t::resizeEvent(QResizeEvent *event) { QSize s; @@ -142,7 +142,7 @@ void gameViewSDL_t::resizeEvent(QResizeEvent *event) sdlViewport.h = view_height; } -void gameViewSDL_t::paintEvent( QPaintEvent *event ) +void ConsoleViewSDL_t::paintEvent( QPaintEvent *event ) { int nesWidth = GL_NES_WIDTH; int nesHeight = GL_NES_HEIGHT; diff --git a/src/drivers/Qt/GameViewerSDL.h b/src/drivers/Qt/ConsoleViewerSDL.h similarity index 84% rename from src/drivers/Qt/GameViewerSDL.h rename to src/drivers/Qt/ConsoleViewerSDL.h index 2a7b4b05..386d148a 100644 --- a/src/drivers/Qt/GameViewerSDL.h +++ b/src/drivers/Qt/ConsoleViewerSDL.h @@ -8,13 +8,13 @@ #include #include -class gameViewSDL_t : public QWidget +class ConsoleViewSDL_t : public QWidget { Q_OBJECT public: - gameViewSDL_t(QWidget *parent = 0); - ~gameViewSDL_t(void); + ConsoleViewSDL_t(QWidget *parent = 0); + ~ConsoleViewSDL_t(void); int init(void); void reset(void); diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index b17e4e9f..2207beb3 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -15,8 +15,8 @@ consoleWin_t::consoleWin_t(QWidget *parent) createMainMenu(); - viewport = new gameViewGL_t(this); - //viewport = new gameViewSDL_t(this); + viewport = new ConsoleViewGL_t(this); + //viewport = new ConsoleViewSDL_t(this); setCentralWidget(viewport); diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index a7acf1a8..048e88f2 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -17,8 +17,8 @@ #include #include -#include "Qt/GameViewerGL.h" -#include "Qt/GameViewerSDL.h" +#include "Qt/ConsoleViewerGL.h" +#include "Qt/ConsoleViewerSDL.h" #include "Qt/GamePadConf.h" class emulatorThread_t : public QThread @@ -39,8 +39,8 @@ class consoleWin_t : public QMainWindow consoleWin_t(QWidget *parent = 0); ~consoleWin_t(void); - gameViewGL_t *viewport; - //gameViewSDL_t *viewport; + ConsoleViewGL_t *viewport; + //ConsoleViewSDL_t *viewport; void setCyclePeriodms( int ms ); From 70a00fab1354ef6a87a9ba41e049f41eaed642c3 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 5 Jul 2020 16:54:33 -0400 Subject: [PATCH 053/100] Added mutex sync when changing sound properties of the emulator. --- src/drivers/Qt/ConsoleSoundConf.cpp | 37 +++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/drivers/Qt/ConsoleSoundConf.cpp b/src/drivers/Qt/ConsoleSoundConf.cpp index f5b34727..9b091fd6 100644 --- a/src/drivers/Qt/ConsoleSoundConf.cpp +++ b/src/drivers/Qt/ConsoleSoundConf.cpp @@ -262,8 +262,10 @@ void ConsoleSndConfDialog_t::bufSizeChanged(int value) g_config->setOption ("SDL.Sound.BufSize", value); // reset sound subsystem for changes to take effect + fceuWrapperLock(); KillSound (); InitSound (); + fceuWrapperUnLock(); } //---------------------------------------------------- void ConsoleSndConfDialog_t::volumeChanged(int value) @@ -275,7 +277,10 @@ void ConsoleSndConfDialog_t::volumeChanged(int value) volLbl->setText(stmp); g_config->setOption ("SDL.Sound.Volume", value); + + fceuWrapperLock(); FCEUI_SetSoundVolume (value); + fceuWrapperUnLock(); } //---------------------------------------------------- void ConsoleSndConfDialog_t::triangleChanged(int value) @@ -287,7 +292,10 @@ void ConsoleSndConfDialog_t::triangleChanged(int value) triLbl->setText(stmp); g_config->setOption ("SDL.Sound.TriangleVolume", value); + + fceuWrapperLock(); FCEUI_SetTriangleVolume (value); + fceuWrapperUnLock(); } //---------------------------------------------------- void ConsoleSndConfDialog_t::square1Changed(int value) @@ -299,7 +307,10 @@ void ConsoleSndConfDialog_t::square1Changed(int value) sqr1Lbl->setText(stmp); g_config->setOption ("SDL.Sound.Square1Volume", value); + + fceuWrapperLock(); FCEUI_SetSquare1Volume (value); + fceuWrapperUnLock(); } //---------------------------------------------------- void ConsoleSndConfDialog_t::square2Changed(int value) @@ -311,7 +322,10 @@ void ConsoleSndConfDialog_t::square2Changed(int value) sqr2Lbl->setText(stmp); g_config->setOption ("SDL.Sound.Square2Volume", value); + + fceuWrapperLock(); FCEUI_SetSquare2Volume (value); + fceuWrapperUnLock(); } //---------------------------------------------------- void ConsoleSndConfDialog_t::noiseChanged(int value) @@ -323,7 +337,10 @@ void ConsoleSndConfDialog_t::noiseChanged(int value) nseLbl->setText(stmp); g_config->setOption ("SDL.Sound.NoiseVolume", value); + + fceuWrapperLock(); FCEUI_SetNoiseVolume (value); + fceuWrapperUnLock(); } //---------------------------------------------------- void ConsoleSndConfDialog_t::pcmChanged(int value) @@ -335,7 +352,10 @@ void ConsoleSndConfDialog_t::pcmChanged(int value) pcmLbl->setText(stmp); g_config->setOption ("SDL.Sound.PCMVolume", value); + + fceuWrapperLock(); FCEUI_SetPCMVolume (value); + fceuWrapperUnLock(); } //---------------------------------------------------- void ConsoleSndConfDialog_t::enaSoundStateChange(int value) @@ -345,15 +365,22 @@ void ConsoleSndConfDialog_t::enaSoundStateChange(int value) int last_soundopt; g_config->getOption ("SDL.Sound", &last_soundopt); g_config->setOption ("SDL.Sound", 1); + + fceuWrapperLock(); + if (GameInfo && !last_soundopt) { InitSound (); } + fceuWrapperUnLock(); } else { g_config->setOption ("SDL.Sound", 0); + + fceuWrapperLock(); KillSound (); + fceuWrapperUnLock(); } } //---------------------------------------------------- @@ -362,12 +389,18 @@ void ConsoleSndConfDialog_t::enaSoundLowPassChange(int value) if (value) { g_config->setOption ("SDL.Sound.LowPass", 1); + + fceuWrapperLock(); FCEUI_SetLowPass (1); + fceuWrapperUnLock(); } else { g_config->setOption ("SDL.Sound.LowPass", 0); + + fceuWrapperLock(); FCEUI_SetLowPass (0); + fceuWrapperUnLock(); } g_config->save (); } @@ -394,8 +427,10 @@ void ConsoleSndConfDialog_t::soundQualityChanged(int index) g_config->setOption ("SDL.Sound.Quality", qualitySelect->itemData(index).toInt() ); // reset sound subsystem for changes to take effect + fceuWrapperLock(); KillSound (); InitSound (); + fceuWrapperUnLock(); g_config->save (); } //---------------------------------------------------- @@ -405,8 +440,10 @@ void ConsoleSndConfDialog_t::soundRateChanged(int index) g_config->setOption ("SDL.Sound.Rate", rateSelect->itemData(index).toInt() ); // reset sound subsystem for changes to take effect + fceuWrapperLock(); KillSound (); InitSound (); + fceuWrapperUnLock(); g_config->save (); } //---------------------------------------------------- From 4dca42bfcaf8ed0831a39b1080f87ac037867cc7 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 5 Jul 2020 21:16:31 -0400 Subject: [PATCH 054/100] Moved the physical input update to the main thread since the MAC OS X SDL2 requires it to be so. --- src/drivers/Qt/ConsoleWindow.cpp | 21 ++++++++-- src/drivers/Qt/ConsoleWindow.h | 2 +- src/drivers/Qt/fceuWrapper.cpp | 71 +++++++++++++++----------------- src/drivers/Qt/input.cpp | 4 +- src/drivers/Qt/input.h | 6 ++- src/drivers/Qt/nes_shm.h | 1 + src/drivers/Qt/sdl-video.cpp | 1 + 7 files changed, 60 insertions(+), 46 deletions(-) diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index 2207beb3..41997c0f 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -2,6 +2,9 @@ // #include +#include "Qt/main.h" +#include "Qt/dface.h" +#include "Qt/input.h" #include "Qt/ConsoleWindow.h" #include "Qt/GamePadConf.h" #include "Qt/ConsoleSoundConf.h" @@ -26,10 +29,11 @@ consoleWin_t::consoleWin_t(QWidget *parent) connect(emulatorThread, &QThread::finished, emulatorThread, &QObject::deleteLater); - connect( gameTimer, &QTimer::timeout, this, &consoleWin_t::updateDisplay ); + connect( gameTimer, &QTimer::timeout, this, &consoleWin_t::update ); gameTimer->setTimerType( Qt::PreciseTimer ); - gameTimer->start( 16 ); // 60hz + //gameTimer->start( 16 ); // 60hz + gameTimer->start( 8 ); // 120hz emulatorThread->start(); @@ -273,7 +277,7 @@ void consoleWin_t::aboutQPlot(void) return; } -void consoleWin_t::updateDisplay(void) +void consoleWin_t::update(void) { //struct timespec ts; //double t; @@ -283,7 +287,16 @@ void consoleWin_t::updateDisplay(void) //t = (double)ts.tv_sec + (double)(ts.tv_nsec * 1.0e-9); //printf("Run Frame %f\n", t); - viewport->repaint(); + // Update Input Devices + FCEUD_UpdateInput(); + + // RePaint Game Viewport + if ( nes_shm->blitUpdated ) + { + nes_shm->blitUpdated = 0; + + viewport->repaint(); + } return; } diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index 048e88f2..10444c5a 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -78,7 +78,7 @@ class consoleWin_t : public QMainWindow void aboutQPlot(void); void openGamePadConfWin(void); void openGameSndConfWin(void); - void updateDisplay(void); + void update(void); }; diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp index 6599d819..f7698afa 100644 --- a/src/drivers/Qt/fceuWrapper.cpp +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -610,36 +610,40 @@ FCEUD_Update(uint8 *XBuf, extern int FCEUDnetplay; #ifdef CREATE_AVI - if(LoggingEnabled == 2 || (eoptions&EO_NOTHROTTLE)) + if (LoggingEnabled == 2 || (eoptions&EO_NOTHROTTLE)) { - if(LoggingEnabled == 2) - { - int16* MonoBuf = new int16[Count]; - int n; - for(n=0; n GetWriteSound()) Count = GetWriteSound(); - if (!mutecapture) - if(Count > 0 && Buffer) WriteSound(Buffer,Count); - } - if(inited & 2) - FCEUD_UpdateInput(); - if(XBuf && (inited & 4)) BlitScreen(XBuf); + if(LoggingEnabled == 2) + { + int16* MonoBuf = new int16[Count]; + int n; + for(n=0; n GetWriteSound()) Count = GetWriteSound(); + + if (!mutecapture) + { + if(Count > 0 && Buffer) WriteSound(Buffer,Count); + } + } + //if (inited & 2) + // FCEUD_UpdateInput(); + if(XBuf && (inited & 4)) BlitScreen(XBuf); - //SpeedThrottle(); return; - } + } #endif int ocount = Count; @@ -732,15 +736,6 @@ FCEUD_Update(uint8 *XBuf, BlitScreen(XBuf); blitDone = 1; } } - FCEUD_UpdateInput(); - //if(!Count && !NoWaiting && !(eoptions&EO_NOTHROTTLE)) - // SpeedThrottle(); - //if(XBuf && (inited&4)) - //{ - // BlitScreen(XBuf); - //} - //if(Count) - // WriteSound(Buffer,Count,NoWaiting); //FCEUD_UpdateInput(); } @@ -823,7 +818,9 @@ int fceuWrapperUpdate( void ) while ( SpeedThrottle() ) { - FCEUD_UpdateInput(); + // Input device processing is in main thread + // because to MAC OS X SDL2 requires it. + //FCEUD_UpdateInput(); } } else diff --git a/src/drivers/Qt/input.cpp b/src/drivers/Qt/input.cpp index 049a5a97..552f7ad8 100644 --- a/src/drivers/Qt/input.cpp +++ b/src/drivers/Qt/input.cpp @@ -1197,7 +1197,7 @@ static uint8 fkbkeys[0x48]; /** * Update all of the input devices required for the active game. */ -void FCEUD_UpdateInput () +void FCEUD_UpdateInput(void) { int x; int t = 0; @@ -1632,7 +1632,7 @@ const char * ButtonName (const ButtConfig * bc, int which) * Waits for a button input and returns the information as to which * button was pressed. Used in button configuration. */ -int DWaitButton (const uint8 * text, ButtConfig * bc, int wb, int *buttonConfigStatus ) +int DWaitButton (const uint8_t * text, ButtConfig * bc, int wb, int *buttonConfigStatus ) { SDL_Event event; static int32 LastAx[64][64]; diff --git a/src/drivers/Qt/input.h b/src/drivers/Qt/input.h index 35361f56..af5f0c47 100644 --- a/src/drivers/Qt/input.h +++ b/src/drivers/Qt/input.h @@ -1,6 +1,8 @@ #ifndef _aosdfjk02fmasf #define _aosdfjk02fmasf +#include + #include "common/configSys.h" #define MAXBUTTCONFIG 4 @@ -15,7 +17,7 @@ struct ButtConfig int ButtType[MAXBUTTCONFIG]; int DeviceNum[MAXBUTTCONFIG]; int ButtonNum[MAXBUTTCONFIG]; - uint32 NumC; + uint32_t NumC; //uint64 DeviceID[MAXBUTTCONFIG]; /* TODO */ }; @@ -30,7 +32,7 @@ int getKeyState( int k ); int ButtonConfigBegin(); void ButtonConfigEnd(); void ConfigButton(char *text, ButtConfig *bc); -int DWaitButton(const uint8 *text, ButtConfig *bc, int wb, int *buttonConfigStatus = NULL); +int DWaitButton(const uint8_t *text, ButtConfig *bc, int wb, int *buttonConfigStatus = NULL); #define FCFGD_GAMEPAD 1 diff --git a/src/drivers/Qt/nes_shm.h b/src/drivers/Qt/nes_shm.h index d626afe4..0b63998d 100644 --- a/src/drivers/Qt/nes_shm.h +++ b/src/drivers/Qt/nes_shm.h @@ -25,6 +25,7 @@ struct nes_shm_t int pitch; char runEmulator; + char blitUpdated; // Pass Key Events back to QT Gui struct diff --git a/src/drivers/Qt/sdl-video.cpp b/src/drivers/Qt/sdl-video.cpp index cbc8c441..79e6c393 100644 --- a/src/drivers/Qt/sdl-video.cpp +++ b/src/drivers/Qt/sdl-video.cpp @@ -379,6 +379,7 @@ BlitScreen(uint8 *XBuf) { Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines, pitch, 1, 1); } + nes_shm->blitUpdated = 1; //guiPixelBufferReDraw(); From f9b5796ef04fa13b7d29e617163e1baba5608348 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 5 Jul 2020 21:40:19 -0400 Subject: [PATCH 055/100] Created a local buffer for the openGL video image to better sync the image with the drawing frame in the gui thread. --- src/drivers/Qt/ConsoleViewerGL.cpp | 20 +++++++++++++++++++- src/drivers/Qt/ConsoleViewerGL.h | 9 ++++++++- src/drivers/Qt/ConsoleWindow.cpp | 5 ++++- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/drivers/Qt/ConsoleViewerGL.cpp b/src/drivers/Qt/ConsoleViewerGL.cpp index d271ac98..b4b19b4a 100644 --- a/src/drivers/Qt/ConsoleViewerGL.cpp +++ b/src/drivers/Qt/ConsoleViewerGL.cpp @@ -30,6 +30,14 @@ ConsoleViewGL_t::ConsoleViewGL_t(QWidget *parent) devPixRatio = screen->devicePixelRatio(); //printf("Ratio: %f \n", screen->devicePixelRatio() ); } + localBufSize = GL_NES_WIDTH * GL_NES_HEIGHT * sizeof(uint32_t); + + localBuf = (uint32_t*)malloc( localBufSize ); + + if ( localBuf ) + { + memset( localBuf, 0, localBufSize ); + } } ConsoleViewGL_t::~ConsoleViewGL_t(void) @@ -47,6 +55,11 @@ ConsoleViewGL_t::~ConsoleViewGL_t(void) } doneCurrent(); + + if ( localBuf ) + { + free( localBuf ); localBuf = NULL; + } } int ConsoleViewGL_t::init( void ) @@ -109,6 +122,11 @@ void ConsoleViewGL_t::resizeGL(int w, int h) buildTextures(); } +void ConsoleViewGL_t::transfer2LocalBuffer(void) +{ + memcpy( localBuf, nes_shm->pixbuf, localBufSize ); +} + void ConsoleViewGL_t::paintGL(void) { int texture_width = nes_shm->ncol; @@ -149,7 +167,7 @@ void ConsoleViewGL_t::paintGL(void) glTexSubImage2D(GL_TEXTURE_RECTANGLE, 0, 0, 0, GL_NES_WIDTH, GL_NES_HEIGHT, - GL_BGRA, GL_UNSIGNED_BYTE, nes_shm->pixbuf ); + GL_BGRA, GL_UNSIGNED_BYTE, localBuf ); glBegin(GL_QUADS); glTexCoord2f( l, b); // Bottom left of picture. diff --git a/src/drivers/Qt/ConsoleViewerGL.h b/src/drivers/Qt/ConsoleViewerGL.h index 8d8e9270..b45ddcb4 100644 --- a/src/drivers/Qt/ConsoleViewerGL.h +++ b/src/drivers/Qt/ConsoleViewerGL.h @@ -3,6 +3,8 @@ #pragma once +#include + #include #include @@ -16,8 +18,10 @@ class ConsoleViewGL_t : public QOpenGLWidget, protected QOpenGLFunctions int init( void ); + void transfer2LocalBuffer(void); + protected: - void initializeGL(void); + void initializeGL(void); void resizeGL(int w, int h); void paintGL(void); @@ -31,6 +35,9 @@ class ConsoleViewGL_t : public QOpenGLWidget, protected QOpenGLFunctions GLuint gltexture; bool linearFilter; + uint32_t *localBuf; + uint32_t localBufSize; + private slots: }; diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index 41997c0f..d1377c41 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -295,7 +295,10 @@ void consoleWin_t::update(void) { nes_shm->blitUpdated = 0; - viewport->repaint(); + viewport->transfer2LocalBuffer(); + + //viewport->repaint(); + viewport->update(); } return; From 1a99903933574c416b3b6fa1964554c1dbf6710a Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 5 Jul 2020 22:10:28 -0400 Subject: [PATCH 056/100] Changed name of main window periodic update function so that is not the same name as QWidget base update function. --- src/drivers/Qt/ConsoleWindow.cpp | 4 ++-- src/drivers/Qt/ConsoleWindow.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index d1377c41..19a779f2 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -29,7 +29,7 @@ consoleWin_t::consoleWin_t(QWidget *parent) connect(emulatorThread, &QThread::finished, emulatorThread, &QObject::deleteLater); - connect( gameTimer, &QTimer::timeout, this, &consoleWin_t::update ); + connect( gameTimer, &QTimer::timeout, this, &consoleWin_t::updatePeriodic ); gameTimer->setTimerType( Qt::PreciseTimer ); //gameTimer->start( 16 ); // 60hz @@ -277,7 +277,7 @@ void consoleWin_t::aboutQPlot(void) return; } -void consoleWin_t::update(void) +void consoleWin_t::updatePeriodic(void) { //struct timespec ts; //double t; diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index 10444c5a..672d4546 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -78,7 +78,7 @@ class consoleWin_t : public QMainWindow void aboutQPlot(void); void openGamePadConfWin(void); void openGameSndConfWin(void); - void update(void); + void updatePeriodic(void); }; From b2c094a6bf8ea12453328535b3638a05f90b701e Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Mon, 6 Jul 2020 21:44:23 -0400 Subject: [PATCH 057/100] Added QT Hotkey configuration window. --- fceux.pro | 2 + src/drivers/Qt/ConsoleWindow.cpp | 29 ++++++- src/drivers/Qt/ConsoleWindow.h | 2 + src/drivers/Qt/HotKeyConf.cpp | 125 +++++++++++++++++++++++++++++++ src/drivers/Qt/HotKeyConf.h | 42 +++++++++++ src/drivers/Qt/input.h | 2 +- 6 files changed, 199 insertions(+), 3 deletions(-) create mode 100644 src/drivers/Qt/HotKeyConf.cpp create mode 100644 src/drivers/Qt/HotKeyConf.h diff --git a/fceux.pro b/fceux.pro index 80711047..f4fe1fc8 100644 --- a/fceux.pro +++ b/fceux.pro @@ -298,12 +298,14 @@ HEADERS += src/drivers/Qt/ConsoleWindow.h HEADERS += src/drivers/Qt/ConsoleViewerGL.h HEADERS += src/drivers/Qt/ConsoleViewerSDL.h HEADERS += src/drivers/Qt/GamePadConf.h +HEADERS += src/drivers/Qt/HotKeyConf.h HEADERS += src/drivers/Qt/ConsoleSoundConf.h SOURCES += src/drivers/Qt/main.cpp SOURCES += src/drivers/Qt/ConsoleWindow.cpp SOURCES += src/drivers/Qt/ConsoleViewerGL.cpp SOURCES += src/drivers/Qt/ConsoleViewerSDL.cpp SOURCES += src/drivers/Qt/GamePadConf.cpp +SOURCES += src/drivers/Qt/HotKeyConf.cpp SOURCES += src/drivers/Qt/ConsoleSoundConf.cpp SOURCES += src/drivers/Qt/fceuWrapper.cpp SOURCES += src/drivers/Qt/config.cpp diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index 19a779f2..d718926a 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -7,6 +7,7 @@ #include "Qt/input.h" #include "Qt/ConsoleWindow.h" #include "Qt/GamePadConf.h" +#include "Qt/HotKeyConf.h" #include "Qt/ConsoleSoundConf.h" #include "Qt/fceuWrapper.h" #include "Qt/keyscan.h" @@ -149,6 +150,14 @@ void consoleWin_t::createMainMenu(void) optMenu->addAction(gameSoundConfig); + // Options -> HotKey Config + hotkeyConfig = new QAction(tr("Hotkey Config"), this); + //hotkeyConfig->setShortcut( QKeySequence(tr("Ctrl+C"))); + hotkeyConfig->setStatusTip(tr("Hotkey Configure")); + connect(hotkeyConfig, SIGNAL(triggered()), this, SLOT(openHotkeyConfWin(void)) ); + + optMenu->addAction(hotkeyConfig); + //----------------------------------------------------------------------- // Help helpMenu = menuBar()->addMenu(tr("Help")); @@ -259,7 +268,7 @@ void consoleWin_t::openGameSndConfWin(void) { ConsoleSndConfDialog_t *sndConfWin; - printf("Open Sound Config Window\n"); + //printf("Open Sound Config Window\n"); sndConfWin = new ConsoleSndConfDialog_t(this); @@ -268,7 +277,23 @@ void consoleWin_t::openGameSndConfWin(void) delete sndConfWin; - printf("Sound Config Window Destroyed\n"); + //printf("Sound Config Window Destroyed\n"); +} + +void consoleWin_t::openHotkeyConfWin(void) +{ + HotKeyConfDialog_t *hkConfWin; + + printf("Open Hot Key Config Window\n"); + + hkConfWin = new HotKeyConfDialog_t(this); + + hkConfWin->show(); + hkConfWin->exec(); + + delete hkConfWin; + + printf("Hotkey Config Window Destroyed\n"); } void consoleWin_t::aboutQPlot(void) diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index 672d4546..87e931af 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -56,6 +56,7 @@ class consoleWin_t : public QMainWindow QAction *quitAct; QAction *gamePadConfig; QAction *gameSoundConfig; + QAction *hotkeyConfig; QAction *aboutAct; QTimer *gameTimer; @@ -78,6 +79,7 @@ class consoleWin_t : public QMainWindow void aboutQPlot(void); void openGamePadConfWin(void); void openGameSndConfWin(void); + void openHotkeyConfWin(void); void updatePeriodic(void); }; diff --git a/src/drivers/Qt/HotKeyConf.cpp b/src/drivers/Qt/HotKeyConf.cpp new file mode 100644 index 00000000..13c33f1c --- /dev/null +++ b/src/drivers/Qt/HotKeyConf.cpp @@ -0,0 +1,125 @@ +// HotKeyConf.cpp +// +#include +#include +#include +#include + +#include +#include + +#include "Qt/main.h" +#include "Qt/dface.h" +#include "Qt/input.h" +#include "Qt/config.h" +#include "Qt/keyscan.h" +#include "Qt/fceuWrapper.h" +#include "Qt/HotKeyConf.h" + +//---------------------------------------------------------------------------- +HotKeyConfDialog_t::HotKeyConfDialog_t(QWidget *parent) + : QDialog( parent ) +{ + QVBoxLayout *mainLayout; + QTreeWidgetItem *item; + std::string prefix = "SDL.Hotkeys."; + int keycode; + + setWindowTitle("Hotkey Configuration"); + + resize( 512, 512 ); + + mainLayout = new QVBoxLayout(); + + tree = new QTreeWidget(); + + tree->setColumnCount(2); + + item = new QTreeWidgetItem(); + item->setText( 0, QString::fromStdString( "Command" ) ); + item->setText( 1, QString::fromStdString( "Key" ) ); + item->setTextAlignment( 0, Qt::AlignLeft); + item->setTextAlignment( 1, Qt::AlignCenter); + + tree->setHeaderItem( item ); + + tree->header()->setSectionResizeMode( QHeaderView::ResizeToContents ); + + for (int i=0; igetOption (optionName.c_str (), &keycode); + + item = new QTreeWidgetItem(); + + item->setText( 0, QString::fromStdString( optionName ) ); + item->setText( 1, QString::fromStdString( SDL_GetKeyName (keycode) ) ); + + item->setTextAlignment( 0, Qt::AlignLeft); + item->setTextAlignment( 1, Qt::AlignCenter); + + tree->addTopLevelItem( item ); + } + mainLayout->addWidget( tree ); + + setLayout( mainLayout ); +} +//---------------------------------------------------------------------------- +HotKeyConfDialog_t::~HotKeyConfDialog_t(void) +{ + +} +//---------------------------------------------------------------------------- +void HotKeyConfDialog_t::closeWindow(void) +{ + //printf("Close Window\n"); + done(0); +} +//---------------------------------------------------------------------------- +void HotKeyConfDialog_t::assignHotkey(QKeyEvent *event) +{ + SDL_Keycode k = convQtKey2SDLKeyCode( (Qt::Key)event->key() ); + + if ( k != SDLK_UNKNOWN ) + { + QList l; + + l = tree->selectedItems(); + + for (size_t i=0; i < l.size(); i++) + { + //int idx; + QString qs; + QTreeWidgetItem *item; + + item = l.at(i); + + //idx = tree->indexOfTopLevelItem( item ); + + qs = item->text(0); + + g_config->setOption ( qs.toStdString(), k ); + + setHotKeys(); + + item->setText( 1, QString::fromStdString( SDL_GetKeyName (k) ) ); + + //printf("Hotkey Window Key Press: 0x%x item:%p\n '%s' : %i\n", + // k, item, qs.toStdString().c_str(), idx ); + } + } +} +//---------------------------------------------------------------------------- +void HotKeyConfDialog_t::keyPressEvent(QKeyEvent *event) +{ + //printf("Hotkey Window Key Press: 0x%x \n", event->key() ); + assignHotkey( event ); +} +//---------------------------------------------------------------------------- +void HotKeyConfDialog_t::keyReleaseEvent(QKeyEvent *event) +{ + //printf("Hotkey Window Key Release: 0x%x \n", event->key() ); + assignHotkey( event ); +} +//---------------------------------------------------------------------------- diff --git a/src/drivers/Qt/HotKeyConf.h b/src/drivers/Qt/HotKeyConf.h new file mode 100644 index 00000000..cba35cee --- /dev/null +++ b/src/drivers/Qt/HotKeyConf.h @@ -0,0 +1,42 @@ +// GamePadConf.h +// + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Qt/main.h" + +class HotKeyConfDialog_t : public QDialog +{ + Q_OBJECT + + public: + HotKeyConfDialog_t(QWidget *parent = 0); + ~HotKeyConfDialog_t(void); + + protected: + void keyPressEvent(QKeyEvent *event); + void keyReleaseEvent(QKeyEvent *event); + void assignHotkey(QKeyEvent *event); + + QTreeWidget *tree; + + private: + + public slots: + void closeWindow(void); + private slots: + +}; diff --git a/src/drivers/Qt/input.h b/src/drivers/Qt/input.h index af5f0c47..d9a70118 100644 --- a/src/drivers/Qt/input.h +++ b/src/drivers/Qt/input.h @@ -27,7 +27,7 @@ extern CFGSTRUCT InputConfig[]; extern ARGPSTRUCT InputArgs[]; extern int Hotkeys[]; void ParseGIInput(FCEUGI *GI); -void setHotKeys(); +void setHotKeys(void); int getKeyState( int k ); int ButtonConfigBegin(); void ButtonConfigEnd(); From ce0a8fdf63d3d3d00f258814f450ba13e0e6a2c8 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Tue, 7 Jul 2020 08:59:47 -0400 Subject: [PATCH 058/100] Added framework for video config window. Still TODO writing logic. --- fceux.pro | 2 + src/drivers/Qt/ConsoleVideoConf.cpp | 64 +++++++++++++++++++++++++++++ src/drivers/Qt/ConsoleVideoConf.h | 40 ++++++++++++++++++ src/drivers/Qt/ConsoleWindow.cpp | 25 +++++++++++ src/drivers/Qt/ConsoleWindow.h | 2 + 5 files changed, 133 insertions(+) create mode 100644 src/drivers/Qt/ConsoleVideoConf.cpp create mode 100644 src/drivers/Qt/ConsoleVideoConf.h diff --git a/fceux.pro b/fceux.pro index f4fe1fc8..847e814f 100644 --- a/fceux.pro +++ b/fceux.pro @@ -299,6 +299,7 @@ HEADERS += src/drivers/Qt/ConsoleViewerGL.h HEADERS += src/drivers/Qt/ConsoleViewerSDL.h HEADERS += src/drivers/Qt/GamePadConf.h HEADERS += src/drivers/Qt/HotKeyConf.h +HEADERS += src/drivers/Qt/ConsoleVideoConf.h HEADERS += src/drivers/Qt/ConsoleSoundConf.h SOURCES += src/drivers/Qt/main.cpp SOURCES += src/drivers/Qt/ConsoleWindow.cpp @@ -306,6 +307,7 @@ SOURCES += src/drivers/Qt/ConsoleViewerGL.cpp SOURCES += src/drivers/Qt/ConsoleViewerSDL.cpp SOURCES += src/drivers/Qt/GamePadConf.cpp SOURCES += src/drivers/Qt/HotKeyConf.cpp +SOURCES += src/drivers/Qt/ConsoleVideoConf.cpp SOURCES += src/drivers/Qt/ConsoleSoundConf.cpp SOURCES += src/drivers/Qt/fceuWrapper.cpp SOURCES += src/drivers/Qt/config.cpp diff --git a/src/drivers/Qt/ConsoleVideoConf.cpp b/src/drivers/Qt/ConsoleVideoConf.cpp new file mode 100644 index 00000000..73fdda87 --- /dev/null +++ b/src/drivers/Qt/ConsoleVideoConf.cpp @@ -0,0 +1,64 @@ +// ConsoleVideoConf.cpp +// +#include "Qt/config.h" +#include "Qt/fceuWrapper.h" +#include "Qt/ConsoleVideoConf.h" + + +//---------------------------------------------------- +ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent) + : QDialog( parent ) +{ + QVBoxLayout *main_vbox; + QHBoxLayout *hbox1; + QLabel *lbl; + + setWindowTitle("Video Config"); + + main_vbox = new QVBoxLayout(); + + // Video Driver Select + lbl = new QLabel( tr("Driver:") ); + + drvSel = new QComboBox(); + + drvSel->addItem( tr("OpenGL"), 0 ); + //drvSel->addItem( tr("SDL"), 1 ); + + hbox1 = new QHBoxLayout(); + + hbox1->addWidget( lbl ); + hbox1->addWidget( drvSel ); + + main_vbox->addLayout( hbox1 ); + + // Enable OpenGL Linear Filter + gl_LF_chkBox = new QCheckBox( tr("Enable OpenGL Linear Filter") ); + + main_vbox->addWidget( gl_LF_chkBox ); + + // Region Select + lbl = new QLabel( tr("Region:") ); + + regionSelect = new QComboBox(); + + regionSelect->addItem( tr("NTSC") , 0 ); + regionSelect->addItem( tr("PAL") , 1 ); + regionSelect->addItem( tr("Dendy"), 2 ); + + hbox1 = new QHBoxLayout(); + + hbox1->addWidget( lbl ); + hbox1->addWidget( regionSelect ); + + main_vbox->addLayout( hbox1 ); + + setLayout( main_vbox ); + +} +//---------------------------------------------------- +ConsoleVideoConfDialog_t::~ConsoleVideoConfDialog_t(void) +{ + +} +//---------------------------------------------------- diff --git a/src/drivers/Qt/ConsoleVideoConf.h b/src/drivers/Qt/ConsoleVideoConf.h new file mode 100644 index 00000000..d8971527 --- /dev/null +++ b/src/drivers/Qt/ConsoleVideoConf.h @@ -0,0 +1,40 @@ +// ConsoleVideoConf.h +// + +#ifndef __ConsoleVideoH__ +#define __ConsoleVideoH__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class ConsoleVideoConfDialog_t : public QDialog +{ + Q_OBJECT + + public: + ConsoleVideoConfDialog_t(QWidget *parent = 0); + ~ConsoleVideoConfDialog_t(void); + + protected: + QCheckBox *gl_LF_chkBox; + QComboBox *drvSel; + QComboBox *regionSelect; + + //void setCheckBoxFromProperty( QCheckBox *cbx, const char *property ); + //void setComboBoxFromProperty( QComboBox *cbx, const char *property ); + //void setSliderFromProperty( QSlider *slider, QLabel *lbl, const char *property ); + + private slots: + +}; + +#endif diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index d718926a..f3dce027 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -9,6 +9,7 @@ #include "Qt/GamePadConf.h" #include "Qt/HotKeyConf.h" #include "Qt/ConsoleSoundConf.h" +#include "Qt/ConsoleVideoConf.h" #include "Qt/fceuWrapper.h" #include "Qt/keyscan.h" #include "Qt/nes_shm.h" @@ -150,6 +151,14 @@ void consoleWin_t::createMainMenu(void) optMenu->addAction(gameSoundConfig); + // Options -> Video Config + gameVideoConfig = new QAction(tr("Video Config"), this); + //gameVideoConfig->setShortcut( QKeySequence(tr("Ctrl+C"))); + gameVideoConfig->setStatusTip(tr("Video Configure")); + connect(gameVideoConfig, SIGNAL(triggered()), this, SLOT(openGameVideoConfWin(void)) ); + + optMenu->addAction(gameVideoConfig); + // Options -> HotKey Config hotkeyConfig = new QAction(tr("Hotkey Config"), this); //hotkeyConfig->setShortcut( QKeySequence(tr("Ctrl+C"))); @@ -280,6 +289,22 @@ void consoleWin_t::openGameSndConfWin(void) //printf("Sound Config Window Destroyed\n"); } +void consoleWin_t::openGameVideoConfWin(void) +{ + ConsoleVideoConfDialog_t *vidConfWin; + + //printf("Open Video Config Window\n"); + + vidConfWin = new ConsoleVideoConfDialog_t(this); + + vidConfWin->show(); + vidConfWin->exec(); + + delete vidConfWin; + + //printf("Video Config Window Destroyed\n"); +} + void consoleWin_t::openHotkeyConfWin(void) { HotKeyConfDialog_t *hkConfWin; diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index 87e931af..713b7674 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -56,6 +56,7 @@ class consoleWin_t : public QMainWindow QAction *quitAct; QAction *gamePadConfig; QAction *gameSoundConfig; + QAction *gameVideoConfig; QAction *hotkeyConfig; QAction *aboutAct; @@ -79,6 +80,7 @@ class consoleWin_t : public QMainWindow void aboutQPlot(void); void openGamePadConfWin(void); void openGameSndConfWin(void); + void openGameVideoConfWin(void); void openHotkeyConfWin(void); void updatePeriodic(void); From 313bba68f99f11194713ee4deb963e3dad62cfb6 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Tue, 7 Jul 2020 18:49:58 -0400 Subject: [PATCH 059/100] Added missing tr function calls around string literals. --- src/drivers/Qt/ConsoleSoundConf.cpp | 12 ++++++------ src/drivers/Qt/ConsoleVideoConf.cpp | 2 +- src/drivers/Qt/ConsoleWindow.cpp | 2 +- src/drivers/Qt/GamePadConf.cpp | 8 ++++---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/drivers/Qt/ConsoleSoundConf.cpp b/src/drivers/Qt/ConsoleSoundConf.cpp index 9b091fd6..aeeec8f6 100644 --- a/src/drivers/Qt/ConsoleSoundConf.cpp +++ b/src/drivers/Qt/ConsoleSoundConf.cpp @@ -1,4 +1,4 @@ -// GameSoundConf.cpp +// ConsoleSoundConf.cpp // #include "../../fceu.h" #include "../../driver.h" @@ -19,15 +19,15 @@ ConsoleSndConfDialog_t::ConsoleSndConfDialog_t(QWidget *parent) QGroupBox *frame; QSlider *vslider; - setWindowTitle("Sound Config"); + setWindowTitle( tr("Sound Config") ); hbox1 = new QHBoxLayout(); vbox1 = new QVBoxLayout(); // Enable Sound Select - enaChkbox = new QCheckBox("Enable Sound"); + enaChkbox = new QCheckBox( tr("Enable Sound") ); // Enable Low Pass Filter Select - enaLowPass = new QCheckBox("Enable Low Pass Filter"); + enaLowPass = new QCheckBox( tr("Enable Low Pass Filter") ); setCheckBoxFromProperty( enaChkbox , "SDL.Sound" ); setCheckBoxFromProperty( enaLowPass, "SDL.Sound.LowPass" ); @@ -86,7 +86,7 @@ ConsoleSndConfDialog_t::ConsoleSndConfDialog_t(QWidget *parent) // hbox2 = new QHBoxLayout(); - lbl = new QLabel("Buffer Size (in ms):"); + lbl = new QLabel( tr("Buffer Size (in ms):") ); bufSizeLabel = new QLabel("128"); bufSizeSlider = new QSlider( Qt::Horizontal ); @@ -105,7 +105,7 @@ ConsoleSndConfDialog_t::ConsoleSndConfDialog_t(QWidget *parent) connect(bufSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(bufSizeChanged(int)) ); // Swap Duty Cycles - swapDutyChkbox = new QCheckBox("Swap Duty Cycles"); + swapDutyChkbox = new QCheckBox( tr("Swap Duty Cycles") ); vbox1->addWidget( swapDutyChkbox ); setCheckBoxFromProperty( swapDutyChkbox , "SDL.SwapDuty" ); diff --git a/src/drivers/Qt/ConsoleVideoConf.cpp b/src/drivers/Qt/ConsoleVideoConf.cpp index 73fdda87..88409bbc 100644 --- a/src/drivers/Qt/ConsoleVideoConf.cpp +++ b/src/drivers/Qt/ConsoleVideoConf.cpp @@ -13,7 +13,7 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent) QHBoxLayout *hbox1; QLabel *lbl; - setWindowTitle("Video Config"); + setWindowTitle( tr("Video Config") ); main_vbox = new QVBoxLayout(); diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index f3dce027..7243b706 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -201,7 +201,7 @@ void consoleWin_t::openROMFile(void) { int ret; QString filename; - QFileDialog dialog(this, "Open ROM File"); + QFileDialog dialog(this, tr("Open ROM File") ); dialog.setFileMode(QFileDialog::ExistingFile); diff --git a/src/drivers/Qt/GamePadConf.cpp b/src/drivers/Qt/GamePadConf.cpp index 37f02f5f..24cfb88c 100644 --- a/src/drivers/Qt/GamePadConf.cpp +++ b/src/drivers/Qt/GamePadConf.cpp @@ -24,7 +24,7 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) configNo = 0; buttonConfigStatus = 1; - setWindowTitle("GamePad Config"); + setWindowTitle( tr("GamePad Config") ); hbox1 = new QHBoxLayout(); hbox2 = new QHBoxLayout(); @@ -39,8 +39,8 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) portSel->addItem( tr("3"), 2 ); portSel->addItem( tr("4"), 3 ); - efs_chkbox = new QCheckBox("Enable Four Score"); - udlr_chkbox = new QCheckBox("Allow Up+Down/Left+Right"); + efs_chkbox = new QCheckBox( tr("Enable Four Score") ); + udlr_chkbox = new QCheckBox( tr("Allow Up+Down/Left+Right") ); int fourScore; g_config->getOption("SDL.FourScore", &fourScore); @@ -72,7 +72,7 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent) buttonName = new QLabel(tr(text)); keyName[i] = new QLabel(); button[i] = new GamePadConfigButton_t(i); - clearButton[i] = new QPushButton("Clear"); + clearButton[i] = new QPushButton( tr("Clear") ); grid->addWidget( buttonName , i, 0, Qt::AlignCenter ); grid->addWidget( keyName[i] , i, 1, Qt::AlignCenter ); From ea1782bfe55e872ff79a5e8241738f895c26b588 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Tue, 7 Jul 2020 20:53:31 -0400 Subject: [PATCH 060/100] Added checkbox logic for video config window. --- src/drivers/Qt/ConsoleSoundConf.cpp | 2 +- src/drivers/Qt/ConsoleVideoConf.cpp | 141 ++++++++++++++++++++++++++-- src/drivers/Qt/ConsoleVideoConf.h | 20 +++- src/drivers/Qt/ConsoleWindow.cpp | 4 +- 4 files changed, 155 insertions(+), 12 deletions(-) diff --git a/src/drivers/Qt/ConsoleSoundConf.cpp b/src/drivers/Qt/ConsoleSoundConf.cpp index aeeec8f6..4d716f3b 100644 --- a/src/drivers/Qt/ConsoleSoundConf.cpp +++ b/src/drivers/Qt/ConsoleSoundConf.cpp @@ -41,7 +41,7 @@ ConsoleSndConfDialog_t::ConsoleSndConfDialog_t(QWidget *parent) // Audio Quality Select hbox2 = new QHBoxLayout(); - lbl = new QLabel("Quality:"); + lbl = new QLabel( tr("Quality:") ); qualitySelect = new QComboBox(); diff --git a/src/drivers/Qt/ConsoleVideoConf.cpp b/src/drivers/Qt/ConsoleVideoConf.cpp index 88409bbc..345d9b71 100644 --- a/src/drivers/Qt/ConsoleVideoConf.cpp +++ b/src/drivers/Qt/ConsoleVideoConf.cpp @@ -1,10 +1,12 @@ // ConsoleVideoConf.cpp // +#include "../../fceu.h" +#include "Qt/main.h" +#include "Qt/dface.h" #include "Qt/config.h" #include "Qt/fceuWrapper.h" #include "Qt/ConsoleVideoConf.h" - //---------------------------------------------------- ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent) : QDialog( parent ) @@ -12,6 +14,7 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent) QVBoxLayout *main_vbox; QHBoxLayout *hbox1; QLabel *lbl; + QPushButton *button; setWindowTitle( tr("Video Config") ); @@ -20,21 +23,23 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent) // Video Driver Select lbl = new QLabel( tr("Driver:") ); - drvSel = new QComboBox(); + driverSelect = new QComboBox(); - drvSel->addItem( tr("OpenGL"), 0 ); - //drvSel->addItem( tr("SDL"), 1 ); + driverSelect->addItem( tr("OpenGL"), 0 ); + //driverSelect->addItem( tr("SDL"), 1 ); hbox1 = new QHBoxLayout(); hbox1->addWidget( lbl ); - hbox1->addWidget( drvSel ); + hbox1->addWidget( driverSelect ); main_vbox->addLayout( hbox1 ); - // Enable OpenGL Linear Filter + // Enable OpenGL Linear Filter Checkbox gl_LF_chkBox = new QCheckBox( tr("Enable OpenGL Linear Filter") ); + setCheckBoxFromProperty( gl_LF_chkBox , "SDL.OpenGLip"); + main_vbox->addWidget( gl_LF_chkBox ); // Region Select @@ -53,6 +58,51 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent) main_vbox->addLayout( hbox1 ); + // Enable New PPU Checkbox + new_PPU_ena = new QCheckBox( tr("Enable New PPU") ); + + // Enable New PPU Checkbox + frmskipcbx = new QCheckBox( tr("Enable Frameskip") ); + + // Disable Sprite Limit Checkbox + sprtLimCbx = new QCheckBox( tr("Disable Sprite Limit") ); + + // Clip Sides Checkbox + clipSidesCbx = new QCheckBox( tr("Clip Sides") ); + + // Show FPS Checkbox + showFPS_cbx = new QCheckBox( tr("Show FPS") ); + + setCheckBoxFromProperty( new_PPU_ena , "SDL.NewPPU"); + setCheckBoxFromProperty( frmskipcbx , "SDL.Frameskip"); + setCheckBoxFromProperty( sprtLimCbx , "SDL.DisableSpriteLimit"); + setCheckBoxFromProperty( clipSidesCbx , "SDL.ClipSides"); + setCheckBoxFromProperty( showFPS_cbx , "SDL.ShowFPS"); + + connect(new_PPU_ena , SIGNAL(stateChanged(int)), this, SLOT(use_new_PPU_changed(int)) ); + connect(frmskipcbx , SIGNAL(stateChanged(int)), this, SLOT(frameskip_changed(int)) ); + connect(sprtLimCbx , SIGNAL(stateChanged(int)), this, SLOT(useSpriteLimitChanged(int)) ); + connect(clipSidesCbx, SIGNAL(stateChanged(int)), this, SLOT(clipSidesChanged(int)) ); + connect(showFPS_cbx , SIGNAL(stateChanged(int)), this, SLOT(showFPSChanged(int)) ); + + main_vbox->addWidget( new_PPU_ena ); + main_vbox->addWidget( frmskipcbx ); + main_vbox->addWidget( sprtLimCbx ); + main_vbox->addWidget( clipSidesCbx); + main_vbox->addWidget( showFPS_cbx ); + + hbox1 = new QHBoxLayout(); + + button = new QPushButton( tr("Apply") ); + hbox1->addWidget( button ); + connect(button, SIGNAL(clicked()), this, SLOT(applyChanges(void)) ); + + button = new QPushButton( tr("Close") ); + hbox1->addWidget( button ); + connect(button, SIGNAL(clicked()), this, SLOT(closewindow(void)) ); + + main_vbox->addLayout( hbox1 ); + setLayout( main_vbox ); } @@ -62,3 +112,82 @@ ConsoleVideoConfDialog_t::~ConsoleVideoConfDialog_t(void) } //---------------------------------------------------- +void ConsoleVideoConfDialog_t::resetVideo(void) +{ + KillVideo (); + InitVideo (GameInfo); +} +//---------------------------------------------------- +void ConsoleVideoConfDialog_t::setCheckBoxFromProperty( QCheckBox *cbx, const char *property ) +{ + int pval; + g_config->getOption (property, &pval); + + cbx->setCheckState( pval ? Qt::Checked : Qt::Unchecked ); +} +//---------------------------------------------------- +void ConsoleVideoConfDialog_t::use_new_PPU_changed( int value ) +{ + //printf("Value:%i \n", value ); + g_config->setOption("SDL.NewPPU", (value == Qt::Checked) ); + g_config->save (); + + fceuWrapperLock(); + UpdateEMUCore (g_config); + fceuWrapperUnLock(); +} +//---------------------------------------------------- +void ConsoleVideoConfDialog_t::frameskip_changed( int value ) +{ + //printf("Value:%i \n", value ); + g_config->setOption("SDL.Frameskip", (value == Qt::Checked) ); + g_config->save (); + + fceuWrapperLock(); + UpdateEMUCore (g_config); + fceuWrapperUnLock(); +} +//---------------------------------------------------- +void ConsoleVideoConfDialog_t::useSpriteLimitChanged( int value ) +{ + //printf("Value:%i \n", value ); + g_config->setOption("SDL.DisableSpriteLimit", (value == Qt::Checked) ); + g_config->save (); + + fceuWrapperLock(); + UpdateEMUCore (g_config); + fceuWrapperUnLock(); +} +//---------------------------------------------------- +void ConsoleVideoConfDialog_t::clipSidesChanged( int value ) +{ + //printf("Value:%i \n", value ); + g_config->setOption("SDL.ClipSides", (value == Qt::Checked) ); + g_config->save (); + + fceuWrapperLock(); + UpdateEMUCore (g_config); + fceuWrapperUnLock(); +} +//---------------------------------------------------- +void ConsoleVideoConfDialog_t::showFPSChanged( int value ) +{ + //printf("Value:%i \n", value ); + g_config->setOption("SDL.ShowFPS", (value == Qt::Checked) ); + g_config->save (); + + fceuWrapperLock(); + UpdateEMUCore (g_config); + fceuWrapperUnLock(); +} +//---------------------------------------------------- +void ConsoleVideoConfDialog_t::applyChanges( void ) +{ + resetVideo(); +} +//---------------------------------------------------- +void ConsoleVideoConfDialog_t::closewindow( void ) +{ + done(0); +} +//---------------------------------------------------- diff --git a/src/drivers/Qt/ConsoleVideoConf.h b/src/drivers/Qt/ConsoleVideoConf.h index d8971527..0c258fe1 100644 --- a/src/drivers/Qt/ConsoleVideoConf.h +++ b/src/drivers/Qt/ConsoleVideoConf.h @@ -25,15 +25,29 @@ class ConsoleVideoConfDialog_t : public QDialog ~ConsoleVideoConfDialog_t(void); protected: - QCheckBox *gl_LF_chkBox; - QComboBox *drvSel; + QComboBox *driverSelect; QComboBox *regionSelect; + QCheckBox *gl_LF_chkBox; + QCheckBox *new_PPU_ena; + QCheckBox *frmskipcbx; + QCheckBox *sprtLimCbx; + QCheckBox *clipSidesCbx; + QCheckBox *showFPS_cbx; - //void setCheckBoxFromProperty( QCheckBox *cbx, const char *property ); + void setCheckBoxFromProperty( QCheckBox *cbx, const char *property ); //void setComboBoxFromProperty( QComboBox *cbx, const char *property ); //void setSliderFromProperty( QSlider *slider, QLabel *lbl, const char *property ); + void resetVideo(void); + private slots: + void use_new_PPU_changed( int value ); + void frameskip_changed( int value ); + void useSpriteLimitChanged( int value ); + void clipSidesChanged( int value ); + void showFPSChanged( int value ); + void applyChanges( void ); + void closewindow( void ); }; diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index 7243b706..523a3455 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -309,7 +309,7 @@ void consoleWin_t::openHotkeyConfWin(void) { HotKeyConfDialog_t *hkConfWin; - printf("Open Hot Key Config Window\n"); + //printf("Open Hot Key Config Window\n"); hkConfWin = new HotKeyConfDialog_t(this); @@ -318,7 +318,7 @@ void consoleWin_t::openHotkeyConfWin(void) delete hkConfWin; - printf("Hotkey Config Window Destroyed\n"); + //printf("Hotkey Config Window Destroyed\n"); } void consoleWin_t::aboutQPlot(void) From 46271dfa614fae24ace56bcde167b1ee1ff45303 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Tue, 7 Jul 2020 21:06:24 -0400 Subject: [PATCH 061/100] Added video region combo box logic. --- src/drivers/Qt/ConsoleVideoConf.cpp | 19 +++++++++++++++++++ src/drivers/Qt/ConsoleVideoConf.h | 1 + 2 files changed, 20 insertions(+) diff --git a/src/drivers/Qt/ConsoleVideoConf.cpp b/src/drivers/Qt/ConsoleVideoConf.cpp index 345d9b71..a70bdca2 100644 --- a/src/drivers/Qt/ConsoleVideoConf.cpp +++ b/src/drivers/Qt/ConsoleVideoConf.cpp @@ -51,6 +51,8 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent) regionSelect->addItem( tr("PAL") , 1 ); regionSelect->addItem( tr("Dendy"), 2 ); + connect(regionSelect, SIGNAL(currentIndexChanged(int)), this, SLOT(regionChanged(int)) ); + hbox1 = new QHBoxLayout(); hbox1->addWidget( lbl ); @@ -181,6 +183,23 @@ void ConsoleVideoConfDialog_t::showFPSChanged( int value ) fceuWrapperUnLock(); } //---------------------------------------------------- +void ConsoleVideoConfDialog_t::regionChanged(int index) +{ + int region; + //printf("Region: %i : %i \n", index, regionSelect->itemData(index).toInt() ); + + region = regionSelect->itemData(index).toInt(); + + g_config->setOption ("SDL.PAL", region); + + g_config->save (); + + // reset sound subsystem for changes to take effect + fceuWrapperLock(); + FCEUI_SetRegion (region); + fceuWrapperUnLock(); +} +//---------------------------------------------------- void ConsoleVideoConfDialog_t::applyChanges( void ) { resetVideo(); diff --git a/src/drivers/Qt/ConsoleVideoConf.h b/src/drivers/Qt/ConsoleVideoConf.h index 0c258fe1..16b5aa5f 100644 --- a/src/drivers/Qt/ConsoleVideoConf.h +++ b/src/drivers/Qt/ConsoleVideoConf.h @@ -46,6 +46,7 @@ class ConsoleVideoConfDialog_t : public QDialog void useSpriteLimitChanged( int value ); void clipSidesChanged( int value ); void showFPSChanged( int value ); + void regionChanged(int index); void applyChanges( void ); void closewindow( void ); From d87b5c7ab70b44d3d743f1a854a12c27c86c77cb Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Tue, 7 Jul 2020 21:26:15 -0400 Subject: [PATCH 062/100] Added logic for auto-resume play menu item. --- src/drivers/Qt/ConsoleWindow.cpp | 21 ++++++++++++++++++++- src/drivers/Qt/ConsoleWindow.h | 2 ++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index 523a3455..740d87b0 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -2,6 +2,7 @@ // #include +#include "../../fceu.h" #include "Qt/main.h" #include "Qt/dface.h" #include "Qt/input.h" @@ -154,7 +155,7 @@ void consoleWin_t::createMainMenu(void) // Options -> Video Config gameVideoConfig = new QAction(tr("Video Config"), this); //gameVideoConfig->setShortcut( QKeySequence(tr("Ctrl+C"))); - gameVideoConfig->setStatusTip(tr("Video Configure")); + gameVideoConfig->setStatusTip(tr("Video Preferences")); connect(gameVideoConfig, SIGNAL(triggered()), this, SLOT(openGameVideoConfWin(void)) ); optMenu->addAction(gameVideoConfig); @@ -167,6 +168,15 @@ void consoleWin_t::createMainMenu(void) optMenu->addAction(hotkeyConfig); + // Options -> Auto-Resume + autoResume = new QAction(tr("Auto-Resume Play"), this); + //autoResume->setShortcut( QKeySequence(tr("Ctrl+C"))); + autoResume->setCheckable(true); + autoResume->setStatusTip(tr("Auto-Resume Play")); + connect(autoResume, SIGNAL(triggered()), this, SLOT(toggleAutoResume(void)) ); + + optMenu->addAction(autoResume); + //----------------------------------------------------------------------- // Help helpMenu = menuBar()->addMenu(tr("Help")); @@ -321,6 +331,15 @@ void consoleWin_t::openHotkeyConfWin(void) //printf("Hotkey Config Window Destroyed\n"); } +void consoleWin_t::toggleAutoResume(void) +{ + //printf("Auto Resume: %i\n", autoResume->isChecked() ); + + g_config->setOption ("SDL.AutoResume", (int) autoResume->isChecked() ); + + AutoResumePlay = autoResume->isChecked(); +} + void consoleWin_t::aboutQPlot(void) { printf("About QPlot\n"); diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index 713b7674..cdfffa1d 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -58,6 +58,7 @@ class consoleWin_t : public QMainWindow QAction *gameSoundConfig; QAction *gameVideoConfig; QAction *hotkeyConfig; + QAction *autoResume; QAction *aboutAct; QTimer *gameTimer; @@ -82,6 +83,7 @@ class consoleWin_t : public QMainWindow void openGameSndConfWin(void); void openGameVideoConfWin(void); void openHotkeyConfWin(void); + void toggleAutoResume(void); void updatePeriodic(void); }; From 5958dc18fb96ef8b0ef1a27f932d4d8c78c6a8b0 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Tue, 7 Jul 2020 21:45:24 -0400 Subject: [PATCH 063/100] Added fullscreen menu function. --- src/drivers/Qt/ConsoleWindow.cpp | 23 +++++++++++++++++++++++ src/drivers/Qt/ConsoleWindow.h | 2 ++ 2 files changed, 25 insertions(+) diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index 740d87b0..db4d8d7e 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -177,6 +177,17 @@ void consoleWin_t::createMainMenu(void) optMenu->addAction(autoResume); + optMenu->addSeparator(); + + // Options -> Full Screen + fullscreen = new QAction(tr("Fullscreen"), this); + fullscreen->setShortcut( QKeySequence(tr("Alt+Return"))); + //fullscreen->setCheckable(true); + fullscreen->setStatusTip(tr("Fullscreen")); + connect(fullscreen, SIGNAL(triggered()), this, SLOT(toggleFullscreen(void)) ); + + optMenu->addAction(fullscreen); + //----------------------------------------------------------------------- // Help helpMenu = menuBar()->addMenu(tr("Help")); @@ -340,6 +351,18 @@ void consoleWin_t::toggleAutoResume(void) AutoResumePlay = autoResume->isChecked(); } +void consoleWin_t::toggleFullscreen(void) +{ + if ( isFullScreen() ) + { + showNormal(); + } + else + { + showFullScreen(); + } +} + void consoleWin_t::aboutQPlot(void) { printf("About QPlot\n"); diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index cdfffa1d..205f09c0 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -59,6 +59,7 @@ class consoleWin_t : public QMainWindow QAction *gameVideoConfig; QAction *hotkeyConfig; QAction *autoResume; + QAction *fullscreen; QAction *aboutAct; QTimer *gameTimer; @@ -84,6 +85,7 @@ class consoleWin_t : public QMainWindow void openGameVideoConfWin(void); void openHotkeyConfWin(void); void toggleAutoResume(void); + void toggleFullscreen(void); void updatePeriodic(void); }; From 0d8c442b35767ab9661af59d1e84e7907ace1d5f Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Thu, 9 Jul 2020 21:00:04 -0400 Subject: [PATCH 064/100] Added a few state load menu items. --- src/drivers/Qt/ConsoleWindow.cpp | 214 ++++++++++++++++++++++++++++++- src/drivers/Qt/ConsoleWindow.h | 10 ++ 2 files changed, 218 insertions(+), 6 deletions(-) diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index db4d8d7e..32cc2235 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -122,6 +122,50 @@ void consoleWin_t::createMainMenu(void) fileMenu->addAction(closeROM); + fileMenu->addSeparator(); + + // File -> Play NSF + playNSF = new QAction(tr("Play NSF"), this); + playNSF->setShortcut( QKeySequence(tr("Ctrl+N"))); + playNSF->setStatusTip(tr("Play NSF")); + connect(playNSF, SIGNAL(triggered()), this, SLOT(loadNSF(void)) ); + + fileMenu->addAction(playNSF); + + fileMenu->addSeparator(); + + // File -> Load State From + loadStateAct = new QAction(tr("Load State From"), this); + //loadStateAct->setShortcut( QKeySequence(tr("Ctrl+N"))); + loadStateAct->setStatusTip(tr("Load State From")); + connect(loadStateAct, SIGNAL(triggered()), this, SLOT(loadStateFrom(void)) ); + + fileMenu->addAction(loadStateAct); + + // File -> Save State As + saveStateAct = new QAction(tr("Save State As"), this); + //loadStateAct->setShortcut( QKeySequence(tr("Ctrl+N"))); + saveStateAct->setStatusTip(tr("Save State As")); + connect(saveStateAct, SIGNAL(triggered()), this, SLOT(saveStateAs(void)) ); + + fileMenu->addAction(saveStateAct); + + // File -> Quick Load + quickLoadAct = new QAction(tr("Quick Load"), this); + quickLoadAct->setShortcut( QKeySequence(tr("F7"))); + quickLoadAct->setStatusTip(tr("Quick Load")); + connect(quickLoadAct, SIGNAL(triggered()), this, SLOT(quickLoad(void)) ); + + fileMenu->addAction(quickLoadAct); + + // File -> Quick Save + quickSaveAct = new QAction(tr("Quick Save"), this); + quickSaveAct->setShortcut( QKeySequence(tr("F5"))); + quickSaveAct->setStatusTip(tr("Quick Save")); + connect(quickSaveAct, SIGNAL(triggered()), this, SLOT(quickSave(void)) ); + + fileMenu->addAction(quickSaveAct); + fileMenu->addSeparator(); // File -> Quit @@ -222,14 +266,19 @@ void consoleWin_t::openROMFile(void) { int ret; QString filename; + std::string last; QFileDialog dialog(this, tr("Open ROM File") ); dialog.setFileMode(QFileDialog::ExistingFile); - dialog.setNameFilter(tr("All files (*.*) ;; NES files (*.nes)")); + dialog.setNameFilter(tr("NES files (*.nes)(*.NES) ;; All files (*)")); dialog.setViewMode(QFileDialog::List); + g_config->getOption ("SDL.LastOpenFile", &last ); + + dialog.setDirectory( tr(last.c_str()) ); + // the gnome default file dialog is not playing nice with QT. // TODO make this a config option to use native file dialog. dialog.setOption(QFileDialog::DontUseNativeDialog, true); @@ -248,11 +297,6 @@ void consoleWin_t::openROMFile(void) } } - //filename = QFileDialog::getOpenFileName( this, - // "Open ROM File", - // QDir::currentPath(), - // "All files (*.*) ;; NES files (*.nes)"); - if ( filename.isNull() ) { return; @@ -276,6 +320,164 @@ void consoleWin_t::closeROMCB(void) fceuWrapperUnLock(); } +void consoleWin_t::loadNSF(void) +{ + int ret; + QString filename; + std::string last; + QFileDialog dialog(this, tr("Load NSF File") ); + + dialog.setFileMode(QFileDialog::ExistingFile); + + dialog.setNameFilter(tr("NSF Sound Files (*.nsf)(*.NSF) ;; Zip Files (*.zip)(*.ZIP) ;; All files (*)")); + + dialog.setViewMode(QFileDialog::List); + + g_config->getOption ("SDL.LastOpenNSF", &last ); + + dialog.setDirectory( tr(last.c_str()) ); + + // the gnome default file dialog is not playing nice with QT. + // TODO make this a config option to use native file dialog. + dialog.setOption(QFileDialog::DontUseNativeDialog, true); + + dialog.show(); + ret = dialog.exec(); + + if ( ret ) + { + QStringList fileList; + fileList = dialog.selectedFiles(); + + if ( fileList.size() > 0 ) + { + filename = fileList[0]; + } + } + + if ( filename.isNull() ) + { + return; + } + qDebug() << "selected file path : " << filename.toUtf8(); + + g_config->setOption ("SDL.LastOpenNSF", filename.toStdString().c_str() ); + + fceuWrapperLock(); + LoadGame( filename.toStdString().c_str() ); + fceuWrapperUnLock(); +} + +void consoleWin_t::loadStateFrom(void) +{ + int ret; + QString filename; + std::string last; + QFileDialog dialog(this, tr("Load State From File") ); + + dialog.setFileMode(QFileDialog::ExistingFile); + + dialog.setNameFilter(tr("FCS Files (*.fc?)(*.FC?) ;; SAV Files (*.sav)(*.SAV) ;; All files (*)")); + + dialog.setViewMode(QFileDialog::List); + + g_config->getOption ("SDL.LastLoadStateFrom", &last ); + + dialog.setDirectory( tr(last.c_str()) ); + + // the gnome default file dialog is not playing nice with QT. + // TODO make this a config option to use native file dialog. + dialog.setOption(QFileDialog::DontUseNativeDialog, true); + + dialog.show(); + ret = dialog.exec(); + + if ( ret ) + { + QStringList fileList; + fileList = dialog.selectedFiles(); + + if ( fileList.size() > 0 ) + { + filename = fileList[0]; + } + } + + if ( filename.isNull() ) + { + return; + } + qDebug() << "selected file path : " << filename.toUtf8(); + + g_config->setOption ("SDL.LastLoadStateFrom", filename.toStdString().c_str() ); + + fceuWrapperLock(); + FCEUI_LoadState( filename.toStdString().c_str() ); + fceuWrapperUnLock(); +} + +void consoleWin_t::saveStateAs(void) +{ + int ret; + QString filename; + std::string last; + QFileDialog dialog(this, tr("Save State To File") ); + + dialog.setFileMode(QFileDialog::AnyFile); + + dialog.setNameFilter(tr("FCS Files (*.fc?)(*.FC?) ;; SAV Files (*.sav)(*.SAV) ;; All files (*)")); + + dialog.setViewMode(QFileDialog::List); + + g_config->getOption ("SDL.LastSaveStateAs", &last ); + + dialog.setDirectory( tr(last.c_str()) ); + + // the gnome default file dialog is not playing nice with QT. + // TODO make this a config option to use native file dialog. + dialog.setOption(QFileDialog::DontUseNativeDialog, true); + + dialog.show(); + ret = dialog.exec(); + + if ( ret ) + { + QStringList fileList; + fileList = dialog.selectedFiles(); + + if ( fileList.size() > 0 ) + { + filename = fileList[0]; + } + } + + if ( filename.isNull() ) + { + return; + } + qDebug() << "selected file path : " << filename.toUtf8(); + + g_config->setOption ("SDL.LastSaveStateAs", filename.toStdString().c_str() ); + + fceuWrapperLock(); + FCEUI_SaveState( filename.toStdString().c_str() ); + fceuWrapperUnLock(); +} + +void consoleWin_t::quickLoad(void) +{ + fceuWrapperLock(); + FCEUI_LoadState( NULL ); + fceuWrapperUnLock(); +} + +void consoleWin_t::quickSave(void) +{ + fceuWrapperLock(); + FCEUI_SaveState( NULL ); + fceuWrapperUnLock(); +} + void consoleWin_t::openGamePadConfWin(void) { if ( gamePadConfWin != NULL ) diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index 205f09c0..0ce074d9 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -53,6 +53,11 @@ class consoleWin_t : public QMainWindow QAction *openROM; QAction *closeROM; + QAction *playNSF; + QAction *loadStateAct; + QAction *saveStateAct; + QAction *quickLoadAct; + QAction *quickSaveAct; QAction *quitAct; QAction *gamePadConfig; QAction *gameSoundConfig; @@ -78,6 +83,11 @@ class consoleWin_t : public QMainWindow private slots: void closeApp(void); void openROMFile(void); + void loadNSF(void); + void loadStateFrom(void); + void saveStateAs(void); + void quickLoad(void); + void quickSave(void); void closeROMCB(void); void aboutQPlot(void); void openGamePadConfWin(void); From 67b7c3457601c48886008be8a36b5ac3cae8908f Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Thu, 9 Jul 2020 21:33:53 -0400 Subject: [PATCH 065/100] Added change state select menu radio button logic. --- src/drivers/Qt/ConsoleWindow.cpp | 104 +++++++++++++++++++++++++++++++ src/drivers/Qt/ConsoleWindow.h | 11 ++++ 2 files changed, 115 insertions(+) diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index 32cc2235..30ca0b7f 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -99,6 +99,9 @@ void consoleWin_t::keyReleaseEvent(QKeyEvent *event) //--------------------------------------------------------------------------- void consoleWin_t::createMainMenu(void) { + QMenu *subMenu; + QActionGroup *group; + // This is needed for menu bar to show up on MacOS menuBar()->setNativeMenuBar(false); @@ -166,6 +169,37 @@ void consoleWin_t::createMainMenu(void) fileMenu->addAction(quickSaveAct); + // File -> Change State + subMenu = fileMenu->addMenu(tr("Change State")); + group = new QActionGroup(this); + + group->setExclusive(true); + + for (int i=0; i<10; i++) + { + char stmp[8]; + + sprintf( stmp, "%i", i ); + + state[i] = new QAction(tr(stmp)); + state[i]->setCheckable(true); + + group->addAction(state[i]); + subMenu->addAction(state[i]); + } + state[0]->setChecked(true); + + connect(state[0], SIGNAL(triggered()), this, SLOT(changeState0(void)) ); + connect(state[1], SIGNAL(triggered()), this, SLOT(changeState1(void)) ); + connect(state[2], SIGNAL(triggered()), this, SLOT(changeState2(void)) ); + connect(state[3], SIGNAL(triggered()), this, SLOT(changeState3(void)) ); + connect(state[4], SIGNAL(triggered()), this, SLOT(changeState4(void)) ); + connect(state[5], SIGNAL(triggered()), this, SLOT(changeState5(void)) ); + connect(state[6], SIGNAL(triggered()), this, SLOT(changeState6(void)) ); + connect(state[7], SIGNAL(triggered()), this, SLOT(changeState7(void)) ); + connect(state[8], SIGNAL(triggered()), this, SLOT(changeState8(void)) ); + connect(state[9], SIGNAL(triggered()), this, SLOT(changeState9(void)) ); + fileMenu->addSeparator(); // File -> Quit @@ -478,6 +512,76 @@ void consoleWin_t::quickSave(void) fceuWrapperUnLock(); } +void consoleWin_t::changeState0(void) +{ + fceuWrapperLock(); + FCEUI_SelectState( 0, 1 ); + fceuWrapperUnLock(); +} + +void consoleWin_t::changeState1(void) +{ + fceuWrapperLock(); + FCEUI_SelectState( 1, 1 ); + fceuWrapperUnLock(); +} + +void consoleWin_t::changeState2(void) +{ + fceuWrapperLock(); + FCEUI_SelectState( 2, 1 ); + fceuWrapperUnLock(); +} + +void consoleWin_t::changeState3(void) +{ + fceuWrapperLock(); + FCEUI_SelectState( 3, 1 ); + fceuWrapperUnLock(); +} + +void consoleWin_t::changeState4(void) +{ + fceuWrapperLock(); + FCEUI_SelectState( 4, 1 ); + fceuWrapperUnLock(); +} + +void consoleWin_t::changeState5(void) +{ + fceuWrapperLock(); + FCEUI_SelectState( 5, 1 ); + fceuWrapperUnLock(); +} + +void consoleWin_t::changeState6(void) +{ + fceuWrapperLock(); + FCEUI_SelectState( 6, 1 ); + fceuWrapperUnLock(); +} + +void consoleWin_t::changeState7(void) +{ + fceuWrapperLock(); + FCEUI_SelectState( 7, 1 ); + fceuWrapperUnLock(); +} + +void consoleWin_t::changeState8(void) +{ + fceuWrapperLock(); + FCEUI_SelectState( 8, 1 ); + fceuWrapperUnLock(); +} + +void consoleWin_t::changeState9(void) +{ + fceuWrapperLock(); + FCEUI_SelectState( 9, 1 ); + fceuWrapperUnLock(); +} + void consoleWin_t::openGamePadConfWin(void) { if ( gamePadConfWin != NULL ) diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index 0ce074d9..16612467 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -66,6 +66,7 @@ class consoleWin_t : public QMainWindow QAction *autoResume; QAction *fullscreen; QAction *aboutAct; + QAction *state[10]; QTimer *gameTimer; emulatorThread_t *emulatorThread; @@ -97,6 +98,16 @@ class consoleWin_t : public QMainWindow void toggleAutoResume(void); void toggleFullscreen(void); void updatePeriodic(void); + void changeState0(void); + void changeState1(void); + void changeState2(void); + void changeState3(void); + void changeState4(void); + void changeState5(void); + void changeState6(void); + void changeState7(void); + void changeState8(void); + void changeState9(void); }; From 26e320b163542e9b942b756a1debf6113db20242 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Thu, 9 Jul 2020 21:38:31 -0400 Subject: [PATCH 066/100] Bug fix for small memory leak on window init. --- src/drivers/Qt/ConsoleWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index 30ca0b7f..487e6b31 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -181,7 +181,7 @@ void consoleWin_t::createMainMenu(void) sprintf( stmp, "%i", i ); - state[i] = new QAction(tr(stmp)); + state[i] = new QAction(tr(stmp), this); state[i]->setCheckable(true); group->addAction(state[i]); From 1206fcebbddd346acda5719d0fb21d52fa8bf2a3 Mon Sep 17 00:00:00 2001 From: mjbudd77 Date: Fri, 10 Jul 2020 10:59:07 -0400 Subject: [PATCH 067/100] Successful build of QT gui using cmake instead of qmake. --- CMakeLists.txt | 2 +- src/CMakeLists.txt | 75 ++++++++++++++++--------------- src/drivers/Qt/ConsoleWindow.cpp | 77 ++++++++++++++++++++++++++++++++ src/drivers/Qt/ConsoleWindow.h | 2 + 4 files changed, 119 insertions(+), 37 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1cbc07cf..fe75fad4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.1) project(fceux) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c1a07e18..d7c4f21c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,8 @@ +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + if(WIN32) set(SOURCES ${SRC_CORE} ${SRC_DRIVERS_COMMON} ${SRC_DRIVERS_WIN}) include_directories( ${CMAKE_SOURCE_DIR}/src/drivers/win/directx ${CMAKE_SOURCE_DIR}/src/drivers/win/zlib ) @@ -15,28 +19,13 @@ else(WIN32) # Non Windows System # Use the package PkgConfig to detect headers/library files find_package(PkgConfig REQUIRED) + find_package(Qt5 COMPONENTS Widgets OpenGL REQUIRED) - # Check for GTK+3 - pkg_check_modules(GTK3 REQUIRED gtk+-3.0) + add_definitions( ${Qt5Widgets_DEFINITIONS} ) + include_directories( ${Qt5Widgets_INCLUDE_DIRS} ) - if ( ${GTK3_FOUND} ) - add_definitions( -D_GTK ${GTK3_CFLAGS} ) - endif() + add_definitions( -D__QT_DRIVER__ -Wall -Wno-write-strings -Wno-sign-compare -Wno-parentheses -Wno-unused-local-typedefs -fPIC -DQT_DEPRECATED_WARNINGS ) - # Check for X11 - pkg_check_modules( X11 x11 ) - - if ( ${X11_FOUND} ) - add_definitions( ${X11_CFLAGS} ) - endif() - - # Check for OpenGL - pkg_check_modules( GL REQUIRED gl) - - if ( ${GL_FOUND} ) - add_definitions( -DOPENGL ${GL_CFLAGS} ) - endif() - # Check for libminizip pkg_check_modules( MINIZIP REQUIRED minizip) @@ -44,6 +33,13 @@ else(WIN32) add_definitions( -D_SYSTEM_MINIZIP ${MINIZIP_CFLAGS} ) endif() + pkg_check_modules( GL REQUIRED gl) + + # Check for OpenGL + if ( ${GL_FOUND} ) + add_definitions( ${GL_CFLAGS} ) + endif() + pkg_check_modules( ZLIB REQUIRED zlib) # Check for zlib @@ -72,6 +68,9 @@ else(WIN32) endif(WIN32) +include_directories( ${CMAKE_SOURCE_DIR}/src ) +include_directories( ${CMAKE_SOURCE_DIR}/src/drivers ) + if(APPLE) add_definitions( -DPSS_STYLE=4 ) else(APPLE) @@ -323,20 +322,24 @@ set(SRC_DRIVERS_COMMON ) set(SRC_DRIVERS_SDL - ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/config.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/input.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/gui.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/cheat.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/debugger.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/memview.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/ramwatch.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/sdl.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/sdl-joystick.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/sdl-sound.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/sdl-throttle.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/sdl-video.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/glxwin.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/unix-netplay.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/main.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleWindow.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleViewerGL.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleViewerSDL.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/GamePadConf.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/HotKeyConf.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleVideoConf.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleSoundConf.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/fceuWrapper.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/config.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/input.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/nes_shm.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/keyscan.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/sdl-sound.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/sdl-video.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/sdl-joystick.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/sdl-throttle.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/unix-netplay.cpp ) set(SOURCES ${SRC_CORE} ${SRC_DRIVERS_COMMON} ${SRC_DRIVERS_SDL}) @@ -344,9 +347,9 @@ set(SOURCES ${SRC_CORE} ${SRC_DRIVERS_COMMON} ${SRC_DRIVERS_SDL}) add_executable( fceux ${SOURCES} ) target_link_libraries( fceux - ${GTK3_LDFLAGS} - ${X11_LDFLAGS} - ${GL_LDFLAGS} + ${Qt5Widgets_LIBRARIES} + ${Qt5OpenGL_LIBRARIES} + ${GL_LDFLAGS} ${SDL2_LDFLAGS} ${MINIZIP_LDFLAGS} ${ZLIB_LDFLAGS} ${LUA_LDFLAGS} diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index 487e6b31..38626b02 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -3,6 +3,11 @@ #include #include "../../fceu.h" + +#ifdef _S9XLUA_H +#include "../../fceulua.h" +#endif + #include "Qt/main.h" #include "Qt/dface.h" #include "Qt/input.h" @@ -202,6 +207,20 @@ void consoleWin_t::createMainMenu(void) fileMenu->addSeparator(); +#ifdef _S9XLUA_H + // File -> Quick Save + loadLuaAct = new QAction(tr("Load Lua Script"), this); + //loadLuaAct->setShortcut( QKeySequence(tr("F5"))); + loadLuaAct->setStatusTip(tr("Load Lua Script")); + connect(loadLuaAct, SIGNAL(triggered()), this, SLOT(loadLua(void)) ); + + fileMenu->addAction(loadLuaAct); + + fileMenu->addSeparator(); +#else + loadLuaAct = NULL; +#endif + // File -> Quit quitAct = new QAction(tr("Quit"), this); quitAct->setShortcut( QKeySequence(tr("Ctrl+Q"))); @@ -582,6 +601,64 @@ void consoleWin_t::changeState9(void) fceuWrapperUnLock(); } +void consoleWin_t::loadLua(void) +{ +#ifdef _S9XLUA_H + int ret; + QString filename; + std::string last; + QFileDialog dialog(this, tr("Open LUA Script") ); + + dialog.setFileMode(QFileDialog::ExistingFile); + + dialog.setNameFilter(tr("LUA Scripts (*.lua)(*.LUA) ;; All files (*)")); + + dialog.setViewMode(QFileDialog::List); + + g_config->getOption ("SDL.LastLoadLua", &last ); + + if ( last.size() == 0 ) + { + last.assign( "/usr/share/fceux/luaScripts" ); + } + + dialog.setDirectory( tr(last.c_str()) ); + + // the gnome default file dialog is not playing nice with QT. + // TODO make this a config option to use native file dialog. + dialog.setOption(QFileDialog::DontUseNativeDialog, true); + + dialog.show(); + ret = dialog.exec(); + + if ( ret ) + { + QStringList fileList; + fileList = dialog.selectedFiles(); + + if ( fileList.size() > 0 ) + { + filename = fileList[0]; + } + } + + if ( filename.isNull() ) + { + return; + } + qDebug() << "selected file path : " << filename.toUtf8(); + + g_config->setOption ("SDL.LastLoadLua", filename.toStdString().c_str() ); + + fceuWrapperLock(); + if ( FCEU_LoadLuaCode( filename.toStdString().c_str() ) ) + { + printf("Error: Could not open the selected lua script: '%s'\n", filename.toStdString().c_str() ); + } + fceuWrapperUnLock(); +#endif +} + void consoleWin_t::openGamePadConfWin(void) { if ( gamePadConfWin != NULL ) diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index 16612467..b1e5b60a 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -58,6 +58,7 @@ class consoleWin_t : public QMainWindow QAction *saveStateAct; QAction *quickLoadAct; QAction *quickSaveAct; + QAction *loadLuaAct; QAction *quitAct; QAction *gamePadConfig; QAction *gameSoundConfig; @@ -108,6 +109,7 @@ class consoleWin_t : public QMainWindow void changeState7(void); void changeState8(void); void changeState9(void); + void loadLua(void); }; From 321ea729d40fcfe6149fff6f09385bda92ef58f6 Mon Sep 17 00:00:00 2001 From: mjbudd77 Date: Fri, 10 Jul 2020 11:22:10 -0400 Subject: [PATCH 068/100] Successful build of Qt GUI on MAC OSX using cmake. --- src/CMakeLists.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d7c4f21c..9c6dc104 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -33,7 +33,7 @@ else(WIN32) add_definitions( -D_SYSTEM_MINIZIP ${MINIZIP_CFLAGS} ) endif() - pkg_check_modules( GL REQUIRED gl) + pkg_check_modules( GL gl) # Check for OpenGL if ( ${GL_FOUND} ) @@ -64,7 +64,11 @@ else(WIN32) add_definitions( -DHAVE_ASPRINTF ) # What system wouldn't have this? - set( SYS_LIBS -lrt -lpthread ) + if(APPLE) + set( SYS_LIBS "-framework OpenGL" ) + else() + set( SYS_LIBS -lrt -lpthread ) + endif() endif(WIN32) From cb453fa194f529fed4e98ae3fe795b51dada6105 Mon Sep 17 00:00:00 2001 From: mjbudd77 Date: Fri, 10 Jul 2020 13:51:32 -0400 Subject: [PATCH 069/100] Moved linux pipeline to cmake instead of qmake. --- fceux.pro | 57 +++++++++++++++++++++++++++++--- pipelines/linux_build.sh | 42 +++++++++++------------ src/CMakeLists.txt | 50 +++++++++++++++++++++++++++- src/drivers/Qt/ConsoleWindow.cpp | 2 +- 4 files changed, 123 insertions(+), 28 deletions(-) diff --git a/fceux.pro b/fceux.pro index 847e814f..fec9f599 100644 --- a/fceux.pro +++ b/fceux.pro @@ -21,7 +21,10 @@ QT += widgets CONFIG += object_parallel_to_source -INCLUDEPATH = src src/drivers +INCLUDEPATH += src src/drivers + +ENABLE_LUA = 0 +USE_INTERNAL_LUA = 0 unix { QT_CONFIG -= no-pkg-config @@ -42,8 +45,13 @@ unix { packagesExist(lua-5.1){ PKGCONFIG += lua-5.1 + USE_INTERNAL_LUA = 0; + QMAKE_CXXFLAGS += -D_S9XLUA_H + } else { + USE_INTERNAL_LUA = 1; QMAKE_CXXFLAGS += -D_S9XLUA_H } + ENABLE_LUA = 1 QMAKE_CXXFLAGS -= -O2 QMAKE_CXXFLAGS += -D__QT_DRIVER__ -O0 -g3 -Wall -Wno-write-strings -Wno-sign-compare -Wno-parentheses -Wno-unused-local-typedefs @@ -81,11 +89,50 @@ SOURCES += src/vsuni.cpp SOURCES += src/wave.cpp SOURCES += src/x6502.cpp -unix { - packagesExist(lua-5.1){ - SOURCES += src/lua-engine.cpp - } +isEqual( ENABLE_LUA, 1 ) { + isEqual( USE_INTERNAL_LUA, 1 ) { + message("Enabling Internal LUA") + INCLUDEPATH += src/lua/src + SOURCES += src/lua/src/lapi.c + SOURCES += src/lua/src/lauxlib.c + SOURCES += src/lua/src/lbaselib.c + SOURCES += src/lua/src/lcode.c + SOURCES += src/lua/src/ldblib.c + SOURCES += src/lua/src/ldebug.c + SOURCES += src/lua/src/ldo.c + SOURCES += src/lua/src/ldump.c + SOURCES += src/lua/src/lfunc.c + SOURCES += src/lua/src/lgc.c + SOURCES += src/lua/src/linit.c + SOURCES += src/lua/src/liolib.c + SOURCES += src/lua/src/llex.c + SOURCES += src/lua/src/lmathlib.c + SOURCES += src/lua/src/lmem.c + SOURCES += src/lua/src/loadlib.c + SOURCES += src/lua/src/lobject.c + SOURCES += src/lua/src/lopcodes.c + SOURCES += src/lua/src/loslib.c + SOURCES += src/lua/src/lparser.c + SOURCES += src/lua/src/lstate.c + SOURCES += src/lua/src/lstring.c + SOURCES += src/lua/src/lstrlib.c + SOURCES += src/lua/src/ltable.c + SOURCES += src/lua/src/ltablib.c + SOURCES += src/lua/src/ltm.c + SOURCES += src/lua/src/lundump.c + SOURCES += src/lua/src/lvm.c + SOURCES += src/lua/src/lzio.c + SOURCES += src/lua/src/print.c + SOURCES += src/lua-engine.cpp + } else { + message("Enabling System LUA") + SOURCES += src/lua-engine.cpp + } + message("Enabling LUA") +} else { + message("Disabling LUA") } + SOURCES += src/boards/01-222.cpp SOURCES += src/boards/09-034a.cpp SOURCES += src/boards/103.cpp diff --git a/pipelines/linux_build.sh b/pipelines/linux_build.sh index e7347a43..1ad6d8ce 100755 --- a/pipelines/linux_build.sh +++ b/pipelines/linux_build.sh @@ -92,30 +92,30 @@ mkdir -p $INSTALL_PREFIX/usr; #scons GTK3=1 SYSTEM_LUA=1 SYSTEM_MINIZIP=1 CREATE_AVI=1 install --prefix=$INSTALL_PREFIX/usr echo "Num CPU: `nproc`"; mkdir build; cd build; -qmake PREFIX=$INSTALL_PREFIX/usr .. -#cmake \ -# -DCMAKE_BUILD_TYPE=Release \ -# -DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX/usr \ -# -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ -# .. +#qmake PREFIX=$INSTALL_PREFIX/usr .. +cmake \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX/usr \ + -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ + .. make -j `nproc` -#make install +make install # Install Files -cd .. # cd out of build -mkdir -p $INSTALL_PREFIX/usr/bin/. -mkdir -p $INSTALL_PREFIX/usr/share/fceux -mkdir -p $INSTALL_PREFIX/usr/share/pixmaps -mkdir -p $INSTALL_PREFIX/usr/share/applications -mkdir -p $INSTALL_PREFIX/usr/man/man6 - -cp -f ./build/fceux $INSTALL_PREFIX/usr/bin/. -cp -a ./output/* $INSTALL_PREFIX/usr/share/fceux/. -cp -a ./src/auxlib.lua $INSTALL_PREFIX/usr/share/fceux/. -cp -a ./fceux.png $INSTALL_PREFIX/usr/share/pixmaps/. -cp -a ./fceux.desktop $INSTALL_PREFIX/usr/share/applications/. -cp -a ./documentation/fceux.6 $INSTALL_PREFIX/usr/man/man6/. -cp -a ./documentation/fceux-net-server.6 $INSTALL_PREFIX/usr/man/man6/. +#cd .. # cd out of build +#mkdir -p $INSTALL_PREFIX/usr/bin/. +#mkdir -p $INSTALL_PREFIX/usr/share/fceux +#mkdir -p $INSTALL_PREFIX/usr/share/pixmaps +#mkdir -p $INSTALL_PREFIX/usr/share/applications +#mkdir -p $INSTALL_PREFIX/usr/man/man6 +# +#cp -f ./build/fceux $INSTALL_PREFIX/usr/bin/. +#cp -a ./output/* $INSTALL_PREFIX/usr/share/fceux/. +#cp -a ./src/auxlib.lua $INSTALL_PREFIX/usr/share/fceux/. +#cp -a ./fceux.png $INSTALL_PREFIX/usr/share/pixmaps/. +#cp -a ./fceux.desktop $INSTALL_PREFIX/usr/share/applications/. +#cp -a ./documentation/fceux.6 $INSTALL_PREFIX/usr/man/man6/. +#cp -a ./documentation/fceux-net-server.6 $INSTALL_PREFIX/usr/man/man6/. # Debug via ssh if necessary diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9c6dc104..b8dc9f52 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -58,8 +58,49 @@ else(WIN32) pkg_check_modules( LUA lua-5.1) if ( ${LUA_FOUND} ) + # Use System LUA add_definitions( -D_S9XLUA_H ${LUA_CFLAGS} ) - set( LUA_ENGINE_SOURCE lua-engine.cpp ) + + set( LUA_ENGINE_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/lua-engine.cpp ) + + else () + + # Use Internal LUA + add_definitions( -D_S9XLUA_H -I${CMAKE_CURRENT_SOURCE_DIR}/lua/src ) + + set( LUA_ENGINE_SOURCE + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/lapi.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/lauxlib.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/lbaselib.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/lcode.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/ldblib.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/ldebug.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/ldo.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/ldump.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/lfunc.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/lgc.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/linit.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/liolib.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/llex.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/lmathlib.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/lmem.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/loadlib.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/lobject.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/lopcodes.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/loslib.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/lparser.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/lstate.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/lstring.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/lstrlib.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/ltable.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/ltablib.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/ltm.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/lundump.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/lvm.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/lzio.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua/src/print.c + ${CMAKE_CURRENT_SOURCE_DIR}/lua-engine.cpp + ) endif() add_definitions( -DHAVE_ASPRINTF ) # What system wouldn't have this? @@ -362,3 +403,10 @@ target_link_libraries( fceux install( TARGETS fceux RUNTIME DESTINATION bin ) + +install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/auxlib.lua DESTINATION share/fceux/luaScripts ) +install( DIRECTORY ${CMAKE_SOURCE_DIR}/output/. DESTINATION share/fceux ) +install( FILES ${CMAKE_SOURCE_DIR}/fceux.png DESTINATION share/pixmaps ) +install( FILES ${CMAKE_SOURCE_DIR}/fceux.desktop DESTINATION share/applications ) +install( FILES ${CMAKE_SOURCE_DIR}/documentation/fceux.6 DESTINATION share/man/man6 ) +install( FILES ${CMAKE_SOURCE_DIR}/documentation/fceux-net-server.6 DESTINATION share/man/man6 ) diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index 38626b02..b777cc57 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -651,7 +651,7 @@ void consoleWin_t::loadLua(void) g_config->setOption ("SDL.LastLoadLua", filename.toStdString().c_str() ); fceuWrapperLock(); - if ( FCEU_LoadLuaCode( filename.toStdString().c_str() ) ) + if ( 0 == FCEU_LoadLuaCode( filename.toStdString().c_str() ) ) { printf("Error: Could not open the selected lua script: '%s'\n", filename.toStdString().c_str() ); } From 9b0fb8efe49db72adbba68b341965a8a579990dd Mon Sep 17 00:00:00 2001 From: mjbudd77 Date: Fri, 10 Jul 2020 14:09:33 -0400 Subject: [PATCH 070/100] Moved MAC OSX build to cmake instead of qmake. --- pipelines/macOS_build.sh | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/pipelines/macOS_build.sh b/pipelines/macOS_build.sh index 32e70a83..75245b31 100755 --- a/pipelines/macOS_build.sh +++ b/pipelines/macOS_build.sh @@ -8,6 +8,8 @@ sw_vers SCRIPT_DIR=$( cd $(dirname $BASH_SOURCE[0]); pwd ); +INSTALL_PREFIX=/tmp/fceux + gcc --version echo '****************************************' @@ -34,15 +36,25 @@ brew install minizip export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig: -QMAKE=`find /usr/local -name qmake`; +#QMAKE=`find /usr/local -name qmake`; +QT_CMAKE=`find /usr/local -name Qt5Config.cmake` +echo $QT_CMAKE; +export Qt5_DIR=`dirname $QT_CMAKE`; +echo "Qt5_DIR=$Qt5_DIR"; echo '**************************' echo '*** Building Project ***' echo '**************************' mkdir build; cd build; -$QMAKE .. -make +#$QMAKE .. +cmake \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX/usr \ + -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ + .. +make +make install # Debug via ssh if necessary if [ ! -z $APPVEYOR_SSH_BLOCK ]; then From cc4ce1978404eadca068df3f942f391cf5eddef0 Mon Sep 17 00:00:00 2001 From: mjbudd77 Date: Fri, 10 Jul 2020 14:48:46 -0400 Subject: [PATCH 071/100] A few build fixes for the mac os with cmake. --- pipelines/macOS_build.sh | 6 +++--- src/CMakeLists.txt | 20 ++++++++++++-------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/pipelines/macOS_build.sh b/pipelines/macOS_build.sh index 75245b31..fd029993 100755 --- a/pipelines/macOS_build.sh +++ b/pipelines/macOS_build.sh @@ -52,9 +52,9 @@ cmake \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX/usr \ -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ - .. -make -make install + .. || exit 1 +make || exit 1 +make install || exit 1 # Debug via ssh if necessary if [ ! -z $APPVEYOR_SSH_BLOCK ]; then diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b8dc9f52..186ad2d1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,6 +20,8 @@ else(WIN32) # Use the package PkgConfig to detect headers/library files find_package(PkgConfig REQUIRED) find_package(Qt5 COMPONENTS Widgets OpenGL REQUIRED) + find_package(OpenGL REQUIRED) + find_package(zlib REQUIRED) add_definitions( ${Qt5Widgets_DEFINITIONS} ) include_directories( ${Qt5Widgets_INCLUDE_DIRS} ) @@ -33,18 +35,19 @@ else(WIN32) add_definitions( -D_SYSTEM_MINIZIP ${MINIZIP_CFLAGS} ) endif() - pkg_check_modules( GL gl) + #pkg_check_modules( GL gl) # Use built in find package instead for OpenGL # Check for OpenGL - if ( ${GL_FOUND} ) - add_definitions( ${GL_CFLAGS} ) + if ( ${OPENGL_FOUND} ) + include_directories( ${OPENGL_INCLUDE_DIR} ) endif() - pkg_check_modules( ZLIB REQUIRED zlib) + #pkg_check_modules( ZLIB REQUIRED zlib) # Use built in find package instead for zlib # Check for zlib if ( ${ZLIB_FOUND} ) - add_definitions( ${ZLIB_CFLAGS} ) + #add_definitions( ${ZLIB_CFLAGS} ) + include_directories( ${ZLIB_INCLUDE_DIRS} ) endif() # Check for SDL2 @@ -106,8 +109,9 @@ else(WIN32) add_definitions( -DHAVE_ASPRINTF ) # What system wouldn't have this? if(APPLE) - set( SYS_LIBS "-framework OpenGL" ) + set( OPENGL_LDFLAGS "-framework OpenGL" ) else() + set( OPENGL_LDFLAGS ${OPENGL_LIBRARIES} ) set( SYS_LIBS -lrt -lpthread ) endif() @@ -394,9 +398,9 @@ add_executable( fceux ${SOURCES} ) target_link_libraries( fceux ${Qt5Widgets_LIBRARIES} ${Qt5OpenGL_LIBRARIES} - ${GL_LDFLAGS} + ${OPENGL_LDFLAGS} ${SDL2_LDFLAGS} - ${MINIZIP_LDFLAGS} ${ZLIB_LDFLAGS} + ${MINIZIP_LDFLAGS} ${ZLIB_LIBRARIES} ${LUA_LDFLAGS} ${SYS_LIBS} ) From 69a761a47784195b28dd0b70e7a340f9e2bd53f7 Mon Sep 17 00:00:00 2001 From: mjbudd77 Date: Fri, 10 Jul 2020 14:57:55 -0400 Subject: [PATCH 072/100] More Cmake fixes between linux and mac os --- pipelines/linux_build.sh | 1 + pipelines/macOS_build.sh | 5 ++++- src/CMakeLists.txt | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pipelines/linux_build.sh b/pipelines/linux_build.sh index 1ad6d8ce..8da0b4e4 100755 --- a/pipelines/linux_build.sh +++ b/pipelines/linux_build.sh @@ -55,6 +55,7 @@ pkg-config --cflags --libs minizip # GTK+-2 is no longer needed #sudo apt-get install libgtk2.0-dev +# GTK3 was retired in favor of cross platform QT ## Install GTK+-3 #echo '****************************************' #echo 'Install Dependency libgtk-3-dev' diff --git a/pipelines/macOS_build.sh b/pipelines/macOS_build.sh index fd029993..19a9fbd8 100755 --- a/pipelines/macOS_build.sh +++ b/pipelines/macOS_build.sh @@ -8,6 +8,9 @@ sw_vers SCRIPT_DIR=$( cd $(dirname $BASH_SOURCE[0]); pwd ); +NPROC=`getconf _NPROCESSORS_ONLN`; +echo "Number of Processors: $NPROC"; + INSTALL_PREFIX=/tmp/fceux gcc --version @@ -53,7 +56,7 @@ cmake \ -DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX/usr \ -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ .. || exit 1 -make || exit 1 +make -j $NPROC || exit 1 make install || exit 1 # Debug via ssh if necessary diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 186ad2d1..afb9a9a4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -21,7 +21,7 @@ else(WIN32) find_package(PkgConfig REQUIRED) find_package(Qt5 COMPONENTS Widgets OpenGL REQUIRED) find_package(OpenGL REQUIRED) - find_package(zlib REQUIRED) + find_package(ZLIB REQUIRED) add_definitions( ${Qt5Widgets_DEFINITIONS} ) include_directories( ${Qt5Widgets_INCLUDE_DIRS} ) From 0188c11e8b1c29bf559cc0be185c674bccb4190d Mon Sep 17 00:00:00 2001 From: mjbudd77 Date: Fri, 10 Jul 2020 15:08:05 -0400 Subject: [PATCH 073/100] Added OpenGL preference variable to cmake build file to get rid of nuisance warning. --- src/CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index afb9a9a4..13e66a35 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -17,7 +17,13 @@ if(WIN32) link_directories( ${CMAKE_SOURCE_DIR}/src/drivers/win/directx ) else(WIN32) # Non Windows System - # Use the package PkgConfig to detect headers/library files + # UNIX (Linux or Mac OSX) + + #set (OpenGL_GL_PREFERENCE GLVND) + set (OpenGL_GL_PREFERENCE LEGACY) + + # Use the built-in cmake find_package functions to find dependencies + # Use package PkgConfig to detect headers/library what find_package cannot find. find_package(PkgConfig REQUIRED) find_package(Qt5 COMPONENTS Widgets OpenGL REQUIRED) find_package(OpenGL REQUIRED) From b830e0aae5011e31a1e400fdb17558d5955fe32c Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 11 Jul 2020 10:29:03 -0400 Subject: [PATCH 074/100] Added screen shot menu function. --- src/drivers/Qt/ConsoleWindow.cpp | 15 +++++++++++++++ src/drivers/Qt/ConsoleWindow.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index b777cc57..1f67dc60 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -221,6 +221,14 @@ void consoleWin_t::createMainMenu(void) loadLuaAct = NULL; #endif + // File -> Screenshort + scrShotAct = new QAction(tr("Screenshot"), this); + scrShotAct->setShortcut( QKeySequence(tr("F12"))); + scrShotAct->setStatusTip(tr("Screenshot")); + connect(scrShotAct, SIGNAL(triggered()), this, SLOT(takeScreenShot())); + + fileMenu->addAction(scrShotAct); + // File -> Quit quitAct = new QAction(tr("Quit"), this); quitAct->setShortcut( QKeySequence(tr("Ctrl+Q"))); @@ -601,6 +609,13 @@ void consoleWin_t::changeState9(void) fceuWrapperUnLock(); } +void consoleWin_t::takeScreenShot(void) +{ + fceuWrapperLock(); + FCEUI_SaveSnapshot(); + fceuWrapperUnLock(); +} + void consoleWin_t::loadLua(void) { #ifdef _S9XLUA_H diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index b1e5b60a..25ef8146 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -59,6 +59,7 @@ class consoleWin_t : public QMainWindow QAction *quickLoadAct; QAction *quickSaveAct; QAction *loadLuaAct; + QAction *scrShotAct; QAction *quitAct; QAction *gamePadConfig; QAction *gameSoundConfig; @@ -110,6 +111,7 @@ class consoleWin_t : public QMainWindow void changeState8(void); void changeState9(void); void loadLua(void); + void takeScreenShot(void); }; From 74afb50949477dfc285fe96046f2dbc6aa7df9e7 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 11 Jul 2020 11:58:11 -0400 Subject: [PATCH 075/100] Added basic functions of emulation menu --- src/drivers/Qt/ConsoleWindow.cpp | 76 ++++++++++++++++++++++++++++++-- src/drivers/Qt/ConsoleWindow.h | 11 ++++- src/drivers/Qt/config.cpp | 3 -- src/drivers/Qt/fceuWrapper.cpp | 44 +++++++++++++++--- src/drivers/Qt/fceuWrapper.h | 3 ++ src/drivers/Qt/sdl-video.cpp | 26 ++--------- 6 files changed, 126 insertions(+), 37 deletions(-) diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index 1f67dc60..dfca073b 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -293,13 +293,49 @@ void consoleWin_t::createMainMenu(void) optMenu->addAction(fullscreen); + //----------------------------------------------------------------------- + // Emulation + emuMenu = menuBar()->addMenu(tr("Emulation")); + + // Emulation -> Power + powerAct = new QAction(tr("Power"), this); + //powerAct->setShortcut( QKeySequence(tr("Ctrl+P"))); + powerAct->setStatusTip(tr("Power On Console")); + connect(powerAct, SIGNAL(triggered()), this, SLOT(powerConsoleCB(void)) ); + + emuMenu->addAction(powerAct); + + // Emulation -> Reset + resetAct = new QAction(tr("Reset"), this); + //resetAct->setShortcut( QKeySequence(tr("Ctrl+R"))); + resetAct->setStatusTip(tr("Reset Console")); + connect(resetAct, SIGNAL(triggered()), this, SLOT(consoleHardReset(void)) ); + + emuMenu->addAction(resetAct); + + // Emulation -> Soft Reset + sresetAct = new QAction(tr("Soft Reset"), this); + //sresetAct->setShortcut( QKeySequence(tr("Ctrl+R"))); + sresetAct->setStatusTip(tr("Soft Reset of Console")); + connect(sresetAct, SIGNAL(triggered()), this, SLOT(consoleSoftReset(void)) ); + + emuMenu->addAction(sresetAct); + + // Emulation -> Pause + pauseAct = new QAction(tr("Pause"), this); + pauseAct->setShortcut( QKeySequence(tr("Pause"))); + pauseAct->setStatusTip(tr("Pause Console")); + connect(pauseAct, SIGNAL(triggered()), this, SLOT(consolePause(void)) ); + + emuMenu->addAction(pauseAct); + //----------------------------------------------------------------------- // Help helpMenu = menuBar()->addMenu(tr("Help")); aboutAct = new QAction(tr("About"), this); - aboutAct->setStatusTip(tr("About Qplot")); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(aboutQPlot(void)) ); + aboutAct->setStatusTip(tr("About FCEUX")); + connect(aboutAct, SIGNAL(triggered()), this, SLOT(aboutFCEUX(void)) ); helpMenu->addAction(aboutAct); }; @@ -761,9 +797,41 @@ void consoleWin_t::toggleFullscreen(void) } } -void consoleWin_t::aboutQPlot(void) +void consoleWin_t::powerConsoleCB(void) { - printf("About QPlot\n"); + fceuWrapperLock(); + FCEUI_PowerNES(); + fceuWrapperUnLock(); + return; +} + +void consoleWin_t::consoleHardReset(void) +{ + fceuWrapperLock(); + fceuWrapperHardReset(); + fceuWrapperUnLock(); + return; +} + +void consoleWin_t::consoleSoftReset(void) +{ + fceuWrapperLock(); + fceuWrapperSoftReset(); + fceuWrapperUnLock(); + return; +} + +void consoleWin_t::consolePause(void) +{ + fceuWrapperLock(); + fceuWrapperTogglePause(); + fceuWrapperUnLock(); + return; +} + +void consoleWin_t::aboutFCEUX(void) +{ + printf("About FCEUX\n"); return; } diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index 25ef8146..849caaee 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -49,6 +49,7 @@ class consoleWin_t : public QMainWindow protected: QMenu *fileMenu; QMenu *optMenu; + QMenu *emuMenu; QMenu *helpMenu; QAction *openROM; @@ -69,6 +70,10 @@ class consoleWin_t : public QMainWindow QAction *fullscreen; QAction *aboutAct; QAction *state[10]; + QAction *powerAct; + QAction *resetAct; + QAction *sresetAct; + QAction *pauseAct; QTimer *gameTimer; emulatorThread_t *emulatorThread; @@ -92,7 +97,7 @@ class consoleWin_t : public QMainWindow void quickLoad(void); void quickSave(void); void closeROMCB(void); - void aboutQPlot(void); + void aboutFCEUX(void); void openGamePadConfWin(void); void openGameSndConfWin(void); void openGameVideoConfWin(void); @@ -112,6 +117,10 @@ class consoleWin_t : public QMainWindow void changeState9(void); void loadLua(void); void takeScreenShot(void); + void powerConsoleCB(void); + void consoleHardReset(void); + void consoleSoftReset(void); + void consolePause(void); }; diff --git a/src/drivers/Qt/config.cpp b/src/drivers/Qt/config.cpp index 305439f0..5c16c617 100644 --- a/src/drivers/Qt/config.cpp +++ b/src/drivers/Qt/config.cpp @@ -285,8 +285,6 @@ InitConfig() //TODO implement this config->addOption("periodicsaves", "SDL.PeriodicSaves", 0); - - #ifdef _GTK char* home_dir = getenv("HOME"); // prefixed with _ because they are internal (not cli options) config->addOption("_lastopenfile", "SDL.LastOpenFile", home_dir); @@ -294,7 +292,6 @@ InitConfig() config->addOption("_lastopennsf", "SDL.LastOpenNSF", home_dir); config->addOption("_lastsavestateas", "SDL.LastSaveStateAs", home_dir); config->addOption("_lastloadlua", "SDL.LastLoadLua", ""); - #endif // fcm -> fm2 conversion config->addOption("fcmconvert", "SDL.FCMConvert", ""); diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp index f7698afa..7c360d3a 100644 --- a/src/drivers/Qt/fceuWrapper.cpp +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -278,6 +278,36 @@ CloseGame(void) return(1); } +int fceuWrapperSoftReset(void) +{ + if ( isloaded ) + { + ResetNES(); + } + return 0; +} + +int fceuWrapperHardReset(void) +{ + if ( isloaded ) + { + std::string lastFile; + CloseGame(); + g_config->getOption ("SDL.LastOpenFile", &lastFile); + LoadGame (lastFile.c_str()); + } + return 0; +} + +int fceuWrapperTogglePause(void) +{ + if ( isloaded ) + { + FCEUI_ToggleEmulationPause(); + } + return 0; +} + int fceuWrapperInit( int argc, char *argv[] ) { int error; @@ -745,7 +775,7 @@ static void DoFun(int frameskip, int periodic_saves) int32 *sound; int32 ssize; static int fskipc = 0; - static int opause = 0; + //static int opause = 0; //TODO peroidic saves, working on it right now if (periodic_saves && FCEUD_GetTime() % PERIODIC_SAVE_INTERVAL < 30){ @@ -762,11 +792,11 @@ static void DoFun(int frameskip, int periodic_saves) FCEUI_Emulate(&gfx, &sound, &ssize, fskipc); FCEUD_Update(gfx, sound, ssize); - if(opause!=FCEUI_EmulationPaused()) - { - opause=FCEUI_EmulationPaused(); - SilenceSound(opause); - } + //if(opause!=FCEUI_EmulationPaused()) + //{ + // opause=FCEUI_EmulationPaused(); + // SilenceSound(opause); + //} } void fceuWrapperLock(void) @@ -810,7 +840,7 @@ int fceuWrapperUpdate( void ) { fceuWrapperLock(); - if (GameInfo) + if ( GameInfo && !FCEUI_EmulationPaused() ) { DoFun(frameskip, periodic_saves); diff --git a/src/drivers/Qt/fceuWrapper.h b/src/drivers/Qt/fceuWrapper.h index 7cd6b70c..ac057025 100644 --- a/src/drivers/Qt/fceuWrapper.h +++ b/src/drivers/Qt/fceuWrapper.h @@ -29,4 +29,7 @@ void fceuWrapperLock(void); bool fceuWrapperTryLock(int timeout); bool fceuWrapperIsLocked(void); void fceuWrapperUnLock(void); +int fceuWrapperSoftReset(void); +int fceuWrapperHardReset(void); +int fceuWrapperTogglePause(void); diff --git a/src/drivers/Qt/sdl-video.cpp b/src/drivers/Qt/sdl-video.cpp index 79e6c393..003f8dcd 100644 --- a/src/drivers/Qt/sdl-video.cpp +++ b/src/drivers/Qt/sdl-video.cpp @@ -248,29 +248,11 @@ void ToggleFS(void) if(!paused) FCEUI_ToggleEmulationPause(); - int error, fullscreen = s_fullscreen; - - // shut down the current video system - KillVideo(); - // flip the fullscreen flag - g_config->setOption("SDL.Fullscreen", !fullscreen); -#ifdef _GTK - if(noGui == 0) - { - if(!fullscreen) - showGui(0); - else - showGui(1); - } -#endif - // try to initialize the video - error = InitVideo(GameInfo); - if(error) { - // if we fail, just continue with what worked before - g_config->setOption("SDL.Fullscreen", fullscreen); - InitVideo(GameInfo); - } + g_config->setOption("SDL.Fullscreen", !s_fullscreen); + + // TODO Call method to make full Screen + // if we paused to make the switch; unpause if(!paused) FCEUI_ToggleEmulationPause(); From c41cd863c6e7a78268960cbb5cd0c878a32187cf Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 11 Jul 2020 12:59:14 -0400 Subject: [PATCH 076/100] Added game genie enable menu logic. --- src/drivers/Qt/ConsoleWindow.cpp | 37 ++++++++++++++++++++++++++++++++ src/drivers/Qt/ConsoleWindow.h | 3 +++ src/drivers/Qt/fceuWrapper.cpp | 10 +++++++++ 3 files changed, 50 insertions(+) diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index dfca073b..e3b9bcc7 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -329,6 +329,19 @@ void consoleWin_t::createMainMenu(void) emuMenu->addAction(pauseAct); + emuMenu->addSeparator(); + + // Options -> Full Screen + gameGenieAct = new QAction(tr("Enable Game Genie"), this); + //gameGenieAct->setShortcut( QKeySequence(tr("Ctrl+G"))); + gameGenieAct->setCheckable(true); + gameGenieAct->setStatusTip(tr("Enable Game Genie")); + connect(gameGenieAct, SIGNAL(triggered(bool)), this, SLOT(toggleGameGenie(bool)) ); + + syncActionConfig( gameGenieAct, "SDL.GameGenie" ); + + emuMenu->addAction(gameGenieAct); + //----------------------------------------------------------------------- // Help helpMenu = menuBar()->addMenu(tr("Help")); @@ -829,12 +842,36 @@ void consoleWin_t::consolePause(void) return; } +void consoleWin_t::toggleGameGenie(bool checked) +{ + int gg_enabled; + + fceuWrapperLock(); + g_config->getOption ("SDL.GameGenie", &gg_enabled); + g_config->setOption ("SDL.GameGenie", !gg_enabled); + g_config->save (); + FCEUI_SetGameGenie (gg_enabled); + fceuWrapperUnLock(); + return; +} + void consoleWin_t::aboutFCEUX(void) { printf("About FCEUX\n"); return; } +void consoleWin_t::syncActionConfig( QAction *act, const char *property ) +{ + if ( act->isCheckable() ) + { + int enable; + g_config->getOption ( property, &enable); + + act->setChecked( enable ? true : false ); + } +} + void consoleWin_t::updatePeriodic(void) { //struct timespec ts; diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index 849caaee..a4b6bebb 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -74,6 +74,7 @@ class consoleWin_t : public QMainWindow QAction *resetAct; QAction *sresetAct; QAction *pauseAct; + QAction *gameGenieAct; QTimer *gameTimer; emulatorThread_t *emulatorThread; @@ -84,6 +85,7 @@ class consoleWin_t : public QMainWindow void closeEvent(QCloseEvent *event); void keyPressEvent(QKeyEvent *event); void keyReleaseEvent(QKeyEvent *event); + void syncActionConfig( QAction *act, const char *property ); private: void createMainMenu(void); @@ -121,6 +123,7 @@ class consoleWin_t : public QMainWindow void consoleHardReset(void); void consoleSoftReset(void); void consolePause(void); + void toggleGameGenie(bool checked); }; diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp index 7c360d3a..5c8943a5 100644 --- a/src/drivers/Qt/fceuWrapper.cpp +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -203,9 +203,19 @@ DriverKill() */ int LoadGame(const char *path) { + int gg_enabled; + if (isloaded){ CloseGame(); } + + // For some reason, the core of the emulator clears the state of + // the game genie option selection. So check the config each time + // and re-enable the core game genie state if needed. + g_config->getOption ("SDL.GameGenie", &gg_enabled); + + FCEUI_SetGameGenie (gg_enabled); + if(!FCEUI_LoadGame(path, 1)) { return 0; } From b4280ee33d96f9b3303a7f6f5f513309ef5fb463 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 11 Jul 2020 14:03:40 -0400 Subject: [PATCH 077/100] Added menu logic to load Game Genie ROM file --- src/drivers/Qt/ConsoleWindow.cpp | 68 +++++++++++++++++++++++++++++++- src/drivers/Qt/ConsoleWindow.h | 2 + 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index e3b9bcc7..8f69bdf6 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -1,5 +1,8 @@ // GameApp.cpp // +#include +#include +#include #include #include "../../fceu.h" @@ -331,7 +334,7 @@ void consoleWin_t::createMainMenu(void) emuMenu->addSeparator(); - // Options -> Full Screen + // Emulation -> Enable Game Genie gameGenieAct = new QAction(tr("Enable Game Genie"), this); //gameGenieAct->setShortcut( QKeySequence(tr("Ctrl+G"))); gameGenieAct->setCheckable(true); @@ -342,6 +345,16 @@ void consoleWin_t::createMainMenu(void) emuMenu->addAction(gameGenieAct); + // Emulation -> Load Game Genie ROM + loadGgROMAct = new QAction(tr("Load Game Genie ROM"), this); + //loadGgROMAct->setShortcut( QKeySequence(tr("Ctrl+G"))); + loadGgROMAct->setStatusTip(tr("Load Game Genie ROM")); + connect(loadGgROMAct, SIGNAL(triggered()), this, SLOT(loadGameGenieROM(void)) ); + + emuMenu->addAction(loadGgROMAct); + + emuMenu->addSeparator(); + //----------------------------------------------------------------------- // Help helpMenu = menuBar()->addMenu(tr("Help")); @@ -855,6 +868,59 @@ void consoleWin_t::toggleGameGenie(bool checked) return; } +void consoleWin_t::loadGameGenieROM(void) +{ + int ret; + QString filename; + std::string last; + QFileDialog dialog(this, tr("Open Game Genie ROM") ); + + dialog.setFileMode(QFileDialog::ExistingFile); + + dialog.setNameFilter(tr("GG ROM File (gg.rom)(*Genie*.nes) ;; All files (*)")); + + dialog.setViewMode(QFileDialog::List); + + g_config->getOption ("SDL.LastOpenFile", &last ); + + dialog.setDirectory( tr(last.c_str()) ); + + // the gnome default file dialog is not playing nice with QT. + // TODO make this a config option to use native file dialog. + dialog.setOption(QFileDialog::DontUseNativeDialog, true); + + dialog.show(); + ret = dialog.exec(); + + if ( ret ) + { + QStringList fileList; + fileList = dialog.selectedFiles(); + + if ( fileList.size() > 0 ) + { + filename = fileList[0]; + } + } + + if ( filename.isNull() ) + { + return; + } + qDebug() << "selected file path : " << filename.toUtf8(); + + g_config->setOption ("SDL.LastOpenFile", filename.toStdString().c_str() ); + + // copy file to proper place (~/.fceux/gg.rom) + std::ifstream f1 ( filename.toStdString().c_str(), std::fstream::binary); + std::string fn_out = FCEU_MakeFName (FCEUMKF_GGROM, 0, ""); + std::ofstream f2 (fn_out.c_str (), + std::fstream::trunc | std::fstream::binary); + f2 << f1.rdbuf (); + + return; +} + void consoleWin_t::aboutFCEUX(void) { printf("About FCEUX\n"); diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index a4b6bebb..032ec9af 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -75,6 +75,7 @@ class consoleWin_t : public QMainWindow QAction *sresetAct; QAction *pauseAct; QAction *gameGenieAct; + QAction *loadGgROMAct; QTimer *gameTimer; emulatorThread_t *emulatorThread; @@ -124,6 +125,7 @@ class consoleWin_t : public QMainWindow void consoleSoftReset(void); void consolePause(void); void toggleGameGenie(bool checked); + void loadGameGenieROM(void); }; From 6fcfb2af7a6d4621072431928c9b73010379dc41 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 11 Jul 2020 14:21:20 -0400 Subject: [PATCH 078/100] Added insert coin menu functionality. --- src/drivers/Qt/ConsoleWindow.cpp | 16 ++++++++++++++++ src/drivers/Qt/ConsoleWindow.h | 2 ++ 2 files changed, 18 insertions(+) diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index 8f69bdf6..bb729f34 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -355,6 +355,14 @@ void consoleWin_t::createMainMenu(void) emuMenu->addSeparator(); + // Emulation -> Insert Coin + insCoinAct = new QAction(tr("Insert Coin"), this); + //insCoinAct->setShortcut( QKeySequence(tr("Ctrl+G"))); + insCoinAct->setStatusTip(tr("Insert Coin")); + connect(insCoinAct, SIGNAL(triggered()), this, SLOT(insertCoin(void)) ); + + emuMenu->addAction(insCoinAct); + //----------------------------------------------------------------------- // Help helpMenu = menuBar()->addMenu(tr("Help")); @@ -921,6 +929,14 @@ void consoleWin_t::loadGameGenieROM(void) return; } +void consoleWin_t::insertCoin(void) +{ + fceuWrapperLock(); + FCEUI_VSUniCoin(); + fceuWrapperUnLock(); + return; +} + void consoleWin_t::aboutFCEUX(void) { printf("About FCEUX\n"); diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index 032ec9af..9239a096 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -76,6 +76,7 @@ class consoleWin_t : public QMainWindow QAction *pauseAct; QAction *gameGenieAct; QAction *loadGgROMAct; + QAction *insCoinAct; QTimer *gameTimer; emulatorThread_t *emulatorThread; @@ -126,6 +127,7 @@ class consoleWin_t : public QMainWindow void consolePause(void); void toggleGameGenie(bool checked); void loadGameGenieROM(void); + void insertCoin(void); }; From 210e04fe92395946e99cb29e5eb1cf9bad81b66c Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 11 Jul 2020 14:42:02 -0400 Subject: [PATCH 079/100] Added FDS menu functionality. --- src/drivers/Qt/ConsoleWindow.cpp | 107 +++++++++++++++++++++++++++++++ src/drivers/Qt/ConsoleWindow.h | 6 ++ 2 files changed, 113 insertions(+) diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index bb729f34..8661c404 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -6,6 +6,7 @@ #include #include "../../fceu.h" +#include "../../fds.h" #ifdef _S9XLUA_H #include "../../fceulua.h" @@ -363,6 +364,35 @@ void consoleWin_t::createMainMenu(void) emuMenu->addAction(insCoinAct); + emuMenu->addSeparator(); + + // Emulation -> FDS + subMenu = emuMenu->addMenu(tr("FDS")); + + // Emulation -> FDS -> Switch Disk + fdsSwitchAct = new QAction(tr("Switch Disk"), this); + //fdsSwitchAct->setShortcut( QKeySequence(tr("Ctrl+G"))); + fdsSwitchAct->setStatusTip(tr("Switch Disk")); + connect(fdsSwitchAct, SIGNAL(triggered()), this, SLOT(fdsSwitchDisk(void)) ); + + subMenu->addAction(fdsSwitchAct); + + // Emulation -> FDS -> Eject Disk + fdsEjectAct = new QAction(tr("Eject Disk"), this); + //fdsEjectAct->setShortcut( QKeySequence(tr("Ctrl+G"))); + fdsEjectAct->setStatusTip(tr("Eject Disk")); + connect(fdsEjectAct, SIGNAL(triggered()), this, SLOT(fdsEjectDisk(void)) ); + + subMenu->addAction(fdsEjectAct); + + // Emulation -> FDS -> Load BIOS + fdsLoadBiosAct = new QAction(tr("Load BIOS"), this); + //fdsLoadBiosAct->setShortcut( QKeySequence(tr("Ctrl+G"))); + fdsLoadBiosAct->setStatusTip(tr("Load BIOS")); + connect(fdsLoadBiosAct, SIGNAL(triggered()), this, SLOT(fdsLoadBiosFile(void)) ); + + subMenu->addAction(fdsLoadBiosAct); + //----------------------------------------------------------------------- // Help helpMenu = menuBar()->addMenu(tr("Help")); @@ -937,6 +967,83 @@ void consoleWin_t::insertCoin(void) return; } +void consoleWin_t::fdsSwitchDisk(void) +{ + fceuWrapperLock(); + FCEU_FDSSelect(); + fceuWrapperUnLock(); + return; +} + +void consoleWin_t::fdsEjectDisk(void) +{ + fceuWrapperLock(); + FCEU_FDSInsert(); + fceuWrapperUnLock(); + return; +} + +void consoleWin_t::fdsLoadBiosFile(void) +{ + int ret; + QString filename; + std::string last; + QFileDialog dialog(this, tr("Load FDS BIOS (disksys.rom)") ); + + dialog.setFileMode(QFileDialog::ExistingFile); + + dialog.setNameFilter(tr("ROM files (*.rom)(*.ROM) ;; All files (*)")); + + dialog.setViewMode(QFileDialog::List); + + g_config->getOption ("SDL.LastOpenFile", &last ); + + dialog.setDirectory( tr(last.c_str()) ); + + // the gnome default file dialog is not playing nice with QT. + // TODO make this a config option to use native file dialog. + dialog.setOption(QFileDialog::DontUseNativeDialog, true); + + dialog.show(); + ret = dialog.exec(); + + if ( ret ) + { + QStringList fileList; + fileList = dialog.selectedFiles(); + + if ( fileList.size() > 0 ) + { + filename = fileList[0]; + } + } + + if ( filename.isNull() ) + { + return; + } + qDebug() << "selected file path : " << filename.toUtf8(); + + // copy BIOS file to proper place (~/.fceux/disksys.rom) + std::ifstream fdsBios (filename.toStdString().c_str(), std::fstream::binary); + std::string output_filename = + FCEU_MakeFName (FCEUMKF_FDSROM, 0, ""); + std::ofstream outFile (output_filename.c_str (), + std::fstream::trunc | std::fstream:: + binary); + outFile << fdsBios.rdbuf (); + if (outFile.fail ()) + { + FCEUD_PrintError ("Error copying the FDS BIOS file."); + } + else + { + printf("Famicom Disk System BIOS loaded. If you are you having issues, make sure your BIOS file is 8KB in size.\n"); + } + + return; +} + void consoleWin_t::aboutFCEUX(void) { printf("About FCEUX\n"); diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index 9239a096..8464106a 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -77,6 +77,9 @@ class consoleWin_t : public QMainWindow QAction *gameGenieAct; QAction *loadGgROMAct; QAction *insCoinAct; + QAction *fdsSwitchAct; + QAction *fdsEjectAct; + QAction *fdsLoadBiosAct; QTimer *gameTimer; emulatorThread_t *emulatorThread; @@ -128,6 +131,9 @@ class consoleWin_t : public QMainWindow void toggleGameGenie(bool checked); void loadGameGenieROM(void); void insertCoin(void); + void fdsSwitchDisk(void); + void fdsEjectDisk(void); + void fdsLoadBiosFile(void); }; From 32116210b84102a94c8ca183387e1446b56bdbfa Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 11 Jul 2020 16:11:48 -0400 Subject: [PATCH 080/100] About FCEUX window in work. --- src/CMakeLists.txt | 1 + src/drivers/Qt/AboutWindow.cpp | 89 ++++++++++++++++++++++++++++++++ src/drivers/Qt/AboutWindow.h | 35 +++++++++++++ src/drivers/Qt/ConsoleWindow.cpp | 14 ++++- 4 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 src/drivers/Qt/AboutWindow.cpp create mode 100644 src/drivers/Qt/AboutWindow.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 13e66a35..2a8ee58f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -385,6 +385,7 @@ set(SRC_DRIVERS_SDL ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/HotKeyConf.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleVideoConf.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleSoundConf.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/AboutWindow.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/fceuWrapper.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/config.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/input.cpp diff --git a/src/drivers/Qt/AboutWindow.cpp b/src/drivers/Qt/AboutWindow.cpp new file mode 100644 index 00000000..ab179fd6 --- /dev/null +++ b/src/drivers/Qt/AboutWindow.cpp @@ -0,0 +1,89 @@ +// AboutWindow.cpp +// +#include +#include +#include +#include + +#include +#include +#include +#include "Qt/icon.xpm" +#include "Qt/AboutWindow.h" +#include "../../version.h" + +//---------------------------------------------------------------------------- +AboutWindow::AboutWindow(QWidget *parent) + : QDialog( parent ) +{ + QVBoxLayout *mainLayout; + QHBoxLayout *hbox1; + QPixmap pm( icon_xpm ); + QLabel *lbl; + + setWindowTitle( tr("About fceuX") ); + + resize( 512, 512 ); + + mainLayout = new QVBoxLayout(); + + hbox1 = new QHBoxLayout(); + lbl = new QLabel(); + lbl->setPixmap(pm); + + hbox1->addWidget( lbl ); + hbox1->setAlignment( Qt::AlignCenter ); + + mainLayout->addLayout( hbox1 ); + + hbox1 = new QHBoxLayout(); + lbl = new QLabel( tr("fceuX") ); + + hbox1->addWidget( lbl ); + hbox1->setAlignment( Qt::AlignCenter ); + + mainLayout->addLayout( hbox1 ); + + hbox1 = new QHBoxLayout(); + lbl = new QLabel( tr(FCEU_VERSION_STRING) ); + + hbox1->addWidget( lbl ); + hbox1->setAlignment( Qt::AlignCenter ); + + mainLayout->addLayout( hbox1 ); + + hbox1 = new QHBoxLayout(); + lbl = new QLabel(); + lbl->setText("Website"); + lbl->setTextInteractionFlags(Qt::TextBrowserInteraction); + lbl->setOpenExternalLinks(true); + + hbox1->addWidget( lbl ); + hbox1->setAlignment( Qt::AlignCenter ); + + mainLayout->addLayout( hbox1 ); + + hbox1 = new QHBoxLayout(); + lbl = new QLabel( tr("License: GPL") ); + + hbox1->addWidget( lbl ); + hbox1->setAlignment( Qt::AlignCenter ); + + mainLayout->addLayout( hbox1 ); + + hbox1 = new QHBoxLayout(); + lbl = new QLabel( tr("© 2016 FceuX Development Team") ); + + hbox1->addWidget( lbl ); + hbox1->setAlignment( Qt::AlignCenter ); + + mainLayout->addLayout( hbox1 ); + + setLayout( mainLayout ); +} +//---------------------------------------------------------------------------- +AboutWindow::~AboutWindow(void) +{ + +} +//---------------------------------------------------------------------------- diff --git a/src/drivers/Qt/AboutWindow.h b/src/drivers/Qt/AboutWindow.h new file mode 100644 index 00000000..e8ebb10c --- /dev/null +++ b/src/drivers/Qt/AboutWindow.h @@ -0,0 +1,35 @@ +// GamePadConf.h +// + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Qt/main.h" + +class AboutWindow : public QDialog +{ + Q_OBJECT + + public: + AboutWindow(QWidget *parent = 0); + ~AboutWindow(void); + + protected: + + private: + + private slots: + +}; diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index 8661c404..e21db2a2 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -20,6 +20,7 @@ #include "Qt/HotKeyConf.h" #include "Qt/ConsoleSoundConf.h" #include "Qt/ConsoleVideoConf.h" +#include "Qt/AboutWindow.h" #include "Qt/fceuWrapper.h" #include "Qt/keyscan.h" #include "Qt/nes_shm.h" @@ -1046,7 +1047,18 @@ void consoleWin_t::fdsLoadBiosFile(void) void consoleWin_t::aboutFCEUX(void) { - printf("About FCEUX\n"); + AboutWindow *aboutWin; + + //printf("About FCEUX Window\n"); + + aboutWin = new AboutWindow(this); + + aboutWin->show(); + aboutWin->exec(); + + delete aboutWin; + + //printf("About Window Destroyed\n"); return; } From 2c370389fda96ed78a31b6b6f1191f9ea45b54f9 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 11 Jul 2020 16:55:45 -0400 Subject: [PATCH 081/100] Added window icon resource. --- resources.qrc | 5 +++ src/CMakeLists.txt | 2 +- src/drivers/Qt/ConsoleWindow.cpp | 1 + src/drivers/Qt/icon.xpm | 55 ++++++++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 resources.qrc create mode 100644 src/drivers/Qt/icon.xpm diff --git a/resources.qrc b/resources.qrc new file mode 100644 index 00000000..147a5bc7 --- /dev/null +++ b/resources.qrc @@ -0,0 +1,5 @@ + + + fceux.png + + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2a8ee58f..e53a34d7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -400,7 +400,7 @@ set(SRC_DRIVERS_SDL set(SOURCES ${SRC_CORE} ${SRC_DRIVERS_COMMON} ${SRC_DRIVERS_SDL}) -add_executable( fceux ${SOURCES} ) +add_executable( fceux ${SOURCES} ../resources.qrc ) target_link_libraries( fceux ${Qt5Widgets_LIBRARIES} diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index e21db2a2..cbe778a8 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -35,6 +35,7 @@ consoleWin_t::consoleWin_t(QWidget *parent) //viewport = new ConsoleViewSDL_t(this); setCentralWidget(viewport); + setWindowIcon(QIcon(":fceux.png")); gameTimer = new QTimer( this ); mutex = new QMutex( QMutex::NonRecursive ); diff --git a/src/drivers/Qt/icon.xpm b/src/drivers/Qt/icon.xpm new file mode 100644 index 00000000..7c817653 --- /dev/null +++ b/src/drivers/Qt/icon.xpm @@ -0,0 +1,55 @@ +/* XPM */ +static const char * icon_xpm[] = { +"32 32 20 1", +" c None", +". c #040204", +"+ c #84A284", +"@ c #C42204", +"# c #8482C4", +"$ c #FCFEFC", +"% c #848284", +"& c #648284", +"* c #646284", +"= c #444244", +"- c #A4A284", +"; c #C4A284", +"> c #C48284", +", c #A4CAF4", +"' c #244244", +") c #444204", +"! c #442204", +"~ c #446244", +"{ c #646244", +"] c #644244", +" ", +" ........ ", +" ............... ", +" ........................ ", +" ...........................+ ", +" ............@@..@@........... ", +" .#............@@............$$ ", +" .##..........@@.@.....$$%%%%$$ ", +" &...........@....@$$$$$$%%&%$$ ", +" *&...............$$$$$$$%%&%$$ ", +" =&*.......-;;>;...$$,$$$%**&.. ", +" '&&..............$$,,,%=)!~.. ", +" ~&&............-%%##%*.~'=%& ", +" *&&.....+%%****&&%%&*.&!!' ", +" **&%&***********&&&*~{'= ", +" ********=**~**~**~ ", +" *****~******] ", +" **~***]' ", +" ~]== ", +" ", +" ..... .... .... .. ..@@ @@", +" ..... .... .... .. ..@@@ @@@", +" .. .. .. .. .. @@@ @@@ ", +" .... .. .. .. .. @@@@@@ ", +" .... .. ... .. .. @@@@ ", +" .. .. ... .. .. @@@@ ", +" .. .. .. .. .. @@@@@@ ", +" .. .. .. .. .. @@@ @@@ ", +" .. .... .... .....@@@ @@@", +" .. .... .... ... @@ @@", +" ", +" "}; From f436408b06ca5f9dd85e3b1f662709cc6b6a6fb5 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 11 Jul 2020 17:06:22 -0400 Subject: [PATCH 082/100] Updated about window to use embedded png. --- src/drivers/Qt/AboutWindow.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/drivers/Qt/AboutWindow.cpp b/src/drivers/Qt/AboutWindow.cpp index ab179fd6..34d6520c 100644 --- a/src/drivers/Qt/AboutWindow.cpp +++ b/src/drivers/Qt/AboutWindow.cpp @@ -8,7 +8,7 @@ #include #include #include -#include "Qt/icon.xpm" +//#include "Qt/icon.xpm" #include "Qt/AboutWindow.h" #include "../../version.h" @@ -18,9 +18,13 @@ AboutWindow::AboutWindow(QWidget *parent) { QVBoxLayout *mainLayout; QHBoxLayout *hbox1; - QPixmap pm( icon_xpm ); + //QPixmap pm( icon_xpm ); + QPixmap pm(":fceux.png"); + QPixmap pm2; QLabel *lbl; + pm2 = pm.scaled( 64, 64 ); + setWindowTitle( tr("About fceuX") ); resize( 512, 512 ); @@ -29,7 +33,7 @@ AboutWindow::AboutWindow(QWidget *parent) hbox1 = new QHBoxLayout(); lbl = new QLabel(); - lbl->setPixmap(pm); + lbl->setPixmap(pm2); hbox1->addWidget( lbl ); hbox1->setAlignment( Qt::AlignCenter ); From 889250b7201d59410edce44e2eac4e2e9b2fdd62 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 11 Jul 2020 17:26:08 -0400 Subject: [PATCH 083/100] Updated About Window. --- src/drivers/Qt/AboutWindow.cpp | 35 ++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/drivers/Qt/AboutWindow.cpp b/src/drivers/Qt/AboutWindow.cpp index 34d6520c..1631ef22 100644 --- a/src/drivers/Qt/AboutWindow.cpp +++ b/src/drivers/Qt/AboutWindow.cpp @@ -7,21 +7,43 @@ #include #include +#include #include //#include "Qt/icon.xpm" #include "Qt/AboutWindow.h" #include "../../version.h" +static const char *Authors[] = { + "Linux/SDL Developers:", + "\t Lukas Sabota //punkrockguy318", "\t Soules", "\t Bryan Cain", "\t radsaq", + "\t Shinydoofy", + "FceuX 2.0 Developers:", + "\t SP", "\t zeromus", "\t adelikat", "\t caH4e3", "\t qfox", + "\t Luke Gustafson", "\t _mz", "\t UncombedCoconut", "\t DwEdit", "\t AnS", + "\t rainwarrior", "\t feos", + "Pre 2.0 Guys:", + "\t Bero", "\t Xodnizel", "\t Aaron Oneal", "\t Joe Nahmias", + "\t Paul Kuliniewicz", "\t Quietust", "\t Ben Parnell", + "\t Parasyte & bbitmaster", + "\t blip & nitsuja", + "Included components:", + "\t Mitsutaka Okazaki - YM2413 emulator", + "\t Andrea Mazzoleni - Scale2x/Scale3x scalers", + "\t Gilles Vollant - unzip.c PKZIP fileio", + NULL +}; //---------------------------------------------------------------------------- AboutWindow::AboutWindow(QWidget *parent) : QDialog( parent ) { + int i; QVBoxLayout *mainLayout; QHBoxLayout *hbox1; //QPixmap pm( icon_xpm ); QPixmap pm(":fceux.png"); QPixmap pm2; QLabel *lbl; + QTextEdit *credits; pm2 = pm.scaled( 64, 64 ); @@ -83,6 +105,19 @@ AboutWindow::AboutWindow(QWidget *parent) mainLayout->addLayout( hbox1 ); + credits = new QTextEdit(); + + i=0; + while ( Authors[i] != NULL ) + { + credits->insertPlainText( Authors[i] ); i++; + credits->insertPlainText( "\n"); + } + credits->moveCursor(QTextCursor::Start); + credits->setReadOnly(true); + + mainLayout->addWidget( credits ); + setLayout( mainLayout ); } //---------------------------------------------------------------------------- From 9fc2d905de77afedac49b0950034d0638046321c Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 11 Jul 2020 17:48:14 -0400 Subject: [PATCH 084/100] Added script to generate C header with git repo url and rev info. --- scripts/genGitHdr.sh | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100755 scripts/genGitHdr.sh diff --git a/scripts/genGitHdr.sh b/scripts/genGitHdr.sh new file mode 100755 index 00000000..274c9d32 --- /dev/null +++ b/scripts/genGitHdr.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +OUTPUT_DIR=$1; + +FILE="fceux_gitrev.h" +TMP_FILE="/tmp/$FILE"; + +GIT_URL=`git config --get remote.origin.url`; +GIT_REV=`git rev-parse HEAD`; + +echo "// fceux_gitrev.h -- DO NOT EDIT: This file is auto-generated at build" >| $TMP_FILE; +echo "#define FCEUX_GIT_URL \"$GIT_URL\" " >> $TMP_FILE; +echo "#define FCEUX_GIT_REV \"$GIT_REV\" " >> $TMP_FILE; + +if [ -e $OUTPUT_DIR/$FILE ]; then + + diff $TMP_FILE $OUTPUT_DIR/$FILE + + if [ $? != 0 ]; then + echo 'File Differs'; + mv -f $TMP_FILE $OUTPUT_DIR/$FILE + fi +else + mv -f $TMP_FILE $OUTPUT_DIR/$FILE +fi From 96df0c25e1a50eeeb18664d3dcd1fc2f4f8f2a33 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 11 Jul 2020 19:52:14 -0400 Subject: [PATCH 085/100] Added logic to auto embed the git URL and revision into the executable so that it can be displayed on the About dialog window. --- scripts/genGitHdr.sh | 9 +++++++-- src/CMakeLists.txt | 10 +++++++++- src/drivers/Qt/AboutWindow.cpp | 22 ++++++++++++++++++++++ src/drivers/Qt/fceux_git_info.h | 4 ++++ 4 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 src/drivers/Qt/fceux_git_info.h diff --git a/scripts/genGitHdr.sh b/scripts/genGitHdr.sh index 274c9d32..07fa2a6b 100755 --- a/scripts/genGitHdr.sh +++ b/scripts/genGitHdr.sh @@ -2,15 +2,20 @@ OUTPUT_DIR=$1; -FILE="fceux_gitrev.h" +FILE="fceux_git_info.cpp" TMP_FILE="/tmp/$FILE"; +echo "Output File: $OUTPUT_DIR/$FILE"; + GIT_URL=`git config --get remote.origin.url`; GIT_REV=`git rev-parse HEAD`; -echo "// fceux_gitrev.h -- DO NOT EDIT: This file is auto-generated at build" >| $TMP_FILE; +echo "// fceux_gitrev.cpp -- DO NOT EDIT: This file is auto-generated at build" >| $TMP_FILE; +echo "#include \"Qt/fceux_git_info.h\" " >> $TMP_FILE; echo "#define FCEUX_GIT_URL \"$GIT_URL\" " >> $TMP_FILE; echo "#define FCEUX_GIT_REV \"$GIT_REV\" " >> $TMP_FILE; +echo "const char *fceu_get_git_url(void){ return FCEUX_GIT_URL; }" >> $TMP_FILE +echo "const char *fceu_get_git_rev(void){ return FCEUX_GIT_REV; }" >> $TMP_FILE if [ -e $OUTPUT_DIR/$FILE ]; then diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e53a34d7..6eb930e8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -400,7 +400,15 @@ set(SRC_DRIVERS_SDL set(SOURCES ${SRC_CORE} ${SRC_DRIVERS_COMMON} ${SRC_DRIVERS_SDL}) -add_executable( fceux ${SOURCES} ../resources.qrc ) +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/fceux_git_info.cpp + COMMAND ${CMAKE_SOURCE_DIR}/scripts/genGitHdr.sh ${CMAKE_CURRENT_BINARY_DIR} + VERBATIM ) + +set_property(SOURCE ${CMAKE_CURRENT_BINARY_DIR}/fceux_git_info.cpp PROPERTY SKIP_AUTOGEN ON) + +add_executable( fceux ${SOURCES} ../resources.qrc + ${CMAKE_CURRENT_BINARY_DIR}/fceux_git_info.cpp) target_link_libraries( fceux ${Qt5Widgets_LIBRARIES} diff --git a/src/drivers/Qt/AboutWindow.cpp b/src/drivers/Qt/AboutWindow.cpp index 1631ef22..f7da8faf 100644 --- a/src/drivers/Qt/AboutWindow.cpp +++ b/src/drivers/Qt/AboutWindow.cpp @@ -11,6 +11,7 @@ #include //#include "Qt/icon.xpm" #include "Qt/AboutWindow.h" +#include "Qt/fceux_git_info.h" #include "../../version.h" static const char *Authors[] = { @@ -44,6 +45,7 @@ AboutWindow::AboutWindow(QWidget *parent) QPixmap pm2; QLabel *lbl; QTextEdit *credits; + char stmp[256]; pm2 = pm.scaled( 64, 64 ); @@ -78,6 +80,26 @@ AboutWindow::AboutWindow(QWidget *parent) mainLayout->addLayout( hbox1 ); + sprintf( stmp, "git URL: %s", fceu_get_git_url() ); + + hbox1 = new QHBoxLayout(); + lbl = new QLabel( tr(stmp) ); + + hbox1->addWidget( lbl ); + hbox1->setAlignment( Qt::AlignCenter ); + + mainLayout->addLayout( hbox1 ); + + sprintf( stmp, "git Revision: %s", fceu_get_git_rev() ); + + hbox1 = new QHBoxLayout(); + lbl = new QLabel( tr(stmp) ); + + hbox1->addWidget( lbl ); + hbox1->setAlignment( Qt::AlignCenter ); + + mainLayout->addLayout( hbox1 ); + hbox1 = new QHBoxLayout(); lbl = new QLabel(); lbl->setText("Website"); diff --git a/src/drivers/Qt/fceux_git_info.h b/src/drivers/Qt/fceux_git_info.h new file mode 100644 index 00000000..fd9cdb8c --- /dev/null +++ b/src/drivers/Qt/fceux_git_info.h @@ -0,0 +1,4 @@ +// fceux_git_info.h + +const char *fceu_get_git_url(void); +const char *fceu_get_git_rev(void); From f2dc2c5755d5ba05f05be5e397594ee9846e72fd Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 11 Jul 2020 20:04:58 -0400 Subject: [PATCH 086/100] Added debug statements to genGitHdr script. --- scripts/genGitHdr.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/genGitHdr.sh b/scripts/genGitHdr.sh index 07fa2a6b..64f4d59b 100755 --- a/scripts/genGitHdr.sh +++ b/scripts/genGitHdr.sh @@ -17,14 +17,17 @@ echo "#define FCEUX_GIT_REV \"$GIT_REV\" " >> $TMP_FILE; echo "const char *fceu_get_git_url(void){ return FCEUX_GIT_URL; }" >> $TMP_FILE echo "const char *fceu_get_git_rev(void){ return FCEUX_GIT_REV; }" >> $TMP_FILE +echo "Git URL: $GIT_URL "; +echo "Git Rev: $GIT_REV "; if [ -e $OUTPUT_DIR/$FILE ]; then - diff $TMP_FILE $OUTPUT_DIR/$FILE + diff -q $TMP_FILE $OUTPUT_DIR/$FILE if [ $? != 0 ]; then - echo 'File Differs'; - mv -f $TMP_FILE $OUTPUT_DIR/$FILE + mv -f $TMP_FILE $OUTPUT_DIR/$FILE; + echo "Updated $OUTPUT_DIR/$FILE"; fi else mv -f $TMP_FILE $OUTPUT_DIR/$FILE + echo "Generated $OUTPUT_DIR/$FILE"; fi From b3c51ef4b1206b4468b61c20a0f3700483731cae Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 11 Jul 2020 20:48:48 -0400 Subject: [PATCH 087/100] Added movie menu logic to gui. --- src/drivers/Qt/ConsoleWindow.cpp | 175 +++++++++++++++++++++++++++++++ src/drivers/Qt/ConsoleWindow.h | 9 ++ src/drivers/Qt/fceuWrapper.cpp | 5 + src/drivers/Qt/fceuWrapper.h | 1 + 4 files changed, 190 insertions(+) diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index cbe778a8..1de89b3b 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -7,6 +7,7 @@ #include "../../fceu.h" #include "../../fds.h" +#include "../../movie.h" #ifdef _S9XLUA_H #include "../../fceulua.h" @@ -395,6 +396,44 @@ void consoleWin_t::createMainMenu(void) subMenu->addAction(fdsLoadBiosAct); + //----------------------------------------------------------------------- + // Movie + movieMenu = menuBar()->addMenu(tr("Movie")); + + // Movie -> Open + openMovAct = new QAction(tr("Open"), this); + openMovAct->setShortcut( QKeySequence(tr("Shift+F7"))); + openMovAct->setStatusTip(tr("Open Movie File")); + connect(openMovAct, SIGNAL(triggered()), this, SLOT(openMovie(void)) ); + + movieMenu->addAction(openMovAct); + + // Movie -> Stop + stopMovAct = new QAction(tr("Stop"), this); + //stopMovAct->setShortcut( QKeySequence(tr("Shift+F7"))); + stopMovAct->setStatusTip(tr("Stop Movie Recording")); + connect(stopMovAct, SIGNAL(triggered()), this, SLOT(stopMovie(void)) ); + + movieMenu->addAction(stopMovAct); + + movieMenu->addSeparator(); + + // Movie -> Record + recMovAct = new QAction(tr("Record"), this); + recMovAct->setShortcut( QKeySequence(tr("Shift+F5"))); + recMovAct->setStatusTip(tr("Record Movie")); + connect(recMovAct, SIGNAL(triggered()), this, SLOT(recordMovie(void)) ); + + movieMenu->addAction(recMovAct); + + // Movie -> Record As + recAsMovAct = new QAction(tr("Record As"), this); + //recAsMovAct->setShortcut( QKeySequence(tr("Shift+F5"))); + recAsMovAct->setStatusTip(tr("Record Movie")); + connect(recAsMovAct, SIGNAL(triggered()), this, SLOT(recordMovieAs(void)) ); + + movieMenu->addAction(recAsMovAct); + //----------------------------------------------------------------------- // Help helpMenu = menuBar()->addMenu(tr("Help")); @@ -1046,6 +1085,142 @@ void consoleWin_t::fdsLoadBiosFile(void) return; } +void consoleWin_t::openMovie(void) +{ + int ret; + QString filename; + std::string last; + QFileDialog dialog(this, tr("Open FM2 Movie") ); + + dialog.setFileMode(QFileDialog::ExistingFile); + + dialog.setNameFilter(tr("FM2 Movies (*.fm2) ;; All files (*)")); + + dialog.setViewMode(QFileDialog::List); + + g_config->getOption ("SDL.LastOpenFile", &last ); + + dialog.setDirectory( tr(last.c_str()) ); + + // the gnome default file dialog is not playing nice with QT. + // TODO make this a config option to use native file dialog. + dialog.setOption(QFileDialog::DontUseNativeDialog, true); + + dialog.show(); + ret = dialog.exec(); + + if ( ret ) + { + QStringList fileList; + fileList = dialog.selectedFiles(); + + if ( fileList.size() > 0 ) + { + filename = fileList[0]; + } + } + + if ( filename.isNull() ) + { + return; + } + qDebug() << "selected file path : " << filename.toUtf8(); + + int pauseframe; + g_config->getOption ("SDL.PauseFrame", &pauseframe); + g_config->setOption ("SDL.PauseFrame", 0); + + FCEUI_printf ("Playing back movie located at %s\n", filename.toStdString().c_str() ); + + fceuWrapperLock(); + if (FCEUI_LoadMovie( filename.toStdString().c_str(), + false, pauseframe ? pauseframe : false) == false) + { + printf("Error: Could not open movie file: %s \n", filename.toStdString().c_str() ); + } + fceuWrapperUnLock(); + + return; +} + +void consoleWin_t::stopMovie(void) +{ + fceuWrapperLock(); + FCEUI_StopMovie(); + fceuWrapperUnLock(); + return; +} + +void consoleWin_t::recordMovie(void) +{ + fceuWrapperLock(); + if (fceuWrapperGameLoaded()) + { + std::string name = FCEU_MakeFName (FCEUMKF_MOVIE, 0, 0); + FCEUI_printf ("Recording movie to %s\n", name.c_str ()); + FCEUI_SaveMovie (name.c_str (), MOVIE_FLAG_NONE, L""); + } + fceuWrapperUnLock(); + return; +} + +void consoleWin_t::recordMovieAs(void) +{ + int ret; + QString filename; + std::string last; + QFileDialog dialog(this, tr("Save FM2 Movie for Recording") ); + + dialog.setFileMode(QFileDialog::AnyFile); + + dialog.setNameFilter(tr("FM2 Movies (*.fm2) ;; All files (*)")); + + dialog.setViewMode(QFileDialog::List); + + g_config->getOption ("SDL.LastOpenFile", &last ); + + dialog.setDirectory( tr(last.c_str()) ); + + // the gnome default file dialog is not playing nice with QT. + // TODO make this a config option to use native file dialog. + dialog.setOption(QFileDialog::DontUseNativeDialog, true); + + dialog.show(); + ret = dialog.exec(); + + if ( ret ) + { + QStringList fileList; + fileList = dialog.selectedFiles(); + + if ( fileList.size() > 0 ) + { + filename = fileList[0]; + } + } + + if ( filename.isNull() ) + { + return; + } + qDebug() << "selected file path : " << filename.toUtf8(); + + int pauseframe; + g_config->getOption ("SDL.PauseFrame", &pauseframe); + g_config->setOption ("SDL.PauseFrame", 0); + + FCEUI_printf ("Recording movie to %s\n", filename.toStdString().c_str() ); + + fceuWrapperLock(); + std::string s = GetUserText ("Author name"); + std::wstring author (s.begin (), s.end ()); + + FCEUI_SaveMovie ( filename.toStdString().c_str(), MOVIE_FLAG_NONE, author); + fceuWrapperUnLock(); + + return; +} + void consoleWin_t::aboutFCEUX(void) { AboutWindow *aboutWin; diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index 8464106a..692f7051 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -50,6 +50,7 @@ class consoleWin_t : public QMainWindow QMenu *fileMenu; QMenu *optMenu; QMenu *emuMenu; + QMenu *movieMenu; QMenu *helpMenu; QAction *openROM; @@ -80,6 +81,10 @@ class consoleWin_t : public QMainWindow QAction *fdsSwitchAct; QAction *fdsEjectAct; QAction *fdsLoadBiosAct; + QAction *openMovAct; + QAction *stopMovAct; + QAction *recMovAct; + QAction *recAsMovAct; QTimer *gameTimer; emulatorThread_t *emulatorThread; @@ -134,6 +139,10 @@ class consoleWin_t : public QMainWindow void fdsSwitchDisk(void); void fdsEjectDisk(void); void fdsLoadBiosFile(void); + void openMovie(void); + void stopMovie(void); + void recordMovie(void); + void recordMovieAs(void); }; diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp index 5c8943a5..c3601449 100644 --- a/src/drivers/Qt/fceuWrapper.cpp +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -318,6 +318,11 @@ int fceuWrapperTogglePause(void) return 0; } +bool fceuWrapperGameLoaded(void) +{ + return (isloaded ? true : false); +} + int fceuWrapperInit( int argc, char *argv[] ) { int error; diff --git a/src/drivers/Qt/fceuWrapper.h b/src/drivers/Qt/fceuWrapper.h index ac057025..e3ce55a8 100644 --- a/src/drivers/Qt/fceuWrapper.h +++ b/src/drivers/Qt/fceuWrapper.h @@ -32,4 +32,5 @@ void fceuWrapperUnLock(void); int fceuWrapperSoftReset(void); int fceuWrapperHardReset(void); int fceuWrapperTogglePause(void); +bool fceuWrapperGameLoaded(void); From d43383d8bfad2ce5e8a677de53f8cc5934ef3322 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 11 Jul 2020 21:14:37 -0400 Subject: [PATCH 088/100] Fixed directory pathing for file browser. --- src/drivers/Qt/ConsoleWindow.cpp | 73 ++++++++++++++++++++++++++++---- src/drivers/Qt/ConsoleWindow.h | 2 + 2 files changed, 66 insertions(+), 9 deletions(-) diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index 1de89b3b..bbf45ed6 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -73,6 +73,11 @@ consoleWin_t::~consoleWin_t(void) delete viewport; delete mutex; + + // LoadGame() checks for an IP and if it finds one begins a network session + // clear the NetworkIP field so this doesn't happen unintentionally + g_config->setOption ("SDL.NetworkIP", ""); + g_config->save (); } void consoleWin_t::setCyclePeriodms( int ms ) @@ -463,12 +468,36 @@ void consoleWin_t::closeApp(void) qApp->quit(); } //--------------------------------------------------------------------------- +int consoleWin_t::getDirFromFile( const char *path, char *dir ) +{ + int i,j; + + i=0; j = -1; + while ( path[i] != 0 ) + { + if ( path[i] == '/' ) + { + j = i; + } + dir[i] = path[i]; i++; + } + dir[i] = 0; + + if ( j >= 0 ) + { + dir[j] = 0; + } + + return 0; +} +//--------------------------------------------------------------------------- void consoleWin_t::openROMFile(void) { int ret; QString filename; std::string last; + char dir[512]; QFileDialog dialog(this, tr("Open ROM File") ); dialog.setFileMode(QFileDialog::ExistingFile); @@ -479,7 +508,9 @@ void consoleWin_t::openROMFile(void) g_config->getOption ("SDL.LastOpenFile", &last ); - dialog.setDirectory( tr(last.c_str()) ); + getDirFromFile( last.c_str(), dir ); + + dialog.setDirectory( tr(dir) ); // the gnome default file dialog is not playing nice with QT. // TODO make this a config option to use native file dialog. @@ -527,6 +558,7 @@ void consoleWin_t::loadNSF(void) int ret; QString filename; std::string last; + char dir[512]; QFileDialog dialog(this, tr("Load NSF File") ); dialog.setFileMode(QFileDialog::ExistingFile); @@ -537,7 +569,9 @@ void consoleWin_t::loadNSF(void) g_config->getOption ("SDL.LastOpenNSF", &last ); - dialog.setDirectory( tr(last.c_str()) ); + getDirFromFile( last.c_str(), dir ); + + dialog.setDirectory( tr(dir) ); // the gnome default file dialog is not playing nice with QT. // TODO make this a config option to use native file dialog. @@ -575,6 +609,7 @@ void consoleWin_t::loadStateFrom(void) int ret; QString filename; std::string last; + char dir[512]; QFileDialog dialog(this, tr("Load State From File") ); dialog.setFileMode(QFileDialog::ExistingFile); @@ -585,7 +620,9 @@ void consoleWin_t::loadStateFrom(void) g_config->getOption ("SDL.LastLoadStateFrom", &last ); - dialog.setDirectory( tr(last.c_str()) ); + getDirFromFile( last.c_str(), dir ); + + dialog.setDirectory( tr(dir) ); // the gnome default file dialog is not playing nice with QT. // TODO make this a config option to use native file dialog. @@ -623,6 +660,7 @@ void consoleWin_t::saveStateAs(void) int ret; QString filename; std::string last; + char dir[512]; QFileDialog dialog(this, tr("Save State To File") ); dialog.setFileMode(QFileDialog::AnyFile); @@ -633,7 +671,9 @@ void consoleWin_t::saveStateAs(void) g_config->getOption ("SDL.LastSaveStateAs", &last ); - dialog.setDirectory( tr(last.c_str()) ); + getDirFromFile( last.c_str(), dir ); + + dialog.setDirectory( tr(dir) ); // the gnome default file dialog is not playing nice with QT. // TODO make this a config option to use native file dialog. @@ -763,6 +803,7 @@ void consoleWin_t::loadLua(void) int ret; QString filename; std::string last; + char dir[512]; QFileDialog dialog(this, tr("Open LUA Script") ); dialog.setFileMode(QFileDialog::ExistingFile); @@ -778,7 +819,9 @@ void consoleWin_t::loadLua(void) last.assign( "/usr/share/fceux/luaScripts" ); } - dialog.setDirectory( tr(last.c_str()) ); + getDirFromFile( last.c_str(), dir ); + + dialog.setDirectory( tr(dir) ); // the gnome default file dialog is not playing nice with QT. // TODO make this a config option to use native file dialog. @@ -952,6 +995,7 @@ void consoleWin_t::loadGameGenieROM(void) int ret; QString filename; std::string last; + char dir[512]; QFileDialog dialog(this, tr("Open Game Genie ROM") ); dialog.setFileMode(QFileDialog::ExistingFile); @@ -962,7 +1006,9 @@ void consoleWin_t::loadGameGenieROM(void) g_config->getOption ("SDL.LastOpenFile", &last ); - dialog.setDirectory( tr(last.c_str()) ); + getDirFromFile( last.c_str(), dir ); + + dialog.setDirectory( tr(dir) ); // the gnome default file dialog is not playing nice with QT. // TODO make this a config option to use native file dialog. @@ -1029,6 +1075,7 @@ void consoleWin_t::fdsLoadBiosFile(void) int ret; QString filename; std::string last; + char dir[512]; QFileDialog dialog(this, tr("Load FDS BIOS (disksys.rom)") ); dialog.setFileMode(QFileDialog::ExistingFile); @@ -1039,7 +1086,9 @@ void consoleWin_t::fdsLoadBiosFile(void) g_config->getOption ("SDL.LastOpenFile", &last ); - dialog.setDirectory( tr(last.c_str()) ); + getDirFromFile( last.c_str(), dir ); + + dialog.setDirectory( tr(dir) ); // the gnome default file dialog is not playing nice with QT. // TODO make this a config option to use native file dialog. @@ -1090,6 +1139,7 @@ void consoleWin_t::openMovie(void) int ret; QString filename; std::string last; + char dir[512]; QFileDialog dialog(this, tr("Open FM2 Movie") ); dialog.setFileMode(QFileDialog::ExistingFile); @@ -1100,7 +1150,9 @@ void consoleWin_t::openMovie(void) g_config->getOption ("SDL.LastOpenFile", &last ); - dialog.setDirectory( tr(last.c_str()) ); + getDirFromFile( last.c_str(), dir ); + + dialog.setDirectory( tr(dir) ); // the gnome default file dialog is not playing nice with QT. // TODO make this a config option to use native file dialog. @@ -1169,6 +1221,7 @@ void consoleWin_t::recordMovieAs(void) int ret; QString filename; std::string last; + char dir[512]; QFileDialog dialog(this, tr("Save FM2 Movie for Recording") ); dialog.setFileMode(QFileDialog::AnyFile); @@ -1179,7 +1232,9 @@ void consoleWin_t::recordMovieAs(void) g_config->getOption ("SDL.LastOpenFile", &last ); - dialog.setDirectory( tr(last.c_str()) ); + getDirFromFile( last.c_str(), dir ); + + dialog.setDirectory( tr(dir) ); // the gnome default file dialog is not playing nice with QT. // TODO make this a config option to use native file dialog. diff --git a/src/drivers/Qt/ConsoleWindow.h b/src/drivers/Qt/ConsoleWindow.h index 692f7051..59bb43f5 100644 --- a/src/drivers/Qt/ConsoleWindow.h +++ b/src/drivers/Qt/ConsoleWindow.h @@ -97,6 +97,8 @@ class consoleWin_t : public QMainWindow void keyReleaseEvent(QKeyEvent *event); void syncActionConfig( QAction *act, const char *property ); + int getDirFromFile( const char *path, char *dir ); + private: void createMainMenu(void); From 76d8b829bd3277b34ed8f37e2eb12ae1b9deaf64 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 11 Jul 2020 21:29:23 -0400 Subject: [PATCH 089/100] Bug fix for file browser initial directory calculation. --- src/drivers/Qt/ConsoleWindow.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index bbf45ed6..ef93bdd7 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -470,22 +470,29 @@ void consoleWin_t::closeApp(void) //--------------------------------------------------------------------------- int consoleWin_t::getDirFromFile( const char *path, char *dir ) { - int i,j; + int i, lastSlash = -1, lastPeriod = -1; - i=0; j = -1; + i=0; while ( path[i] != 0 ) { if ( path[i] == '/' ) { - j = i; + lastSlash = i; + } + else if ( path[i] == '.' ) + { + lastPeriod = i; } dir[i] = path[i]; i++; } dir[i] = 0; - if ( j >= 0 ) + if ( lastPeriod >= 0 ) { - dir[j] = 0; + if ( lastPeriod > lastSlash ) + { + dir[lastSlash] = 0; + } } return 0; From c93d0b3113fbe38393875d58563aadc8a21bea84 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 11 Jul 2020 22:09:51 -0400 Subject: [PATCH 090/100] Added command line help output. --- src/CMakeLists.txt | 3 + src/drivers/Qt/fceuWrapper.cpp | 100 ++++++++++++++++++++++++++++++++- 2 files changed, 100 insertions(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6eb930e8..05207915 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -113,6 +113,7 @@ else(WIN32) endif() add_definitions( -DHAVE_ASPRINTF ) # What system wouldn't have this? + #add_definitions( -DCREATE_AVI ) if(APPLE) set( OPENGL_LDFLAGS "-framework OpenGL" ) @@ -374,6 +375,8 @@ set(SRC_DRIVERS_COMMON ${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/scalebit.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/vidblit.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/nes_ntsc.c + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/videolog/nesvideos-piece.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/videolog/rgbtorgb.cpp ) set(SRC_DRIVERS_SDL diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp index c3601449..7e1daca0 100644 --- a/src/drivers/Qt/fceuWrapper.cpp +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -59,6 +59,10 @@ static int periodic_saves = 0; static bool mutexLocked = 0; extern double g_fpsScale; + +#ifdef CREATE_AVI +int mutecapture = 0; +#endif //***************************************************************** // Define Global Functions to be shared with FCEU Core //***************************************************************** @@ -323,17 +327,107 @@ bool fceuWrapperGameLoaded(void) return (isloaded ? true : false); } +static const char *DriverUsage = +"Option Value Description\n" +"--pal {0|1} Use PAL timing.\n" +"--newppu {0|1} Enable the new PPU core. (WARNING: May break savestates)\n" +"--inputcfg d Configures input device d on startup.\n" +"--input(1,2) d Set which input device to emulate for input 1 or 2.\n" +" Devices: gamepad zapper powerpad.0 powerpad.1\n" +" arkanoid\n" +"--input(3,4) d Set the famicom expansion device to emulate for\n" +" input(3, 4)\n" +" Devices: quizking hypershot mahjong toprider ftrainer\n" +" familykeyboard oekakids arkanoid shadow bworld\n" +" 4player\n" +"--gamegenie {0|1} Enable emulated Game Genie.\n" +"--frameskip x Set # of frames to skip per emulated frame.\n" +"--xres x Set horizontal resolution for full screen mode.\n" +"--yres x Set vertical resolution for full screen mode.\n" +"--autoscale {0|1} Enable autoscaling in fullscreen. \n" +"--keepratio {0|1} Keep native NES aspect ratio when autoscaling. \n" +"--(x/y)scale x Multiply width/height by x. \n" +" (Real numbers >0 with OpenGL, otherwise integers >0).\n" +"--(x/y)stretch {0|1} Stretch to fill surface on x/y axis (OpenGL only).\n" +"--bpp {8|16|32} Set bits per pixel.\n" +"--opengl {0|1} Enable OpenGL support.\n" +"--fullscreen {0|1} Enable full screen mode.\n" +"--noframe {0|1} Hide title bar and window decorations.\n" +"--special {1-4} Use special video scaling filters\n" +" (1 = hq2x; 2 = Scale2x; 3 = NTSC 2x; 4 = hq3x;\n" +" 5 = Scale3x; 6 = Prescale2x; 7 = Prescale3x; 8=Precale4x; 9=PAL)\n" +"--palette f Load custom global palette from file f.\n" +"--sound {0|1} Enable sound.\n" +"--soundrate x Set sound playback rate to x Hz.\n" +"--soundq {0|1|2} Set sound quality. (0 = Low 1 = High 2 = Very High)\n" +"--soundbufsize x Set sound buffer size to x ms.\n" +"--volume {0-256} Set volume to x.\n" +"--soundrecord f Record sound to file f.\n" +"--playmov f Play back a recorded FCM/FM2/FM3 movie from filename f.\n" +"--pauseframe x Pause movie playback at frame x.\n" +"--fcmconvert f Convert fcm movie file f to fm2.\n" +"--ripsubs f Convert movie's subtitles to srt\n" +"--subtitles {0|1} Enable subtitle display\n" +"--fourscore {0|1} Enable fourscore emulation\n" +"--no-config {0|1} Use default config file and do not save\n" +"--net s Connect to server 's' for TCP/IP network play.\n" +"--port x Use TCP/IP port x for network play.\n" +"--user x Set the nickname to use in network play.\n" +"--pass x Set password to use for connecting to the server.\n" +"--netkey s Use string 's' to create a unique session for the\n" +" game loaded.\n" +"--players x Set the number of local players in a network play\n" +" session.\n" +"--rp2mic {0|1} Replace Port 2 Start with microphone (Famicom).\n" +"--nogui Don't load the GTK GUI\n" +"--4buttonexit {0|1} exit the emulator when A+B+Select+Start is pressed\n" +"--loadstate {0-9|>9} load from the given state when the game is loaded\n" +"--savestate {0-9|>9} save to the given state when the game is closed\n" +" to not save/load automatically provide a number\n" +" greater than 9\n" +"--periodicsaves {0|1} enable automatic periodic saving. This will save to\n" +" the state passed to --savestate\n"; + +static void ShowUsage(const char *prog) +{ + printf("\nUsage is as follows:\n%s filename\n\n",prog); + puts(DriverUsage); +#ifdef _S9XLUA_H + puts ("--loadlua f Loads lua script from filename f."); +#endif +#ifdef CREATE_AVI + puts ("--videolog c Calls mencoder to grab the video and audio streams to\n encode them. Check the documentation for more on this."); + puts ("--mute {0|1} Mutes FCEUX while still passing the audio stream to\n mencoder during avi creation."); +#endif + puts(""); + printf("Compiled with SDL version %d.%d.%d\n", SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL ); + SDL_version v; + SDL_GetVersion(&v); + printf("Linked with SDL version %d.%d.%d\n", v.major, v.minor, v.patch); + printf("Compiled with QT version %d.%d.%d\n", QT_VERSION_MAJOR, QT_VERSION_MINOR, QT_VERSION_PATCH ); + +} + int fceuWrapperInit( int argc, char *argv[] ) { int error; + for (int i=0; iparse(argc, argv); From 3a6c861326fcccb4ed2e63cd7ff941440f15c78f Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 11 Jul 2020 22:36:55 -0400 Subject: [PATCH 091/100] Bug fix for SDL port lock up when selecting dendy video option. --- src/ppu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ppu.cpp b/src/ppu.cpp index ca2ee0e7..0e667a43 100644 --- a/src/ppu.cpp +++ b/src/ppu.cpp @@ -1853,8 +1853,8 @@ int FCEUPPU_Loop(int skip) { for (scanline = 0; scanline < totalscanlines; ) { //scanline is incremented in DoLine. Evil. :/ deempcnt[deemp]++; - if (scanline < 240) #ifdef WIN32 + if (scanline < 240) DEBUG(FCEUD_UpdatePPUView(scanline, 1)); #endif DoLine(); From 35b0227809aee070ce4ecdfdcb2c6df57981ca6f Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 11 Jul 2020 22:37:29 -0400 Subject: [PATCH 092/100] Added logic to initialize the video PAL combo box with proper config value at window creation. --- src/drivers/Qt/ConsoleVideoConf.cpp | 18 +++++++++++++++++- src/drivers/Qt/ConsoleVideoConf.h | 2 +- src/fceu.cpp | 10 +++------- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/drivers/Qt/ConsoleVideoConf.cpp b/src/drivers/Qt/ConsoleVideoConf.cpp index a70bdca2..05104e20 100644 --- a/src/drivers/Qt/ConsoleVideoConf.cpp +++ b/src/drivers/Qt/ConsoleVideoConf.cpp @@ -51,6 +51,8 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent) regionSelect->addItem( tr("PAL") , 1 ); regionSelect->addItem( tr("Dendy"), 2 ); + setComboBoxFromProperty( regionSelect, "SDL.PAL"); + connect(regionSelect, SIGNAL(currentIndexChanged(int)), this, SLOT(regionChanged(int)) ); hbox1 = new QHBoxLayout(); @@ -128,6 +130,20 @@ void ConsoleVideoConfDialog_t::setCheckBoxFromProperty( QCheckBox *cbx, const c cbx->setCheckState( pval ? Qt::Checked : Qt::Unchecked ); } //---------------------------------------------------- +void ConsoleVideoConfDialog_t::setComboBoxFromProperty( QComboBox *cbx, const char *property ) +{ + int i, pval; + g_config->getOption (property, &pval); + + for (i=0; icount(); i++) + { + if ( pval == cbx->itemData(i).toInt() ) + { + cbx->setCurrentIndex(i); break; + } + } +} +//---------------------------------------------------- void ConsoleVideoConfDialog_t::use_new_PPU_changed( int value ) { //printf("Value:%i \n", value ); @@ -196,7 +212,7 @@ void ConsoleVideoConfDialog_t::regionChanged(int index) // reset sound subsystem for changes to take effect fceuWrapperLock(); - FCEUI_SetRegion (region); + FCEUI_SetRegion (region, true); fceuWrapperUnLock(); } //---------------------------------------------------- diff --git a/src/drivers/Qt/ConsoleVideoConf.h b/src/drivers/Qt/ConsoleVideoConf.h index 16b5aa5f..e27d59c0 100644 --- a/src/drivers/Qt/ConsoleVideoConf.h +++ b/src/drivers/Qt/ConsoleVideoConf.h @@ -35,7 +35,7 @@ class ConsoleVideoConfDialog_t : public QDialog QCheckBox *showFPS_cbx; void setCheckBoxFromProperty( QCheckBox *cbx, const char *property ); - //void setComboBoxFromProperty( QComboBox *cbx, const char *property ); + void setComboBoxFromProperty( QComboBox *cbx, const char *property ); //void setSliderFromProperty( QSlider *slider, QLabel *lbl, const char *property ); void resetVideo(void); diff --git a/src/fceu.cpp b/src/fceu.cpp index bb311c6c..96aa9a5d 100644 --- a/src/fceu.cpp +++ b/src/fceu.cpp @@ -1054,38 +1054,34 @@ void FCEUI_SetRegion(int region, int notify) { normalscanlines = 240; pal_emulation = 0; dendy = 0; -// until it's fixed on sdl. see issue #740 -#ifdef WIN32 + if (notify) { FCEU_DispMessage("NTSC mode set", 0); FCEUI_printf("NTSC mode set"); } -#endif break; case 1: // PAL normalscanlines = 240; pal_emulation = 1; dendy = 0; -#ifdef WIN32 + if (notify) { FCEU_DispMessage("PAL mode set", 0); FCEUI_printf("PAL mode set"); } -#endif break; case 2: // Dendy normalscanlines = 290; pal_emulation = 0; dendy = 1; -#ifdef WIN32 + if (notify) { FCEU_DispMessage("Dendy mode set", 0); FCEUI_printf("Dendy mode set"); } -#endif break; } normalscanlines += newppu; From 1a3427685e82a89be02563a85be89bffbe639f10 Mon Sep 17 00:00:00 2001 From: mjbudd77 Date: Sun, 12 Jul 2020 09:00:17 -0400 Subject: [PATCH 093/100] Added logic to print shared object dependencies of mac os executable. --- pipelines/macOS_build.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pipelines/macOS_build.sh b/pipelines/macOS_build.sh index 19a9fbd8..f32e52f4 100755 --- a/pipelines/macOS_build.sh +++ b/pipelines/macOS_build.sh @@ -63,3 +63,13 @@ make install || exit 1 if [ ! -z $APPVEYOR_SSH_BLOCK ]; then curl -sflL 'https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-ssh.sh' | bash -e - fi + +if [ -e $INSTALL_PREFIX/usr/bin/fceux ]; then + echo '**************************************************************' + echo 'Printing Shared Object Dependencies for fceux Executable' + echo '**************************************************************' + otool -L $INSTALL_PREFIX/usr/bin/fceux +else + echo "Error: Executable Failed to build: $INSTALL_PREFIX/usr/bin/fceux"; + exit 1; +fi From 70a2b3023a6ff26775d5644a7cd25fa9e2433e6a Mon Sep 17 00:00:00 2001 From: mjbudd77 Date: Sun, 12 Jul 2020 11:50:18 -0400 Subject: [PATCH 094/100] Added logic to generate a mac osx drag and drop package. --- fceux.icns | Bin 0 -> 1770 bytes pipelines/macOS_build.sh | 22 +++++++++++---------- src/CMakeLists.txt | 41 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 51 insertions(+), 12 deletions(-) create mode 100644 fceux.icns diff --git a/fceux.icns b/fceux.icns new file mode 100644 index 0000000000000000000000000000000000000000..3c7ef062b453ac7cd3143a2c69347d29dc4ad0ea GIT binary patch literal 1770 zcmcIjOKuZE5Pgn6LY$({02`Kll$KaU1U6jYjb~!w5C~Sthn>YD8_s~#JER>vuK%%9t>8kgty6U-o`0~wLVDjtm==n3?;Ag@$zz-P52*h|MXO2OPGAR)Q z@*Rf4;?x2aM=1f}MBGZdR%Dzb;S5cBN(P$iLui0y6^VnCZkZrtiUY;p=fbxNc!WBK z=AuqH3GmJvEpOIgtfYWI-(VO5c^(Gd&v350PQwC?5-tt#{)e?(o4Ekh8RKW|frg1! zsN)T)_(l6h=c^7dhA}Vt-0#S0ETx8XfOAC+=Qh+3=GN7q)NoS6t<<2YQE`&BU}(VQ zfXgh#9n(-_(bOPYHSR|A-UX?lDSI_E7mcQv?2@d)l;Z$8=Nk-6krQpUsvJv=nUtC9 z+i7FkNgC%QjdPMlZPICQXVN%H<0OrfH2T)^3t$XmN}7^eq~TZn=-1_G#Q16LP4FZ7 z`MEhi8%&vpzo%4LpZs2v1K!?&O-_zt6qQ~NPY*%+lp|1-1`AexhGW9p)}*ov)YPN6 zMCFryy@YQ#dhz-dFnWT&TdAxqSsnBT;{njSZH?aDaxli0@G7(q*Pm=f-gf%``0fVw zO=$Rz3K@Q!P~dHZ9%>I8+C0Fr+Yz>57Bl=YY-cvyD&! literal 0 HcmV?d00001 diff --git a/pipelines/macOS_build.sh b/pipelines/macOS_build.sh index f32e52f4..a058d91f 100755 --- a/pipelines/macOS_build.sh +++ b/pipelines/macOS_build.sh @@ -6,6 +6,10 @@ pwd uname -a sw_vers +FCEUX_VERSION_MAJOR=2 +FCEUX_VERSION_MINOR=2 +FCEUX_VERSION_PATCH=3 + SCRIPT_DIR=$( cd $(dirname $BASH_SOURCE[0]); pwd ); NPROC=`getconf _NPROCESSORS_ONLN`; @@ -53,23 +57,21 @@ cd build; #$QMAKE .. cmake \ -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX/usr \ + -DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX \ -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \ + -DCMAKE_PROJECT_VERSION_MAJOR=$FCEUX_VERSION_MAJOR \ + -DCMAKE_PROJECT_VERSION_MINOR=$FCEUX_VERSION_MINOR \ + -DCMAKE_PROJECT_VERSION_PATCH=$FCEUX_VERSION_PATCH \ + -DCPACK_PACKAGE_VERSION_MAJOR=$FCEUX_VERSION_MAJOR \ + -DCPACK_PACKAGE_VERSION_MINOR=$FCEUX_VERSION_MINOR \ + -DCPACK_PACKAGE_VERSION_PATCH=$FCEUX_VERSION_PATCH \ .. || exit 1 make -j $NPROC || exit 1 make install || exit 1 +cpack -G DragNDrop || exit 1 # Debug via ssh if necessary if [ ! -z $APPVEYOR_SSH_BLOCK ]; then curl -sflL 'https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-ssh.sh' | bash -e - fi -if [ -e $INSTALL_PREFIX/usr/bin/fceux ]; then - echo '**************************************************************' - echo 'Printing Shared Object Dependencies for fceux Executable' - echo '**************************************************************' - otool -L $INSTALL_PREFIX/usr/bin/fceux -else - echo "Error: Executable Failed to build: $INSTALL_PREFIX/usr/bin/fceux"; - exit 1; -fi diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 05207915..6ea527ae 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,6 +3,8 @@ set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_AUTOUIC ON) +set( APP_NAME fceux) + if(WIN32) set(SOURCES ${SRC_CORE} ${SRC_DRIVERS_COMMON} ${SRC_DRIVERS_WIN}) include_directories( ${CMAKE_SOURCE_DIR}/src/drivers/win/directx ${CMAKE_SOURCE_DIR}/src/drivers/win/zlib ) @@ -410,9 +412,20 @@ add_custom_command( set_property(SOURCE ${CMAKE_CURRENT_BINARY_DIR}/fceux_git_info.cpp PROPERTY SKIP_AUTOGEN ON) -add_executable( fceux ${SOURCES} ../resources.qrc +if (APPLE) + +set(MACOSX_BUNDLE_ICON_FILE fceux.icns) +set(APP_ICON ${CMAKE_SOURCE_DIR}/fceux.icns ) +set_source_files_properties( ${APP_ICON} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources" ) + +add_executable( ${APP_NAME} MACOSX_BUNDLE ${APP_ICON} ${SOURCES} ../resources.qrc ${CMAKE_CURRENT_BINARY_DIR}/fceux_git_info.cpp) +else() +add_executable( ${APP_NAME} ${SOURCES} ../resources.qrc + ${CMAKE_CURRENT_BINARY_DIR}/fceux_git_info.cpp) +endif() + target_link_libraries( fceux ${Qt5Widgets_LIBRARIES} ${Qt5OpenGL_LIBRARIES} @@ -423,7 +436,29 @@ target_link_libraries( fceux ${SYS_LIBS} ) -install( TARGETS fceux +if (APPLE) + +install( TARGETS ${APP_NAME} + BUNDLE DESTINATION . COMPONENT Runtime + RUNTIME DESTINATION bin COMPONENT Runtime ) + +set( APPS ${CMAKE_INSTALL_PREFIX}/${APP_NAME}.app) +set( DIRS ${CMAKE_BINARY_DIR} /usr/local/lib) + +message(STATUS APPS: ${APPS}) +message(STATUS DIRS: ${DIRS} ) + +#set(CPACK_PACKAGE_ICON ${CMAKE_SOURCE_DIR}/fceux.icns ) +#set(CPACK_BUNDLE_ICON ${CMAKE_SOURCE_DIR}/fceux.icns ) +set(CPACK_GENERATOR "DRAGNDROP") +include(CPACK) + +install( CODE "include(BundleUtilities) + fixup_bundle( \"${APPS}\" \"\" \"${DIRS}\") ") + +else(APPLE) + +install( TARGETS ${APP_NAME} RUNTIME DESTINATION bin ) install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/auxlib.lua DESTINATION share/fceux/luaScripts ) @@ -432,3 +467,5 @@ install( FILES ${CMAKE_SOURCE_DIR}/fceux.png DESTINA install( FILES ${CMAKE_SOURCE_DIR}/fceux.desktop DESTINATION share/applications ) install( FILES ${CMAKE_SOURCE_DIR}/documentation/fceux.6 DESTINATION share/man/man6 ) install( FILES ${CMAKE_SOURCE_DIR}/documentation/fceux-net-server.6 DESTINATION share/man/man6 ) + +endif(APPLE) From 71f64529bf09782003d1303a420c0d08acbbe918 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 12 Jul 2020 12:33:42 -0400 Subject: [PATCH 095/100] Added sudo calls to mac os build --- pipelines/macOS_build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pipelines/macOS_build.sh b/pipelines/macOS_build.sh index a058d91f..7e82d3d2 100755 --- a/pipelines/macOS_build.sh +++ b/pipelines/macOS_build.sh @@ -67,8 +67,8 @@ cmake \ -DCPACK_PACKAGE_VERSION_PATCH=$FCEUX_VERSION_PATCH \ .. || exit 1 make -j $NPROC || exit 1 -make install || exit 1 -cpack -G DragNDrop || exit 1 +sudo make install || exit 1 +sudo cpack -G DragNDrop || exit 1 # Debug via ssh if necessary if [ ! -z $APPVEYOR_SSH_BLOCK ]; then From 44750bf88fd980ccaa4fd5e0d4555e06c8efa810 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 12 Jul 2020 12:53:41 -0400 Subject: [PATCH 096/100] Added a higher resolution icon to project. --- fceux1.png | Bin 0 -> 38229 bytes resources.qrc | 1 + src/drivers/Qt/AboutWindow.cpp | 2 +- src/drivers/Qt/ConsoleWindow.cpp | 2 +- 4 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 fceux1.png diff --git a/fceux1.png b/fceux1.png new file mode 100644 index 0000000000000000000000000000000000000000..f4966c09a199d64f17d7ca2421bd53e86eda469e GIT binary patch literal 38229 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

Ekn;jN2!>$te9Q8s9)omsg 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 fceux.png + fceux1.png diff --git a/src/drivers/Qt/AboutWindow.cpp b/src/drivers/Qt/AboutWindow.cpp index f7da8faf..4d67090d 100644 --- a/src/drivers/Qt/AboutWindow.cpp +++ b/src/drivers/Qt/AboutWindow.cpp @@ -41,7 +41,7 @@ AboutWindow::AboutWindow(QWidget *parent) QVBoxLayout *mainLayout; QHBoxLayout *hbox1; //QPixmap pm( icon_xpm ); - QPixmap pm(":fceux.png"); + QPixmap pm(":fceux1.png"); QPixmap pm2; QLabel *lbl; QTextEdit *credits; diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index ef93bdd7..c9bc21db 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -36,7 +36,7 @@ consoleWin_t::consoleWin_t(QWidget *parent) //viewport = new ConsoleViewSDL_t(this); setCentralWidget(viewport); - setWindowIcon(QIcon(":fceux.png")); + setWindowIcon(QIcon(":fceux1.png")); gameTimer = new QTimer( this ); mutex = new QMutex( QMutex::NonRecursive ); From 08beead25399f4f21b0f94ec8c5a9a3124727ed0 Mon Sep 17 00:00:00 2001 From: mjbudd77 Date: Sun, 12 Jul 2020 14:10:32 -0400 Subject: [PATCH 097/100] Successful addition of fceux icon to mac osx dmg package. --- fceux.icns | Bin 1770 -> 874096 bytes scripts/macosx_makeIcons.sh | 34 ++++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 4 ++-- 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100755 scripts/macosx_makeIcons.sh diff --git a/fceux.icns b/fceux.icns index 3c7ef062b453ac7cd3143a2c69347d29dc4ad0ea..938275fda8560ffd72a8830bac1c7bb2f9a83de4 100644 GIT binary patch literal 874096 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%0A?Y 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%0A1&>x9I{!m@MAB=n5 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%0A?Y zW>PMWx;-VZ#XbA(4cKx?0kUz208{V}Uwk=vOh@>S*VD7{#bL8?RW$~QN zfM?(noU)xyx-0JDVHCXbt|ai*BoO;+Y%_ep{oTWi+w6)`@bcef-^9OP`itm}I{??4 zmn>#(Zt@8a-Z~dhL$AaCL44}CF_TC z;@*IGnZ<2?yx@YIUbjB`aU8|#f`IqiAF$j10UHb-u{7|2S7jG6;@d714~}x3@_)@Q zM*4IFp7N^vm1DKf;rluF7I14mQ`;b5)_9k~HX(n_^rQTO+|!mJ&45+{hR;5oA@tk3 zi!MC0^zB$_Y9?TcQa_=od5SE!EjeaJqH}=T+Y{qX0PH;q>L{ZwVXFcw%_V3n@Ja$J z33L*$15j^{!0WA(lUH0g|N3%cYs$MiV?@aeoek6_gUT7-12|_yv^Ux1>vS6&PdYe! z%q+mO$*b32O-_&9smy^L&plzbIT>(u&533FPGz33Q{8*R-H~lW(9ocs_}!?d`Gd&n zajOJMc7?P^hW1uZ**td6z6@o*v$GRFj||4rK#N?Bb3Y@{8q=yF)wVA47ZYQ<;@t*c zhBJ&)>6SeTi@d9SRp4nwO$v1At3>Vi_@~*}*<+@Pt_?R@x>v>fEV>PW(g4>>f@Ump z@rA6(^yoF8ti6a)|1N9wzni|CJmJmwHJdHn@vrJO8&aR)QSpC;!gr(FpJp4O-2Oi< zAM#VVPaXM#=dnIbas=n4Cuj>{gPwy(v&y50bn$s5A#;)Gtl4bcpTbX-EU@Wf%Eu)IvQv$9j+jKhppP$Ap zwR1C_o5f*u&%`RpdI5&B1AT$sq&bFE{G~613AOwz!m0ROr2|)3D*xm*KIPl!#BF`# zy?Bg^gFvpMk{3<+W}+oX*PZ2@XpIi;HJ|w1yqa>?Kc8#n_1NbvLQiG7*ruSQ zofC7~-zk4P0d@xdhT`{Dydz}kdiF-VULbZag6<_IGDcYOIrcA#R=A78zBgDEqzPv2 zsj`zj`)tR+H}NQ|1Ad;2cu1Ig0h|eN20$6xIgR4z=Ic5_k~ z0;#m`fw?gQFn#&*eDleZDf_06eeY;&4t>{DB3`KCUVt`Ii_#G|Ja`;Cr8oWu zdvDStS(YVesjAIpZtgLMM`l)KbvIRrGy(#fUbP5o1lF+OAMh9WMeNwHqeUn{Xj(u7 z>7hEaE3z_U%<%Bh+~!gFzH{z*@2Q%aySayZjC#%V-TB;e&mGRWGZ&Yf@-Fx>=b@bm z$o`4R*4RbOwY982=W!)BV0m`gFg-P^ldmRT^egwWFZG)#P_!x^vqUHuaH?qm>AMyK~DgHm6Pey-;k-y6T?0#<; zD=1WMF#cjy(ZIbB-?%}O^7+HrWvu^yLUHb}yz&vw4;g%HQEt-DBa+fjRq@ld{4Oc* zGo?UPbo-j2YJJbp>9%GCfT5Z`;I58eudLXQMPEkuDHq^%V9y%ou4HEcRK5!k$E6Se zwzlpXj85}_X=c`&y$c}1;mZ0cK}TDY?O;6azIJoq$#E_P1hC3fWilN3lzZ8i`im(r ztPDjv^k9mm|$ZC>D_Q3f-b5^ zR{%rR?BO?bFSAjFA=hu5-(`$cO;;H49|o`PtdwRS_nB~KevIy|cM7RZura=1;>~)d z{LfCf3*UVz{N?6JOifTQ*;51nPr0~!;@bQN?DSuS>3_U&Il52FaeCTy|5bj5w^bbT zdB*Q^Cb|B^6u=)506yiCp9e6uV{lIFGv}^@XG`j`NnR?1*pjiK0=M*SJ|T5n3pI@K zgPSV{9o{W}F*5^pbqrO1mqfnd!k-Ih{Rbj?55RrgJPq(MbpM*db0#3}66gRzJHl81 zkrtnsx~Sh$Eh(_1z(NYl3jhXUaCmhNV?Ur%yn{WvV0z#jwO=qWq>0hlsz)bHN8|=U zX970Xw~4|@W=2=;4anny425i_ZDi&t0oPnrabG+83Sw7f>khMf4Da~NFq7VSX?g(# zZbL(v-&rijP!3FQdnf*e_u_k;)6sBaFj2;&HOGFgryf0U1ibFIz$M^TM?TBiqPp0l zPjbg1CrV6ThY(YOu?K$EJz*;dG$mY*qD~QT;@mv5O(DE8dh{ZoOJ3`9CMsUCBGJ|e z!BV&0bj;s+p_|=5{}E4c3X3p;9NA;yqABa#Dx>=t(Yq^OrcbztA26+JY%*n8K8Vebh0`;TG=HVe21JW7YszYX}++PDMZSm3V1iV>cRWVWYp~mcL)qVt$JN;3Get z`8Sl$_CA5}f5Yz&v>bn5GUfjzqgfyJIY9uBnpLmOYmEGj+#GWxjJ>Ijw&l?DM&3Es zAHTJ)4~?$fOn@Y46laFS>HX(W=QC*cE?t5`fEO$IyT>fRyOi&tyOY{xz%J(l!VHX^ z_tNnFP#{Y;+tK%v;xd)*LV=+GQ0<1z&l6d(`G6<3!YjrN}XnU0x9N*w7&*C&(D+XHhZ0p1T2@&*UnC-`9!S8-ZnWc;F)*JDEU+Z=)p9* znm^%|rzmyIJ^d;@^?FcBVKGVodq9N0I?}D z`&_HAtQ)GZwi47# zPmwTHE1-;|6ToZh^PUW`o=n;%L^qZaAb-Sl>Rx#Dz|=WHiqrRJ zZr}^uH|#myNS$=LUqNyz!!I1w1D;xg8%~%b%n*60(ef0SQ&rJF;I+kf5dwaT0N{1C zPDjhw-LdX%exI^<{d<_dYyA%yxjuq<$((X`fiRNlrc|lTrh>;WToqlUxBCN}e*A{z zlPOCnE71NOHUcUHypR3>L2eCmc21P*FPwHih3s2K*UG8d<4++2^EldfR39_%_p0`5 zglPae_%{S-&a-`1g{>C#Vq}H_Ko@d4T|0(Bf6DM_;(vHhSm)gKcYL(R=BR_{fLFL0 z*f#)DfkvfmhX?X2yc9TQYW3ZBe}y1$LPKVQ4;uuJiC;4aMo|dxu7EAx5^zs|o39*^ z4lfs)sXdjqF1?1rQhPB4=IK>*G?sq+)M5%9rfQjZL~e_j0B^xt;mP4(-VIJguL_t9 zR$$5GCm!T3hEL_l(Y$&l@3&OmQ;&inAPN13<6(K=f`gPBd)jlc`3~w zneuHB<3nW9v4C6M6` z5d^-4ruU%t9cX5`JM-d3z#Yov96`%cFPIo1DDWEn!@m6dAQXuDPRcW7vj~$eKp86L zqQGy_?Y7B^X0%@;)UR-Vi}(q8n9R`J`kB&tEGknofqQRELjj-*MMFD+>wk*F7MZk- z#gwg^r;e{K$0sKU0B1*2u2iKj_cnl1cJ8*plo{66HlxwL|K4w4?71H6Y`_VlH%E4f zFw?9smdP|nf;oa?qYr|>1)cs-*?rOtgj4HEhu%x`EhsQgH|aU=b`Db=^CqM-0Wn1n z$uGIfVH+VJW&&DGtZutH+!)<6YhWDL=@kxj^GfJg(~pihtC>^y{yc^#^LCxyt9Lz` z*S~h>dcGS(Vf+dPcJ2xQ=CgJ3y+8t7+;k4NnbtB(n1F**)+GHjK?hOer%mGyyZ-MY z1bEHw2aG&@=*ODwX@s4|guN6_|| z-yM1&b`7y1(AgJvsiXkleG0?Pl@<3E$t;8X2q<6~`}-*?yQFC3FUrJxCL@v&<~ww+TC=_RQ>eq z^pN}gpT%*j&8=N9N$I?L&@m(ZqDpqqUZuJ|dgq;wV@be-TpBn$d=k^QF@nQQCgIxi z2Dc1yB{2>;rK>QIL~bY!h!8m|%;(+1bNRWE0z-NYXc$bCnx-7*qe90gCv50EXFq_~ zI{UJqGduVS`RGmmp1lHKylLN# zk=A;B<^cxpwbFto{SJK*F8nLA^Y(Hd=qU&g(6Ba2zzEd|{B_2b_rd)gnE$U~I=lG! zfR8Wu{hsxHude;~F#dgX&-N>-)>^+wMDqBlL@(8K@wM}+Aiog3@*Q-dorfKI4eh#W z_qD{Ym!r3V3x*Nv->vrqow>T+I>}d zCEA#~H<-gAD9z$HbkkwzX1@~t>N(pQ{b87~^B4VS44mx5`KhuaGG@fqX(#}+P>gOK zKJHpwrXC@zLQkHv8>HVloLkQ<*}+PIIo`$~64l zyZcd_)@S{W&4CIMJ_$O7x!Ba>;S<(?Hwhcl|M;E4eDcU(!pbVv;cv?3Bk%~r^7Bd* zke>523>rgXw^_;KkB@m22m3m+0A3mtPYYAlv6l|r4Sg%@&R^T&2qHA>xg+Y(H%MVtkDa=*f`lRme@6h_7vnH!UR*6~nvKe{Um~;o{ z__Z*r*f;on0$YC{8vKe@vO&CW5da+h|7%A6kHPErSF58lcBIFpG%y}V{=?)8jThqE z(p+lSDIopql%7HBQ`Us~E|1R@bqt!$KD$&@|dEkC!Sz&yQ~J#S znDc)Hs~h$7xpcRB8PSs5H zow1~6=Trq4u?C+mz`*UtX{;O+#${iOZTVK{#i4?J1~GU9#ZcxUh;nNYVlZuZ`xg7l z&|HqiJQM(2ZiV^BtU$Q44Vm^baS-JQE|qNd>S?nq5&&xc{%pFs`jAxq7A*gU@c#tJ zYXG`BJw2E_X9eKy?)#u>B8&mq>=#qKw8TIR2kaGGjG{EPKn}Qo98O z=4m!hOYN3kjMynxYmiir{Q#8L(eYt0_tTR$)eoaLMz?Msb)rQgW)m4Z7_A6PtExf- zR92fb-|A}wRO_^E72S#&I3jeCu}^sA?;dRBw`~4X0PuXjXJY@4)0KF^?=v2*IfwJ- zmAsM)D7DHW!K8r%@HV6||J{44eK_`Y^F`7jWKXpg( z3IK|~@Jgrk5dhr(6c?lUwoVBLx);4$il(ZQ18I*~WB25?(5K_om7@up{Ao;q+#&&> z>q;Lzdi3n0d-wi!Wpj@4WNL=+5r@tm_j@29Cs` zARyAIiVz7pH+GF#0=UOzGdt+JY&1JyCSaZQ;-i2Wf&{rR^Bxmi<)pyI=61{iI2+)) zvNHj>>Bli_P>)xx(=@YKW>c@~ zu*h#dPD#jv5&e9S0N%ms471MKD&2-uwhDJTx;Eu z{GXvG<4<6flJU!2dWP_uenaY!h=5hEL6>TCcP2*oS`y|J?b#q_(vYy}W;E9s$IgSyndD+MHO6m}CaTS-K# zPp=oIP-XL?Kq)i6D8#GznP%06Fe9i^S0_~PO@x?DCc3P}Ci|Ev=Mxyt9;419bY8)T zDyDxeF{A(*4t`JtJZ;PG>rkLoj3)HeHOacl=)GEbkKYL;Rdbn3szV$*UX|_dCiNn} zic@gPKGZwVX_&JHbJDHcO-^vxavFX^ct3!-uqYhMK1AiVZo@cTt{VY@Q3umbhaf#4 zN9KyL@tQ97X}e#=<#Ef-y>I#lKQ%nRPJx*8)Ia{4zd;O_KL##`F3WPXdO{1KZ_5b) zX3aQEbH&YCzX9Nv{5sK~OTe;9r9gf8$8W#=_Wu3*eM5Yq@yn8qg4o zRyn#yK)>>Tc`8585Jj^W(cwjYQl((rM4^gb%`%ykGcuF`juYN%NG6nhz2Po-+SwN# zLlE%us_JD?3aLeKuf;8giq!1o+`+i!kUl!|liw82>7r-=tRwY!TuesK6ntECCn03? zxH&B!BYYV>GXP$4t#`}_1hB-d`oy`z-06FnGL;6Ikoqxw6LbY>#5gOP`It zV7B~lbgU4-zy>4&IWFc~V-UYKZ4$sD0U%Hqe86LR0>k}+68xKn1o)1}Fy66`{&>x= z=la*z^D-YdC@?T5LskY0-X#HuHdpvo6rId`Om85Mtg@G2duNx5#3dld_dIRDjDTHo z5+JeI&8G~RK04EJG={M=dd)qG6jl;jkZB> zfH>?Zg`2)yRmGRyfDR;lhhYc7E7~tYuRd>4X6O3eML{|@;B+KxhH|MSU?Pwo*U;28 z=#-<|+@)RRh{uge$od<$g~#-w7>htv%!)T}H%_@#{CRu15A}kVZrV!h9E57Lm6=Ni zpCn&_KgA|J89w|lM*WTPPhyQ9SkOv%xd#CJ8bXpX+#@+>0&+&c<9z|24fie&$oL&R zyF9+S<}5lwK+GnvS844*?yGC~21uYX=(+GW{?arS&j6&)fL^Dkr%yNo{x2qLD}TiZ z|DOkP+zNAcelk73JR9vle>i%+_i*&?dmCdBLckz1GH4mUx4pSL+*{>nyphR7N55W4 zyxbW0?)tBZbA~{%GkUi7fX9R$Fxo$jUsN!N>WhNHa>>AV1P+f5xj~Lw<>DOyrgW2v zk~fmbZX+=7lU$nK90jU|6~t;?=w*x`tz0Ttl}~Rk(+&Czumxcj;W6*lqB#RVn;mUk zoQ$?v??1P$(kTC7vKiCMUWReW=-+b>Zl$T(x(J0uZVRwmI^B{2!y+r%8nxW3EUHD@ zEf2#D!`?E81?Eh7%0XAnu= zB(q=J*dDF#>@)$OF@M5E_yKBhYEE~Tu|bEG#zwuI5%As>nZKLtV-Fl}?8sktc#Lm@ zy>sih`{!o3}G7nt#wRE>ky&&5dI%c=r%I|B(`x5pvM&E zQ{e4k=85z%ccp+hyT8xRkKGHvx_zAjNUB&#yvSu`g>_Xb&V}=+(M&VLhUyT60%=Z` zuu5iJ64*Z5B|{t$JUw7agHD)m-V|q8^A?$gZ0l=G+G4+8v>;*Qlt3onwF0T&upH3b>`eN*(KbspoA7JGH1s{@;CMzr3 z)DM|9qjZSZ3j&6d$TELT3I-6Eux5Oh&4nB5+uR`d;b@PUfM?7ExHrHP19E$#ct=27 z3IbA|J~%wsM_}*`c+NQhYdI4jU4K}WWqSh-)ncRkZwNDVzHPXQvoL%*dg+hqkOp^7 zBYMU--%5XYnlB65WDRMk`eE!E))4iD$ryO4zB2`ev>npC055VYzn_ABTl|M~80M?u z58W1-jc;3w!4tK(Gvj7I8KeHzuLh%U;j?p|O}&Ae4BfO zd)ep4jFm^>)a>OPt#t^z^XMJLX`s^DyA_%aHY0EBLzC&}AQv9S+a)lwL0^yq*jV3} z@9`52=@YXc=)tkzjXsj*V0CpR*XuXALDhlm*5=zQbm#Mr!2cP<`XC*ZWmt!2_A$%6{kuBPqwOI8z+Y1EG3^vKLl2JqInv+Y9-L(GJMc(n zymN#vpVNJv!LNdWqkIJbj|&Pjmtm5CF$*6kBpw#u0HZK#&(P+J*L~_(4eqxQ0CJel zawy~d-%(5cXK?>-7%Tm?B?WVzGAh4%`sC}0cLMnG+nqb_u@}HAI;2k`Ec4%B4MT)I z=9e=8?MYV`KSH^)F(n!4>U{wcqKNR$J0FamKYz?U0gpycpZz&5A(GjvCWLd=WoMV^ zTxJ4}4i7>gIXz|rA!(M9fFfq0b_%Dgww=q;@O@FBivIgb&tk7MTNSu;7cTQiI#1cf z+~%cXRHJ%!-Bf3o z4TLTFw1FNBf&^=4{+K#VAQ+JSYxZ>!rwAqZsU z-~Eh$NhQ?8ucbh(ODPDci6w^3vmJIjvI&schCFf@K#Uv}P+bAU*yl{eTp?iaa6yNS z{!8@>rGS;9R5RNW{I#Z3zDs>cfgdjgsJm5PI{_d@@aeAG*xQl}2Sc)|#}vQrEmys1 zkj>`lWnQUT%V_bcod`?d3Kas(8|pB~8F9deMkP~CC_l)Tv@`i+nJ!Df$^$2FFO9#z z5!Z_pPD;Pv=v**<*Zc{?oN~r%5F^twnSv=pX9ugU&$~&_=g{4mzr~|@3Im%Qmsj7~ zzC$<#fE?-Pv*`#?xCKpRmr&4jRZW9Wh83?gl+{6Y<+O!}xLte;D1OKUFk8UOh(p~* z0O-~WzJB!RvwQbO-`?B)_@A<^@1G<6+@qr1y1IJ;WX>1N2;@vak5}#;$m4?&feO_&IqdF!FxuI9H*W>x&VVORIPb`- zg1#poL%`-5002M$NklR)zM^h_{a&GER42G88{ms7&Ygas054p5r!(;Djw1~{LnqJn=@ubRbk)&A5GeT*4-)|bAChaalXMPB449vAW^xL zVH;l^rY@uB=UTq};L;I2c;!1KxWV{iV|g1O#`1V1o;eFa2jdEpMckbFmk$P~p$xNZla`G#fX&=jJ~NEI zrd+=a9fM~E*33mjyvRE^MSh(Hh%>Z75C;Ae-T~mDlPi9W#J3RuGNt^U@9mAQcDBaP zVd2j}G;Rj8EJga(!0f|f&=Q7pciLE0Oe#k0ge%5zt?oAX_SeF2W|rkqS6mpTU~y^wg9I*D za|93pVS}~&Ev~nZUHYESM+lJT#qvlKoRS!gE_0c-{Q7dyvk0bM=8TlQQnz_nL5Swu z$HR2%QvjJleuW?hHLGX5m;O6y!v8|`<4%C-$4GO!UvXxC_2l$${L#n%c@t-pRz9nGhYtn)0Mr|#L$joat)4O**K<5TGrdr%n@aWO!aXR4S z_&J5c-C%AAAQ}CQ;~oJkW`2V>X=7%z=KUkYTMvfQKK$tZgK ztRYMFi=sdkxmBRl0=Mv-cwc(#z4R@ag%E}24H*G79h14K&Dst1deHnZzs^SnDLejK;nWfa4H5LqkGZ| z<{kq=1%Srr4ToRmM>3=+Q#4p}pa|1<%3fVYZ82hw`m;GG z%^D0o;Fm*KB2`_crsYpY2JX)aa0d5a`Yk^a(fpbBpn)?Rm>sBw0MIdf zXPRaF2m%TQ@QvWtgj*p!q6DGT0zE#?kGQ`re;z3YU&({JzP0&2;_8e_b5J}T_y%k1 zY_Di2+5}dOaDX6>_~3|6YI=m{Z3O@W*RXuFcXafJ_4W0=?bX%4qB8xL5Xz(YYv(5i z)2oZq>C>lQGc|HKx(`$KmLltrR4;+22p~ohUm{xoGG}K3+(?)bCDK)(Sp?Ez9;#4X z0^m}F)t%A(`L2AQZPTvCwrlv5FQ_kuD zjWl6$@ki{Ihh&a2Q8#7xQ{(o-!DMTsAK_)ZiB#gyqmlWok!ghqugn~@{O=2ar_ zoww7fq_s@XCGMn80Bt@d zl1f~gDYV{R?xpwnE0@%Jcjy6n%y6HdPo1g2$HZOY@G?KA*pH`|mnX!FNVgRLX42c- z+&m#2Zv^Bt!1Ms~4(2rr&Wdvy_xE!epiK`M*#fM5hPf<>U%=1Cl2VlNhRXq|AbOui zoOFkn**R>{DT)(P!IlD+IVnPG*~Se8b%chOL+pz58T-%R01azA09O zFHibkjihEmF<{hXdhS3EPQYL?a6QKjhuEQS9GS7W8mA#(nkit_tcLu=!6n=H{CT}@ zFn&k;j_^5VPT|%1e9qJ-T?HAeq2844^uw)Hl6hZ4yuK2L z`bjOW=*RIPm>js&tXN7!Kjr@6J;2=YQO zOV1ya0v4ZTSmm`48H%)(>a2Gw{_0O=J$qZkwSQ=d1cSw~&fNDq^Mf1HCz+t(6UMM# z>7klx|5xrgrEgrv^QbnGtY>8N>R9~OgbEXjK~c+rjDS8=sF!h+4d%|^EJn@2?Dfaj z{*ExJWN2k>2#1d!?elJCt-`CP+0dyfeCf0P;^$KF^gL${;_N**xxXMr^liBzHrf$Y zH&x^og2vJXOneQxDDacEYo*T=&!=Y!#n{&ToNy7y{Wnrk!L;xM%fj;T!B@T zv9t@wQ5NUCYjSk-j6wL($ai|oW28S~clay17HR3LUPI^&3{iV5xpN6tHeqEyg&kUYfJ&{&L8% z%xO=7Ru_u#ga>_v{Y)|V=$lMt!AsgL%m`b7#KH%~@6Z)12;40l-Mf$Oc$pthSH{n%7V_wu8X5 z#RF#}=w!a&j{eOn8CaecAm5;nW|+Sl_{1MPjaF0pNsXkj@Z}FNogWO|4SWay3Irhl zitD zkC3B(9|H>f$wQ-=h&%0n#4O19`qtKK%>WeAU5c0E^FK0E|1TI-e+bF`nK}22!O8J~ zqw4AY^G6iY+UULacPJOnjq43Q;gZ(?VEt+KYI29VWFRB zZu+AX05pYFLyRyYs@`E$Pxhi|R>_beEvM>*#V=seKlP(k6K!b_y&I`>=3cX-KI?EY zQ2J2U#`*JjwC;q8U)J-U*$14+2A?_N1WsLArX!r|s^uPB3xA{%h$QZ*CZluT);M7_ z+HeV2n9om{-Q`Dj+p9oQt0Vl}n77KkG1A0YUInW)W^i-*9wtv(j`nqTX2gQvp<1aL zW{V>g6d@r}3v0|UkXFusfLb7-UCNo?L@I4KbY#OlaBO-44}8SKi+;pgm9z;oL@UZx z*Mi-mF3=L`es(2;%$7;wCsAt_N3`U7y_ZaE{1N}pPI(FN+duuu zsR1h0>(2lLMwIb$W|zLCmOld#x#+~H5U1cBO*;$Vy#PV5nHnZF&16?P0nblmQnLhA znK73w{G|jN&ie4P;%S!<>Iq|=shF#kjnVe@*=Y4_WAvQ+0t|cRBSEb+O)Dx7m1uP} zg`%vuG$5=q*p;QFG3y!0E{)y)CCyn-y_FVzpkfRs*R|jF# zE?hH|J$q{WvtO}~h`(lc&rt?3LNe({56MQzPRP`h~5fG(lG*b%MA0_hTR}$s=*DZpvBW)p~NGW>erPKlOoss z-i(WRIAfZyLR|3cX2|neQu0KnQTe=;%@gld*7Q{1A0a zWuoAnO~^d~XHD8QR1({Q%u1LNmUaogy?u`>81DdwCtjHec=+f~u|#onxEF;lUKZH; zCbu?S<=WBN$;s&K^n^5+PC=ShMLTT;XoU*5w_Ko+$nx{XD3GOQt(a3v|NN*4Gk;ai zt?-Fd5a!}9tv@IQZd)qRQ)EMqIuMMC%3#-&eTO=s>=VdQ{91T3n6)E4B27NUIOcJv z_;gwUn{WIDbHkI~EYpd!TIdF}7?ORR=58%NM)b{&d!~&Zo29ke=k+*6o=CND3{O6N zf7^#GzfNx%iu+W6A&rcf44%Bup9XxU-F07a_ndiYLW=__nfoPtU@|!+vH%NcredGG z#?68OlRkLWeO$m;WrT0PA7}F^56|99y?R|%>O~&-2vOA3b4@(*2SY(*6D9p!3QwZx@`d9Ew#%ddik{f3Wm7prnFB!;1MOLyaQvTb?^ z^FKa(HrjvwkY|gT{l-1G7c${wI{iBY!hdtNwROsaIvt=_6#%-38b1B>Q%m-A>ywY3 zAX7Yq8o!Z%qGhE$J3SbkA_>Y!l}0Vpj`9L9VC7N!0%e0N`k2v_*sNSNy=5eq77~yJ ztTgRD9CA|aT5SKybIr? z{Y&v*kfo*5kB9@x^ngUZr6G~@Z_zp2K|qG{Qmk-k&c5rV06mHklk zZ3?6GJ5EWv+g&C)jS)V5QuKLk-JCe~w8NBzlhE?3UDf5G0+%iUT8zp=7Zd#S%ec5o zJATEi$8NX_+Ia$;{M0Bs;u)Oq9M`_`lvS4o#!#jLEeHeGAFWMt+I+<`__(bDTR~ur zk$$8funceH4#VizvlG{?7{5B{QXf(PkVeHT$gl2#xj{vl-QZVMEaA35;g~qds}yQN zi0oiwUOVd>GMKD*WVv~hZoZ4-fcx@{B_Zk0to z%HmMuq(+WDC8_@vbbgEVT?@~GIyiVb^wNj-F#Xxggcq!6N(;boK7#AaA9FroTw$hNYsKxKw9PTpa~W2{{8}usFGt?YitZCY>;lQeNxJ_3xr3__EYMA{DK-JIMbp7;{td91J_9R4W;O-7qLT$#I_FXEYItlgte8%*H`SYh%zXLFzqwL?Dy zCL9!!TEK>av66o2uCs2vmX^WS#8fRv6fE70MZSN#8{Hn4;uI#1T&EJ42 zTq9rvY7P8qeG^!oS}$Cf5HWPq*;ZH+$ciB zq~du!F)m$wz>=ymqpjSU*HZflQ6Q`4Oc7d~!{VLEO?fQKe1?_=vZyUG2P{oLoaA`A2nL4N#bj!jOFt#)LpaJ{seXwe85C(gdh41 zoWmHTjC?Xk9pod!8S_Q4=b_!!E`~jpZg@XuKlss}qhCfEV90na%d;oN_# zh?&mo3IL|uO(h(hoqb7xPIuN;KO^A}#w)Au5n!D)2@#k+dHmJ*^yF}~%g%fohST#R z=rKuE?RKEV=@~7Fn zIGS(M*4oXtVN52H@{{=#sHwUNSwiML*hU-jT zG;|s|%N3-+ls|%mC`IL_LOTA7^>G*Me7CRj9u$Rw z;Bn3%h9EFNMo@u$?^b0Nf(dT#>_%Q!CWoT~j>f5sS-)^-pJJp%o0xee zWQ_QY1N~H)b{MaHk`hIaYu@1yP^#aaqqzYxm5f`EhHkSV5*z)k7eT)epyp|q@ZQ{a z4x`8qya|ERS?wGMH%Cxp_y1E^*0*ahvW?Myo5D$qUUvqd@{=`A#t=l=n{ zBgpYzqi<6&m<5_nkxW+4SW7=S+7l(1FEBfyM2zW4h{P2rdPdVc#MKlHw zSn+HpjmEf2z`i5k4&4g{8Y-tvBmY}kttw?6D>qC1M@50GMv0Quuv)w>QR#YztOpr% z`0YasU4Q!KBF%TnU%_}8HIj#uQcEnS>9z9LM%&Sj@VA{+(R8@sQ07W=eq>)bL`RKf z+Sak%C2iT(v~9OU5HNu%V1U{W+0I=GmayTC=q?y|uuN3XRzV|sdWJbL!%%hBGWKhrno z3`iEBDL6XbnX6f{gn7HErN8*k#CZgI)U5C{@SH)SjtR z?Ox)b5VFdXiB7vabrzDiL=?hnDGN-A+_#toproFXcRf#8wI~ZVP|Ze3vUUhoY_HTr zhKUM%u>Oe3${Gp+Ma7Mg2C%2@7ob6Tm9UL8HttjhBV6=?Ow(2pyeU z(O#h;H?^(D)9q`c&Fx*7{Mu+|`!0TKjP&oJuObNS1pGB{us?Mwe3j$dhs29?Wd$O^ zr*tXh$%fmihldNCXi=Y(d`S=NE=-QhtVdG}K3Nf{k zedD^RR$io}^)3dZ41C=P=w5&n4I&)G_5ARRR9nlOHloSVgCQe7Q=5Q z>udiNJoyu9-a3W0a&~+mw;VlXo&A)T{v2_yQb{a(D{rw?Q9u6k7ni<-HDc%beQPNhED9pa zqHj?{JP6j}G8n)Vf&(TQdnToBS_X?$`@+SgnE2V0&a*N2s1uI*W%jmh`y&6WCz^3r zMQ4m2@WbBcMSlkwvnnyqerwhzYR0~iz$5FoQ-rK5)55;GiEq`5oaJ& z;ZteZXGQA5R4@>xqjrBjrp5qglfjt`eSPB&Gpp;|p`smk7`*zruiX(o1%nh2BJY;3 z^nq5w6%FYn!*%wgsF1nWGXg}GBe16QL@z_d%3ytfW;c;gEqvF8o4xs4M$R;xa;oe2 zNG8egO3KeriTil8wYf!pS4X>dnAsp+foc=ZEgex)Ak6xZc*<_`N_pugjU1E;+~f{SuW087&;*0BX16$a)-Iu9CDpFIN&0uGE3CMn(r*EDpi@I$xR z(6crL5s!0w6Kp&yJOd3zNd8sxWjqVzCYy9~G*Vp%OUUVJfcNPGK*o^n5(<7$HpRJFle-C}x1v2`N!Dg30QybO6 z^G7U6T(}g#QBMiQVcAfE@z<>BIQR~e8JcZy8LSE}3WCb*-T*5;bV&)GLkotfHrF?n zN?S=TJB=-7D8$d@3Lg_XJvm?_<6*4(RW-B&^Y*}%OC&!2VkY3slL*=1#7g&}%EoZr zeHdnG{^2N4HDMlus4KHYIUnQ~X_qe5{xnFUZq$lp=wA#!Xi2!D>HK7Cwc~k$CM?ry z1%WP8G|}=4yAc~M8f|k|G2NSHJAh>B*kz3Vwe{c_6_!viV49|A-RRQR%rBHv8Uu9` z{(X=P-_LYpp6qXsSV)7Pdi-SUGW>F9fJ5}OJAffhDDn{fj`kF=3`jKMJGw8Xy+(hQ zqf|%tj{0T#+0W6}v5{|sy->~oXm(H(GXu=hCR<$bfe`E)nxMkl?y0WhZV zB61Shsk~Vjy4z^n;Bqf!0@hczM!qSqxA!1s1soN)@h2K5p-n@)%*DmICkosY$bA8J zBBnL$95UIYlzvO~!&0EiLo6_BEhp=RwW#a{`RS>`-kc28yuJ5(IrFleX8c~Knmfw( z$DbSPB;L%_K5iAhPi@u|?VC?wt#8Fq_g9RsI$Ec|!_Uov?a#Dha~^OX~mnS_UFH#7^EX1#?50%k^XRi>m(xMhBl**l%@2t0qCIT%V40NNCP zL>7ihT166k$Wxeo!WIRkLJ;$Lb^9})sC9aJi|Kr?Mc-gF?>?;5w}R<=tU81OXBiM0 zLXZPemWXK$GZM*XS}{Xrelq1Lah)}byxB8~XWK_1UKz0EAt21%MO+ zOjq~($sHD}c`8ISg3e{TMIPobVM`xpst*nxhfdvQe=8gB#}hcvA*6=^7)c+B+~|-acQ(Y`-4BugWI&t0 z$dO|~BuQLTS*-dnN!&h^g_Ww}S}9Xa`Bcsgd+=~H{1-bs!CP%a9nL?d2 zqVS0+Z}dv9(rkc3t7Bsv$BFiPX}>`_btk+7qDZ&h+u`Uh{9_E1{eejb=8;itz3S5J zof6)_K5wiz_B{bP@{l9?pi%5gAjMd6RH#WNANh9#DFKKZa5RIR`Bc$)@_|%g%RLUl zj7@*Uamrr0t;67jyTOiqN3$USur}@Or!nGZ^zT}=4ByedKg0V==sn{z{mh4LBh8V# zHmwbtbhGXF)6WmCL38^-^PmV|nd)zT@@FuWRmAd&jcl;6v)E`Ejsef7+Z6)ETlm5V zHD9;zAXd=L{{9#NK;@|3r3-1SKu}jJhbJG?K0!!WL1@^d?>DUP5@eYMMBwIM#UWPY z(`BakS&uu!`cP>S#%robK5-DdLM*?jv(tx%PvJ|anJz&tVNTHdGm7H()E%C`y;;2} z0brQIB_{!X4-(HO(<`M92n1D7K2<1@k9e>^wY&R%6k;?|DoD~TX9V=uUS&I^sc!S` zW$)uzLA=|4Ez(q|a0DNt0qSC15Y*2ETo(d7@)AOS4RxE! zb3IIEw_r3-11;NF>!5LuQ9WSj+M;e3v$sAQHudZ23_wQPleXRpm-J3wAoOhjV0P@b zrdY419XYyB=9utJ%dS@y-5c#IrgJGX+nWOSCGAqd+_z7wPnj>$Xp4dwpdD@j`IeuG zU%-V`Zqf?i(dEI6V{egpV`MFJc4xl*hD^Mu2aV7gu6-1f4 z^iu$k*|QFgK*S!0HnKl+%D)L#!}x9#v@V`*o`&#L0zlEmY;DLcN{2 zgS#NO`Ai%%!GpZ{&!hDS0P@od2Bww_z82~wcP@Q)0UtiNysXWC3!uKaB>;hond)l& z&Yg#chljM&tIw%6A237rE2P&I*C>1)>iP3WEK*#I-s3htE2f26gl*-TkY4bua7DDT zSCn#ZwJjQkX|1nk#W?eB{|KaHY6FveR-bHaISY|y8`b9K&gk8DKjBfKcVbDvqm7=q zbmLGc;>Uv+bY7d>Z>_L#!j4lbq5B>(E#OxTEozlLp)9{Y00pWjx}>8XWWhw2tTC)_ zzOblak!+;XAuwm?lI;vL0jhJFaa>@@ELhLevpUhxagzb38Jq}|)4&=Vc8x9-KcKXR zHc!JIb}|lyWB=$|QJ6HCrt8?~!C=y>fpv3jwwvns)MNI}@r`DL0NreB(QW}$Va2g$ zRspjA;CCz4@)luRrjtJ6FA#M4l*ospXTsEmLoeGgY#cErul-Ja=@A(YuqF|8Km+c9 zS}Wv(OMT+4S>^D*I` zOefPX$LCj{@9yoLxC2mdsm*@h)C@oY57a;X^wWnQe)!?>%If5E3gSa{n0`$9tC$%) zpSu@eEW!!{N~&I^lS(lDie#k^!4J*GDtqY}CmA@tIA`Uy;0@y_{elYQdZ3+*Zdt*E zCb%ePjhH368(>@`d+%M>`Mufe3j1@+Tsp)}Ux6>l##9<{Y;3+!;8dh(o$>^86lNR2 zRTYVbAF(T+SeEMhr$7{rYkBn-CHnp2@s?ApS{95QOHH%e{LFdYnUBc^5dIb8I%3%w zMRSRUVk;UdV+NeY`17?m)65Q-zQGWIL&dW_#IZ5TLk5tub+%J}*ll+)?T^2+0ODA9 zXwJ6V;~eQ1@LT8|EW<{f7(~(zU1YE(9P7O>YS-2kW{Tm5op9;j!Z&)xoOghf;fb#K zU;tu%bT=NFj9P)nzEOI4$&Mp=XCYmR^z6Mi?`?0(_+^Bi!LO-t;zoBWaf%i~H%;x4 z61vF_`aSGPuZ+`u3q-^ie&#(A?lo7O&FfHUopCY@<>^S>5&O|`zGpv-6K4Es79~dX z%*;x&M!haL6o`5h%e~Ooe98FZs2@ySb-9Uvfsl5}Y{NnU0Kq`UzkR+P8CYTVAj&Dq zY6km&uK-|~C-I94>Sc~(U+W|NEUQe_I+8d49UnbMSUQX&@3^9D+0zqf`IuR-FTQ^G z@G}yWL8%<+UQ=&M04Ttf+v&rH4=?`W{{7#97b^i*|0z0;?8VK1qeBokGbiYxyv}V> z782QPzXW5(!&%qNJ*HG;zsY~GdrHA>jv0--FTjz5XZX3{&xRPART91hmoQQ|NnBVj z&; zMzOl%p^F-yw1rcADj(%y_=*$ZvD@i}IhYqrtg{!ige$3qcNtgZ+7iMcnLF;m8x7E= z-yDP(x5Nm*}@g1xQ)$Sg7k$`1iOy&Fb`!mZ$mZfK06a&Vfavk8)jtsP9Zu< zPhBW6%@bAA!nSb;FV_@pj7&apeeg%b&8h!mjt9Ca@Dv!A%`G0;Kp5Oy$xDf3`sd6X zcml#a`Dd9_1HckW_j$MSTk3D00$DPYO;o`7diD0x|L!SRU$aBfKy!=wl;`3xH|Ep} z1dH=n9ck!xdIQ9&ofadD(JCFOY3Syt$uPkP2emmmS76op`~_>6&cL~Dub(q!whaa5 zNLSQa!ZTQ!FX6w2%6v7TY5|6iLOELGDQHAqWa$3LkIYua8=JhMlZWZ*7c`d93#h?u z<`87`A#Zlr(Y6EcOt_f7=kDEWV!%$ zJ!9A6K6?Qq+8s6nT0l8vB?vo%l%NC4xzDhyEf1A$s1`NvxNQKMzxBvAiSO1O)6sbpT)tfKXX3O znd4T>yu8ER@D+!Mm41XZP6XB?V`W|o!XSKup)f3rXq(2D>G>D&TUsqlgP1d3SY+z9 zmFOxl1Y_6McINvWt^pV&5Zd+@#0W5jcj1|^U*S7|)c|JXKwRc64aC3Y$HtG{QGJXS zgUOZb61wYg^OD2*^YVq?vJm|jd@xck4-f71fMu*k2z z`1aecc6N3S-oJbI2_<+3LfwHTlj+69)y4Rf;|oth@>N>1(pCkJ{F>b=E3%d9MWidg z#bGU^f}uInNXac{0$dMsozaa)8M2~O*etp%2w}L()`o0@RFXg9lmj!Hltdmiq(`CB z}CA9GaqLIQs>*Oy z{o1IWj=aLg8C$WA??$w{!Pqw# z-Nz37CJ1EsVq!Az`OIo>X@_QigC19`(-L{y_SZtGL4tTf4M(!LQt6vIS*ZO zx>oNLd~EIm_w8+tDlQ^HpKvN5SS)V^09#9I6S&@9S!$|z>ZEH+xZ&=;H3ra} z|91}nC)1GA;Xp)nB7j+!C+Alee>^|GsB3I*0GhDhv;fdB?rPRK1<7!C`VCmHU^V&} z@^DiyeFYyz&0}xab8Xy$agxA{_^W~{fNw*$0YxK%@JizrqMvnFYJHI+~o$0?ZAXISq{Xkw?1qj%=#C_mdkH*H zOp54H%-Q2-$+$g}&J=#E(=%;-=bd2e-Xbc4-`Z-gW-PNf4K<7en5f?% zNo(T|=8w?Gm9?z1dqW}19x!9WY;tkWm3<{ks*c3>_YeAdM(V~sXOF=?{iuVgb(dN} z7ivdA#w<;jw)x1s1mfi$vuA7uY?lNb@W5MN*Bn)6U+;bfqgNl%XFf7CnlOXlzK&RK z!>Pb$T7BrDsSiU0RAE={>i(MS5#{aq{{xnq4-faI$1FP=jTtMB|4sME?=yaX`s&+n z{~q_e{m7B&3)I^Z08G+c#SaPZD~i-NbbXT08v-M*GFcyIaQ)oM?zC7cqlve{iY)2# zcD|X0XgNBVPW?%moUXJ&RH0;+5{s4%EQzO6daCX1cVZ;qBMokXk;xZ1><;bhryPUw zjA;;vPgd4eRywLG>t#>Z-o5Ng{moH8S{L2BDm(z+SA>D%4aThI39i8`cBrFH4zg|8 z)}^RV>bg@$!qi6L*HW0rqs22^GArs-xd{*j8;rC{*vK^TNIpnsXMN8)7%WgD>Bt7H zpECXsiWzlfM`*k7N5FY}h?>dHRo;dR-iy^d9P&^q+gpe+jb{2lC23{WV6>4Z7%;6Y zrj+%N`KrtBlQum}A!L#QsM(cdKqY_)H#Y4dICuu%(f^va>;X4l$>WF_kLD;?xN%S2 zSwR_ptmBigW)cvM(1%PW-E>D`N$mVq`0()a<5m{+O#6|xH`EQuZEgr}T~k?(S?{&* z--Kb811#5=xw*>q_=wOx)=6gwoDDFJcLi9cRh4>*Mv7f}Ll`#1s7H#JQLT> z34^#>oU zl)5-RyZpZpoWEkE@f1hSwoG&xohrPCQAnW$q_ z(qY4@^s6o>Bg~Exz%dfij{!o|(+tSqs{b_Sl;c`IOPiyzPvktshm>D=pih z=A@?dNcu=8+rK}j=4JM=L!S$G-0S0Lzn;Z)O5Yg(XB%>aUz@G7Z>XfRQ2YL>`kTTj zzUhV(#)mHnv81cjN|l zdBonc2cuJG&Dpiifi~n*>icx`HEI68RK_oXCPAt~<|wu$F|WNX0brQUluaE+l+r$Q zdq~zdncduE4PccFkq2&mIyxAy!#F)g=cuKq>qz|i)cp|jn>J^`REJ~3p0JBoe5Nc} zI6895F3Tq?gcxMUswvIR9#AH1PGQ3joyp;*_XNn`+trpCkPeD5-IS}ecrA7milW^KxPmf4zZ)-K(}cpsjDD#>=~_v1I1Z2pvll9(Hpuna|?e%v_^!)-P{Pryo7m{`Nt@p29}H;0RVkQ8y8jx5&TJ8RIoBqF80^YVCZTH7xEE;5MvNcfHaX+hOM@CUH*elC;%*^ms2#FQq_F#sxuB zu!}|~0~xkH;|=1LH5e^kF;yIV$GTZR>+qyrfdBwN07*naR4XC18@>O`q+Rtjbc%L% zXFhQo9yPr!qcS~5OQs)FrkX1qpvTCI`sEQjN4w_=mDXDsJ@$CV0=SO+3C&;YG_z{W z;HRb976E%@er};Ef2OlY1w*t=lb2wmjH<~X4B6{z6~I?`IvfFjYYOq7W`3osj6bL< z74bnhqp5`yK1|Y!-u|%j~^D&-T5&eK$t(+uQdT>C5Ons^?6A*T5>w zyH_Idt2|Uck{H;UGk=7NAm&9si!a0IER6IoIM?-xf8D2OIINnBLRGFSeAxr?wdAik zECzXNSLq-%vR+x=8fjh*A){UkC&`>CyTi?gZUl^neA-@=3T$fZe&;1t`{a2*FVCa( zw6CiLb)X9}R1Z7KnsNrY*aKiaRaI*0_0xU6+^R0zm@aMBycka5=KSo4$A6xCm3~}9 z-|GL^cFrDvFA)#^C5P;t0Z?@qr*-l7Z3zJLsZCE#R?l~LMqk0h8TpSKPD>nf##zRr z$j~WwK#w-*+%{cHw?HI7GTDA6pv6>sYbuK{8@+hsCLZq#h;x{+B#;cFr?ZVaY2FJ0 zSs^?kXz6crO29o2qpQ8hn_H`#yRjnK+1V*wtz{Z+d_h_uhtMEuPEadzEP7SEiRxRU z#LphEbPO6|2%5Ieyy&ZA6B=XWNLfU1KH149%7AN0YD*AMxRHUTqi{W@E>Kpe&Ot(fo7FS z+@zw84m<D|CL)LpN@N@G=-Vt!jV~p-$ytzRU_o8jU6;`!BiBqtuugEoj zr(^?`JM)3-REvkLanpGd~1^IFs+lU&gQSksJPUbeHs=@2tCQw)~M3vjc6D zSf>9=Q`X3=UpXqDr&-b?>G>+OQTVH$3~@%y)j!i*obF7l8H;!)?laE4g=}TcaMBRU z@~#;G9l8+d{hhuA%etP^|1JT{?EXirr$=hL|0j>m&L+1y|6gdmZ2_Polcxc8S6Ba* zX}90}q^Uf44Gv^7yOK&YgEhA8qYo=cc~PD`)9qL=c@_G%gDk zTWeTVU{%AG7H`6iQT<6QB00jV_UaWlq89f_$3M_@2@!cb^ zGP=9_;pmc$ft%bLaD2Q!did~9OyQiwIZi8#d37Y>E@ginA#xVr_{hy3d8YvVA1b<+ zK(z9$%Tm3B0#yr(RAo0>xdjM3qRi4!8XGj2E%j}ajhj*JT4&$w%IF7JF=I_!|+ouP2EwK^?G>bKC;(7 zVkV~5HX5qKAZZ?EXU@0U&8&0gIo!n49L1=}HUzNfC^LU>;Yfc~e}0bm#m5d_RkRgL z(`x@=?uD3?xQSyE3T7_T_U?So`0upW@wV8RFN5FYE`8fs?aGGi zo(i7&R!GarRhy{K)ZZ-M>+vf_&;o(VcnaaMY|3$1M!W;Gfi8%_uZOz`_8_XpEaW-I zS!;rB2?R*%t99GKo5w$sM`Ym>zzo+=k-D5Cw8vaW~M}X#e0b%aha5-IEVkJ9qk>2N+aPBx#XVs0f(U%^+|4YvanPz`R1Z z3e97JRpjJ>oRHD}L!i)WhwXLxn88 z0a^$zBPa6#bE~`=@#lX`pR-nuM}%P-UOn$kuaT4SA|eqIUe}}oRK~>!2JCw>J`$1) zJcVarda5R0!Q1qCT+;RO9owB3c4_z4PLJ``S$*A9j_^gc$|T!!cy*u5pVmHH=V?Zl zYB2?hn=ST@67Aa$w2i+7fgy3{yO7*fIn~R&0M2VW2{UV82VR^4FZ8%eLg1CQNcwvn zHJ=CCHGIR}|6Z5u+Fe5Te%k3F-NbPBf8Sx;BI&m+0F)FWz8BmK_^0>ZfB$4_diifD z%>C8z>VHQ6x=yEcetP_T{N;+Cm;K=t$c%F#%6X)iJMe)}H*D=gfE8sZYHQI;sPxvRxDl+T$KmyCi8*7|1wY)yfE-0nh3=ZSaEK z`IEJct?~BeE+@n`#xVG4o5DvZU~NBc*UM$Qz^O6%!XLn4tZ(L1r@$=I?D5N3fqRRW zF7w|8EwzE?EdBbl20^YF3s%OhK5HJQKH9ZJd#|@_ifX$k4Nu?k)QOuiDM(B=|`noco&Revb zu7p>2Wa3Yp$Vn3zt|y)aoDJBW!;VI*H0(0w=ZGYyaC556_=b(?C7(@Y55oC570omt znQ1N68>YaJrbDyI%-dUg4Q1GuUl|XBnFQ&Cgs7CTJZR)-G zv~Iq1Xx1@IQTVilK_$pE1uD$mHZ(?(H+^o%Uj`q-OLKjb@slCiz{Cx9=9ju1j9&o& z_jn|T{IioUP?HL(Oj29oEQ1Z7h$rcCb|Cl0_~?sMtg8wE<2a(nMn3NialKxl+Svfx zk^+FjfbrE$)OMtvv@`WoiHYVkMfvrPoqL8}es83JML1uFy1+MhW|4HEZf&p)yePR_ z1A3i+!%S+<#++HvJghvgm%%}^4g|B#+UGOS^(mpAOHSeuH=TfQE0QgomDXC*^lq`D%C<2#zA1;YEE1l6P0lFA_#^Hdgf9k_O&-T8} zOY`!r>9MygaudL3EEE3kmzU$uS{7~w-U1A@?@Iva()^OCiGRfFfH1So%kk(Ns)9EJ zzLNpSI?T=U@=hfl@@%k|Z=7*V$5HYM8+dHo<}gRyjvulCNx1JzW#zX+6cd*OQW(j# ze3^WX(yKDe*J$JCWhEXp^pcUCSl?MY-5gzvnIMU0Fad2iD;UC#YnR5evdxYLzpq^X z%+iTU)bez#$w+w1$R?kEVGpzABEx|(HveG$GO}<>zW@N-5GZ7RRtAK{erLWr_htAn zMD=zgFQ&i)tszn%6ScnKD+)T@Rt-VT#F+!qfCl3?uhIYp>w3LZh-Hiz;pgsn{bF`Q zCR_pl;X;LGEECt#rv4)w!4=?1z?r^a{2aY=bJsd;VI3i0clVw6-MMowcI$6)wXQM| zcb|;U&#$;R458SKlYw)l88pt+XTDL61hEJ*iy1!gDs%bGL|s~LLjj9;Q60n0GFjvm zRiY>TZBpsN1WXI_WvYU_W;z}Cf-{p79J{(_J*;-$#d;Vo8DKVH z3L1ozK(}+qEZdWnmG1GMS4#K$5&&vAqiBBd$FIKn-QBx)zj)`)*8fOW{|iR{{{u4t z+@-m)AzZi_VjCS3Y>oM;a`s4|L`vvbTQuI(I9s|+km~jD;jbu z3@e8!JBF-);m|(w?!7$&)M!6oQs4>B0v#Hb<--ts8BF zX%o&i=`4`;{Iy;B*lTCL@I$qF+O)zd($Uh7_|t2){&m3@8mbMXXVuj~P)GKt%!m1r z8M`#)h#o)cn0fYX06f7-;ggyaGagYLBfi3SK=%_<7g6idEk^j(*PI=3gP!Rq?79Tz z&U~lq-Kp=+{M@+b`n>}2=IFimJ{)gyM~3@gOc7ygdU$xWdVGA$F=A)h*z9coXc@!@ zYs*(4*FMrMmJEe5Eb|$Add&MLh-gebALyIbP(`wNm8W8Z%(Bi)Ef&@}aNJt0?q~-yMcU}>%PzaEq zd2In|AwfUT&^2^J-FvGtuQT&H?euJiW1h~y|F`~ooo|Q}VTaR>bY`9%@tr-dz4qQ~ zueIl$p+O!sJ6w3T+I~I-AlxTPcIHtxRWKO@fE#@jrxpk?prK|0jQ^md2fAvy>s=_xvvHX zqst-_-48H+OZk0AUyQ3+3q8=rhh1%!+uB;~ENdiiPA>;?i3b9=)Jnj0p+QtG_i#L= zAE)VyisCU9QN?gbM}UogjQm`wMn?z+Rb(B(eBBu4w8pup&clK>FfA@{K!Q=Bgh@mc zu@O#YUaX=yc?YwuQPA>2Bog6fKQCMYQ~?EwnwU$ylxji<1~saZnf448+7$T3Y1e#jU&eb%-;Gf`G{$I`Nh;ed5k;PC9o0r z;xWDQh>j$Gq!6PVOeGyOzBt*yz8qBeA+WtnhH#G)FcR$Ek)J#C)dA3~7Pn=_#y!sD zGXtRZjo@Ee(o%pr0_>HEp}#=WzTkasGn2$7_=HPIA9E^2nW@)U0;Sc|Qm{)1;KQD^ zaIepp0{w8u>m|~xx3O0A;L9Sg=+L}yqiq3cSnG+IcO2;M7zUN>17HB5)&%V~E2EYH-ILHOpayFWj7?%eH_<>gP*!~co0`yYzuz9r^yO|6=y ze6YUusJFTCq_?TtkDffb-MxDC2jeT(e#izO4M^rR3Z}rAN+h2Q35dq$f=mK{AW*5d z-7C8oVK5QHjYxt;^sL|P-B;^)gwi^urt?XcnE*!nJX7h8K%Q5HP{6^(V6&=Jd5Eh< zwTWp-jPlaOt6J}Qr0;%bOXohB0?NeM3&6+7iqi)>o139?J!Iq!pz%*a{DV0E`kAR? zOJJy_7fNZofUZqsJl3ST8nF>i1TfTT3`X+2T!x+Ld&n;~?x|r$`OA(9vyJgv(HGXL zE+(dlp%&>Fqv4mtGF(`pUm62~T|h+-OyP_2)aoSIHHv4Xk2`{wa2#O*zcJJF5v7St zrZpzN1^4I-C>>yNI$~a(R+jB}3p7Gg6WodeG*7zec;I=D(4 zxVV7_8zzK(REn6Lycu&*ws;1vM8Te=E*mfiRjCM6S!*Uo%epEoqUJx%Xy8@bPkV-) zZcpFup6)iIT2Mz&BB(H zS4C^;;C9(`8na`9ra;hJ!aWL}-7{2TQ(%kdWO}?R`&4h`NCry&>w$SSK<$N98sj?( z^rwPwOR#utjz*7MMYtqD8IM<|-2td$1Co22o15!e4j?lt!uytpXHT@VqB5KlJ!!KK z)2Q0~wzt*k>$u$Z&Kl1L>p`8xC}=l$@}3oB20&%C89_bqS8aA$5WQ+a#K6Nry?Bxt zH}LapfYYVo`LaJ`Tw#8Um{2hlsvFAo=e8B!BTRs2o;=$?T4JOMKZrC1PhnoT_9La) zPnLk@Q&fI_?w0)>VhJvLjo_(+iQreqi;aPF?kMljgZ_>xd1}Zi>o4uk)!QH^pfK>2 z00JCr2R#yzE}CfW%vW=dk-Zoef4PRP5kH_bwl+GE1|c$WySrZzF++eO(4jx3KNrib zddm{@aU`!?y2Il+(Db54^n|A~0Dd`x70fd5bz1IND2+)zoJ~^YKNV3tvd57xam^4j z{j^Gel5doL@F3ccT=B>%DhQ>u5$81^YYbjRDs33p^(iCJD}T}Ef{tGk3 zOZKr8%pj0$LK#d+?}+<6QKS>y{5MIY7`~|vKu%YX{_w8Ul}_jB($%ZK)QSJ!>W#<$ zfd&NcXeQuyG}2W*J44;2-_xT(o!zbV?xTmdIzRmQ_s8eYU)E0Hx5ei)EzX_*^&I+o zX-Ku9D4v!t`BYuuCRGLtF!ZpNN~_!LMfj??308%v+yh7nm+@eDg!N3oNHYOj5)#BA z+X#+=OAwAb2E-*ySNj|0=jSvF@NT@0_+*va1Gn@7)IGu3Rv1!LxSpm~1?KFEmm7LY zlamO03d{b8XngXYLCZTfN2x;JTz-wa~-Sa9QCC6EOd|dD75zS?Y zF#$zv9Et$NSky^*LeiL{mjn}7A}V`q$kR+y2uy^!ge%kbA@pOzsN9&k7Xo=kKLmKd zasgz1m}0k?nJWC04{7YLVL8A@RoUy}dn}ly_nrA?;_{uaYX*Ru&^VUIG(F1;A;g2m zg~OyEfKR8`d8^tLd7%AzR)HA;+O=S@El6=h^W;VmybRDNYrJY{G|Mg15|HO8U=Sqh zIxNMl9rZZBcG&Nt-T9}i>PjVO7pAKvym$(ItTx31RE>gELBpda%Ver!;_`Qt!slq; z>9K+am6qv`6!}9HyoDF!h3#nAB@E%>Q%J=VC2B@X7q;n}3x3Q1yZ|~Hn8UPw39izJ zUpnm!_4jtY`=8hUI2tc3)Iu~6VX3j~{#O(EvVbBBCsyB72cV89hz}pBC-d&y+`Vr1 z;QV+rcT2KRvfgL;Rc~v_Xuem50;RJ9W4*Uz6g#QYE~rMlk?1J0!DihVxkDt zm^0)-)?uCfJf{TQ8E~0t-wjovx{BV`L~nwi-s<&uLON?kjr0z~R~jTERWun8&Y}|u z*on}ebO7iC$Xztxku*BN5tdV61!Vl88T%8KjsrSV`Uv60IA_naes%!L%Xo6<;T+#* zQAYSohbk^>qXBc0&xs*ZRXEZv)`^CL;*-bnO}wg7sGMe|H?jmQC<|(Z6zYghajJVC zHV66eqpwX$heMy-MF=0=QEVkxG8cKEZIzDp$rG(&L<$8iT_KFQ`=9%9au1Q5b(6k& zS7rCVUY?aee0lXvcK~v6JfxN;0?5oSu3fwKpJ^oj>k^j#et*>YZSj)dp`67SxGP|E zu)j0D`RV`DUy$(s=%e4&Ou*Zni4@EaH0fXj$zA!Y(t2062M zUPlGDI!~V5rf2Amka~<}_
jPE4qYU9>m|3FJ6TS`J51=g>HF1<=Juhas~=p3Y- z0{A{C7jf!8Ne^|mqsQ+nQjkeu&FGuX9T)4+ z;fNLi?=^Dj^fY%-Rny%-Poioc^ zohyMan)3~NzG9bke$w|NJJ6@$IN4IT(3d{;O4Qw*uW$+!P4^KZ9CHtVX8~B+0=_!| zR9Ajw)kSegC(AE&<4~$M;QGhzN3Yx0f`*ZF+io-aik8g3w<34xqyPt$7NJmp=H`H2a6C^46L|>j$?L*i6@fqJ|7uD7qTZDu+>ib;<_5`Z|3~_sw0HmSX(0JPd*8m+?*GK)o9+N49;s7u`wt#G zc&JXmS@Ee`D$uJcQf>}hQi(6Y%&2^30+=S@f&|VIFQ0uY7*dXYc)`zg1j!&&Prp%T zCj&+a^Wk&=inSe2<>v@9ob?02Py{9%2!YuH;ox0VQe0AcO z9{1)sHi3#T6g`D7u$)5CWC>1HlCUr(ykTg+N!*;r2wxlc1eeQpxNn0?s-gp+5kL1& zFx^i_*0=FFP182*s-02ekjRi9KDR~uj2+B!y28EbS7(mX&;aJ;DiUu*Y&ru3$C0CG7eCotI07KhUr1h z!oxe>1(yseBlkuhLbz(fJgd=wy%r`)WwR?SgiYbc$P3fotWG<|@4XD!bv* zHvCn2C9d0?a+(ctlIJRoG*vLuC3Pc|xTNb$e|04Q1;QQ?tV0dZ*uV`BGp(o|qa8(s zDv;}w*~!?fDn071kaI=Vg}QLiC+f4|NVGLb)X>O-MZc*LbfaiOh4pjcrM(FVS+3XR zG?kvBKPb0y*1^*Lm_ZO#h6EAHfdd+t#Ee|DQ9_u$@Uefv8;6F|6$_Hs+y{%1<~E5#~{l_%f*pXj_P9e~7VqTkW7w_eNn^v3n; z7gbRgL_+V0c(%kG*hW0hQ>Wd*aJ;?wY`nX>-QBqGD2VL*`KvLCq2hv6%K2n&=W}(m zI|7p=UyH%ah6>jqs~{9Q0q$ucq(yr{sCANY9EgK>j>~cY8yuH4J$rD##VI-=pq}Sm zpN)Ygq-YpS(Ta(NP!J$SaO__1ssnI{D(m!@H2GRe;adi@D)!?M&+=i@!Wik7IFtGVDrv(h5W*Nqi+K9DEXso1f}dCM=x8iU zN62%vu8-_7(&q@D*6)>8oVkb92}WQZdP%3!WSXWjZ}xN4K)e+=-Lmj1?@W%gD>K=& zps4FrteNReD*=bAPM4UHzjH&K{z6OW8rIK_LRBX}Zwc%Y5H zT*G}JMvQ-3#Ry+*ani`@0hFb<2S9DdZN_Pl9`yU-IW9;R*mMLKD6;8Wci{+ix-5W; ze@2ZDmELAajaV<96rpSCP3r(;4P=J8TYGz-oauJ&jpygT&|>yKmT3DM+63{>i#ckD zqGN*ej)uGAdv`wVb5FqD&i45H%9YObcR$t(VSYe_(xW0>PJpf$48(xS3QT*JsTq-b zWmT9&Z+hH{c{RgDEe50Ilz^{O9cmVX%^naVf}Auw$};Rg&fGqXb8|5Dh0eS0e5{VZ zUgy!1GchBuzV=x0>1`8Ff}h>k%mk>D!0CY99qA(a*hHxi(LsoibQ|hvMd?IZZ{$y+ znnjyP9%aw)3YYm*?PsjevtApHwRjGs_=Q#);jlzlXv&NLT^8FzxXYc*ahQuABYe`W z&fpW5XvQtm@`(ITmS>9Cw8s%V%{{Pz4Rs;i9Y;c-b@^ zvwkxrK%G_f7Hj4bs!7LnoPv(2#3Y)!IRYk})J;dgim#DU9kR_6Oaylz95~$rf8{A% zWl3*w{905DjK8H?Z|P62k8}_~W8{fCI)O=$>4rD018@k-)z#H? zZ2(xiaplUAt^&~n{z-(*`h?H|ef^kO_r=`VptYn?-CAc) z@wfVGiVq>1m`I1wV|PJ^75Z`qhGcCye!cV zuO1XU{ekOYeCuIn<~OPYm~(Ge7^Kl6kGd7JDYKQ6LIz2gcr2H3Pw=qg#T0 zO`{lHAk>NbLUmE{_|b!3_1D%OcG(}Wq^ZvLKlq6z4>SUrUlMnbh*iaNMQ^ONGMXwy zn3bEtHc8O53uA(gjTT{07TVL?3(!Kw8NLoPh%1%^{Di5Gd~lCEQ&SLUVpar1^b&Cc z2RZ`2FW~aqH(~~XJo1PVZzm)y!a<<@`CezKcQ*1K&n&aKL?6_|bQ1-Wse$>VEE=x( zyhfEZUPokFa&7+-??{|$;hVWEz!g8@*3-vaix(l~7M(BEeGKA7J28r9?}h3yj?Ss9 zCxSo1A#C{+CgAZC1|>?_>nkIVxK3Ao7JizJFC&Xszn9=fxU)9TO?%WmNAlQ|$4n3I zT(HA*J~+9Pfxxdu_NGC1B*`%<>9UY>;AV5dF+x>8^>DaWc5H@Onn>gg*B4hV8<&^M zEb%i8%1dJ<&5~t1d~w*bkgvT2T>XW-y|Ioh%2j>UXrDG9;^F4NXalNKcu^2kxT}px zPb$oM-_^!%M({C;KQvuWeB~0*YMXPS{dsk~5%}BFI$af=cg>#C z0D(Y$zn7^LIQkV!+TL+0izdTVZ6w%0&~;`X-XA;v^$_0n?&f%?Sze`spxPI&cq~3~ zdwYBT)1{>zmjIyv-%cVtUgYOZ?Eutq@9K_#?%&p)fd71BW9#aftDmXpH~OQ|zpg-+ z^l>F%KWT}n6CO-p`h+R+J>4LP@(p{ejl0mh2)>}O6tEHO)P91%A#&k>u=fTKQ<&HE z+x6|lzr{PY%aIfbt-7-S-w`CcCa9ocm^+pGP zc!X2zRMef74gO_hkE?WG!dTRygJwOAFTo#2^A_Xod<4E{fEJ?8+0aL)AZf~&SDCER zEJ@cfieTi8BEe#FhMeiM5_qW+favtG9gn}m3W9_0P4OqVK6M{L2UM)rBmA|TIUO9d zTPR;f*5;!^ZO_r`IKkWfygbVl z3}WHc(XPkJdZ)9grIihp#hOmaasU6R$ox|rq-1z6V1fXZhy)_#Egx)|tiH0Yku^`sws@H=BhQD>GfL|tjBT;#S(=BjNj6-`&x=(c`CI$*!p+b$}o$PgQA6iz`{xGiGGDuPLTI zrkT|1Wa&VVBJb#@u8vAF3-u_RO1!B!m-=WhAi`J08QIKBYkV|Kkks%gh!E`3*&ObVQ5JT<}$DPCLQm<*BSiSsK;4+KbC{w zr!&AA{aC**H|(XL2L^OYXMuE+7U@i;89x+gr3w@yOu9&Su+%2;YaxoUY7aPM)fm1L zsi$=~e&qs9PE(ne%mZNvTa6^A#hST&(dCeuRKihAqU(TP|fj-wbIJArsSkbCNarqH_Uc#(?0h6*!{n@_8=a> z)2pvyA!W9jhkv@`KT*Ht7t0$PyBh*4@J#VVaZ7(G^=;??kTEhz>2+`3yvbtD-la>I z{#*t6)qHRMUl94M=xy+~W!GE`q@}f)( zPeCK-&z!laPM~(`$4Flt0qya?pILwyjVMgu7f6?pQ|7avaI|KcN&lnI;Ae<$MvtLeML5JX(tUYV4qcV#_Lc{Vy=L4!z(Yq zBCq(`yZ^;k9tiRi{p55+6Zw-QTf%-@Isl-H6r;4rbYGhTncLr6di(AFN}Td-T@v{3 zsGImBG1uQ#wOmxigw)&Gc--CHUhDi)FY++T`r*fa5cdR}KmQiXt`dUg-2Fa#14MjW zK&(_eiWej$63NPtM3h9+wkIv+`hCs>80C8W0IDBDcee0HKr^LO)^at{xowX3)^jF+-sez_ zELG+{?XOg?=>B-HS*X)O2}Ur4IxNgttR+qecp7VdjNJ8?Yvn5RXvBF1Zm(<{rGp*G zPjDzh<-&yWdQJk72JmAIUiHQUIS6k$W_)MPuvEi)_l)eBfw8`*3!Xd!WI>v-AkZLYXwQ1(^Rg!Pw$QNx zXLY3NiA6f3)yC~*)0)LQNeR4ou~R?#igq}SBp~Uu8FjdEp04`CVYGjd;8bQ@x}h=IVQsBHlGXW{AW4{b>;kOFQ)6{JAThxf&BYU^M z=*$Z@@T->rFe9AWcplxwpW$bv6sNLGF?pazEX3RX-u8HRXH$Cs9_#kMHC&?w44v?r zSo}X8_WNHda58DYAD_gORO?RPrVapjlUYiO59%1)ee&d!cRQUkqj%r^>nhIWh4J_! z72C3ET6t5iQJdX{T`pD7On}Z+?(961w=RbmuBZatTLhZRn0)~WUeHfbCDErq2X}Dl z^{8v`1+P@e9C3?&jyegLMfj}sOL%BTBpSh%Zb}rXsxz>mFbb{4L0Z9JJB)O7DUoIZ zVuK8uak6unWK~Z#lYgChJw0d1wN08?`)zaJlM#)$ZTh7?i*Sy7OS;55dq^6l3+V_k z&FAupK{l9f6=g~9wKkQzwmyREK3pdTKFl~o9ruOm51{@Ie<9f)tNWA0uT(K-h_hvSp&WCyArah1P zc_7ChdpkS}5O-3|~dyW8&InA`q9%L2rVN_&P)-M*Fo zVSAQI>KVd1a9wsycWkChw=3*Uvz^U~`Qo2=0n@M}W^ta510iPW^h+S?$75hFYKtq+ zc@;3&wJ^#mE%g`lADv*eNo`7Io&O{%M&OFSq**isH*G1}O^v+gbVvWv68ozV@+_lC ziRfZ&Upk#|;>3(V@QCmh?jC4#-nZ)UjZm#`~HT7Z?~-tKw~ z)WoN?`(OJZG#XK99*FigR5DM72M70;=I7b{PeC<-mK0B_eOo&KWIn`W$?(CQ`}hA( znU~(bc5P97^>KIH|1Iq95lVdS?Tq#{75>%jUvzjph*8LH0YX3IRb>KL86w|f%@hSn zS{4c>p{JT-L!L(UOy{4`I(v5>T>{W(qRXl~RiYMR%p* zDw-faLa%a&_zf!{8!9pr@fyxAYH@Ve`7v<{stOUvm+)yeZ}Kvj-6mzN(xg42fZ@D2 zQSzT<5CI&@zY1%A>zQs9Zf1I;N+9Zz!HW0@Pix99Y8Hz6qSD<-pe^=gM}YdA{mE*U zw!wv1%gelFp|)PqD6Ke(gm%iutCiWoAYKf1z(t=a&?R`725Ti-vXCyp6QTov7{xQ` zoe(8(%?X;X6!cEf(9ZD~>4n=Z4bV220nnp&I{xRzqO0ykPZZ+e-gx}g{Ra=U|8J5| z17ZdH#ZBMF4nXEEyNmVu8}|C6f1-VpT#I)}6?9Gg(7&z#EC~eX84U*`cFEtr`>AFE zbc#@=&yMSr^H+3$fR2D_1jyl%bug_`cl6>C_fLxu z^?ITF^VX~hQP-20X3p#uKjmUdC?ncHcSrU ztN7@Op=gS$f7S&r@kM}S3^*};TLcMw-k6Kr=+PA3kwW$q#k$*9q%YJ+X_OpQzJ^u#r%#5r zJ!!|f{nD+32(9uz942wEbmu?uK9<1-bZ||4oho=cUK8K+o#}6I2|z4OA_^*{CWE(0 zM>x|Wc6N8fZ<4Ja&J$DiC=XWHNUOFdo`ry?6A=Rz`I|?`P)j!k2MQBPTJ`Qni>8Y8 z5R8%!ykp8(1RnU8wr;@sh44wHBsFmlLp?2M8X03ZmSMNHR%5T0WK{TRr~;TBeK!U7 zwr=&z&3_a`pwfhYa@)7L1CXUzFY3XqyN~|Kl`B_%xgdV6{e2(mUi^PX#j-4c5#dII z{o&5=pu3|Dax4WvOy@KsKxbf11VUdm1ixkiAetOmQ=>^wW^NUIO%N!CcDO^~Tj8j- z41+o2+Z`MbLY^W!IFN7_ZU}BG7Xvsue8#ssMCxhj%bE(?S3{ZWJbQLuLS36;blX%M zHH>^}8cdBTHp8f)v1Z0CT4PN`sSD7+sU&D%mN z=UANV(GieePUS^MfFw#hjL}r|6Mss>9VeF$-o$}{00SXThmcOdS?$cne)imjnD$@R z5mJ~9BYnz|>HS~=!I%5$Hj8E z#GR07&a%p~tNg-L5-{%YCU;t`muXp`2~3O#i4+wc2HTXqsNw+PyrwVlTxaPr)8Et* zpyv2WYbz9FY)$9#FV&lEhaLCK0PL|}>zEEej@r4Nmnr|V8u{bK=pR_nNK#HxY?f1` zl?jI<7)n7~8K|ZohC@IH4!_`;-tz;mI7&IJeTiO71r`qQb3fL`^6a)c0pjh-iUaGH zSN}d!+IJp3dc=k>JlqqqS=N_VM`Ql-Fi$(COR7q>M?rmX{rWF-bJBy+T=&0IKe(%U!2Fn0-EQIrHA)51~NnE(tslRQi& z8OnM)T!zn3ZU3~>NHT1?A)s($L(81dhlW@dsNS%KW*m*iKu=l?qQJ2qH(Q;T-%t%` zp|iF9tg|Vi<5fY{{Ub&FaQOwhp(9@AhbqLJb-N*==m}PF-dTC;9XWI*2 z#!mtx6W7uQULN7A^TT>Qn5mHw)<^Q>qDBv^Nv41q6@nrRdoMGJe`dg1#X>oSdct=h*6(|r<>A>vH_!_wLKyrofU$swC(!9f_~#`(L64D$ zev&XMLeA8a&@21IWK3uiN2&AeGRL62#O;Xc0H`&7DsW#4iW{b(2PTI6^1m(2UmnmK6q6b~`11b!Ur1kk|N8Y^ zbp+lY_IrO>j|k1H()1D!*pBG{bRRwXRp-p+`5>N^mCK!#i`V4m3Z5{W=x^RQ!ijs?B4WseIC2l*BgNGQwmI)c zkJ0QiHW;$@v>qD-368+@IyxgV-YlS#0Ym5d1%tDJU*P)#XH0#I3P+4TM zJIp+}1J&t#sM#!?kXWQct7%*@b1Pt);aB-_I!=RhvJ^^`nfB(CKvqp575D}l0cnQE zD+zc6x@I4#UpkKaod1`Z>3uo@vB6L6kv&b&+?+b$rRf#W=5*82Dd>b(8MeO=hLyR#OX0L65p2^4zY z?v6&kRGQlB9!In$uwRAYyVwE9;znYR^d#V25!Lp5XZ(kHMB!a+^7}W$#?FeTpVPDx z%SIzcziUtL_Lvdiw!oDOS34K<(Ys?rNF`}(qdH)ZfQy|PvKgjmxAaTB?Vk43GaRwg z4Rg9rb8}eEzFK%Iw8HBQ={^D)=1!*o7>GP8P)4Ak@bmO_M^oFELfCIEt_mKT1-Ih^ z9*V{Wk)JuUB%0JZo8b2mhH@{(5aIZVG}9IdVgUo;5j}Y`cL5BzF(Sq+`1r^Ap5S^4 z-|5CAOb7+QI5+O>0NctVYYCIUOC6+ngggyXIs%^$v+B_s^A@%7b0x};d-ZXzUdv-- zPY27L4dYL#ww3cGw54p$5JuCuX8iCgPU(~3+j`c0+r4DJ0W!n1v+n+n$v^BPy z>2;s7CrfQ*%&~QiSmdD{$m8)7HIIk;y72DInKO?C-;DX?QLj)erte}0APb4SjqlvK z^Of}b@4ffdn$FU{t3KrKt9-9YLab;IshZU6_i(TKZ1rAuOP4Q5_-VCZz*PBI^r(m2 z)OAoz20^OAQPp~T)_R-Vj&jd%0Y*P*uZK@_>g_PZW%NYv*bLjFbk79jeE@YPiW#Av z`S9p=p>t0A9+uB|6b!r#T|lv~7Zu|qga{Ks7^&&ZdeB_iFc@&;0-fr=Ql%A4FsIX@ z05NqJf*#?j8lcx4Ga1ZisG5L7XCUBF#sHl_2{U<&21S#R7rs>A>3I8Lb`C0q~_f;8UPUM^V?!^vN&E49Mv^--N3Qz-|$=_EY)S9A(V> zrEA-s?y0xoWcYM9lgZFgMu9hLjJOisWtU;H{4y^&(~M*y&jnK~p*?#h+L6%T++2+jKcoIEH{d~Y%)H#V@taY;=g(h~o*j({0U4A!%{(P0 z!oJi&uxLtN%nTTTb~IbI zy~Ql7IsmczU&A5oX4gYT-u=I~cSm>sztY|RSrXsH4nXEDI|3n5w4A-ZtL4e=p!Bumu$a^Rd2X~KZ-8N%4E)%+&-9t6V>w=Jje4Mc0dW(T01zfr=0kB~_L#iulQh@A;%YZci{7Yj#y`>UWOU7BvG_v{el z{t;b27ueub|W66e9}h9yS_LT!HtLIh?eS| zssDW3sH&F=Q%sbjf|hc2-DIB7D^<~UkcvFgJMC52ndx*&psF9$P7GHom+2T}lZkNp zA>Q*;#vxogbol8f-RohGg&S$NLzu>bu5tjSAR4NOKAF8NAL+$D7bgq{GY^qLaw6$5 z2NukX(B6gvUHPj^f7bPI9XJ2+nr&Q0Lo^-p620FP#QN_4%uZ%cA-|sbK6C&gk2h~V zT~|@ji~6tMxqSI2-MRh`B*fmIAJ1J^Woj(VOy!`vvHoPNx1+lon@_s~ZMk_7ZwUYZ zKmbWZK~#^+g3d|+X+)_Gf+~RNW{-@SKtSc1Dt=a3KdHCf(_Vr%;(076rMD4N}UE1YSJQz4=%z9+{46=OP090*eN#tFp>uj zSL)IUU=IW9_sn20OS2^Wqaz?8!!{4hOhxlCdPR3yG)U@?a>*34jPRo)BHZnyFfO++ z9Qji<@+t_hQK{SJbTQWwNUzY_;nTD2p7HHos#JmN^-J9B(AbQ>_mB{d`W=e-=mkx6 z0ya0F#gzT#=F`xhJ$n=aetrFE2>FeTr$J-HN#)L)j@gu16;9JI`*PvJ+o7+lydCwF zbdXmfyL{Vua#<(LOanb>*5>rd_|397x@TW{3)5AAo zPqD=y0r!`ogG{p>x1@7KHlXLEY4{1e*BcWQPsX@_xG<4~99F@DgYxa~?v8hK`On7s zqb|p?;Zw{Ou+*x&9B791Gnwu@e*BpAT^PCr&nw&u@LlczsJuc^aHy;YiGt4E`F{6* zRyqGb=i({c%aRx$i!8OtwBO~3-0t@J`03-@aa``w+wXQRy>&yvXC;J9-c8-r<2%in zfJ`FNn+TDl?-VL&52Q+z^usOvaZ7XR87}Qki5@2e$&OhBCHoZ^=|M;^>uTyZ1a?U? zU`$ZfrWFbd_!UVy;6zlcgxz9*`F<#AM6PacLbagLN z`filoIAlCa+DZ>J(~WGn@zOb=Q{r&O7r(Seq{+__&J+K(p+7b4|rHr^h zi_VtUX}RIhYqrc9Q9scUE3X(X$7^aV$@uOBcLIB=H=n40UR?HIoJv%o3}!iJ`DK2Z zWkVUb%qFq3SkhsppIQmHCTP{rp?Hrr4r}wZstER5e4}n%$5F{y(NnNIt}5%bp5ekx zmh?;a2I%714wLpq*p`Jb5zdV*=oI=5zB?J%n3Jdklx;rWvy#WH*<;2rSf>0v!?vzY zfMx*JAL-&BO-~0y<%lT9q_~6c=T(kRmr%X==NZ&3L1}A@AkI0pJ`TRIA*k|+XJ;&pc|!FB-hBd$E|@u z#0H(CbCW^6a+1W7EZg=Bi+}pn-7u%SVN`90DSG*8)QVzL^-$MpLNhRLJ~Ps0yl|5f zuEAIZp3VcK=aq|kTtNiM@j%o-mjVqKp(~paJ_LJoE5f16efA31n-h?LsUH~=(eRWe?T*euT{*9H7jQ9CqM+grJqpmh z_zWFRk&}r_8d`ehES=L%DWpns`lWl*Uf~OlDn6sDz|C;PwqG5t!&oq4HVk+8Mlp(K z%APfPbVl%dVnXZdk7Ejdb@fp&BK%|YA?8GtpXycqVjUwpT#K(*g)BWCW z!PLHvP?jYm>IXW?PFAHe8^Q7q)?UT{T7#?Wz#@St#+9dnAf?iUESd_(C@& zvWG1@0Ezr_OXNiZd>=Xh)5>C`O%+==-hTVBD)JMRE<2WfsH(fDPj3rZiHOIHhBi0X zI*Y3hHO+iM400f0E>VT~3uBoT871aqip9dZXuAR`AlN^JZSVY{KI z%!DALcy{PB!e<`?w-hq9zgR|)2o&sGw~NqV{TLk~6Ae#sDCbzNmmZBKa^XBs7nFtT zg53BIyg)6`lbgd3_I0Xexi?d?pYc_3xgvyLF$9i|(e_Jw!oyBEun~_@|LW>}F&90B zt<8I8L>h5umoZcQ)d=4Yi@9tO&d`tdSs?t~0XQ3@{d2lHn>BoP^QTTHjrOppm)8s< z1;1ed50z)RJp%=PkL^p-gQPWizP=mBAps?YWg1}1+xIvM)hbFrX z^>8p<7_+WDP&o22h!G$oab7}9CJclWoI!U1dn{plHr%gWTM{AfcOF0fQbJ_2^Hfg@ z1FNJAreXBC)&fgTxRXcj9f%``5)kYy;JBSP>1mg~gop)6c^yxi_;l5!;`sVq%0J49 zh9*_ATbW!8lwkNf1nFY8fbrAL9NlCjl66BEk3LI8*(atjWLc(bThB6Aj$2-pJ?pg! z;JVKGt8_vn9b|m)$31nM`K{7Sq={SqMxD<;|5*tC&p-eFH0ocKKl~%Z$P}ZEUX1J! z@E0yzj*gX{$c_%#`STZpetcg-o|a&i#(OJ>L)}y#bp^uU>w2Rz;Bs|Gz&oC+{7^ns zxnr)w%e;Xrctf+!gY!W-%+woI0ztaen+y~4Gz=AnijT^VfVDuS-Y1>k;#HhIvXEQa zYca!Ecws@H?Q8oa$%$clIJr6*=uUhSg5@J~@?d`xc^DwTwOMv+V|C1?Sv|qt-QC+7 z@9CylKHN0xrdegpi0FY822+}CX6&Tj*eVF=GeQwO*~jV|bjA;4zq7Ts_vdSCYxNGm zEAI$=pE>|4;X`V4M|Uk>UtWGT-|c>`%3)Uj&s0HIL~K{7B&xgI%{<;Lo1m6;uReD- zGabr?H)aA9O!Pqgya_V_*+LM)Fl&);2yS|;7T^{@5Ok%YO$vYVK%~BernWz7RK6l> zU&QP)-oD*UaZB_#ud9%Z>VulKCJ)2s*c}~!IFhGM0G*Q9XsC_=n<_nW^cwNJ){zk& zli7lhfZzds`iaI@;hLr#VU~aqHuHgBC0H`XtJ2B53t&2G2(CKXrLeNlT4)&ObgYE6 z_i^A3ed)IdTI*i^$ykgeSYu=p9~=1g_V#3_LxS_FWkF6q8+;v>dIfhdrK3=l9WGf%n8~LVVbY9C zmY;oRzi(m*xQ_UR7OOo!^?Eekhh2_$ujjT-8AnmYQSNm(X+8=U!{Ar#vCto3>7RI3 zRLg4G!B1OciH+qoKK9z|AMEIMKRxTazuV=+OpNj=6UEm^w2UzfRrJ3vcU@D{*_GFh zpnsxZx7BWQ^PjA*M|~eV0NIPmdhgx8e}7fQ`@dXXUcNkc_Ux^>Uhm)3boJj>#mq^l zX{&&SkXq2XclXn|-rRh5Z+~mdhNv4iellJ@t7&rNBqXA#_KKM$Ba}~(5cr|e4ui9k z;zAig9_a>^5H`__00F-aqZ+L?!vT-+SW+3-~=v?LpmxV zSr8a}Z(n*h;xdZg6H!0Wj6m$JXC$dV9`isrEXO8EZrWqBBpbuLX)<^2Go_C}u^_6- z$N4e-Mn||rSqQ7i42K1ZaU=$+2?LkN69y^FwpZa?2jsCSJPDsgQNbYGVP${&Rc4oG z+EXVTn-h+4iE}5y-^Ycjx^q}x>;%(*c_h8SXb|QIVR!73-oU*Zvo(x3Zr}d2^WcGQ zxYSxbyYVkyelMo%sRsl+BYo(C7cuDwFntef>IXP<7SP?vFl_7|)strZb2x{umvcS8 zX+}4lQ7(s-%Om=JHBZVUznb&R_(qig^{G#E0{_UV?U)^mx-K-Hq<$Rk0b@#lj5{Hn zG_*X@c?yU_PDiCx`l$@o{V5Y-i_pHDIs+}SZLU4;-2C*9M4M`_n(h~W)eXo4Hi*Ht zMY6OCO2jt>NGs)2s9zz}kx-2Bn()%5s{?lZKOW9?{|7~SpeyawA&9~Q8&t|J+g`!% z_pt*ot=J%$gVEB`riA}(RoN%n#PO$Ee|bmM_%1c5n$nGos#rafyQ4K7)Vg-bYg$Ja z%ji)dMzCV4Fe+*t#pnxjkb#{}`PYbm10yj`k-+4m52~2}@Jr!RNV4DuBX>T?k4JHw zwMSsgb(T3PptBSRDDuWsK7xe~K&;!Bqk1eQAWXcI-?IYs5u{S6(l@GdNfb=;!X$9X zj?hWUGV_3*iu|Oio71hXS7lSVI*x%<@e^q3RrtgqVZkia|B|p~TAT7`d4fF_zQ2LB zdOB!axI-B;qOhWzmpYd&U5heikA&+iXP;yXc%1(5=Ff9_#E9dP*RH)EoA&55P#>IT z!3;d=gQEOofTl;oR+SZbse2`zHXQ2# zX6A3K1gMi{y@V}k@i}-kV>Sb)Us6xn2~{^YV>N9Vx9Qrn1uO`T{}|p&58g;ehW6?K zQ58#VOdG=oto+!w%k|66TZ^&DTC4g2Ef;)zRw*1)kP@w20$nMr%#`5Kkan>Q_Tjf=&ZYL4z$#K^zfEuz3007yW3r606zS|?`lTia%VxW^}r-~6a|pt zwV|i*3JSxeFjO;a!r&Ia`hnTmoD310QIxMeOL*)_;?7RO&a?;)98Upz$Ng}~WiDF3 z((Zmy?gR$238m{=(gP-)7?1c?R<6o_6fY;zD1d_>0>x9u7oxMkNHJ8&CrzO^ga%IJ z!}+sc{FWcIDj&t)T7gs7+WsyF7n225mR*)fJvL^CHBRY=8~CAuyLz~nt~KQh&ljStOau*Hp=hJgx{UjRbW1{iO`(6GI8S8$RGorHTB`eOI6u#5 ze?v2T!~1t1?vqma!1%Rw1isH50F~=RWntqW**4nfE-l?x1%0A1&>x9I{!m@MAB=n5 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

V<^04+VH|-^s;Me@UO1?Ah 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.$oxO( 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 z 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
X29WNTsHj$D+;Xz&J-=bO&ffJrFoDT+i|?6U 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 diff --git a/scripts/macosx_makeIcons.sh b/scripts/macosx_makeIcons.sh new file mode 100755 index 00000000..386b5d34 --- /dev/null +++ b/scripts/macosx_makeIcons.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +SRC_PNG=../fceux1.png +OUTDIR=/tmp/fceux.iconset; +mkdir -p $OUTDIR; + +function convert() { + #echo "Convert $1 $2" + WIDTH=$1; + SCALE=$2; + WIDTH2=`expr $WIDTH / 2`; + + if [ $SCALE == "2" ]; then + OUT=icon_$WIDTH\x$WIDTH.png + else + OUT=icon_$WIDTH2\x$WIDTH2\@2x.png + fi + CMD="sips -z $WIDTH $WIDTH $SRC_PNG --out $OUTDIR/$OUT"; + echo $CMD; + $CMD; +} + +convert 32 1 ; +convert 32 2 ; +convert 64 1 ; +convert 64 2 ; +convert 256 1 ; +convert 256 2 ; +convert 512 1 ; +convert 512 2 ; +convert 1024 1 ; +convert 1024 2 ; + +iconutil -c icns $OUTDIR/ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6ea527ae..a4feb9a5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -448,8 +448,8 @@ set( DIRS ${CMAKE_BINARY_DIR} /usr/local/lib) message(STATUS APPS: ${APPS}) message(STATUS DIRS: ${DIRS} ) -#set(CPACK_PACKAGE_ICON ${CMAKE_SOURCE_DIR}/fceux.icns ) -#set(CPACK_BUNDLE_ICON ${CMAKE_SOURCE_DIR}/fceux.icns ) +set(CPACK_PACKAGE_ICON ${CMAKE_SOURCE_DIR}/fceux.icns ) +set(CPACK_BUNDLE_ICON ${CMAKE_SOURCE_DIR}/fceux.icns ) set(CPACK_GENERATOR "DRAGNDROP") include(CPACK) From f8558a963617a1b98f282044726819a24eda98ee Mon Sep 17 00:00:00 2001 From: mjbudd77 Date: Sun, 12 Jul 2020 15:43:48 -0400 Subject: [PATCH 098/100] Added component runtime to cpack line --- src/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a4feb9a5..c1063f0c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -454,7 +454,9 @@ set(CPACK_GENERATOR "DRAGNDROP") include(CPACK) install( CODE "include(BundleUtilities) - fixup_bundle( \"${APPS}\" \"\" \"${DIRS}\") ") + fixup_bundle( \"${APPS}\" \"\" \"${DIRS}\") " + COMPONENT Runtime + ) else(APPLE) From 7df1fdd25fb745a65ebaa0eb89315bca13bb4358 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 12 Jul 2020 16:11:23 -0400 Subject: [PATCH 099/100] Added logic to Mac OS pipeline to save generated DMG package as an artifact. --- pipelines/macOS_build.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pipelines/macOS_build.sh b/pipelines/macOS_build.sh index 7e82d3d2..b096dce2 100755 --- a/pipelines/macOS_build.sh +++ b/pipelines/macOS_build.sh @@ -70,6 +70,9 @@ make -j $NPROC || exit 1 sudo make install || exit 1 sudo cpack -G DragNDrop || exit 1 +echo 'Pushing DMG Package to Build Artifacts' +appveyor PushArtifact fceux-*.dmg + # Debug via ssh if necessary if [ ! -z $APPVEYOR_SSH_BLOCK ]; then curl -sflL 'https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-ssh.sh' | bash -e - From 1cdb6fc9faaf925c0d65ad82b09eeccc3002e9c9 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 12 Jul 2020 20:54:18 -0400 Subject: [PATCH 100/100] Updated SDL README and TODO files. --- README | 71 +++++++++++++++++++++++++++++++------------------------- TODO-SDL | 44 +++++++++-------------------------- 2 files changed, 50 insertions(+), 65 deletions(-) diff --git a/README b/README index d906928f..53c559fc 100644 --- a/README +++ b/README @@ -1,12 +1,13 @@ -FCEUX SDL 2.2.1 SDL README +FCEUX SDL 2.2.3 SDL README ========================== -By Lukas Sabota (sf: punkrockguy318) +Originally By Lukas Sabota (sf: punkrockguy318) +Updated By mjbudd77 -[NOTE: This is old and out of date and only applies to SDL (non windows) builds] +[NOTE: This only applies to SDL (non windows) builds] http://www.fceux.com -Last Modified: March 10, 2013 +Last Modified: July 12, 2020 Table of Contents ----------------- @@ -21,58 +22,64 @@ Table of Contents 1 - Requirements ---------------- -* libsdl1.2 - It is strongly recommended that you upgrade to the latest - version of sdl (1.2.15 at the time of writing). -* scons - Required to build fceux. -* libgtk2.0 (optional) - version >= 2.24 recommended -* libgtk3.0 (optional) - this compiles as of fceux 2.2.0 -* liblua5.1 (optional) -* libgd (optional) - required for LOGO and CREATE_AVI options (https://bitbucket.org/libgd/gd-libgd/downloads) -* minizip (optional) - you may chose to use the version of minizip on your system by enabling SYSTEM_MINIZIP in the SConstruct +* sdl2 - Version >= 2.0 +* cmake - Required to build fceux. +* qt5 - version >= 5.11 recommended +* liblua5.1 (optional) - Will statically link internally if the system cannot provide this. +* minizip +* zlib +* openGL * c++ compiler -- you may use g++ from gcc or clang++ from llvm. 2 - Installation ---------------- -Fceux can be compiled and built using the scons build system. To compile, run: +Fceux can be compiled and built using the cmake build system. To compile, run: - scons + mkdir build; cd build; + cmake -DCMAKE_BUILD_TYPE=Release .. # For a release build + +To build a binary with debug information included in it: + cmake -DCMAKE_BUILD_TYPE=Debug .. + +To do the actual compiling: + make + +To compile faster with multiple processes in parallel: + make -j `nproc` After a sucessful compilation, the fceux binary will be generated to -./src/fceux . You can install fceux to your system with the following command: +./build/src/fceux . You can install fceux to your system with the following command: - scons install + make install -You can optionally define a prefix: +You can optionally define a install prefix when running cmake from the previous step: - scons --prefix=/usr/local install + cmake -DCMAKE_INSTALL_PREFIX=/usr/local install You can choose to install the lua scripts (located in output/luaScripts) to a directory of your choosing: cp -R output/luaScripts /usr/local/some/directory/that/i/will/find/later -If you would like to clean the temporary scons files to perform a 'make clean' like function, you can do the following: +If you would like to do a full clean build a 'make clean' like function, you can do either of following: - scons -c && rm -rf .scon* + make clean # from inside build directory + +OR: + Delete build directory and start over at initial cmake step: + rm -rf build; 3 - Compile-time options ------------------------ You can enable and disable certain features of fceux at build time. -To edit these options, edit the "BoolOptions" following the "opts.AddVariables" method -at the head of the "SConstruct" file in this source directory. The -default options will be fine for most users, but power users may want to -tweak some of these options. +Look in the src/CMakeList.txt file to tweak options. 4 - GUI ------- -You can enable the GTK GUI by setting GTK to 1 in the SConstruct build file. -GfceuX is deprecated in favor of the new GTK GUI. You can disable the GTK GUI at -run-time by passing the --nogui option, or disable it at build-time by setting -GTK to 0 in the SConstruct file. If you prefer GTK3 to GTK2, you can set the -GTK3 BoolVariable to 1 in the SConstruct. +The Qt GUI is required and automatically builds as part of the build. 5 - LUA Scripting ----------------- -FCEUX provides a LUA 5.1 engine that allows for in-game scripting capabilities. LUA can be enabled or disabled at build time by adjusting the "LUA" BoolVariable in the SConstruct file. +FCEUX provides a LUA 5.1 engine that allows for in-game scripting capabilities. LUA is enabled either way. It is just a matter of whether LUA is statically linked internally or dynamically linked to a system library. A collection of LUA scripts are provided with the source distribuition in the output directory: @@ -94,7 +101,7 @@ Finally, if any scripts complaints about "attempt to index global 'iup' (a nil v require("iuplua") -The latest version of iup (3.5 at the time of writing) is recomended. +The latest version of iup (3.5 at the time of writing) is recommended. 6 - FAQ ------- @@ -116,4 +123,4 @@ Running fceux through esddsp is known to fix some audio issues with pulseaudio o 7 - Contact ----------- -If you have an issue with fceux, report it in the sourceforge bug tracker (see fceux.com). If you would like to contact the author of this readme personally, e-mail LTsmooth42 gmail com. You can also check us out at #fceu on irc.freenode.net. +If you have an issue with fceux, report it in the github bug tracker (see fceux at github.com). If you would like to contact the author of this readme personally, e-mail LTsmooth42 gmail com. You can also check us out at #fceu on irc.freenode.net. diff --git a/TODO-SDL b/TODO-SDL index 95defb4b..67111867 100644 --- a/TODO-SDL +++ b/TODO-SDL @@ -1,47 +1,25 @@ Priorities ========== - * SDL 2.0 RC is released - SDL2.0 compatibility is a goal - * Backwards-cpp still has an issue with clang++; look into this - * Users are reporting crashing issues with hotkey dialog (probably because its a mess!). A huge chunk of the hotkey code should be rewritten (GUI and hotkey structs - or lack there-of) - * GTK File menu quit element has "CTRL-Q" accelerator. This causes confusion with there being another SDL Hotkey for quit. This should be addressed. - * Quit was mapped to '0' to prevent users from accidently quitting. Perhaps a default quit combo could be used. + * Clean out old unused files - scons build system is dead, cmake is the way to go. + * GTK GUI was not cross-platform. Has been replaced in favor of Qt5. Need to clean out dead code. + * Cheat Editor will be a high priority. + * Code cleanup. Lots of compiler warning with newer GCC. Maybe I'm OCD... but these warnings bother me. Features ======== - * SDL.Vsync - * lets wait on this -- theres no simple way to use the OS default in SDL unless we just dont touch it, which might be the best thing to do here. + * Emulator no runs as a separate thread from the GUI. Much improved performance. + * Cross platform QT GUI is fully functional minus Debug Tools and Cheat Menu. -GTK +QT === - * Better on-the-fly video resizing with window resize / video config - * Smarter video config (disable widgets that are not used when openGL is enabled) - * Options to investigate: - * bpp - * scanlines - * GUI Cheat editor - -SDL 2.0 -======= - * segfaults when opening a second game - * segfaults on fullscreen entry - * has not been tested in a while + * Clean out rest of old GTK comments and #ifdefs + * GUI Cheat editor TODO + * GUI Debug Tools TODO + * GUI should compile in windows as well.... but testing is not a priority since the windows gui has a totally separate backend. BUGS ==== - * F1 from terminal-less gui fceux process hangs fceux (since input is required from console in cheat editor) - -OS X -==== - * Single window mode does not work (the XWINDOWID hack does not work in Apples X11 server, so this may never get fixed). - * It is possible to use GTK to build native OS X menus: http://developer.gnome.org/gtk3/3.4/GtkApplication.html . It would be awesome to do this and hide the main GTK window if the top bar is available - * Zapper input is taken from GTK window instead of X11 window (a workaround could be implemented to resolve with with some #ifdef APPLE etc) - * Not an "official" target, but testing should be done before release on OS X - * DMG Static binary download for Intel OS X - * Include needful libaries - * Adjust scons to produce static binary/libraries with an option - * http://www.scons.org/wiki/StaticallyLink DOCS ==== - * Be sure to include details about new scons features for package maintainers so that the manpage, luascripts, and auxlib will be included in future packages * Docs REALLY need a cleanup/rewrite