diff --git a/src/drivers/Qt/sdl-video.cpp b/src/drivers/Qt/sdl-video.cpp index cd52b9e5..aba7cc3d 100644 --- a/src/drivers/Qt/sdl-video.cpp +++ b/src/drivers/Qt/sdl-video.cpp @@ -207,24 +207,6 @@ int InitVideo(FCEUGI *gi) return -1; } -#ifdef OPENGL - if(s_exs <= 0.01) { - FCEUD_PrintError("xscale out of bounds."); - KillVideo(); - return -1; - } - if(s_eys <= 0.01) { - FCEUD_PrintError("yscale out of bounds."); - KillVideo(); - return -1; - } - //if(s_sponge && s_useOpenGL) { - // FCEUD_PrintError("scalers not compatible with openGL mode."); - // KillVideo(); - // return -1; - //} -#endif - if ( !initBlitToHighDone ) { InitBlitToHigh(s_curbpp >> 3, diff --git a/src/drivers/sdl/config.cpp b/src/drivers/sdl/config.cpp index 4856cbb2..8389d65a 100644 --- a/src/drivers/sdl/config.cpp +++ b/src/drivers/sdl/config.cpp @@ -199,6 +199,7 @@ InitConfig() // video controls config->addOption('f', "fullscreen", "SDL.Fullscreen", 0); + config->addOption("videoDriver", "SDL.VideoDriver", 0); // set x/y res to 0 for automatic fullscreen resolution detection (no change) config->addOption('x', "xres", "SDL.XResolution", 0); diff --git a/src/drivers/sdl/glxwin.cpp b/src/drivers/sdl/glxwin.cpp index 547df24f..228f5d25 100644 --- a/src/drivers/sdl/glxwin.cpp +++ b/src/drivers/sdl/glxwin.cpp @@ -258,7 +258,7 @@ static void render_image(void) //print_pixbuf(); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, - GL_RGBA, GL_UNSIGNED_BYTE, glx_shm->pixbuf ); + GL_BGRA, GL_UNSIGNED_BYTE, glx_shm->pixbuf ); glBegin(GL_QUADS); glTexCoord2f(1.0f*l/256, 1.0f*b/256); // Bottom left of picture. diff --git a/src/drivers/sdl/gui.cpp b/src/drivers/sdl/gui.cpp index b9df897e..cc458831 100644 --- a/src/drivers/sdl/gui.cpp +++ b/src/drivers/sdl/gui.cpp @@ -51,6 +51,7 @@ #include #include "glxwin.h" +#include "sdl-video.h" // Fix compliation errors for older version of GTK (Ubuntu 10.04 LTS) #if GTK_MINOR_VERSION < 24 && GTK_MAJOR_VERSION == 2 @@ -81,8 +82,9 @@ bool gtkIsStarted = false; bool menuTogglingEnabled = false; static int buttonConfigStatus = 0; -static char useCairoDraw = 0; -static int drawAreaGL = 0; +enum videoDriver_t videoDriver = VIDEO_NONE; +//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 GtkTreeStore *hotkey_store = NULL; @@ -955,41 +957,13 @@ void resizeGtkWindow (void) return; } -void setScaler (GtkWidget * w, gpointer p) +static void setVideoDriver (GtkWidget * w, gpointer p) { - int scaler = gtk_combo_box_get_active (GTK_COMBO_BOX (w)); - int opengl; - g_config->getOption ("SDL.OpenGL", &opengl); - if (opengl && scaler) - { - FCEUD_PrintError ("Scalers not supported in OpenGL mode."); - gtk_combo_box_set_active (GTK_COMBO_BOX (w), 0); - return; - } + int vdSel = gtk_combo_box_get_active (GTK_COMBO_BOX (w)); - g_config->setOption ("SDL.SpecialFilter", scaler); - - // 1=hq2x 2=Scale2x 3=NTSC2x 4=hq3x 5=Scale3x 6=Prescale2x 7=Prescale3x 8=Prescale4x 9=pal - switch (scaler) - { - case 4: // hq3x - case 5: // scale3x - case 7: // prescale3x - g_config->setOption ("SDL.XScale", 3.0); - g_config->setOption ("SDL.YScale", 3.0); - resizeGtkWindow (); - break; - case 8: // prescale4x - g_config->setOption ("SDL.XScale", 4.0); - g_config->setOption ("SDL.YScale", 4.0); - break; - default: - g_config->setOption ("SDL.XScale", 2.0); - g_config->setOption ("SDL.YScale", 2.0); - resizeGtkWindow (); - break; - } + init_gui_video( (videoDriver_t)vdSel ); + g_config->setOption ("SDL.VideoDriver", videoDriver); g_config->save (); } @@ -1057,8 +1031,8 @@ void openVideoConfig (void) GtkWidget *lbl; GtkWidget *hbox1; GtkWidget *scalerLbl; - GtkWidget *scalerCombo; - GtkWidget *glChk; + GtkWidget *DriverCombo; + //GtkWidget *glChk; GtkWidget *linearChk; GtkWidget *dbChk; GtkWidget *palHbox; @@ -1092,42 +1066,26 @@ void openVideoConfig (void) // scalar widgets hbox1 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3); - scalerLbl = gtk_label_new ("Special Scaler: "); - scalerCombo = gtk_combo_box_text_new (); + scalerLbl = gtk_label_new ("Video Driver: "); + DriverCombo = gtk_combo_box_text_new (); // -Video Modes Tag- - gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (scalerCombo), - "none"); - gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (scalerCombo), - "hq2x"); - gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (scalerCombo), - "scale2x"); - gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (scalerCombo), - "NTSC 2x"); - gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (scalerCombo), - "hq3x"); - gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (scalerCombo), - "scale3x"); - gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (scalerCombo), - "prescale2x"); - gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (scalerCombo), - "prescale3x"); - gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (scalerCombo), - "prescale4x"); - //gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(scalerCombo), "pal"); + gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (DriverCombo), "OpenGL (GLX)"); + gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (DriverCombo), "SDL"); + gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (DriverCombo), "Cairo"); // sync with cfg int buf; g_config->getOption ("SDL.SpecialFilter", &buf); - gtk_combo_box_set_active (GTK_COMBO_BOX (scalerCombo), buf); + gtk_combo_box_set_active (GTK_COMBO_BOX (DriverCombo), buf); - g_signal_connect (scalerCombo, "changed", G_CALLBACK (setScaler), NULL); + g_signal_connect (DriverCombo, "changed", G_CALLBACK (setVideoDriver), NULL); gtk_box_pack_start (GTK_BOX (hbox1), scalerLbl, FALSE, FALSE, 5); - gtk_box_pack_start (GTK_BOX (hbox1), scalerCombo, FALSE, FALSE, 5); + gtk_box_pack_start (GTK_BOX (hbox1), DriverCombo, FALSE, FALSE, 5); #ifdef OPENGL // openGL check - glChk = gtk_check_button_new_with_label ("Enable OpenGL"); - g_signal_connect (glChk, "clicked", G_CALLBACK (setGl), NULL); - setCheckbox (glChk, "SDL.OpenGL"); + //glChk = gtk_check_button_new_with_label ("Enable OpenGL"); + //g_signal_connect (glChk, "clicked", G_CALLBACK (setGl), NULL); + //setCheckbox (glChk, "SDL.OpenGL"); // openGL linear filter check linearChk = @@ -1219,7 +1177,7 @@ void openVideoConfig (void) gtk_box_pack_start (GTK_BOX (vbox), lbl, FALSE, FALSE, 5); gtk_box_pack_start (GTK_BOX (vbox), hbox1, FALSE, FALSE, 5); #ifdef OPENGL - gtk_box_pack_start (GTK_BOX (vbox), glChk, FALSE, FALSE, 5); + //gtk_box_pack_start (GTK_BOX (vbox), glChk, FALSE, FALSE, 5); gtk_box_pack_start (GTK_BOX (vbox), linearChk, FALSE, FALSE, 5); gtk_box_pack_start (GTK_BOX (vbox), dbChk, FALSE, FALSE, 5); #endif @@ -3175,18 +3133,19 @@ static void transferPix2CairoSurface(void) else { // 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] = 0xff; // Force Alpha to full - #else - // 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 + //#ifdef LSB_FIRST + p[i].u32 = g[j].u32 | 0xff000000; + //p[i].u8[0] = g[j].u8[0]; + //p[i].u8[1] = g[j].u8[1]; + //p[i].u8[2] = g[j].u8[2]; + //p[i].u8[3] = 0xff; // Force Alpha to full + //#else + //// 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; } i++; @@ -3237,13 +3196,21 @@ int guiPixelBufferReDraw(void) { glx_shm->blit_count++; - if ( useCairoDraw ) + switch ( videoDriver ) { - transferPix2CairoSurface(); - } - else - { - gtk3_glx_render(); + case VIDEO_CAIRO: + transferPix2CairoSurface(); + break; + case VIDEO_OPENGL_GLX: + gtk3_glx_render(); + break; + case VIDEO_SDL: + gtk3_sdl_render(); + break; + default: + case VIDEO_NONE: + // Nothing to do + break; } return 0; @@ -3467,33 +3434,57 @@ int destroy_gui_video( void ) destroy_gtk3_GLXContext(); + destroy_gtk3_sdl_video(); + + videoDriver = VIDEO_NONE; + return 0; } -int init_gui_video( int use_openGL ) +int init_gui_video( videoDriver_t videoDriverSelect ) { - drawAreaGL = use_openGL; - useCairoDraw = !drawAreaGL; - - if ( use_openGL ) + if ( videoDriver == videoDriverSelect ) { - 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( flags ); + return 0; } - else + //drawAreaGL = use_openGL; + //useCairoDraw = !drawAreaGL; + + destroy_gui_video(); + + videoDriver = videoDriverSelect; + + switch ( videoDriver ) { - destroy_gtk3_GLXContext(); - init_cairo_screen(); + case VIDEO_OPENGL_GLX: + { + int flags=0; + int linear_interpolation_ena=0; + int double_buffer_ena=0; + + g_config->getOption("SDL.OpenGLip" , &linear_interpolation_ena ); + g_config->getOption("SDL.DoubleBuffering", &double_buffer_ena ); + + if ( linear_interpolation_ena ) flags |= GLXWIN_PIXEL_LINEAR_FILTER; + if ( double_buffer_ena ) flags |= GLXWIN_DOUBLE_BUFFER; + + init_gtk3_GLXContext( flags ); + } + break; + case VIDEO_CAIRO: + { + init_cairo_screen(); + } + break; + case VIDEO_SDL: + { + init_gtk3_sdl_video(); + } + break; + default: + case VIDEO_NONE: + // Nothing to do + break; } return 0; } @@ -3541,7 +3532,7 @@ gboolean handle_resize (GtkWindow * win, GdkEvent * event, gpointer data) double xscale = width / (double) NES_WIDTH; double yscale = height / (double) NES_HEIGHT; - //printf("DRAW: %ix%i MenuY: %i \n", draw_width, draw_height, gtk_win_menu_ysize ); + printf("DRAW: %ix%i \n", width, height ); if ( (width != gtk_draw_area_width) || (height != gtk_draw_area_height) ) { @@ -3560,9 +3551,21 @@ gboolean handle_resize (GtkWindow * win, GdkEvent * event, gpointer data) if (yscale > xscale) yscale = xscale; - if ( useCairoDraw && winsize_changed ) + if ( winsize_changed ) { - cairo_handle_resize(); + switch ( videoDriver ) + { + case VIDEO_CAIRO: + cairo_handle_resize(); + break; + case VIDEO_SDL: + gtk3_sdl_resize(); + break; + default: + case VIDEO_OPENGL_GLX: + // Nothing to do + break; + } } //TODO if openGL make these integers @@ -3630,13 +3633,21 @@ static gboolean draw_cb (GtkWidget * widget, cairo_t * cr, gpointer data) if ( gtk_draw_area_width < NES_WIDTH ) gtk_draw_area_width = NES_WIDTH; if ( gtk_draw_area_height < NES_HEIGHT ) gtk_draw_area_height = NES_HEIGHT; - if ( useCairoDraw ) + switch ( videoDriver ) { - cairo_draw_cb( widget, cr, data ); - } - else - { - gtk3_glx_render(); + case VIDEO_CAIRO: + cairo_draw_cb( widget, cr, data ); + break; + case VIDEO_OPENGL_GLX: + gtk3_glx_render(); + break; + case VIDEO_SDL: + gtk3_sdl_render(); + break; + default: + case VIDEO_NONE: + // Nothing to do + break; } return FALSE; @@ -3646,16 +3657,18 @@ static void drawAreaRealizeCB (GtkWidget *widget, gpointer user_data) { - printf("Draw Area Realize\n"); + int vdSel = VIDEO_OPENGL_GLX; - init_gui_video( drawAreaGL ); + g_config->getOption("SDL.VideoDriver", &vdSel); + + printf("Draw Area Realize: Video Driver Select: %i\n", vdSel); + + init_gui_video( (videoDriver_t)vdSel ); } int InitGTKSubsystem (int argc, char **argv) { - - int s_useOpenGL=0; GtkWidget *vbox; MainWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL); @@ -3688,13 +3701,6 @@ int InitGTKSubsystem (int argc, char **argv) // // prg - Bryan Cain, you are the man! - #ifdef OPENGL - g_config->getOption("SDL.OpenGL", &s_useOpenGL); - #endif - - drawAreaGL = s_useOpenGL; - useCairoDraw = !drawAreaGL; - evbox = gtk_drawing_area_new (); gtk_box_pack_start (GTK_BOX (vbox), evbox, TRUE, TRUE, 0); diff --git a/src/drivers/sdl/gui.h b/src/drivers/sdl/gui.h index a06fc4d8..13ad108f 100644 --- a/src/drivers/sdl/gui.h +++ b/src/drivers/sdl/gui.h @@ -89,7 +89,16 @@ int InitGTKSubsystem(int argc, char** argv); uint32_t *getGuiPixelBuffer( int *w, int *h, int *s ); int guiPixelBufferReDraw(void); -int init_gui_video( int use_openGL ); +enum videoDriver_t +{ + VIDEO_NONE = -1, + VIDEO_OPENGL_GLX, + VIDEO_SDL, + VIDEO_CAIRO +}; +extern enum videoDriver_t videoDriver; + +int init_gui_video( videoDriver_t vd ); int destroy_gui_video( void ); void init_cairo_screen(void); void destroy_cairo_screen(void); diff --git a/src/drivers/sdl/sdl-video.cpp b/src/drivers/sdl/sdl-video.cpp index e9667696..1edb7af9 100644 --- a/src/drivers/sdl/sdl-video.cpp +++ b/src/drivers/sdl/sdl-video.cpp @@ -83,6 +83,11 @@ extern bool MaxSpeed; extern unsigned int gtk_draw_area_width; extern unsigned int gtk_draw_area_height; + +static SDL_Window *sdlWindow = NULL; +static SDL_Renderer *sdlRenderer = NULL; +static SDL_Texture *sdlTexture = NULL; + /** * Attempts to destroy the graphical video display. Returns 0 on * success, -1 on failure. @@ -152,6 +157,7 @@ void FCEUD_VideoChanged() int InitVideo(FCEUGI *gi) { + int vdSel; int doublebuf, xstretch, ystretch, xres, yres, show_fps; FCEUI_printf("Initializing video..."); @@ -184,7 +190,9 @@ int InitVideo(FCEUGI *gi) FCEUI_GetCurrentVidSystem(&s_srendline, &s_erendline); s_tlines = s_erendline - s_srendline + 1; - init_gui_video( s_useOpenGL ); + g_config->getOption("SDL.VideoDriver", &vdSel); + + init_gui_video( (videoDriver_t)vdSel ); s_inited = 1; @@ -192,9 +200,9 @@ int InitVideo(FCEUGI *gi) FCEUI_SetShowFPS(show_fps); #ifdef LSB_FIRST - rmask = 0x000000FF; + rmask = 0x00FF0000; gmask = 0x0000FF00; - bmask = 0x00FF0000; + bmask = 0x000000FF; #else rmask = 0x00FF0000; gmask = 0x0000FF00; @@ -214,24 +222,6 @@ int InitVideo(FCEUGI *gi) return -1; } -#ifdef OPENGL - if(s_exs <= 0.01) { - FCEUD_PrintError("xscale out of bounds."); - KillVideo(); - return -1; - } - if(s_eys <= 0.01) { - FCEUD_PrintError("yscale out of bounds."); - KillVideo(); - return -1; - } - if(s_sponge && s_useOpenGL) { - FCEUD_PrintError("scalers not compatible with openGL mode."); - KillVideo(); - return -1; - } -#endif - if ( !initBlitToHighDone ) { InitBlitToHigh(s_curbpp >> 3, @@ -471,3 +461,150 @@ void FCEUI_SetAviDisableMovieMessages(bool disable) { disableMovieMessages = disable; } + +//***************************************************************************** +int init_gtk3_sdl_video( void ) +{ + GdkWindow *gdkWin = gtk_widget_get_window(evbox); + Window win; + int vsyncEnabled=0; + + if ( gdkWin == NULL ) + { + printf("Error: Failed to obtain gdkWindow Handle for evbox widget\n"); + return -1; + } + win = GDK_WINDOW_XID( gdkWin ); + + for (int i=0; incol; + nesHeight = glx_shm->nrow; + } + //printf(" %i x %i \n", nesWidth, nesHeight ); + float xscale = (float)gtk_draw_area_width / (float)nesWidth; + float yscale = (float)gtk_draw_area_height / (float)nesHeight; + + if (xscale < yscale ) + { + yscale = xscale; + } + else + { + xscale = yscale; + } + + rw=(int)(nesWidth*xscale); + rh=(int)(nesHeight*yscale); + //sx=sdlViewport.x + (view_width-rw)/2; + //sy=sdlViewport.y + (view_height-rh)/2; + sx=(gtk_draw_area_width-rw)/2; + sy=(gtk_draw_area_height-rh)/2; + + if ( (sdlRenderer == NULL) || (sdlTexture == NULL) ) + { + return -1; + } + + SDL_SetRenderDrawColor( sdlRenderer, 0, 0, 0, 0 ); + + SDL_RenderClear(sdlRenderer); + + uint8_t *textureBuffer; + int rowPitch; + SDL_LockTexture( sdlTexture, nullptr, (void**)&textureBuffer, &rowPitch); + { + memcpy( textureBuffer, glx_shm->pixbuf, GLX_NES_HEIGHT*GLX_NES_WIDTH*sizeof(uint32_t) ); + } + SDL_UnlockTexture(sdlTexture); + + //SDL_RenderSetViewport( sdlRenderer, &sdlViewport ); + + SDL_Rect source = {0, 0, nesWidth, nesHeight }; + SDL_Rect dest = { sx, sy, rw, rh }; + SDL_RenderCopy(sdlRenderer, sdlTexture, &source, &dest); + + SDL_RenderPresent(sdlRenderer); + + return 0; +} +//***************************************************************************** diff --git a/src/drivers/sdl/sdl-video.h b/src/drivers/sdl/sdl-video.h index 82ac15f7..efc055e1 100644 --- a/src/drivers/sdl/sdl-video.h +++ b/src/drivers/sdl/sdl-video.h @@ -13,5 +13,11 @@ bool FCEUI_AviEnableHUDrecording(); void FCEUI_SetAviEnableHUDrecording(bool enable); bool FCEUI_AviDisableMovieMessages(); void FCEUI_SetAviDisableMovieMessages(bool disable); + +int init_gtk3_sdl_video(void); +int destroy_gtk3_sdl_video(void); +int gtk3_sdl_render(void); +int gtk3_sdl_resize(void); + #endif