Successful display of graphics using cairo. Not as efficient as other methods but works.
This commit is contained in:
parent
88e0c838e2
commit
1fc0725e94
|
@ -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')
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue