Merge pull request #22 from TASVideos/master

Sync code to the newest
This commit is contained in:
owomomo 2020-08-31 21:59:23 +08:00 committed by GitHub
commit 3945f290d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
89 changed files with 10674 additions and 1948 deletions

1
CNAME Normal file
View File

@ -0,0 +1 @@
fceux.com

View File

@ -1,7 +1,9 @@
To compile and install FCEUX for SDL, follow the instructions in the README-SDL.md file.
Users of Microsoft Visual Studio can use the solution files within the vc directory.
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.
CMake has been depreciated in favor of scons. However, if you wish to use it you can find the old cmake build files in the attic.
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.

17
README
View File

@ -24,7 +24,7 @@ Table of Contents
----------------
* sdl2 - Version >= 2.0
* cmake - Required to build fceux.
* qt5 - version >= 5.11 recommended
* 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.
* minizip
* zlib
@ -33,6 +33,7 @@ Table of Contents
2 - Installation
----------------
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;
@ -41,6 +42,11 @@ Fceux can be compiled and built using the cmake build system. To compile, run:
To build a binary with debug information included in it:
cmake -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
To do the actual compiling:
make
@ -75,7 +81,12 @@ Look in the src/CMakeList.txt file to tweak options.
4 - GUI
-------
The Qt GUI is required and automatically builds as part of the build.
The Qt (or GTK) GUI is required and automatically builds as part of the build. The Qt GUI is the default.
When invoking cmake, the GTK GUI can be built (instead of Qt) by specifying a -DGTK=1 on the command line.
See above build instructions.
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.
5 - LUA Scripting
-----------------
@ -107,7 +118,7 @@ The latest version of iup (3.5 at the time of writing) is recommended.
-------
* Q. Im having issues with my sound!
* A. First of all, for the best sound quality be sure you are using SDL 1.2.14 or later. Versions 1.2.13 and earlier are known to have problems with fceux! Next, try different SDL audio drivers to see if this makes any difference. You can do this by using this command before running fceux:
* A. Try different SDL audio drivers to see if this makes any difference. You can do this by using this command before running fceux:
export SDL_AUDIODRIVER=driver

View File

@ -98,16 +98,16 @@ else:
conf.env.Append(CCFLAGS = "-DHAVE_ASPRINTF")
if env['SYSTEM_MINIZIP']:
assert env.ParseConfig('pkg-config minizip --cflags --libs'), "please install: libminizip"
assert conf.CheckLibWithHeader('z', 'zlib.h', 'c', 'inflate;', 1), "please install: zlib"
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 conf.CheckLibWithHeader('z', 'zlib.h', 'c', 'inflate;', 1), "please install: zlib"
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']:
if not conf.CheckLib('SDL2'):
print('Did not find libSDL2 or SDL2.lib, exiting!')
Exit(1)
assert env.ParseConfig('pkg-config sdl2 --cflags --libs'), "please install: sdl2"
env.Append(CPPDEFINES=["_SDL2"])
env.ParseConfig('pkg-config sdl2 --cflags --libs')
#env.ParseConfig('pkg-config sdl2 --cflags --libs')
else:
if not conf.CheckLib('SDL'):
print('Did not find libSDL or SDL.lib, exiting!')

View File

@ -1,21 +1,66 @@
Priorities
==========
* Clean out old unused files - scons build system is dead, cmake is the way to go.
* GTK GUI was not cross-platform. Has been replaced in favor of Qt5. Need to clean out dead code.
* Cheat Editor will be a high priority.
* Code cleanup. Lots of compiler warning with newer GCC. Maybe I'm OCD... but these warnings bother me.
* 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).
* Code cleanup. Lots of compiler warnings with newer GCC. Maybe I'm OCD... but these warnings bother me.
Features
========
* Emulator no runs as a separate thread from the GUI. Much improved performance.
* Cross platform QT GUI is fully functional minus Debug Tools and Cheat Menu.
* Cross platform QT GUI is fully functional minus Debug Tools.
---------------------------------------------------------------------------------|
---------------------- GUI Capability Matrix -----------------------------------|
---------------------------------------------------------------------------------|
Feature | Qt5 | GTK3 |
-----------------------------------------------------|-------------|-------------|
Basic game ROM open/run and close via menu functions | YES | YES |
Load/save game states | YES | YES |
Select and execute Lua script via file browser | YES | YES |
Lua Console/Control Window | YES | NO |
Screenshot snap/save functionality | YES | YES |
Virtual game pad button mapping window | YES | YES |
Other input device type button mapping window | NO | NO |
Audio mixer / config window | YES | YES |
Video config window | YES | YES |
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 hotkeys | YES | YES |
Fullscreen functionality | YES | YES |
AVI Record Functionality | NO | NO |
NES Emulation Power/Reset/Pause functionality | YES | YES |
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 |
Memory Watch Window | NO | NO |
TAS Editor | NO | NO |
6502 Debugger Window | NO | YES |
PPU Viewer | NO | NO |
Name Table Viewer | NO | NO |
Memory Hex Editor | NO | YES |
Trace Logger | NO | NO |
Code/Data Logger | NO | NO |
Game Genie Encoder/Decoder | NO | NO |
iNES Header Editor | NO | NO |
Built in help pages | NO | NO |
Network play (who actually uses this???) | NO | NO |
-----------------------------------------------------|-------------|-------------|
---------------------------------------------------------------------------------|
---------------------------------------------------------------------------------|
QT
===
* Clean out rest of old GTK comments and #ifdefs
* GUI Cheat editor TODO
* GUI Debug Tools TODO
* GUI should compile in windows as well.... but testing is not a priority since the windows gui has a totally separate backend.
* 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

@ -10,7 +10,9 @@ my $PKG_OUTPUT_FILE="fceux-$VERSION-$ARCH.deb";
# Start by auto figuring out dependencies of the executable.
# the rest of the package creation is trival.
my $SO_LIST=`objdump -x $INSTALL_PREFIX/usr/bin/fceux`;
my $SO_LIST="";
$SO_LIST=`objdump -x $INSTALL_PREFIX/usr/bin/fceux`;
$SO_LIST= $SO_LIST . `objdump -x $INSTALL_PREFIX/usr/bin/fceux-gtk`;
#print "$SO_LIST";

View File

@ -60,8 +60,8 @@ pkg-config --cflags --libs minizip
#echo '****************************************'
#echo 'Install Dependency libgtk-3-dev'
#echo '****************************************'
#sudo apt-get --assume-yes install libgtk-3-dev
#pkg-config --cflags --libs gtk+-3.0
sudo apt-get --assume-yes install libgtk-3-dev
pkg-config --cflags --libs gtk+-3.0
#
## Install GTK+-3 Sourceview
#sudo apt-get --assume-yes install libgtksourceview-3.0-dev
@ -92,8 +92,7 @@ mkdir -p $INSTALL_PREFIX/usr;
#scons --clean
#scons GTK3=1 SYSTEM_LUA=1 SYSTEM_MINIZIP=1 CREATE_AVI=1 install --prefix=$INSTALL_PREFIX/usr
echo "Num CPU: `nproc`";
mkdir build; cd build;
#qmake PREFIX=$INSTALL_PREFIX/usr ..
mkdir buildQT; cd buildQT;
cmake \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX/usr \
@ -102,6 +101,17 @@ cmake \
make -j `nproc`
make install
cd ..;
mkdir buildGTK; cd buildGTK;
cmake \
-DGTK=1 \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX/usr \
-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \
..
make -j `nproc`
make install
# Install Files
#cd .. # cd out of build
#mkdir -p $INSTALL_PREFIX/usr/bin/.
@ -134,6 +144,16 @@ else
exit 1;
fi
if [ -e $INSTALL_PREFIX/usr/bin/fceux-gtk ]; then
echo '**************************************************************'
echo 'Printing Shared Object Dependencies for fceux-gtk Executable'
echo '**************************************************************'
ldd $INSTALL_PREFIX/usr/bin/fceux-gtk
else
echo "Error: Executable Failed to build: $INSTALL_PREFIX/usr/bin/fceux-gtk";
exit 1;
fi
echo '**************************************************************'
echo 'Printing To Be Packaged Files '
echo '**************************************************************'

View File

@ -8,6 +8,7 @@ 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)
* Status: [Appveyor](https://ci.appveyor.com/project/zeromus/fceux/)
But you might like mesen more: https://github.com/SourMesen/Mesen

View File

@ -1,9 +1,14 @@
if ( ${GTK} )
message( STATUS "GUI backend: GTK")
set( APP_NAME fceux-gtk)
else()
message( STATUS "GUI backend: QT")
set( APP_NAME fceux)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set( APP_NAME fceux)
endif()
if(WIN32)
set(SOURCES ${SRC_CORE} ${SRC_DRIVERS_COMMON} ${SRC_DRIVERS_WIN})
@ -21,20 +26,34 @@ else(WIN32)
# Non Windows System
# UNIX (Linux or Mac OSX)
#set (OpenGL_GL_PREFERENCE GLVND)
if ( ${GLVND} )
message( STATUS "OpenGL preference: GLVND")
set (OpenGL_GL_PREFERENCE GLVND)
else()
message( STATUS "OpenGL preference: LEGACY")
set (OpenGL_GL_PREFERENCE LEGACY)
endif()
# Use the built-in cmake find_package functions to find dependencies
# Use package PkgConfig to detect headers/library what find_package cannot find.
find_package(PkgConfig REQUIRED)
find_package(Qt5 COMPONENTS Widgets OpenGL REQUIRED)
find_package(OpenGL REQUIRED)
find_package(ZLIB REQUIRED)
add_definitions( -Wall -Wno-write-strings -Wno-sign-compare -Wno-parentheses -Wno-unused-local-typedefs -fPIC )
add_definitions( -DFCEUDEF_DEBUGGER )
if ( ${GTK} )
pkg_check_modules( GTK3 REQUIRED gtk+-3.0)
pkg_check_modules( X11 REQUIRED x11)
add_definitions( ${GTK3_CFLAGS} ${X11_CFLAGS} )
add_definitions( -D_GTK -DOPENGL )
else(${GTK})
find_package(Qt5 COMPONENTS Widgets OpenGL REQUIRED)
add_definitions( ${Qt5Widgets_DEFINITIONS} )
include_directories( ${Qt5Widgets_INCLUDE_DIRS} )
add_definitions( -D__QT_DRIVER__ -Wall -Wno-write-strings -Wno-sign-compare -Wno-parentheses -Wno-unused-local-typedefs -fPIC -DQT_DEPRECATED_WARNINGS )
add_definitions( -D__QT_DRIVER__ -DQT_DEPRECATED_WARNINGS )
endif()
# Check for libminizip
pkg_check_modules( MINIZIP REQUIRED minizip)
@ -376,11 +395,31 @@ set(SRC_DRIVERS_COMMON
${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/scale3x.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/scalebit.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/vidblit.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/os_utils.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/nes_ntsc.c
${CMAKE_CURRENT_SOURCE_DIR}/drivers/videolog/nesvideos-piece.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/videolog/rgbtorgb.cpp
)
if ( ${GTK} )
set(SRC_DRIVERS_SDL
${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/cheat.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/config.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/debugger.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/glxwin.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/gui.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/GamePadConf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/input.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/memview.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/ramwatch.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/sdl.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/sdl-joystick.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/sdl-sound.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/sdl-throttle.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/sdl-video.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/sdl/unix-netplay.cpp
)
else()
set(SRC_DRIVERS_SDL
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/main.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleWindow.cpp
@ -388,6 +427,12 @@ set(SRC_DRIVERS_SDL
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ConsoleViewerSDL.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/GamePadConf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/HotKeyConf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/PaletteConf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/GuiConf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/LuaControl.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/CheatsConf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/HexEditor.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/AboutWindow.cpp
@ -402,6 +447,7 @@ set(SRC_DRIVERS_SDL
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/sdl-throttle.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/unix-netplay.cpp
)
endif()
set(SOURCES ${SRC_CORE} ${SRC_DRIVERS_COMMON} ${SRC_DRIVERS_SDL})
@ -421,12 +467,28 @@ set_source_files_properties( ${APP_ICON} PROPERTIES MACOSX_PACKAGE_LOCATION "Res
add_executable( ${APP_NAME} MACOSX_BUNDLE ${APP_ICON} ${SOURCES} ../resources.qrc
${CMAKE_CURRENT_BINARY_DIR}/fceux_git_info.cpp)
else()
if ( ${GTK} )
add_executable( ${APP_NAME} ${SOURCES}
${CMAKE_CURRENT_BINARY_DIR}/fceux_git_info.cpp)
else()
add_executable( ${APP_NAME} ${SOURCES} ../resources.qrc
${CMAKE_CURRENT_BINARY_DIR}/fceux_git_info.cpp)
endif()
endif()
target_link_libraries( fceux
if ( ${GTK} )
target_link_libraries( ${APP_NAME}
${GTK3_LDFLAGS} ${X11_LDFLAGS}
${OPENGL_LDFLAGS}
${SDL2_LDFLAGS}
${MINIZIP_LDFLAGS} ${ZLIB_LIBRARIES}
${LUA_LDFLAGS}
${SYS_LIBS}
)
else()
target_link_libraries( ${APP_NAME}
${Qt5Widgets_LIBRARIES}
${Qt5OpenGL_LIBRARIES}
${OPENGL_LDFLAGS}
@ -435,6 +497,7 @@ target_link_libraries( fceux
${LUA_LDFLAGS}
${SYS_LIBS}
)
endif()
if (APPLE)

View File

@ -48,120 +48,205 @@ static SFORMAT StateRegs[] =
#define X24C0X_READ 3
#define X24C0X_WRITE 4
static uint8 x24c0x_data[256], x24c0x_state;
static uint8 x24c0x_addr, x24c0x_word, x24c0x_latch, x24c0x_bitcount;
static uint8 x24c0x_sda, x24c0x_scl, x24c0x_out, x24c0x_oe;
static uint8 x24c0x_data[512];
static SFORMAT x24c0xStateRegs[] =
static uint8 x24c01_state;
static uint8 x24c01_addr, x24c01_word, x24c01_latch, x24c01_bitcount;
static uint8 x24c01_sda, x24c01_scl, x24c01_out;
static uint8 x24c02_state;
static uint8 x24c02_addr, x24c02_word, x24c02_latch, x24c02_bitcount;
static uint8 x24c02_sda, x24c02_scl, x24c02_out;
static SFORMAT x24c01StateRegs[] =
{
{ &x24c0x_addr, 1, "ADDR" },
{ &x24c0x_word, 1, "WORD" },
{ &x24c0x_latch, 1, "LATC" },
{ &x24c0x_bitcount, 1, "BITC" },
{ &x24c0x_sda, 1, "SDA" },
{ &x24c0x_scl, 1, "SCL" },
{ &x24c0x_out, 1, "OUT" },
{ &x24c0x_oe, 1, "OE" },
{ &x24c0x_state, 1, "STAT" },
{ &x24c01_addr, 1, "ADDR" },
{ &x24c01_word, 1, "WORD" },
{ &x24c01_latch, 1, "LATC" },
{ &x24c01_bitcount, 1, "BITC" },
{ &x24c01_sda, 1, "SDA" },
{ &x24c01_scl, 1, "SCL" },
{ &x24c01_out, 1, "OUT" },
{ &x24c01_state, 1, "STAT" },
{ 0 }
};
static void x24c0x_init() {
x24c0x_addr = x24c0x_word = x24c0x_latch = x24c0x_bitcount = x24c0x_sda = x24c0x_scl = x24c0x_oe = 0;
x24c0x_state = X24C0X_STANDBY;
static SFORMAT x24c02StateRegs[] =
{
{ &x24c02_addr, 1, "ADDR" },
{ &x24c02_word, 1, "WORD" },
{ &x24c02_latch, 1, "LATC" },
{ &x24c02_bitcount, 1, "BITC" },
{ &x24c02_sda, 1, "SDA" },
{ &x24c02_scl, 1, "SCL" },
{ &x24c02_out, 1, "OUT" },
{ &x24c02_state, 1, "STAT" },
{ 0 }
};
static void x24c01_init() {
x24c01_addr = x24c01_word = x24c01_latch = x24c01_bitcount = x24c01_sda = x24c01_scl = 0;
x24c01_state = X24C0X_STANDBY;
}
static void x24c0x_write(uint8 data) {
uint8 sda = (data >> 6) & 1;
static void x24c02_init() {
x24c02_addr = x24c02_word = x24c02_latch = x24c02_bitcount = x24c02_sda = x24c02_scl = 0;
x24c02_state = X24C0X_STANDBY;
}
static void x24c01_write(uint8 data) {
uint8 scl = (data >> 5) & 1;
x24c0x_oe = (data >> 7);
uint8 sda = (data >> 6) & 1;
if(x24c0x_scl && scl) {
if(x24c0x_sda && !sda) { // START
x24c0x_state = X24C0X_ADDRESS;
x24c0x_bitcount = 0;
x24c0x_addr = 0;
} else if(!x24c0x_sda && sda) { //STOP
x24c0x_state = X24C0X_STANDBY;
if(x24c01_scl && scl) {
if(x24c01_sda && !sda) { // START
x24c01_state = X24C0X_ADDRESS;
x24c01_bitcount = 0;
x24c01_addr = 0;
} else if(!x24c01_sda && sda) { //STOP
x24c01_state = X24C0X_STANDBY;
}
} else if(!x24c0x_scl && scl) { // RISING EDGE
switch(x24c0x_state) {
} else if(!x24c01_scl && scl) { // RISING EDGE
switch(x24c01_state) {
case X24C0X_ADDRESS:
if(x24c0x_bitcount < 7) {
x24c0x_addr <<= 1;
x24c0x_addr |= sda;
if(x24c01_bitcount < 7) {
x24c01_addr <<= 1;
x24c01_addr |= sda;
} else {
if(!x24c02) // X24C01 mode
x24c0x_word = x24c0x_addr;
if(sda) { // READ COMMAND
x24c0x_state = X24C0X_READ;
} else { // WRITE COMMAND
if(x24c02) // X24C02 mode
x24c0x_state = X24C0X_WORD;
else
x24c0x_state = X24C0X_WRITE;
x24c01_word = x24c01_addr;
if(sda) // READ COMMAND
x24c01_state = X24C0X_READ;
else // WRITE COMMAND
x24c01_state = X24C0X_WRITE;
}
}
x24c0x_bitcount++;
break;
case X24C0X_WORD:
if(x24c0x_bitcount == 8) { // ACK
x24c0x_word = 0;
x24c0x_out = 0;
} else { // WORD ADDRESS INPUT
x24c0x_word <<= 1;
x24c0x_word |= sda;
if(x24c0x_bitcount == 16) { // END OF ADDRESS INPUT
x24c0x_bitcount = 7;
x24c0x_state = X24C0X_WRITE;
}
}
x24c0x_bitcount++;
x24c01_bitcount++;
break;
case X24C0X_READ:
if (x24c0x_bitcount == 8) { // ACK
x24c0x_out = 0;
x24c0x_latch = x24c0x_data[x24c0x_word];
x24c0x_bitcount = 0;
if (x24c01_bitcount == 8) { // ACK
x24c01_out = 0;
x24c01_latch = x24c0x_data[x24c01_word];
x24c01_bitcount = 0;
} else { // REAL OUTPUT
x24c0x_out = x24c0x_latch >> 7;
x24c0x_latch <<= 1;
x24c0x_bitcount++;
if(x24c0x_bitcount == 8) {
x24c0x_word++;
x24c0x_word &= 0xff;
x24c01_out = x24c01_latch >> 7;
x24c01_latch <<= 1;
x24c01_bitcount++;
if(x24c01_bitcount == 8) {
x24c01_word++;
x24c01_word &= 0xff;
}
}
break;
case X24C0X_WRITE:
if (x24c0x_bitcount == 8) { // ACK
x24c0x_out = 0;
x24c0x_latch = 0;
x24c0x_bitcount = 0;
if (x24c01_bitcount == 8) { // ACK
x24c01_out = 0;
x24c01_latch = 0;
x24c01_bitcount = 0;
} else { // REAL INPUT
x24c0x_latch <<= 1;
x24c0x_latch |= sda;
x24c0x_bitcount++;
if(x24c0x_bitcount == 8) {
x24c0x_data[x24c0x_word] = x24c0x_latch;
x24c0x_word++;
x24c0x_word &= 0xff;
x24c01_latch <<= 1;
x24c01_latch |= sda;
x24c01_bitcount++;
if(x24c01_bitcount == 8) {
x24c0x_data[x24c01_word] = x24c01_latch;
x24c01_word++;
x24c01_word &= 0xff;
}
}
break;
}
}
x24c0x_sda = sda;
x24c0x_scl = scl;
x24c01_sda = sda;
x24c01_scl = scl;
}
static uint8 x24c0x_read() {
return x24c0x_out << 4;
static void x24c02_write(uint8 data) {
uint8 scl = (data >> 5) & 1;
uint8 sda = (data >> 6) & 1;
if (x24c02_scl && scl) {
if (x24c02_sda && !sda) { // START
x24c02_state = X24C0X_ADDRESS;
x24c02_bitcount = 0;
x24c02_addr = 0;
} else if (!x24c02_sda && sda) { //STOP
x24c02_state = X24C0X_STANDBY;
}
} else if (!x24c02_scl && scl) { // RISING EDGE
switch (x24c02_state) {
case X24C0X_ADDRESS:
if (x24c02_bitcount < 7) {
x24c02_addr <<= 1;
x24c02_addr |= sda;
} else {
if (sda) // READ COMMAND
x24c02_state = X24C0X_READ;
else // WRITE COMMAND
x24c02_state = X24C0X_WORD;
}
x24c02_bitcount++;
break;
case X24C0X_WORD:
if (x24c02_bitcount == 8) { // ACK
x24c02_word = 0;
x24c02_out = 0;
} else { // WORD ADDRESS INPUT
x24c02_word <<= 1;
x24c02_word |= sda;
if (x24c02_bitcount == 16) {// END OF ADDRESS INPUT
x24c02_bitcount = 7;
x24c02_state = X24C0X_WRITE;
}
}
x24c02_bitcount++;
break;
case X24C0X_READ:
if (x24c02_bitcount == 8) { // ACK
x24c02_out = 0;
x24c02_latch = x24c0x_data[x24c02_word|0x100];
x24c02_bitcount = 0;
} else { // REAL OUTPUT
x24c02_out = x24c02_latch >> 7;
x24c02_latch <<= 1;
x24c02_bitcount++;
if (x24c02_bitcount == 8) {
x24c02_word++;
x24c02_word &= 0xff;
}
}
break;
case X24C0X_WRITE:
if (x24c02_bitcount == 8) { // ACK
x24c02_out = 0;
x24c02_latch = 0;
x24c02_bitcount = 0;
} else { // REAL INPUT
x24c02_latch <<= 1;
x24c02_latch |= sda;
x24c02_bitcount++;
if (x24c02_bitcount == 8) {
x24c0x_data[x24c02_word|0x100] = x24c02_latch;
x24c02_word++;
x24c02_word &= 0xff;
}
}
break;
}
}
x24c02_sda = sda;
x24c02_scl = scl;
}
//
static void SyncMirror(void) {
switch (reg[9] & 3) {
case 0: setmirror(MI_V); break;
case 1: setmirror(MI_H); break;
case 2: setmirror(MI_0); break;
case 3: setmirror(MI_1); break;
}
}
static void Sync(void) {
if (is153) {
int base = (reg[0] & 1) << 4;
@ -174,12 +259,7 @@ static void Sync(void) {
setprg16(0x8000, reg[8]);
setprg16(0xC000, ~0);
}
switch (reg[9] & 3) {
case 0: setmirror(MI_V); break;
case 1: setmirror(MI_H); break;
case 2: setmirror(MI_0); break;
case 3: setmirror(MI_1); break;
}
SyncMirror();
}
static DECLFW(BandaiWrite) {
@ -192,12 +272,15 @@ static DECLFW(BandaiWrite) {
case 0x0A: X6502_IRQEnd(FCEU_IQEXT); IRQa = V & 1; IRQCount = IRQLatch; break;
case 0x0B: IRQLatch &= 0xFF00; IRQLatch |= V; break;
case 0x0C: IRQLatch &= 0xFF; IRQLatch |= V << 8; break;
case 0x0D: x24c0x_write(V); break;
case 0x0D: if(x24c02) x24c02_write(V); else x24c01_write(V); break;
}
}
static DECLFR(BandaiRead) {
return (X.DB & 0xEF) | x24c0x_read();
if(x24c02)
return (X.DB & 0xEF) | (x24c02_out << 4);
else
return (X.DB & 0xEF) | (x24c01_out << 4);
}
static void BandaiIRQHook(int a) {
@ -213,11 +296,14 @@ static void BandaiIRQHook(int a) {
static void BandaiPower(void) {
IRQa = 0;
x24c0x_init();
if(x24c02)
x24c02_init();
else
x24c01_init();
Sync();
SetReadHandler(0x6000, 0x7FFF, BandaiRead);
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x6000, 0xFFFF, BandaiWrite);
SetWriteHandler(0x8000, 0xFFFF, BandaiWrite);
}
static void StateRestore(int version) {
@ -231,12 +317,12 @@ void Mapper16_Init(CartInfo *info) {
MapIRQHook = BandaiIRQHook;
info->battery = 1;
info->SaveGame[0] = x24c0x_data;
info->SaveGame[0] = x24c0x_data + 256;
info->SaveGameLen[0] = 256;
AddExState(x24c0x_data, 256, 0, "DATA");
AddExState(&x24c02StateRegs, ~0, 0, 0);
GameStateRestore = StateRestore;
AddExState(&x24c0xStateRegs, ~0, 0, 0);
AddExState(&StateRegs, ~0, 0, 0);
}
@ -250,9 +336,9 @@ void Mapper159_Init(CartInfo *info) {
info->SaveGame[0] = x24c0x_data;
info->SaveGameLen[0] = 128;
AddExState(x24c0x_data, 128, 0, "DATA");
AddExState(&x24c01StateRegs, ~0, 0, 0);
GameStateRestore = StateRestore;
AddExState(&x24c0xStateRegs, ~0, 0, 0);
AddExState(&StateRegs, ~0, 0, 0);
}
@ -307,7 +393,9 @@ static int BarcodeReadPos;
static int BarcodeCycleCount;
static uint32 BarcodeOut;
int FCEUI_DatachSet(const uint8 *rcode) {
// #define INTERL2OF5
int FCEUI_DatachSet(uint8 *rcode) {
int prefix_parity_type[10][6] = {
{ 0, 0, 0, 0, 0, 0 }, { 0, 0, 1, 0, 1, 1 }, { 0, 0, 1, 1, 0, 1 }, { 0, 0, 1, 1, 1, 0 },
{ 0, 1, 0, 0, 1, 1 }, { 0, 1, 1, 0, 0, 1 }, { 0, 1, 1, 1, 0, 0 }, { 0, 1, 0, 1, 0, 1 },
@ -330,6 +418,7 @@ int FCEUI_DatachSet(const uint8 *rcode) {
};
uint8 code[13 + 1];
uint32 tmp_p = 0;
uint32 csum = 0;
int i, j;
int len;
@ -343,16 +432,44 @@ int FCEUI_DatachSet(const uint8 *rcode) {
#define BS(x) BarcodeData[tmp_p] = x; tmp_p++
for (j = 0; j < 32; j++) {
for (j = 0; j < 32; j++) { // delay before sending a code
BS(0x00);
}
/* Left guard bars */
#ifdef INTERL2OF5
BS(1); BS(1); BS(0); BS(0); // 1
BS(1); BS(1); BS(0); BS(0); // 1
BS(1); BS(1); BS(0); BS(0); // 1
BS(1); BS(1); BS(0); BS(0); // 1
BS(1); BS(1); BS(0); BS(0); // 1
BS(1); BS(0); BS(0); // 0
BS(1); BS(0); BS(0); // 0
BS(1); BS(0); BS(0); // 0
BS(1); BS(0); BS(0); // 0
BS(1); BS(0); BS(0); // 0
BS(1); BS(0); BS(0); // 0
BS(1); BS(0); BS(0); // 0
BS(1); BS(0); BS(0); // 0
BS(1); BS(0); BS(0); // 0
BS(1); BS(0); BS(0); // 0
BS(1); BS(0); BS(0); // 0
BS(1); BS(0); BS(0); // 0
BS(1); BS(0); BS(0); // 0
BS(1); BS(0); BS(0); // 0
BS(1); BS(0); BS(0); // 0
BS(1); BS(0); BS(0); // 0
BS(1); BS(0); BS(0); // 0
BS(1); BS(0); BS(0); // 0
BS(1); BS(0); BS(0); // 0
BS(1); BS(0); BS(0); // 0
BS(1); BS(0); BS(0); // 0 cs
BS(1); BS(1); BS(0); BS(0); // 1
#else
// Left guard bars
BS(1); BS(0); BS(1);
if (len == 13 || len == 12) {
uint32 csum;
for (i = 0; i < 6; i++)
if (prefix_parity_type[code[0]][i]) {
for (j = 0; j < 7; j++) {
@ -362,53 +479,53 @@ int FCEUI_DatachSet(const uint8 *rcode) {
for (j = 0; j < 7; j++) {
BS(data_left_odd[code[i + 1]][j]);
}
/* Center guard bars */
// Center guard bars
BS(0); BS(1); BS(0); BS(1); BS(0);
for (i = 7; i < 12; i++)
for (j = 0; j < 7; j++) {
BS(data_right[code[i]][j]);
}
csum = 0;
for (i = 0; i < 12; i++) csum += code[i] * ((i & 1) ? 3 : 1);
// Calc and write down the control code if not assigned, instead, send code as is
// Battle Rush uses modified type of codes with different control code calculation
if (len == 12) {
for (i = 0; i < 12; i++)
csum += code[i] * ((i & 1) ? 3 : 1);
csum = (10 - (csum % 10)) % 10;
rcode[12] = csum + 0x30; // update check code to the input string as well
rcode[13] = 0;
code[12] = csum;
}
for (j = 0; j < 7; j++) {
BS(data_right[csum][j]);
BS(data_right[code[12]][j]);
}
} else if (len == 8 || len == 7) {
uint32 csum = 0;
for (i = 0; i < 7; i++) csum += (i & 1) ? code[i] : (code[i] * 3);
csum = (10 - (csum % 10)) % 10;
for (i = 0; i < 4; i++)
for (j = 0; j < 7; j++) {
BS(data_left_odd[code[i]][j]);
}
/* Center guard bars */
// Center guard bars
BS(0); BS(1); BS(0); BS(1); BS(0);
for (i = 4; i < 7; i++)
for (j = 0; j < 7; j++) {
BS(data_right[code[i]][j]);
}
csum = 0;
for (i = 0; i < 7; i++)
csum += (i & 1) ? code[i] : (code[i] * 3);
csum = (10 - (csum % 10)) % 10;
rcode[7] = csum + 0x30; // update check code to the input string as well
rcode[8] = 0;
for (j = 0; j < 7; j++) {
BS(data_right[csum][j]);
}
}
/* Right guard bars */
// Right guard bars
BS(1); BS(0); BS(1);
#endif
for (j = 0; j < 32; j++) {
BS(0x00);
}
BS(0xFF);
#undef BS
@ -419,6 +536,26 @@ int FCEUI_DatachSet(const uint8 *rcode) {
return(1);
}
static void BarcodeSync(void) {
setchr8(0);
setprg16(0x8000, (reg[8] & 0x0F));
setprg16(0xC000, 0x0F);
SyncMirror();
}
static DECLFW(BarcodeWrite) {
A &= 0x0F;
switch (A) {
case 0x00: reg[0] = (V & 8) << 2; x24c01_write(reg[0xD] | reg[0]); break; // extra EEPROM x24C01 used in Battle Rush mini-cart
case 0x08:
case 0x09: reg[A] = V; BarcodeSync(); break;
case 0x0A: X6502_IRQEnd(FCEU_IQEXT); IRQa = V & 1; IRQCount = IRQLatch; break;
case 0x0B: IRQLatch &= 0xFF00; IRQLatch |= V; break;
case 0x0C: IRQLatch &= 0xFF; IRQLatch |= V << 8; break;
case 0x0D: reg[0xD] = V & (~0x20); x24c01_write(reg[0xD] | reg[0]); x24c02_write(V); break;
}
}
static void BarcodeIRQHook(int a) {
BandaiIRQHook(a);
@ -436,7 +573,7 @@ static void BarcodeIRQHook(int a) {
}
static DECLFR(BarcodeRead) {
return BarcodeOut;
return (X.DB & 0xE7) | ((x24c02_out | x24c01_out) << 4) | BarcodeOut;
}
static void M157Power(void) {
@ -446,20 +583,29 @@ static void M157Power(void) {
BarcodeOut = 0;
BarcodeCycleCount = 0;
Sync();
x24c01_init();
x24c02_init();
BarcodeSync();
SetWriteHandler(0x6000, 0xFFFF, BandaiWrite);
SetReadHandler(0x6000, 0x7FFF, BarcodeRead);
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, BarcodeWrite);
}
void Mapper157_Init(CartInfo *info) {
is153 = 1;
x24c02 = 1;
info->Power = M157Power;
MapIRQHook = BarcodeIRQHook;
GameInfo->cspecial = SIS_DATACH;
info->battery = 1;
info->SaveGame[0] = x24c0x_data;
info->SaveGameLen[0] = 512;
AddExState(x24c0x_data, 512, 0, "DATA");
AddExState(&x24c01StateRegs, ~0, 0, 0);
AddExState(&x24c02StateRegs, ~0, 0, 0);
GameStateRestore = StateRestore;
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
}

View File

@ -604,8 +604,8 @@ void OPLL_reset(OPLL * opll) {
for (i = 0; i < 0x40; i++)
OPLL_writeReg(opll, i, 0);
opll->realstep = (uint32)((1 << 31) / rate);
opll->opllstep = (uint32)((1 << 31) / (clk / 72));
opll->realstep = (uint32)((1u << 31) / rate);
opll->opllstep = (uint32)((1u << 31) / (clk / 72));
opll->oplltime = 0;
}

View File

@ -82,10 +82,10 @@ static int prg_mask;
//PRG wrapper
static void BMCFK23CPW(uint32 A, uint8 V)
{
uint32 bank = (EXPREGS[1] & 0x1F);
uint32 hiblock = ((EXPREGS[0] & 8) << 4)|((EXPREGS[0] & 0x80) << 1)|(UNIFchrrama?((EXPREGS[2] & 0x40)<<3):0);
uint32 block = (EXPREGS[1] & 0x60) | hiblock;
uint32 extra = (EXPREGS[3] & 2);
//uint32 bank = (EXPREGS[1] & 0x1F);
//uint32 hiblock = ((EXPREGS[0] & 8) << 4)|((EXPREGS[0] & 0x80) << 1)|(UNIFchrrama?((EXPREGS[2] & 0x40)<<3):0);
//uint32 block = (EXPREGS[1] & 0x60) | hiblock;
//uint32 extra = (EXPREGS[3] & 2);
// FCEU_printf("0:%04X:%02X\n",A,V);
if((EXPREGS[0]&7)==4)
@ -161,7 +161,7 @@ static DECLFW(BMCFK23CWrite)
EXPREGS[A&3]=V;
// BUT WHY is there any rom that need it actually?
bool remap = false;
// bool remap = false;
// FCEU_printf("K3:(exp0=%02x)\n",EXPREGS[0]);
// FCEU_printf("WH0:%04X:%02X\n",A,V);
@ -199,7 +199,7 @@ static void BMCFK23CReset(void)
//this little hack makes sure that we try all the dip switch settings eventually, if we reset enough
dipswitch++;
dipswitch&=7;
printf("BMCFK23C dipswitch set to %d\n",dipswitch);
printf("BMCFK23C dipswitch set to %u\n",dipswitch);
EXPREGS[0]=EXPREGS[1]=EXPREGS[2]=EXPREGS[3]=0;
EXPREGS[4]=EXPREGS[5]=EXPREGS[6]=EXPREGS[7]=0xFF;

View File

@ -52,7 +52,9 @@ static void MMC1CHR(void) {
static void MMC1PRG(void) {
uint8 offs_16banks = DRegs[1] & 0x10;
uint8 prg_reg = DRegs[3] & 0xF;
setprg8r(0x10, 0x6000, DRegs[1] & 3);
switch (DRegs[0] & 0xC) {
case 0xC:
setprg16(0x8000, (prg_reg + offs_16banks));
@ -96,13 +98,13 @@ static DECLFW(MMC1_write) {
Buffer |= (V & 1) << (BufferShift++);
if (BufferShift == 5) {
FCEU_printf("MMC1 REG%d:%02x (PC %04x)\n", n, Buffer, X.PC);
DRegs[n] = Buffer;
// FCEU_printf("MMC1 REG%d:%02x\n", n, Buffer);
BufferShift = Buffer = 0;
switch (n) {
case 0: MMC1MIRROR(); // break;
case 1: // break;
// case 2: MMC1CHR(); break;
case 0: MMC1MIRROR();
case 1:
case 2:
case 3: MMC1PRG(); break;
}
}
@ -151,13 +153,13 @@ static DECLFW(FNC_cmd_write) {
break;
}
case 0x40C0: {
// FCEU_printf("FNS W %04x:%02x\n", A, V);
FCEU_printf("FNS W %04x:%02x (PC %04x)\n", A, V, X.PC);
r40C0 = V;
MMC1CHR();
break;
}
// default:
// FCEU_printf("FNS W %04x:%02x\n", A, V);
default:
FCEU_printf("FNS W %04x:%02x (PC %04x)\n", A, V, X.PC);
}
}
@ -169,23 +171,32 @@ static DECLFR(FNC_stat_read) {
IRQa = 0;
return ret;
}
case 0x40AC: { // NMI/IRQ state reset (lookalike)
return 0;
}
case 0x40B0: {
kanji_pos = 0;
return 0;
}
case 0x40C0: {
// FCEU_printf("FNS R %04x\n", A);
FCEU_printf("FNS R %04x (PC %04x)\n", A, X.PC);
int ret = r40C0;
r40C0 &= 0;
return ret;
}
default: {
// FCEU_printf("FNS R %04x\n", A);
FCEU_printf("FNS R %04x (PC %04x)\n", A, X.PC);
return 0xff;
}
}
}
static DECLFR(FNC_cart_i2c_read) {
FCEU_printf("I2C R %04x (PC %04x)\n", A, X.PC);
return 0;
}
static DECLFR(FNC_kanji_read) {
int32 ofs = ((A & 0xFFF) << 5) + kanji_pos;
kanji_pos++;
@ -217,8 +228,9 @@ static void FNS_Power(void) {
SetReadHandler(0x4080, 0x40FF, FNC_stat_read);
SetReadHandler(0x5000, 0x5FFF, FNC_kanji_read);
SetReadHandler(0x6000, 0x7FFF, MAWRAM);
SetWriteHandler(0x6000, 0x7FFF, MBWRAM);
SetReadHandler(0x6000, 0x6000, FNC_cart_i2c_read);
SetReadHandler(0x6001, 0x7FFF, CartBR);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
FCEU_CheatAddRAM(8, 0x6000, WRAM);
MMC1CMReset();

View File

@ -569,7 +569,7 @@ int FCEUI_DecodeGG(const char *str, int *a, int *v, int *c)
int FCEUI_DecodePAR(const char *str, int *a, int *v, int *c, int *type)
{
int boo[4];
unsigned int boo[4];
if(strlen(str)!=8) return(0);
sscanf(str,"%02x%02x%02x%02x",boo,boo+1,boo+2,boo+3);
@ -921,7 +921,7 @@ inline void FCEUI_CreateCheatMap()
inline void FCEUI_RefreshCheatMap()
{
memset(cheatMap, 0, CHEATMAP_SIZE);
for (int i = 0; i < numsubcheats; ++i)
for (uint32 i = 0; i < numsubcheats; ++i)
FCEUI_SetCheatMapByte(SubCheats[i].addr, true);
}

View File

@ -194,10 +194,10 @@ Condition* Parentheses(const char** str, Condition* c, char openPar, char closeP
{
scan(str);
c->lhs = Connect(str);
if (!c) return 0;
c->lhs = Connect(str);
if (next == closePar)
{
scan(str);

View File

@ -22,7 +22,7 @@ int offsetStringToInt(unsigned int type, const char* offsetBuffer)
{
int offset = -1;
if (sscanf(offsetBuffer,"%4X",&offset) == EOF)
if (sscanf(offsetBuffer,"%4X",(unsigned int *)&offset) == EOF)
{
return -1;
}

View File

@ -142,7 +142,9 @@ void FCEUI_SetRenderedLines(int ntscf, int ntscl, int palf, int pall);
//Sets the base directory(save states, snapshots, etc. are saved in directories below this directory.
void FCEUI_SetBaseDirectory(std::string const & dir);
const char *FCEUI_GetBaseDirectory(void);
bool FCEUI_GetUserPaletteAvail(void);
void FCEUI_SetUserPalette(uint8 *pal, int nEntries);
//Sets up sound code to render sound at the specified rate, in samples
@ -250,7 +252,7 @@ void FCEUI_FDSInsert(void); //mbg merge 7/17/06 changed to void fn(void) to make
//int FCEUI_FDSEject(void);
void FCEUI_FDSSelect(void);
int FCEUI_DatachSet(const uint8 *rcode);
int FCEUI_DatachSet(uint8 *rcode);
///returns a flag indicating whether emulation is paused
int FCEUI_EmulationPaused();
@ -340,7 +342,7 @@ enum EFCEUI
FCEUI_STOPMOVIE, FCEUI_RECORDMOVIE, FCEUI_PLAYMOVIE,
FCEUI_OPENGAME, FCEUI_CLOSEGAME,
FCEUI_TASEDITOR,
FCEUI_RESET, FCEUI_POWER, FCEUI_PLAYFROMBEGINNING, FCEUI_EJECT_DISK, FCEUI_SWITCH_DISK, FCEUI_INSERT_COIN,
FCEUI_RESET, FCEUI_POWER, FCEUI_PLAYFROMBEGINNING, FCEUI_EJECT_DISK, FCEUI_SWITCH_DISK, FCEUI_INSERT_COIN, FCEUI_INPUT_BARCODE,
FCEUI_TOGGLERECORDINGMOVIE, FCEUI_TRUNCATEMOVIE, FCEUI_INSERT1FRAME, FCEUI_DELETE1FRAME
};

View File

@ -16,6 +16,7 @@
static const char *Authors[] = {
"Linux/SDL Developers:",
"\t mjbudd77",
"\t Lukas Sabota //punkrockguy318", "\t Soules", "\t Bryan Cain", "\t radsaq",
"\t Shinydoofy",
"FceuX 2.0 Developers:",

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,99 @@
// GamePadConf.h
//
#pragma once
#include <QWidget>
#include <QDialog>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QComboBox>
#include <QCheckBox>
#include <QPushButton>
#include <QLabel>
#include <QFrame>
#include <QLineEdit>
#include <QGroupBox>
#include <QTreeView>
#include <QTreeWidget>
#include <QTextEdit>
#include "Qt/main.h"
class GuiCheatsDialog_t : public QDialog
{
Q_OBJECT
public:
GuiCheatsDialog_t(QWidget *parent = 0);
~GuiCheatsDialog_t(void);
int addSearchResult( uint32_t a, uint8_t last, uint8_t current );
int activeCheatListCB (char *name, uint32 a, uint8 v, int c, int s, int type, void *data);
protected:
void closeEvent(QCloseEvent *event);
QGroupBox *actCheatFrame;
QGroupBox *cheatSearchFrame;
QGroupBox *cheatResultFrame;
QPushButton *addCheatBtn;
QPushButton *delCheatBtn;
QPushButton *modCheatBtn;
QPushButton *importCheatFileBtn;
QPushButton *exportCheatFileBtn;
QPushButton *srchResetBtn;
QPushButton *knownValBtn;
QPushButton *eqValBtn;
QPushButton *neValBtn;
QPushButton *grValBtn;
QPushButton *ltValBtn;
QCheckBox *useNeVal;
QCheckBox *useGrVal;
QCheckBox *useLtVal;
QCheckBox *enaCheats;
QCheckBox *autoSave;
QCheckBox *pauseBox;
QTreeWidget *actvCheatList;
QTreeWidget *srchResults;
QLineEdit *cheatNameEntry;
QLineEdit *cheatAddrEntry;
QLineEdit *cheatValEntry;
QLineEdit *cheatCmpEntry;
QLineEdit *knownValEntry;
QLineEdit *neValEntry;
QLineEdit *grValEntry;
QLineEdit *ltValEntry;
QFont font;
int fontCharWidth;
int actvCheatIdx;
bool actvCheatRedraw;
bool pauseWhileActive;
bool wasPausedByCheats;
private:
void showCheatSearchResults(void);
void showActiveCheatList(bool redraw);
public slots:
void closeWindow(void);
private slots:
void resetSearchCallback(void);
void knownValueCallback(void);
void equalValueCallback(void);
void notEqualValueCallback(void);
void lessThanValueCallback(void);
void greaterThanValueCallback(void);
void openCheatFile(void);
void saveCheatFile(void);
void addActvCheat(void);
void deleteActvCheat(void);
void updateCheatParameters(void);
void autoLoadSaveCheats(int state);
void globalEnableCheats(int state);
void pauseWindowState(int state);
void actvCheatItemClicked( QTreeWidgetItem *item, int column);
};

View File

@ -1,5 +1,7 @@
// ConsoleSoundConf.cpp
//
#include <QCloseEvent>
#include "../../fceu.h"
#include "../../driver.h"
#include "Qt/ConsoleSoundConf.h"
@ -217,7 +219,22 @@ ConsoleSndConfDialog_t::ConsoleSndConfDialog_t(QWidget *parent)
//----------------------------------------------------
ConsoleSndConfDialog_t::~ConsoleSndConfDialog_t(void)
{
printf("Destroy Sound Config Window\n");
}
//----------------------------------------------------------------------------
void ConsoleSndConfDialog_t::closeEvent(QCloseEvent *event)
{
printf("Sound Config Close Window Event\n");
done(0);
deleteLater();
event->accept();
}
//----------------------------------------------------------------------------
void ConsoleSndConfDialog_t::closeWindow(void)
{
//printf("Sound Close Window\n");
done(0);
deleteLater();
}
//----------------------------------------------------
void ConsoleSndConfDialog_t::setCheckBoxFromProperty( QCheckBox *cbx, const char *property )
@ -262,11 +279,13 @@ void ConsoleSndConfDialog_t::bufSizeChanged(int value)
g_config->setOption ("SDL.Sound.BufSize", value);
// reset sound subsystem for changes to take effect
fceuWrapperLock();
if ( fceuWrapperTryLock() )
{
KillSound ();
InitSound ();
fceuWrapperUnLock();
}
}
//----------------------------------------------------
void ConsoleSndConfDialog_t::volumeChanged(int value)
{
@ -278,10 +297,12 @@ void ConsoleSndConfDialog_t::volumeChanged(int value)
g_config->setOption ("SDL.Sound.Volume", value);
fceuWrapperLock();
if ( fceuWrapperTryLock() )
{
FCEUI_SetSoundVolume (value);
fceuWrapperUnLock();
}
}
//----------------------------------------------------
void ConsoleSndConfDialog_t::triangleChanged(int value)
{
@ -293,10 +314,12 @@ void ConsoleSndConfDialog_t::triangleChanged(int value)
g_config->setOption ("SDL.Sound.TriangleVolume", value);
fceuWrapperLock();
if ( fceuWrapperTryLock() )
{
FCEUI_SetTriangleVolume (value);
fceuWrapperUnLock();
}
}
//----------------------------------------------------
void ConsoleSndConfDialog_t::square1Changed(int value)
{
@ -308,10 +331,12 @@ void ConsoleSndConfDialog_t::square1Changed(int value)
g_config->setOption ("SDL.Sound.Square1Volume", value);
fceuWrapperLock();
if ( fceuWrapperTryLock() )
{
FCEUI_SetSquare1Volume (value);
fceuWrapperUnLock();
}
}
//----------------------------------------------------
void ConsoleSndConfDialog_t::square2Changed(int value)
{
@ -323,10 +348,12 @@ void ConsoleSndConfDialog_t::square2Changed(int value)
g_config->setOption ("SDL.Sound.Square2Volume", value);
fceuWrapperLock();
if ( fceuWrapperTryLock() )
{
FCEUI_SetSquare2Volume (value);
fceuWrapperUnLock();
}
}
//----------------------------------------------------
void ConsoleSndConfDialog_t::noiseChanged(int value)
{
@ -338,10 +365,12 @@ void ConsoleSndConfDialog_t::noiseChanged(int value)
g_config->setOption ("SDL.Sound.NoiseVolume", value);
fceuWrapperLock();
if ( fceuWrapperTryLock() )
{
FCEUI_SetNoiseVolume (value);
fceuWrapperUnLock();
}
}
//----------------------------------------------------
void ConsoleSndConfDialog_t::pcmChanged(int value)
{
@ -353,10 +382,12 @@ void ConsoleSndConfDialog_t::pcmChanged(int value)
g_config->setOption ("SDL.Sound.PCMVolume", value);
fceuWrapperLock();
if ( fceuWrapperTryLock() )
{
FCEUI_SetPCMVolume (value);
fceuWrapperUnLock();
}
}
//----------------------------------------------------
void ConsoleSndConfDialog_t::enaSoundStateChange(int value)
{
@ -427,10 +458,12 @@ void ConsoleSndConfDialog_t::soundQualityChanged(int index)
g_config->setOption ("SDL.Sound.Quality", qualitySelect->itemData(index).toInt() );
// reset sound subsystem for changes to take effect
fceuWrapperLock();
if ( fceuWrapperTryLock() )
{
KillSound ();
InitSound ();
fceuWrapperUnLock();
}
g_config->save ();
}
//----------------------------------------------------
@ -440,10 +473,12 @@ void ConsoleSndConfDialog_t::soundRateChanged(int index)
g_config->setOption ("SDL.Sound.Rate", rateSelect->itemData(index).toInt() );
// reset sound subsystem for changes to take effect
fceuWrapperLock();
if ( fceuWrapperTryLock() )
{
KillSound ();
InitSound ();
fceuWrapperUnLock();
}
g_config->save ();
}
//----------------------------------------------------

View File

@ -25,6 +25,8 @@ class ConsoleSndConfDialog_t : public QDialog
~ConsoleSndConfDialog_t(void);
protected:
void closeEvent(QCloseEvent *event);
QCheckBox *enaChkbox;
QCheckBox *enaLowPass;
QCheckBox *swapDutyChkbox;
@ -44,6 +46,7 @@ class ConsoleSndConfDialog_t : public QDialog
void setSliderFromProperty( QSlider *slider, QLabel *lbl, const char *property );
private slots:
void closeWindow(void);
void bufSizeChanged(int value);
void volumeChanged(int value);
void triangleChanged(int value);

View File

@ -0,0 +1,85 @@
// ConsoleUtilities.cpp
#include <stdio.h>
#include <string.h>
#include "../../fceu.h"
#include "Qt/ConsoleUtilities.h"
//---------------------------------------------------------------------------
int getDirFromFile( const char *path, char *dir )
{
int i, lastSlash = -1, lastPeriod = -1;
i=0;
while ( path[i] != 0 )
{
if ( path[i] == '/' )
{
lastSlash = i;
}
else if ( path[i] == '.' )
{
lastPeriod = i;
}
dir[i] = path[i]; i++;
}
dir[i] = 0;
if ( lastPeriod >= 0 )
{
if ( lastPeriod > lastSlash )
{
dir[lastSlash] = 0;
}
}
return 0;
}
//---------------------------------------------------------------------------
const char *getRomFile( void )
{
if ( GameInfo )
{
return GameInfo->filename;
}
return NULL;
}
//---------------------------------------------------------------------------
// Return file base name stripping out preceding path and trailing suffix.
int getFileBaseName( const char *filepath, char *base )
{
int i=0,j=0,end=0;
if ( filepath == NULL )
{
base[0] = 0;
return 0;
}
i=0; j=0;
while ( filepath[i] != 0 )
{
if ( (filepath[i] == '/') || (filepath[i] == '\\') )
{
j = i+1;
}
i++;
}
i = j;
j=0;
while ( filepath[i] != 0 )
{
base[j] = filepath[i]; i++; j++;
}
base[j] = 0; end=j;
while ( j > 1 )
{
j--;
if ( base[j] == '.' )
{
end=j; base[j] = 0; break;
}
}
return end;
}
//---------------------------------------------------------------------------

View File

@ -0,0 +1,7 @@
// ConsoleUtilities.h
int getDirFromFile( const char *path, char *dir );
const char *getRomFile( void );
int getFileBaseName( const char *filepath, char *base );

View File

@ -1,5 +1,7 @@
// ConsoleVideoConf.cpp
//
#include <QCloseEvent>
#include "../../fceu.h"
#include "Qt/main.h"
#include "Qt/dface.h"
@ -26,7 +28,7 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent)
driverSelect = new QComboBox();
driverSelect->addItem( tr("OpenGL"), 0 );
//driverSelect->addItem( tr("SDL"), 1 );
driverSelect->addItem( tr("SDL"), 1 );
hbox1 = new QHBoxLayout();
@ -52,8 +54,10 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent)
regionSelect->addItem( tr("Dendy"), 2 );
setComboBoxFromProperty( regionSelect, "SDL.PAL");
setComboBoxFromProperty( driverSelect, "SDL.VideoDriver");
connect(regionSelect, SIGNAL(currentIndexChanged(int)), this, SLOT(regionChanged(int)) );
connect(driverSelect, SIGNAL(currentIndexChanged(int)), this, SLOT(driverChanged(int)) );
hbox1 = new QHBoxLayout();
@ -103,7 +107,7 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent)
button = new QPushButton( tr("Close") );
hbox1->addWidget( button );
connect(button, SIGNAL(clicked()), this, SLOT(closewindow(void)) );
connect(button, SIGNAL(clicked()), this, SLOT(closeWindow(void)) );
main_vbox->addLayout( hbox1 );
@ -113,8 +117,24 @@ ConsoleVideoConfDialog_t::ConsoleVideoConfDialog_t(QWidget *parent)
//----------------------------------------------------
ConsoleVideoConfDialog_t::~ConsoleVideoConfDialog_t(void)
{
printf("Destroy Video Config Window\n");
}
//----------------------------------------------------------------------------
void ConsoleVideoConfDialog_t::closeEvent(QCloseEvent *event)
{
printf("Video Config Close Window Event\n");
done(0);
deleteLater();
event->accept();
}
//----------------------------------------------------------------------------
void ConsoleVideoConfDialog_t::closeWindow(void)
{
//printf("Video Config Close Window\n");
done(0);
deleteLater();
}
//----------------------------------------------------
void ConsoleVideoConfDialog_t::resetVideo(void)
{
@ -199,6 +219,20 @@ void ConsoleVideoConfDialog_t::showFPSChanged( int value )
fceuWrapperUnLock();
}
//----------------------------------------------------
void ConsoleVideoConfDialog_t::driverChanged(int index)
{
int driver;
//printf("Driver: %i : %i \n", index, driverSelect->itemData(index).toInt() );
driver = driverSelect->itemData(index).toInt();
g_config->setOption ("SDL.VideoDriver", driver);
g_config->save ();
printf("Note: A restart of the application is needed for video driver change to take effect...\n");
}
//----------------------------------------------------
void ConsoleVideoConfDialog_t::regionChanged(int index)
{
int region;
@ -221,8 +255,3 @@ void ConsoleVideoConfDialog_t::applyChanges( void )
resetVideo();
}
//----------------------------------------------------
void ConsoleVideoConfDialog_t::closewindow( void )
{
done(0);
}
//----------------------------------------------------

View File

@ -25,6 +25,8 @@ class ConsoleVideoConfDialog_t : public QDialog
~ConsoleVideoConfDialog_t(void);
protected:
void closeEvent(QCloseEvent *bar);
QComboBox *driverSelect;
QComboBox *regionSelect;
QCheckBox *gl_LF_chkBox;
@ -40,6 +42,9 @@ class ConsoleVideoConfDialog_t : public QDialog
void resetVideo(void);
public slots:
void closeWindow(void);
private slots:
void use_new_PPU_changed( int value );
void frameskip_changed( int value );
@ -47,8 +52,8 @@ class ConsoleVideoConfDialog_t : public QDialog
void clipSidesChanged( int value );
void showFPSChanged( int value );
void regionChanged(int index);
void driverChanged(int index);
void applyChanges( void );
void closewindow( void );
};

View File

@ -15,6 +15,12 @@ extern unsigned int gui_draw_area_height;
ConsoleViewSDL_t::ConsoleViewSDL_t(QWidget *parent)
: QWidget( parent )
{
QPalette pal = palette();
pal.setColor(QPalette::Background, Qt::black);
setAutoFillBackground(true);
setPalette(pal);
view_width = GL_NES_WIDTH;
view_height = GL_NES_HEIGHT;
@ -30,11 +36,29 @@ ConsoleViewSDL_t::ConsoleViewSDL_t(QWidget *parent)
sdlTexture = NULL;
vsyncEnabled = false;
localBufSize = GL_NES_WIDTH * GL_NES_HEIGHT * sizeof(uint32_t);
localBuf = (uint32_t*)malloc( localBufSize );
if ( localBuf )
{
memset( localBuf, 0, localBufSize );
}
}
ConsoleViewSDL_t::~ConsoleViewSDL_t(void)
{
if ( localBuf )
{
free( localBuf ); localBuf = NULL;
}
}
void ConsoleViewSDL_t::transfer2LocalBuffer(void)
{
memcpy( localBuf, nes_shm->pixbuf, localBufSize );
}
int ConsoleViewSDL_t::init(void)
@ -46,10 +70,16 @@ int ConsoleViewSDL_t::init(void)
printf("[SDL] Failed to initialize video subsystem.\n");
return -1;
}
//else
//{
// printf("Initialized SDL Video Subsystem\n");
//}
else
{
printf("Initialized SDL Video Subsystem\n");
}
for (int i=0; i<SDL_GetNumVideoDrivers(); i++)
{
printf("SDL Video Driver %i: %s\n", i, SDL_GetVideoDriver(i) );
}
printf("Using Video Driver: %s \n", SDL_GetCurrentVideoDriver() );
windowHandle = this->winId();
@ -132,17 +162,18 @@ void ConsoleViewSDL_t::resizeEvent(QResizeEvent *event)
s = event->size();
view_width = s.width();
view_height = s.height();
//printf("SDL Resize: %i x %i \n", view_width, view_height);
printf("SDL Resize: %i x %i \n", view_width, view_height);
reset();
sdlViewport.x = sdlRendW - view_width;
sdlViewport.y = sdlRendH - view_height;
sdlViewport.w = view_width;
sdlViewport.h = view_height;
//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::paintEvent( QPaintEvent *event )
void ConsoleViewSDL_t::render(void)
{
int nesWidth = GL_NES_WIDTH;
int nesHeight = GL_NES_HEIGHT;
@ -167,8 +198,10 @@ void ConsoleViewSDL_t::paintEvent( QPaintEvent *event )
rw=(int)(nesWidth*xscale);
rh=(int)(nesHeight*yscale);
sx=sdlViewport.x + (view_width-rw)/2;
sy=sdlViewport.y + (view_height-rh)/2;
//sx=sdlViewport.x + (view_width-rw)/2;
//sy=sdlViewport.y + (view_height-rh)/2;
sx=(view_width-rw)/2;
sy=(view_height-rh)/2;
if ( (sdlRenderer == NULL) || (sdlTexture == NULL) )
{
@ -183,13 +216,13 @@ void ConsoleViewSDL_t::paintEvent( QPaintEvent *event )
int rowPitch;
SDL_LockTexture( sdlTexture, nullptr, (void**)&textureBuffer, &rowPitch);
{
memcpy( textureBuffer, nes_shm->pixbuf, GL_NES_HEIGHT*GL_NES_WIDTH*sizeof(uint32_t) );
memcpy( textureBuffer, localBuf, GL_NES_HEIGHT*GL_NES_WIDTH*sizeof(uint32_t) );
}
SDL_UnlockTexture(sdlTexture);
SDL_RenderSetViewport( sdlRenderer, &sdlViewport );
//SDL_RenderSetViewport( sdlRenderer, &sdlViewport );
SDL_Rect source = {0, 0, GL_NES_WIDTH, GL_NES_HEIGHT };
SDL_Rect source = {0, 0, nesWidth, nesHeight };
SDL_Rect dest = { sx, sy, rw, rh };
SDL_RenderCopy(sdlRenderer, sdlTexture, &source, &dest);

View File

@ -19,10 +19,13 @@ class ConsoleViewSDL_t : public QWidget
int init(void);
void reset(void);
void cleanup(void);
void render(void);
void transfer2LocalBuffer(void);
protected:
void paintEvent(QPaintEvent *event);
//void paintEvent(QPaintEvent *event);
void resizeEvent(QResizeEvent *event);
int view_width;
int view_height;
@ -37,10 +40,13 @@ class ConsoleViewSDL_t : public QWidget
bool vsyncEnabled;
uint32_t *localBuf;
uint32_t localBufSize;
SDL_Window *sdlWindow;
SDL_Renderer *sdlRenderer;
SDL_Texture *sdlTexture;
SDL_Rect sdlViewport;
//SDL_Rect sdlViewport;
private slots:
};

View File

@ -4,6 +4,7 @@
#include <iostream>
#include <cstdlib>
#include <QFileDialog>
#include <QMessageBox>
#include "../../fceu.h"
#include "../../fds.h"
@ -19,6 +20,12 @@
#include "Qt/ConsoleWindow.h"
#include "Qt/GamePadConf.h"
#include "Qt/HotKeyConf.h"
#include "Qt/PaletteConf.h"
#include "Qt/GuiConf.h"
#include "Qt/LuaControl.h"
#include "Qt/CheatsConf.h"
#include "Qt/HexEditor.h"
#include "Qt/ConsoleUtilities.h"
#include "Qt/ConsoleSoundConf.h"
#include "Qt/ConsoleVideoConf.h"
#include "Qt/AboutWindow.h"
@ -29,17 +36,33 @@
consoleWin_t::consoleWin_t(QWidget *parent)
: QMainWindow( parent )
{
int use_SDL_video = false;
createMainMenu();
viewport = new ConsoleViewGL_t(this);
//viewport = new ConsoleViewSDL_t(this);
g_config->getOption( "SDL.VideoDriver", &use_SDL_video );
errorMsgValid = false;
viewport_GL = NULL;
viewport_SDL = NULL;
if ( use_SDL_video )
{
viewport_SDL = new ConsoleViewSDL_t(this);
setCentralWidget(viewport_SDL);
}
else
{
viewport_GL = new ConsoleViewGL_t(this);
setCentralWidget(viewport_GL);
}
setCentralWidget(viewport);
setWindowIcon(QIcon(":fceux1.png"));
gameTimer = new QTimer( this );
mutex = new QMutex( QMutex::NonRecursive );
mutex = new QMutex( QMutex::Recursive );
emulatorThread = new emulatorThread_t();
connect(emulatorThread, &QThread::finished, emulatorThread, &QObject::deleteLater);
@ -52,17 +75,16 @@ consoleWin_t::consoleWin_t(QWidget *parent)
emulatorThread->start();
gamePadConfWin = NULL;
}
consoleWin_t::~consoleWin_t(void)
{
nes_shm->runEmulator = 0;
if ( gamePadConfWin != NULL )
{
gamePadConfWin->closeWindow();
}
gameTimer->stop();
closeGamePadConfWindow();
fceuWrapperLock();
fceuWrapperClose();
fceuWrapperUnLock();
@ -71,7 +93,14 @@ consoleWin_t::~consoleWin_t(void)
emulatorThread->quit();
emulatorThread->wait();
delete viewport;
if ( viewport_GL != NULL )
{
delete viewport_GL; viewport_GL = NULL;
}
if ( viewport_SDL != NULL )
{
delete viewport_SDL; viewport_SDL = NULL;
}
delete mutex;
// LoadGame() checks for an IP and if it finds one begins a network session
@ -88,14 +117,31 @@ void consoleWin_t::setCyclePeriodms( int ms )
//printf("Period Set to: %i ms \n", ms );
}
void consoleWin_t::showErrorMsgWindow()
{
QMessageBox msgBox(this);
fceuWrapperLock();
msgBox.setIcon( QMessageBox::Critical );
msgBox.setText( tr(errorMsg.c_str()) );
errorMsg.clear();
fceuWrapperUnLock();
msgBox.show();
msgBox.exec();
}
void consoleWin_t::QueueErrorMsgWindow( const char *msg )
{
errorMsg.append( msg );
errorMsg.append("\n");
errorMsgValid = true;
}
void consoleWin_t::closeEvent(QCloseEvent *event)
{
//printf("Main Window Close Event\n");
if ( gamePadConfWin != NULL )
{
//printf("Command Game Pad Close\n");
gamePadConfWin->closeWindow();
}
closeGamePadConfWindow();
event->accept();
closeApp();
@ -118,9 +164,12 @@ void consoleWin_t::createMainMenu(void)
{
QMenu *subMenu;
QActionGroup *group;
int useNativeMenuBar;
// This is needed for menu bar to show up on MacOS
menuBar()->setNativeMenuBar(false);
g_config->getOption( "SDL.UseNativeMenuBar", &useNativeMenuBar );
menuBar()->setNativeMenuBar( useNativeMenuBar ? true : false );
//-----------------------------------------------------------------------
// File
@ -285,6 +334,22 @@ void consoleWin_t::createMainMenu(void)
optMenu->addAction(hotkeyConfig);
// Options -> Palette Config
paletteConfig = new QAction(tr("Palette Config"), this);
//paletteConfig->setShortcut( QKeySequence(tr("Ctrl+C")));
paletteConfig->setStatusTip(tr("Palette Configure"));
connect(paletteConfig, SIGNAL(triggered()), this, SLOT(openPaletteConfWin(void)) );
optMenu->addAction(paletteConfig);
// Options -> GUI Config
guiConfig = new QAction(tr("GUI Config"), this);
//guiConfig->setShortcut( QKeySequence(tr("Ctrl+C")));
guiConfig->setStatusTip(tr("GUI Configure"));
connect(guiConfig, SIGNAL(triggered()), this, SLOT(openGuiConfWin(void)) );
optMenu->addAction(guiConfig);
// Options -> Auto-Resume
autoResume = new QAction(tr("Auto-Resume Play"), this);
//autoResume->setShortcut( QKeySequence(tr("Ctrl+C")));
@ -401,6 +466,30 @@ void consoleWin_t::createMainMenu(void)
subMenu->addAction(fdsLoadBiosAct);
//-----------------------------------------------------------------------
// Tools
toolsMenu = menuBar()->addMenu(tr("Tools"));
// Tools -> Cheats
cheatsAct = new QAction(tr("Cheats..."), this);
//cheatsAct->setShortcut( QKeySequence(tr("Shift+F7")));
cheatsAct->setStatusTip(tr("Open Cheat Window"));
connect(cheatsAct, SIGNAL(triggered()), this, SLOT(openCheats(void)) );
toolsMenu->addAction(cheatsAct);
//-----------------------------------------------------------------------
// Debug
debugMenu = menuBar()->addMenu(tr("Debug"));
// Debug -> Hex Editor
hexEditAct = new QAction(tr("Hex Editor..."), this);
//hexEditAct->setShortcut( QKeySequence(tr("Shift+F7")));
hexEditAct->setStatusTip(tr("Open Memory Hex Editor"));
connect(hexEditAct, SIGNAL(triggered()), this, SLOT(openHexEditor(void)) );
debugMenu->addAction(hexEditAct);
//-----------------------------------------------------------------------
// Movie
movieMenu = menuBar()->addMenu(tr("Movie"));
@ -443,11 +532,19 @@ void consoleWin_t::createMainMenu(void)
// Help
helpMenu = menuBar()->addMenu(tr("Help"));
aboutAct = new QAction(tr("About"), this);
// Help -> About FCEUX
aboutAct = new QAction(tr("About FCEUX"), this);
aboutAct->setStatusTip(tr("About FCEUX"));
connect(aboutAct, SIGNAL(triggered()), this, SLOT(aboutFCEUX(void)) );
helpMenu->addAction(aboutAct);
// Help -> About Qt
aboutActQt = new QAction(tr("About Qt"), this);
aboutActQt->setStatusTip(tr("About Qt"));
connect(aboutActQt, SIGNAL(triggered()), this, SLOT(aboutQt(void)) );
helpMenu->addAction(aboutActQt);
};
//---------------------------------------------------------------------------
void consoleWin_t::closeApp(void)
@ -468,40 +565,10 @@ void consoleWin_t::closeApp(void)
qApp->quit();
}
//---------------------------------------------------------------------------
int consoleWin_t::getDirFromFile( const char *path, char *dir )
{
int i, lastSlash = -1, lastPeriod = -1;
i=0;
while ( path[i] != 0 )
{
if ( path[i] == '/' )
{
lastSlash = i;
}
else if ( path[i] == '.' )
{
lastPeriod = i;
}
dir[i] = path[i]; i++;
}
dir[i] = 0;
if ( lastPeriod >= 0 )
{
if ( lastPeriod > lastSlash )
{
dir[lastSlash] = 0;
}
}
return 0;
}
//---------------------------------------------------------------------------
void consoleWin_t::openROMFile(void)
{
int ret;
int ret, useNativeFileDialogVal;
QString filename;
std::string last;
char dir[512];
@ -509,9 +576,11 @@ void consoleWin_t::openROMFile(void)
dialog.setFileMode(QFileDialog::ExistingFile);
dialog.setNameFilter(tr("NES files (*.nes)(*.NES) ;; All files (*)"));
dialog.setNameFilter(tr("NES files (*.nes *.NES) ;; All files (*)"));
dialog.setViewMode(QFileDialog::List);
dialog.setFilter( QDir::AllEntries | QDir::Hidden );
dialog.setLabelText( QFileDialog::Accept, tr("Open") );
g_config->getOption ("SDL.LastOpenFile", &last );
@ -519,9 +588,10 @@ void consoleWin_t::openROMFile(void)
dialog.setDirectory( tr(dir) );
// the gnome default file dialog is not playing nice with QT.
// TODO make this a config option to use native file dialog.
dialog.setOption(QFileDialog::DontUseNativeDialog, true);
// 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();
@ -562,7 +632,7 @@ void consoleWin_t::closeROMCB(void)
void consoleWin_t::loadNSF(void)
{
int ret;
int ret, useNativeFileDialogVal;
QString filename;
std::string last;
char dir[512];
@ -570,9 +640,11 @@ void consoleWin_t::loadNSF(void)
dialog.setFileMode(QFileDialog::ExistingFile);
dialog.setNameFilter(tr("NSF Sound Files (*.nsf)(*.NSF) ;; Zip Files (*.zip)(*.ZIP) ;; All files (*)"));
dialog.setNameFilter(tr("NSF Sound Files (*.nsf *.NSF) ;; Zip Files (*.zip *.ZIP) ;; All files (*)"));
dialog.setViewMode(QFileDialog::List);
dialog.setFilter( QDir::AllEntries | QDir::Hidden );
dialog.setLabelText( QFileDialog::Accept, tr("Load") );
g_config->getOption ("SDL.LastOpenNSF", &last );
@ -580,9 +652,10 @@ void consoleWin_t::loadNSF(void)
dialog.setDirectory( tr(dir) );
// the gnome default file dialog is not playing nice with QT.
// TODO make this a config option to use native file dialog.
dialog.setOption(QFileDialog::DontUseNativeDialog, true);
// 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();
@ -613,7 +686,7 @@ void consoleWin_t::loadNSF(void)
void consoleWin_t::loadStateFrom(void)
{
int ret;
int ret, useNativeFileDialogVal;
QString filename;
std::string last;
char dir[512];
@ -621,9 +694,11 @@ void consoleWin_t::loadStateFrom(void)
dialog.setFileMode(QFileDialog::ExistingFile);
dialog.setNameFilter(tr("FCS Files (*.fc?)(*.FC?) ;; SAV Files (*.sav)(*.SAV) ;; All files (*)"));
dialog.setNameFilter(tr("FCS & SAV Files (*.sav *.SAV *.fc? *.FC?) ;; All files (*)"));
dialog.setViewMode(QFileDialog::List);
dialog.setFilter( QDir::AllEntries | QDir::Hidden );
dialog.setLabelText( QFileDialog::Accept, tr("Load") );
g_config->getOption ("SDL.LastLoadStateFrom", &last );
@ -631,9 +706,10 @@ void consoleWin_t::loadStateFrom(void)
dialog.setDirectory( tr(dir) );
// the gnome default file dialog is not playing nice with QT.
// TODO make this a config option to use native file dialog.
dialog.setOption(QFileDialog::DontUseNativeDialog, true);
// 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();
@ -664,7 +740,7 @@ void consoleWin_t::loadStateFrom(void)
void consoleWin_t::saveStateAs(void)
{
int ret;
int ret, useNativeFileDialogVal;
QString filename;
std::string last;
char dir[512];
@ -672,9 +748,12 @@ void consoleWin_t::saveStateAs(void)
dialog.setFileMode(QFileDialog::AnyFile);
dialog.setNameFilter(tr("FCS Files (*.fc?)(*.FC?) ;; SAV Files (*.sav)(*.SAV) ;; All files (*)"));
dialog.setNameFilter(tr("SAV Files (*.sav *.SAV) ;; All files (*)"));
dialog.setViewMode(QFileDialog::List);
dialog.setFilter( QDir::AllEntries | QDir::Hidden );
dialog.setLabelText( QFileDialog::Accept, tr("Save") );
dialog.setDefaultSuffix( tr(".sav") );
g_config->getOption ("SDL.LastSaveStateAs", &last );
@ -682,9 +761,10 @@ void consoleWin_t::saveStateAs(void)
dialog.setDirectory( tr(dir) );
// the gnome default file dialog is not playing nice with QT.
// TODO make this a config option to use native file dialog.
dialog.setOption(QFileDialog::DontUseNativeDialog, true);
// 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();
@ -807,80 +887,21 @@ void consoleWin_t::takeScreenShot(void)
void consoleWin_t::loadLua(void)
{
#ifdef _S9XLUA_H
int ret;
QString filename;
std::string last;
char dir[512];
QFileDialog dialog(this, tr("Open LUA Script") );
LuaControlDialog_t *luaCtrlWin;
dialog.setFileMode(QFileDialog::ExistingFile);
//printf("Open Lua Control Window\n");
dialog.setNameFilter(tr("LUA Scripts (*.lua)(*.LUA) ;; All files (*)"));
luaCtrlWin = new LuaControlDialog_t(this);
dialog.setViewMode(QFileDialog::List);
g_config->getOption ("SDL.LastLoadLua", &last );
if ( last.size() == 0 )
{
last.assign( "/usr/share/fceux/luaScripts" );
}
getDirFromFile( last.c_str(), dir );
dialog.setDirectory( tr(dir) );
// the gnome default file dialog is not playing nice with QT.
// TODO make this a config option to use native file dialog.
dialog.setOption(QFileDialog::DontUseNativeDialog, true);
dialog.show();
ret = dialog.exec();
if ( ret )
{
QStringList fileList;
fileList = dialog.selectedFiles();
if ( fileList.size() > 0 )
{
filename = fileList[0];
}
}
if ( filename.isNull() )
{
return;
}
qDebug() << "selected file path : " << filename.toUtf8();
g_config->setOption ("SDL.LastLoadLua", filename.toStdString().c_str() );
fceuWrapperLock();
if ( 0 == FCEU_LoadLuaCode( filename.toStdString().c_str() ) )
{
printf("Error: Could not open the selected lua script: '%s'\n", filename.toStdString().c_str() );
}
fceuWrapperUnLock();
luaCtrlWin->show();
#endif
}
void consoleWin_t::openGamePadConfWin(void)
{
if ( gamePadConfWin != NULL )
{
printf("GamePad Config Window Already Open\n");
return;
}
//printf("Open GamePad Config Window\n");
gamePadConfWin = new GamePadConfDialog_t(this);
gamePadConfWin->show();
gamePadConfWin->exec();
delete gamePadConfWin;
gamePadConfWin = NULL;
//printf("GamePad Config Window Destroyed\n");
openGamePadConfWindow(this);
}
void consoleWin_t::openGameSndConfWin(void)
@ -892,11 +913,6 @@ void consoleWin_t::openGameSndConfWin(void)
sndConfWin = new ConsoleSndConfDialog_t(this);
sndConfWin->show();
sndConfWin->exec();
delete sndConfWin;
//printf("Sound Config Window Destroyed\n");
}
void consoleWin_t::openGameVideoConfWin(void)
@ -908,11 +924,6 @@ void consoleWin_t::openGameVideoConfWin(void)
vidConfWin = new ConsoleVideoConfDialog_t(this);
vidConfWin->show();
vidConfWin->exec();
delete vidConfWin;
//printf("Video Config Window Destroyed\n");
}
void consoleWin_t::openHotkeyConfWin(void)
@ -924,11 +935,50 @@ void consoleWin_t::openHotkeyConfWin(void)
hkConfWin = new HotKeyConfDialog_t(this);
hkConfWin->show();
hkConfWin->exec();
}
delete hkConfWin;
void consoleWin_t::openPaletteConfWin(void)
{
PaletteConfDialog_t *paletteConfWin;
//printf("Hotkey Config Window Destroyed\n");
//printf("Open Palette Config Window\n");
paletteConfWin = new PaletteConfDialog_t(this);
paletteConfWin->show();
}
void consoleWin_t::openGuiConfWin(void)
{
GuiConfDialog_t *guiConfWin;
//printf("Open GUI Config Window\n");
guiConfWin = new GuiConfDialog_t(this);
guiConfWin->show();
}
void consoleWin_t::openCheats(void)
{
GuiCheatsDialog_t *cheatWin;
//printf("Open GUI Cheat Window\n");
cheatWin = new GuiCheatsDialog_t(this);
cheatWin->show();
}
void consoleWin_t::openHexEditor(void)
{
HexEditorDialog_t *hexEditWin;
//printf("Open GUI Hex Editor Window\n");
hexEditWin = new HexEditorDialog_t(this);
hexEditWin->show();
}
void consoleWin_t::toggleAutoResume(void)
@ -999,7 +1049,7 @@ void consoleWin_t::toggleGameGenie(bool checked)
void consoleWin_t::loadGameGenieROM(void)
{
int ret;
int ret, useNativeFileDialogVal;
QString filename;
std::string last;
char dir[512];
@ -1007,9 +1057,11 @@ void consoleWin_t::loadGameGenieROM(void)
dialog.setFileMode(QFileDialog::ExistingFile);
dialog.setNameFilter(tr("GG ROM File (gg.rom)(*Genie*.nes) ;; All files (*)"));
dialog.setNameFilter(tr("GG ROM File (gg.rom *Genie*.nes) ;; All files (*)"));
dialog.setViewMode(QFileDialog::List);
dialog.setFilter( QDir::AllEntries | QDir::Hidden );
dialog.setLabelText( QFileDialog::Accept, tr("Load") );
g_config->getOption ("SDL.LastOpenFile", &last );
@ -1017,9 +1069,10 @@ void consoleWin_t::loadGameGenieROM(void)
dialog.setDirectory( tr(dir) );
// the gnome default file dialog is not playing nice with QT.
// TODO make this a config option to use native file dialog.
dialog.setOption(QFileDialog::DontUseNativeDialog, true);
// 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();
@ -1079,7 +1132,7 @@ void consoleWin_t::fdsEjectDisk(void)
void consoleWin_t::fdsLoadBiosFile(void)
{
int ret;
int ret, useNativeFileDialogVal;
QString filename;
std::string last;
char dir[512];
@ -1087,9 +1140,11 @@ void consoleWin_t::fdsLoadBiosFile(void)
dialog.setFileMode(QFileDialog::ExistingFile);
dialog.setNameFilter(tr("ROM files (*.rom)(*.ROM) ;; All files (*)"));
dialog.setNameFilter(tr("ROM files (*.rom *.ROM) ;; All files (*)"));
dialog.setViewMode(QFileDialog::List);
dialog.setFilter( QDir::AllEntries | QDir::Hidden );
dialog.setLabelText( QFileDialog::Accept, tr("Load") );
g_config->getOption ("SDL.LastOpenFile", &last );
@ -1097,9 +1152,10 @@ void consoleWin_t::fdsLoadBiosFile(void)
dialog.setDirectory( tr(dir) );
// the gnome default file dialog is not playing nice with QT.
// TODO make this a config option to use native file dialog.
dialog.setOption(QFileDialog::DontUseNativeDialog, true);
// 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();
@ -1143,7 +1199,7 @@ void consoleWin_t::fdsLoadBiosFile(void)
void consoleWin_t::openMovie(void)
{
int ret;
int ret, useNativeFileDialogVal;
QString filename;
std::string last;
char dir[512];
@ -1154,6 +1210,8 @@ void consoleWin_t::openMovie(void)
dialog.setNameFilter(tr("FM2 Movies (*.fm2) ;; All files (*)"));
dialog.setViewMode(QFileDialog::List);
dialog.setFilter( QDir::AllEntries | QDir::Hidden );
dialog.setLabelText( QFileDialog::Accept, tr("Open") );
g_config->getOption ("SDL.LastOpenFile", &last );
@ -1161,9 +1219,10 @@ void consoleWin_t::openMovie(void)
dialog.setDirectory( tr(dir) );
// the gnome default file dialog is not playing nice with QT.
// TODO make this a config option to use native file dialog.
dialog.setOption(QFileDialog::DontUseNativeDialog, true);
// 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();
@ -1225,7 +1284,7 @@ void consoleWin_t::recordMovie(void)
void consoleWin_t::recordMovieAs(void)
{
int ret;
int ret, useNativeFileDialogVal;
QString filename;
std::string last;
char dir[512];
@ -1236,6 +1295,8 @@ void consoleWin_t::recordMovieAs(void)
dialog.setNameFilter(tr("FM2 Movies (*.fm2) ;; All files (*)"));
dialog.setViewMode(QFileDialog::List);
dialog.setFilter( QDir::AllEntries | QDir::Hidden );
dialog.setLabelText( QFileDialog::Accept, tr("Save") );
g_config->getOption ("SDL.LastOpenFile", &last );
@ -1243,9 +1304,10 @@ void consoleWin_t::recordMovieAs(void)
dialog.setDirectory( tr(dir) );
// the gnome default file dialog is not playing nice with QT.
// TODO make this a config option to use native file dialog.
dialog.setOption(QFileDialog::DontUseNativeDialog, true);
// 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();
@ -1292,11 +1354,16 @@ void consoleWin_t::aboutFCEUX(void)
aboutWin = new AboutWindow(this);
aboutWin->show();
aboutWin->exec();
return;
}
delete aboutWin;
void consoleWin_t::aboutQt(void)
{
//printf("About Qt Window\n");
//printf("About Window Destroyed\n");
QMessageBox::aboutQt(this);
//printf("About Qt Destroyed\n");
return;
}
@ -1329,10 +1396,23 @@ void consoleWin_t::updatePeriodic(void)
{
nes_shm->blitUpdated = 0;
viewport->transfer2LocalBuffer();
if ( viewport_SDL )
{
viewport_SDL->transfer2LocalBuffer();
viewport_SDL->render();
}
else
{
viewport_GL->transfer2LocalBuffer();
//viewport_GL->repaint();
viewport_GL->update();
}
}
//viewport->repaint();
viewport->update();
if ( errorMsgValid )
{
showErrorMsgWindow();
errorMsgValid = false;
}
return;

View File

@ -39,17 +39,21 @@ class consoleWin_t : public QMainWindow
consoleWin_t(QWidget *parent = 0);
~consoleWin_t(void);
ConsoleViewGL_t *viewport;
//ConsoleViewSDL_t *viewport;
ConsoleViewGL_t *viewport_GL;
ConsoleViewSDL_t *viewport_SDL;
void setCyclePeriodms( int ms );
QMutex *mutex;
void QueueErrorMsgWindow( const char *msg );
protected:
QMenu *fileMenu;
QMenu *optMenu;
QMenu *emuMenu;
QMenu *toolsMenu;
QMenu *debugMenu;
QMenu *movieMenu;
QMenu *helpMenu;
@ -67,9 +71,12 @@ class consoleWin_t : public QMainWindow
QAction *gameSoundConfig;
QAction *gameVideoConfig;
QAction *hotkeyConfig;
QAction *paletteConfig;
QAction *guiConfig;
QAction *autoResume;
QAction *fullscreen;
QAction *aboutAct;
QAction *aboutActQt;
QAction *state[10];
QAction *powerAct;
QAction *resetAct;
@ -81,23 +88,26 @@ class consoleWin_t : public QMainWindow
QAction *fdsSwitchAct;
QAction *fdsEjectAct;
QAction *fdsLoadBiosAct;
QAction *cheatsAct;
QAction *hexEditAct;
QAction *openMovAct;
QAction *stopMovAct;
QAction *recMovAct;
QAction *recAsMovAct;
QTimer *gameTimer;
emulatorThread_t *emulatorThread;
GamePadConfDialog_t *gamePadConfWin;
std::string errorMsg;
bool errorMsgValid;
protected:
void closeEvent(QCloseEvent *event);
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);
void syncActionConfig( QAction *act, const char *property );
int getDirFromFile( const char *path, char *dir );
void showErrorMsgWindow(void);
private:
void createMainMenu(void);
@ -112,10 +122,13 @@ class consoleWin_t : public QMainWindow
void quickSave(void);
void closeROMCB(void);
void aboutFCEUX(void);
void aboutQt(void);
void openGamePadConfWin(void);
void openGameSndConfWin(void);
void openGameVideoConfWin(void);
void openHotkeyConfWin(void);
void openPaletteConfWin(void);
void openGuiConfWin(void);
void toggleAutoResume(void);
void toggleFullscreen(void);
void updatePeriodic(void);
@ -141,6 +154,8 @@ class consoleWin_t : public QMainWindow
void fdsSwitchDisk(void);
void fdsEjectDisk(void);
void fdsLoadBiosFile(void);
void openCheats(void);
void openHexEditor(void);
void openMovie(void);
void stopMovie(void);
void recordMovie(void);

View File

@ -1,35 +1,105 @@
// GamePadConf.cpp
//
#include <QDir>
#include <QInputDialog>
#include <QMessageBox>
#include "Qt/GamePadConf.h"
#include "Qt/main.h"
#include "Qt/dface.h"
#include "Qt/input.h"
#include "Qt/config.h"
#include "Qt/keyscan.h"
#include "Qt/sdl-joystick.h"
#include "Qt/fceuWrapper.h"
struct GamePadConfigLocalData_t
{
std::string guid;
std::string profile;
struct {
char needsSave;
} btn[GAMEPAD_NUM_BUTTONS];
GamePadConfigLocalData_t(void)
{
for (int i=0; i<GAMEPAD_NUM_BUTTONS; i++)
{
btn[i].needsSave = 0;
}
}
};
static GamePadConfigLocalData_t lcl[GAMEPAD_NUM_DEVICES];
static GamePadConfDialog_t *gamePadConfWin = NULL;
//----------------------------------------------------
int openGamePadConfWindow( QWidget *parent )
{
if ( gamePadConfWin != NULL )
{
return -1;
}
gamePadConfWin = new GamePadConfDialog_t(parent);
gamePadConfWin->show();
return 0;
}
//----------------------------------------------------
int closeGamePadConfWindow(void)
{
if ( gamePadConfWin != NULL )
{
gamePadConfWin->closeWindow();
}
return 0;
}
//----------------------------------------------------
GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent)
: QDialog( parent )
{
QHBoxLayout *hbox1, *hbox2;
QHBoxLayout *hbox, *hbox1, *hbox2, *hbox3, *hbox4;
QVBoxLayout *vbox;
QGridLayout *grid;
QCheckBox *efs_chkbox, *udlr_chkbox;
QGroupBox *frame;
QPushButton *loadDefaultButton;
QGroupBox *frame1, *frame2;
QLabel *label;
QPushButton *newProfileButton;
QPushButton *saveProfileButton;
QPushButton *applyProfileButton;
QPushButton *removeProfileButton;
QPushButton *clearAllButton;
QPushButton *closebutton;
QPushButton *clearButton[GAMEPAD_NUM_BUTTONS];
std::string prefix;
char stmp[256];
gamePadConfWin = this;
// Ensure that joysticks are enabled, no harm calling init again.
InitJoysticks();
portNum = 0;
configNo = 0;
buttonConfigStatus = 1;
inputTimer = new QTimer( this );
connect( inputTimer, &QTimer::timeout, this, &GamePadConfDialog_t::updatePeriodic );
setWindowTitle( tr("GamePad Config") );
hbox1 = new QHBoxLayout();
hbox2 = new QHBoxLayout();
hbox3 = new QHBoxLayout();
hbox4 = new QHBoxLayout();
QLabel *label = new QLabel(tr("Port:"));
label = new QLabel(tr("Console Port:"));
portSel = new QComboBox();
hbox1->addWidget( label );
hbox1->addWidget( portSel );
@ -39,6 +109,83 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent)
portSel->addItem( tr("3"), 2 );
portSel->addItem( tr("4"), 3 );
label = new QLabel(tr("Device:"));
devSel = new QComboBox();
hbox2->addWidget( label );
hbox2->addWidget( devSel );
devSel->addItem( tr("Keyboard"), -1 );
for (int i=0; i<MAX_JOYSTICKS; i++)
{
jsDev_t *js = getJoystickDevice( i );
if ( js != NULL )
{
if ( js->isConnected() )
{
sprintf( stmp, "%i: %s", i, js->getName() );
devSel->addItem( tr(stmp), i );
}
}
}
for (int i=0; i<devSel->count(); i++)
{
if ( devSel->itemData(i).toInt() == GamePad[portNum].getDeviceIndex() )
{
devSel->setCurrentIndex( i );
}
}
label = new QLabel(tr("GUID:"));
guidLbl = new QLabel();
hbox3->addWidget( label );
hbox3->addWidget( guidLbl );
guidLbl->setText( GamePad[portNum].getGUID() );
frame1 = new QGroupBox(tr("Mapping Profile:"));
//grid = new QGridLayout();
vbox = new QVBoxLayout();
//frame1->setLayout( grid );
frame1->setLayout( vbox );
hbox = new QHBoxLayout();
vbox->addLayout( hbox );
mapSel = new QComboBox();
hbox->addWidget( mapSel );
mapSel->setWhatsThis( tr("Combo box for selection of a saved button mapping profile for the selected device"));
mapSel->addItem( tr("default"), 0 );
hbox = new QHBoxLayout();
vbox->addLayout( hbox );
applyProfileButton = new QPushButton( tr("Load") );
applyProfileButton->setWhatsThis(tr("Sets Current Active Map to the Selected Profile"));
hbox->addWidget( applyProfileButton );
saveProfileButton = new QPushButton( tr("Save") );
saveProfileButton->setWhatsThis(tr("Stores Current Active Map to the Selected Profile"));
hbox->addWidget( saveProfileButton );
hbox = new QHBoxLayout();
vbox->addLayout( hbox );
newProfileButton = new QPushButton( tr("New") );
newProfileButton->setWhatsThis(tr("Create a New Map Profile"));
hbox->addWidget( newProfileButton );
removeProfileButton = new QPushButton( tr("Delete") );
removeProfileButton->setWhatsThis(tr("Deletes the Selected Map Profile"));
hbox->addWidget( removeProfileButton );
mapMsg = new QLabel();
vbox->addWidget(mapMsg);
efs_chkbox = new QCheckBox( tr("Enable Four Score") );
udlr_chkbox = new QCheckBox( tr("Allow Up+Down/Left+Right") );
@ -50,13 +197,12 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent)
g_config->getOption("SDL.Input.EnableOppositeDirectionals", &opposite_dirs);
udlr_chkbox->setChecked( opposite_dirs );
frame = new QGroupBox(tr("Buttons:"));
frame2 = new QGroupBox(tr("Current Active Button Mappings:"));
grid = new QGridLayout();
grid-> setHorizontalSpacing(50);
//frame->setFrameStyle( QFrame::Box );
frame->setLayout( grid );
frame2->setLayout( grid );
for (int i=0; i<GAMEPAD_NUM_BUTTONS; i++)
{
@ -71,23 +217,25 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent)
buttonName = new QLabel(tr(text));
keyName[i] = new QLabel();
keyState[i] = new QLabel( tr("F") );
label = new QLabel( tr("State:") );
button[i] = new GamePadConfigButton_t(i);
clearButton[i] = new QPushButton( tr("Clear") );
grid->addWidget( buttonName , i, 0, Qt::AlignCenter );
grid->addWidget( keyName[i] , i, 1, Qt::AlignCenter );
grid->addWidget( button[i] , i, 2, Qt::AlignCenter );
grid->addWidget( clearButton[i], i, 3, Qt::AlignCenter );
grid->addWidget( label , i, 2, Qt::AlignCenter );
grid->addWidget( keyState[i] , i, 3, Qt::AlignCenter );
grid->addWidget( button[i] , i, 4, Qt::AlignCenter );
grid->addWidget( clearButton[i], i, 5, Qt::AlignCenter );
}
updateCntrlrDpy();
loadDefaultButton = new QPushButton(tr("Load Defaults"));
clearAllButton = new QPushButton(tr("Clear All"));
closebutton = new QPushButton(tr("Close"));
hbox2->addWidget( loadDefaultButton );
hbox2->addWidget( clearAllButton );
hbox2->addWidget( closebutton );
hbox4->addWidget( clearAllButton );
hbox4->addWidget( closebutton );
connect(button[0], SIGNAL(clicked()), this, SLOT(changeButton0(void)) );
connect(button[1], SIGNAL(clicked()), this, SLOT(changeButton1(void)) );
@ -111,30 +259,55 @@ GamePadConfDialog_t::GamePadConfDialog_t(QWidget *parent)
connect(clearButton[8], SIGNAL(clicked()), this, SLOT(clearButton8(void)) );
connect(clearButton[9], SIGNAL(clicked()), this, SLOT(clearButton9(void)) );
connect(loadDefaultButton, SIGNAL(clicked()), this, SLOT(loadDefaults(void)) );
connect(newProfileButton , SIGNAL(clicked()), this, SLOT(newProfileCallback(void)) );
connect(applyProfileButton , SIGNAL(clicked()), this, SLOT(loadProfileCallback(void)) );
connect(saveProfileButton , SIGNAL(clicked()), this, SLOT(saveProfileCallback(void)) );
connect(removeProfileButton, SIGNAL(clicked()), this, SLOT(deleteProfileCallback(void)) );
connect(clearAllButton , SIGNAL(clicked()), this, SLOT(clearAllCallback(void)) );
connect(closebutton , SIGNAL(clicked()), this, SLOT(closeWindow(void)) );
connect(portSel , SIGNAL(activated(int)), this, SLOT(controllerSelect(int)) );
connect(portSel , SIGNAL(activated(int)), this, SLOT(portSelect(int)) );
connect(devSel , SIGNAL(activated(int)), this, SLOT(deviceSelect(int)) );
connect(efs_chkbox , SIGNAL(stateChanged(int)), this, SLOT(ena4score(int)) );
connect(udlr_chkbox, SIGNAL(stateChanged(int)), this, SLOT(oppDirEna(int)) );
QVBoxLayout *mainLayout = new QVBoxLayout();
mainLayout->addLayout( hbox1 );
mainLayout->addLayout( hbox2 );
mainLayout->addLayout( hbox3 );
mainLayout->addWidget( frame1 );
mainLayout->addWidget( efs_chkbox );
mainLayout->addWidget( udlr_chkbox );
mainLayout->addWidget( frame );
mainLayout->addLayout( hbox2 );
mainLayout->addWidget( frame2 );
mainLayout->addLayout( hbox4 );
setLayout( mainLayout );
inputTimer->start( 33 ); // 30hz
for (int i=0; i<GAMEPAD_NUM_DEVICES; i++)
{
sprintf( stmp, "SDL.Input.GamePad.%i.", i );
prefix = stmp;
g_config->getOption(prefix + "Profile", &lcl[i].profile );
lcl[i].guid.assign( GamePad[i].getGUID() );
}
loadMapList();
}
//----------------------------------------------------
GamePadConfDialog_t::~GamePadConfDialog_t(void)
{
inputTimer->stop();
buttonConfigStatus = 0;
gamePadConfWin = NULL;
printf("GamePad Window Deleted\n");
}
void GamePadConfDialog_t::keyPressEvent(QKeyEvent *event)
{
@ -148,30 +321,152 @@ void GamePadConfDialog_t::keyReleaseEvent(QKeyEvent *event)
pushKeyEvent( event, 0 );
}
//----------------------------------------------------
void GamePadConfDialog_t::loadMapList(void)
{
QDir dir;
QStringList filters, fileList;
const char *baseDir = FCEUI_GetBaseDirectory();
const char *guid;
std::string path;
std::string prefix, mapName;
int index, devIdx;
jsDev_t *js;
size_t n=0;
char stmp[256];
index = devSel->currentIndex();
devIdx = devSel->itemData(index).toInt();
if ( devIdx < 0 )
{
guid = "keyboard";
}
else
{
js = getJoystickDevice( devIdx );
guid = js->getGUID();
}
if ( guid == NULL )
{
return;
}
path = std::string(baseDir) + "/input/" + std::string(guid);
dir.setPath( QString::fromStdString(path) );
filters << "*.txt";
dir.setNameFilters(filters);
fileList = dir.entryList( filters, QDir::Files, QDir::NoSort );
sprintf( stmp, "SDL.Input.GamePad.%u.", portNum );
prefix = stmp;
g_config->getOption(prefix + "Profile", &mapName );
mapSel->clear();
mapSel->addItem( tr("default"), 0 ); n=1;
for (size_t i=0; i < fileList.size(); i++)
{
size_t suffixIdx;
std::string fileName = fileList[i].toStdString();
suffixIdx = fileName.find_last_of('.');
fileName.erase( suffixIdx );
//printf("File: %s \n", fileName.c_str() );
//
if ( fileName.compare("default") == 0 ) continue;
mapSel->addItem( tr(fileName.c_str()), (int)i+1 );
if ( mapName.compare( fileName ) == 0 )
{
mapSel->setCurrentIndex(n);
}
n++;
}
}
//----------------------------------------------------
void GamePadConfDialog_t::updateCntrlrDpy(void)
{
char keyNameStr[128];
for (int i=0; i<GAMEPAD_NUM_BUTTONS; i++)
{
if (GamePadConfig[portNum][i].ButtType[configNo] == BUTTC_KEYBOARD)
if (GamePad[portNum].bmap[i].ButtType == BUTTC_KEYBOARD)
{
snprintf( keyNameStr, sizeof (keyNameStr), "%s",
SDL_GetKeyName (GamePadConfig[portNum][i].ButtonNum[configNo]));
SDL_GetKeyName (GamePad[portNum].bmap[i].ButtonNum));
}
else
{
strcpy( keyNameStr, ButtonName( &GamePadConfig[portNum][i], configNo ) );
strcpy( keyNameStr, ButtonName( &GamePad[portNum].bmap[i] ) );
}
keyName[i]->setText( tr(keyNameStr) );
//if ( lcl[portNum].btn[i].needsSave )
//{
// keyName[i]->setStyleSheet("color: red;");
//}
//else
//{
// keyName[i]->setStyleSheet("color: black;");
//}
}
}
//----------------------------------------------------
void GamePadConfDialog_t::controllerSelect(int index)
void GamePadConfDialog_t::portSelect(int index)
{
//printf("Port Number:%i \n", index);
portNum = index;
updateCntrlrDpy();
for (int i=0; i<devSel->count(); i++)
{
if ( devSel->itemData(i).toInt() == GamePad[portNum].getDeviceIndex() )
{
devSel->setCurrentIndex( i );
}
}
guidLbl->setText( GamePad[portNum].getGUID() );
loadMapList();
}
//----------------------------------------------------
void GamePadConfDialog_t::deviceSelect(int index)
{
jsDev_t *js;
int devIdx = devSel->itemData(index).toInt();
js = getJoystickDevice( devIdx );
if ( js != NULL )
{
if ( js->isConnected() )
{
guidLbl->setText( js->getGUID() );
}
}
else
{
guidLbl->setText("");
}
GamePad[portNum].setDeviceIndex( devIdx );
lcl[portNum].guid.assign( GamePad[portNum].getGUID() );
lcl[portNum].profile.assign("default");
loadMapList();
updateCntrlrDpy();
}
//----------------------------------------------------
void GamePadConfDialog_t::ena4score(int state)
@ -190,8 +485,8 @@ void GamePadConfDialog_t::oppDirEna(int state)
//----------------------------------------------------
void GamePadConfDialog_t::changeButton(int padNo, int x)
{
char buf[256];
std::string prefix;
//char buf[256];
//std::string prefix;
const char *keyNameStr;
if ( buttonConfigStatus == 2 )
@ -205,32 +500,13 @@ void GamePadConfDialog_t::changeButton(int padNo, int x)
button[x]->setText("Waiting" );
snprintf (buf, sizeof(buf)-1, "SDL.Input.GamePad.%d.", padNo);
prefix = buf;
DWaitButton (NULL, &GamePadConfig[padNo][x], configNo, &buttonConfigStatus );
DWaitButton (NULL, &GamePad[padNo].bmap[x], &buttonConfigStatus );
g_config->setOption (prefix + GamePadNames[x],
GamePadConfig[padNo][x].ButtonNum[configNo]);
if (GamePadConfig[padNo][x].ButtType[configNo] == BUTTC_KEYBOARD)
{
g_config->setOption (prefix + "DeviceType", "Keyboard");
}
else if (GamePadConfig[padNo][x].ButtType[configNo] == BUTTC_JOYSTICK)
{
g_config->setOption (prefix + "DeviceType", "Joystick");
}
else
{
g_config->setOption (prefix + "DeviceType", "Unknown");
}
g_config->setOption (prefix + "DeviceNum",
GamePadConfig[padNo][x].DeviceNum[configNo]);
keyNameStr = ButtonName( &GamePadConfig[padNo][x], configNo );
keyNameStr = ButtonName( &GamePad[padNo].bmap[x] );
keyName[x]->setText( keyNameStr );
button[x]->setText("Change");
lcl[padNo].btn[x].needsSave = 1;
ButtonConfigEnd ();
@ -239,34 +515,32 @@ void GamePadConfDialog_t::changeButton(int padNo, int x)
//----------------------------------------------------
void GamePadConfDialog_t::clearButton( int padNo, int x )
{
char buf[256];
std::string prefix;
GamePadConfig[padNo][x].ButtonNum[configNo] = -1;
GamePad[padNo].bmap[x].ButtonNum = -1;
keyName[x]->setText("");
snprintf (buf, sizeof(buf)-1, "SDL.Input.GamePad.%d.", padNo);
prefix = buf;
g_config->setOption (prefix + GamePadNames[x],
GamePadConfig[padNo][x].ButtonNum[configNo]);
lcl[padNo].btn[x].needsSave = 1;
}
//----------------------------------------------------
void GamePadConfDialog_t::closeEvent(QCloseEvent *event)
{
//printf("GamePad Close Window Event\n");
promptToSave();
printf("GamePad Close Window Event\n");
buttonConfigStatus = 0;
done(0);
deleteLater();
event->accept();
}
//----------------------------------------------------
void GamePadConfDialog_t::closeWindow(void)
{
//printf("Close Window\n");
promptToSave();
printf("Close Window\n");
buttonConfigStatus = 0;
done(0);
deleteLater();
}
//----------------------------------------------------
void GamePadConfDialog_t::changeButton0(void)
@ -377,48 +651,238 @@ void GamePadConfDialog_t::clearAllCallback(void)
}
}
//----------------------------------------------------
void GamePadConfDialog_t::loadDefaults(void)
void GamePadConfDialog_t::saveConfig(void)
{
char buf[256];
std::string prefix;
int i;
char stmp[256];
std::string prefix, mapName;
if ( portNum > 0 )
sprintf( stmp, "SDL.Input.GamePad.%u.", portNum );
prefix = stmp;
mapName = mapSel->currentText().toStdString();
g_config->setOption(prefix + "DeviceGUID", GamePad[portNum].getGUID() );
g_config->setOption(prefix + "Profile" , mapName.c_str() );
for (i=0; i<GAMEPAD_NUM_BUTTONS; i++)
{
clearAllCallback();
return;
lcl[portNum].btn[i].needsSave = 0;
}
snprintf (buf, sizeof(buf)-1, "SDL.Input.GamePad.%d.", portNum);
prefix = buf;
for (int x=0; x<GAMEPAD_NUM_BUTTONS; x++)
{
GamePadConfig[portNum][x].ButtType[configNo] = BUTTC_KEYBOARD;
GamePadConfig[portNum][x].DeviceNum[configNo] = 0;
GamePadConfig[portNum][x].ButtonNum[configNo] = DefaultGamePad[portNum][x];
GamePadConfig[portNum][x].NumC = 1;
g_config->setOption (prefix + GamePadNames[x],
GamePadConfig[portNum][x].ButtonNum[configNo]);
if (GamePadConfig[portNum][x].ButtType[configNo] == BUTTC_KEYBOARD)
{
g_config->setOption (prefix + "DeviceType", "Keyboard");
g_config->save();
}
else if (GamePadConfig[portNum][x].ButtType[configNo] == BUTTC_JOYSTICK)
//----------------------------------------------------
void GamePadConfDialog_t::createNewProfile( const char *name )
{
g_config->setOption (prefix + "DeviceType", "Joystick");
char stmp[256];
//printf("Creating: %s \n", name );
GamePad[portNum].createProfile(name);
mapSel->addItem( tr(name) );
mapSel->setCurrentIndex( mapSel->count() - 1 );
saveConfig();
sprintf( stmp, "Mapping Created: %s/%s \n", GamePad[portNum].getGUID(), name );
mapMsg->setText( tr(stmp) );
}
//----------------------------------------------------
void GamePadConfDialog_t::newProfileCallback(void)
{
int ret;
QInputDialog dialog(this);
dialog.setWindowTitle( tr("New Profile") );
dialog.setLabelText( tr("Specify New Profile Name") );
dialog.setOkButtonText( tr("Create") );
dialog.show();
ret = dialog.exec();
if ( QDialog::Accepted == ret )
{
createNewProfile( dialog.textValue().toStdString().c_str() );
}
}
//----------------------------------------------------
void GamePadConfDialog_t::loadProfileCallback(void)
{
char stmp[256];
int index, devIdx, ret;
std::string mapName;
index = devSel->currentIndex();
devIdx = devSel->itemData(index).toInt();
mapName = mapSel->currentText().toStdString();
GamePad[portNum].setDeviceIndex( devIdx );
if ( mapName.compare("default") == 0 )
{
ret =GamePad[portNum].loadDefaults();
}
else
{
g_config->setOption (prefix + "DeviceType", "Unknown");
ret = GamePad[portNum].loadProfile( mapName.c_str() );
}
g_config->setOption (prefix + "DeviceNum",
GamePadConfig[portNum][x].DeviceNum[configNo]);
if ( ret == 0 )
{
saveConfig();
sprintf( stmp, "Mapping Loaded: %s/%s \n", GamePad[portNum].getGUID(), mapName.c_str() );
}
else
{
sprintf( stmp, "Error: Failed to Load Mapping: %s/%s \n", GamePad[portNum].getGUID(), mapName.c_str() );
}
mapMsg->setText( tr(stmp) );
updateCntrlrDpy();
}
//----------------------------------------------------
void GamePadConfDialog_t::saveProfileCallback(void)
{
int ret;
std::string mapName;
char stmp[256];
mapName = mapSel->currentText().toStdString();
ret = GamePad[portNum].saveCurrentMapToFile( mapName.c_str() );
if ( ret == 0 )
{
saveConfig();
sprintf( stmp, "Mapping Saved: %s/%s \n", GamePad[portNum].getGUID(), mapName.c_str() );
}
else
{
sprintf( stmp, "Error: Failed to Save Mapping: %s \n", mapName.c_str() );
}
mapMsg->setText( tr(stmp) );
}
//----------------------------------------------------
void GamePadConfDialog_t::deleteProfileCallback(void)
{
int ret;
std::string mapName;
char stmp[256];
mapName = mapSel->currentText().toStdString();
ret = GamePad[portNum].deleteMapping( mapName.c_str() );
if ( ret == 0 )
{
sprintf( stmp, "Mapping Deleted: %s/%s \n", GamePad[portNum].getGUID(), mapName.c_str() );
}
else
{
sprintf( stmp, "Error: Failed to Delete Mapping: %s \n", mapName.c_str() );
}
mapMsg->setText( tr(stmp) );
loadMapList();
}
//----------------------------------------------------
void GamePadConfDialog_t::promptToSave(void)
{
int i,j,n;
std::string msg;
QMessageBox msgBox(this);
char saveRequired = 0;
char padNeedsSave[GAMEPAD_NUM_DEVICES];
char stmp[256];
n=0;
for (i=0; i<GAMEPAD_NUM_DEVICES; i++)
{
padNeedsSave[i] = 0;
for (j=0; j<GAMEPAD_NUM_BUTTONS; j++)
{
if ( lcl[i].btn[j].needsSave )
{
padNeedsSave[i] = 1;
saveRequired = 1;
n++;
break;
}
}
}
if ( !saveRequired )
{
return;
}
sprintf( stmp, "Warning: Gamepad mappings have not been saved for port%c ", (n > 1) ? 's':' ');
msg.assign( stmp );
j=n;
for (i=0; i<GAMEPAD_NUM_DEVICES; i++)
{
if ( padNeedsSave[i] )
{
sprintf( stmp, "%i", i+1 );
msg.append(stmp);
j--;
if ( j > 1 )
{
msg.append(", ");
}
else if ( j == 1 )
{
msg.append(" and ");
}
}
}
msg.append(".");
msgBox.setIcon( QMessageBox::Warning );
msgBox.setText( tr(msg.c_str()) );
msgBox.show();
//msgBox.resize( 512, 128 );
msgBox.exec();
}
//----------------------------------------------------
void GamePadConfDialog_t::updatePeriodic(void)
{
for (int i=0; i<GAMEPAD_NUM_BUTTONS; i++)
{
const char *txt, *style;
if ( GamePad[portNum].bmap[i].state )
{
txt = " T ";
style = "background-color: green; color: white;";
}
else
{
txt = " F ";
style = "background-color: red; color: white;";
}
keyState[i]->setText( tr(txt) );
keyState[i]->setStyleSheet( style );
if ( lcl[portNum].btn[i].needsSave )
{
keyName[i]->setStyleSheet("color: red;");
}
else
{
keyName[i]->setStyleSheet("color: black;");
}
}
}
//----------------------------------------------------
GamePadConfigButton_t::GamePadConfigButton_t(int i)
{
idx = i;

View File

@ -12,6 +12,7 @@
#include <QPushButton>
#include <QLabel>
#include <QFrame>
#include <QTimer>
#include <QGroupBox>
#include "Qt/main.h"
@ -37,12 +38,18 @@ class GamePadConfDialog_t : public QDialog
~GamePadConfDialog_t(void);
protected:
QTimer *inputTimer;
QComboBox *portSel;
QComboBox *devSel;
QComboBox *mapSel;
QComboBox *profSel;
QLabel *guidLbl;
QLabel *mapMsg;
QLabel *keyName[GAMEPAD_NUM_BUTTONS];
QLabel *keyState[GAMEPAD_NUM_BUTTONS];
GamePadConfigButton_t *button[GAMEPAD_NUM_BUTTONS];
int portNum;
int configNo;
int buttonConfigStatus;
void changeButton( int port, int button );
@ -52,6 +59,10 @@ class GamePadConfDialog_t : public QDialog
void closeEvent(QCloseEvent *bar);
private:
void updateCntrlrDpy(void);
void createNewProfile( const char *name );
void loadMapList(void);
void saveConfig(void);
void promptToSave(void);
public slots:
void closeWindow(void);
@ -77,9 +88,18 @@ class GamePadConfDialog_t : public QDialog
void clearButton8(void);
void clearButton9(void);
void clearAllCallback(void);
void loadDefaults(void);
void ena4score(int state);
void oppDirEna(int state);
void controllerSelect(int index);
void portSelect(int index);
void deviceSelect(int index);
void newProfileCallback(void);
void loadProfileCallback(void);
void saveProfileCallback(void);
void deleteProfileCallback(void);
void updatePeriodic(void);
};
int openGamePadConfWindow( QWidget *parent );
int closeGamePadConfWindow(void);

View File

@ -0,0 +1,82 @@
// PaletteConf.cpp
//
#include <QTextEdit>
#include "Qt/GuiConf.h"
#include "Qt/main.h"
#include "Qt/input.h"
#include "Qt/config.h"
#include "Qt/keyscan.h"
#include "Qt/fceuWrapper.h"
#include "Qt/ConsoleWindow.h"
//----------------------------------------------------
GuiConfDialog_t::GuiConfDialog_t(QWidget *parent)
: QDialog( parent )
{
int useNativeFileDialogVal;
int useNativeMenuBarVal;
QVBoxLayout *mainLayout;
//resize( 512, 600 );
// sync with config
g_config->getOption ("SDL.UseNativeFileDialog", &useNativeFileDialogVal);
g_config->getOption ("SDL.UseNativeMenuBar", &useNativeMenuBarVal);
setWindowTitle( tr("GUI Config") );
mainLayout = new QVBoxLayout();
useNativeFileDialog = new QCheckBox( tr("Use Native OS File Dialog") );
useNativeMenuBar = new QCheckBox( tr("Use Native OS Menu Bar") );
useNativeFileDialog->setChecked( useNativeFileDialogVal );
useNativeMenuBar->setChecked( useNativeMenuBarVal );
connect(useNativeFileDialog , SIGNAL(stateChanged(int)), this, SLOT(useNativeFileDialogChanged(int)) );
connect(useNativeMenuBar , SIGNAL(stateChanged(int)), this, SLOT(useNativeMenuBarChanged(int)) );
mainLayout->addWidget( useNativeFileDialog );
mainLayout->addWidget( useNativeMenuBar );
setLayout( mainLayout );
}
//----------------------------------------------------
GuiConfDialog_t::~GuiConfDialog_t(void)
{
printf("Destroy GUI Config Close Window\n");
}
//----------------------------------------------------------------------------
void GuiConfDialog_t::closeEvent(QCloseEvent *event)
{
printf("GUI Config Close Window Event\n");
done(0);
deleteLater();
event->accept();
}
//----------------------------------------------------
void GuiConfDialog_t::closeWindow(void)
{
//printf("Close Window\n");
done(0);
deleteLater();
}
//----------------------------------------------------
void GuiConfDialog_t::useNativeFileDialogChanged(int state)
{
int value = (state == Qt::Unchecked) ? 0 : 1;
g_config->setOption ("SDL.UseNativeFileDialog", value);
}
//----------------------------------------------------
void GuiConfDialog_t::useNativeMenuBarChanged(int state)
{
int value = (state == Qt::Unchecked) ? 0 : 1;
g_config->setOption ("SDL.UseNativeMenuBar", value);
consoleWindow->menuBar()->setNativeMenuBar( value );
}
//----------------------------------------------------

41
src/drivers/Qt/GuiConf.h Normal file
View File

@ -0,0 +1,41 @@
// GuiConf.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 "Qt/main.h"
class GuiConfDialog_t : public QDialog
{
Q_OBJECT
public:
GuiConfDialog_t(QWidget *parent = 0);
~GuiConfDialog_t(void);
protected:
void closeEvent(QCloseEvent *event);
QCheckBox *useNativeFileDialog;
QCheckBox *useNativeMenuBar;
private:
public slots:
void closeWindow(void);
private slots:
void useNativeFileDialogChanged(int v);
void useNativeMenuBarChanged(int v);
};

1921
src/drivers/Qt/HexEditor.cpp Normal file

File diff suppressed because it is too large Load Diff

231
src/drivers/Qt/HexEditor.h Normal file
View File

@ -0,0 +1,231 @@
// GamePadConf.h
//
#pragma once
#include <list>
#include <vector>
#include <QWidget>
#include <QDialog>
#include <QTimer>
#include <QAction>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QComboBox>
#include <QCheckBox>
#include <QPushButton>
#include <QLabel>
#include <QMenu>
#include <QFrame>
#include <QGroupBox>
#include <QPlainTextEdit>
#include <QKeyEvent>
struct memByte_t
{
unsigned char data;
unsigned char color;
unsigned char actv;
};
struct memBlock_t
{
memBlock_t(void);
~memBlock_t(void);
void init(void);
int size(void){ return _size; }
int numLines(void){ return _maxLines; }
int reAlloc( int newSize );
void setAccessFunc( int (*newMemAccessFunc)( unsigned int offset) );
struct memByte_t *buf;
int _size;
int _maxLines;
int (*memAccessFunc)( unsigned int offset);
};
class HexBookMark
{
public:
HexBookMark(void);
~HexBookMark(void);
int addr;
int mode;
char desc[64];
};
class HexBookMarkManager_t
{
public:
HexBookMarkManager_t(void);
~HexBookMarkManager_t(void);
void removeAll(void);
int addBookMark( int addr, int mode, const char *desc );
int size(void);
HexBookMark *getBookMark( int index );
int saveToFile(void);
int loadFromFile(void);
private:
void updateVector(void);
std::list <HexBookMark*> ls;
std::vector <HexBookMark*> v;
};
class QHexEdit;
class HexBookMarkMenuAction : public QAction
{
Q_OBJECT
public:
HexBookMarkMenuAction( QString desc, QWidget *parent = 0);
~HexBookMarkMenuAction(void);
QHexEdit *qedit;
HexBookMark *bm;
public slots:
void activateCB(void);
};
class HexEditorDialog_t;
class QHexEdit : public QWidget
{
Q_OBJECT
public:
QHexEdit(QWidget *parent = 0);
~QHexEdit(void);
int getMode(void){ return viewMode; };
void setMode( int mode );
void setLine( int newLineOffset );
void setAddr( int newAddrOffset );
void setScrollBars( QScrollBar *h, QScrollBar *v );
void setHorzScroll( int value );
void setHighlightActivity( int enable );
void setHighlightReverseVideo( int enable );
void setForeGroundColor( QColor fg );
void setBackGroundColor( QColor bg );
void memModeUpdate(void);
int checkMemActivity(void);
enum {
MODE_NES_RAM = 0,
MODE_NES_PPU,
MODE_NES_OAM,
MODE_NES_ROM
};
static const int HIGHLIGHT_ACTIVITY_NUM_COLORS = 16;
protected:
void paintEvent(QPaintEvent *event);
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);
void mousePressEvent(QMouseEvent * event);
void resizeEvent(QResizeEvent *event);
void contextMenuEvent(QContextMenuEvent *event);
void calcFontData(void);
void resetCursor(void);
QPoint convPixToCursor( QPoint p );
int convPixToAddr( QPoint p );
QFont font;
memBlock_t mb;
int (*memAccessFunc)( unsigned int offset);
QScrollBar *vbar;
QScrollBar *hbar;
QColor highLightColor[ HIGHLIGHT_ACTIVITY_NUM_COLORS ];
QColor rvActvTextColor[ HIGHLIGHT_ACTIVITY_NUM_COLORS ];
HexEditorDialog_t *parent;
uint64_t total_instructions_lp;
int viewMode;
int lineOffset;
int pxCharWidth;
int pxCharHeight;
int pxCursorHeight;
int pxLineSpacing;
int pxLineLead;
int pxLineWidth;
int pxLineXScroll;
int pxXoffset;
int pxYoffset;
int pxHexOffset;
int pxHexAscii;
int cursorPosX;
int cursorPosY;
int cursorBlinkCount;
int viewLines;
int viewWidth;
int viewHeight;
int maxLineOffset;
int editAddr;
int editValue;
int editMask;
int jumpToRomValue;
int ctxAddr;
bool cursorBlink;
bool reverseVideo;
bool actvHighlightEnable;
private slots:
void jumpToROM(void);
void addBookMarkCB(void);
};
class HexEditorDialog_t : public QDialog
{
Q_OBJECT
public:
HexEditorDialog_t(QWidget *parent = 0);
~HexEditorDialog_t(void);
void gotoAddress(int newAddr);
void populateBookmarkMenu(void);
protected:
void closeEvent(QCloseEvent *bar);
QScrollBar *vbar;
QScrollBar *hbar;
QHexEdit *editor;
QTimer *periodicTimer;
QMenu *bookmarkMenu;
private:
public slots:
void closeWindow(void);
private slots:
void updatePeriodic(void);
void vbarMoved(int value);
void vbarChanged(int value);
void hbarChanged(int value);
void saveRomFile(void);
void saveRomFileAs(void);
void setViewRAM(void);
void setViewPPU(void);
void setViewOAM(void);
void setViewROM(void);
void actvHighlightCB(bool value);
void actvHighlightRVCB(bool value);
void pickForeGroundColor(void);
void pickBackGroundColor(void);
void removeAllBookmarks(void);
};
void hexEditorLoadBookmarks(void);
void hexEditorSaveBookmarks(void);

View File

@ -7,6 +7,7 @@
#include <SDL.h>
#include <QHeaderView>
#include <QCloseEvent>
#include "Qt/main.h"
#include "Qt/dface.h"
@ -68,13 +69,22 @@ HotKeyConfDialog_t::HotKeyConfDialog_t(QWidget *parent)
//----------------------------------------------------------------------------
HotKeyConfDialog_t::~HotKeyConfDialog_t(void)
{
printf("Destroy Hot Key Config Window\n");
}
//----------------------------------------------------------------------------
void HotKeyConfDialog_t::closeEvent(QCloseEvent *event)
{
printf("Hot Key Close Window Event\n");
done(0);
deleteLater();
event->accept();
}
//----------------------------------------------------------------------------
void HotKeyConfDialog_t::closeWindow(void)
{
//printf("Close Window\n");
done(0);
deleteLater();
}
//----------------------------------------------------------------------------
void HotKeyConfDialog_t::assignHotkey(QKeyEvent *event)

View File

@ -27,6 +27,7 @@ class HotKeyConfDialog_t : public QDialog
~HotKeyConfDialog_t(void);
protected:
void closeEvent(QCloseEvent *event);
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);
void assignHotkey(QKeyEvent *event);

View File

@ -0,0 +1,266 @@
// LuaControl.cpp
//
#include <list>
#include <QTextEdit>
#include <QFileDialog>
#include "../../fceu.h"
#ifdef _S9XLUA_H
#include "../../fceulua.h"
#endif
#include "Qt/LuaControl.h"
#include "Qt/main.h"
#include "Qt/input.h"
#include "Qt/config.h"
#include "Qt/keyscan.h"
#include "Qt/fceuWrapper.h"
#include "Qt/ConsoleUtilities.h"
static bool luaScriptRunning = false;
static std::string luaOutputText;
static std::list <LuaControlDialog_t*> winList;
//----------------------------------------------------
LuaControlDialog_t::LuaControlDialog_t(QWidget *parent)
: QDialog( parent )
{
QVBoxLayout *mainLayout;
QHBoxLayout *hbox;
QLabel *lbl;
std::string filename;
resize( 512, 512 );
setWindowTitle( tr("Lua Script Control") );
mainLayout = new QVBoxLayout();
lbl = new QLabel( tr("Script File:") );
scriptPath = new QLineEdit();
scriptArgs = new QLineEdit();
g_config->getOption ("SDL.LastLoadLua", &filename );
scriptPath->setText( filename.c_str() );
luaOutput = new QTextEdit();
luaOutput->setReadOnly(true);
hbox = new QHBoxLayout();
browseButton = new QPushButton( tr("Browse") );
stopButton = new QPushButton( tr("Stop") );
if ( luaScriptRunning )
{
startButton = new QPushButton( tr("Restart") );
}
else
{
startButton = new QPushButton( tr("Start") );
}
stopButton->setEnabled( luaScriptRunning );
connect(browseButton , SIGNAL(clicked()), this, SLOT(openLuaScriptFile(void)) );
connect(stopButton , SIGNAL(clicked()), this, SLOT(stopLuaScript(void)) );
connect(startButton , SIGNAL(clicked()), this, SLOT(startLuaScript(void)) );
hbox->addWidget( browseButton );
hbox->addWidget( stopButton );
hbox->addWidget( startButton );
mainLayout->addWidget( lbl );
mainLayout->addWidget( scriptPath );
mainLayout->addLayout( hbox );
hbox = new QHBoxLayout();
lbl = new QLabel( tr("Arguments:") );
hbox->addWidget( lbl );
hbox->addWidget( scriptArgs );
mainLayout->addLayout( hbox );
lbl = new QLabel( tr("Output Console:") );
mainLayout->addWidget( lbl );
mainLayout->addWidget( luaOutput );
//connect(useNativeFileDialog , SIGNAL(stateChanged(int)), this, SLOT(useNativeFileDialogChanged(int)) );
setLayout( mainLayout );
winList.push_back( this );
}
//----------------------------------------------------
LuaControlDialog_t::~LuaControlDialog_t(void)
{
std::list <LuaControlDialog_t*>::iterator it;
printf("Destroy Lua Control Window\n");
for (it = winList.begin(); it != winList.end(); it++)
{
if ( (*it) == this )
{
winList.erase(it);
//printf("Removing Lua Window\n");
break;
}
}
}
//----------------------------------------------------
void LuaControlDialog_t::closeEvent(QCloseEvent *event)
{
printf("Lua Control Close Window Event\n");
done(0);
deleteLater();
event->accept();
}
//----------------------------------------------------
void LuaControlDialog_t::closeWindow(void)
{
//printf("Lua Control Close Window\n");
done(0);
deleteLater();
}
//----------------------------------------------------
void LuaControlDialog_t::openLuaScriptFile(void)
{
#ifdef _S9XLUA_H
int ret, useNativeFileDialogVal;
QString filename;
std::string last;
char dir[512];
QFileDialog dialog(this, tr("Open LUA Script") );
dialog.setFileMode(QFileDialog::ExistingFile);
dialog.setNameFilter(tr("LUA Scripts (*.lua *.LUA) ;; All files (*)"));
dialog.setViewMode(QFileDialog::List);
dialog.setFilter( QDir::AllEntries | QDir::Hidden );
dialog.setLabelText( QFileDialog::Accept, tr("Load") );
g_config->getOption ("SDL.LastLoadLua", &last );
if ( last.size() == 0 )
{
last.assign( "/usr/share/fceux/luaScripts" );
}
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();
g_config->setOption ("SDL.LastLoadLua", filename.toStdString().c_str() );
scriptPath->setText( filename.toStdString().c_str() );
#endif
}
//----------------------------------------------------
void LuaControlDialog_t::startLuaScript(void)
{
#ifdef _S9XLUA_H
luaOutputText.clear();
fceuWrapperLock();
if ( 0 == FCEU_LoadLuaCode( scriptPath->text().toStdString().c_str(), scriptArgs->text().toStdString().c_str() ) )
{
printf("Error: Could not open the selected lua script: '%s'\n", scriptPath->text().toStdString().c_str() );
}
fceuWrapperUnLock();
#endif
}
//----------------------------------------------------
void LuaControlDialog_t::stopLuaScript(void)
{
#ifdef _S9XLUA_H
fceuWrapperLock();
FCEU_LuaStop();
fceuWrapperUnLock();
#endif
}
//----------------------------------------------------
void LuaControlDialog_t::refreshState(void)
{
if ( luaScriptRunning )
{
stopButton->setEnabled( true );
startButton->setText( tr("Restart") );
}
else
{
stopButton->setEnabled( false );
startButton->setText( tr("Start") );
}
luaOutput->setText( luaOutputText.c_str() );
}
//----------------------------------------------------
void updateLuaWindows( void )
{
std::list <LuaControlDialog_t*>::iterator it;
for (it = winList.begin(); it != winList.end(); it++)
{
(*it)->refreshState();
}
}
//----------------------------------------------------
void WinLuaOnStart(intptr_t hDlgAsInt)
{
luaScriptRunning = true;
//printf("Lua Script Running: %i \n", luaScriptRunning );
updateLuaWindows();
}
//----------------------------------------------------
void WinLuaOnStop(intptr_t hDlgAsInt)
{
luaScriptRunning = false;
//printf("Lua Script Running: %i \n", luaScriptRunning );
updateLuaWindows();
}
//----------------------------------------------------
void PrintToWindowConsole(intptr_t hDlgAsInt, const char* str)
{
//printf("%s\n", str );
luaOutputText.append( str );
updateLuaWindows();
}
//----------------------------------------------------

View File

@ -0,0 +1,49 @@
// LuaControl.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 <QTextEdit>
#include "Qt/main.h"
class LuaControlDialog_t : public QDialog
{
Q_OBJECT
public:
LuaControlDialog_t(QWidget *parent = 0);
~LuaControlDialog_t(void);
void refreshState(void);
protected:
void closeEvent(QCloseEvent *bar);
QLineEdit *scriptPath;
QLineEdit *scriptArgs;
QPushButton *browseButton;
QPushButton *stopButton;
QPushButton *startButton;
QTextEdit *luaOutput;
private:
public slots:
void closeWindow(void);
private slots:
void openLuaScriptFile(void);
void startLuaScript(void);
void stopLuaScript(void);
};

View File

@ -0,0 +1,369 @@
// PaletteConf.cpp
//
#include <QFileDialog>
#include <QTextEdit>
#include "Qt/PaletteConf.h"
#include "Qt/main.h"
#include "Qt/input.h"
#include "Qt/config.h"
#include "Qt/keyscan.h"
#include "Qt/fceuWrapper.h"
#include "Qt/ConsoleUtilities.h"
#include "../../ppu.h"
extern bool force_grayscale;
static const char *commentText =
"Palette Selection uses the 1st Matching Condition:\n\
1. Game type is NSF (always uses fixed palette) \n\
2. Custom User Palette is Available and Enabled \n\
3. NTSC Color Emulation is Enabled \n\
4. Individual Game Palette is Available \n\
5. Default Built-in Palette ";
//----------------------------------------------------
PaletteConfDialog_t::PaletteConfDialog_t(QWidget *parent)
: QDialog( parent )
{
QVBoxLayout *mainLayout, *vbox;
QHBoxLayout *hbox1;
QGroupBox *frame;
//QPushButton *closebutton;
QPushButton *button;
QTextEdit *comments;
int hue, tint;
char stmp[64];
std::string paletteFile;
resize( 512, 600 );
// sync with config
g_config->getOption ("SDL.Hue", &hue);
g_config->getOption ("SDL.Tint", &tint);
setWindowTitle( tr("Palette Config") );
mainLayout = new QVBoxLayout();
frame = new QGroupBox( tr("Custom Palette:") );
vbox = new QVBoxLayout();
hbox1 = new QHBoxLayout();
useCustom = new QCheckBox( tr("Use Custom Palette") );
GrayScale = new QCheckBox( tr("Force Grayscale") );
deemphSwap = new QCheckBox( tr("De-emphasis Bit Swap") );
useCustom->setChecked( FCEUI_GetUserPaletteAvail() );
GrayScale->setChecked( force_grayscale );
deemphSwap->setChecked( paldeemphswap );
connect(useCustom , SIGNAL(stateChanged(int)), this, SLOT(use_Custom_Changed(int)) );
connect(GrayScale , SIGNAL(stateChanged(int)), this, SLOT(force_GrayScale_Changed(int)) );
connect(deemphSwap, SIGNAL(stateChanged(int)), this, SLOT(deemphswap_Changed(int)) );
button = new QPushButton( tr("Open Palette") );
hbox1->addWidget( button );
connect( button, SIGNAL(clicked(void)), this, SLOT(openPaletteFile(void)) );
g_config->getOption ("SDL.Palette", &paletteFile);
custom_palette_path = new QLineEdit();
custom_palette_path->setReadOnly(true);
custom_palette_path->setText( paletteFile.c_str() );
vbox->addWidget( useCustom );
vbox->addLayout( hbox1 );
vbox->addWidget( custom_palette_path );
vbox->addWidget( GrayScale );
vbox->addWidget( deemphSwap);
button = new QPushButton( tr("Clear") );
hbox1->addWidget( button );
connect( button, SIGNAL(clicked(void)), this, SLOT(clearPalette(void)) );
frame->setLayout( vbox );
mainLayout->addWidget( frame );
frame = new QGroupBox( tr("NTSC Palette Controls:") );
vbox = new QVBoxLayout();
useNTSC = new QCheckBox( tr("Use NTSC Palette") );
int ntscPaletteEnable;
g_config->getOption("SDL.NTSCpalette", &ntscPaletteEnable);
useNTSC->setChecked( ntscPaletteEnable );
connect(useNTSC , SIGNAL(stateChanged(int)), this, SLOT(use_NTSC_Changed(int)) );
vbox->addWidget( useNTSC );
sprintf( stmp, "Tint: %3i \n", tint );
tintFrame = new QGroupBox( tr(stmp) );
hbox1 = new QHBoxLayout();
tintSlider = new QSlider( Qt::Horizontal );
tintSlider->setMinimum( 0);
tintSlider->setMaximum(128);
tintSlider->setValue( tint );
connect( tintSlider, SIGNAL(valueChanged(int)), this, SLOT(tintChanged(int)) );
hbox1->addWidget( tintSlider );
tintFrame->setLayout( hbox1 );
vbox->addWidget( tintFrame );
sprintf( stmp, "Hue: %3i \n", hue );
hueFrame = new QGroupBox( tr(stmp) );
hbox1 = new QHBoxLayout();
hueSlider = new QSlider( Qt::Horizontal );
hueSlider->setMinimum( 0);
hueSlider->setMaximum(128);
hueSlider->setValue( hue );
connect( hueSlider, SIGNAL(valueChanged(int)), this, SLOT(hueChanged(int)) );
hbox1->addWidget( hueSlider );
hueFrame->setLayout( hbox1 );
vbox->addWidget( hueFrame );
frame->setLayout( vbox );
mainLayout->addWidget( frame );
comments = new QTextEdit();
comments->setText( commentText );
comments->moveCursor(QTextCursor::Start);
comments->setReadOnly(true);
mainLayout->addWidget( comments );
setLayout( mainLayout );
}
//----------------------------------------------------
PaletteConfDialog_t::~PaletteConfDialog_t(void)
{
printf("Destroy Palette Config Window\n");
}
//----------------------------------------------------------------------------
void PaletteConfDialog_t::closeEvent(QCloseEvent *event)
{
printf("Palette Config Close Window Event\n");
done(0);
deleteLater();
event->accept();
}
//----------------------------------------------------
void PaletteConfDialog_t::closeWindow(void)
{
//printf("Close Window\n");
done(0);
deleteLater();
}
//----------------------------------------------------
void PaletteConfDialog_t::hueChanged(int v)
{
int c, t;
char stmp[64];
sprintf( stmp, "Hue: %3i", v );
hueFrame->setTitle(stmp);
g_config->setOption ("SDL.Hue", v);
g_config->save ();
g_config->getOption ("SDL.Tint", &t);
g_config->getOption ("SDL.NTSCpalette", &c);
if ( fceuWrapperTryLock() )
{
FCEUI_SetNTSCTH (c, t, v);
fceuWrapperUnLock();
}
}
//----------------------------------------------------
void PaletteConfDialog_t::tintChanged(int v)
{
int c, h;
char stmp[64];
sprintf( stmp, "Tint: %3i", v );
tintFrame->setTitle(stmp);
g_config->setOption ("SDL.Tint", v);
g_config->save ();
g_config->getOption ("SDL.NTSCpalette", &c);
g_config->getOption ("SDL.Hue", &h);
if ( fceuWrapperTryLock() )
{
FCEUI_SetNTSCTH (c, v, h);
fceuWrapperUnLock();
}
}
//----------------------------------------------------
void PaletteConfDialog_t::use_Custom_Changed(int state)
{
int value = (state == Qt::Unchecked) ? 0 : 1;
std::string filename;
//printf("Use Custom:%i \n", state );
g_config->getOption ("SDL.Palette", &filename);
if ( fceuWrapperTryLock() )
{
if ( value && (filename.size() > 0) )
{
LoadCPalette ( filename.c_str() );
}
else
{
FCEUI_SetUserPalette( NULL, 0);
}
fceuWrapperUnLock();
}
}
//----------------------------------------------------
void PaletteConfDialog_t::force_GrayScale_Changed(int state)
{
int value = (state == Qt::Unchecked) ? 0 : 1;
if ( fceuWrapperTryLock() )
{
int e, h, t;
g_config->getOption ("SDL.NTSCpalette", &e);
g_config->getOption ("SDL.Hue", &h);
g_config->getOption ("SDL.Tint", &t);
force_grayscale = value ? true : false;
FCEUI_SetNTSCTH( e, t, h);
fceuWrapperUnLock();
}
}
//----------------------------------------------------
void PaletteConfDialog_t::deemphswap_Changed(int state)
{
int value = (state == Qt::Unchecked) ? 0 : 1;
if ( fceuWrapperTryLock() )
{
int e, h, t;
g_config->getOption ("SDL.NTSCpalette", &e);
g_config->getOption ("SDL.Hue", &h);
g_config->getOption ("SDL.Tint", &t);
paldeemphswap = value ? true : false;
FCEUI_SetNTSCTH( e, t, h);
fceuWrapperUnLock();
}
}
//----------------------------------------------------
void PaletteConfDialog_t::use_NTSC_Changed(int state)
{
int h, t;
int value = (state == Qt::Unchecked) ? 0 : 1;
g_config->setOption ("SDL.NTSCpalette", value);
g_config->save ();
g_config->getOption ("SDL.Hue", &h);
g_config->getOption ("SDL.Tint", &t);
if ( fceuWrapperTryLock() )
{
FCEUI_SetNTSCTH (value, t, h);
//UpdateEMUCore (g_config);
fceuWrapperUnLock();
}
}
//----------------------------------------------------
void PaletteConfDialog_t::clearPalette(void)
{
g_config->setOption ("SDL.Palette", "");
custom_palette_path->setText("");
if ( fceuWrapperTryLock() )
{
FCEUI_SetUserPalette( NULL, 0);
fceuWrapperUnLock();
useCustom->setChecked(false);
}
}
//----------------------------------------------------
void PaletteConfDialog_t::openPaletteFile(void)
{
int ret, useNativeFileDialogVal;
QString filename;
std::string last;
char dir[512];
QFileDialog dialog(this, tr("Open NES Palette") );
dialog.setFileMode(QFileDialog::ExistingFile);
dialog.setNameFilter(tr("NES Palettes (*.pal *.PAL) ;; All files (*)"));
dialog.setViewMode(QFileDialog::List);
dialog.setFilter( QDir::AllEntries | QDir::Hidden );
dialog.setLabelText( QFileDialog::Accept, tr("Load") );
g_config->getOption ("SDL.Palette", &last );
if ( last.size() == 0 )
{
last.assign( "/usr/share/fceux/palettes" );
}
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 ( fceuWrapperTryLock() )
{
if ( LoadCPalette ( filename.toStdString().c_str() ) )
{
g_config->setOption ("SDL.Palette", filename.toStdString().c_str() );
custom_palette_path->setText( filename.toStdString().c_str() );
}
else
{
printf("Error: Failed to Load Palette File: %s \n", filename.toStdString().c_str() );
}
fceuWrapperUnLock();
useCustom->setChecked( FCEUI_GetUserPaletteAvail() );
}
return;
}
//----------------------------------------------------

View File

@ -0,0 +1,54 @@
// PaletteConf.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 "Qt/main.h"
class PaletteConfDialog_t : public QDialog
{
Q_OBJECT
public:
PaletteConfDialog_t(QWidget *parent = 0);
~PaletteConfDialog_t(void);
protected:
void closeEvent(QCloseEvent *event);
QLineEdit *custom_palette_path;
QCheckBox *useCustom;
QCheckBox *GrayScale;
QCheckBox *deemphSwap;
QCheckBox *useNTSC;
QSlider *tintSlider;
QSlider *hueSlider;
QGroupBox *tintFrame;
QGroupBox *hueFrame;
private:
public slots:
void closeWindow(void);
private slots:
void hueChanged(int value);
void tintChanged(int value);
void openPaletteFile(void);
void clearPalette(void);
void use_NTSC_Changed(int v);
void use_Custom_Changed(int v);
void force_GrayScale_Changed(int v);
void deemphswap_Changed(int v);
};

View File

@ -102,20 +102,20 @@ LoadCPalette(const std::string &file)
static void
CreateDirs(const std::string &dir)
{
const char *subs[8]={"fcs","snaps","gameinfo","sav","cheats","movies","cfg.d"};
const char *subs[9]={"fcs","snaps","gameinfo","sav","cheats","movies","input"};
std::string subdir;
int x;
#if defined(WIN32) || defined(NEED_MINGW_HACKS)
mkdir(dir.c_str());
chmod(dir.c_str(), 755);
for(x = 0; x < 6; x++) {
for(x = 0; x < 7; x++) {
subdir = dir + PSS + subs[x];
mkdir(subdir.c_str());
}
#else
mkdir(dir.c_str(), S_IRWXU);
for(x = 0; x < 6; x++) {
for(x = 0; x < 7; x++) {
subdir = dir + PSS + subs[x];
mkdir(subdir.c_str(), S_IRWXU);
}
@ -199,6 +199,7 @@ InitConfig()
// video controls
config->addOption('f', "fullscreen", "SDL.Fullscreen", 0);
config->addOption("videoDriver", "SDL.VideoDriver", 0);
// set x/y res to 0 for automatic fullscreen resolution detection (no change)
config->addOption('x', "xres", "SDL.XResolution", 0);
@ -241,7 +242,7 @@ InitConfig()
config->addOption("input4", "SDL.Input.3", "Gamepad.3");
// allow for input configuration
config->addOption('i', "inputcfg", "SDL.InputCfg", InputCfg);
//config->addOption('i', "inputcfg", "SDL.InputCfg", InputCfg);
// display input
config->addOption("inputdisplay", "SDL.InputDisplay", 0);
@ -254,6 +255,10 @@ InitConfig()
config->addOption("recordhud", "SDL.RecordHUD", 1);
config->addOption("moviemsg", "SDL.MovieMsg", 1);
// Hex Editor Options
config->addOption("hexEditBgColor", "SDL.HexEditBgColor", "#000000");
config->addOption("hexEditFgColor", "SDL.HexEditFgColor", "#FFFFFF");
// overwrite the config file?
config->addOption("no-config", "SDL.NoConfig", 0);
@ -293,6 +298,9 @@ InitConfig()
config->addOption("_lastsavestateas", "SDL.LastSaveStateAs", home_dir);
config->addOption("_lastloadlua", "SDL.LastLoadLua", "");
config->addOption("_useNativeFileDialog", "SDL.UseNativeFileDialog", false);
config->addOption("_useNativeMenuBar" , "SDL.UseNativeMenuBar", false);
// fcm -> fm2 conversion
config->addOption("fcmconvert", "SDL.FCMConvert", "");
@ -313,10 +321,8 @@ InitConfig()
prefix = buf;
config->addOption(prefix + "DeviceType", DefaultGamePadDevice[i]);
config->addOption(prefix + "DeviceNum", 0);
for(unsigned int j = 0; j < GAMEPAD_NUM_BUTTONS; j++) {
config->addOption(prefix + GamePadNames[j], DefaultGamePad[i][j]);
}
config->addOption(prefix + "DeviceGUID", "");
config->addOption(prefix + "Profile" , "");
}
// PowerPad 0 - 1

View File

@ -18,6 +18,8 @@ void SilenceSound(int s); /* DOS and SDL */
int InitJoysticks(void);
int KillJoysticks(void);
int AddJoystick( int which );
int RemoveJoystick( int which );
uint32 *GetJSOr(void);
int InitVideo(FCEUGI *gi);

View File

@ -14,7 +14,9 @@
#include "Qt/sdl-video.h"
#include "Qt/nes_shm.h"
#include "Qt/unix-netplay.h"
#include "Qt/HexEditor.h"
#include "Qt/ConsoleWindow.h"
#include "Qt/fceux_git_info.h"
#include "common/cheat.h"
#include "../../fceu.h"
@ -56,7 +58,9 @@ static int inited = 0;
static int noconfig=0;
static int frameskip=0;
static int periodic_saves = 0;
static bool mutexLocked = 0;
static int mutexLocks = 0;
static int mutexPending = 0;
static bool emulatorHasMutux = 0;
extern double g_fpsScale;
@ -78,19 +82,22 @@ int mutecapture = 0;
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 GTK mode, display a dialog message box of the error.
* 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 );
}
/**
@ -98,7 +105,8 @@ void FCEUD_PrintError(const char *errormsg)
*/
FILE *FCEUD_UTF8fopen(const char *fn, const char *mode)
{
return(fopen(fn,mode));
FILE *fp = ::fopen(fn,mode);
return(fp);
}
/**
@ -190,8 +198,8 @@ DriverKill()
if (!noconfig)
g_config->save();
if(inited&2)
KillJoysticks();
if(inited&4)
KillVideo();
if(inited&1)
@ -224,6 +232,8 @@ int LoadGame(const char *path)
return 0;
}
hexEditorLoadBookmarks();
int state_to_load;
g_config->getOption("SDL.AutoLoadState", &state_to_load);
if (state_to_load >= 0 && state_to_load < 10){
@ -270,6 +280,7 @@ CloseGame(void)
if(!isloaded) {
return(0);
}
hexEditorSaveBookmarks();
int state_to_save;
g_config->getOption("SDL.AutoSaveState", &state_to_save);
@ -405,12 +416,15 @@ static void ShowUsage(const char *prog)
SDL_GetVersion(&v);
printf("Linked with SDL version %d.%d.%d\n", v.major, v.minor, v.patch);
printf("Compiled with QT version %d.%d.%d\n", QT_VERSION_MAJOR, QT_VERSION_MINOR, QT_VERSION_PATCH );
printf("git URL: %s\n", fceu_get_git_url() );
printf("git Rev: %s\n", fceu_get_git_rev() );
}
int fceuWrapperInit( int argc, char *argv[] )
{
int error;
std::string s;
for (int i=0; i<argc; i++)
{
@ -429,6 +443,10 @@ int fceuWrapperInit( int argc, char *argv[] )
printf("Could not initialize SDL: %s.\n", SDL_GetError());
exit(-1);
}
if ( SDL_SetHint( SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1" ) == SDL_FALSE )
{
printf("Error setting SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS\n");
}
// Initialize the configuration system
g_config = InitConfig();
@ -465,15 +483,14 @@ int fceuWrapperInit( int argc, char *argv[] )
g_config->save();
}
std::string s;
g_config->getOption("SDL.InputCfg", &s);
//g_config->getOption("SDL.InputCfg", &s);
if (s.size() != 0)
{
InitVideo(GameInfo);
InputCfg(s);
}
//if (s.size() != 0)
//{
// InitVideo(GameInfo);
// InputCfg(s);
//}
// update the input devices
UpdateInput(g_config);
@ -910,29 +927,33 @@ static void DoFun(int frameskip, int periodic_saves)
void fceuWrapperLock(void)
{
mutexPending++;
consoleWindow->mutex->lock();
mutexLocked = 1;
mutexPending--;
mutexLocks++;
}
bool fceuWrapperTryLock(int timeout)
{
bool lockAcq;
mutexPending++;
lockAcq = consoleWindow->mutex->tryLock( timeout );
mutexPending--;
if ( lockAcq )
{
mutexLocked = 1;
mutexLocks++;
}
return lockAcq;
}
void fceuWrapperUnLock(void)
{
if ( mutexLocked )
if ( mutexLocks > 0 )
{
consoleWindow->mutex->unlock();
mutexLocked = 0;
mutexLocks--;
}
else
{
@ -942,12 +963,30 @@ void fceuWrapperUnLock(void)
bool fceuWrapperIsLocked(void)
{
return mutexLocked;
return mutexLocks > 0;
}
int fceuWrapperUpdate( void )
{
fceuWrapperLock();
bool lock_acq;
// If a request is pending,
// sleep to allow request to be serviced.
if ( mutexPending > 0 )
{
usleep( 100000 );
}
lock_acq = fceuWrapperTryLock();
if ( !lock_acq )
{
printf("Error: Emulator Failed to Acquire Mutex\n");
usleep( 100000 );
return -1;
}
emulatorHasMutux = 1;
if ( GameInfo && !FCEUI_EmulationPaused() )
{
@ -955,6 +994,8 @@ int fceuWrapperUpdate( void )
fceuWrapperUnLock();
emulatorHasMutux = 0;
while ( SpeedThrottle() )
{
// Input device processing is in main thread
@ -966,6 +1007,8 @@ int fceuWrapperUpdate( void )
{
fceuWrapperUnLock();
emulatorHasMutux = 0;
usleep( 100000 );
}
return 0;

View File

@ -26,7 +26,7 @@ int fceuWrapperInit( int argc, char *argv[] );
int fceuWrapperClose( void );
int fceuWrapperUpdate( void );
void fceuWrapperLock(void);
bool fceuWrapperTryLock(int timeout);
bool fceuWrapperTryLock(int timeout = 1000);
bool fceuWrapperIsLocked(void);
void fceuWrapperUnLock(void);
int fceuWrapperSoftReset(void);

View File

@ -24,8 +24,9 @@
#include "Qt/config.h"
#include "Qt/sdl-video.h"
#include "Qt/sdl.h"
#include "Qt/sdl-video.h"
#include "Qt/sdl-joystick.h"
#include "common/cheat.h"
#include "../../movie.h"
@ -49,8 +50,8 @@ extern bool bindSavestate, frameAdvanceLagSkip, lagCounterDisplay;
/* UsrInputType[] is user-specified. CurInputType[] is current
(game loading can override user settings)
*/
static int UsrInputType[NUM_INPUT_DEVICES];
static int CurInputType[NUM_INPUT_DEVICES];
static int UsrInputType[NUM_INPUT_DEVICES] = { SI_GAMEPAD, SI_GAMEPAD, SI_NONE };
static int CurInputType[NUM_INPUT_DEVICES] = { SI_GAMEPAD, SI_GAMEPAD, SI_NONE };
static int cspec = 0;
static int buttonConfigInProgress = 0;
@ -956,6 +957,12 @@ UpdatePhysicalInput ()
g_keyState[ event.key.keysym.scancode ] = (event.type == SDL_KEYDOWN) ? 1 : 0;
//checkKeyBoardState( event.key.keysym.scancode );
break;
case SDL_JOYDEVICEADDED:
AddJoystick( event.jdevice.which );
break;
case SDL_JOYDEVICEREMOVED:
RemoveJoystick( event.jdevice.which );
break;
default:
break;
}
@ -964,8 +971,6 @@ UpdatePhysicalInput ()
}
static int bcpv=0, bcpj=0;
/**
* Begin configuring the buttons by placing the video and joystick
* subsystems into a well-known state. Button configuration really
@ -973,13 +978,7 @@ static int bcpv=0, bcpj=0;
*/
int ButtonConfigBegin ()
{
// shut down the joystick subsystems
//SDL_Surface *screen;
bcpj = KillJoysticks ();
// XXX soules - why did we shut this down?
// initialize the joystick subsystem
// initialize the joystick subsystem (if not already inited)
InitJoysticks ();
buttonConfigInProgress = 1;
@ -995,18 +994,6 @@ int ButtonConfigBegin ()
void
ButtonConfigEnd ()
{
// shutdown the joystick and video subsystems
KillJoysticks ();
//SDL_QuitSubSystem(SDL_INIT_VIDEO);
// re-initialize joystick and video subsystems if they were active before
/*if(!bcpv) {
InitVideo(GameInfo);
} */
if (!bcpj)
{
InitJoysticks ();
}
buttonConfigInProgress = 0;
}
@ -1016,49 +1003,50 @@ ButtonConfigEnd ()
static int
DTestButton (ButtConfig * bc)
{
int x;
for (x = 0; x < bc->NumC; x++)
if (bc->ButtType == BUTTC_KEYBOARD)
{
if (bc->ButtType[x] == BUTTC_KEYBOARD)
{
if (g_keyState[SDL_GetScancodeFromKey (bc->ButtonNum[x])])
if (g_keyState[SDL_GetScancodeFromKey (bc->ButtonNum)])
{
bc->state = 1;
return 1;
}
else
{
bc->state = 0;
}
else if (bc->ButtType[x] == BUTTC_JOYSTICK)
}
else if (bc->ButtType == BUTTC_JOYSTICK)
{
if (DTestButtonJoy (bc))
{
return 1;
}
}
}
return 0;
}
#define MK(x) {{BUTTC_KEYBOARD},{0},{MKK(x)},1}
#define MK2(x1,x2) {{BUTTC_KEYBOARD},{0},{MKK(x1),MKK(x2)},2}
#define MKZ() {{0},{0},{-1},0}
#define MK(x) {BUTTC_KEYBOARD,0,MKK(x),0}
//#define MK2(x1,x2) {BUTTC_KEYBOARD,0,MKK(x1)}
#define MKZ() {0,0,-1,0}
#define GPZ() {MKZ(), MKZ(), MKZ(), MKZ()}
ButtConfig GamePadConfig[ GAMEPAD_NUM_DEVICES ][ GAMEPAD_NUM_BUTTONS ] =
{
/* Gamepad 1 */
{MK (KP_3), MK (KP_2), MK (SLASH), MK (ENTER),
MK (w), MK (z), MK (a), MK (s), MKZ (), MKZ ()},
/* Gamepad 2 */
GPZ (),
/* Gamepad 3 */
GPZ (),
/* Gamepad 4 */
GPZ ()
};
//ButtConfig GamePadConfig[ GAMEPAD_NUM_DEVICES ][ GAMEPAD_NUM_BUTTONS ] =
//{
///* Gamepad 1 */
// {MK (KP_3), MK (KP_2), MK (SLASH), MK (ENTER),
// MK (w), MK (z), MK (a), MK (s), MKZ (), MKZ ()},
//
// /* Gamepad 2 */
// GPZ (),
//
// /* Gamepad 3 */
// GPZ (),
//
// /* Gamepad 4 */
// GPZ ()
//};
/**
* Update the status of the gamepad input devices.
@ -1090,7 +1078,7 @@ UpdateGamepad(void)
// a, b, select, start, up, down, left, right
for (x = 0; x < 8; x++)
{
if (DTestButton (&GamePadConfig[wg][x]))
if (DTestButton (&GamePad[wg].bmap[x]))
{
//printf("GamePad%i Button Hit: %i \n", wg, x );
if(opposite_dirs == 0)
@ -1128,7 +1116,7 @@ UpdateGamepad(void)
{
for (x = 0; x < 2; x++)
{
if (DTestButton (&GamePadConfig[wg][8 + x]))
if (DTestButton (&GamePad[wg].bmap[8 + x]))
{
JS |= (1 << x) << (wg << 3);
}
@ -1563,42 +1551,42 @@ UpdateFTrainer ()
* @param bc the NES gamepad's button config
* @param which the index of the button
*/
const char * ButtonName (const ButtConfig * bc, int which)
const char * ButtonName (const ButtConfig * bc)
{
static char name[256];
name[0] = 0;
if (bc->ButtonNum[which] == -1)
if (bc->ButtonNum == -1)
{
return name;
}
switch (bc->ButtType[which])
switch (bc->ButtType)
{
case BUTTC_KEYBOARD:
return SDL_GetKeyName (bc->ButtonNum[which]);
return SDL_GetKeyName (bc->ButtonNum);
break;
case BUTTC_JOYSTICK:
{
int joyNum, inputNum;
const char *inputType, *inputDirection;
joyNum = bc->DeviceNum[which];
if (bc->ButtonNum[which] & 0x8000)
{
inputType = "Axis";
inputNum = bc->ButtonNum[which] & 0x3FFF;
inputDirection = bc->ButtonNum[which] & 0x4000 ? "-" : "+";
}
else if (bc->ButtonNum[which] & 0x2000)
{
int inputValue;
char direction[128] = "";
joyNum = bc->DeviceNum;
if (bc->ButtonNum & 0x8000)
{
inputType = "Axis";
inputNum = bc->ButtonNum & 0x3FFF;
inputDirection = bc->ButtonNum & 0x4000 ? "-" : "+";
}
else if (bc->ButtonNum & 0x2000)
{
int inputValue;
inputType = "Hat";
inputNum = (bc->ButtonNum[which] >> 8) & 0x1F;
inputValue = bc->ButtonNum[which] & 0xF;
inputNum = (bc->ButtonNum >> 8) & 0x1F;
inputValue = bc->ButtonNum & 0xF;
if (inputValue & SDL_HAT_UP)
strncat (direction, "Up ", sizeof (direction)-1);
@ -1617,7 +1605,7 @@ const char * ButtonName (const ButtConfig * bc, int which)
else
{
inputType = "Button";
inputNum = bc->ButtonNum[which];
inputNum = bc->ButtonNum;
inputDirection = "";
}
sprintf( name, "js%i:%s%i%s", joyNum, inputType, inputNum, inputDirection );
@ -1632,7 +1620,7 @@ const char * ButtonName (const ButtConfig * bc, int which)
* Waits for a button input and returns the information as to which
* button was pressed. Used in button configuration.
*/
int DWaitButton (const uint8_t * text, ButtConfig * bc, int wb, int *buttonConfigStatus )
int DWaitButton (const uint8_t * text, ButtConfig * bc, int *buttonConfigStatus )
{
SDL_Event event;
static int32 LastAx[64][64];
@ -1684,23 +1672,23 @@ int DWaitButton (const uint8_t * text, ButtConfig * bc, int wb, int *buttonConfi
{
case SDL_KEYDOWN:
//printf("SDL KeyDown:%i \n", event.key.keysym.sym );
bc->ButtType[wb] = BUTTC_KEYBOARD;
bc->DeviceNum[wb] = 0;
bc->ButtonNum[wb] = event.key.keysym.sym;
bc->ButtType = BUTTC_KEYBOARD;
bc->DeviceNum = 0;
bc->ButtonNum = event.key.keysym.sym;
return (1);
case SDL_JOYBUTTONDOWN:
bc->ButtType[wb] = BUTTC_JOYSTICK;
bc->DeviceNum[wb] = event.jbutton.which;
bc->ButtonNum[wb] = event.jbutton.button;
bc->ButtType = BUTTC_JOYSTICK;
bc->DeviceNum = event.jbutton.which;
bc->ButtonNum = event.jbutton.button;
return (1);
case SDL_JOYHATMOTION:
if (event.jhat.value == SDL_HAT_CENTERED)
done--;
else
{
bc->ButtType[wb] = BUTTC_JOYSTICK;
bc->DeviceNum[wb] = event.jhat.which;
bc->ButtonNum[wb] =
bc->ButtType = BUTTC_JOYSTICK;
bc->DeviceNum = event.jhat.which;
bc->ButtonNum =
(0x2000 | ((event.jhat.hat & 0x1F) << 8) | event.
jhat.value);
return (1);
@ -1722,9 +1710,9 @@ int DWaitButton (const uint8_t * text, ButtConfig * bc, int wb, int *buttonConfi
(LastAx[event.jaxis.which][event.jaxis.axis] -
event.jaxis.value) >= 8192)
{
bc->ButtType[wb] = BUTTC_JOYSTICK;
bc->DeviceNum[wb] = event.jaxis.which;
bc->ButtonNum[wb] = (0x8000 | event.jaxis.axis |
bc->ButtType = BUTTC_JOYSTICK;
bc->DeviceNum = event.jaxis.which;
bc->ButtonNum = (0x8000 | event.jaxis.axis |
((event.jaxis.value < 0)
? 0x4000 : 0));
return (1);
@ -1761,170 +1749,169 @@ int DWaitButton (const uint8_t * text, ButtConfig * bc, int wb, int *buttonConfi
* used as input for the specified button, thus allowing up to four
* possible settings for each input button.
*/
void
ConfigButton (char *text, ButtConfig * bc)
{
uint8 buf[256];
int wc;
for (wc = 0; wc < MAXBUTTCONFIG; wc++)
{
sprintf ((char *) buf, "%s (%d)", text, wc + 1);
DWaitButton (buf, bc, wc, NULL);
if (wc &&
bc->ButtType[wc] == bc->ButtType[wc - 1] &&
bc->DeviceNum[wc] == bc->DeviceNum[wc - 1] &&
bc->ButtonNum[wc] == bc->ButtonNum[wc - 1])
{
break;
}
}
bc->NumC = wc;
}
// void
//ConfigButton (char *text, ButtConfig * bc)
//{
// uint8 buf[256];
// int wc;
//
// for (wc = 0; wc < MAXBUTTCONFIG; wc++)
// {
// sprintf ((char *) buf, "%s (%d)", text, wc + 1);
// DWaitButton (buf, bc, wc, NULL);
//
// if (wc &&
// bc->ButtType[wc] == bc->ButtType[wc - 1] &&
// bc->DeviceNum[wc] == bc->DeviceNum[wc - 1] &&
// bc->ButtonNum[wc] == bc->ButtonNum[wc - 1])
// {
// break;
// }
// }
//}
/**
* Update the button configuration for a specified device.
*/
extern Config *g_config;
void ConfigDevice (int which, int arg)
{
char buf[256];
int x;
std::string prefix;
const char *str[10] =
{ "A", "B", "SELECT", "START", "UP", "DOWN", "LEFT", "RIGHT", "Rapid A",
"Rapid B"
};
// XXX soules - set the configuration options so that later calls
// don't override these. This is a temp hack until I
// can clean up this file.
ButtonConfigBegin ();
switch (which)
{
case FCFGD_QUIZKING:
prefix = "SDL.Input.QuizKing.";
for (x = 0; x < 6; x++)
{
sprintf (buf, "Quiz King Buzzer #%d", x + 1);
ConfigButton (buf, &QuizKingButtons[x]);
g_config->setOption (prefix + QuizKingNames[x],
QuizKingButtons[x].ButtonNum[0]);
}
if (QuizKingButtons[0].ButtType[0] == BUTTC_KEYBOARD)
{
g_config->setOption (prefix + "DeviceType", "Keyboard");
}
else if (QuizKingButtons[0].ButtType[0] == BUTTC_JOYSTICK)
{
g_config->setOption (prefix + "DeviceType", "Joystick");
}
else
{
g_config->setOption (prefix + "DeviceType", "Unknown");
}
g_config->setOption (prefix + "DeviceNum",
QuizKingButtons[0].DeviceNum[0]);
break;
case FCFGD_HYPERSHOT:
prefix = "SDL.Input.HyperShot.";
for (x = 0; x < 4; x++)
{
sprintf (buf, "Hyper Shot %d: %s",
((x & 2) >> 1) + 1, (x & 1) ? "JUMP" : "RUN");
ConfigButton (buf, &HyperShotButtons[x]);
g_config->setOption (prefix + HyperShotNames[x],
HyperShotButtons[x].ButtonNum[0]);
}
if (HyperShotButtons[0].ButtType[0] == BUTTC_KEYBOARD)
{
g_config->setOption (prefix + "DeviceType", "Keyboard");
}
else if (HyperShotButtons[0].ButtType[0] == BUTTC_JOYSTICK)
{
g_config->setOption (prefix + "DeviceType", "Joystick");
}
else
{
g_config->setOption (prefix + "DeviceType", "Unknown");
}
g_config->setOption (prefix + "DeviceNum",
HyperShotButtons[0].DeviceNum[0]);
break;
case FCFGD_POWERPAD:
snprintf (buf, 256, "SDL.Input.PowerPad.%d", (arg & 1));
prefix = buf;
for (x = 0; x < 12; x++)
{
sprintf (buf, "PowerPad %d: %d", (arg & 1) + 1, x + 11);
ConfigButton (buf, &powerpadsc[arg & 1][x]);
g_config->setOption (prefix + PowerPadNames[x],
powerpadsc[arg & 1][x].ButtonNum[0]);
}
if (powerpadsc[arg & 1][0].ButtType[0] == BUTTC_KEYBOARD)
{
g_config->setOption (prefix + "DeviceType", "Keyboard");
}
else if (powerpadsc[arg & 1][0].ButtType[0] == BUTTC_JOYSTICK)
{
g_config->setOption (prefix + "DeviceType", "Joystick");
}
else
{
g_config->setOption (prefix + "DeviceType", "Unknown");
}
g_config->setOption (prefix + "DeviceNum",
powerpadsc[arg & 1][0].DeviceNum[0]);
break;
case FCFGD_GAMEPAD:
snprintf (buf, 256, "SDL.Input.GamePad.%d", arg);
prefix = buf;
for (x = 0; x < 10; x++)
{
sprintf (buf, "GamePad #%d: %s", arg + 1, str[x]);
ConfigButton (buf, &GamePadConfig[arg][x]);
g_config->setOption (prefix + GamePadNames[x],
GamePadConfig[arg][x].ButtonNum[0]);
}
if (GamePadConfig[arg][0].ButtType[0] == BUTTC_KEYBOARD)
{
g_config->setOption (prefix + "DeviceType", "Keyboard");
}
else if (GamePadConfig[arg][0].ButtType[0] == BUTTC_JOYSTICK)
{
g_config->setOption (prefix + "DeviceType", "Joystick");
}
else
{
g_config->setOption (prefix + "DeviceType", "Unknown");
}
g_config->setOption (prefix + "DeviceNum",
GamePadConfig[arg][0].DeviceNum[0]);
break;
}
ButtonConfigEnd ();
}
//void ConfigDevice (int which, int arg)
//{
// char buf[256];
// int x;
// std::string prefix;
// const char *str[10] =
// { "A", "B", "SELECT", "START", "UP", "DOWN", "LEFT", "RIGHT", "Rapid A",
// "Rapid B"
// };
//
// // XXX soules - set the configuration options so that later calls
// // don't override these. This is a temp hack until I
// // can clean up this file.
//
// ButtonConfigBegin ();
// switch (which)
// {
// case FCFGD_QUIZKING:
// prefix = "SDL.Input.QuizKing.";
// for (x = 0; x < 6; x++)
// {
// sprintf (buf, "Quiz King Buzzer #%d", x + 1);
// ConfigButton (buf, &QuizKingButtons[x]);
//
// g_config->setOption (prefix + QuizKingNames[x],
// QuizKingButtons[x].ButtonNum);
// }
//
// if (QuizKingButtons[0].ButtType == BUTTC_KEYBOARD)
// {
// g_config->setOption (prefix + "DeviceType", "Keyboard");
// }
// else if (QuizKingButtons[0].ButtType == BUTTC_JOYSTICK)
// {
// g_config->setOption (prefix + "DeviceType", "Joystick");
// }
// else
// {
// g_config->setOption (prefix + "DeviceType", "Unknown");
// }
// g_config->setOption (prefix + "DeviceNum",
// QuizKingButtons[0].DeviceNum);
// break;
// case FCFGD_HYPERSHOT:
// prefix = "SDL.Input.HyperShot.";
// for (x = 0; x < 4; x++)
// {
// sprintf (buf, "Hyper Shot %d: %s",
// ((x & 2) >> 1) + 1, (x & 1) ? "JUMP" : "RUN");
// ConfigButton (buf, &HyperShotButtons[x]);
//
// g_config->setOption (prefix + HyperShotNames[x],
// HyperShotButtons[x].ButtonNum);
// }
//
// if (HyperShotButtons[0].ButtType == BUTTC_KEYBOARD)
// {
// g_config->setOption (prefix + "DeviceType", "Keyboard");
// }
// else if (HyperShotButtons[0].ButtType == BUTTC_JOYSTICK)
// {
// g_config->setOption (prefix + "DeviceType", "Joystick");
// }
// else
// {
// g_config->setOption (prefix + "DeviceType", "Unknown");
// }
// g_config->setOption (prefix + "DeviceNum",
// HyperShotButtons[0].DeviceNum);
// break;
// case FCFGD_POWERPAD:
// snprintf (buf, 256, "SDL.Input.PowerPad.%d", (arg & 1));
// prefix = buf;
// for (x = 0; x < 12; x++)
// {
// sprintf (buf, "PowerPad %d: %d", (arg & 1) + 1, x + 11);
// ConfigButton (buf, &powerpadsc[arg & 1][x]);
//
// g_config->setOption (prefix + PowerPadNames[x],
// powerpadsc[arg & 1][x].ButtonNum);
// }
//
// if (powerpadsc[arg & 1][0].ButtType == BUTTC_KEYBOARD)
// {
// g_config->setOption (prefix + "DeviceType", "Keyboard");
// }
// else if (powerpadsc[arg & 1][0].ButtType == BUTTC_JOYSTICK)
// {
// g_config->setOption (prefix + "DeviceType", "Joystick");
// }
// else
// {
// g_config->setOption (prefix + "DeviceType", "Unknown");
// }
// g_config->setOption (prefix + "DeviceNum",
// powerpadsc[arg & 1][0].DeviceNum);
// break;
//
// case FCFGD_GAMEPAD:
// snprintf (buf, 256, "SDL.Input.GamePad.%d", arg);
// prefix = buf;
// for (x = 0; x < 10; x++)
// {
// sprintf (buf, "GamePad #%d: %s", arg + 1, str[x]);
// ConfigButton (buf, &GamePadConfig[arg][x]);
//
// g_config->setOption (prefix + GamePadNames[x],
// GamePadConfig[arg][x].ButtonNum);
// }
//
// if (GamePadConfig[arg][0].ButtType == BUTTC_KEYBOARD)
// {
// g_config->setOption (prefix + "DeviceType", "Keyboard");
// }
// else if (GamePadConfig[arg][0].ButtType == BUTTC_JOYSTICK)
// {
// g_config->setOption (prefix + "DeviceType", "Joystick");
// }
// else
// {
// g_config->setOption (prefix + "DeviceType", "Unknown");
// }
// g_config->setOption (prefix + "DeviceNum",
// GamePadConfig[arg][0].DeviceNum);
// break;
// }
//
// ButtonConfigEnd ();
//}
/**
* Update the button configuration for a device, specified by a text string.
*/
void InputCfg (const std::string & text)
{
//void InputCfg (const std::string & text)
//{
//
// if (noGui)
// {
// if (text.find ("gamepad") != std::string::npos)
@ -1960,8 +1947,8 @@ void InputCfg (const std::string & text)
// }
// else
// printf ("Please run \"fceux --nogui\" before using --inputcfg\n");
}
//
//}
/**
@ -1973,7 +1960,9 @@ void InputCfg (const std::string & text)
UpdateInput (Config * config)
{
char buf[64];
std::string device, prefix;
std::string device, prefix, guid, mapping;
InitJoysticks();
for (unsigned int i = 0; i < 3; i++)
{
@ -2067,36 +2056,17 @@ UpdateInput (Config * config)
prefix = buf;
config->getOption (prefix + "DeviceType", &device );
if (device.find ("Keyboard") != std::string::npos)
{
type = BUTTC_KEYBOARD;
}
else if (device.find ("Joystick") != std::string::npos)
{
type = BUTTC_JOYSTICK;
}
else
{
type = 0;
}
config->getOption (prefix + "DeviceGUID", &guid );
config->getOption (prefix + "Profile" , &mapping);
config->getOption (prefix + "DeviceNum", &devnum);
for (unsigned int j = 0; j < GAMEPAD_NUM_BUTTONS; j++)
{
config->getOption (prefix + GamePadNames[j], &button);
GamePadConfig[i][j].ButtType[0] = type;
GamePadConfig[i][j].DeviceNum[0] = devnum;
GamePadConfig[i][j].ButtonNum[0] = button;
GamePadConfig[i][j].NumC = 1;
}
GamePad[i].init( i, guid.c_str(), mapping.c_str() );
}
// PowerPad 0 - 1
for (unsigned int i = 0; i < POWERPAD_NUM_DEVICES; i++)
{
char buf[64];
snprintf (buf, 32, "SDL.Input.PowerPad.%u.", i);
snprintf (buf, sizeof(buf)-1, "SDL.Input.PowerPad.%u.", i);
prefix = buf;
config->getOption (prefix + "DeviceType", &device);
@ -2118,10 +2088,9 @@ UpdateInput (Config * config)
{
config->getOption (prefix + PowerPadNames[j], &button);
powerpadsc[i][j].ButtType[0] = type;
powerpadsc[i][j].DeviceNum[0] = devnum;
powerpadsc[i][j].ButtonNum[0] = button;
powerpadsc[i][j].NumC = 1;
powerpadsc[i][j].ButtType = type;
powerpadsc[i][j].DeviceNum = devnum;
powerpadsc[i][j].ButtonNum = button;
}
}
@ -2145,10 +2114,9 @@ UpdateInput (Config * config)
{
config->getOption (prefix + QuizKingNames[j], &button);
QuizKingButtons[j].ButtType[0] = type;
QuizKingButtons[j].DeviceNum[0] = devnum;
QuizKingButtons[j].ButtonNum[0] = button;
QuizKingButtons[j].NumC = 1;
QuizKingButtons[j].ButtType = type;
QuizKingButtons[j].DeviceNum = devnum;
QuizKingButtons[j].ButtonNum = button;
}
// HyperShot
@ -2171,10 +2139,9 @@ UpdateInput (Config * config)
{
config->getOption (prefix + HyperShotNames[j], &button);
HyperShotButtons[j].ButtType[0] = type;
HyperShotButtons[j].DeviceNum[0] = devnum;
HyperShotButtons[j].ButtonNum[0] = button;
HyperShotButtons[j].NumC = 1;
HyperShotButtons[j].ButtType = type;
HyperShotButtons[j].DeviceNum = devnum;
HyperShotButtons[j].ButtonNum = button;
}
// Mahjong
@ -2197,10 +2164,9 @@ UpdateInput (Config * config)
{
config->getOption (prefix + MahjongNames[j], &button);
MahjongButtons[j].ButtType[0] = type;
MahjongButtons[j].DeviceNum[0] = devnum;
MahjongButtons[j].ButtonNum[0] = button;
MahjongButtons[j].NumC = 1;
MahjongButtons[j].ButtType = type;
MahjongButtons[j].DeviceNum = devnum;
MahjongButtons[j].ButtonNum = button;
}
// TopRider
@ -2223,10 +2189,9 @@ UpdateInput (Config * config)
{
config->getOption (prefix + TopRiderNames[j], &button);
TopRiderButtons[j].ButtType[0] = type;
TopRiderButtons[j].DeviceNum[0] = devnum;
TopRiderButtons[j].ButtonNum[0] = button;
TopRiderButtons[j].NumC = 1;
TopRiderButtons[j].ButtType = type;
TopRiderButtons[j].DeviceNum = devnum;
TopRiderButtons[j].ButtonNum = button;
}
// FTrainer
@ -2249,10 +2214,9 @@ UpdateInput (Config * config)
{
config->getOption (prefix + FTrainerNames[j], &button);
FTrainerButtons[j].ButtType[0] = type;
FTrainerButtons[j].DeviceNum[0] = devnum;
FTrainerButtons[j].ButtonNum[0] = button;
FTrainerButtons[j].NumC = 1;
FTrainerButtons[j].ButtType = type;
FTrainerButtons[j].DeviceNum = devnum;
FTrainerButtons[j].ButtonNum = button;
}
// FamilyKeyBoard
@ -2275,10 +2239,9 @@ UpdateInput (Config * config)
{
config->getOption (prefix + FamilyKeyBoardNames[j], &button);
fkbmap[j].ButtType[0] = type;
fkbmap[j].DeviceNum[0] = devnum;
fkbmap[j].ButtonNum[0] = button;
fkbmap[j].NumC = 1;
fkbmap[j].ButtType = type;
fkbmap[j].DeviceNum = devnum;
fkbmap[j].ButtonNum = button;
}
}

View File

@ -5,7 +5,7 @@
#include "common/configSys.h"
#define MAXBUTTCONFIG 4
//#define MAXBUTTCONFIG 4
enum {
BUTTC_KEYBOARD = 0,
@ -14,14 +14,14 @@ enum {
};
struct ButtConfig
{
int ButtType[MAXBUTTCONFIG];
int DeviceNum[MAXBUTTCONFIG];
int ButtonNum[MAXBUTTCONFIG];
uint32_t NumC;
int ButtType; //[MAXBUTTCONFIG];
int DeviceNum; //[MAXBUTTCONFIG];
int ButtonNum; //[MAXBUTTCONFIG];
int state;
//uint32_t NumC;
//uint64 DeviceID[MAXBUTTCONFIG]; /* TODO */
};
extern int NoWaiting;
extern CFGSTRUCT InputConfig[];
extern ARGPSTRUCT InputArgs[];
@ -32,7 +32,7 @@ int getKeyState( int k );
int ButtonConfigBegin();
void ButtonConfigEnd();
void ConfigButton(char *text, ButtConfig *bc);
int DWaitButton(const uint8_t *text, ButtConfig *bc, int wb, int *buttonConfigStatus = NULL);
int DWaitButton(const uint8_t *text, ButtConfig *bc, int *buttonConfigStatus = NULL);
#define FCFGD_GAMEPAD 1
@ -46,7 +46,7 @@ void InitInputInterface(void);
void InputUserActiveFix(void);
extern bool replaceP2StartWithMicrophone;
extern ButtConfig GamePadConfig[4][10];
//extern ButtConfig GamePadConfig[4][10];
//extern ButtConfig powerpadsc[2][12];
//extern ButtConfig QuizKingButtons[6];
//extern ButtConfig FTrainerButtons[12];
@ -59,9 +59,9 @@ int DTestButtonJoy(ButtConfig *bc);
void FCEUD_UpdateInput(void);
void UpdateInput(Config *config);
void InputCfg(const std::string &);
//void InputCfg(const std::string &);
std::string GetUserText(const char* title);
const char* ButtonName(const ButtConfig* bc, int which);
const char* ButtonName(const ButtConfig* bc);
#endif

View File

@ -17,7 +17,14 @@ int main( int argc, char *argv[] )
consoleWindow->resize( 512, 512 );
consoleWindow->show();
consoleWindow->viewport->init();
if ( consoleWindow->viewport_SDL )
{
consoleWindow->viewport_SDL->init();
}
else
{
consoleWindow->viewport_GL->init();
}
retval = app.exec();

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,92 @@
// sdl-joystick.h
#ifndef __SDL_JOYSTICK_H__
#define __SDL_JOYSTICK_H__
#include <string>
#include "Qt/main.h"
#include "Qt/input.h"
#include "Qt/sdl.h"
#define MAX_JOYSTICKS 32
struct nesGamePadMap_t
{
char guid[64];
char name[128];
char btn[GAMEPAD_NUM_BUTTONS][32];
char os[64];
nesGamePadMap_t(void);
~nesGamePadMap_t(void);
void clearMapping(void);
int parseMapping( const char *text );
};
struct jsDev_t
{
SDL_Joystick *js;
SDL_GameController *gc;
jsDev_t(void);
//~jsDev_t(void);
void init( int idx );
int close(void);
SDL_Joystick *getJS(void);
bool isGameController(void);
bool isConnected(void);
void print(void);
int bindPort( int idx );
int unbindPort( int idx );
int getBindPorts(void);
const char *getName(void);
const char *getGUID(void);
private:
int devIdx;
int portBindMask;
std::string guidStr;
std::string name;
};
class GamePad_t
{
public:
ButtConfig bmap[GAMEPAD_NUM_BUTTONS];
GamePad_t(void);
~GamePad_t(void);
int init( int port, const char *guid, const char *profile = NULL );
const char *getGUID(void);
int loadDefaults(void);
int loadProfile( const char *name, const char *guid = NULL );
int getDeviceIndex(void){ return devIdx; }
int setDeviceIndex( int devIdx );
int setMapping( const char *map );
int setMapping( nesGamePadMap_t *map );
int createProfile( const char *name );
int getMapFromFile( const char *filename, char *out );
int getDefaultMap( char *out, const char *guid = NULL );
int saveMappingToFile( const char *filename, const char *txtMap );
int saveCurrentMapToFile( const char *filename );
int deleteMapping( const char *name );
private:
int devIdx;
int portNum;
};
extern GamePad_t GamePad[4];
jsDev_t *getJoystickDevice( int devNum );
#endif

View File

@ -195,11 +195,19 @@ WriteSound(int32 *buf,
extern int EmulationPaused;
if (EmulationPaused == 0)
{
int waitCount = 0;
while(Count)
{
while(s_BufferIn == s_BufferSize)
{
SDL_Delay(1);
SDL_Delay(1); waitCount++;
if ( waitCount > 1000 )
{
printf("Error: Sound sink is not draining... Breaking out of audio loop to prevent lockup.\n");
return;
}
}
s_Buffer[s_BufferWrite] = *buf;

View File

@ -51,6 +51,7 @@
// GLOBALS
extern Config *g_config;
extern bool force_grayscale;
// STATIC GLOBALS
static int s_curbpp = 0;
@ -206,24 +207,6 @@ int InitVideo(FCEUGI *gi)
return -1;
}
#ifdef OPENGL
if(s_exs <= 0.01) {
FCEUD_PrintError("xscale out of bounds.");
KillVideo();
return -1;
}
if(s_eys <= 0.01) {
FCEUD_PrintError("yscale out of bounds.");
KillVideo();
return -1;
}
//if(s_sponge && s_useOpenGL) {
// FCEUD_PrintError("scalers not compatible with openGL mode.");
// KillVideo();
// return -1;
//}
#endif
if ( !initBlitToHighDone )
{
InitBlitToHigh(s_curbpp >> 3,
@ -268,10 +251,22 @@ FCEUD_SetPalette(uint8 index,
uint8 r,
uint8 g,
uint8 b)
{
if ( force_grayscale )
{
// convert the palette entry to grayscale
int gray = ((float)r * 0.299 + (float)g * 0.587 + (float)b * 0.114);
s_psdl[index].r = gray;
s_psdl[index].g = gray;
s_psdl[index].b = gray;
}
else
{
s_psdl[index].r = r;
s_psdl[index].g = g;
s_psdl[index].b = b;
}
s_paletterefresh = 1;
}
@ -297,6 +292,7 @@ static void RedoPalette()
{
if (s_curbpp > 8)
{
//printf("Refresh Palette\n");
SetPaletteBlitToHigh((uint8*)s_psdl);
}
}

View File

@ -226,7 +226,7 @@ static void ModifyCheat(int num)
printf("Address [$%04x]: ",(unsigned int)A);
A=GetH16(A);
printf("Value [%03d]: ",(unsigned int)V);
printf("Value [%03u]: ",(unsigned int)V);
V=Get8(V);
printf("Compare [%3d]: ",compare);
@ -302,9 +302,9 @@ static void AddCheatParam(uint32 A, uint8 V)
GetString(name,256);
printf("Address [$%04x]: ",(unsigned int)A);
A=GetH16(A);
printf("Value [%03d]: ",(unsigned int)V);
printf("Value [%03u]: ",(unsigned int)V);
V=Get8(V);
printf("Add cheat \"%s\" for address $%04x with value %03d?",name,(unsigned int)A,(unsigned int)V);
printf("Add cheat \"%s\" for address $%04x with value %03u?",name,(unsigned int)A,(unsigned int)V);
if(GetYN(0))
{
if(FCEUI_AddCheat(name,A,V,-1,0))
@ -326,9 +326,9 @@ static int clistcallb(char *name, uint32 a, uint8 v, int compare, int s, int typ
int ret;
if(compare>=0)
sprintf(tmp,"%s $%04x:%03d:%03d - %s",s?"*":" ",(unsigned int)a,(unsigned int)v,compare,name);
sprintf(tmp,"%s $%04x:%03u:%03d - %s",s?"*":" ",(unsigned int)a,(unsigned int)v,compare,name);
else
sprintf(tmp,"%s $%04x:%03d - %s",s?"*":" ",(unsigned int)a,(unsigned int)v,name);
sprintf(tmp,"%s $%04x:%03u - %s",s?"*":" ",(unsigned int)a,(unsigned int)v,name);
if(type==1)
tmp[2]='S';
ret=AddToList(tmp,lid);
@ -373,7 +373,7 @@ static void ResetSearch(void)
static int srescallb(uint32 a, uint8 last, uint8 current, void *data)
{
char tmp[14];
sprintf(tmp, "$%04x:%03d:%03d",(unsigned int)a,(unsigned int)last,(unsigned int)current);
sprintf(tmp, "$%04x:%03u:%03u",(unsigned int)a,(unsigned int)last,(unsigned int)current);
return(AddToList(tmp,a));
}

View File

@ -0,0 +1,87 @@
// os_util.cpp
#include <stdio.h>
#include <stdlib.h>
#if defined(WIN32)
#include <windows.h>
#else
#include <errno.h>
#include <sys/stat.h>
#endif
#include "common/os_utils.h"
//************************************************************
int fceu_mkdir( const char *path )
{
int retval;
#if defined(WIN32)
retval = mkdir(path);
chmod(path, 755);
#else
retval = mkdir(path, S_IRWXU);
if ( retval != 0 )
{
if ( errno == EEXIST )
{
//printf("Path Exists: '%s'\n", path);
retval = 0;
}
}
#endif
return retval;
}
//************************************************************
int fceu_mkpath( const char *path )
{
int i, retval = 0;
char p[512];
i=0;
while ( path[i] != 0 )
{
if ( path[i] == '/' )
{
if ( i > 0 )
{
p[i] = 0;
retval = fceu_mkdir( p );
if ( retval )
{
return retval;
}
}
}
p[i] = path[i]; i++;
}
p[i] = 0;
retval = fceu_mkdir( p );
return retval;
}
//************************************************************
bool fceu_file_exists( const char *filepath )
{
#ifdef WIN32
FILE *fp;
fp = ::fopen( filename, "r" );
if ( fp != NULL )
{
::fclose(fp);
return true;
}
#else
struct stat sb;
if ( stat( filepath, &sb ) == 0 )
{
return true;
}
#endif
return false;
}
//************************************************************

View File

@ -0,0 +1,9 @@
// os_utils.h
//
int fceu_mkdir( const char *path );
int fceu_mkpath( const char *path );
bool fceu_file_exists( const char *filepath );

View File

@ -88,13 +88,13 @@ static int PAL_LUT(uint32 *buffer, int index, int x, int y)
static void CalculateShift(uint32 *CBM, int *cshiftr, int *cshiftl)
{
int a,x,z,y;
int a,x,z;
cshiftl[0]=cshiftl[1]=cshiftl[2]=-1;
for(a=0;a<3;a++)
{
for(x=0,y=-1,z=0;x<32;x++)
for(x=0,z=0;x<32;x++)
{
if(CBM[a]&(1<<x))
if(CBM[a]&(1u<<x))
{
if(cshiftl[a]==-1) cshiftl[a]=x;
z++;

View File

@ -0,0 +1,873 @@
// GamePadConf.cpp
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <gtk/gtk.h>
#include "sdl/GamePadConf.h"
#include "sdl/main.h"
#include "sdl/dface.h"
#include "sdl/input.h"
#include "sdl/config.h"
#include "sdl/keyscan.h"
#include "sdl/sdl-joystick.h"
#include "sdl/gui.h"
extern Config *g_config;
static GtkWidget *gamePadConfwin = NULL;
static GtkWidget *padNoCombo = NULL;
static GtkWidget *devSelCombo = NULL;
static GtkWidget *mapProfCombo = NULL;
static GtkWidget *buttonMappings[GAMEPAD_NUM_BUTTONS] = { NULL };
static GtkWidget *buttonState[GAMEPAD_NUM_BUTTONS] = { NULL };
static GtkWidget *guidLbl = NULL;
static GtkWidget *msgLbl = NULL;
static int buttonConfigStatus = 0;
static int padNo = 0;
static int numProfiles = 0;
struct GamePadConfigLocalData_t
{
std::string guid;
std::string profile;
struct {
char needsSave;
} btn[GAMEPAD_NUM_BUTTONS];
GamePadConfigLocalData_t(void)
{
for (int i=0; i<GAMEPAD_NUM_BUTTONS; i++)
{
btn[i].needsSave = 0;
}
}
};
static GamePadConfigLocalData_t lcl[GAMEPAD_NUM_DEVICES];
static int getDeviceIndex( void )
{
int devIdx = -1;
const char *s;
s = gtk_combo_box_text_get_active_text ( GTK_COMBO_BOX_TEXT(devSelCombo) );
if ( s && isdigit( s[0] ) )
{
devIdx = atoi( s );
}
return devIdx;
}
static void updateCntrlrDpy(void)
{
int i;
char strBuf[128];
if ( (padNoCombo == NULL) )
{
return;
}
for (i = 0; i < GAMEPAD_NUM_BUTTONS; i++)
{
GtkWidget *mappedKey = buttonMappings[i];
if (GamePad[padNo].bmap[i].ButtType == BUTTC_KEYBOARD)
{
snprintf (strBuf, sizeof (strBuf), "<tt>%s</tt>",
SDL_GetKeyName (GamePad[padNo].bmap[i].
ButtonNum));
}
else
sprintf (strBuf, "<tt>%s</tt>", ButtonName( &GamePad[padNo].bmap[i] ) );
if ( mappedKey != NULL )
{
gtk_label_set_text (GTK_LABEL (mappedKey), strBuf);
gtk_label_set_use_markup (GTK_LABEL (mappedKey), TRUE);
}
}
}
static void loadMapList(void)
{
const char *baseDir = FCEUI_GetBaseDirectory();
const char *guid;
std::string path;
std::string prefix, mapName;
int devIdx = -1;
jsDev_t *js;
size_t i,n=0;
char stmp[256];
struct dirent *d;
DIR *dir;
devIdx = getDeviceIndex();
if ( devIdx < 0 )
{
guid = "keyboard";
}
else
{
js = getJoystickDevice( devIdx );
guid = js->getGUID();
}
if ( guid == NULL )
{
return;
}
path = std::string(baseDir) + "/input/" + std::string(guid);
sprintf( stmp, "SDL.Input.GamePad.%i.", padNo );
prefix = stmp;
g_config->getOption(prefix + "Profile", &mapName );
gtk_combo_box_text_remove_all( GTK_COMBO_BOX_TEXT(mapProfCombo) );
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (mapProfCombo), "default");
gtk_combo_box_set_active (GTK_COMBO_BOX (mapProfCombo), 0);
numProfiles = n = 1;
dir = ::opendir( path.c_str() );
if ( dir == NULL ) return;
d = ::readdir( dir );
while ( d != NULL )
{
i=0;
while ( d->d_name[i] != 0 )
{
if ( d->d_name[i] == '.' )
{
break;
}
stmp[i] = d->d_name[i]; i++;
}
stmp[i] = 0;
//printf("Directory: '%s'\n", stmp );
if ( i > 0 )
{
if ( strcmp( stmp, "default" ) != 0 )
{
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (mapProfCombo), stmp);
if ( mapName.compare(stmp) == 0 )
{
gtk_combo_box_set_active (GTK_COMBO_BOX (mapProfCombo), n);
}
n++;
}
}
d = ::readdir( dir );
}
numProfiles = n;
::closedir( dir );
}
static void selPortChanged( GtkWidget * w, gpointer p )
{
const char *txt;
txt = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT (padNoCombo));
if ( txt == NULL )
{
return;
}
padNo = atoi(txt) - 1;
GtkTreeModel *treeModel = gtk_combo_box_get_model( GTK_COMBO_BOX (devSelCombo) );
GtkTreeIter iter;
gboolean iterValid;
iterValid = gtk_tree_model_get_iter_first( treeModel, &iter );
while ( iterValid )
{
GValue value;
memset( &value, 0, sizeof(value));
gtk_tree_model_get_value (treeModel, &iter, 0, &value );
if ( G_IS_VALUE(&value) )
{
if ( G_VALUE_TYPE(&value) == G_TYPE_STRING )
{
int devIdx = -1;
const char *s = (const char *)g_value_peek_pointer( &value );
if ( isdigit( s[0] ) )
{
devIdx = atoi(s);
}
if ( (devIdx >= 0) && (devIdx == GamePad[padNo].getDeviceIndex() ) )
{
gtk_combo_box_set_active_iter (GTK_COMBO_BOX (devSelCombo), &iter);
}
}
}
g_value_unset(&value);
iterValid = gtk_tree_model_iter_next( treeModel, &iter );
}
gtk_label_set_text( GTK_LABEL(guidLbl), GamePad[padNo].getGUID() );
loadMapList();
updateCntrlrDpy();
}
static void selInputDevice (GtkWidget * w, gpointer p)
{
//std::string s = "SDL.Input.";
int devIdx = -1;
jsDev_t *js;
if ( (padNoCombo == NULL) )
{
return;
}
devIdx = getDeviceIndex();
js = getJoystickDevice( devIdx );
if ( js != NULL )
{
if ( js->isConnected() )
{
gtk_label_set_text( GTK_LABEL(guidLbl), js->getGUID() );
}
}
else
{
gtk_label_set_text( GTK_LABEL(guidLbl), "keyboard" );
}
GamePad[padNo].setDeviceIndex( devIdx );
lcl[padNo].guid.assign( GamePad[padNo].getGUID() );
lcl[padNo].profile.assign("default");
loadMapList();
updateCntrlrDpy();
return;
}
static void saveConfig(void)
{
int i;
char stmp[256];
const char *txt;
std::string prefix, mapName;
sprintf( stmp, "SDL.Input.GamePad.%i.", padNo );
prefix = stmp;
txt = gtk_combo_box_text_get_active_text( GTK_COMBO_BOX_TEXT(mapProfCombo) );
if ( txt == NULL )
{
return;
}
mapName.assign( txt );
g_config->setOption(prefix + "DeviceGUID", GamePad[padNo].getGUID() );
g_config->setOption(prefix + "Profile" , mapName.c_str() );
for (i=0; i<GAMEPAD_NUM_BUTTONS; i++)
{
lcl[padNo].btn[i].needsSave = 0;
}
g_config->save();
}
static void createNewProfile( const char *name )
{
char stmp[256];
//printf("Creating: %s \n", name );
GamePad[padNo].createProfile(name);
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (mapProfCombo), name);
numProfiles++;
gtk_combo_box_set_active( GTK_COMBO_BOX (mapProfCombo), numProfiles - 1 );
saveConfig();
sprintf( stmp, "Mapping Created: %s/%s \n", GamePad[padNo].getGUID(), name );
gtk_label_set_text( GTK_LABEL(msgLbl), stmp );
loadMapList();
}
static void loadProfileCB (GtkButton * button, gpointer p)
{
char stmp[256];
int devIdx, ret;
std::string mapName;
const char *txt;
devIdx = getDeviceIndex();
txt = gtk_combo_box_text_get_active_text( GTK_COMBO_BOX_TEXT(mapProfCombo) );
if ( txt == NULL )
{
return;
}
mapName.assign( txt );
GamePad[padNo].setDeviceIndex( devIdx );
if ( mapName.compare("default") == 0 )
{
ret = GamePad[padNo].loadDefaults();
}
else
{
ret = GamePad[padNo].loadProfile( mapName.c_str() );
}
if ( ret == 0 )
{
saveConfig();
sprintf( stmp, "Mapping Loaded: %s/%s \n", GamePad[padNo].getGUID(), mapName.c_str() );
}
else
{
sprintf( stmp, "Error: Failed to Load Mapping: %s/%s \n", GamePad[padNo].getGUID(), mapName.c_str() );
}
gtk_label_set_text( GTK_LABEL(msgLbl), stmp );
updateCntrlrDpy();
}
static void saveProfileCB (GtkButton * button, gpointer p)
{
int ret;
std::string mapName;
char stmp[256];
const char *txt;
txt = gtk_combo_box_text_get_active_text( GTK_COMBO_BOX_TEXT(mapProfCombo) );
if ( txt == NULL )
{
return;
}
mapName.assign( txt );
ret = GamePad[padNo].saveCurrentMapToFile( mapName.c_str() );
if ( ret == 0 )
{
saveConfig();
sprintf( stmp, "Mapping Saved: %s/%s \n", GamePad[padNo].getGUID(), mapName.c_str() );
}
else
{
sprintf( stmp, "Error: Failed to Save Mapping: %s \n", mapName.c_str() );
}
gtk_label_set_text( GTK_LABEL(msgLbl), stmp );
}
static void newProfileCB (GtkButton * button, gpointer p)
{
int ret;
GtkWidget *vbox, *lbl, *entry;
GtkWidget *dialog
= gtk_dialog_new_with_buttons ("New Profile", GTK_WINDOW(gamePadConfwin),
(GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
"_Cancel", GTK_RESPONSE_CANCEL, "_Create", GTK_RESPONSE_ACCEPT, NULL );
vbox = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
gtk_box_set_homogeneous (GTK_BOX (vbox), FALSE);
lbl = gtk_label_new("Specify New Profile Name");
entry = gtk_entry_new();
gtk_box_pack_start (GTK_BOX (vbox), lbl, TRUE, TRUE, 5);
gtk_box_pack_start (GTK_BOX (vbox), entry, TRUE, TRUE, 5);
gtk_widget_show_all( dialog );
ret = gtk_dialog_run( GTK_DIALOG(dialog) );
if ( ret == GTK_RESPONSE_ACCEPT )
{
printf("Text: '%s'\n", gtk_entry_get_text( GTK_ENTRY(entry) ) );
createNewProfile( gtk_entry_get_text( GTK_ENTRY(entry) ) );
}
gtk_widget_destroy( dialog );
}
static void deleteProfileCB (GtkButton * button, gpointer p)
{
int ret;
std::string mapName;
char stmp[256];
const char *txt;
txt = gtk_combo_box_text_get_active_text( GTK_COMBO_BOX_TEXT(mapProfCombo) );
if ( txt == NULL )
{
return;
}
mapName.assign( txt );
ret = GamePad[padNo].deleteMapping( mapName.c_str() );
if ( ret == 0 )
{
sprintf( stmp, "Mapping Deleted: %s/%s \n", GamePad[padNo].getGUID(), mapName.c_str() );
}
else
{
sprintf( stmp, "Error: Failed to Delete Mapping: %s \n", mapName.c_str() );
}
gtk_label_set_text( GTK_LABEL(msgLbl), stmp );
loadMapList();
}
// This function configures a single button on a gamepad
static void clearGamepadButton (GtkButton * button, gpointer p)
{
long int x = (long int)p;
GamePad[padNo].bmap[x].ButtonNum = -1;
gtk_label_set_text (GTK_LABEL (buttonMappings[x]), "");
lcl[padNo].btn[x].needsSave = 1;
updateCntrlrDpy();
}
// This function configures a single button on a gamepad
static void configGamepadButton (GtkButton * button, gpointer p)
{
gint x = ((gint) (glong) (p));
//gint x = GPOINTER_TO_INT(p);
char buf[256];
std::string prefix;
// only configure when the "Change" button is pressed in, not when it is unpressed
if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
return;
gtk_button_set_label (GTK_BUTTON (button), "Waiting");
buttonConfigStatus = 2;
ButtonConfigBegin ();
snprintf (buf, sizeof(buf)-1, "SDL.Input.GamePad.%d.", padNo);
prefix = buf;
DWaitButton (NULL, &GamePad[padNo].bmap[x], &buttonConfigStatus );
// g_config->setOption (prefix + GamePadNames[x],
// GamePadConfig[padNo][x].ButtonNum[configNo]);
//
// if (GamePadConfig[padNo][x].ButtType[0] == BUTTC_KEYBOARD)
// {
// g_config->setOption (prefix + "DeviceType", "Keyboard");
// }
// else if (GamePadConfig[padNo][x].ButtType[0] == BUTTC_JOYSTICK)
// {
// g_config->setOption (prefix + "DeviceType", "Joystick");
// }
// else
// {
// g_config->setOption (prefix + "DeviceType", "Unknown");
// }
// g_config->setOption (prefix + "DeviceNum",
// GamePadConfig[padNo][x].DeviceNum[configNo]);
snprintf (buf, sizeof (buf), "<tt>%s</tt>",
ButtonName (&GamePad[padNo].bmap[x]));
if ( buttonMappings[x] != NULL )
{
gtk_label_set_markup (GTK_LABEL (buttonMappings[x]), buf);
}
lcl[padNo].btn[x].needsSave = 1;
ButtonConfigEnd ();
buttonConfigStatus = 1;
gtk_button_set_label (GTK_BUTTON (button), "Change");
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
return;
}
//static void updateGamepadConfig (GtkWidget * w, gpointer p)
//{
// updateCntrlrDpy();
//}
static gint timeout_callback (gpointer data)
{
if ( gamePadConfwin == NULL )
{
return FALSE;
}
for (int i=0; i<GAMEPAD_NUM_BUTTONS; i++)
{
const char *txt;
if ( GamePad[padNo].bmap[i].state )
{
txt = "<b><span background='green' foreground='white'> T </span></b>";
}
else
{
txt = "<b><span background='red' foreground='white'> F </span></b>";
}
gtk_label_set_markup( GTK_LABEL( buttonState[i] ), txt );
//if ( lcl[portNum].btn[i].needsSave )
//{
// keyName[i]->setStyleSheet("color: red;");
//}
//else
//{
// keyName[i]->setStyleSheet("color: black;");
//}
}
return TRUE;
}
static void closeGamepadConfig (GtkWidget * w, GdkEvent * e, gpointer p)
{
gtk_widget_destroy (w);
gamePadConfwin = NULL;
padNoCombo = NULL;
for (int i = 0; i < GAMEPAD_NUM_BUTTONS; i++)
{
buttonMappings[i] = NULL;
buttonState[i] = NULL;
}
buttonConfigStatus = 0;
}
void openGamepadConfig (void)
{
GtkWidget *win;
GtkWidget *mainVbox;
GtkWidget *hbox, /* *vbox,*/ *lbl;
GtkWidget *hboxPadNo;
GtkWidget *padNoLabel;
GtkWidget* devSelLabel, *devSelHbox;
GtkWidget *fourScoreChk;
GtkWidget *oppositeDirChk;
GtkWidget *buttonFrame;
GtkWidget *buttonTable;
GtkWidget *button;
GtkWidget *grid;
GtkWidget *mappingFrame;
char stmp[256];
if ( gamePadConfwin != NULL )
{
return;
}
// Ensure that joysticks are enabled, no harm calling init again.
InitJoysticks();
padNo = 0;
win = gtk_dialog_new_with_buttons ("Controller Configuration",
GTK_WINDOW (MainWindow),
(GtkDialogFlags)
(GTK_DIALOG_DESTROY_WITH_PARENT),
"_Close", GTK_RESPONSE_OK, NULL);
gtk_window_set_title (GTK_WINDOW (win), "Controller Configuration");
gtk_window_set_icon_name (GTK_WINDOW (win), "input-gaming");
gtk_widget_set_size_request (win, 350, 500);
mainVbox = gtk_dialog_get_content_area (GTK_DIALOG (win));
gtk_box_set_homogeneous (GTK_BOX (mainVbox), FALSE);
hboxPadNo = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_set_homogeneous( GTK_BOX(hboxPadNo), TRUE );
padNoLabel = gtk_label_new ("Port:");
//configNoLabel = gtk_label_new("Config Number:");
fourScoreChk = gtk_check_button_new_with_label ("Enable Four Score");
oppositeDirChk =
gtk_check_button_new_with_label ("Allow Up+Down / Left+Right");
//typeCombo = gtk_combo_box_text_new ();
//gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (typeCombo),
// "gamepad");
//gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (typeCombo),
// "zapper");
//gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (typeCombo),
// "powerpad.0");
//gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (typeCombo),
// "powerpad.1");
//gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (typeCombo),
// "arkanoid");
//gtk_combo_box_set_active (GTK_COMBO_BOX (typeCombo), 0);
padNoCombo = gtk_combo_box_text_new ();
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (padNoCombo), "1");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (padNoCombo), "2");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (padNoCombo), "3");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (padNoCombo), "4");
gtk_combo_box_set_active (GTK_COMBO_BOX (padNoCombo), 0);
g_signal_connect (padNoCombo, "changed",
G_CALLBACK (selPortChanged), NULL);
devSelHbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_set_homogeneous( GTK_BOX(devSelHbox), TRUE );
devSelLabel = gtk_label_new ("Device:");
devSelCombo = gtk_combo_box_text_new ();
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (devSelCombo), "Keyboard");
gtk_combo_box_set_active (GTK_COMBO_BOX (devSelCombo), 0);
for (int i=0; i<MAX_JOYSTICKS; i++)
{
jsDev_t *js = getJoystickDevice( i );
if ( js != NULL )
{
if ( js->isConnected() )
{
sprintf( stmp, "%i: %s", i, js->getName() );
gtk_combo_box_text_append_text( GTK_COMBO_BOX_TEXT (devSelCombo), stmp );
}
}
}
gtk_combo_box_set_active (GTK_COMBO_BOX (devSelCombo), 0);
{
GtkTreeModel *treeModel = gtk_combo_box_get_model( GTK_COMBO_BOX (devSelCombo) );
GtkTreeIter iter;
gboolean iterValid;
iterValid = gtk_tree_model_get_iter_first( treeModel, &iter );
while ( iterValid )
{
GValue value;
memset( &value, 0, sizeof(value));
gtk_tree_model_get_value (treeModel, &iter, 0, &value );
if ( G_IS_VALUE(&value) )
{
if ( G_VALUE_TYPE(&value) == G_TYPE_STRING )
{
int devIdx = -1;
const char *s = (const char *)g_value_peek_pointer( &value );
if ( isdigit( s[0] ) )
{
devIdx = atoi(s);
}
if ( (devIdx >= 0) && (devIdx == GamePad[padNo].getDeviceIndex() ) )
{
gtk_combo_box_set_active_iter (GTK_COMBO_BOX (devSelCombo), &iter);
}
}
}
g_value_unset(&value);
iterValid = gtk_tree_model_iter_next( treeModel, &iter );
}
}
g_signal_connect (devSelCombo, "changed", G_CALLBACK (selInputDevice), NULL );
//g_signal_connect (typeCombo, "changed", G_CALLBACK (setInputDevice),
// gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT
// (typeCombo)));
setCheckbox (fourScoreChk, "SDL.FourScore");
g_signal_connect (fourScoreChk, "clicked", G_CALLBACK (toggleOption),
(gpointer) "SDL.FourScore");
setCheckbox (oppositeDirChk, "SDL.Input.EnableOppositeDirectionals");
g_signal_connect (oppositeDirChk, "clicked", G_CALLBACK (toggleOption),
(gpointer) "SDL.Input.EnableOppositeDirectionals");
gtk_box_pack_start (GTK_BOX (hboxPadNo), padNoLabel, TRUE, TRUE, 5);
gtk_box_pack_start (GTK_BOX (hboxPadNo), padNoCombo, TRUE, TRUE, 5);
gtk_box_pack_start (GTK_BOX (mainVbox), hboxPadNo, FALSE, TRUE, 5);
//gtk_box_pack_start_defaults(GTK_BOX(mainVbox), typeCombo);
gtk_box_pack_start (GTK_BOX (devSelHbox), devSelLabel, TRUE, TRUE, 5);
gtk_box_pack_start (GTK_BOX (devSelHbox), devSelCombo, TRUE, TRUE, 5);
gtk_box_pack_start (GTK_BOX (mainVbox), devSelHbox, TRUE, TRUE, 5);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_set_homogeneous( GTK_BOX(hbox), TRUE );
lbl = gtk_label_new ("GUID:");
guidLbl = gtk_label_new ("");
gtk_box_pack_start (GTK_BOX (hbox), lbl, TRUE, TRUE, 5);
gtk_box_pack_start (GTK_BOX (hbox), guidLbl, TRUE, TRUE, 5);
gtk_box_pack_start (GTK_BOX (mainVbox), hbox, TRUE, TRUE, 5);
gtk_label_set_text( GTK_LABEL(guidLbl), GamePad[padNo].getGUID() );
mappingFrame = gtk_frame_new ("<b><i>Mapping Profile:</i></b>");
gtk_label_set_use_markup (GTK_LABEL
(gtk_frame_get_label_widget
(GTK_FRAME (mappingFrame))), TRUE);
gtk_box_pack_start (GTK_BOX (mainVbox), mappingFrame, FALSE, TRUE, 5);
grid = gtk_grid_new ();
gtk_grid_set_row_spacing (GTK_GRID (grid), 5);
gtk_grid_set_column_spacing (GTK_GRID (grid), 5);
gtk_grid_set_column_homogeneous (GTK_GRID (grid), TRUE);
//vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (mappingFrame), grid);
mapProfCombo = gtk_combo_box_text_new ();
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (mapProfCombo), "default");
gtk_combo_box_set_active (GTK_COMBO_BOX (mapProfCombo), 0);
gtk_grid_attach (GTK_GRID (grid), mapProfCombo, 0, 0, 2, 1 );
button = gtk_button_new_with_label ("Load");
gtk_grid_attach (GTK_GRID (grid), button, 0, 1, 1, 1 );
g_signal_connect (button, "clicked", G_CALLBACK (loadProfileCB), NULL );
button = gtk_button_new_with_label ("Save");
gtk_grid_attach (GTK_GRID (grid), button, 1, 1, 1, 1 );
g_signal_connect (button, "clicked", G_CALLBACK (saveProfileCB), NULL );
button = gtk_button_new_with_label ("New");
gtk_grid_attach (GTK_GRID (grid), button, 0, 2, 1, 1 );
g_signal_connect (button, "clicked", G_CALLBACK (newProfileCB), NULL );
button = gtk_button_new_with_label ("Delete");
gtk_grid_attach (GTK_GRID (grid), button, 1, 2, 1, 1 );
g_signal_connect (button, "clicked", G_CALLBACK (deleteProfileCB), NULL );
msgLbl = gtk_label_new("");
gtk_grid_attach (GTK_GRID (grid), msgLbl, 0, 3, 2, 1 );
gtk_box_pack_start (GTK_BOX (mainVbox), fourScoreChk, FALSE, TRUE, 5);
gtk_box_pack_start (GTK_BOX (mainVbox), oppositeDirChk, FALSE, TRUE, 5);
// create gamepad buttons
buttonFrame = gtk_frame_new ("<b><i>Active Button Mappings:</i></b>");
gtk_label_set_use_markup (GTK_LABEL
(gtk_frame_get_label_widget
(GTK_FRAME (buttonFrame))), TRUE);
buttonTable = gtk_grid_new ();
gtk_container_add (GTK_CONTAINER (buttonFrame), buttonTable);
for (int i = 0; i < 3; i++)
{
gtk_grid_insert_column (GTK_GRID (buttonTable), i);
}
gtk_grid_set_column_spacing (GTK_GRID (buttonTable), 5);
gtk_grid_set_column_homogeneous (GTK_GRID (buttonTable), TRUE);
gtk_grid_set_row_spacing (GTK_GRID (buttonTable), 3);
for (int i = 0; i < GAMEPAD_NUM_BUTTONS; i++)
{
GtkWidget *buttonName = gtk_label_new (GamePadNames[i]);
GtkWidget *mappedKey = gtk_label_new (NULL);
GtkWidget *changeButton = gtk_toggle_button_new ();
GtkWidget *clearButton = gtk_button_new ();
char strBuf[128];
lbl = gtk_label_new ("State:");
buttonState[i] = gtk_label_new (" F ");
gtk_grid_insert_row (GTK_GRID (buttonTable), i);
sprintf (strBuf, "%s:", GamePadNames[i]);
gtk_label_set_text (GTK_LABEL (buttonName), strBuf);
gtk_button_set_label (GTK_BUTTON (changeButton), "Change");
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (changeButton),
FALSE);
gtk_button_set_label (GTK_BUTTON (clearButton), "Clear");
gtk_grid_attach (GTK_GRID (buttonTable), buttonName, 0, i, 1, 1);
gtk_grid_attach (GTK_GRID (buttonTable), mappedKey, 1, i, 1, 1);
gtk_grid_attach (GTK_GRID (buttonTable), lbl, 2, i, 1, 1);
gtk_grid_attach (GTK_GRID (buttonTable), buttonState[i], 3, i, 1, 1);
gtk_grid_attach (GTK_GRID (buttonTable), changeButton, 4, i, 1, 1);
gtk_grid_attach (GTK_GRID (buttonTable), clearButton, 5, i, 1, 1);
g_signal_connect (changeButton, "clicked",
G_CALLBACK (configGamepadButton),
GINT_TO_POINTER (i));
g_signal_connect (clearButton, "clicked",
G_CALLBACK (clearGamepadButton),
GINT_TO_POINTER (i));
buttonMappings[i] = mappedKey;
}
gtk_box_pack_start (GTK_BOX (mainVbox), buttonFrame, TRUE, TRUE, 5);
g_signal_connect (win, "delete-event", G_CALLBACK (closeGamepadConfig), NULL);
g_signal_connect (win, "response", G_CALLBACK (closeGamepadConfig), NULL);
gtk_widget_show_all (win);
g_signal_connect (G_OBJECT (win), "key-press-event",
G_CALLBACK (convertKeypress), NULL);
g_signal_connect (G_OBJECT (win), "key-release-event",
G_CALLBACK (convertKeypress), NULL);
buttonConfigStatus = 1;
gamePadConfwin = win;
loadMapList();
// display the button mappings for the currently selected configuration
updateCntrlrDpy();
g_timeout_add ( 100, timeout_callback, NULL );
return;
}

View File

@ -0,0 +1,4 @@
// GamePadConf.h
// creates and opens the gamepad config window (GTK)
void openGamepadConfig (void);

View File

@ -102,20 +102,20 @@ LoadCPalette(const std::string &file)
static void
CreateDirs(const std::string &dir)
{
const char *subs[8]={"fcs","snaps","gameinfo","sav","cheats","movies","cfg.d"};
const char *subs[9]={"fcs","snaps","gameinfo","sav","cheats","movies","input"};
std::string subdir;
int x;
#if defined(WIN32) || defined(NEED_MINGW_HACKS)
mkdir(dir.c_str());
chmod(dir.c_str(), 755);
for(x = 0; x < 6; x++) {
for(x = 0; x < 7; x++) {
subdir = dir + PSS + subs[x];
mkdir(subdir.c_str());
}
#else
mkdir(dir.c_str(), S_IRWXU);
for(x = 0; x < 6; x++) {
for(x = 0; x < 7; x++) {
subdir = dir + PSS + subs[x];
mkdir(subdir.c_str(), S_IRWXU);
}
@ -199,6 +199,7 @@ InitConfig()
// video controls
config->addOption('f', "fullscreen", "SDL.Fullscreen", 0);
config->addOption("videoDriver", "SDL.VideoDriver", 0);
// set x/y res to 0 for automatic fullscreen resolution detection (no change)
config->addOption('x', "xres", "SDL.XResolution", 0);
@ -241,7 +242,7 @@ InitConfig()
config->addOption("input4", "SDL.Input.3", "Gamepad.3");
// allow for input configuration
config->addOption('i', "inputcfg", "SDL.InputCfg", InputCfg);
//config->addOption('i', "inputcfg", "SDL.InputCfg", InputCfg);
// display input
config->addOption("inputdisplay", "SDL.InputDisplay", 0);
@ -285,8 +286,6 @@ InitConfig()
//TODO implement this
config->addOption("periodicsaves", "SDL.PeriodicSaves", 0);
#ifdef _GTK
char* home_dir = getenv("HOME");
// prefixed with _ because they are internal (not cli options)
config->addOption("_lastopenfile", "SDL.LastOpenFile", home_dir);
@ -294,7 +293,9 @@ InitConfig()
config->addOption("_lastopennsf", "SDL.LastOpenNSF", home_dir);
config->addOption("_lastsavestateas", "SDL.LastSaveStateAs", home_dir);
config->addOption("_lastloadlua", "SDL.LastLoadLua", "");
#endif
config->addOption("_useNativeFileDialog", "SDL.UseNativeFileDialog", false);
config->addOption("_useNativeMenuBar" , "SDL.UseNativeMenuBar", false);
// fcm -> fm2 conversion
config->addOption("fcmconvert", "SDL.FCMConvert", "");
@ -316,10 +317,8 @@ InitConfig()
prefix = buf;
config->addOption(prefix + "DeviceType", DefaultGamePadDevice[i]);
config->addOption(prefix + "DeviceNum", 0);
for(unsigned int j = 0; j < GAMEPAD_NUM_BUTTONS; j++) {
config->addOption(prefix + GamePadNames[j], DefaultGamePad[i][j]);
}
config->addOption(prefix + "DeviceGUID", "");
config->addOption(prefix + "Profile" , "");
}
// PowerPad 0 - 1

View File

@ -18,6 +18,8 @@ void SilenceSound(int s); /* DOS and SDL */
int InitJoysticks(void);
int KillJoysticks(void);
int AddJoystick( int which );
int RemoveJoystick( int which );
uint32 *GetJSOr(void);
int InitVideo(FCEUGI *gi);

View File

@ -0,0 +1,4 @@
// fceux_git_info.h
const char *fceu_get_git_url(void);
const char *fceu_get_git_rev(void);

View File

@ -33,6 +33,7 @@ static GLXContext glc = NULL;
static XWindowAttributes gwa;
static XEvent xev;
static GLint double_buffer_ena = 1;
static bool isDoubleBuffered = true;
static GLuint gltexture = 0;
static int spawn_new_window = 0;
@ -89,8 +90,14 @@ static void getAttrbList( GLint *buf )
int i=0;
buf[i] = GLX_RGBA; i++;
buf[i] = GLX_DEPTH_SIZE; i++;
buf[i] = 24; i++;
//buf[i] = GLX_DEPTH_SIZE; i++;
//buf[i] = 24; i++;
buf[i] = GLX_RED_SIZE; i++;
buf[i] = 8; i++;
buf[i] = GLX_GREEN_SIZE; i++;
buf[i] = 8; i++;
buf[i] = GLX_BLUE_SIZE; i++;
buf[i] = 8; i++;
if ( double_buffer_ena )
{
@ -258,7 +265,7 @@ static void render_image(void)
//print_pixbuf();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0,
GL_RGBA, GL_UNSIGNED_BYTE, glx_shm->pixbuf );
GL_BGRA, GL_UNSIGNED_BYTE, glx_shm->pixbuf );
glBegin(GL_QUADS);
glTexCoord2f(1.0f*l/256, 1.0f*b/256); // Bottom left of picture.
@ -283,7 +290,7 @@ static void render_image(void)
//glVertex2f( 1.0f, 1.0f); // Top right of target.
//glEnd();
if ( double_buffer_ena )
if ( isDoubleBuffered )
{
glXSwapBuffers( dpy, win );
}
@ -392,6 +399,7 @@ int spawn_glxwin( int flags )
//************************************************************************
int init_gtk3_GLXContext( int flags )
{
int screenNumber;
GLint att[32];
XWindowAttributes xattrb;
@ -410,12 +418,20 @@ int init_gtk3_GLXContext( int flags )
printf("Error: Failed to obtain gdkWindow Handle for evbox widget\n");
return -1;
}
if (!GDK_IS_X11_WINDOW (gdkWin))
{
printf("Error: GDK Window is not of X11 Type\n");
return -1;
}
GdkDisplay *gdk_display = gdk_window_get_display (gdkWin);
GdkScreen *gdk_screen = gdk_window_get_screen (gdkWin);
screenNumber = gdk_x11_screen_get_screen_number (gdk_screen);
dpy = GDK_DISPLAY_XDISPLAY( gdk_display );
win = GDK_WINDOW_XID( gdkWin );
root = GDK_ROOT_WINDOW();
dpy = gdk_x11_get_default_xdisplay();
if ( dpy == NULL )
{
printf("Error: Failed to obtain X Display Handle for evbox widget\n");
@ -431,16 +447,65 @@ int init_gtk3_GLXContext( int flags )
//printf("XWinSize: (%i x %i) \n", xattrb.width, xattrb.height );
//printf("XWinDepth: %i \n", xattrb.depth );
//printf("XWinVisual: %p \n", xattrb.visual );
printf("XScreenNumber: %i \n", screenNumber );
vi = glXChooseVisual(dpy, 0, att);
vi = glXChooseVisual(dpy, screenNumber, att);
if (vi == NULL)
{
printf("\n\tno appropriate visual found\n\n");
printf("\n\tERROR: GLX No appropriate visual found\n\n");
exit(0);
}
else {
printf("\n\tvisual %p selected\n", (void *)vi->visualid); /* %p creates hexadecimal output like in glxinfo */
else
{
int val;
printf("\n\tGLX visual %p selected\n", (void *)vi->visualid); /* %p creates hexadecimal output like in glxinfo */
if ( glXGetConfig( dpy, vi, GLX_RGBA, &val ) == 0 )
{
printf("GLX_RGBA: %i \n", val );
}
if ( glXGetConfig( dpy, vi, GLX_USE_GL, &val ) == 0 )
{
printf("GLX_USE_GL: %i \n", val );
}
if ( glXGetConfig( dpy, vi, GLX_LEVEL, &val ) == 0 )
{
printf("GLX_LEVEL: %i \n", val );
}
if ( glXGetConfig( dpy, vi, GLX_BUFFER_SIZE, &val ) == 0 )
{
printf("GLX_BUFFER_SIZE: %i \n", val );
}
if ( glXGetConfig( dpy, vi, GLX_DOUBLEBUFFER, &val ) == 0 )
{
isDoubleBuffered = val ? true : false;
printf("GLX_DOUBLEBUFFER: %i \n", val );
}
if ( glXGetConfig( dpy, vi, GLX_RED_SIZE, &val ) == 0 )
{
printf("GLX_RED_SIZE: %i \n", val );
}
if ( glXGetConfig( dpy, vi, GLX_GREEN_SIZE, &val ) == 0 )
{
printf("GLX_GREEN_SIZE: %i \n", val );
}
if ( glXGetConfig( dpy, vi, GLX_BLUE_SIZE, &val ) == 0 )
{
printf("GLX_BLUE_SIZE: %i \n", val );
}
if ( glXGetConfig( dpy, vi, GLX_ALPHA_SIZE, &val ) == 0 )
{
printf("GLX_ALPHA_SIZE: %i \n", val );
}
if ( glXGetConfig( dpy, vi, GLX_DEPTH_SIZE, &val ) == 0 )
{
printf("GLX_DEPTH_SIZE: %i \n", val );
}
if ( glXGetConfig( dpy, vi, GLX_STENCIL_SIZE, &val ) == 0 )
{
printf("GLX_STENCIL_SIZE: %i \n", val );
}
}
if ( glc == NULL )
@ -449,11 +514,20 @@ int init_gtk3_GLXContext( int flags )
if ( glc == NULL )
{
printf("Error: glXCreateContext Failed\n");
printf("ERROR: glXCreateContext Failed\n");
}
else
{
printf("glXIsDirect: %i \n", glXIsDirect( dpy, glc ) );
}
}
XFree(vi); vi = NULL;
if ( glc == NULL )
{
return -1;
}
glXMakeCurrent(dpy, win, glc);
genTextures( flags & GLXWIN_PIXEL_LINEAR_FILTER ? 1 : 0 );

File diff suppressed because it is too large Load Diff

View File

@ -35,6 +35,10 @@ void pushOutputToGTK(const char* str);
void showGui(bool b);
void toggleMenuVis(void);
gint convertKeypress (GtkWidget * grab, GdkEventKey * event, gpointer user_data);
void toggleOption (GtkWidget * w, gpointer p);
void setCheckbox (GtkWidget * w, const char *configName);
bool checkGTKVersion(int major_required, int minor_required);
int configHotkey(char* hotkeyString);
@ -50,16 +54,10 @@ void openGamepadConfig();
void resizeGtkWindow();
#ifdef OPENGL
void setGl(GtkWidget* w, gpointer p);
void setDoubleBuffering(GtkWidget* w, gpointer p);
#endif
void setStateMenuItem( int i );
void openVideoConfig();
void openSoundConfig();
void quit ();
void openAbout ();
void emuReset ();
@ -90,7 +88,16 @@ int InitGTKSubsystem(int argc, char** argv);
uint32_t *getGuiPixelBuffer( int *w, int *h, int *s );
int guiPixelBufferReDraw(void);
int init_gui_video( int use_openGL );
enum videoDriver_t
{
VIDEO_NONE = -1,
VIDEO_OPENGL_GLX,
VIDEO_SDL,
VIDEO_CAIRO
};
extern enum videoDriver_t videoDriver;
int init_gui_video( videoDriver_t vd );
int destroy_gui_video( void );
void init_cairo_screen(void);
void destroy_cairo_screen(void);

View File

@ -24,8 +24,9 @@
#include "config.h"
#include "sdl-video.h"
#include "sdl.h"
#include "sdl-video.h"
#include "sdl-joystick.h"
#include "../common/cheat.h"
#include "../../movie.h"
@ -57,9 +58,10 @@ extern bool bindSavestate, frameAdvanceLagSkip, lagCounterDisplay;
/* UsrInputType[] is user-specified. CurInputType[] is current
(game loading can override user settings)
*/
static int UsrInputType[NUM_INPUT_DEVICES];
static int CurInputType[NUM_INPUT_DEVICES];
static int UsrInputType[NUM_INPUT_DEVICES] = { SI_GAMEPAD, SI_GAMEPAD, SI_NONE };
static int CurInputType[NUM_INPUT_DEVICES] = { SI_GAMEPAD, SI_GAMEPAD, SI_NONE };
static int cspec = 0;
static int buttonConfigInProgress = 0;
extern int gametype;
@ -692,19 +694,12 @@ static void KeyboardCommands (void)
// FCEUI_PowerNES();
//}
if (_keyonly (Hotkeys[HK_QUIT]))
{
if (noGui == 1)
{
CloseGame ();
}
else
{
CloseGame();
FCEUI_Kill();
SDL_Quit();
exit(0);
}
}
else
#ifdef _S9XLUA_H
if (_keyonly (Hotkeys[HK_LOAD_LUA]))
@ -957,6 +952,8 @@ UpdatePhysicalInput ()
{
SDL_Event event;
//SDL_JoystickUpdate();
// loop, handling all pending events
while (SDL_PollEvent (&event))
{
@ -985,6 +982,12 @@ UpdatePhysicalInput ()
g_keyState[ event.key.keysym.scancode ] = (event.type == SDL_KEYDOWN) ? 1 : 0;
//checkKeyBoardState( event.key.keysym.scancode );
break;
case SDL_JOYDEVICEADDED:
AddJoystick( event.jdevice.which );
break;
case SDL_JOYDEVICEREMOVED:
RemoveJoystick( event.jdevice.which );
break;
default:
break;
}
@ -993,8 +996,6 @@ UpdatePhysicalInput ()
}
static int bcpv, bcpj;
/**
* Begin configuring the buttons by placing the video and joystick
* subsystems into a well-known state. Button configuration really
@ -1002,31 +1003,11 @@ static int bcpv, bcpj;
*/
int ButtonConfigBegin ()
{
//dont shut down video subsystem if we are using gtk to prevent the sdl window from becoming detached to GTK window
// prg318 - 10-2-2011
#ifdef _GTK
int noGui;
g_config->getOption ("SDL.NoGUI", &noGui);
if (noGui == 1)
{
//SDL_QuitSubSystem (SDL_INIT_VIDEO);
bcpv = KillVideo ();
}
#else
// XXX soules - why are we doing this right before KillVideo()?
//SDL_QuitSubSystem (SDL_INIT_VIDEO);
// shut down the video and joystick subsystems
bcpv = KillVideo ();
#endif
//SDL_Surface *screen;
bcpj = KillJoysticks ();
// XXX soules - why did we shut this down?
// initialize the joystick subsystem
// initialize the joystick subsystem (if not already inited)
InitJoysticks ();
buttonConfigInProgress = 1;
return 1;
}
@ -1038,18 +1019,7 @@ int ButtonConfigBegin ()
void
ButtonConfigEnd ()
{
// shutdown the joystick and video subsystems
KillJoysticks ();
//SDL_QuitSubSystem(SDL_INIT_VIDEO);
// re-initialize joystick and video subsystems if they were active before
/*if(!bcpv) {
InitVideo(GameInfo);
} */
if (!bcpj)
{
InitJoysticks ();
}
buttonConfigInProgress = 0;
}
/**
@ -1058,48 +1028,50 @@ ButtonConfigEnd ()
static int
DTestButton (ButtConfig * bc)
{
int x;
for (x = 0; x < bc->NumC; x++)
if (bc->ButtType == BUTTC_KEYBOARD)
{
if (bc->ButtType[x] == BUTTC_KEYBOARD)
{
if (g_keyState[SDL_GetScancodeFromKey (bc->ButtonNum[x])])
if (g_keyState[SDL_GetScancodeFromKey (bc->ButtonNum)])
{
bc->state = 1;
return 1;
}
else
{
bc->state = 0;
}
else if (bc->ButtType[x] == BUTTC_JOYSTICK)
}
else if (bc->ButtType == BUTTC_JOYSTICK)
{
if (DTestButtonJoy (bc))
{
return 1;
}
}
}
return 0;
}
#define MK(x) {{BUTTC_KEYBOARD},{0},{MKK(x)},1}
#define MK2(x1,x2) {{BUTTC_KEYBOARD},{0},{MKK(x1),MKK(x2)},2}
#define MKZ() {{0},{0},{0},0}
#define MK(x) {BUTTC_KEYBOARD,0,MKK(x),0}
//#define MK2(x1,x2) {BUTTC_KEYBOARD,0,MKK(x1)}
#define MKZ() {0,0,-1,0}
#define GPZ() {MKZ(), MKZ(), MKZ(), MKZ()}
ButtConfig GamePadConfig[4][10] = {
/* Gamepad 1 */
{MK (KP_3), MK (KP_2), MK (SLASH), MK (ENTER),
MK (W), MK (Z), MK (A), MK (S), MKZ (), MKZ ()},
/* Gamepad 2 */
GPZ (),
/* Gamepad 3 */
GPZ (),
/* Gamepad 4 */
GPZ ()
};
//ButtConfig GamePadConfig[ GAMEPAD_NUM_DEVICES ][ GAMEPAD_NUM_BUTTONS ] =
//{
///* Gamepad 1 */
// {MK (KP_3), MK (KP_2), MK (SLASH), MK (ENTER),
// MK (w), MK (z), MK (a), MK (s), MKZ (), MKZ ()},
//
// /* Gamepad 2 */
// GPZ (),
//
// /* Gamepad 3 */
// GPZ (),
//
// /* Gamepad 4 */
// GPZ ()
//};
/**
* Update the status of the gamepad input devices.
@ -1131,7 +1103,7 @@ UpdateGamepad(void)
// a, b, select, start, up, down, left, right
for (x = 0; x < 8; x++)
{
if (DTestButton (&GamePadConfig[wg][x]))
if (DTestButton (&GamePad[wg].bmap[x]))
{
//printf("GamePad%i Button Hit: %i \n", wg, x );
if(opposite_dirs == 0)
@ -1169,7 +1141,7 @@ UpdateGamepad(void)
{
for (x = 0; x < 2; x++)
{
if (DTestButton (&GamePadConfig[wg][8 + x]))
if (DTestButton (&GamePad[wg].bmap[8 + x]))
{
JS |= (1 << x) << (wg << 3);
}
@ -1238,11 +1210,15 @@ static uint8 fkbkeys[0x48];
/**
* Update all of the input devices required for the active game.
*/
void FCEUD_UpdateInput ()
void FCEUD_UpdateInput(void)
{
int x;
int t = 0;
if ( buttonConfigInProgress )
{
return;
}
UpdatePhysicalInput ();
KeyboardCommands ();
@ -1356,8 +1332,8 @@ void InitInputInterface ()
{
void *InputDPtr;
int t;
int x;
int t = 0;
int x = 0;
int attrib;
memset( g_keyState, 0, sizeof(g_keyState) );
@ -1600,36 +1576,42 @@ UpdateFTrainer ()
* @param bc the NES gamepad's button config
* @param which the index of the button
*/
const char * ButtonName (const ButtConfig * bc, int which)
const char * ButtonName (const ButtConfig * bc)
{
static char name[256];
switch (bc->ButtType[which])
name[0] = 0;
if (bc->ButtonNum == -1)
{
return name;
}
switch (bc->ButtType)
{
case BUTTC_KEYBOARD:
return SDL_GetKeyName (bc->ButtonNum[which]);
return SDL_GetKeyName (bc->ButtonNum);
break;
case BUTTC_JOYSTICK:
{
int joyNum, inputNum;
const char *inputType, *inputDirection;
joyNum = bc->DeviceNum[which];
joyNum = bc->DeviceNum;
if (bc->ButtonNum[which] & 0x8000)
if (bc->ButtonNum & 0x8000)
{
inputType = "Axis";
inputNum = bc->ButtonNum[which] & 0x3FFF;
inputDirection = bc->ButtonNum[which] & 0x4000 ? "-" : "+";
inputNum = bc->ButtonNum & 0x3FFF;
inputDirection = bc->ButtonNum & 0x4000 ? "-" : "+";
}
else if (bc->ButtonNum[which] & 0x2000)
else if (bc->ButtonNum & 0x2000)
{
int inputValue;
char direction[128] = "";
inputType = "Hat";
inputNum = (bc->ButtonNum[which] >> 8) & 0x1F;
inputValue = bc->ButtonNum[which] & 0xF;
inputNum = (bc->ButtonNum >> 8) & 0x1F;
inputValue = bc->ButtonNum & 0xF;
if (inputValue & SDL_HAT_UP)
strncat (direction, "Up ", sizeof (direction)-1);
@ -1648,7 +1630,7 @@ const char * ButtonName (const ButtConfig * bc, int which)
else
{
inputType = "Button";
inputNum = bc->ButtonNum[which];
inputNum = bc->ButtonNum;
inputDirection = "";
}
sprintf( name, "js%i:%s%i%s", joyNum, inputType, inputNum, inputDirection );
@ -1663,11 +1645,12 @@ const char * ButtonName (const ButtConfig * bc, int which)
* Waits for a button input and returns the information as to which
* button was pressed. Used in button configuration.
*/
int DWaitButton (const uint8 * text, ButtConfig * bc, int wb, int *buttonConfigStatus )
int DWaitButton (const uint8_t * text, ButtConfig * bc, int *buttonConfigStatus )
{
SDL_Event event;
static int32 LastAx[64][64];
int x, y;
int timeout_ms = 10000;
if (text)
{
@ -1686,36 +1669,53 @@ int DWaitButton (const uint8 * text, ButtConfig * bc, int wb, int *buttonConfigS
}
}
// Purge all pending events, so that this next button press
// will be the one we want.
while (SDL_PollEvent (&event))
{
}
while (1)
{
int done = 0;
usleep(10000);
timeout_ms -= 10;
if ( timeout_ms <= 0 )
{
break;
}
#ifdef _GTK
while (gtk_events_pending ())
gtk_main_iteration_do (FALSE);
#endif
while (SDL_PollEvent (&event))
{
printf("Event Type: %i \n", event.type );
done++;
switch (event.type)
{
case SDL_KEYDOWN:
bc->ButtType[wb] = BUTTC_KEYBOARD;
bc->DeviceNum[wb] = 0;
bc->ButtonNum[wb] = event.key.keysym.sym;
//printf("SDL KeyDown:%i \n", event.key.keysym.sym );
bc->ButtType = BUTTC_KEYBOARD;
bc->DeviceNum = 0;
bc->ButtonNum = event.key.keysym.sym;
return (1);
case SDL_JOYBUTTONDOWN:
bc->ButtType[wb] = BUTTC_JOYSTICK;
bc->DeviceNum[wb] = event.jbutton.which;
bc->ButtonNum[wb] = event.jbutton.button;
bc->ButtType = BUTTC_JOYSTICK;
bc->DeviceNum = event.jbutton.which;
bc->ButtonNum = event.jbutton.button;
return (1);
case SDL_JOYHATMOTION:
if (event.jhat.value == SDL_HAT_CENTERED)
done--;
else
{
bc->ButtType[wb] = BUTTC_JOYSTICK;
bc->DeviceNum[wb] = event.jhat.which;
bc->ButtonNum[wb] =
bc->ButtType = BUTTC_JOYSTICK;
bc->DeviceNum = event.jhat.which;
bc->ButtonNum =
(0x2000 | ((event.jhat.hat & 0x1F) << 8) | event.
jhat.value);
return (1);
@ -1737,9 +1737,9 @@ int DWaitButton (const uint8 * text, ButtConfig * bc, int wb, int *buttonConfigS
(LastAx[event.jaxis.which][event.jaxis.axis] -
event.jaxis.value) >= 8192)
{
bc->ButtType[wb] = BUTTC_JOYSTICK;
bc->DeviceNum[wb] = event.jaxis.which;
bc->ButtonNum[wb] = (0x8000 | event.jaxis.axis |
bc->ButtType = BUTTC_JOYSTICK;
bc->DeviceNum = event.jaxis.which;
bc->ButtonNum = (0x8000 | event.jaxis.axis |
((event.jaxis.value < 0)
? 0x4000 : 0));
return (1);
@ -1776,213 +1776,206 @@ int DWaitButton (const uint8 * text, ButtConfig * bc, int wb, int *buttonConfigS
* used as input for the specified button, thus allowing up to four
* possible settings for each input button.
*/
void
ConfigButton (char *text, ButtConfig * bc)
{
uint8 buf[256];
int wc;
for (wc = 0; wc < MAXBUTTCONFIG; wc++)
{
sprintf ((char *) buf, "%s (%d)", text, wc + 1);
DWaitButton (buf, bc, wc, NULL);
if (wc &&
bc->ButtType[wc] == bc->ButtType[wc - 1] &&
bc->DeviceNum[wc] == bc->DeviceNum[wc - 1] &&
bc->ButtonNum[wc] == bc->ButtonNum[wc - 1])
{
break;
}
}
bc->NumC = wc;
}
// void
//ConfigButton (char *text, ButtConfig * bc)
//{
// uint8 buf[256];
// int wc;
//
// for (wc = 0; wc < MAXBUTTCONFIG; wc++)
// {
// sprintf ((char *) buf, "%s (%d)", text, wc + 1);
// DWaitButton (buf, bc, wc, NULL);
//
// if (wc &&
// bc->ButtType[wc] == bc->ButtType[wc - 1] &&
// bc->DeviceNum[wc] == bc->DeviceNum[wc - 1] &&
// bc->ButtonNum[wc] == bc->ButtonNum[wc - 1])
// {
// break;
// }
// }
//}
/**
* Update the button configuration for a specified device.
*/
extern Config *g_config;
void ConfigDevice (int which, int arg)
{
char buf[256];
int x;
std::string prefix;
const char *str[10] =
{ "A", "B", "SELECT", "START", "UP", "DOWN", "LEFT", "RIGHT", "Rapid A",
"Rapid B"
};
// XXX soules - set the configuration options so that later calls
// don't override these. This is a temp hack until I
// can clean up this file.
ButtonConfigBegin ();
switch (which)
{
case FCFGD_QUIZKING:
prefix = "SDL.Input.QuizKing.";
for (x = 0; x < 6; x++)
{
sprintf (buf, "Quiz King Buzzer #%d", x + 1);
ConfigButton (buf, &QuizKingButtons[x]);
g_config->setOption (prefix + QuizKingNames[x],
QuizKingButtons[x].ButtonNum[0]);
}
if (QuizKingButtons[0].ButtType[0] == BUTTC_KEYBOARD)
{
g_config->setOption (prefix + "DeviceType", "Keyboard");
}
else if (QuizKingButtons[0].ButtType[0] == BUTTC_JOYSTICK)
{
g_config->setOption (prefix + "DeviceType", "Joystick");
}
else
{
g_config->setOption (prefix + "DeviceType", "Unknown");
}
g_config->setOption (prefix + "DeviceNum",
QuizKingButtons[0].DeviceNum[0]);
break;
case FCFGD_HYPERSHOT:
prefix = "SDL.Input.HyperShot.";
for (x = 0; x < 4; x++)
{
sprintf (buf, "Hyper Shot %d: %s",
((x & 2) >> 1) + 1, (x & 1) ? "JUMP" : "RUN");
ConfigButton (buf, &HyperShotButtons[x]);
g_config->setOption (prefix + HyperShotNames[x],
HyperShotButtons[x].ButtonNum[0]);
}
if (HyperShotButtons[0].ButtType[0] == BUTTC_KEYBOARD)
{
g_config->setOption (prefix + "DeviceType", "Keyboard");
}
else if (HyperShotButtons[0].ButtType[0] == BUTTC_JOYSTICK)
{
g_config->setOption (prefix + "DeviceType", "Joystick");
}
else
{
g_config->setOption (prefix + "DeviceType", "Unknown");
}
g_config->setOption (prefix + "DeviceNum",
HyperShotButtons[0].DeviceNum[0]);
break;
case FCFGD_POWERPAD:
snprintf (buf, 256, "SDL.Input.PowerPad.%d", (arg & 1));
prefix = buf;
for (x = 0; x < 12; x++)
{
sprintf (buf, "PowerPad %d: %d", (arg & 1) + 1, x + 11);
ConfigButton (buf, &powerpadsc[arg & 1][x]);
g_config->setOption (prefix + PowerPadNames[x],
powerpadsc[arg & 1][x].ButtonNum[0]);
}
if (powerpadsc[arg & 1][0].ButtType[0] == BUTTC_KEYBOARD)
{
g_config->setOption (prefix + "DeviceType", "Keyboard");
}
else if (powerpadsc[arg & 1][0].ButtType[0] == BUTTC_JOYSTICK)
{
g_config->setOption (prefix + "DeviceType", "Joystick");
}
else
{
g_config->setOption (prefix + "DeviceType", "Unknown");
}
g_config->setOption (prefix + "DeviceNum",
powerpadsc[arg & 1][0].DeviceNum[0]);
break;
case FCFGD_GAMEPAD:
snprintf (buf, 256, "SDL.Input.GamePad.%d", arg);
prefix = buf;
for (x = 0; x < 10; x++)
{
sprintf (buf, "GamePad #%d: %s", arg + 1, str[x]);
ConfigButton (buf, &GamePadConfig[arg][x]);
g_config->setOption (prefix + GamePadNames[x],
GamePadConfig[arg][x].ButtonNum[0]);
}
if (GamePadConfig[arg][0].ButtType[0] == BUTTC_KEYBOARD)
{
g_config->setOption (prefix + "DeviceType", "Keyboard");
}
else if (GamePadConfig[arg][0].ButtType[0] == BUTTC_JOYSTICK)
{
g_config->setOption (prefix + "DeviceType", "Joystick");
}
else
{
g_config->setOption (prefix + "DeviceType", "Unknown");
}
g_config->setOption (prefix + "DeviceNum",
GamePadConfig[arg][0].DeviceNum[0]);
break;
}
ButtonConfigEnd ();
}
//void ConfigDevice (int which, int arg)
//{
// char buf[256];
// int x;
// std::string prefix;
// const char *str[10] =
// { "A", "B", "SELECT", "START", "UP", "DOWN", "LEFT", "RIGHT", "Rapid A",
// "Rapid B"
// };
//
// // XXX soules - set the configuration options so that later calls
// // don't override these. This is a temp hack until I
// // can clean up this file.
//
// ButtonConfigBegin ();
// switch (which)
// {
// case FCFGD_QUIZKING:
// prefix = "SDL.Input.QuizKing.";
// for (x = 0; x < 6; x++)
// {
// sprintf (buf, "Quiz King Buzzer #%d", x + 1);
// ConfigButton (buf, &QuizKingButtons[x]);
//
// g_config->setOption (prefix + QuizKingNames[x],
// QuizKingButtons[x].ButtonNum);
// }
//
// if (QuizKingButtons[0].ButtType == BUTTC_KEYBOARD)
// {
// g_config->setOption (prefix + "DeviceType", "Keyboard");
// }
// else if (QuizKingButtons[0].ButtType == BUTTC_JOYSTICK)
// {
// g_config->setOption (prefix + "DeviceType", "Joystick");
// }
// else
// {
// g_config->setOption (prefix + "DeviceType", "Unknown");
// }
// g_config->setOption (prefix + "DeviceNum",
// QuizKingButtons[0].DeviceNum);
// break;
// case FCFGD_HYPERSHOT:
// prefix = "SDL.Input.HyperShot.";
// for (x = 0; x < 4; x++)
// {
// sprintf (buf, "Hyper Shot %d: %s",
// ((x & 2) >> 1) + 1, (x & 1) ? "JUMP" : "RUN");
// ConfigButton (buf, &HyperShotButtons[x]);
//
// g_config->setOption (prefix + HyperShotNames[x],
// HyperShotButtons[x].ButtonNum);
// }
//
// if (HyperShotButtons[0].ButtType == BUTTC_KEYBOARD)
// {
// g_config->setOption (prefix + "DeviceType", "Keyboard");
// }
// else if (HyperShotButtons[0].ButtType == BUTTC_JOYSTICK)
// {
// g_config->setOption (prefix + "DeviceType", "Joystick");
// }
// else
// {
// g_config->setOption (prefix + "DeviceType", "Unknown");
// }
// g_config->setOption (prefix + "DeviceNum",
// HyperShotButtons[0].DeviceNum);
// break;
// case FCFGD_POWERPAD:
// snprintf (buf, 256, "SDL.Input.PowerPad.%d", (arg & 1));
// prefix = buf;
// for (x = 0; x < 12; x++)
// {
// sprintf (buf, "PowerPad %d: %d", (arg & 1) + 1, x + 11);
// ConfigButton (buf, &powerpadsc[arg & 1][x]);
//
// g_config->setOption (prefix + PowerPadNames[x],
// powerpadsc[arg & 1][x].ButtonNum);
// }
//
// if (powerpadsc[arg & 1][0].ButtType == BUTTC_KEYBOARD)
// {
// g_config->setOption (prefix + "DeviceType", "Keyboard");
// }
// else if (powerpadsc[arg & 1][0].ButtType == BUTTC_JOYSTICK)
// {
// g_config->setOption (prefix + "DeviceType", "Joystick");
// }
// else
// {
// g_config->setOption (prefix + "DeviceType", "Unknown");
// }
// g_config->setOption (prefix + "DeviceNum",
// powerpadsc[arg & 1][0].DeviceNum);
// break;
//
// case FCFGD_GAMEPAD:
// snprintf (buf, 256, "SDL.Input.GamePad.%d", arg);
// prefix = buf;
// for (x = 0; x < 10; x++)
// {
// sprintf (buf, "GamePad #%d: %s", arg + 1, str[x]);
// ConfigButton (buf, &GamePadConfig[arg][x]);
//
// g_config->setOption (prefix + GamePadNames[x],
// GamePadConfig[arg][x].ButtonNum);
// }
//
// if (GamePadConfig[arg][0].ButtType == BUTTC_KEYBOARD)
// {
// g_config->setOption (prefix + "DeviceType", "Keyboard");
// }
// else if (GamePadConfig[arg][0].ButtType == BUTTC_JOYSTICK)
// {
// g_config->setOption (prefix + "DeviceType", "Joystick");
// }
// else
// {
// g_config->setOption (prefix + "DeviceType", "Unknown");
// }
// g_config->setOption (prefix + "DeviceNum",
// GamePadConfig[arg][0].DeviceNum);
// break;
// }
//
// ButtonConfigEnd ();
//}
/**
* Update the button configuration for a device, specified by a text string.
*/
void InputCfg (const std::string & text)
{
#ifdef _GTK
// enable noGui to prevent the gtk x11 hack from executing
noGui = 1;
// this is only called at the begininng of execution; make sure the video subsystem is initialized
InitVideo (GameInfo);
#endif
if (noGui)
{
if (text.find ("gamepad") != std::string::npos)
{
int device = (text[strlen ("gamepad")] - '1');
if (device < 0 || device > 3)
{
FCEUD_PrintError
("Invalid gamepad device specified; must be one of gamepad1 through gamepad4");
exit (-1);
}
ConfigDevice (FCFGD_GAMEPAD, device);
}
else if (text.find ("powerpad") != std::string::npos)
{
int device = (text[strlen ("powerpad")] - '1');
if (device < 0 || device > 1)
{
FCEUD_PrintError
("Invalid powerpad device specified; must be powerpad1 or powerpad2");
exit (-1);
}
ConfigDevice (FCFGD_POWERPAD, device);
}
else if (text.find ("hypershot") != std::string::npos)
{
ConfigDevice (FCFGD_HYPERSHOT, 0);
}
else if (text.find ("quizking") != std::string::npos)
{
ConfigDevice (FCFGD_QUIZKING, 0);
}
}
else
printf ("Please run \"fceux --nogui\" before using --inputcfg\n");
}
//void InputCfg (const std::string & text)
//{
//
// if (noGui)
// {
// if (text.find ("gamepad") != std::string::npos)
// {
// int device = (text[strlen ("gamepad")] - '1');
// if (device < 0 || device > 3)
// {
// FCEUD_PrintError
// ("Invalid gamepad device specified; must be one of gamepad1 through gamepad4");
// exit (-1);
// }
// ConfigDevice (FCFGD_GAMEPAD, device);
// }
// else if (text.find ("powerpad") != std::string::npos)
// {
// int device = (text[strlen ("powerpad")] - '1');
// if (device < 0 || device > 1)
// {
// FCEUD_PrintError
// ("Invalid powerpad device specified; must be powerpad1 or powerpad2");
// exit (-1);
// }
// ConfigDevice (FCFGD_POWERPAD, device);
// }
// else if (text.find ("hypershot") != std::string::npos)
// {
// ConfigDevice (FCFGD_HYPERSHOT, 0);
// }
// else if (text.find ("quizking") != std::string::npos)
// {
// ConfigDevice (FCFGD_QUIZKING, 0);
// }
// }
// else
// printf ("Please run \"fceux --nogui\" before using --inputcfg\n");
//
//}
/**
@ -1994,7 +1987,9 @@ void InputCfg (const std::string & text)
UpdateInput (Config * config)
{
char buf[64];
std::string device, prefix;
std::string device, prefix, guid, mapping;
InitJoysticks();
for (unsigned int i = 0; i < 3; i++)
{
@ -2088,36 +2083,17 @@ UpdateInput (Config * config)
prefix = buf;
config->getOption (prefix + "DeviceType", &device );
if (device.find ("Keyboard") != std::string::npos)
{
type = BUTTC_KEYBOARD;
}
else if (device.find ("Joystick") != std::string::npos)
{
type = BUTTC_JOYSTICK;
}
else
{
type = 0;
}
config->getOption (prefix + "DeviceGUID", &guid );
config->getOption (prefix + "Profile" , &mapping);
config->getOption (prefix + "DeviceNum", &devnum);
for (unsigned int j = 0; j < GAMEPAD_NUM_BUTTONS; j++)
{
config->getOption (prefix + GamePadNames[j], &button);
GamePadConfig[i][j].ButtType[0] = type;
GamePadConfig[i][j].DeviceNum[0] = devnum;
GamePadConfig[i][j].ButtonNum[0] = button;
GamePadConfig[i][j].NumC = 1;
}
GamePad[i].init( i, guid.c_str(), mapping.c_str() );
}
// PowerPad 0 - 1
for (unsigned int i = 0; i < POWERPAD_NUM_DEVICES; i++)
{
char buf[64];
snprintf (buf, 32, "SDL.Input.PowerPad.%u.", i);
snprintf (buf, sizeof(buf)-1, "SDL.Input.PowerPad.%u.", i);
prefix = buf;
config->getOption (prefix + "DeviceType", &device);
@ -2139,10 +2115,9 @@ UpdateInput (Config * config)
{
config->getOption (prefix + PowerPadNames[j], &button);
powerpadsc[i][j].ButtType[0] = type;
powerpadsc[i][j].DeviceNum[0] = devnum;
powerpadsc[i][j].ButtonNum[0] = button;
powerpadsc[i][j].NumC = 1;
powerpadsc[i][j].ButtType = type;
powerpadsc[i][j].DeviceNum = devnum;
powerpadsc[i][j].ButtonNum = button;
}
}
@ -2166,10 +2141,9 @@ UpdateInput (Config * config)
{
config->getOption (prefix + QuizKingNames[j], &button);
QuizKingButtons[j].ButtType[0] = type;
QuizKingButtons[j].DeviceNum[0] = devnum;
QuizKingButtons[j].ButtonNum[0] = button;
QuizKingButtons[j].NumC = 1;
QuizKingButtons[j].ButtType = type;
QuizKingButtons[j].DeviceNum = devnum;
QuizKingButtons[j].ButtonNum = button;
}
// HyperShot
@ -2192,10 +2166,9 @@ UpdateInput (Config * config)
{
config->getOption (prefix + HyperShotNames[j], &button);
HyperShotButtons[j].ButtType[0] = type;
HyperShotButtons[j].DeviceNum[0] = devnum;
HyperShotButtons[j].ButtonNum[0] = button;
HyperShotButtons[j].NumC = 1;
HyperShotButtons[j].ButtType = type;
HyperShotButtons[j].DeviceNum = devnum;
HyperShotButtons[j].ButtonNum = button;
}
// Mahjong
@ -2218,10 +2191,9 @@ UpdateInput (Config * config)
{
config->getOption (prefix + MahjongNames[j], &button);
MahjongButtons[j].ButtType[0] = type;
MahjongButtons[j].DeviceNum[0] = devnum;
MahjongButtons[j].ButtonNum[0] = button;
MahjongButtons[j].NumC = 1;
MahjongButtons[j].ButtType = type;
MahjongButtons[j].DeviceNum = devnum;
MahjongButtons[j].ButtonNum = button;
}
// TopRider
@ -2244,10 +2216,9 @@ UpdateInput (Config * config)
{
config->getOption (prefix + TopRiderNames[j], &button);
TopRiderButtons[j].ButtType[0] = type;
TopRiderButtons[j].DeviceNum[0] = devnum;
TopRiderButtons[j].ButtonNum[0] = button;
TopRiderButtons[j].NumC = 1;
TopRiderButtons[j].ButtType = type;
TopRiderButtons[j].DeviceNum = devnum;
TopRiderButtons[j].ButtonNum = button;
}
// FTrainer
@ -2270,10 +2241,9 @@ UpdateInput (Config * config)
{
config->getOption (prefix + FTrainerNames[j], &button);
FTrainerButtons[j].ButtType[0] = type;
FTrainerButtons[j].DeviceNum[0] = devnum;
FTrainerButtons[j].ButtonNum[0] = button;
FTrainerButtons[j].NumC = 1;
FTrainerButtons[j].ButtType = type;
FTrainerButtons[j].DeviceNum = devnum;
FTrainerButtons[j].ButtonNum = button;
}
// FamilyKeyBoard
@ -2296,10 +2266,9 @@ UpdateInput (Config * config)
{
config->getOption (prefix + FamilyKeyBoardNames[j], &button);
fkbmap[j].ButtType[0] = type;
fkbmap[j].DeviceNum[0] = devnum;
fkbmap[j].ButtonNum[0] = button;
fkbmap[j].NumC = 1;
fkbmap[j].ButtType = type;
fkbmap[j].DeviceNum = devnum;
fkbmap[j].ButtonNum = button;
}
}
@ -2311,11 +2280,11 @@ const char *GamePadNames[GAMEPAD_NUM_BUTTONS] = { "A", "B", "Select", "Start",
const char *DefaultGamePadDevice[GAMEPAD_NUM_DEVICES] =
{ "Keyboard", "None", "None", "None" };
const int DefaultGamePad[GAMEPAD_NUM_DEVICES][GAMEPAD_NUM_BUTTONS] =
{ {SDLK_F, SDLK_D, SDLK_S, SDLK_RETURN,
SDLK_UP, SDLK_DOWN, SDLK_LEFT, SDLK_RIGHT, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
{ {SDLK_f, SDLK_d, SDLK_s, SDLK_RETURN,
SDLK_UP, SDLK_DOWN, SDLK_LEFT, SDLK_RIGHT, -1, -1},
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
};
// PowerPad defaults

View File

@ -1,34 +1,39 @@
#ifndef _aosdfjk02fmasf
#define _aosdfjk02fmasf
#include "../common/configSys.h"
#include <stdint.h>
#define MAXBUTTCONFIG 4
typedef struct {
uint8 ButtType[MAXBUTTCONFIG];
uint8 DeviceNum[MAXBUTTCONFIG];
//uint16 ButtonNum[MAXBUTTCONFIG];
int ButtonNum[MAXBUTTCONFIG];
uint32 NumC;
#include "common/configSys.h"
//#define MAXBUTTCONFIG 4
enum {
BUTTC_KEYBOARD = 0,
BUTTC_JOYSTICK = 1,
BUTTC_MOUSE = 2
};
struct ButtConfig
{
int ButtType; //[MAXBUTTCONFIG];
int DeviceNum; //[MAXBUTTCONFIG];
int ButtonNum; //[MAXBUTTCONFIG];
int state;
//uint32_t NumC;
//uint64 DeviceID[MAXBUTTCONFIG]; /* TODO */
} ButtConfig;
};
extern int NoWaiting;
extern CFGSTRUCT InputConfig[];
extern ARGPSTRUCT InputArgs[];
extern int Hotkeys[];
void ParseGIInput(FCEUGI *GI);
void setHotKeys();
void setHotKeys(void);
int getKeyState( int k );
int ButtonConfigBegin();
void ButtonConfigEnd();
void ConfigButton(char *text, ButtConfig *bc);
int DWaitButton(const uint8 *text, ButtConfig *bc, int wb, int *buttonConfigStatus = NULL);
int DWaitButton(const uint8_t *text, ButtConfig *bc, int *buttonConfigStatus = NULL);
#define BUTTC_KEYBOARD 0x00
#define BUTTC_JOYSTICK 0x01
#define BUTTC_MOUSE 0x02
#define FCFGD_GAMEPAD 1
#define FCFGD_POWERPAD 2
@ -41,7 +46,7 @@ void InitInputInterface(void);
void InputUserActiveFix(void);
extern bool replaceP2StartWithMicrophone;
extern ButtConfig GamePadConfig[4][10];
//extern ButtConfig GamePadConfig[4][10];
//extern ButtConfig powerpadsc[2][12];
//extern ButtConfig QuizKingButtons[6];
//extern ButtConfig FTrainerButtons[12];
@ -54,9 +59,9 @@ int DTestButtonJoy(ButtConfig *bc);
void FCEUD_UpdateInput(void);
void UpdateInput(Config *config);
void InputCfg(const std::string &);
//void InputCfg(const std::string &);
std::string GetUserText(const char* title);
const char* ButtonName(const ButtConfig* bc, int which);
const char* ButtonName(const ButtConfig* bc);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,92 @@
// sdl-joystick.h
#ifndef __SDL_JOYSTICK_H__
#define __SDL_JOYSTICK_H__
#include <string>
#include "sdl/main.h"
#include "sdl/input.h"
#include "sdl/sdl.h"
#define MAX_JOYSTICKS 32
struct nesGamePadMap_t
{
char guid[64];
char name[128];
char btn[GAMEPAD_NUM_BUTTONS][32];
char os[64];
nesGamePadMap_t(void);
~nesGamePadMap_t(void);
void clearMapping(void);
int parseMapping( const char *text );
};
struct jsDev_t
{
SDL_Joystick *js;
SDL_GameController *gc;
jsDev_t(void);
//~jsDev_t(void);
void init( int idx );
int close(void);
SDL_Joystick *getJS(void);
bool isGameController(void);
bool isConnected(void);
void print(void);
int bindPort( int idx );
int unbindPort( int idx );
int getBindPorts(void);
const char *getName(void);
const char *getGUID(void);
private:
int devIdx;
int portBindMask;
std::string guidStr;
std::string name;
};
class GamePad_t
{
public:
ButtConfig bmap[GAMEPAD_NUM_BUTTONS];
GamePad_t(void);
~GamePad_t(void);
int init( int port, const char *guid, const char *profile = NULL );
const char *getGUID(void);
int loadDefaults(void);
int loadProfile( const char *name, const char *guid = NULL );
int getDeviceIndex(void){ return devIdx; }
int setDeviceIndex( int devIdx );
int setMapping( const char *map );
int setMapping( nesGamePadMap_t *map );
int createProfile( const char *name );
int getMapFromFile( const char *filename, char *out );
int getDefaultMap( char *out, const char *guid = NULL );
int saveMappingToFile( const char *filename, const char *txtMap );
int saveCurrentMapToFile( const char *filename );
int deleteMapping( const char *name );
private:
int devIdx;
int portNum;
};
extern GamePad_t GamePad[4];
jsDev_t *getJoystickDevice( int devNum );
#endif

View File

@ -49,16 +49,21 @@ fillaudio(void *udata,
uint8 *stream,
int len)
{
static int16_t sample = 0;
int16 *tmps = (int16*)stream;
len >>= 1;
while(len) {
int16 sample = 0;
if(s_BufferIn) {
while (len)
{
if (s_BufferIn)
{
sample = s_Buffer[s_BufferRead];
s_BufferRead = (s_BufferRead + 1) % s_BufferSize;
s_BufferIn--;
} else {
sample = 0;
// Retain last known sample value, helps avoid clicking
// noise when sound system is starved of audio data.
//sample = 0;
//bufStarveDetected = 1;
}
*tmps = sample;
@ -179,11 +184,20 @@ WriteSound(int32 *buf,
{
extern int EmulationPaused;
if (EmulationPaused == 0)
{
int waitCount = 0;
while(Count)
{
while(s_BufferIn == s_BufferSize)
{
SDL_Delay(1);
SDL_Delay(1); waitCount++;
if ( waitCount > 1000 )
{
printf("Error: Sound sink is not draining... Breaking out of audio loop to prevent lockup.\n");
return;
}
}
s_Buffer[s_BufferWrite] = *buf;
@ -197,6 +211,7 @@ WriteSound(int32 *buf,
buf++;
}
}
}
/**
* Pause (1) or unpause (0) the audio output.

View File

@ -51,6 +51,10 @@
#include <cstring>
#include <cstdlib>
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define LSB_FIRST
#endif
// GLOBALS
extern Config *g_config;
@ -79,6 +83,13 @@ extern bool MaxSpeed;
extern unsigned int gtk_draw_area_width;
extern unsigned int gtk_draw_area_height;
static int sdl_win_width = 0;
static int sdl_win_height = 0;
static SDL_Window *sdlWindow = NULL;
static SDL_Renderer *sdlRenderer = NULL;
static SDL_Texture *sdlTexture = NULL;
/**
* Attempts to destroy the graphical video display. Returns 0 on
* success, -1 on failure.
@ -148,6 +159,7 @@ void FCEUD_VideoChanged()
int InitVideo(FCEUGI *gi)
{
int vdSel;
int doublebuf, xstretch, ystretch, xres, yres, show_fps;
FCEUI_printf("Initializing video...");
@ -180,7 +192,9 @@ int InitVideo(FCEUGI *gi)
FCEUI_GetCurrentVidSystem(&s_srendline, &s_erendline);
s_tlines = s_erendline - s_srendline + 1;
init_gui_video( s_useOpenGL );
g_config->getOption("SDL.VideoDriver", &vdSel);
init_gui_video( (videoDriver_t)vdSel );
s_inited = 1;
@ -188,9 +202,9 @@ int InitVideo(FCEUGI *gi)
FCEUI_SetShowFPS(show_fps);
#ifdef LSB_FIRST
rmask = 0x000000FF;
rmask = 0x00FF0000;
gmask = 0x0000FF00;
bmask = 0x00FF0000;
bmask = 0x000000FF;
#else
rmask = 0x00FF0000;
gmask = 0x0000FF00;
@ -210,24 +224,6 @@ int InitVideo(FCEUGI *gi)
return -1;
}
#ifdef OPENGL
if(s_exs <= 0.01) {
FCEUD_PrintError("xscale out of bounds.");
KillVideo();
return -1;
}
if(s_eys <= 0.01) {
FCEUD_PrintError("yscale out of bounds.");
KillVideo();
return -1;
}
if(s_sponge && s_useOpenGL) {
FCEUD_PrintError("scalers not compatible with openGL mode.");
KillVideo();
return -1;
}
#endif
if ( !initBlitToHighDone )
{
InitBlitToHigh(s_curbpp >> 3,
@ -467,3 +463,176 @@ void FCEUI_SetAviDisableMovieMessages(bool disable)
{
disableMovieMessages = disable;
}
//*****************************************************************************
int init_gtk3_sdl_video( void )
{
GdkWindow *gdkWin = gtk_widget_get_window(evbox);
Window win;
int sdlRendW, sdlRendH;
int vsyncEnabled=0;
if ( (gtk_draw_area_width < GLX_NES_WIDTH) || (gtk_draw_area_height < GLX_NES_HEIGHT) )
{
usleep(100000);
return -1;
}
if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0)
{
printf("[SDL] Failed to initialize video subsystem.\n");
return -1;
}
else
{
printf("Initialized SDL Video Subsystem\n");
}
if ( gdkWin == NULL )
{
printf("Error: Failed to obtain gdkWindow Handle for evbox widget\n");
return -1;
}
win = GDK_WINDOW_XID( gdkWin );
for (int i=0; i<SDL_GetNumVideoDrivers(); i++)
{
printf("SDL Video Driver %i: %s\n", i, SDL_GetVideoDriver(i) );
}
printf("Using Video Driver: %s \n", SDL_GetCurrentVideoDriver() );
sdlWindow = SDL_CreateWindowFrom( (void*)win);
if (sdlWindow == NULL)
{
printf("[SDL] Failed to create window from handle.\n");
return -1;
}
uint32_t baseFlags = vsyncEnabled ? SDL_RENDERER_PRESENTVSYNC : 0;
sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, baseFlags | SDL_RENDERER_ACCELERATED);
if (sdlRenderer == NULL)
{
printf("[SDL] Failed to create accelerated renderer.\n");
printf("[SDL] Attempting to create software renderer...\n");
sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, baseFlags | SDL_RENDERER_SOFTWARE);
if (sdlRenderer == NULL)
{
printf("[SDL] Failed to create software renderer.\n");
return -1;
}
}
SDL_GetRendererOutputSize( sdlRenderer, &sdlRendW, &sdlRendH );
printf("[SDL] Renderer Output Size: %i x %i \n", sdlRendW, sdlRendH );
sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, GLX_NES_WIDTH, GLX_NES_HEIGHT);
if (sdlTexture == NULL)
{
printf("[SDL] Failed to create texture: %i x %i", GLX_NES_WIDTH, GLX_NES_HEIGHT );
return -1;
}
sdl_win_width = sdlRendW;
sdl_win_height = sdlRendH;
return 0;
}
//*****************************************************************************
int destroy_gtk3_sdl_video(void)
{
if (sdlTexture)
{
printf("Destroying SDL Texture...\n");
SDL_DestroyTexture(sdlTexture);
sdlTexture = NULL;
}
if (sdlRenderer)
{
printf("Destroying SDL Renderer...\n");
SDL_DestroyRenderer(sdlRenderer);
sdlRenderer = NULL;
}
//SDL_QuitSubSystem(SDL_INIT_VIDEO);
return 0;
}
//*****************************************************************************
int gtk3_sdl_resize(void)
{
destroy_gtk3_sdl_video();
init_gtk3_sdl_video();
return 0;
}
//*****************************************************************************
int gtk3_sdl_render(void)
{
int sx, sy, rw, rh;
int nesWidth = GLX_NES_WIDTH;
int nesHeight = GLX_NES_HEIGHT;
if ( (sdl_win_width != gtk_draw_area_width) || (sdl_win_height != gtk_draw_area_height) )
{
gtk3_sdl_resize();
}
if ( glx_shm != NULL )
{
nesWidth = glx_shm->ncol;
nesHeight = glx_shm->nrow;
}
//printf(" %i x %i \n", nesWidth, nesHeight );
float xscale = (float)gtk_draw_area_width / (float)nesWidth;
float yscale = (float)gtk_draw_area_height / (float)nesHeight;
if (xscale < yscale )
{
yscale = xscale;
}
else
{
xscale = yscale;
}
rw=(int)(nesWidth*xscale);
rh=(int)(nesHeight*yscale);
//sx=sdlViewport.x + (view_width-rw)/2;
//sy=sdlViewport.y + (view_height-rh)/2;
sx=(gtk_draw_area_width-rw)/2;
sy=(gtk_draw_area_height-rh)/2;
if ( (sdlRenderer == NULL) || (sdlTexture == NULL) )
{
return -1;
}
SDL_SetRenderDrawColor( sdlRenderer, 0, 0, 0, 0 );
SDL_RenderClear(sdlRenderer);
uint8_t *textureBuffer;
int rowPitch;
SDL_LockTexture( sdlTexture, nullptr, (void**)&textureBuffer, &rowPitch);
{
memcpy( textureBuffer, glx_shm->pixbuf, GLX_NES_HEIGHT*GLX_NES_WIDTH*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);
SDL_RenderPresent(sdlRenderer);
return 0;
}
//*****************************************************************************

View File

@ -13,5 +13,11 @@ bool FCEUI_AviEnableHUDrecording();
void FCEUI_SetAviEnableHUDrecording(bool enable);
bool FCEUI_AviDisableMovieMessages();
void FCEUI_SetAviDisableMovieMessages(bool disable);
int init_gtk3_sdl_video(void);
int destroy_gtk3_sdl_video(void);
int gtk3_sdl_render(void);
int gtk3_sdl_resize(void);
#endif

View File

@ -35,6 +35,8 @@
#include "gui.h"
#endif
#include "fceux_git_info.h"
#include <unistd.h>
#include <csignal>
#include <cstring>
@ -57,6 +59,7 @@ extern bool MaxSpeed;
int isloaded;
bool turbo = false;
bool gtk_gui_run = true;
int closeFinishedMovie = 0;
@ -77,6 +80,8 @@ int pal_emulation;
int dendy;
bool swapDuty;
static bool luaScriptRunning = false;
// -Video Modes Tag- : See --special
static const char *DriverUsage=
"Option Value Description\n"
@ -179,6 +184,8 @@ static void ShowUsage(char *prog)
printf("Compiled with GTK version %d.%d.%d\n", GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION );
//printf("Linked with GTK version %d.%d.%d\n", GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION );
#endif
printf("git URL: %s\n", fceu_get_git_url() );
printf("git Rev: %s\n", fceu_get_git_rev() );
}
@ -330,8 +337,8 @@ DriverKill()
if (!noconfig)
g_config->save();
if(inited&2)
KillJoysticks();
if(inited&4)
KillVideo();
if(inited&1)
@ -348,6 +355,7 @@ FCEUD_Update(uint8 *XBuf,
int32 *Buffer,
int Count)
{
int blitDone = 0;
extern int FCEUDnetplay;
#ifdef CREATE_AVI
@ -374,8 +382,8 @@ FCEUD_Update(uint8 *XBuf,
if (!mutecapture)
if(Count > 0 && Buffer) WriteSound(Buffer,Count);
}
if(inited & 2)
FCEUD_UpdateInput();
// if(inited & 2)
// FCEUD_UpdateInput();
if(XBuf && (inited & 4)) BlitScreen(XBuf);
//SpeedThrottle();
@ -407,7 +415,9 @@ FCEUD_Update(uint8 *XBuf,
// don't underflow when scaling fps
if(g_fpsScale>1.0 || ((tmpcan < Count*0.90) && !uflow)) {
if(XBuf && (inited&4) && !(NoWaiting & 2))
BlitScreen(XBuf);
{
BlitScreen(XBuf); blitDone = 1;
}
Buffer+=can;
Count-=can;
if(Count) {
@ -442,24 +452,23 @@ FCEUD_Update(uint8 *XBuf,
}
} else {
if(!NoWaiting && (!(eoptions&EO_NOTHROTTLE) || FCEUI_EmulationPaused()))
while (SpeedThrottle())
{
FCEUD_UpdateInput();
}
if(XBuf && (inited&4)) {
BlitScreen(XBuf);
}
}
FCEUD_UpdateInput();
//if(!Count && !NoWaiting && !(eoptions&EO_NOTHROTTLE))
// SpeedThrottle();
//if(XBuf && (inited&4))
//if(!NoWaiting && (!(eoptions&EO_NOTHROTTLE) || FCEUI_EmulationPaused()))
//while (SpeedThrottle())
//{
// BlitScreen(XBuf);
// FCEUD_UpdateInput();
//}
//if(Count)
// WriteSound(Buffer,Count,NoWaiting);
if (XBuf && (inited&4))
{
BlitScreen(XBuf); blitDone = 1;
}
}
if ( !blitDone )
{
if (XBuf && (inited&4))
{
BlitScreen(XBuf); blitDone = 1;
}
}
//FCEUD_UpdateInput();
}
@ -552,10 +561,15 @@ int main(int argc, char *argv[])
#endif
/* SDL_INIT_VIDEO Needed for (joystick config) event processing? */
if(SDL_Init(SDL_INIT_VIDEO)) {
if (SDL_Init(SDL_INIT_VIDEO))
{
printf("Could not initialize SDL: %s.\n", SDL_GetError());
return(-1);
}
if ( SDL_SetHint( SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1" ) == SDL_FALSE )
{
printf("Error setting SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS\n");
}
//#ifdef OPENGL
// SDL_GL_LoadLibrary(0);
@ -608,12 +622,14 @@ int main(int argc, char *argv[])
std::string s;
g_config->getOption("SDL.InputCfg", &s);
if(s.size() != 0)
{
InitVideo(GameInfo);
InputCfg(s);
}
//g_config->getOption("SDL.InputCfg", &s);
//
//if(s.size() != 0)
//{
// InitVideo(GameInfo);
// InputCfg(s);
//}
// set the FAMICOM PAD 2 Mic thing
{
int t;
@ -625,18 +641,6 @@ int main(int argc, char *argv[])
// update the input devices
UpdateInput(g_config);
// check if opengl is enabled with a scaler and display an error and bail
int opengl;
int scaler;
g_config->getOption("SDL.OpenGL", &opengl);
g_config->getOption("SDL.SpecialFilter", &scaler);
if(opengl && scaler)
{
printf("Scalers are not supported in OpenGL mode. Terminating.\n");
exit(2);
}
// check for a .fcm file to convert to .fm2
g_config->getOption ("SDL.FCMConvert", &s);
g_config->setOption ("SDL.FCMConvert", "");
@ -908,7 +912,7 @@ int main(int argc, char *argv[])
#ifdef _GTK
if(noGui == 0)
{
while(1)
while ( gtk_gui_run )
{
if(GameInfo)
{
@ -916,14 +920,16 @@ int main(int argc, char *argv[])
}
else
{
SDL_Delay(1);
SDL_Delay(10);
}
FCEUD_UpdateInput();
while(gtk_events_pending())
{
gtk_main_iteration_do(FALSE);
}
}
printf("Exiting GUI Main Loop...\n");
}
else
{
@ -936,11 +942,34 @@ int main(int argc, char *argv[])
DoFun(frameskip, periodic_saves);
}
#endif
printf("Closing Game...\n");
CloseGame();
printf("Exiting Infrastructure...\n");
// exit the infrastructure
FCEUI_Kill();
SDL_Quit();
#ifdef _GTK
usleep(50000);
if ( MainWindow != NULL )
{
printf("Destroying GUI Window...\n");
gtk_widget_destroy( MainWindow ); MainWindow = NULL;
}
usleep(50000);
while(gtk_events_pending())
{
//printf("Processing the last of the events...\n");
gtk_main_iteration_do(FALSE);
}
#endif
// LoadGame() checks for an IP and if it finds one begins a network session
// clear the NetworkIP field so this doesn't happen unintentionally
g_config->setOption ("SDL.NetworkIP", "");
g_config->save ();
printf("Done!\n");
return 0;
}
@ -1002,6 +1031,27 @@ void FCEUD_PrintError(const char *errormsg)
fprintf(stderr, "%s\n", errormsg);
}
//----------------------------------------------------
void WinLuaOnStart(intptr_t hDlgAsInt)
{
luaScriptRunning = true;
//printf("Lua Script Running: %i \n", luaScriptRunning );
}
//----------------------------------------------------
void WinLuaOnStop(intptr_t hDlgAsInt)
{
luaScriptRunning = false;
//printf("Lua Script Running: %i \n", luaScriptRunning );
}
//----------------------------------------------------
void PrintToWindowConsole(intptr_t hDlgAsInt, const char* str)
{
printf("Lua Output: %s\n", str );
}
//----------------------------------------------------
// dummy functions

View File

@ -828,7 +828,7 @@ extern "C"
|| new_height != LogoInfo::height)
{
if(new_height < LogoInfo::height || new_height > LogoInfo::height+20)
fprintf(stderr, "'%s': ERROR, expected %dx%d, got %dx%d\n", fn,
fprintf(stderr, "'%s': ERROR, expected %ux%u, got %ux%u\n", fn,
LogoInfo::width, LogoInfo::height,
new_width, new_height);
}
@ -857,7 +857,7 @@ extern "C"
std::string avdir = "/home/you/yourlogo/";
char AvName[512];
sprintf(AvName, "logo_%d_%d_f%03u.png",
sprintf(AvName, "logo_%u_%u_f%03u.png",
LogoInfo::width,
LogoInfo::height,
frameno);

View File

@ -246,6 +246,29 @@ INT_PTR CWin32InputBox::GetInteger(
return ret;
}
INT_PTR CWin32InputBox::GetString(
LPCTSTR szTitle,
LPCTSTR szPrompt,
CHAR* result,
HWND hwndParent)
{
WIN32INPUTBOX_PARAM param;
char szResult[32+1];
sprintf(szResult, "");
param.szTitle = szTitle;
param.szPrompt = szPrompt;
param.szResult = szResult;
param.nResultSize = sizeof(szResult);
param.bMultiline = false;
param.hwndOwner = hwndParent;
INT_PTR ret = InputBoxEx(&param);
if (ret == IDOK)
sprintf(result, "%s", szResult);
return ret;
}
void CWin32InputBox::InitDialog()
{
// Set the button captions
@ -290,7 +313,7 @@ void CWin32InputBox::InitDialog()
0,
0,
rectDlg.right - rectDlg.left,
rectDlg.bottom - rectDlg.top - (rectEdit1.bottom - rectEdit1.top),
rectDlg.bottom - rectDlg.top - (rectEdit1.bottom - rectEdit1.top) + 16,
SWP_NOMOVE);
}
@ -302,7 +325,7 @@ void CWin32InputBox::InitDialog()
0,
0,
rectDlg.right - rectDlg.left,
rectEdit1.bottom - rectDlg.top + 5,
rectEdit1.bottom - rectDlg.top + 5 + 16,
SWP_NOMOVE);
::ShowWindow(hwndEdit2, SW_HIDE);

View File

@ -99,6 +99,12 @@ public:
LPCTSTR szPrompt,
int& result,
HWND hwndParent = 0);
static INT_PTR GetString(
LPCTSTR szTitle,
LPCTSTR szPrompt,
CHAR* result,
HWND hwndParent = 0);
};
#endif

View File

@ -106,8 +106,6 @@ static uint32 FTrainerData=0;
static uint8 TopRiderData=0;
static uint32 FamiNetSysData = 0;
static uint8 BWorldData[1+13+1];
static void UpdateFKB(void);
static void UpdateSuborKB(void);
void UpdateGamepad(void);

View File

@ -1,5 +1,5 @@
#ifndef WIN_INPUT_H
#define WIN_INPU_H
#define WIN_INPUT_H
#include "dinput.h"
@ -30,6 +30,8 @@ extern LPDIRECTINPUT7 lpDI;
extern int InputType[3];
//extern int UsrInputType[3];
extern int cidisabled;
extern uint8 BWorldData[1 + 13 + 1];
#ifndef _aosdfjk02fmasf
#define _aosdfjk02fmasf

View File

@ -108,7 +108,7 @@ BOOL updateResults(HWND hwndDlg, int rule)
int chosen_rules[NUMBER_OF_RULES] = { 0 };
unsigned int values[NUMBER_OF_RULES] = { 0 };
for (int i=0;i<sizeof(chosen_rules) && i <= rule;i++)
for (int i=0;i<NUMBER_OF_RULES && i <= rule;i++)
{
chosen_rules[i] = SendDlgItemMessage(hwndDlg, RULE_BOX_1 + i, CB_GETCURSEL, 0, 0);

View File

@ -1419,6 +1419,7 @@ INT_PTR CALLBACK RamWatchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
if (target[i].comment)
free(target[i].comment);
}
free(target);
}
if(msg.Addresses)
free(msg.Addresses);
@ -1442,6 +1443,7 @@ INT_PTR CALLBACK RamWatchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
InsertWatch(*sep);
if (sep->comment)
free(sep->comment);
free(sep);
}
if (msg.comment)
free(msg.comment);

View File

@ -148,6 +148,7 @@ int menuYoffset = 0;
bool wasPausedByCheats = false; //For unpausing the emulator if paused by the cheats dialog
bool rightClickEnabled = true; //If set to false, the right click context menu will be disabled.
bool fullscreenByDoubleclick = false;
uint8 BWorldData[1 + 13 + 1];
//Function Prototypes
void ChangeMenuItemText(int menuitem, string text); //Alters a menu item name
@ -381,6 +382,7 @@ void updateGameDependentMenus()
MENU_SWITCH_DISK,
MENU_EJECT_DISK,
MENU_RECORD_AVI,
MENU_INPUT_BARCODE,
MENU_STOP_AVI,
MENU_RECORD_WAV,
MENU_STOP_WAV,
@ -1303,7 +1305,7 @@ void DumpSubtitles(HWND hWnd)
for (unsigned int i = 0; i < subtitleFrames.size(); i++)
{
fprintf(srtfile, "%i\n", i+1); // starts with 1, not 0
fprintf(srtfile, "%u\n", i+1); // starts with 1, not 0
double seconds, ms, endseconds, endms;
seconds = subtitleFrames[i]/fps;
if (i+1 < subtitleFrames.size()) // there's another subtitle coming after this one
@ -1327,9 +1329,9 @@ void DumpSubtitles(HWND hWnd)
floor(endseconds/3600), (int)floor(endseconds/60) % 60, (int)floor(endseconds) % 60, (int)(endms*1000));
fprintf(srtfile, "%s\n\n", subtitleMessages[i].c_str()); // new line for every subtitle
}
}
fclose(srtfile);
}
}
return;
@ -1930,6 +1932,23 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
case MENU_INSERT_COIN:
FCEUI_VSUniCoin();
break;
case MENU_INPUT_BARCODE:
char bbuf[32 + 1];
if ((CWin32InputBox::GetString("Input Barcode", "Input full 13- or 8-digit barcode to be directly send to the reader. Or input partial 12- or 7-digit number to allow the program to calculate control code automatically.", bbuf, hWnd) == IDOK)) {
uint32 stl = strlen(bbuf);
if (InputType[2] == SIFC_BWORLD) {
strcpy((char *)&BWorldData[1], (char *)bbuf);
BWorldData[0] = 1;
FCEU_DispMessage("Barcode entered: %s", 0, bbuf);
}
else {
if(FCEUI_DatachSet((uint8 *)bbuf) == 1)
FCEU_DispMessage("Barcode entered: %s", 0, bbuf);
else
FCEU_DispMessage("Invalid barcode size or characters!", 0);
}
}
break;
//Emulation submenu
case ID_NES_PAUSE:
@ -2521,6 +2540,7 @@ adelikat: Outsourced this to a remappable hotkey
EnableMenuItem(fceumenu,MENU_EJECT_DISK,MF_BYCOMMAND | (FCEU_IsValidUI(FCEUI_EJECT_DISK)?MF_ENABLED:MF_GRAYED));
EnableMenuItem(fceumenu,MENU_SWITCH_DISK,MF_BYCOMMAND | (FCEU_IsValidUI(FCEUI_SWITCH_DISK)?MF_ENABLED:MF_GRAYED));
EnableMenuItem(fceumenu,MENU_INSERT_COIN,MF_BYCOMMAND | (FCEU_IsValidUI(FCEUI_INSERT_COIN)?MF_ENABLED:MF_GRAYED));
EnableMenuItem(fceumenu,MENU_INPUT_BARCODE,MF_BYCOMMAND | (FCEU_IsValidUI(FCEUI_INPUT_BARCODE)?MF_ENABLED:MF_GRAYED));
EnableMenuItem(fceumenu,MENU_TASEDITOR,MF_BYCOMMAND | (FCEU_IsValidUI(FCEUI_TASEDITOR)?MF_ENABLED:MF_GRAYED));
EnableMenuItem(fceumenu,MENU_CLOSE_FILE,MF_BYCOMMAND | (FCEU_IsValidUI(FCEUI_CLOSEGAME) && GameInfo ?MF_ENABLED:MF_GRAYED));
EnableMenuItem(fceumenu,MENU_RECENT_FILES,MF_BYCOMMAND | ((FCEU_IsValidUI(FCEUI_OPENGAME) && HasRecentFiles()) ?MF_ENABLED:MF_GRAYED)); //adelikat - added && recent_files, otherwise this line prevents recent from ever being gray when TAS Editor is not engaged

View File

@ -465,6 +465,11 @@ void FCEUI_SetBaseDirectory(std::string const & dir)
{
BaseDirectory = dir;
}
/// Gets the base directory
const char *FCEUI_GetBaseDirectory(void)
{
return BaseDirectory.c_str();
}
static char *odirs[FCEUIOD__COUNT]={0,0,0,0,0,0,0,0,0,0,0,0,0}; // odirs, odors. ^_^

View File

@ -956,7 +956,7 @@ init_ok:
}
// bbit edited: the whole function below was added
int iNesSave() {
int iNesSave(void) {
char name[2048];
strcpy(name, LoadedRomFName);
@ -967,7 +967,7 @@ int iNesSave() {
return iNesSaveAs(name);
}
int iNesSaveAs(char* name)
int iNesSaveAs(const char* name)
{
//adelikat: TODO: iNesSave() and this have pretty much the same code, outsource the common code to a single function
//caitsith2: done. iNesSave() now gets filename and calls iNesSaveAs with that filename.

View File

@ -43,8 +43,8 @@ extern uint8 *VROM;
extern uint32 VROM_size;
extern uint32 ROM_size;
extern uint8 *ExtraNTARAM;
extern int iNesSave(); //bbit Edited: line added
extern int iNesSaveAs(char* name);
extern int iNesSave(void); //bbit Edited: line added
extern int iNesSaveAs(const char* name);
extern char LoadedRomFName[2048]; //bbit Edited: line added
extern const TMasterRomInfo* MasterRomInfo;
extern TMasterRomInfoParams MasterRomInfoParams;

View File

@ -170,11 +170,11 @@ static intptr_t info_uid;
#ifdef WIN32
extern HWND LuaConsoleHWnd;
extern INT_PTR CALLBACK DlgLuaScriptDialog(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
void TaseditorDisableManualFunctionIfNeeded();
#endif
extern void PrintToWindowConsole(intptr_t hDlgAsInt, const char* str);
extern void WinLuaOnStart(intptr_t hDlgAsInt);
extern void WinLuaOnStop(intptr_t hDlgAsInt);
void TaseditorDisableManualFunctionIfNeeded();
#endif
static lua_State *L;
@ -6249,9 +6249,10 @@ int FCEU_LoadLuaCode(const char *filename, const char *arg) {
LuaConsoleHWnd = CreateDialog(fceu_hInstance, MAKEINTRESOURCE(IDD_LUA), hAppWnd, DlgLuaScriptDialog);
info_uid = (intptr_t)LuaConsoleHWnd;
#else
info_print = NULL;
info_onstart = NULL;
info_onstop = NULL;
info_print = PrintToWindowConsole;
info_onstart = WinLuaOnStart;
info_onstop = WinLuaOnStop;
info_uid = (intptr_t)0;
#endif
if (info_onstart)
info_onstart(info_uid);

View File

@ -46,8 +46,8 @@ pal palette_game[64*8]; //custom palette for an individual game. (formerly palet
pal palette_user[64*8]; //user's overridden palette (formerly palettec)
pal palette_ntsc[64*8]; //mathematically generated NTSC palette (formerly paletten)
static bool palette_game_available; //whether palette_game is available
static bool palette_user_available; //whether palette_user is available
static bool palette_game_available=false; //whether palette_game is available
static bool palette_user_available=false; //whether palette_user is available
//ntsc parameters:
bool ntsccol_enable = false; //whether NTSC palette is selected
@ -289,6 +289,11 @@ static void ApplyDeemphasisComplete(pal* pal512)
}
}
bool FCEUI_GetUserPaletteAvail( void )
{
return palette_user_available;
}
void FCEUI_SetUserPalette(uint8 *pal, int nEntries)
{
if(!pal)

View File

@ -1,6 +1,6 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2015
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fceux", "vc14_fceux.vcxproj", "{6893EF44-FEA3-46DF-B236-C4C200F54294}"
EndProject
Global

View File

@ -84,6 +84,7 @@
<li><a href="https://ci.appveyor.com/api/projects/zeromus/fceux/artifacts/fceux.zip?branch=master&job=Windows%2032">Windows 32-bit</a></li>
<li><a href="https://ci.appveyor.com/api/projects/zeromus/fceux/artifacts/fceux64.zip?branch=master&job=Windows%2064">Windows 64-bit</a></li>
<li><a href="https://ci.appveyor.com/api/projects/zeromus/fceux/artifacts/fceux-2.2.3-amd64.deb?branch=master&job=Ubuntu">Ubuntu Linux</a></li>
<li><a href="https://ci.appveyor.com/api/projects/zeromus/fceux/artifacts/fceux-2.2.3-Darwin.dmg?branch=master&job=MacOS">Mac OS X</a></li>
</ul>
<h3>Source Code</h3>

View File

@ -59,37 +59,23 @@
</div>
<div id="page_content">
To compile FCEUX in osx, you must have fink or macports. The FCEUX developers recommend fink, since that's what they use, but then again, the only time they compile software on osx is when folks come nagging.<p>
To run FCEUX in Mac OSX, you must have the following library dependencies installed on your system:
<p>
first, install the prerequisites.<p>
Qt5, SDL2, minizip, and zlib
<p>
macports requires these prerequisites: scons, libsdl, zenity, lua, gtk2<p>
fink requires these prerequisites: try all the same ones as macports, but i know at least one of them is named gtk+2 instead. please report your results.<p>
<p>
Building instructions for fink:<p>
<p>
CFLAGS=-I/sw/include LDFLAGS=-L/sw/lib scons<p>
if you are getting link errors about 64bitness then your system is compiling fceux as 64bit but fink is providing i386 libraries. you need to force fceux to compile 32 bits:<p>
CFLAGS="-I/sw/include -arch i386" LDFLAGS="-L/sw/lib -arch i386" scons<p>
<p>
None of the modifications listed at the paperkettle URL were necessary in our latest fink test only 18-jul-2010<p>
<p>
This URL is a little old, but he got FCEUX compiling via fink<p>
http://beesbuzz.biz/blog/e/2009/04/14-how_to_build_fceux_for_mac_os_x.php<p>
<p>
Building instructions for macports:<p>
<p>
CFLAGS=-I/opt/local/include LDFLAGS=-L/opt/local/lib scons<p>
<p>
This URL is fresh, and he got FCEUX compiling via macports:<p>
http://www.paperkettle.com/blog/2010/07/17/fceux-2-14a-compiled-on-mac-osx-10-6/<p>
<p>
---<p>
<p>
At any given time while fooling around you may discover that scons begins behaving irrationally. To fix this, try deleting .sconsign.dblite which will clear out its memory of what has come before.<p>
<p>
To clean your scons build, issue the main scons build command as discussed above with the -c parameter<p>
If you are attempting to use the appveyor pipeline autobuild of fceux, you must install these
dependencies via the home brew package management tool. The following commands will install
the necessary dependencies to run the autobuild:
<pre>
brew install qt5
brew install sdl2
brew install minizip
</pre>
If you are attempting to compile fceux, you can either install the dependencies via home brew
or you can install the dmg packages available from the Qt and SDL websites. The cmake and make
build tools are required to compile fceux. See the README file in the root directory of the
project for build instructions. You can also look at what is being done in the ./pipelines/macOS_build.sh
script if you wish to build fceux in the same way the autobuild does.
</div>
</div>