Successful display of graphics using cairo. Not as efficient as other methods but works.

This commit is contained in:
Matthew Budd 2020-06-05 21:08:53 -04:00
parent 88e0c838e2
commit 1fc0725e94
8 changed files with 589 additions and 119 deletions

View File

@ -28,7 +28,7 @@ opts.AddVariables(
BoolVariable('SYSTEM_MINIZIP', 'Use system minizip instead of static minizip provided with fceux', 0), BoolVariable('SYSTEM_MINIZIP', 'Use system minizip instead of static minizip provided with fceux', 0),
BoolVariable('LSB_FIRST', 'Least signficant byte first (non-PPC)', 1), BoolVariable('LSB_FIRST', 'Least signficant byte first (non-PPC)', 1),
BoolVariable('CLANG', 'Compile with llvm-clang instead of gcc', 0), BoolVariable('CLANG', 'Compile with llvm-clang instead of gcc', 0),
BoolVariable('SDL2', 'Compile using SDL2 instead of SDL 1.2 (experimental/non-functional)', 0) BoolVariable('SDL2', 'Compile using SDL2 instead of SDL 1.2 (experimental/non-functional)', 1)
) )
AddOption('--prefix', dest='prefix', type='string', nargs=1, action='store', metavar='DIR', help='installation prefix') AddOption('--prefix', dest='prefix', type='string', nargs=1, action='store', metavar='DIR', help='installation prefix')

View File

@ -72,6 +72,7 @@ static unsigned int gtk_win_width = 0;
static unsigned int gtk_win_height = 0; static unsigned int gtk_win_height = 0;
static int gtk_win_menu_ysize = 30; static int gtk_win_menu_ysize = 30;
static GtkTreeStore *hotkey_store = NULL; static GtkTreeStore *hotkey_store = NULL;
static cairo_surface_t *cairo_surface = NULL;
static gint convertKeypress (GtkWidget * grab, GdkEventKey * event, gpointer user_data); 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 #define SDLK_RMETA 0
#endif #endif
// Adapted from Gens/GS. Converts a GDK key value into an SDL key value. // 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)) if (!(gdk_key & 0xFF00))
{ {
@ -2242,7 +2243,7 @@ unsigned short GDKToSDLKeyval (int gdk_key)
} }
// Non-ASCII symbol. // Non-ASCII symbol.
static const uint16_t gdk_to_sdl_table[0x100] = { static const int gdk_to_sdl_table[0x100] = {
// 0x00 - 0x0F // 0x00 - 0x0F
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@ -2340,7 +2341,7 @@ unsigned short GDKToSDLKeyval (int gdk_key)
0x0000, 0x0000, 0x0000, SDLK_DELETE, 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) if (sdl_key == 0)
{ {
// Unhandled GDK key. // Unhandled GDK key.
@ -3070,8 +3071,126 @@ gint handleMouseClick (GtkWidget * widget, GdkEvent * event,
return 0; 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<z; i++)
{
p[i] = 0x00000000;
}
cairo_surface_mark_dirty( cairo_surface );
}
return 0;
}
static void setPixels(void)
{
int32_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);
cairo_surface_flush( cairo_surface );
p = (int32_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 );
i=0;
for (y=0; y<height; y++)
{
for (x=0; x<width; x++)
{
if ( x < w2 )
{
if ( y < h2 )
{
p[i] = 0xff0000ff;
}
else
{
p[i] = 0xffffffff;
}
}
else
{
if ( y < h2 )
{
p[i] = 0xffff0000;
}
else
{
p[i] = 0xff00ff00;
}
}
i++;
}
}
cairo_surface_mark_dirty( cairo_surface );
gtk_widget_queue_draw( evbox );
}
gboolean handle_resize (GtkWindow * win, GdkEvent * event, gpointer data) 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 // This should handle resizing so the emulation takes up as much
// of the GTK window as possible // of the GTK window as possible
@ -3112,6 +3231,36 @@ gboolean handle_resize (GtkWindow * win, GdkEvent * event, gpointer data)
if (yscale > xscale) if (yscale > xscale)
yscale = 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 //TODO if openGL make these integers
g_config->setOption ("SDL.XScale", xscale); g_config->setOption ("SDL.XScale", xscale);
g_config->setOption ("SDL.YScale", yscale); 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; 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 // Clear the screen on a window redraw
//if (GameInfo == 0) //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, "delete-event", quit, NULL);
g_signal_connect (MainWindow, "destroy-event", quit, NULL); g_signal_connect (MainWindow, "destroy-event", quit, NULL);
// resize handler // resize handler
g_signal_connect (MainWindow, "configure-event", g_signal_connect (evbox, "configure-event",
G_CALLBACK (handle_resize), NULL); G_CALLBACK (handle_resize), NULL);
g_signal_connect (evbox, "draw", G_CALLBACK (draw_cb), NULL); g_signal_connect (evbox, "draw", G_CALLBACK (draw_cb), NULL);

View File

@ -83,7 +83,10 @@ void saveStateAs();
void loadStateFrom(); void loadStateFrom();
void quickLoad(); void quickLoad();
void quickSave(); void quickSave();
unsigned short GDKToSDLKeyval(int gdk_key); unsigned int GDKToSDLKeyval(int gdk_key);
int InitGTKSubsystem(int argc, char** argv); int InitGTKSubsystem(int argc, char** argv);
uint32_t *getGuiPixelBuffer( int *w, int *h, int *s );
int guiPixelBufferReDraw(void);
#endif // ifndef FCEUX_GUI_H #endif // ifndef FCEUX_GUI_H

View File

@ -1019,65 +1019,65 @@ int ButtonConfigBegin ()
g_config->getOption ("SDL.NoGUI", &noGui); g_config->getOption ("SDL.NoGUI", &noGui);
if (noGui == 1) if (noGui == 1)
{ {
SDL_QuitSubSystem (SDL_INIT_VIDEO); //SDL_QuitSubSystem (SDL_INIT_VIDEO);
bcpv = KillVideo (); bcpv = KillVideo ();
} }
#else #else
// XXX soules - why are we doing this right before KillVideo()? // XXX soules - why are we doing this right before KillVideo()?
SDL_QuitSubSystem (SDL_INIT_VIDEO); //SDL_QuitSubSystem (SDL_INIT_VIDEO);
// shut down the video and joystick subsystems // shut down the video and joystick subsystems
bcpv = KillVideo (); bcpv = KillVideo ();
#endif #endif
SDL_Surface *screen; //SDL_Surface *screen;
bcpj = KillJoysticks (); bcpj = KillJoysticks ();
// reactivate the video subsystem // reactivate the video subsystem
if (!SDL_WasInit (SDL_INIT_VIDEO)) // if (!SDL_WasInit (SDL_INIT_VIDEO))
{ // {
if (!bcpv) // if (!bcpv)
{ // {
InitVideo (GameInfo); // InitVideo (GameInfo);
} // }
else // else
{ // {
#if defined(_GTK) && defined(SDL_VIDEO_DRIVER_X11) //#if defined(_GTK) && defined(SDL_VIDEO_DRIVER_X11)
if (noGui == 0) // if (noGui == 0)
{ // {
while (gtk_events_pending ()) // while (gtk_events_pending ())
gtk_main_iteration_do (FALSE); // gtk_main_iteration_do (FALSE);
//
char SDL_windowhack[128]; // char SDL_windowhack[128];
if (gtk_widget_get_window (evbox)) // if (gtk_widget_get_window (evbox))
sprintf (SDL_windowhack, "SDL_WINDOWID=%u", // sprintf (SDL_windowhack, "SDL_WINDOWID=%u",
(unsigned int) GDK_WINDOW_XID (gtk_widget_get_window (evbox))); // (unsigned int) GDK_WINDOW_XID (gtk_widget_get_window (evbox)));
#if SDL_VERSION_ATLEAST(2, 0, 0) //#if SDL_VERSION_ATLEAST(2, 0, 0)
// TODO - SDL2 // // TODO - SDL2
#else //#else
SDL_putenv (SDL_windowhack); // SDL_putenv (SDL_windowhack);
#endif //#endif
} // }
#endif //#endif
if (SDL_InitSubSystem (SDL_INIT_VIDEO) == -1) // if (SDL_InitSubSystem (SDL_INIT_VIDEO) == -1)
{ // {
FCEUD_Message (SDL_GetError ()); // FCEUD_Message (SDL_GetError ());
return 0; // return 0;
} // }
//
// set the screen and notify the user of button configuration // // set the screen and notify the user of button configuration
#if SDL_VERSION_ATLEAST(2, 0, 0) //#if SDL_VERSION_ATLEAST(2, 0, 0)
// TODO - SDL2 // // TODO - SDL2
#else //#else
screen = SDL_SetVideoMode (420, 200, 8, 0); // screen = SDL_SetVideoMode (420, 200, 8, 0);
if ( screen == NULL ) // if ( screen == NULL )
{ // {
printf("Error: SDL_SetVideoMode Failed\n"); // printf("Error: SDL_SetVideoMode Failed\n");
} // }
SDL_WM_SetCaption ("Button Config", 0); // SDL_WM_SetCaption ("Button Config", 0);
#endif //#endif
} // }
} // }
// XXX soules - why did we shut this down? // XXX soules - why did we shut this down?
// initialize the joystick subsystem // initialize the joystick subsystem

View File

@ -7,7 +7,8 @@
typedef struct { typedef struct {
uint8 ButtType[MAXBUTTCONFIG]; uint8 ButtType[MAXBUTTCONFIG];
uint8 DeviceNum[MAXBUTTCONFIG]; uint8 DeviceNum[MAXBUTTCONFIG];
uint16 ButtonNum[MAXBUTTCONFIG]; //uint16 ButtonNum[MAXBUTTCONFIG];
int ButtonNum[MAXBUTTCONFIG];
uint32 NumC; uint32 NumC;
//uint64 DeviceID[MAXBUTTCONFIG]; /* TODO */ //uint64 DeviceID[MAXBUTTCONFIG]; /* TODO */
} ButtConfig; } ButtConfig;

View File

@ -21,6 +21,9 @@
#define APIENTRY #define APIENTRY
#endif #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 GLuint textures[2]={0,0}; // Normal image, scanline overlay.
static int left,right,top,bottom; // right and bottom are not inclusive. static int left,right,top,bottom; // right and bottom are not inclusive.
@ -104,7 +107,11 @@ BlitOpenGL(uint8 *buf)
glEnd(); glEnd();
glDisable(GL_BLEND); glDisable(GL_BLEND);
} }
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_GL_SwapWindow(s_window);
#else
SDL_GL_SwapBuffers(); SDL_GL_SwapBuffers();
#endif
} }
void void
@ -132,6 +139,9 @@ InitOpenGL(int l,
int ipolate, int ipolate,
int stretchx, int stretchx,
int stretchy, int stretchy,
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_Window *window,
#endif
SDL_Surface *screen) SDL_Surface *screen)
{ {
const char *extensions; const char *extensions;
@ -167,6 +177,9 @@ InitOpenGL(int l,
HiBuffer=0; HiBuffer=0;
#if SDL_VERSION_ATLEAST(2, 0, 0)
s_window = window;
#endif
extensions=(const char*)glGetString(GL_EXTENSIONS); extensions=(const char*)glGetString(GL_EXTENSIONS);
if((efx&2) || !extensions || !p_glColorTableEXT || !strstr(extensions,"GL_EXT_paletted_texture")) if((efx&2) || !extensions || !p_glColorTableEXT || !strstr(extensions,"GL_EXT_paletted_texture"))
@ -182,6 +195,9 @@ InitOpenGL(int l,
#endif #endif
} }
#if SDL_VERSION_ATLEAST(2, 0, 0)
// FIXME
#else
if(screen->flags & SDL_FULLSCREEN) if(screen->flags & SDL_FULLSCREEN)
{ {
xscale=(double)screen->w / (double)(r-l); xscale=(double)screen->w / (double)(r-l);
@ -189,6 +205,7 @@ InitOpenGL(int l,
if(xscale<yscale) yscale = xscale; if(xscale<yscale) yscale = xscale;
if(yscale<xscale) xscale = yscale; if(yscale<xscale) xscale = yscale;
} }
#endif
{ {
int rw=(int)((r-l)*xscale); int rw=(int)((r-l)*xscale);
@ -243,9 +260,20 @@ InitOpenGL(int l,
// In a double buffered setup with page flipping, be sure to clear both buffers. // In a double buffered setup with page flipping, be sure to clear both buffers.
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_GL_SwapWindow(s_window);
#else
SDL_GL_SwapBuffers(); SDL_GL_SwapBuffers();
#endif
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_GL_SwapWindow(s_window);
#else
SDL_GL_SwapBuffers(); SDL_GL_SwapBuffers();
#endif
return 1; return 1;
} }

View File

@ -1,6 +1,13 @@
void SetOpenGLPalette(uint8 *data); void SetOpenGLPalette(uint8 *data);
void BlitOpenGL(uint8 *buf); void BlitOpenGL(uint8 *buf);
void KillOpenGL(void); void KillOpenGL(void);
int InitOpenGL(int l, int r, int t, int b, double xscale,double yscale, int efx, int ipolate,
int stretchx, int stretchy, SDL_Surface *screen); 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);

View File

@ -55,31 +55,36 @@
extern Config *g_config; extern Config *g_config;
// STATIC GLOBALS // 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_screen = NULL;
static SDL_Surface *s_BlitBuf; // Buffer when using hardware-accelerated blits. static SDL_Surface *s_BlitBuf; // Buffer when using hardware-accelerated blits.
static SDL_Surface *s_IconSurface = NULL; static SDL_Surface *s_IconSurface = NULL;
static int s_curbpp; static int s_curbpp = 0;
static int s_srendline, s_erendline; static int s_srendline, s_erendline;
static int s_tlines; static int s_tlines;
static int s_inited; static int s_inited = 0;
#ifdef OPENGL #ifdef OPENGL
static int s_useOpenGL; static int s_useOpenGL = 0;
#endif #endif
static double s_exs, s_eys; static double s_exs = 1.0, s_eys = 1.0;
static int s_eefx; static int s_eefx = 0;
static int s_clipSides; static int s_clipSides = 0;
static int s_fullscreen; static int s_fullscreen = 0;
static int noframe; static int noframe = 0;
static int s_nativeWidth = -1; static int s_nativeWidth = -1;
static int s_nativeHeight = -1; static int s_nativeHeight = -1;
#define NWIDTH (256 - (s_clipSides ? 16 : 0)) #define NWIDTH (256 - (s_clipSides ? 16 : 0))
#define NOFFSET (s_clipSides ? 8 : 0) #define NOFFSET (s_clipSides ? 8 : 0)
static int s_paletterefresh; static int s_paletterefresh = 1;
extern bool MaxSpeed; extern bool MaxSpeed;
@ -90,6 +95,38 @@ extern unsigned int gtk_draw_area_height;
* success, -1 on failure. * 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; x<s_screen->w; x++)
{
for (int y=0; y<s_screen->h; 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 //draw input aids if we are fullscreen
bool FCEUD_ShouldDrawInputAids() bool FCEUD_ShouldDrawInputAids()
{ {
@ -100,7 +137,8 @@ int
KillVideo() KillVideo()
{ {
// if the IconSurface has been initialized, destroy it // if the IconSurface has been initialized, destroy it
if(s_IconSurface) { if (s_IconSurface)
{
SDL_FreeSurface(s_IconSurface); SDL_FreeSurface(s_IconSurface);
s_IconSurface=0; s_IconSurface=0;
} }
@ -113,15 +151,46 @@ KillVideo()
#ifdef OPENGL #ifdef OPENGL
// check for OpenGL and shut it down // check for OpenGL and shut it down
if(s_useOpenGL) if(s_useOpenGL)
{
KillOpenGL(); KillOpenGL();
}
else else
#endif #endif
{
// shut down the system that converts from 8 to 16/32 bpp // shut down the system that converts from 8 to 16/32 bpp
if(s_curbpp > 8) if (s_curbpp > 8)
{
KillBlitToHigh(); 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 // shut down the SDL video sub-system
SDL_QuitSubSystem(SDL_INIT_VIDEO); //SDL_QuitSubSystem(SDL_INIT_VIDEO);
s_inited = 0; s_inited = 0;
return 0; return 0;
@ -158,6 +227,203 @@ int InitVideo(FCEUGI *gi)
// This is a big TODO. Stubbing this off into its own function, // This is a big TODO. Stubbing this off into its own function,
// as the SDL surface routines have changed drastically in SDL2 // as the SDL surface routines have changed drastically in SDL2
// TODO - 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 #else
/** /**
@ -632,13 +898,14 @@ void UnlockConsole(){}
void void
BlitScreen(uint8 *XBuf) BlitScreen(uint8 *XBuf)
{ {
SDL_Surface *TmpScreen; //SDL_Surface *TmpScreen;
uint8 *dest; uint8 *dest;
int xo = 0, yo = 0; int xo = 0, yo = 0;
int w, h, pitch;
if(!s_screen) { //if(!s_screen) {
return; // return;
} //}
// refresh the palette if required // refresh the palette if required
if(s_paletterefresh) { if(s_paletterefresh) {
@ -657,27 +924,32 @@ BlitScreen(uint8 *XBuf)
// XXX soules - not entirely sure why this is being done yet // XXX soules - not entirely sure why this is being done yet
XBuf += s_srendline * 256; XBuf += s_srendline * 256;
if(s_BlitBuf) { //if(s_BlitBuf) {
TmpScreen = s_BlitBuf; // TmpScreen = s_BlitBuf;
} else { //} else {
TmpScreen = s_screen; // TmpScreen = s_screen;
} //}
// lock the display, if necessary // lock the display, if necessary
if(SDL_MUSTLOCK(TmpScreen)) { //if(SDL_MUSTLOCK(TmpScreen)) {
if(SDL_LockSurface(TmpScreen) < 0) { // if(SDL_LockSurface(TmpScreen) < 0) {
return; // 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. //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); dest += xo * (s_curbpp >> 3);
if(TmpScreen->h > (s_tlines * s_eys)) { if(h > (s_tlines * s_eys)) {
yo = (int)((TmpScreen->h - s_tlines * s_eys) / 2); yo = (int)((h - s_tlines * s_eys) / 2);
dest += yo * TmpScreen->pitch; dest += yo * pitch;
} }
//} //}
@ -686,26 +958,29 @@ BlitScreen(uint8 *XBuf)
if(s_curbpp > 8) { if(s_curbpp > 8) {
if(s_BlitBuf) { if(s_BlitBuf) {
Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines, Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines,
TmpScreen->pitch, 1, 1); pitch, 1, 1);
} else { } else {
Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines, Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines,
TmpScreen->pitch, (int)s_exs, (int)s_eys); pitch, (int)s_exs, (int)s_eys);
} }
} else { } else {
if(s_BlitBuf) { if(s_BlitBuf) {
Blit8To8(XBuf + NOFFSET, dest, NWIDTH, s_tlines, Blit8To8(XBuf + NOFFSET, dest, NWIDTH, s_tlines,
TmpScreen->pitch, 1, 1, 0, s_sponge); pitch, 1, 1, 0, s_sponge);
} else { } else {
Blit8To8(XBuf + NOFFSET, dest, NWIDTH, s_tlines, 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); s_eefx, s_sponge);
} }
} }
//print_pixels();
//
guiPixelBufferReDraw();
// unlock the display, if necessary // unlock the display, if necessary
if(SDL_MUSTLOCK(TmpScreen)) { //if(SDL_MUSTLOCK(TmpScreen)) {
SDL_UnlockSurface(TmpScreen); // SDL_UnlockSurface(TmpScreen);
} //}
int scrw; int scrw;
if(s_sponge == 3) { // NTSC 2x 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 we have a hardware video buffer, do a fast video->video copy
if(s_BlitBuf) { //if(s_BlitBuf) {
SDL_Rect srect; // SDL_Rect srect;
SDL_Rect drect; // SDL_Rect drect;
srect.x = 0; // srect.x = 0;
srect.y = 0; // srect.y = 0;
srect.w = scrw; // srect.w = scrw;
srect.h = s_tlines; // srect.h = s_tlines;
drect.x = 0; // drect.x = 0;
drect.y = 0; // drect.y = 0;
drect.w = (Uint16)(s_exs * scrw); // drect.w = (Uint16)(s_exs * scrw);
drect.h = (Uint16)(s_eys * s_tlines); // 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 // ensure that the display is updated
#if SDL_VERSION_ATLEAST(2, 0, 0) #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 #else
SDL_UpdateRect(s_screen, xo, yo, //SDL_UpdateRect(s_screen, xo, yo,
(Uint32)(scrw * s_exs), (Uint32)(s_tlines * s_eys)); // (Uint32)(scrw * s_exs), (Uint32)(s_tlines * s_eys));
#endif #endif
#ifdef CREATE_AVI #ifdef CREATE_AVI
@ -781,7 +1059,7 @@ BlitScreen(uint8 *XBuf)
break; break;
#endif #endif
default: default:
NESVideoLoggingVideo(s_screen->pixels, width,height, fps, s_curbpp); NESVideoLoggingVideo( dest, width,height, fps, s_curbpp);
} }
} }
#endif #endif
@ -814,14 +1092,14 @@ BlitScreen(uint8 *XBuf)
#endif #endif
#endif #endif
#if SDL_VERSION_ATLEAST(2, 0, 0) //#if SDL_VERSION_ATLEAST(2, 0, 0)
// TODO // // TODO
#else //#else
// have to flip the displayed buffer in the case of double buffering // // have to flip the displayed buffer in the case of double buffering
if(s_screen->flags & SDL_DOUBLEBUF) { // if(s_screen->flags & SDL_DOUBLEBUF) {
SDL_Flip(s_screen); // SDL_Flip(s_screen);
} // }
#endif //#endif
} }
/** /**