Merge pull request #117 from mjbudd77/master

SDL2 Update
This commit is contained in:
mjbudd77 2020-06-15 21:23:20 -04:00 committed by GitHub
commit b1b6a87c47
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 1485 additions and 1167 deletions

View File

@ -28,7 +28,7 @@ opts.AddVariables(
BoolVariable('SYSTEM_MINIZIP', 'Use system minizip instead of static minizip provided with fceux', 0),
BoolVariable('LSB_FIRST', 'Least signficant byte first (non-PPC)', 1),
BoolVariable('CLANG', 'Compile with llvm-clang instead of gcc', 0),
BoolVariable('SDL2', 'Compile using SDL2 instead of SDL 1.2 (experimental/non-functional)', 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')

View File

@ -32,11 +32,12 @@ sudo apt-get --assume-yes install lua5.1-dev
pkg-config --cflags --libs lua5.1
# Install libSDL-1.2 and libSDL-2
echo '****************************************'
echo 'Install Dependency libsdl1.2-dev'
echo '****************************************'
sudo apt-get --assume-yes install libsdl1.2-dev
sdl-config --cflags --libs
# 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 '****************************************'

View File

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

View File

@ -206,7 +206,7 @@ InitConfig()
config->addOption("SDL.LastXRes", 0);
config->addOption("SDL.LastYRes", 0);
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("keepratio", "SDL.KeepRatio", 1);
config->addOption("xscale", "SDL.XScale", 1.0);
@ -219,8 +219,8 @@ InitConfig()
config->addOption("togglemenu", "SDL.ToggleMenu", 0);
// OpenGL options
config->addOption("opengl", "SDL.OpenGL", 0);
config->addOption("openglip", "SDL.OpenGLip", 0);
config->addOption("opengl", "SDL.OpenGL", 1);
config->addOption("openglip", "SDL.OpenGLip", 1);
config->addOption("SDL.SpecialFilter", 0);
config->addOption("SDL.SpecialFX", 0);
config->addOption("SDL.Vsync", 1);

View File

@ -141,6 +141,12 @@ struct debuggerWin_t
textbuf = NULL;
bp_store = NULL;
bp_tree = NULL;
bkm_store = NULL;
bkm_tree = NULL;
pc_entry = NULL;
A_entry = NULL;
X_entry = NULL;
Y_entry = NULL;
stackview = NULL;
stackTextBuf = NULL;
ppu_label = NULL;

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

@ -33,6 +33,7 @@ extern bool gtkIsStarted;
int InitGTKSubsystem(int argc, char** argv);
void pushOutputToGTK(const char* str);
void showGui(bool b);
void toggleMenuVis(void);
bool checkGTKVersion(int major_required, int minor_required);
@ -83,7 +84,15 @@ void saveStateAs();
void loadStateFrom();
void quickLoad();
void quickSave();
unsigned short GDKToSDLKeyval(int gdk_key);
unsigned int GDKToSDLKeyval(int gdk_key);
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

View File

@ -49,7 +49,7 @@
#include <cstdio>
/** GLOBALS **/
int NoWaiting = 1;
int NoWaiting = 0;
extern Config *g_config;
extern bool bindSavestate, frameAdvanceLagSkip, lagCounterDisplay;
@ -137,32 +137,50 @@ DoCheatSeq ()
}
#include "keyscan.h"
static uint8 *g_keyState = 0;
static uint8 g_keyState[SDL_NUM_SCANCODES];
static int DIPS = 0;
static uint8 keyonce[MKK_COUNT];
static uint8 keyonce[SDL_NUM_SCANCODES];
#define KEY(__a) g_keyState[MKK(__a)]
int getKeyState( int k )
{
if ( (k >= 0) && (k < SDL_NUM_SCANCODES) )
{
return g_keyState[k];
}
return 0;
}
static int
_keyonly (int a)
{
// check for valid key
if (a > SDLK_LAST + 1 || a < 0)
return 0;
#if SDL_VERSION_ATLEAST(2, 0, 0)
if (g_keyState[SDL_GetScancodeFromKey (a)])
#else
if (g_keyState[a])
#endif
int sc;
if ( a < 0 )
{
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;
}
}
else {
keyonce[a] = 0;
else
{
keyonce[sc] = 0;
}
return 0;
}
@ -202,24 +220,6 @@ TogglePause ()
int 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;
}
@ -433,88 +433,53 @@ void FCEUD_LoadStateFrom ()
unsigned int *GetKeyboard(void)
{
int size = 256;
#if SDL_VERSION_ATLEAST(2, 0, 0)
Uint8* keystate = (Uint8*)SDL_GetKeyboardState(&size);
#else
Uint8* keystate = SDL_GetKeyState(&size);
#endif
return (unsigned int*)(keystate);
}
/**
* Parse keyboard commands and execute accordingly.
*/
static void KeyboardCommands ()
static void KeyboardCommands (void)
{
int is_shift, is_alt;
char *movie_fname = "";
// 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
if (CurInputType[2] == SIFC_FKB)
{
#if SDL_VERSION_ATLEAST(1, 3, 0)
// TODO - SDL2
if (0)
#else
if (keyonly (SCROLLLOCK))
#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_keyState[SDL_SCANCODE_SCROLLLOCK] )
{
g_fkbEnabled ^= 1;
FCEUI_DispMessage ("Family Keyboard %sabled.", 0,
g_fkbEnabled ? "en" : "dis");
}
if (g_fkbEnabled)
{
return;
}
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
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
if (g_keyState[SDL_SCANCODE_LSHIFT] || g_keyState[SDL_SCANCODE_RSHIFT])
{
is_alt = 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
is_shift = 1;
}
else
{
is_shift = 0;
}
if (g_keyState[SDL_SCANCODE_LALT] || g_keyState[SDL_SCANCODE_RALT])
{
is_alt = 1;
}
else
{
is_alt = 0;
}
if (_keyonly (Hotkeys[HK_TOGGLE_BG]))
@ -530,37 +495,50 @@ static void KeyboardCommands ()
}
// 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
if (keyonly (M) && is_shift)
if ( is_shift )
{
autoMovieBackup ^= 1;
FCEUI_DispMessage ("Automatic movie backup %sabled.", 0,
autoMovieBackup ? "en" : "dis");
if (keyonly (M))
{
autoMovieBackup ^= 1;
FCEUI_DispMessage ("Automatic movie backup %sabled.", 0,
autoMovieBackup ? "en" : "dis");
}
}
// Start recording an FM2 movie on Alt+R
if (keyonly (R) && is_alt)
if ( is_alt )
{
FCEUD_MovieRecordTo ();
}
// Save a state from a file
if (keyonly (S) && is_alt)
{
FCEUD_SaveStateAs ();
}
// Load a state from a file
if (keyonly (L) && is_alt)
{
FCEUD_LoadStateFrom ();
// Start recording an FM2 movie on Alt+R
if (keyonly (R))
{
FCEUD_MovieRecordTo ();
}
// Save a state from a file
if (keyonly (S))
{
FCEUD_SaveStateAs ();
}
// Load a state from a file
if (keyonly (L))
{
FCEUD_LoadStateFrom ();
}
}
// Famicom disk-system games
@ -594,10 +572,9 @@ static void KeyboardCommands ()
{
if (is_shift)
{
movie_fname =
const_cast <char *>(FCEU_MakeFName (FCEUMKF_MOVIE, 0, 0).c_str ());
FCEUI_printf ("Recording movie to %s\n", movie_fname);
FCEUI_SaveMovie (movie_fname, MOVIE_FLAG_NONE, L"");
std::string movie_fname = FCEU_MakeFName (FCEUMKF_MOVIE, 0, 0);
FCEUI_printf ("Recording movie to %s\n", movie_fname.c_str() );
FCEUI_SaveMovie(movie_fname.c_str() , MOVIE_FLAG_NONE, L"");
}
else
{
@ -683,14 +660,14 @@ static void KeyboardCommands ()
}
// Toggle throttling
NoWaiting &= ~1;
if (g_keyState[Hotkeys[HK_TURBO]])
if ( _keyonly(Hotkeys[HK_TURBO]) )
{
NoWaiting |= 1;
NoWaiting ^= 1;
//printf("NoWaiting: 0x%04x\n", NoWaiting );
}
static bool frameAdvancing = false;
if (g_keyState[Hotkeys[HK_FRAME_ADVANCE]])
if ( _keyonly(Hotkeys[HK_FRAME_ADVANCE]))
{
if (frameAdvancing == false)
{
@ -968,6 +945,10 @@ void GetMouseRelative (int32 (&d)[3])
d[2] = md[2]; // buttons
}
//static void checkKeyBoardState( int scanCode )
//{
// printf("Key State is: %i \n", g_keyState[ scanCode ] );
//}
/**
* Handles outstanding SDL events.
*/
@ -995,6 +976,15 @@ UpdatePhysicalInput ()
FCEU_printf ("Warning: unknown hotkey event %d\n",
event.user.code);
}
break;
case SDL_KEYDOWN:
case SDL_KEYUP:
//printf("SDL_Event.type: %i Keysym: %i ScanCode: %i\n",
// event.type, event.key.keysym.sym, event.key.keysym.scancode );
g_keyState[ event.key.keysym.scancode ] = (event.type == SDL_KEYDOWN) ? 1 : 0;
//checkKeyBoardState( event.key.keysym.scancode );
break;
default:
break;
}
@ -1019,66 +1009,20 @@ int ButtonConfigBegin ()
g_config->getOption ("SDL.NoGUI", &noGui);
if (noGui == 1)
{
SDL_QuitSubSystem (SDL_INIT_VIDEO);
//SDL_QuitSubSystem (SDL_INIT_VIDEO);
bcpv = KillVideo ();
}
#else
// 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
bcpv = KillVideo ();
#endif
SDL_Surface *screen;
//SDL_Surface *screen;
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);
if ( screen == NULL )
{
printf("Error: SDL_SetVideoMode Failed\n");
}
SDL_WM_SetCaption ("Button Config", 0);
#endif
}
}
// XXX soules - why did we shut this down?
// initialize the joystick subsystem
InitJoysticks ();
@ -1120,13 +1064,8 @@ DTestButton (ButtConfig * bc)
{
if (bc->ButtType[x] == BUTTC_KEYBOARD)
{
#if SDL_VERSION_ATLEAST(2, 0, 0)
if (g_keyState[SDL_GetScancodeFromKey (bc->ButtonNum[x])])
{
#else
if (g_keyState[bc->ButtonNum[x]])
{
#endif
return 1;
}
}
@ -1137,8 +1076,8 @@ DTestButton (ButtConfig * bc)
return 1;
}
}
}
return 0;
}
return 0;
}
@ -1148,15 +1087,9 @@ DTestButton (ButtConfig * bc)
#define GPZ() {MKZ(), MKZ(), MKZ(), MKZ()}
ButtConfig GamePadConfig[4][10] = {
#if SDL_VERSION_ATLEAST(2, 0, 0)
/* Gamepad 1 */
{MK (KP_3), MK (KP_2), MK (SLASH), MK (ENTER),
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 */
GPZ (),
@ -1200,6 +1133,7 @@ UpdateGamepad(void)
{
if (DTestButton (&GamePadConfig[wg][x]))
{
//printf("GamePad%i Button Hit: %i \n", wg, x );
if(opposite_dirs == 0)
{
// test for left+right and up+down
@ -1426,6 +1360,8 @@ void InitInputInterface ()
int x;
int attrib;
memset( g_keyState, 0, sizeof(g_keyState) );
for (t = 0, x = 0; x < 2; x++)
{
attrib = 0;
@ -1671,11 +1607,7 @@ const char * ButtonName (const ButtConfig * bc, int which)
switch (bc->ButtType[which])
{
case BUTTC_KEYBOARD:
#if SDL_VERSION_ATLEAST(2,0,0)
return SDL_GetKeyName (bc->ButtonNum[which]);
#else
return SDL_GetKeyName ((SDLKey) bc->ButtonNum[which]);
#endif
break;
case BUTTC_JOYSTICK:
{
@ -1731,7 +1663,7 @@ const char * ButtonName (const ButtConfig * bc, int which)
* Waits for a button input and returns the information as to which
* button was pressed. Used in button configuration.
*/
int DWaitButton (const uint8 * text, ButtConfig * bc, int wb)
int DWaitButton (const uint8 * text, ButtConfig * bc, int wb, int *buttonConfigStatus )
{
SDL_Event event;
static int32 LastAx[64][64];
@ -1741,11 +1673,8 @@ int DWaitButton (const uint8 * text, ButtConfig * bc, int wb)
{
std::string title = "Press a key for ";
title += (const char *) text;
#if SDL_VERSION_ATLEAST(2,0,0)
// TODO - SDL2
#else
SDL_WM_SetCaption (title.c_str (), 0);
#endif
//SDL_WM_SetCaption (title.c_str (), 0);
puts ((const char *) text);
}
@ -1825,6 +1754,16 @@ int DWaitButton (const uint8 * text, ButtConfig * bc, int wb)
}
if (done)
break;
// If the button config window is Closed,
// get out of loop.
if ( buttonConfigStatus != NULL )
{
if ( *buttonConfigStatus == 0 )
{
break;
}
}
}
return (0);
@ -1846,7 +1785,7 @@ ConfigButton (char *text, ButtConfig * bc)
for (wc = 0; wc < MAXBUTTCONFIG; wc++)
{
sprintf ((char *) buf, "%s (%d)", text, wc + 1);
DWaitButton (buf, bc, wc);
DWaitButton (buf, bc, wc, NULL);
if (wc &&
bc->ButtType[wc] == bc->ButtType[wc - 1] &&

View File

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

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;
SDL_AudioSpec spec;
const char *driverName;
g_config->getOption("SDL.Sound", &sound);
if(!sound) {
if (!sound)
{
return 0;
}
memset(&spec, 0, sizeof(spec));
if(SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
{
puts(SDL_GetError());
KillSound();
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
g_config->getOption("SDL.Sound.Rate", &soundrate);
@ -117,21 +113,33 @@ InitSound()
// For safety, set a bare minimum:
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);
if (!s_Buffer)
{
return 0;
}
s_BufferRead = s_BufferWrite = s_BufferIn = 0;
if(SDL_OpenAudio(&spec, 0) < 0)
if (SDL_OpenAudio(&spec, 0) < 0)
{
puts(SDL_GetError());
KillSound();
return 0;
}
}
SDL_PauseAudio(0);
driverName = SDL_GetCurrentAudioDriver();
if ( driverName )
{
fprintf(stderr, "Loading SDL sound with %s driver...\n", driverName);
}
FCEUI_SetSoundVolume(soundvolume);
FCEUI_SetSoundQuality(soundq);
FCEUI_Sound(soundrate);

View File

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

View File

@ -22,7 +22,7 @@
/// \brief Handles the graphical game display for the SDL implementation.
#include "sdl.h"
#include "sdl-opengl.h"
#include "glxwin.h"
#include "../common/vidblit.h"
#include "../../fceu.h"
#include "../../version.h"
@ -55,31 +55,25 @@
extern Config *g_config;
// STATIC GLOBALS
static SDL_Surface *s_screen = NULL;
static SDL_Surface *s_BlitBuf; // Buffer when using hardware-accelerated blits.
static SDL_Surface *s_IconSurface = NULL;
static int s_curbpp;
static int s_curbpp = 0;
static int s_srendline, s_erendline;
static int s_tlines;
static int s_inited;
static int s_inited = 0;
#ifdef OPENGL
static int s_useOpenGL;
static int s_useOpenGL = 0;
#endif
static double s_exs, s_eys;
static int s_eefx;
static int s_clipSides;
static int s_fullscreen;
static int noframe;
static int s_nativeWidth = -1;
static int s_nativeHeight = -1;
static double s_exs = 1.0, s_eys = 1.0;
static int s_eefx = 0;
static int s_clipSides = 0;
static int s_fullscreen = 0;
static int noframe = 0;
static int initBlitToHighDone = 0;
#define NWIDTH (256 - (s_clipSides ? 16 : 0))
#define NOFFSET (s_clipSides ? 8 : 0)
static int s_paletterefresh;
static int s_paletterefresh = 1;
extern bool MaxSpeed;
@ -99,29 +93,29 @@ bool FCEUD_ShouldDrawInputAids()
int
KillVideo()
{
// if the IconSurface has been initialized, destroy it
if(s_IconSurface) {
SDL_FreeSurface(s_IconSurface);
s_IconSurface=0;
//printf("Killing Video\n");
if ( glx_shm != NULL )
{
glx_shm->clear_pixbuf();
}
// return failure if the video system was not initialized
if(s_inited == 0)
return -1;
// if the rest of the system has been initialized, shut it down
#ifdef OPENGL
// check for OpenGL and shut it down
if(s_useOpenGL)
KillOpenGL();
else
#endif
// shut down the system that converts from 8 to 16/32 bpp
if(s_curbpp > 8)
KillBlitToHigh();
destroy_gui_video();
// return failure if the video system was not initialized
if (s_inited == 0)
return -1;
// if the rest of the system has been initialized, shut it down
// // shut down the system that converts from 8 to 16/32 bpp
// if (s_curbpp > 8)
// {
// KillBlitToHigh();
// }
// SDL Video system is not used.
// shut down the SDL video sub-system
SDL_QuitSubSystem(SDL_INIT_VIDEO);
//SDL_QuitSubSystem(SDL_INIT_VIDEO);
s_inited = 0;
return 0;
@ -129,7 +123,7 @@ KillVideo()
// 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/
@ -152,24 +146,8 @@ void FCEUD_VideoChanged()
PAL = 0; // NTSC and Dendy
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
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;
FCEUI_printf("Initializing video...");
@ -180,7 +158,7 @@ InitVideo(FCEUGI *gi)
#ifdef OPENGL
g_config->getOption("SDL.OpenGL", &s_useOpenGL);
#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.YStretch", &ystretch);
//g_config->getOption("SDL.LastXRes", &xres);
@ -188,7 +166,13 @@ InitVideo(FCEUGI *gi)
g_config->getOption("SDL.ClipSides", &s_clipSides);
g_config->getOption("SDL.NoFrame", &noframe);
g_config->getOption("SDL.ShowFPS", &show_fps);
//g_config->getOption("SDL.XScale", &s_exs);
//g_config->getOption("SDL.YScale", &s_eys);
uint32_t rmask, gmask, bmask;
s_sponge = 0;
s_exs = 1.0;
s_eys = 1.0;
xres = gtk_draw_area_width;
yres = gtk_draw_area_height;
// check the starting, ending, and total scan lines
@ -196,339 +180,72 @@ InitVideo(FCEUGI *gi)
FCEUI_GetCurrentVidSystem(&s_srendline, &s_erendline);
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;
// 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
FCEUI_SetShowFPS(show_fps);
// check if we are rendering fullscreen
if(s_fullscreen) {
int no_cursor;
g_config->getOption("SDL.NoFullscreenCursor", &no_cursor);
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);
#ifdef LSB_FIRST
rmask = 0x000000FF;
gmask = 0x0000FF00;
bmask = 0x00FF0000;
#else
s_screen = SDL_SetVideoMode(xres, yres, desbpp, flags);
rmask = 0x00FF0000;
gmask = 0x0000FF00;
bmask = 0x000000FF;
#endif
if(!s_screen) {
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),
s_screen = SDL_SetVideoMode( xres, yres,
desbpp, flags);
if(!s_screen) {
FCEUD_PrintError(SDL_GetError());
return -1;
}
// This code is not needed, gui.cpp handles all window sizing.
//#ifdef _GTK
// if(noGui == 0)
// {
// GtkRequisition req;
// gtk_widget_get_preferred_size(GTK_WIDGET(MainWindow), NULL, &req);
// gtk_window_resize(GTK_WINDOW(MainWindow), req.width, req.height);
// }
//#endif
}
if(!s_screen) {
FCEUD_PrintError(SDL_GetError());
KillVideo();
return -1;
}
s_curbpp = s_screen->format->BitsPerPixel;
#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
s_curbpp = 32; // Bits per pixel is always 32
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" : "");
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);
KillVideo();
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
if(s_useOpenGL)
{
int openGLip;
g_config->getOption("SDL.OpenGLip", &openGLip);
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_exs <= 0.01) {
FCEUD_PrintError("xscale out of bounds.");
KillVideo();
return -1;
}
if(s_eys <= 0.01) {
FCEUD_PrintError("yscale out of bounds.");
KillVideo();
return -1;
}
if(s_sponge && s_useOpenGL) {
FCEUD_PrintError("scalers not compatible with openGL mode.");
KillVideo();
return -1;
}
#endif
if ( !initBlitToHighDone )
{
InitBlitToHigh(s_curbpp >> 3,
rmask,
gmask,
bmask,
s_eefx, s_sponge, 0);
initBlitToHighDone = 1;
}
return 0;
}
#endif
/**
* Toggles the full-screen display.
*/
void ToggleFS()
void ToggleFS(void)
{
// pause while we we are making the switch
bool paused = FCEUI_EmulationPaused();
@ -600,23 +317,10 @@ FCEUD_GetPalette(uint8 index,
*/
static void RedoPalette()
{
#ifdef OPENGL
if(s_useOpenGL)
SetOpenGLPalette((uint8*)s_psdl);
else
#endif
if (s_curbpp > 8)
{
if(s_curbpp > 8) {
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
}
}
SetPaletteBlitToHigh((uint8*)s_psdl);
}
}
// XXX soules - console lock/unlock unimplemented?
@ -632,126 +336,32 @@ void UnlockConsole(){}
void
BlitScreen(uint8 *XBuf)
{
SDL_Surface *TmpScreen;
uint8 *dest;
int xo = 0, yo = 0;
if(!s_screen) {
return;
}
int w, h, pitch;
// refresh the palette if required
if(s_paletterefresh) {
if (s_paletterefresh)
{
RedoPalette();
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
XBuf += s_srendline * 256;
if(s_BlitBuf) {
TmpScreen = s_BlitBuf;
} else {
TmpScreen = s_screen;
}
dest = (uint8*)getGuiPixelBuffer( &w, &h, &pitch );
// lock the display, if necessary
if(SDL_MUSTLOCK(TmpScreen)) {
if(SDL_LockSurface(TmpScreen) < 0) {
return;
}
}
glx_shm->ncol = NWIDTH;
glx_shm->nrow = s_tlines;
glx_shm->pitch = pitch;
dest = (uint8*)TmpScreen->pixels;
if ( dest == NULL ) return;
//if(s_fullscreen) { // Always do this calculation now. Screen resolution is always provided.
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;
}
//}
Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines, pitch, 1, 1);
// XXX soules - again, I'm surprised SDL can't handle this
// 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
guiPixelBufferReDraw();
#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();
static unsigned char* result = NULL;
static unsigned resultsize = 0;
@ -781,10 +391,10 @@ BlitScreen(uint8 *XBuf)
break;
#endif
default:
NESVideoLoggingVideo(s_screen->pixels, width,height, fps, s_curbpp);
NESVideoLoggingVideo( dest, width,height, fps, s_curbpp);
}
}
#endif
#endif // CREATE_AVI
#if REALTIME_LOGGING
{
@ -811,17 +421,8 @@ BlitScreen(uint8 *XBuf)
}
memcpy(&last_time, &cur_time, sizeof(last_time));
}
#endif
#endif
#endif // REALTIME_LOGGING
#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

@ -16,6 +16,7 @@
#include "sdl.h"
#include "sdl-video.h"
#include "unix-netplay.h"
#include "glxwin.h"
#include "../common/configSys.h"
#include "../../oldmovie.h"
@ -171,13 +172,9 @@ static void ShowUsage(char *prog)
#endif
puts("");
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_GetVersion(v);
#else
const SDL_version* v = SDL_Linked_Version();
#endif
printf("Linked with SDL version %d.%d.%d\n", v->major, v->minor, v->patch);
SDL_version v;
SDL_GetVersion(&v);
printf("Linked with SDL version %d.%d.%d\n", v.major, v.minor, v.patch);
#ifdef GTK
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 );
@ -560,9 +557,9 @@ int main(int argc, char *argv[])
return(-1);
}
#ifdef OPENGL
SDL_GL_LoadLibrary(0);
#endif
//#ifdef OPENGL
// SDL_GL_LoadLibrary(0);
//#endif
// Initialize the configuration system
g_config = InitConfig();
@ -679,41 +676,6 @@ int main(int argc, char *argv[])
int yres, xres;
g_config->getOption("SDL.XResolution", &xres);
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;
g_config->getOption("SDL.AutoResume", &autoResume);
@ -857,6 +819,7 @@ int main(int argc, char *argv[])
#ifdef _GTK
if(noGui == 0)
{
spawn_glxwin(0); // even though it is not spawning a window, still needed for shared memory segment.
gtk_init(&argc, &argv);
InitGTKSubsystem(argc, argv);
while(gtk_events_pending())
@ -948,11 +911,18 @@ int main(int argc, char *argv[])
while(1)
{
if(GameInfo)
{
DoFun(frameskip, periodic_saves);
}
else
{
SDL_Delay(1);
}
while(gtk_events_pending())
gtk_main_iteration_do(FALSE);
{
gtk_main_iteration_do(FALSE);
}
}
}
else