Added video driver select option for GTK/SDL GUI. Currently there are 3 possible video drivers: OpenGL GLX, SDL2, and Cairo.

This commit is contained in:
Matthew Budd 2020-08-07 21:22:07 -04:00
parent 5e2ac49da7
commit a2fbb33d68
7 changed files with 304 additions and 163 deletions

View File

@ -207,24 +207,6 @@ int InitVideo(FCEUGI *gi)
return -1; return -1;
} }
#ifdef OPENGL
if(s_exs <= 0.01) {
FCEUD_PrintError("xscale out of bounds.");
KillVideo();
return -1;
}
if(s_eys <= 0.01) {
FCEUD_PrintError("yscale out of bounds.");
KillVideo();
return -1;
}
//if(s_sponge && s_useOpenGL) {
// FCEUD_PrintError("scalers not compatible with openGL mode.");
// KillVideo();
// return -1;
//}
#endif
if ( !initBlitToHighDone ) if ( !initBlitToHighDone )
{ {
InitBlitToHigh(s_curbpp >> 3, InitBlitToHigh(s_curbpp >> 3,

View File

@ -199,6 +199,7 @@ InitConfig()
// video controls // video controls
config->addOption('f', "fullscreen", "SDL.Fullscreen", 0); config->addOption('f', "fullscreen", "SDL.Fullscreen", 0);
config->addOption("videoDriver", "SDL.VideoDriver", 0);
// set x/y res to 0 for automatic fullscreen resolution detection (no change) // set x/y res to 0 for automatic fullscreen resolution detection (no change)
config->addOption('x', "xres", "SDL.XResolution", 0); config->addOption('x', "xres", "SDL.XResolution", 0);

View File

@ -258,7 +258,7 @@ static void render_image(void)
//print_pixbuf(); //print_pixbuf();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0,
GL_RGBA, GL_UNSIGNED_BYTE, glx_shm->pixbuf ); GL_BGRA, GL_UNSIGNED_BYTE, glx_shm->pixbuf );
glBegin(GL_QUADS); glBegin(GL_QUADS);
glTexCoord2f(1.0f*l/256, 1.0f*b/256); // Bottom left of picture. glTexCoord2f(1.0f*l/256, 1.0f*b/256); // Bottom left of picture.

View File

@ -51,6 +51,7 @@
#include <list> #include <list>
#include "glxwin.h" #include "glxwin.h"
#include "sdl-video.h"
// Fix compliation errors for older version of GTK (Ubuntu 10.04 LTS) // Fix compliation errors for older version of GTK (Ubuntu 10.04 LTS)
#if GTK_MINOR_VERSION < 24 && GTK_MAJOR_VERSION == 2 #if GTK_MINOR_VERSION < 24 && GTK_MAJOR_VERSION == 2
@ -81,8 +82,9 @@ bool gtkIsStarted = false;
bool menuTogglingEnabled = false; bool menuTogglingEnabled = false;
static int buttonConfigStatus = 0; static int buttonConfigStatus = 0;
static char useCairoDraw = 0; enum videoDriver_t videoDriver = VIDEO_NONE;
static int drawAreaGL = 0; //static char useCairoDraw = 0;
//static int drawAreaGL = 0;
unsigned int gtk_draw_area_width = NES_WIDTH; unsigned int gtk_draw_area_width = NES_WIDTH;
unsigned int gtk_draw_area_height = NES_HEIGHT; unsigned int gtk_draw_area_height = NES_HEIGHT;
static GtkTreeStore *hotkey_store = NULL; static GtkTreeStore *hotkey_store = NULL;
@ -955,41 +957,13 @@ void resizeGtkWindow (void)
return; return;
} }
void setScaler (GtkWidget * w, gpointer p) static void setVideoDriver (GtkWidget * w, gpointer p)
{ {
int scaler = gtk_combo_box_get_active (GTK_COMBO_BOX (w)); int vdSel = gtk_combo_box_get_active (GTK_COMBO_BOX (w));
int opengl;
g_config->getOption ("SDL.OpenGL", &opengl);
if (opengl && scaler)
{
FCEUD_PrintError ("Scalers not supported in OpenGL mode.");
gtk_combo_box_set_active (GTK_COMBO_BOX (w), 0);
return;
}
g_config->setOption ("SDL.SpecialFilter", scaler); init_gui_video( (videoDriver_t)vdSel );
// 1=hq2x 2=Scale2x 3=NTSC2x 4=hq3x 5=Scale3x 6=Prescale2x 7=Prescale3x 8=Prescale4x 9=pal
switch (scaler)
{
case 4: // hq3x
case 5: // scale3x
case 7: // prescale3x
g_config->setOption ("SDL.XScale", 3.0);
g_config->setOption ("SDL.YScale", 3.0);
resizeGtkWindow ();
break;
case 8: // prescale4x
g_config->setOption ("SDL.XScale", 4.0);
g_config->setOption ("SDL.YScale", 4.0);
break;
default:
g_config->setOption ("SDL.XScale", 2.0);
g_config->setOption ("SDL.YScale", 2.0);
resizeGtkWindow ();
break;
}
g_config->setOption ("SDL.VideoDriver", videoDriver);
g_config->save (); g_config->save ();
} }
@ -1057,8 +1031,8 @@ void openVideoConfig (void)
GtkWidget *lbl; GtkWidget *lbl;
GtkWidget *hbox1; GtkWidget *hbox1;
GtkWidget *scalerLbl; GtkWidget *scalerLbl;
GtkWidget *scalerCombo; GtkWidget *DriverCombo;
GtkWidget *glChk; //GtkWidget *glChk;
GtkWidget *linearChk; GtkWidget *linearChk;
GtkWidget *dbChk; GtkWidget *dbChk;
GtkWidget *palHbox; GtkWidget *palHbox;
@ -1092,42 +1066,26 @@ void openVideoConfig (void)
// scalar widgets // scalar widgets
hbox1 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3); hbox1 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
scalerLbl = gtk_label_new ("Special Scaler: "); scalerLbl = gtk_label_new ("Video Driver: ");
scalerCombo = gtk_combo_box_text_new (); DriverCombo = gtk_combo_box_text_new ();
// -Video Modes Tag- // -Video Modes Tag-
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (scalerCombo), gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (DriverCombo), "OpenGL (GLX)");
"none"); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (DriverCombo), "SDL");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (scalerCombo), gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (DriverCombo), "Cairo");
"hq2x");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (scalerCombo),
"scale2x");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (scalerCombo),
"NTSC 2x");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (scalerCombo),
"hq3x");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (scalerCombo),
"scale3x");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (scalerCombo),
"prescale2x");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (scalerCombo),
"prescale3x");
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (scalerCombo),
"prescale4x");
//gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(scalerCombo), "pal");
// sync with cfg // sync with cfg
int buf; int buf;
g_config->getOption ("SDL.SpecialFilter", &buf); g_config->getOption ("SDL.SpecialFilter", &buf);
gtk_combo_box_set_active (GTK_COMBO_BOX (scalerCombo), buf); gtk_combo_box_set_active (GTK_COMBO_BOX (DriverCombo), buf);
g_signal_connect (scalerCombo, "changed", G_CALLBACK (setScaler), NULL); g_signal_connect (DriverCombo, "changed", G_CALLBACK (setVideoDriver), NULL);
gtk_box_pack_start (GTK_BOX (hbox1), scalerLbl, FALSE, FALSE, 5); gtk_box_pack_start (GTK_BOX (hbox1), scalerLbl, FALSE, FALSE, 5);
gtk_box_pack_start (GTK_BOX (hbox1), scalerCombo, FALSE, FALSE, 5); gtk_box_pack_start (GTK_BOX (hbox1), DriverCombo, FALSE, FALSE, 5);
#ifdef OPENGL #ifdef OPENGL
// openGL check // openGL check
glChk = gtk_check_button_new_with_label ("Enable OpenGL"); //glChk = gtk_check_button_new_with_label ("Enable OpenGL");
g_signal_connect (glChk, "clicked", G_CALLBACK (setGl), NULL); //g_signal_connect (glChk, "clicked", G_CALLBACK (setGl), NULL);
setCheckbox (glChk, "SDL.OpenGL"); //setCheckbox (glChk, "SDL.OpenGL");
// openGL linear filter check // openGL linear filter check
linearChk = linearChk =
@ -1219,7 +1177,7 @@ void openVideoConfig (void)
gtk_box_pack_start (GTK_BOX (vbox), lbl, FALSE, FALSE, 5); gtk_box_pack_start (GTK_BOX (vbox), lbl, FALSE, FALSE, 5);
gtk_box_pack_start (GTK_BOX (vbox), hbox1, FALSE, FALSE, 5); gtk_box_pack_start (GTK_BOX (vbox), hbox1, FALSE, FALSE, 5);
#ifdef OPENGL #ifdef OPENGL
gtk_box_pack_start (GTK_BOX (vbox), glChk, FALSE, FALSE, 5); //gtk_box_pack_start (GTK_BOX (vbox), glChk, FALSE, FALSE, 5);
gtk_box_pack_start (GTK_BOX (vbox), linearChk, FALSE, FALSE, 5); gtk_box_pack_start (GTK_BOX (vbox), linearChk, FALSE, FALSE, 5);
gtk_box_pack_start (GTK_BOX (vbox), dbChk, FALSE, FALSE, 5); gtk_box_pack_start (GTK_BOX (vbox), dbChk, FALSE, FALSE, 5);
#endif #endif
@ -3175,18 +3133,19 @@ static void transferPix2CairoSurface(void)
else else
{ {
// RGBA to ARGB // RGBA to ARGB
#ifdef LSB_FIRST //#ifdef LSB_FIRST
p[i].u8[2] = g[j].u8[0]; p[i].u32 = g[j].u32 | 0xff000000;
p[i].u8[1] = g[j].u8[1]; //p[i].u8[0] = g[j].u8[0];
p[i].u8[0] = g[j].u8[2]; //p[i].u8[1] = g[j].u8[1];
p[i].u8[3] = 0xff; // Force Alpha to full //p[i].u8[2] = g[j].u8[2];
#else //p[i].u8[3] = 0xff; // Force Alpha to full
// Big-Endian is untested. //#else
p[i].u8[2] = g[j].u8[0]; //// Big-Endian is untested.
p[i].u8[1] = g[j].u8[1]; //p[i].u8[2] = g[j].u8[0];
p[i].u8[0] = g[j].u8[2]; //p[i].u8[1] = g[j].u8[1];
p[i].u8[3] = 0xff; // Force Alpha to full //p[i].u8[0] = g[j].u8[2];
#endif //p[i].u8[3] = 0xff; // Force Alpha to full
//#endif
//p[i].u32 = 0xffffffff; //p[i].u32 = 0xffffffff;
} }
i++; i++;
@ -3237,13 +3196,21 @@ int guiPixelBufferReDraw(void)
{ {
glx_shm->blit_count++; glx_shm->blit_count++;
if ( useCairoDraw ) switch ( videoDriver )
{ {
transferPix2CairoSurface(); case VIDEO_CAIRO:
} transferPix2CairoSurface();
else break;
{ case VIDEO_OPENGL_GLX:
gtk3_glx_render(); gtk3_glx_render();
break;
case VIDEO_SDL:
gtk3_sdl_render();
break;
default:
case VIDEO_NONE:
// Nothing to do
break;
} }
return 0; return 0;
@ -3467,33 +3434,57 @@ int destroy_gui_video( void )
destroy_gtk3_GLXContext(); destroy_gtk3_GLXContext();
destroy_gtk3_sdl_video();
videoDriver = VIDEO_NONE;
return 0; return 0;
} }
int init_gui_video( int use_openGL ) int init_gui_video( videoDriver_t videoDriverSelect )
{ {
drawAreaGL = use_openGL; if ( videoDriver == videoDriverSelect )
useCairoDraw = !drawAreaGL;
if ( use_openGL )
{ {
int flags=0; return 0;
int linear_interpolation_ena=0;
int double_buffer_ena=0;
g_config->getOption("SDL.OpenGLip" , &linear_interpolation_ena );
g_config->getOption("SDL.DoubleBuffering", &double_buffer_ena );
if ( linear_interpolation_ena ) flags |= GLXWIN_PIXEL_LINEAR_FILTER;
if ( double_buffer_ena ) flags |= GLXWIN_DOUBLE_BUFFER;
destroy_cairo_screen();
init_gtk3_GLXContext( flags );
} }
else //drawAreaGL = use_openGL;
//useCairoDraw = !drawAreaGL;
destroy_gui_video();
videoDriver = videoDriverSelect;
switch ( videoDriver )
{ {
destroy_gtk3_GLXContext(); case VIDEO_OPENGL_GLX:
init_cairo_screen(); {
int flags=0;
int linear_interpolation_ena=0;
int double_buffer_ena=0;
g_config->getOption("SDL.OpenGLip" , &linear_interpolation_ena );
g_config->getOption("SDL.DoubleBuffering", &double_buffer_ena );
if ( linear_interpolation_ena ) flags |= GLXWIN_PIXEL_LINEAR_FILTER;
if ( double_buffer_ena ) flags |= GLXWIN_DOUBLE_BUFFER;
init_gtk3_GLXContext( flags );
}
break;
case VIDEO_CAIRO:
{
init_cairo_screen();
}
break;
case VIDEO_SDL:
{
init_gtk3_sdl_video();
}
break;
default:
case VIDEO_NONE:
// Nothing to do
break;
} }
return 0; return 0;
} }
@ -3541,7 +3532,7 @@ gboolean handle_resize (GtkWindow * win, GdkEvent * event, gpointer data)
double xscale = width / (double) NES_WIDTH; double xscale = width / (double) NES_WIDTH;
double yscale = height / (double) NES_HEIGHT; double yscale = height / (double) NES_HEIGHT;
//printf("DRAW: %ix%i MenuY: %i \n", draw_width, draw_height, gtk_win_menu_ysize ); printf("DRAW: %ix%i \n", width, height );
if ( (width != gtk_draw_area_width) || (height != gtk_draw_area_height) ) if ( (width != gtk_draw_area_width) || (height != gtk_draw_area_height) )
{ {
@ -3560,9 +3551,21 @@ gboolean handle_resize (GtkWindow * win, GdkEvent * event, gpointer data)
if (yscale > xscale) if (yscale > xscale)
yscale = xscale; yscale = xscale;
if ( useCairoDraw && winsize_changed ) if ( winsize_changed )
{ {
cairo_handle_resize(); switch ( videoDriver )
{
case VIDEO_CAIRO:
cairo_handle_resize();
break;
case VIDEO_SDL:
gtk3_sdl_resize();
break;
default:
case VIDEO_OPENGL_GLX:
// Nothing to do
break;
}
} }
//TODO if openGL make these integers //TODO if openGL make these integers
@ -3630,13 +3633,21 @@ static gboolean draw_cb (GtkWidget * widget, cairo_t * cr, gpointer data)
if ( gtk_draw_area_width < NES_WIDTH ) gtk_draw_area_width = NES_WIDTH; if ( gtk_draw_area_width < NES_WIDTH ) gtk_draw_area_width = NES_WIDTH;
if ( gtk_draw_area_height < NES_HEIGHT ) gtk_draw_area_height = NES_HEIGHT; if ( gtk_draw_area_height < NES_HEIGHT ) gtk_draw_area_height = NES_HEIGHT;
if ( useCairoDraw ) switch ( videoDriver )
{ {
cairo_draw_cb( widget, cr, data ); case VIDEO_CAIRO:
} cairo_draw_cb( widget, cr, data );
else break;
{ case VIDEO_OPENGL_GLX:
gtk3_glx_render(); gtk3_glx_render();
break;
case VIDEO_SDL:
gtk3_sdl_render();
break;
default:
case VIDEO_NONE:
// Nothing to do
break;
} }
return FALSE; return FALSE;
@ -3646,16 +3657,18 @@ static void
drawAreaRealizeCB (GtkWidget *widget, drawAreaRealizeCB (GtkWidget *widget,
gpointer user_data) gpointer user_data)
{ {
printf("Draw Area Realize\n"); int vdSel = VIDEO_OPENGL_GLX;
init_gui_video( drawAreaGL ); g_config->getOption("SDL.VideoDriver", &vdSel);
printf("Draw Area Realize: Video Driver Select: %i\n", vdSel);
init_gui_video( (videoDriver_t)vdSel );
} }
int InitGTKSubsystem (int argc, char **argv) int InitGTKSubsystem (int argc, char **argv)
{ {
int s_useOpenGL=0;
GtkWidget *vbox; GtkWidget *vbox;
MainWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL); MainWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
@ -3688,13 +3701,6 @@ int InitGTKSubsystem (int argc, char **argv)
// //
// prg - Bryan Cain, you are the man! // prg - Bryan Cain, you are the man!
#ifdef OPENGL
g_config->getOption("SDL.OpenGL", &s_useOpenGL);
#endif
drawAreaGL = s_useOpenGL;
useCairoDraw = !drawAreaGL;
evbox = gtk_drawing_area_new (); evbox = gtk_drawing_area_new ();
gtk_box_pack_start (GTK_BOX (vbox), evbox, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (vbox), evbox, TRUE, TRUE, 0);

View File

@ -89,7 +89,16 @@ int InitGTKSubsystem(int argc, char** argv);
uint32_t *getGuiPixelBuffer( int *w, int *h, int *s ); uint32_t *getGuiPixelBuffer( int *w, int *h, int *s );
int guiPixelBufferReDraw(void); int guiPixelBufferReDraw(void);
int init_gui_video( int use_openGL ); enum videoDriver_t
{
VIDEO_NONE = -1,
VIDEO_OPENGL_GLX,
VIDEO_SDL,
VIDEO_CAIRO
};
extern enum videoDriver_t videoDriver;
int init_gui_video( videoDriver_t vd );
int destroy_gui_video( void ); int destroy_gui_video( void );
void init_cairo_screen(void); void init_cairo_screen(void);
void destroy_cairo_screen(void); void destroy_cairo_screen(void);

View File

@ -83,6 +83,11 @@ extern bool MaxSpeed;
extern unsigned int gtk_draw_area_width; extern unsigned int gtk_draw_area_width;
extern unsigned int gtk_draw_area_height; extern unsigned int gtk_draw_area_height;
static SDL_Window *sdlWindow = NULL;
static SDL_Renderer *sdlRenderer = NULL;
static SDL_Texture *sdlTexture = NULL;
/** /**
* Attempts to destroy the graphical video display. Returns 0 on * Attempts to destroy the graphical video display. Returns 0 on
* success, -1 on failure. * success, -1 on failure.
@ -152,6 +157,7 @@ void FCEUD_VideoChanged()
int InitVideo(FCEUGI *gi) int InitVideo(FCEUGI *gi)
{ {
int vdSel;
int doublebuf, xstretch, ystretch, xres, yres, show_fps; int doublebuf, xstretch, ystretch, xres, yres, show_fps;
FCEUI_printf("Initializing video..."); FCEUI_printf("Initializing video...");
@ -184,7 +190,9 @@ int InitVideo(FCEUGI *gi)
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;
init_gui_video( s_useOpenGL ); g_config->getOption("SDL.VideoDriver", &vdSel);
init_gui_video( (videoDriver_t)vdSel );
s_inited = 1; s_inited = 1;
@ -192,9 +200,9 @@ int InitVideo(FCEUGI *gi)
FCEUI_SetShowFPS(show_fps); FCEUI_SetShowFPS(show_fps);
#ifdef LSB_FIRST #ifdef LSB_FIRST
rmask = 0x000000FF; rmask = 0x00FF0000;
gmask = 0x0000FF00; gmask = 0x0000FF00;
bmask = 0x00FF0000; bmask = 0x000000FF;
#else #else
rmask = 0x00FF0000; rmask = 0x00FF0000;
gmask = 0x0000FF00; gmask = 0x0000FF00;
@ -214,24 +222,6 @@ int InitVideo(FCEUGI *gi)
return -1; return -1;
} }
#ifdef OPENGL
if(s_exs <= 0.01) {
FCEUD_PrintError("xscale out of bounds.");
KillVideo();
return -1;
}
if(s_eys <= 0.01) {
FCEUD_PrintError("yscale out of bounds.");
KillVideo();
return -1;
}
if(s_sponge && s_useOpenGL) {
FCEUD_PrintError("scalers not compatible with openGL mode.");
KillVideo();
return -1;
}
#endif
if ( !initBlitToHighDone ) if ( !initBlitToHighDone )
{ {
InitBlitToHigh(s_curbpp >> 3, InitBlitToHigh(s_curbpp >> 3,
@ -471,3 +461,150 @@ void FCEUI_SetAviDisableMovieMessages(bool disable)
{ {
disableMovieMessages = disable; disableMovieMessages = disable;
} }
//*****************************************************************************
int init_gtk3_sdl_video( void )
{
GdkWindow *gdkWin = gtk_widget_get_window(evbox);
Window win;
int vsyncEnabled=0;
if ( gdkWin == NULL )
{
printf("Error: Failed to obtain gdkWindow Handle for evbox widget\n");
return -1;
}
win = GDK_WINDOW_XID( gdkWin );
for (int i=0; i<SDL_GetNumVideoDrivers(); i++)
{
printf("SDL Video Driver %i: %s\n", i, SDL_GetVideoDriver(i) );
}
printf("Using Video Driver: %s \n", SDL_GetCurrentVideoDriver() );
sdlWindow = SDL_CreateWindowFrom( (void*)win);
if (sdlWindow == NULL)
{
printf("[SDL] Failed to create window from handle.\n");
return -1;
}
uint32_t baseFlags = vsyncEnabled ? SDL_RENDERER_PRESENTVSYNC : 0;
sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, baseFlags | SDL_RENDERER_ACCELERATED);
if (sdlRenderer == NULL)
{
printf("[SDL] Failed to create accelerated renderer.\n");
printf("[SDL] Attempting to create software renderer...\n");
sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, baseFlags | SDL_RENDERER_SOFTWARE);
if (sdlRenderer == NULL)
{
printf("[SDL] Failed to create software renderer.\n");
return -1;
}
}
//SDL_GetRendererOutputSize( sdlRenderer, &sdlRendW, &sdlRendH );
//printf("[SDL] Renderer Output Size: %i x %i \n", sdlRendW, sdlRendH );
sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, GLX_NES_WIDTH, GLX_NES_HEIGHT);
if (sdlTexture == NULL)
{
printf("[SDL] Failed to create texture: %i x %i", GLX_NES_WIDTH, GLX_NES_HEIGHT );
return -1;
}
return 0;
}
//*****************************************************************************
int destroy_gtk3_sdl_video(void)
{
if (sdlTexture)
{
printf("Destroying SDL Texture...\n");
SDL_DestroyTexture(sdlTexture);
sdlTexture = NULL;
}
if (sdlRenderer)
{
printf("Destroying SDL Renderer...\n");
SDL_DestroyRenderer(sdlRenderer);
sdlRenderer = NULL;
}
return 0;
}
//*****************************************************************************
int gtk3_sdl_resize(void)
{
destroy_gtk3_sdl_video();
init_gtk3_sdl_video();
return 0;
}
//*****************************************************************************
int gtk3_sdl_render(void)
{
int sx, sy, rw, rh;
int nesWidth = GLX_NES_WIDTH;
int nesHeight = GLX_NES_HEIGHT;
if ( glx_shm != NULL )
{
nesWidth = glx_shm->ncol;
nesHeight = glx_shm->nrow;
}
//printf(" %i x %i \n", nesWidth, nesHeight );
float xscale = (float)gtk_draw_area_width / (float)nesWidth;
float yscale = (float)gtk_draw_area_height / (float)nesHeight;
if (xscale < yscale )
{
yscale = xscale;
}
else
{
xscale = yscale;
}
rw=(int)(nesWidth*xscale);
rh=(int)(nesHeight*yscale);
//sx=sdlViewport.x + (view_width-rw)/2;
//sy=sdlViewport.y + (view_height-rh)/2;
sx=(gtk_draw_area_width-rw)/2;
sy=(gtk_draw_area_height-rh)/2;
if ( (sdlRenderer == NULL) || (sdlTexture == NULL) )
{
return -1;
}
SDL_SetRenderDrawColor( sdlRenderer, 0, 0, 0, 0 );
SDL_RenderClear(sdlRenderer);
uint8_t *textureBuffer;
int rowPitch;
SDL_LockTexture( sdlTexture, nullptr, (void**)&textureBuffer, &rowPitch);
{
memcpy( textureBuffer, glx_shm->pixbuf, GLX_NES_HEIGHT*GLX_NES_WIDTH*sizeof(uint32_t) );
}
SDL_UnlockTexture(sdlTexture);
//SDL_RenderSetViewport( sdlRenderer, &sdlViewport );
SDL_Rect source = {0, 0, nesWidth, nesHeight };
SDL_Rect dest = { sx, sy, rw, rh };
SDL_RenderCopy(sdlRenderer, sdlTexture, &source, &dest);
SDL_RenderPresent(sdlRenderer);
return 0;
}
//*****************************************************************************

View File

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