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('LSB_FIRST', 'Least signficant byte first (non-PPC)', 1),
BoolVariable('CLANG', 'Compile with llvm-clang instead of gcc', 0),
BoolVariable('SDL2', 'Compile using SDL2 instead of SDL 1.2 (experimental/non-functional)', 0)
BoolVariable('SDL2', 'Compile using SDL2 instead of SDL 1.2 (experimental/non-functional)', 1)
)
AddOption('--prefix', dest='prefix', type='string', nargs=1, action='store', metavar='DIR', help='installation prefix')

View File

@ -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<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)
{
cairo_format_t cairo_format;
// This should handle resizing so the emulation takes up as much
// of the GTK window as possible
@ -3112,6 +3231,36 @@ gboolean handle_resize (GtkWindow * win, GdkEvent * event, gpointer data)
if (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
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);

View File

@ -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

View File

@ -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

View File

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

View File

@ -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(xscale<yscale) yscale = xscale;
if(yscale<xscale) xscale = yscale;
}
#endif
{
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.
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;
}

View File

@ -1,6 +1,13 @@
void SetOpenGLPalette(uint8 *data);
void BlitOpenGL(uint8 *buf);
void KillOpenGL(void);
int InitOpenGL(int l, int r, int t, int b, double xscale,double yscale, int efx, int ipolate,
int stretchx, int stretchy, SDL_Surface *screen);
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;
// 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;
static int s_curbpp = 0;
static int s_srendline, s_erendline;
static int s_tlines;
static int s_inited;
static int s_inited = 0;
#ifdef OPENGL
static int s_useOpenGL;
static int s_useOpenGL = 0;
#endif
static double s_exs, s_eys;
static int s_eefx;
static int s_clipSides;
static int s_fullscreen;
static int noframe;
static double s_exs = 1.0, s_eys = 1.0;
static int s_eefx = 0;
static int s_clipSides = 0;
static int s_fullscreen = 0;
static int noframe = 0;
static int s_nativeWidth = -1;
static int s_nativeHeight = -1;
#define NWIDTH (256 - (s_clipSides ? 16 : 0))
#define NOFFSET (s_clipSides ? 8 : 0)
static int s_paletterefresh;
static int s_paletterefresh = 1;
extern bool MaxSpeed;
@ -90,6 +95,38 @@ 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; 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
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
}
/**