From 1fc0725e9469f371a29d24699b864f73a7d595ee Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Fri, 5 Jun 2020 21:08:53 -0400 Subject: [PATCH 01/25] Successful display of graphics using cairo. Not as efficient as other methods but works. --- SConstruct | 2 +- src/drivers/sdl/gui.cpp | 161 ++++++++++++- src/drivers/sdl/gui.h | 5 +- src/drivers/sdl/input.cpp | 94 ++++---- src/drivers/sdl/input.h | 3 +- src/drivers/sdl/sdl-opengl.cpp | 28 +++ src/drivers/sdl/sdl-opengl.h | 11 +- src/drivers/sdl/sdl-video.cpp | 404 ++++++++++++++++++++++++++++----- 8 files changed, 589 insertions(+), 119 deletions(-) diff --git a/SConstruct b/SConstruct index a5e5ec1c..97b30bce 100644 --- a/SConstruct +++ b/SConstruct @@ -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') diff --git a/src/drivers/sdl/gui.cpp b/src/drivers/sdl/gui.cpp index 63f20ed4..0402b086 100644 --- a/src/drivers/sdl/gui.cpp +++ b/src/drivers/sdl/gui.cpp @@ -72,6 +72,7 @@ static unsigned int gtk_win_width = 0; static unsigned int gtk_win_height = 0; static int gtk_win_menu_ysize = 30; static GtkTreeStore *hotkey_store = NULL; +static cairo_surface_t *cairo_surface = NULL; static gint convertKeypress (GtkWidget * grab, GdkEventKey * event, gpointer user_data); @@ -2215,7 +2216,7 @@ static void changeState (GtkRadioMenuItem * radiomenuitem, gpointer user_data) #define SDLK_RMETA 0 #endif // Adapted from Gens/GS. Converts a GDK key value into an SDL key value. -unsigned short GDKToSDLKeyval (int gdk_key) +unsigned int GDKToSDLKeyval (int gdk_key) { if (!(gdk_key & 0xFF00)) { @@ -2242,7 +2243,7 @@ unsigned short GDKToSDLKeyval (int gdk_key) } // Non-ASCII symbol. - static const uint16_t gdk_to_sdl_table[0x100] = { + static const int gdk_to_sdl_table[0x100] = { // 0x00 - 0x0F 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, @@ -2340,7 +2341,7 @@ unsigned short GDKToSDLKeyval (int gdk_key) 0x0000, 0x0000, 0x0000, SDLK_DELETE, }; - unsigned short sdl_key = gdk_to_sdl_table[gdk_key & 0xFF]; + unsigned int sdl_key = gdk_to_sdl_table[gdk_key & 0xFF]; if (sdl_key == 0) { // Unhandled GDK key. @@ -3070,8 +3071,126 @@ gint handleMouseClick (GtkWidget * widget, GdkEvent * event, return 0; } +uint32_t *getGuiPixelBuffer( int *w, int *h, int *s ) +{ + + if ( cairo_surface == NULL ) + { + if ( w ) *w = 0; + if ( h ) *h = 0; + if ( s ) *s = 0; + return NULL; + } + cairo_surface_flush( cairo_surface ); + + if ( w ) + { + *w = cairo_image_surface_get_width (cairo_surface); + } + if ( h ) + { + *h = cairo_image_surface_get_height (cairo_surface); + } + if ( s ) + { + *s = cairo_image_surface_get_stride(cairo_surface); + } + + //return NULL; + return (uint32_t*)cairo_image_surface_get_data (cairo_surface); +} + +int guiPixelBufferReDraw(void) +{ + if ( cairo_surface != NULL ) + { + cairo_surface_mark_dirty( cairo_surface ); + + gtk_widget_queue_draw( evbox ); + } + return 0; +} + +int guiClearSurface(void) +{ + uint32_t *p; + int w, h, z, i; + if ( cairo_surface != NULL ) + { + cairo_surface_flush( cairo_surface ); + + p = (uint32_t*)cairo_image_surface_get_data (cairo_surface); + + w = cairo_image_surface_get_width (cairo_surface); + h = cairo_image_surface_get_height (cairo_surface); + + z = w * h; + for (i=0; i xscale) yscale = xscale; + if (cairo_surface) + { + cairo_surface_destroy (cairo_surface); cairo_surface = NULL; + } + + //cairo_surface = gdk_window_create_similar_surface ( + // gtk_widget_get_window (evbox), + // CAIRO_CONTENT_COLOR_ALPHA, + // gtk_widget_get_allocated_width (evbox), + // gtk_widget_get_allocated_height (evbox) ); + + //cairo_surface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, + cairo_surface = cairo_image_surface_create( CAIRO_FORMAT_RGB24, + gtk_widget_get_allocated_width (evbox), + gtk_widget_get_allocated_height (evbox) ); + + printf("Cairo Surface: %p \n", cairo_surface ); + + cairo_format = cairo_image_surface_get_format( cairo_surface ); + + printf("Cairo Format: %i \n", cairo_format ); + if ( cairo_format == CAIRO_FORMAT_ARGB32 ) + { + printf("Cairo Format: ARGB32 \n" ); + } + guiClearSurface(); + + //setPixels(); + cairo_surface_mark_dirty( cairo_surface ); + //TODO if openGL make these integers g_config->setOption ("SDL.XScale", xscale); g_config->setOption ("SDL.YScale", yscale); @@ -3150,6 +3299,10 @@ static gboolean draw_cb (GtkWidget * widget, cairo_t * cr, gpointer data) gtk_win_menu_ysize = gtk_win_height - gtk_draw_area_height; + cairo_set_source_surface (cr, cairo_surface, 0, 0); + cairo_paint (cr); + return FALSE; + // Clear the screen on a window redraw //if (GameInfo == 0) //{ @@ -3229,7 +3382,7 @@ int InitGTKSubsystem (int argc, char **argv) g_signal_connect (MainWindow, "delete-event", quit, NULL); g_signal_connect (MainWindow, "destroy-event", quit, NULL); // resize handler - g_signal_connect (MainWindow, "configure-event", + g_signal_connect (evbox, "configure-event", G_CALLBACK (handle_resize), NULL); g_signal_connect (evbox, "draw", G_CALLBACK (draw_cb), NULL); diff --git a/src/drivers/sdl/gui.h b/src/drivers/sdl/gui.h index 3edb5782..73147ee9 100644 --- a/src/drivers/sdl/gui.h +++ b/src/drivers/sdl/gui.h @@ -83,7 +83,10 @@ 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); + #endif // ifndef FCEUX_GUI_H diff --git a/src/drivers/sdl/input.cpp b/src/drivers/sdl/input.cpp index 31cd81fe..c0d972aa 100644 --- a/src/drivers/sdl/input.cpp +++ b/src/drivers/sdl/input.cpp @@ -1019,65 +1019,65 @@ 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 - } - } +// 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 diff --git a/src/drivers/sdl/input.h b/src/drivers/sdl/input.h index bd3d4994..033d5077 100644 --- a/src/drivers/sdl/input.h +++ b/src/drivers/sdl/input.h @@ -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; diff --git a/src/drivers/sdl/sdl-opengl.cpp b/src/drivers/sdl/sdl-opengl.cpp index ce8562fc..24456a5f 100644 --- a/src/drivers/sdl/sdl-opengl.cpp +++ b/src/drivers/sdl/sdl-opengl.cpp @@ -21,6 +21,9 @@ #define APIENTRY #endif +#if SDL_VERSION_ATLEAST(2, 0, 0) +static SDL_Window *s_window = NULL; +#endif static GLuint textures[2]={0,0}; // Normal image, scanline overlay. static int left,right,top,bottom; // right and bottom are not inclusive. @@ -104,7 +107,11 @@ BlitOpenGL(uint8 *buf) glEnd(); glDisable(GL_BLEND); } + #if SDL_VERSION_ATLEAST(2, 0, 0) + SDL_GL_SwapWindow(s_window); + #else SDL_GL_SwapBuffers(); + #endif } void @@ -132,6 +139,9 @@ InitOpenGL(int l, int ipolate, int stretchx, int stretchy, +#if SDL_VERSION_ATLEAST(2, 0, 0) + SDL_Window *window, +#endif SDL_Surface *screen) { const char *extensions; @@ -167,6 +177,9 @@ InitOpenGL(int l, HiBuffer=0; +#if SDL_VERSION_ATLEAST(2, 0, 0) + s_window = window; +#endif extensions=(const char*)glGetString(GL_EXTENSIONS); if((efx&2) || !extensions || !p_glColorTableEXT || !strstr(extensions,"GL_EXT_paletted_texture")) @@ -182,6 +195,9 @@ InitOpenGL(int l, #endif } +#if SDL_VERSION_ATLEAST(2, 0, 0) + // FIXME +#else if(screen->flags & SDL_FULLSCREEN) { xscale=(double)screen->w / (double)(r-l); @@ -189,6 +205,7 @@ InitOpenGL(int l, if(xscalepixels; + + i=0; j=0; + for (int x=0; xw; x++) + { + for (int y=0; yh; y++) + { + pixel = buf[i]; i++; + + if ( pixel != 0 ) + { + printf("(%i,%i) %08x ", x, y, pixel ); j++; + if ( j % 10 == 0 ) + { + printf("\n"); + } + } + //printf("(%i,%i) %08x ", x, y, pixel ); + + } + } + + + +} + //draw input aids if we are fullscreen bool FCEUD_ShouldDrawInputAids() { @@ -100,7 +137,8 @@ int KillVideo() { // if the IconSurface has been initialized, destroy it - if(s_IconSurface) { + if (s_IconSurface) + { SDL_FreeSurface(s_IconSurface); s_IconSurface=0; } @@ -113,15 +151,46 @@ KillVideo() #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) + if (s_curbpp > 8) + { KillBlitToHigh(); + } + } + +#if SDL_VERSION_ATLEAST(2, 0, 0) + + if ( s_screen != NULL ) + { + SDL_FreeSurface( s_screen ); s_screen = NULL; + } + + if ( s_texture != NULL ) + { + SDL_DestroyTexture( s_texture ); s_texture = NULL; + } + + if ( s_renderer != NULL ) + { + SDL_DestroyRenderer( s_renderer ); s_renderer = NULL; + } + + if ( s_window != NULL ) + { + SDL_DestroyWindow( s_window ); + s_window = NULL; + } + +#endif // shut down the SDL video sub-system - SDL_QuitSubSystem(SDL_INIT_VIDEO); + //SDL_QuitSubSystem(SDL_INIT_VIDEO); s_inited = 0; return 0; @@ -158,6 +227,203 @@ 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 + // 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..."); + + // load the relevant configuration variables + g_config->getOption("SDL.Fullscreen", &s_fullscreen); + g_config->getOption("SDL.DoubleBuffering", &doublebuf); +#ifdef OPENGL + g_config->getOption("SDL.OpenGL", &s_useOpenGL); +#endif + 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); + //g_config->getOption("SDL.LastYRes", &yres); + 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_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 + + FCEUI_GetCurrentVidSystem(&s_srendline, &s_erendline); + s_tlines = s_erendline - s_srendline + 1; + + // check if we should auto-set x/y resolution + + // check for OpenGL and set the global flags +#ifdef OPENGL + // FIXME + //if(s_useOpenGL && !s_sponge) { + // flags = SDL_OPENGL; + //} +#endif + + s_inited = 1; + + // check to see if we are showing FPS + FCEUI_SetShowFPS(show_fps); + +#ifdef LSB_FIRST + //rmask = 0x000000FF; + //gmask = 0x0000FF00; + //bmask = 0x00FF0000; + rmask = 0x00FF0000; + gmask = 0x0000FF00; + bmask = 0x000000FF; +#else + rmask = 0x00FF0000; + gmask = 0x0000FF00; + bmask = 0x000000FF; +#endif + + // if all this hex scares you, check out SDL_PixelFormatEnumToMasks()! +//#ifdef LSB_FIRST +// //printf("Little Endian\n"); +// s_screen = SDL_CreateRGBSurface(0, xres, yres, 32, +// 0xFF, 0xFF00, 0xFF0000, 0x00); +//#else +// //printf("Big Endian\n"); +// s_screen = SDL_CreateRGBSurface(0, xres, yres, 32, +// 0xFF0000, 0xFF00, 0xFF, 0x00); +//#endif +// +// if ( s_screen == NULL ) +// { +// fprintf(stderr, "Couldn't init SDL screen: %s\n", SDL_GetError()); +// KillVideo(); +// exit(-1); +// } +// +// s_texture = SDL_CreateTexture(s_renderer, +//#ifdef LSB_FIRST +// SDL_PIXELFORMAT_ABGR8888, +//#else +// SDL_PIXELFORMAT_ARGB8888, +//#endif +// SDL_TEXTUREACCESS_STREAMING | SDL_TEXTUREACCESS_TARGET, +// xres, yres ); +// +// if ( s_texture == NULL ) +// { +// fprintf(stderr, "Couldn't init SDL texture: %s\n", SDL_GetError()); +// KillVideo(); +// exit(-1); +// } +// #endif + + //s_curbpp = s_screen->format->BitsPerPixel; + s_curbpp = 32; + + //FCEU_printf(" Video Mode: %d x %d x %d bpp %s\n", + // s_screen->w, s_screen->h, s_screen->format->BitsPerPixel, + // s_fullscreen ? "full screen" : ""); + FCEU_printf(" Video Mode: %d x %d x %d bpp %s\n", + xres, yres, s_curbpp, + s_fullscreen ? "full screen" : ""); + + 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; + } + + // 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_SetWindowIcon( s_window, s_IconSurface); + + //s_paletterefresh = 1; + + // -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 (s_curbpp > 8) + { + InitBlitToHigh(s_curbpp >> 3, + rmask, + gmask, + bmask, + s_eefx, s_sponge, 0); + } + + return 0; } #else /** @@ -632,13 +898,14 @@ void UnlockConsole(){} void BlitScreen(uint8 *XBuf) { - SDL_Surface *TmpScreen; + //SDL_Surface *TmpScreen; uint8 *dest; int xo = 0, yo = 0; + int w, h, pitch; - if(!s_screen) { - return; - } + //if(!s_screen) { + // return; + //} // refresh the palette if required if(s_paletterefresh) { @@ -657,27 +924,32 @@ BlitScreen(uint8 *XBuf) // 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; - } + //if(s_BlitBuf) { + // TmpScreen = s_BlitBuf; + //} else { + // TmpScreen = s_screen; + //} // lock the display, if necessary - if(SDL_MUSTLOCK(TmpScreen)) { - if(SDL_LockSurface(TmpScreen) < 0) { - return; - } - } + //if(SDL_MUSTLOCK(TmpScreen)) { + // if(SDL_LockSurface(TmpScreen) < 0) { + // return; + // } + //} - dest = (uint8*)TmpScreen->pixels; + //dest = (uint8*)TmpScreen->pixels; + dest = (uint8*)getGuiPixelBuffer( &w, &h, &pitch ); + + pitch = w * 4; + + 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); + xo = (int)(((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; + if(h > (s_tlines * s_eys)) { + yo = (int)((h - s_tlines * s_eys) / 2); + dest += yo * pitch; } //} @@ -686,26 +958,29 @@ BlitScreen(uint8 *XBuf) if(s_curbpp > 8) { if(s_BlitBuf) { Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines, - TmpScreen->pitch, 1, 1); + pitch, 1, 1); } else { Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines, - TmpScreen->pitch, (int)s_exs, (int)s_eys); + 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); + pitch, 1, 1, 0, s_sponge); } else { Blit8To8(XBuf + NOFFSET, dest, NWIDTH, s_tlines, - TmpScreen->pitch, (int)s_exs, (int)s_eys, + pitch, (int)s_exs, (int)s_eys, s_eefx, s_sponge); } } + //print_pixels(); + // + guiPixelBufferReDraw(); // unlock the display, if necessary - if(SDL_MUSTLOCK(TmpScreen)) { - SDL_UnlockSurface(TmpScreen); - } + //if(SDL_MUSTLOCK(TmpScreen)) { + // SDL_UnlockSurface(TmpScreen); + //} int scrw; if(s_sponge == 3) { // NTSC 2x @@ -715,29 +990,32 @@ BlitScreen(uint8 *XBuf) } // if we have a hardware video buffer, do a fast video->video copy - if(s_BlitBuf) { - SDL_Rect srect; - SDL_Rect drect; + //if(s_BlitBuf) { + // SDL_Rect srect; + // SDL_Rect drect; - srect.x = 0; - srect.y = 0; - srect.w = scrw; - srect.h = s_tlines; + // 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); + // 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); - } + // SDL_BlitSurface(s_BlitBuf, &srect, s_screen, &drect); + //} // ensure that the display is updated #if SDL_VERSION_ATLEAST(2, 0, 0) - //TODO - SDL2 + //SDL_UpdateTexture(s_texture, NULL, s_screen->pixels, s_screen->pitch); + //SDL_RenderClear(s_renderer); + //SDL_RenderCopy(s_renderer, s_texture, NULL, NULL); + //SDL_RenderPresent(s_renderer); #else - SDL_UpdateRect(s_screen, xo, yo, - (Uint32)(scrw * s_exs), (Uint32)(s_tlines * s_eys)); + //SDL_UpdateRect(s_screen, xo, yo, + // (Uint32)(scrw * s_exs), (Uint32)(s_tlines * s_eys)); #endif #ifdef CREATE_AVI @@ -781,7 +1059,7 @@ BlitScreen(uint8 *XBuf) break; #endif default: - NESVideoLoggingVideo(s_screen->pixels, width,height, fps, s_curbpp); + NESVideoLoggingVideo( dest, width,height, fps, s_curbpp); } } #endif @@ -814,14 +1092,14 @@ BlitScreen(uint8 *XBuf) #endif #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 +//#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 } /** From 8c2cea1ed40704e583c1583c00b77d5178884e62 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Fri, 5 Jun 2020 21:23:33 -0400 Subject: [PATCH 02/25] Added logic to change how full screen mode works with cairo drawing. --- src/drivers/sdl/gui.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/drivers/sdl/gui.cpp b/src/drivers/sdl/gui.cpp index 0402b086..d766c218 100644 --- a/src/drivers/sdl/gui.cpp +++ b/src/drivers/sdl/gui.cpp @@ -3005,9 +3005,19 @@ void pushOutputToGTK (const char *str) void showGui (bool b) { if (b) + { + //gtk_window_unmaximize( GTK_WINDOW(MainWindow) ); + gtk_window_unfullscreen( GTK_WINDOW(MainWindow) ); gtk_widget_show_all (MainWindow); + //gtk_window_unfullscreen( GTK_WINDOW(MainWindow) ); + } else - gtk_widget_hide (MainWindow); + { + //gtk_widget_hide (MainWindow); + //gtk_widget_hide (Menubar); + //gtk_window_maximize( GTK_WINDOW(MainWindow) ); + gtk_window_fullscreen( GTK_WINDOW(MainWindow) ); + } } gint handleKeyRelease (GtkWidget * w, GdkEvent * event, gpointer cb_data) From 6b406e411f933bcfb6145e172d614717334ddba1 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 6 Jun 2020 09:02:36 -0400 Subject: [PATCH 03/25] Bug fixes for SDL2 keyboard interaction. --- src/drivers/sdl/gui.cpp | 2 ++ src/drivers/sdl/input.cpp | 38 ++++++++++++++++++++++++++++++-------- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/drivers/sdl/gui.cpp b/src/drivers/sdl/gui.cpp index d766c218..8962f88f 100644 --- a/src/drivers/sdl/gui.cpp +++ b/src/drivers/sdl/gui.cpp @@ -2399,7 +2399,9 @@ static gboolean convertKeypress (GtkWidget * grab, GdkEventKey * event, #endif // Create an SDL event from the keypress. + sdlev.key.keysym.scancode = SDL_GetScancodeFromKey(sdlkey); sdlev.key.keysym.sym = sdlkey; + sdlev.key.keysym.mod = 0; if (sdlkey != 0) { SDL_PushEvent (&sdlev); diff --git a/src/drivers/sdl/input.cpp b/src/drivers/sdl/input.cpp index c0d972aa..c41665d7 100644 --- a/src/drivers/sdl/input.cpp +++ b/src/drivers/sdl/input.cpp @@ -137,7 +137,11 @@ DoCheatSeq () } #include "keyscan.h" +#if SDL_VERSION_ATLEAST(2, 0, 0) +static uint8 g_keyState[SDL_NUM_SCANCODES]; +#else static uint8 *g_keyState = 0; +#endif static int DIPS = 0; static uint8 keyonce[MKK_COUNT]; @@ -451,7 +455,7 @@ static void KeyboardCommands () char *movie_fname = ""; // get the keyboard input #if SDL_VERSION_ATLEAST(1, 3, 0) - g_keyState = (Uint8*)SDL_GetKeyboardState (NULL); + //g_keyState = (Uint8*)SDL_GetKeyboardState (NULL); #else g_keyState = SDL_GetKeyState (NULL); #endif @@ -461,7 +465,7 @@ static void KeyboardCommands () { #if SDL_VERSION_ATLEAST(1, 3, 0) // TODO - SDL2 - if (0) + if ( g_keyState[SDL_SCANCODE_SCROLLLOCK] ) #else if (keyonly (SCROLLLOCK)) #endif @@ -482,8 +486,8 @@ static void KeyboardCommands () } #if SDL_VERSION_ATLEAST(2, 0, 0) - if (g_keyState[SDL_GetScancodeFromKey (SDLK_LSHIFT)] - || g_keyState[SDL_GetScancodeFromKey (SDLK_RSHIFT)]) + if (g_keyState[SDL_SCANCODE_LSHIFT] + || g_keyState[SDL_SCANCODE_RSHIFT]) #else if (g_keyState[SDLK_LSHIFT] || g_keyState[SDLK_RSHIFT]) #endif @@ -491,8 +495,8 @@ static void KeyboardCommands () else is_shift = 0; #if SDL_VERSION_ATLEAST(2, 0, 0) - if (g_keyState[SDL_GetScancodeFromKey (SDLK_LALT)] - || g_keyState[SDL_GetScancodeFromKey (SDLK_RALT)]) + if (g_keyState[SDL_SCANCODE_LALT] + || g_keyState[SDL_SCANCODE_RALT]) #else if (g_keyState[SDLK_LALT] || g_keyState[SDLK_RALT]) #endif @@ -684,13 +688,13 @@ static void KeyboardCommands () // Toggle throttling NoWaiting &= ~1; - if (g_keyState[Hotkeys[HK_TURBO]]) + if ( _keyonly(Hotkeys[HK_TURBO]) ) { NoWaiting |= 1; } static bool frameAdvancing = false; - if (g_keyState[Hotkeys[HK_FRAME_ADVANCE]]) + if ( _keyonly(Hotkeys[HK_FRAME_ADVANCE])) { if (frameAdvancing == false) { @@ -968,6 +972,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 +1003,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; } @@ -1200,6 +1217,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 +1444,10 @@ void InitInputInterface () int x; int attrib; +#if SDL_VERSION_ATLEAST(2, 0, 0) + memset( g_keyState, 0, sizeof(g_keyState) ); +#endif + for (t = 0, x = 0; x < 2; x++) { attrib = 0; From 76df04d8300eca6529049c00cb9047acf19cb2df Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 6 Jun 2020 22:53:34 -0400 Subject: [PATCH 04/25] Added an experimental shared memory interface to allow for the video window to be a separate process. --- src/drivers/sdl/SConscript | 1 + src/drivers/sdl/glxwin.cpp | 330 ++++++++++++++++++++++++++++++++++ src/drivers/sdl/glxwin.h | 59 ++++++ src/drivers/sdl/gui.cpp | 303 +++++++++++++++++++++++++++++-- src/drivers/sdl/sdl-video.cpp | 40 ++--- src/drivers/sdl/sdl.cpp | 2 + 6 files changed, 702 insertions(+), 33 deletions(-) create mode 100644 src/drivers/sdl/glxwin.cpp create mode 100644 src/drivers/sdl/glxwin.h diff --git a/src/drivers/sdl/SConscript b/src/drivers/sdl/SConscript index a8bde4ac..b16ffbe7 100644 --- a/src/drivers/sdl/SConscript +++ b/src/drivers/sdl/SConscript @@ -13,6 +13,7 @@ source_list = Split( memview.cpp ramwatch.cpp debugger.cpp + glxwin.cpp sdl.cpp sdl-joystick.cpp sdl-sound.cpp diff --git a/src/drivers/sdl/glxwin.cpp b/src/drivers/sdl/glxwin.cpp new file mode 100644 index 00000000..7f00b5c8 --- /dev/null +++ b/src/drivers/sdl/glxwin.cpp @@ -0,0 +1,330 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "glxwin.h" + +static Display *dpy = NULL; +static Window root; +static GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None }; +static XVisualInfo *vi = NULL; +static Colormap cmap; +static XSetWindowAttributes swa; +static Window win; +static GLXContext glc; +static XWindowAttributes gwa; +static XEvent xev; + +static GLuint gltexture = 0; + +glxwin_shm_t *glx_shm = NULL; + +static int screen_width = 512; +static int screen_height = 512; +//************************************************************************ +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 ); + + return vaddr; +} +//************************************************************************ +static void genTextures(void) +{ + int ipolate = 1; + + glEnable(GL_TEXTURE_2D); + glGenTextures(1, &gltexture); + + 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) +{ + + 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"); + + glc = glXCreateContext(dpy, vi, NULL, GL_TRUE); + glXMakeCurrent(dpy, win, glc); + + genTextures(); + 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[x*256+y] ); + } + } +} +//************************************************************************ +static void render_image(void) +{ + int l=0, r=GLX_NES_WIDTH; + int t=0, b=GLX_NES_HEIGHT; + + float xscale = (float)screen_width / (float)GLX_NES_WIDTH; + float yscale = (float)screen_height / (float)GLX_NES_HEIGHT; + 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; + + 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(); + + glFlush(); + + glXSwapBuffers( dpy, win ); +} +//************************************************************************ +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) + { + //XGetWindowAttributes(dpy, win, &gwa); + + screen_width = xev.xconfigure.width; + screen_height = xev.xconfigure.height; + + //if (gltexture) { + // glDeleteTextures(1, &gltexture); + //} + //gltexture=0; + + //genTextures(); + + printf("Resize Request: (%i,%i)\n", screen_width, screen_height ); + render_image(); + //glViewport(0, 0, gwa.width, gwa.height); + //DrawAQuad(); + //glXSwapBuffers(dpy, win); + } + 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(); + + 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; +} +//************************************************************************ + +//************************************************************************ diff --git a/src/drivers/sdl/glxwin.h b/src/drivers/sdl/glxwin.h new file mode 100644 index 00000000..03f162c3 --- /dev/null +++ b/src/drivers/sdl/glxwin.h @@ -0,0 +1,59 @@ +// glxwin.cpp +// + +#ifndef __GLXWIN_H__ +#define __GLXWIN_H__ + +#include + +#include + +int spawn_glxwin( int flags ); + +#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; + + // 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 +}; + +extern glxwin_shm_t *glx_shm; + +#endif diff --git a/src/drivers/sdl/gui.cpp b/src/drivers/sdl/gui.cpp index 8962f88f..ac71ef00 100644 --- a/src/drivers/sdl/gui.cpp +++ b/src/drivers/sdl/gui.cpp @@ -34,11 +34,23 @@ #include #endif +#ifdef APPLEOPENGL +#include +#include +#include +#else +#include +#include +#include +#endif + #include #include #include #include +#include "glxwin.h" + // Fix compliation errors for older version of GTK (Ubuntu 10.04 LTS) #if GTK_MINOR_VERSION < 24 && GTK_MAJOR_VERSION == 2 #define GTK_COMBO_BOX_TEXT GTK_COMBO_BOX @@ -66,6 +78,9 @@ static GtkRadioMenuItem *stateSlot[10] = { NULL }; bool gtkIsStarted = false; bool menuTogglingEnabled = false; +static int drawAreaGL = 0; +static GLuint gltexture = 0; +static uint32_t *drawAreaGLpixBuf = NULL; unsigned int gtk_draw_area_width = NES_WIDTH; unsigned int gtk_draw_area_height = NES_HEIGHT; static unsigned int gtk_win_width = 0; @@ -3085,6 +3100,15 @@ gint handleMouseClick (GtkWidget * widget, GdkEvent * event, uint32_t *getGuiPixelBuffer( int *w, int *h, int *s ) { + if ( drawAreaGL ) + { + if ( w ) *w = 256; + if ( h ) *h = 256; + if ( s ) *s = 256*4; + + //return NULL; + return glx_shm->pixbuf; + } if ( cairo_surface == NULL ) { @@ -3114,6 +3138,13 @@ uint32_t *getGuiPixelBuffer( int *w, int *h, int *s ) int guiPixelBufferReDraw(void) { + glx_shm->blit_count++; + + if ( drawAreaGL ) + { + gtk_gl_area_queue_render( (GtkGLArea*)evbox); + return 0; + } if ( cairo_surface != NULL ) { cairo_surface_mark_dirty( cairo_surface ); @@ -3148,20 +3179,30 @@ int guiClearSurface(void) static void setPixels(void) { - int32_t *p; + uint32_t *p; int i,x,y,width,height,w2,h2; - width = cairo_image_surface_get_width (cairo_surface); - height = cairo_image_surface_get_height (cairo_surface); + if ( drawAreaGL ) + { + width = 256; + height = 256; + //p = (uint32_t*)drawAreaGLpixBuf; + p = (uint32_t*)glx_shm->pixbuf; + } + else + { + width = cairo_image_surface_get_width (cairo_surface); + height = cairo_image_surface_get_height (cairo_surface); - cairo_surface_flush( cairo_surface ); + cairo_surface_flush( cairo_surface ); - p = (int32_t*)cairo_image_surface_get_data (cairo_surface); + p = (uint32_t*)cairo_image_surface_get_data (cairo_surface); + } w2 = width / 2; h2 = height / 2; - printf("W:%i H:%i W/2:%i H/2:%i\n", width, height, w2, h2 ); + //printf("W:%i H:%i W/2:%i H/2:%i\n", width, height, w2, h2 ); i=0; for (y=0; y 1.0 ) + { + red = 1.0; dir = 0; + } + } + else + { + red -= 0.01; + if ( red < 0.0 ) + { + red = 0.0; dir = 1; + } + } + //if(stretchx) { sx=0; rw=screen->w; } + //if(stretchy) { sy=0; rh=screen->h; } + //glViewport(sx, sy, rw, rh); + //glViewport(0, 0, gtk_draw_area_width, gtk_draw_area_height); + + //glLoadIdentity(); + //glPushMatrix(); + //glLoadIdentity(); + //glMatrixMode(GL_MODELVIEW); + //glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0); + + //printf("GL Render!\n"); + + glDisable(GL_DEPTH_TEST); + glClearColor( red, 0.0f, 0.0f, 0.0f); // Background color to black. + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glDisable(GL_TEXTURE_2D); + glEnable(GL_LINE_SMOOTH); + //glEnable(GL_TEXTURE_2D); + //glBindTexture(GL_TEXTURE_2D, gltexture); + glBindTexture(GL_TEXTURE_2D, gltexture); + + + //setPixels(); + + //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, + // GL_RGBA, GL_UNSIGNED_BYTE, drawAreaGLpixBuf ); + + //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(); + + //glPushMatrix(); + + //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(); + + //glPopMatrix(); + + glDisable(GL_TEXTURE_2D); + + glFlush(); + + return TRUE; +} + +static void +glwin_realize (GtkGLArea *area) +{ + int ipolate = 0; + gboolean has_alpha; + + printf("GL Realize!\n"); + // We need to make the context current if we want to + // call GL API + gtk_gl_area_make_current (area); + + // If there were errors during the initialization or + // when trying to make the context current, this + // function will return a #GError for you to catch + if (gtk_gl_area_get_error (area) != NULL) + { + printf("GL Realize Error\n"); + return; + } + + if ( drawAreaGLpixBuf == NULL ) + { + int bufSize; + + bufSize = 256 * 256 * sizeof(uint32_t); + + drawAreaGLpixBuf = (uint32_t*)malloc ( bufSize ); + + if ( drawAreaGLpixBuf ) + { + memset( drawAreaGLpixBuf, 0, bufSize ); + } + } + + has_alpha = gtk_gl_area_get_has_alpha( area ); + + printf("Has Alpha: %i \n", has_alpha ); + + if ( has_alpha ) + { + gtk_gl_area_set_has_alpha( area, 0 ); + } + // Enable depth buffer: + gtk_gl_area_set_has_depth_buffer(area, TRUE); + + has_alpha = gtk_gl_area_get_has_alpha( area ); + + printf("Has Alpha: %i \n", has_alpha ); + + glEnable(GL_TEXTURE_2D); + glGenTextures(1, &gltexture); + + 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); + glDisable(GL_TEXTURE_2D); + glDisable(GL_DEPTH_TEST); + glClearColor(1.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 | GL_DEPTH_BUFFER_BIT); + +} + /* Redraw the screen from the surface. Note that the ::draw * signal receives a ready-to-be-used cairo_t that is already * clipped to only draw the exposed areas of the widget @@ -3335,6 +3586,8 @@ static gboolean draw_cb (GtkWidget * widget, cairo_t * cr, gpointer data) int InitGTKSubsystem (int argc, char **argv) { + + int s_useOpenGL=0; GtkWidget *vbox; MainWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL); @@ -3367,8 +3620,22 @@ int InitGTKSubsystem (int argc, char **argv) // // prg - Bryan Cain, you are the man! - //evbox = gtk_event_box_new(); - evbox = gtk_drawing_area_new (); + #ifdef OPENGL + g_config->getOption("SDL.OpenGL", &s_useOpenGL); + #endif + + drawAreaGL = s_useOpenGL; + + if ( drawAreaGL ) + { + evbox = gtk_gl_area_new (); + gtk_gl_area_set_has_alpha( GTK_GL_AREA(evbox), TRUE); + gtk_gl_area_set_has_depth_buffer( GTK_GL_AREA(evbox), TRUE); + } + else + { + evbox = gtk_drawing_area_new (); + } gtk_box_pack_start (GTK_BOX (vbox), evbox, TRUE, TRUE, 0); double xscale, yscale; @@ -3394,9 +3661,19 @@ int InitGTKSubsystem (int argc, char **argv) g_signal_connect (MainWindow, "delete-event", quit, NULL); g_signal_connect (MainWindow, "destroy-event", quit, NULL); // resize handler - g_signal_connect (evbox, "configure-event", - G_CALLBACK (handle_resize), NULL); - g_signal_connect (evbox, "draw", G_CALLBACK (draw_cb), NULL); + if ( s_useOpenGL ) + { + g_signal_connect (evbox, "resize" , G_CALLBACK (glwin_resize ), NULL); + g_signal_connect (evbox, "realize", G_CALLBACK (glwin_realize), NULL); + g_signal_connect (evbox, "render" , G_CALLBACK (glwin_render ), NULL); + } + else + { + g_signal_connect (evbox, "configure-event", + G_CALLBACK (handle_resize), NULL); + + g_signal_connect (evbox, "draw", G_CALLBACK (draw_cb), NULL); + } gtk_widget_set_size_request (evbox, NES_WIDTH * xscale, NES_HEIGHT * yscale); diff --git a/src/drivers/sdl/sdl-video.cpp b/src/drivers/sdl/sdl-video.cpp index 7f5c0364..38aa34b1 100644 --- a/src/drivers/sdl/sdl-video.cpp +++ b/src/drivers/sdl/sdl-video.cpp @@ -252,8 +252,8 @@ int InitVideo(FCEUGI *gi) g_config->getOption("SDL.YScale", &s_eys); uint32_t rmask, gmask, bmask; - //s_exs = 1.0; - //s_eys = 1.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 @@ -277,12 +277,12 @@ int InitVideo(FCEUGI *gi) FCEUI_SetShowFPS(show_fps); #ifdef LSB_FIRST - //rmask = 0x000000FF; - //gmask = 0x0000FF00; - //bmask = 0x00FF0000; - rmask = 0x00FF0000; + rmask = 0x000000FF; gmask = 0x0000FF00; - bmask = 0x000000FF; + bmask = 0x00FF0000; + //rmask = 0x00FF0000; + //gmask = 0x0000FF00; + //bmask = 0x000000FF; #else rmask = 0x00FF0000; gmask = 0x0000FF00; @@ -866,11 +866,11 @@ FCEUD_GetPalette(uint8 index, */ static void RedoPalette() { -#ifdef OPENGL - if(s_useOpenGL) - SetOpenGLPalette((uint8*)s_psdl); - else -#endif +//#ifdef OPENGL +// if(s_useOpenGL) +// SetOpenGLPalette((uint8*)s_psdl); +// else +//#endif { if(s_curbpp > 8) { SetPaletteBlitToHigh((uint8*)s_psdl); @@ -913,13 +913,13 @@ BlitScreen(uint8 *XBuf) s_paletterefresh = 0; } -#ifdef OPENGL - // OpenGL is handled separately - if(s_useOpenGL) { - BlitOpenGL(XBuf); - return; - } -#endif +//#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; @@ -956,7 +956,7 @@ BlitScreen(uint8 *XBuf) // 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) { + if(s_useOpenGL) { Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines, pitch, 1, 1); } else { diff --git a/src/drivers/sdl/sdl.cpp b/src/drivers/sdl/sdl.cpp index a2c00cda..2e8beda7 100644 --- a/src/drivers/sdl/sdl.cpp +++ b/src/drivers/sdl/sdl.cpp @@ -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" @@ -857,6 +858,7 @@ int main(int argc, char *argv[]) #ifdef _GTK if(noGui == 0) { + int glxwin_pid = spawn_glxwin(0); gtk_init(&argc, &argv); InitGTKSubsystem(argc, argv); while(gtk_events_pending()) From 4f27c58856eb0cc8bbadc2a667774a9ae28cde9b Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 7 Jun 2020 09:32:47 -0400 Subject: [PATCH 05/25] Moved poor performing cairo draw routines into their own functions. Removed GtkGlArea experimental code that did not work. --- src/drivers/sdl/gui.cpp | 439 ++++++++++------------------------------ 1 file changed, 103 insertions(+), 336 deletions(-) diff --git a/src/drivers/sdl/gui.cpp b/src/drivers/sdl/gui.cpp index ac71ef00..26ee1cc7 100644 --- a/src/drivers/sdl/gui.cpp +++ b/src/drivers/sdl/gui.cpp @@ -78,9 +78,8 @@ static GtkRadioMenuItem *stateSlot[10] = { NULL }; bool gtkIsStarted = false; bool menuTogglingEnabled = false; +static char useCairoDraw = 0; static int drawAreaGL = 0; -static GLuint gltexture = 0; -static uint32_t *drawAreaGLpixBuf = NULL; unsigned int gtk_draw_area_width = NES_WIDTH; unsigned int gtk_draw_area_height = NES_HEIGHT; static unsigned int gtk_win_width = 0; @@ -3100,51 +3099,43 @@ gint handleMouseClick (GtkWidget * widget, GdkEvent * event, uint32_t *getGuiPixelBuffer( int *w, int *h, int *s ) { - if ( drawAreaGL ) - { - if ( w ) *w = 256; - if ( h ) *h = 256; - if ( s ) *s = 256*4; - - //return NULL; - return glx_shm->pixbuf; - } - - if ( cairo_surface == NULL ) - { - if ( w ) *w = 0; - if ( h ) *h = 0; - if ( s ) *s = 0; - return NULL; - } - cairo_surface_flush( cairo_surface ); - - if ( w ) - { - *w = cairo_image_surface_get_width (cairo_surface); - } - if ( h ) - { - *h = cairo_image_surface_get_height (cairo_surface); - } - if ( s ) - { - *s = cairo_image_surface_get_stride(cairo_surface); - } + if ( w ) *w = GLX_NES_WIDTH; + if ( h ) *h = GLX_NES_HEIGHT; + if ( s ) *s = GLX_NES_WIDTH*4; //return NULL; - return (uint32_t*)cairo_image_surface_get_data (cairo_surface); + return glx_shm->pixbuf; + + //if ( cairo_surface == NULL ) + //{ + // if ( w ) *w = 0; + // if ( h ) *h = 0; + // if ( s ) *s = 0; + // return NULL; + //} + //cairo_surface_flush( cairo_surface ); + + //if ( w ) + //{ + // *w = cairo_image_surface_get_width (cairo_surface); + //} + //if ( h ) + //{ + // *h = cairo_image_surface_get_height (cairo_surface); + //} + //if ( s ) + //{ + // *s = cairo_image_surface_get_stride(cairo_surface); + //} + + ////return NULL; + //return (uint32_t*)cairo_image_surface_get_data (cairo_surface); } int guiPixelBufferReDraw(void) { glx_shm->blit_count++; - if ( drawAreaGL ) - { - gtk_gl_area_queue_render( (GtkGLArea*)evbox); - return 0; - } if ( cairo_surface != NULL ) { cairo_surface_mark_dirty( cairo_surface ); @@ -3158,6 +3149,7 @@ int guiClearSurface(void) { uint32_t *p; int w, h, z, i; + if ( cairo_surface != NULL ) { cairo_surface_flush( cairo_surface ); @@ -3177,27 +3169,14 @@ int guiClearSurface(void) return 0; } -static void setPixels(void) +static void loadPixelTestPattern(void) { uint32_t *p; int i,x,y,width,height,w2,h2; - if ( drawAreaGL ) - { - width = 256; - height = 256; - //p = (uint32_t*)drawAreaGLpixBuf; - p = (uint32_t*)glx_shm->pixbuf; - } - else - { - width = cairo_image_surface_get_width (cairo_surface); - height = cairo_image_surface_get_height (cairo_surface); - - cairo_surface_flush( cairo_surface ); - - p = (uint32_t*)cairo_image_surface_get_data (cairo_surface); - } + width = 256; + height = 256; + p = (uint32_t*)glx_shm->pixbuf; w2 = width / 2; h2 = height / 2; @@ -3234,23 +3213,41 @@ static void setPixels(void) i++; } } - //cairo_surface_mark_dirty( cairo_surface ); - if ( drawAreaGL ) - { - gtk_gl_area_queue_render( (GtkGLArea*)evbox); - } - else - { - gtk_widget_queue_draw( evbox ); - } } +static void cairo_handle_resize( int width, int height ) +{ + cairo_format_t cairo_format; + + if (cairo_surface) + { + cairo_surface_destroy (cairo_surface); cairo_surface = NULL; + } + + cairo_surface = cairo_image_surface_create( CAIRO_FORMAT_RGB24, + gtk_widget_get_allocated_width (evbox), + gtk_widget_get_allocated_height (evbox) ); + + printf("Cairo Surface: %p \n", cairo_surface ); + + cairo_format = cairo_image_surface_get_format( cairo_surface ); + + printf("Cairo Format: %i \n", cairo_format ); + + if ( cairo_format == CAIRO_FORMAT_ARGB32 ) + { + printf("Cairo Format: ARGB32 \n" ); + } + guiClearSurface(); + + cairo_surface_mark_dirty( cairo_surface ); +} + gboolean handle_resize (GtkWindow * win, GdkEvent * event, gpointer data) { - cairo_format_t cairo_format; // This should handle resizing so the emulation takes up as much // of the GTK window as possible @@ -3291,36 +3288,11 @@ gboolean handle_resize (GtkWindow * win, GdkEvent * event, gpointer data) if (yscale > xscale) yscale = xscale; - if (cairo_surface) + if ( useCairoDraw ) { - cairo_surface_destroy (cairo_surface); cairo_surface = NULL; + cairo_handle_resize( draw_width, draw_height ); } - //cairo_surface = gdk_window_create_similar_surface ( - // gtk_widget_get_window (evbox), - // CAIRO_CONTENT_COLOR_ALPHA, - // gtk_widget_get_allocated_width (evbox), - // gtk_widget_get_allocated_height (evbox) ); - - //cairo_surface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, - cairo_surface = cairo_image_surface_create( CAIRO_FORMAT_RGB24, - gtk_widget_get_allocated_width (evbox), - gtk_widget_get_allocated_height (evbox) ); - - printf("Cairo Surface: %p \n", cairo_surface ); - - cairo_format = cairo_image_surface_get_format( cairo_surface ); - - printf("Cairo Format: %i \n", cairo_format ); - if ( cairo_format == CAIRO_FORMAT_ARGB32 ) - { - printf("Cairo Format: ARGB32 \n" ); - } - guiClearSurface(); - - //setPixels(); - cairo_surface_mark_dirty( cairo_surface ); - //TODO if openGL make these integers g_config->setOption ("SDL.XScale", xscale); g_config->setOption ("SDL.YScale", yscale); @@ -3342,219 +3314,31 @@ gboolean handle_resize (GtkWindow * win, GdkEvent * event, gpointer data) return FALSE; } -static void -glwin_resize (GtkGLArea *area, - gint width, - gint height, - gpointer user_data) -{ - //char sizeChange = 0; - //printf("GL Resize: %ix%i \n", width, height ); - - //sizeChange = (width != gtk_draw_area_width) || (height != gtk_draw_area_height); - - //if ( sizeChange ) - //{ - // if ( drawAreaGLpixBuf != NULL) - // { - // free( drawAreaGLpixBuf ); drawAreaGLpixBuf = NULL; - // } - //} - gtk_draw_area_width = width; - gtk_draw_area_height = height; - - if ( drawAreaGLpixBuf == NULL ) - { - int bufSize; - - bufSize = 256 * 256 * sizeof(uint32_t); - - drawAreaGLpixBuf = (uint32_t*)malloc ( bufSize ); - - if ( drawAreaGLpixBuf ) - { - memset( drawAreaGLpixBuf, 0, bufSize ); - } - } - glViewport(0, 0, gtk_draw_area_width, gtk_draw_area_height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); -} - -static gboolean -glwin_render (GtkGLArea *area, - GdkGLContext *context, - gpointer user_data) -{ - int l=0, r=256; - int t=0, b=256; - - float xscale = 1.0; - float yscale = 1.0; - int rw=(int)((r-l)*xscale); - int rh=(int)((b-t)*yscale); - int sx=(gtk_draw_area_width-rw)/2; // Start x - int sy=(gtk_draw_area_height-rh)/2; // Start y - static float red = 1.0; - static int dir = 0; - - if ( dir ) - { - red += 0.01; - if ( red > 1.0 ) - { - red = 1.0; dir = 0; - } - } - else - { - red -= 0.01; - if ( red < 0.0 ) - { - red = 0.0; dir = 1; - } - } - //if(stretchx) { sx=0; rw=screen->w; } - //if(stretchy) { sy=0; rh=screen->h; } - //glViewport(sx, sy, rw, rh); - //glViewport(0, 0, gtk_draw_area_width, gtk_draw_area_height); - - //glLoadIdentity(); - //glPushMatrix(); - //glLoadIdentity(); - //glMatrixMode(GL_MODELVIEW); - //glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0); - - //printf("GL Render!\n"); - - glDisable(GL_DEPTH_TEST); - glClearColor( red, 0.0f, 0.0f, 0.0f); // Background color to black. - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glDisable(GL_TEXTURE_2D); - glEnable(GL_LINE_SMOOTH); - //glEnable(GL_TEXTURE_2D); - //glBindTexture(GL_TEXTURE_2D, gltexture); - glBindTexture(GL_TEXTURE_2D, gltexture); - - - //setPixels(); - - //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, - // GL_RGBA, GL_UNSIGNED_BYTE, drawAreaGLpixBuf ); - - //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(); - - //glPushMatrix(); - - //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(); - - //glPopMatrix(); - - glDisable(GL_TEXTURE_2D); - - glFlush(); - - return TRUE; -} - -static void -glwin_realize (GtkGLArea *area) -{ - int ipolate = 0; - gboolean has_alpha; - - printf("GL Realize!\n"); - // We need to make the context current if we want to - // call GL API - gtk_gl_area_make_current (area); - - // If there were errors during the initialization or - // when trying to make the context current, this - // function will return a #GError for you to catch - if (gtk_gl_area_get_error (area) != NULL) - { - printf("GL Realize Error\n"); - return; - } - - if ( drawAreaGLpixBuf == NULL ) - { - int bufSize; - - bufSize = 256 * 256 * sizeof(uint32_t); - - drawAreaGLpixBuf = (uint32_t*)malloc ( bufSize ); - - if ( drawAreaGLpixBuf ) - { - memset( drawAreaGLpixBuf, 0, bufSize ); - } - } - - has_alpha = gtk_gl_area_get_has_alpha( area ); - - printf("Has Alpha: %i \n", has_alpha ); - - if ( has_alpha ) - { - gtk_gl_area_set_has_alpha( area, 0 ); - } - // Enable depth buffer: - gtk_gl_area_set_has_depth_buffer(area, TRUE); - - has_alpha = gtk_gl_area_get_has_alpha( area ); - - printf("Has Alpha: %i \n", has_alpha ); - - glEnable(GL_TEXTURE_2D); - glGenTextures(1, &gltexture); - - 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); - glDisable(GL_TEXTURE_2D); - glDisable(GL_DEPTH_TEST); - glClearColor(1.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 | GL_DEPTH_BUFFER_BIT); - -} - -/* Redraw the screen from the surface. Note that the ::draw - * signal receives a ready-to-be-used cairo_t that is already - * clipped to only draw the exposed areas of the widget - */ -static gboolean draw_cb (GtkWidget * widget, cairo_t * cr, gpointer data) +static gboolean cairo_clear_cb (GtkWidget * widget, cairo_t * cr, gpointer data) { GdkRGBA color; GtkStyleContext *context; - gtk_draw_area_width = gtk_widget_get_allocated_width (widget); + context = gtk_widget_get_style_context (widget); + + color.red = 0, color.blue = 0; color.green = 0; color.alpha = 1.0; + + gtk_render_background( context, cr, 0, 0, gtk_draw_area_width, gtk_draw_area_height ); + gdk_cairo_set_source_rgba (cr, &color); + + cairo_fill (cr); + cairo_paint (cr); + + return FALSE; +} +/* Redraw the screen from the surface. Note that the ::draw + * signal receives a ready-to-be-used cairo_t that is already + * clipped to only draw the exposed areas of the widget + */ + +static gboolean cairo_draw_cb (GtkWidget * widget, cairo_t * cr, gpointer data) +{ + gtk_draw_area_width = gtk_widget_get_allocated_width (widget); gtk_draw_area_height = gtk_widget_get_allocated_height (widget); if ( gtk_draw_area_width < NES_WIDTH ) gtk_draw_area_width = NES_WIDTH; @@ -3564,21 +3348,21 @@ static gboolean draw_cb (GtkWidget * widget, cairo_t * cr, gpointer data) cairo_set_source_surface (cr, cairo_surface, 0, 0); cairo_paint (cr); + return FALSE; +} - // Clear the screen on a window redraw - //if (GameInfo == 0) - //{ - context = gtk_widget_get_style_context (widget); +static gboolean draw_cb (GtkWidget * widget, cairo_t * cr, gpointer data) +{ - color.red = 0, color.blue = 0; color.green = 0; color.alpha = 1.0; + if ( useCairoDraw ) + { + cairo_draw_cb( widget, cr, data ); + } + else + { - gtk_render_background( context, cr, 0, 0, gtk_draw_area_width, gtk_draw_area_height ); - gdk_cairo_set_source_rgba (cr, &color); - - cairo_fill (cr); - cairo_paint (cr); - //} + } return FALSE; } @@ -3626,16 +3410,8 @@ int InitGTKSubsystem (int argc, char **argv) drawAreaGL = s_useOpenGL; - if ( drawAreaGL ) - { - evbox = gtk_gl_area_new (); - gtk_gl_area_set_has_alpha( GTK_GL_AREA(evbox), TRUE); - gtk_gl_area_set_has_depth_buffer( GTK_GL_AREA(evbox), TRUE); - } - else - { - evbox = gtk_drawing_area_new (); - } + evbox = gtk_drawing_area_new (); + gtk_box_pack_start (GTK_BOX (vbox), evbox, TRUE, TRUE, 0); double xscale, yscale; @@ -3660,20 +3436,11 @@ int InitGTKSubsystem (int argc, char **argv) // signal handlers g_signal_connect (MainWindow, "delete-event", quit, NULL); g_signal_connect (MainWindow, "destroy-event", quit, NULL); - // resize handler - if ( s_useOpenGL ) - { - g_signal_connect (evbox, "resize" , G_CALLBACK (glwin_resize ), NULL); - g_signal_connect (evbox, "realize", G_CALLBACK (glwin_realize), NULL); - g_signal_connect (evbox, "render" , G_CALLBACK (glwin_render ), NULL); - } - else - { - g_signal_connect (evbox, "configure-event", - G_CALLBACK (handle_resize), NULL); - g_signal_connect (evbox, "draw", G_CALLBACK (draw_cb), NULL); - } + g_signal_connect (evbox, "configure-event", + G_CALLBACK (handle_resize), NULL); + + g_signal_connect (evbox, "draw", G_CALLBACK (draw_cb), NULL); gtk_widget_set_size_request (evbox, NES_WIDTH * xscale, NES_HEIGHT * yscale); From 5bbbd0e8e70f084b3e1eebce157f5862a5b46284 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 7 Jun 2020 10:54:00 -0400 Subject: [PATCH 06/25] Successful use of GLX openGL inside gtk3 window. This eliminates the need for SDL video. --- src/drivers/sdl/glxwin.cpp | 110 ++++++++++++++++++++++++++++++++++--- src/drivers/sdl/glxwin.h | 4 ++ src/drivers/sdl/gui.cpp | 15 ++++- 3 files changed, 120 insertions(+), 9 deletions(-) diff --git a/src/drivers/sdl/glxwin.cpp b/src/drivers/sdl/glxwin.cpp index 7f00b5c8..1166169c 100644 --- a/src/drivers/sdl/glxwin.cpp +++ b/src/drivers/sdl/glxwin.cpp @@ -15,6 +15,12 @@ #include #include +#include +#include +#ifdef GDK_WINDOWING_X11 +#include +#endif + #include "glxwin.h" static Display *dpy = NULL; @@ -29,11 +35,16 @@ static XWindowAttributes gwa; static XEvent xev; 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) { @@ -121,6 +132,11 @@ static int open_window(void) XStoreName(dpy, win, "FCEUX VIEWPORT"); glc = glXCreateContext(dpy, vi, NULL, GL_TRUE); + + if ( glc == NULL ) + { + printf("Error: glXCreateContext Failed\n"); + } glXMakeCurrent(dpy, win, glc); genTextures(); @@ -171,8 +187,8 @@ static void render_image(void) 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); + glViewport(sx, sy, rw, rh); + //glViewport( 0, 0, screen_width, screen_height); glLoadIdentity(); glMatrixMode(GL_PROJECTION); @@ -208,12 +224,12 @@ static void render_image(void) 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(); + //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(); glFlush(); @@ -297,6 +313,10 @@ int spawn_glxwin( int flags ) glx_shm = open_shm(); + if ( !spawn_new_window ) + { + return 0; + } pid = fork(); if ( pid == 0 ) @@ -326,5 +346,79 @@ int spawn_glxwin( int flags ) return pid; } //************************************************************************ +int init_gtk3_GLXContext( void ) +{ + XWindowAttributes xattrb; + 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 */ + } + + glc = glXCreateContext(dpy, vi, NULL, GL_TRUE); + + if ( glc == NULL ) + { + printf("Error: glXCreateContext Failed\n"); + } + glXMakeCurrent(dpy, win, glc); + + genTextures(); + 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 gtk3_glx_render(void) +{ + screen_width = gtk_draw_area_width; + screen_height = gtk_draw_area_height; + + render_image(); + + return 0; +} //************************************************************************ diff --git a/src/drivers/sdl/glxwin.h b/src/drivers/sdl/glxwin.h index 03f162c3..ed1b64e5 100644 --- a/src/drivers/sdl/glxwin.h +++ b/src/drivers/sdl/glxwin.h @@ -10,6 +10,10 @@ int spawn_glxwin( int flags ); +int init_gtk3_GLXContext( void ); + +int gtk3_glx_render(void); + #define GLX_NES_WIDTH 256 #define GLX_NES_HEIGHT 256 diff --git a/src/drivers/sdl/gui.cpp b/src/drivers/sdl/gui.cpp index 26ee1cc7..cb1dc137 100644 --- a/src/drivers/sdl/gui.cpp +++ b/src/drivers/sdl/gui.cpp @@ -3136,6 +3136,8 @@ int guiPixelBufferReDraw(void) { glx_shm->blit_count++; + gtk3_glx_render(); + if ( cairo_surface != NULL ) { cairo_surface_mark_dirty( cairo_surface ); @@ -3361,12 +3363,21 @@ static gboolean draw_cb (GtkWidget * widget, cairo_t * cr, gpointer data) } else { - + gtk3_glx_render(); } return FALSE; } +static void +drawAreaRealizeCB (GtkWidget *widget, + gpointer user_data) +{ + printf("Draw Area Realize\n"); + + init_gtk3_GLXContext(); +} + int InitGTKSubsystem (int argc, char **argv) { @@ -3440,6 +3451,8 @@ int InitGTKSubsystem (int argc, char **argv) g_signal_connect (evbox, "configure-event", G_CALLBACK (handle_resize), NULL); + g_signal_connect (evbox, "realize", G_CALLBACK (drawAreaRealizeCB), NULL); + g_signal_connect (evbox, "draw", G_CALLBACK (draw_cb), NULL); gtk_widget_set_size_request (evbox, NES_WIDTH * xscale, From 79b796f790d7ea40b8348ed7cf1f1c3d6011b5fc Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 7 Jun 2020 13:58:09 -0400 Subject: [PATCH 07/25] Implementing secondary cairo interface. --- src/drivers/sdl/glxwin.cpp | 2 +- src/drivers/sdl/gui.cpp | 212 ++++++++++++++++++++++++++++------ src/drivers/sdl/sdl-video.cpp | 65 ++++++----- 3 files changed, 213 insertions(+), 66 deletions(-) diff --git a/src/drivers/sdl/glxwin.cpp b/src/drivers/sdl/glxwin.cpp index 1166169c..12a84801 100644 --- a/src/drivers/sdl/glxwin.cpp +++ b/src/drivers/sdl/glxwin.cpp @@ -35,7 +35,7 @@ static XWindowAttributes gwa; static XEvent xev; static GLuint gltexture = 0; -static int spawn_new_window = 0; +static int spawn_new_window = 1; glxwin_shm_t *glx_shm = NULL; diff --git a/src/drivers/sdl/gui.cpp b/src/drivers/sdl/gui.cpp index cb1dc137..796ca4be 100644 --- a/src/drivers/sdl/gui.cpp +++ b/src/drivers/sdl/gui.cpp @@ -82,11 +82,9 @@ static char useCairoDraw = 0; static int drawAreaGL = 0; unsigned int gtk_draw_area_width = NES_WIDTH; unsigned int gtk_draw_area_height = NES_HEIGHT; -static unsigned int gtk_win_width = 0; -static unsigned int gtk_win_height = 0; -static int gtk_win_menu_ysize = 30; static GtkTreeStore *hotkey_store = NULL; static cairo_surface_t *cairo_surface = NULL; +static int *cairo_pix_remapper = NULL; static gint convertKeypress (GtkWidget * grab, GdkEventKey * event, gpointer user_data); @@ -3097,6 +3095,53 @@ gint handleMouseClick (GtkWidget * widget, GdkEvent * event, return 0; } +union cairo_pixel_t +{ + uint32_t u32; + uint8_t u8[4]; +}; + +static void transferPix2CairoSurface(void) +{ + union cairo_pixel_t *p; + int x, y, i,j, w, h; + + if ( cairo_surface == NULL ) + { + return; + } + cairo_surface_flush( cairo_surface ); + + w = cairo_image_surface_get_width (cairo_surface); + h = cairo_image_surface_get_height (cairo_surface); + + p = (cairo_pixel_t*)cairo_image_surface_get_data (cairo_surface); + + i=0; + for (y=0; ypixbuf[j]; + //p[i].u32 = 0xffffffff; + } + i++; + } + } + + cairo_surface_mark_dirty( cairo_surface ); + + gtk_widget_queue_draw( evbox ); +} + uint32_t *getGuiPixelBuffer( int *w, int *h, int *s ) { if ( w ) *w = GLX_NES_WIDTH; @@ -3136,14 +3181,15 @@ int guiPixelBufferReDraw(void) { glx_shm->blit_count++; - gtk3_glx_render(); - - if ( cairo_surface != NULL ) + if ( useCairoDraw ) { - cairo_surface_mark_dirty( cairo_surface ); - - gtk_widget_queue_draw( evbox ); + transferPix2CairoSurface(); } + else + { + gtk3_glx_render(); + } + return 0; } @@ -3218,19 +3264,119 @@ static void loadPixelTestPattern(void) } +static void cairo_recalc_mapper(void) +{ + int w, h, s; + int i, j, x, y; + int sw, sh, rx, ry; + int llx, lly, urx, ury; + float sx, sy, nw, nh; + + w = cairo_image_surface_get_width (cairo_surface); + h = cairo_image_surface_get_height (cairo_surface); + s = w * h * 4; + + if ( cairo_pix_remapper != NULL ) + { + ::free( cairo_pix_remapper ); cairo_pix_remapper = NULL; + } + cairo_pix_remapper = (int*)malloc(s); + + if ( cairo_pix_remapper == NULL ) + { + printf("Error: Failed to allocate memory for Pixel Surface Remapper\n"); + return; + } + memset( cairo_pix_remapper, 0, s ); + + sx = (float)w / (float)GLX_NES_WIDTH; + sy = (float)h / (float)GLX_NES_HEIGHT; + + if (sx < sy ) + { + sy = sx; + } + else + { + sx = sy; + } + + sw = (int) ( (float)GLX_NES_WIDTH * sx ); + sh = (int) ( (float)GLX_NES_HEIGHT * sy ); + + llx = (w - sw) / 2; + lly = (h - sh) / 2; + urx = llx + sw; + ury = lly + sh; + + i=0; + for (y=0; y ury) ) + { + for (x=0; x urx) ) + { + cairo_pix_remapper[i] = -1; i++; + } + else + { + nw = (float)(x - llx) / (float)sw; + nh = (float)(y - lly) / (float)sh; + + rx = (int)((float)GLX_NES_WIDTH * nw); + ry = (int)((float)GLX_NES_HEIGHT * nh); + + if ( rx < 0 ) + { + rx = 0; + } + else if ( rx >= GLX_NES_WIDTH ) + { + rx = GLX_NES_WIDTH-1; + } + if ( ry < 0 ) + { + ry = 0; + } + else if ( ry >= GLX_NES_HEIGHT ) + { + ry = GLX_NES_HEIGHT-1; + } + + j = (ry * GLX_NES_WIDTH) + rx; + //j = (rx * GLX_NES_WIDTH) + ry; + + cairo_pix_remapper[i] = j; i++; + + //printf("Remap: (%i,%i)=%i (%i,%i)=%i \n", x,y,i, rx,ry,j ); + } + } + } + } +} static void cairo_handle_resize( int width, int height ) { + int w, h; cairo_format_t cairo_format; if (cairo_surface) { cairo_surface_destroy (cairo_surface); cairo_surface = NULL; } + w = gtk_widget_get_allocated_width( evbox ); + h = gtk_widget_get_allocated_height( evbox ); - cairo_surface = cairo_image_surface_create( CAIRO_FORMAT_RGB24, - gtk_widget_get_allocated_width (evbox), - gtk_widget_get_allocated_height (evbox) ); + cairo_surface = cairo_image_surface_create( CAIRO_FORMAT_RGB24, w, h ); printf("Cairo Surface: %p \n", cairo_surface ); @@ -3242,9 +3388,13 @@ static void cairo_handle_resize( int width, int height ) { printf("Cairo Format: ARGB32 \n" ); } + cairo_recalc_mapper(); + guiClearSurface(); - cairo_surface_mark_dirty( cairo_surface ); + transferPix2CairoSurface(); + + //cairo_surface_mark_dirty( cairo_surface ); } @@ -3254,31 +3404,26 @@ gboolean handle_resize (GtkWindow * win, GdkEvent * event, gpointer data) // of the GTK window as possible // get new window width/height - int width, height, draw_width, draw_height, winsize_changed = 0; + int width, height, winsize_changed = 0; + width = event->configure.width; height = event->configure.height; //printf ("DEBUG: Configure new window size: %dx%d\n", width, height); - winsize_changed = (width != gtk_win_width) || (height != gtk_win_height); - - gtk_win_width = width; - gtk_win_height = height; + winsize_changed = 0; // get width/height multipliers double xscale = width / (double) NES_WIDTH; double yscale = height / (double) NES_HEIGHT; - draw_width = gtk_win_width; - draw_height = gtk_win_height - gtk_win_menu_ysize; - //printf("DRAW: %ix%i MenuY: %i \n", draw_width, draw_height, gtk_win_menu_ysize ); - if ( (draw_width != gtk_draw_area_width) || (draw_height != gtk_draw_area_height) ) + if ( (width != gtk_draw_area_width) || (height != gtk_draw_area_height) ) { winsize_changed = 1; } - gtk_draw_area_width = draw_width; - gtk_draw_area_height = draw_height; + gtk_draw_area_width = width; + gtk_draw_area_height = height; 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; @@ -3292,7 +3437,7 @@ gboolean handle_resize (GtkWindow * win, GdkEvent * event, gpointer data) if ( useCairoDraw ) { - cairo_handle_resize( draw_width, draw_height ); + cairo_handle_resize( width, height ); } //TODO if openGL make these integers @@ -3340,14 +3485,6 @@ static gboolean cairo_clear_cb (GtkWidget * widget, cairo_t * cr, gpointer data) static gboolean cairo_draw_cb (GtkWidget * widget, cairo_t * cr, gpointer data) { - gtk_draw_area_width = gtk_widget_get_allocated_width (widget); - gtk_draw_area_height = gtk_widget_get_allocated_height (widget); - - 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; - - gtk_win_menu_ysize = gtk_win_height - gtk_draw_area_height; - cairo_set_source_surface (cr, cairo_surface, 0, 0); cairo_paint (cr); @@ -3357,6 +3494,12 @@ static gboolean cairo_draw_cb (GtkWidget * widget, cairo_t * cr, gpointer data) static gboolean draw_cb (GtkWidget * widget, cairo_t * cr, gpointer data) { + gtk_draw_area_width = gtk_widget_get_allocated_width (widget); + gtk_draw_area_height = gtk_widget_get_allocated_height (widget); + + 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 ( useCairoDraw ) { cairo_draw_cb( widget, cr, data ); @@ -3419,7 +3562,8 @@ int InitGTKSubsystem (int argc, char **argv) g_config->getOption("SDL.OpenGL", &s_useOpenGL); #endif - drawAreaGL = s_useOpenGL; + drawAreaGL = s_useOpenGL; + useCairoDraw = !drawAreaGL; evbox = gtk_drawing_area_new (); diff --git a/src/drivers/sdl/sdl-video.cpp b/src/drivers/sdl/sdl-video.cpp index 38aa34b1..7a42a3c2 100644 --- a/src/drivers/sdl/sdl-video.cpp +++ b/src/drivers/sdl/sdl-video.cpp @@ -908,7 +908,8 @@ BlitScreen(uint8 *XBuf) //} // refresh the palette if required - if(s_paletterefresh) { + if (s_paletterefresh) + { RedoPalette(); s_paletterefresh = 0; } @@ -945,34 +946,36 @@ BlitScreen(uint8 *XBuf) if ( dest == NULL ) return; //if(s_fullscreen) { // Always do this calculation now. Screen resolution is always provided. - xo = (int)(((w - NWIDTH * s_exs)) / 2); - dest += xo * (s_curbpp >> 3); - if(h > (s_tlines * s_eys)) { - yo = (int)((h - s_tlines * s_eys) / 2); - dest += yo * pitch; - } +// xo = (int)(((w - NWIDTH * s_exs)) / 2); +// dest += xo * (s_curbpp >> 3); +// if(h > (s_tlines * s_eys)) { +// yo = (int)((h - s_tlines * s_eys) / 2); +// dest += yo * 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_useOpenGL) { - Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines, - pitch, 1, 1); - } else { - Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines, - pitch, (int)s_exs, (int)s_eys); - } - } else { - if(s_BlitBuf) { - Blit8To8(XBuf + NOFFSET, dest, NWIDTH, s_tlines, - pitch, 1, 1, 0, s_sponge); - } else { - Blit8To8(XBuf + NOFFSET, dest, NWIDTH, s_tlines, - pitch, (int)s_exs, (int)s_eys, - s_eefx, s_sponge); - } - } + //if(s_curbpp > 8) { + // if(s_useOpenGL) { + // Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines, + // pitch, 1, 1); + // } else { + // Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines, + // pitch, (int)s_exs, (int)s_eys); + // } + //} else { + // if(s_BlitBuf) { + // Blit8To8(XBuf + NOFFSET, dest, NWIDTH, s_tlines, + // pitch, 1, 1, 0, s_sponge); + // } else { + // Blit8To8(XBuf + NOFFSET, dest, NWIDTH, s_tlines, + // pitch, (int)s_exs, (int)s_eys, + // s_eefx, s_sponge); + // } + //} //print_pixels(); // guiPixelBufferReDraw(); @@ -982,12 +985,12 @@ BlitScreen(uint8 *XBuf) // SDL_UnlockSurface(TmpScreen); //} - int scrw; - if(s_sponge == 3) { // NTSC 2x - scrw = 301; - } else { - scrw = NWIDTH; - } + //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) { From 9db334275fa9879f3aceb623ff89dca0862a0110 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Mon, 8 Jun 2020 09:14:01 -0400 Subject: [PATCH 08/25] Added logic to allow for switching from openGL to cairo draw functions. There is still an issue with the GTK draw update stops getting called when switch from openGL to cairo. --- src/drivers/sdl/glxwin.cpp | 81 +++++++++++++--- src/drivers/sdl/glxwin.h | 10 ++ src/drivers/sdl/gui.cpp | 104 ++++++++++++++++---- src/drivers/sdl/gui.h | 5 + src/drivers/sdl/sdl-video.cpp | 178 ++++++++++++++++++---------------- 5 files changed, 266 insertions(+), 112 deletions(-) diff --git a/src/drivers/sdl/glxwin.cpp b/src/drivers/sdl/glxwin.cpp index 12a84801..6e496dfe 100644 --- a/src/drivers/sdl/glxwin.cpp +++ b/src/drivers/sdl/glxwin.cpp @@ -30,7 +30,7 @@ static XVisualInfo *vi = NULL; static Colormap cmap; static XSetWindowAttributes swa; static Window win; -static GLXContext glc; +static GLXContext glc = NULL; static XWindowAttributes gwa; static XEvent xev; @@ -77,6 +77,10 @@ static glxwin_shm_t *open_shm(void) sem_init( &vaddr->sem, 1, 1 ); + vaddr->ncol = 256; + vaddr->nrow = 256; + vaddr->pitch = 256 * 4; + return vaddr; } //************************************************************************ @@ -84,6 +88,11 @@ static void genTextures(void) { int ipolate = 1; + if ( gltexture ) + { + printf("GL Texture already exists\n"); + return; + } glEnable(GL_TEXTURE_2D); glGenTextures(1, &gltexture); @@ -131,11 +140,18 @@ static int open_window(void) XStoreName(dpy, win, "FCEUX VIEWPORT"); - glc = glXCreateContext(dpy, vi, NULL, GL_TRUE); - if ( glc == NULL ) { - printf("Error: glXCreateContext Failed\n"); + glc = glXCreateContext(dpy, vi, NULL, GL_TRUE); + + if ( glc == NULL ) + { + printf("Error: glXCreateContext Failed\n"); + } + } + else + { + printf("GLX Context Already Exists\n"); } glXMakeCurrent(dpy, win, glc); @@ -166,11 +182,13 @@ static void print_pixbuf(void) //************************************************************************ static void render_image(void) { - int l=0, r=GLX_NES_WIDTH; - int t=0, b=GLX_NES_HEIGHT; + 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; - float xscale = (float)screen_width / (float)GLX_NES_WIDTH; - float yscale = (float)screen_height / (float)GLX_NES_HEIGHT; if (xscale < yscale ) { yscale = xscale; @@ -184,6 +202,17 @@ static void render_image(void) 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 ); @@ -251,7 +280,7 @@ static int mainWindowLoop(void) //glViewport(0, 0, gwa.width, gwa.height); //DrawAQuad(); glXSwapBuffers(dpy, win); - printf("Expose\n"); + //printf("Expose\n"); } else if (xev.type == ConfigureNotify) { @@ -267,7 +296,7 @@ static int mainWindowLoop(void) //genTextures(); - printf("Resize Request: (%i,%i)\n", screen_width, screen_height ); + //printf("Resize Request: (%i,%i)\n", screen_width, screen_height ); render_image(); //glViewport(0, 0, gwa.width, gwa.height); //DrawAQuad(); @@ -350,6 +379,8 @@ int init_gtk3_GLXContext( void ) { XWindowAttributes xattrb; + printf("Init GLX Context\n"); + GdkWindow *gdkWin = gtk_widget_get_window(evbox); if ( gdkWin == NULL ) @@ -390,11 +421,14 @@ int init_gtk3_GLXContext( void ) printf("\n\tvisual %p selected\n", (void *)vi->visualid); /* %p creates hexadecimal output like in glxinfo */ } - glc = glXCreateContext(dpy, vi, NULL, GL_TRUE); - if ( glc == NULL ) { - printf("Error: glXCreateContext Failed\n"); + glc = glXCreateContext(dpy, vi, NULL, GL_TRUE); + + if ( glc == NULL ) + { + printf("Error: glXCreateContext Failed\n"); + } } glXMakeCurrent(dpy, win, glc); @@ -412,6 +446,27 @@ int init_gtk3_GLXContext( void ) 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; + } + return 0; +} +//************************************************************************ int gtk3_glx_render(void) { screen_width = gtk_draw_area_width; diff --git a/src/drivers/sdl/glxwin.h b/src/drivers/sdl/glxwin.h index ed1b64e5..2f2fad40 100644 --- a/src/drivers/sdl/glxwin.h +++ b/src/drivers/sdl/glxwin.h @@ -11,6 +11,7 @@ int spawn_glxwin( int flags ); int init_gtk3_GLXContext( void ); +int destroy_gtk3_GLXContext( void ); int gtk3_glx_render(void); @@ -25,6 +26,10 @@ struct glxwin_shm_t uint32_t blit_count; sem_t sem; + int ncol; + int nrow; + int pitch; + // Pass Key Events back to GTK Gui struct { @@ -56,6 +61,11 @@ struct glxwin_shm_t } guiEvent; uint32_t pixbuf[65536]; // 256 x 256 + + void clear_pixbuf(void) + { + memset( pixbuf, 0, sizeof(pixbuf) ); + } }; extern glxwin_shm_t *glx_shm; diff --git a/src/drivers/sdl/gui.cpp b/src/drivers/sdl/gui.cpp index 796ca4be..90e006ac 100644 --- a/src/drivers/sdl/gui.cpp +++ b/src/drivers/sdl/gui.cpp @@ -85,6 +85,8 @@ unsigned int gtk_draw_area_height = NES_HEIGHT; static GtkTreeStore *hotkey_store = NULL; static cairo_surface_t *cairo_surface = NULL; static int *cairo_pix_remapper = NULL; +static int numRendLines = 0; +static void cairo_recalc_mapper(void); static gint convertKeypress (GtkWidget * grab, GdkEventKey * event, gpointer user_data); @@ -3104,6 +3106,7 @@ union cairo_pixel_t static void transferPix2CairoSurface(void) { union cairo_pixel_t *p; + union cairo_pixel_t *g; int x, y, i,j, w, h; if ( cairo_surface == NULL ) @@ -3112,10 +3115,16 @@ static void transferPix2CairoSurface(void) } cairo_surface_flush( cairo_surface ); + if ( numRendLines != glx_shm->nrow ) + { + cairo_recalc_mapper(); + } + w = cairo_image_surface_get_width (cairo_surface); h = cairo_image_surface_get_height (cairo_surface); p = (cairo_pixel_t*)cairo_image_surface_get_data (cairo_surface); + g = (cairo_pixel_t*)glx_shm->pixbuf; i=0; for (y=0; ypixbuf[j]; + // RGBA to ARGB + #ifdef LSB_FIRST + p[i].u8[2] = g[j].u8[0]; + p[i].u8[1] = g[j].u8[1]; + p[i].u8[0] = g[j].u8[2]; + p[i].u8[3] = g[j].u8[3]; + #else + p[i].u32 = g[j].u32; + #endif //p[i].u32 = 0xffffffff; } i++; @@ -3268,7 +3285,7 @@ static void cairo_recalc_mapper(void) { int w, h, s; int i, j, x, y; - int sw, sh, rx, ry; + int sw, sh, rx, ry, gw, gh; int llx, lly, urx, ury; float sx, sy, nw, nh; @@ -3276,6 +3293,9 @@ static void cairo_recalc_mapper(void) h = cairo_image_surface_get_height (cairo_surface); s = w * h * 4; + gw = glx_shm->ncol; + gh = glx_shm->nrow; + if ( cairo_pix_remapper != NULL ) { ::free( cairo_pix_remapper ); cairo_pix_remapper = NULL; @@ -3289,8 +3309,8 @@ static void cairo_recalc_mapper(void) } memset( cairo_pix_remapper, 0, s ); - sx = (float)w / (float)GLX_NES_WIDTH; - sy = (float)h / (float)GLX_NES_HEIGHT; + sx = (float)w / (float)gw; + sy = (float)h / (float)gh; if (sx < sy ) { @@ -3301,8 +3321,8 @@ static void cairo_recalc_mapper(void) sx = sy; } - sw = (int) ( (float)GLX_NES_WIDTH * sx ); - sh = (int) ( (float)GLX_NES_HEIGHT * sy ); + sw = (int) ( (float)gw * sx ); + sh = (int) ( (float)gh * sy ); llx = (w - sw) / 2; lly = (h - sh) / 2; @@ -3332,8 +3352,8 @@ static void cairo_recalc_mapper(void) nw = (float)(x - llx) / (float)sw; nh = (float)(y - lly) / (float)sh; - rx = (int)((float)GLX_NES_WIDTH * nw); - ry = (int)((float)GLX_NES_HEIGHT * nh); + rx = (int)((float)gw * nw); + ry = (int)((float)gh * nh); if ( rx < 0 ) { @@ -3353,7 +3373,6 @@ static void cairo_recalc_mapper(void) } j = (ry * GLX_NES_WIDTH) + rx; - //j = (rx * GLX_NES_WIDTH) + ry; cairo_pix_remapper[i] = j; i++; @@ -3362,9 +3381,10 @@ static void cairo_recalc_mapper(void) } } } + numRendLines = gh; } -static void cairo_handle_resize( int width, int height ) +static void cairo_handle_resize(void) { int w, h; cairo_format_t cairo_format; @@ -3376,18 +3396,15 @@ static void cairo_handle_resize( int width, int height ) w = gtk_widget_get_allocated_width( evbox ); h = gtk_widget_get_allocated_height( evbox ); + //cairo_surface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, w, h ); cairo_surface = cairo_image_surface_create( CAIRO_FORMAT_RGB24, w, h ); printf("Cairo Surface: %p \n", cairo_surface ); cairo_format = cairo_image_surface_get_format( cairo_surface ); - printf("Cairo Format: %i \n", cairo_format ); + //printf("Cairo Format: %i \n", cairo_format ); - if ( cairo_format == CAIRO_FORMAT_ARGB32 ) - { - printf("Cairo Format: ARGB32 \n" ); - } cairo_recalc_mapper(); guiClearSurface(); @@ -3397,6 +3414,54 @@ static void cairo_handle_resize( int width, int height ) //cairo_surface_mark_dirty( cairo_surface ); } +int destroy_gui_video( void ) +{ + printf("Destroy GUI Video\n"); + + destroy_cairo_screen(); + + destroy_gtk3_GLXContext(); + + return 0; +} + +int init_gui_video( int use_openGL ) +{ + drawAreaGL = use_openGL; + useCairoDraw = !drawAreaGL; + + if ( use_openGL ) + { + destroy_cairo_screen(); + init_gtk3_GLXContext(); + } + else + { + destroy_gtk3_GLXContext(); + init_cairo_screen(); + } + return 0; +} + +void init_cairo_screen(void) +{ + cairo_handle_resize(); +} + +void destroy_cairo_screen(void) +{ + if (cairo_surface) + { + printf("Destroying Cairo Surface\n"); + cairo_surface_destroy (cairo_surface); cairo_surface = NULL; + } + if ( cairo_pix_remapper != NULL ) + { + printf("Destroying Cairo Pixel Remapper\n"); + ::free( cairo_pix_remapper ); cairo_pix_remapper = NULL; + } +} + gboolean handle_resize (GtkWindow * win, GdkEvent * event, gpointer data) { @@ -3435,9 +3500,9 @@ gboolean handle_resize (GtkWindow * win, GdkEvent * event, gpointer data) if (yscale > xscale) yscale = xscale; - if ( useCairoDraw ) + if ( useCairoDraw && winsize_changed ) { - cairo_handle_resize( width, height ); + cairo_handle_resize(); } //TODO if openGL make these integers @@ -3518,7 +3583,10 @@ drawAreaRealizeCB (GtkWidget *widget, { printf("Draw Area Realize\n"); - init_gtk3_GLXContext(); + if ( drawAreaGL ) + { + init_gtk3_GLXContext(); + } } diff --git a/src/drivers/sdl/gui.h b/src/drivers/sdl/gui.h index 73147ee9..b3313bb6 100644 --- a/src/drivers/sdl/gui.h +++ b/src/drivers/sdl/gui.h @@ -89,4 +89,9 @@ 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 diff --git a/src/drivers/sdl/sdl-video.cpp b/src/drivers/sdl/sdl-video.cpp index 7a42a3c2..bc555fcb 100644 --- a/src/drivers/sdl/sdl-video.cpp +++ b/src/drivers/sdl/sdl-video.cpp @@ -23,6 +23,7 @@ #include "sdl.h" #include "sdl-opengl.h" +#include "glxwin.h" #include "../common/vidblit.h" #include "../../fceu.h" #include "../../version.h" @@ -80,6 +81,7 @@ static int s_fullscreen = 0; static int noframe = 0; static int s_nativeWidth = -1; static int s_nativeHeight = -1; +static int initBlitToHighDone = 0; #define NWIDTH (256 - (s_clipSides ? 16 : 0)) #define NOFFSET (s_clipSides ? 8 : 0) @@ -136,6 +138,13 @@ bool FCEUD_ShouldDrawInputAids() int KillVideo() { + printf("Killing Video\n"); + + if ( glx_shm != NULL ) + { + glx_shm->clear_pixbuf(); + } + // if the IconSurface has been initialized, destroy it if (s_IconSurface) { @@ -143,51 +152,53 @@ KillVideo() s_IconSurface=0; } + //destroy_gui_video(); + // return failure if the video system was not initialized - if(s_inited == 0) + 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(); - } - } +//#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(); +// } +// } -#if SDL_VERSION_ATLEAST(2, 0, 0) - - if ( s_screen != NULL ) - { - SDL_FreeSurface( s_screen ); s_screen = NULL; - } - - if ( s_texture != NULL ) - { - SDL_DestroyTexture( s_texture ); s_texture = NULL; - } - - if ( s_renderer != NULL ) - { - SDL_DestroyRenderer( s_renderer ); s_renderer = NULL; - } - - if ( s_window != NULL ) - { - SDL_DestroyWindow( s_window ); - s_window = NULL; - } - -#endif +//#if SDL_VERSION_ATLEAST(2, 0, 0) +// +// if ( s_screen != NULL ) +// { +// SDL_FreeSurface( s_screen ); s_screen = NULL; +// } +// +// if ( s_texture != NULL ) +// { +// SDL_DestroyTexture( s_texture ); s_texture = NULL; +// } +// +// if ( s_renderer != NULL ) +// { +// SDL_DestroyRenderer( s_renderer ); s_renderer = NULL; +// } +// +// if ( s_window != NULL ) +// { +// SDL_DestroyWindow( s_window ); +// s_window = NULL; +// } +// +//#endif // shut down the SDL video sub-system //SDL_QuitSubSystem(SDL_INIT_VIDEO); @@ -198,7 +209,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/ @@ -240,7 +251,7 @@ int 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); @@ -248,10 +259,11 @@ int 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); + //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; @@ -271,6 +283,8 @@ int InitVideo(FCEUGI *gi) //} #endif + init_gui_video( s_useOpenGL ); + s_inited = 1; // check to see if we are showing FPS @@ -280,9 +294,6 @@ int InitVideo(FCEUGI *gi) rmask = 0x000000FF; gmask = 0x0000FF00; bmask = 0x00FF0000; - //rmask = 0x00FF0000; - //gmask = 0x0000FF00; - //bmask = 0x000000FF; #else rmask = 0x00FF0000; gmask = 0x0000FF00; @@ -356,36 +367,36 @@ int InitVideo(FCEUGI *gi) //s_paletterefresh = 1; // -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; - //} - } + //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) { @@ -414,13 +425,15 @@ int InitVideo(FCEUGI *gi) } #endif - if (s_curbpp > 8) + if ( !initBlitToHighDone ) { InitBlitToHigh(s_curbpp >> 3, rmask, gmask, bmask, s_eefx, s_sponge, 0); + + initBlitToHighDone = 1; } return 0; @@ -466,7 +479,7 @@ InitVideo(FCEUGI *gi) // check for OpenGL and set the global flags #ifdef OPENGL - if(s_useOpenGL && !s_sponge) { + if (s_useOpenGL && !s_sponge) { flags = SDL_OPENGL; } #endif @@ -941,7 +954,9 @@ BlitScreen(uint8 *XBuf) //dest = (uint8*)TmpScreen->pixels; dest = (uint8*)getGuiPixelBuffer( &w, &h, &pitch ); - pitch = w * 4; + glx_shm->ncol = NWIDTH; + glx_shm->nrow = s_tlines; + glx_shm->pitch = pitch; if ( dest == NULL ) return; @@ -954,6 +969,7 @@ BlitScreen(uint8 *XBuf) // } //} + //Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines, pitch, 1, 1); Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines, pitch, 1, 1); // XXX soules - again, I'm surprised SDL can't handle this From 3e2802a2de28e4fabe07f54b4fa51ae8959b22e4 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Tue, 9 Jun 2020 08:44:51 -0400 Subject: [PATCH 09/25] Bug fix for switching between openGL and cairo graphics contexts. --- src/drivers/sdl/glxwin.cpp | 17 +++++++++++++---- src/drivers/sdl/gui.cpp | 33 +++++++++++++++++++++++++++------ src/drivers/sdl/sdl.cpp | 6 +++--- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/src/drivers/sdl/glxwin.cpp b/src/drivers/sdl/glxwin.cpp index 6e496dfe..0ee7a691 100644 --- a/src/drivers/sdl/glxwin.cpp +++ b/src/drivers/sdl/glxwin.cpp @@ -153,6 +153,8 @@ static int open_window(void) { printf("GLX Context Already Exists\n"); } + XFree(vi); vi = NULL; + glXMakeCurrent(dpy, win, glc); genTextures(); @@ -405,10 +407,10 @@ int init_gtk3_GLXContext( void ) 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 ); + //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); @@ -430,6 +432,8 @@ int init_gtk3_GLXContext( void ) printf("Error: glXCreateContext Failed\n"); } } + XFree(vi); vi = NULL; + glXMakeCurrent(dpy, win, glc); genTextures(); @@ -464,6 +468,11 @@ int destroy_gtk3_GLXContext(void) printf("Destroying GLX Context\n"); glXDestroyContext(dpy, glc); glc = NULL; } + if ( dpy != NULL ) + { + XSync( dpy, False ); + } + return 0; } //************************************************************************ diff --git a/src/drivers/sdl/gui.cpp b/src/drivers/sdl/gui.cpp index 90e006ac..0c1ab7fc 100644 --- a/src/drivers/sdl/gui.cpp +++ b/src/drivers/sdl/gui.cpp @@ -84,6 +84,7 @@ unsigned int gtk_draw_area_width = NES_WIDTH; unsigned int gtk_draw_area_height = NES_HEIGHT; static GtkTreeStore *hotkey_store = NULL; static cairo_surface_t *cairo_surface = NULL; +static cairo_pattern_t *cairo_pattern = NULL; static int *cairo_pix_remapper = NULL; static int numRendLines = 0; static void cairo_recalc_mapper(void); @@ -3113,6 +3114,7 @@ static void transferPix2CairoSurface(void) { return; } + //printf("Cairo Pixel ReMap\n"); cairo_surface_flush( cairo_surface ); if ( numRendLines != glx_shm->nrow ) @@ -3135,7 +3137,7 @@ static void transferPix2CairoSurface(void) if ( j < 0 ) { - p[i].u32 = 0; + p[i].u32 = 0xff000000; } else { @@ -3144,9 +3146,13 @@ static void transferPix2CairoSurface(void) p[i].u8[2] = g[j].u8[0]; p[i].u8[1] = g[j].u8[1]; p[i].u8[0] = g[j].u8[2]; - p[i].u8[3] = g[j].u8[3]; + p[i].u8[3] = 0xff; // Force Alpha to full #else - p[i].u32 = g[j].u32; + // Big-Endian is untested. + p[i].u8[2] = g[j].u8[0]; + p[i].u8[1] = g[j].u8[1]; + p[i].u8[0] = g[j].u8[2]; + p[i].u8[3] = 0xff; // Force Alpha to full #endif //p[i].u32 = 0xffffffff; } @@ -3396,13 +3402,19 @@ static void cairo_handle_resize(void) w = gtk_widget_get_allocated_width( evbox ); h = gtk_widget_get_allocated_height( evbox ); - //cairo_surface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, w, h ); - cairo_surface = cairo_image_surface_create( CAIRO_FORMAT_RGB24, w, h ); + cairo_surface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, w, h ); + //cairo_surface = cairo_image_surface_create( CAIRO_FORMAT_RGB24, w, h ); printf("Cairo Surface: %p \n", cairo_surface ); cairo_format = cairo_image_surface_get_format( cairo_surface ); + if (cairo_pattern) + { + cairo_pattern_destroy (cairo_pattern); cairo_pattern = NULL; + } + cairo_pattern = cairo_pattern_create_for_surface( cairo_surface ); + //printf("Cairo Format: %i \n", cairo_format ); cairo_recalc_mapper(); @@ -3450,6 +3462,11 @@ void init_cairo_screen(void) void destroy_cairo_screen(void) { + if (cairo_pattern) + { + printf("Destroying Cairo Pattern\n"); + cairo_pattern_destroy (cairo_pattern); cairo_pattern = NULL; + } if (cairo_surface) { printf("Destroying Cairo Surface\n"); @@ -3550,7 +3567,11 @@ static gboolean cairo_clear_cb (GtkWidget * widget, cairo_t * cr, gpointer data) static gboolean cairo_draw_cb (GtkWidget * widget, cairo_t * cr, gpointer data) { - cairo_set_source_surface (cr, cairo_surface, 0, 0); + //printf("Cairo Draw\n"); + //cairo_clear_cb( widget, cr, data ); + //cairo_surface_mark_dirty( cairo_surface ); + //cairo_set_source_surface (cr, cairo_surface, 0, 0); + cairo_set_source (cr, cairo_pattern); cairo_paint (cr); return FALSE; diff --git a/src/drivers/sdl/sdl.cpp b/src/drivers/sdl/sdl.cpp index 2e8beda7..137a1deb 100644 --- a/src/drivers/sdl/sdl.cpp +++ b/src/drivers/sdl/sdl.cpp @@ -561,9 +561,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(); From cfbe2dc5f3f2b8902d39206ea25ecd4f49701aaa Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Tue, 9 Jun 2020 09:23:32 -0400 Subject: [PATCH 10/25] Bug fixes for GL linear filters and double buffering options. --- src/drivers/sdl/config.cpp | 6 +-- src/drivers/sdl/glxwin.cpp | 78 ++++++++++++++++++++++---------------- src/drivers/sdl/glxwin.h | 6 ++- src/drivers/sdl/gui.cpp | 17 ++++++--- 4 files changed, 65 insertions(+), 42 deletions(-) diff --git a/src/drivers/sdl/config.cpp b/src/drivers/sdl/config.cpp index 0c91e621..9774e0d0 100644 --- a/src/drivers/sdl/config.cpp +++ b/src/drivers/sdl/config.cpp @@ -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); diff --git a/src/drivers/sdl/glxwin.cpp b/src/drivers/sdl/glxwin.cpp index 0ee7a691..ab000ee3 100644 --- a/src/drivers/sdl/glxwin.cpp +++ b/src/drivers/sdl/glxwin.cpp @@ -25,7 +25,6 @@ static Display *dpy = NULL; static Window root; -static GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None }; static XVisualInfo *vi = NULL; static Colormap cmap; static XSetWindowAttributes swa; @@ -33,9 +32,10 @@ static Window win; static GLXContext glc = NULL; static XWindowAttributes gwa; static XEvent xev; +static GLint double_buffer_ena = True; static GLuint gltexture = 0; -static int spawn_new_window = 1; +static int spawn_new_window = 0; glxwin_shm_t *glx_shm = NULL; @@ -84,17 +84,32 @@ static glxwin_shm_t *open_shm(void) return vaddr; } //************************************************************************ -static void genTextures(void) +static void getAttrbList( GLint *buf ) { - int ipolate = 1; + int i=0; + + buf[i] = GLX_RGBA; i++; + buf[i] = GLX_DEPTH_SIZE; i++; + buf[i] = 24; i++; + buf[i] = GLX_DOUBLEBUFFER ; i++; + buf[i] = double_buffer_ena; i++; + buf[i] = None; + +} +//************************************************************************ +static void genTextures( int ipolate ) +{ + glEnable(GL_TEXTURE_2D); if ( gltexture ) { printf("GL Texture already exists\n"); - return; } - glEnable(GL_TEXTURE_2D); - glGenTextures(1, &gltexture); + else + { + glGenTextures(1, &gltexture); + } + printf("Linear Interpolation on GL Texture: %s \n", ipolate ? "Enabled" : "Disabled"); glBindTexture(GL_TEXTURE_2D, gltexture); @@ -107,6 +122,9 @@ static void genTextures(void) //************************************************************************ static int open_window(void) { + GLint att[32]; + + getAttrbList( att ); dpy = XOpenDisplay(NULL); @@ -157,7 +175,7 @@ static int open_window(void) glXMakeCurrent(dpy, win, glc); - genTextures(); + genTextures(1); glDisable(GL_DEPTH_TEST); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Background color to black. glMatrixMode(GL_PROJECTION); @@ -171,16 +189,16 @@ static int open_window(void) 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[x*256+y] ); - } - } -} +//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) { @@ -286,23 +304,10 @@ static int mainWindowLoop(void) } else if (xev.type == ConfigureNotify) { - //XGetWindowAttributes(dpy, win, &gwa); - screen_width = xev.xconfigure.width; screen_height = xev.xconfigure.height; - //if (gltexture) { - // glDeleteTextures(1, &gltexture); - //} - //gltexture=0; - - //genTextures(); - - //printf("Resize Request: (%i,%i)\n", screen_width, screen_height ); render_image(); - //glViewport(0, 0, gwa.width, gwa.height); - //DrawAQuad(); - //glXSwapBuffers(dpy, win); } else if (xev.type == KeyPress) { @@ -377,11 +382,18 @@ int spawn_glxwin( int flags ) return pid; } //************************************************************************ -int init_gtk3_GLXContext( void ) +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); @@ -436,7 +448,7 @@ int init_gtk3_GLXContext( void ) glXMakeCurrent(dpy, win, glc); - genTextures(); + 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); diff --git a/src/drivers/sdl/glxwin.h b/src/drivers/sdl/glxwin.h index 2f2fad40..ba2d8224 100644 --- a/src/drivers/sdl/glxwin.h +++ b/src/drivers/sdl/glxwin.h @@ -10,7 +10,11 @@ int spawn_glxwin( int flags ); -int init_gtk3_GLXContext( void ); +#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); diff --git a/src/drivers/sdl/gui.cpp b/src/drivers/sdl/gui.cpp index 0c1ab7fc..180de200 100644 --- a/src/drivers/sdl/gui.cpp +++ b/src/drivers/sdl/gui.cpp @@ -3444,8 +3444,18 @@ int init_gui_video( int use_openGL ) if ( use_openGL ) { + 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; + destroy_cairo_screen(); - init_gtk3_GLXContext(); + init_gtk3_GLXContext( flags ); } else { @@ -3604,10 +3614,7 @@ drawAreaRealizeCB (GtkWidget *widget, { printf("Draw Area Realize\n"); - if ( drawAreaGL ) - { - init_gtk3_GLXContext(); - } + init_gui_video( drawAreaGL ); } From d08671404011fd81931ba71d7396476b0d509898 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Tue, 9 Jun 2020 21:47:07 -0400 Subject: [PATCH 11/25] Bug fix for full screen mode update. --- src/drivers/sdl/gui.cpp | 23 +++++++++++++++++++--- src/drivers/sdl/input.cpp | 40 +++++++++++---------------------------- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/src/drivers/sdl/gui.cpp b/src/drivers/sdl/gui.cpp index 180de200..ea945496 100644 --- a/src/drivers/sdl/gui.cpp +++ b/src/drivers/sdl/gui.cpp @@ -2366,10 +2366,11 @@ unsigned int GDKToSDLKeyval (int gdk_key) } // ignore pause and screenshot hotkeys since they is handled by GTK+ as accelerators - if (sdl_key == Hotkeys[HK_PAUSE] || sdl_key == Hotkeys[HK_SCREENSHOT] || - sdl_key == Hotkeys[HK_SAVE_STATE] - || sdl_key == Hotkeys[HK_LOAD_STATE]) + if ( (sdl_key == Hotkeys[HK_PAUSE]) || (sdl_key == Hotkeys[HK_SCREENSHOT]) || + (sdl_key == Hotkeys[HK_SAVE_STATE]) || (sdl_key == Hotkeys[HK_LOAD_STATE]) ) + { return 0; + } return sdl_key; } @@ -2416,7 +2417,23 @@ static gboolean convertKeypress (GtkWidget * grab, GdkEventKey * event, // Create an SDL event from the keypress. sdlev.key.keysym.scancode = SDL_GetScancodeFromKey(sdlkey); sdlev.key.keysym.sym = sdlkey; + sdlev.key.keysym.mod = 0; + + if ( event->state & GDK_SHIFT_MASK ) + { + sdlev.key.keysym.mod |= KMOD_SHIFT; + } + if ( event->state & GDK_CONTROL_MASK ) + { + sdlev.key.keysym.mod |= KMOD_CTRL; + } + if ( event->state & GDK_MOD1_MASK ) + { + sdlev.key.keysym.mod |= KMOD_ALT; + } + sdlev.key.repeat = 0; + if (sdlkey != 0) { SDL_PushEvent (&sdlev); diff --git a/src/drivers/sdl/input.cpp b/src/drivers/sdl/input.cpp index c41665d7..618a480f 100644 --- a/src/drivers/sdl/input.cpp +++ b/src/drivers/sdl/input.cpp @@ -49,7 +49,7 @@ #include /** GLOBALS **/ -int NoWaiting = 1; +int NoWaiting = 0; extern Config *g_config; extern bool bindSavestate, frameAdvanceLagSkip, lagCounterDisplay; @@ -448,7 +448,7 @@ unsigned int *GetKeyboard(void) /** * Parse keyboard commands and execute accordingly. */ -static void KeyboardCommands () +static void KeyboardCommands (void) { int is_shift, is_alt; @@ -474,11 +474,6 @@ static void KeyboardCommands () 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) { return; @@ -502,23 +497,11 @@ static void KeyboardCommands () #endif { 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 } else + { is_alt = 0; + } if (_keyonly (Hotkeys[HK_TOGGLE_BG])) @@ -534,12 +517,11 @@ static void KeyboardCommands () } // Alt-Enter to toggle full-screen - if (keyonly (ENTER) && is_alt) - { - ToggleFS (); - } - - + // This is already handled by GTK Accelerator + //if (keyonly (ENTER) && is_alt) + //{ + // ToggleFS (); + //} // Toggle Movie auto-backup if (keyonly (M) && is_shift) @@ -687,10 +669,10 @@ static void KeyboardCommands () } // Toggle throttling - NoWaiting &= ~1; if ( _keyonly(Hotkeys[HK_TURBO]) ) { - NoWaiting |= 1; + NoWaiting ^= 1; + //printf("NoWaiting: 0x%04x\n", NoWaiting ); } static bool frameAdvancing = false; From 1463e7c0f8ba7622f0b1af654388cf2ecde4116a Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Tue, 9 Jun 2020 22:09:29 -0400 Subject: [PATCH 12/25] Added logic to now pass ALT + Return to the SDL event queue as the is fullscreen toggle that is handled by GTK. --- src/drivers/sdl/gui.cpp | 11 +++++++++++ src/drivers/sdl/input.cpp | 9 +++++++++ src/drivers/sdl/input.h | 1 + 3 files changed, 21 insertions(+) diff --git a/src/drivers/sdl/gui.cpp b/src/drivers/sdl/gui.cpp index ea945496..ccf53e0d 100644 --- a/src/drivers/sdl/gui.cpp +++ b/src/drivers/sdl/gui.cpp @@ -2434,6 +2434,17 @@ static gboolean convertKeypress (GtkWidget * grab, GdkEventKey * event, } sdlev.key.repeat = 0; + + if ( (event->state & GDK_MOD1_MASK) || + getKeyState( SDL_SCANCODE_LALT ) || getKeyState( SDL_SCANCODE_RALT ) ) + { + // Don't pass ALT + Enter to game, as this toggles fullscreen in GTK + if ( sdlkey == SDLK_RETURN ) + { + return FALSE; + } + } + if (sdlkey != 0) { SDL_PushEvent (&sdlev); diff --git a/src/drivers/sdl/input.cpp b/src/drivers/sdl/input.cpp index 618a480f..731624cf 100644 --- a/src/drivers/sdl/input.cpp +++ b/src/drivers/sdl/input.cpp @@ -147,6 +147,15 @@ static int DIPS = 0; static uint8 keyonce[MKK_COUNT]; #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) { diff --git a/src/drivers/sdl/input.h b/src/drivers/sdl/input.h index 033d5077..331d2795 100644 --- a/src/drivers/sdl/input.h +++ b/src/drivers/sdl/input.h @@ -20,6 +20,7 @@ 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); From 4cbfed2a726bb829fabdf4efbeaab73378df4b61 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Fri, 12 Jun 2020 18:59:38 -0400 Subject: [PATCH 13/25] Clean up of input and video files. Removed SDL1 code. --- src/drivers/sdl/input.cpp | 154 ++------ src/drivers/sdl/sdl-video.cpp | 691 +--------------------------------- 2 files changed, 31 insertions(+), 814 deletions(-) diff --git a/src/drivers/sdl/input.cpp b/src/drivers/sdl/input.cpp index 731624cf..30626c8d 100644 --- a/src/drivers/sdl/input.cpp +++ b/src/drivers/sdl/input.cpp @@ -137,14 +137,10 @@ DoCheatSeq () } #include "keyscan.h" -#if SDL_VERSION_ATLEAST(2, 0, 0) static uint8 g_keyState[SDL_NUM_SCANCODES]; -#else -static uint8 *g_keyState = 0; -#endif 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 ) @@ -161,12 +157,11 @@ _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 { if (!keyonce[a]) { @@ -215,24 +210,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; } @@ -446,11 +423,9 @@ 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); } @@ -463,47 +438,32 @@ static void KeyboardCommands (void) 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 ( g_keyState[SDL_SCANCODE_SCROLLLOCK] ) -#else - if (keyonly (SCROLLLOCK)) -#endif - { - g_fkbEnabled ^= 1; - FCEUI_DispMessage ("Family Keyboard %sabled.", 0, - g_fkbEnabled ? "en" : "dis"); - } + { + 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_SCANCODE_LSHIFT] - || g_keyState[SDL_SCANCODE_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_SCANCODE_LALT] - || g_keyState[SDL_SCANCODE_RALT]) -#else - if (g_keyState[SDLK_LALT] || g_keyState[SDLK_RALT]) -#endif + if (g_keyState[SDL_SCANCODE_LSHIFT] || g_keyState[SDL_SCANCODE_RSHIFT]) + { + is_shift = 1; + } + else + { + is_shift = 0; + } + + if (g_keyState[SDL_SCANCODE_LALT] || g_keyState[SDL_SCANCODE_RALT]) { is_alt = 1; } @@ -1041,52 +1001,6 @@ int ButtonConfigBegin () 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 (); @@ -1128,13 +1042,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; } } @@ -1145,8 +1054,8 @@ DTestButton (ButtConfig * bc) return 1; } } - } - return 0; + } + return 0; } @@ -1156,15 +1065,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 (), @@ -1435,9 +1338,7 @@ void InitInputInterface () int x; int attrib; -#if SDL_VERSION_ATLEAST(2, 0, 0) memset( g_keyState, 0, sizeof(g_keyState) ); -#endif for (t = 0, x = 0; x < 2; x++) { @@ -1684,11 +1585,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: { @@ -1754,11 +1651,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); } diff --git a/src/drivers/sdl/sdl-video.cpp b/src/drivers/sdl/sdl-video.cpp index bc555fcb..c6361311 100644 --- a/src/drivers/sdl/sdl-video.cpp +++ b/src/drivers/sdl/sdl-video.cpp @@ -56,16 +56,6 @@ extern Config *g_config; // STATIC GLOBALS -#if SDL_VERSION_ATLEAST(2, 0, 0) -static SDL_Window *s_window = NULL; -static SDL_Renderer *s_renderer = NULL; -static SDL_Texture *s_texture = NULL; -#endif -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 = 0; static int s_srendline, s_erendline; static int s_tlines; @@ -79,8 +69,6 @@ static int s_eefx = 0; static int s_clipSides = 0; static int s_fullscreen = 0; static int noframe = 0; -static int s_nativeWidth = -1; -static int s_nativeHeight = -1; static int initBlitToHighDone = 0; #define NWIDTH (256 - (s_clipSides ? 16 : 0)) @@ -97,38 +85,6 @@ extern unsigned int gtk_draw_area_height; * success, -1 on failure. */ -static void print_pixels(void) -{ - uint32_t i,j; - uint32_t *buf; - uint32_t pixel; - - buf = (uint32_t*)s_screen->pixels; - - i=0; j=0; - for (int x=0; xw; x++) - { - for (int y=0; yh; y++) - { - pixel = buf[i]; i++; - - if ( pixel != 0 ) - { - printf("(%i,%i) %08x ", x, y, pixel ); j++; - if ( j % 10 == 0 ) - { - printf("\n"); - } - } - //printf("(%i,%i) %08x ", x, y, pixel ); - - } - } - - - -} - //draw input aids if we are fullscreen bool FCEUD_ShouldDrawInputAids() { @@ -138,68 +94,27 @@ bool FCEUD_ShouldDrawInputAids() int KillVideo() { - printf("Killing Video\n"); + //printf("Killing Video\n"); if ( glx_shm != NULL ) { glx_shm->clear_pixbuf(); } - // if the IconSurface has been initialized, destroy it - if (s_IconSurface) - { - SDL_FreeSurface(s_IconSurface); - s_IconSurface=0; - } - //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 -//#ifdef OPENGL -// // check for OpenGL and shut it down -// if(s_useOpenGL) -// { -// KillOpenGL(); -// } -// else -//#endif -// { + // 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(); // } -// } - -//#if SDL_VERSION_ATLEAST(2, 0, 0) -// -// if ( s_screen != NULL ) -// { -// SDL_FreeSurface( s_screen ); s_screen = NULL; -// } -// -// if ( s_texture != NULL ) -// { -// SDL_DestroyTexture( s_texture ); s_texture = NULL; -// } -// -// if ( s_renderer != NULL ) -// { -// SDL_DestroyRenderer( s_renderer ); s_renderer = NULL; -// } -// -// if ( s_window != NULL ) -// { -// SDL_DestroyWindow( s_window ); -// s_window = NULL; -// } -// -//#endif + // SDL Video system is not used. // shut down the SDL video sub-system //SDL_QuitSubSystem(SDL_INIT_VIDEO); @@ -232,15 +147,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 - // 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..."); @@ -273,16 +181,6 @@ int 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 - - // check for OpenGL and set the global flags -#ifdef OPENGL - // FIXME - //if(s_useOpenGL && !s_sponge) { - // flags = SDL_OPENGL; - //} -#endif - init_gui_video( s_useOpenGL ); s_inited = 1; @@ -300,47 +198,8 @@ int InitVideo(FCEUGI *gi) bmask = 0x000000FF; #endif - // if all this hex scares you, check out SDL_PixelFormatEnumToMasks()! -//#ifdef LSB_FIRST -// //printf("Little Endian\n"); -// s_screen = SDL_CreateRGBSurface(0, xres, yres, 32, -// 0xFF, 0xFF00, 0xFF0000, 0x00); -//#else -// //printf("Big Endian\n"); -// s_screen = SDL_CreateRGBSurface(0, xres, yres, 32, -// 0xFF0000, 0xFF00, 0xFF, 0x00); -//#endif -// -// if ( s_screen == NULL ) -// { -// fprintf(stderr, "Couldn't init SDL screen: %s\n", SDL_GetError()); -// KillVideo(); -// exit(-1); -// } -// -// s_texture = SDL_CreateTexture(s_renderer, -//#ifdef LSB_FIRST -// SDL_PIXELFORMAT_ABGR8888, -//#else -// SDL_PIXELFORMAT_ARGB8888, -//#endif -// SDL_TEXTUREACCESS_STREAMING | SDL_TEXTUREACCESS_TARGET, -// xres, yres ); -// -// if ( s_texture == NULL ) -// { -// fprintf(stderr, "Couldn't init SDL texture: %s\n", SDL_GetError()); -// KillVideo(); -// exit(-1); -// } -// #endif + s_curbpp = 32; // Bits per pixel is always 32 - //s_curbpp = s_screen->format->BitsPerPixel; - s_curbpp = 32; - - //FCEU_printf(" Video Mode: %d x %d x %d bpp %s\n", - // s_screen->w, s_screen->h, s_screen->format->BitsPerPixel, - // s_fullscreen ? "full screen" : ""); FCEU_printf(" Video Mode: %d x %d x %d bpp %s\n", xres, yres, s_curbpp, s_fullscreen ? "full screen" : ""); @@ -352,62 +211,7 @@ int InitVideo(FCEUGI *gi) return -1; } - // 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_SetWindowIcon( s_window, s_IconSurface); - - //s_paletterefresh = 1; - - // -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(); @@ -438,376 +242,11 @@ int InitVideo(FCEUGI *gi) return 0; } -#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..."); - - // load the relevant configuration variables - g_config->getOption("SDL.Fullscreen", &s_fullscreen); - g_config->getOption("SDL.DoubleBuffering", &doublebuf); -#ifdef OPENGL - g_config->getOption("SDL.OpenGL", &s_useOpenGL); -#endif - 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); - //g_config->getOption("SDL.LastYRes", &yres); - g_config->getOption("SDL.ClipSides", &s_clipSides); - g_config->getOption("SDL.NoFrame", &noframe); - g_config->getOption("SDL.ShowFPS", &show_fps); - - xres = gtk_draw_area_width; - yres = gtk_draw_area_height; - // check the starting, ending, and total scan lines - - FCEUI_GetCurrentVidSystem(&s_srendline, &s_erendline); - s_tlines = s_erendline - s_srendline + 1; - - // check if we should auto-set x/y resolution - - // 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); -#else - s_screen = SDL_SetVideoMode(xres, yres, desbpp, flags); -#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 - - FCEU_printf(" Video Mode: %d x %d x %d bpp %s\n", - s_screen->w, s_screen->h, s_screen->format->BitsPerPixel, - s_fullscreen ? "full screen" : ""); - - 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 - } - 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(); @@ -913,7 +352,6 @@ BlitScreen(uint8 *XBuf) { //SDL_Surface *TmpScreen; uint8 *dest; - int xo = 0, yo = 0; int w, h, pitch; //if(!s_screen) { @@ -927,31 +365,9 @@ BlitScreen(uint8 *XBuf) 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; - //} - - // lock the display, if necessary - //if(SDL_MUSTLOCK(TmpScreen)) { - // if(SDL_LockSurface(TmpScreen) < 0) { - // return; - // } - //} - - //dest = (uint8*)TmpScreen->pixels; dest = (uint8*)getGuiPixelBuffer( &w, &h, &pitch ); glx_shm->ncol = NWIDTH; @@ -960,95 +376,11 @@ BlitScreen(uint8 *XBuf) if ( dest == NULL ) return; - //if(s_fullscreen) { // Always do this calculation now. Screen resolution is always provided. -// xo = (int)(((w - NWIDTH * s_exs)) / 2); -// dest += xo * (s_curbpp >> 3); -// if(h > (s_tlines * s_eys)) { -// yo = (int)((h - s_tlines * s_eys) / 2); -// dest += yo * pitch; -// } - //} - - //Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines, pitch, 1, 1); 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_useOpenGL) { - // Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines, - // pitch, 1, 1); - // } else { - // Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines, - // pitch, (int)s_exs, (int)s_eys); - // } - //} else { - // if(s_BlitBuf) { - // Blit8To8(XBuf + NOFFSET, dest, NWIDTH, s_tlines, - // pitch, 1, 1, 0, s_sponge); - // } else { - // Blit8To8(XBuf + NOFFSET, dest, NWIDTH, s_tlines, - // pitch, (int)s_exs, (int)s_eys, - // s_eefx, s_sponge); - // } - //} - //print_pixels(); - // guiPixelBufferReDraw(); - // 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) - //SDL_UpdateTexture(s_texture, NULL, s_screen->pixels, s_screen->pitch); - //SDL_RenderClear(s_renderer); - //SDL_RenderCopy(s_renderer, s_texture, NULL, NULL); - //SDL_RenderPresent(s_renderer); -#else - //SDL_UpdateRect(s_screen, xo, yo, - // (Uint32)(scrw * s_exs), (Uint32)(s_tlines * s_eys)); -#endif - #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; @@ -1081,7 +413,7 @@ BlitScreen(uint8 *XBuf) NESVideoLoggingVideo( dest, width,height, fps, s_curbpp); } } -#endif +#endif // CREATE_AVI #if REALTIME_LOGGING { @@ -1108,17 +440,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 } /** From 0a61bab99e42732cff12f728996a2892f7661df4 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Fri, 12 Jun 2020 19:14:26 -0400 Subject: [PATCH 14/25] More SDL1 cleanup. --- src/drivers/sdl/SConscript | 2 - src/drivers/sdl/sdl-opengl.cpp | 279 --------------------------------- src/drivers/sdl/sdl-opengl.h | 13 -- src/drivers/sdl/sdl-sound.cpp | 32 ++-- src/drivers/sdl/sdl-video.cpp | 25 +-- 5 files changed, 23 insertions(+), 328 deletions(-) delete mode 100644 src/drivers/sdl/sdl-opengl.cpp delete mode 100644 src/drivers/sdl/sdl-opengl.h diff --git a/src/drivers/sdl/SConscript b/src/drivers/sdl/SConscript index b16ffbe7..22fbb644 100644 --- a/src/drivers/sdl/SConscript +++ b/src/drivers/sdl/SConscript @@ -23,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') diff --git a/src/drivers/sdl/sdl-opengl.cpp b/src/drivers/sdl/sdl-opengl.cpp deleted file mode 100644 index 24456a5f..00000000 --- a/src/drivers/sdl/sdl-opengl.cpp +++ /dev/null @@ -1,279 +0,0 @@ -#define GL_GLEXT_LEGACY - -#include "sdl.h" -#include "sdl-opengl.h" -#include "../common/vidblit.h" -#include "../../utils/memory.h" - -#ifdef APPLEOPENGL -#include -#include -#include -#else -#include -#include -#include -#endif -#include -#include - -#ifndef APIENTRY -#define APIENTRY -#endif - -#if SDL_VERSION_ATLEAST(2, 0, 0) -static SDL_Window *s_window = NULL; -#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); - } - #if SDL_VERSION_ATLEAST(2, 0, 0) - SDL_GL_SwapWindow(s_window); - #else - SDL_GL_SwapBuffers(); - #endif -} - -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, -#if SDL_VERSION_ATLEAST(2, 0, 0) - SDL_Window *window, -#endif - 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; - -#if SDL_VERSION_ATLEAST(2, 0, 0) - s_window = window; -#endif - 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 SDL_VERSION_ATLEAST(2, 0, 0) - // FIXME -#else - if(screen->flags & SDL_FULLSCREEN) - { - xscale=(double)screen->w / (double)(r-l); - yscale=(double)screen->h / (double)(b-t); - if(xscalew-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); - - #if SDL_VERSION_ATLEAST(2, 0, 0) - SDL_GL_SwapWindow(s_window); - #else - SDL_GL_SwapBuffers(); - #endif - - glClear(GL_COLOR_BUFFER_BIT); - - #if SDL_VERSION_ATLEAST(2, 0, 0) - SDL_GL_SwapWindow(s_window); - #else - SDL_GL_SwapBuffers(); - #endif - - return 1; -} diff --git a/src/drivers/sdl/sdl-opengl.h b/src/drivers/sdl/sdl-opengl.h deleted file mode 100644 index 4fe18d4f..00000000 --- a/src/drivers/sdl/sdl-opengl.h +++ /dev/null @@ -1,13 +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, -#if SDL_VERSION_ATLEAST(2, 0, 0) - SDL_Window *window, -#endif - SDL_Surface *screen); - diff --git a/src/drivers/sdl/sdl-sound.cpp b/src/drivers/sdl/sdl-sound.cpp index 36830ca3..00b7c9a6 100644 --- a/src/drivers/sdl/sdl-sound.cpp +++ b/src/drivers/sdl/sdl-sound.cpp @@ -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); diff --git a/src/drivers/sdl/sdl-video.cpp b/src/drivers/sdl/sdl-video.cpp index c6361311..39ca7cb8 100644 --- a/src/drivers/sdl/sdl-video.cpp +++ b/src/drivers/sdl/sdl-video.cpp @@ -22,7 +22,6 @@ /// \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" @@ -318,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? @@ -350,14 +336,9 @@ void UnlockConsole(){} void BlitScreen(uint8 *XBuf) { - //SDL_Surface *TmpScreen; uint8 *dest; int w, h, pitch; - //if(!s_screen) { - // return; - //} - // refresh the palette if required if (s_paletterefresh) { From 47ad3b1dee93ec45b3ead47d4f09ece2e805a1ae Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Fri, 12 Jun 2020 19:40:46 -0400 Subject: [PATCH 15/25] More SDL1 cleanup. --- src/drivers/sdl/input.cpp | 24 +++++++++++++++------ src/drivers/sdl/keyscan.h | 4 ---- src/drivers/sdl/sdl.cpp | 45 +++------------------------------------ 3 files changed, 20 insertions(+), 53 deletions(-) diff --git a/src/drivers/sdl/input.cpp b/src/drivers/sdl/input.cpp index 30626c8d..666725c7 100644 --- a/src/drivers/sdl/input.cpp +++ b/src/drivers/sdl/input.cpp @@ -155,22 +155,32 @@ int getKeyState( int k ) static int _keyonly (int a) { - // check for valid key - if (a > SDLK_LAST + 1 || a < 0) + int sc; + + if ( a < 0 ) { return 0; } - if (g_keyState[SDL_GetScancodeFromKey (a)]) + sc = SDL_GetScancodeFromKey(a); + + // check for valid key + if (sc >= SDL_NUM_SCANCODES || sc < 0) { - if (!keyonce[a]) + 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; } diff --git a/src/drivers/sdl/keyscan.h b/src/drivers/sdl/keyscan.h index 0a73804b..b3973c20 100644 --- a/src/drivers/sdl/keyscan.h +++ b/src/drivers/sdl/keyscan.h @@ -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) diff --git a/src/drivers/sdl/sdl.cpp b/src/drivers/sdl/sdl.cpp index 137a1deb..6859af71 100644 --- a/src/drivers/sdl/sdl.cpp +++ b/src/drivers/sdl/sdl.cpp @@ -172,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 ); @@ -680,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); From d340c1465ee178fa95af76d4e48fdc86d3798743 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Fri, 12 Jun 2020 19:48:51 -0400 Subject: [PATCH 16/25] Removed the last of the SDL1 specific functions. --- src/drivers/sdl/gui.cpp | 205 +++++++++++++++------------------------- 1 file changed, 78 insertions(+), 127 deletions(-) diff --git a/src/drivers/sdl/gui.cpp b/src/drivers/sdl/gui.cpp index ccf53e0d..c4abaa09 100644 --- a/src/drivers/sdl/gui.cpp +++ b/src/drivers/sdl/gui.cpp @@ -553,11 +553,7 @@ static void hotKeyWindowRefresh (void) g_config->getOption (optionName.c_str (), &keycode); gtk_tree_store_set (hotkey_store, &iter, 0, optionName.c_str (), 1, -#if SDL_VERSION_ATLEAST(2, 0, 0) SDL_GetKeyName (keycode), -#else - SDL_GetKeyName ((SDLKey) keycode), -#endif -1); gtk_tree_store_append (hotkey_store, &iter, NULL); // acquire child iterator } @@ -602,11 +598,8 @@ static gint hotKeyPressCB (GtkTreeView * tree, GdkEventKey * event, hotKeyName.append ( getHotkeyString(indexArray[0]) ); // Convert this keypress from GDK to SDL. -#if SDL_VERSION_ATLEAST(2, 0, 0) sdlkey = GDKToSDLKeyval (event->keyval); -#else - sdlkey = (SDLKey) GDKToSDLKeyval (event->keyval); -#endif + printf ("HotKey Index: %i '%s' %i %i \n", indexArray[0], hotKeyName.c_str (), event->keyval, sdlkey); @@ -706,16 +699,9 @@ void updateGamepadConfig (GtkWidget * w, gpointer p) if (GamePadConfig[padNo][i].ButtType[configNo] == BUTTC_KEYBOARD) { -#if SDL_VERSION_ATLEAST(2, 0, 0) snprintf (strBuf, sizeof (strBuf), "%s", SDL_GetKeyName (GamePadConfig[padNo][i]. ButtonNum[configNo])); -#else - snprintf (strBuf, sizeof (strBuf), "%s", - SDL_GetKeyName ((SDLKey) - GamePadConfig[padNo][i]. - ButtonNum[configNo])); -#endif } else sprintf (strBuf, "%s", ButtonName( &GamePadConfig[padNo][i], configNo ) ); @@ -2208,28 +2194,15 @@ static void changeState (GtkRadioMenuItem * radiomenuitem, gpointer user_data) FCEUI_SelectState ((long) user_data, 1); } -#if SDL_VERSION_ATLEAST(2, 0, 0) // SDL 1.2/2.0 compatibility macros #define SDLK_SCROLLOCK SDLK_SCROLLLOCK #define SDLK_PRINT SDLK_PRINTSCREEN #define SDLK_BREAK 0 #define SDLK_COMPOSE 0 #define SDLK_NUMLOCK SDLK_NUMLOCKCLEAR -#define SDLK_KP0 SDLK_KP_0 -#define SDLK_KP1 SDLK_KP_1 -#define SDLK_KP2 SDLK_KP_2 -#define SDLK_KP3 SDLK_KP_3 -#define SDLK_KP4 SDLK_KP_4 -#define SDLK_KP5 SDLK_KP_5 -#define SDLK_KP6 SDLK_KP_6 -#define SDLK_KP7 SDLK_KP_7 -#define SDLK_KP8 SDLK_KP_8 -#define SDLK_KP9 SDLK_KP_9 -#define SDLK_LSUPER SDLK_LGUI -#define SDLK_RSUPER SDLK_RGUI #define SDLK_LMETA 0 #define SDLK_RMETA 0 -#endif + // Adapted from Gens/GS. Converts a GDK key value into an SDL key value. unsigned int GDKToSDLKeyval (int gdk_key) { @@ -2308,16 +2281,16 @@ unsigned int GDKToSDLKeyval (int gdk_key) 0x0000, 0x0000, SDLK_MODE, SDLK_NUMLOCK, // 0x80 - 0x8F [mostly unused, except for some numeric keypad keys] - SDLK_KP5, 0x0000, 0x0000, 0x0000, + SDLK_KP_5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, SDLK_KP_ENTER, 0x0000, 0x0000, // 0x90 - 0x9F 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, SDLK_KP7, SDLK_KP4, SDLK_KP8, - SDLK_KP6, SDLK_KP2, SDLK_KP9, SDLK_KP3, - SDLK_KP1, SDLK_KP5, SDLK_KP0, SDLK_KP_PERIOD, + 0x0000, SDLK_KP_7, SDLK_KP_4, SDLK_KP_8, + SDLK_KP_6, SDLK_KP_2, SDLK_KP_9, SDLK_KP_3, + SDLK_KP_1, SDLK_KP_5, SDLK_KP_0, SDLK_KP_PERIOD, // 0xA0 - 0xAF 0x0000, 0x0000, 0x0000, 0x0000, @@ -2326,9 +2299,9 @@ unsigned int GDKToSDLKeyval (int gdk_key) 0x0000, SDLK_KP_MINUS, SDLK_KP_PERIOD, SDLK_KP_DIVIDE, // 0xB0 - 0xBF - SDLK_KP0, SDLK_KP1, SDLK_KP2, SDLK_KP3, - SDLK_KP4, SDLK_KP5, SDLK_KP6, SDLK_KP7, - SDLK_KP8, SDLK_KP9, 0x0000, 0x0000, + SDLK_KP_0, SDLK_KP_1, SDLK_KP_2, SDLK_KP_3, + SDLK_KP_4, SDLK_KP_5, SDLK_KP_6, SDLK_KP_7, + SDLK_KP_8, SDLK_KP_9, 0x0000, 0x0000, 0x0000, SDLK_KP_EQUALS, SDLK_F1, SDLK_F2, // 0xC0 - 0xCF @@ -2346,8 +2319,8 @@ unsigned int GDKToSDLKeyval (int gdk_key) // 0xE0 - 0xEF 0x0000, SDLK_LSHIFT, SDLK_RSHIFT, SDLK_LCTRL, SDLK_RCTRL, SDLK_CAPSLOCK, 0x0000, SDLK_LMETA, - SDLK_RMETA, SDLK_LALT, SDLK_RALT, SDLK_LSUPER, - SDLK_RSUPER, 0x0000, 0x0000, 0x0000, + SDLK_RMETA, SDLK_LALT, SDLK_RALT, SDLK_LGUI, + SDLK_RGUI, 0x0000, 0x0000, 0x0000, // 0xF0 - 0xFF [mostly unused, except for Delete] 0x0000, 0x0000, 0x0000, 0x0000, @@ -2381,24 +2354,18 @@ static gboolean convertKeypress (GtkWidget * grab, GdkEventKey * event, gpointer user_data) { SDL_Event sdlev; - int keystate; -#if SDL_VERSION_ATLEAST(2, 0, 0) SDL_Keycode sdlkey; -#else - SDLKey sdlkey; -#endif + switch (event->type) { case GDK_KEY_PRESS: sdlev.type = SDL_KEYDOWN; sdlev.key.state = SDL_PRESSED; - keystate = 1; break; case GDK_KEY_RELEASE: sdlev.type = SDL_KEYUP; sdlev.key.state = SDL_RELEASED; - keystate = 0; break; default: @@ -2408,11 +2375,7 @@ static gboolean convertKeypress (GtkWidget * grab, GdkEventKey * event, } // Convert this keypress from GDK to SDL. -#if SDL_VERSION_ATLEAST(2, 0, 0) sdlkey = GDKToSDLKeyval (event->keyval); -#else - sdlkey = (SDLKey) GDKToSDLKeyval (event->keyval); -#endif // Create an SDL event from the keypress. sdlev.key.keysym.scancode = SDL_GetScancodeFromKey(sdlkey); @@ -2448,19 +2411,6 @@ static gboolean convertKeypress (GtkWidget * grab, GdkEventKey * event, if (sdlkey != 0) { SDL_PushEvent (&sdlev); - - // Only let the emulator handle the key event if this window has the input focus. - //if (keystate == 0 - // || gtk_window_is_active (GTK_WINDOW (MainWindow))) - //{ -#if SDL_VERSION_ATLEAST(2, 0, 0) - // Not sure how to do this yet with SDL 2.0 - // TODO - SDL 2.0 - //SDL_GetKeyboardState(NULL)[SDL_GetScancodeFromKey(sdlkey)] = keystate; -#else - SDL_GetKeyState (NULL)[sdlkey] = keystate; -#endif - //} } // Allow GTK+ to process this key. @@ -3268,52 +3218,52 @@ int guiClearSurface(void) return 0; } -static void loadPixelTestPattern(void) -{ - uint32_t *p; - int i,x,y,width,height,w2,h2; - - width = 256; - height = 256; - p = (uint32_t*)glx_shm->pixbuf; - - w2 = width / 2; - h2 = height / 2; - - //printf("W:%i H:%i W/2:%i H/2:%i\n", width, height, w2, h2 ); - - i=0; - for (y=0; ypixbuf; +// +// w2 = width / 2; +// h2 = height / 2; +// +// //printf("W:%i H:%i W/2:%i H/2:%i\n", width, height, w2, h2 ); +// +// i=0; +// for (y=0; y Date: Fri, 12 Jun 2020 20:34:26 -0400 Subject: [PATCH 17/25] Bugfix for GUI hanging when gamepad config window is closed while waiting a button press. --- src/drivers/sdl/gui.cpp | 58 +++++++++++++++++++++++++++------------ src/drivers/sdl/input.cpp | 14 ++++++++-- src/drivers/sdl/input.h | 2 +- 3 files changed, 54 insertions(+), 20 deletions(-) diff --git a/src/drivers/sdl/gui.cpp b/src/drivers/sdl/gui.cpp index c4abaa09..daa1f08d 100644 --- a/src/drivers/sdl/gui.cpp +++ b/src/drivers/sdl/gui.cpp @@ -72,11 +72,12 @@ GtkWidget *MainWindow = NULL; GtkWidget *evbox = NULL; GtkWidget *padNoCombo = NULL; GtkWidget *configNoCombo = NULL; -GtkWidget *buttonMappings[10]; +GtkWidget *buttonMappings[10] = { NULL }; static GtkWidget *Menubar = NULL; static GtkRadioMenuItem *stateSlot[10] = { NULL }; bool gtkIsStarted = false; bool menuTogglingEnabled = false; +static int buttonConfigStatus = 0; static char useCairoDraw = 0; static int drawAreaGL = 0; @@ -145,11 +146,13 @@ int configGamepadButton (GtkButton * button, gpointer p) if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) return 0; + buttonConfigStatus = 2; + ButtonConfigBegin (); snprintf (buf, sizeof(buf)-1, "SDL.Input.GamePad.%d.", padNo); prefix = buf; - DWaitButton (NULL, &GamePadConfig[padNo][x], configNo); + DWaitButton (NULL, &GamePadConfig[padNo][x], configNo, &buttonConfigStatus ); g_config->setOption (prefix + GamePadNames[x], GamePadConfig[padNo][x].ButtonNum[configNo]); @@ -171,10 +174,16 @@ int configGamepadButton (GtkButton * button, gpointer p) snprintf (buf, sizeof (buf), "%s", ButtonName (&GamePadConfig[padNo][x], configNo)); - gtk_label_set_markup (GTK_LABEL (buttonMappings[x]), buf); + + if ( buttonMappings[x] != NULL ) + { + gtk_label_set_markup (GTK_LABEL (buttonMappings[x]), buf); + } ButtonConfigEnd (); + buttonConfigStatus = 1; + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE); return 0; @@ -686,6 +695,11 @@ void updateGamepadConfig (GtkWidget * w, gpointer p) { int i; char strBuf[128]; + + if ( (padNoCombo == NULL) || (configNoCombo == NULL) ) + { + return; + } int padNo = atoi (gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (padNoCombo))) - 1; @@ -696,8 +710,7 @@ void updateGamepadConfig (GtkWidget * w, gpointer p) for (i = 0; i < 10; i++) { GtkWidget *mappedKey = buttonMappings[i]; - if (GamePadConfig[padNo][i].ButtType[configNo] == - BUTTC_KEYBOARD) + if (GamePadConfig[padNo][i].ButtType[configNo] == BUTTC_KEYBOARD) { snprintf (strBuf, sizeof (strBuf), "%s", SDL_GetKeyName (GamePadConfig[padNo][i]. @@ -706,22 +719,31 @@ void updateGamepadConfig (GtkWidget * w, gpointer p) else sprintf (strBuf, "%s", ButtonName( &GamePadConfig[padNo][i], configNo ) ); - gtk_label_set_text (GTK_LABEL (mappedKey), strBuf); - gtk_label_set_use_markup (GTK_LABEL (mappedKey), TRUE); + if ( mappedKey != NULL ) + { + gtk_label_set_text (GTK_LABEL (mappedKey), strBuf); + gtk_label_set_use_markup (GTK_LABEL (mappedKey), TRUE); + } } } +static void closeGamepadConfig (GtkWidget * w, GdkEvent * e, gpointer p) +{ + gtk_widget_destroy (w); + + padNoCombo = NULL; + configNoCombo = NULL; + + for (int i = 0; i < 10; i++) + { + buttonMappings[i] = NULL; + } + buttonConfigStatus = 0; +} + // creates and opens the gamepad config window (requires GTK 2.24) void openGamepadConfig (void) { - // GTK 2.24 required for this dialog - if (checkGTKVersion (2, 24) == false) - { - // TODO: present this in a GTK MessageBox? - printf (" Warning: GTK >= 2.24 required for this dialog.\nTo configure the gamepads, use \"--inputcfg\" from the command line (ie: \"fceux --inputcfg gamepad1\").\n"); - return; - } - GtkWidget *win; GtkWidget *vbox; GtkWidget *hboxPadNo; @@ -861,8 +883,8 @@ void openGamepadConfig (void) gtk_box_pack_start (GTK_BOX (vbox), buttonFrame, TRUE, TRUE, 5); - g_signal_connect (win, "delete-event", G_CALLBACK (closeDialog), NULL); - g_signal_connect (win, "response", G_CALLBACK (closeDialog), NULL); + g_signal_connect (win, "delete-event", G_CALLBACK (closeGamepadConfig), NULL); + g_signal_connect (win, "response", G_CALLBACK (closeGamepadConfig), NULL); gtk_widget_show_all (win); @@ -871,6 +893,8 @@ void openGamepadConfig (void) g_signal_connect (G_OBJECT (win), "key-release-event", G_CALLBACK (convertKeypress), NULL); + buttonConfigStatus = 1; + return; } diff --git a/src/drivers/sdl/input.cpp b/src/drivers/sdl/input.cpp index 666725c7..897508af 100644 --- a/src/drivers/sdl/input.cpp +++ b/src/drivers/sdl/input.cpp @@ -1651,7 +1651,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]; @@ -1742,6 +1742,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); @@ -1763,7 +1773,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] && diff --git a/src/drivers/sdl/input.h b/src/drivers/sdl/input.h index 331d2795..2a1a2d85 100644 --- a/src/drivers/sdl/input.h +++ b/src/drivers/sdl/input.h @@ -24,7 +24,7 @@ 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 From 6dd0ef841e56ae2874a55359e5a3d1af53e802c5 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Fri, 12 Jun 2020 20:51:46 -0400 Subject: [PATCH 18/25] Cleaned up unused variable. --- src/drivers/sdl/sdl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/sdl/sdl.cpp b/src/drivers/sdl/sdl.cpp index 6859af71..3d10af15 100644 --- a/src/drivers/sdl/sdl.cpp +++ b/src/drivers/sdl/sdl.cpp @@ -819,7 +819,7 @@ int main(int argc, char *argv[]) #ifdef _GTK if(noGui == 0) { - int glxwin_pid = spawn_glxwin(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()) From a4309af84782b23a566ec38383a0b35a5185b3f1 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Fri, 12 Jun 2020 21:10:52 -0400 Subject: [PATCH 19/25] Removed SDL1 from pipeline build script. --- pipelines/linux_build.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pipelines/linux_build.sh b/pipelines/linux_build.sh index 5acd73b1..118422fa 100755 --- a/pipelines/linux_build.sh +++ b/pipelines/linux_build.sh @@ -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 '****************************************' From 6de7a681495fd99da2ecff3fe2c2b2d5c18d9a7b Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Fri, 12 Jun 2020 21:34:18 -0400 Subject: [PATCH 20/25] Added a TODO for fixing the menu bar hide function. --- src/drivers/sdl/gui.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/drivers/sdl/gui.cpp b/src/drivers/sdl/gui.cpp index daa1f08d..286e12b5 100644 --- a/src/drivers/sdl/gui.cpp +++ b/src/drivers/sdl/gui.cpp @@ -3685,6 +3685,7 @@ int InitGTKSubsystem (int argc, char **argv) g_signal_connect (G_OBJECT (evbox), "button-release-event", G_CALLBACK (handleMouseClick), NULL); + // TODO Menu Bar Toggle Needs Work //g_signal_connect(G_OBJECT(MainWindow), "key-release-event", G_CALLBACK(handleKeyRelease), NULL); // signal handlers From b4b2cca9ec4ad7f70e5a3ba0d28950f6e4af47ac Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 13 Jun 2020 12:51:57 -0400 Subject: [PATCH 21/25] Bug fix for menu visibility toggle. --- src/drivers/sdl/gui.cpp | 27 ++++++-------------- src/drivers/sdl/gui.h | 1 + src/drivers/sdl/input.cpp | 52 +++++++++++++++++++++++++-------------- 3 files changed, 42 insertions(+), 38 deletions(-) diff --git a/src/drivers/sdl/gui.cpp b/src/drivers/sdl/gui.cpp index 286e12b5..48bb3b6b 100644 --- a/src/drivers/sdl/gui.cpp +++ b/src/drivers/sdl/gui.cpp @@ -2698,7 +2698,7 @@ static GtkWidget *CreateMenubar (GtkWidget * window) gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); //-Options --> Toggle Menubar --------------------- - item = gtk_check_menu_item_new_with_label ("Toggle Menubar (alt)"); + item = gtk_check_menu_item_new_with_label ("Toggle Menubar (Alt+M)"); //gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(item), FALSE); @@ -3039,27 +3039,19 @@ void showGui (bool b) } } -gint handleKeyRelease (GtkWidget * w, GdkEvent * event, gpointer cb_data) +void toggleMenuVis(void) { if (menuTogglingEnabled) { - static bool menuShown = true; - if (((GdkEventKey *) event)->keyval == GDK_KEY_Alt_L - || ((GdkEventKey *) event)->keyval == GDK_KEY_Alt_R) + if ( gtk_widget_get_visible(Menubar) ) { - if (menuShown) - { - gtk_widget_hide (Menubar); - menuShown = false; - } - else - { - gtk_widget_show (Menubar); - menuShown = true; - } + gtk_widget_hide (Menubar); + } + else + { + gtk_widget_show (Menubar); } } - return 0; }; int GtkMouseData[3] = { 0, 0, 0 }; @@ -3685,9 +3677,6 @@ int InitGTKSubsystem (int argc, char **argv) g_signal_connect (G_OBJECT (evbox), "button-release-event", G_CALLBACK (handleMouseClick), NULL); - // TODO Menu Bar Toggle Needs Work - //g_signal_connect(G_OBJECT(MainWindow), "key-release-event", G_CALLBACK(handleKeyRelease), NULL); - // signal handlers g_signal_connect (MainWindow, "delete-event", quit, NULL); g_signal_connect (MainWindow, "destroy-event", quit, NULL); diff --git a/src/drivers/sdl/gui.h b/src/drivers/sdl/gui.h index b3313bb6..e824d4a2 100644 --- a/src/drivers/sdl/gui.h +++ b/src/drivers/sdl/gui.h @@ -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); diff --git a/src/drivers/sdl/input.cpp b/src/drivers/sdl/input.cpp index 897508af..3943f35f 100644 --- a/src/drivers/sdl/input.cpp +++ b/src/drivers/sdl/input.cpp @@ -501,31 +501,45 @@ static void KeyboardCommands (void) //{ // ToggleFS (); //} + // + + // Alt-M to toggle Main Menu Visibility + if ( is_alt ) + { + 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 From a1c0e86026e4e056c221a677216ee06095260f1e Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sat, 13 Jun 2020 20:07:01 -0400 Subject: [PATCH 22/25] Code cleanup, found that rendering of openGL graphics are limiting the max frame speed to 60 hz. Have not solution for it yet. --- src/drivers/sdl/sdl-throttle.cpp | 10 +++++++--- src/drivers/sdl/sdl.cpp | 9 ++++++++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/drivers/sdl/sdl-throttle.cpp b/src/drivers/sdl/sdl-throttle.cpp index 6832f954..498d4fe7 100644 --- a/src/drivers/sdl/sdl-throttle.cpp +++ b/src/drivers/sdl/sdl-throttle.cpp @@ -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) { diff --git a/src/drivers/sdl/sdl.cpp b/src/drivers/sdl/sdl.cpp index 3d10af15..fb421832 100644 --- a/src/drivers/sdl/sdl.cpp +++ b/src/drivers/sdl/sdl.cpp @@ -911,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 From f5e8b09200b3501411db39511295d198d1ac3ae0 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 14 Jun 2020 10:15:47 -0400 Subject: [PATCH 23/25] Bug fix for enable/disabling of glx double buffering. Single buffering allows for faster emulation rates, double buffering is not allowing faster than 60hz due to vsync. --- src/drivers/sdl/glxwin.cpp | 20 ++++++++++++++------ src/drivers/sdl/gui.cpp | 14 +++++++------- src/drivers/sdl/sdl-video.cpp | 2 +- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/drivers/sdl/glxwin.cpp b/src/drivers/sdl/glxwin.cpp index ab000ee3..547df24f 100644 --- a/src/drivers/sdl/glxwin.cpp +++ b/src/drivers/sdl/glxwin.cpp @@ -32,7 +32,7 @@ static Window win; static GLXContext glc = NULL; static XWindowAttributes gwa; static XEvent xev; -static GLint double_buffer_ena = True; +static GLint double_buffer_ena = 1; static GLuint gltexture = 0; static int spawn_new_window = 0; @@ -91,8 +91,11 @@ static void getAttrbList( GLint *buf ) buf[i] = GLX_RGBA; i++; buf[i] = GLX_DEPTH_SIZE; i++; buf[i] = 24; i++; - buf[i] = GLX_DOUBLEBUFFER ; i++; - buf[i] = double_buffer_ena; i++; + + if ( double_buffer_ena ) + { + buf[i] = GLX_DOUBLEBUFFER ; i++; + } buf[i] = None; } @@ -280,9 +283,14 @@ static void render_image(void) //glVertex2f( 1.0f, 1.0f); // Top right of target. //glEnd(); - glFlush(); - - glXSwapBuffers( dpy, win ); + if ( double_buffer_ena ) + { + glXSwapBuffers( dpy, win ); + } + else + { + glFlush(); + } } //************************************************************************ static int mainWindowLoop(void) diff --git a/src/drivers/sdl/gui.cpp b/src/drivers/sdl/gui.cpp index 48bb3b6b..fe82a062 100644 --- a/src/drivers/sdl/gui.cpp +++ b/src/drivers/sdl/gui.cpp @@ -191,7 +191,7 @@ int configGamepadButton (GtkButton * button, gpointer p) void resetVideo (void) { - resizeGtkWindow (); + //resizeGtkWindow (); KillVideo (); InitVideo (GameInfo); } @@ -3399,7 +3399,7 @@ static void cairo_handle_resize(void) cairo_surface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, w, h ); //cairo_surface = cairo_image_surface_create( CAIRO_FORMAT_RGB24, w, h ); - printf("Cairo Surface: %p \n", cairo_surface ); + //printf("Cairo Surface: %p \n", cairo_surface ); //cairo_format = cairo_image_surface_get_format( cairo_surface ); @@ -3532,11 +3532,11 @@ gboolean handle_resize (GtkWindow * win, GdkEvent * event, gpointer data) //gtk_widget_realize(evbox); //flushGtkEvents (); - if ( winsize_changed && (GameInfo != 0) ) - { - KillVideo (); - InitVideo (GameInfo); - } + //if ( winsize_changed && (GameInfo != 0) ) + //{ + // KillVideo (); + // InitVideo (GameInfo); + //} gtk_widget_queue_draw( evbox ); diff --git a/src/drivers/sdl/sdl-video.cpp b/src/drivers/sdl/sdl-video.cpp index 39ca7cb8..2b5e44f2 100644 --- a/src/drivers/sdl/sdl-video.cpp +++ b/src/drivers/sdl/sdl-video.cpp @@ -100,7 +100,7 @@ KillVideo() glx_shm->clear_pixbuf(); } - //destroy_gui_video(); + destroy_gui_video(); // return failure if the video system was not initialized if (s_inited == 0) From c5bbd3cec53f0edbf212364f79d21b1b3683c602 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 14 Jun 2020 19:55:36 -0400 Subject: [PATCH 24/25] Added uninitialized class members to constructor for debug window. --- src/drivers/sdl/debugger.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/drivers/sdl/debugger.cpp b/src/drivers/sdl/debugger.cpp index 4aeb27ab..c5982e24 100644 --- a/src/drivers/sdl/debugger.cpp +++ b/src/drivers/sdl/debugger.cpp @@ -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; From 9748d3916936cca40d902a9b27b03152d7f6d22e Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Sun, 14 Jun 2020 20:11:59 -0400 Subject: [PATCH 25/25] Resolved dangerous usage of c_str(). The value returned by c_str() is invalid after this call --- src/drivers/sdl/input.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/drivers/sdl/input.cpp b/src/drivers/sdl/input.cpp index 3943f35f..f4246e96 100644 --- a/src/drivers/sdl/input.cpp +++ b/src/drivers/sdl/input.cpp @@ -446,7 +446,6 @@ static void KeyboardCommands (void) { int is_shift, is_alt; - char *movie_fname = ""; // get the keyboard input // check if the family keyboard is enabled @@ -573,10 +572,9 @@ static void KeyboardCommands (void) { if (is_shift) { - movie_fname = - const_cast (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 {