|
@ -40,3 +40,6 @@ fceux-net-server
|
|||
/output/cheats
|
||||
/output/snaps
|
||||
/output/sav
|
||||
|
||||
# typical CMake build directory
|
||||
/build
|
||||
|
|
4
INSTALL
|
@ -1,9 +1,9 @@
|
|||
To compile and install FCEUX for SDL, follow the instructions in the README-SDL.md file.
|
||||
To compile and install FCEUX for SDL, follow the instructions in the README file.
|
||||
|
||||
Users of Microsoft Visual Studio can use the solution files within the vc directory. The Windows XP toolset is required to open and build this solution. If it
|
||||
is not installed, go to "Tools" > "Get Tools and Features". Select "Individual Components" and then install "C++ Windows XP Support for VS 2017 (v141) tools".
|
||||
These solution files will compile FCEUX and some included libraries for full functionality.
|
||||
|
||||
The SDL port build tool of choice has come full circle back to Cmake. The cmake build tool will compile the new Qt version of the SDL GUI.
|
||||
The scons build tool will build the older GTK based GUI which currently only builds on Linux.
|
||||
Building of the SDL fceux no longer supports use of the scons build tool.
|
||||
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
ACLOCAL_AMFLAGS = -I m4 --install
|
||||
SUBDIRS = src
|
28
README
|
@ -1,4 +1,4 @@
|
|||
FCEUX SDL 2.2.3 SDL README
|
||||
FCEUX SDL 2.3.0 SDL README
|
||||
==========================
|
||||
Originally By Lukas Sabota (sf: punkrockguy318)
|
||||
Updated By mjbudd77
|
||||
|
@ -7,7 +7,7 @@ Updated By mjbudd77
|
|||
|
||||
http://www.fceux.com
|
||||
|
||||
Last Modified: July 12, 2020
|
||||
Last Modified: October 21, 2020
|
||||
|
||||
Table of Contents
|
||||
-----------------
|
||||
|
@ -22,7 +22,7 @@ Table of Contents
|
|||
|
||||
1 - Requirements
|
||||
----------------
|
||||
* sdl2 - Version >= 2.0
|
||||
* sdl2 - Version >= 2.0 (sdl2 >= 2.8 recommended)
|
||||
* cmake - Required to build fceux.
|
||||
* qt5 OR gtk3 - (qt version >= 5.11 recommended) (gtk3 >= 3.22 recommended)
|
||||
* liblua5.1 (optional) - Will statically link internally if the system cannot provide this.
|
||||
|
@ -37,15 +37,19 @@ The old scons build system is no longer supported.
|
|||
Fceux can be compiled and built using the cmake build system. To compile, run:
|
||||
|
||||
mkdir build; cd build;
|
||||
cmake -DCMAKE_BUILD_TYPE=Release .. # For a release build
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release .. # For a release build
|
||||
|
||||
To build a binary with debug information included in it:
|
||||
cmake -DCMAKE_BUILD_TYPE=Debug ..
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug ..
|
||||
|
||||
The Qt version of the GUI builds by default and this is the preferred GUI for use.
|
||||
For those who must have GTK/Gnome style,
|
||||
the GTK version of the GUI can be selected to build with:
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DGTK=1 .. # Release build using GTK GUI
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DGTK=1 .. # Release build using GTK GUI
|
||||
|
||||
The Qt version GUI by far exceeds the GTK gui in capability and performance.
|
||||
I HIGHLY RECOMMEND USING THE Qt GUI instead of the GTK. See the TODO-SDL file for
|
||||
a capability matrix that compares what the two GUIs can do.
|
||||
|
||||
To do the actual compiling:
|
||||
make
|
||||
|
@ -58,9 +62,8 @@ After a sucessful compilation, the fceux binary will be generated to
|
|||
|
||||
sudo make install
|
||||
|
||||
You can optionally define a install prefix when running cmake from the previous step:
|
||||
|
||||
cmake -DCMAKE_INSTALL_PREFIX=/usr/local install
|
||||
By default cmake will use an installation prefix of /usr/local.
|
||||
The recommended installation prefix is /usr (this is where the installed fceux.desktop file expects everything to be)
|
||||
|
||||
You can choose to install the lua scripts (located in output/luaScripts) to a directory of your choosing:
|
||||
|
||||
|
@ -88,6 +91,13 @@ OpenGL options:
|
|||
For Linux builds, the OpenGL library preference can be either GLVND or LEGACY (default).
|
||||
To use GLVND OpenGL, add a -DGLVND=1 on the cmake command line.
|
||||
|
||||
Qt Styling Options:
|
||||
The Qt GUI can use custom Qt widget styling by providing it a Qt stylesheet file. At startup, the GUI will look
|
||||
for an environment variable named FCEUX_QT_STYLESHEET that must contain the full path to the file. If the variable
|
||||
is defined and the file is readable by the program, then the styling settings will be used by the GUI.
|
||||
Bash Shell Setup Example:
|
||||
export FCEUX_QT_STYLESHEET=/home/me/myQt.stylesheet
|
||||
|
||||
5 - LUA Scripting
|
||||
-----------------
|
||||
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.
|
||||
|
|
256
SConstruct
|
@ -1,256 +0,0 @@
|
|||
#
|
||||
# SConstruct - build script for the SDL port of fceux
|
||||
#
|
||||
# You can adjust the BoolVariables below to include/exclude features
|
||||
# at compile-time. You may also use arguments to specify the parameters.
|
||||
# ie: scons RELEASE=1 GTK3=1
|
||||
#
|
||||
# Use "scons" to compile and "scons install" to install.
|
||||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
import platform
|
||||
|
||||
opts = Variables(None, ARGUMENTS)
|
||||
opts.AddVariables(
|
||||
BoolVariable('DEBUG', 'Build with debugging symbols', 1),
|
||||
BoolVariable('RELEASE', 'Set to 1 to build for release', 0),
|
||||
BoolVariable('FRAMESKIP', 'Enable frameskipping', 1),
|
||||
BoolVariable('OPENGL', 'Enable OpenGL support', 1),
|
||||
BoolVariable('LUA', 'Enable Lua support', 1),
|
||||
BoolVariable('GTK', 'Enable GTK2 GUI (SDL only)', 0),
|
||||
BoolVariable('GTK3', 'Enable GTK3 GUI (SDL only)', 1),
|
||||
BoolVariable('NEWPPU', 'Enable new PPU core', 1),
|
||||
BoolVariable('CREATE_AVI', 'Enable avi creation support (SDL only)', 1),
|
||||
BoolVariable('LOGO', 'Enable a logoscreen when creating avis (SDL only)', 1),
|
||||
BoolVariable('SYSTEM_LUA','Use system lua instead of static lua provided with fceux', 0),
|
||||
BoolVariable('SYSTEM_MINIZIP', 'Use system minizip instead of static minizip provided with fceux', 0),
|
||||
BoolVariable('LSB_FIRST', 'Least signficant byte first (non-PPC)', 1),
|
||||
BoolVariable('CLANG', 'Compile with llvm-clang instead of gcc', 0),
|
||||
BoolVariable('SDL2', 'Compile using SDL2 instead of SDL 1.2 (experimental/non-functional)', 1)
|
||||
)
|
||||
AddOption('--prefix', dest='prefix', type='string', nargs=1, action='store', metavar='DIR', help='installation prefix')
|
||||
|
||||
prefix = GetOption('prefix')
|
||||
env = Environment(options = opts)
|
||||
|
||||
if env['RELEASE']:
|
||||
env.Append(CPPDEFINES=["PUBLIC_RELEASE"])
|
||||
env['DEBUG'] = 0
|
||||
|
||||
# LSB_FIRST must be off for PPC to compile
|
||||
if platform.system == "ppc":
|
||||
env['LSB_FIRST'] = 0
|
||||
|
||||
# Default compiler flags:
|
||||
env.Append(CCFLAGS = ['-Wall', '-Wno-write-strings', '-Wno-sign-compare', '-Wno-parentheses', '-Wno-unused-local-typedefs'])
|
||||
env.Append(CXXFLAGS = ['-std=c++0x'])
|
||||
|
||||
if 'PLATFORM' in os.environ:
|
||||
env.Replace(PLATFORM = os.environ['PLATFORM'])
|
||||
if 'CC' in os.environ:
|
||||
env.Replace(CC = os.environ['CC'])
|
||||
if 'CXX' in os.environ:
|
||||
env.Replace(CXX = os.environ['CXX'])
|
||||
if 'WINDRES' in os.environ:
|
||||
env.Replace(WINDRES = os.environ['WINDRES'])
|
||||
if 'CFLAGS' in os.environ:
|
||||
env.Append(CCFLAGS = os.environ['CFLAGS'].split())
|
||||
if 'CXXFLAGS' in os.environ:
|
||||
env.Append(CXXFLAGS = os.environ['CXXFLAGS'].split())
|
||||
if 'CPPFLAGS' in os.environ:
|
||||
env.Append(CPPFLAGS = os.environ['CPPFLAGS'].split())
|
||||
if 'LDFLAGS' in os.environ:
|
||||
env.Append(LINKFLAGS = os.environ['LDFLAGS'].split())
|
||||
if 'PKG_CONFIG_PATH' in os.environ:
|
||||
env['ENV']['PKG_CONFIG_PATH'] = os.environ['PKG_CONFIG_PATH']
|
||||
if 'PKG_CONFIG_PATH' not in os.environ and env['PLATFORM'] == 'darwin':
|
||||
env['ENV']['PKG_CONFIG_PATH'] = "/usr/local/lib/pkgconfig:/opt/X11/lib/pkgconfig"
|
||||
if 'PKG_CONFIG_LIBDIR' in os.environ:
|
||||
env['ENV']['PKG_CONFIG_LIBDIR'] = os.environ['PKG_CONFIG_LIBDIR']
|
||||
|
||||
print("platform: ", env['PLATFORM'])
|
||||
|
||||
# compile with clang
|
||||
if env['CLANG']:
|
||||
env.Replace(CC='clang')
|
||||
env.Replace(CXX='clang++')
|
||||
|
||||
# special flags for cygwin
|
||||
# we have to do this here so that the function and lib checks will go through mingw
|
||||
if env['PLATFORM'] == 'cygwin':
|
||||
env.Append(CCFLAGS = " -mno-cygwin")
|
||||
env.Append(LINKFLAGS = " -mno-cygwin")
|
||||
env['LIBS'] = ['wsock32'];
|
||||
|
||||
if env['PLATFORM'] == 'win32':
|
||||
env.Append(CPPPATH = [".", "drivers/win/", "drivers/common/", "drivers/", "drivers/win/zlib", "drivers/win/directx", "drivers/win/lua/include"])
|
||||
env.Append(CPPDEFINES = ["PSS_STYLE=2", "WIN32", "_USE_SHARED_MEMORY_", "NETWORK", "FCEUDEF_DEBUGGER", "NOMINMAX", "NEED_MINGW_HACKS", "_WIN32_IE=0x0600"])
|
||||
env.Append(LIBS = ["rpcrt4", "comctl32", "vfw32", "winmm", "ws2_32", "comdlg32", "ole32", "gdi32", "htmlhelp"])
|
||||
else:
|
||||
conf = Configure(env)
|
||||
# If libdw is available, compile in backward-cpp support
|
||||
if conf.CheckLib('dw'):
|
||||
conf.env.Append(CCFLAGS = "-DBACKWARD_HAS_DW=1")
|
||||
conf.env.Append(LINKFLAGS = "-ldw")
|
||||
if conf.CheckFunc('asprintf'):
|
||||
conf.env.Append(CCFLAGS = "-DHAVE_ASPRINTF")
|
||||
if env['SYSTEM_MINIZIP']:
|
||||
assert env.ParseConfig('pkg-config minizip --cflags --libs'), "please install: libminizip"
|
||||
assert env.ParseConfig('pkg-config zlib --cflags --libs'), "please install: zlib"
|
||||
#assert conf.CheckLibWithHeader('z', 'zlib.h', 'c', 'inflate;', 1), "please install: zlib"
|
||||
env.Append(CPPDEFINES=["_SYSTEM_MINIZIP"])
|
||||
else:
|
||||
assert env.ParseConfig('pkg-config zlib --cflags --libs'), "please install: zlib"
|
||||
#assert conf.CheckLibWithHeader('z', 'zlib.h', 'c', 'inflate;', 1), "please install: zlib"
|
||||
if env['SDL2']:
|
||||
assert env.ParseConfig('pkg-config sdl2 --cflags --libs'), "please install: sdl2"
|
||||
env.Append(CPPDEFINES=["_SDL2"])
|
||||
#env.ParseConfig('pkg-config sdl2 --cflags --libs')
|
||||
else:
|
||||
if not conf.CheckLib('SDL'):
|
||||
print('Did not find libSDL or SDL.lib, exiting!')
|
||||
Exit(1)
|
||||
env.ParseConfig('sdl-config --cflags --libs')
|
||||
if env['GTK']:
|
||||
if not conf.CheckLib('gtk-x11-2.0'):
|
||||
print('Could not find libgtk-2.0, exiting!')
|
||||
Exit(1)
|
||||
# Add compiler and linker flags from pkg-config
|
||||
config_string = 'pkg-config --cflags --libs gtk+-2.0'
|
||||
env.ParseConfig(config_string)
|
||||
env.Append(CPPDEFINES=["_GTK2"])
|
||||
env.Append(CCFLAGS = ["-D_GTK"])
|
||||
if env['GTK3']:
|
||||
# Add compiler and linker flags from pkg-config
|
||||
config_string = 'pkg-config --cflags --libs gtk+-3.0'
|
||||
env.ParseConfig(config_string)
|
||||
env.Append(CPPDEFINES=["_GTK3"])
|
||||
env.Append(CCFLAGS = ["-D_GTK"])
|
||||
|
||||
### Just make every configuration use -ldl, it may be needed for some reason.
|
||||
env.Append(LIBS = ["-ldl"])
|
||||
|
||||
### Lua platform defines
|
||||
### Applies to all files even though only lua needs it, but should be ok
|
||||
if env['LUA']:
|
||||
env.Append(CPPDEFINES=["_S9XLUA_H"])
|
||||
if env['PLATFORM'] == 'darwin':
|
||||
# Define LUA_USE_MACOSX otherwise we can't bind external libs from lua
|
||||
env.Append(CCFLAGS = ["-DLUA_USE_MACOSX"])
|
||||
if env['PLATFORM'] == 'posix':
|
||||
# If we're POSIX, we use LUA_USE_LINUX since that combines usual lua posix defines with dlfcn calls for dynamic library loading.
|
||||
# Should work on any *nix
|
||||
env.Append(CCFLAGS = ["-DLUA_USE_LINUX"])
|
||||
if env['SYSTEM_LUA']:
|
||||
lua_link_flags = ''
|
||||
lua_include_dir = ''
|
||||
|
||||
if conf.CheckLib('luajit-5.1'):
|
||||
lua_link_flags = "-lluajit-5.1"
|
||||
lua_include_dir = "/usr/include/luajit-2.0"
|
||||
elif conf.CheckLib('lua5.1'):
|
||||
lua_link_flags = "-llua5.1"
|
||||
lua_include_dir = "/usr/include/lua5.1"
|
||||
elif conf.CheckLib('lua-5.1'):
|
||||
lua_link_flags = "-llua-5.1"
|
||||
lua_include_dir = "/usr/include/lua-5.1"
|
||||
elif conf.CheckLib('lua'):
|
||||
lua_link_flags = "-llua"
|
||||
lua_include_dir = "/usr/include/lua"
|
||||
|
||||
if 'LUA_LINKFLAGS' in os.environ:
|
||||
lua_link_flags = os.environ['LUA_LINKFLAGS']
|
||||
if 'LUA_INCDIR' in os.environ:
|
||||
lua_include_dir = os.environ['LUA_INCDIR']
|
||||
|
||||
if not lua_link_flags or not lua_include_dir:
|
||||
print('Could not find liblua, exiting!')
|
||||
Exit(1)
|
||||
|
||||
env.Append(LINKFLAGS = lua_link_flags.split())
|
||||
env.Append(CCFLAGS = ["-I" + lua_include_dir])
|
||||
else:
|
||||
env.Append(CCFLAGS = ["-Isrc/lua/src"])
|
||||
# "--as-needed" no longer available on OSX (probably BSD as well? TODO: test)
|
||||
if env['PLATFORM'] != 'darwin':
|
||||
env.Append(LINKFLAGS=['-Wl,--as-needed'])
|
||||
|
||||
### Search for gd if we're not in Windows
|
||||
if (env['PLATFORM'] != 'win32' and env['PLATFORM'] != 'cygwin') and (env['CREATE_AVI'] or env['LOGO']):
|
||||
gd = conf.CheckLib('gd', autoadd=1)
|
||||
if gd == 0:
|
||||
env['LOGO'] = 0
|
||||
print('Did not find libgd, you won\'t be able to create a logo screen for your avis.')
|
||||
|
||||
if env['OPENGL'] and conf.CheckLibWithHeader('GL', 'GL/gl.h', 'c', autoadd=1):
|
||||
conf.env.Append(CCFLAGS = "-DOPENGL")
|
||||
conf.env.Append(CPPDEFINES = ['PSS_STYLE=1',"FCEUDEF_DEBUGGER"])
|
||||
|
||||
env = conf.Finish()
|
||||
|
||||
if sys.byteorder == 'little' or env['PLATFORM'] == 'win32':
|
||||
env.Append(CPPDEFINES = ['LSB_FIRST'])
|
||||
|
||||
if env['FRAMESKIP']:
|
||||
env.Append(CPPDEFINES = ['FRAMESKIP'])
|
||||
|
||||
print("base CPPDEFINES:",env['CPPDEFINES'])
|
||||
print("base CCFLAGS:",env['CCFLAGS'])
|
||||
|
||||
if env['DEBUG']:
|
||||
env.Append(CPPDEFINES=["_DEBUG"], CCFLAGS = ['-g', '-O0'])
|
||||
else:
|
||||
env.Append(CCFLAGS = ['-O2'])
|
||||
|
||||
if env['PLATFORM'] != 'win32' and env['PLATFORM'] != 'cygwin' and env['CREATE_AVI']:
|
||||
env.Append(CPPDEFINES=["CREATE_AVI"])
|
||||
else:
|
||||
env['CREATE_AVI']=0;
|
||||
|
||||
Export('env')
|
||||
fceux = SConscript('src/SConscript')
|
||||
env.Program(target="fceux-net-server", source=["fceux-server/server.cpp", "fceux-server/md5.cpp", "fceux-server/throttle.cpp"])
|
||||
|
||||
# Installation rules
|
||||
if prefix == None:
|
||||
prefix = "/usr/local"
|
||||
|
||||
exe_suffix = ''
|
||||
if env['PLATFORM'] == 'win32':
|
||||
exe_suffix = '.exe'
|
||||
|
||||
fceux_src = 'src/fceux' + exe_suffix
|
||||
fceux_dst = 'bin/fceux' + exe_suffix
|
||||
|
||||
fceux_net_server_src = 'fceux-net-server' + exe_suffix
|
||||
fceux_net_server_dst = 'bin/fceux-net-server' + exe_suffix
|
||||
|
||||
auxlib_src = 'src/auxlib.lua'
|
||||
auxlib_dst = 'bin/auxlib.lua'
|
||||
|
||||
fceux_h_src = 'output/fceux.chm'
|
||||
fceux_h_dst = 'bin/fceux.chm'
|
||||
|
||||
env.Command(fceux_h_dst, fceux_h_src, [Copy(fceux_h_dst, fceux_h_src)])
|
||||
env.Command(fceux_dst, fceux_src, [Copy(fceux_dst, fceux_src)])
|
||||
env.Command(fceux_net_server_dst, fceux_net_server_src, [Copy(fceux_net_server_dst, fceux_net_server_src)])
|
||||
env.Command(auxlib_dst, auxlib_src, [Copy(auxlib_dst, auxlib_src)])
|
||||
|
||||
man_src = 'documentation/fceux.6'
|
||||
man_net_src = 'documentation/fceux-net-server.6'
|
||||
|
||||
share_src = 'output/'
|
||||
|
||||
image_src = 'fceux.png'
|
||||
|
||||
desktop_src = 'fceux.desktop'
|
||||
|
||||
env.Install(prefix + "/bin/", [fceux, fceux_net_server_src])
|
||||
env.InstallAs(prefix + '/share/fceux/', share_src)
|
||||
env.Install(prefix + '/share/fceux/', auxlib_src)
|
||||
env.Install(prefix + '/share/pixmaps/', image_src)
|
||||
env.Install(prefix + '/share/applications/', desktop_src)
|
||||
env.Install(prefix + "/share/man/man6/", [man_src, man_net_src])
|
||||
env.Alias('install', prefix)
|
18
TODO-SDL
|
@ -4,6 +4,8 @@ Priorities
|
|||
* GTK GUI was not cross-platform. A Qt5 version of the GUI has been created to meet this need.
|
||||
I will keep the GTK GUI around for Linux users who prefer it, but when it comes to adding new features
|
||||
the Qt GUI is where I plan to add them first (if at all).
|
||||
* The Qt GUI has by far exceeded the capabilities of the older GTK version. Below is a GUI capability
|
||||
matrix showing the differences between the two. I HIGHLY RECOMMEND USING THE Qt GUI.
|
||||
* Code cleanup. Lots of compiler warnings with newer GCC. Maybe I'm OCD... but these warnings bother me.
|
||||
|
||||
Features
|
||||
|
@ -29,7 +31,7 @@ OpenGL graphics | YES | YES
|
|||
Hot key config window | YES | YES |
|
||||
Palette config window | YES | YES |
|
||||
Multi-thread (GUI and emulation on separate threads) | YES | NO |
|
||||
Emulation speed control via menu | NO | NO |
|
||||
Emulation speed control via menu | YES | NO |
|
||||
Emulation speed control via hotkeys | YES | YES |
|
||||
Fullscreen functionality | YES | YES |
|
||||
AVI Record Functionality | NO | NO |
|
||||
|
@ -38,18 +40,18 @@ Game genie load/enable capability | YES | YES
|
|||
Movie record/save/play functionality | YES | YES |
|
||||
Cheat search window | YES | YES |
|
||||
Active Cheat window | YES | YES |
|
||||
RAM Search Window | NO | NO |
|
||||
RAM Watch Window | NO | YES |
|
||||
RAM Search Window | YES | NO |
|
||||
RAM Watch Window | YES | YES |
|
||||
Memory Watch Window | NO | NO |
|
||||
TAS Editor | NO | NO |
|
||||
6502 Debugger Window | YES | YES |
|
||||
PPU Viewer | NO | NO |
|
||||
Name Table Viewer | NO | NO |
|
||||
PPU Viewer | YES | NO |
|
||||
Name Table Viewer | YES | NO |
|
||||
Memory Hex Editor | YES | YES |
|
||||
Trace Logger | YES | NO |
|
||||
Code/Data Logger | YES | NO |
|
||||
Game Genie Encoder/Decoder | NO | NO |
|
||||
iNES Header Editor | NO | NO |
|
||||
Game Genie Encoder/Decoder | YES | NO |
|
||||
iNES Header Editor | YES | NO |
|
||||
Built in help pages | NO | NO |
|
||||
Network play (who actually uses this???) | NO | NO |
|
||||
-----------------------------------------------------|-------------|-------------|
|
||||
|
@ -59,7 +61,7 @@ Network play (who actually uses this???) | NO | NO
|
|||
QT
|
||||
===
|
||||
* Clean out rest of old GTK comments and #ifdefs
|
||||
* GUI Debug Tools TODO
|
||||
* GUI Debug Tools Pretty Much Done
|
||||
* GUI should compile in windows as well.... but testing is not a priority since the windows gui already has a totally separate backend.
|
||||
|
||||
BUGS
|
||||
|
|
72
_config.yml
|
@ -5,39 +5,41 @@
|
|||
# - web/
|
||||
# - fceux.png
|
||||
# - index.html
|
||||
|
||||
exclude:
|
||||
- attic
|
||||
- fceux-server
|
||||
- getSDLKey
|
||||
- gfceu
|
||||
- m4
|
||||
- output
|
||||
- pipelines
|
||||
- src
|
||||
- vc
|
||||
- .gitignore
|
||||
- COPYING
|
||||
- ChangeLog
|
||||
- INSTALL
|
||||
- Makefile.am
|
||||
- NEWS
|
||||
- NewPPUtests.txt
|
||||
- README
|
||||
- SConstruct
|
||||
- STYLE-GUIDELINES-SDL
|
||||
- TODO-SDL
|
||||
- _config.yml
|
||||
- appveyor.yml
|
||||
- autogen.sh
|
||||
- azure-pipelines.yml
|
||||
- changelog.txt
|
||||
- configure.ac
|
||||
- debian-crossbuild.sh
|
||||
- doxygen
|
||||
- fceux.desktop
|
||||
- readme.md
|
||||
- fceux-server/fceux-net-server.exe
|
||||
- vc/BizHawk.Build.Tool.exe
|
||||
- vc/pscp.exe
|
||||
- vc/upx.exe
|
||||
- vc/zip.exe
|
||||
- attic
|
||||
- fceux-server
|
||||
- getSDLKey
|
||||
- gfceu
|
||||
- m4
|
||||
- output
|
||||
- pipelines
|
||||
- src
|
||||
- vc
|
||||
- .gitignore
|
||||
- COPYING
|
||||
- ChangeLog
|
||||
- INSTALL
|
||||
- Makefile.am
|
||||
- NEWS
|
||||
- NewPPUtests.txt
|
||||
- README
|
||||
- STYLE-GUIDELINES-SDL
|
||||
- TODO-SDL
|
||||
- _config.yml
|
||||
- appveyor.yml
|
||||
- autogen.sh
|
||||
- azure-pipelines.yml
|
||||
- changelog.txt
|
||||
- configure.ac
|
||||
- doxygen
|
||||
- fceux.desktop
|
||||
- readme.md
|
||||
- fceux-server/fceux-net-server.exe
|
||||
- vc/BizHawk.Build.Tool.exe
|
||||
- vc/pscp.exe
|
||||
- vc/upx.exe
|
||||
- vc/zip.exe
|
||||
|
||||
# Include all .js and .json files that start with an '_'
|
||||
include: [ "_*.js", "_*.json" ]
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
autoreconf --install || exit 1
|
159
configure.ac
|
@ -1,159 +0,0 @@
|
|||
AC_INIT([fceux], [2.2.3])
|
||||
AC_CONFIG_SRCDIR([src/fceu.cpp])
|
||||
AM_INIT_AUTOMAKE
|
||||
|
||||
AC_PROG_CC
|
||||
AC_PROG_CPP
|
||||
AC_PROG_CXX
|
||||
AC_PROG_INSTALL
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
AC_CHECK_FUNC(asprintf, AC_DEFINE([HAVE_ASPRINTF]))
|
||||
|
||||
## This is almost sure to not work
|
||||
AC_ARG_WITH(nativewin32,
|
||||
[AC_HELP_STRING([--with-nativewin32],
|
||||
[use nativewin32])],
|
||||
use_nativewin32=$withval,
|
||||
use_nativewin32="no")
|
||||
|
||||
AM_CONDITIONAL(WIN32, false)
|
||||
AM_CONDITIONAL(UNIX, false)
|
||||
AM_CONDITIONAL(NATIVEWIN32,false)
|
||||
AM_CONDITIONAL(OPENGL, false)
|
||||
AM_CONDITIONAL(GTK2, false)
|
||||
AM_CONDITIONAL(GTK3, false)
|
||||
AM_CONDITIONAL(LUA, false)
|
||||
AM_CONDITIONAL(LUA_BUILTIN, false)
|
||||
AM_CONDITIONAL(SYSTEM_MINIZIP, false)
|
||||
AM_CONDITIONAL(GD, false)
|
||||
AM_CONDITIONAL(FRAMESKIP, true)
|
||||
|
||||
## Check for zlib
|
||||
AC_CHECK_LIB([z], [zlibVersion],[], AC_MSG_ERROR([*** zlib not found!]))
|
||||
LIBS="$LIBS -lz"
|
||||
AC_CHECK_LIB([pthread], [pthread_create],[], AC_MSG_ERROR([*** pthread not found!]))
|
||||
LIBS="$LIBS -lpthread"
|
||||
|
||||
## Platform specific setup
|
||||
if expr x"$target" : 'x.*beos' > /dev/null; then
|
||||
CFLAGS="-no-fpic $CFLAGS"
|
||||
CPPFLAGS="-no-fpic $CPPFLAGS"
|
||||
AC_DEFINE([PSS_STYLE],[1])
|
||||
elif expr x"$target" : 'x.*mingw' > /dev/null; then
|
||||
## Probably doesn't work
|
||||
AC_DEFINE([PSS_STYLE],[2])
|
||||
AC_DEFINE([WIN32])
|
||||
AM_CONDITIONAL(WIN32, true)
|
||||
|
||||
if test x$use_nativewin32 = xyes; then
|
||||
LIBS="$LIBS -mwindows -lddraw -ldinput -ldsound -lgdi32 -ldxguid -lwinmm -lshell32 -lwsock32 -lcomdlg32 -lole32"
|
||||
AM_CONDITIONAL(NATIVEWIN32,true)
|
||||
else
|
||||
LIBS="$LIBS -ldsound -lwinmm"
|
||||
fi
|
||||
elif expr x"$target" : 'x.*darwin' > /dev/null; then
|
||||
## Probably doesn't work
|
||||
AC_DEFINE([MACOSX])
|
||||
else
|
||||
AM_CONDITIONAL(UNIX, true)
|
||||
AC_DEFINE([UNIX])
|
||||
AC_DEFINE([PSS_STYLE],[1])
|
||||
fi
|
||||
if test x$use_nativewin32 = xno; then
|
||||
## Check for SDL
|
||||
SDL_VERSION=1.2.0
|
||||
AM_PATH_SDL($SDL_VERSION, [:],
|
||||
AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!]))
|
||||
AC_DEFINE([SDL])
|
||||
|
||||
LIBS="$LIBS $SDL_LIBS"
|
||||
CFLAGS="-Wall -fomit-frame-pointer $CFLAGS $SDL_CFLAGS"
|
||||
CPPFLAGS="-Wall -fomit-frame-pointer $CPPFLAGS $SDL_CFLAGS"
|
||||
|
||||
## Check for OpenGL
|
||||
AC_ARG_ENABLE([opengl],
|
||||
AS_HELP_STRING([--enable-opengl], [Enable OpenGL support]))
|
||||
AS_IF([test "x$enable_opengl" != "xno"], [
|
||||
AC_CHECK_HEADER([GL/gl.h],[AC_DEFINE([OPENGL]) AM_CONDITIONAL(OPENGL, true)],
|
||||
[
|
||||
AC_CHECK_HEADER([OpenGL/gl.h],[AC_DEFINE([OPENGL]) AM_CONDITIONAL(OPENGL, true)],[])
|
||||
AC_DEFINE([APPLEOPENGL])
|
||||
])
|
||||
LIBS="$LIBS -lGL -lGLU"
|
||||
])
|
||||
|
||||
## Check for GTK2
|
||||
AC_ARG_ENABLE([gtk2],
|
||||
AS_HELP_STRING([--enable-gtk2], [Enable GTK2 GUI]))
|
||||
AS_IF([test "x$enable_gtk2" = "xyes"], [
|
||||
AM_PATH_GTK_2_0([2.24.0],AM_CONDITIONAL(GTK2, true),AC_MSG_ERROR([Gtk+ 2.24.0 or higher required.]))
|
||||
AC_DEFINE([_GTK])
|
||||
AC_DEFINE([GTK2])
|
||||
])
|
||||
|
||||
## Check for GTK3
|
||||
AC_ARG_ENABLE([gtk3],
|
||||
AS_HELP_STRING([--enable-gtk3], [Enable GTK3 GUI]))
|
||||
AS_IF([test "x$enable_gtk2" = "xyes" -a "x$enable_gtk3" = "xyes"], [
|
||||
AC_MSG_ERROR([GTK2 and GTK3 cannot be simulatenously enabled.])
|
||||
])
|
||||
AS_IF([test "x$enable_gtk3" = "xyes"], [
|
||||
AM_PATH_GTK_3_0([3.0.0],AM_CONDITIONAL(GTK3, true),AC_MSG_ERROR([Gtk+ 3.0.0 or higher required.]))
|
||||
AC_DEFINE([_GTK])
|
||||
AC_DEFINE([GTK3])
|
||||
])
|
||||
fi
|
||||
|
||||
## Check for system lua
|
||||
AC_ARG_ENABLE([lua],
|
||||
AS_HELP_STRING([--enable-lua], [Use lua libraries found on this system]))
|
||||
AS_IF([test "x$enable_lua" = "xyes"], [
|
||||
AC_SUBST(LUA, lua5.1)
|
||||
AX_PROG_LUA([5.1],[5.2])
|
||||
PKG_CHECK_MODULES([lua51], [lua51])
|
||||
AX_LUA_LIBS([], AC_MSG_ERROR([Lua libs not found!]))
|
||||
AC_DEFINE([_S9XLUA_H])
|
||||
AM_CONDITIONAL(LUA, true)
|
||||
LIBS="$LIBS $LUA_LIB"
|
||||
])
|
||||
|
||||
## Check for lua builtin
|
||||
AC_ARG_ENABLE([lua-builtin],
|
||||
AS_HELP_STRING([--enable-lua-builtin], [Use lua5.1 included with fceux]))
|
||||
AS_IF([test "x$enable_lua-builtin" = "xyes"], [
|
||||
#AX_LUA_HEADERS([], AC_MSG_ERROR([Lua 5.1 headers not found!]))
|
||||
AC_DEFINE([_S9XLUA_H])
|
||||
AM_CONDITIONAL(LUA_BUILTIN, true)
|
||||
])
|
||||
|
||||
## Check for gd
|
||||
AC_ARG_ENABLE([gd],
|
||||
AS_HELP_STRING([--enable-gd], [Use libgd for AVI creation]))
|
||||
AS_IF([test "x$enable_gd" = "xyes"], [
|
||||
#AX_LUA_HEADERS([], AC_MSG_ERROR([Lua 5.1 headers not found!]))
|
||||
AX_CHECK_GD
|
||||
LIBS="$LIBS $GD_LIBS"
|
||||
AC_DEFINE([CREATE_AVI])
|
||||
])
|
||||
|
||||
## Check for system minizip
|
||||
AC_ARG_ENABLE([system-minizip],
|
||||
AS_HELP_STRING([--enable-system-minizip], [Use minizip from system instead of fceux distribution]))
|
||||
AS_IF([test "x$enable_system_minizip" = "xyes"], [
|
||||
PKG_CHECK_MODULES([minizip], [minizip])
|
||||
AM_CONDITIONAL(SYSTEM_MINIZIP, true)
|
||||
LIBS="$LIBS $minizip_LIBS"
|
||||
])
|
||||
|
||||
AC_C_BIGENDIAN([], [AC_DEFINE([LSB_FIRST])])
|
||||
|
||||
## Check for frameskip disable
|
||||
AC_ARG_ENABLE([frameskip],
|
||||
AS_HELP_STRING([--disable-frameskip], [Disable frameskip feature]))
|
||||
|
||||
AS_IF([test "x$disable_frameskip" != "xno"], [
|
||||
AC_DEFINE([FRAMESKIP])
|
||||
])
|
||||
|
||||
AC_OUTPUT([Makefile src/Makefile])
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/sh
|
||||
if [ -f /usr/bin/i586-mingw32msvc-windres ]; then HOST=i586-mingw32msvc
|
||||
else HOST=i586-mingw32
|
||||
fi
|
||||
PLATFORM=win32 CC=${HOST}-gcc CXX=${HOST}-g++ WRC=${HOST}-windres WINDRES=${HOST}-windres scons $@
|
|
@ -6,7 +6,7 @@ GenericName=NES/Famicom emulator
|
|||
NoDisplay=false
|
||||
Comment=Emulate NES ROMs
|
||||
Exec=/usr/bin/fceux
|
||||
Icon=/usr/share/pixmaps/fceux.png
|
||||
Icon=/usr/share/pixmaps/fceux1.png
|
||||
Terminal=false
|
||||
MimeType=application/x-nes-rom
|
||||
Categories=Game;Emulator;
|
||||
|
|
BIN
fceux.icns
369
fceux.pro
|
@ -1,369 +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
|
||||
|
||||
INCLUDEPATH += src src/drivers
|
||||
|
||||
ENABLE_LUA = 0
|
||||
USE_INTERNAL_LUA = 0
|
||||
|
||||
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
|
||||
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
|
||||
QMAKE_CXXFLAGS_RELEASE -= -O2
|
||||
|
||||
LIBS += -lz
|
||||
}
|
||||
|
||||
# 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
|
||||
|
||||
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
|
||||
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/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/ConsoleVideoConf.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/ConsoleVideoConf.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
|
||||
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
|
||||
SOURCES += src/drivers/Qt/sdl-joystick.cpp
|
||||
SOURCES += src/drivers/Qt/sdl-throttle.cpp
|
||||
SOURCES += src/drivers/Qt/unix-netplay.cpp
|
||||
|
BIN
fceux1.png
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 83 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 403 B |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 464 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 235 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 739 B |
BIN
output/fceux.chm
|
@ -2,7 +2,7 @@
|
|||
|
||||
use strict;
|
||||
|
||||
my $VERSION="2.2.3";
|
||||
my $VERSION="2.3.0";
|
||||
my $INSTALL_PREFIX="/tmp/fceux";
|
||||
my $CTL_FILENAME="$INSTALL_PREFIX/DEBIAN/control";
|
||||
my $ARCH="amd64";
|
||||
|
|
|
@ -25,6 +25,10 @@ echo '****************************************'
|
|||
echo '*** Installing Package Dependencies ***'
|
||||
echo '****************************************'
|
||||
echo '****************************************'
|
||||
echo '****************************************'
|
||||
echo 'Install Dependency Updates'
|
||||
echo '****************************************'
|
||||
sudo apt-get --assume-yes update
|
||||
# Install Lua-5.1 development package
|
||||
echo '****************************************'
|
||||
echo 'Install Dependency lua5.1-dev'
|
||||
|
@ -89,28 +93,27 @@ 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
|
||||
|
||||
echo "Num CPU: `nproc`";
|
||||
mkdir buildQT; cd buildQT;
|
||||
cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX/usr \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \
|
||||
..
|
||||
make -j `nproc`
|
||||
make install
|
||||
make install DESTDIR=$INSTALL_PREFIX
|
||||
|
||||
cd ..;
|
||||
mkdir buildGTK; cd buildGTK;
|
||||
cmake \
|
||||
-DGTK=1 \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX/usr \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \
|
||||
..
|
||||
make -j `nproc`
|
||||
make install
|
||||
make install DESTDIR=$INSTALL_PREFIX
|
||||
|
||||
# Install Files
|
||||
#cd .. # cd out of build
|
||||
|
|
|
@ -7,8 +7,8 @@ uname -a
|
|||
sw_vers
|
||||
|
||||
FCEUX_VERSION_MAJOR=2
|
||||
FCEUX_VERSION_MINOR=2
|
||||
FCEUX_VERSION_PATCH=3
|
||||
FCEUX_VERSION_MINOR=3
|
||||
FCEUX_VERSION_PATCH=0
|
||||
|
||||
SCRIPT_DIR=$( cd $(dirname $BASH_SOURCE[0]); pwd );
|
||||
|
||||
|
@ -43,7 +43,6 @@ brew install minizip
|
|||
|
||||
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig:
|
||||
|
||||
#QMAKE=`find /usr/local -name qmake`;
|
||||
QT_CMAKE=`find /usr/local -name Qt5Config.cmake`
|
||||
echo $QT_CMAKE;
|
||||
export Qt5_DIR=`dirname $QT_CMAKE`;
|
||||
|
@ -54,11 +53,11 @@ echo '*** Building Project ***'
|
|||
echo '**************************'
|
||||
mkdir build;
|
||||
cd build;
|
||||
#$QMAKE ..
|
||||
cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX \
|
||||
-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \
|
||||
-DCMAKE_PREFIX_PATH=`brew --prefix qt5` \
|
||||
-DCMAKE_PROJECT_VERSION_MAJOR=$FCEUX_VERSION_MAJOR \
|
||||
-DCMAKE_PROJECT_VERSION_MINOR=$FCEUX_VERSION_MINOR \
|
||||
-DCMAKE_PROJECT_VERSION_PATCH=$FCEUX_VERSION_PATCH \
|
||||
|
|
|
@ -7,8 +7,8 @@ An open source NES Emulator for Windows and Unix that features solid emulation a
|
|||
Interim builds:
|
||||
* Win32: [fceux.zip](https://ci.appveyor.com/api/projects/zeromus/fceux/artifacts/fceux.zip?branch=master&job=Windows%2032)
|
||||
* Win64: [fceux64.zip](https://ci.appveyor.com/api/projects/zeromus/fceux/artifacts/fceux64.zip?branch=master&job=Windows%2064)
|
||||
* Ubuntu: [fceux-2.2.3-amd64.deb](https://ci.appveyor.com/api/projects/zeromus/fceux/artifacts/fceux-2.2.3-amd64.deb?branch=master&job=Ubuntu)
|
||||
* MacOSX: [fceux-2.2.3-Darwin.dmg](https://ci.appveyor.com/api/projects/zeromus/fceux/artifacts/fceux-2.2.3-Darwin.dmg?branch=master&job=MacOS)
|
||||
* Ubuntu: [fceux-2.3.0-amd64.deb](https://ci.appveyor.com/api/projects/zeromus/fceux/artifacts/fceux-2.3.0-amd64.deb?branch=master&job=Ubuntu)
|
||||
* MacOSX: [fceux-2.3.0-Darwin.dmg](https://ci.appveyor.com/api/projects/zeromus/fceux/artifacts/fceux-2.3.0-Darwin.dmg?branch=master&job=MacOS)
|
||||
* Status: [Appveyor](https://ci.appveyor.com/project/zeromus/fceux/)
|
||||
|
||||
But you might like mesen more: https://github.com/SourMesen/Mesen
|
||||
|
@ -17,4 +17,4 @@ You should get releases from here: https://sourceforge.net/projects/fceultra/fil
|
|||
|
||||
That's because github forces us to use tags we don't have for releases.
|
||||
|
||||
2.2.3 is the most recent release but most people are using the autobuilds.
|
||||
2.3.0 is the most recent release but most people are using the autobuilds.
|
||||
|
|
|
@ -2,5 +2,16 @@
|
|||
<qresource>
|
||||
<file>fceux.png</file>
|
||||
<file>fceux1.png</file>
|
||||
<file>icons/power.png</file>
|
||||
<file>icons/media-record.png</file>
|
||||
<file>icons/application-exit.png</file>
|
||||
<file>icons/graphics-palette.png</file>
|
||||
<file>icons/view-fullscreen.png</file>
|
||||
<file>icons/input-keyboard.png</file>
|
||||
<file>icons/input-gaming.png</file>
|
||||
<file>icons/input-gaming-symbolic.png</file>
|
||||
<file>icons/timer.png</file>
|
||||
<file>icons/movie.png</file>
|
||||
<file>icons/camera.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
#!/bin/bash
|
||||
|
||||
SRC_PNG=../fceux1.png
|
||||
ICON_PATH=/usr/share/icons/hicolor
|
||||
|
||||
convert -resize 32x32 $SRC_PNG fceux-32x32.png
|
||||
convert -resize 48x48 $SRC_PNG fceux-48x48.png
|
||||
convert -resize 64x64 $SRC_PNG fceux-64x64.png
|
||||
convert -resize 72x72 $SRC_PNG fceux-72x72.png
|
||||
convert -resize 96x96 $SRC_PNG fceux-96x96.png
|
||||
convert -resize 128x128 $SRC_PNG fceux-128x128.png
|
||||
convert -resize 256x256 $SRC_PNG fceux-256x256.png
|
||||
|
||||
#sudo cp -f fceux-32x32.png $ICON_PATH/32x32/apps/fceux.png
|
||||
#sudo cp -f fceux-48x48.png $ICON_PATH/48x48/apps/fceux.png
|
||||
#sudo cp -f fceux-64x64.png $ICON_PATH/64x64/apps/fceux.png
|
||||
#sudo cp -f fceux-72x72.png $ICON_PATH/72x72/apps/fceux.png
|
||||
#sudo cp -f fceux-96x96.png $ICON_PATH/96x96/apps/fceux.png
|
||||
#sudo cp -f fceux-128x128.png $ICON_PATH/128x128/apps/fceux.png
|
||||
#sudo cp -f fceux-256x256.png $ICON_PATH/256x256/apps/fceux.png
|
|
@ -81,14 +81,16 @@ else(WIN32)
|
|||
pkg_check_modules( SDL2 REQUIRED sdl2)
|
||||
|
||||
if ( ${SDL2_FOUND} )
|
||||
add_definitions( ${SDL2_CFLAGS} )
|
||||
add_definitions( ${SDL2_CFLAGS} -D__SDL__ )
|
||||
endif()
|
||||
|
||||
# Check for LUA
|
||||
pkg_check_modules( LUA lua-5.1)
|
||||
pkg_search_module( LUA lua5.1 lua-5.1 )
|
||||
|
||||
if ( ${LUA_FOUND} )
|
||||
# Use System LUA
|
||||
message( STATUS "Using System Lua ${LUA_VERSION}" )
|
||||
|
||||
add_definitions( -D_S9XLUA_H ${LUA_CFLAGS} )
|
||||
|
||||
set( LUA_ENGINE_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/lua-engine.cpp )
|
||||
|
@ -96,6 +98,8 @@ else(WIN32)
|
|||
else ()
|
||||
|
||||
# Use Internal LUA
|
||||
message( STATUS "Using Internal Lua" )
|
||||
|
||||
add_definitions( -D_S9XLUA_H -I${CMAKE_CURRENT_SOURCE_DIR}/lua/src )
|
||||
|
||||
set( LUA_ENGINE_SOURCE
|
||||
|
@ -279,6 +283,7 @@ set(SRC_CORE
|
|||
${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/bs4xxxr.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/boards/cheapocabra.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/boards/cityfighter.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/boards/coolboy.cpp
|
||||
|
@ -371,6 +376,7 @@ set(SRC_CORE
|
|||
${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/lcdcompzapper.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/input/zapper.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/utils/backward.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/utils/ConvertUTF.c
|
||||
|
@ -425,22 +431,34 @@ set(SRC_DRIVERS_SDL
|
|||
${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/InputConf.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/GamePadConf.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/HotKeyConf.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/TimingConf.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/FrameTimingStats.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/PaletteConf.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/GuiConf.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/MoviePlay.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/MovieOptions.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/LuaControl.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/CheatsConf.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/GameGenie.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/HexEditor.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/MsgLogViewer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/CodeDataLogger.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/SymbolicDebug.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleDebugger.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleUtilities.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleVideoConf.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleSoundConf.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/iNesHeaderEditor.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/TraceLogger.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/AboutWindow.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/fceuWrapper.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ppuViewer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/NameTableViewer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/RamWatch.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/RamSearch.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
|
||||
|
@ -509,19 +527,24 @@ 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} )
|
||||
# Use \$ to defer expansion until install script is called; CPack will call it with its own CMAKE_INSTALL_PREFIX
|
||||
set(APP \${CMAKE_INSTALL_PREFIX}/${APP_NAME}.app)
|
||||
|
||||
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}\") "
|
||||
# macdeployqt tool that comes with Qt: https://doc.qt.io/qt-5/macos-deployment.html#macdeploy
|
||||
# Compared to fixup_bundle, correctly finds and installs Qt-specific resources as well as non-Qt dependencies
|
||||
find_program(MACDEPLOYQT macdeployqt)
|
||||
if(NOT MACDEPLOYQT)
|
||||
message(FATAL_ERROR "Could not find macdeployqt executable")
|
||||
endif()
|
||||
|
||||
install( CODE "
|
||||
message(STATUS \"Deploying and fixing up dependencies in app: ${APP}\")
|
||||
execute_process(COMMAND \"${MACDEPLOYQT}\" \"${APP}\" -verbose=1)
|
||||
"
|
||||
COMPONENT Runtime
|
||||
)
|
||||
|
||||
|
@ -532,7 +555,7 @@ install( TARGETS ${APP_NAME}
|
|||
|
||||
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}/fceux1.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 )
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
import glob
|
||||
file_list = glob.glob('*.cpp')
|
||||
file_list.remove('lua-engine.cpp') # use logic below for this
|
||||
|
||||
subdirs = Split("""
|
||||
boards
|
||||
drivers/common
|
||||
fir
|
||||
input
|
||||
utils
|
||||
""")
|
||||
#palettes
|
||||
|
||||
Import('env')
|
||||
Export('env')
|
||||
|
||||
if env['LUA']:
|
||||
file_list.append('lua-engine.cpp')
|
||||
if env['SYSTEM_LUA'] == 0:
|
||||
subdirs.append('lua')
|
||||
|
||||
if env['CREATE_AVI']:
|
||||
subdirs.append('drivers/videolog')
|
||||
|
||||
|
||||
|
||||
for dir in subdirs:
|
||||
subdir_files = SConscript('%s/SConscript' % dir)
|
||||
file_list.append(subdir_files)
|
||||
if env['PLATFORM'] == 'win32':
|
||||
platform_files = SConscript('drivers/win/SConscript')
|
||||
else:
|
||||
platform_files = SConscript('drivers/sdl/SConscript')
|
||||
file_list.append(platform_files)
|
||||
|
||||
print(env['LINKFLAGS'])
|
||||
|
||||
if env['PLATFORM'] == 'win32':
|
||||
fceux = env.Program('fceux.exe', file_list)
|
||||
else:
|
||||
fceux = env.Program('fceux', file_list)
|
||||
Return('fceux')
|
|
@ -44,7 +44,7 @@ void LockConsole(void);
|
|||
void UnlockConsole(void);
|
||||
void ToggleFS(); /* SDL */
|
||||
|
||||
int LoadGame(const char *path);
|
||||
int LoadGame(const char *path, bool silent = false);
|
||||
int CloseGame(void);
|
||||
int GUI_Init(int argc, char **argv, int (*dofunc)(void));
|
||||
int GUI_Idle(void);
|
||||
|
|
|
@ -275,12 +275,12 @@ static void DoArgs(int argc, char *argv[])
|
|||
provides data necessary for the driver code(number of scanlines to
|
||||
render, what virtual input devices to use, etc.).
|
||||
*/
|
||||
int LoadGame(const char *path)
|
||||
int LoadGame(const char *path, bool silent)
|
||||
{
|
||||
FCEUGI *tmp;
|
||||
|
||||
CloseGame();
|
||||
if(!(tmp=FCEUI_LoadGame(path,1)))
|
||||
if(!(tmp=FCEUI_LoadGame(path,1,silent)))
|
||||
return 0;
|
||||
CurGame=tmp;
|
||||
ParseGI(tmp);
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
import glob
|
||||
source_list = glob.glob('*.cpp')+glob.glob('*.c')
|
||||
|
||||
for x in range(len(source_list)):
|
||||
source_list[x] = 'boards/' + source_list[x]
|
||||
Return('source_list')
|
|
@ -0,0 +1,164 @@
|
|||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2020 CaH4e3
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Double Dragon 310000-in-1 (4040R)
|
||||
* 700000-in-1 (BS-400R)(Unl)
|
||||
*/
|
||||
|
||||
#include "mapinc.h"
|
||||
#include "mmc3.h"
|
||||
|
||||
static uint8 pointer;
|
||||
static uint8 offset;
|
||||
static uint8 *WRAM = NULL;
|
||||
static uint32 WRAMSIZE;
|
||||
|
||||
static int getPRGBankBS4XXXR(int bank)
|
||||
{
|
||||
if (((~bank) & 1) && (pointer & 0x40))
|
||||
bank ^= 2;
|
||||
return (bank & 2) ? (0xFE | (bank & 1)) : EXPREGS[4 | (bank & 1)];
|
||||
}
|
||||
|
||||
static void BS4XXXRPW(uint32 A, uint8 V) {
|
||||
|
||||
if ((EXPREGS[3] >> 4) & 0x01)
|
||||
{
|
||||
int AND = ((EXPREGS[0] >> 1) & 1) ? 0x0F : 0x0F;
|
||||
int OR = (EXPREGS[0] & 7) << 4;
|
||||
int bank0 = getPRGBankBS4XXXR(0);
|
||||
int bank1 = getPRGBankBS4XXXR(1);
|
||||
if (!((EXPREGS[3] >> 1) & 1)) //16K Mode
|
||||
{
|
||||
setprg8(0x8000, ((bank0) & AND) | OR);
|
||||
setprg8(0xA000, ((bank1) & AND) | OR);
|
||||
setprg8(0xC000, ((bank0) & AND) | OR);
|
||||
setprg8(0xE000, ((bank1) & AND) | OR);
|
||||
}
|
||||
else // 32K Mode
|
||||
{
|
||||
setprg8(0x8000, ((bank0) & AND) | OR);
|
||||
setprg8(0xA000, ((bank1) & AND) | OR);
|
||||
setprg8(0xC000, ((bank0 | 2) & AND) | OR);
|
||||
setprg8(0xE000, ((bank1 | 2) & AND) | OR);
|
||||
}
|
||||
}
|
||||
else // MMC3 Mode
|
||||
{
|
||||
int prgAND = ((EXPREGS[0] >> offset) & 1) ? 0x0F : 0x1F;
|
||||
int prgOR = (EXPREGS[0] & 7) << 4;
|
||||
setprg8(A, (V & prgAND) | (prgOR));
|
||||
}
|
||||
setprg8r(0x10, 0x6000, 0);
|
||||
}
|
||||
|
||||
static void BS4XXXRCW(uint32 A, uint8 V) {
|
||||
if ((EXPREGS[3] >> 4) & 1)
|
||||
{
|
||||
int AND = ((EXPREGS[0] >> 1) & 1) ? 0x0F : 0x0F;
|
||||
int bank = EXPREGS[2] & AND;
|
||||
int chrOR = ((EXPREGS[0] >> 3) & 7) << 4;
|
||||
setchr8((bank) | (chrOR));
|
||||
}
|
||||
else
|
||||
{
|
||||
int chrAND = ((EXPREGS[0] >> 1) & 1) ? 0xFF : 0xFF;
|
||||
int chrOR = ((EXPREGS[0] >> 3) & 7) << 7;
|
||||
setchr1(A, (V & chrAND) | (chrOR));
|
||||
}
|
||||
}
|
||||
|
||||
static DECLFW(BS4XXXRHiWrite) {
|
||||
// FCEU_printf("w: %04x-%02x\n",A,V)
|
||||
if (A==0x8000)
|
||||
{
|
||||
pointer = MMC3_cmd ^ V;
|
||||
}
|
||||
else if (A == 0x8001)
|
||||
{
|
||||
if((MMC3_cmd & 7) > 5)
|
||||
EXPREGS[4|(MMC3_cmd & 1)] = V;
|
||||
}
|
||||
MMC3_CMDWrite(A, V);
|
||||
}
|
||||
|
||||
static DECLFW(BS4XXXRLoWrite) {
|
||||
// FCEU_printf("w: %04x-%02x\n", A, V);
|
||||
if (A & 0x800)
|
||||
{
|
||||
if (!(EXPREGS[3] & 0x80)) {
|
||||
EXPREGS[A & 0x03] = V;
|
||||
FixMMC3PRG(MMC3_cmd);
|
||||
FixMMC3CHR(MMC3_cmd);
|
||||
}
|
||||
else if (EXPREGS[3] & 0x10)
|
||||
{
|
||||
EXPREGS[A & 0x03] = V;
|
||||
FixMMC3PRG(MMC3_cmd);
|
||||
FixMMC3CHR(MMC3_cmd);
|
||||
}
|
||||
else
|
||||
WRAM[A - 0x6000] = V;
|
||||
}
|
||||
else
|
||||
WRAM[A - 0x6000] = V;
|
||||
}
|
||||
|
||||
|
||||
static void BSXXXXRPower(void) {
|
||||
EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = EXPREGS[4] = EXPREGS[5] = 0;
|
||||
GenMMC3Power();
|
||||
SetReadHandler(0x6000, 0x7FFF, CartBR);
|
||||
SetWriteHandler(0x6000, 0x7FFF, BS4XXXRLoWrite);
|
||||
SetWriteHandler(0x8000, 0x9FFF, BS4XXXRHiWrite);
|
||||
FixMMC3PRG(MMC3_cmd);
|
||||
FixMMC3CHR(MMC3_cmd);
|
||||
}
|
||||
|
||||
static void BS4XXXRClose(void) {
|
||||
if (WRAM)
|
||||
FCEU_gfree(WRAM);
|
||||
WRAM = NULL;
|
||||
}
|
||||
|
||||
void BSXXXXR_Init(CartInfo *info) {
|
||||
GenMMC3_Init(info, 512, 256, 8, 0);
|
||||
cwrap = BS4XXXRCW;
|
||||
pwrap = BS4XXXRPW;
|
||||
|
||||
info->Power = BSXXXXRPower;
|
||||
info->Close = BS4XXXRClose;
|
||||
|
||||
WRAMSIZE = 8192;
|
||||
WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
|
||||
SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
|
||||
AddExState(WRAM, WRAMSIZE, 0, "WRAM");
|
||||
|
||||
AddExState(EXPREGS, 8, 0, "EXPR");
|
||||
}
|
||||
|
||||
void BS400R_Init(CartInfo *info) {
|
||||
offset = 1;
|
||||
BSXXXXR_Init(info);
|
||||
}
|
||||
|
||||
void BS4040R_Init(CartInfo *info) {
|
||||
offset = 6;
|
||||
BSXXXXR_Init(info);
|
||||
}
|
|
@ -22,6 +22,8 @@
|
|||
|
||||
#include "mapinc.h"
|
||||
|
||||
#include <array>
|
||||
|
||||
#define ABANKS MMC5SPRVPage
|
||||
#define BBANKS MMC5BGVPage
|
||||
#define SpriteON (PPU[1] & 0x10) //Show Sprite
|
||||
|
@ -81,10 +83,11 @@ static INLINE void MMC5BGVROM_BANK8(uint32 V) {
|
|||
}
|
||||
}
|
||||
|
||||
static uint8 PRGBanks[4];
|
||||
static std::array<uint8,4> PRGBanks;
|
||||
static uint8 WRAMPage;
|
||||
static uint16 CHRBanksA[8], CHRBanksB[4];
|
||||
static uint8 WRAMMaskEnable[2];
|
||||
static std::array<uint16,8> CHRBanksA;
|
||||
static std::array<uint16,4> CHRBanksB;
|
||||
static std::array<uint8,2> WRAMMaskEnable;
|
||||
uint8 mmc5ABMode; /* A=0, B=1 */
|
||||
|
||||
static uint8 IRQScanline, IRQEnable;
|
||||
|
@ -93,7 +96,7 @@ static uint8 CHRMode, NTAMirroring, NTFill, ATFill;
|
|||
static uint8 MMC5IRQR;
|
||||
static uint8 MMC5LineCounter;
|
||||
static uint8 mmc5psize, mmc5vsize;
|
||||
static uint8 mul[2];
|
||||
static std::array<uint8,2> mul;
|
||||
|
||||
static uint32 WRAMSIZE = 0;
|
||||
static uint8 *WRAM = NULL;
|
||||
|
@ -104,8 +107,8 @@ const int MMC5WRAMMAX = 1<<7; // 7 bits in register interface (real MMC5 has onl
|
|||
static uint8 MMC5WRAMsize; //configuration, not state
|
||||
static uint8 MMC5WRAMIndex[MMC5WRAMMAX]; //configuration, not state
|
||||
|
||||
static uint8 MMC5ROMWrProtect[4];
|
||||
static uint8 MMC5MemIn[5];
|
||||
static std::array<uint8,4> MMC5ROMWrProtect;
|
||||
static std::array<uint8,5> MMC5MemIn;
|
||||
|
||||
static void MMC5CHRA(void);
|
||||
static void MMC5CHRB(void);
|
||||
|
@ -895,18 +898,35 @@ void NSFMMC5_Close(void) {
|
|||
ExRAM = NULL;
|
||||
}
|
||||
|
||||
static void GenMMC5Reset(void) {
|
||||
int x;
|
||||
static void GenMMC5Power(void) {
|
||||
|
||||
for (x = 0; x < 4; x++) PRGBanks[x] = ~0;
|
||||
for (x = 0; x < 8; x++) CHRBanksA[x] = ~0;
|
||||
for (x = 0; x < 4; x++) CHRBanksB[x] = ~0;
|
||||
WRAMMaskEnable[0] = WRAMMaskEnable[1] = ~0;
|
||||
|
||||
mmc5psize = mmc5vsize = 3;
|
||||
PRGBanks.fill(0xFF);
|
||||
WRAMPage = 0;
|
||||
CHRBanksA.fill(0xFF);
|
||||
CHRBanksB.fill(0xFF);
|
||||
WRAMMaskEnable.fill(0xFF);
|
||||
mmc5ABMode = 0;
|
||||
IRQScanline = 0;
|
||||
IRQEnable = 0;
|
||||
CHRMode = 0;
|
||||
|
||||
NTAMirroring = NTFill = ATFill = 0xFF;
|
||||
MMC5IRQR = 0;
|
||||
MMC5LineCounter = 0;
|
||||
mmc5psize = mmc5vsize = 3;
|
||||
mul.fill(0);
|
||||
|
||||
MMC5ROMWrProtect.fill(0);
|
||||
MMC5MemIn.fill(0);
|
||||
|
||||
// MMC5fill is and 8-bit tile index, and a 2-bit attribute implented as a mirrored nametable
|
||||
u8 nval = MMC5fill[0x000];
|
||||
u8 aval = MMC5fill[0x3C0] & 3; aval = aval | (aval << 2) | (aval << 4) | (aval << 6);
|
||||
FCEU_dwmemset(MMC5fill + 0x000, nval | (nval<<8) | (nval<<16) | (nval<<24), 0x3C0);
|
||||
FCEU_dwmemset(MMC5fill + 0x3C0, aval | (aval<<8) | (aval<<16) | (aval<<24), 0x040);
|
||||
|
||||
FCEU_MemoryRand(WRAM, MMC5WRAMsize * 8 * 1024);
|
||||
FCEU_MemoryRand(MMC5fill,1024);
|
||||
FCEU_MemoryRand(ExRAM,1024);
|
||||
|
||||
MMC5Synco();
|
||||
|
||||
|
@ -929,11 +949,11 @@ static void GenMMC5Reset(void) {
|
|||
}
|
||||
|
||||
static SFORMAT MMC5_StateRegs[] = {
|
||||
{ PRGBanks, 4, "PRGB" },
|
||||
{ CHRBanksA, 16, "CHRA" },
|
||||
{ CHRBanksB, 8, "CHRB" },
|
||||
{ &PRGBanks, 4, "PRGB" },
|
||||
{ &CHRBanksA, 16, "CHRA" },
|
||||
{ &CHRBanksB, 8, "CHRB" },
|
||||
{ &WRAMPage, 1, "WRMP" },
|
||||
{ WRAMMaskEnable, 2, "WRME" },
|
||||
{ &WRAMMaskEnable, 2, "WRME" },
|
||||
{ &mmc5ABMode, 1, "ABMD" },
|
||||
{ &IRQScanline, 1, "IRQS" },
|
||||
{ &IRQEnable, 1, "IRQE" },
|
||||
|
@ -947,9 +967,9 @@ static SFORMAT MMC5_StateRegs[] = {
|
|||
{ &MMC5LineCounter, 1, "LCTR" },
|
||||
{ &mmc5psize, 1, "PSIZ" },
|
||||
{ &mmc5vsize, 1, "VSIZ" },
|
||||
{ mul, 2, "MUL2" },
|
||||
{ MMC5ROMWrProtect, 4, "WRPR" },
|
||||
{ MMC5MemIn, 5, "MEMI" },
|
||||
{ &mul, 2, "MUL2" },
|
||||
{ &MMC5ROMWrProtect, 4, "WRPR" },
|
||||
{ &MMC5MemIn, 5, "MEMI" },
|
||||
|
||||
{ &MMC5Sound.wl[0], 2 | FCEUSTATE_RLSB, "SDW0" },
|
||||
{ &MMC5Sound.wl[1], 2 | FCEUSTATE_RLSB, "SDW1" },
|
||||
|
@ -972,19 +992,14 @@ static SFORMAT MMC5_StateRegs[] = {
|
|||
|
||||
static void GenMMC5_Init(CartInfo *info, int wsize, int battery) {
|
||||
if (wsize) {
|
||||
WRAM = (uint8*)FCEU_gmalloc(wsize * 1024);
|
||||
WRAM = (uint8*)FCEU_malloc(wsize * 1024);
|
||||
SetupCartPRGMapping(0x10, WRAM, wsize * 1024, 1);
|
||||
AddExState(WRAM, wsize * 1024, 0, "WRAM");
|
||||
}
|
||||
|
||||
MMC5fill = (uint8*)FCEU_gmalloc(1024);
|
||||
ExRAM = (uint8*)FCEU_gmalloc(1024);
|
||||
MMC5fill = (uint8*)FCEU_malloc(1024);
|
||||
ExRAM = (uint8*)FCEU_malloc(1024);
|
||||
|
||||
// MMC5fill is and 8-bit tile index, and a 2-bit attribute implented as a mirrored nametable
|
||||
u8 nval = MMC5fill[0x000];
|
||||
u8 aval = MMC5fill[0x3C0] & 3; aval = aval | (aval << 2) | (aval << 4) | (aval << 6);
|
||||
FCEU_dwmemset(MMC5fill + 0x000, nval | (nval<<8) | (nval<<16) | (nval<<24), 0x3C0);
|
||||
FCEU_dwmemset(MMC5fill + 0x3C0, aval | (aval<<8) | (aval<<16) | (aval<<24), 0x040);
|
||||
|
||||
AddExState(ExRAM, 1024, 0, "ERAM");
|
||||
AddExState(&MMC5HackSPMode, 1, 0, "SPLM");
|
||||
|
@ -996,7 +1011,7 @@ static void GenMMC5_Init(CartInfo *info, int wsize, int battery) {
|
|||
MMC5WRAMsize = wsize / 8;
|
||||
BuildWRAMSizeTable();
|
||||
GameStateRestore = MMC5_StateRestore;
|
||||
info->Power = GenMMC5Reset;
|
||||
info->Power = GenMMC5Power;
|
||||
|
||||
if (battery) {
|
||||
info->SaveGame[0] = WRAM;
|
||||
|
|
|
@ -902,31 +902,31 @@ int FCEU_DisableAllCheats(){
|
|||
return count;
|
||||
}
|
||||
|
||||
inline int FCEUI_FindCheatMapByte(uint16 address)
|
||||
int FCEUI_FindCheatMapByte(uint16 address)
|
||||
{
|
||||
return cheatMap[address / 8] >> (address % 8) & 1;
|
||||
}
|
||||
|
||||
inline void FCEUI_SetCheatMapByte(uint16 address, bool cheat)
|
||||
void FCEUI_SetCheatMapByte(uint16 address, bool cheat)
|
||||
{
|
||||
cheat ? cheatMap[address / 8] |= (1 << address % 8) : cheatMap[address / 8] ^= (1 << address % 8);
|
||||
}
|
||||
|
||||
inline void FCEUI_CreateCheatMap()
|
||||
void FCEUI_CreateCheatMap(void)
|
||||
{
|
||||
if (!cheatMap)
|
||||
cheatMap = (unsigned char*)malloc(CHEATMAP_SIZE);
|
||||
FCEUI_RefreshCheatMap();
|
||||
}
|
||||
|
||||
inline void FCEUI_RefreshCheatMap()
|
||||
void FCEUI_RefreshCheatMap(void)
|
||||
{
|
||||
memset(cheatMap, 0, CHEATMAP_SIZE);
|
||||
for (uint32 i = 0; i < numsubcheats; ++i)
|
||||
FCEUI_SetCheatMapByte(SubCheats[i].addr, true);
|
||||
}
|
||||
|
||||
inline void FCEUI_ReleaseCheatMap()
|
||||
void FCEUI_ReleaseCheatMap(void)
|
||||
{
|
||||
if (cheatMap)
|
||||
{
|
||||
|
|
|
@ -18,9 +18,10 @@ typedef unsigned char _8BYTECHEATMAP;
|
|||
|
||||
extern int FCEUI_FindCheatMapByte(uint16 address);
|
||||
extern void FCEUI_SetCheatMapByte(uint16 address, bool cheat);
|
||||
extern void FCEUI_CreateCheatMap();
|
||||
extern void FCEUI_RefreshCheatMap();
|
||||
extern void FCEUI_ReleaseCheatMap();
|
||||
extern void FCEUI_CreateCheatMap(void);
|
||||
extern void FCEUI_RefreshCheatMap(void);
|
||||
extern void FCEUI_ReleaseCheatMap(void);
|
||||
extern unsigned int FrozenAddressCount;
|
||||
|
||||
int FCEU_CheatGetByte(uint32 A);
|
||||
void FCEU_CheatSetByte(uint32 A, uint8 V);
|
||||
|
|
|
@ -18,10 +18,10 @@ char *FCEUI_GetAboutString() {
|
|||
const char *aboutTemplate =
|
||||
FCEU_NAME_AND_VERSION "\n\n"
|
||||
"Administrators:\n"
|
||||
"zeromus, punkrockguy318 (Lukas Sabota), feos\n"
|
||||
"zeromus, mjbudd77, feos\n"
|
||||
"\n"
|
||||
"Current Contributors:\n"
|
||||
"CaH4e3, rainwarrior\n"
|
||||
"CaH4e3, rainwarrior, owomomo, punkrockguy318\n"
|
||||
"\n"
|
||||
"Past Contributors:\n"
|
||||
"xhainingx, gocha, AnS\n"
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include <QUrl>
|
||||
#include <QTextEdit>
|
||||
#include <QDesktopServices>
|
||||
//#include "Qt/icon.xpm"
|
||||
#include "Qt/AboutWindow.h"
|
||||
#include "Qt/fceux_git_info.h"
|
||||
#include "../../version.h"
|
||||
|
@ -41,7 +40,6 @@ AboutWindow::AboutWindow(QWidget *parent)
|
|||
int i;
|
||||
QVBoxLayout *mainLayout;
|
||||
QHBoxLayout *hbox1;
|
||||
//QPixmap pm( icon_xpm );
|
||||
QPixmap pm(":fceux1.png");
|
||||
QPixmap pm2;
|
||||
QLabel *lbl;
|
||||
|
@ -121,7 +119,7 @@ AboutWindow::AboutWindow(QWidget *parent)
|
|||
mainLayout->addLayout( hbox1 );
|
||||
|
||||
hbox1 = new QHBoxLayout();
|
||||
lbl = new QLabel( tr("© 2016 FceuX Development Team") );
|
||||
lbl = new QLabel( tr("© 2020 FceuX Development Team") );
|
||||
|
||||
hbox1->addWidget( lbl );
|
||||
hbox1->setAlignment( Qt::AlignCenter );
|
||||
|
|
|
@ -27,8 +27,28 @@
|
|||
|
||||
static GuiCheatsDialog_t *win = NULL;
|
||||
//----------------------------------------------------------------------------
|
||||
void openCheatDialog(QWidget *parent)
|
||||
{
|
||||
if ( win != NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
win = new GuiCheatsDialog_t(parent);
|
||||
|
||||
win->show();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void updateCheatDialog(void)
|
||||
{
|
||||
if ( win == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
win->showActiveCheatList( true );
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
GuiCheatsDialog_t::GuiCheatsDialog_t(QWidget *parent)
|
||||
: QDialog( parent )
|
||||
: QDialog( parent, Qt::Window )
|
||||
{
|
||||
QHBoxLayout *mainLayout, *hbox, *hbox1;
|
||||
QVBoxLayout *vbox, *vbox1, *vbox2, *vbox3;
|
||||
|
@ -36,14 +56,6 @@ GuiCheatsDialog_t::GuiCheatsDialog_t(QWidget *parent)
|
|||
QLabel *lbl;
|
||||
QGroupBox *groupBox;
|
||||
QFrame *frame;
|
||||
QScreen *screen = QGuiApplication::primaryScreen();
|
||||
double devPixRatio = 1.0f;
|
||||
|
||||
if ( screen != NULL )
|
||||
{
|
||||
devPixRatio = (int)( screen->devicePixelRatio() + 0.50f);
|
||||
//printf("Pix Ratio: %f \n", devPixRatio );
|
||||
}
|
||||
|
||||
font.setFamily("Courier New");
|
||||
font.setStyle( QFont::StyleNormal );
|
||||
|
@ -51,8 +63,11 @@ GuiCheatsDialog_t::GuiCheatsDialog_t(QWidget *parent)
|
|||
|
||||
QFontMetrics fm(font);
|
||||
|
||||
//fontCharWidth = fm.boundingRect('X').width() * devPixRatio;
|
||||
fontCharWidth = 2.00 * fm.averageCharWidth() * devPixRatio;
|
||||
#if QT_VERSION > QT_VERSION_CHECK(5, 11, 0)
|
||||
fontCharWidth = 2 * fm.horizontalAdvance(QLatin1Char('2'));
|
||||
#else
|
||||
fontCharWidth = 2 * fm.width(QLatin1Char('2'));
|
||||
#endif
|
||||
|
||||
setWindowTitle("Cheat Search");
|
||||
|
||||
|
@ -417,6 +432,7 @@ GuiCheatsDialog_t::~GuiCheatsDialog_t(void)
|
|||
}
|
||||
wasPausedByCheats = false;
|
||||
|
||||
win = NULL;
|
||||
printf("Destroy Cheat Window Event\n");
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -618,7 +634,7 @@ int GuiCheatsDialog_t::activeCheatListCB (char *name, uint32 a, uint8 v, int c,
|
|||
|
||||
if (c >= 0)
|
||||
{
|
||||
sprintf (codeStr, "$%04X:%02X:%02X", a,v,c);
|
||||
sprintf (codeStr, "$%04X?%02X:%02X", a,c,v);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -644,6 +660,7 @@ int GuiCheatsDialog_t::activeCheatListCB (char *name, uint32 a, uint8 v, int c,
|
|||
|
||||
item->setTextAlignment( 0, Qt::AlignLeft);
|
||||
item->setTextAlignment( 1, Qt::AlignLeft);
|
||||
item->setTextAlignment( 2, Qt::AlignLeft);
|
||||
|
||||
actvCheatIdx++;
|
||||
|
||||
|
@ -684,7 +701,7 @@ void GuiCheatsDialog_t::openCheatFile(void)
|
|||
dialog.setNameFilter(tr("Cheat files (*.cht *.CHT) ;; All files (*)"));
|
||||
|
||||
dialog.setViewMode(QFileDialog::List);
|
||||
dialog.setFilter( QDir::AllEntries | QDir::Hidden );
|
||||
dialog.setFilter( QDir::AllEntries | QDir::AllDirs | QDir::Hidden );
|
||||
dialog.setLabelText( QFileDialog::Accept, tr("Open") );
|
||||
|
||||
g_config->getOption ("SDL.LastOpenFile", &last );
|
||||
|
@ -749,7 +766,7 @@ void GuiCheatsDialog_t::saveCheatFile(void)
|
|||
dialog.setNameFilter(tr("Cheat files (*.cht *.CHT) ;; All files (*)"));
|
||||
|
||||
dialog.setViewMode(QFileDialog::List);
|
||||
dialog.setFilter( QDir::AllEntries | QDir::Hidden );
|
||||
dialog.setFilter( QDir::AllEntries | QDir::AllDirs | QDir::Hidden );
|
||||
dialog.setLabelText( QFileDialog::Accept, tr("Save") );
|
||||
|
||||
if ( GameInfo )
|
||||
|
|
|
@ -32,6 +32,8 @@ class GuiCheatsDialog_t : public QDialog
|
|||
|
||||
int activeCheatListCB (char *name, uint32 a, uint8 v, int c, int s, int type, void *data);
|
||||
|
||||
void showActiveCheatList(bool redraw);
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event);
|
||||
|
||||
|
@ -75,7 +77,6 @@ class GuiCheatsDialog_t : public QDialog
|
|||
|
||||
private:
|
||||
void showCheatSearchResults(void);
|
||||
void showActiveCheatList(bool redraw);
|
||||
|
||||
public slots:
|
||||
void closeWindow(void);
|
||||
|
@ -97,3 +98,7 @@ class GuiCheatsDialog_t : public QDialog
|
|||
void actvCheatItemClicked( QTreeWidgetItem *item, int column);
|
||||
|
||||
};
|
||||
|
||||
void openCheatDialog(QWidget *parent);
|
||||
|
||||
void updateCheatDialog(void);
|
||||
|
|
|
@ -30,7 +30,7 @@ static char loadedcdfile[512] = {0};
|
|||
static int getDefaultCDLFile( char *filepath );
|
||||
//----------------------------------------------------
|
||||
CodeDataLoggerDialog_t::CodeDataLoggerDialog_t(QWidget *parent)
|
||||
: QDialog( parent )
|
||||
: QDialog( parent, Qt::Window )
|
||||
{
|
||||
QVBoxLayout *mainLayout, *vbox1, *vbox;
|
||||
QHBoxLayout *hbox;
|
||||
|
@ -324,7 +324,7 @@ void CodeDataLoggerDialog_t::saveCdlFileAs(void)
|
|||
dialog.setNameFilter(tr("CDL Files (*.cdl *.CDL) ;; All files (*)"));
|
||||
|
||||
dialog.setViewMode(QFileDialog::List);
|
||||
dialog.setFilter( QDir::AllEntries | QDir::Hidden );
|
||||
dialog.setFilter( QDir::AllEntries | QDir::AllDirs | QDir::Hidden );
|
||||
dialog.setLabelText( QFileDialog::Accept, tr("Save") );
|
||||
dialog.setDefaultSuffix( tr(".cdl") );
|
||||
|
||||
|
@ -387,7 +387,7 @@ void CodeDataLoggerDialog_t::loadCdlFile(void)
|
|||
dialog.setNameFilter(tr("CDL files (*.cdl *.CDL) ;; All files (*)"));
|
||||
|
||||
dialog.setViewMode(QFileDialog::List);
|
||||
dialog.setFilter( QDir::AllEntries | QDir::Hidden );
|
||||
dialog.setFilter( QDir::AllEntries | QDir::AllDirs | QDir::Hidden );
|
||||
dialog.setLabelText( QFileDialog::Accept, tr("Load") );
|
||||
|
||||
romFile = getRomFile();
|
||||
|
@ -470,7 +470,7 @@ void CodeDataLoggerDialog_t::SaveStrippedROM(int invert)
|
|||
dialog.setDefaultSuffix( tr(".nes") );
|
||||
}
|
||||
dialog.setViewMode(QFileDialog::List);
|
||||
dialog.setFilter( QDir::AllEntries | QDir::Hidden );
|
||||
dialog.setFilter( QDir::AllEntries | QDir::AllDirs | QDir::Hidden );
|
||||
dialog.setLabelText( QFileDialog::Accept, tr("Save") );
|
||||
|
||||
romFile = getRomFile();
|
||||
|
@ -623,7 +623,14 @@ static int getDefaultCDLFile( char *filepath )
|
|||
|
||||
parseFilepath( romFile, dir, baseFile );
|
||||
|
||||
sprintf( filepath, "%s/%s.cdl", dir, baseFile );
|
||||
if ( dir[0] == 0 )
|
||||
{
|
||||
sprintf( filepath, "%s.cdl", baseFile );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( filepath, "%s/%s.cdl", dir, baseFile );
|
||||
}
|
||||
|
||||
//printf("%s\n", filepath );
|
||||
|
||||
|
@ -785,6 +792,8 @@ void CDLoggerROMChanged(void)
|
|||
ResetCDLog();
|
||||
RenameCDLog("");
|
||||
|
||||
g_config->getOption("SDL.AutoResumeCDL", &autoResumeCDL);
|
||||
|
||||
if (!autoResumeCDL)
|
||||
return;
|
||||
|
||||
|
@ -827,7 +836,7 @@ void SaveCDLogFile(void)
|
|||
FP = fopen(loadedcdfile, "wb");
|
||||
if (FP == NULL)
|
||||
{
|
||||
FCEUD_PrintError("Error Saving File");
|
||||
FCEUD_PrintError("Error Saving CDL File");
|
||||
return;
|
||||
}
|
||||
fwrite(cdloggerdata, cdloggerdataSize, 1, FP);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <QLineEdit>
|
||||
#include <QTextEdit>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QClipboard>
|
||||
#include <QScrollBar>
|
||||
|
||||
#include "Qt/main.h"
|
||||
|
@ -37,6 +38,7 @@ struct dbg_asm_entry_t
|
|||
int line;
|
||||
uint8 opcode[3];
|
||||
std::string text;
|
||||
debugSymbol_t sym;
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -110,23 +112,34 @@ class QAsmView : public QWidget
|
|||
void setSymbolDebugEnable( bool value );
|
||||
void setRegisterNameEnable( bool value );
|
||||
int getCtxMenuAddr(void){ return ctxMenuAddr; };
|
||||
int getCursorAddr(void){ return cursorLineAddr; };
|
||||
void setPC_placement( int mode, int ofs = 0 );
|
||||
void setBreakpointAtSelectedLine(void);
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event);
|
||||
void keyPressEvent(QKeyEvent *event);
|
||||
void keyReleaseEvent(QKeyEvent *event);
|
||||
void mousePressEvent(QMouseEvent * event);
|
||||
void mouseReleaseEvent(QMouseEvent * event);
|
||||
void mouseMoveEvent(QMouseEvent * event);
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
void wheelEvent(QWheelEvent *event);
|
||||
void contextMenuEvent(QContextMenuEvent *event);
|
||||
void loadHighlightToClipboard(void);
|
||||
|
||||
void calcFontData(void);
|
||||
QPoint convPixToCursor( QPoint p );
|
||||
bool textIsHighlighted(void);
|
||||
void setHighlightEndCoord( int x, int y );
|
||||
void loadClipboard( const char *txt );
|
||||
void drawText( QPainter *painter, int x, int y, const char *txt );
|
||||
|
||||
private:
|
||||
ConsoleDebugger *parent;
|
||||
QFont font;
|
||||
QScrollBar *vbar;
|
||||
QScrollBar *hbar;
|
||||
QClipboard *clipboard;
|
||||
|
||||
int ctxMenuAddr;
|
||||
int maxLineLen;
|
||||
|
@ -144,13 +157,59 @@ class QAsmView : public QWidget
|
|||
int pxLineXScroll;
|
||||
int cursorPosX;
|
||||
int cursorPosY;
|
||||
int cursorLineAddr;
|
||||
int pcLinePlacement;
|
||||
int pcLineOffset;
|
||||
|
||||
int selAddrLine;
|
||||
int selAddrChar;
|
||||
int selAddrWidth;
|
||||
int selAddrValue;
|
||||
char selAddrText[128];
|
||||
|
||||
int txtHlgtAnchorChar;
|
||||
int txtHlgtAnchorLine;
|
||||
int txtHlgtStartChar;
|
||||
int txtHlgtStartLine;
|
||||
int txtHlgtEndChar;
|
||||
int txtHlgtEndLine;
|
||||
|
||||
int wheelPixelCounter;
|
||||
|
||||
dbg_asm_entry_t *asmPC;
|
||||
std::vector <dbg_asm_entry_t*> asmEntry;
|
||||
|
||||
bool useDarkTheme;
|
||||
bool displayROMoffsets;
|
||||
bool symbolicDebugEnable;
|
||||
bool registerNameEnable;
|
||||
bool mouseLeftBtnDown;
|
||||
|
||||
};
|
||||
|
||||
class DebuggerStackDisplay : public QPlainTextEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DebuggerStackDisplay(QWidget *parent = 0);
|
||||
~DebuggerStackDisplay(void);
|
||||
|
||||
void updateText(void);
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *event);
|
||||
void contextMenuEvent(QContextMenuEvent *event);
|
||||
|
||||
int stackBytesPerLine;
|
||||
bool showAddrs;
|
||||
|
||||
private slots:
|
||||
void toggleShowAddr(void);
|
||||
void sel1BytePerLine(void);
|
||||
void sel2BytesPerLine(void);
|
||||
void sel3BytesPerLine(void);
|
||||
void sel4BytesPerLine(void);
|
||||
};
|
||||
|
||||
class ConsoleDebugger : public QDialog
|
||||
|
@ -181,7 +240,7 @@ class ConsoleDebugger : public QDialog
|
|||
QScrollBar *vbar;
|
||||
QScrollBar *hbar;
|
||||
QAsmView *asmView;
|
||||
QPlainTextEdit *stackText;
|
||||
DebuggerStackDisplay *stackText;
|
||||
QLineEdit *seekEntry;
|
||||
QLineEdit *pcEntry;
|
||||
QLineEdit *regAEntry;
|
||||
|
@ -239,6 +298,7 @@ class ConsoleDebugger : public QDialog
|
|||
void asmViewCtxMenuAddBM(void);
|
||||
void asmViewCtxMenuAddSym(void);
|
||||
void asmViewCtxMenuOpenHexEdit(void);
|
||||
void asmViewCtxMenuRunToCursor(void);
|
||||
private slots:
|
||||
void updatePeriodic(void);
|
||||
void hbarChanged(int value);
|
||||
|
@ -247,6 +307,7 @@ class ConsoleDebugger : public QDialog
|
|||
void debugStepIntoCB(void);
|
||||
void debugStepOutCB(void);
|
||||
void debugStepOverCB(void);
|
||||
void debugRunToCursorCB(void);
|
||||
void debugRunLineCB(void);
|
||||
void debugRunLine128CB(void);
|
||||
void seekToCB(void);
|
||||
|
@ -273,6 +334,12 @@ class ConsoleDebugger : public QDialog
|
|||
void cpuCycleThresChanged(const QString &txt);
|
||||
void instructionsThresChanged(const QString &txt);
|
||||
void selBmAddrChanged(const QString &txt);
|
||||
void pcSetPlaceTop(void);
|
||||
void pcSetPlaceUpperMid(void);
|
||||
void pcSetPlaceCenter(void);
|
||||
void pcSetPlaceLowerMid(void);
|
||||
void pcSetPlaceBottom(void);
|
||||
void pcSetPlaceCustom(void);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -38,17 +38,52 @@ int getDirFromFile( const char *path, char *dir )
|
|||
//---------------------------------------------------------------------------
|
||||
const char *getRomFile( void )
|
||||
{
|
||||
static char filePath[2048];
|
||||
|
||||
if ( GameInfo )
|
||||
{
|
||||
return GameInfo->filename;
|
||||
//printf("filename: '%s' \n", GameInfo->filename );
|
||||
//printf("archiveFilename: '%s' \n", GameInfo->archiveFilename );
|
||||
|
||||
if ( GameInfo->archiveFilename != NULL )
|
||||
{
|
||||
char dir[1024], base[512], suffix[64];
|
||||
|
||||
parseFilepath( GameInfo->archiveFilename, dir, base, suffix );
|
||||
|
||||
filePath[0] = 0;
|
||||
|
||||
if ( dir[0] != 0 )
|
||||
{
|
||||
strcat( filePath, dir );
|
||||
}
|
||||
|
||||
parseFilepath( GameInfo->filename, dir, base, suffix );
|
||||
|
||||
strcat( filePath, base );
|
||||
strcat( filePath, suffix );
|
||||
|
||||
//printf("ArchivePath: '%s' \n", filePath );
|
||||
|
||||
return filePath;
|
||||
}
|
||||
else
|
||||
{
|
||||
return GameInfo->filename;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
// Return file base name stripping out preceding path and trailing suffix.
|
||||
int getFileBaseName( const char *filepath, char *base )
|
||||
int getFileBaseName( const char *filepath, char *base, char *suffix )
|
||||
{
|
||||
int i=0,j=0,end=0;
|
||||
|
||||
if ( suffix != NULL )
|
||||
{
|
||||
suffix[0] = 0;
|
||||
}
|
||||
if ( filepath == NULL )
|
||||
{
|
||||
base[0] = 0;
|
||||
|
@ -77,6 +112,10 @@ int getFileBaseName( const char *filepath, char *base )
|
|||
j--;
|
||||
if ( base[j] == '.' )
|
||||
{
|
||||
if ( suffix != NULL )
|
||||
{
|
||||
strcpy( suffix, &base[j] );
|
||||
}
|
||||
end=j; base[j] = 0; break;
|
||||
}
|
||||
}
|
||||
|
@ -86,6 +125,11 @@ int getFileBaseName( const char *filepath, char *base )
|
|||
int parseFilepath( const char *filepath, char *dir, char *base, char *suffix )
|
||||
{
|
||||
int i=0,j=0,end=0;
|
||||
|
||||
if ( suffix != NULL )
|
||||
{
|
||||
suffix[0] = 0;
|
||||
}
|
||||
if ( filepath == NULL )
|
||||
{
|
||||
if ( dir ) dir[0] = 0;
|
||||
|
@ -145,3 +189,138 @@ int parseFilepath( const char *filepath, char *dir, char *base, char *suffix )
|
|||
return end;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
// FCEU Data Entry Custom Validators
|
||||
//---------------------------------------------------------------------------
|
||||
fceuDecIntValidtor::fceuDecIntValidtor( int min, int max, QObject *parent)
|
||||
: QValidator(parent)
|
||||
{
|
||||
this->min = min;
|
||||
this->max = max;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void fceuDecIntValidtor::setMinMax( int min, int max)
|
||||
{
|
||||
this->min = min;
|
||||
this->max = max;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
QValidator::State fceuDecIntValidtor::validate(QString &input, int &pos) const
|
||||
{
|
||||
int i, v;
|
||||
//printf("Validate: %i '%s'\n", input.size(), input.toStdString().c_str() );
|
||||
|
||||
if ( input.size() == 0 )
|
||||
{
|
||||
return QValidator::Acceptable;
|
||||
}
|
||||
std::string s = input.toStdString();
|
||||
i=0;
|
||||
|
||||
if (s[i] == '-')
|
||||
{
|
||||
if ( min >= 0 )
|
||||
{
|
||||
return QValidator::Invalid;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
else if ( s[i] == '+' )
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
if ( s[i] == 0 )
|
||||
{
|
||||
return QValidator::Acceptable;
|
||||
}
|
||||
|
||||
if ( isdigit(s[i]) )
|
||||
{
|
||||
while ( isdigit(s[i]) ) i++;
|
||||
|
||||
if ( s[i] == 0 )
|
||||
{
|
||||
v = strtol( s.c_str(), NULL, 0 );
|
||||
|
||||
if ( v < min )
|
||||
{
|
||||
return QValidator::Invalid;
|
||||
}
|
||||
else if ( v > max )
|
||||
{
|
||||
return QValidator::Invalid;
|
||||
}
|
||||
return QValidator::Acceptable;
|
||||
}
|
||||
}
|
||||
return QValidator::Invalid;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
// FCEU Data Entry Custom Validators
|
||||
//---------------------------------------------------------------------------
|
||||
fceuHexIntValidtor::fceuHexIntValidtor( int min, int max, QObject *parent)
|
||||
: QValidator(parent)
|
||||
{
|
||||
this->min = min;
|
||||
this->max = max;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void fceuHexIntValidtor::setMinMax( int min, int max)
|
||||
{
|
||||
this->min = min;
|
||||
this->max = max;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
QValidator::State fceuHexIntValidtor::validate(QString &input, int &pos) const
|
||||
{
|
||||
int i, v;
|
||||
//printf("Validate: %i '%s'\n", input.size(), input.toStdString().c_str() );
|
||||
|
||||
if ( input.size() == 0 )
|
||||
{
|
||||
return QValidator::Acceptable;
|
||||
}
|
||||
input = input.toUpper();
|
||||
std::string s = input.toStdString();
|
||||
i=0;
|
||||
|
||||
if (s[i] == '-')
|
||||
{
|
||||
if ( min >= 0 )
|
||||
{
|
||||
return QValidator::Invalid;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
else if ( s[i] == '+' )
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
if ( s[i] == 0 )
|
||||
{
|
||||
return QValidator::Acceptable;
|
||||
}
|
||||
|
||||
if ( isxdigit(s[i]) )
|
||||
{
|
||||
while ( isxdigit(s[i]) ) i++;
|
||||
|
||||
if ( s[i] == 0 )
|
||||
{
|
||||
v = strtol( s.c_str(), NULL, 16 );
|
||||
|
||||
if ( v < min )
|
||||
{
|
||||
return QValidator::Invalid;
|
||||
}
|
||||
else if ( v > max )
|
||||
{
|
||||
return QValidator::Invalid;
|
||||
}
|
||||
return QValidator::Acceptable;
|
||||
}
|
||||
}
|
||||
return QValidator::Invalid;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -1,9 +1,41 @@
|
|||
// ConsoleUtilities.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QValidator>
|
||||
|
||||
int getDirFromFile( const char *path, char *dir );
|
||||
|
||||
const char *getRomFile( void );
|
||||
|
||||
int getFileBaseName( const char *filepath, char *base );
|
||||
int getFileBaseName( const char *filepath, char *base, char *suffix = NULL );
|
||||
|
||||
int parseFilepath( const char *filepath, char *dir, char *base, char *suffix = NULL );
|
||||
|
||||
|
||||
class fceuDecIntValidtor : public QValidator
|
||||
{
|
||||
public:
|
||||
fceuDecIntValidtor( int min, int max, QObject *parent);
|
||||
|
||||
QValidator::State validate(QString &input, int &pos) const;
|
||||
|
||||
void setMinMax( int min, int max );
|
||||
private:
|
||||
int min;
|
||||
int max;
|
||||
};
|
||||
|
||||
class fceuHexIntValidtor : public QValidator
|
||||
{
|
||||
public:
|
||||
fceuHexIntValidtor( int min, int max, QObject *parent);
|
||||
|
||||
QValidator::State validate(QString &input, int &pos) const;
|
||||
|
||||
void setMinMax( int min, int max );
|
||||
private:
|
||||
int min;
|
||||
int max;
|
||||
};
|
||||
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
#include "Qt/dface.h"
|
||||
#include "Qt/config.h"
|
||||
#include "Qt/fceuWrapper.h"
|
||||
#include "Qt/ConsoleWindow.h"
|
||||
#include "Qt/ConsoleVideoConf.h"
|
||||
#include "Qt/nes_shm.h"
|
||||
|
||||
//----------------------------------------------------
|
||||
ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent)
|
||||
|
@ -17,6 +19,9 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent)
|
|||
QHBoxLayout *hbox1;
|
||||
QLabel *lbl;
|
||||
QPushButton *button;
|
||||
QStyle *style;
|
||||
|
||||
style = this->style();
|
||||
|
||||
setWindowTitle( tr("Video Config") );
|
||||
|
||||
|
@ -37,11 +42,36 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent)
|
|||
|
||||
main_vbox->addLayout( hbox1 );
|
||||
|
||||
// Video Driver Select
|
||||
lbl = new QLabel( tr("Scaler:") );
|
||||
|
||||
scalerSelect = new QComboBox();
|
||||
|
||||
scalerSelect->addItem( tr("None"), 0 );
|
||||
scalerSelect->addItem( tr("hq2x"), 1 );
|
||||
scalerSelect->addItem( tr("scale2x"), 2 );
|
||||
scalerSelect->addItem( tr("NTSC 2x"), 3 );
|
||||
scalerSelect->addItem( tr("hq3x"), 4 );
|
||||
scalerSelect->addItem( tr("scale3x"), 5 );
|
||||
scalerSelect->addItem( tr("Prescale 2x"), 6 );
|
||||
scalerSelect->addItem( tr("Prescale 3x"), 7 );
|
||||
scalerSelect->addItem( tr("Prescale 4x"), 8 );
|
||||
scalerSelect->addItem( tr("PAL"), 9 );
|
||||
|
||||
hbox1 = new QHBoxLayout();
|
||||
|
||||
hbox1->addWidget( lbl );
|
||||
hbox1->addWidget( scalerSelect );
|
||||
|
||||
main_vbox->addLayout( hbox1 );
|
||||
|
||||
// Enable OpenGL Linear Filter Checkbox
|
||||
gl_LF_chkBox = new QCheckBox( tr("Enable OpenGL Linear Filter") );
|
||||
|
||||
setCheckBoxFromProperty( gl_LF_chkBox , "SDL.OpenGLip");
|
||||
|
||||
connect(gl_LF_chkBox , SIGNAL(stateChanged(int)), this, SLOT(openGL_linearFilterChanged(int)) );
|
||||
|
||||
main_vbox->addWidget( gl_LF_chkBox );
|
||||
|
||||
// Region Select
|
||||
|
@ -55,9 +85,11 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent)
|
|||
|
||||
setComboBoxFromProperty( regionSelect, "SDL.PAL");
|
||||
setComboBoxFromProperty( driverSelect, "SDL.VideoDriver");
|
||||
setComboBoxFromProperty( scalerSelect, "SDL.SpecialFilter");
|
||||
|
||||
connect(regionSelect, SIGNAL(currentIndexChanged(int)), this, SLOT(regionChanged(int)) );
|
||||
connect(driverSelect, SIGNAL(currentIndexChanged(int)), this, SLOT(driverChanged(int)) );
|
||||
connect(scalerSelect, SIGNAL(currentIndexChanged(int)), this, SLOT(scalerChanged(int)) );
|
||||
|
||||
hbox1 = new QHBoxLayout();
|
||||
|
||||
|
@ -81,32 +113,106 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent)
|
|||
// Show FPS Checkbox
|
||||
showFPS_cbx = new QCheckBox( tr("Show FPS") );
|
||||
|
||||
// Auto Scale on Resize
|
||||
autoScaleCbx = new QCheckBox( tr("Auto Scale on Resize") );
|
||||
|
||||
// Square Pixels
|
||||
sqrPixCbx = new QCheckBox( tr("Square Pixels") );
|
||||
|
||||
setCheckBoxFromProperty( new_PPU_ena , "SDL.NewPPU");
|
||||
setCheckBoxFromProperty( frmskipcbx , "SDL.Frameskip");
|
||||
setCheckBoxFromProperty( sprtLimCbx , "SDL.DisableSpriteLimit");
|
||||
setCheckBoxFromProperty( clipSidesCbx , "SDL.ClipSides");
|
||||
setCheckBoxFromProperty( showFPS_cbx , "SDL.ShowFPS");
|
||||
|
||||
if ( consoleWindow )
|
||||
{
|
||||
if ( consoleWindow->viewport_GL )
|
||||
{
|
||||
autoScaleCbx->setChecked( consoleWindow->viewport_GL->getAutoScaleOpt() );
|
||||
sqrPixCbx->setChecked( consoleWindow->viewport_GL->getSqrPixelOpt() );
|
||||
}
|
||||
else if ( consoleWindow->viewport_SDL )
|
||||
{
|
||||
autoScaleCbx->setChecked( consoleWindow->viewport_SDL->getAutoScaleOpt() );
|
||||
sqrPixCbx->setChecked( consoleWindow->viewport_SDL->getSqrPixelOpt() );
|
||||
}
|
||||
}
|
||||
|
||||
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)) );
|
||||
connect(sqrPixCbx , SIGNAL(stateChanged(int)), this, SLOT(sqrPixChanged(int)) );
|
||||
|
||||
main_vbox->addWidget( new_PPU_ena );
|
||||
main_vbox->addWidget( frmskipcbx );
|
||||
main_vbox->addWidget( sprtLimCbx );
|
||||
main_vbox->addWidget( clipSidesCbx);
|
||||
main_vbox->addWidget( showFPS_cbx );
|
||||
main_vbox->addWidget( autoScaleCbx);
|
||||
main_vbox->addWidget( sqrPixCbx );
|
||||
|
||||
xScaleBox = new QDoubleSpinBox(this);
|
||||
yScaleBox = new QDoubleSpinBox(this);
|
||||
|
||||
xScaleBox->setRange( 1.0, 16.0 );
|
||||
yScaleBox->setRange( 1.0, 16.0 );
|
||||
|
||||
xScaleBox->setSingleStep( 0.10 );
|
||||
yScaleBox->setSingleStep( 0.10 );
|
||||
|
||||
if ( consoleWindow )
|
||||
{
|
||||
if ( consoleWindow->viewport_GL )
|
||||
{
|
||||
xScaleBox->setValue( consoleWindow->viewport_GL->getScaleX() );
|
||||
yScaleBox->setValue( consoleWindow->viewport_GL->getScaleY() );
|
||||
}
|
||||
else if ( consoleWindow->viewport_SDL )
|
||||
{
|
||||
xScaleBox->setValue( consoleWindow->viewport_SDL->getScaleX() );
|
||||
yScaleBox->setValue( consoleWindow->viewport_SDL->getScaleY() );
|
||||
}
|
||||
}
|
||||
|
||||
if ( sqrPixCbx->isChecked() )
|
||||
{
|
||||
xScaleLabel = new QLabel( tr("Scale:") );
|
||||
}
|
||||
else
|
||||
{
|
||||
xScaleLabel = new QLabel( tr("X Scale:") );
|
||||
}
|
||||
yScaleLabel = new QLabel( tr("Y Scale:") );
|
||||
|
||||
hbox1 = new QHBoxLayout();
|
||||
hbox1->addWidget( xScaleLabel );
|
||||
hbox1->addWidget( xScaleBox );
|
||||
main_vbox->addLayout( hbox1 );
|
||||
|
||||
hbox1 = new QHBoxLayout();
|
||||
hbox1->addWidget( yScaleLabel );
|
||||
hbox1->addWidget( yScaleBox );
|
||||
main_vbox->addLayout( hbox1 );
|
||||
|
||||
if ( sqrPixCbx->isChecked() )
|
||||
{
|
||||
yScaleLabel->hide();
|
||||
yScaleBox->hide();
|
||||
}
|
||||
|
||||
hbox1 = new QHBoxLayout();
|
||||
|
||||
button = new QPushButton( tr("Apply") );
|
||||
hbox1->addWidget( button );
|
||||
connect(button, SIGNAL(clicked()), this, SLOT(applyChanges(void)) );
|
||||
button->setIcon( style->standardIcon( QStyle::SP_DialogApplyButton ) );
|
||||
|
||||
button = new QPushButton( tr("Close") );
|
||||
hbox1->addWidget( button );
|
||||
button->setIcon( style->standardIcon( QStyle::SP_DialogCloseButton ) );
|
||||
connect(button, SIGNAL(clicked()), this, SLOT(closeWindow(void)) );
|
||||
|
||||
main_vbox->addLayout( hbox1 );
|
||||
|
@ -138,8 +244,10 @@ void ConsoleVideoConfDialog_t::closeWindow(void)
|
|||
//----------------------------------------------------
|
||||
void ConsoleVideoConfDialog_t::resetVideo(void)
|
||||
{
|
||||
fceuWrapperLock();
|
||||
KillVideo ();
|
||||
InitVideo (GameInfo);
|
||||
fceuWrapperUnLock();
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ConsoleVideoConfDialog_t::setCheckBoxFromProperty( QCheckBox *cbx, const char *property )
|
||||
|
@ -164,6 +272,25 @@ void ConsoleVideoConfDialog_t::setComboBoxFromProperty( QComboBox *cbx, const c
|
|||
}
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ConsoleVideoConfDialog_t::openGL_linearFilterChanged( int value )
|
||||
{
|
||||
bool opt = (value != Qt::Unchecked);
|
||||
g_config->setOption("SDL.OpenGLip", opt );
|
||||
g_config->save ();
|
||||
|
||||
if ( consoleWindow != NULL )
|
||||
{
|
||||
if ( consoleWindow->viewport_GL )
|
||||
{
|
||||
consoleWindow->viewport_GL->setLinearFilterEnable( opt );
|
||||
}
|
||||
if ( consoleWindow->viewport_SDL )
|
||||
{
|
||||
consoleWindow->viewport_SDL->setLinearFilterEnable( opt );
|
||||
}
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ConsoleVideoConfDialog_t::use_new_PPU_changed( int value )
|
||||
{
|
||||
//printf("Value:%i \n", value );
|
||||
|
@ -219,6 +346,26 @@ void ConsoleVideoConfDialog_t::showFPSChanged( int value )
|
|||
fceuWrapperUnLock();
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ConsoleVideoConfDialog_t::sqrPixChanged( int value )
|
||||
{
|
||||
//printf("Value:%i \n", value );
|
||||
int useSqrPix = (value != Qt::Unchecked);
|
||||
|
||||
if ( useSqrPix )
|
||||
{
|
||||
xScaleLabel->setText( tr("Scale:") );
|
||||
yScaleLabel->hide();
|
||||
yScaleBox->hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
xScaleLabel->setText( tr("X Scale:") );
|
||||
yScaleLabel->show();
|
||||
yScaleBox->show();
|
||||
}
|
||||
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ConsoleVideoConfDialog_t::driverChanged(int index)
|
||||
{
|
||||
int driver;
|
||||
|
@ -233,6 +380,18 @@ void ConsoleVideoConfDialog_t::driverChanged(int index)
|
|||
printf("Note: A restart of the application is needed for video driver change to take effect...\n");
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ConsoleVideoConfDialog_t::scalerChanged(int index)
|
||||
{
|
||||
int scaler;
|
||||
//printf("Scaler: %i : %i \n", index, scalerSelect->itemData(index).toInt() );
|
||||
|
||||
scaler = scalerSelect->itemData(index).toInt();
|
||||
|
||||
g_config->setOption ("SDL.SpecialFilter", scaler);
|
||||
|
||||
g_config->save ();
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ConsoleVideoConfDialog_t::regionChanged(int index)
|
||||
{
|
||||
int region;
|
||||
|
@ -250,8 +409,88 @@ void ConsoleVideoConfDialog_t::regionChanged(int index)
|
|||
fceuWrapperUnLock();
|
||||
}
|
||||
//----------------------------------------------------
|
||||
QSize ConsoleVideoConfDialog_t::calcNewScreenSize(void)
|
||||
{
|
||||
QSize out( GL_NES_WIDTH, GL_NES_HEIGHT );
|
||||
|
||||
if ( consoleWindow )
|
||||
{
|
||||
QSize w, v;
|
||||
double xscale, yscale;
|
||||
int texture_width = nes_shm->video.ncol;
|
||||
int texture_height = nes_shm->video.nrow;
|
||||
int l=0, r=texture_width;
|
||||
int t=0, b=texture_height;
|
||||
int dw=0, dh=0, rw, rh;
|
||||
|
||||
w = consoleWindow->size();
|
||||
|
||||
if ( consoleWindow->viewport_GL )
|
||||
{
|
||||
v = consoleWindow->viewport_GL->size();
|
||||
}
|
||||
else if ( consoleWindow->viewport_SDL )
|
||||
{
|
||||
v = consoleWindow->viewport_SDL->size();
|
||||
}
|
||||
|
||||
dw = w.width() - v.width();
|
||||
dh = w.height() - v.height();
|
||||
|
||||
if ( sqrPixCbx->isChecked() )
|
||||
{
|
||||
xscale = xScaleBox->value();
|
||||
|
||||
yscale = xscale * (double)nes_shm->video.xyRatio;
|
||||
}
|
||||
else
|
||||
{
|
||||
xscale = xScaleBox->value();
|
||||
yscale = yScaleBox->value();
|
||||
}
|
||||
rw=(int)((r-l)*xscale);
|
||||
rh=(int)((b-t)*yscale);
|
||||
|
||||
out.setWidth( rw + dw );
|
||||
out.setHeight( rh + dh );
|
||||
}
|
||||
return out;
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ConsoleVideoConfDialog_t::applyChanges( void )
|
||||
{
|
||||
resetVideo();
|
||||
|
||||
if ( consoleWindow )
|
||||
{
|
||||
float xscale, yscale;
|
||||
QSize s = calcNewScreenSize();
|
||||
|
||||
if ( sqrPixCbx->isChecked() )
|
||||
{
|
||||
yscale = xscale = xScaleBox->value();
|
||||
}
|
||||
else
|
||||
{
|
||||
xscale = xScaleBox->value();
|
||||
yscale = yScaleBox->value();
|
||||
}
|
||||
|
||||
if ( consoleWindow->viewport_GL )
|
||||
{
|
||||
consoleWindow->viewport_GL->setSqrPixelOpt( sqrPixCbx->isChecked() );
|
||||
consoleWindow->viewport_GL->setAutoScaleOpt( autoScaleCbx->isChecked() );
|
||||
consoleWindow->viewport_GL->setScaleXY( xscale, yscale );
|
||||
}
|
||||
if ( consoleWindow->viewport_SDL )
|
||||
{
|
||||
consoleWindow->viewport_SDL->setSqrPixelOpt( sqrPixCbx->isChecked() );
|
||||
consoleWindow->viewport_SDL->setAutoScaleOpt( autoScaleCbx->isChecked() );
|
||||
consoleWindow->viewport_SDL->setScaleXY( xscale, yscale );
|
||||
}
|
||||
|
||||
consoleWindow->resize( s );
|
||||
}
|
||||
|
||||
}
|
||||
//----------------------------------------------------
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <QSlider>
|
||||
#include <QFrame>
|
||||
#include <QGroupBox>
|
||||
#include <QDoubleSpinBox>
|
||||
|
||||
class ConsoleVideoConfDialog_t : public QDialog
|
||||
{
|
||||
|
@ -28,6 +29,7 @@ class ConsoleVideoConfDialog_t : public QDialog
|
|||
void closeEvent(QCloseEvent *bar);
|
||||
|
||||
QComboBox *driverSelect;
|
||||
QComboBox *scalerSelect;
|
||||
QComboBox *regionSelect;
|
||||
QCheckBox *gl_LF_chkBox;
|
||||
QCheckBox *new_PPU_ena;
|
||||
|
@ -35,17 +37,26 @@ class ConsoleVideoConfDialog_t : public QDialog
|
|||
QCheckBox *sprtLimCbx;
|
||||
QCheckBox *clipSidesCbx;
|
||||
QCheckBox *showFPS_cbx;
|
||||
QCheckBox *autoScaleCbx;
|
||||
QCheckBox *sqrPixCbx;
|
||||
QDoubleSpinBox *xScaleBox;
|
||||
QDoubleSpinBox *yScaleBox;
|
||||
QLabel *xScaleLabel;
|
||||
QLabel *yScaleLabel;
|
||||
|
||||
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);
|
||||
QSize calcNewScreenSize(void);
|
||||
|
||||
public slots:
|
||||
void closeWindow(void);
|
||||
|
||||
private slots:
|
||||
void openGL_linearFilterChanged( int value );
|
||||
void sqrPixChanged( int value );
|
||||
void use_new_PPU_changed( int value );
|
||||
void frameskip_changed( int value );
|
||||
void useSpriteLimitChanged( int value );
|
||||
|
@ -53,6 +64,7 @@ class ConsoleVideoConfDialog_t : public QDialog
|
|||
void showFPSChanged( int value );
|
||||
void regionChanged(int index);
|
||||
void driverChanged(int index);
|
||||
void scalerChanged(int index);
|
||||
void applyChanges( void );
|
||||
|
||||
};
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
|
||||
#include <QApplication>
|
||||
#include <QScreen>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include "Qt/nes_shm.h"
|
||||
#include "Qt/fceuWrapper.h"
|
||||
#include "Qt/ConsoleViewerGL.h"
|
||||
|
||||
extern unsigned int gui_draw_area_width;
|
||||
|
@ -22,15 +24,26 @@ ConsoleViewGL_t::ConsoleViewGL_t(QWidget *parent)
|
|||
gltexture = 0;
|
||||
devPixRatio = 1.0f;
|
||||
linearFilter = false;
|
||||
sqrPixels = true;
|
||||
autoScaleEna = true;
|
||||
xscale = 2.0;
|
||||
yscale = 2.0;
|
||||
sx = 0; sy = 0;
|
||||
rw = 256;
|
||||
rh = 240;
|
||||
mouseButtonMask = 0;
|
||||
|
||||
QScreen *screen = QGuiApplication::primaryScreen();
|
||||
setMinimumWidth( GL_NES_WIDTH );
|
||||
setMinimumHeight( GL_NES_HEIGHT );
|
||||
|
||||
if ( screen != NULL )
|
||||
{
|
||||
QScreen *screen = QGuiApplication::primaryScreen();
|
||||
|
||||
if ( screen != NULL )
|
||||
{
|
||||
devPixRatio = screen->devicePixelRatio();
|
||||
//printf("Ratio: %f \n", screen->devicePixelRatio() );
|
||||
//printf("Ratio: %f \n", screen->devicePixelRatio() );
|
||||
}
|
||||
localBufSize = GL_NES_WIDTH * GL_NES_HEIGHT * sizeof(uint32_t);
|
||||
localBufSize = (4 * GL_NES_WIDTH) * (4 * GL_NES_HEIGHT) * sizeof(uint32_t);
|
||||
|
||||
localBuf = (uint32_t*)malloc( localBufSize );
|
||||
|
||||
|
@ -38,6 +51,16 @@ ConsoleViewGL_t::ConsoleViewGL_t(QWidget *parent)
|
|||
{
|
||||
memset( localBuf, 0, localBufSize );
|
||||
}
|
||||
|
||||
linearFilter = false;
|
||||
|
||||
if ( g_config )
|
||||
{
|
||||
int opt;
|
||||
g_config->getOption("SDL.OpenGLip", &opt );
|
||||
|
||||
linearFilter = (opt) ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
ConsoleViewGL_t::~ConsoleViewGL_t(void)
|
||||
|
@ -69,6 +92,7 @@ int ConsoleViewGL_t::init( void )
|
|||
|
||||
void ConsoleViewGL_t::buildTextures(void)
|
||||
{
|
||||
int w, h;
|
||||
glEnable(GL_TEXTURE_RECTANGLE);
|
||||
|
||||
if ( gltexture )
|
||||
|
@ -87,8 +111,11 @@ void ConsoleViewGL_t::buildTextures(void)
|
|||
glTexParameteri( GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
|
||||
glTexParameteri( GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
|
||||
|
||||
w = nes_shm->video.ncol;
|
||||
h = nes_shm->video.nrow;
|
||||
|
||||
glTexImage2D( GL_TEXTURE_RECTANGLE, 0,
|
||||
GL_RGBA8, GL_NES_WIDTH, GL_NES_HEIGHT, 0,
|
||||
GL_RGBA8, w, h, 0,
|
||||
GL_BGRA, GL_UNSIGNED_BYTE, 0 );
|
||||
|
||||
}
|
||||
|
@ -122,33 +149,168 @@ void ConsoleViewGL_t::resizeGL(int w, int h)
|
|||
buildTextures();
|
||||
}
|
||||
|
||||
void ConsoleViewGL_t::setLinearFilterEnable( bool ena )
|
||||
{
|
||||
if ( linearFilter != ena )
|
||||
{
|
||||
linearFilter = ena;
|
||||
|
||||
buildTextures();
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleViewGL_t::setScaleXY( double xs, double ys )
|
||||
{
|
||||
float xyRatio = (float)nes_shm->video.xyRatio;
|
||||
|
||||
xscale = xs;
|
||||
yscale = ys;
|
||||
|
||||
if ( sqrPixels )
|
||||
{
|
||||
if ( (xscale*xyRatio) < yscale )
|
||||
{
|
||||
yscale = (xscale*xyRatio);
|
||||
}
|
||||
else
|
||||
{
|
||||
xscale = (yscale/xyRatio);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleViewGL_t::transfer2LocalBuffer(void)
|
||||
{
|
||||
memcpy( localBuf, nes_shm->pixbuf, localBufSize );
|
||||
int i=0, hq = 0;
|
||||
int numPixels = nes_shm->video.ncol * nes_shm->video.nrow;
|
||||
int cpSize = numPixels * 4;
|
||||
uint8_t *src, *dest;
|
||||
|
||||
if ( cpSize > localBufSize )
|
||||
{
|
||||
cpSize = localBufSize;
|
||||
}
|
||||
src = (uint8_t*)nes_shm->pixbuf;
|
||||
dest = (uint8_t*)localBuf;
|
||||
|
||||
hq = (nes_shm->video.preScaler == 1) || (nes_shm->video.preScaler == 4); // hq2x and hq3x
|
||||
|
||||
if ( hq )
|
||||
{
|
||||
for (i=0; i<numPixels; i++)
|
||||
{
|
||||
dest[3] = 0xFF;
|
||||
dest[1] = src[1];
|
||||
dest[2] = src[2];
|
||||
dest[0] = src[0];
|
||||
|
||||
src += 4; dest += 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy( localBuf, nes_shm->pixbuf, cpSize );
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleViewGL_t::mousePressEvent(QMouseEvent * event)
|
||||
{
|
||||
//printf("Mouse Button Press: (%i,%i) %x %x\n",
|
||||
// event->pos().x(), event->pos().y(), event->button(), event->buttons() );
|
||||
|
||||
mouseButtonMask = event->buttons();
|
||||
}
|
||||
|
||||
void ConsoleViewGL_t::mouseReleaseEvent(QMouseEvent * event)
|
||||
{
|
||||
//printf("Mouse Button Release: (%i,%i) %x %x\n",
|
||||
// event->pos().x(), event->pos().y(), event->button(), event->buttons() );
|
||||
|
||||
mouseButtonMask = event->buttons();
|
||||
}
|
||||
|
||||
bool ConsoleViewGL_t::getMouseButtonState( unsigned int btn )
|
||||
{
|
||||
return (mouseButtonMask & btn) ? true : false;
|
||||
}
|
||||
|
||||
void ConsoleViewGL_t::getNormalizedCursorPos( double &x, double &y )
|
||||
{
|
||||
QPoint cursor;
|
||||
|
||||
cursor = QCursor::pos();
|
||||
|
||||
//printf("Global Cursor (%i,%i) \n", cursor.x(), cursor.y() );
|
||||
|
||||
cursor = mapFromGlobal( cursor );
|
||||
|
||||
//printf("Window Cursor (%i,%i) \n", cursor.x(), cursor.y() );
|
||||
|
||||
x = (double)(cursor.x() - sx) / (double)rw;
|
||||
y = (double)(cursor.y() - sy) / (double)rh;
|
||||
|
||||
if ( x < 0.0 )
|
||||
{
|
||||
x = 0.0;
|
||||
}
|
||||
else if ( x > 1.0 )
|
||||
{
|
||||
x = 1.0;
|
||||
}
|
||||
if ( y < 0.0 )
|
||||
{
|
||||
y = 0.0;
|
||||
}
|
||||
else if ( y > 1.0 )
|
||||
{
|
||||
y = 1.0;
|
||||
}
|
||||
//printf("Normalized Cursor (%f,%f) \n", x, y );
|
||||
}
|
||||
|
||||
void ConsoleViewGL_t::paintGL(void)
|
||||
{
|
||||
int texture_width = nes_shm->ncol;
|
||||
int texture_height = nes_shm->nrow;
|
||||
int texture_width = nes_shm->video.ncol;
|
||||
int texture_height = nes_shm->video.nrow;
|
||||
int l=0, r=texture_width;
|
||||
int t=0, b=texture_height;
|
||||
|
||||
float xscale = (float)view_width / (float)texture_width;
|
||||
float yscale = (float)view_height / (float)texture_height;
|
||||
float xyRatio = (float)nes_shm->video.xyRatio;
|
||||
float xscaleTmp = (float)(view_width) / (float)(texture_width);
|
||||
float yscaleTmp = (float)(view_height) / (float)(texture_height);
|
||||
|
||||
if (xscale < yscale )
|
||||
if ( sqrPixels )
|
||||
{
|
||||
yscale = xscale;
|
||||
if ( (xscaleTmp*xyRatio) < yscaleTmp )
|
||||
{
|
||||
yscaleTmp = (xscaleTmp*xyRatio);
|
||||
}
|
||||
else
|
||||
{
|
||||
xscaleTmp = (yscaleTmp/xyRatio);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if ( autoScaleEna )
|
||||
{
|
||||
xscale = yscale;
|
||||
xscale = xscaleTmp;
|
||||
yscale = yscaleTmp;
|
||||
}
|
||||
int rw=(int)((r-l)*xscale);
|
||||
int rh=(int)((b-t)*yscale);
|
||||
int sx=(view_width-rw)/2;
|
||||
int sy=(view_height-rh)/2;
|
||||
else
|
||||
{
|
||||
if ( xscaleTmp > xscale )
|
||||
{
|
||||
xscaleTmp = xscale;
|
||||
}
|
||||
if ( yscaleTmp > yscale )
|
||||
{
|
||||
yscaleTmp = yscale;
|
||||
}
|
||||
}
|
||||
rw=(int)((r-l)*xscaleTmp);
|
||||
rh=(int)((b-t)*yscaleTmp);
|
||||
sx=(view_width-rw)/2;
|
||||
sy=(view_height-rh)/2;
|
||||
|
||||
glViewport(sx, sy, rw, rh);
|
||||
|
||||
|
@ -166,7 +328,7 @@ void ConsoleViewGL_t::paintGL(void)
|
|||
glBindTexture(GL_TEXTURE_RECTANGLE, gltexture);
|
||||
|
||||
glTexSubImage2D(GL_TEXTURE_RECTANGLE, 0,
|
||||
0, 0, GL_NES_WIDTH, GL_NES_HEIGHT,
|
||||
0, 0, texture_width, texture_height,
|
||||
GL_BGRA, GL_UNSIGNED_BYTE, localBuf );
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
|
|
|
@ -20,20 +20,44 @@ class ConsoleViewGL_t : public QOpenGLWidget, protected QOpenGLFunctions
|
|||
|
||||
void transfer2LocalBuffer(void);
|
||||
|
||||
void setLinearFilterEnable( bool ena );
|
||||
|
||||
bool getSqrPixelOpt(void){ return sqrPixels; };
|
||||
void setSqrPixelOpt( bool val ){ sqrPixels = val; return; };
|
||||
bool getAutoScaleOpt(void){ return autoScaleEna; };
|
||||
void setAutoScaleOpt( bool val ){ autoScaleEna = val; return; };
|
||||
double getScaleX(void){ return xscale; };
|
||||
double getScaleY(void){ return yscale; };
|
||||
void setScaleXY( double xs, double ys );
|
||||
void getNormalizedCursorPos( double &x, double &y );
|
||||
bool getMouseButtonState( unsigned int btn );
|
||||
|
||||
protected:
|
||||
void initializeGL(void);
|
||||
void resizeGL(int w, int h);
|
||||
void paintGL(void);
|
||||
void mousePressEvent(QMouseEvent * event);
|
||||
void mouseReleaseEvent(QMouseEvent * event);
|
||||
|
||||
void buildTextures(void);
|
||||
void calcPixRemap(void);
|
||||
void doRemap(void);
|
||||
|
||||
double devPixRatio;
|
||||
double xscale;
|
||||
double yscale;
|
||||
int view_width;
|
||||
int view_height;
|
||||
int sx;
|
||||
int sy;
|
||||
int rw;
|
||||
int rh;
|
||||
GLuint gltexture;
|
||||
bool linearFilter;
|
||||
bool sqrPixels;
|
||||
bool autoScaleEna;
|
||||
|
||||
unsigned int mouseButtonMask;
|
||||
|
||||
uint32_t *localBuf;
|
||||
uint32_t localBufSize;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#include "Qt/nes_shm.h"
|
||||
#include "Qt/fceuWrapper.h"
|
||||
#include "Qt/ConsoleViewerSDL.h"
|
||||
|
||||
extern unsigned int gui_draw_area_width;
|
||||
|
@ -21,6 +22,9 @@ ConsoleViewSDL_t::ConsoleViewSDL_t(QWidget *parent)
|
|||
setAutoFillBackground(true);
|
||||
setPalette(pal);
|
||||
|
||||
setMinimumWidth( GL_NES_WIDTH );
|
||||
setMinimumHeight( GL_NES_HEIGHT );
|
||||
|
||||
view_width = GL_NES_WIDTH;
|
||||
view_height = GL_NES_HEIGHT;
|
||||
|
||||
|
@ -29,6 +33,8 @@ ConsoleViewSDL_t::ConsoleViewSDL_t(QWidget *parent)
|
|||
rh = view_height;
|
||||
sdlRendW = 0;
|
||||
sdlRendH = 0;
|
||||
xscale = 2.0;
|
||||
yscale = 2.0;
|
||||
|
||||
devPixRatio = 1.0f;
|
||||
sdlWindow = NULL;
|
||||
|
@ -36,8 +42,9 @@ ConsoleViewSDL_t::ConsoleViewSDL_t(QWidget *parent)
|
|||
sdlTexture = NULL;
|
||||
|
||||
vsyncEnabled = false;
|
||||
mouseButtonMask = 0;
|
||||
|
||||
localBufSize = GL_NES_WIDTH * GL_NES_HEIGHT * sizeof(uint32_t);
|
||||
localBufSize = (4 * GL_NES_WIDTH) * (4 * GL_NES_HEIGHT) * sizeof(uint32_t);
|
||||
|
||||
localBuf = (uint32_t*)malloc( localBufSize );
|
||||
|
||||
|
@ -46,6 +53,17 @@ ConsoleViewSDL_t::ConsoleViewSDL_t(QWidget *parent)
|
|||
memset( localBuf, 0, localBufSize );
|
||||
}
|
||||
|
||||
sqrPixels = true;
|
||||
autoScaleEna = true;
|
||||
linearFilter = false;
|
||||
|
||||
if ( g_config )
|
||||
{
|
||||
int opt;
|
||||
g_config->getOption("SDL.OpenGLip", &opt );
|
||||
|
||||
linearFilter = (opt) ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
ConsoleViewSDL_t::~ConsoleViewSDL_t(void)
|
||||
|
@ -56,15 +74,83 @@ ConsoleViewSDL_t::~ConsoleViewSDL_t(void)
|
|||
}
|
||||
}
|
||||
|
||||
void ConsoleViewSDL_t::setLinearFilterEnable( bool ena )
|
||||
{
|
||||
if ( ena != linearFilter )
|
||||
{
|
||||
linearFilter = ena;
|
||||
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleViewSDL_t::setScaleXY( double xs, double ys )
|
||||
{
|
||||
float xyRatio = (float)nes_shm->video.xyRatio;
|
||||
|
||||
xscale = xs;
|
||||
yscale = ys;
|
||||
|
||||
if ( sqrPixels )
|
||||
{
|
||||
if ( (xscale*xyRatio) < yscale )
|
||||
{
|
||||
yscale = (xscale*xyRatio);
|
||||
}
|
||||
else
|
||||
{
|
||||
xscale = (yscale/xyRatio);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleViewSDL_t::transfer2LocalBuffer(void)
|
||||
{
|
||||
memcpy( localBuf, nes_shm->pixbuf, localBufSize );
|
||||
int i=0, hq = 0;
|
||||
int numPixels = nes_shm->video.ncol * nes_shm->video.nrow;
|
||||
int cpSize = numPixels * 4;
|
||||
uint8_t *src, *dest;
|
||||
|
||||
if ( cpSize > localBufSize )
|
||||
{
|
||||
cpSize = localBufSize;
|
||||
}
|
||||
src = (uint8_t*)nes_shm->pixbuf;
|
||||
dest = (uint8_t*)localBuf;
|
||||
|
||||
hq = (nes_shm->video.preScaler == 1) || (nes_shm->video.preScaler == 4); // hq2x and hq3x
|
||||
|
||||
if ( hq )
|
||||
{
|
||||
for (i=0; i<numPixels; i++)
|
||||
{
|
||||
dest[3] = 0xFF;
|
||||
dest[1] = src[1];
|
||||
dest[2] = src[2];
|
||||
dest[0] = src[0];
|
||||
|
||||
src += 4; dest += 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy( localBuf, nes_shm->pixbuf, cpSize );
|
||||
}
|
||||
}
|
||||
|
||||
int ConsoleViewSDL_t::init(void)
|
||||
{
|
||||
WId windowHandle;
|
||||
|
||||
if ( linearFilter )
|
||||
{
|
||||
SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "1" );
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "0" );
|
||||
}
|
||||
|
||||
if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0)
|
||||
{
|
||||
printf("[SDL] Failed to initialize video subsystem.\n");
|
||||
|
@ -117,11 +203,11 @@ int ConsoleViewSDL_t::init(void)
|
|||
|
||||
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);
|
||||
sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, nes_shm->video.ncol, nes_shm->video.nrow);
|
||||
|
||||
if (sdlTexture == NULL)
|
||||
{
|
||||
printf("[SDL] Failed to create texture: %i x %i", GL_NES_WIDTH, GL_NES_HEIGHT );
|
||||
printf("[SDL] Failed to create texture: %i x %i", nes_shm->video.ncol, nes_shm->video.nrow );
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -147,7 +233,7 @@ void ConsoleViewSDL_t::reset(void)
|
|||
cleanup();
|
||||
if ( init() == 0 )
|
||||
{
|
||||
//console->GetVideoRenderer()->RegisterRenderingDevice(this);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -165,41 +251,110 @@ void ConsoleViewSDL_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 ConsoleViewSDL_t::paintEvent( QPaintEvent *event )
|
||||
void ConsoleViewSDL_t::mousePressEvent(QMouseEvent * event)
|
||||
{
|
||||
//printf("Mouse Button Press: (%i,%i) %x %x\n",
|
||||
// event->pos().x(), event->pos().y(), event->button(), event->buttons() );
|
||||
|
||||
mouseButtonMask = event->buttons();
|
||||
}
|
||||
|
||||
void ConsoleViewSDL_t::mouseReleaseEvent(QMouseEvent * event)
|
||||
{
|
||||
//printf("Mouse Button Release: (%i,%i) %x %x\n",
|
||||
// event->pos().x(), event->pos().y(), event->button(), event->buttons() );
|
||||
|
||||
mouseButtonMask = event->buttons();
|
||||
}
|
||||
|
||||
bool ConsoleViewSDL_t::getMouseButtonState( unsigned int btn )
|
||||
{
|
||||
return (mouseButtonMask & btn) ? true : false;
|
||||
}
|
||||
|
||||
void ConsoleViewSDL_t::getNormalizedCursorPos( double &x, double &y )
|
||||
{
|
||||
QPoint cursor;
|
||||
|
||||
cursor = QCursor::pos();
|
||||
|
||||
//printf("Global Cursor (%i,%i) \n", cursor.x(), cursor.y() );
|
||||
|
||||
cursor = mapFromGlobal( cursor );
|
||||
|
||||
//printf("Window Cursor (%i,%i) \n", cursor.x(), cursor.y() );
|
||||
|
||||
x = (double)(cursor.x() - sx) / (double)rw;
|
||||
y = (double)(cursor.y() - sy) / (double)rh;
|
||||
|
||||
if ( x < 0.0 )
|
||||
{
|
||||
x = 0.0;
|
||||
}
|
||||
else if ( x > 1.0 )
|
||||
{
|
||||
x = 1.0;
|
||||
}
|
||||
if ( y < 0.0 )
|
||||
{
|
||||
y = 0.0;
|
||||
}
|
||||
else if ( y > 1.0 )
|
||||
{
|
||||
y = 1.0;
|
||||
}
|
||||
//printf("Normalized Cursor (%f,%f) \n", x, y );
|
||||
}
|
||||
|
||||
void ConsoleViewSDL_t::render(void)
|
||||
{
|
||||
int nesWidth = GL_NES_WIDTH;
|
||||
int nesHeight = GL_NES_HEIGHT;
|
||||
float xyRatio = 1.0;
|
||||
|
||||
if ( nes_shm != NULL )
|
||||
{
|
||||
nesWidth = nes_shm->ncol;
|
||||
nesHeight = nes_shm->nrow;
|
||||
nesWidth = nes_shm->video.ncol;
|
||||
nesHeight = nes_shm->video.nrow;
|
||||
xyRatio = (float)nes_shm->video.xyRatio;
|
||||
}
|
||||
//printf(" %i x %i \n", nesWidth, nesHeight );
|
||||
float xscale = (float)view_width / (float)nesWidth;
|
||||
float yscale = (float)view_height / (float)nesHeight;
|
||||
float xscaleTmp = (float)view_width / (float)nesWidth;
|
||||
float yscaleTmp = (float)view_height / (float)nesHeight;
|
||||
|
||||
if (xscale < yscale )
|
||||
if ( sqrPixels )
|
||||
{
|
||||
yscale = xscale;
|
||||
}
|
||||
else
|
||||
{
|
||||
xscale = yscale;
|
||||
if ( (xscaleTmp*xyRatio) < yscaleTmp )
|
||||
{
|
||||
yscaleTmp = (xscaleTmp*xyRatio);
|
||||
}
|
||||
else
|
||||
{
|
||||
xscaleTmp = (yscaleTmp/xyRatio);
|
||||
}
|
||||
}
|
||||
|
||||
rw=(int)(nesWidth*xscale);
|
||||
rh=(int)(nesHeight*yscale);
|
||||
//sx=sdlViewport.x + (view_width-rw)/2;
|
||||
//sy=sdlViewport.y + (view_height-rh)/2;
|
||||
if ( autoScaleEna )
|
||||
{
|
||||
xscale = xscaleTmp;
|
||||
yscale = yscaleTmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( xscaleTmp > xscale )
|
||||
{
|
||||
xscaleTmp = xscale;
|
||||
}
|
||||
if ( yscaleTmp > yscale )
|
||||
{
|
||||
yscaleTmp = yscale;
|
||||
}
|
||||
}
|
||||
|
||||
rw=(int)(nesWidth*xscaleTmp);
|
||||
rh=(int)(nesHeight*yscaleTmp);
|
||||
sx=(view_width-rw)/2;
|
||||
sy=(view_height-rh)/2;
|
||||
|
||||
|
@ -216,12 +371,10 @@ void ConsoleViewSDL_t::render(void)
|
|||
int rowPitch;
|
||||
SDL_LockTexture( sdlTexture, nullptr, (void**)&textureBuffer, &rowPitch);
|
||||
{
|
||||
memcpy( textureBuffer, localBuf, GL_NES_HEIGHT*GL_NES_WIDTH*sizeof(uint32_t) );
|
||||
memcpy( textureBuffer, localBuf, nesWidth*nesHeight*sizeof(uint32_t) );
|
||||
}
|
||||
SDL_UnlockTexture(sdlTexture);
|
||||
|
||||
//SDL_RenderSetViewport( sdlRenderer, &sdlViewport );
|
||||
|
||||
SDL_Rect source = {0, 0, nesWidth, nesHeight };
|
||||
SDL_Rect dest = { sx, sy, rw, rh };
|
||||
SDL_RenderCopy(sdlRenderer, sdlTexture, &source, &dest);
|
||||
|
|
|
@ -23,25 +23,46 @@ class ConsoleViewSDL_t : public QWidget
|
|||
|
||||
void transfer2LocalBuffer(void);
|
||||
|
||||
void setLinearFilterEnable( bool ena );
|
||||
|
||||
bool getSqrPixelOpt(void){ return sqrPixels; };
|
||||
void setSqrPixelOpt( bool val ){ sqrPixels = val; return; };
|
||||
bool getAutoScaleOpt(void){ return autoScaleEna; };
|
||||
void setAutoScaleOpt( bool val ){ autoScaleEna = val; return; };
|
||||
double getScaleX(void){ return xscale; };
|
||||
double getScaleY(void){ return yscale; };
|
||||
void setScaleXY( double xs, double ys );
|
||||
void getNormalizedCursorPos( double &x, double &y );
|
||||
bool getMouseButtonState( unsigned int btn );
|
||||
|
||||
protected:
|
||||
|
||||
//void paintEvent(QPaintEvent *event);
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
int view_width;
|
||||
int view_height;
|
||||
void mousePressEvent(QMouseEvent * event);
|
||||
void mouseReleaseEvent(QMouseEvent * event);
|
||||
|
||||
double devPixRatio;
|
||||
int rw;
|
||||
int rh;
|
||||
int sx;
|
||||
int sy;
|
||||
int sdlRendW;
|
||||
int sdlRendH;
|
||||
int view_width;
|
||||
int view_height;
|
||||
|
||||
bool vsyncEnabled;
|
||||
double devPixRatio;
|
||||
double xscale;
|
||||
double yscale;
|
||||
int rw;
|
||||
int rh;
|
||||
int sx;
|
||||
int sy;
|
||||
int sdlRendW;
|
||||
int sdlRendH;
|
||||
|
||||
uint32_t *localBuf;
|
||||
bool vsyncEnabled;
|
||||
bool linearFilter;
|
||||
bool sqrPixels;
|
||||
bool autoScaleEna;
|
||||
|
||||
uint32_t *localBuf;
|
||||
uint32_t localBufSize;
|
||||
unsigned int mouseButtonMask;
|
||||
|
||||
SDL_Window *sdlWindow;
|
||||
SDL_Renderer *sdlRenderer;
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
#ifndef __GameAppH__
|
||||
#define __GameAppH__
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMainWindow>
|
||||
#include <QWidget>
|
||||
|
@ -25,10 +28,32 @@ class emulatorThread_t : public QThread
|
|||
{
|
||||
Q_OBJECT
|
||||
|
||||
//public slots:
|
||||
protected:
|
||||
void run( void ) override;
|
||||
|
||||
public:
|
||||
emulatorThread_t(void);
|
||||
|
||||
void setPriority( QThread::Priority priority );
|
||||
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
int setSchedParam( int policy, int priority );
|
||||
int getSchedParam( int &policy, int &priority );
|
||||
int setNicePriority( int value );
|
||||
int getNicePriority( void );
|
||||
int getMinSchedPriority(void);
|
||||
int getMaxSchedPriority(void);
|
||||
#endif
|
||||
private:
|
||||
void init(void);
|
||||
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
pthread_t pself;
|
||||
int pid;
|
||||
#endif
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
void finished();
|
||||
};
|
||||
|
||||
class consoleWin_t : public QMainWindow
|
||||
|
@ -46,8 +71,23 @@ class consoleWin_t : public QMainWindow
|
|||
|
||||
QMutex *mutex;
|
||||
|
||||
void requestClose(void);
|
||||
|
||||
void QueueErrorMsgWindow( const char *msg );
|
||||
|
||||
int showListSelectDialog( const char *title, std::vector <std::string> &l );
|
||||
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
int setSchedParam( int policy, int priority );
|
||||
int getSchedParam( int &policy, int &priority );
|
||||
int setNicePriority( int value );
|
||||
int getNicePriority( void );
|
||||
int getMinSchedPriority(void);
|
||||
int getMaxSchedPriority(void);
|
||||
#endif
|
||||
|
||||
emulatorThread_t *emulatorThread;
|
||||
|
||||
protected:
|
||||
QMenu *fileMenu;
|
||||
QMenu *optMenu;
|
||||
|
@ -67,16 +107,20 @@ class consoleWin_t : public QMainWindow
|
|||
QAction *loadLuaAct;
|
||||
QAction *scrShotAct;
|
||||
QAction *quitAct;
|
||||
QAction *inputConfig;
|
||||
QAction *gamePadConfig;
|
||||
QAction *gameSoundConfig;
|
||||
QAction *gameVideoConfig;
|
||||
QAction *hotkeyConfig;
|
||||
QAction *paletteConfig;
|
||||
QAction *guiConfig;
|
||||
QAction *timingConfig;
|
||||
QAction *movieConfig;
|
||||
QAction *autoResume;
|
||||
QAction *fullscreen;
|
||||
QAction *aboutAct;
|
||||
QAction *aboutActQt;
|
||||
QAction *msgLogAct;
|
||||
QAction *state[10];
|
||||
QAction *powerAct;
|
||||
QAction *resetAct;
|
||||
|
@ -89,10 +133,16 @@ class consoleWin_t : public QMainWindow
|
|||
QAction *fdsEjectAct;
|
||||
QAction *fdsLoadBiosAct;
|
||||
QAction *cheatsAct;
|
||||
QAction *ramWatchAct;
|
||||
QAction *ramSearchAct;
|
||||
QAction *debuggerAct;
|
||||
QAction *codeDataLogAct;
|
||||
QAction *traceLogAct;
|
||||
QAction *hexEditAct;
|
||||
QAction *ppuViewAct;
|
||||
QAction *ntViewAct;
|
||||
QAction *ggEncodeAct;
|
||||
QAction *iNesEditAct;
|
||||
QAction *openMovAct;
|
||||
QAction *stopMovAct;
|
||||
QAction *recMovAct;
|
||||
|
@ -100,10 +150,9 @@ class consoleWin_t : public QMainWindow
|
|||
|
||||
QTimer *gameTimer;
|
||||
|
||||
emulatorThread_t *emulatorThread;
|
||||
|
||||
std::string errorMsg;
|
||||
bool errorMsgValid;
|
||||
bool closeRequested;
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event);
|
||||
|
@ -118,6 +167,7 @@ class consoleWin_t : public QMainWindow
|
|||
public slots:
|
||||
void openDebugWindow(void);
|
||||
void openHexEditor(void);
|
||||
void openGamePadConfWin(void);
|
||||
private slots:
|
||||
void closeApp(void);
|
||||
void openROMFile(void);
|
||||
|
@ -129,12 +179,16 @@ class consoleWin_t : public QMainWindow
|
|||
void closeROMCB(void);
|
||||
void aboutFCEUX(void);
|
||||
void aboutQt(void);
|
||||
void openGamePadConfWin(void);
|
||||
void openMsgLogWin(void);
|
||||
void openInputConfWin(void);
|
||||
void openGameSndConfWin(void);
|
||||
void openGameVideoConfWin(void);
|
||||
void openHotkeyConfWin(void);
|
||||
void openPaletteConfWin(void);
|
||||
void openGuiConfWin(void);
|
||||
void openTimingConfWin(void);
|
||||
void openTimingStatWin(void);
|
||||
void openMovieOptWin(void);
|
||||
void openCodeDataLogger(void);
|
||||
void openTraceLogger(void);
|
||||
void toggleAutoResume(void);
|
||||
|
@ -162,7 +216,20 @@ class consoleWin_t : public QMainWindow
|
|||
void fdsSwitchDisk(void);
|
||||
void fdsEjectDisk(void);
|
||||
void fdsLoadBiosFile(void);
|
||||
void emuSpeedUp(void);
|
||||
void emuSlowDown(void);
|
||||
void emuSlowestSpd(void);
|
||||
void emuNormalSpd(void);
|
||||
void emuFastestSpd(void);
|
||||
void emuCustomSpd(void);
|
||||
void emuSetFrameAdvDelay(void);
|
||||
void openPPUViewer(void);
|
||||
void openNTViewer(void);
|
||||
void openGGEncoder(void);
|
||||
void openNesHeaderEditor(void);
|
||||
void openCheats(void);
|
||||
void openRamWatch(void);
|
||||
void openRamSearch(void);
|
||||
void openMovie(void);
|
||||
void stopMovie(void);
|
||||
void recordMovie(void);
|
||||
|
|
|
@ -0,0 +1,265 @@
|
|||
// FrameTimingStats.cpp
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#include <SDL.h>
|
||||
#include <QHeaderView>
|
||||
#include <QCloseEvent>
|
||||
|
||||
#include "Qt/main.h"
|
||||
#include "Qt/dface.h"
|
||||
#include "Qt/input.h"
|
||||
#include "Qt/config.h"
|
||||
#include "Qt/keyscan.h"
|
||||
#include "Qt/throttle.h"
|
||||
#include "Qt/fceuWrapper.h"
|
||||
#include "Qt/FrameTimingStats.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
FrameTimingDialog_t::FrameTimingDialog_t(QWidget *parent)
|
||||
: QDialog( parent )
|
||||
{
|
||||
QVBoxLayout *mainLayout, *vbox;
|
||||
QHBoxLayout *hbox;
|
||||
QGroupBox *frame;
|
||||
QTreeWidgetItem *item;
|
||||
QPushButton *resetBtn;
|
||||
struct frameTimingStat_t stats;
|
||||
|
||||
getFrameTimingStats( &stats );
|
||||
|
||||
setWindowTitle("Frame Timing Statistics");
|
||||
|
||||
resize( 512, 512 );
|
||||
|
||||
mainLayout = new QVBoxLayout();
|
||||
vbox = new QVBoxLayout();
|
||||
frame = new QGroupBox( tr("Timing Statistics") );
|
||||
frame->setLayout( vbox );
|
||||
|
||||
tree = new QTreeWidget();
|
||||
vbox->addWidget( tree );
|
||||
|
||||
tree->setColumnCount(4);
|
||||
|
||||
item = new QTreeWidgetItem();
|
||||
item->setText( 0, tr( "Parameter" ) );
|
||||
item->setText( 1, tr( "Target" ) );
|
||||
item->setText( 2, tr( "Current" ) );
|
||||
item->setText( 3, tr( "Minimum" ) );
|
||||
item->setText( 4, tr( "Maximum" ) );
|
||||
item->setTextAlignment( 0, Qt::AlignLeft);
|
||||
item->setTextAlignment( 1, Qt::AlignCenter);
|
||||
item->setTextAlignment( 2, Qt::AlignCenter);
|
||||
item->setTextAlignment( 3, Qt::AlignCenter);
|
||||
item->setTextAlignment( 4, Qt::AlignCenter);
|
||||
|
||||
tree->setHeaderItem( item );
|
||||
tree->header()->setSectionResizeMode( QHeaderView::Stretch );
|
||||
tree->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents );
|
||||
|
||||
frameTimeAbs = new QTreeWidgetItem();
|
||||
frameTimeDel = new QTreeWidgetItem();
|
||||
frameTimeWork = new QTreeWidgetItem();
|
||||
frameTimeIdle = new QTreeWidgetItem();
|
||||
frameTimeWorkPct = new QTreeWidgetItem();
|
||||
frameTimeIdlePct = new QTreeWidgetItem();
|
||||
frameLateCount = new QTreeWidgetItem();
|
||||
|
||||
tree->addTopLevelItem( frameTimeAbs );
|
||||
tree->addTopLevelItem( frameTimeDel );
|
||||
tree->addTopLevelItem( frameTimeWork );
|
||||
tree->addTopLevelItem( frameTimeIdle );
|
||||
tree->addTopLevelItem( frameTimeWorkPct );
|
||||
tree->addTopLevelItem( frameTimeIdlePct );
|
||||
tree->addTopLevelItem( frameLateCount );
|
||||
|
||||
frameTimeAbs->setFlags( Qt::ItemIsEnabled | Qt::ItemNeverHasChildren );
|
||||
frameTimeDel->setFlags( Qt::ItemIsEnabled | Qt::ItemNeverHasChildren );
|
||||
|
||||
frameTimeAbs->setText( 0, tr("Frame Period ms") );
|
||||
frameTimeDel->setText( 0, tr("Frame Delta ms") );
|
||||
frameTimeWork->setText( 0, tr("Frame Work ms") );
|
||||
frameTimeIdle->setText( 0, tr("Frame Idle ms") );
|
||||
frameTimeWorkPct->setText( 0, tr("Frame Work %") );
|
||||
frameTimeIdlePct->setText( 0, tr("Frame Idle %") );
|
||||
frameLateCount->setText( 0, tr("Frame Late Count") );
|
||||
|
||||
frameTimeAbs->setTextAlignment( 0, Qt::AlignLeft);
|
||||
frameTimeDel->setTextAlignment( 0, Qt::AlignLeft);
|
||||
frameTimeWork->setTextAlignment( 0, Qt::AlignLeft);
|
||||
frameTimeIdle->setTextAlignment( 0, Qt::AlignLeft);
|
||||
frameTimeWorkPct->setTextAlignment( 0, Qt::AlignLeft);
|
||||
frameTimeIdlePct->setTextAlignment( 0, Qt::AlignLeft);
|
||||
frameLateCount->setTextAlignment( 0, Qt::AlignLeft);
|
||||
|
||||
for (int i=0; i<4; i++)
|
||||
{
|
||||
frameTimeAbs->setTextAlignment( i+1, Qt::AlignCenter);
|
||||
frameTimeDel->setTextAlignment( i+1, Qt::AlignCenter);
|
||||
frameTimeWork->setTextAlignment( i+1, Qt::AlignCenter);
|
||||
frameTimeIdle->setTextAlignment( i+1, Qt::AlignCenter);
|
||||
frameTimeWorkPct->setTextAlignment( i+1, Qt::AlignCenter);
|
||||
frameTimeIdlePct->setTextAlignment( i+1, Qt::AlignCenter);
|
||||
frameLateCount->setTextAlignment( i+1, Qt::AlignCenter);
|
||||
}
|
||||
|
||||
hbox = new QHBoxLayout();
|
||||
timingEnable = new QCheckBox( tr("Enable Timing Statistics Calculations") );
|
||||
resetBtn = new QPushButton( tr("Reset") );
|
||||
|
||||
timingEnable->setChecked( stats.enabled );
|
||||
|
||||
hbox->addWidget( timingEnable );
|
||||
hbox->addWidget( resetBtn );
|
||||
|
||||
connect( timingEnable, SIGNAL(stateChanged(int)), this, SLOT(timingEnableChanged(int)) );
|
||||
connect( resetBtn , SIGNAL(clicked(void)) , this, SLOT(resetTimingClicked(void)) );
|
||||
|
||||
mainLayout->addLayout( hbox );
|
||||
mainLayout->addWidget( frame );
|
||||
|
||||
setLayout( mainLayout );
|
||||
|
||||
updateTimingStats();
|
||||
|
||||
updateTimer = new QTimer( this );
|
||||
|
||||
connect( updateTimer, &QTimer::timeout, this, &FrameTimingDialog_t::updatePeriodic );
|
||||
|
||||
updateTimer->start( 200 ); // 5hz
|
||||
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
FrameTimingDialog_t::~FrameTimingDialog_t(void)
|
||||
{
|
||||
printf("Destroy Frame Timing Window\n");
|
||||
updateTimer->stop();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void FrameTimingDialog_t::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
printf("Frame Timing Close Window Event\n");
|
||||
done(0);
|
||||
deleteLater();
|
||||
event->accept();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void FrameTimingDialog_t::closeWindow(void)
|
||||
{
|
||||
//printf("Close Window\n");
|
||||
done(0);
|
||||
deleteLater();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void FrameTimingDialog_t::updateTimingStats(void)
|
||||
{
|
||||
char stmp[128];
|
||||
struct frameTimingStat_t stats;
|
||||
|
||||
getFrameTimingStats( &stats );
|
||||
|
||||
// Absolute
|
||||
sprintf( stmp, "%.3f", stats.frameTimeAbs.tgt * 1e3 );
|
||||
frameTimeAbs->setText( 1, tr(stmp) );
|
||||
|
||||
sprintf( stmp, "%.3f", stats.frameTimeAbs.cur * 1e3 );
|
||||
frameTimeAbs->setText( 2, tr(stmp) );
|
||||
|
||||
sprintf( stmp, "%.3f", stats.frameTimeAbs.min * 1e3 );
|
||||
frameTimeAbs->setText( 3, tr(stmp) );
|
||||
|
||||
sprintf( stmp, "%.3f", stats.frameTimeAbs.max * 1e3 );
|
||||
frameTimeAbs->setText( 4, tr(stmp) );
|
||||
|
||||
// Delta
|
||||
sprintf( stmp, "%.3f", stats.frameTimeDel.tgt * 1e3 );
|
||||
frameTimeDel->setText( 1, tr(stmp) );
|
||||
|
||||
sprintf( stmp, "%.3f", stats.frameTimeDel.cur * 1e3 );
|
||||
frameTimeDel->setText( 2, tr(stmp) );
|
||||
|
||||
sprintf( stmp, "%.3f", stats.frameTimeDel.min * 1e3 );
|
||||
frameTimeDel->setText( 3, tr(stmp) );
|
||||
|
||||
sprintf( stmp, "%.3f", stats.frameTimeDel.max * 1e3 );
|
||||
frameTimeDel->setText( 4, tr(stmp) );
|
||||
|
||||
// Work
|
||||
sprintf( stmp, "lt %.3f", stats.frameTimeWork.tgt * 1e3 );
|
||||
frameTimeWork->setText( 1, tr(stmp) );
|
||||
|
||||
sprintf( stmp, "%.3f", stats.frameTimeWork.cur * 1e3 );
|
||||
frameTimeWork->setText( 2, tr(stmp) );
|
||||
|
||||
sprintf( stmp, "%.3f", stats.frameTimeWork.min * 1e3 );
|
||||
frameTimeWork->setText( 3, tr(stmp) );
|
||||
|
||||
sprintf( stmp, "%.3f", stats.frameTimeWork.max * 1e3 );
|
||||
frameTimeWork->setText( 4, tr(stmp) );
|
||||
|
||||
// Idle
|
||||
sprintf( stmp, "gt %.3f", stats.frameTimeIdle.tgt * 1e3 );
|
||||
frameTimeIdle->setText( 1, tr(stmp) );
|
||||
|
||||
sprintf( stmp, "%.3f", stats.frameTimeIdle.cur * 1e3 );
|
||||
frameTimeIdle->setText( 2, tr(stmp) );
|
||||
|
||||
sprintf( stmp, "%.3f", stats.frameTimeIdle.min * 1e3 );
|
||||
frameTimeIdle->setText( 3, tr(stmp) );
|
||||
|
||||
sprintf( stmp, "%.3f", stats.frameTimeIdle.max * 1e3 );
|
||||
frameTimeIdle->setText( 4, tr(stmp) );
|
||||
|
||||
// Work %
|
||||
sprintf( stmp, "lt %.1f", 100.0 * stats.frameTimeWork.tgt / stats.frameTimeAbs.tgt );
|
||||
frameTimeWorkPct->setText( 1, tr(stmp) );
|
||||
|
||||
sprintf( stmp, "%.1f", 100.0 * stats.frameTimeWork.cur / stats.frameTimeAbs.tgt );
|
||||
frameTimeWorkPct->setText( 2, tr(stmp) );
|
||||
|
||||
sprintf( stmp, "%.1f", 100.0 * stats.frameTimeWork.min / stats.frameTimeAbs.tgt );
|
||||
frameTimeWorkPct->setText( 3, tr(stmp) );
|
||||
|
||||
sprintf( stmp, "%.1f", 100.0 * stats.frameTimeWork.max / stats.frameTimeAbs.tgt );
|
||||
frameTimeWorkPct->setText( 4, tr(stmp) );
|
||||
|
||||
// Idle %
|
||||
sprintf( stmp, "gt %.1f", 100.0 * stats.frameTimeIdle.tgt / stats.frameTimeAbs.tgt );
|
||||
frameTimeIdlePct->setText( 1, tr(stmp) );
|
||||
|
||||
sprintf( stmp, "%.1f", 100.0 * stats.frameTimeIdle.cur / stats.frameTimeAbs.tgt );
|
||||
frameTimeIdlePct->setText( 2, tr(stmp) );
|
||||
|
||||
sprintf( stmp, "%.1f", 100.0 * stats.frameTimeIdle.min / stats.frameTimeAbs.tgt );
|
||||
frameTimeIdlePct->setText( 3, tr(stmp) );
|
||||
|
||||
sprintf( stmp, "%.1f", 100.0 * stats.frameTimeIdle.max / stats.frameTimeAbs.tgt );
|
||||
frameTimeIdlePct->setText( 4, tr(stmp) );
|
||||
|
||||
// Late Count
|
||||
sprintf( stmp, "%u", stats.lateCount );
|
||||
frameLateCount->setText( 1, tr("0") );
|
||||
frameLateCount->setText( 2, tr(stmp) );
|
||||
|
||||
tree->viewport()->update();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void FrameTimingDialog_t::updatePeriodic(void)
|
||||
{
|
||||
updateTimingStats();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void FrameTimingDialog_t::timingEnableChanged(int state)
|
||||
{
|
||||
setFrameTimingEnable( state != Qt::Unchecked );
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void FrameTimingDialog_t::resetTimingClicked(void)
|
||||
{
|
||||
resetFrameTiming();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
|
@ -0,0 +1,55 @@
|
|||
// FrameTimingStats.h
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDialog>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
#include <QLabel>
|
||||
#include <QTimer>
|
||||
#include <QFrame>
|
||||
#include <QGroupBox>
|
||||
#include <QTreeWidget>
|
||||
#include <QTreeWidgetItem>
|
||||
|
||||
#include "Qt/main.h"
|
||||
|
||||
class FrameTimingDialog_t : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FrameTimingDialog_t(QWidget *parent = 0);
|
||||
~FrameTimingDialog_t(void);
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event);
|
||||
|
||||
QTimer *updateTimer;
|
||||
QCheckBox *timingEnable;
|
||||
QTreeWidgetItem *frameTimeAbs;
|
||||
QTreeWidgetItem *frameTimeDel;
|
||||
QTreeWidgetItem *frameTimeWork;
|
||||
QTreeWidgetItem *frameTimeWorkPct;
|
||||
QTreeWidgetItem *frameTimeIdle;
|
||||
QTreeWidgetItem *frameTimeIdlePct;
|
||||
QTreeWidgetItem *frameLateCount;
|
||||
|
||||
QTreeWidget *tree;
|
||||
|
||||
private:
|
||||
void updateTimingStats(void);
|
||||
|
||||
public slots:
|
||||
void closeWindow(void);
|
||||
private slots:
|
||||
void updatePeriodic(void);
|
||||
void resetTimingClicked(void);
|
||||
void timingEnableChanged(int state);
|
||||
|
||||
};
|
|
@ -0,0 +1,445 @@
|
|||
// GameGenie.cpp
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#include <QHeaderView>
|
||||
#include <QCloseEvent>
|
||||
|
||||
#include "../../types.h"
|
||||
#include "../../fceu.h"
|
||||
#include "../../cart.h"
|
||||
#include "../../cheat.h"
|
||||
#include "../../debug.h"
|
||||
#include "../../driver.h"
|
||||
|
||||
#include "Qt/main.h"
|
||||
#include "Qt/dface.h"
|
||||
#include "Qt/dface.h"
|
||||
#include "Qt/input.h"
|
||||
#include "Qt/config.h"
|
||||
#include "Qt/keyscan.h"
|
||||
#include "Qt/fceuWrapper.h"
|
||||
#include "Qt/HexEditor.h"
|
||||
#include "Qt/GameGenie.h"
|
||||
|
||||
static const char *GameGenieLetters = "APZLGITYEOXUKSVN";
|
||||
|
||||
class fceuGGCodeValidtor : public QValidator
|
||||
{
|
||||
public:
|
||||
fceuGGCodeValidtor( QObject *parent)
|
||||
: QValidator(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QValidator::State validate(QString &input, int &pos) const
|
||||
{
|
||||
int i,j, ok;
|
||||
//printf("Validate: %i '%s'\n", input.size(), input.toStdString().c_str() );
|
||||
|
||||
if ( input.size() == 0 )
|
||||
{
|
||||
return QValidator::Acceptable;
|
||||
}
|
||||
input = input.toUpper();
|
||||
std::string s = input.toStdString();
|
||||
i=0;
|
||||
|
||||
while ( s[i] != 0 )
|
||||
{
|
||||
j=0; ok=0;
|
||||
while ( GameGenieLetters[j] != 0 )
|
||||
{
|
||||
if ( s[i] == GameGenieLetters[j] )
|
||||
{
|
||||
ok = 1; break;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
|
||||
if ( !ok )
|
||||
{
|
||||
return QValidator::Invalid;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return QValidator::Acceptable;
|
||||
}
|
||||
|
||||
private:
|
||||
};
|
||||
//----------------------------------------------------------------------------
|
||||
GameGenieDialog_t::GameGenieDialog_t(QWidget *parent)
|
||||
: QDialog( parent )
|
||||
{
|
||||
int charWidth;
|
||||
QVBoxLayout *mainLayout, *vbox1, *vbox;
|
||||
QHBoxLayout *hbox1, *hbox;
|
||||
QTreeWidgetItem *item;
|
||||
QGroupBox *frame;
|
||||
QFont font;
|
||||
fceuGGCodeValidtor *ggCodeValidator;
|
||||
|
||||
font.setFamily("Courier New");
|
||||
font.setStyle( QFont::StyleNormal );
|
||||
font.setStyleHint( QFont::Monospace );
|
||||
|
||||
QFontMetrics fm(font);
|
||||
|
||||
#if QT_VERSION > QT_VERSION_CHECK(5, 11, 0)
|
||||
charWidth = fm.horizontalAdvance(QLatin1Char('2'));
|
||||
#else
|
||||
charWidth = fm.width(QLatin1Char('2'));
|
||||
#endif
|
||||
|
||||
setWindowTitle("Game Genie Encoder/Decoder Tool");
|
||||
|
||||
mainLayout = new QVBoxLayout();
|
||||
vbox = new QVBoxLayout();
|
||||
vbox1 = new QVBoxLayout();
|
||||
hbox1 = new QHBoxLayout();
|
||||
|
||||
frame = new QGroupBox( tr("Address/Compare/Value") );
|
||||
mainLayout->addLayout( hbox1 );
|
||||
frame->setLayout( vbox );
|
||||
|
||||
hbox1->addWidget( frame );
|
||||
hbox1->addLayout( vbox1 );
|
||||
addr = new QLineEdit();
|
||||
cmp = new QLineEdit();
|
||||
val = new QLineEdit();
|
||||
|
||||
hbox = new QHBoxLayout();
|
||||
vbox->addLayout( hbox );
|
||||
hbox->addWidget( new QLabel( tr("Address:") ), 0, Qt::AlignRight );
|
||||
hbox->addWidget( addr, 0, Qt::AlignLeft );
|
||||
|
||||
hbox = new QHBoxLayout();
|
||||
vbox->addLayout( hbox );
|
||||
hbox->addWidget( new QLabel( tr("Compare:") ), 0, Qt::AlignRight );
|
||||
hbox->addWidget( cmp, 0, Qt::AlignLeft );
|
||||
|
||||
hbox = new QHBoxLayout();
|
||||
vbox->addLayout( hbox );
|
||||
hbox->addWidget( new QLabel( tr("Value:") ), 0, Qt::AlignRight );
|
||||
hbox->addWidget( val, 0, Qt::AlignLeft );
|
||||
|
||||
frame = new QGroupBox( tr("Game Genie Code") );
|
||||
vbox = new QVBoxLayout();
|
||||
vbox1->addWidget( frame );
|
||||
frame->setLayout( vbox );
|
||||
|
||||
ggCode = new QLineEdit();
|
||||
vbox->addWidget( ggCode );
|
||||
|
||||
addCheatBtn = new QPushButton( tr("Add To Cheat List") );
|
||||
vbox1->addWidget( addCheatBtn );
|
||||
|
||||
tree = new QTreeWidget();
|
||||
|
||||
tree->setColumnCount(1);
|
||||
|
||||
item = new QTreeWidgetItem();
|
||||
item->setText( 0, QString::fromStdString( "Possible Affected ROM File Addresses" ) );
|
||||
item->setTextAlignment( 0, Qt::AlignLeft);
|
||||
|
||||
tree->setHeaderItem( item );
|
||||
|
||||
tree->header()->setSectionResizeMode( QHeaderView::ResizeToContents );
|
||||
|
||||
mainLayout->addWidget( tree );
|
||||
|
||||
setLayout( mainLayout );
|
||||
|
||||
addrValidator = new fceuHexIntValidtor( 0, 0xFFFF, this );
|
||||
cmpValidator = new fceuHexIntValidtor( 0, 0x00FF, this );
|
||||
valValidator = new fceuHexIntValidtor( 0, 0x00FF, this );
|
||||
|
||||
ggCodeValidator = new fceuGGCodeValidtor( this );
|
||||
|
||||
addr->setValidator( addrValidator );
|
||||
cmp->setValidator( cmpValidator );
|
||||
val->setValidator( valValidator );
|
||||
ggCode->setValidator( ggCodeValidator );
|
||||
|
||||
addr->setMaxLength( 4 );
|
||||
cmp->setMaxLength( 2 );
|
||||
val->setMaxLength( 2 );
|
||||
ggCode->setMaxLength( 8 );
|
||||
|
||||
addr->setMinimumWidth( 6 * charWidth );
|
||||
cmp->setMinimumWidth( 4 * charWidth );
|
||||
val->setMinimumWidth( 4 * charWidth );
|
||||
addr->setMaximumWidth( 6 * charWidth );
|
||||
cmp->setMaximumWidth( 4 * charWidth );
|
||||
val->setMaximumWidth( 4 * charWidth );
|
||||
|
||||
addr->setAlignment(Qt::AlignCenter);
|
||||
cmp->setAlignment(Qt::AlignCenter);
|
||||
val->setAlignment(Qt::AlignCenter);
|
||||
|
||||
addr->setFont( font );
|
||||
cmp->setFont( font );
|
||||
val->setFont( font );
|
||||
ggCode->setFont( font );
|
||||
|
||||
connect( addCheatBtn, SIGNAL(clicked(void)), this, SLOT(addCheatClicked(void)));
|
||||
|
||||
connect( addr , SIGNAL(textEdited(const QString &)), this, SLOT(addrChanged(const QString &)));
|
||||
connect( cmp , SIGNAL(textEdited(const QString &)), this, SLOT(cmpChanged(const QString &)));
|
||||
connect( val , SIGNAL(textEdited(const QString &)), this, SLOT(valChanged(const QString &)));
|
||||
connect( ggCode, SIGNAL(textEdited(const QString &)), this, SLOT(ggChanged(const QString &)));
|
||||
|
||||
connect( tree, SIGNAL(itemActivated(QTreeWidgetItem*, int)), this, SLOT(romAddrDoubleClicked(QTreeWidgetItem*, int)) );
|
||||
|
||||
addCheatBtn->setEnabled( false );
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
GameGenieDialog_t::~GameGenieDialog_t(void)
|
||||
{
|
||||
printf("Destroy Game Genie Window\n");
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void GameGenieDialog_t::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
printf("Game Genie Close Window Event\n");
|
||||
done(0);
|
||||
deleteLater();
|
||||
event->accept();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void GameGenieDialog_t::closeWindow(void)
|
||||
{
|
||||
//printf("Close Window\n");
|
||||
done(0);
|
||||
deleteLater();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void GameGenieDialog_t::addCheatClicked(void)
|
||||
{
|
||||
int a = -1, v = -1, c = -1;
|
||||
std::string name;
|
||||
|
||||
name = ggCode->text().toStdString();
|
||||
|
||||
if ( addr->text().size() > 0 )
|
||||
{
|
||||
a = strtol( addr->text().toStdString().c_str(), NULL, 16 );
|
||||
}
|
||||
if ( val->text().size() > 0 )
|
||||
{
|
||||
v = strtol( val->text().toStdString().c_str(), NULL, 16 );
|
||||
}
|
||||
if ( cmp->text().size() > 0 )
|
||||
{
|
||||
c = strtol( cmp->text().toStdString().c_str(), NULL, 16 );
|
||||
}
|
||||
|
||||
fceuWrapperLock();
|
||||
FCEUI_AddCheat( name.c_str(), a, v, c, 1 );
|
||||
fceuWrapperUnLock();
|
||||
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void GameGenieDialog_t::romAddrDoubleClicked(QTreeWidgetItem *item, int column)
|
||||
{
|
||||
int addr;
|
||||
|
||||
addr = strtol( item->text(0).toStdString().c_str(), NULL, 16 );
|
||||
|
||||
printf("ROM Addr: %06X \n", addr );
|
||||
|
||||
hexEditorOpenFromDebugger( QHexEdit::MODE_NES_ROM, addr );
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void GameGenieDialog_t::addrChanged(const QString &s)
|
||||
{
|
||||
int a, v, c = -1;
|
||||
char gg[12];
|
||||
|
||||
a = strtol( s.toStdString().c_str(), NULL, 16 );
|
||||
v = strtol( val->text().toStdString().c_str(), NULL, 16 );
|
||||
|
||||
if ( cmp->text().size() > 0 )
|
||||
{
|
||||
c = strtol( cmp->text().toStdString().c_str(), NULL, 16 );
|
||||
}
|
||||
|
||||
EncodeGG( gg, a, v, c );
|
||||
|
||||
ggCode->setText( tr(gg) );
|
||||
|
||||
ListGGAddresses();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void GameGenieDialog_t::cmpChanged(const QString &s)
|
||||
{
|
||||
int a, v, c = -1;
|
||||
char gg[12];
|
||||
|
||||
a = strtol( addr->text().toStdString().c_str(), NULL, 16 );
|
||||
v = strtol( val->text().toStdString().c_str(), NULL, 16 );
|
||||
|
||||
if ( s.size() > 0 )
|
||||
{
|
||||
c = strtol( s.toStdString().c_str(), NULL, 16 );
|
||||
}
|
||||
|
||||
EncodeGG( gg, a, v, c );
|
||||
|
||||
ggCode->setText( tr(gg) );
|
||||
|
||||
ListGGAddresses();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void GameGenieDialog_t::valChanged(const QString &s)
|
||||
{
|
||||
int a, v, c = -1;
|
||||
char gg[12];
|
||||
|
||||
a = strtol( addr->text().toStdString().c_str(), NULL, 16 );
|
||||
v = strtol( s.toStdString().c_str(), NULL, 16 );
|
||||
|
||||
if ( cmp->text().size() > 0 )
|
||||
{
|
||||
c = strtol( cmp->text().toStdString().c_str(), NULL, 16 );
|
||||
}
|
||||
EncodeGG( gg, a, v, c );
|
||||
|
||||
ggCode->setText( tr(gg) );
|
||||
|
||||
ListGGAddresses();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void GameGenieDialog_t::ggChanged(const QString &s)
|
||||
{
|
||||
int a = -1, c = -1, v = -1;
|
||||
char gg[12];
|
||||
char stmp[32];
|
||||
|
||||
memset( gg, 0, sizeof(gg) );
|
||||
|
||||
strncpy( gg, ggCode->text().toStdString().c_str(), 8 );
|
||||
|
||||
FCEUI_DecodeGG( gg, &a, &v, &c);
|
||||
|
||||
if ( a >= 0 )
|
||||
{
|
||||
sprintf( stmp, "%04X", a );
|
||||
|
||||
addr->setText( tr(stmp) );
|
||||
}
|
||||
else
|
||||
{
|
||||
addr->clear();
|
||||
}
|
||||
|
||||
if ( v >= 0 )
|
||||
{
|
||||
sprintf( stmp, "%02X", v );
|
||||
|
||||
val->setText( tr(stmp) );
|
||||
}
|
||||
else
|
||||
{
|
||||
val->clear();
|
||||
}
|
||||
|
||||
if ( c >= 0 )
|
||||
{
|
||||
sprintf( stmp, "%02X", c );
|
||||
|
||||
cmp->setText( tr(stmp) );
|
||||
}
|
||||
else
|
||||
{
|
||||
cmp->clear();
|
||||
}
|
||||
|
||||
ListGGAddresses();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
//The code in this function is a modified version
|
||||
//of Chris Covell's work - I'd just like to point that out
|
||||
void EncodeGG(char *str, int a, int v, int c)
|
||||
{
|
||||
uint8 num[8];
|
||||
int i;
|
||||
|
||||
a&=0x7fff;
|
||||
|
||||
num[0]=(v&7)+((v>>4)&8);
|
||||
num[1]=((v>>4)&7)+((a>>4)&8);
|
||||
num[2]=((a>>4)&7);
|
||||
num[3]=(a>>12)+(a&8);
|
||||
num[4]=(a&7)+((a>>8)&8);
|
||||
num[5]=((a>>8)&7);
|
||||
|
||||
if (c == -1){
|
||||
num[5]+=v&8;
|
||||
for(i = 0;i < 6;i++)str[i] = GameGenieLetters[num[i]];
|
||||
str[6] = 0;
|
||||
} else {
|
||||
num[2]+=8;
|
||||
num[5]+=c&8;
|
||||
num[6]=(c&7)+((c>>4)&8);
|
||||
num[7]=((c>>4)&7)+(v&8);
|
||||
for(i = 0;i < 8;i++)str[i] = GameGenieLetters[num[i]];
|
||||
str[8] = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void GameGenieDialog_t::ListGGAddresses(void)
|
||||
{
|
||||
int i; //mbg merge 7/18/06 changed from int
|
||||
int a = -1; int v = -1; int c = -1;
|
||||
QTreeWidgetItem *item;
|
||||
char str[32];
|
||||
bool addCheatEmable;
|
||||
|
||||
if ( addr->text().size() > 0 )
|
||||
{
|
||||
a = strtol( addr->text().toStdString().c_str(), NULL, 16 );
|
||||
}
|
||||
if ( val->text().size() > 0 )
|
||||
{
|
||||
v = strtol( val->text().toStdString().c_str(), NULL, 16 );
|
||||
}
|
||||
if ( cmp->text().size() > 0 )
|
||||
{
|
||||
c = strtol( cmp->text().toStdString().c_str(), NULL, 16 );
|
||||
}
|
||||
// also enable/disable the add GG button here
|
||||
addCheatEmable = (a >= 0) && ( (ggCode->text().size() == 6) || (ggCode->text().size() == 8) );
|
||||
|
||||
addCheatBtn->setEnabled( addCheatEmable );
|
||||
|
||||
tree->clear();
|
||||
|
||||
if (a != -1 && v != -1)
|
||||
{
|
||||
for (i = 0; i < PRGsize[0]; i += 0x2000)
|
||||
{
|
||||
if (c == -1 || PRGptr[0][i + (a & 0x1FFF)] == c)
|
||||
{
|
||||
item = new QTreeWidgetItem();
|
||||
|
||||
sprintf(str, "%06X", i + (a & 0x1FFF) + 0x10);
|
||||
|
||||
//printf("Added ROM ADDR: %s\n", str );
|
||||
item->setText( 0, tr(str) );
|
||||
|
||||
item->setTextAlignment( 0, Qt::AlignCenter);
|
||||
tree->addTopLevelItem( item );
|
||||
}
|
||||
}
|
||||
}
|
||||
tree->viewport()->update();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
|
@ -0,0 +1,60 @@
|
|||
// GameGenie.h
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDialog>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
#include <QLabel>
|
||||
#include <QFrame>
|
||||
#include <QGroupBox>
|
||||
#include <QLineEdit>
|
||||
#include <QTreeView>
|
||||
#include <QTreeWidget>
|
||||
|
||||
#include "Qt/main.h"
|
||||
#include "Qt/ConsoleUtilities.h"
|
||||
|
||||
class GameGenieDialog_t : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GameGenieDialog_t(QWidget *parent = 0);
|
||||
~GameGenieDialog_t(void);
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event);
|
||||
|
||||
fceuHexIntValidtor *addrValidator;
|
||||
fceuHexIntValidtor *cmpValidator;
|
||||
fceuHexIntValidtor *valValidator;
|
||||
|
||||
QLineEdit *addr;
|
||||
QLineEdit *cmp;
|
||||
QLineEdit *val;
|
||||
QLineEdit *ggCode;
|
||||
QPushButton *addCheatBtn;
|
||||
QTreeWidget *tree;
|
||||
|
||||
private:
|
||||
void ListGGAddresses(void);
|
||||
|
||||
public slots:
|
||||
void closeWindow(void);
|
||||
private slots:
|
||||
void addCheatClicked(void);
|
||||
void addrChanged(const QString &);
|
||||
void cmpChanged(const QString &);
|
||||
void valChanged(const QString &);
|
||||
void ggChanged(const QString &);
|
||||
void romAddrDoubleClicked(QTreeWidgetItem *item, int column);
|
||||
|
||||
};
|
||||
|
||||
void EncodeGG(char *str, int a, int v, int c);
|
|
@ -3,6 +3,7 @@
|
|||
#include <QDir>
|
||||
#include <QInputDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QScrollArea>
|
||||
|
||||
#include "Qt/GamePadConf.h"
|
||||
#include "Qt/main.h"
|
||||
|
@ -64,10 +65,12 @@ int closeGamePadConfWindow(void)
|
|||
GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent)
|
||||
: QDialog( parent )
|
||||
{
|
||||
QHBoxLayout *hbox, *hbox1, *hbox2, *hbox3, *hbox4;
|
||||
QVBoxLayout *vbox;
|
||||
QWidget *mainWidget;
|
||||
QVBoxLayout *mainLayout;
|
||||
QHBoxLayout *hbox, *hbox1, *hbox2, *hbox3, *hbox4, *hbox5;
|
||||
QVBoxLayout *vbox, *vbox1, *vbox2;
|
||||
QGridLayout *grid;
|
||||
QCheckBox *efs_chkbox, *udlr_chkbox;
|
||||
QCheckBox *udlr_chkbox;
|
||||
QGroupBox *frame1, *frame2;
|
||||
QLabel *label;
|
||||
QPushButton *newProfileButton;
|
||||
|
@ -77,14 +80,21 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent)
|
|||
QPushButton *clearAllButton;
|
||||
QPushButton *closebutton;
|
||||
QPushButton *clearButton[GAMEPAD_NUM_BUTTONS];
|
||||
QScrollArea *scroll;
|
||||
QStyle *style;
|
||||
std::string prefix;
|
||||
char stmp[256];
|
||||
|
||||
style = this->style();
|
||||
|
||||
gamePadConfWin = this;
|
||||
|
||||
// Ensure that joysticks are enabled, no harm calling init again.
|
||||
InitJoysticks();
|
||||
|
||||
scroll = new QScrollArea(this);
|
||||
mainWidget = new QWidget();
|
||||
|
||||
portNum = 0;
|
||||
buttonConfigStatus = 1;
|
||||
|
||||
|
@ -98,6 +108,7 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent)
|
|||
hbox2 = new QHBoxLayout();
|
||||
hbox3 = new QHBoxLayout();
|
||||
hbox4 = new QHBoxLayout();
|
||||
hbox5 = new QHBoxLayout();
|
||||
|
||||
label = new QLabel(tr("Console Port:"));
|
||||
portSel = new QComboBox();
|
||||
|
@ -166,10 +177,12 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent)
|
|||
|
||||
applyProfileButton = new QPushButton( tr("Load") );
|
||||
applyProfileButton->setWhatsThis(tr("Sets Current Active Map to the Selected Profile"));
|
||||
applyProfileButton->setIcon( style->standardIcon( QStyle::SP_DialogApplyButton ) );
|
||||
hbox->addWidget( applyProfileButton );
|
||||
|
||||
saveProfileButton = new QPushButton( tr("Save") );
|
||||
saveProfileButton->setWhatsThis(tr("Stores Current Active Map to the Selected Profile"));
|
||||
saveProfileButton->setIcon( style->standardIcon( QStyle::SP_DialogSaveButton ) );
|
||||
hbox->addWidget( saveProfileButton );
|
||||
|
||||
hbox = new QHBoxLayout();
|
||||
|
@ -177,10 +190,12 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent)
|
|||
|
||||
newProfileButton = new QPushButton( tr("New") );
|
||||
newProfileButton->setWhatsThis(tr("Create a New Map Profile"));
|
||||
newProfileButton->setIcon( style->standardIcon( QStyle::SP_FileIcon ) );
|
||||
hbox->addWidget( newProfileButton );
|
||||
|
||||
removeProfileButton = new QPushButton( tr("Delete") );
|
||||
removeProfileButton->setWhatsThis(tr("Deletes the Selected Map Profile"));
|
||||
removeProfileButton->setIcon( style->standardIcon( QStyle::SP_TrashIcon ) );
|
||||
hbox->addWidget( removeProfileButton );
|
||||
|
||||
mapMsg = new QLabel();
|
||||
|
@ -234,6 +249,9 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent)
|
|||
clearAllButton = new QPushButton(tr("Clear All"));
|
||||
closebutton = new QPushButton(tr("Close"));
|
||||
|
||||
clearAllButton->setIcon( style->standardIcon( QStyle::SP_LineEditClearButton ) );
|
||||
closebutton->setIcon( style->standardIcon( QStyle::SP_DialogCloseButton ) );
|
||||
|
||||
hbox4->addWidget( clearAllButton );
|
||||
hbox4->addWidget( closebutton );
|
||||
|
||||
|
@ -272,18 +290,39 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent)
|
|||
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 = new QVBoxLayout();
|
||||
vbox1 = new QVBoxLayout();
|
||||
vbox2 = new QVBoxLayout();
|
||||
|
||||
mainLayout->addLayout( hbox1 );
|
||||
mainLayout->addLayout( hbox2 );
|
||||
mainLayout->addLayout( hbox3 );
|
||||
mainLayout->addWidget( frame1 );
|
||||
mainLayout->addWidget( efs_chkbox );
|
||||
mainLayout->addWidget( udlr_chkbox );
|
||||
mainLayout->addWidget( frame2 );
|
||||
mainLayout->addLayout( hbox4 );
|
||||
hbox5->addWidget( efs_chkbox );
|
||||
hbox5->addWidget( udlr_chkbox );
|
||||
|
||||
setLayout( mainLayout );
|
||||
vbox1->addLayout( hbox1 );
|
||||
vbox1->addLayout( hbox2 );
|
||||
vbox1->addLayout( hbox3 );
|
||||
vbox1->addWidget( frame1);
|
||||
vbox1->addLayout( hbox5 );
|
||||
|
||||
vbox2->addWidget( frame2 );
|
||||
vbox2->addLayout( hbox4 );
|
||||
|
||||
mainLayout->addLayout( vbox1 );
|
||||
mainLayout->addLayout( vbox2 );
|
||||
|
||||
mainWidget->setLayout( mainLayout );
|
||||
mainWidget->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
|
||||
|
||||
scroll->setWidget( mainWidget );
|
||||
scroll->setWidgetResizable(true);
|
||||
scroll->setSizeAdjustPolicy( QAbstractScrollArea::AdjustToContents );
|
||||
scroll->setHorizontalScrollBarPolicy( Qt::ScrollBarAsNeeded );
|
||||
scroll->setVerticalScrollBarPolicy( Qt::ScrollBarAsNeeded );
|
||||
|
||||
QHBoxLayout *dialogLayout = new QHBoxLayout();
|
||||
|
||||
dialogLayout->addWidget( scroll );
|
||||
|
||||
setLayout( dialogLayout );
|
||||
|
||||
inputTimer->start( 33 ); // 30hz
|
||||
|
||||
|
@ -881,6 +920,13 @@ void GamePadConfDialog_t::updatePeriodic(void)
|
|||
keyName[i]->setStyleSheet("color: black;");
|
||||
}
|
||||
}
|
||||
|
||||
int fourScore;
|
||||
g_config->getOption("SDL.FourScore", &fourScore);
|
||||
if ( fourScore != efs_chkbox->isChecked() )
|
||||
{
|
||||
efs_chkbox->setChecked( fourScore );
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------
|
||||
GamePadConfigButton_t::GamePadConfigButton_t(int i)
|
||||
|
|
|
@ -43,6 +43,7 @@ class GamePadConfDialog_t : public QDialog
|
|||
QComboBox *devSel;
|
||||
QComboBox *mapSel;
|
||||
QComboBox *profSel;
|
||||
QCheckBox *efs_chkbox;
|
||||
QLabel *guidLbl;
|
||||
QLabel *mapMsg;
|
||||
QLabel *keyName[GAMEPAD_NUM_BUTTONS];
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
#include <QHBoxLayout>
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QRadioButton>
|
||||
#include <QLabel>
|
||||
#include <QMenu>
|
||||
#include <QFrame>
|
||||
|
@ -113,8 +115,15 @@ class QHexEdit : public QWidget
|
|||
void setForeGroundColor( QColor fg );
|
||||
void setBackGroundColor( QColor bg );
|
||||
void memModeUpdate(void);
|
||||
void openGotoAddrDialog(void);
|
||||
int checkMemActivity(void);
|
||||
int getAddr(void){ return cursorAddr; };
|
||||
int FreezeRam( const char *name, uint32_t a, uint8_t v, int c, int s, int type );
|
||||
void loadHighlightToClipboard(void);
|
||||
void pasteFromClipboard(void);
|
||||
void clearHighlight(void);
|
||||
int findPattern( std::vector <unsigned char> &varray, int dir );
|
||||
void requestUpdate(void);
|
||||
|
||||
enum {
|
||||
MODE_NES_RAM = 0,
|
||||
|
@ -126,15 +135,22 @@ class QHexEdit : public QWidget
|
|||
protected:
|
||||
void paintEvent(QPaintEvent *event);
|
||||
void keyPressEvent(QKeyEvent *event);
|
||||
void keyReleaseEvent(QKeyEvent *event);
|
||||
void keyReleaseEvent(QKeyEvent *event);
|
||||
void mousePressEvent(QMouseEvent * event);
|
||||
void mouseReleaseEvent(QMouseEvent * event);
|
||||
void mouseMoveEvent(QMouseEvent * event);
|
||||
void wheelEvent(QWheelEvent *event);
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
void contextMenuEvent(QContextMenuEvent *event);
|
||||
|
||||
void calcFontData(void);
|
||||
void resetCursor(void);
|
||||
bool textIsHighlighted(void);
|
||||
void setHighlightEndCoord( int x, int y );
|
||||
QPoint convPixToCursor( QPoint p );
|
||||
int convPixToAddr( QPoint p );
|
||||
bool frzRamAddrValid( int addr );
|
||||
void loadClipboard( const char *txt );
|
||||
|
||||
QFont font;
|
||||
|
||||
|
@ -147,12 +163,13 @@ class QHexEdit : public QWidget
|
|||
QScrollBar *hbar;
|
||||
QColor highLightColor[ HIGHLIGHT_ACTIVITY_NUM_COLORS ];
|
||||
QColor rvActvTextColor[ HIGHLIGHT_ACTIVITY_NUM_COLORS ];
|
||||
QClipboard *clipboard;
|
||||
|
||||
HexEditorDialog_t *parent;
|
||||
|
||||
uint64_t total_instructions_lp;
|
||||
|
||||
int viewMode;
|
||||
int viewMode;
|
||||
int lineOffset;
|
||||
int pxCharWidth;
|
||||
int pxCharHeight;
|
||||
|
@ -172,16 +189,31 @@ class QHexEdit : public QWidget
|
|||
int viewLines;
|
||||
int viewWidth;
|
||||
int viewHeight;
|
||||
int maxLineOffset;
|
||||
int editAddr;
|
||||
int editValue;
|
||||
int editMask;
|
||||
int maxLineOffset;
|
||||
int editAddr;
|
||||
int editValue;
|
||||
int editMask;
|
||||
int jumpToRomValue;
|
||||
int ctxAddr;
|
||||
int frzRamAddr;
|
||||
int frzRamVal;
|
||||
int frzRamMode;
|
||||
int frzIdx;
|
||||
int wheelPixelCounter;
|
||||
int txtHlgtAnchorChar;
|
||||
int txtHlgtAnchorLine;
|
||||
int txtHlgtStartChar;
|
||||
int txtHlgtStartLine;
|
||||
int txtHlgtStartAddr;
|
||||
int txtHlgtEndChar;
|
||||
int txtHlgtEndLine;
|
||||
int txtHlgtEndAddr;
|
||||
|
||||
bool cursorBlink;
|
||||
bool reverseVideo;
|
||||
bool actvHighlightEnable;
|
||||
bool mouseLeftBtnDown;
|
||||
bool updateRequested;
|
||||
|
||||
private slots:
|
||||
void jumpToROM(void);
|
||||
|
@ -192,9 +224,35 @@ class QHexEdit : public QWidget
|
|||
void addRamExecuteBP(void);
|
||||
void addPpuReadBP(void);
|
||||
void addPpuWriteBP(void);
|
||||
void frzRamSet(void);
|
||||
void frzRamUnset(void);
|
||||
void frzRamToggle(void);
|
||||
void frzRamUnsetAll(void);
|
||||
|
||||
};
|
||||
|
||||
class HexEditorFindDialog_t : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HexEditorFindDialog_t(QWidget *parent = 0);
|
||||
~HexEditorFindDialog_t(void);
|
||||
|
||||
QLineEdit *searchBox;
|
||||
QRadioButton *upBtn;
|
||||
QRadioButton *dnBtn;
|
||||
QRadioButton *hexBtn;
|
||||
QRadioButton *txtBtn;
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *bar);
|
||||
|
||||
HexEditorDialog_t *parent;
|
||||
|
||||
public slots:
|
||||
void closeWindow(void);
|
||||
void runSearch(void);
|
||||
};
|
||||
|
||||
class HexEditorDialog_t : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -209,8 +267,9 @@ class HexEditorDialog_t : public QDialog
|
|||
void openDebugSymbolEditWindow( int addr );
|
||||
|
||||
QHexEdit *editor;
|
||||
protected:
|
||||
HexEditorFindDialog_t *findDialog;
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *bar);
|
||||
|
||||
QScrollBar *vbar;
|
||||
|
@ -221,11 +280,13 @@ class HexEditorDialog_t : public QDialog
|
|||
QAction *viewPPU;
|
||||
QAction *viewOAM;
|
||||
QAction *viewROM;
|
||||
QAction *gotoAddrAct;
|
||||
QAction *undoEditAct;
|
||||
|
||||
private:
|
||||
|
||||
public slots:
|
||||
void closeWindow(void);
|
||||
public slots:
|
||||
void closeWindow(void);
|
||||
private slots:
|
||||
void updatePeriodic(void);
|
||||
void vbarMoved(int value);
|
||||
|
@ -242,9 +303,16 @@ class HexEditorDialog_t : public QDialog
|
|||
void pickForeGroundColor(void);
|
||||
void pickBackGroundColor(void);
|
||||
void removeAllBookmarks(void);
|
||||
void openGotoAddrDialog(void);
|
||||
void copyToClipboard(void);
|
||||
void pasteFromClipboard(void);
|
||||
void openFindDialog(void);
|
||||
void undoRomPatch(void);
|
||||
};
|
||||
|
||||
int hexEditorNumWindows(void);
|
||||
void hexEditorRequestUpdateAll(void);
|
||||
void hexEditorUpdateMemoryValues(void);
|
||||
void hexEditorLoadBookmarks(void);
|
||||
void hexEditorSaveBookmarks(void);
|
||||
int hexEditorOpenFromDebugger( int mode, int addr );
|
||||
|
|
|
@ -24,7 +24,6 @@ HotKeyConfDialog_t::HotKeyConfDialog_t(QWidget *parent)
|
|||
QVBoxLayout *mainLayout;
|
||||
QTreeWidgetItem *item;
|
||||
std::string prefix = "SDL.Hotkeys.";
|
||||
int keycode;
|
||||
|
||||
setWindowTitle("Hotkey Configuration");
|
||||
|
||||
|
@ -48,14 +47,16 @@ HotKeyConfDialog_t::HotKeyConfDialog_t(QWidget *parent)
|
|||
|
||||
for (int i=0; i<HK_MAX; i++)
|
||||
{
|
||||
char keyName[128];
|
||||
std::string optionName = prefix + getHotkeyString(i);
|
||||
|
||||
g_config->getOption (optionName.c_str (), &keycode);
|
||||
//g_config->getOption (optionName.c_str (), &keycode);
|
||||
Hotkeys[i].getString( keyName );
|
||||
|
||||
item = new QTreeWidgetItem();
|
||||
|
||||
item->setText( 0, QString::fromStdString( optionName ) );
|
||||
item->setText( 1, QString::fromStdString( SDL_GetKeyName (keycode) ) );
|
||||
item->setText( 1, QString::fromStdString( keyName ) );
|
||||
|
||||
item->setTextAlignment( 0, Qt::AlignLeft);
|
||||
item->setTextAlignment( 1, Qt::AlignCenter);
|
||||
|
@ -89,9 +90,17 @@ void HotKeyConfDialog_t::closeWindow(void)
|
|||
//----------------------------------------------------------------------------
|
||||
void HotKeyConfDialog_t::assignHotkey(QKeyEvent *event)
|
||||
{
|
||||
bool keyIsModifier;
|
||||
SDL_Keycode k = convQtKey2SDLKeyCode( (Qt::Key)event->key() );
|
||||
SDL_Keymod m = convQtKey2SDLModifier( event->modifiers() );
|
||||
|
||||
if ( k != SDLK_UNKNOWN )
|
||||
keyIsModifier = (k == SDLK_LCTRL ) || (k == SDLK_RCTRL ) ||
|
||||
(k == SDLK_LSHIFT) || (k == SDLK_RSHIFT) ||
|
||||
(k == SDLK_LALT ) || (k == SDLK_RALT ) ||
|
||||
(k == SDLK_LGUI ) || (k == SDLK_RGUI ) ||
|
||||
(k == SDLK_CAPSLOCK);
|
||||
|
||||
if ( (k != SDLK_UNKNOWN) && !keyIsModifier )
|
||||
{
|
||||
QList <QTreeWidgetItem *> l;
|
||||
|
||||
|
@ -99,21 +108,59 @@ void HotKeyConfDialog_t::assignHotkey(QKeyEvent *event)
|
|||
|
||||
for (size_t i=0; i < l.size(); i++)
|
||||
{
|
||||
//int idx;
|
||||
int j,idx;
|
||||
QString qs;
|
||||
QTreeWidgetItem *item;
|
||||
std::string keyText;
|
||||
char keyName[128];
|
||||
char buf[256];
|
||||
|
||||
|
||||
keyText.assign(" mod=");
|
||||
|
||||
j=0;
|
||||
if ( m & (KMOD_LSHIFT | KMOD_RSHIFT) )
|
||||
{
|
||||
if ( j > 0 )
|
||||
{
|
||||
keyText.append("+");
|
||||
}
|
||||
keyText.append("Shift"); j++;
|
||||
}
|
||||
if ( m & (KMOD_LALT | KMOD_RALT) )
|
||||
{
|
||||
if ( j > 0 )
|
||||
{
|
||||
keyText.append("+");
|
||||
}
|
||||
keyText.append("Alt"); j++;
|
||||
}
|
||||
if ( m & (KMOD_LCTRL | KMOD_RCTRL) )
|
||||
{
|
||||
if ( j > 0 )
|
||||
{
|
||||
keyText.append("+");
|
||||
}
|
||||
keyText.append("Ctrl"); j++;
|
||||
}
|
||||
|
||||
sprintf( buf, " key=%s", SDL_GetKeyName( k ) );
|
||||
|
||||
keyText.append( buf );
|
||||
|
||||
item = l.at(i);
|
||||
|
||||
//idx = tree->indexOfTopLevelItem( item );
|
||||
idx = tree->indexOfTopLevelItem( item );
|
||||
|
||||
qs = item->text(0);
|
||||
|
||||
g_config->setOption ( qs.toStdString(), k );
|
||||
g_config->setOption ( qs.toStdString(), keyText );
|
||||
|
||||
setHotKeys();
|
||||
|
||||
item->setText( 1, QString::fromStdString( SDL_GetKeyName (k) ) );
|
||||
Hotkeys[idx].getString( keyName );
|
||||
|
||||
item->setText( 1, QString::fromStdString( keyName ) );
|
||||
|
||||
//printf("Hotkey Window Key Press: 0x%x item:%p\n '%s' : %i\n",
|
||||
// k, item, qs.toStdString().c_str(), idx );
|
||||
|
|
|
@ -0,0 +1,562 @@
|
|||
// InputConf.cpp
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#include <SDL.h>
|
||||
#include <QHeaderView>
|
||||
#include <QCloseEvent>
|
||||
#include <QFileDialog>
|
||||
#include <QGroupBox>
|
||||
|
||||
#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/ConsoleWindow.h"
|
||||
#include "Qt/ConsoleUtilities.h"
|
||||
#include "Qt/InputConf.h"
|
||||
|
||||
static InputConfDialog_t *win = NULL;
|
||||
//----------------------------------------------------------------------------
|
||||
void openInputConfWindow( QWidget *parent )
|
||||
{
|
||||
if ( win != NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
win = new InputConfDialog_t(parent);
|
||||
|
||||
win->show();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
InputConfDialog_t::InputConfDialog_t(QWidget *parent)
|
||||
: QDialog( parent )
|
||||
{
|
||||
QVBoxLayout *mainLayout, *vbox1, *vbox;
|
||||
QHBoxLayout *hbox;
|
||||
QGroupBox *nesInputFrame, *port1Frame, *port2Frame;
|
||||
QGroupBox *presetFrame, *expansionPortFrame;
|
||||
QPalette pal;
|
||||
QColor color;
|
||||
char stmp[256];
|
||||
int fourscore, autoInputPreset;
|
||||
|
||||
pal = this->palette();
|
||||
|
||||
inputTimer = new QTimer( this );
|
||||
|
||||
connect( inputTimer, &QTimer::timeout, this, &InputConfDialog_t::updatePeriodic );
|
||||
|
||||
setWindowTitle("Input Configuration");
|
||||
|
||||
mainLayout = new QVBoxLayout();
|
||||
|
||||
nesInputFrame = new QGroupBox( tr("NES-Style Input Ports") );
|
||||
vbox1 = new QVBoxLayout();
|
||||
hbox = new QHBoxLayout();
|
||||
fourScoreEna = new QCheckBox( tr("Attach 4-Score (Implies four gamepads)") );
|
||||
port2Mic = new QCheckBox( tr("Replace Port 2 Start with Microphone") );
|
||||
autoPreset = new QCheckBox( tr("Auto Load/Save Presets at ROM Open/Close") );
|
||||
|
||||
g_config->getOption("SDL.FourScore", &fourscore);
|
||||
fourScoreEna->setChecked( fourscore );
|
||||
port2Mic->setChecked( replaceP2StartWithMicrophone );
|
||||
|
||||
g_config->getOption( "SDL.AutoInputPreset", &autoInputPreset );
|
||||
autoPreset->setChecked( autoInputPreset );
|
||||
|
||||
hbox->addWidget( fourScoreEna );
|
||||
hbox->addWidget( port2Mic );
|
||||
vbox1->addLayout( hbox );
|
||||
|
||||
hbox = new QHBoxLayout();
|
||||
port1Frame = new QGroupBox( tr("Port 1:") );
|
||||
port2Frame = new QGroupBox( tr("Port 2:") );
|
||||
|
||||
hbox->addWidget( port1Frame );
|
||||
hbox->addWidget( port2Frame );
|
||||
vbox1->addLayout( hbox );
|
||||
|
||||
nesPortComboxBox[0] = new QComboBox();
|
||||
nesPortComboxBox[1] = new QComboBox();
|
||||
expPortComboxBox = new QComboBox();
|
||||
|
||||
vbox = new QVBoxLayout();
|
||||
hbox = new QHBoxLayout();
|
||||
|
||||
vbox->addLayout( hbox );
|
||||
hbox->addWidget( nesPortLabel[0] = new QLabel( tr("<None>") ) );
|
||||
hbox->addWidget( nesPortConfButton[0] = new QPushButton( tr("Configure") ) );
|
||||
vbox->addWidget( nesPortComboxBox[0] );
|
||||
|
||||
port1Frame->setLayout( vbox );
|
||||
|
||||
vbox = new QVBoxLayout();
|
||||
hbox = new QHBoxLayout();
|
||||
|
||||
vbox->addLayout( hbox );
|
||||
hbox->addWidget( nesPortLabel[1] = new QLabel( tr("<None>") ) );
|
||||
hbox->addWidget( nesPortConfButton[1] = new QPushButton( tr("Configure") ) );
|
||||
vbox->addWidget( nesPortComboxBox[1] );
|
||||
|
||||
port2Frame->setLayout( vbox );
|
||||
|
||||
nesInputFrame->setLayout( vbox1 );
|
||||
nesPortConfButton[0]->setEnabled(false);
|
||||
nesPortConfButton[1]->setEnabled(false);
|
||||
|
||||
mainLayout->addWidget( nesInputFrame );
|
||||
|
||||
hbox = new QHBoxLayout();
|
||||
presetFrame = new QGroupBox( tr("Input Presets:") );
|
||||
expansionPortFrame = new QGroupBox( tr("Famicom Expansion Port:") );
|
||||
|
||||
hbox->addWidget( presetFrame );
|
||||
hbox->addWidget( expansionPortFrame );
|
||||
|
||||
mainLayout->addLayout( hbox );
|
||||
|
||||
vbox = new QVBoxLayout();
|
||||
hbox = new QHBoxLayout();
|
||||
vbox->addLayout( hbox );
|
||||
hbox->addWidget( autoPreset );
|
||||
|
||||
hbox = new QHBoxLayout();
|
||||
vbox->addLayout( hbox );
|
||||
hbox->addWidget( loadConfigButton = new QPushButton( tr("Load") ) );
|
||||
hbox->addWidget( saveConfigButton = new QPushButton( tr("Save") ) );
|
||||
|
||||
presetFrame->setLayout( vbox );
|
||||
|
||||
vbox = new QVBoxLayout();
|
||||
hbox = new QHBoxLayout();
|
||||
|
||||
vbox->addLayout( hbox );
|
||||
hbox->addWidget( expPortLabel = new QLabel( tr("<None>") ) );
|
||||
hbox->addWidget( expPortConfButton = new QPushButton( tr("Configure") ) );
|
||||
vbox->addWidget( expPortComboxBox );
|
||||
|
||||
expPortConfButton->setEnabled(false);
|
||||
expansionPortFrame->setLayout( vbox );
|
||||
|
||||
color = pal.color(QPalette::WindowText);
|
||||
|
||||
sprintf( stmp, "border: 2px solid #%02X%02X%02X", color.red(), color.green(), color.blue() );
|
||||
|
||||
//printf("%s\n", stmp);
|
||||
nesPortLabel[0]->setAlignment(Qt::AlignCenter);
|
||||
nesPortLabel[1]->setAlignment(Qt::AlignCenter);
|
||||
expPortLabel->setAlignment(Qt::AlignCenter);
|
||||
nesPortLabel[0]->setStyleSheet( stmp );
|
||||
nesPortLabel[1]->setStyleSheet( stmp );
|
||||
expPortLabel->setStyleSheet( stmp );
|
||||
|
||||
setLayout( mainLayout );
|
||||
|
||||
for (int i=0; i<2; i++)
|
||||
{
|
||||
getInputSelection( i, &curNesInput[i], &usrNesInput[i] );
|
||||
nesPortComboxBox[i]->addItem( tr("<None>") , SI_NONE );
|
||||
nesPortComboxBox[i]->addItem( tr("Gamepad") , SI_GAMEPAD );
|
||||
nesPortComboxBox[i]->addItem( tr("Zapper") , SI_ZAPPER );
|
||||
nesPortComboxBox[i]->addItem( tr("Power Pad A") , SI_POWERPADA );
|
||||
nesPortComboxBox[i]->addItem( tr("Power Pad B") , SI_POWERPADB );
|
||||
nesPortComboxBox[i]->addItem( tr("Arkanoid Paddle") , SI_ARKANOID );
|
||||
|
||||
for (int j=0; j<nesPortComboxBox[i]->count(); j++)
|
||||
{
|
||||
if ( nesPortComboxBox[i]->itemData(j).toInt() == curNesInput[i] )
|
||||
{
|
||||
nesPortComboxBox[i]->setCurrentIndex( j );
|
||||
}
|
||||
if ( nesPortComboxBox[i]->itemData(j).toInt() == curNesInput[i] )
|
||||
{
|
||||
nesPortLabel[i]->setText( nesPortComboxBox[i]->itemText(j) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getInputSelection( 2, &curNesInput[2], &usrNesInput[2] );
|
||||
expPortComboxBox->addItem( tr("<None>") , SIFC_NONE );
|
||||
expPortComboxBox->addItem( tr("Arkanoid Paddle") , SIFC_ARKANOID );
|
||||
expPortComboxBox->addItem( tr("Shadow") , SIFC_SHADOW );
|
||||
expPortComboxBox->addItem( tr("Hyper Shot Gun") , SIFC_HYPERSHOT );
|
||||
expPortComboxBox->addItem( tr("Family Keyboard") , SIFC_FKB );
|
||||
expPortComboxBox->addItem( tr("Mahjong") , SIFC_MAHJONG );
|
||||
expPortComboxBox->addItem( tr("Quiz King Buzzers"), SIFC_QUIZKING );
|
||||
expPortComboxBox->addItem( tr("Family Trainer A") , SIFC_FTRAINERA );
|
||||
expPortComboxBox->addItem( tr("Family Trainer B") , SIFC_FTRAINERB );
|
||||
expPortComboxBox->addItem( tr("Oeka Kids Tablet") , SIFC_OEKAKIDS );
|
||||
expPortComboxBox->addItem( tr("Top Rider") , SIFC_TOPRIDER );
|
||||
|
||||
for (int j=0; j<expPortComboxBox->count(); j++)
|
||||
{
|
||||
if ( expPortComboxBox->itemData(j).toInt() == curNesInput[2] )
|
||||
{
|
||||
expPortComboxBox->setCurrentIndex( j );
|
||||
}
|
||||
if ( expPortComboxBox->itemData(j).toInt() == curNesInput[2] )
|
||||
{
|
||||
expPortLabel->setText( expPortComboxBox->itemText(j) );
|
||||
}
|
||||
}
|
||||
|
||||
connect( fourScoreEna, SIGNAL(stateChanged(int)), this, SLOT(fourScoreChanged(int)) );
|
||||
connect( port2Mic , SIGNAL(stateChanged(int)), this, SLOT(port2MicChanged(int)) );
|
||||
connect( autoPreset , SIGNAL(stateChanged(int)), this, SLOT(autoPresetChanged(int)));
|
||||
|
||||
connect( nesPortComboxBox[0], SIGNAL(activated(int)), this, SLOT(port1Select(int)) );
|
||||
connect( nesPortComboxBox[1], SIGNAL(activated(int)), this, SLOT(port2Select(int)) );
|
||||
connect( expPortComboxBox , SIGNAL(activated(int)), this, SLOT(expSelect(int)) );
|
||||
|
||||
connect( nesPortConfButton[0], SIGNAL(clicked(void)), this, SLOT(port1Configure(void)) );
|
||||
connect( nesPortConfButton[1], SIGNAL(clicked(void)), this, SLOT(port2Configure(void)) );
|
||||
|
||||
connect( loadConfigButton, SIGNAL(clicked(void)), this, SLOT(openLoadPresetFile(void)) );
|
||||
connect( saveConfigButton, SIGNAL(clicked(void)), this, SLOT(openSavePresetFile(void)) );
|
||||
|
||||
updatePortLabels();
|
||||
|
||||
inputTimer->start( 500 ); // 2hz
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
InputConfDialog_t::~InputConfDialog_t(void)
|
||||
{
|
||||
printf("Destroy Input Config Window\n");
|
||||
inputTimer->stop();
|
||||
|
||||
if ( win == this )
|
||||
{
|
||||
win = NULL;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void InputConfDialog_t::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
printf("Input Config Close Window Event\n");
|
||||
done(0);
|
||||
deleteLater();
|
||||
event->accept();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void InputConfDialog_t::closeWindow(void)
|
||||
{
|
||||
//printf("Close Window\n");
|
||||
done(0);
|
||||
deleteLater();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void InputConfDialog_t::setInputs(void)
|
||||
{
|
||||
int idx[3];
|
||||
ESI port[2];
|
||||
ESIFC fcexp;
|
||||
int fourscore = false, microphone = false;
|
||||
|
||||
g_config->getOption("SDL.FourScore", &fourscore);
|
||||
|
||||
microphone = port2Mic->isChecked();
|
||||
|
||||
idx[0] = nesPortComboxBox[0]->currentIndex();
|
||||
idx[1] = nesPortComboxBox[1]->currentIndex();
|
||||
idx[2] = expPortComboxBox->currentIndex();
|
||||
|
||||
port[0] = (ESI)nesPortComboxBox[0]->itemData( idx[0] ).toInt();
|
||||
port[1] = (ESI)nesPortComboxBox[1]->itemData( idx[1] ).toInt();
|
||||
fcexp = (ESIFC)expPortComboxBox->itemData( idx[2] ).toInt();
|
||||
|
||||
FCEUD_SetInput( fourscore, microphone, port[0], port[1], fcexp );
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void InputConfDialog_t::updatePortLabels(void)
|
||||
{
|
||||
|
||||
for (int i=0; i<2; i++)
|
||||
{
|
||||
getInputSelection( i, &curNesInput[i], &usrNesInput[i] );
|
||||
|
||||
for (int j=0; j<nesPortComboxBox[i]->count(); j++)
|
||||
{
|
||||
if ( nesPortComboxBox[i]->itemData(j).toInt() == curNesInput[i] )
|
||||
{
|
||||
nesPortLabel[i]->setText( nesPortComboxBox[i]->itemText(j) );
|
||||
}
|
||||
}
|
||||
|
||||
nesPortConfButton[i]->setEnabled( curNesInput[i] == SI_GAMEPAD );
|
||||
}
|
||||
|
||||
getInputSelection( 2, &curNesInput[2], &usrNesInput[2] );
|
||||
|
||||
for (int j=0; j<expPortComboxBox->count(); j++)
|
||||
{
|
||||
if ( expPortComboxBox->itemData(j).toInt() == curNesInput[2] )
|
||||
{
|
||||
expPortLabel->setText( expPortComboxBox->itemText(j) );
|
||||
}
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void InputConfDialog_t::updatePortComboBoxes(void)
|
||||
{
|
||||
for (int i=0; i<2; i++)
|
||||
{
|
||||
getInputSelection( i, &curNesInput[i], &usrNesInput[i] );
|
||||
|
||||
for (int j=0; j<nesPortComboxBox[i]->count(); j++)
|
||||
{
|
||||
if ( nesPortComboxBox[i]->itemData(j).toInt() == curNesInput[i] )
|
||||
{
|
||||
nesPortComboxBox[i]->setCurrentIndex( j );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getInputSelection( 2, &curNesInput[2], &usrNesInput[2] );
|
||||
|
||||
for (int j=0; j<expPortComboxBox->count(); j++)
|
||||
{
|
||||
if ( expPortComboxBox->itemData(j).toInt() == curNesInput[2] )
|
||||
{
|
||||
expPortComboxBox->setCurrentIndex( j );
|
||||
}
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void InputConfDialog_t::port1Select(int index)
|
||||
{
|
||||
//printf("Port 1 Number:%i \n", index);
|
||||
setInputs();
|
||||
updatePortLabels();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void InputConfDialog_t::port2Select(int index)
|
||||
{
|
||||
//printf("Port 2 Number:%i \n", index);
|
||||
setInputs();
|
||||
updatePortLabels();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void InputConfDialog_t::expSelect(int index)
|
||||
{
|
||||
//printf("Expansion Port Number:%i \n", index);
|
||||
setInputs();
|
||||
updatePortLabels();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void InputConfDialog_t::fourScoreChanged(int state)
|
||||
{
|
||||
int value = (state == Qt::Unchecked) ? 0 : 1;
|
||||
printf("Set 'SDL.FourScore' = %i\n", value);
|
||||
g_config->setOption("SDL.FourScore", value);
|
||||
|
||||
setInputs();
|
||||
updatePortLabels();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void InputConfDialog_t::port2MicChanged(int state)
|
||||
{
|
||||
setInputs();
|
||||
updatePortLabels();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void InputConfDialog_t::autoPresetChanged(int state)
|
||||
{
|
||||
int value = (state == Qt::Unchecked) ? 0 : 1;
|
||||
//printf("Set 'SDL.AutoInputPreset' = %i\n", value);
|
||||
g_config->setOption("SDL.AutoInputPreset", value);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void InputConfDialog_t::openPortConfig(int portNum)
|
||||
{
|
||||
updatePortLabels();
|
||||
|
||||
switch ( curNesInput[portNum] )
|
||||
{
|
||||
default:
|
||||
case SI_NONE:
|
||||
case SI_ZAPPER:
|
||||
// Do Nothing
|
||||
break;
|
||||
case SI_GAMEPAD:
|
||||
consoleWindow->openGamePadConfWin();
|
||||
break;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void InputConfDialog_t::port1Configure(void)
|
||||
{
|
||||
openPortConfig(0);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void InputConfDialog_t::port2Configure(void)
|
||||
{
|
||||
openPortConfig(1);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void InputConfDialog_t::openLoadPresetFile(void)
|
||||
{
|
||||
int ret, useNativeFileDialogVal;
|
||||
QString filename;
|
||||
std::string last;
|
||||
std::string path;
|
||||
const char *baseDir;
|
||||
QFileDialog dialog(this, tr("Load Preset From File") );
|
||||
QDir dir;
|
||||
|
||||
baseDir = FCEUI_GetBaseDirectory();
|
||||
|
||||
path = std::string(baseDir) + "/input/presets/";
|
||||
|
||||
dir.mkpath( QString::fromStdString(path) );
|
||||
|
||||
dialog.setFileMode(QFileDialog::ExistingFile);
|
||||
|
||||
dialog.setNameFilter(tr("Preset File (*.pre *.PRE) ;; All files (*)"));
|
||||
|
||||
dialog.setViewMode(QFileDialog::List);
|
||||
dialog.setFilter( QDir::AllEntries | QDir::AllDirs | QDir::Hidden );
|
||||
dialog.setLabelText( QFileDialog::Accept, tr("Load") );
|
||||
|
||||
dialog.setDirectory( tr(path.c_str()) );
|
||||
|
||||
// Check config option to use native file dialog or not
|
||||
g_config->getOption ("SDL.UseNativeFileDialog", &useNativeFileDialogVal);
|
||||
|
||||
dialog.setOption(QFileDialog::DontUseNativeDialog, !useNativeFileDialogVal);
|
||||
|
||||
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();
|
||||
|
||||
fceuWrapperLock();
|
||||
loadInputSettingsFromFile( filename.toStdString().c_str() );
|
||||
fceuWrapperUnLock();
|
||||
|
||||
updatePortLabels();
|
||||
updatePortComboBoxes();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void InputConfDialog_t::openSavePresetFile(void)
|
||||
{
|
||||
int ret, useNativeFileDialogVal;
|
||||
QString filename;
|
||||
std::string path;
|
||||
const char *baseDir, *romFile;
|
||||
QFileDialog dialog(this, tr("Save Preset to File") );
|
||||
QDir dir;
|
||||
|
||||
baseDir = FCEUI_GetBaseDirectory();
|
||||
|
||||
path = std::string(baseDir) + "/input/presets/";
|
||||
|
||||
dir.mkpath( QString::fromStdString(path) );
|
||||
|
||||
dialog.setFileMode(QFileDialog::AnyFile);
|
||||
|
||||
dialog.setNameFilter(tr("Preset Files (*.pre *.PRE) ;; All files (*)"));
|
||||
|
||||
dialog.setViewMode(QFileDialog::List);
|
||||
dialog.setFilter( QDir::AllEntries | QDir::AllDirs | QDir::Hidden );
|
||||
dialog.setLabelText( QFileDialog::Accept, tr("Save") );
|
||||
dialog.setDefaultSuffix( tr(".pre") );
|
||||
|
||||
romFile = getRomFile();
|
||||
|
||||
if ( romFile != NULL )
|
||||
{
|
||||
char dirStr[256], base[256];
|
||||
|
||||
parseFilepath( romFile, dirStr, base );
|
||||
|
||||
strcat( base, ".pre");
|
||||
|
||||
dialog.selectFile( tr(base) );
|
||||
}
|
||||
|
||||
dialog.setDirectory( tr(path.c_str()) );
|
||||
|
||||
// Check config option to use native file dialog or not
|
||||
g_config->getOption ("SDL.UseNativeFileDialog", &useNativeFileDialogVal);
|
||||
|
||||
dialog.setOption(QFileDialog::DontUseNativeDialog, !useNativeFileDialogVal);
|
||||
|
||||
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();
|
||||
|
||||
saveInputSettingsToFile( filename.toStdString().c_str() );
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void InputConfDialog_t::updatePeriodic(void)
|
||||
{
|
||||
bool updateNeeded = false;
|
||||
int tmpCurInputType[3], tmpUsrInputType[3];
|
||||
int fourScoreValue;
|
||||
|
||||
for (int i=0; i<3; i++)
|
||||
{
|
||||
getInputSelection( i, &tmpCurInputType[i], &tmpUsrInputType[i] );
|
||||
|
||||
if ( curNesInput[i] != tmpCurInputType[i] )
|
||||
{
|
||||
updateNeeded = true;
|
||||
}
|
||||
if ( usrNesInput[i] != tmpUsrInputType[i] )
|
||||
{
|
||||
updateNeeded = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( updateNeeded )
|
||||
{
|
||||
updatePortLabels();
|
||||
updatePortComboBoxes();
|
||||
}
|
||||
|
||||
g_config->getOption("SDL.FourScore", &fourScoreValue);
|
||||
|
||||
if ( fourScoreValue != fourScoreEna->isChecked() )
|
||||
{
|
||||
fourScoreEna->setChecked( fourScoreValue );
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
|
@ -0,0 +1,73 @@
|
|||
// InputConf.h
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDialog>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
#include <QLineEdit>
|
||||
#include <QLabel>
|
||||
#include <QFrame>
|
||||
#include <QGroupBox>
|
||||
#include <QTreeView>
|
||||
#include <QTreeWidget>
|
||||
#include <QTimer>
|
||||
|
||||
#include "Qt/main.h"
|
||||
|
||||
class InputConfDialog_t : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
InputConfDialog_t(QWidget *parent = 0);
|
||||
~InputConfDialog_t(void);
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event);
|
||||
|
||||
QTimer *inputTimer;
|
||||
QCheckBox *fourScoreEna;
|
||||
QCheckBox *port2Mic;
|
||||
QCheckBox *autoPreset;
|
||||
QLabel *nesPortLabel[2];
|
||||
QPushButton *nesPortConfButton[2];
|
||||
QComboBox *nesPortComboxBox[2];
|
||||
QLabel *expPortLabel;
|
||||
QPushButton *expPortConfButton;
|
||||
QComboBox *expPortComboxBox;
|
||||
QPushButton *loadConfigButton;
|
||||
QPushButton *saveConfigButton;
|
||||
|
||||
int curNesInput[3];
|
||||
int usrNesInput[3];
|
||||
|
||||
private:
|
||||
void setInputs(void);
|
||||
void updatePortLabels(void);
|
||||
void updatePortComboBoxes(void);
|
||||
void openPortConfig(int portNum);
|
||||
|
||||
public slots:
|
||||
void closeWindow(void);
|
||||
private slots:
|
||||
void port1Configure(void);
|
||||
void port2Configure(void);
|
||||
void port1Select(int index);
|
||||
void port2Select(int index);
|
||||
void expSelect(int index);
|
||||
void fourScoreChanged(int state);
|
||||
void port2MicChanged(int state);
|
||||
void autoPresetChanged(int state);
|
||||
void openLoadPresetFile(void);
|
||||
void openSavePresetFile(void);
|
||||
void updatePeriodic(void);
|
||||
|
||||
};
|
||||
|
||||
void openInputConfWindow( QWidget *parent );
|
|
@ -1,9 +1,12 @@
|
|||
// LuaControl.cpp
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <list>
|
||||
|
||||
#include <QTextEdit>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "../../fceu.h"
|
||||
|
||||
|
@ -20,12 +23,64 @@
|
|||
#include "Qt/ConsoleUtilities.h"
|
||||
|
||||
static bool luaScriptRunning = false;
|
||||
static bool updateLuaDisplay = false;
|
||||
static bool openLuaKillMsgBox = false;
|
||||
static int luaKillMsgBoxRetVal = 0;
|
||||
|
||||
struct luaConsoleOutputBuffer
|
||||
{
|
||||
int head;
|
||||
int tail;
|
||||
int size;
|
||||
char *buf;
|
||||
|
||||
luaConsoleOutputBuffer(void)
|
||||
{
|
||||
tail = head = 0;
|
||||
size = 4096;
|
||||
|
||||
buf = (char*)malloc(size);
|
||||
}
|
||||
|
||||
~luaConsoleOutputBuffer(void)
|
||||
{
|
||||
if ( buf )
|
||||
{
|
||||
free(buf); buf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void addLine( const char *l )
|
||||
{
|
||||
int i=0;
|
||||
//printf("Adding Line %i: '%s'\n", head, l );
|
||||
while ( l[i] != 0 )
|
||||
{
|
||||
buf[head] = l[i]; i++;
|
||||
|
||||
head = (head + 1) % size;
|
||||
|
||||
if ( head == tail )
|
||||
{
|
||||
tail = (tail + 1) % size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
tail = head = 0;
|
||||
}
|
||||
};
|
||||
|
||||
static luaConsoleOutputBuffer outBuf;
|
||||
|
||||
static std::string luaOutputText;
|
||||
static std::list <LuaControlDialog_t*> winList;
|
||||
|
||||
static void updateLuaWindows( void );
|
||||
//----------------------------------------------------
|
||||
LuaControlDialog_t::LuaControlDialog_t(QWidget *parent)
|
||||
: QDialog( parent )
|
||||
: QDialog( parent, Qt::Window )
|
||||
{
|
||||
QVBoxLayout *mainLayout;
|
||||
QHBoxLayout *hbox;
|
||||
|
@ -95,6 +150,12 @@ LuaControlDialog_t::LuaControlDialog_t(QWidget *parent)
|
|||
setLayout( mainLayout );
|
||||
|
||||
winList.push_back( this );
|
||||
|
||||
periodicTimer = new QTimer( this );
|
||||
|
||||
connect( periodicTimer, &QTimer::timeout, this, &LuaControlDialog_t::updatePeriodic );
|
||||
|
||||
periodicTimer->start( 200 ); // 5hz
|
||||
}
|
||||
|
||||
//----------------------------------------------------
|
||||
|
@ -104,6 +165,8 @@ LuaControlDialog_t::~LuaControlDialog_t(void)
|
|||
|
||||
printf("Destroy Lua Control Window\n");
|
||||
|
||||
periodicTimer->stop();
|
||||
|
||||
for (it = winList.begin(); it != winList.end(); it++)
|
||||
{
|
||||
if ( (*it) == this )
|
||||
|
@ -130,6 +193,43 @@ void LuaControlDialog_t::closeWindow(void)
|
|||
deleteLater();
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void LuaControlDialog_t::updatePeriodic(void)
|
||||
{
|
||||
//printf("Update Lua\n");
|
||||
if ( updateLuaDisplay )
|
||||
{
|
||||
updateLuaWindows();
|
||||
updateLuaDisplay = false;
|
||||
}
|
||||
|
||||
if ( openLuaKillMsgBox )
|
||||
{
|
||||
openLuaKillMessageBox();
|
||||
openLuaKillMsgBox = false;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void LuaControlDialog_t::openLuaKillMessageBox(void)
|
||||
{
|
||||
int ret;
|
||||
QMessageBox msgBox(this);
|
||||
|
||||
luaKillMsgBoxRetVal = 0;
|
||||
|
||||
msgBox.setIcon( QMessageBox::Warning );
|
||||
msgBox.setText( tr("The Lua script running has been running a long time.\nIt may have gone crazy. Kill it? (I won't ask again if you say No)\n") );
|
||||
msgBox.setStandardButtons(QMessageBox::Yes);
|
||||
msgBox.addButton(QMessageBox::No);
|
||||
msgBox.setDefaultButton(QMessageBox::No);
|
||||
|
||||
ret = msgBox.exec();
|
||||
|
||||
if ( ret == QMessageBox::Yes )
|
||||
{
|
||||
luaKillMsgBoxRetVal = 1;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void LuaControlDialog_t::openLuaScriptFile(void)
|
||||
{
|
||||
#ifdef _S9XLUA_H
|
||||
|
@ -144,7 +244,7 @@ void LuaControlDialog_t::openLuaScriptFile(void)
|
|||
dialog.setNameFilter(tr("LUA Scripts (*.lua *.LUA) ;; All files (*)"));
|
||||
|
||||
dialog.setViewMode(QFileDialog::List);
|
||||
dialog.setFilter( QDir::AllEntries | QDir::Hidden );
|
||||
dialog.setFilter( QDir::AllEntries | QDir::AllDirs | QDir::Hidden );
|
||||
dialog.setLabelText( QFileDialog::Accept, tr("Load") );
|
||||
|
||||
g_config->getOption ("SDL.LastLoadLua", &last );
|
||||
|
@ -193,7 +293,7 @@ void LuaControlDialog_t::openLuaScriptFile(void)
|
|||
void LuaControlDialog_t::startLuaScript(void)
|
||||
{
|
||||
#ifdef _S9XLUA_H
|
||||
luaOutputText.clear();
|
||||
outBuf.clear();
|
||||
fceuWrapperLock();
|
||||
if ( 0 == FCEU_LoadLuaCode( scriptPath->text().toStdString().c_str(), scriptArgs->text().toStdString().c_str() ) )
|
||||
{
|
||||
|
@ -214,6 +314,9 @@ void LuaControlDialog_t::stopLuaScript(void)
|
|||
//----------------------------------------------------
|
||||
void LuaControlDialog_t::refreshState(void)
|
||||
{
|
||||
int i;
|
||||
std::string luaOutputText;
|
||||
|
||||
if ( luaScriptRunning )
|
||||
{
|
||||
stopButton->setEnabled( true );
|
||||
|
@ -224,10 +327,22 @@ void LuaControlDialog_t::refreshState(void)
|
|||
stopButton->setEnabled( false );
|
||||
startButton->setText( tr("Start") );
|
||||
}
|
||||
|
||||
i = outBuf.tail;
|
||||
|
||||
while ( i != outBuf.head )
|
||||
{
|
||||
luaOutputText.append( 1, outBuf.buf[i] );
|
||||
|
||||
i = (i + 1) % outBuf.size;
|
||||
}
|
||||
|
||||
luaOutput->setText( luaOutputText.c_str() );
|
||||
|
||||
luaOutput->moveCursor( QTextCursor::End );
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void updateLuaWindows( void )
|
||||
static void updateLuaWindows( void )
|
||||
{
|
||||
std::list <LuaControlDialog_t*>::iterator it;
|
||||
|
||||
|
@ -243,7 +358,7 @@ void WinLuaOnStart(intptr_t hDlgAsInt)
|
|||
|
||||
//printf("Lua Script Running: %i \n", luaScriptRunning );
|
||||
|
||||
updateLuaWindows();
|
||||
updateLuaDisplay = true;
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void WinLuaOnStop(intptr_t hDlgAsInt)
|
||||
|
@ -252,15 +367,52 @@ void WinLuaOnStop(intptr_t hDlgAsInt)
|
|||
|
||||
//printf("Lua Script Running: %i \n", luaScriptRunning );
|
||||
|
||||
updateLuaWindows();
|
||||
updateLuaDisplay = true;
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void PrintToWindowConsole(intptr_t hDlgAsInt, const char* str)
|
||||
{
|
||||
//printf("%s\n", str );
|
||||
|
||||
luaOutputText.append( str );
|
||||
outBuf.addLine( str );
|
||||
|
||||
updateLuaWindows();
|
||||
updateLuaDisplay = true;
|
||||
}
|
||||
//----------------------------------------------------
|
||||
#ifdef WIN32
|
||||
int LuaPrintfToWindowConsole(_In_z_ _Printf_format_string_ const char* const format, ...)
|
||||
#else
|
||||
int LuaPrintfToWindowConsole(const char *__restrict format, ...) throw()
|
||||
#endif
|
||||
{
|
||||
int retval;
|
||||
va_list args;
|
||||
char msg[2048];
|
||||
va_start( args, format );
|
||||
retval = ::vsnprintf( msg, sizeof(msg), format, args );
|
||||
va_end(args);
|
||||
|
||||
msg[ sizeof(msg)-1 ] = 0;
|
||||
|
||||
outBuf.addLine( msg );
|
||||
|
||||
updateLuaDisplay = true;
|
||||
|
||||
return(retval);
|
||||
};
|
||||
//----------------------------------------------------
|
||||
int LuaKillMessageBox(void)
|
||||
{
|
||||
//printf("Kill Lua Prompted\n");
|
||||
luaKillMsgBoxRetVal = 0;
|
||||
|
||||
openLuaKillMsgBox = true;
|
||||
|
||||
while ( openLuaKillMsgBox )
|
||||
{
|
||||
usleep(100000);
|
||||
}
|
||||
|
||||
return luaKillMsgBoxRetVal;
|
||||
}
|
||||
//----------------------------------------------------
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDialog>
|
||||
#include <QVBoxLayout>
|
||||
|
@ -30,7 +32,9 @@ class LuaControlDialog_t : public QDialog
|
|||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *bar);
|
||||
void openLuaKillMessageBox(void);
|
||||
|
||||
QTimer *periodicTimer;
|
||||
QLineEdit *scriptPath;
|
||||
QLineEdit *scriptArgs;
|
||||
QPushButton *browseButton;
|
||||
|
@ -42,8 +46,28 @@ class LuaControlDialog_t : public QDialog
|
|||
public slots:
|
||||
void closeWindow(void);
|
||||
private slots:
|
||||
void updatePeriodic(void);
|
||||
void openLuaScriptFile(void);
|
||||
void startLuaScript(void);
|
||||
void stopLuaScript(void);
|
||||
|
||||
};
|
||||
|
||||
// Formatted print
|
||||
#ifdef WIN32
|
||||
int LuaPrintfToWindowConsole(_In_z_ _Printf_format_string_ const char* const format, ...) ;
|
||||
#elif __linux__
|
||||
#ifdef __THROWNL
|
||||
int LuaPrintfToWindowConsole(const char *__restrict format, ...)
|
||||
__THROWNL __attribute__ ((__format__ (__printf__, 1, 2)));
|
||||
#else
|
||||
int LuaPrintfToWindowConsole(const char *__restrict format, ...)
|
||||
throw() __attribute__ ((__format__ (__printf__, 1, 2)));
|
||||
#endif
|
||||
#else
|
||||
int LuaPrintfToWindowConsole(const char *__restrict format, ...) throw();
|
||||
#endif
|
||||
|
||||
void PrintToWindowConsole(intptr_t hDlgAsInt, const char* str);
|
||||
|
||||
int LuaKillMessageBox(void);
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
// MovieOptions.cpp
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#include <QHeaderView>
|
||||
#include <QCloseEvent>
|
||||
|
||||
#include "../../fceu.h"
|
||||
#include "../../movie.h"
|
||||
|
||||
#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/MovieOptions.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
MovieOptionsDialog_t::MovieOptionsDialog_t(QWidget *parent)
|
||||
: QDialog( parent )
|
||||
{
|
||||
QLabel *lbl;
|
||||
QVBoxLayout *mainLayout;
|
||||
|
||||
setWindowTitle("Movie Options");
|
||||
|
||||
mainLayout = new QVBoxLayout();
|
||||
|
||||
readOnlyReplay = new QCheckBox( tr("Always Suggest Read-Only Replay") );
|
||||
pauseAfterPlay = new QCheckBox( tr("Pause After Playback") );
|
||||
closeAfterPlay = new QCheckBox( tr("Close After Playback") );
|
||||
bindSaveStates = new QCheckBox( tr("Bind Save-States to Movies") );
|
||||
dpySubTitles = new QCheckBox( tr("Display Movie Sub Titles") );
|
||||
putSubTitlesAvi = new QCheckBox( tr("Put Movie Sub Titles in AVI") );
|
||||
autoBackUp = new QCheckBox( tr("Automatically Backup Movies") );
|
||||
loadFullStates = new QCheckBox( tr("Load Full Save-State Movies:") );
|
||||
|
||||
lbl = new QLabel( tr("Loading states in record mode will not immediately truncate movie, next frame input will. (VBA-rr and SNES9x style)") );
|
||||
lbl->setWordWrap(true);
|
||||
|
||||
mainLayout->addWidget( readOnlyReplay );
|
||||
mainLayout->addWidget( pauseAfterPlay );
|
||||
mainLayout->addWidget( closeAfterPlay );
|
||||
mainLayout->addWidget( bindSaveStates );
|
||||
mainLayout->addWidget( dpySubTitles );
|
||||
mainLayout->addWidget( putSubTitlesAvi );
|
||||
mainLayout->addWidget( autoBackUp );
|
||||
mainLayout->addWidget( loadFullStates );
|
||||
mainLayout->addWidget( lbl );
|
||||
|
||||
readOnlyReplay->setChecked( suggestReadOnlyReplay );
|
||||
pauseAfterPlay->setChecked( pauseAfterPlayback );
|
||||
closeAfterPlay->setChecked( closeFinishedMovie );
|
||||
bindSaveStates->setChecked( bindSavestate );
|
||||
dpySubTitles->setChecked( movieSubtitles );
|
||||
putSubTitlesAvi->setChecked( subtitlesOnAVI );
|
||||
autoBackUp->setChecked( autoMovieBackup );
|
||||
loadFullStates->setChecked( fullSaveStateLoads );
|
||||
|
||||
setLayout( mainLayout );
|
||||
|
||||
connect( readOnlyReplay , SIGNAL(stateChanged(int)), this, SLOT(readOnlyReplayChanged(int)) );
|
||||
connect( pauseAfterPlay , SIGNAL(stateChanged(int)), this, SLOT(pauseAfterPlayChanged(int)) );
|
||||
connect( closeAfterPlay , SIGNAL(stateChanged(int)), this, SLOT(closeAfterPlayChanged(int)) );
|
||||
connect( bindSaveStates , SIGNAL(stateChanged(int)), this, SLOT(bindSaveStatesChanged(int)) );
|
||||
connect( dpySubTitles , SIGNAL(stateChanged(int)), this, SLOT(dpySubTitlesChanged(int)) );
|
||||
connect( putSubTitlesAvi, SIGNAL(stateChanged(int)), this, SLOT(putSubTitlesAviChanged(int)) );
|
||||
connect( autoBackUp , SIGNAL(stateChanged(int)), this, SLOT(autoBackUpChanged(int)) );
|
||||
connect( loadFullStates , SIGNAL(stateChanged(int)), this, SLOT(loadFullStatesChanged(int)) );
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
MovieOptionsDialog_t::~MovieOptionsDialog_t(void)
|
||||
{
|
||||
printf("Destroy Movie Options Window\n");
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void MovieOptionsDialog_t::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
printf("Movie Options Close Window Event\n");
|
||||
done(0);
|
||||
deleteLater();
|
||||
event->accept();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void MovieOptionsDialog_t::closeWindow(void)
|
||||
{
|
||||
//printf("Close Window\n");
|
||||
done(0);
|
||||
deleteLater();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void MovieOptionsDialog_t::readOnlyReplayChanged( int state )
|
||||
{
|
||||
suggestReadOnlyReplay = (state != Qt::Unchecked);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void MovieOptionsDialog_t::pauseAfterPlayChanged( int state )
|
||||
{
|
||||
pauseAfterPlayback = (state != Qt::Unchecked);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void MovieOptionsDialog_t::closeAfterPlayChanged( int state )
|
||||
{
|
||||
closeFinishedMovie = (state != Qt::Unchecked);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void MovieOptionsDialog_t::bindSaveStatesChanged( int state )
|
||||
{
|
||||
bindSavestate = (state != Qt::Unchecked);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void MovieOptionsDialog_t::dpySubTitlesChanged( int state )
|
||||
{
|
||||
movieSubtitles = (state != Qt::Unchecked);
|
||||
|
||||
g_config->setOption("SDL.SubtitleDisplay", movieSubtitles);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void MovieOptionsDialog_t::putSubTitlesAviChanged( int state )
|
||||
{
|
||||
subtitlesOnAVI = (state != Qt::Unchecked);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void MovieOptionsDialog_t::autoBackUpChanged( int state )
|
||||
{
|
||||
autoMovieBackup = (state != Qt::Unchecked);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void MovieOptionsDialog_t::loadFullStatesChanged( int state )
|
||||
{
|
||||
fullSaveStateLoads = (state != Qt::Unchecked);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
|
@ -0,0 +1,55 @@
|
|||
// MovieOptions.h
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDialog>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
#include <QLabel>
|
||||
#include <QFrame>
|
||||
#include <QGroupBox>
|
||||
#include <QTreeView>
|
||||
#include <QTreeWidget>
|
||||
|
||||
#include "Qt/main.h"
|
||||
|
||||
class MovieOptionsDialog_t : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MovieOptionsDialog_t(QWidget *parent = 0);
|
||||
~MovieOptionsDialog_t(void);
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event);
|
||||
|
||||
QCheckBox *readOnlyReplay;
|
||||
QCheckBox *pauseAfterPlay;
|
||||
QCheckBox *closeAfterPlay;
|
||||
QCheckBox *bindSaveStates;
|
||||
QCheckBox *dpySubTitles;
|
||||
QCheckBox *putSubTitlesAvi;
|
||||
QCheckBox *autoBackUp;
|
||||
QCheckBox *loadFullStates;
|
||||
|
||||
private:
|
||||
|
||||
public slots:
|
||||
void closeWindow(void);
|
||||
private slots:
|
||||
void readOnlyReplayChanged( int state );
|
||||
void pauseAfterPlayChanged( int state );
|
||||
void closeAfterPlayChanged( int state );
|
||||
void bindSaveStatesChanged( int state );
|
||||
void dpySubTitlesChanged( int state );
|
||||
void putSubTitlesAviChanged( int state );
|
||||
void autoBackUpChanged( int state );
|
||||
void loadFullStatesChanged( int state );
|
||||
|
||||
};
|
|
@ -0,0 +1,559 @@
|
|||
// MoviePlay.cpp
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#include <QHeaderView>
|
||||
#include <QCloseEvent>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QGridLayout>
|
||||
|
||||
#include "../../fceu.h"
|
||||
#include "../../movie.h"
|
||||
|
||||
#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/ConsoleUtilities.h"
|
||||
#include "Qt/MoviePlay.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
MoviePlayDialog_t::MoviePlayDialog_t(QWidget *parent)
|
||||
: QDialog( parent )
|
||||
{
|
||||
QVBoxLayout *mainLayout, *vbox;
|
||||
QHBoxLayout *hbox;
|
||||
QGroupBox *frame;
|
||||
QGridLayout *grid;
|
||||
QLabel *lbl;
|
||||
QPushButton *okButton, *cancelButton;
|
||||
bool replayReadOnlySetting;
|
||||
|
||||
setWindowTitle("Movie Play");
|
||||
|
||||
mainLayout = new QVBoxLayout();
|
||||
hbox = new QHBoxLayout();
|
||||
|
||||
lbl = new QLabel( tr("File:") );
|
||||
movSelBox = new QComboBox();
|
||||
movBrowseBtn = new QPushButton( tr("Browse") );
|
||||
|
||||
hbox->addWidget( lbl, 1 );
|
||||
hbox->addWidget( movSelBox, 100 );
|
||||
hbox->addWidget( movBrowseBtn, 1 );
|
||||
|
||||
mainLayout->addLayout( hbox );
|
||||
|
||||
frame = new QGroupBox( tr("Parameters:") );
|
||||
vbox = new QVBoxLayout();
|
||||
hbox = new QHBoxLayout();
|
||||
|
||||
frame->setLayout( vbox );
|
||||
|
||||
openReadOnly = new QCheckBox( tr("Open Read-Only") );
|
||||
pauseAtFrame = new QCheckBox( tr("Pause Movie At Frame") );
|
||||
|
||||
validator = new fceuDecIntValidtor( 0, 100000000, this );
|
||||
|
||||
pauseAtFrameEntry = new QLineEdit();
|
||||
|
||||
pauseAtFrameEntry->setValidator( validator );
|
||||
|
||||
vbox->addWidget( openReadOnly );
|
||||
vbox->addLayout( hbox );
|
||||
hbox->addWidget( pauseAtFrame );
|
||||
hbox->addWidget( pauseAtFrameEntry );
|
||||
|
||||
mainLayout->addWidget( frame );
|
||||
|
||||
grid = new QGridLayout();
|
||||
grid->setColumnStretch( 0, 1 );
|
||||
grid->setColumnStretch( 1, 10 );
|
||||
|
||||
mainLayout->addLayout( grid );
|
||||
|
||||
movLenLbl = new QLabel();
|
||||
movFramesLbl = new QLabel();
|
||||
recCountLbl = new QLabel();
|
||||
recFromLbl = new QLabel();
|
||||
romUsedLbl = new QLabel();
|
||||
romCsumLbl = new QLabel();
|
||||
curCsumLbl = new QLabel();
|
||||
emuUsedLbl = new QLabel();
|
||||
palUsedLbl = new QLabel();
|
||||
newppuUsedLbl = new QLabel();
|
||||
|
||||
grid->addWidget( new QLabel( tr("Length:") ) , 0, 0, Qt::AlignRight );
|
||||
grid->addWidget( new QLabel( tr("Frames:") ) , 1, 0, Qt::AlignRight );
|
||||
grid->addWidget( new QLabel( tr("Record Count:") ) , 2, 0, Qt::AlignRight );
|
||||
grid->addWidget( new QLabel( tr("Recorded From:") ) , 3, 0, Qt::AlignRight );
|
||||
grid->addWidget( new QLabel( tr("ROM Used:") ) , 4, 0, Qt::AlignRight );
|
||||
grid->addWidget( new QLabel( tr("ROM Checksum:") ) , 5, 0, Qt::AlignRight );
|
||||
grid->addWidget( new QLabel( tr("Current ROM Sum:") ) , 6, 0, Qt::AlignRight );
|
||||
grid->addWidget( new QLabel( tr("Emulator Used:") ) , 7, 0, Qt::AlignRight );
|
||||
grid->addWidget( new QLabel( tr("PAL:") ) , 8, 0, Qt::AlignRight );
|
||||
grid->addWidget( new QLabel( tr("New PPU:") ) , 9, 0, Qt::AlignRight );
|
||||
|
||||
grid->addWidget( movLenLbl , 0, 1, Qt::AlignLeft );
|
||||
grid->addWidget( movFramesLbl , 1, 1, Qt::AlignLeft );
|
||||
grid->addWidget( recCountLbl , 2, 1, Qt::AlignLeft );
|
||||
grid->addWidget( recFromLbl , 3, 1, Qt::AlignLeft );
|
||||
grid->addWidget( romUsedLbl , 4, 1, Qt::AlignLeft );
|
||||
grid->addWidget( romCsumLbl , 5, 1, Qt::AlignLeft );
|
||||
grid->addWidget( curCsumLbl , 6, 1, Qt::AlignLeft );
|
||||
grid->addWidget( emuUsedLbl , 7, 1, Qt::AlignLeft );
|
||||
grid->addWidget( palUsedLbl , 8, 1, Qt::AlignLeft );
|
||||
grid->addWidget( newppuUsedLbl , 9, 1, Qt::AlignLeft );
|
||||
|
||||
hbox = new QHBoxLayout();
|
||||
okButton = new QPushButton( tr("Play") );
|
||||
cancelButton = new QPushButton( tr("Cancel") );
|
||||
hbox->addWidget( cancelButton );
|
||||
hbox->addWidget( okButton );
|
||||
okButton->setDefault(true);
|
||||
mainLayout->addLayout( hbox );
|
||||
|
||||
setLayout( mainLayout );
|
||||
|
||||
connect( cancelButton , SIGNAL(clicked(void)), this, SLOT(closeWindow(void)) );
|
||||
connect( okButton , SIGNAL(clicked(void)), this, SLOT(playMovie(void)) );
|
||||
|
||||
connect( movBrowseBtn , SIGNAL(clicked(void)) , this, SLOT(openMovie(void)) );
|
||||
connect( movSelBox , SIGNAL(activated(int)), this, SLOT(movieSelect(int)) );
|
||||
|
||||
connect( pauseAtFrame , SIGNAL(stateChanged(int)), this, SLOT(pauseAtFrameChange(int)) );
|
||||
|
||||
if (suggestReadOnlyReplay)
|
||||
{
|
||||
replayReadOnlySetting = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
replayReadOnlySetting = FCEUI_GetMovieToggleReadOnly();
|
||||
}
|
||||
openReadOnly->setChecked( replayReadOnlySetting );
|
||||
|
||||
pauseAtFrameEntry->setEnabled( pauseAtFrame->isChecked() );
|
||||
|
||||
doScan();
|
||||
|
||||
updateMovieText();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
MoviePlayDialog_t::~MoviePlayDialog_t(void)
|
||||
{
|
||||
printf("Destroy Movie Play Window\n");
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void MoviePlayDialog_t::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
printf("Movie Play Close Window Event\n");
|
||||
done(0);
|
||||
deleteLater();
|
||||
event->accept();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void MoviePlayDialog_t::closeWindow(void)
|
||||
{
|
||||
//printf("Close Window\n");
|
||||
done(0);
|
||||
deleteLater();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
//void MoviePlayDialog_t::readOnlyReplayChanged( int state )
|
||||
//{
|
||||
// suggestReadOnlyReplay = (state != Qt::Unchecked);
|
||||
//}
|
||||
//----------------------------------------------------------------------------
|
||||
void MoviePlayDialog_t::movieSelect(int index)
|
||||
{
|
||||
updateMovieText();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void MoviePlayDialog_t::pauseAtFrameChange(int state)
|
||||
{
|
||||
pauseAtFrameEntry->setEnabled( state != Qt::Unchecked );
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void MoviePlayDialog_t::clearMovieText(void)
|
||||
{
|
||||
movLenLbl->clear();
|
||||
movFramesLbl->clear();
|
||||
recCountLbl->clear();
|
||||
recFromLbl->clear();
|
||||
romUsedLbl->clear();
|
||||
romCsumLbl->clear();
|
||||
curCsumLbl->clear();
|
||||
emuUsedLbl->clear();
|
||||
palUsedLbl->clear();
|
||||
newppuUsedLbl->clear();
|
||||
pauseAtFrameEntry->clear();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void MoviePlayDialog_t::updateMovieText(void)
|
||||
{
|
||||
int idx;
|
||||
std::string path;
|
||||
FCEUFILE* fp;
|
||||
MOVIE_INFO info;
|
||||
bool scanok;
|
||||
char stmp[256];
|
||||
|
||||
if ( movSelBox->count() == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
idx = movSelBox->currentIndex();
|
||||
|
||||
path = movSelBox->itemText(idx).toStdString();
|
||||
|
||||
fp = FCEU_fopen( path.c_str(),0,"rb",0);
|
||||
|
||||
if ( fp == NULL )
|
||||
{
|
||||
sprintf( stmp, "Error: Failed to open file '%s'", path.c_str() );
|
||||
showErrorMsgWindow( stmp );
|
||||
clearMovieText();
|
||||
return;
|
||||
}
|
||||
scanok = FCEUI_MovieGetInfo(fp, info, false);
|
||||
|
||||
if ( scanok )
|
||||
{
|
||||
double div;
|
||||
|
||||
validator->setMinMax( 0, info.num_frames );
|
||||
|
||||
sprintf(stmp, "%u", (unsigned)info.num_frames);
|
||||
|
||||
movFramesLbl->setText( tr(stmp) );
|
||||
pauseAtFrameEntry->setText( tr(stmp) );
|
||||
|
||||
div = (FCEUI_GetCurrentVidSystem(0,0)) ? 50.006977968268290849 : 60.098813897440515532; // PAL timing
|
||||
double tempCount = (info.num_frames / div) + 0.005; // +0.005s for rounding
|
||||
int num_seconds = (int)tempCount;
|
||||
int fraction = (int)((tempCount - num_seconds) * 100);
|
||||
int seconds = num_seconds % 60;
|
||||
int minutes = (num_seconds / 60) % 60;
|
||||
int hours = (num_seconds / 60 / 60) % 60;
|
||||
sprintf(stmp, "%02d:%02d:%02d.%02d", hours, minutes, seconds, fraction);
|
||||
|
||||
movLenLbl->setText( tr(stmp) );
|
||||
|
||||
sprintf(stmp, "%u", (unsigned)info.rerecord_count);
|
||||
|
||||
recCountLbl->setText( tr(stmp) );
|
||||
|
||||
recFromLbl->setText( tr(info.poweron ? "Power-On" : (info.reset?"Soft-Reset":"Savestate") ) );
|
||||
|
||||
romUsedLbl->setText( tr(info.name_of_rom_used.c_str()) );
|
||||
|
||||
romCsumLbl->setText( tr(md5_asciistr(info.md5_of_rom_used)) );
|
||||
|
||||
if ( GameInfo )
|
||||
{
|
||||
curCsumLbl->setText( tr(md5_asciistr(GameInfo->MD5)) );
|
||||
}
|
||||
else
|
||||
{
|
||||
curCsumLbl->clear();
|
||||
}
|
||||
|
||||
if (info.emu_version_used < 20000 )
|
||||
{
|
||||
sprintf( stmp, "FCEU %u.%02u.%02u%s", info.emu_version_used/10000, (info.emu_version_used/100)%100, (info.emu_version_used)%100, info.emu_version_used < 9813 ? " (blip)" : "");
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( stmp, "FCEUX %u.%02u.%02u", info.emu_version_used/10000, (info.emu_version_used/100)%100, (info.emu_version_used)%100);
|
||||
}
|
||||
emuUsedLbl->setText( tr(stmp) );
|
||||
|
||||
palUsedLbl->setText( tr(info.pal ? "On" : "Off") );
|
||||
|
||||
newppuUsedLbl->setText( tr(info.ppuflag ? "On" : "Off") );
|
||||
|
||||
if ( GameInfo )
|
||||
{
|
||||
strcpy( stmp, md5_asciistr(GameInfo->MD5) );
|
||||
|
||||
if ( strcmp( stmp, md5_asciistr(info.md5_of_rom_used) ) != 0 )
|
||||
{
|
||||
sprintf( stmp, "Warning: Selected movie file '%s' may not have been created using the currently loaded ROM.", path.c_str() );
|
||||
showWarningMsgWindow( stmp );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( stmp, "Error: Selected file '%s' does not have a recognized movie format.", path.c_str() );
|
||||
showErrorMsgWindow( stmp );
|
||||
clearMovieText();
|
||||
}
|
||||
delete fp;
|
||||
|
||||
return;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
int MoviePlayDialog_t::addFileToList( const char *file, bool setActive )
|
||||
{
|
||||
int n=0;
|
||||
|
||||
for (int i=0; i<movSelBox->count(); i++)
|
||||
{
|
||||
if ( strcmp( file, movSelBox->itemText(i).toStdString().c_str() ) == 0 )
|
||||
{
|
||||
if ( setActive )
|
||||
{
|
||||
movSelBox->setCurrentIndex(i);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
n = movSelBox->count();
|
||||
|
||||
movSelBox->addItem( tr(file), n );
|
||||
|
||||
if ( setActive )
|
||||
{
|
||||
movSelBox->setCurrentIndex(n);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
bool MoviePlayDialog_t::checkMD5Sum( const char *path, const char *md5 )
|
||||
{
|
||||
FCEUFILE* fp;
|
||||
MOVIE_INFO info;
|
||||
bool scanok, md5Match = false;
|
||||
|
||||
fp = FCEU_fopen( path,0,"rb",0);
|
||||
|
||||
if ( fp == NULL )
|
||||
{
|
||||
return md5Match;
|
||||
}
|
||||
scanok = FCEUI_MovieGetInfo(fp, info, true);
|
||||
|
||||
if ( scanok )
|
||||
{
|
||||
if ( strcmp( md5, md5_asciistr(info.md5_of_rom_used) ) == 0 )
|
||||
{
|
||||
md5Match = true;
|
||||
}
|
||||
}
|
||||
delete fp;
|
||||
|
||||
return md5Match;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void MoviePlayDialog_t::scanDirectory( const char *dirPath, const char *md5 )
|
||||
{
|
||||
QDir dir;
|
||||
QFileInfoList list;
|
||||
std::string path;
|
||||
const QStringList filters( { "*.fm2" } );
|
||||
|
||||
path.assign( dirPath );
|
||||
|
||||
dir.setPath( QString::fromStdString(path) );
|
||||
|
||||
list = dir.entryInfoList( filters, QDir::Files );
|
||||
|
||||
for (int i = 0; i < list.size(); ++i)
|
||||
{
|
||||
QFileInfo fileInfo = list.at(i);
|
||||
|
||||
path = std::string(dirPath) + fileInfo.fileName().toStdString();
|
||||
|
||||
//printf("File: '%s'\n", path.c_str() );
|
||||
|
||||
if ( checkMD5Sum( path.c_str(), md5 ) )
|
||||
{
|
||||
addFileToList( path.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void MoviePlayDialog_t::doScan(void)
|
||||
{
|
||||
std::string path, last;
|
||||
const char *romFile;
|
||||
const char *baseDir = FCEUI_GetBaseDirectory();
|
||||
char md5[256];
|
||||
char dir[512], base[256];
|
||||
|
||||
md5[0] = 0;
|
||||
|
||||
if ( GameInfo )
|
||||
{
|
||||
strcpy( md5, md5_asciistr(GameInfo->MD5) );
|
||||
}
|
||||
|
||||
path = std::string(baseDir) + "/movies/";
|
||||
|
||||
scanDirectory( path.c_str(), md5 );
|
||||
|
||||
romFile = getRomFile();
|
||||
|
||||
if ( romFile != NULL )
|
||||
{
|
||||
parseFilepath( romFile, dir, base );
|
||||
|
||||
path = std::string(dir);
|
||||
|
||||
scanDirectory( path.c_str(), md5 );
|
||||
}
|
||||
|
||||
g_config->getOption ("SDL.LastOpenMovie", &last );
|
||||
|
||||
getDirFromFile( last.c_str(), dir );
|
||||
|
||||
scanDirectory( dir, md5 );
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void MoviePlayDialog_t::playMovie(void)
|
||||
{
|
||||
int idx, pauseframe = 0;
|
||||
bool replayReadOnlySetting, movieLoadError = false;
|
||||
|
||||
if ( movSelBox->count() == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
std::string path;
|
||||
|
||||
idx = movSelBox->currentIndex();
|
||||
|
||||
path = movSelBox->itemText(idx).toStdString();
|
||||
|
||||
replayReadOnlySetting = openReadOnly->isChecked();
|
||||
|
||||
if ( pauseAtFrame->isChecked() )
|
||||
{
|
||||
pauseframe = strtol( pauseAtFrameEntry->text().toStdString().c_str(), NULL, 0 );
|
||||
}
|
||||
|
||||
fceuWrapperLock();
|
||||
if (FCEUI_LoadMovie( path.c_str(),
|
||||
replayReadOnlySetting, pauseframe ? pauseframe : false) == false)
|
||||
{
|
||||
movieLoadError = true;
|
||||
}
|
||||
fceuWrapperUnLock();
|
||||
|
||||
if ( movieLoadError )
|
||||
{
|
||||
char stmp[256];
|
||||
sprintf( stmp, "Error: Could not load movie file: %s \n", path.c_str() );
|
||||
showErrorMsgWindow( stmp );
|
||||
}
|
||||
else
|
||||
{
|
||||
closeWindow();
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void MoviePlayDialog_t::openMovie(void)
|
||||
{
|
||||
int ret, useNativeFileDialogVal;
|
||||
QString filename;
|
||||
std::string last;
|
||||
char dir[512];
|
||||
char md5Match = 0;
|
||||
QFileDialog dialog(this, tr("Open FM2 Movie") );
|
||||
|
||||
dialog.setFileMode(QFileDialog::ExistingFile);
|
||||
|
||||
dialog.setNameFilter(tr("FM2 Movies (*.fm2) ;; All files (*)"));
|
||||
|
||||
dialog.setViewMode(QFileDialog::List);
|
||||
dialog.setFilter( QDir::AllEntries | QDir::AllDirs | QDir::Hidden );
|
||||
dialog.setLabelText( QFileDialog::Accept, tr("Open") );
|
||||
|
||||
g_config->getOption ("SDL.LastOpenMovie", &last );
|
||||
|
||||
getDirFromFile( last.c_str(), dir );
|
||||
|
||||
dialog.setDirectory( tr(dir) );
|
||||
|
||||
// Check config option to use native file dialog or not
|
||||
g_config->getOption ("SDL.UseNativeFileDialog", &useNativeFileDialogVal);
|
||||
|
||||
dialog.setOption(QFileDialog::DontUseNativeDialog, !useNativeFileDialogVal);
|
||||
|
||||
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();
|
||||
|
||||
if ( GameInfo )
|
||||
{
|
||||
char md5[256];
|
||||
|
||||
strcpy( md5, md5_asciistr(GameInfo->MD5) );
|
||||
|
||||
if ( checkMD5Sum( filename.toStdString().c_str(), md5 ) )
|
||||
{
|
||||
md5Match = 1;
|
||||
}
|
||||
|
||||
if ( !md5Match )
|
||||
{
|
||||
printf("Warning MD5 Mismatch\n");
|
||||
}
|
||||
}
|
||||
|
||||
addFileToList( filename.toStdString().c_str(), true );
|
||||
|
||||
updateMovieText();
|
||||
|
||||
g_config->setOption ("SDL.LastOpenMovie", filename.toStdString().c_str() );
|
||||
|
||||
return;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void MoviePlayDialog_t::showErrorMsgWindow(const char *str)
|
||||
{
|
||||
QMessageBox msgBox(this);
|
||||
|
||||
msgBox.setIcon( QMessageBox::Critical );
|
||||
msgBox.setText( tr(str) );
|
||||
msgBox.show();
|
||||
msgBox.exec();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void MoviePlayDialog_t::showWarningMsgWindow(const char *str)
|
||||
{
|
||||
QMessageBox msgBox(this);
|
||||
|
||||
msgBox.setIcon( QMessageBox::Warning );
|
||||
msgBox.setText( tr(str) );
|
||||
msgBox.show();
|
||||
msgBox.exec();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
|
@ -0,0 +1,69 @@
|
|||
// MoviePlay.h
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDialog>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
#include <QLineEdit>
|
||||
#include <QLabel>
|
||||
#include <QFrame>
|
||||
#include <QGroupBox>
|
||||
|
||||
#include "Qt/main.h"
|
||||
#include "Qt/ConsoleUtilities.h"
|
||||
|
||||
class MoviePlayDialog_t : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MoviePlayDialog_t(QWidget *parent = 0);
|
||||
~MoviePlayDialog_t(void);
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event);
|
||||
|
||||
QComboBox *movSelBox;
|
||||
QPushButton *movBrowseBtn;
|
||||
QCheckBox *openReadOnly;
|
||||
QCheckBox *pauseAtFrame;
|
||||
QLineEdit *pauseAtFrameEntry;
|
||||
|
||||
QLabel *movLenLbl;
|
||||
QLabel *movFramesLbl;
|
||||
QLabel *recCountLbl;
|
||||
QLabel *recFromLbl;
|
||||
QLabel *romUsedLbl;
|
||||
QLabel *romCsumLbl;
|
||||
QLabel *curCsumLbl;
|
||||
QLabel *emuUsedLbl;
|
||||
QLabel *palUsedLbl;
|
||||
QLabel *newppuUsedLbl;
|
||||
|
||||
fceuDecIntValidtor *validator;
|
||||
|
||||
private:
|
||||
void doScan(void);
|
||||
void clearMovieText(void);
|
||||
void updateMovieText(void);
|
||||
int addFileToList( const char *file, bool setActive = false );
|
||||
bool checkMD5Sum( const char *path, const char *md5 );
|
||||
void scanDirectory( const char *dirPath, const char *md5 );
|
||||
void showErrorMsgWindow(const char *str);
|
||||
void showWarningMsgWindow(const char *str);
|
||||
|
||||
public slots:
|
||||
void closeWindow(void);
|
||||
private slots:
|
||||
void openMovie(void);
|
||||
void playMovie(void);
|
||||
void movieSelect(int index);
|
||||
void pauseAtFrameChange(int state);
|
||||
|
||||
};
|
|
@ -0,0 +1,279 @@
|
|||
// MsgLogViewer.cpp
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#include <SDL.h>
|
||||
#include <QHeaderView>
|
||||
#include <QCloseEvent>
|
||||
|
||||
#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/MsgLogViewer.h"
|
||||
#include "Qt/ConsoleWindow.h"
|
||||
|
||||
#define MSG_LOG_MAX_LINES 256
|
||||
|
||||
class msgLogBuf_t
|
||||
{
|
||||
public:
|
||||
msgLogBuf_t(void)
|
||||
{
|
||||
char filename[256];
|
||||
|
||||
strcpy( filename, "/tmp/fceux.log" );
|
||||
|
||||
fp = ::fopen( filename, "w+");
|
||||
|
||||
if ( fp == NULL )
|
||||
{
|
||||
printf("Error: Failed to open message log file: '%s'\n", filename);
|
||||
}
|
||||
maxLines = MSG_LOG_MAX_LINES;
|
||||
totalLines = 0;
|
||||
head = tail = 0;
|
||||
|
||||
for (int i=0; i<MSG_LOG_MAX_LINES; i++)
|
||||
{
|
||||
fpOfsList[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
~msgLogBuf_t(void)
|
||||
{
|
||||
if ( fp != NULL )
|
||||
{
|
||||
::fclose(fp); fp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
head = tail = 0;
|
||||
}
|
||||
|
||||
void addLine( const char *txt, bool NewLine = false )
|
||||
{
|
||||
long ofs;
|
||||
|
||||
if ( fp == NULL ) return;
|
||||
|
||||
::fseek( fp, 0L, SEEK_END);
|
||||
|
||||
ofs = ::ftell(fp);
|
||||
|
||||
if ( NewLine )
|
||||
{
|
||||
::fprintf( fp, "%s\n", txt );
|
||||
}
|
||||
else
|
||||
{
|
||||
::fprintf( fp, "%s", txt );
|
||||
}
|
||||
|
||||
fpOfsList[head] = ofs;
|
||||
|
||||
head = (head + 1) % MSG_LOG_MAX_LINES;
|
||||
|
||||
if ( head == tail )
|
||||
{
|
||||
tail = (tail + 1) % MSG_LOG_MAX_LINES;
|
||||
}
|
||||
|
||||
totalLines++;
|
||||
}
|
||||
|
||||
size_t getTotalLineCount(void)
|
||||
{
|
||||
return totalLines;
|
||||
}
|
||||
|
||||
size_t size(void)
|
||||
{
|
||||
size_t s;
|
||||
|
||||
s = head - tail;
|
||||
|
||||
if ( s < 0 )
|
||||
{
|
||||
s += MSG_LOG_MAX_LINES;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void loadTextViewer( QPlainTextEdit *viewer )
|
||||
{
|
||||
long ofs, nbytes;
|
||||
|
||||
if ( fp == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( head == tail )
|
||||
{
|
||||
return;
|
||||
}
|
||||
char buf[65536];
|
||||
|
||||
ofs = fpOfsList[tail];
|
||||
|
||||
::fseek( fp, ofs, SEEK_SET);
|
||||
|
||||
//printf("Seek: %li \n", ofs );
|
||||
|
||||
if ( (nbytes = ::fread( buf, 1, sizeof(buf), fp )) > 0 )
|
||||
{
|
||||
//printf("READ: %li \n", nbytes );
|
||||
buf[ nbytes ] = 0;
|
||||
viewer->setPlainText( buf );
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
FILE *fp;
|
||||
size_t maxLines;
|
||||
size_t totalLines;
|
||||
size_t head;
|
||||
size_t tail;
|
||||
|
||||
long fpOfsList[MSG_LOG_MAX_LINES];
|
||||
};
|
||||
|
||||
static msgLogBuf_t msgLog;
|
||||
//----------------------------------------------------------------------------
|
||||
MsgLogViewDialog_t::MsgLogViewDialog_t(QWidget *parent)
|
||||
: QDialog( parent )
|
||||
{
|
||||
QVBoxLayout *mainLayout;
|
||||
QHBoxLayout *hbox;
|
||||
QPushButton *clearBtn, *closeBtn;
|
||||
|
||||
setWindowTitle("Message Log Viewer");
|
||||
|
||||
resize( 512, 512 );
|
||||
|
||||
mainLayout = new QVBoxLayout();
|
||||
|
||||
txtView = new QPlainTextEdit();
|
||||
txtView->setReadOnly(true);
|
||||
|
||||
mainLayout->addWidget( txtView );
|
||||
|
||||
hbox = new QHBoxLayout();
|
||||
clearBtn = new QPushButton( tr("Clear") );
|
||||
closeBtn = new QPushButton( tr("Close") );
|
||||
hbox->addWidget( clearBtn );
|
||||
hbox->addWidget( closeBtn );
|
||||
|
||||
connect( clearBtn, SIGNAL(clicked(void)), this, SLOT(clearLog(void)) );
|
||||
connect( closeBtn, SIGNAL(clicked(void)), this, SLOT(closeWindow(void)) );
|
||||
|
||||
mainLayout->addLayout( hbox );
|
||||
|
||||
setLayout( mainLayout );
|
||||
|
||||
totalLines = 0;
|
||||
|
||||
updateTimer = new QTimer( this );
|
||||
|
||||
connect( updateTimer, &QTimer::timeout, this, &MsgLogViewDialog_t::updatePeriodic );
|
||||
|
||||
updateTimer->start( 500 ); // 2hz
|
||||
|
||||
msgLog.loadTextViewer( txtView );
|
||||
|
||||
totalLines = msgLog.getTotalLineCount();
|
||||
|
||||
txtView->moveCursor(QTextCursor::End);
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
MsgLogViewDialog_t::~MsgLogViewDialog_t(void)
|
||||
{
|
||||
printf("Destroy Msg Log Key Config Window\n");
|
||||
updateTimer->stop();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void MsgLogViewDialog_t::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
printf("Msg Log Key Close Window Event\n");
|
||||
done(0);
|
||||
deleteLater();
|
||||
event->accept();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void MsgLogViewDialog_t::closeWindow(void)
|
||||
{
|
||||
//printf("Close Window\n");
|
||||
done(0);
|
||||
deleteLater();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void MsgLogViewDialog_t::clearLog(void)
|
||||
{
|
||||
fceuWrapperLock();
|
||||
|
||||
msgLog.clear();
|
||||
|
||||
txtView->clear();
|
||||
|
||||
fceuWrapperUnLock();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void MsgLogViewDialog_t::updatePeriodic(void)
|
||||
{
|
||||
if ( msgLog.getTotalLineCount() != totalLines )
|
||||
{
|
||||
fceuWrapperLock();
|
||||
|
||||
msgLog.loadTextViewer( txtView );
|
||||
|
||||
totalLines = msgLog.getTotalLineCount();
|
||||
|
||||
fceuWrapperUnLock();
|
||||
|
||||
txtView->moveCursor(QTextCursor::End);
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
/**
|
||||
* 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);
|
||||
//fprintf(stdout, "\n");
|
||||
//
|
||||
msgLog.addLine( text, false );
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
/**
|
||||
* Shows an error message in a message box.
|
||||
* (For now: prints to stderr.)
|
||||
*
|
||||
* If running in Qt 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);
|
||||
|
||||
msgLog.addLine( errormsg, true );
|
||||
|
||||
if ( consoleWindow )
|
||||
{
|
||||
consoleWindow->QueueErrorMsgWindow( errormsg );
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
|
@ -0,0 +1,46 @@
|
|||
// MsgLogViewer.h
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDialog>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
#include <QLabel>
|
||||
#include <QTimer>
|
||||
#include <QFrame>
|
||||
#include <QGroupBox>
|
||||
#include <QPlainTextEdit>
|
||||
|
||||
#include "Qt/main.h"
|
||||
|
||||
class MsgLogViewDialog_t : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MsgLogViewDialog_t(QWidget *parent = 0);
|
||||
~MsgLogViewDialog_t(void);
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event);
|
||||
|
||||
QTimer *updateTimer;
|
||||
QPlainTextEdit *txtView;
|
||||
|
||||
size_t totalLines;
|
||||
|
||||
private:
|
||||
|
||||
public slots:
|
||||
void closeWindow(void);
|
||||
private slots:
|
||||
void updatePeriodic(void);
|
||||
void clearLog(void);
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,778 @@
|
|||
// NameTableViewer.cpp
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QPainter>
|
||||
#include <QInputDialog>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "../../types.h"
|
||||
#include "../../fceu.h"
|
||||
#include "../../cart.h"
|
||||
#include "../../ppu.h"
|
||||
#include "../../ines.h"
|
||||
#include "../../debug.h"
|
||||
#include "../../palette.h"
|
||||
|
||||
#include "Qt/NameTableViewer.h"
|
||||
#include "Qt/main.h"
|
||||
#include "Qt/dface.h"
|
||||
#include "Qt/input.h"
|
||||
#include "Qt/config.h"
|
||||
#include "Qt/fceuWrapper.h"
|
||||
|
||||
static ppuNameTableViewerDialog_t *nameTableViewWindow = NULL;
|
||||
static uint8_t palcache[36]; //palette cache
|
||||
static int NTViewScanline = 0;
|
||||
static int NTViewSkip = 100;
|
||||
static int NTViewRefresh = 1;
|
||||
static int chrchanged = 0;
|
||||
|
||||
static int xpos = 0, ypos = 0;
|
||||
static int attview = 0;
|
||||
static int hidepal = 0;
|
||||
static bool drawScrollLines = true;
|
||||
static bool redrawtables = true;
|
||||
|
||||
// checkerboard tile for attribute view
|
||||
static const uint8_t ATTRIBUTE_VIEW_TILE[16] = { 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
|
||||
|
||||
static class NTCache
|
||||
{
|
||||
public:
|
||||
NTCache(void)
|
||||
: curr_vnapage(0)
|
||||
{
|
||||
memset( cache, 0, sizeof(cache) );
|
||||
}
|
||||
|
||||
uint8_t* curr_vnapage;
|
||||
uint8_t cache[0x400];
|
||||
} cache[4];
|
||||
|
||||
static ppuNameTable_t nameTable[4];
|
||||
|
||||
enum NT_MirrorType
|
||||
{
|
||||
NT_NONE = -1,
|
||||
NT_HORIZONTAL, NT_VERTICAL, NT_FOUR_SCREEN,
|
||||
NT_SINGLE_SCREEN_TABLE_0, NT_SINGLE_SCREEN_TABLE_1,
|
||||
NT_SINGLE_SCREEN_TABLE_2, NT_SINGLE_SCREEN_TABLE_3,
|
||||
NT_NUM_MIRROR_TYPES
|
||||
};
|
||||
static NT_MirrorType ntmirroring = NT_NONE, oldntmirroring = NT_NONE;
|
||||
|
||||
static void initNameTableViewer(void);
|
||||
static void ChangeMirroring(void);
|
||||
//----------------------------------------------------
|
||||
int openNameTableViewWindow( QWidget *parent )
|
||||
{
|
||||
if ( nameTableViewWindow != NULL )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
initNameTableViewer();
|
||||
|
||||
nameTableViewWindow = new ppuNameTableViewerDialog_t(parent);
|
||||
|
||||
nameTableViewWindow->show();
|
||||
|
||||
return 0;
|
||||
}
|
||||
//----------------------------------------------------
|
||||
ppuNameTableViewerDialog_t::ppuNameTableViewerDialog_t(QWidget *parent)
|
||||
: QDialog( parent, Qt::Window )
|
||||
{
|
||||
QVBoxLayout *mainLayout, *vbox;
|
||||
QHBoxLayout *hbox;
|
||||
QGridLayout *grid;
|
||||
QGroupBox *frame;
|
||||
char stmp[64];
|
||||
|
||||
nameTableViewWindow = this;
|
||||
|
||||
setWindowTitle( tr("Name Table Viewer") );
|
||||
|
||||
mainLayout = new QVBoxLayout();
|
||||
|
||||
setLayout( mainLayout );
|
||||
|
||||
vbox = new QVBoxLayout();
|
||||
frame = new QGroupBox( tr("Name Tables") );
|
||||
ntView = new ppuNameTableView_t(this);
|
||||
grid = new QGridLayout();
|
||||
|
||||
vbox->addWidget( ntView );
|
||||
frame->setLayout( vbox );
|
||||
mainLayout->addWidget( frame, 100 );
|
||||
mainLayout->addLayout( grid , 1 );
|
||||
|
||||
showScrollLineCbox = new QCheckBox( tr("Show Scroll Lines") );
|
||||
showAttrbCbox = new QCheckBox( tr("Show Attributes") );
|
||||
ignorePaletteCbox = new QCheckBox( tr("Ignore Palette") );
|
||||
|
||||
showScrollLineCbox->setChecked( drawScrollLines );
|
||||
showAttrbCbox->setChecked( attview );
|
||||
ignorePaletteCbox->setChecked( hidepal );
|
||||
|
||||
grid->addWidget( showScrollLineCbox, 0, 0, Qt::AlignLeft );
|
||||
grid->addWidget( showAttrbCbox , 1, 0, Qt::AlignLeft );
|
||||
grid->addWidget( ignorePaletteCbox , 2, 0, Qt::AlignLeft );
|
||||
|
||||
connect( showScrollLineCbox, SIGNAL(stateChanged(int)), this, SLOT(showScrollLinesChanged(int)));
|
||||
connect( showAttrbCbox , SIGNAL(stateChanged(int)), this, SLOT(showAttrbChanged(int)));
|
||||
connect( ignorePaletteCbox , SIGNAL(stateChanged(int)), this, SLOT(ignorePaletteChanged(int)));
|
||||
|
||||
hbox = new QHBoxLayout();
|
||||
refreshSlider = new QSlider( Qt::Horizontal );
|
||||
hbox->addWidget( new QLabel( tr("Refresh: More") ) );
|
||||
hbox->addWidget( refreshSlider );
|
||||
hbox->addWidget( new QLabel( tr("Less") ) );
|
||||
grid->addLayout( hbox, 0, 1, Qt::AlignRight );
|
||||
|
||||
refreshSlider->setMinimum( 0);
|
||||
refreshSlider->setMaximum(25);
|
||||
refreshSlider->setValue(NTViewRefresh);
|
||||
|
||||
connect( refreshSlider, SIGNAL(valueChanged(int)), this, SLOT(refreshSliderChanged(int)));
|
||||
|
||||
hbox = new QHBoxLayout();
|
||||
scanLineEdit = new QLineEdit();
|
||||
hbox->addWidget( new QLabel( tr("Display on Scanline:") ) );
|
||||
hbox->addWidget( scanLineEdit );
|
||||
grid->addLayout( hbox, 1, 1, Qt::AlignRight );
|
||||
|
||||
scanLineEdit->setMaxLength( 3 );
|
||||
scanLineEdit->setInputMask( ">900;" );
|
||||
sprintf( stmp, "%i", NTViewScanline );
|
||||
scanLineEdit->setText( tr(stmp) );
|
||||
|
||||
connect( scanLineEdit, SIGNAL(textEdited(const QString &)), this, SLOT(scanLineChanged(const QString &)));
|
||||
|
||||
hbox = new QHBoxLayout();
|
||||
frame = new QGroupBox( tr("Current Mirroring") );
|
||||
grid = new QGridLayout();
|
||||
|
||||
mainLayout->addLayout( hbox, 1 );
|
||||
hbox->addWidget( frame );
|
||||
frame->setLayout( grid );
|
||||
|
||||
horzMirrorBtn = new QRadioButton( tr("Horizontal") );
|
||||
vertMirrorBtn = new QRadioButton( tr("Vertical") );
|
||||
fourScreenBtn = new QRadioButton( tr("Four Screen") );
|
||||
singleScreenBtn[0] = new QRadioButton( tr("Single Screen 0") );
|
||||
singleScreenBtn[1] = new QRadioButton( tr("Single Screen 1") );
|
||||
singleScreenBtn[2] = new QRadioButton( tr("Single Screen 2") );
|
||||
singleScreenBtn[3] = new QRadioButton( tr("Single Screen 3") );
|
||||
|
||||
grid->addWidget( horzMirrorBtn, 0, 0, Qt::AlignLeft );
|
||||
grid->addWidget( vertMirrorBtn, 1, 0, Qt::AlignLeft );
|
||||
grid->addWidget( fourScreenBtn, 2, 0, Qt::AlignLeft );
|
||||
grid->addWidget( singleScreenBtn[0], 0, 1, Qt::AlignLeft );
|
||||
grid->addWidget( singleScreenBtn[1], 1, 1, Qt::AlignLeft );
|
||||
grid->addWidget( singleScreenBtn[2], 2, 1, Qt::AlignLeft );
|
||||
grid->addWidget( singleScreenBtn[3], 3, 1, Qt::AlignLeft );
|
||||
|
||||
connect( horzMirrorBtn , SIGNAL(clicked(void)), this, SLOT(horzMirrorClicked(void)));
|
||||
connect( vertMirrorBtn , SIGNAL(clicked(void)), this, SLOT(vertMirrorClicked(void)));
|
||||
connect( fourScreenBtn , SIGNAL(clicked(void)), this, SLOT(fourScreenClicked(void)));
|
||||
connect( singleScreenBtn[0], SIGNAL(clicked(void)), this, SLOT(singleScreen0Clicked(void)));
|
||||
connect( singleScreenBtn[1], SIGNAL(clicked(void)), this, SLOT(singleScreen1Clicked(void)));
|
||||
connect( singleScreenBtn[2], SIGNAL(clicked(void)), this, SLOT(singleScreen2Clicked(void)));
|
||||
connect( singleScreenBtn[3], SIGNAL(clicked(void)), this, SLOT(singleScreen3Clicked(void)));
|
||||
|
||||
updateMirrorButtons();
|
||||
|
||||
vbox = new QVBoxLayout();
|
||||
frame = new QGroupBox( tr("Properties") );
|
||||
hbox->addWidget( frame );
|
||||
frame->setLayout( vbox );
|
||||
|
||||
tileID = new QLabel( tr("Tile ID:") );
|
||||
tileXY = new QLabel( tr("X/Y :") );
|
||||
ppuAddrLbl = new QLabel( tr("PPU Address:") );
|
||||
attrbLbl = new QLabel( tr("Attribute:") );
|
||||
|
||||
vbox->addWidget( tileID );
|
||||
vbox->addWidget( tileXY );
|
||||
vbox->addWidget( ppuAddrLbl );
|
||||
vbox->addWidget( attrbLbl );
|
||||
|
||||
FCEUD_UpdateNTView( -1, true);
|
||||
|
||||
updateTimer = new QTimer( this );
|
||||
|
||||
connect( updateTimer, &QTimer::timeout, this, &ppuNameTableViewerDialog_t::periodicUpdate );
|
||||
|
||||
updateTimer->start( 33 ); // 30hz
|
||||
}
|
||||
//----------------------------------------------------
|
||||
ppuNameTableViewerDialog_t::~ppuNameTableViewerDialog_t(void)
|
||||
{
|
||||
updateTimer->stop();
|
||||
nameTableViewWindow = NULL;
|
||||
|
||||
printf("Name Table Viewer Window Deleted\n");
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ppuNameTableViewerDialog_t::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
printf("Name Table Viewer Close Window Event\n");
|
||||
done(0);
|
||||
deleteLater();
|
||||
event->accept();
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ppuNameTableViewerDialog_t::closeWindow(void)
|
||||
{
|
||||
printf("Close Window\n");
|
||||
done(0);
|
||||
deleteLater();
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ppuNameTableViewerDialog_t::periodicUpdate(void)
|
||||
{
|
||||
updateMirrorButtons();
|
||||
|
||||
if ( redrawtables )
|
||||
{
|
||||
this->update();
|
||||
redrawtables = false;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ppuNameTableViewerDialog_t::setPropertyLabels( int TileID, int TileX, int TileY, int NameTable, int PPUAddress, int AttAddress, int Attrib )
|
||||
{
|
||||
char stmp[64];
|
||||
|
||||
sprintf( stmp, "Tile ID: %02X", TileID);
|
||||
|
||||
tileID->setText( tr(stmp) );
|
||||
|
||||
sprintf( stmp, "X/Y : %0d/%0d", TileX, TileY);
|
||||
|
||||
tileXY->setText( tr(stmp) );
|
||||
|
||||
sprintf(stmp,"PPU Address: %04X",PPUAddress);
|
||||
|
||||
ppuAddrLbl->setText( tr(stmp) );
|
||||
|
||||
sprintf(stmp,"Attribute: %1X (%04X)",Attrib,AttAddress);
|
||||
|
||||
attrbLbl->setText( tr(stmp) );
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ppuNameTableViewerDialog_t::updateMirrorButtons(void)
|
||||
{
|
||||
switch ( ntmirroring )
|
||||
{
|
||||
default:
|
||||
case NT_NONE:
|
||||
break;
|
||||
case NT_HORIZONTAL:
|
||||
horzMirrorBtn->setChecked(true);
|
||||
break;
|
||||
case NT_VERTICAL:
|
||||
vertMirrorBtn->setChecked(true);
|
||||
break;
|
||||
case NT_FOUR_SCREEN:
|
||||
fourScreenBtn->setChecked(true);
|
||||
break;
|
||||
case NT_SINGLE_SCREEN_TABLE_0:
|
||||
case NT_SINGLE_SCREEN_TABLE_1:
|
||||
case NT_SINGLE_SCREEN_TABLE_2:
|
||||
case NT_SINGLE_SCREEN_TABLE_3:
|
||||
{
|
||||
int i = ntmirroring - NT_SINGLE_SCREEN_TABLE_0;
|
||||
|
||||
singleScreenBtn[i]->setChecked(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ppuNameTableViewerDialog_t::horzMirrorClicked(void)
|
||||
{
|
||||
ntmirroring = NT_HORIZONTAL;
|
||||
ChangeMirroring();
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ppuNameTableViewerDialog_t::vertMirrorClicked(void)
|
||||
{
|
||||
ntmirroring = NT_VERTICAL;
|
||||
ChangeMirroring();
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ppuNameTableViewerDialog_t::fourScreenClicked(void)
|
||||
{
|
||||
ntmirroring = NT_FOUR_SCREEN;
|
||||
ChangeMirroring();
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ppuNameTableViewerDialog_t::singleScreen0Clicked(void)
|
||||
{
|
||||
ntmirroring = NT_SINGLE_SCREEN_TABLE_0;
|
||||
ChangeMirroring();
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ppuNameTableViewerDialog_t::singleScreen1Clicked(void)
|
||||
{
|
||||
ntmirroring = NT_SINGLE_SCREEN_TABLE_1;
|
||||
ChangeMirroring();
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ppuNameTableViewerDialog_t::singleScreen2Clicked(void)
|
||||
{
|
||||
ntmirroring = NT_SINGLE_SCREEN_TABLE_2;
|
||||
ChangeMirroring();
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ppuNameTableViewerDialog_t::singleScreen3Clicked(void)
|
||||
{
|
||||
ntmirroring = NT_SINGLE_SCREEN_TABLE_3;
|
||||
ChangeMirroring();
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ppuNameTableViewerDialog_t::scanLineChanged( const QString &txt )
|
||||
{
|
||||
std::string s;
|
||||
|
||||
s = txt.toStdString();
|
||||
|
||||
if ( s.size() > 0 )
|
||||
{
|
||||
NTViewScanline = strtoul( s.c_str(), NULL, 10 );
|
||||
}
|
||||
//printf("ScanLine: '%s' %i\n", s.c_str(), PPUViewScanline );
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ppuNameTableViewerDialog_t::showScrollLinesChanged(int state)
|
||||
{
|
||||
drawScrollLines = (state != Qt::Unchecked);
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ppuNameTableViewerDialog_t::showAttrbChanged(int state)
|
||||
{
|
||||
attview = (state != Qt::Unchecked);
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ppuNameTableViewerDialog_t::ignorePaletteChanged(int state)
|
||||
{
|
||||
hidepal = (state != Qt::Unchecked);
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ppuNameTableViewerDialog_t::refreshSliderChanged(int value)
|
||||
{
|
||||
NTViewRefresh = value;
|
||||
}
|
||||
//----------------------------------------------------
|
||||
ppuNameTableView_t::ppuNameTableView_t(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
this->parent = (ppuNameTableViewerDialog_t*)parent;
|
||||
this->setFocusPolicy(Qt::StrongFocus);
|
||||
this->setMouseTracking(true);
|
||||
viewWidth = 256 * 2;
|
||||
viewHeight = 240 * 2;
|
||||
setMinimumWidth( viewWidth );
|
||||
setMinimumHeight( viewHeight );
|
||||
}
|
||||
//----------------------------------------------------
|
||||
ppuNameTableView_t::~ppuNameTableView_t(void)
|
||||
{
|
||||
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ppuNameTableView_t::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
viewWidth = event->size().width();
|
||||
viewHeight = event->size().height();
|
||||
|
||||
//printf("%ix%i\n", viewWidth, viewHeight );
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ppuNameTableView_t::computeNameTableProperties( int x, int y )
|
||||
{
|
||||
int i, xx, yy, w, h, TileID, TileX, TileY, NameTable, PPUAddress, AttAddress, Attrib;
|
||||
ppuNameTable_t *tbl = NULL;
|
||||
|
||||
NameTable = 0;
|
||||
|
||||
if ( vnapage[0] == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (i=0; i<4; i++)
|
||||
{
|
||||
xx = nameTable[i].x;
|
||||
yy = nameTable[i].y;
|
||||
w = (nameTable[i].w * 256);
|
||||
h = (nameTable[i].h * 240);
|
||||
|
||||
if ( (x >= xx) && (x < (xx+w) ) &&
|
||||
(y >= yy) && (y < (yy+h) ) )
|
||||
{
|
||||
tbl = &nameTable[i];
|
||||
NameTable = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( tbl == NULL )
|
||||
{
|
||||
//printf("Mouse not over a tile\n");
|
||||
return;
|
||||
}
|
||||
xx = tbl->x; yy = tbl->y;
|
||||
w = tbl->w; h = tbl->h;
|
||||
|
||||
if ( (NameTable%2) == 1 )
|
||||
{
|
||||
TileX = ((x - xx) / (w*8)) + 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
TileX = (x - xx) / (w*8);
|
||||
}
|
||||
|
||||
if ( (NameTable/2) == 1 )
|
||||
{
|
||||
TileY = ((y - yy) / (h*8)) + 30;
|
||||
}
|
||||
else
|
||||
{
|
||||
TileY = (y - yy) / (h*8);
|
||||
}
|
||||
|
||||
PPUAddress = 0x2000+(NameTable*0x400)+((TileY%30)*32)+(TileX%32);
|
||||
|
||||
TileID = vnapage[(PPUAddress>>10)&0x3][PPUAddress&0x3FF];
|
||||
|
||||
AttAddress = 0x23C0 | (PPUAddress & 0x0C00) | ((PPUAddress >> 4) & 0x38) | ((PPUAddress >> 2) & 0x07);
|
||||
Attrib = vnapage[(AttAddress>>10)&0x3][AttAddress&0x3FF];
|
||||
Attrib = (Attrib >> ((PPUAddress&2) | ((PPUAddress&64)>>4))) & 0x3;
|
||||
|
||||
//printf("NT:%i Tile X/Y : %i/%i \n", NameTable, TileX, TileY );
|
||||
|
||||
if ( parent )
|
||||
{
|
||||
parent->setPropertyLabels( TileID, TileX, TileY, NameTable, PPUAddress, AttAddress, Attrib );
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ppuNameTableView_t::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
computeNameTableProperties( event->pos().x(), event->pos().y() );
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void ppuNameTableView_t::mousePressEvent(QMouseEvent * event)
|
||||
{
|
||||
//QPoint tile = convPixToTile( event->pos() );
|
||||
|
||||
if ( event->button() == Qt::LeftButton )
|
||||
{
|
||||
}
|
||||
else if ( event->button() == Qt::RightButton )
|
||||
{
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void ppuNameTableView_t::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
ppuNameTable_t *nt;
|
||||
int n,i,j,ii,jj,w,h,x,y,xx,yy,ww,hh;
|
||||
QPainter painter(this);
|
||||
QColor scanLineColor(255,255,255);
|
||||
viewWidth = event->rect().width();
|
||||
viewHeight = event->rect().height();
|
||||
|
||||
w = viewWidth / (256*2);
|
||||
h = viewHeight / (240*2);
|
||||
|
||||
//printf("%ix%i\n", viewWidth, viewHeight );
|
||||
|
||||
xx = 0; yy = 0;
|
||||
|
||||
for (n=0; n<4; n++)
|
||||
{
|
||||
nt = &nameTable[n];
|
||||
|
||||
nt->w = w; nt->h = h;
|
||||
|
||||
nt->x = xx = (n%2) * (viewWidth / 2);
|
||||
nt->y = yy = (n/2) * (viewHeight / 2);
|
||||
|
||||
for (j=0; j<30; j++)
|
||||
{
|
||||
jj = (j*8);
|
||||
|
||||
for (i=0; i<32; i++)
|
||||
{
|
||||
ii = (i*8);
|
||||
|
||||
nt->tile[j][i].x = xx+(ii*w);
|
||||
nt->tile[j][i].y = yy+(jj*h);
|
||||
|
||||
for (y=0; y<8; y++)
|
||||
{
|
||||
for (x=0; x<8; x++)
|
||||
{
|
||||
painter.fillRect( xx+(ii+x)*w, yy+(jj+y)*h, w, h, nt->tile[j][i].pixel[y][x].color );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( drawScrollLines )
|
||||
{
|
||||
ww = nt->w * 256;
|
||||
hh = nt->h * 240;
|
||||
|
||||
painter.setPen( scanLineColor );
|
||||
|
||||
if ( (xpos >= xx) && (xpos < (xx+ww)) )
|
||||
{
|
||||
painter.drawLine( xpos, yy, xpos, yy + hh );
|
||||
}
|
||||
|
||||
if ( (ypos >= yy) && (ypos < (yy+hh)) )
|
||||
{
|
||||
painter.drawLine( xx, ypos, xx + ww, ypos );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//----------------------------------------------------
|
||||
static void initNameTableViewer(void)
|
||||
{
|
||||
//clear cache
|
||||
memset(palcache,0,32);
|
||||
|
||||
// forced palette (e.g. for debugging nametables when palettes are all-black)
|
||||
palcache[(8*4)+0] = 0x0F;
|
||||
palcache[(8*4)+1] = 0x00;
|
||||
palcache[(8*4)+2] = 0x10;
|
||||
palcache[(8*4)+3] = 0x20;
|
||||
|
||||
}
|
||||
//----------------------------------------------------
|
||||
static void ChangeMirroring(void)
|
||||
{
|
||||
switch (ntmirroring)
|
||||
{
|
||||
case NT_HORIZONTAL:
|
||||
vnapage[0] = vnapage[1] = &NTARAM[0x000];
|
||||
vnapage[2] = vnapage[3] = &NTARAM[0x400];
|
||||
break;
|
||||
case NT_VERTICAL:
|
||||
vnapage[0] = vnapage[2] = &NTARAM[0x000];
|
||||
vnapage[1] = vnapage[3] = &NTARAM[0x400];
|
||||
break;
|
||||
case NT_FOUR_SCREEN:
|
||||
vnapage[0] = &NTARAM[0x000];
|
||||
vnapage[1] = &NTARAM[0x400];
|
||||
if(ExtraNTARAM)
|
||||
{
|
||||
vnapage[2] = ExtraNTARAM;
|
||||
vnapage[3] = ExtraNTARAM + 0x400;
|
||||
}
|
||||
break;
|
||||
case NT_SINGLE_SCREEN_TABLE_0:
|
||||
vnapage[0] = vnapage[1] = vnapage[2] = vnapage[3] = &NTARAM[0x000];
|
||||
break;
|
||||
case NT_SINGLE_SCREEN_TABLE_1:
|
||||
vnapage[0] = vnapage[1] = vnapage[2] = vnapage[3] = &NTARAM[0x400];
|
||||
break;
|
||||
case NT_SINGLE_SCREEN_TABLE_2:
|
||||
if(ExtraNTARAM)
|
||||
vnapage[0] = vnapage[1] = vnapage[2] = vnapage[3] = ExtraNTARAM;
|
||||
break;
|
||||
case NT_SINGLE_SCREEN_TABLE_3:
|
||||
if(ExtraNTARAM)
|
||||
vnapage[0] = vnapage[1] = vnapage[2] = vnapage[3] = ExtraNTARAM + 0x400;
|
||||
break;
|
||||
default:
|
||||
case NT_NONE:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
//----------------------------------------------------
|
||||
inline void DrawChr( ppuNameTableTile_t *tile, const uint8_t *chr, int pal)
|
||||
{
|
||||
int y, x, tmp, index=0, p=0;
|
||||
uint8 chr0, chr1;
|
||||
//uint8 *table = &VPage[0][0]; //use the background table
|
||||
//pbitmap += 3*
|
||||
|
||||
for (y = 0; y < 8; y++) { //todo: use index for y?
|
||||
chr0 = chr[index];
|
||||
chr1 = chr[index+8];
|
||||
tmp=7;
|
||||
for (x = 0; x < 8; x++) { //todo: use tmp for x?
|
||||
p = (chr0>>tmp)&1;
|
||||
p |= ((chr1>>tmp)&1)<<1;
|
||||
p = palcache[p+(pal*4)];
|
||||
tmp--;
|
||||
|
||||
tile->pixel[y][x].color.setBlue( palo[p].b );
|
||||
tile->pixel[y][x].color.setGreen( palo[p].g );
|
||||
tile->pixel[y][x].color.setRed( palo[p].r );
|
||||
}
|
||||
index++;
|
||||
//pbitmap += (NTWIDTH*3)-24;
|
||||
}
|
||||
//index+=8;
|
||||
//pbitmap -= (((PALETTEBITWIDTH>>2)<<3)-24);
|
||||
}
|
||||
//----------------------------------------------------
|
||||
static void DrawNameTable(int scanline, int ntnum, bool invalidateCache)
|
||||
{
|
||||
NTCache &c = cache[ntnum];
|
||||
uint8_t *tablecache = c.cache;
|
||||
|
||||
uint8_t *table = vnapage[ntnum];
|
||||
if (table == NULL)
|
||||
{
|
||||
table = vnapage[ntnum&1];
|
||||
}
|
||||
|
||||
int a, ptable=0;
|
||||
|
||||
if (PPU[0]&0x10){ //use the correct pattern table based on this bit
|
||||
ptable=0x1000;
|
||||
}
|
||||
|
||||
bool invalid = invalidateCache;
|
||||
//if we werent asked to invalidate the cache, maybe we need to invalidate it anyway due to vnapage changing
|
||||
if (!invalid)
|
||||
{
|
||||
invalid = (c.curr_vnapage != vnapage[ntnum]);
|
||||
}
|
||||
c.curr_vnapage = vnapage[ntnum];
|
||||
|
||||
//HACK: never cache anything
|
||||
invalid = true;
|
||||
|
||||
for (int y=0;y<30;y++)
|
||||
{
|
||||
for (int x=0;x<32;x++)
|
||||
{
|
||||
int ntaddr = (y*32)+x;
|
||||
int attraddr = 0x3C0+((y>>2)<<3)+(x>>2);
|
||||
if (invalid
|
||||
|| (table[ntaddr] != tablecache[ntaddr])
|
||||
|| (table[attraddr] != tablecache[attraddr]))
|
||||
{
|
||||
int temp = (((y&2)<<1)+(x&2));
|
||||
a = (table[attraddr] & (3<<temp)) >> temp;
|
||||
|
||||
//the commented out code below is all allegedly equivalent to the single line above:
|
||||
//tmpx = x>>2;
|
||||
//tmpy = y>>2;
|
||||
//a = 0x3C0+(tmpy*8)+tmpx;
|
||||
//if((((x>>1)&1) == 0) && (((y>>1)&1) == 0)) a = table[a]&0x3;
|
||||
//if((((x>>1)&1) == 1) && (((y>>1)&1) == 0)) a = (table[a]&0xC)>>2;
|
||||
//if((((x>>1)&1) == 0) && (((y>>1)&1) == 1)) a = (table[a]&0x30)>>4;
|
||||
//if((((x>>1)&1) == 1) && (((y>>1)&1) == 1)) a = (table[a]&0xC0)>>6;
|
||||
|
||||
int chr = table[ntaddr]*16;
|
||||
|
||||
extern int FCEUPPU_GetAttr(int ntnum, int xt, int yt);
|
||||
|
||||
//test.. instead of pretending that the nametable is a screen at 0,0 we pretend that it is at the current xscroll and yscroll
|
||||
//int xpos = ((RefreshAddr & 0x400) >> 2) | ((RefreshAddr & 0x1F) << 3) | XOffset;
|
||||
//int ypos = ((RefreshAddr & 0x3E0) >> 2) | ((RefreshAddr & 0x7000) >> 12);
|
||||
//if(RefreshAddr & 0x800) ypos += 240;
|
||||
//int refreshaddr = (xpos/8+x)+(ypos/8+y)*32;
|
||||
|
||||
int refreshaddr = (x)+(y)*32;
|
||||
|
||||
a = FCEUPPU_GetAttr(ntnum,x,y);
|
||||
if (hidepal) a = 8;
|
||||
|
||||
const uint8* chrp = FCEUPPU_GetCHR(ptable+chr,refreshaddr);
|
||||
if (attview) chrp = ATTRIBUTE_VIEW_TILE;
|
||||
|
||||
//a good way to do it:
|
||||
DrawChr( &nameTable[ntnum].tile[y][x], chrp, a);
|
||||
|
||||
tablecache[ntaddr] = table[ntaddr];
|
||||
tablecache[attraddr] = table[attraddr];
|
||||
//one could comment out the line above...
|
||||
//since there are so many fewer attribute values than NT values, it might be best just to refresh the whole attr table below with the memcpy
|
||||
|
||||
//obviously this whole scheme of nt cache doesnt work if an mmc5 game is playing tricks with the attribute table
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------
|
||||
void FCEUD_UpdateNTView(int scanline, bool drawall)
|
||||
{
|
||||
if (nameTableViewWindow == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( (scanline != -1) && (scanline != NTViewScanline) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ppu_getScroll(xpos,ypos);
|
||||
|
||||
if (NTViewSkip < NTViewRefresh)
|
||||
{
|
||||
NTViewSkip++;
|
||||
return;
|
||||
}
|
||||
NTViewSkip = 0;
|
||||
|
||||
if (chrchanged)
|
||||
{
|
||||
drawall = 1;
|
||||
}
|
||||
|
||||
//update palette only if required
|
||||
if (memcmp(palcache,PALRAM,32) != 0)
|
||||
{
|
||||
memcpy(palcache,PALRAM,32);
|
||||
drawall = 1; //palette has changed, so redraw all
|
||||
}
|
||||
|
||||
if ( vnapage[0] == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ntmirroring = NT_NONE;
|
||||
if (vnapage[0] == vnapage[1])ntmirroring = NT_HORIZONTAL;
|
||||
if (vnapage[0] == vnapage[2])ntmirroring = NT_VERTICAL;
|
||||
if ((vnapage[0] != vnapage[1]) && (vnapage[0] != vnapage[2]))ntmirroring = NT_FOUR_SCREEN;
|
||||
|
||||
if ((vnapage[0] == vnapage[1]) && (vnapage[1] == vnapage[2]) && (vnapage[2] == vnapage[3]))
|
||||
{
|
||||
if(vnapage[0] == &NTARAM[0x000])ntmirroring = NT_SINGLE_SCREEN_TABLE_0;
|
||||
if(vnapage[0] == &NTARAM[0x400])ntmirroring = NT_SINGLE_SCREEN_TABLE_1;
|
||||
if(vnapage[0] == ExtraNTARAM)ntmirroring = NT_SINGLE_SCREEN_TABLE_2;
|
||||
if(vnapage[0] == ExtraNTARAM+0x400)ntmirroring = NT_SINGLE_SCREEN_TABLE_3;
|
||||
}
|
||||
|
||||
if (oldntmirroring != ntmirroring)
|
||||
{
|
||||
//UpdateMirroringButtons();
|
||||
oldntmirroring = ntmirroring;
|
||||
}
|
||||
|
||||
for (int i=0;i<4;i++)
|
||||
{
|
||||
DrawNameTable(scanline,i,drawall);
|
||||
}
|
||||
|
||||
chrchanged = 0;
|
||||
redrawtables = true;
|
||||
return;
|
||||
}
|
||||
//----------------------------------------------------
|
|
@ -0,0 +1,114 @@
|
|||
// NameTableViewer.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDialog>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
#include <QRadioButton>
|
||||
#include <QLabel>
|
||||
#include <QFrame>
|
||||
#include <QTimer>
|
||||
#include <QSlider>
|
||||
#include <QLineEdit>
|
||||
#include <QGroupBox>
|
||||
#include <QCloseEvent>
|
||||
|
||||
struct ppuNameTablePixel_t
|
||||
{
|
||||
QColor color;
|
||||
};
|
||||
|
||||
struct ppuNameTableTile_t
|
||||
{
|
||||
struct ppuNameTablePixel_t pixel[8][8];
|
||||
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
struct ppuNameTable_t
|
||||
{
|
||||
struct ppuNameTableTile_t tile[30][32];
|
||||
|
||||
int x;
|
||||
int y;
|
||||
int w;
|
||||
int h;
|
||||
};
|
||||
|
||||
class ppuNameTableViewerDialog_t;
|
||||
|
||||
class ppuNameTableView_t : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ppuNameTableView_t( QWidget *parent = 0);
|
||||
~ppuNameTableView_t(void);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event);
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
void mouseMoveEvent(QMouseEvent *event);
|
||||
void mousePressEvent(QMouseEvent * event);
|
||||
void computeNameTableProperties( int x, int y );
|
||||
|
||||
ppuNameTableViewerDialog_t *parent;
|
||||
int viewWidth;
|
||||
int viewHeight;
|
||||
};
|
||||
|
||||
class ppuNameTableViewerDialog_t : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ppuNameTableViewerDialog_t(QWidget *parent = 0);
|
||||
~ppuNameTableViewerDialog_t(void);
|
||||
|
||||
void setPropertyLabels( int TileID, int TileX, int TileY, int NameTable, int PPUAddress, int AttAddress, int Attrib );
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *bar);
|
||||
|
||||
ppuNameTableView_t *ntView;
|
||||
QCheckBox *showScrollLineCbox;
|
||||
QCheckBox *showAttrbCbox;
|
||||
QCheckBox *ignorePaletteCbox;
|
||||
QSlider *refreshSlider;
|
||||
QLineEdit *scanLineEdit;
|
||||
QTimer *updateTimer;
|
||||
QRadioButton *horzMirrorBtn;
|
||||
QRadioButton *vertMirrorBtn;
|
||||
QRadioButton *fourScreenBtn;
|
||||
QRadioButton *singleScreenBtn[4];
|
||||
QLabel *tileID;
|
||||
QLabel *tileXY;
|
||||
QLabel *ppuAddrLbl;
|
||||
QLabel *attrbLbl;
|
||||
|
||||
public slots:
|
||||
void closeWindow(void);
|
||||
private slots:
|
||||
void periodicUpdate(void);
|
||||
void updateMirrorButtons(void);
|
||||
void horzMirrorClicked(void);
|
||||
void vertMirrorClicked(void);
|
||||
void fourScreenClicked(void);
|
||||
void singleScreen0Clicked(void);
|
||||
void singleScreen1Clicked(void);
|
||||
void singleScreen2Clicked(void);
|
||||
void singleScreen3Clicked(void);
|
||||
void showAttrbChanged(int state);
|
||||
void ignorePaletteChanged(int state);
|
||||
void showScrollLinesChanged(int state);
|
||||
void refreshSliderChanged(int value);
|
||||
void scanLineChanged( const QString &txt );
|
||||
};
|
||||
|
||||
int openNameTableViewWindow( QWidget *parent );
|
||||
|
|
@ -32,10 +32,13 @@ PaletteConfDialog_t::PaletteConfDialog_t(QWidget *parent)
|
|||
//QPushButton *closebutton;
|
||||
QPushButton *button;
|
||||
QTextEdit *comments;
|
||||
QStyle *style;
|
||||
int hue, tint;
|
||||
char stmp[64];
|
||||
std::string paletteFile;
|
||||
|
||||
style = this->style();
|
||||
|
||||
resize( 512, 600 );
|
||||
|
||||
// sync with config
|
||||
|
@ -63,6 +66,7 @@ PaletteConfDialog_t::PaletteConfDialog_t(QWidget *parent)
|
|||
connect(deemphSwap, SIGNAL(stateChanged(int)), this, SLOT(deemphswap_Changed(int)) );
|
||||
|
||||
button = new QPushButton( tr("Open Palette") );
|
||||
button->setIcon( style->standardIcon( QStyle::SP_FileDialogStart ) );
|
||||
hbox1->addWidget( button );
|
||||
|
||||
connect( button, SIGNAL(clicked(void)), this, SLOT(openPaletteFile(void)) );
|
||||
|
@ -81,6 +85,7 @@ PaletteConfDialog_t::PaletteConfDialog_t(QWidget *parent)
|
|||
|
||||
|
||||
button = new QPushButton( tr("Clear") );
|
||||
button->setIcon( style->standardIcon( QStyle::SP_LineEditClearButton ) );
|
||||
hbox1->addWidget( button );
|
||||
|
||||
connect( button, SIGNAL(clicked(void)), this, SLOT(clearPalette(void)) );
|
||||
|
@ -308,7 +313,7 @@ void PaletteConfDialog_t::openPaletteFile(void)
|
|||
dialog.setNameFilter(tr("NES Palettes (*.pal *.PAL) ;; All files (*)"));
|
||||
|
||||
dialog.setViewMode(QFileDialog::List);
|
||||
dialog.setFilter( QDir::AllEntries | QDir::Hidden );
|
||||
dialog.setFilter( QDir::AllEntries | QDir::AllDirs | QDir::Hidden );
|
||||
dialog.setLabelText( QFileDialog::Accept, tr("Load") );
|
||||
|
||||
g_config->getOption ("SDL.Palette", &last );
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
// RamSearch.h
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <QWidget>
|
||||
#include <QDialog>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
#include <QRadioButton>
|
||||
#include <QLabel>
|
||||
#include <QFrame>
|
||||
#include <QGroupBox>
|
||||
#include <QScrollBar>
|
||||
|
||||
#include "Qt/main.h"
|
||||
|
||||
class QRamSearchView : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QRamSearchView(QWidget *parent = 0);
|
||||
~QRamSearchView(void);
|
||||
|
||||
void setScrollBars( QScrollBar *hbar, QScrollBar *vbar );
|
||||
|
||||
int getSelAddr(void){ return selAddr; }
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event);
|
||||
void keyPressEvent(QKeyEvent *event);
|
||||
//void keyReleaseEvent(QKeyEvent *event);
|
||||
void mousePressEvent(QMouseEvent * event);
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
void wheelEvent(QWheelEvent *event);
|
||||
|
||||
int convPixToLine( QPoint p );
|
||||
void calcFontData(void);
|
||||
|
||||
QFont font;
|
||||
QScrollBar *vbar;
|
||||
QScrollBar *hbar;
|
||||
|
||||
int lineOffset;
|
||||
int maxLineOffset;
|
||||
int pxCharWidth;
|
||||
int pxCharHeight;
|
||||
int pxLineSpacing;
|
||||
int pxLineLead;
|
||||
int pxCursorHeight;
|
||||
int pxLineXScroll;
|
||||
int pxLineWidth;
|
||||
int pxColWidth[4];
|
||||
int viewLines;
|
||||
int viewWidth;
|
||||
int viewHeight;
|
||||
int selAddr;
|
||||
int selLine;
|
||||
int wheelPixelCounter;
|
||||
};
|
||||
|
||||
class RamSearchDialog_t : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RamSearchDialog_t(QWidget *parent = 0);
|
||||
~RamSearchDialog_t(void);
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event);
|
||||
|
||||
QRamSearchView *ramView;
|
||||
QScrollBar *vbar;
|
||||
QScrollBar *hbar;
|
||||
QTimer *updateTimer;
|
||||
QPushButton *searchButton;
|
||||
QPushButton *resetButton;
|
||||
QPushButton *clearChangeButton;
|
||||
QPushButton *undoButton;
|
||||
QPushButton *elimButton;
|
||||
QPushButton *watchButton;
|
||||
QPushButton *addCheatButton;
|
||||
QPushButton *hexEditButton;
|
||||
|
||||
QRadioButton *lt_btn;
|
||||
QRadioButton *gt_btn;
|
||||
QRadioButton *le_btn;
|
||||
QRadioButton *ge_btn;
|
||||
QRadioButton *eq_btn;
|
||||
QRadioButton *ne_btn;
|
||||
QRadioButton *df_btn;
|
||||
QRadioButton *md_btn;
|
||||
|
||||
QRadioButton *pv_btn;
|
||||
QRadioButton *sv_btn;
|
||||
QRadioButton *sa_btn;
|
||||
QRadioButton *nc_btn;
|
||||
|
||||
QRadioButton *ds1_btn;
|
||||
QRadioButton *ds2_btn;
|
||||
QRadioButton *ds4_btn;
|
||||
|
||||
QRadioButton *signed_btn;
|
||||
QRadioButton *unsigned_btn;
|
||||
QRadioButton *hex_btn;
|
||||
|
||||
QLineEdit *diffByEdit;
|
||||
QLineEdit *moduloEdit;
|
||||
QLineEdit *specValEdit;
|
||||
QLineEdit *specAddrEdit;
|
||||
QLineEdit *numChangeEdit;
|
||||
|
||||
QCheckBox *searchROMCbox;
|
||||
QCheckBox *misalignedCbox;
|
||||
QCheckBox *autoSearchCbox;
|
||||
|
||||
int fontCharWidth;
|
||||
int frameCounterLastPass;
|
||||
unsigned int cycleCounter;
|
||||
|
||||
|
||||
private:
|
||||
void updateRamValues(void);
|
||||
void calcRamList(void);
|
||||
void SearchRelative(void);
|
||||
void SearchSpecificValue(void);
|
||||
void SearchSpecificAddress(void);
|
||||
void SearchNumberChanges(void);
|
||||
|
||||
public slots:
|
||||
void closeWindow(void);
|
||||
private slots:
|
||||
void runSearch(void);
|
||||
void resetSearch(void);
|
||||
void undoSearch(void);
|
||||
void clearChangeCounts(void);
|
||||
void eliminateSelAddr(void);
|
||||
void hexEditSelAddr(void);
|
||||
void addCheatClicked(void);
|
||||
void addRamWatchClicked(void);
|
||||
void periodicUpdate(void);
|
||||
void hbarChanged(int val);
|
||||
void vbarChanged(int val);
|
||||
void searchROMChanged(int state);
|
||||
void misalignedChanged(int state);
|
||||
void ds1Clicked(void);
|
||||
void ds2Clicked(void);
|
||||
void ds4Clicked(void);
|
||||
void signedTypeClicked(void);
|
||||
void unsignedTypeClicked(void);
|
||||
void hexTypeClicked(void);
|
||||
void opLtClicked(void);
|
||||
void opGtClicked(void);
|
||||
void opLeClicked(void);
|
||||
void opGeClicked(void);
|
||||
void opEqClicked(void);
|
||||
void opNeClicked(void);
|
||||
void opDfClicked(void);
|
||||
void opMdClicked(void);
|
||||
void pvBtnClicked(void);
|
||||
void svBtnClicked(void);
|
||||
void saBtnClicked(void);
|
||||
void ncBtnClicked(void);
|
||||
|
||||
};
|
||||
|
||||
void openRamSearchWindow(QWidget *parent);
|
|
@ -0,0 +1,258 @@
|
|||
// RamWatch.h
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <QWidget>
|
||||
#include <QDialog>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
#include <QLabel>
|
||||
#include <QFrame>
|
||||
#include <QGroupBox>
|
||||
#include <QTreeView>
|
||||
#include <QTreeWidget>
|
||||
|
||||
#include "Qt/main.h"
|
||||
|
||||
struct ramWatch_t
|
||||
{
|
||||
std::string name;
|
||||
int addr;
|
||||
int type;
|
||||
int size;
|
||||
int isSep;
|
||||
|
||||
union
|
||||
{
|
||||
int8_t i8;
|
||||
uint8_t u8;
|
||||
int16_t i16;
|
||||
uint16_t u16;
|
||||
int32_t i32;
|
||||
uint32_t u32;
|
||||
} val;
|
||||
|
||||
ramWatch_t (void)
|
||||
{
|
||||
addr = 0;
|
||||
type = 's';
|
||||
size = 0;
|
||||
isSep = 0;
|
||||
val.u32 = 0;
|
||||
};
|
||||
|
||||
void updateMem (void);
|
||||
};
|
||||
|
||||
struct ramWatchList_t
|
||||
{
|
||||
|
||||
std::list <ramWatch_t*> ls;
|
||||
|
||||
ramWatchList_t (void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
~ramWatchList_t (void)
|
||||
{
|
||||
ramWatch_t *rw;
|
||||
|
||||
while (!ls.empty ())
|
||||
{
|
||||
rw = ls.front ();
|
||||
|
||||
delete rw;
|
||||
|
||||
ls.pop_front ();
|
||||
}
|
||||
}
|
||||
|
||||
size_t size (void)
|
||||
{
|
||||
return ls.size ();
|
||||
};
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
ramWatch_t *rw;
|
||||
|
||||
while (!ls.empty ())
|
||||
{
|
||||
rw = ls.front ();
|
||||
|
||||
delete rw;
|
||||
|
||||
ls.pop_front ();
|
||||
}
|
||||
}
|
||||
|
||||
void add_entry (const char *name, int addr, int type, int size, int isSep = 0)
|
||||
{
|
||||
ramWatch_t *rw = new ramWatch_t;
|
||||
|
||||
rw->name.assign (name);
|
||||
rw->addr = addr;
|
||||
rw->type = type;
|
||||
rw->size = size;
|
||||
rw->isSep = isSep;
|
||||
ls.push_back (rw);
|
||||
}
|
||||
|
||||
void updateMemoryValues (void)
|
||||
{
|
||||
ramWatch_t *rw;
|
||||
std::list < ramWatch_t * >::iterator it;
|
||||
|
||||
for (it = ls.begin (); it != ls.end (); it++)
|
||||
{
|
||||
rw = *it;
|
||||
|
||||
rw->updateMem ();
|
||||
}
|
||||
}
|
||||
|
||||
ramWatch_t *getIndex (size_t idx)
|
||||
{
|
||||
size_t i = 0;
|
||||
std::list < ramWatch_t * >::iterator it;
|
||||
|
||||
for (it = ls.begin (); it != ls.end (); it++)
|
||||
{
|
||||
if (i == idx)
|
||||
{
|
||||
return *it;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int deleteIndex (size_t idx)
|
||||
{
|
||||
size_t i = 0;
|
||||
std::list < ramWatch_t * >::iterator it;
|
||||
|
||||
for (it = ls.begin (); it != ls.end (); it++)
|
||||
{
|
||||
if (i == idx)
|
||||
{
|
||||
delete *it;
|
||||
ls.erase (it);
|
||||
return 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int moveIndexUp(size_t idx)
|
||||
{
|
||||
size_t i = 0;
|
||||
std::list < ramWatch_t * >::iterator it, lp;
|
||||
|
||||
lp = ls.begin();
|
||||
|
||||
for (it = ls.begin (); it != ls.end (); it++)
|
||||
{
|
||||
if (i == idx)
|
||||
{
|
||||
ls.insert( lp, *it );
|
||||
ls.erase (it);
|
||||
return 0;
|
||||
}
|
||||
lp = it;
|
||||
|
||||
i++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int moveIndexDown(size_t idx)
|
||||
{
|
||||
size_t i = 0;
|
||||
std::list < ramWatch_t * >::iterator it, next;
|
||||
|
||||
for (it = ls.begin (); it != ls.end (); it++)
|
||||
{
|
||||
if (i == idx)
|
||||
{
|
||||
next = it; next++;
|
||||
|
||||
if ( next != ls.end() )
|
||||
{
|
||||
ls.insert( it, *next );
|
||||
ls.erase (next);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
class RamWatchDialog_t : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RamWatchDialog_t(QWidget *parent = 0);
|
||||
~RamWatchDialog_t(void);
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event);
|
||||
void loadWatchFile (const char *filename, int append = 0);
|
||||
void saveWatchFile (const char *filename, int append = 0);
|
||||
|
||||
QFont font;
|
||||
QTreeWidget *tree;
|
||||
QPushButton *up_btn;
|
||||
QPushButton *down_btn;
|
||||
QPushButton *edit_btn;
|
||||
QPushButton *del_btn;
|
||||
QPushButton *new_btn;
|
||||
QPushButton *dup_btn;
|
||||
QPushButton *sep_btn;
|
||||
QPushButton *cht_btn;
|
||||
QTimer *updateTimer;
|
||||
|
||||
std::string saveFileName;
|
||||
|
||||
//ramWatchList_t ramWatchList;
|
||||
|
||||
int fontCharWidth;
|
||||
|
||||
private:
|
||||
void updateRamWatchDisplay(void);
|
||||
void openWatchEditWindow( ramWatch_t *rw = NULL, int mode = 0);
|
||||
|
||||
public slots:
|
||||
void closeWindow(void);
|
||||
private slots:
|
||||
void newListCB(void);
|
||||
void openListCB(void);
|
||||
void saveListCB(void);
|
||||
void saveListAs(void);
|
||||
void appendListCB(void);
|
||||
void periodicUpdate(void);
|
||||
void addCheatClicked(void);
|
||||
void newWatchClicked(void);
|
||||
void sepWatchClicked(void);
|
||||
void dupWatchClicked(void);
|
||||
void editWatchClicked(void);
|
||||
void removeWatchClicked(void);
|
||||
void moveWatchUpClicked(void);
|
||||
void moveWatchDownClicked(void);
|
||||
void watchClicked( QTreeWidgetItem *item, int column);
|
||||
|
||||
};
|
||||
|
||||
extern ramWatchList_t ramWatchList;
|
||||
|
||||
void openRamWatchWindow( QWidget *parent, int force = 0 );
|
|
@ -9,6 +9,8 @@
|
|||
#include "../../driver.h"
|
||||
#include "../../cart.h"
|
||||
#include "../../ines.h"
|
||||
#include "../../asm.h"
|
||||
#include "../../x6502.h"
|
||||
|
||||
#include "Qt/SymbolicDebug.h"
|
||||
#include "Qt/ConsoleUtilities.h"
|
||||
|
@ -301,7 +303,7 @@ int debugSymbolTable_t::loadFileNL( int bank )
|
|||
while ( fgets( line, sizeof(line), fp ) != 0 )
|
||||
{
|
||||
i=0; lineNum++;
|
||||
printf("%4i:%s", lineNum, line );
|
||||
//printf("%4i:%s", lineNum, line );
|
||||
|
||||
if ( line[i] == '\\' )
|
||||
{
|
||||
|
@ -471,6 +473,52 @@ int debugSymbolTable_t::loadFileNL( int bank )
|
|||
return 0;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
int debugSymbolTable_t::loadRegisterMap(void)
|
||||
{
|
||||
debugSymbolPage_t *page;
|
||||
|
||||
page = new debugSymbolPage_t();
|
||||
|
||||
page->pageNum = -2;
|
||||
|
||||
page->addSymbol( new debugSymbol_t( 0x2000, "PPU_CTRL" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x2001, "PPU_MASK" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x2002, "PPU_STATUS" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x2003, "PPU_OAM_ADDR" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x2004, "PPU_OAM_DATA" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x2005, "PPU_SCROLL" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x2006, "PPU_ADDRESS" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x2007, "PPU_DATA" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4000, "SQ1_VOL" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4001, "SQ1_SWEEP" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4002, "SQ1_LO" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4003, "SQ1_HI" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4004, "SQ2_VOL" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4005, "SQ2_SWEEP" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4006, "SQ2_LO" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4007, "SQ2_HI" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4008, "TRI_LINEAR" ) );
|
||||
// page->addSymbol( new debugSymbol_t( 0x4009, "UNUSED" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x400A, "TRI_LO" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x400B, "TRI_HI" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x400C, "NOISE_VOL" ) );
|
||||
// page->addSymbol( new debugSymbol_t( 0x400D, "UNUSED" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x400E, "NOISE_LO" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x400F, "NOISE_HI" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4010, "DMC_FREQ" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4011, "DMC_RAW" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4012, "DMC_START" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4013, "DMC_LEN" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4014, "OAM_DMA" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4015, "APU_STATUS" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4016, "JOY1" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4017, "JOY2_FRAME" ) );
|
||||
|
||||
pageMap[ page->pageNum ] = page;
|
||||
|
||||
return 0;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
int debugSymbolTable_t::loadGameSymbols(void)
|
||||
{
|
||||
int nPages, pageSize, romSize = 0x10000;
|
||||
|
@ -485,12 +533,14 @@ int debugSymbolTable_t::loadGameSymbols(void)
|
|||
|
||||
loadFileNL( -1 );
|
||||
|
||||
loadRegisterMap();
|
||||
|
||||
pageSize = (1<<debuggerPageSize);
|
||||
|
||||
//nPages = 1<<(15-debuggerPageSize);
|
||||
nPages = romSize / pageSize;
|
||||
|
||||
printf("RomSize: %i NumPages: %i \n", romSize, nPages );
|
||||
//printf("RomSize: %i NumPages: %i \n", romSize, nPages );
|
||||
|
||||
for(int i=0;i<nPages;i++)
|
||||
{
|
||||
|
@ -499,7 +549,7 @@ int debugSymbolTable_t::loadGameSymbols(void)
|
|||
loadFileNL( i );
|
||||
}
|
||||
|
||||
print();
|
||||
//print();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -566,3 +616,441 @@ void debugSymbolTable_t::print(void)
|
|||
}
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
debugSymbol_t *replaceSymbols( int flags, int addr, char *str )
|
||||
{
|
||||
debugSymbol_t *sym;
|
||||
|
||||
if ( addr >= 0x8000 )
|
||||
{
|
||||
int bank = getBank(addr);
|
||||
|
||||
sym = debugSymbolTable.getSymbolAtBankOffset( bank, addr );
|
||||
}
|
||||
else
|
||||
{
|
||||
sym = debugSymbolTable.getSymbolAtBankOffset( -1, addr );
|
||||
|
||||
if ( (sym == NULL) && (flags & ASM_DEBUG_REGS) )
|
||||
{
|
||||
sym = debugSymbolTable.getSymbolAtBankOffset( -2, addr );
|
||||
}
|
||||
}
|
||||
|
||||
if ( sym )
|
||||
{
|
||||
if ( flags & ASM_DEBUG_REPLACE )
|
||||
{
|
||||
strcpy( str, sym->name.c_str() );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( flags & ASM_DEBUG_ADDR_02X )
|
||||
{
|
||||
sprintf( str, "%02X ", addr );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( str, "%04X ", addr );
|
||||
}
|
||||
strcat( str, sym->name.c_str() );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( flags & ASM_DEBUG_ADDR_02X )
|
||||
{
|
||||
sprintf( str, "%02X", addr );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( str, "%04X", addr );
|
||||
}
|
||||
}
|
||||
|
||||
return sym;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
int DisassembleWithDebug(int addr, uint8_t *opcode, int flags, char *str, debugSymbol_t *symOut, debugSymbol_t *symOut2 )
|
||||
{
|
||||
debugSymbol_t *sym = NULL;
|
||||
debugSymbol_t *sym2 = NULL;
|
||||
static char chr[8]={0};
|
||||
uint16_t tmp,tmp2;
|
||||
char stmp[128], stmp2[128];
|
||||
|
||||
//these may be replaced later with passed-in values to make a lighter-weight disassembly mode that may not query the referenced values
|
||||
#define RX (X.X)
|
||||
#define RY (X.Y)
|
||||
|
||||
switch (opcode[0])
|
||||
{
|
||||
#define relative(a) { \
|
||||
if (((a)=opcode[1])&0x80) (a) = addr-(((a)-1)^0xFF); \
|
||||
else (a)+=addr; \
|
||||
}
|
||||
#define absolute(a) { \
|
||||
(a) = opcode[1] | opcode[2]<<8; \
|
||||
}
|
||||
#define zpIndex(a,i) { \
|
||||
(a) = (opcode[1]+(i))&0xFF; \
|
||||
}
|
||||
#define indirectX(a) { \
|
||||
(a) = (opcode[1]+RX)&0xFF; \
|
||||
(a) = GetMem((a)) | (GetMem(((a)+1)&0xff))<<8; \
|
||||
}
|
||||
#define indirectY(a) { \
|
||||
(a) = GetMem(opcode[1]) | (GetMem((opcode[1]+1)&0xff))<<8; \
|
||||
(a) += RY; \
|
||||
}
|
||||
|
||||
|
||||
#ifdef BRK_3BYTE_HACK
|
||||
case 0x00:
|
||||
sprintf(str,"BRK %02X %02X", opcode[1], opcode[2]);
|
||||
break;
|
||||
#else
|
||||
case 0x00: strcpy(str,"BRK"); break;
|
||||
#endif
|
||||
|
||||
//odd, 1-byte opcodes
|
||||
case 0x08: strcpy(str,"PHP"); break;
|
||||
case 0x0A: strcpy(str,"ASL"); break;
|
||||
case 0x18: strcpy(str,"CLC"); break;
|
||||
case 0x28: strcpy(str,"PLP"); break;
|
||||
case 0x2A: strcpy(str,"ROL"); break;
|
||||
case 0x38: strcpy(str,"SEC"); break;
|
||||
case 0x40: strcpy(str,"RTI"); break;
|
||||
case 0x48: strcpy(str,"PHA"); break;
|
||||
case 0x4A: strcpy(str,"LSR"); break;
|
||||
case 0x58: strcpy(str,"CLI"); break;
|
||||
case 0x60: strcpy(str,"RTS"); break;
|
||||
case 0x68: strcpy(str,"PLA"); break;
|
||||
case 0x6A: strcpy(str,"ROR"); break;
|
||||
case 0x78: strcpy(str,"SEI"); break;
|
||||
case 0x88: strcpy(str,"DEY"); break;
|
||||
case 0x8A: strcpy(str,"TXA"); break;
|
||||
case 0x98: strcpy(str,"TYA"); break;
|
||||
case 0x9A: strcpy(str,"TXS"); break;
|
||||
case 0xA8: strcpy(str,"TAY"); break;
|
||||
case 0xAA: strcpy(str,"TAX"); break;
|
||||
case 0xB8: strcpy(str,"CLV"); break;
|
||||
case 0xBA: strcpy(str,"TSX"); break;
|
||||
case 0xC8: strcpy(str,"INY"); break;
|
||||
case 0xCA: strcpy(str,"DEX"); break;
|
||||
case 0xD8: strcpy(str,"CLD"); break;
|
||||
case 0xE8: strcpy(str,"INX"); break;
|
||||
case 0xEA: strcpy(str,"NOP"); break;
|
||||
case 0xF8: strcpy(str,"SED"); break;
|
||||
|
||||
//(Indirect,X)
|
||||
case 0x01: strcpy(chr,"ORA"); goto _indirectx;
|
||||
case 0x21: strcpy(chr,"AND"); goto _indirectx;
|
||||
case 0x41: strcpy(chr,"EOR"); goto _indirectx;
|
||||
case 0x61: strcpy(chr,"ADC"); goto _indirectx;
|
||||
case 0x81: strcpy(chr,"STA"); goto _indirectx;
|
||||
case 0xA1: strcpy(chr,"LDA"); goto _indirectx;
|
||||
case 0xC1: strcpy(chr,"CMP"); goto _indirectx;
|
||||
case 0xE1: strcpy(chr,"SBC"); goto _indirectx;
|
||||
_indirectx:
|
||||
indirectX(tmp);
|
||||
|
||||
if ( flags )
|
||||
{
|
||||
sym = replaceSymbols( flags, tmp, stmp );
|
||||
sprintf(str,"%s ($%02X,X) @ $%s = #$%02X", chr,opcode[1],stmp,GetMem(tmp));
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(str,"%s ($%02X,X) @ $%04X = #$%02X", chr,opcode[1],tmp,GetMem(tmp));
|
||||
}
|
||||
break;
|
||||
|
||||
//Zero Page
|
||||
case 0x05: strcpy(chr,"ORA"); goto _zeropage;
|
||||
case 0x06: strcpy(chr,"ASL"); goto _zeropage;
|
||||
case 0x24: strcpy(chr,"BIT"); goto _zeropage;
|
||||
case 0x25: strcpy(chr,"AND"); goto _zeropage;
|
||||
case 0x26: strcpy(chr,"ROL"); goto _zeropage;
|
||||
case 0x45: strcpy(chr,"EOR"); goto _zeropage;
|
||||
case 0x46: strcpy(chr,"LSR"); goto _zeropage;
|
||||
case 0x65: strcpy(chr,"ADC"); goto _zeropage;
|
||||
case 0x66: strcpy(chr,"ROR"); goto _zeropage;
|
||||
case 0x84: strcpy(chr,"STY"); goto _zeropage;
|
||||
case 0x85: strcpy(chr,"STA"); goto _zeropage;
|
||||
case 0x86: strcpy(chr,"STX"); goto _zeropage;
|
||||
case 0xA4: strcpy(chr,"LDY"); goto _zeropage;
|
||||
case 0xA5: strcpy(chr,"LDA"); goto _zeropage;
|
||||
case 0xA6: strcpy(chr,"LDX"); goto _zeropage;
|
||||
case 0xC4: strcpy(chr,"CPY"); goto _zeropage;
|
||||
case 0xC5: strcpy(chr,"CMP"); goto _zeropage;
|
||||
case 0xC6: strcpy(chr,"DEC"); goto _zeropage;
|
||||
case 0xE4: strcpy(chr,"CPX"); goto _zeropage;
|
||||
case 0xE5: strcpy(chr,"SBC"); goto _zeropage;
|
||||
case 0xE6: strcpy(chr,"INC"); goto _zeropage;
|
||||
_zeropage:
|
||||
// ################################## Start of SP CODE ###########################
|
||||
// Change width to %04X // don't!
|
||||
if ( flags )
|
||||
{
|
||||
sym = replaceSymbols( flags | ASM_DEBUG_ADDR_02X, opcode[1], stmp );
|
||||
sprintf(str,"%s $%s = #$%02X", chr,stmp,GetMem(opcode[1]));
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(str,"%s $%02X = #$%02X", chr,opcode[1],GetMem(opcode[1]));
|
||||
}
|
||||
// ################################## End of SP CODE ###########################
|
||||
break;
|
||||
|
||||
//#Immediate
|
||||
case 0x09: strcpy(chr,"ORA"); goto _immediate;
|
||||
case 0x29: strcpy(chr,"AND"); goto _immediate;
|
||||
case 0x49: strcpy(chr,"EOR"); goto _immediate;
|
||||
case 0x69: strcpy(chr,"ADC"); goto _immediate;
|
||||
//case 0x89: strcpy(chr,"STA"); goto _immediate; //baka, no STA #imm!!
|
||||
case 0xA0: strcpy(chr,"LDY"); goto _immediate;
|
||||
case 0xA2: strcpy(chr,"LDX"); goto _immediate;
|
||||
case 0xA9: strcpy(chr,"LDA"); goto _immediate;
|
||||
case 0xC0: strcpy(chr,"CPY"); goto _immediate;
|
||||
case 0xC9: strcpy(chr,"CMP"); goto _immediate;
|
||||
case 0xE0: strcpy(chr,"CPX"); goto _immediate;
|
||||
case 0xE9: strcpy(chr,"SBC"); goto _immediate;
|
||||
_immediate:
|
||||
sprintf(str,"%s #$%02X", chr,opcode[1]);
|
||||
break;
|
||||
|
||||
//Absolute
|
||||
case 0x0D: strcpy(chr,"ORA"); goto _absolute;
|
||||
case 0x0E: strcpy(chr,"ASL"); goto _absolute;
|
||||
case 0x2C: strcpy(chr,"BIT"); goto _absolute;
|
||||
case 0x2D: strcpy(chr,"AND"); goto _absolute;
|
||||
case 0x2E: strcpy(chr,"ROL"); goto _absolute;
|
||||
case 0x4D: strcpy(chr,"EOR"); goto _absolute;
|
||||
case 0x4E: strcpy(chr,"LSR"); goto _absolute;
|
||||
case 0x6D: strcpy(chr,"ADC"); goto _absolute;
|
||||
case 0x6E: strcpy(chr,"ROR"); goto _absolute;
|
||||
case 0x8C: strcpy(chr,"STY"); goto _absolute;
|
||||
case 0x8D: strcpy(chr,"STA"); goto _absolute;
|
||||
case 0x8E: strcpy(chr,"STX"); goto _absolute;
|
||||
case 0xAC: strcpy(chr,"LDY"); goto _absolute;
|
||||
case 0xAD: strcpy(chr,"LDA"); goto _absolute;
|
||||
case 0xAE: strcpy(chr,"LDX"); goto _absolute;
|
||||
case 0xCC: strcpy(chr,"CPY"); goto _absolute;
|
||||
case 0xCD: strcpy(chr,"CMP"); goto _absolute;
|
||||
case 0xCE: strcpy(chr,"DEC"); goto _absolute;
|
||||
case 0xEC: strcpy(chr,"CPX"); goto _absolute;
|
||||
case 0xED: strcpy(chr,"SBC"); goto _absolute;
|
||||
case 0xEE: strcpy(chr,"INC"); goto _absolute;
|
||||
_absolute:
|
||||
absolute(tmp);
|
||||
|
||||
if ( flags )
|
||||
{
|
||||
sym = replaceSymbols( flags, tmp, stmp );
|
||||
sprintf(str,"%s $%s = #$%02X", chr,stmp,GetMem(tmp));
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(str,"%s $%04X = #$%02X", chr,tmp,GetMem(tmp));
|
||||
}
|
||||
break;
|
||||
|
||||
//branches
|
||||
case 0x10: strcpy(chr,"BPL"); goto _branch;
|
||||
case 0x30: strcpy(chr,"BMI"); goto _branch;
|
||||
case 0x50: strcpy(chr,"BVC"); goto _branch;
|
||||
case 0x70: strcpy(chr,"BVS"); goto _branch;
|
||||
case 0x90: strcpy(chr,"BCC"); goto _branch;
|
||||
case 0xB0: strcpy(chr,"BCS"); goto _branch;
|
||||
case 0xD0: strcpy(chr,"BNE"); goto _branch;
|
||||
case 0xF0: strcpy(chr,"BEQ"); goto _branch;
|
||||
_branch:
|
||||
relative(tmp);
|
||||
|
||||
if ( flags )
|
||||
{
|
||||
sym = replaceSymbols( flags, tmp, stmp );
|
||||
sprintf(str,"%s $%s", chr,stmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(str,"%s $%04X", chr,tmp);
|
||||
}
|
||||
break;
|
||||
|
||||
//(Indirect),Y
|
||||
case 0x11: strcpy(chr,"ORA"); goto _indirecty;
|
||||
case 0x31: strcpy(chr,"AND"); goto _indirecty;
|
||||
case 0x51: strcpy(chr,"EOR"); goto _indirecty;
|
||||
case 0x71: strcpy(chr,"ADC"); goto _indirecty;
|
||||
case 0x91: strcpy(chr,"STA"); goto _indirecty;
|
||||
case 0xB1: strcpy(chr,"LDA"); goto _indirecty;
|
||||
case 0xD1: strcpy(chr,"CMP"); goto _indirecty;
|
||||
case 0xF1: strcpy(chr,"SBC"); goto _indirecty;
|
||||
_indirecty:
|
||||
indirectY(tmp);
|
||||
|
||||
if ( flags )
|
||||
{
|
||||
sym = replaceSymbols( flags, tmp, stmp );
|
||||
sprintf(str,"%s ($%02X),Y @ $%s = #$%02X", chr,opcode[1],stmp,GetMem(tmp));
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(str,"%s ($%02X),Y @ $%04X = #$%02X", chr,opcode[1],tmp,GetMem(tmp));
|
||||
}
|
||||
break;
|
||||
|
||||
//Zero Page,X
|
||||
case 0x15: strcpy(chr,"ORA"); goto _zeropagex;
|
||||
case 0x16: strcpy(chr,"ASL"); goto _zeropagex;
|
||||
case 0x35: strcpy(chr,"AND"); goto _zeropagex;
|
||||
case 0x36: strcpy(chr,"ROL"); goto _zeropagex;
|
||||
case 0x55: strcpy(chr,"EOR"); goto _zeropagex;
|
||||
case 0x56: strcpy(chr,"LSR"); goto _zeropagex;
|
||||
case 0x75: strcpy(chr,"ADC"); goto _zeropagex;
|
||||
case 0x76: strcpy(chr,"ROR"); goto _zeropagex;
|
||||
case 0x94: strcpy(chr,"STY"); goto _zeropagex;
|
||||
case 0x95: strcpy(chr,"STA"); goto _zeropagex;
|
||||
case 0xB4: strcpy(chr,"LDY"); goto _zeropagex;
|
||||
case 0xB5: strcpy(chr,"LDA"); goto _zeropagex;
|
||||
case 0xD5: strcpy(chr,"CMP"); goto _zeropagex;
|
||||
case 0xD6: strcpy(chr,"DEC"); goto _zeropagex;
|
||||
case 0xF5: strcpy(chr,"SBC"); goto _zeropagex;
|
||||
case 0xF6: strcpy(chr,"INC"); goto _zeropagex;
|
||||
_zeropagex:
|
||||
zpIndex(tmp,RX);
|
||||
// ################################## Start of SP CODE ###########################
|
||||
// Change width to %04X // don't!
|
||||
if ( flags )
|
||||
{
|
||||
sym = replaceSymbols( flags, tmp, stmp );
|
||||
sprintf(str,"%s $%02X,X @ $%s = #$%02X", chr,opcode[1],stmp,GetMem(tmp));
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(str,"%s $%02X,X @ $%04X = #$%02X", chr,opcode[1],tmp,GetMem(tmp));
|
||||
}
|
||||
// ################################## End of SP CODE ###########################
|
||||
break;
|
||||
|
||||
//Absolute,Y
|
||||
case 0x19: strcpy(chr,"ORA"); goto _absolutey;
|
||||
case 0x39: strcpy(chr,"AND"); goto _absolutey;
|
||||
case 0x59: strcpy(chr,"EOR"); goto _absolutey;
|
||||
case 0x79: strcpy(chr,"ADC"); goto _absolutey;
|
||||
case 0x99: strcpy(chr,"STA"); goto _absolutey;
|
||||
case 0xB9: strcpy(chr,"LDA"); goto _absolutey;
|
||||
case 0xBE: strcpy(chr,"LDX"); goto _absolutey;
|
||||
case 0xD9: strcpy(chr,"CMP"); goto _absolutey;
|
||||
case 0xF9: strcpy(chr,"SBC"); goto _absolutey;
|
||||
_absolutey:
|
||||
absolute(tmp);
|
||||
tmp2=(tmp+RY);
|
||||
if ( flags )
|
||||
{
|
||||
sym = replaceSymbols( flags, tmp , stmp );
|
||||
sym2 = replaceSymbols( flags, tmp2, stmp2 );
|
||||
sprintf(str,"%s $%s,Y @ $%s = #$%02X", chr,stmp,stmp2,GetMem(tmp2));
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(str,"%s $%04X,Y @ $%04X = #$%02X", chr,tmp,tmp2,GetMem(tmp2));
|
||||
}
|
||||
break;
|
||||
|
||||
//Absolute,X
|
||||
case 0x1D: strcpy(chr,"ORA"); goto _absolutex;
|
||||
case 0x1E: strcpy(chr,"ASL"); goto _absolutex;
|
||||
case 0x3D: strcpy(chr,"AND"); goto _absolutex;
|
||||
case 0x3E: strcpy(chr,"ROL"); goto _absolutex;
|
||||
case 0x5D: strcpy(chr,"EOR"); goto _absolutex;
|
||||
case 0x5E: strcpy(chr,"LSR"); goto _absolutex;
|
||||
case 0x7D: strcpy(chr,"ADC"); goto _absolutex;
|
||||
case 0x7E: strcpy(chr,"ROR"); goto _absolutex;
|
||||
case 0x9D: strcpy(chr,"STA"); goto _absolutex;
|
||||
case 0xBC: strcpy(chr,"LDY"); goto _absolutex;
|
||||
case 0xBD: strcpy(chr,"LDA"); goto _absolutex;
|
||||
case 0xDD: strcpy(chr,"CMP"); goto _absolutex;
|
||||
case 0xDE: strcpy(chr,"DEC"); goto _absolutex;
|
||||
case 0xFD: strcpy(chr,"SBC"); goto _absolutex;
|
||||
case 0xFE: strcpy(chr,"INC"); goto _absolutex;
|
||||
_absolutex:
|
||||
absolute(tmp);
|
||||
tmp2=(tmp+RX);
|
||||
if ( flags )
|
||||
{
|
||||
sym = replaceSymbols( flags, tmp , stmp );
|
||||
sym2 = replaceSymbols( flags, tmp2, stmp2 );
|
||||
sprintf(str,"%s $%s,X @ $%s = #$%02X", chr,stmp,stmp2,GetMem(tmp2));
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(str,"%s $%04X,X @ $%04X = #$%02X", chr,tmp,tmp2,GetMem(tmp2));
|
||||
}
|
||||
break;
|
||||
|
||||
//jumps
|
||||
case 0x20: strcpy(chr,"JSR"); goto _jump;
|
||||
case 0x4C: strcpy(chr,"JMP"); goto _jump;
|
||||
case 0x6C: absolute(tmp); sprintf(str,"JMP ($%04X) = $%04X", tmp,GetMem(tmp)|GetMem(tmp+1)<<8); break;
|
||||
_jump:
|
||||
absolute(tmp);
|
||||
|
||||
if ( flags )
|
||||
{
|
||||
sym = replaceSymbols( flags, tmp, stmp );
|
||||
sprintf(str,"%s $%s", chr,stmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(str,"%s $%04X", chr,tmp);
|
||||
}
|
||||
break;
|
||||
|
||||
//Zero Page,Y
|
||||
case 0x96: strcpy(chr,"STX"); goto _zeropagey;
|
||||
case 0xB6: strcpy(chr,"LDX"); goto _zeropagey;
|
||||
_zeropagey:
|
||||
zpIndex(tmp,RY);
|
||||
// ################################## Start of SP CODE ###########################
|
||||
// Change width to %04X // don't!
|
||||
if ( flags )
|
||||
{
|
||||
sym = replaceSymbols( flags, tmp, stmp );
|
||||
sprintf(str,"%s $%02X,Y @ $%s = #$%02X", chr,opcode[1],stmp,GetMem(tmp));
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(str,"%s $%02X,Y @ $%04X = #$%02X", chr,opcode[1],tmp,GetMem(tmp));
|
||||
}
|
||||
// ################################## End of SP CODE ###########################
|
||||
break;
|
||||
|
||||
//UNDEFINED
|
||||
default: strcpy(str,"ERROR"); break;
|
||||
|
||||
}
|
||||
|
||||
if ( symOut )
|
||||
{
|
||||
if ( sym )
|
||||
{
|
||||
*symOut = *sym;
|
||||
}
|
||||
else if ( sym2 )
|
||||
{
|
||||
*symOut = *sym2; sym2 = NULL;
|
||||
}
|
||||
}
|
||||
if ( symOut2 )
|
||||
{
|
||||
if ( sym2 )
|
||||
{
|
||||
*symOut2 = *sym2;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
|
|
|
@ -17,6 +17,43 @@ struct debugSymbol_t
|
|||
{
|
||||
ofs = 0;
|
||||
};
|
||||
|
||||
debugSymbol_t( int ofs, const char *name, const char *comment = NULL )
|
||||
{
|
||||
this->ofs = ofs;
|
||||
this->name.assign( name );
|
||||
|
||||
if ( comment )
|
||||
{
|
||||
this->comment.assign( comment );
|
||||
}
|
||||
}
|
||||
|
||||
void trimTrailingSpaces(void)
|
||||
{
|
||||
while ( name.size() > 0 )
|
||||
{
|
||||
if ( isspace( name.back() ) )
|
||||
{
|
||||
name.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
while ( comment.size() > 0 )
|
||||
{
|
||||
if ( isspace( comment.back() ) )
|
||||
{
|
||||
comment.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct debugSymbolPage_t
|
||||
|
@ -59,6 +96,8 @@ class debugSymbolTable_t
|
|||
private:
|
||||
std::map <int, debugSymbolPage_t*> pageMap;
|
||||
|
||||
int loadRegisterMap(void);
|
||||
|
||||
};
|
||||
|
||||
extern debugSymbolTable_t debugSymbolTable;
|
||||
|
@ -73,4 +112,11 @@ extern debugSymbolTable_t debugSymbolTable;
|
|||
int generateNLFilenameForBank(int bank, char *NLfilename);
|
||||
int generateNLFilenameForAddress(int address, char *NLfilename);
|
||||
|
||||
#define ASM_DEBUG_SYMS 0x0001
|
||||
#define ASM_DEBUG_REGS 0x0002
|
||||
#define ASM_DEBUG_REPLACE 0x0004
|
||||
#define ASM_DEBUG_ADDR_02X 0x0008
|
||||
|
||||
int DisassembleWithDebug(int addr, uint8_t *opcode, int flags, char *str, debugSymbol_t *symOut = NULL, debugSymbol_t *symOut2 = NULL );
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,534 @@
|
|||
// TimingConf.cpp
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include <SDL.h>
|
||||
#include <QHeaderView>
|
||||
#include <QCloseEvent>
|
||||
|
||||
#include "Qt/main.h"
|
||||
#include "Qt/dface.h"
|
||||
#include "Qt/input.h"
|
||||
#include "Qt/config.h"
|
||||
#include "Qt/keyscan.h"
|
||||
#include "Qt/throttle.h"
|
||||
#include "Qt/fceuWrapper.h"
|
||||
#include "Qt/ConsoleWindow.h"
|
||||
#include "Qt/TimingConf.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool hasNicePermissions( int val )
|
||||
{
|
||||
int usrID;
|
||||
bool usrRoot;
|
||||
|
||||
usrID = geteuid();
|
||||
|
||||
usrRoot = (usrID == 0);
|
||||
|
||||
if ( usrRoot )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#ifdef __linux__
|
||||
struct rlimit r;
|
||||
|
||||
if ( getrlimit( RLIMIT_NICE, &r ) == 0 )
|
||||
{
|
||||
int ncur = 20 - r.rlim_cur;
|
||||
|
||||
if ( val >= ncur )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
//printf("RLim Cur: %lu \n", r.rlim_cur );
|
||||
//printf("RLim Max: %lu \n", r.rlim_max );
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
TimingConfDialog_t::TimingConfDialog_t(QWidget *parent)
|
||||
: QDialog( parent )
|
||||
{
|
||||
int opt;
|
||||
QVBoxLayout *mainLayout;
|
||||
QHBoxLayout *hbox;
|
||||
QGridLayout *grid;
|
||||
QGroupBox *emuPrioBox, *guiPrioBox;
|
||||
|
||||
setWindowTitle("Timing Configuration");
|
||||
|
||||
mainLayout = new QVBoxLayout();
|
||||
|
||||
emuPrioCtlEna = new QCheckBox( tr("Set Scheduling Parameters at Startup") );
|
||||
|
||||
emuPrioBox = new QGroupBox( tr("EMU Thread Scheduling Parameters") );
|
||||
guiPrioBox = new QGroupBox( tr("GUI Thread Scheduling Parameters") );
|
||||
grid = new QGridLayout();
|
||||
emuPrioBox->setLayout( grid );
|
||||
|
||||
emuSchedPolicyBox = new QComboBox();
|
||||
emuSchedPrioSlider = new QSlider( Qt::Horizontal );
|
||||
emuSchedNiceSlider = new QSlider( Qt::Horizontal );
|
||||
emuSchedPrioLabel = new QLabel( tr("Priority (RT)") );
|
||||
emuSchedNiceLabel = new QLabel( tr("Priority (Nice)") );
|
||||
|
||||
emuSchedPolicyBox->addItem( tr("SCHED_OTHER") , SCHED_OTHER );
|
||||
emuSchedPolicyBox->addItem( tr("SCHED_FIFO") , SCHED_FIFO );
|
||||
emuSchedPolicyBox->addItem( tr("SCHED_RR") , SCHED_RR );
|
||||
|
||||
grid->addWidget( new QLabel( tr("Policy") ), 0, 0 );
|
||||
grid->addWidget( emuSchedPolicyBox, 0, 1 );
|
||||
grid->addWidget( emuSchedPrioLabel, 1, 0 );
|
||||
grid->addWidget( emuSchedPrioSlider, 1, 1 );
|
||||
grid->addWidget( emuSchedNiceLabel, 2, 0 );
|
||||
grid->addWidget( emuSchedNiceSlider, 2, 1 );
|
||||
|
||||
mainLayout->addWidget( emuPrioCtlEna );
|
||||
mainLayout->addWidget( emuPrioBox );
|
||||
|
||||
grid = new QGridLayout();
|
||||
guiPrioBox->setLayout( grid );
|
||||
|
||||
guiSchedPolicyBox = new QComboBox();
|
||||
guiSchedPrioSlider = new QSlider( Qt::Horizontal );
|
||||
guiSchedNiceSlider = new QSlider( Qt::Horizontal );
|
||||
guiSchedPrioLabel = new QLabel( tr("Priority (RT)") );
|
||||
guiSchedNiceLabel = new QLabel( tr("Priority (Nice)") );
|
||||
|
||||
guiSchedPolicyBox->addItem( tr("SCHED_OTHER") , SCHED_OTHER );
|
||||
guiSchedPolicyBox->addItem( tr("SCHED_FIFO") , SCHED_FIFO );
|
||||
guiSchedPolicyBox->addItem( tr("SCHED_RR") , SCHED_RR );
|
||||
|
||||
grid->addWidget( new QLabel( tr("Policy") ), 0, 0 );
|
||||
grid->addWidget( guiSchedPolicyBox, 0, 1 );
|
||||
grid->addWidget( guiSchedPrioLabel, 1, 0 );
|
||||
grid->addWidget( guiSchedPrioSlider, 1, 1 );
|
||||
grid->addWidget( guiSchedNiceLabel, 2, 0 );
|
||||
grid->addWidget( guiSchedNiceSlider, 2, 1 );
|
||||
|
||||
mainLayout->addWidget( guiPrioBox );
|
||||
|
||||
hbox = new QHBoxLayout();
|
||||
timingDevSelBox = new QComboBox();
|
||||
timingDevSelBox->addItem( tr("NanoSleep") , 0 );
|
||||
|
||||
#ifdef __linux__
|
||||
timingDevSelBox->addItem( tr("Timer FD") , 1 );
|
||||
#endif
|
||||
hbox->addWidget( new QLabel( tr("Timing Mechanism:") ) );
|
||||
hbox->addWidget( timingDevSelBox );
|
||||
mainLayout->addLayout( hbox );
|
||||
|
||||
setLayout( mainLayout );
|
||||
|
||||
g_config->getOption( "SDL.SetSchedParam", &opt );
|
||||
|
||||
emuPrioCtlEna->setChecked( opt );
|
||||
|
||||
updatePolicyBox();
|
||||
updateSliderLimits();
|
||||
updateSliderValues();
|
||||
updateTimingMech();
|
||||
|
||||
connect( emuSchedPolicyBox , SIGNAL(activated(int)) , this, SLOT(emuSchedPolicyChange(int)) );
|
||||
connect( emuSchedNiceSlider , SIGNAL(valueChanged(int)), this, SLOT(emuSchedNiceChange(int)) );
|
||||
connect( emuSchedPrioSlider , SIGNAL(valueChanged(int)), this, SLOT(emuSchedPrioChange(int)) );
|
||||
connect( guiSchedPolicyBox , SIGNAL(activated(int)) , this, SLOT(guiSchedPolicyChange(int)) );
|
||||
connect( guiSchedNiceSlider , SIGNAL(valueChanged(int)), this, SLOT(guiSchedNiceChange(int)) );
|
||||
connect( guiSchedPrioSlider , SIGNAL(valueChanged(int)), this, SLOT(guiSchedPrioChange(int)) );
|
||||
connect( emuPrioCtlEna , SIGNAL(stateChanged(int)), this, SLOT(emuSchedCtlChange(int)) );
|
||||
connect( timingDevSelBox , SIGNAL(activated(int)) , this, SLOT(emuTimingMechChange(int)) );
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
TimingConfDialog_t::~TimingConfDialog_t(void)
|
||||
{
|
||||
printf("Destroy Timing Config Window\n");
|
||||
saveValues();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void TimingConfDialog_t::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
printf("Timing Close Window Event\n");
|
||||
done(0);
|
||||
deleteLater();
|
||||
event->accept();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void TimingConfDialog_t::closeWindow(void)
|
||||
{
|
||||
//printf("Close Window\n");
|
||||
done(0);
|
||||
deleteLater();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void TimingConfDialog_t::emuSchedCtlChange( int state )
|
||||
{
|
||||
g_config->setOption( "SDL.SetSchedParam", (state != Qt::Unchecked) );
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void TimingConfDialog_t::saveValues(void)
|
||||
{
|
||||
int policy, prio, nice;
|
||||
|
||||
if ( consoleWindow == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
nice = consoleWindow->emulatorThread->getNicePriority();
|
||||
|
||||
consoleWindow->emulatorThread->getSchedParam( policy, prio );
|
||||
|
||||
g_config->setOption( "SDL.EmuSchedPolicy", policy );
|
||||
g_config->setOption( "SDL.EmuSchedPrioRt", prio );
|
||||
g_config->setOption( "SDL.EmuSchedNice" , nice );
|
||||
|
||||
//printf("EMU Sched: %i %i %i\n", policy, prio, nice );
|
||||
|
||||
nice = consoleWindow->getNicePriority();
|
||||
|
||||
consoleWindow->getSchedParam( policy, prio );
|
||||
|
||||
g_config->setOption( "SDL.GuiSchedPolicy", policy );
|
||||
g_config->setOption( "SDL.GuiSchedPrioRt", prio );
|
||||
g_config->setOption( "SDL.GuiSchedNice" , nice );
|
||||
|
||||
//printf("GUI Sched: %i %i %i\n", policy, prio, nice );
|
||||
|
||||
g_config->save();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void TimingConfDialog_t::emuSchedNiceChange(int val)
|
||||
{
|
||||
if ( consoleWindow == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
fceuWrapperLock();
|
||||
if ( consoleWindow->emulatorThread->setNicePriority( -val ) )
|
||||
{
|
||||
char msg[1024];
|
||||
|
||||
sprintf( msg, "Error: system call setPriority Failed\nReason: %s\n", strerror(errno) );
|
||||
#ifdef __linux__
|
||||
strcat( msg, "Ensure that your system has the proper resource permissions set in the file:\n\n");
|
||||
strcat( msg, " /etc/security/limits.conf \n\n");
|
||||
strcat( msg, "Adding the following lines to that file and rebooting will usually fix the issue:\n\n");
|
||||
strcat( msg, "* - priority 99 \n");
|
||||
strcat( msg, "* - rtprio 99 \n");
|
||||
strcat( msg, "* - nice -20 \n");
|
||||
#endif
|
||||
printf("%s\n", msg );
|
||||
consoleWindow->QueueErrorMsgWindow( msg );
|
||||
updateSliderValues();
|
||||
}
|
||||
fceuWrapperUnLock();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void TimingConfDialog_t::emuSchedPrioChange(int val)
|
||||
{
|
||||
int policy, prio;
|
||||
|
||||
if ( consoleWindow == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
fceuWrapperLock();
|
||||
consoleWindow->emulatorThread->getSchedParam( policy, prio );
|
||||
|
||||
if ( consoleWindow->emulatorThread->setSchedParam( policy, val ) )
|
||||
{
|
||||
char msg[1024];
|
||||
|
||||
sprintf( msg, "Error: system call pthread_setschedparam Failed\nReason: %s\n", strerror(errno) );
|
||||
#ifdef __linux__
|
||||
strcat( msg, "Ensure that your system has the proper resource permissions set in the file:\n\n");
|
||||
strcat( msg, " /etc/security/limits.conf \n\n");
|
||||
strcat( msg, "Adding the following lines to that file and rebooting will usually fix the issue:\n\n");
|
||||
strcat( msg, "* - priority 99 \n");
|
||||
strcat( msg, "* - rtprio 99 \n");
|
||||
strcat( msg, "* - nice -20 \n");
|
||||
#endif
|
||||
printf("%s\n", msg );
|
||||
consoleWindow->QueueErrorMsgWindow( msg );
|
||||
updateSliderValues();
|
||||
}
|
||||
fceuWrapperUnLock();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void TimingConfDialog_t::emuSchedPolicyChange( int index )
|
||||
{
|
||||
int policy, prio;
|
||||
|
||||
if ( consoleWindow == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
fceuWrapperLock();
|
||||
consoleWindow->emulatorThread->getSchedParam( policy, prio );
|
||||
|
||||
policy = emuSchedPolicyBox->itemData( index ).toInt();
|
||||
|
||||
if ( consoleWindow->emulatorThread->setSchedParam( policy, prio ) )
|
||||
{
|
||||
char msg[1024];
|
||||
|
||||
sprintf( msg, "Error: system call pthread_setschedparam Failed\nReason: %s\n", strerror(errno) );
|
||||
#ifdef __linux__
|
||||
strcat( msg, "Ensure that your system has the proper resource permissions set in the file:\n\n");
|
||||
strcat( msg, " /etc/security/limits.conf \n\n");
|
||||
strcat( msg, "Adding the following lines to that file and rebooting will usually fix the issue:\n\n");
|
||||
strcat( msg, "* - priority 99 \n");
|
||||
strcat( msg, "* - rtprio 99 \n");
|
||||
strcat( msg, "* - nice -20 \n");
|
||||
#endif
|
||||
printf("%s\n", msg );
|
||||
consoleWindow->QueueErrorMsgWindow( msg );
|
||||
}
|
||||
|
||||
updatePolicyBox();
|
||||
updateSliderLimits();
|
||||
updateSliderValues();
|
||||
fceuWrapperUnLock();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void TimingConfDialog_t::guiSchedNiceChange(int val)
|
||||
{
|
||||
if ( consoleWindow == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
fceuWrapperLock();
|
||||
if ( consoleWindow->setNicePriority( -val ) )
|
||||
{
|
||||
char msg[1024];
|
||||
|
||||
sprintf( msg, "Error: system call setPriority Failed\nReason: %s\n", strerror(errno) );
|
||||
#ifdef __linux__
|
||||
strcat( msg, "Ensure that your system has the proper resource permissions set in the file:\n\n");
|
||||
strcat( msg, " /etc/security/limits.conf \n\n");
|
||||
strcat( msg, "Adding the following lines to that file and rebooting will usually fix the issue:\n\n");
|
||||
strcat( msg, "* - priority 99 \n");
|
||||
strcat( msg, "* - rtprio 99 \n");
|
||||
strcat( msg, "* - nice -20 \n");
|
||||
#endif
|
||||
printf("%s\n", msg );
|
||||
consoleWindow->QueueErrorMsgWindow( msg );
|
||||
updateSliderValues();
|
||||
}
|
||||
fceuWrapperUnLock();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void TimingConfDialog_t::guiSchedPrioChange(int val)
|
||||
{
|
||||
int policy, prio;
|
||||
|
||||
if ( consoleWindow == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
fceuWrapperLock();
|
||||
consoleWindow->getSchedParam( policy, prio );
|
||||
|
||||
if ( consoleWindow->setSchedParam( policy, val ) )
|
||||
{
|
||||
char msg[1024];
|
||||
|
||||
sprintf( msg, "Error: system call pthread_setschedparam Failed\nReason: %s\n", strerror(errno) );
|
||||
#ifdef __linux__
|
||||
strcat( msg, "Ensure that your system has the proper resource permissions set in the file:\n\n");
|
||||
strcat( msg, " /etc/security/limits.conf \n\n");
|
||||
strcat( msg, "Adding the following lines to that file and rebooting will usually fix the issue:\n\n");
|
||||
strcat( msg, "* - priority 99 \n");
|
||||
strcat( msg, "* - rtprio 99 \n");
|
||||
strcat( msg, "* - nice -20 \n");
|
||||
#endif
|
||||
printf("%s\n", msg );
|
||||
consoleWindow->QueueErrorMsgWindow( msg );
|
||||
updateSliderValues();
|
||||
}
|
||||
fceuWrapperUnLock();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void TimingConfDialog_t::guiSchedPolicyChange( int index )
|
||||
{
|
||||
int policy, prio;
|
||||
|
||||
if ( consoleWindow == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
fceuWrapperLock();
|
||||
consoleWindow->getSchedParam( policy, prio );
|
||||
|
||||
policy = guiSchedPolicyBox->itemData( index ).toInt();
|
||||
|
||||
if ( consoleWindow->setSchedParam( policy, prio ) )
|
||||
{
|
||||
char msg[1024];
|
||||
|
||||
sprintf( msg, "Error: system call pthread_setschedparam Failed\nReason: %s\n", strerror(errno) );
|
||||
#ifdef __linux__
|
||||
strcat( msg, "Ensure that your system has the proper resource permissions set in the file:\n\n");
|
||||
strcat( msg, " /etc/security/limits.conf \n\n");
|
||||
strcat( msg, "Adding the following lines to that file and rebooting will usually fix the issue:\n\n");
|
||||
strcat( msg, "* - priority 99 \n");
|
||||
strcat( msg, "* - rtprio 99 \n");
|
||||
strcat( msg, "* - nice -20 \n");
|
||||
#endif
|
||||
printf("%s\n", msg );
|
||||
consoleWindow->QueueErrorMsgWindow( msg );
|
||||
}
|
||||
|
||||
updatePolicyBox();
|
||||
updateSliderLimits();
|
||||
updateSliderValues();
|
||||
fceuWrapperUnLock();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void TimingConfDialog_t::updatePolicyBox(void)
|
||||
{
|
||||
int policy, prio;
|
||||
|
||||
if ( consoleWindow == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
consoleWindow->emulatorThread->getSchedParam( policy, prio );
|
||||
|
||||
for (int j=0; j<emuSchedPolicyBox->count(); j++)
|
||||
{
|
||||
if ( emuSchedPolicyBox->itemData(j).toInt() == policy )
|
||||
{
|
||||
//printf("Found Policy %i %i\n", j , policy );
|
||||
emuSchedPolicyBox->setCurrentIndex( j );
|
||||
}
|
||||
}
|
||||
|
||||
consoleWindow->getSchedParam( policy, prio );
|
||||
|
||||
for (int j=0; j<guiSchedPolicyBox->count(); j++)
|
||||
{
|
||||
if ( guiSchedPolicyBox->itemData(j).toInt() == policy )
|
||||
{
|
||||
//printf("Found Policy %i %i\n", j , policy );
|
||||
guiSchedPolicyBox->setCurrentIndex( j );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void TimingConfDialog_t::updateSliderValues(void)
|
||||
{
|
||||
int policy, prio;
|
||||
bool hasNicePerms;
|
||||
|
||||
if ( consoleWindow == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
consoleWindow->emulatorThread->getSchedParam( policy, prio );
|
||||
|
||||
emuSchedNiceSlider->setValue( -consoleWindow->emulatorThread->getNicePriority() );
|
||||
emuSchedPrioSlider->setValue( prio );
|
||||
|
||||
if ( (policy == SCHED_RR) || (policy == SCHED_FIFO) )
|
||||
{
|
||||
emuSchedPrioLabel->setEnabled(true);
|
||||
emuSchedPrioSlider->setEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
emuSchedPrioLabel->setEnabled(false);
|
||||
emuSchedPrioSlider->setEnabled(false);
|
||||
}
|
||||
hasNicePerms = hasNicePermissions( consoleWindow->emulatorThread->getNicePriority() );
|
||||
|
||||
emuSchedNiceLabel->setEnabled( hasNicePerms );
|
||||
emuSchedNiceSlider->setEnabled( hasNicePerms );
|
||||
|
||||
consoleWindow->getSchedParam( policy, prio );
|
||||
|
||||
guiSchedNiceSlider->setValue( -consoleWindow->getNicePriority() );
|
||||
guiSchedPrioSlider->setValue( prio );
|
||||
|
||||
if ( (policy == SCHED_RR) || (policy == SCHED_FIFO) )
|
||||
{
|
||||
guiSchedPrioLabel->setEnabled(true);
|
||||
guiSchedPrioSlider->setEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
guiSchedPrioLabel->setEnabled(false);
|
||||
guiSchedPrioSlider->setEnabled(false);
|
||||
}
|
||||
hasNicePerms = hasNicePermissions( consoleWindow->getNicePriority() );
|
||||
|
||||
guiSchedNiceLabel->setEnabled( hasNicePerms );
|
||||
guiSchedNiceSlider->setEnabled( hasNicePerms );
|
||||
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void TimingConfDialog_t::updateSliderLimits(void)
|
||||
{
|
||||
if ( consoleWindow == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
emuSchedNiceSlider->setMinimum( -20 );
|
||||
emuSchedNiceSlider->setMaximum( 20 );
|
||||
emuSchedPrioSlider->setMinimum( consoleWindow->emulatorThread->getMinSchedPriority() );
|
||||
emuSchedPrioSlider->setMaximum( consoleWindow->emulatorThread->getMaxSchedPriority() );
|
||||
|
||||
guiSchedNiceSlider->setMinimum( -20 );
|
||||
guiSchedNiceSlider->setMaximum( 20 );
|
||||
guiSchedPrioSlider->setMinimum( consoleWindow->getMinSchedPriority() );
|
||||
guiSchedPrioSlider->setMaximum( consoleWindow->getMaxSchedPriority() );
|
||||
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void TimingConfDialog_t::emuTimingMechChange( int index )
|
||||
{
|
||||
int mode;
|
||||
|
||||
if ( consoleWindow == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
fceuWrapperLock();
|
||||
|
||||
mode = timingDevSelBox->itemData( index ).toInt();
|
||||
|
||||
setTimingMode( mode );
|
||||
|
||||
RefreshThrottleFPS();
|
||||
|
||||
g_config->setOption("SDL.EmuTimingMech", mode);
|
||||
|
||||
fceuWrapperUnLock();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
void TimingConfDialog_t::updateTimingMech(void)
|
||||
{
|
||||
int mode = getTimingMode();
|
||||
|
||||
for (int j=0; j<timingDevSelBox->count(); j++)
|
||||
{
|
||||
if ( timingDevSelBox->itemData(j).toInt() == mode )
|
||||
{
|
||||
timingDevSelBox->setCurrentIndex( j );
|
||||
}
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
|
@ -0,0 +1,65 @@
|
|||
// TimingConf.h
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDialog>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
#include <QLabel>
|
||||
#include <QSlider>
|
||||
#include <QFrame>
|
||||
#include <QGroupBox>
|
||||
#include <QTreeView>
|
||||
#include <QTreeWidget>
|
||||
|
||||
#include "Qt/main.h"
|
||||
|
||||
class TimingConfDialog_t : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TimingConfDialog_t(QWidget *parent = 0);
|
||||
~TimingConfDialog_t(void);
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event);
|
||||
|
||||
QCheckBox *emuPrioCtlEna;
|
||||
QComboBox *emuSchedPolicyBox;
|
||||
QSlider *emuSchedPrioSlider;
|
||||
QSlider *emuSchedNiceSlider;
|
||||
QLabel *emuSchedPrioLabel;
|
||||
QLabel *emuSchedNiceLabel;
|
||||
QComboBox *guiSchedPolicyBox;
|
||||
QSlider *guiSchedPrioSlider;
|
||||
QSlider *guiSchedNiceSlider;
|
||||
QLabel *guiSchedPrioLabel;
|
||||
QLabel *guiSchedNiceLabel;
|
||||
QComboBox *timingDevSelBox;
|
||||
|
||||
private:
|
||||
void updatePolicyBox(void);
|
||||
void updateSliderLimits(void);
|
||||
void updateSliderValues(void);
|
||||
void updateTimingMech(void);
|
||||
void saveValues(void);
|
||||
|
||||
public slots:
|
||||
void closeWindow(void);
|
||||
private slots:
|
||||
void emuSchedCtlChange( int state );
|
||||
void emuSchedNiceChange( int val );
|
||||
void emuSchedPrioChange( int val );
|
||||
void emuSchedPolicyChange( int index );
|
||||
void guiSchedNiceChange( int val );
|
||||
void guiSchedPrioChange( int val );
|
||||
void guiSchedPolicyChange( int index );
|
||||
void emuTimingMechChange( int index );
|
||||
|
||||
};
|
|
@ -10,12 +10,18 @@
|
|||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
#include <QRadioButton>
|
||||
#include <QLabel>
|
||||
#include <QFrame>
|
||||
#include <QTimer>
|
||||
#include <QGroupBox>
|
||||
#include <QScrollBar>
|
||||
#include <QCloseEvent>
|
||||
#include <QClipboard>
|
||||
|
||||
#include "Qt/SymbolicDebug.h"
|
||||
#include "Qt/ConsoleDebugger.h"
|
||||
#include "../../debug.h"
|
||||
|
||||
struct traceRecord_t
|
||||
{
|
||||
|
@ -47,7 +53,7 @@ struct traceRecord_t
|
|||
|
||||
int appendAsmText( const char *txt );
|
||||
|
||||
int convToText( char *line );
|
||||
int convToText( char *line, int *len = 0 );
|
||||
};
|
||||
|
||||
class QTraceLogView : public QWidget
|
||||
|
@ -59,16 +65,31 @@ class QTraceLogView : public QWidget
|
|||
~QTraceLogView(void);
|
||||
|
||||
void setScrollBars( QScrollBar *h, QScrollBar *v );
|
||||
void highlightClear(void);
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event);
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
void wheelEvent(QWheelEvent *event);
|
||||
void mousePressEvent(QMouseEvent * event);
|
||||
void mouseReleaseEvent(QMouseEvent * event);
|
||||
void mouseMoveEvent(QMouseEvent * event);
|
||||
|
||||
void calcFontData(void);
|
||||
QPoint convPixToCursor( QPoint p );
|
||||
bool textIsHighlighted(void);
|
||||
void setHighlightEndCoord( int x, int y );
|
||||
void loadClipboard( const char *txt );
|
||||
void contextMenuEvent(QContextMenuEvent *event);
|
||||
void drawText( QPainter *painter, int x, int y, const char *txt, int maxChars = 256 );
|
||||
void calcTextSel( int x, int y );
|
||||
void openBpEditWindow( int editIdx, watchpointinfo *wp, traceRecord_t *recp );
|
||||
void openDebugSymbolEditWindow( int addr, int bank = -1 );
|
||||
|
||||
protected:
|
||||
QFont font;
|
||||
QScrollBar *vbar;
|
||||
QScrollBar *hbar;
|
||||
traceRecord_t rec[64];
|
||||
|
||||
int pxCharWidth;
|
||||
int pxCharHeight;
|
||||
|
@ -80,6 +101,31 @@ class QTraceLogView : public QWidget
|
|||
int viewLines;
|
||||
int viewWidth;
|
||||
int viewHeight;
|
||||
int wheelPixelCounter;
|
||||
int txtHlgtAnchorChar;
|
||||
int txtHlgtAnchorLine;
|
||||
int txtHlgtStartChar;
|
||||
int txtHlgtStartLine;
|
||||
int txtHlgtEndChar;
|
||||
int txtHlgtEndLine;
|
||||
|
||||
bool mouseLeftBtnDown;
|
||||
bool captureHighLightText;
|
||||
|
||||
int selAddrIdx;
|
||||
int selAddrLine;
|
||||
int selAddrChar;
|
||||
int selAddrWidth;
|
||||
int selAddrValue;
|
||||
char selAddrText[128];
|
||||
|
||||
int lineBufIdx[64];
|
||||
std::string hlgtText;
|
||||
std::string lineText[64];
|
||||
|
||||
private slots:
|
||||
void ctxMenuAddBP(void);
|
||||
void ctxMenuAddSym(void);
|
||||
};
|
||||
|
||||
class TraceLoggerDialog_t : public QDialog
|
||||
|
@ -119,6 +165,7 @@ class TraceLoggerDialog_t : public QDialog
|
|||
QScrollBar *vbar;
|
||||
|
||||
int traceViewCounter;
|
||||
int recbufHeadLp;
|
||||
|
||||
void closeEvent(QCloseEvent *bar);
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ static const char* HotkeyStrings[HK_MAX] = {
|
|||
"SelectState0", "SelectState1", "SelectState2", "SelectState3",
|
||||
"SelectState4", "SelectState5", "SelectState6", "SelectState7",
|
||||
"SelectState8", "SelectState9", "SelectStateNext", "SelectStatePrev",
|
||||
"VolumeDown", "VolumeUp" };
|
||||
"VolumeDown", "VolumeUp", "FKB_Enable" };
|
||||
|
||||
const char *getHotkeyString( int i )
|
||||
{
|
||||
|
@ -206,7 +206,6 @@ InitConfig()
|
|||
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);
|
||||
|
@ -221,7 +220,7 @@ InitConfig()
|
|||
|
||||
// OpenGL options
|
||||
config->addOption("opengl", "SDL.OpenGL", 1);
|
||||
config->addOption("openglip", "SDL.OpenGLip", 1);
|
||||
config->addOption("openglip", "SDL.OpenGLip", 0);
|
||||
config->addOption("SDL.SpecialFilter", 0);
|
||||
config->addOption("SDL.SpecialFX", 0);
|
||||
config->addOption("SDL.Vsync", 1);
|
||||
|
@ -241,9 +240,8 @@ InitConfig()
|
|||
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);
|
||||
|
||||
config->addOption("autoInputPreset", "SDL.AutoInputPreset", 0);
|
||||
|
||||
// display input
|
||||
config->addOption("inputdisplay", "SDL.InputDisplay", 0);
|
||||
|
||||
|
@ -260,8 +258,10 @@ InitConfig()
|
|||
config->addOption("hexEditFgColor", "SDL.HexEditFgColor", "#FFFFFF");
|
||||
|
||||
// Debugger Options
|
||||
config->addOption("autoLoadDebugFiles", "SDL.AutoLoadDebugFiles", 1);
|
||||
config->addOption("autoOpenDebugger" , "SDL.AutoOpenDebugger" , 0);
|
||||
config->addOption("autoLoadDebugFiles" , "SDL.AutoLoadDebugFiles", 1);
|
||||
config->addOption("autoOpenDebugger" , "SDL.AutoOpenDebugger" , 0);
|
||||
config->addOption("debuggerPCPlacementMode", "SDL.DebuggerPCPlacement" , 0);
|
||||
config->addOption("debuggerPCDLineOffset" , "SDL.DebuggerPCLineOffset" , 0);
|
||||
|
||||
// Code Data Logger Options
|
||||
config->addOption("autoSaveCDL" , "SDL.AutoSaveCDL", 1);
|
||||
|
@ -305,11 +305,21 @@ InitConfig()
|
|||
config->addOption("_laststatefrom", "SDL.LastLoadStateFrom", home_dir);
|
||||
config->addOption("_lastopennsf", "SDL.LastOpenNSF", home_dir);
|
||||
config->addOption("_lastsavestateas", "SDL.LastSaveStateAs", home_dir);
|
||||
config->addOption("_lastopenmovie", "SDL.LastOpenMovie", home_dir);
|
||||
config->addOption("_lastloadlua", "SDL.LastLoadLua", "");
|
||||
|
||||
config->addOption("_useNativeFileDialog", "SDL.UseNativeFileDialog", false);
|
||||
config->addOption("_useNativeMenuBar" , "SDL.UseNativeMenuBar", false);
|
||||
|
||||
config->addOption("_setSchedParam" , "SDL.SetSchedParam" , 0);
|
||||
config->addOption("_emuSchedPolicy" , "SDL.EmuSchedPolicy", 0);
|
||||
config->addOption("_emuSchedNice" , "SDL.EmuSchedNice" , 0);
|
||||
config->addOption("_emuSchedPrioRt" , "SDL.EmuSchedPrioRt", 40);
|
||||
config->addOption("_guiSchedPolicy" , "SDL.GuiSchedPolicy", 0);
|
||||
config->addOption("_guiSchedNice" , "SDL.GuiSchedNice" , 0);
|
||||
config->addOption("_guiSchedPrioRt" , "SDL.GuiSchedPrioRt", 40);
|
||||
config->addOption("_emuTimingMech" , "SDL.EmuTimingMech" , 0);
|
||||
|
||||
// fcm -> fm2 conversion
|
||||
config->addOption("fcmconvert", "SDL.FCMConvert", "");
|
||||
|
||||
|
@ -433,11 +443,25 @@ InitConfig()
|
|||
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
|
||||
SDLK_PAGEDOWN, // select state prev
|
||||
0, // Volume Down Internal
|
||||
0, // Volume Up Internal
|
||||
SDLK_SCROLLLOCK }; // FKB Enable Toggle
|
||||
|
||||
prefix = "SDL.Hotkeys.";
|
||||
for(int i=0; i < HK_MAX; i++)
|
||||
config->addOption(prefix + HotkeyStrings[i], Hotkeys[i]);
|
||||
{
|
||||
char buf[256];
|
||||
std::string keyText;
|
||||
|
||||
keyText.assign(" mod=");
|
||||
|
||||
sprintf( buf, " key=%s", SDL_GetKeyName( Hotkeys[i] ) );
|
||||
|
||||
keyText.append( buf );
|
||||
|
||||
config->addOption(prefix + HotkeyStrings[i], keyText);
|
||||
}
|
||||
// All mouse devices
|
||||
config->addOption("SDL.OekaKids.0.DeviceType", "Mouse");
|
||||
config->addOption("SDL.OekaKids.0.DeviceNum", 0);
|
||||
|
|
|
@ -20,6 +20,7 @@ enum HOTKEY { HK_CHEAT_MENU=0, HK_BIND_STATE, HK_LOAD_LUA, HK_TOGGLE_BG,
|
|||
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_FKB_ENABLE,
|
||||
HK_MAX};
|
||||
|
||||
const char *getHotkeyString( int i );
|
||||
|
|
|
@ -29,7 +29,7 @@ void LockConsole(void);
|
|||
void UnlockConsole(void);
|
||||
void ToggleFS(); /* SDL */
|
||||
|
||||
int LoadGame(const char *path);
|
||||
int LoadGame(const char *path, bool silent);
|
||||
//int CloseGame(void);
|
||||
|
||||
void Giggles(int);
|
||||
|
|
|
@ -2,8 +2,11 @@
|
|||
//
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
#include <unzip.h>
|
||||
|
||||
#include <QStyleFactory>
|
||||
#include "Qt/main.h"
|
||||
#include "Qt/throttle.h"
|
||||
#include "Qt/config.h"
|
||||
|
@ -19,6 +22,7 @@
|
|||
#include "Qt/CodeDataLogger.h"
|
||||
#include "Qt/ConsoleDebugger.h"
|
||||
#include "Qt/ConsoleWindow.h"
|
||||
#include "Qt/ConsoleUtilities.h"
|
||||
#include "Qt/fceux_git_info.h"
|
||||
|
||||
#include "common/cheat.h"
|
||||
|
@ -51,6 +55,8 @@ int KillFCEUXonFrame = 0;
|
|||
|
||||
bool swapDuty = 0;
|
||||
bool turbo = false;
|
||||
bool pauseAfterPlayback = false;
|
||||
bool suggestReadOnlyReplay = true;
|
||||
unsigned int gui_draw_area_width = 256;
|
||||
unsigned int gui_draw_area_height = 256;
|
||||
|
||||
|
@ -64,6 +70,7 @@ static int periodic_saves = 0;
|
|||
static int mutexLocks = 0;
|
||||
static int mutexPending = 0;
|
||||
static bool emulatorHasMutux = 0;
|
||||
static unsigned int emulatorCycleCount = 0;
|
||||
|
||||
extern double g_fpsScale;
|
||||
|
||||
|
@ -75,33 +82,9 @@ int mutecapture = 0;
|
|||
//*****************************************************************
|
||||
//
|
||||
|
||||
/**
|
||||
* 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);
|
||||
//fprintf(stdout, "\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows an error message in a message box.
|
||||
* (For now: prints to stderr.)
|
||||
*
|
||||
* If running in Qt 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);
|
||||
|
||||
consoleWindow->QueueErrorMsgWindow( errormsg );
|
||||
}
|
||||
// Message functions defined in MsgLogViewer.cpp
|
||||
//void FCEUD_Message(const char *text)
|
||||
//void FCEUD_PrintError(const char *errormsg)
|
||||
|
||||
/**
|
||||
* Opens a file, C++ style, to be read a byte at a time.
|
||||
|
@ -205,20 +188,44 @@ DriverKill()
|
|||
inited=0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads last game
|
||||
*/
|
||||
int reloadLastGame(void)
|
||||
{
|
||||
std::string lastRom;
|
||||
g_config->getOption(std::string("SDL.LastOpenFile"), &lastRom);
|
||||
return LoadGame(lastRom.c_str(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
int LoadGame(const char *path, bool silent)
|
||||
{
|
||||
int gg_enabled, autoLoadDebug, autoOpenDebugger;
|
||||
char fullpath[4096];
|
||||
int gg_enabled, autoLoadDebug, autoOpenDebugger, autoInputPreset;
|
||||
|
||||
if (isloaded){
|
||||
CloseGame();
|
||||
}
|
||||
|
||||
#if defined(__linux) || defined(__APPLE__)
|
||||
|
||||
// Resolve absolute path to file
|
||||
if ( realpath( path, fullpath ) == NULL )
|
||||
{
|
||||
strcpy( fullpath, path );
|
||||
}
|
||||
#else
|
||||
strcpy( fullpath, path );
|
||||
#endif
|
||||
|
||||
//printf("Fullpath: %zi '%s'\n", sizeof(fullpath), fullpath );
|
||||
|
||||
// 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.
|
||||
|
@ -226,7 +233,7 @@ int LoadGame(const char *path)
|
|||
|
||||
FCEUI_SetGameGenie (gg_enabled);
|
||||
|
||||
if(!FCEUI_LoadGame(path, 1)) {
|
||||
if(!FCEUI_LoadGame(fullpath, 1, silent)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -250,12 +257,19 @@ int LoadGame(const char *path)
|
|||
|
||||
CDLoggerROMChanged();
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
g_config->getOption( "SDL.AutoInputPreset", &autoInputPreset );
|
||||
|
||||
if ( autoInputPreset )
|
||||
{
|
||||
loadInputSettingsFromFile();
|
||||
}
|
||||
|
||||
ParseGIInput(GameInfo);
|
||||
RefreshThrottleFPS();
|
||||
|
@ -304,12 +318,21 @@ CloseGame(void)
|
|||
debugSymbolTable.clear();
|
||||
CDLoggerROMClosed();
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
int autoInputPreset;
|
||||
g_config->getOption( "SDL.AutoInputPreset", &autoInputPreset );
|
||||
|
||||
if ( autoInputPreset )
|
||||
{
|
||||
saveInputSettingsToFile();
|
||||
}
|
||||
|
||||
FCEUI_CloseGame();
|
||||
|
||||
DriverKill();
|
||||
|
@ -360,11 +383,18 @@ bool fceuWrapperGameLoaded(void)
|
|||
return (isloaded ? true : false);
|
||||
}
|
||||
|
||||
void fceuWrapperRequestAppExit(void)
|
||||
{
|
||||
if ( consoleWindow )
|
||||
{
|
||||
consoleWindow->requestClose();
|
||||
}
|
||||
}
|
||||
|
||||
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"
|
||||
|
@ -382,8 +412,6 @@ static const char *DriverUsage =
|
|||
"--(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"
|
||||
|
@ -412,7 +440,6 @@ static const char *DriverUsage =
|
|||
"--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"
|
||||
|
@ -423,6 +450,7 @@ static const char *DriverUsage =
|
|||
|
||||
static void ShowUsage(const char *prog)
|
||||
{
|
||||
int i,j;
|
||||
printf("\nUsage is as follows:\n%s <options> filename\n\n",prog);
|
||||
puts(DriverUsage);
|
||||
#ifdef _S9XLUA_H
|
||||
|
@ -432,6 +460,25 @@ static void ShowUsage(const char *prog)
|
|||
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 ("--style=KEY Use Qt GUI Style based on supplied key. Available system style keys are:\n");
|
||||
|
||||
QStringList styleList = QStyleFactory::keys();
|
||||
|
||||
j=0;
|
||||
for (i=0; i<styleList.size(); i++)
|
||||
{
|
||||
printf(" %16s ", styleList[i].toStdString().c_str() ); j++;
|
||||
|
||||
if ( j >= 4 )
|
||||
{
|
||||
printf("\n"); j=0;
|
||||
}
|
||||
}
|
||||
printf("\n\n");
|
||||
printf(" Custom Qt stylesheets (.qss files) may be used by setting an\n");
|
||||
printf(" environment variable named FCEUX_QT_STYLESHEET equal to the \n");
|
||||
printf(" full (absolute) path to the qss file.\n");
|
||||
|
||||
puts("");
|
||||
printf("Compiled with SDL version %d.%d.%d\n", SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL );
|
||||
SDL_version v;
|
||||
|
@ -505,16 +552,7 @@ int fceuWrapperInit( int argc, char *argv[] )
|
|||
g_config->save();
|
||||
}
|
||||
|
||||
|
||||
//g_config->getOption("SDL.InputCfg", &s);
|
||||
|
||||
//if (s.size() != 0)
|
||||
//{
|
||||
// InitVideo(GameInfo);
|
||||
// InputCfg(s);
|
||||
//}
|
||||
|
||||
// update the input devices
|
||||
// update the input devices
|
||||
UpdateInput(g_config);
|
||||
|
||||
// check for a .fcm file to convert to .fm2
|
||||
|
@ -682,8 +720,16 @@ int fceuWrapperInit( int argc, char *argv[] )
|
|||
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;
|
||||
movieSubtitles = id ? true : false;
|
||||
}
|
||||
|
||||
// Emulation Timing Mechanism
|
||||
{
|
||||
int timingMode;
|
||||
|
||||
g_config->getOption("SDL.EmuTimingMech", &timingMode);
|
||||
|
||||
setTimingMode( timingMode );
|
||||
}
|
||||
|
||||
// load the hotkeys from the config life
|
||||
|
@ -711,10 +757,20 @@ int fceuWrapperInit( int argc, char *argv[] )
|
|||
if(s.find(".fm2") != std::string::npos || s.find(".fm3") != std::string::npos)
|
||||
{
|
||||
static int pauseframe;
|
||||
char replayReadOnlySetting;
|
||||
g_config->getOption("SDL.PauseFrame", &pauseframe);
|
||||
g_config->setOption("SDL.PauseFrame", 0);
|
||||
|
||||
if (suggestReadOnlyReplay)
|
||||
{
|
||||
replayReadOnlySetting = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
replayReadOnlySetting = FCEUI_GetMovieToggleReadOnly();
|
||||
}
|
||||
FCEUI_printf("Playing back movie located at %s\n", s.c_str());
|
||||
FCEUI_LoadMovie(s.c_str(), false, pauseframe ? pauseframe : false);
|
||||
FCEUI_LoadMovie(s.c_str(), replayReadOnlySetting, pauseframe ? pauseframe : false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -739,7 +795,8 @@ int fceuWrapperInit( int argc, char *argv[] )
|
|||
g_config->setOption("SDL.LuaScript", "");
|
||||
if (s != "")
|
||||
{
|
||||
#ifdef __linux
|
||||
#if defined(__linux) || defined(__APPLE__)
|
||||
|
||||
// Resolve absolute path to file
|
||||
char fullpath[2048];
|
||||
if ( realpath( s.c_str(), fullpath ) != NULL )
|
||||
|
@ -895,13 +952,6 @@ FCEUD_Update(uint8 *XBuf,
|
|||
}
|
||||
else
|
||||
{
|
||||
//if (!NoWaiting && (!(eoptions&EO_NOTHROTTLE) || FCEUI_EmulationPaused()))
|
||||
//{
|
||||
// while (SpeedThrottle())
|
||||
// {
|
||||
// FCEUD_UpdateInput();
|
||||
// }
|
||||
//}
|
||||
if (XBuf && (inited&4))
|
||||
{
|
||||
BlitScreen(XBuf); blitDone = 1;
|
||||
|
@ -945,6 +995,8 @@ static void DoFun(int frameskip, int periodic_saves)
|
|||
// opause=FCEUI_EmulationPaused();
|
||||
// SilenceSound(opause);
|
||||
//}
|
||||
|
||||
emulatorCycleCount++;
|
||||
}
|
||||
|
||||
void fceuWrapperLock(void)
|
||||
|
@ -1012,17 +1064,22 @@ int fceuWrapperUpdate( void )
|
|||
|
||||
if ( !lock_acq )
|
||||
{
|
||||
printf("Error: Emulator Failed to Acquire Mutex\n");
|
||||
if ( GameInfo )
|
||||
{
|
||||
printf("Error: Emulator Failed to Acquire Mutex\n");
|
||||
}
|
||||
usleep( 100000 );
|
||||
|
||||
return -1;
|
||||
}
|
||||
emulatorHasMutux = 1;
|
||||
|
||||
if ( GameInfo && !FCEUI_EmulationPaused() )
|
||||
if ( GameInfo )
|
||||
{
|
||||
DoFun(frameskip, periodic_saves);
|
||||
|
||||
hexEditorUpdateMemoryValues();
|
||||
|
||||
fceuWrapperUnLock();
|
||||
|
||||
emulatorHasMutux = 0;
|
||||
|
@ -1045,6 +1102,277 @@ int fceuWrapperUpdate( void )
|
|||
return 0;
|
||||
}
|
||||
|
||||
ArchiveScanRecord FCEUD_ScanArchive(std::string fname)
|
||||
{
|
||||
int idx=0, ret;
|
||||
unzFile zf;
|
||||
unz_file_info fi;
|
||||
char filename[512];
|
||||
ArchiveScanRecord rec;
|
||||
|
||||
zf = unzOpen( fname.c_str() );
|
||||
|
||||
if ( zf == NULL )
|
||||
{
|
||||
//printf("Error: Failed to open Zip File: '%s'\n", fname.c_str() );
|
||||
return rec;
|
||||
}
|
||||
rec.type = 0;
|
||||
|
||||
ret = unzGoToFirstFile( zf );
|
||||
|
||||
//printf("unzGoToFirstFile: %i \n", ret );
|
||||
|
||||
while ( ret == 0 )
|
||||
{
|
||||
FCEUARCHIVEFILEINFO_ITEM item;
|
||||
|
||||
unzGetCurrentFileInfo( zf, &fi, filename, sizeof(filename), NULL, 0, NULL, 0 );
|
||||
|
||||
//printf("Filename: %u '%s' \n", fi.uncompressed_size, filename );
|
||||
|
||||
item.name.assign( filename );
|
||||
item.size = fi.uncompressed_size;
|
||||
item.index = idx; idx++;
|
||||
|
||||
rec.files.push_back( item );
|
||||
|
||||
ret = unzGoToNextFile( zf );
|
||||
|
||||
//printf("unzGoToNextFile: %i \n", ret );
|
||||
}
|
||||
rec.numFilesInArchive = idx;
|
||||
|
||||
unzClose( zf );
|
||||
|
||||
return rec;
|
||||
}
|
||||
|
||||
FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::string* innerFilename, int* userCancel)
|
||||
{
|
||||
int ret;
|
||||
FCEUFILE* fp = 0;
|
||||
unzFile zf;
|
||||
unz_file_info fi;
|
||||
char filename[512];
|
||||
char foundFile = 0;
|
||||
void *tmpMem = NULL;
|
||||
std::string searchFile;
|
||||
|
||||
if ( innerFilename != NULL )
|
||||
{
|
||||
searchFile = *innerFilename;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector <std::string> fileList;
|
||||
|
||||
for (size_t i=0; i<asr.files.size(); i++)
|
||||
{
|
||||
char base[512], suffix[32];
|
||||
|
||||
getFileBaseName( asr.files[i].name.c_str(), base, suffix );
|
||||
|
||||
if ( (strcasecmp( suffix, ".nes" ) == 0) ||
|
||||
(strcasecmp( suffix, ".nsf" ) == 0) ||
|
||||
(strcasecmp( suffix, ".fds" ) == 0) ||
|
||||
(strcasecmp( suffix, ".unf" ) == 0) ||
|
||||
(strcasecmp( suffix, ".unif") == 0) )
|
||||
{
|
||||
fileList.push_back( asr.files[i].name );
|
||||
}
|
||||
}
|
||||
|
||||
if ( fileList.size() > 1 )
|
||||
{
|
||||
if ( consoleWindow != NULL )
|
||||
{
|
||||
int sel = consoleWindow->showListSelectDialog( "Select ROM From Archive", fileList );
|
||||
|
||||
if ( sel < 0 )
|
||||
{
|
||||
if ( userCancel )
|
||||
{
|
||||
*userCancel = 1;
|
||||
}
|
||||
return fp;
|
||||
}
|
||||
searchFile = fileList[sel];
|
||||
}
|
||||
}
|
||||
else if ( fileList.size() > 0 )
|
||||
{
|
||||
searchFile = fileList[0];
|
||||
}
|
||||
}
|
||||
|
||||
zf = unzOpen( fname.c_str() );
|
||||
|
||||
if ( zf == NULL )
|
||||
{
|
||||
//printf("Error: Failed to open Zip File: '%s'\n", fname.c_str() );
|
||||
return fp;
|
||||
}
|
||||
|
||||
//printf("Searching for %s in %s \n", searchFile.c_str(), fname.c_str() );
|
||||
|
||||
ret = unzGoToFirstFile( zf );
|
||||
|
||||
//printf("unzGoToFirstFile: %i \n", ret );
|
||||
|
||||
while ( ret == 0 )
|
||||
{
|
||||
unzGetCurrentFileInfo( zf, &fi, filename, sizeof(filename), NULL, 0, NULL, 0 );
|
||||
|
||||
//printf("Filename: %u '%s' \n", fi.uncompressed_size, filename );
|
||||
|
||||
if ( strcmp( searchFile.c_str(), filename ) == 0 )
|
||||
{
|
||||
//printf("Found Filename: %u '%s' \n", fi.uncompressed_size, filename );
|
||||
foundFile = 1; break;
|
||||
}
|
||||
|
||||
ret = unzGoToNextFile( zf );
|
||||
|
||||
//printf("unzGoToNextFile: %i \n", ret );
|
||||
}
|
||||
|
||||
if ( !foundFile )
|
||||
{
|
||||
unzClose( zf );
|
||||
return fp;
|
||||
}
|
||||
|
||||
tmpMem = ::malloc( fi.uncompressed_size );
|
||||
|
||||
if ( tmpMem == NULL )
|
||||
{
|
||||
unzClose( zf );
|
||||
return fp;
|
||||
}
|
||||
|
||||
EMUFILE_MEMORY* ms = new EMUFILE_MEMORY(fi.uncompressed_size);
|
||||
|
||||
unzOpenCurrentFile( zf );
|
||||
unzReadCurrentFile( zf, tmpMem, fi.uncompressed_size );
|
||||
unzCloseCurrentFile( zf );
|
||||
|
||||
ms->fwrite( tmpMem, fi.uncompressed_size );
|
||||
|
||||
free( tmpMem );
|
||||
|
||||
//if we extracted the file correctly
|
||||
fp = new FCEUFILE();
|
||||
fp->archiveFilename = fname;
|
||||
fp->filename = searchFile;
|
||||
fp->fullFilename = fp->archiveFilename + "|" + fp->filename;
|
||||
fp->archiveIndex = ret;
|
||||
fp->mode = FCEUFILE::READ;
|
||||
fp->size = fi.uncompressed_size;
|
||||
fp->stream = ms;
|
||||
fp->archiveCount = (int)asr.numFilesInArchive;
|
||||
ms->fseek(0,SEEK_SET); //rewind so that the rom analyzer sees a freshly opened file
|
||||
|
||||
unzClose( zf );
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::string* innerFilename)
|
||||
{
|
||||
int userCancel = 0;
|
||||
|
||||
return FCEUD_OpenArchive( asr, fname, innerFilename, &userCancel );
|
||||
}
|
||||
|
||||
FCEUFILE* FCEUD_OpenArchiveIndex(ArchiveScanRecord& asr, std::string &fname, int innerIndex, int* userCancel)
|
||||
{
|
||||
int ret, idx=0;
|
||||
FCEUFILE* fp = 0;
|
||||
unzFile zf;
|
||||
unz_file_info fi;
|
||||
char filename[512];
|
||||
char foundFile = 0;
|
||||
void *tmpMem = NULL;
|
||||
|
||||
zf = unzOpen( fname.c_str() );
|
||||
|
||||
if ( zf == NULL )
|
||||
{
|
||||
//printf("Error: Failed to open Zip File: '%s'\n", fname.c_str() );
|
||||
return fp;
|
||||
}
|
||||
|
||||
ret = unzGoToFirstFile( zf );
|
||||
|
||||
//printf("unzGoToFirstFile: %i \n", ret );
|
||||
|
||||
while ( ret == 0 )
|
||||
{
|
||||
unzGetCurrentFileInfo( zf, &fi, filename, sizeof(filename), NULL, 0, NULL, 0 );
|
||||
|
||||
//printf("Filename: %u '%s' \n", fi.uncompressed_size, filename );
|
||||
|
||||
if ( idx == innerIndex )
|
||||
{
|
||||
//printf("Found Filename: %u '%s' \n", fi.uncompressed_size, filename );
|
||||
foundFile = 1; break;
|
||||
}
|
||||
idx++;
|
||||
|
||||
ret = unzGoToNextFile( zf );
|
||||
|
||||
//printf("unzGoToNextFile: %i \n", ret );
|
||||
}
|
||||
|
||||
if ( !foundFile )
|
||||
{
|
||||
unzClose( zf );
|
||||
return fp;
|
||||
}
|
||||
|
||||
tmpMem = ::malloc( fi.uncompressed_size );
|
||||
|
||||
if ( tmpMem == NULL )
|
||||
{
|
||||
unzClose( zf );
|
||||
return fp;
|
||||
}
|
||||
|
||||
EMUFILE_MEMORY* ms = new EMUFILE_MEMORY(fi.uncompressed_size);
|
||||
|
||||
unzOpenCurrentFile( zf );
|
||||
unzReadCurrentFile( zf, tmpMem, fi.uncompressed_size );
|
||||
unzCloseCurrentFile( zf );
|
||||
|
||||
ms->fwrite( tmpMem, fi.uncompressed_size );
|
||||
|
||||
free( tmpMem );
|
||||
|
||||
//if we extracted the file correctly
|
||||
fp = new FCEUFILE();
|
||||
fp->archiveFilename = fname;
|
||||
fp->filename = filename;
|
||||
fp->fullFilename = fp->archiveFilename + "|" + fp->filename;
|
||||
fp->archiveIndex = ret;
|
||||
fp->mode = FCEUFILE::READ;
|
||||
fp->size = fi.uncompressed_size;
|
||||
fp->stream = ms;
|
||||
fp->archiveCount = (int)asr.numFilesInArchive;
|
||||
ms->fseek(0,SEEK_SET); //rewind so that the rom analyzer sees a freshly opened file
|
||||
|
||||
unzClose( zf );
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
FCEUFILE* FCEUD_OpenArchiveIndex(ArchiveScanRecord& asr, std::string &fname, int innerIndex)
|
||||
{
|
||||
int userCancel = 0;
|
||||
|
||||
return FCEUD_OpenArchiveIndex( asr, fname, innerIndex, &userCancel );
|
||||
}
|
||||
|
||||
// dummy functions
|
||||
|
||||
#define DUMMY(__f) \
|
||||
|
@ -1061,15 +1389,9 @@ 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; }
|
||||
bool FCEUD_PauseAfterPlayback() { return pauseAfterPlayback; }
|
||||
|
||||
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(); }
|
||||
|
||||
|
|
|
@ -13,14 +13,17 @@ extern int gametype;
|
|||
extern int closeFinishedMovie;
|
||||
extern bool turbo;
|
||||
extern bool swapDuty;
|
||||
extern bool pauseAfterPlayback;
|
||||
extern bool suggestReadOnlyReplay;
|
||||
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 LoadGame(const char *path, bool silent = false);
|
||||
int CloseGame(void);
|
||||
int reloadLastGame(void);
|
||||
|
||||
int fceuWrapperInit( int argc, char *argv[] );
|
||||
int fceuWrapperClose( void );
|
||||
|
@ -33,4 +36,5 @@ int fceuWrapperSoftReset(void);
|
|||
int fceuWrapperHardReset(void);
|
||||
int fceuWrapperTogglePause(void);
|
||||
bool fceuWrapperGameLoaded(void);
|
||||
void fceuWrapperRequestAppExit(void);
|
||||
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
// HotKeyConf.h
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDialog>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
#include <QRadioButton>
|
||||
#include <QLineEdit>
|
||||
#include <QLabel>
|
||||
#include <QFrame>
|
||||
#include <QGroupBox>
|
||||
#include <QFont>
|
||||
|
||||
#include "Qt/main.h"
|
||||
|
||||
class iNES_HEADER;
|
||||
|
||||
class iNesHeaderEditor_t : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
iNesHeaderEditor_t(QWidget *parent = 0);
|
||||
~iNesHeaderEditor_t(void);
|
||||
|
||||
bool isInitialized(void){ return initOK; };
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event);
|
||||
|
||||
QFont font;
|
||||
QRadioButton *iNes1Btn;
|
||||
QRadioButton *iNes2Btn;
|
||||
QComboBox *mapperComboBox;
|
||||
QLineEdit *mapperSubEdit;
|
||||
QLineEdit *miscRomsEdit;
|
||||
QComboBox *prgRomBox;
|
||||
QComboBox *prgRamBox;
|
||||
QComboBox *prgNvRamBox;
|
||||
QComboBox *chrRomBox;
|
||||
QComboBox *chrRamBox;
|
||||
QComboBox *chrNvRamBox;
|
||||
QComboBox *vsHwBox;
|
||||
QComboBox *vsPpuBox;
|
||||
QComboBox *extCslBox;
|
||||
QComboBox *inputDevBox;
|
||||
QCheckBox *trainerCBox;
|
||||
QCheckBox *iNesUnOfBox;
|
||||
QCheckBox *iNesDualRegBox;
|
||||
QCheckBox *iNesBusCfltBox;
|
||||
QCheckBox *iNesPrgRamBox;
|
||||
QCheckBox *battNvRamBox;
|
||||
QRadioButton *horzMirrorBtn;
|
||||
QRadioButton *vertMirrorBtn;
|
||||
QRadioButton *fourMirrorBtn;
|
||||
QRadioButton *ntscRegionBtn;
|
||||
QRadioButton *palRegionBtn;
|
||||
QRadioButton *dendyRegionBtn;
|
||||
QRadioButton *dualRegionBtn;
|
||||
QRadioButton *normSysbtn;
|
||||
QRadioButton *vsSysbtn;
|
||||
QRadioButton *plySysbtn;
|
||||
QRadioButton *extSysbtn;
|
||||
QPushButton *restoreBtn;
|
||||
QPushButton *saveAsBtn;
|
||||
QPushButton *closeBtn;
|
||||
QGroupBox *iNesUnOfGroupBox;
|
||||
QGroupBox *sysGroupBox;
|
||||
QGroupBox *vsGroupBox;
|
||||
QGroupBox *extGroupBox;
|
||||
QLabel *prgRamLbl;
|
||||
QLabel *prgNvRamLbl;
|
||||
QLabel *mapperSubLbl;
|
||||
QLabel *chrRamLbl;
|
||||
QLabel *chrNvRamLbl;
|
||||
QLabel *inputDevLbl;
|
||||
QLabel *miscRomsLbl;
|
||||
iNES_HEADER *iNesHdr;
|
||||
|
||||
bool initOK;
|
||||
private:
|
||||
|
||||
bool openFile(void);
|
||||
void printHeader(iNES_HEADER* _header);
|
||||
bool loadHeader(iNES_HEADER *header);
|
||||
bool SaveINESFile(const char* path, iNES_HEADER* header);
|
||||
bool WriteHeaderData(iNES_HEADER* header);
|
||||
void setHeaderData(iNES_HEADER *header);
|
||||
void showErrorMsgWindow(const char *str);
|
||||
void ToggleINES20(bool ines20);
|
||||
void ToggleUnofficialPropertiesEnabled(bool ines20, bool check);
|
||||
void ToggleUnofficialExtraRegionCode(bool ines20, bool unofficial_check, bool check);
|
||||
void ToggleUnofficialPrgRamPresent(bool ines20, bool unofficial_check, bool check);
|
||||
void ToggleVSSystemGroup(bool enable);
|
||||
void ToggleExtendSystemList(bool enable);
|
||||
|
||||
public slots:
|
||||
void closeWindow(void);
|
||||
private slots:
|
||||
void saveHeader(void);
|
||||
void saveFileAs(void);
|
||||
void restoreHeader(void);
|
||||
void iNes1Clicked(bool checked);
|
||||
void iNes2Clicked(bool checked);
|
||||
void normSysClicked(bool checked);
|
||||
void vsSysClicked(bool checked);
|
||||
void plySysClicked(bool checked);
|
||||
void extSysClicked(bool checked);
|
||||
void unofficialStateChange(int state);
|
||||
void unofficialPrgRamStateChange(int state);
|
||||
void unofficialDualRegionStateChange(int state);
|
||||
|
||||
};
|
|
@ -1,55 +0,0 @@
|
|||
/* 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",
|
||||
" ",
|
||||
" ........ ",
|
||||
" ............... ",
|
||||
" ........................ ",
|
||||
" ...........................+ ",
|
||||
" ............@@..@@........... ",
|
||||
" .#............@@............$$ ",
|
||||
" .##..........@@.@.....$$%%%%$$ ",
|
||||
" &...........@....@$$$$$$%%&%$$ ",
|
||||
" *&...............$$$$$$$%%&%$$ ",
|
||||
" =&*.......-;;>;...$$,$$$%**&.. ",
|
||||
" '&&..............$$,,,%=)!~.. ",
|
||||
" ~&&............-%%##%*.~'=%& ",
|
||||
" *&&.....+%%****&&%%&*.&!!' ",
|
||||
" **&%&***********&&&*~{'= ",
|
||||
" ********=**~**~**~ ",
|
||||
" *****~******] ",
|
||||
" **~***]' ",
|
||||
" ~]== ",
|
||||
" ",
|
||||
" ..... .... .... .. ..@@ @@",
|
||||
" ..... .... .... .. ..@@@ @@@",
|
||||
" .. .. .. .. .. @@@ @@@ ",
|
||||
" .... .. .. .. .. @@@@@@ ",
|
||||
" .... .. ... .. .. @@@@ ",
|
||||
" .. .. ... .. .. @@@@ ",
|
||||
" .. .. .. .. .. @@@@@@ ",
|
||||
" .. .. .. .. .. @@@ @@@ ",
|
||||
" .. .... .... .....@@@ @@@",
|
||||
" .. .... .... ... @@ @@",
|
||||
" ",
|
||||
" "};
|