Merge pull request #20 from TASVideos/master

Sync code to the newest
This commit is contained in:
owomomo 2020-06-17 11:46:54 +08:00 committed by GitHub
commit 876455a4f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
54 changed files with 10902 additions and 2958 deletions

View File

@ -19,8 +19,8 @@ opts.AddVariables(
BoolVariable('FRAMESKIP', 'Enable frameskipping', 1), BoolVariable('FRAMESKIP', 'Enable frameskipping', 1),
BoolVariable('OPENGL', 'Enable OpenGL support', 1), BoolVariable('OPENGL', 'Enable OpenGL support', 1),
BoolVariable('LUA', 'Enable Lua support', 1), BoolVariable('LUA', 'Enable Lua support', 1),
BoolVariable('GTK', 'Enable GTK2 GUI (SDL only)', 1), BoolVariable('GTK', 'Enable GTK2 GUI (SDL only)', 0),
BoolVariable('GTK3', 'Enable GTK3 GUI (SDL only)', 0), BoolVariable('GTK3', 'Enable GTK3 GUI (SDL only)', 1),
BoolVariable('NEWPPU', 'Enable new PPU core', 1), BoolVariable('NEWPPU', 'Enable new PPU core', 1),
BoolVariable('CREATE_AVI', 'Enable avi creation support (SDL only)', 1), BoolVariable('CREATE_AVI', 'Enable avi creation support (SDL only)', 1),
BoolVariable('LOGO', 'Enable a logoscreen when creating avis (SDL only)', 1), BoolVariable('LOGO', 'Enable a logoscreen when creating avis (SDL only)', 1),
@ -28,7 +28,7 @@ opts.AddVariables(
BoolVariable('SYSTEM_MINIZIP', 'Use system minizip instead of static minizip provided with fceux', 0), BoolVariable('SYSTEM_MINIZIP', 'Use system minizip instead of static minizip provided with fceux', 0),
BoolVariable('LSB_FIRST', 'Least signficant byte first (non-PPC)', 1), BoolVariable('LSB_FIRST', 'Least signficant byte first (non-PPC)', 1),
BoolVariable('CLANG', 'Compile with llvm-clang instead of gcc', 0), BoolVariable('CLANG', 'Compile with llvm-clang instead of gcc', 0),
BoolVariable('SDL2', 'Compile using SDL2 instead of SDL 1.2 (experimental/non-functional)', 0) BoolVariable('SDL2', 'Compile using SDL2 instead of SDL 1.2 (experimental/non-functional)', 1)
) )
AddOption('--prefix', dest='prefix', type='string', nargs=1, action='store', metavar='DIR', help='installation prefix') AddOption('--prefix', dest='prefix', type='string', nargs=1, action='store', metavar='DIR', help='installation prefix')
@ -44,7 +44,7 @@ if platform.system == "ppc":
env['LSB_FIRST'] = 0 env['LSB_FIRST'] = 0
# Default compiler flags: # Default compiler flags:
env.Append(CCFLAGS = ['-Wall', '-Wno-write-strings', '-Wno-sign-compare']) env.Append(CCFLAGS = ['-Wall', '-Wno-write-strings', '-Wno-sign-compare', '-Wno-parentheses', '-Wno-unused-local-typedefs'])
env.Append(CXXFLAGS = ['-std=c++0x']) env.Append(CXXFLAGS = ['-std=c++0x'])
if 'PLATFORM' in os.environ: if 'PLATFORM' in os.environ:
@ -97,7 +97,7 @@ else:
if conf.CheckFunc('asprintf'): if conf.CheckFunc('asprintf'):
conf.env.Append(CCFLAGS = "-DHAVE_ASPRINTF") conf.env.Append(CCFLAGS = "-DHAVE_ASPRINTF")
if env['SYSTEM_MINIZIP']: if env['SYSTEM_MINIZIP']:
assert conf.CheckLibWithHeader('minizip', 'minizip/unzip.h', 'C', 'unzOpen;', 1), "please install: libminizip" assert env.ParseConfig('pkg-config minizip --cflags --libs'), "please install: libminizip"
assert conf.CheckLibWithHeader('z', 'zlib.h', 'c', 'inflate;', 1), "please install: zlib" assert conf.CheckLibWithHeader('z', 'zlib.h', 'c', 'inflate;', 1), "please install: zlib"
env.Append(CPPDEFINES=["_SYSTEM_MINIZIP"]) env.Append(CPPDEFINES=["_SYSTEM_MINIZIP"])
else: else:
@ -153,6 +153,9 @@ else:
elif conf.CheckLib('lua5.1'): elif conf.CheckLib('lua5.1'):
lua_link_flags = "-llua5.1" lua_link_flags = "-llua5.1"
lua_include_dir = "/usr/include/lua5.1" lua_include_dir = "/usr/include/lua5.1"
elif conf.CheckLib('lua-5.1'):
lua_link_flags = "-llua-5.1"
lua_include_dir = "/usr/include/lua-5.1"
elif conf.CheckLib('lua'): elif conf.CheckLib('lua'):
lua_link_flags = "-llua" lua_link_flags = "-llua"
lua_include_dir = "/usr/include/lua" lua_include_dir = "/usr/include/lua"
@ -183,7 +186,7 @@ else:
if env['OPENGL'] and conf.CheckLibWithHeader('GL', 'GL/gl.h', 'c', autoadd=1): if env['OPENGL'] and conf.CheckLibWithHeader('GL', 'GL/gl.h', 'c', autoadd=1):
conf.env.Append(CCFLAGS = "-DOPENGL") conf.env.Append(CCFLAGS = "-DOPENGL")
conf.env.Append(CPPDEFINES = ['PSS_STYLE=1']) conf.env.Append(CPPDEFINES = ['PSS_STYLE=1',"FCEUDEF_DEBUGGER"])
env = conf.Finish() env = conf.Finish()

8
appveyor.yml Normal file
View File

@ -0,0 +1,8 @@
version: 1.0.{build}
image:
- Visual Studio 2019
- Ubuntu2004
#- Ubuntu1804
build_script:
- cmd: pipelines/win32_build.bat
- sh: ./pipelines/linux_build.sh

16
azure-pipelines.yml Normal file
View File

@ -0,0 +1,16 @@
# C/C++ with GCC
# Build your C/C++ project with GCC using make.
# Add steps that publish test results, save build artifacts, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/apps/c-cpp/gcc
trigger:
- master
- development
pool:
vmImage: 'ubuntu-latest'
steps:
- script: |
./pipelines/linux_build.sh
displayName: 'make'

119
pipelines/debpkg.pl Executable file
View File

@ -0,0 +1,119 @@
#!/usr/bin/perl
use strict;
my $VERSION="2.2.3";
my $INSTALL_PREFIX="/tmp/fceux";
my $CTL_FILENAME="$INSTALL_PREFIX/DEBIAN/control";
my $ARCH="amd64";
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`;
#print "$SO_LIST";
my $i; my $j; my $k; my $pkg;
my @fd = split /\n/, $SO_LIST;
my @libls;
$#libls=0;
for ($i=0; $i<=$#fd; $i++)
{
#$fd[$i] =~ s/^\s+//;
#print "$fd[$i]\n";
if ( $fd[$i] =~ m/NEEDED\s+(.*)/ )
{
#print "$1 \n";
$libls[$#libls] = $1; $#libls++;
}
}
my %pkghash; my $pkgsearch;
my @pkglist; my @pkgdeps;
my $pkg; my $filepath;
$#pkgdeps=0;
for ($i=0; $i<$#libls; $i++)
{
$pkgsearch=`dpkg-query -S $libls[$i]`;
@pkglist = split /\n/, $pkgsearch;
for ($j=0; $j<=$#pkglist; $j++)
{
#$pkghash{$pkg} = 1;
#print " $libls[$i] '$pkglist[$j]' \n";
if ( $pkglist[$j] =~ m/(.*):$ARCH:\s+(.*)/ )
{
$pkg = $1;
$filepath = $2;
$filepath =~ s/^.*\///;
if ( $libls[$i] eq $filepath )
{
#print "PKG: '$pkg' '$libls[$i]' == '$filepath' \n";
# Don't put duplicate entries into the pkg depend list.
if ( !defined( $pkghash{$pkg} ) )
{
$pkgdeps[ $#pkgdeps ] = $pkg; $#pkgdeps++;
$pkghash{$pkg} = 1;
}
}
}
}
}
#
#
system("mkdir -p $INSTALL_PREFIX/DEBIAN");
open CTL, ">$CTL_FILENAME" or die "Error: Could not open file '$CTL_FILENAME'\n";
#
print CTL "Package: fceux\n";
print CTL "Version: $VERSION\n";
print CTL "Section: games\n";
print CTL "Priority: extra\n";
print CTL "Architecture: $ARCH\n";
print CTL "Homepage: http://fceux.com/\n";
print CTL "Essential: no\n";
#print CTL "Installed-Size: 1024\n";
print CTL "Maintainer: mjbudd77\n";
print CTL "Description: fceux is an emulator of the original (8-bit) Nintendo Entertainment System (NES)\n";
print CTL "Depends: $pkgdeps[0]";
for ($i=1; $i<$#pkgdeps; $i++)
{
print CTL ", $pkgdeps[$i]";
}
print CTL "\n";
close CTL;
#system("cat $CTL_FILENAME");
#
chdir "/tmp";
system("dpkg-deb --build fceux ");
if ( !(-e "/tmp/fceux.deb") )
{
die "Error: Failed to create package $PKG_OUTPUT_FILE\n";
}
system("mv fceux.deb $PKG_OUTPUT_FILE");
system("dpkg-deb -I $PKG_OUTPUT_FILE");
#
if ( -e "/tmp/$PKG_OUTPUT_FILE" )
{
print "**********************************************\n";
print "Created deb package: /tmp/$PKG_OUTPUT_FILE\n";
print "**********************************************\n";
}
else
{
die "Error: Failed to create package $PKG_OUTPUT_FILE\n";
}

118
pipelines/linux_build.sh Executable file
View File

@ -0,0 +1,118 @@
#!/bin/bash
id
pwd
cat /etc/os-release
SCRIPT_DIR=$( cd $(dirname $BASH_SOURCE[0]); pwd );
#echo $SCRIPT_DIR;
gcc --version
python2 --version
python3 --version
INSTALL_PREFIX=/tmp/fceux
echo '****************************************'
echo "APPVEYOR_SSH_KEY=$APPVEYOR_SSH_KEY";
echo "APPVEYOR_SSH_BLOCK=$APPVEYOR_SSH_BLOCK";
echo '****************************************'
echo '****************************************'
echo '****************************************'
echo '*** Installing Package Dependencies ***'
echo '****************************************'
echo '****************************************'
# Install Lua-5.1 development package
echo '****************************************'
echo 'Install Dependency lua5.1-dev'
echo '****************************************'
sudo apt-get --assume-yes install lua5.1-dev
pkg-config --cflags --libs lua5.1
# Install libSDL-1.2 and libSDL-2
# libSDL-1.2 no long needed
#echo '****************************************'
#echo 'Install Dependency libsdl1.2-dev'
#echo '****************************************'
#sudo apt-get --assume-yes install libsdl1.2-dev
#sdl-config --cflags --libs
echo '****************************************'
echo 'Install Dependency libsdl2-dev'
echo '****************************************'
sudo apt-get --assume-yes install libsdl2-dev
sdl2-config --cflags --libs
# Install libminizip-dev
echo '****************************************'
echo 'Install Dependency libminizip-dev'
echo '****************************************'
sudo apt-get --assume-yes install libminizip-dev
pkg-config --cflags --libs minizip
# GTK+-2 is no longer needed
#sudo apt-get install libgtk2.0-dev
# Install GTK+-3
echo '****************************************'
echo 'Install Dependency libgtk-3-dev'
echo '****************************************'
sudo apt-get --assume-yes install libgtk-3-dev
pkg-config --cflags --libs gtk+-3.0
# Install GTK+-3 Sourceview
sudo apt-get --assume-yes install libgtksourceview-3.0-dev
pkg-config --cflags --libs gtksourceview-3.0
# Install scons
echo '****************************************'
echo 'Install Build Dependency scons'
echo '****************************************'
sudo apt-get --assume-yes install scons
# Install cppcheck
echo '****************************************'
echo 'Install Check Dependency cppcheck'
echo '****************************************'
sudo apt-get --assume-yes install cppcheck
echo '**************************'
echo '*** Building Project ***'
echo '**************************'
mkdir -p $INSTALL_PREFIX/usr;
scons --clean
scons GTK3=1 SYSTEM_LUA=1 SYSTEM_MINIZIP=1 CREATE_AVI=1 install --prefix=$INSTALL_PREFIX/usr
# Debug via ssh if necessary
if [ ! -z $APPVEYOR_SSH_BLOCK ]; then
curl -sflL 'https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-ssh.sh' | bash -e -
fi
if [ -e $INSTALL_PREFIX/usr/bin/fceux ]; then
echo '**************************************************************'
echo 'Printing Shared Object Dependencies for ./bin/fceux Executable'
echo '**************************************************************'
ldd $INSTALL_PREFIX/usr/bin/fceux
else
echo "Error: Executable Failed to build: $INSTALL_PREFIX/usr/bin/fceux";
exit 1;
fi
echo '**************************************************************'
echo 'Printing To Be Packaged Files '
echo '**************************************************************'
find $INSTALL_PREFIX
echo '**************************************************************'
echo 'Creating Debian Package'
echo '**************************************************************'
$SCRIPT_DIR/debpkg.pl;
echo '**************************************************************'
echo 'Testing Install of Package'
echo '**************************************************************'
sudo dpkg -i /tmp/fceux-*.deb
echo 'Pushing Debian Package to Build Artifacts'
appveyor PushArtifact /tmp/fceux-*.deb

22
pipelines/win32_build.bat Normal file
View File

@ -0,0 +1,22 @@
set PROJECT_ROOT=%~dp0..
REM echo %PROJECT_ROOT%
msbuild %PROJECT_ROOT%\vc\vc14_fceux.vcxproj
cd %PROJECT_ROOT%\vc
REM Copy Executable and dlls to output directory
copy vc14_bin_Debug\fceux.exe ..\output\.
copy vc14_bin_Debug\7z.dll ..\output\.
REM Create Zip Archive
REM archive.bat
cd %PROJECT_ROOT%\output
..\vc\zip -X -9 -r ..\vc\fceux.zip fceux.exe fceux.chm taseditor.chm 7z.dll *.dll palettes luaScripts tools
cd %PROJECT_ROOT%
appveyor PushArtifact %PROJECT_ROOT%\vc\fceux.zip

View File

@ -104,4 +104,4 @@ bool FCEU_OpenGenie(void);
void FCEU_CloseGenie(void); void FCEU_CloseGenie(void);
void FCEU_KillGenie(void); void FCEU_KillGenie(void);
#endif#endif #endif

View File

@ -565,9 +565,9 @@ void BreakHit(int bp_num)
{ {
FCEUI_SetEmulationPaused(EMULATIONPAUSED_PAUSED); //mbg merge 7/19/06 changed to use EmulationPaused() FCEUI_SetEmulationPaused(EMULATIONPAUSED_PAUSED); //mbg merge 7/19/06 changed to use EmulationPaused()
#ifdef WIN32 //#ifdef WIN32
FCEUD_DebugBreakpoint(bp_num); FCEUD_DebugBreakpoint(bp_num);
#endif //#endif
} }
int StackAddrBackup; int StackAddrBackup;

View File

@ -218,6 +218,11 @@ int InitBlitToHigh(int b, uint32 rmask, uint32 gmask, uint32 bmask, int efx, int
return(0); return(0);
//allocate adequate room for 32bpp palette //allocate adequate room for 32bpp palette
if ( palettetranslate )
{
free(palettetranslate);
palettetranslate=NULL;
}
palettetranslate=(uint32*)FCEU_dmalloc(256*4 + 512*4); palettetranslate=(uint32*)FCEU_dmalloc(256*4 + 512*4);
if(!palettetranslate) if(!palettetranslate)

View File

@ -8,7 +8,12 @@ Export('env')
source_list = Split( source_list = Split(
""" """
input.cpp input.cpp
cheat.cpp
config.cpp config.cpp
memview.cpp
ramwatch.cpp
debugger.cpp
glxwin.cpp
sdl.cpp sdl.cpp
sdl-joystick.cpp sdl-joystick.cpp
sdl-sound.cpp sdl-sound.cpp
@ -18,8 +23,6 @@ source_list = Split(
""") """)
Import('env') Import('env')
if 'GL' in env['LIBS']:
source_list.append('sdl-opengl.cpp')
if env['GTK'] or env['GTK3']: if env['GTK'] or env['GTK3']:
source_list.append('gui.cpp') source_list.append('gui.cpp')

1323
src/drivers/sdl/cheat.cpp Normal file

File diff suppressed because it is too large Load Diff

3
src/drivers/sdl/cheat.h Normal file
View File

@ -0,0 +1,3 @@
// cheat.h
void openCheatsWindow(void);

View File

@ -26,6 +26,46 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
static const char* HotkeyStrings[HK_MAX] = {
"CheatMenu",
"BindState",
"LoadLua",
"ToggleBG",
"SaveState",
"FDSSelect",
"LoadState",
"FDSEject",
"VSInsertCoin",
"VSToggleDip",
"MovieToggleFrameDisplay",
"SubtitleDisplay",
"Reset",
"Screenshot",
"Pause",
"DecreaseSpeed",
"IncreaseSpeed",
"FrameAdvance",
"Turbo",
"ToggleInputDisplay",
"ToggleMovieRW",
"MuteCapture",
"Quit",
"FrameAdvanceLagSkip",
"LagCounterDisplay",
"SelectState0", "SelectState1", "SelectState2", "SelectState3",
"SelectState4", "SelectState5", "SelectState6", "SelectState7",
"SelectState8", "SelectState9", "SelectStateNext", "SelectStatePrev",
"VolumeDown", "VolumeUp" };
const char *getHotkeyString( int i )
{
if ( (i>=0) && (i<HK_MAX) )
{
return HotkeyStrings[i];
}
return NULL;
}
/** /**
* Read a custom pallete from a file and load it into the core. * Read a custom pallete from a file and load it into the core.
*/ */
@ -166,7 +206,7 @@ InitConfig()
config->addOption("SDL.LastXRes", 0); config->addOption("SDL.LastXRes", 0);
config->addOption("SDL.LastYRes", 0); config->addOption("SDL.LastYRes", 0);
config->addOption('b', "bpp", "SDL.BitsPerPixel", 32); config->addOption('b', "bpp", "SDL.BitsPerPixel", 32);
config->addOption("doublebuf", "SDL.DoubleBuffering", 0); config->addOption("doublebuf", "SDL.DoubleBuffering", 1);
config->addOption("autoscale", "SDL.AutoScale", 1); config->addOption("autoscale", "SDL.AutoScale", 1);
config->addOption("keepratio", "SDL.KeepRatio", 1); config->addOption("keepratio", "SDL.KeepRatio", 1);
config->addOption("xscale", "SDL.XScale", 1.0); config->addOption("xscale", "SDL.XScale", 1.0);
@ -179,8 +219,8 @@ InitConfig()
config->addOption("togglemenu", "SDL.ToggleMenu", 0); config->addOption("togglemenu", "SDL.ToggleMenu", 0);
// OpenGL options // OpenGL options
config->addOption("opengl", "SDL.OpenGL", 0); config->addOption("opengl", "SDL.OpenGL", 1);
config->addOption("openglip", "SDL.OpenGLip", 0); config->addOption("openglip", "SDL.OpenGLip", 1);
config->addOption("SDL.SpecialFilter", 0); config->addOption("SDL.SpecialFilter", 0);
config->addOption("SDL.SpecialFX", 0); config->addOption("SDL.SpecialFX", 0);
config->addOption("SDL.Vsync", 1); config->addOption("SDL.Vsync", 1);
@ -269,9 +309,10 @@ InitConfig()
config->addOption("4buttonexit", "SDL.ABStartSelectExit", 0); config->addOption("4buttonexit", "SDL.ABStartSelectExit", 0);
// GamePad 0 - 3 // GamePad 0 - 3
for(unsigned int i = 0; i < GAMEPAD_NUM_DEVICES; i++) { for(unsigned int i = 0; i < GAMEPAD_NUM_DEVICES; i++)
{
char buf[64]; char buf[64];
snprintf(buf, 20, "SDL.Input.GamePad.%d.", i); snprintf(buf, sizeof(buf)-1, "SDL.Input.GamePad.%u.", i);
prefix = buf; prefix = buf;
config->addOption(prefix + "DeviceType", DefaultGamePadDevice[i]); config->addOption(prefix + "DeviceType", DefaultGamePadDevice[i]);
@ -284,7 +325,7 @@ InitConfig()
// PowerPad 0 - 1 // PowerPad 0 - 1
for(unsigned int i = 0; i < POWERPAD_NUM_DEVICES; i++) { for(unsigned int i = 0; i < POWERPAD_NUM_DEVICES; i++) {
char buf[64]; char buf[64];
snprintf(buf, 20, "SDL.Input.PowerPad.%d.", i); snprintf(buf, sizeof(buf)-1, "SDL.Input.PowerPad.%u.", i);
prefix = buf; prefix = buf;
config->addOption(prefix + "DeviceType", DefaultPowerPadDevice[i]); config->addOption(prefix + "DeviceType", DefaultPowerPadDevice[i]);

View File

@ -22,36 +22,7 @@ enum HOTKEY { HK_CHEAT_MENU=0, HK_BIND_STATE, HK_LOAD_LUA, HK_TOGGLE_BG,
HK_SELECT_STATE_NEXT, HK_SELECT_STATE_PREV, HK_VOLUME_DOWN, HK_VOLUME_UP, HK_SELECT_STATE_NEXT, HK_SELECT_STATE_PREV, HK_VOLUME_DOWN, HK_VOLUME_UP,
HK_MAX}; HK_MAX};
const char *getHotkeyString( int i );
static const char* HotkeyStrings[HK_MAX] = {
"CheatMenu",
"BindState",
"LoadLua",
"ToggleBG",
"SaveState",
"FDSSelect",
"LoadState",
"FDSEject",
"VSInsertCoin",
"VSToggleDip",
"MovieToggleFrameDisplay",
"SubtitleDisplay",
"Reset",
"Screenshot",
"Pause",
"DecreaseSpeed",
"IncreaseSpeed",
"FrameAdvance",
"Turbo",
"ToggleInputDisplay",
"ToggleMovieRW",
"MuteCapture",
"Quit",
"FrameAdvanceLagSkip",
"LagCounterDisplay",
"SelectState0", "SelectState1", "SelectState2", "SelectState3",
"SelectState4", "SelectState5", "SelectState6", "SelectState7",
"SelectState8", "SelectState9", "SelectStateNext", "SelectStatePrev",
"VolumeDown", "VolumeUp" };
#endif #endif

2290
src/drivers/sdl/debugger.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,3 @@
// debugger.h
//
void openDebuggerWindow (void);

508
src/drivers/sdl/glxwin.cpp Normal file
View File

@ -0,0 +1,508 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <GL/glu.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h>
#endif
#include "glxwin.h"
static Display *dpy = NULL;
static Window root;
static XVisualInfo *vi = NULL;
static Colormap cmap;
static XSetWindowAttributes swa;
static Window win;
static GLXContext glc = NULL;
static XWindowAttributes gwa;
static XEvent xev;
static GLint double_buffer_ena = 1;
static GLuint gltexture = 0;
static int spawn_new_window = 0;
glxwin_shm_t *glx_shm = NULL;
static int screen_width = 512;
static int screen_height = 512;
extern GtkWidget *evbox;
extern unsigned int gtk_draw_area_width;
extern unsigned int gtk_draw_area_height;
//************************************************************************
static glxwin_shm_t *open_shm(void)
{
int shmId;
glxwin_shm_t *vaddr;
struct shmid_ds ds;
shmId = shmget( IPC_PRIVATE, sizeof(struct glxwin_shm_t), IPC_CREAT | S_IRWXU | S_IRWXG );
if ( shmId == -1 )
{
perror("Error: GLX shmget Failed:");
return NULL;
}
printf("Created ShmID: %i \n", shmId );
vaddr = (glxwin_shm_t*)shmat( shmId, NULL, 0);
if ( vaddr == (glxwin_shm_t*)-1 )
{
perror("Error: GLX shmat Failed:");
return NULL;
}
memset( vaddr, 0, sizeof(struct glxwin_shm_t));
if ( shmctl( shmId, IPC_RMID, &ds ) != 0 )
{
perror("Error: GLX shmctl IPC_RMID Failed:");
}
sem_init( &vaddr->sem, 1, 1 );
vaddr->ncol = 256;
vaddr->nrow = 256;
vaddr->pitch = 256 * 4;
return vaddr;
}
//************************************************************************
static void getAttrbList( GLint *buf )
{
int i=0;
buf[i] = GLX_RGBA; i++;
buf[i] = GLX_DEPTH_SIZE; i++;
buf[i] = 24; i++;
if ( double_buffer_ena )
{
buf[i] = GLX_DOUBLEBUFFER ; i++;
}
buf[i] = None;
}
//************************************************************************
static void genTextures( int ipolate )
{
glEnable(GL_TEXTURE_2D);
if ( gltexture )
{
printf("GL Texture already exists\n");
}
else
{
glGenTextures(1, &gltexture);
}
printf("Linear Interpolation on GL Texture: %s \n", ipolate ? "Enabled" : "Disabled");
glBindTexture(GL_TEXTURE_2D, gltexture);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,ipolate?GL_LINEAR:GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,ipolate?GL_LINEAR:GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
}
//************************************************************************
static int open_window(void)
{
GLint att[32];
getAttrbList( att );
dpy = XOpenDisplay(NULL);
if (dpy == NULL) {
printf("\n\tcannot connect to X server\n\n");
exit(0);
}
root = DefaultRootWindow(dpy);
vi = glXChooseVisual(dpy, 0, att);
if (vi == NULL)
{
printf("\n\tno appropriate visual found\n\n");
exit(0);
}
else {
printf("\n\tvisual %p selected\n", (void *)vi->visualid); /* %p creates hexadecimal output like in glxinfo */
}
cmap = XCreateColormap(dpy, root, vi->visual, AllocNone);
swa.colormap = cmap;
swa.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask;
win = XCreateWindow(dpy, root, 0, 0, screen_width, screen_height, 0,
vi->depth, InputOutput, vi->visual,
CWColormap | CWEventMask, &swa);
XMapWindow(dpy, win);
XStoreName(dpy, win, "FCEUX VIEWPORT");
if ( glc == NULL )
{
glc = glXCreateContext(dpy, vi, NULL, GL_TRUE);
if ( glc == NULL )
{
printf("Error: glXCreateContext Failed\n");
}
}
else
{
printf("GLX Context Already Exists\n");
}
XFree(vi); vi = NULL;
glXMakeCurrent(dpy, win, glc);
genTextures(1);
glDisable(GL_DEPTH_TEST);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Background color to black.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// In a double buffered setup with page flipping, be sure to clear both buffers.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
return 0;
}
//************************************************************************
//static void print_pixbuf(void)
//{
// for (int x=0; x<256; x++)
// {
// for (int y=0; y<256; y++)
// {
// printf("(%i,%i) = %08X \n", x, y, glx_shm->pixbuf[y*256+x] );
// }
// }
//}
//************************************************************************
static void render_image(void)
{
static int null_glc_error = 0;
int l=0, r=glx_shm->ncol;
int t=0, b=glx_shm->nrow;
float xscale = (float)screen_width / (float)glx_shm->ncol;
float yscale = (float)screen_height / (float)glx_shm->nrow;
if (xscale < yscale )
{
yscale = xscale;
}
else
{
xscale = yscale;
}
int rw=(int)((r-l)*xscale);
int rh=(int)((b-t)*yscale);
int sx=(screen_width-rw)/2;
int sy=(screen_height-rh)/2;
if ( glc == NULL )
{
if ( !null_glc_error )
{
printf("Error: GLX Render has NULL Context\n");
null_glc_error = 1;
}
return;
}
null_glc_error = 0;
glXMakeCurrent(dpy, win, glc);
//printf("Viewport: (%i,%i) %i %i %i %i \n",
// screen_width, screen_height, sx, sy, rw, rh );
glViewport(sx, sy, rw, rh);
//glViewport( 0, 0, screen_width, screen_height);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
glDisable(GL_DEPTH_TEST);
glClearColor( 0.0, 0.0f, 0.0f, 0.0f); // Background color to black.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_TEXTURE_2D);
//glBindTexture(GL_TEXTURE_2D, gltexture);
glBindTexture(GL_TEXTURE_2D, gltexture);
//print_pixbuf();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0,
GL_RGBA, GL_UNSIGNED_BYTE, glx_shm->pixbuf );
glBegin(GL_QUADS);
glTexCoord2f(1.0f*l/256, 1.0f*b/256); // Bottom left of picture.
glVertex2f(-1.0f, -1.0f); // Bottom left of target.
glTexCoord2f(1.0f*r/256, 1.0f*b/256);// Bottom right of picture.
glVertex2f( 1.0f, -1.0f); // Bottom right of target.
glTexCoord2f(1.0f*r/256, 1.0f*t/256); // Top right of our picture.
glVertex2f( 1.0f, 1.0f); // Top right of target.
glTexCoord2f(1.0f*l/256, 1.0f*t/256); // Top left of our picture.
glVertex2f(-1.0f, 1.0f); // Top left of target.
glEnd();
glDisable(GL_TEXTURE_2D);
//glColor4f( 1.0, 1.0, 1.0, 1.0 );
//glLineWidth(5.0);
//glBegin(GL_LINES);
//glVertex2f(-1.0f, -1.0f); // Bottom left of target.
//glVertex2f( 1.0f, 1.0f); // Top right of target.
//glEnd();
if ( double_buffer_ena )
{
glXSwapBuffers( dpy, win );
}
else
{
glFlush();
}
}
//************************************************************************
static int mainWindowLoop(void)
{
while( glx_shm->run )
{
while ( XPending( dpy ) )
{
XNextEvent(dpy, &xev);
if (xev.type == Expose)
{
XGetWindowAttributes(dpy, win, &gwa);
//glViewport(0, 0, gwa.width, gwa.height);
//DrawAQuad();
glXSwapBuffers(dpy, win);
//printf("Expose\n");
}
else if (xev.type == ConfigureNotify)
{
screen_width = xev.xconfigure.width;
screen_height = xev.xconfigure.height;
render_image();
}
else if (xev.type == KeyPress)
{
printf("Key press: %i %08X \n", xev.xkey.keycode, xev.xkey.state );
}
else if (xev.type == DestroyNotify)
{
printf("DestroyNotify\n");
glx_shm->run = 0;
//glXMakeCurrent(dpy, None, NULL);
//glXDestroyContext(dpy, glc);
//XDestroyWindow(dpy, win);
//XCloseDisplay(dpy);
//exit(0);
}
}
if ( glx_shm->blit_count != glx_shm->render_count )
{
render_image();
glx_shm->render_count++;
}
usleep(10000);
}
glXMakeCurrent(dpy, None, NULL);
glXDestroyContext(dpy, glc);
XDestroyWindow(dpy, win);
XCloseDisplay(dpy);
exit(0);
return 0;
}
//************************************************************************
int spawn_glxwin( int flags )
{
int pid;
glx_shm = open_shm();
if ( !spawn_new_window )
{
return 0;
}
pid = fork();
if ( pid == 0 )
{
// Child Process
glx_shm->run = 1;
glx_shm->pid = getpid();
printf("Child Process Running: %i\n", glx_shm->pid );
open_window();
mainWindowLoop();
exit(0);
}
else if ( pid > 0 )
{ // Parent Process
}
else
{
// Error
printf("Error: Failed to Fork GLX Window Process\n");
}
return pid;
}
//************************************************************************
int init_gtk3_GLXContext( int flags )
{
GLint att[32];
XWindowAttributes xattrb;
double_buffer_ena = (flags & GLXWIN_DOUBLE_BUFFER) ? 1 : 0;
getAttrbList( att );
printf("Init GLX Context\n");
printf("Double Buffering: %s\n", double_buffer_ena ? "Enabled" : "Disabled");
GdkWindow *gdkWin = gtk_widget_get_window(evbox);
if ( gdkWin == NULL )
{
printf("Error: Failed to obtain gdkWindow Handle for evbox widget\n");
return -1;
}
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");
return -1;
}
if ( XGetWindowAttributes( dpy, win, &xattrb ) == 0 )
{
printf("Error: XGetWindowAttributes failed\n");
return -1;
}
//printf("XWinLocation: (%i,%i) \n", xattrb.x, xattrb.y );
//printf("XWinSize: (%i x %i) \n", xattrb.width, xattrb.height );
//printf("XWinDepth: %i \n", xattrb.depth );
//printf("XWinVisual: %p \n", xattrb.visual );
vi = glXChooseVisual(dpy, 0, att);
if (vi == NULL)
{
printf("\n\tno appropriate visual found\n\n");
exit(0);
}
else {
printf("\n\tvisual %p selected\n", (void *)vi->visualid); /* %p creates hexadecimal output like in glxinfo */
}
if ( glc == NULL )
{
glc = glXCreateContext(dpy, vi, NULL, GL_TRUE);
if ( glc == NULL )
{
printf("Error: glXCreateContext Failed\n");
}
}
XFree(vi); vi = NULL;
glXMakeCurrent(dpy, win, glc);
genTextures( flags & GLXWIN_PIXEL_LINEAR_FILTER ? 1 : 0 );
glDisable(GL_DEPTH_TEST);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Background color to black.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// In a double buffered setup with page flipping, be sure to clear both buffers.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
return 0;
}
//************************************************************************
int destroy_gtk3_GLXContext(void)
{
if ( dpy != NULL )
{
glXMakeCurrent(dpy, None, NULL);
}
if (gltexture)
{
printf("Destroying GLX Texture\n");
glDeleteTextures(1, &gltexture);
gltexture=0;
}
if ( glc != NULL )
{
printf("Destroying GLX Context\n");
glXDestroyContext(dpy, glc); glc = NULL;
}
if ( dpy != NULL )
{
XSync( dpy, False );
}
return 0;
}
//************************************************************************
int gtk3_glx_render(void)
{
screen_width = gtk_draw_area_width;
screen_height = gtk_draw_area_height;
render_image();
return 0;
}
//************************************************************************

77
src/drivers/sdl/glxwin.h Normal file
View File

@ -0,0 +1,77 @@
// glxwin.cpp
//
#ifndef __GLXWIN_H__
#define __GLXWIN_H__
#include <stdint.h>
#include <semaphore.h>
int spawn_glxwin( int flags );
#define GLXWIN_PIXEL_LINEAR_FILTER 0x0001
#define GLXWIN_DOUBLE_BUFFER 0x0002
int init_gtk3_GLXContext( int flags );
int destroy_gtk3_GLXContext( void );
int gtk3_glx_render(void);
#define GLX_NES_WIDTH 256
#define GLX_NES_HEIGHT 256
struct glxwin_shm_t
{
int pid;
int run;
uint32_t render_count;
uint32_t blit_count;
sem_t sem;
int ncol;
int nrow;
int pitch;
// Pass Key Events back to GTK Gui
struct
{
int head;
int tail;
struct {
int type;
int keycode;
int state;
} data[64];
} keyEventBuf;
// Gui Command Event Queue
struct
{
int head;
int tail;
struct {
int id;
union {
int i32[4];
float f32[4];
} param;
} cmd[64];
} guiEvent;
uint32_t pixbuf[65536]; // 256 x 256
void clear_pixbuf(void)
{
memset( pixbuf, 0, sizeof(pixbuf) );
}
};
extern glxwin_shm_t *glx_shm;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -27,13 +27,13 @@
#endif #endif
extern GtkWidget* MainWindow; extern GtkWidget* MainWindow;
extern GtkWidget* evbox; extern GtkWidget* evbox;
extern GtkRadioAction* stateSlot;
extern int GtkMouseData[3]; extern int GtkMouseData[3];
extern bool gtkIsStarted; extern bool gtkIsStarted;
int InitGTKSubsystem(int argc, char** argv); int InitGTKSubsystem(int argc, char** argv);
void pushOutputToGTK(const char* str); void pushOutputToGTK(const char* str);
void showGui(bool b); void showGui(bool b);
void toggleMenuVis(void);
bool checkGTKVersion(int major_required, int minor_required); bool checkGTKVersion(int major_required, int minor_required);
@ -55,6 +55,8 @@ void setGl(GtkWidget* w, gpointer p);
void setDoubleBuffering(GtkWidget* w, gpointer p); void setDoubleBuffering(GtkWidget* w, gpointer p);
#endif #endif
void setStateMenuItem( int i );
void openVideoConfig(); void openVideoConfig();
void openSoundConfig(); void openSoundConfig();
void quit (); void quit ();
@ -82,7 +84,15 @@ void saveStateAs();
void loadStateFrom(); void loadStateFrom();
void quickLoad(); void quickLoad();
void quickSave(); void quickSave();
unsigned short GDKToSDLKeyval(int gdk_key); unsigned int GDKToSDLKeyval(int gdk_key);
int InitGTKSubsystem(int argc, char** argv); 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 );
int destroy_gui_video( void );
void init_cairo_screen(void);
void destroy_cairo_screen(void);
#endif // ifndef FCEUX_GUI_H #endif // ifndef FCEUX_GUI_H

View File

@ -31,6 +31,7 @@
#include "../../movie.h" #include "../../movie.h"
#include "../../fceu.h" #include "../../fceu.h"
#include "../../driver.h" #include "../../driver.h"
#include "../../state.h"
#include "../../utils/xstring.h" #include "../../utils/xstring.h"
#ifdef _S9XLUA_H #ifdef _S9XLUA_H
#include "../../fceulua.h" #include "../../fceulua.h"
@ -48,7 +49,7 @@
#include <cstdio> #include <cstdio>
/** GLOBALS **/ /** GLOBALS **/
int NoWaiting = 1; int NoWaiting = 0;
extern Config *g_config; extern Config *g_config;
extern bool bindSavestate, frameAdvanceLagSkip, lagCounterDisplay; extern bool bindSavestate, frameAdvanceLagSkip, lagCounterDisplay;
@ -136,32 +137,50 @@ DoCheatSeq ()
} }
#include "keyscan.h" #include "keyscan.h"
static uint8 *g_keyState = 0; static uint8 g_keyState[SDL_NUM_SCANCODES];
static int DIPS = 0; static int DIPS = 0;
static uint8 keyonce[MKK_COUNT]; static uint8 keyonce[SDL_NUM_SCANCODES];
#define KEY(__a) g_keyState[MKK(__a)] #define KEY(__a) g_keyState[MKK(__a)]
int getKeyState( int k )
{
if ( (k >= 0) && (k < SDL_NUM_SCANCODES) )
{
return g_keyState[k];
}
return 0;
}
static int static int
_keyonly (int a) _keyonly (int a)
{ {
// check for valid key int sc;
if (a > SDLK_LAST + 1 || a < 0)
return 0; if ( a < 0 )
#if SDL_VERSION_ATLEAST(2, 0, 0)
if (g_keyState[SDL_GetScancodeFromKey (a)])
#else
if (g_keyState[a])
#endif
{ {
if (!keyonce[a]) return 0;
}
sc = SDL_GetScancodeFromKey(a);
// check for valid key
if (sc >= SDL_NUM_SCANCODES || sc < 0)
{
return 0;
}
if (g_keyState[sc])
{
if (!keyonce[sc])
{ {
keyonce[a] = 1; keyonce[sc] = 1;
return 1; return 1;
} }
} }
else { else
keyonce[a] = 0; {
keyonce[sc] = 0;
} }
return 0; return 0;
} }
@ -177,12 +196,12 @@ int Hotkeys[HK_MAX] = { 0 };
// on every cycle of keyboardinput() // on every cycle of keyboardinput()
void void
setHotKeys () setHotKeys (void)
{ {
std::string prefix = "SDL.Hotkeys."; std::string prefix = "SDL.Hotkeys.";
for (int i = 0; i < HK_MAX; i++) for (int i = 0; i < HK_MAX; i++)
{ {
g_config->getOption (prefix + HotkeyStrings[i], &Hotkeys[i]); g_config->getOption (prefix + getHotkeyString(i), &Hotkeys[i]);
} }
return; return;
} }
@ -201,24 +220,6 @@ TogglePause ()
int fullscreen; int fullscreen;
g_config->getOption ("SDL.Fullscreen", &fullscreen); g_config->getOption ("SDL.Fullscreen", &fullscreen);
// Don't touch grab when in windowed mode
if(fullscreen == 0)
return;
#if SDL_VERSION_ATLEAST(2, 0, 0)
// TODO - SDL2
#else
if (FCEUI_EmulationPaused () == 0)
{
SDL_WM_GrabInput (SDL_GRAB_ON);
if(no_cursor)
SDL_ShowCursor (0);
}
else {
SDL_WM_GrabInput (SDL_GRAB_OFF);
SDL_ShowCursor (1);
}
#endif
return; return;
} }
@ -281,16 +282,16 @@ std::string GetFilename (const char *title, bool save, const char *filter)
if (save) if (save)
fileChooser = gtk_file_chooser_dialog_new ("Save as", NULL, fileChooser = gtk_file_chooser_dialog_new ("Save as", NULL,
GTK_FILE_CHOOSER_ACTION_SAVE, GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, "_Cancel",
GTK_RESPONSE_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_SAVE_AS, "_Save",
GTK_RESPONSE_ACCEPT, NULL); GTK_RESPONSE_ACCEPT, NULL);
else else
fileChooser = gtk_file_chooser_dialog_new ("Open", NULL, fileChooser = gtk_file_chooser_dialog_new ("Open", NULL,
GTK_FILE_CHOOSER_ACTION_OPEN, GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, "_Cancel",
GTK_RESPONSE_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, "_Open",
GTK_RESPONSE_ACCEPT, NULL); GTK_RESPONSE_ACCEPT, NULL);
// TODO: make file filters case insensitive // TODO: make file filters case insensitive
@ -432,88 +433,53 @@ void FCEUD_LoadStateFrom ()
unsigned int *GetKeyboard(void) unsigned int *GetKeyboard(void)
{ {
int size = 256; int size = 256;
#if SDL_VERSION_ATLEAST(2, 0, 0)
Uint8* keystate = (Uint8*)SDL_GetKeyboardState(&size); Uint8* keystate = (Uint8*)SDL_GetKeyboardState(&size);
#else
Uint8* keystate = SDL_GetKeyState(&size);
#endif
return (unsigned int*)(keystate); return (unsigned int*)(keystate);
} }
/** /**
* Parse keyboard commands and execute accordingly. * Parse keyboard commands and execute accordingly.
*/ */
static void KeyboardCommands () static void KeyboardCommands (void)
{ {
int is_shift, is_alt; int is_shift, is_alt;
char *movie_fname = "";
// get the keyboard input // get the keyboard input
#if SDL_VERSION_ATLEAST(1, 3, 0)
g_keyState = (Uint8*)SDL_GetKeyboardState (NULL);
#else
g_keyState = SDL_GetKeyState (NULL);
#endif
// check if the family keyboard is enabled // check if the family keyboard is enabled
if (CurInputType[2] == SIFC_FKB) if (CurInputType[2] == SIFC_FKB)
{ {
#if SDL_VERSION_ATLEAST(1, 3, 0) if ( g_keyState[SDL_SCANCODE_SCROLLLOCK] )
// TODO - SDL2 {
if (0) g_fkbEnabled ^= 1;
#else FCEUI_DispMessage ("Family Keyboard %sabled.", 0,
if (keyonly (SCROLLLOCK)) g_fkbEnabled ? "en" : "dis");
#endif }
{
g_fkbEnabled ^= 1;
FCEUI_DispMessage ("Family Keyboard %sabled.", 0,
g_fkbEnabled ? "en" : "dis");
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
// TODO - SDL2
#else
SDL_WM_GrabInput (g_fkbEnabled ? SDL_GRAB_ON : SDL_GRAB_OFF);
#endif
if (g_fkbEnabled) if (g_fkbEnabled)
{ {
return; return;
} }
} }
#if SDL_VERSION_ATLEAST(2, 0, 0) if (g_keyState[SDL_SCANCODE_LSHIFT] || g_keyState[SDL_SCANCODE_RSHIFT])
if (g_keyState[SDL_GetScancodeFromKey (SDLK_LSHIFT)]
|| g_keyState[SDL_GetScancodeFromKey (SDLK_RSHIFT)])
#else
if (g_keyState[SDLK_LSHIFT] || g_keyState[SDLK_RSHIFT])
#endif
is_shift = 1;
else
is_shift = 0;
#if SDL_VERSION_ATLEAST(2, 0, 0)
if (g_keyState[SDL_GetScancodeFromKey (SDLK_LALT)]
|| g_keyState[SDL_GetScancodeFromKey (SDLK_RALT)])
#else
if (g_keyState[SDLK_LALT] || g_keyState[SDLK_RALT])
#endif
{ {
is_alt = 1; is_shift = 1;
#if !SDL_VERSION_ATLEAST(2, 0, 0)
// workaround for GDK->SDL in GTK problems where ALT release is never
// getting sent
// I know this is sort of an ugly hack to fix this, but the bug is
// rather annoying
// prg318 10/23/11
int fullscreen;
g_config->getOption ("SDL.Fullscreen", &fullscreen);
if (!fullscreen)
{
g_keyState[SDLK_LALT] = 0;
g_keyState[SDLK_RALT] = 0;
}
#endif
} }
else else
{
is_shift = 0;
}
if (g_keyState[SDL_SCANCODE_LALT] || g_keyState[SDL_SCANCODE_RALT])
{
is_alt = 1;
}
else
{
is_alt = 0; is_alt = 0;
}
if (_keyonly (Hotkeys[HK_TOGGLE_BG])) if (_keyonly (Hotkeys[HK_TOGGLE_BG]))
@ -529,37 +495,50 @@ static void KeyboardCommands ()
} }
// Alt-Enter to toggle full-screen // Alt-Enter to toggle full-screen
if (keyonly (ENTER) && is_alt) // This is already handled by GTK Accelerator
//if (keyonly (ENTER) && is_alt)
//{
// ToggleFS ();
//}
//
// Alt-M to toggle Main Menu Visibility
if ( is_alt )
{ {
ToggleFS (); if (keyonly (M))
{
toggleMenuVis();
}
} }
// Toggle Movie auto-backup // Toggle Movie auto-backup
if (keyonly (M) && is_shift) if ( is_shift )
{ {
autoMovieBackup ^= 1; if (keyonly (M))
FCEUI_DispMessage ("Automatic movie backup %sabled.", 0, {
autoMovieBackup ? "en" : "dis"); autoMovieBackup ^= 1;
FCEUI_DispMessage ("Automatic movie backup %sabled.", 0,
autoMovieBackup ? "en" : "dis");
}
} }
// Start recording an FM2 movie on Alt+R if ( is_alt )
if (keyonly (R) && is_alt)
{ {
FCEUD_MovieRecordTo (); // Start recording an FM2 movie on Alt+R
} if (keyonly (R))
{
// Save a state from a file FCEUD_MovieRecordTo ();
if (keyonly (S) && is_alt) }
{ // Save a state from a file
FCEUD_SaveStateAs (); if (keyonly (S))
} {
FCEUD_SaveStateAs ();
// Load a state from a file }
if (keyonly (L) && is_alt) // Load a state from a file
{ if (keyonly (L))
FCEUD_LoadStateFrom (); {
FCEUD_LoadStateFrom ();
}
} }
// Famicom disk-system games // Famicom disk-system games
@ -593,10 +572,9 @@ static void KeyboardCommands ()
{ {
if (is_shift) if (is_shift)
{ {
movie_fname = std::string movie_fname = FCEU_MakeFName (FCEUMKF_MOVIE, 0, 0);
const_cast <char *>(FCEU_MakeFName (FCEUMKF_MOVIE, 0, 0).c_str ()); FCEUI_printf ("Recording movie to %s\n", movie_fname.c_str() );
FCEUI_printf ("Recording movie to %s\n", movie_fname); FCEUI_SaveMovie(movie_fname.c_str() , MOVIE_FLAG_NONE, L"");
FCEUI_SaveMovie (movie_fname, MOVIE_FLAG_NONE, L"");
} }
else else
{ {
@ -682,14 +660,14 @@ static void KeyboardCommands ()
} }
// Toggle throttling // Toggle throttling
NoWaiting &= ~1; if ( _keyonly(Hotkeys[HK_TURBO]) )
if (g_keyState[Hotkeys[HK_TURBO]])
{ {
NoWaiting |= 1; NoWaiting ^= 1;
//printf("NoWaiting: 0x%04x\n", NoWaiting );
} }
static bool frameAdvancing = false; static bool frameAdvancing = false;
if (g_keyState[Hotkeys[HK_FRAME_ADVANCE]]) if ( _keyonly(Hotkeys[HK_FRAME_ADVANCE]))
{ {
if (frameAdvancing == false) if (frameAdvancing == false)
{ {
@ -739,22 +717,30 @@ static void KeyboardCommands ()
#endif #endif
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++)
{
if (_keyonly (Hotkeys[HK_SELECT_STATE_0 + i])) if (_keyonly (Hotkeys[HK_SELECT_STATE_0 + i]))
{ {
#ifdef _GTK #ifdef _GTK
gtk_radio_action_set_current_value (stateSlot, i); setStateMenuItem(i);
#endif #endif
FCEUI_SelectState (i, 1); FCEUI_SelectState (i, 1);
} }
}
if (_keyonly (Hotkeys[HK_SELECT_STATE_NEXT])) if (_keyonly (Hotkeys[HK_SELECT_STATE_NEXT]))
{ {
FCEUI_SelectStateNext (1); FCEUI_SelectStateNext (1);
#ifdef _GTK
setStateMenuItem( CurrentState );
#endif
} }
if (_keyonly (Hotkeys[HK_SELECT_STATE_PREV])) if (_keyonly (Hotkeys[HK_SELECT_STATE_PREV]))
{ {
FCEUI_SelectStateNext (-1); FCEUI_SelectStateNext (-1);
#ifdef _GTK
setStateMenuItem( CurrentState );
#endif
} }
if (_keyonly (Hotkeys[HK_BIND_STATE])) if (_keyonly (Hotkeys[HK_BIND_STATE]))
@ -959,6 +945,10 @@ void GetMouseRelative (int32 (&d)[3])
d[2] = md[2]; // buttons d[2] = md[2]; // buttons
} }
//static void checkKeyBoardState( int scanCode )
//{
// printf("Key State is: %i \n", g_keyState[ scanCode ] );
//}
/** /**
* Handles outstanding SDL events. * Handles outstanding SDL events.
*/ */
@ -986,6 +976,15 @@ UpdatePhysicalInput ()
FCEU_printf ("Warning: unknown hotkey event %d\n", FCEU_printf ("Warning: unknown hotkey event %d\n",
event.user.code); event.user.code);
} }
break;
case SDL_KEYDOWN:
case SDL_KEYUP:
//printf("SDL_Event.type: %i Keysym: %i ScanCode: %i\n",
// event.type, event.key.keysym.sym, event.key.keysym.scancode );
g_keyState[ event.key.keysym.scancode ] = (event.type == SDL_KEYDOWN) ? 1 : 0;
//checkKeyBoardState( event.key.keysym.scancode );
break;
default: default:
break; break;
} }
@ -1010,62 +1009,20 @@ int ButtonConfigBegin ()
g_config->getOption ("SDL.NoGUI", &noGui); g_config->getOption ("SDL.NoGUI", &noGui);
if (noGui == 1) if (noGui == 1)
{ {
SDL_QuitSubSystem (SDL_INIT_VIDEO); //SDL_QuitSubSystem (SDL_INIT_VIDEO);
bcpv = KillVideo (); bcpv = KillVideo ();
} }
#else #else
// XXX soules - why are we doing this right before KillVideo()? // XXX soules - why are we doing this right before KillVideo()?
SDL_QuitSubSystem (SDL_INIT_VIDEO); //SDL_QuitSubSystem (SDL_INIT_VIDEO);
// shut down the video and joystick subsystems // shut down the video and joystick subsystems
bcpv = KillVideo (); bcpv = KillVideo ();
#endif #endif
SDL_Surface *screen; //SDL_Surface *screen;
bcpj = KillJoysticks (); bcpj = KillJoysticks ();
// reactivate the video subsystem
if (!SDL_WasInit (SDL_INIT_VIDEO))
{
if (!bcpv)
{
InitVideo (GameInfo);
}
else
{
#if defined(_GTK) && defined(SDL_VIDEO_DRIVER_X11)
if (noGui == 0)
{
while (gtk_events_pending ())
gtk_main_iteration_do (FALSE);
char SDL_windowhack[128];
if (gtk_widget_get_window (evbox))
sprintf (SDL_windowhack, "SDL_WINDOWID=%u",
(unsigned int) GDK_WINDOW_XID (gtk_widget_get_window (evbox)));
#if SDL_VERSION_ATLEAST(2, 0, 0)
// TODO - SDL2
#else
SDL_putenv (SDL_windowhack);
#endif
}
#endif
if (SDL_InitSubSystem (SDL_INIT_VIDEO) == -1)
{
FCEUD_Message (SDL_GetError ());
return 0;
}
// set the screen and notify the user of button configuration
#if SDL_VERSION_ATLEAST(2, 0, 0)
// TODO - SDL2
#else
screen = SDL_SetVideoMode (420, 200, 8, 0);
SDL_WM_SetCaption ("Button Config", 0);
#endif
}
}
// XXX soules - why did we shut this down? // XXX soules - why did we shut this down?
// initialize the joystick subsystem // initialize the joystick subsystem
InitJoysticks (); InitJoysticks ();
@ -1107,13 +1064,8 @@ DTestButton (ButtConfig * bc)
{ {
if (bc->ButtType[x] == BUTTC_KEYBOARD) if (bc->ButtType[x] == BUTTC_KEYBOARD)
{ {
#if SDL_VERSION_ATLEAST(2, 0, 0)
if (g_keyState[SDL_GetScancodeFromKey (bc->ButtonNum[x])]) if (g_keyState[SDL_GetScancodeFromKey (bc->ButtonNum[x])])
{ {
#else
if (g_keyState[bc->ButtonNum[x]])
{
#endif
return 1; return 1;
} }
} }
@ -1124,8 +1076,8 @@ DTestButton (ButtConfig * bc)
return 1; return 1;
} }
} }
} }
return 0; return 0;
} }
@ -1135,15 +1087,9 @@ DTestButton (ButtConfig * bc)
#define GPZ() {MKZ(), MKZ(), MKZ(), MKZ()} #define GPZ() {MKZ(), MKZ(), MKZ(), MKZ()}
ButtConfig GamePadConfig[4][10] = { ButtConfig GamePadConfig[4][10] = {
#if SDL_VERSION_ATLEAST(2, 0, 0)
/* Gamepad 1 */ /* Gamepad 1 */
{MK (KP_3), MK (KP_2), MK (SLASH), MK (ENTER), {MK (KP_3), MK (KP_2), MK (SLASH), MK (ENTER),
MK (W), MK (Z), MK (A), MK (S), MKZ (), MKZ ()}, MK (W), MK (Z), MK (A), MK (S), MKZ (), MKZ ()},
#else
/* Gamepad 1 */
{MK (KP3), MK (KP2), MK (SLASH), MK (ENTER),
MK (W), MK (Z), MK (A), MK (S), MKZ (), MKZ ()},
#endif
/* Gamepad 2 */ /* Gamepad 2 */
GPZ (), GPZ (),
@ -1187,6 +1133,7 @@ UpdateGamepad(void)
{ {
if (DTestButton (&GamePadConfig[wg][x])) if (DTestButton (&GamePadConfig[wg][x]))
{ {
//printf("GamePad%i Button Hit: %i \n", wg, x );
if(opposite_dirs == 0) if(opposite_dirs == 0)
{ {
// test for left+right and up+down // test for left+right and up+down
@ -1413,6 +1360,8 @@ void InitInputInterface ()
int x; int x;
int attrib; int attrib;
memset( g_keyState, 0, sizeof(g_keyState) );
for (t = 0, x = 0; x < 2; x++) for (t = 0, x = 0; x < 2; x++)
{ {
attrib = 0; attrib = 0;
@ -1658,12 +1607,10 @@ const char * ButtonName (const ButtConfig * bc, int which)
switch (bc->ButtType[which]) switch (bc->ButtType[which])
{ {
case BUTTC_KEYBOARD: case BUTTC_KEYBOARD:
#if SDL_VERSION_ATLEAST(2,0,0)
return SDL_GetKeyName (bc->ButtonNum[which]); return SDL_GetKeyName (bc->ButtonNum[which]);
#else break;
return SDL_GetKeyName ((SDLKey) bc->ButtonNum[which]);
#endif
case BUTTC_JOYSTICK: case BUTTC_JOYSTICK:
{
int joyNum, inputNum; int joyNum, inputNum;
const char *inputType, *inputDirection; const char *inputType, *inputDirection;
@ -1685,13 +1632,13 @@ const char * ButtonName (const ButtConfig * bc, int which)
inputValue = bc->ButtonNum[which] & 0xF; inputValue = bc->ButtonNum[which] & 0xF;
if (inputValue & SDL_HAT_UP) if (inputValue & SDL_HAT_UP)
strncat (direction, "Up ", sizeof (direction)); strncat (direction, "Up ", sizeof (direction)-1);
if (inputValue & SDL_HAT_DOWN) if (inputValue & SDL_HAT_DOWN)
strncat (direction, "Down ", sizeof (direction)); strncat (direction, "Down ", sizeof (direction)-1);
if (inputValue & SDL_HAT_LEFT) if (inputValue & SDL_HAT_LEFT)
strncat (direction, "Left ", sizeof (direction)); strncat (direction, "Left ", sizeof (direction)-1);
if (inputValue & SDL_HAT_RIGHT) if (inputValue & SDL_HAT_RIGHT)
strncat (direction, "Right ", sizeof (direction)); strncat (direction, "Right ", sizeof (direction)-1);
if (direction[0]) if (direction[0])
inputDirection = direction; inputDirection = direction;
@ -1704,6 +1651,9 @@ const char * ButtonName (const ButtConfig * bc, int which)
inputNum = bc->ButtonNum[which]; inputNum = bc->ButtonNum[which];
inputDirection = ""; inputDirection = "";
} }
sprintf( name, "js%i:%s%i%s", joyNum, inputType, inputNum, inputDirection );
}
break;
} }
return name; return name;
@ -1713,7 +1663,7 @@ const char * ButtonName (const ButtConfig * bc, int which)
* Waits for a button input and returns the information as to which * Waits for a button input and returns the information as to which
* button was pressed. Used in button configuration. * button was pressed. Used in button configuration.
*/ */
int DWaitButton (const uint8 * text, ButtConfig * bc, int wb) int DWaitButton (const uint8 * text, ButtConfig * bc, int wb, int *buttonConfigStatus )
{ {
SDL_Event event; SDL_Event event;
static int32 LastAx[64][64]; static int32 LastAx[64][64];
@ -1723,11 +1673,8 @@ int DWaitButton (const uint8 * text, ButtConfig * bc, int wb)
{ {
std::string title = "Press a key for "; std::string title = "Press a key for ";
title += (const char *) text; title += (const char *) text;
#if SDL_VERSION_ATLEAST(2,0,0)
// TODO - SDL2 // TODO - SDL2
#else //SDL_WM_SetCaption (title.c_str (), 0);
SDL_WM_SetCaption (title.c_str (), 0);
#endif
puts ((const char *) text); puts ((const char *) text);
} }
@ -1807,6 +1754,16 @@ int DWaitButton (const uint8 * text, ButtConfig * bc, int wb)
} }
if (done) if (done)
break; break;
// If the button config window is Closed,
// get out of loop.
if ( buttonConfigStatus != NULL )
{
if ( *buttonConfigStatus == 0 )
{
break;
}
}
} }
return (0); return (0);
@ -1828,7 +1785,7 @@ ConfigButton (char *text, ButtConfig * bc)
for (wc = 0; wc < MAXBUTTCONFIG; wc++) for (wc = 0; wc < MAXBUTTCONFIG; wc++)
{ {
sprintf ((char *) buf, "%s (%d)", text, wc + 1); sprintf ((char *) buf, "%s (%d)", text, wc + 1);
DWaitButton (buf, bc, wc); DWaitButton (buf, bc, wc, NULL);
if (wc && if (wc &&
bc->ButtType[wc] == bc->ButtType[wc - 1] && bc->ButtType[wc] == bc->ButtType[wc - 1] &&
@ -2041,7 +1998,7 @@ UpdateInput (Config * config)
for (unsigned int i = 0; i < 3; i++) for (unsigned int i = 0; i < 3; i++)
{ {
snprintf (buf, 64, "SDL.Input.%d", i); snprintf (buf, 64, "SDL.Input.%u", i);
config->getOption (buf, &device); config->getOption (buf, &device);
if (device == "None") if (device == "None")
@ -2127,7 +2084,7 @@ UpdateInput (Config * config)
for (unsigned int i = 0; i < GAMEPAD_NUM_DEVICES; i++) for (unsigned int i = 0; i < GAMEPAD_NUM_DEVICES; i++)
{ {
char buf[64]; char buf[64];
snprintf (buf, 20, "SDL.Input.GamePad.%d.", i); snprintf (buf, sizeof(buf)-1, "SDL.Input.GamePad.%u.", i);
prefix = buf; prefix = buf;
config->getOption (prefix + "DeviceType", &device); config->getOption (prefix + "DeviceType", &device);
@ -2160,7 +2117,7 @@ UpdateInput (Config * config)
for (unsigned int i = 0; i < POWERPAD_NUM_DEVICES; i++) for (unsigned int i = 0; i < POWERPAD_NUM_DEVICES; i++)
{ {
char buf[64]; char buf[64];
snprintf (buf, 20, "SDL.Input.PowerPad.%d.", i); snprintf (buf, 32, "SDL.Input.PowerPad.%u.", i);
prefix = buf; prefix = buf;
config->getOption (prefix + "DeviceType", &device); config->getOption (prefix + "DeviceType", &device);

View File

@ -7,7 +7,8 @@
typedef struct { typedef struct {
uint8 ButtType[MAXBUTTCONFIG]; uint8 ButtType[MAXBUTTCONFIG];
uint8 DeviceNum[MAXBUTTCONFIG]; uint8 DeviceNum[MAXBUTTCONFIG];
uint16 ButtonNum[MAXBUTTCONFIG]; //uint16 ButtonNum[MAXBUTTCONFIG];
int ButtonNum[MAXBUTTCONFIG];
uint32 NumC; uint32 NumC;
//uint64 DeviceID[MAXBUTTCONFIG]; /* TODO */ //uint64 DeviceID[MAXBUTTCONFIG]; /* TODO */
} ButtConfig; } ButtConfig;
@ -19,10 +20,11 @@ extern ARGPSTRUCT InputArgs[];
extern int Hotkeys[]; extern int Hotkeys[];
void ParseGIInput(FCEUGI *GI); void ParseGIInput(FCEUGI *GI);
void setHotKeys(); void setHotKeys();
int getKeyState( int k );
int ButtonConfigBegin(); int ButtonConfigBegin();
void ButtonConfigEnd(); void ButtonConfigEnd();
void ConfigButton(char *text, ButtConfig *bc); void ConfigButton(char *text, ButtConfig *bc);
int DWaitButton(const uint8 *text, ButtConfig *bc, int wb); int DWaitButton(const uint8 *text, ButtConfig *bc, int wb, int *buttonConfigStatus = NULL);
#define BUTTC_KEYBOARD 0x00 #define BUTTC_KEYBOARD 0x00
#define BUTTC_JOYSTICK 0x01 #define BUTTC_JOYSTICK 0x01

View File

@ -42,7 +42,3 @@
#define SDLK_SCROLLLOCK SDLK_SCROLLOCK /* I guess the SDL people don't like lots of Ls... */ #define SDLK_SCROLLLOCK SDLK_SCROLLOCK /* I guess the SDL people don't like lots of Ls... */
#define SDLK_GRAVE SDLK_BACKQUOTE #define SDLK_GRAVE SDLK_BACKQUOTE
#define MKK(k) SDLK_##k #define MKK(k) SDLK_##k
#if SDL_VERSION_ATLEAST(2, 0, 0)
#define SDLK_LAST SDL_NUM_SCANCODES
#endif
#define MKK_COUNT (SDLK_LAST+1)

1627
src/drivers/sdl/memview.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,4 @@
// memview.h
//
void openMemoryViewWindow (void);

1235
src/drivers/sdl/ramwatch.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,3 @@
// ramwatch.h
void openMemoryWatchWindow(void);

View File

@ -216,7 +216,7 @@ int FCEUD_GetDataFromServer(uint8 *data)
} }
} }
if(SDLNet_SocketReady(UDPSocket) if(SDLNet_SocketReady(UDPSocket))
{ {

View File

@ -1,251 +0,0 @@
#define GL_GLEXT_LEGACY
#include "sdl.h"
#include "sdl-opengl.h"
#include "../common/vidblit.h"
#include "../../utils/memory.h"
#ifdef APPLEOPENGL
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include <OpenGL/glext.h>
#else
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glext.h>
#endif
#include <cstring>
#include <cstdlib>
#ifndef APIENTRY
#define APIENTRY
#endif
static GLuint textures[2]={0,0}; // Normal image, scanline overlay.
static int left,right,top,bottom; // right and bottom are not inclusive.
static int scanlines;
static void *HiBuffer;
typedef void APIENTRY (*glColorTableEXT_Func)(GLenum target,
GLenum internalformat, GLsizei width, GLenum format, GLenum type,
const GLvoid *table);
glColorTableEXT_Func p_glColorTableEXT;
void
SetOpenGLPalette(uint8 *data)
{
if(!HiBuffer) {
glBindTexture(GL_TEXTURE_2D, textures[0]);
p_glColorTableEXT(GL_TEXTURE_2D, GL_RGB, 256,
GL_RGBA, GL_UNSIGNED_BYTE, data);
} else {
SetPaletteBlitToHigh((uint8*)data);
}
}
void
BlitOpenGL(uint8 *buf)
{
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, textures[0]);
if(HiBuffer) {
Blit8ToHigh(buf, (uint8*)HiBuffer, 256, 240, 256*4, 1, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0,
GL_RGBA, GL_UNSIGNED_BYTE, HiBuffer);
}
else {
//glPixelStorei(GL_UNPACK_ROW_LENGTH, 256);
glTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, 256, 256, 0,
GL_COLOR_INDEX,GL_UNSIGNED_BYTE,buf);
}
glBegin(GL_QUADS);
glTexCoord2f(1.0f*left/256, 1.0f*bottom/256); // Bottom left of picture.
glVertex2f(-1.0f, -1.0f); // Bottom left of target.
glTexCoord2f(1.0f*right/256, 1.0f*bottom/256);// Bottom right of picture.
glVertex2f( 1.0f, -1.0f); // Bottom right of target.
glTexCoord2f(1.0f*right/256, 1.0f*top/256); // Top right of our picture.
glVertex2f( 1.0f, 1.0f); // Top right of target.
glTexCoord2f(1.0f*left/256, 1.0f*top/256); // Top left of our picture.
glVertex2f(-1.0f, 1.0f); // Top left of target.
glEnd();
//glDisable(GL_BLEND);
if(scanlines) {
glEnable(GL_BLEND);
glBindTexture(GL_TEXTURE_2D, textures[1]);
glBlendFunc(GL_DST_COLOR, GL_SRC_ALPHA);
glBegin(GL_QUADS);
glTexCoord2f(1.0f*left/256,
1.0f*bottom/256); // Bottom left of our picture.
glVertex2f(-1.0f, -1.0f); // Bottom left of target.
glTexCoord2f(1.0f*right/256,
1.0f*bottom/256); // Bottom right of our picture.
glVertex2f( 1.0f, -1.0f); // Bottom right of target.
glTexCoord2f(1.0f*right/256,
1.0f*top/256); // Top right of our picture.
glVertex2f( 1.0f, 1.0f); // Top right of target.
glTexCoord2f(1.0f*left/256,
1.0f*top/256); // Top left of our picture.
glVertex2f(-1.0f, 1.0f); // Top left of target.
glEnd();
glDisable(GL_BLEND);
}
SDL_GL_SwapBuffers();
}
void
KillOpenGL(void)
{
if(textures[0]) {
glDeleteTextures(2, &textures[0]);
}
textures[0]=0;
if(HiBuffer) {
free(HiBuffer);
HiBuffer=0;
}
}
/* Rectangle, left, right(not inclusive), top, bottom(not inclusive). */
int
InitOpenGL(int l,
int r,
int t,
int b,
double xscale,
double yscale,
int efx,
int ipolate,
int stretchx,
int stretchy,
SDL_Surface *screen)
{
const char *extensions;
#define LFG(x) if(!(##x = (x##_Func) SDL_GL_GetProcAddress(#x))) return(0);
#define LFGN(x) p_##x = (x##_Func) SDL_GL_GetProcAddress(#x)
// LFG(glBindTexture);
LFGN(glColorTableEXT);
// LFG(glTexImage2D);
// LFG(glBegin);
// LFG(glVertex2f);
// LFG(glTexCoord2f);
// LFG(glEnd);
// LFG(glEnable);
// LFG(glBlendFunc);
// LFG(glGetString);
// LFG(glViewport);
// LFG(glGenTextures);
// LFG(glDeleteTextures);
// LFG(glTexParameteri);
// LFG(glClearColor);
// LFG(glLoadIdentity);
// LFG(glClear);
// LFG(glMatrixMode);
// LFG(glDisable);
left=l;
right=r;
top=t;
bottom=b;
HiBuffer=0;
extensions=(const char*)glGetString(GL_EXTENSIONS);
if((efx&2) || !extensions || !p_glColorTableEXT || !strstr(extensions,"GL_EXT_paletted_texture"))
{
if(!(efx&2)) // Don't want to print out a warning message in this case...
FCEU_printf("Paletted texture extension not found. Using slower texture format...\n");
HiBuffer=FCEU_malloc(4*256*256);
memset(HiBuffer,0x00,4*256*256);
#ifndef LSB_FIRST
InitBlitToHigh(4,0xFF000000,0xFF0000,0xFF00,efx&2,0,0);
#else
InitBlitToHigh(4,0xFF,0xFF00,0xFF0000,efx&2,0,0);
#endif
}
if(screen->flags & SDL_FULLSCREEN)
{
xscale=(double)screen->w / (double)(r-l);
yscale=(double)screen->h / (double)(b-t);
if(xscale<yscale) yscale = xscale;
if(yscale<xscale) xscale = yscale;
}
{
int rw=(int)((r-l)*xscale);
int rh=(int)((b-t)*yscale);
int sx=(screen->w-rw)/2; // Start x
int sy=(screen->h-rh)/2; // Start y
if(stretchx) { sx=0; rw=screen->w; }
if(stretchy) { sy=0; rh=screen->h; }
glViewport(sx, sy, rw, rh);
}
glGenTextures(2, &textures[0]);
scanlines=0;
if(efx&1)
{
uint8 *buf;
int x,y;
scanlines=1;
glBindTexture(GL_TEXTURE_2D, textures[1]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,ipolate?GL_LINEAR:GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,ipolate?GL_LINEAR:GL_NEAREST);
buf=(uint8*)FCEU_dmalloc(256*(256*2)*4);
for(y=0;y<(256*2);y++)
for(x=0;x<256;x++)
{
buf[y*256*4+x*4]=0;
buf[y*256*4+x*4+1]=0;
buf[y*256*4+x*4+2]=0;
buf[y*256*4+x*4+3]=(y&1)?0x00:0xFF; //?0xa0:0xFF; // <-- Pretty
//buf[y*256+x]=(y&1)?0x00:0xFF;
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, (scanlines==2)?256*4:512, 0,
GL_RGBA,GL_UNSIGNED_BYTE,buf);
FCEU_dfree(buf);
}
glBindTexture(GL_TEXTURE_2D, textures[0]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,ipolate?GL_LINEAR:GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,ipolate?GL_LINEAR:GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
glEnable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Background color to black.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// In a double buffered setup with page flipping, be sure to clear both buffers.
glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapBuffers();
glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapBuffers();
return 1;
}

View File

@ -1,6 +0,0 @@
void SetOpenGLPalette(uint8 *data);
void BlitOpenGL(uint8 *buf);
void KillOpenGL(void);
int InitOpenGL(int l, int r, int t, int b, double xscale,double yscale, int efx, int ipolate,
int stretchx, int stretchy, SDL_Surface *screen);

View File

@ -75,25 +75,21 @@ InitSound()
{ {
int sound, soundrate, soundbufsize, soundvolume, soundtrianglevolume, soundsquare1volume, soundsquare2volume, soundnoisevolume, soundpcmvolume, soundq; int sound, soundrate, soundbufsize, soundvolume, soundtrianglevolume, soundsquare1volume, soundsquare2volume, soundnoisevolume, soundpcmvolume, soundq;
SDL_AudioSpec spec; SDL_AudioSpec spec;
const char *driverName;
g_config->getOption("SDL.Sound", &sound); g_config->getOption("SDL.Sound", &sound);
if(!sound) { if (!sound)
{
return 0; return 0;
} }
memset(&spec, 0, sizeof(spec)); memset(&spec, 0, sizeof(spec));
if(SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
{
puts(SDL_GetError()); puts(SDL_GetError());
KillSound(); KillSound();
return 0; return 0;
} }
char driverName[8];
#if SDL_VERSION_ATLEAST(2, 0, 0)
// TODO - SDL 2
#else
SDL_AudioDriverName(driverName, 8);
fprintf(stderr, "Loading SDL sound with %s driver...\n", driverName);
#endif
// load configuration variables // load configuration variables
g_config->getOption("SDL.Sound.Rate", &soundrate); g_config->getOption("SDL.Sound.Rate", &soundrate);
@ -117,21 +113,33 @@ InitSound()
// For safety, set a bare minimum: // For safety, set a bare minimum:
if (s_BufferSize < spec.samples * 2) if (s_BufferSize < spec.samples * 2)
s_BufferSize = spec.samples * 2; {
s_BufferSize = spec.samples * 2;
}
s_Buffer = (int *)FCEU_dmalloc(sizeof(int) * s_BufferSize); s_Buffer = (int *)FCEU_dmalloc(sizeof(int) * s_BufferSize);
if (!s_Buffer) if (!s_Buffer)
{
return 0; return 0;
}
s_BufferRead = s_BufferWrite = s_BufferIn = 0; s_BufferRead = s_BufferWrite = s_BufferIn = 0;
if(SDL_OpenAudio(&spec, 0) < 0) if (SDL_OpenAudio(&spec, 0) < 0)
{ {
puts(SDL_GetError()); puts(SDL_GetError());
KillSound(); KillSound();
return 0; return 0;
} }
SDL_PauseAudio(0); SDL_PauseAudio(0);
driverName = SDL_GetCurrentAudioDriver();
if ( driverName )
{
fprintf(stderr, "Loading SDL sound with %s driver...\n", driverName);
}
FCEUI_SetSoundVolume(soundvolume); FCEUI_SetSoundVolume(soundvolume);
FCEUI_SetSoundQuality(soundq); FCEUI_SetSoundQuality(soundq);
FCEUI_Sound(soundrate); FCEUI_Sound(soundrate);

View File

@ -75,9 +75,13 @@ SpeedThrottle()
else else
InFrame = 0; InFrame = 0;
/*fprintf(stderr, "attempting to sleep %Ld ms, frame complete=%s\n", //fprintf(stderr, "attempting to sleep %Ld ms, frame complete=%s\n",
time_left, InFrame?"no":"yes");*/ // time_left, InFrame?"no":"yes");
SDL_Delay(time_left);
if ( time_left > 0 )
{
SDL_Delay(time_left);
}
if(!InFrame) if(!InFrame)
{ {

View File

@ -22,7 +22,7 @@
/// \brief Handles the graphical game display for the SDL implementation. /// \brief Handles the graphical game display for the SDL implementation.
#include "sdl.h" #include "sdl.h"
#include "sdl-opengl.h" #include "glxwin.h"
#include "../common/vidblit.h" #include "../common/vidblit.h"
#include "../../fceu.h" #include "../../fceu.h"
#include "../../version.h" #include "../../version.h"
@ -55,34 +55,30 @@
extern Config *g_config; extern Config *g_config;
// STATIC GLOBALS // STATIC GLOBALS
extern SDL_Surface *s_screen; static int s_curbpp = 0;
static SDL_Surface *s_BlitBuf; // Buffer when using hardware-accelerated blits.
static SDL_Surface *s_IconSurface = NULL;
static int s_curbpp;
static int s_srendline, s_erendline; static int s_srendline, s_erendline;
static int s_tlines; static int s_tlines;
static int s_inited; static int s_inited = 0;
#ifdef OPENGL #ifdef OPENGL
static int s_useOpenGL; static int s_useOpenGL = 0;
#endif #endif
static double s_exs, s_eys; static double s_exs = 1.0, s_eys = 1.0;
static int s_eefx; static int s_eefx = 0;
static int s_clipSides; static int s_clipSides = 0;
static int s_fullscreen; static int s_fullscreen = 0;
static int noframe; static int noframe = 0;
static int s_nativeWidth = -1; static int initBlitToHighDone = 0;
static int s_nativeHeight = -1;
#define NWIDTH (256 - (s_clipSides ? 16 : 0)) #define NWIDTH (256 - (s_clipSides ? 16 : 0))
#define NOFFSET (s_clipSides ? 8 : 0) #define NOFFSET (s_clipSides ? 8 : 0)
static int s_paletterefresh; static int s_paletterefresh = 1;
extern bool MaxSpeed; extern bool MaxSpeed;
extern unsigned int gtk_draw_area_width;
extern unsigned int gtk_draw_area_height;
/** /**
* Attempts to destroy the graphical video display. Returns 0 on * Attempts to destroy the graphical video display. Returns 0 on
* success, -1 on failure. * success, -1 on failure.
@ -97,29 +93,29 @@ bool FCEUD_ShouldDrawInputAids()
int int
KillVideo() KillVideo()
{ {
// if the IconSurface has been initialized, destroy it //printf("Killing Video\n");
if(s_IconSurface) {
SDL_FreeSurface(s_IconSurface); if ( glx_shm != NULL )
s_IconSurface=0; {
glx_shm->clear_pixbuf();
} }
destroy_gui_video();
// return failure if the video system was not initialized // return failure if the video system was not initialized
if(s_inited == 0) if (s_inited == 0)
return -1; return -1;
// if the rest of the system has been initialized, shut it down // if the rest of the system has been initialized, shut it down
#ifdef OPENGL // // shut down the system that converts from 8 to 16/32 bpp
// check for OpenGL and shut it down // if (s_curbpp > 8)
if(s_useOpenGL) // {
KillOpenGL(); // KillBlitToHigh();
else // }
#endif
// shut down the system that converts from 8 to 16/32 bpp
if(s_curbpp > 8)
KillBlitToHigh();
// SDL Video system is not used.
// shut down the SDL video sub-system // shut down the SDL video sub-system
SDL_QuitSubSystem(SDL_INIT_VIDEO); //SDL_QuitSubSystem(SDL_INIT_VIDEO);
s_inited = 0; s_inited = 0;
return 0; return 0;
@ -127,7 +123,7 @@ KillVideo()
// this variable contains information about the special scaling filters // this variable contains information about the special scaling filters
static int s_sponge; static int s_sponge = 0;
/** /**
* These functions determine an appropriate scale factor for fullscreen/ * These functions determine an appropriate scale factor for fullscreen/
@ -150,24 +146,8 @@ void FCEUD_VideoChanged()
PAL = 0; // NTSC and Dendy PAL = 0; // NTSC and Dendy
} }
#if SDL_VERSION_ATLEAST(2, 0, 0)
int InitVideo(FCEUGI *gi) int InitVideo(FCEUGI *gi)
{ {
// This is a big TODO. Stubbing this off into its own function,
// as the SDL surface routines have changed drastically in SDL2
// TODO - SDL2
}
#else
/**
* Attempts to initialize the graphical video display. Returns 0 on
* success, -1 on failure.
*/
int
InitVideo(FCEUGI *gi)
{
// XXX soules - const? is this necessary?
const SDL_VideoInfo *vinf;
int error, flags = 0;
int doublebuf, xstretch, ystretch, xres, yres, show_fps; int doublebuf, xstretch, ystretch, xres, yres, show_fps;
FCEUI_printf("Initializing video..."); FCEUI_printf("Initializing video...");
@ -178,350 +158,94 @@ InitVideo(FCEUGI *gi)
#ifdef OPENGL #ifdef OPENGL
g_config->getOption("SDL.OpenGL", &s_useOpenGL); g_config->getOption("SDL.OpenGL", &s_useOpenGL);
#endif #endif
g_config->getOption("SDL.SpecialFilter", &s_sponge); //g_config->getOption("SDL.SpecialFilter", &s_sponge);
g_config->getOption("SDL.XStretch", &xstretch); g_config->getOption("SDL.XStretch", &xstretch);
g_config->getOption("SDL.YStretch", &ystretch); g_config->getOption("SDL.YStretch", &ystretch);
g_config->getOption("SDL.LastXRes", &xres); //g_config->getOption("SDL.LastXRes", &xres);
g_config->getOption("SDL.LastYRes", &yres); //g_config->getOption("SDL.LastYRes", &yres);
g_config->getOption("SDL.ClipSides", &s_clipSides); g_config->getOption("SDL.ClipSides", &s_clipSides);
g_config->getOption("SDL.NoFrame", &noframe); g_config->getOption("SDL.NoFrame", &noframe);
g_config->getOption("SDL.ShowFPS", &show_fps); g_config->getOption("SDL.ShowFPS", &show_fps);
//g_config->getOption("SDL.XScale", &s_exs);
//g_config->getOption("SDL.YScale", &s_eys);
uint32_t rmask, gmask, bmask;
s_sponge = 0;
s_exs = 1.0;
s_eys = 1.0;
xres = gtk_draw_area_width;
yres = gtk_draw_area_height;
// check the starting, ending, and total scan lines // check the starting, ending, and total scan lines
FCEUI_GetCurrentVidSystem(&s_srendline, &s_erendline); FCEUI_GetCurrentVidSystem(&s_srendline, &s_erendline);
s_tlines = s_erendline - s_srendline + 1; s_tlines = s_erendline - s_srendline + 1;
// check if we should auto-set x/y resolution init_gui_video( s_useOpenGL );
// check for OpenGL and set the global flags
#ifdef OPENGL
if(s_useOpenGL && !s_sponge) {
flags = SDL_OPENGL;
}
#endif
// initialize the SDL video subsystem if it is not already active
if(!SDL_WasInit(SDL_INIT_VIDEO)) {
error = SDL_InitSubSystem(SDL_INIT_VIDEO);
if(error) {
FCEUD_PrintError(SDL_GetError());
return -1;
}
}
s_inited = 1; s_inited = 1;
// shows the cursor within the display window
SDL_ShowCursor(1);
// determine if we can allocate the display on the video card
vinf = SDL_GetVideoInfo();
if(vinf->hw_available) {
flags |= SDL_HWSURFACE;
}
// get the monitor's current resolution if we do not already have it
if(s_nativeWidth < 0) {
s_nativeWidth = vinf->current_w;
}
if(s_nativeHeight < 0) {
s_nativeHeight = vinf->current_h;
}
// check to see if we are showing FPS // check to see if we are showing FPS
FCEUI_SetShowFPS(show_fps); FCEUI_SetShowFPS(show_fps);
// check if we are rendering fullscreen #ifdef LSB_FIRST
if(s_fullscreen) { rmask = 0x000000FF;
int no_cursor; gmask = 0x0000FF00;
g_config->getOption("SDL.NoFullscreenCursor", &no_cursor); bmask = 0x00FF0000;
flags |= SDL_FULLSCREEN;
SDL_ShowCursor(!no_cursor);
}
else {
SDL_ShowCursor(1);
}
if(noframe) {
flags |= SDL_NOFRAME;
}
// gives the SDL exclusive palette control... ensures the requested colors
flags |= SDL_HWPALETTE;
// enable double buffering if requested and we have hardware support
#ifdef OPENGL
if(s_useOpenGL) {
FCEU_printf("Initializing with OpenGL (Disable with '--opengl 0').\n");
if(doublebuf) {
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
}
} else
#endif
if(doublebuf && (flags & SDL_HWSURFACE)) {
flags |= SDL_DOUBLEBUF;
}
if(s_fullscreen) {
int desbpp, autoscale;
g_config->getOption("SDL.BitsPerPixel", &desbpp);
g_config->getOption("SDL.AutoScale", &autoscale);
if (autoscale)
{
double auto_xscale = GetXScale(xres);
double auto_yscale = GetYScale(yres);
double native_ratio = ((double)NWIDTH) / s_tlines;
double screen_ratio = ((double)xres) / yres;
int keep_ratio;
g_config->getOption("SDL.KeepRatio", &keep_ratio);
// Try to choose resolution
if (screen_ratio < native_ratio)
{
// The screen is narrower than the original. Maximizing width will not clip
auto_xscale = auto_yscale = GetXScale(xres);
if (keep_ratio)
auto_yscale = GetYScale(yres);
}
else
{
auto_yscale = auto_xscale = GetYScale(yres);
if (keep_ratio)
auto_xscale = GetXScale(xres);
}
s_exs = auto_xscale;
s_eys = auto_yscale;
}
else
{
g_config->getOption("SDL.XScale", &s_exs);
g_config->getOption("SDL.YScale", &s_eys);
}
g_config->getOption("SDL.SpecialFX", &s_eefx);
#ifdef OPENGL
if(!s_useOpenGL) {
s_exs = (int)s_exs;
s_eys = (int)s_eys;
} else {
desbpp = 0;
}
if((s_useOpenGL && !xstretch) || !s_useOpenGL)
#endif
if(xres < (NWIDTH * s_exs) || s_exs <= 0.01) {
FCEUD_PrintError("xscale out of bounds.");
KillVideo();
return -1;
}
#ifdef OPENGL
if((s_useOpenGL && !ystretch) || !s_useOpenGL)
#endif
if(yres < int(s_tlines * s_eys) || s_eys <= 0.01) {
FCEUD_PrintError("yscale out of bounds.");
KillVideo();
return -1;
}
#ifdef OPENGL
s_screen = SDL_SetVideoMode(s_useOpenGL ? s_nativeWidth : xres,
s_useOpenGL ? s_nativeHeight : yres,
desbpp, flags);
#else #else
s_screen = SDL_SetVideoMode(xres, yres, desbpp, flags); rmask = 0x00FF0000;
gmask = 0x0000FF00;
bmask = 0x000000FF;
#endif #endif
if(!s_screen) { s_curbpp = 32; // Bits per pixel is always 32
FCEUD_PrintError(SDL_GetError());
return -1;
}
} else {
int desbpp;
g_config->getOption("SDL.BitsPerPixel", &desbpp);
g_config->getOption("SDL.XScale", &s_exs);
g_config->getOption("SDL.YScale", &s_eys);
g_config->getOption("SDL.SpecialFX", &s_eefx);
// -Video Modes Tag-
if(s_sponge) {
if(s_sponge <= 3 && s_sponge >= 1)
{
s_exs = s_eys = 2;
} else if (s_sponge >=4 && s_sponge <= 5)
{
s_exs = s_eys = 3;
} else if (s_sponge >= 6 && s_sponge <= 8)
{
s_exs = s_eys = s_sponge - 4;
}
else if(s_sponge == 9)
{
s_exs = s_eys = 3;
}
else
{
s_exs = s_eys = 1;
}
if(s_sponge == 3) {
xres = 301 * s_exs;
}
s_eefx = 0;
if(s_sponge == 1 || s_sponge == 4) {
desbpp = 32;
}
}
int scrw = NWIDTH * s_exs;
if(s_sponge == 3) {
scrw = 301 * s_exs;
}
#ifdef OPENGL
if(!s_useOpenGL) {
s_exs = (int)s_exs;
s_eys = (int)s_eys;
}
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 defined(_GTK) && defined(SDL_VIDEO_DRIVER_X11) && defined(GDK_WINDOWING_X11)
if(noGui == 0)
{
while (gtk_events_pending())
gtk_main_iteration_do(FALSE);
char SDL_windowhack[128];
sprintf(SDL_windowhack, "SDL_WINDOWID=%u", (unsigned int)GDK_WINDOW_XID(gtk_widget_get_window(evbox)));
SDL_putenv(SDL_windowhack);
// init SDL video
if (SDL_WasInit(SDL_INIT_VIDEO))
SDL_QuitSubSystem(SDL_INIT_VIDEO);
if ( SDL_InitSubSystem(SDL_INIT_VIDEO) < 0 )
{
fprintf(stderr, "Couldn't init SDL video: %s\n", SDL_GetError());
gtk_main_quit();
}
}
#endif
s_screen = SDL_SetVideoMode(scrw, (int)(s_tlines * s_eys),
desbpp, flags);
if(!s_screen) {
FCEUD_PrintError(SDL_GetError());
return -1;
}
#ifdef _GTK
if(noGui == 0)
{
GtkRequisition req;
gtk_widget_size_request(GTK_WIDGET(MainWindow), &req);
gtk_window_resize(GTK_WINDOW(MainWindow), req.width, req.height);
}
#endif
}
s_curbpp = s_screen->format->BitsPerPixel;
if(!s_screen) {
FCEUD_PrintError(SDL_GetError());
KillVideo();
return -1;
}
#if 0
// XXX soules - this would be creating a surface on the video
// card, but was commented out for some reason...
s_BlitBuf = SDL_CreateRGBSurface(SDL_HWSURFACE, 256, 240,
s_screen->format->BitsPerPixel,
s_screen->format->Rmask,
s_screen->format->Gmask,
s_screen->format->Bmask, 0);
#endif
FCEU_printf(" Video Mode: %d x %d x %d bpp %s\n", FCEU_printf(" Video Mode: %d x %d x %d bpp %s\n",
s_screen->w, s_screen->h, s_screen->format->BitsPerPixel, xres, yres, s_curbpp,
s_fullscreen ? "full screen" : ""); s_fullscreen ? "full screen" : "");
if(s_curbpp != 8 && s_curbpp != 16 && s_curbpp != 24 && s_curbpp != 32) { if (s_curbpp != 8 && s_curbpp != 16 && s_curbpp != 24 && s_curbpp != 32)
{
FCEU_printf(" Sorry, %dbpp modes are not supported by FCE Ultra. Supported bit depths are 8bpp, 16bpp, and 32bpp.\n", s_curbpp); FCEU_printf(" Sorry, %dbpp modes are not supported by FCE Ultra. Supported bit depths are 8bpp, 16bpp, and 32bpp.\n", s_curbpp);
KillVideo(); KillVideo();
return -1; return -1;
} }
// if the game being run has a name, set it as the window name
if(gi)
{
if(gi->name) {
SDL_WM_SetCaption((const char *)gi->name, (const char *)gi->name);
} else {
SDL_WM_SetCaption(FCEU_NAME_AND_VERSION,"FCE Ultra");
}
}
// create the surface for displaying graphical messages
#ifdef LSB_FIRST
s_IconSurface = SDL_CreateRGBSurfaceFrom((void *)fceu_playicon.pixel_data,
32, 32, 24, 32 * 3,
0xFF, 0xFF00, 0xFF0000, 0x00);
#else
s_IconSurface = SDL_CreateRGBSurfaceFrom((void *)fceu_playicon.pixel_data,
32, 32, 24, 32 * 3,
0xFF0000, 0xFF00, 0xFF, 0x00);
#endif
SDL_WM_SetIcon(s_IconSurface,0);
s_paletterefresh = 1;
// XXX soules - can't SDL do this for us?
// if using more than 8bpp, initialize the conversion routines
if(s_curbpp > 8) {
InitBlitToHigh(s_curbpp >> 3,
s_screen->format->Rmask,
s_screen->format->Gmask,
s_screen->format->Bmask,
s_eefx, s_sponge, 0);
#ifdef OPENGL #ifdef OPENGL
if(s_useOpenGL) if(s_exs <= 0.01) {
{ FCEUD_PrintError("xscale out of bounds.");
int openGLip; KillVideo();
g_config->getOption("SDL.OpenGLip", &openGLip); return -1;
if(!InitOpenGL(NOFFSET, 256 - (s_clipSides ? 8 : 0),
s_srendline, s_erendline + 1,
s_exs, s_eys, s_eefx,
openGLip, xstretch, ystretch, s_screen))
{
FCEUD_PrintError("Error initializing OpenGL.");
KillVideo();
return -1;
}
}
#endif
} }
if(s_eys <= 0.01) {
FCEUD_PrintError("yscale out of bounds.");
KillVideo();
return -1;
}
if(s_sponge && s_useOpenGL) {
FCEUD_PrintError("scalers not compatible with openGL mode.");
KillVideo();
return -1;
}
#endif
if ( !initBlitToHighDone )
{
InitBlitToHigh(s_curbpp >> 3,
rmask,
gmask,
bmask,
s_eefx, s_sponge, 0);
initBlitToHighDone = 1;
}
return 0; return 0;
} }
#endif
/** /**
* Toggles the full-screen display. * Toggles the full-screen display.
*/ */
void ToggleFS() void ToggleFS(void)
{ {
// pause while we we are making the switch // pause while we we are making the switch
bool paused = FCEUI_EmulationPaused(); bool paused = FCEUI_EmulationPaused();
@ -539,7 +263,7 @@ void ToggleFS()
if(noGui == 0) if(noGui == 0)
{ {
if(!fullscreen) if(!fullscreen)
showGui(0); showGui(0);
else else
showGui(1); showGui(1);
} }
@ -593,22 +317,9 @@ FCEUD_GetPalette(uint8 index,
*/ */
static void RedoPalette() static void RedoPalette()
{ {
#ifdef OPENGL if (s_curbpp > 8)
if(s_useOpenGL)
SetOpenGLPalette((uint8*)s_psdl);
else
#endif
{ {
if(s_curbpp > 8) { SetPaletteBlitToHigh((uint8*)s_psdl);
SetPaletteBlitToHigh((uint8*)s_psdl);
} else
{
#if SDL_VERSION_ATLEAST(2, 0, 0)
//TODO - SDL2
#else
SDL_SetPalette(s_screen, SDL_PHYSPAL, s_psdl, 0, 256);
#endif
}
} }
} }
// XXX soules - console lock/unlock unimplemented? // XXX soules - console lock/unlock unimplemented?
@ -625,126 +336,32 @@ void UnlockConsole(){}
void void
BlitScreen(uint8 *XBuf) BlitScreen(uint8 *XBuf)
{ {
SDL_Surface *TmpScreen;
uint8 *dest; uint8 *dest;
int xo = 0, yo = 0; int w, h, pitch;
if(!s_screen) {
return;
}
// refresh the palette if required // refresh the palette if required
if(s_paletterefresh) { if (s_paletterefresh)
{
RedoPalette(); RedoPalette();
s_paletterefresh = 0; s_paletterefresh = 0;
} }
#ifdef OPENGL
// OpenGL is handled separately
if(s_useOpenGL) {
BlitOpenGL(XBuf);
return;
}
#endif
// XXX soules - not entirely sure why this is being done yet // XXX soules - not entirely sure why this is being done yet
XBuf += s_srendline * 256; XBuf += s_srendline * 256;
if(s_BlitBuf) { dest = (uint8*)getGuiPixelBuffer( &w, &h, &pitch );
TmpScreen = s_BlitBuf;
} else {
TmpScreen = s_screen;
}
// lock the display, if necessary glx_shm->ncol = NWIDTH;
if(SDL_MUSTLOCK(TmpScreen)) { glx_shm->nrow = s_tlines;
if(SDL_LockSurface(TmpScreen) < 0) { glx_shm->pitch = pitch;
return;
}
}
dest = (uint8*)TmpScreen->pixels; if ( dest == NULL ) return;
if(s_fullscreen) { Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines, pitch, 1, 1);
xo = (int)(((TmpScreen->w - NWIDTH * s_exs)) / 2);
dest += xo * (s_curbpp >> 3);
if(TmpScreen->h > (s_tlines * s_eys)) {
yo = (int)((TmpScreen->h - s_tlines * s_eys) / 2);
dest += yo * TmpScreen->pitch;
}
}
// XXX soules - again, I'm surprised SDL can't handle this guiPixelBufferReDraw();
// perform the blit, converting bpp if necessary
if(s_curbpp > 8) {
if(s_BlitBuf) {
Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines,
TmpScreen->pitch, 1, 1);
} else {
Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines,
TmpScreen->pitch, (int)s_exs, (int)s_eys);
}
} else {
if(s_BlitBuf) {
Blit8To8(XBuf + NOFFSET, dest, NWIDTH, s_tlines,
TmpScreen->pitch, 1, 1, 0, s_sponge);
} else {
Blit8To8(XBuf + NOFFSET, dest, NWIDTH, s_tlines,
TmpScreen->pitch, (int)s_exs, (int)s_eys,
s_eefx, s_sponge);
}
}
// unlock the display, if necessary
if(SDL_MUSTLOCK(TmpScreen)) {
SDL_UnlockSurface(TmpScreen);
}
int scrw;
if(s_sponge == 3) { // NTSC 2x
scrw = 301;
} else {
scrw = NWIDTH;
}
// if we have a hardware video buffer, do a fast video->video copy
if(s_BlitBuf) {
SDL_Rect srect;
SDL_Rect drect;
srect.x = 0;
srect.y = 0;
srect.w = scrw;
srect.h = s_tlines;
drect.x = 0;
drect.y = 0;
drect.w = (Uint16)(s_exs * scrw);
drect.h = (Uint16)(s_eys * s_tlines);
SDL_BlitSurface(s_BlitBuf, &srect, s_screen, &drect);
}
// ensure that the display is updated
#if SDL_VERSION_ATLEAST(2, 0, 0)
//TODO - SDL2
#else
SDL_UpdateRect(s_screen, xo, yo,
(Uint32)(scrw * s_exs), (Uint32)(s_tlines * s_eys));
#endif
#ifdef CREATE_AVI #ifdef CREATE_AVI
#if 0 /* PAL INTO NTSC HACK */
{ int fps = FCEUI_GetDesiredFPS();
if(FCEUI_GetDesiredFPS() == 838977920) fps = 1008307711;
NESVideoLoggingVideo(s_screen->pixels, width,height, fps, s_curbpp);
if(FCEUI_GetDesiredFPS() == 838977920)
{
static unsigned dup=0;
if(++dup==5) { dup=0;
NESVideoLoggingVideo(s_screen->pixels, width,height, fps, s_curbpp); }
} }
#else
{ int fps = FCEUI_GetDesiredFPS(); { int fps = FCEUI_GetDesiredFPS();
static unsigned char* result = NULL; static unsigned char* result = NULL;
static unsigned resultsize = 0; static unsigned resultsize = 0;
@ -774,10 +391,10 @@ BlitScreen(uint8 *XBuf)
break; break;
#endif #endif
default: default:
NESVideoLoggingVideo(s_screen->pixels, width,height, fps, s_curbpp); NESVideoLoggingVideo( dest, width,height, fps, s_curbpp);
} }
} }
#endif #endif // CREATE_AVI
#if REALTIME_LOGGING #if REALTIME_LOGGING
{ {
@ -804,17 +421,8 @@ BlitScreen(uint8 *XBuf)
} }
memcpy(&last_time, &cur_time, sizeof(last_time)); memcpy(&last_time, &cur_time, sizeof(last_time));
} }
#endif #endif // REALTIME_LOGGING
#endif
#if SDL_VERSION_ATLEAST(2, 0, 0)
// TODO
#else
// have to flip the displayed buffer in the case of double buffering
if(s_screen->flags & SDL_DOUBLEBUF) {
SDL_Flip(s_screen);
}
#endif
} }
/** /**

View File

@ -9,7 +9,6 @@
uint32 PtoV(uint16 x, uint16 y); uint32 PtoV(uint16 x, uint16 y);
bool FCEUD_ShouldDrawInputAids(); bool FCEUD_ShouldDrawInputAids();
bool FCEUI_AviDisableMovieMessages(); bool FCEUI_AviDisableMovieMessages();
static SDL_Surface *s_screen;
bool FCEUI_AviEnableHUDrecording(); bool FCEUI_AviEnableHUDrecording();
void FCEUI_SetAviEnableHUDrecording(bool enable); void FCEUI_SetAviEnableHUDrecording(bool enable);
bool FCEUI_AviDisableMovieMessages(); bool FCEUI_AviDisableMovieMessages();

View File

@ -16,6 +16,7 @@
#include "sdl.h" #include "sdl.h"
#include "sdl-video.h" #include "sdl-video.h"
#include "unix-netplay.h" #include "unix-netplay.h"
#include "glxwin.h"
#include "../common/configSys.h" #include "../common/configSys.h"
#include "../../oldmovie.h" #include "../../oldmovie.h"
@ -171,13 +172,9 @@ static void ShowUsage(char *prog)
#endif #endif
puts(""); puts("");
printf("Compiled with SDL version %d.%d.%d\n", SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL ); printf("Compiled with SDL version %d.%d.%d\n", SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL );
#if SDL_VERSION_ATLEAST(2, 0, 0) SDL_version v;
SDL_version* v; SDL_GetVersion(&v);
SDL_GetVersion(v); printf("Linked with SDL version %d.%d.%d\n", v.major, v.minor, v.patch);
#else
const SDL_version* v = SDL_Linked_Version();
#endif
printf("Linked with SDL version %d.%d.%d\n", v->major, v->minor, v->patch);
#ifdef GTK #ifdef GTK
printf("Compiled with GTK version %d.%d.%d\n", GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION ); 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 ); //printf("Linked with GTK version %d.%d.%d\n", GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION );
@ -193,9 +190,9 @@ static void ShowUsage(char *prog)
*/ */
int LoadGame(const char *path) int LoadGame(const char *path)
{ {
if (isloaded){ if (isloaded){
CloseGame(); CloseGame();
} }
if(!FCEUI_LoadGame(path, 1)) { if(!FCEUI_LoadGame(path, 1)) {
return 0; return 0;
} }
@ -560,9 +557,9 @@ int main(int argc, char *argv[])
return(-1); return(-1);
} }
#ifdef OPENGL //#ifdef OPENGL
SDL_GL_LoadLibrary(0); // SDL_GL_LoadLibrary(0);
#endif //#endif
// Initialize the configuration system // Initialize the configuration system
g_config = InitConfig(); g_config = InitConfig();
@ -614,8 +611,8 @@ int main(int argc, char *argv[])
g_config->getOption("SDL.InputCfg", &s); g_config->getOption("SDL.InputCfg", &s);
if(s.size() != 0) if(s.size() != 0)
{ {
InitVideo(GameInfo); InitVideo(GameInfo);
InputCfg(s); InputCfg(s);
} }
// set the FAMICOM PAD 2 Mic thing // set the FAMICOM PAD 2 Mic thing
{ {
@ -679,41 +676,6 @@ int main(int argc, char *argv[])
int yres, xres; int yres, xres;
g_config->getOption("SDL.XResolution", &xres); g_config->getOption("SDL.XResolution", &xres);
g_config->getOption("SDL.YResolution", &yres); g_config->getOption("SDL.YResolution", &yres);
#if SDL_VERSION_ATLEAST(2, 0, 0)
// TODO _ SDL 2.0
#else
const SDL_VideoInfo* vid_info = SDL_GetVideoInfo();
if(xres == 0)
{
if(vid_info != NULL)
{
g_config->setOption("SDL.LastXRes", vid_info->current_w);
}
else
{
g_config->setOption("SDL.LastXRes", 512);
}
}
else
{
g_config->setOption("SDL.LastXRes", xres);
}
if(yres == 0)
{
if(vid_info != NULL)
{
g_config->setOption("SDL.LastYRes", vid_info->current_h);
}
else
{
g_config->setOption("SDL.LastYRes", 448);
}
}
else
{
g_config->setOption("SDL.LastYRes", yres);
}
#endif
int autoResume; int autoResume;
g_config->getOption("SDL.AutoResume", &autoResume); g_config->getOption("SDL.AutoResume", &autoResume);
@ -857,14 +819,20 @@ int main(int argc, char *argv[])
#ifdef _GTK #ifdef _GTK
if(noGui == 0) if(noGui == 0)
{ {
spawn_glxwin(0); // even though it is not spawning a window, still needed for shared memory segment.
gtk_init(&argc, &argv); gtk_init(&argc, &argv);
InitGTKSubsystem(argc, argv); InitGTKSubsystem(argc, argv);
while(gtk_events_pending()) while(gtk_events_pending())
gtk_main_iteration_do(FALSE); gtk_main_iteration_do(FALSE);
// Ensure that the GUI has fully initialized.
// Give the X-server a small amount of time to init.
usleep(100000);
while(gtk_events_pending())
gtk_main_iteration_do(FALSE);
} }
#endif #endif
if(romIndex >= 0) if(romIndex >= 0)
{ {
// load the specified game // load the specified game
error = LoadGame(argv[romIndex]); error = LoadGame(argv[romIndex]);
@ -915,6 +883,15 @@ int main(int argc, char *argv[])
g_config->setOption("SDL.LuaScript", ""); g_config->setOption("SDL.LuaScript", "");
if (s != "") if (s != "")
{ {
#ifdef __linux
// Resolve absolute path to file
char fullpath[2048];
if ( realpath( s.c_str(), fullpath ) != NULL )
{
//printf("Fullpath: '%s'\n", fullpath );
s.assign( fullpath );
}
#endif
FCEU_LoadLuaCode(s.c_str()); FCEU_LoadLuaCode(s.c_str());
} }
#endif #endif
@ -934,11 +911,18 @@ int main(int argc, char *argv[])
while(1) while(1)
{ {
if(GameInfo) if(GameInfo)
{
DoFun(frameskip, periodic_saves); DoFun(frameskip, periodic_saves);
}
else else
{
SDL_Delay(1); SDL_Delay(1);
}
while(gtk_events_pending()) while(gtk_events_pending())
gtk_main_iteration_do(FALSE); {
gtk_main_iteration_do(FALSE);
}
} }
} }
else else

View File

@ -145,12 +145,14 @@ public:
class ThreadData { class ThreadData {
public: public:
ThreadData() { kill = dead = false; } ThreadData() { ds = NULL; kill = dead = false; }
OAKRA_Module_OutputDS *ds; OAKRA_Module_OutputDS *ds;
bool kill,dead; bool kill,dead;
}; };
OAKRA_Module_OutputDS::OAKRA_Module_OutputDS() { OAKRA_Module_OutputDS::OAKRA_Module_OutputDS()
{
threadData = NULL;
data = new Data(); data = new Data();
((Data *)data)->global = false; ((Data *)data)->global = false;
InitializeCriticalSection(&((Data *)data)->criticalSection); InitializeCriticalSection(&((Data *)data)->criticalSection);
@ -179,6 +181,7 @@ OAKRA_Voice *OAKRA_Module_OutputDS::getVoice(OAKRA_Format &format, OAKRA_Module
if(dsv->dead) if(dsv->dead)
{ {
delete dsv; delete dsv;
dsv = 0;
} }
else else
{ {
@ -214,7 +217,7 @@ void OAKRA_Module_OutputDS::freeVoiceInternal(OAKRA_Voice *voice, bool internal)
if(!internal) if(!internal)
{ {
delete voice; delete voice;
voice = 0; //voice = 0; // Assignment of function parameter has no effect outside the function, commenting out to avoid cppcheck warning
} }
unlock(); unlock();
} }

View File

@ -181,7 +181,7 @@ protected:
public: public:
explicit InStream() explicit InStream()
: refCount(0) : refCount(0), size(0)
{} {}
}; };
@ -374,17 +374,21 @@ void initArchiveSystem()
} }
} }
static std::string wstringFromPROPVARIANT(BSTR bstr, bool& success) { static std::string wstringFromPROPVARIANT(BSTR bstr, bool& success)
{
std::string strret;
std::wstring tempfname = bstr; std::wstring tempfname = bstr;
int buflen = tempfname.size()*2; int buflen = tempfname.size()*2;
char* buf = new char[buflen]; char* buf = new char[buflen];
int ret = WideCharToMultiByte(CP_ACP,0,tempfname.c_str(),tempfname.size(),buf,buflen,0,0); int ret = WideCharToMultiByte(CP_ACP,0,tempfname.c_str(),tempfname.size(),buf,buflen,0,0);
if(ret == 0) { if (ret == 0)
{
delete[] buf; delete[] buf;
success = false; success = false;
return strret;
} }
buf[ret] = 0; buf[ret] = 0;
std::string strret = buf; strret = buf;
delete[] buf; delete[] buf;
success = true; success = true;
return strret; return strret;

View File

@ -538,7 +538,7 @@ INT_PTR CALLBACK CheatConsoleCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARA
break; break;
case CHEAT_CONTEXT_POSSI_ADDTOMEMORYWATCH: case CHEAT_CONTEXT_POSSI_ADDTOMEMORYWATCH:
{ {
char addr[16] = { 0 }; char addr[32] = { 0 };
int sel = SendDlgItemMessage(hwndDlg, IDC_CHEAT_LIST_POSSIBILITIES, LVM_GETSELECTIONMARK, 0, 0); int sel = SendDlgItemMessage(hwndDlg, IDC_CHEAT_LIST_POSSIBILITIES, LVM_GETSELECTIONMARK, 0, 0);
if (sel != -1) if (sel != -1)
{ {
@ -816,9 +816,9 @@ INT_PTR CALLBACK CheatConsoleCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARA
if (strchr(buf, ':')) if (strchr(buf, ':'))
{ {
if (strchr(buf, '?')) if (strchr(buf, '?'))
sscanf(buf, "%X:%X?%X", &a, &c, &v); sscanf(buf, "%X:%X?%X", (unsigned int*)&a, (unsigned int*)&c, (unsigned int*)&v);
else else
sscanf(buf, "%X:%X", &a, &v); sscanf(buf, "%X:%X", (unsigned int*)&a, (unsigned int*)&v);
} }
SetDlgItemText(hwndDlg, IDC_CHEAT_ADDR, (LPCSTR)(a == -1 ? "" : U16ToStr(a))); SetDlgItemText(hwndDlg, IDC_CHEAT_ADDR, (LPCSTR)(a == -1 ? "" : U16ToStr(a)));
@ -978,7 +978,7 @@ INT_PTR CALLBACK CheatConsoleCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARA
break; break;
case NM_DBLCLK: case NM_DBLCLK:
{ {
char addr[16]; char addr[32];
sprintf(addr, "%04X", possiList[((NMITEMACTIVATE*)lParam)->iItem].addr); sprintf(addr, "%04X", possiList[((NMITEMACTIVATE*)lParam)->iItem].addr);
AddMemWatch(addr); AddMemWatch(addr);
} }
@ -1035,19 +1035,19 @@ void UpdateCheatListGroupBoxUI()
char temp[64]; char temp[64];
if (FrozenAddressCount < 256) if (FrozenAddressCount < 256)
{ {
sprintf(temp, "Active Cheats %d", FrozenAddressCount); sprintf(temp, "Active Cheats %u", FrozenAddressCount);
EnableWindow(GetDlgItem(hCheat, IDC_BTN_CHEAT_ADD), TRUE); EnableWindow(GetDlgItem(hCheat, IDC_BTN_CHEAT_ADD), TRUE);
EnableWindow(GetDlgItem(hCheat, IDC_BTN_CHEAT_ADDFROMFILE), TRUE); EnableWindow(GetDlgItem(hCheat, IDC_BTN_CHEAT_ADDFROMFILE), TRUE);
} }
else if (FrozenAddressCount == 256) else if (FrozenAddressCount == 256)
{ {
sprintf(temp, "Active Cheats %d (Max Limit)", FrozenAddressCount); sprintf(temp, "Active Cheats %u (Max Limit)", FrozenAddressCount);
EnableWindow(GetDlgItem(hCheat, IDC_BTN_CHEAT_ADD), FALSE); EnableWindow(GetDlgItem(hCheat, IDC_BTN_CHEAT_ADD), FALSE);
EnableWindow(GetDlgItem(hCheat, IDC_BTN_CHEAT_ADDFROMFILE), FALSE); EnableWindow(GetDlgItem(hCheat, IDC_BTN_CHEAT_ADDFROMFILE), FALSE);
} }
else else
{ {
sprintf(temp, "%d Error: Too many cheats loaded!", FrozenAddressCount); sprintf(temp, "%u Error: Too many cheats loaded!", FrozenAddressCount);
EnableWindow(GetDlgItem(hCheat, IDC_BTN_CHEAT_ADD), FALSE); EnableWindow(GetDlgItem(hCheat, IDC_BTN_CHEAT_ADD), FALSE);
EnableWindow(GetDlgItem(hCheat, IDC_BTN_CHEAT_ADDFROMFILE), FALSE); EnableWindow(GetDlgItem(hCheat, IDC_BTN_CHEAT_ADDFROMFILE), FALSE);
} }

View File

@ -1454,7 +1454,7 @@ int GetComboBoxByteSize(HWND hwnd, UINT id, int* value)
if (!GetComboBoxListItemData(hwnd, id, value, buf, true)) if (!GetComboBoxListItemData(hwnd, id, value, buf, true))
{ {
char buf2[4]; char buf2[4];
if (sscanf(buf, "%d%[KMB]", value, buf2) < 2 || !strcmp(buf2, "")) if (sscanf(buf, "%d%3[KMB]", value, buf2) < 2 || !strcmp(buf2, ""))
err = errors::FORMAT_ERR; err = errors::FORMAT_ERR;
else else
{ {
@ -1524,15 +1524,15 @@ bool GetComboBoxListItemData(HWND hwnd, UINT id, int* value, char* buf, bool exa
case IDC_VS_SYSTEM_COMBO: case IDC_VS_SYSTEM_COMBO:
case IDC_VS_PPU_COMBO: case IDC_VS_PPU_COMBO:
case IDC_SYSTEM_EXTEND_COMBO: case IDC_SYSTEM_EXTEND_COMBO:
if (!(success = sscanf(buf, "$%X", value) > 0)) if (!(success = sscanf(buf, "$%X", (unsigned int *)value) > 0))
success = SearchByString(hwnd, id, value, buf); success = SearchByString(hwnd, id, value, buf);
else else
SetDlgItemText(hwnd, id, buf); SetDlgItemText(hwnd, id, buf);
break; break;
case IDC_INPUT_DEVICE_COMBO: case IDC_INPUT_DEVICE_COMBO:
if (success = sscanf(buf, "$%X", value) > 0) if (success = sscanf(buf, "$%X", (unsigned int *)value) > 0)
{ {
char buf2[3]; char buf2[8];
sprintf(buf2, "$%02X", *value); sprintf(buf2, "$%02X", *value);
if (SendDlgItemMessage(hwnd, id, CB_SELECTSTRING, 0, (LPARAM)buf2) == CB_ERR) if (SendDlgItemMessage(hwnd, id, CB_SELECTSTRING, 0, (LPARAM)buf2) == CB_ERR)
SetDlgItemText(hwnd, id, buf); SetDlgItemText(hwnd, id, buf);

View File

@ -38,6 +38,10 @@
#include "sound.h" #include "sound.h"
#include "keyscan.h" #include "keyscan.h"
#ifdef _S9XLUA_H
#include "fceulua.h"
#endif
LPDIRECTINPUT7 lpDI=0; LPDIRECTINPUT7 lpDI=0;
void InitInputPorts(bool fourscore); void InitInputPorts(bool fourscore);
@ -71,6 +75,13 @@ static void PresetImport(int preset);
static uint32 MouseData[3]; static uint32 MouseData[3];
static int32 MouseRelative[3]; static int32 MouseRelative[3];
#ifdef _S9XLUA_H
static uint32 LuaMouseData[3];
#else
static uint32* const LuaMouseData = MouseData;
#endif
//force the input types suggested by the game //force the input types suggested by the game
void ParseGIInput(FCEUGI *gi) void ParseGIInput(FCEUGI *gi)
{ {
@ -505,7 +516,13 @@ void FCEUD_UpdateInput()
if(joy) if(joy)
UpdateGamepad(false); UpdateGamepad(false);
if (mouse) GetMouseData(MouseData); if (mouse)
{
GetMouseData(MouseData);
#ifdef _S9XLUA_H
FCEU_LuaReadZapper(MouseData, LuaMouseData);
#endif
}
if (mouse_relative) GetMouseRelative(MouseRelative); if (mouse_relative) GetMouseRelative(MouseRelative);
} }
} }
@ -553,7 +570,7 @@ void InitInputPorts(bool fourscore)
InputDPtr=MouseData; InputDPtr=MouseData;
break; break;
case SI_ZAPPER: case SI_ZAPPER:
InputDPtr=MouseData; InputDPtr=LuaMouseData;
break; break;
case SI_MOUSE: case SI_MOUSE:
InputDPtr=MouseRelative; InputDPtr=MouseRelative;

View File

@ -52,11 +52,17 @@ struct AddressWatcher
{ {
unsigned int Address; // hardware address unsigned int Address; // hardware address
unsigned int CurValue; unsigned int CurValue;
char* comment = NULL; // NULL means no comment, non-NULL means allocated comment char* comment; // NULL means no comment, non-NULL means allocated comment
bool WrongEndian; bool WrongEndian;
char Size; //'d' = 4 bytes, 'w' = 2 bytes, 'b' = 1 byte, and 'S' means it's a separator. char Size; //'d' = 4 bytes, 'w' = 2 bytes, 'b' = 1 byte, and 'S' means it's a separator.
char Type;//'s' = signed integer, 'u' = unsigned, 'h' = hex, 'b' = binary, 'S' = separator char Type;//'s' = signed integer, 'u' = unsigned, 'h' = hex, 'b' = binary, 'S' = separator
short Cheats; // how many bytes are affected by cheat short Cheats; // how many bytes are affected by cheat
AddressWatcher(void)
{
Address = 0; CurValue = 0; comment = NULL; WrongEndian = false;
Size = 'b'; Type = 's'; Cheats = 0;
}
}; };
// the struct for communicating with add watch window // the struct for communicating with add watch window

View File

@ -133,7 +133,7 @@ void EMUFILE::write64le(u64 val)
size_t EMUFILE::read64le(u64 *Bufo) size_t EMUFILE::read64le(u64 *Bufo)
{ {
u64 buf; u64 buf=0;
if(fread((char*)&buf,8) != 8) if(fread((char*)&buf,8) != 8)
return 0; return 0;
#ifndef LOCAL_BE #ifndef LOCAL_BE
@ -174,7 +174,7 @@ size_t EMUFILE::read32le(s32* Bufo) { return read32le((u32*)Bufo); }
size_t EMUFILE::read32le(u32* Bufo) size_t EMUFILE::read32le(u32* Bufo)
{ {
u32 buf; u32 buf=0;
if(fread(&buf,4)<4) if(fread(&buf,4)<4)
return 0; return 0;
#ifndef LOCAL_BE #ifndef LOCAL_BE
@ -213,7 +213,7 @@ size_t EMUFILE::read16le(s16* Bufo) { return read16le((u16*)Bufo); }
size_t EMUFILE::read16le(u16* Bufo) size_t EMUFILE::read16le(u16* Bufo)
{ {
u32 buf; u32 buf=0;
if(fread(&buf,2)<2) if(fread(&buf,2)<2)
return 0; return 0;
#ifndef LOCAL_BE #ifndef LOCAL_BE

View File

@ -72,6 +72,7 @@ void FCEU_ReloadLuaCode();
void FCEU_LuaStop(); void FCEU_LuaStop();
int FCEU_LuaRunning(); int FCEU_LuaRunning();
void FCEU_LuaReadZapper(const uint32* mouse_in, uint32* mouse_out);
uint8 FCEU_LuaReadJoypad(int,uint8); // HACK - Function needs controller input uint8 FCEU_LuaReadJoypad(int,uint8); // HACK - Function needs controller input
int FCEU_LuaSpeed(); int FCEU_LuaSpeed();
int FCEU_LuaFrameskip(); int FCEU_LuaFrameskip();

View File

@ -104,12 +104,14 @@ void ApplyIPS(FILE *ips, FCEUFILE* fp)
if((offset+size)>(uint32)fp->size) if((offset+size)>(uint32)fp->size)
{ {
// Probably a little slow. // Probably a little slow.
buf=(char *)realloc(buf,offset+size); char *newbuf=(char *)realloc(buf,offset+size);
if(!buf) if(!newbuf)
{ {
free(buf); buf=NULL;
FCEU_printf(" Oops. IPS patch %d(type RLE) goes beyond end of file. Could not allocate memory.\n",count); FCEU_printf(" Oops. IPS patch %d(type RLE) goes beyond end of file. Could not allocate memory.\n",count);
goto end; goto end;
} }
buf=newbuf;
memset(buf+fp->size,0,offset+size-fp->size); memset(buf+fp->size,0,offset+size-fp->size);
fp->size=offset+size; fp->size=offset+size;
} }
@ -127,12 +129,14 @@ void ApplyIPS(FILE *ips, FCEUFILE* fp)
if((offset+size)>(uint32)fp->size) if((offset+size)>(uint32)fp->size)
{ {
// Probably a little slow. // Probably a little slow.
buf=(char *)realloc(buf,offset+size); char *newbuf=(char *)realloc(buf,offset+size);
if(!buf) if(!newbuf)
{ {
free(buf); buf=NULL;
FCEU_printf(" Oops. IPS patch %d(type normal) goes beyond end of file. Could not allocate memory.\n",count); FCEU_printf(" Oops. IPS patch %d(type normal) goes beyond end of file. Could not allocate memory.\n",count);
goto end; goto end;
} }
buf=newbuf;
memset(buf+fp->size,0,offset+size-fp->size); memset(buf+fp->size,0,offset+size-fp->size);
} }
fread(buf+offset,1,size,ips); fread(buf+offset,1,size,ips);
@ -475,9 +479,9 @@ void FCEUI_SetDirOverride(int which, char *n)
va_list ap; va_list ap;
int ret; int ret;
va_start(ap,fmt);
if(!(*strp=(char*)FCEU_dmalloc(2048))) //mbg merge 7/17/06 cast to char* if(!(*strp=(char*)FCEU_dmalloc(2048))) //mbg merge 7/17/06 cast to char*
return(0); return(0);
va_start(ap,fmt);
ret=vsnprintf(*strp,2048,fmt,ap); ret=vsnprintf(*strp,2048,fmt,ap);
va_end(ap); va_end(ap);
return(ret); return(ret);

View File

@ -42,7 +42,7 @@ struct FCEUFILE {
FCEUFILE() FCEUFILE()
: stream(0) : stream(0)
, archiveCount(-1) , archiveCount(-1), archiveIndex(0), size(0), mode(READ)
{} {}
~FCEUFILE() ~FCEUFILE()

View File

@ -484,6 +484,7 @@ static void SetInputStuff(int port)
joyports[port].driver=FCEU_InitVirtualBoy(port); joyports[port].driver=FCEU_InitVirtualBoy(port);
break; break;
case SI_NONE: case SI_NONE:
case SI_UNSET:
joyports[port].driver=&DummyJPort; joyports[port].driver=&DummyJPort;
break; break;
} }
@ -494,6 +495,7 @@ static void SetInputStuffFC()
switch(portFC.type) switch(portFC.type)
{ {
case SIFC_NONE: case SIFC_NONE:
case SIFC_UNSET:
portFC.driver=&DummyPortFC; portFC.driver=&DummyPortFC;
break; break;
case SIFC_ARKANOID: case SIFC_ARKANOID:
@ -721,7 +723,7 @@ const char* FCEUI_CommandTypeNames[]=
"TAS Editor", "TAS Editor",
}; };
static void CommandUnImpl(void); //static void CommandUnImpl(void);
static void CommandToggleDip(void); static void CommandToggleDip(void);
static void CommandStateLoad(void); static void CommandStateLoad(void);
static void CommandStateSave(void); static void CommandStateSave(void);
@ -938,10 +940,11 @@ void FCEUI_HandleEmuCommands(TestCommandState* testfn)
} }
} }
static void CommandUnImpl(void) // Function not currently used
{ //static void CommandUnImpl(void)
FCEU_DispMessage("command '%s' unimplemented.",0, FCEUI_CommandTable[i].name); //{
} // FCEU_DispMessage("command '%s' unimplemented.",0, FCEUI_CommandTable[i].name);
//}
static void CommandToggleDip(void) static void CommandToggleDip(void)
{ {

View File

@ -74,7 +74,7 @@ struct INPUTCFC
extern struct JOYPORT extern struct JOYPORT
{ {
JOYPORT(int _w) JOYPORT(int _w)
: w(_w) : w(_w), attrib(0), type(SI_UNSET), ptr(0), driver(0)
{} {}
int w; int w;

View File

@ -208,6 +208,11 @@ static int wasPaused = FALSE;
// Transparency strength. 255=opaque, 0=so transparent it's invisible // Transparency strength. 255=opaque, 0=so transparent it's invisible
static int transparencyModifier = 255; static int transparencyModifier = 255;
// Our zapper.
static int luazapperx = -1;
static int luazappery = -1;
static int luazapperfire = -1;
// Our joypads. // Our joypads.
static uint8 luajoypads1[4]= { 0xFF, 0xFF, 0xFF, 0xFF }; //x1 static uint8 luajoypads1[4]= { 0xFF, 0xFF, 0xFF, 0xFF }; //x1
static uint8 luajoypads2[4]= { 0x00, 0x00, 0x00, 0x00 }; //0x static uint8 luajoypads2[4]= { 0x00, 0x00, 0x00, 0x00 }; //0x
@ -278,6 +283,9 @@ static const char* toCString(lua_State* L, int idx=0);
static void FCEU_LuaOnStop() static void FCEU_LuaOnStop()
{ {
luaRunning = FALSE; luaRunning = FALSE;
luazapperx = -1;
luazappery = -1;
luazapperfire = -1;
for (int i = 0 ; i < 4 ; i++ ){ for (int i = 0 ; i < 4 ; i++ ){
luajoypads1[i]= 0xFF; // Set these back to pass-through luajoypads1[i]= 0xFF; // Set these back to pass-through
luajoypads2[i]= 0x00; luajoypads2[i]= 0x00;
@ -2536,7 +2544,37 @@ static int zapper_read(lua_State *L){
return 1; return 1;
} }
// zapper.set(table state)
//
// Sets the zapper state for the next frame advance.
static int zapper_set(lua_State* L) {
luaL_checktype(L, 1, LUA_TTABLE);
luazapperx = -1;
luazappery = -1;
luazapperfire = -1;
lua_getfield(L, 1, "x");
if (!lua_isnil(L, -1)) luazapperx = lua_tointeger(L, -1);
lua_pop(L, 1);
lua_getfield(L, 1, "y");
if (!lua_isnil(L, -1)) luazappery = lua_tointeger(L, -1);
lua_pop(L, 1);
lua_getfield(L, 1, "fire");
if (!lua_isnil(L, -1))
{
if (lua_toboolean(L, -1)) // True or string
luazapperfire = 1;
if (lua_toboolean(L, -1) == 0 || lua_isstring(L, -1)) // False or string
luazapperfire = 0;
}
lua_pop(L, 1);
return 0;
}
// table joypad.read(int which = 1) // table joypad.read(int which = 1)
// //
@ -5815,6 +5853,7 @@ static const struct luaL_reg joypadlib[] = {
static const struct luaL_reg zapperlib[] = { static const struct luaL_reg zapperlib[] = {
{"read", zapper_read}, {"read", zapper_read},
{"set", zapper_set},
{NULL,NULL} {NULL,NULL}
}; };
@ -6309,6 +6348,15 @@ int FCEU_LuaRunning() {
return (int) (L != NULL); // should return true if callback functions are active. return (int) (L != NULL); // should return true if callback functions are active.
} }
/**
* Applies zapper.set overrides to zapper input.
*/
void FCEU_LuaReadZapper(const uint32* mouse_in, uint32* mouse_out)
{
mouse_out[0] = luazapperx >= 0 ? luazapperx : mouse_in[0];
mouse_out[1] = luazappery >= 0 ? luazappery : mouse_in[1];
mouse_out[2] = luazapperfire >= 0 ? (luazapperfire | (mouse_in[2] & ~1)) : mouse_in[2];
}
/** /**
* Returns true if Lua would like to steal the given joypad control. * Returns true if Lua would like to steal the given joypad control.

View File

@ -1375,7 +1375,9 @@ static void DoLine(void) {
GameHBIRQHook(); GameHBIRQHook();
} }
#ifdef WIN32
DEBUG(FCEUD_UpdateNTView(scanline, 0)); DEBUG(FCEUD_UpdateNTView(scanline, 0));
#endif
if (SpriteON) if (SpriteON)
RefreshSprites(); RefreshSprites();
@ -1852,7 +1854,9 @@ int FCEUPPU_Loop(int skip) {
for (scanline = 0; scanline < totalscanlines; ) { //scanline is incremented in DoLine. Evil. :/ for (scanline = 0; scanline < totalscanlines; ) { //scanline is incremented in DoLine. Evil. :/
deempcnt[deemp]++; deempcnt[deemp]++;
if (scanline < 240) if (scanline < 240)
#ifdef WIN32
DEBUG(FCEUD_UpdatePPUView(scanline, 1)); DEBUG(FCEUD_UpdatePPUView(scanline, 1));
#endif
DoLine(); DoLine();
if (scanline < normalscanlines || scanline == totalscanlines) if (scanline < normalscanlines || scanline == totalscanlines)
@ -2145,8 +2149,10 @@ int FCEUX_PPU_Loop(int skip) {
ppuphase = PPUPHASE_BG; ppuphase = PPUPHASE_BG;
if (sl != 0 && sl < 241) { // ignore the invisible if (sl != 0 && sl < 241) { // ignore the invisible
#ifdef WIN32
DEBUG(FCEUD_UpdatePPUView(scanline = yp, 1)); DEBUG(FCEUD_UpdatePPUView(scanline = yp, 1));
DEBUG(FCEUD_UpdateNTView(scanline = yp, 1)); DEBUG(FCEUD_UpdateNTView(scanline = yp, 1));
#endif
} }
//hack to fix SDF ship intro screen with split. is it right? //hack to fix SDF ship intro screen with split. is it right?

View File

@ -275,7 +275,7 @@ int write64le(uint64 b, EMUFILE* os)
int read32le(uint32 *Bufo, EMUFILE *fp) int read32le(uint32 *Bufo, EMUFILE *fp)
{ {
uint32 buf; uint32 buf=0;
if(fp->_fread(&buf,4)<4) if(fp->_fread(&buf,4)<4)
return 0; return 0;
#ifdef LOCAL_LE #ifdef LOCAL_LE
@ -288,7 +288,7 @@ int read32le(uint32 *Bufo, EMUFILE *fp)
int read16le(u16 *Bufo, EMUFILE *is) int read16le(u16 *Bufo, EMUFILE *is)
{ {
u16 buf; u16 buf=0;
if(is->_fread((char*)&buf,2) != 2) if(is->_fread((char*)&buf,2) != 2)
return 0; return 0;
#ifdef LOCAL_LE #ifdef LOCAL_LE
@ -301,7 +301,7 @@ int read16le(u16 *Bufo, EMUFILE *is)
int read64le(uint64 *Bufo, EMUFILE *is) int read64le(uint64 *Bufo, EMUFILE *is)
{ {
uint64 buf; uint64 buf=0;
if(is->_fread((char*)&buf,8) != 8) if(is->_fread((char*)&buf,8) != 8)
return 0; return 0;
#ifdef LOCAL_LE #ifdef LOCAL_LE

View File

@ -28,10 +28,10 @@ uint32 uppow2(uint32 n)
int x; int x;
for(x=31;x>=0;x--) for(x=31;x>=0;x--)
if(n&(1<<x)) if(n&(1u<<x))
{ {
if((1<<x)!=n) if((1u<<x)!=n)
return(1<<(x+1)); return(1u<<(x+1));
break; break;
} }
return n; return n;

View File

@ -5,7 +5,7 @@ IF ERRORLEVEL 1 IF NOT ERRORLEVEL 2 GOTO UPXFailed
cd ..\output cd ..\output
..\vc\zip -X -9 -r ..\vc\fceux.zip fceux.exe fceux.chm taseditor.chm 7z.dll *.dll palettes luaScripts tools ..\vc\zip -X -9 -r ..\vc\fceux.zip fceux.exe fceux.chm taseditor.chm 7z.dll *.dll palettes luaScripts tools
move /y ..\vc\fceux.exe . move /y ..\vc\fceux.exe .
..\vc\zip -X -9 -r ..\vc\fceux.zip auxlib.lua REM ..\vc\zip -X -9 -r ..\vc\fceux.zip auxlib.lua
cd .. cd ..
REM vc\zip -X -9 -r vc\fceux.zip documentation REM vc\zip -X -9 -r vc\fceux.zip documentation
cd vc cd vc

View File

@ -79,14 +79,14 @@
<li><a href="http://sourceforge.net/projects/fceultra/files/Source%20Code/2.2.3%20src/fceux-2.2.3.src.tar.gz/download">FCEUX 2.2.3 src</a></li> <li><a href="http://sourceforge.net/projects/fceultra/files/Source%20Code/2.2.3%20src/fceux-2.2.3.src.tar.gz/download">FCEUX 2.2.3 src</a></li>
</ul> </ul>
<p>If you are working with a developer to fix an issue affecting you then this is where you will find your fixed build. It may potentially be out of date.</p> <p>If you are working with a developer to fix an issue affecting you then this is where you will find your fixed build:</p>
<ul><li><a href="http://fceux.com/zip">Interim Build $WCREV$</a> $WCDATE$</li></ul> <ul><li><a href="https://ci.appveyor.com/project/zeromus/fceux/build/artifacts">Interim Build</a></li></ul>
<h3>Source Code</h3> <h3>Source Code</h3>
<ul> <ul>
<li><a href="http://sourceforge.net/p/fceultra/code/">SVN repository</a></li> <li><a href="https://github.com/TASVideos/fceux">Git repository</a></li>
</ul> </ul>
<p>FCEUX development is done commited to a subversion repository hosted at sourceforge. The last version of the source can be found there.</p> <p>FCEUX development is done commited to a Git repository hosted at Github. The last version of the source can be found there.</p>
<h4>Compiling</h4> <h4>Compiling</h4>
<ul> <ul>
<li>Win32 uses MS Visual Studio 2010. Newer versions of visual studio should be able to build it, with a little trouble.</li> <li>Win32 uses MS Visual Studio 2010. Newer versions of visual studio should be able to build it, with a little trouble.</li>

View File

@ -418,8 +418,17 @@
<p><span class="rvts37"><br/></span></p> <p><span class="rvts37"><br/></span></p>
<p><span class="rvts37">The return table consists of 3 values: x, y, and fire. &nbsp;x and y are the x,y coordinates of the zapper target in terms of pixels. &nbsp;fire represents the zapper firing. &nbsp;0 = not firing, 1 = firing</span></p> <p><span class="rvts37">The return table consists of 3 values: x, y, and fire. &nbsp;x and y are the x,y coordinates of the zapper target in terms of pixels. &nbsp;fire represents the zapper firing. &nbsp;0 = not firing, 1 = firing</span></p>
<p><span class="rvts37"><br/></span></p> <p><span class="rvts37"><br/></span></p>
<p><span class="rvts64">zapper.set(table input)</span></p>
<p><span class="rvts37"><br/></span></p> <p><span class="rvts37"><br/></span></p>
<p><span class="rvts37">Note: The zapper is always controller 2 on the NES so there is no player argument to this function.</span></p> <p><span class="rvts37">Sets the zapper input state.</span></p>
<p><span class="rvts37"><br/></span></p>
<p><span class="rvts37">Taple entries (nil or -1 to leave unaffected):</span></p>
<p><span class="rvts37">x &nbsp; &nbsp;- Forces the X position </span></p>
<p><span class="rvts37">y &nbsp; &nbsp;- Forces the Y position</span></p>
<p><span class="rvts37">fire - Forces trigger (true/1 on, false/0 off)</span></p>
<p><span class="rvts37"><br/></span></p>
<p><span class="rvts37"><br/></span></p>
<p><span class="rvts37">Note: The zapper is always controller 2 on the NES so there is no player argument to these functions.</span></p>
<p><span class="rvts37"><br/></span></p> <p><span class="rvts37"><br/></span></p>
<p><span class="rvts37"><br/></span></p> <p><span class="rvts37"><br/></span></p>
<p><span class="rvts71">Input Library</span></p> <p><span class="rvts71">Input Library</span></p>