Merge pull request #25 from TASVideos/master

Sync code to the newest
This commit is contained in:
owomomo 2020-12-19 11:35:18 +08:00 committed by GitHub
commit ead6ff6dc5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
657 changed files with 75007 additions and 26408 deletions

3
.gitignore vendored
View File

@ -40,3 +40,6 @@ fceux-net-server
/output/cheats
/output/snaps
/output/sav
# typical CMake build directory
/build

View File

@ -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.

View File

@ -1,2 +0,0 @@
ACLOCAL_AMFLAGS = -I m4 --install
SUBDIRS = src

28
README
View File

@ -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.

View File

@ -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)

View File

@ -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

View File

@ -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" ]

View File

@ -1 +0,0 @@
autoreconf --install || exit 1

View File

@ -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])

View File

@ -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 $@

View File

@ -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;

Binary file not shown.

369
fceux.pro
View File

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 83 KiB

BIN
icons/application-exit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
icons/camera.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 B

BIN
icons/graphics-palette.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 B

BIN
icons/input-gaming.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
icons/input-keyboard.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

BIN
icons/media-record.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
icons/movie.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
icons/power.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
icons/timer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
icons/view-fullscreen.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 739 B

Binary file not shown.

Binary file not shown.

View File

@ -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";

View File

@ -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

View File

@ -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 \

View File

@ -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.

View File

@ -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>

20
scripts/linux_makeIcons.sh Executable file
View File

@ -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

View File

@ -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 )

View File

@ -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')

View File

@ -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);

View File

@ -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);

View File

@ -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')

164
src/boards/bs4xxxr.cpp Normal file
View File

@ -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);
}

View File

@ -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;

View File

@ -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)
{

View File

@ -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);

View File

@ -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"

View File

@ -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 );

View File

@ -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 )

View File

@ -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);

View File

@ -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);

File diff suppressed because it is too large Load Diff

View File

@ -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);
};

View File

@ -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;
}
//---------------------------------------------------------------------------

View File

@ -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;
};

View File

@ -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 );
}
}
//----------------------------------------------------

View File

@ -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 );
};

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;

File diff suppressed because it is too large Load Diff

View File

@ -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);

View File

@ -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();
}
//----------------------------------------------------------------------------

View File

@ -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);
};

View File

@ -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();
}
//----------------------------------------------------------------------------

View File

@ -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);

View File

@ -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)

View File

@ -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];

File diff suppressed because it is too large Load Diff

View File

@ -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 );

View File

@ -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 );

View File

@ -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 );
}
}
//----------------------------------------------------------------------------

View File

@ -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 );

View File

@ -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;
}
//----------------------------------------------------

View File

@ -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);

View File

@ -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);
}
//----------------------------------------------------------------------------

View File

@ -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 );
};

View File

@ -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();
}
//----------------------------------------------------------------------------

View File

@ -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);
};

View File

@ -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 );
}
}
//----------------------------------------------------------------------------

View File

@ -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);
};

View File

@ -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;
}
//----------------------------------------------------

View File

@ -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 );

View File

@ -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 );

1908
src/drivers/Qt/RamSearch.cpp Normal file

File diff suppressed because it is too large Load Diff

172
src/drivers/Qt/RamSearch.h Normal file
View File

@ -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);

1356
src/drivers/Qt/RamWatch.cpp Normal file

File diff suppressed because it is too large Load Diff

258
src/drivers/Qt/RamWatch.h Normal file
View File

@ -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 );

View File

@ -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;
}
//--------------------------------------------------------------

View File

@ -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

View File

@ -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 );
}
}
}
//----------------------------------------------------------------------------

View File

@ -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 );
};

File diff suppressed because it is too large Load Diff

View File

@ -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);

View File

@ -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);

View File

@ -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 );

View File

@ -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);

View File

@ -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(); }

View File

@ -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);

File diff suppressed because it is too large Load Diff

View File

@ -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);
};

View File

@ -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",
" ",
" ........ ",
" ............... ",
" ........................ ",
" ...........................+ ",
" ............@@..@@........... ",
" .#............@@............$$ ",
" .##..........@@.@.....$$%%%%$$ ",
" &...........@....@$$$$$$%%&%$$ ",
" *&...............$$$$$$$%%&%$$ ",
" =&*.......-;;>;...$$,$$$%**&.. ",
" '&&..............$$,,,%=)!~.. ",
" ~&&............-%%##%*.~'=%& ",
" *&&.....+%%****&&%%&*.&!!' ",
" **&%&***********&&&*~{'= ",
" ********=**~**~**~ ",
" *****~******] ",
" **~***]' ",
" ~]== ",
" ",
" ..... .... .... .. ..@@ @@",
" ..... .... .... .. ..@@@ @@@",
" .. .. .. .. .. @@@ @@@ ",
" .... .. .. .. .. @@@@@@ ",
" .... .. ... .. .. @@@@ ",
" .. .. ... .. .. @@@@ ",
" .. .. .. .. .. @@@@@@ ",
" .. .. .. .. .. @@@ @@@ ",
" .. .... .... .....@@@ @@@",
" .. .... .... ... @@ @@",
" ",
" "};

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More