From fb0ff7e4da1dd368c41e57fc9a22754dc0d40d40 Mon Sep 17 00:00:00 2001 From: masscat Date: Thu, 24 May 2007 14:43:58 +0000 Subject: [PATCH] Added command line options. Added frame rate limiter. --- desmume/src/gtk-glade/desmume.c | 12 + desmume/src/gtk-glade/desmume.h | 5 + desmume/src/gtk-glade/gdk_gl.c | 399 ++++---------------------------- desmume/src/gtk-glade/gdk_gl.h | 13 +- desmume/src/gtk-glade/main.c | 249 +++++++++++++++++--- 5 files changed, 281 insertions(+), 397 deletions(-) diff --git a/desmume/src/gtk-glade/desmume.c b/desmume/src/gtk-glade/desmume.c index 47111d951..0fd382335 100755 --- a/desmume/src/gtk-glade/desmume.c +++ b/desmume/src/gtk-glade/desmume.c @@ -129,6 +129,7 @@ gboolean EmuLoop(gpointer data) if(desmume_running()) /* Si on est en train d'executer le programme ... */ { + static int limiter_frame_counter = 0; fps_FrameCount += Frameskip + 1; if(!fps_SecStart) fps_SecStart = SDL_GetTicks(); if(SDL_GetTicks() - fps_SecStart >= 1000) @@ -150,6 +151,17 @@ gboolean EmuLoop(gpointer data) notify_Tools(); gtk_widget_queue_draw(pDrawingArea); gtk_widget_queue_draw(pDrawingArea2); + + if ( !glade_fps_limiter_disabled) { + limiter_frame_counter += 1; + if ( limiter_frame_counter >= FPS_LIMITER_FRAME_PERIOD) { + limiter_frame_counter = 0; + + /* wait for the timer to expire */ + SDL_SemWait( glade_fps_limiter_semaphore); + } + } + return TRUE; } gtk_widget_queue_draw(pDrawingArea); diff --git a/desmume/src/gtk-glade/desmume.h b/desmume/src/gtk-glade/desmume.h index 5b410237b..2133eb257 100755 --- a/desmume/src/gtk-glade/desmume.h +++ b/desmume/src/gtk-glade/desmume.h @@ -22,6 +22,11 @@ #include "globals.h" + +#define FPS_LIMITER_FRAME_PERIOD 5 +extern SDL_sem *glade_fps_limiter_semaphore; +extern int glade_fps_limiter_disabled; + extern void desmume_init(); extern void desmume_free(); diff --git a/desmume/src/gtk-glade/gdk_gl.c b/desmume/src/gtk-glade/gdk_gl.c index 192644a2a..65aee8a28 100755 --- a/desmume/src/gtk-glade/gdk_gl.c +++ b/desmume/src/gtk-glade/gdk_gl.c @@ -21,7 +21,10 @@ #include "gdk_gl.h" -#ifdef HAVE_LIBGDKGLEXT_X11_1_0 +#ifdef GTKGLEXT_AVAILABLE + +#include +#include #define _DUP8(a) a,a,a,a, a,a,a,a #define _DUP4(a) a,a,a,a @@ -37,6 +40,9 @@ GtkWidget *pDrawingTexArea; GLuint screen_texture[1]; +/* enable software colour format conversion */ +static int gtk_glade_use_software_colour_convert; + #undef _DUP8 #undef _DUP4 #undef _DUP2 @@ -80,7 +86,7 @@ void my_gl_Identity() { glLoadIdentity(); } -void my_gl_DrawBeautifulQuad() { +void my_gl_DrawBeautifulQuad( void) { // beautiful quad glBegin(GL_QUADS); glColor3ub(255,0,0); glVertex2d(-0.75,-0.75); @@ -116,7 +122,6 @@ void my_gl_Clear(int screen) { /************************************************/ void init_GL(GtkWidget * widget, int screen, int share_num) { - int n; // for (n=gtk_events_pending(); n>0; n--) // gtk_main_iteration(); // init GL capability @@ -166,13 +171,16 @@ int init_GL_free(GtkWidget * widget) { return r; } -void init_GL_capabilities() { +void init_GL_capabilities( int use_software_convert) { + uint16_t blank_texture[256 * 512]; my_glConfig = gdk_gl_config_new_by_mode ( GDK_GL_MODE_RGBA | GDK_GL_MODE_DEPTH | GDK_GL_MODE_DOUBLE ); + + gtk_glade_use_software_colour_convert = use_software_convert; // initialize 1st drawing area init_GL(pDrawingArea,0,0); my_gl_Clear(0); @@ -181,30 +189,18 @@ void init_GL_capabilities() { // generate ONE texture (display) glEnable(GL_TEXTURE_2D); glGenTextures(2, Textures); + + /* Generate The Texture */ + glBindTexture( GL_TEXTURE_2D, Textures[0]); + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 256, 512, + 0, GL_RGBA, + GL_UNSIGNED_SHORT_1_5_5_5_REV, + blank_texture); my_gl_End(0); // initialize 2nd drawing area (sharing context) init_GL(pDrawingArea2,1,0); my_gl_Clear(1); - - // Signals binding - // Top screen - g_signal_connect_after (G_OBJECT (pDrawingArea), "realize", - G_CALLBACK (gtk_init_main_gl_area), - NULL); - g_signal_connect( G_OBJECT(pDrawingArea), "expose_event", - G_CALLBACK(top_screen_expose_fn), NULL ) ; - g_signal_connect( G_OBJECT(pDrawingArea), "configure_event", - G_CALLBACK(common_configure_fn), NULL ) ; - // Bottom screen - g_signal_connect_after (G_OBJECT (pDrawingArea2), "realize", - G_CALLBACK (gtk_init_sub_gl_area), - NULL); - g_signal_connect( G_OBJECT(pDrawingArea2), "expose_event", - G_CALLBACK(bottom_screen_expose_fn), NULL ) ; - g_signal_connect( G_OBJECT(pDrawingArea2), "configure_event", - G_CALLBACK(common_configure_fn), NULL ) ; - } /************************************************/ @@ -234,14 +230,29 @@ void my_gl_Texture2D() { #undef MyFILTER } -void my_gl_ScreenTex() { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, -// pause effect -// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, - 256, 512, 0, GL_RGBA, - GL_UNSIGNED_SHORT_1_5_5_5_REV, -// GL_UNSIGNED_SHORT_5_5_5_1, - GPU_screen); +static void +my_gl_ScreenTex( int software_convert) { + if ( software_convert) { + u8 converted[256 * 384 * 3]; + int i; + + for ( i = 0; i < (256 * 384); i++) { + converted[(i * 3) + 0] = ((*((u16 *)&GPU_screen[(i<<1)]) >> 0) & 0x1f) << 3; + converted[(i * 3) + 1] = ((*((u16 *)&GPU_screen[(i<<1)]) >> 5) & 0x1f) << 3; + converted[(i * 3) + 2] = ((*((u16 *)&GPU_screen[(i<<1)]) >> 10) & 0x1f) << 3; + } + + glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 256, 384, + GL_RGB, + GL_UNSIGNED_BYTE, + converted); + } + else { + glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 256, 384, + GL_RGBA, + GL_UNSIGNED_SHORT_1_5_5_5_REV, + &GPU_screen); + } } void my_gl_ScreenTexApply(int screen) { @@ -260,7 +271,7 @@ void my_gl_ScreenTexApply(int screen) { /************************************************/ gboolean screen (GtkWidget * widget, int viewportscreen) { - int H,W,screen; + int screen; GPU * gpu; float bright_color = 0.0f; // blend with black float bright_alpha = 0.0f; // don't blend @@ -303,7 +314,7 @@ gboolean screen (GtkWidget * widget, int viewportscreen) { // create the texture for both display my_gl_Texture2D(); if (viewportscreen==0) { - my_gl_ScreenTex(); + my_gl_ScreenTex( gtk_glade_use_software_colour_convert); } } else { // pause @@ -333,324 +344,4 @@ gboolean screen (GtkWidget * widget, int viewportscreen) { return TRUE; } -/* 3D Rendering */ -static void -gtk_init_main_gl_area(GtkWidget *widget, - gpointer data) -{ - GLenum errCode; - int i; - GdkGLContext *glcontext; - GdkGLDrawable *gldrawable; - GtkWidget *other_drawing_area = (GtkWidget *)data; - glcontext = gtk_widget_get_gl_context (widget); - gldrawable = gtk_widget_get_gl_drawable (widget); - uint16_t blank_texture[256 * 512]; - - /*** OpenGL BEGIN ***/ - if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) - return; - - //printf("Doing GL init\n"); - - for ( i = 0; i < 256 * 512; i++) { - blank_texture[i] = 0x001f; - } - - /* Enable Texture Mapping */ - glEnable( GL_TEXTURE_2D ); - - /* Set the background black */ - glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); - - /* Create The Texture */ - glGenTextures( 1, &screen_texture[0]); - - glBindTexture( GL_TEXTURE_2D, screen_texture[0]); - - /* Generate The Texture */ - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 256, 512, - 0, GL_RGBA, - GL_UNSIGNED_SHORT_1_5_5_5_REV, - blank_texture); - - /* Linear Filtering */ - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - - if ((errCode = glGetError()) != GL_NO_ERROR) { - GLubyte errString; - - errString = gluErrorString(errCode); - fprintf( stderr, "Failed to init GL: %s\n", errString); - } - - gdk_gl_drawable_gl_end (gldrawable); - /*** OpenGL END ***/ -} - -static void -gtk_init_sub_gl_area(GtkWidget *widget, - gpointer data) -{ - GLenum errCode; - GdkGLContext *glcontext; - GdkGLDrawable *gldrawable; - glcontext = gtk_widget_get_gl_context (widget); - gldrawable = gtk_widget_get_gl_drawable (widget); - - - /*** OpenGL BEGIN ***/ - if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) - return; - - /* Enable Texture Mapping */ - glEnable( GL_TEXTURE_2D ); - - /* Set the background black */ - glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); - - glBindTexture( GL_TEXTURE_2D, screen_texture[0]); - - if ((errCode = glGetError()) != GL_NO_ERROR) { - GLubyte errString; - - errString = gluErrorString(errCode); - fprintf( stderr, "Failed to init GL: %s\n", errString); - } - - gdk_gl_drawable_gl_end (gldrawable); - /*** OpenGL END ***/ -} - -static int -top_screen_expose_fn( GtkWidget *widget, GdkEventExpose *event, gpointer data) { - GdkGLContext *glcontext = gtk_widget_get_gl_context (widget); - GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget); - // FIXME: Hardcoded to false for now... - int software_convert = 0; - - /*** OpenGL BEGIN ***/ - if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) - return FALSE; - - GLenum errCode; - - /* Clear The Screen And The Depth Buffer */ - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); - - /* Move Into The Screen 5 Units */ - //glLoadIdentity( ); - - /* Select screen Texture */ - glBindTexture( GL_TEXTURE_2D, screen_texture[0]); - - if ( software_convert) { - int i; - u8 converted[256 * 384 * 3]; - - for ( i = 0; i < (256 * 384); i++) { - converted[(i * 3) + 0] = ((*((u16 *)&GPU_screen[(i<<1)]) >> 0) & 0x1f) << 3; - converted[(i * 3) + 1] = ((*((u16 *)&GPU_screen[(i<<1)]) >> 5) & 0x1f) << 3; - converted[(i * 3) + 2] = ((*((u16 *)&GPU_screen[(i<<1)]) >> 10) & 0x1f) << 3; - } - - glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 256, 384, - GL_RGB, - GL_UNSIGNED_BYTE, - converted); - } - else { - glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 256, 384, - GL_RGBA, - GL_UNSIGNED_SHORT_1_5_5_5_REV, - &GPU_screen); - } - - - if ((errCode = glGetError()) != GL_NO_ERROR) { - GLubyte errString; - - errString = gluErrorString(errCode); - fprintf( stderr, "GL subimage failed: %s\n", errString); - } - - - glBegin( GL_QUADS); - - /* Top screen */ - glTexCoord2f( 0.0f, 0.0f ); glVertex3f( 0.0f, 0.0f, 0.0f ); - glTexCoord2f( 1.0f, 0.0f ); glVertex3f( 256.0f, 0.0f, 0.0f ); - glTexCoord2f( 1.0f, 0.375f ); glVertex3f( 256.0f, 192.0f, 0.0f ); - glTexCoord2f( 0.0f, 0.375f ); glVertex3f( 0.0f, 192.0f, 0.0f ); - glEnd( ); - - if ((errCode = glGetError()) != GL_NO_ERROR) { - GLubyte errString; - - errString = gluErrorString(errCode); - fprintf( stderr, "GL draw failed: %s\n", errString); - } - - if (gdk_gl_drawable_is_double_buffered (gldrawable)) - gdk_gl_drawable_swap_buffers (gldrawable); - else - glFlush (); - - - gdk_gl_drawable_gl_end (gldrawable); - /*** OpenGL END ***/ - - gtk_widget_queue_draw(pDrawingArea2); -} - -static int -bottom_screen_expose_fn(GtkWidget *widget, GdkEventExpose *event, gpointer data) -{ - GdkGLContext *glcontext = gtk_widget_get_gl_context (widget); - GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget); - - //g_print("Sub Expose\n"); - - /*** OpenGL BEGIN ***/ - if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) { - g_print("begin failed\n"); - return FALSE; - } - //g_print("begin\n"); - - GLenum errCode; - - /* Clear The Screen */ - glClear( GL_COLOR_BUFFER_BIT); - - //glBindTexture( GL_TEXTURE_2D, screen_texture[0]); - - glBegin( GL_QUADS); - - /* Bottom screen */ - glTexCoord2f( 0.0f, 0.375f ); glVertex2f( 0.0f, 0.0f); - glTexCoord2f( 1.0f, 0.375f ); glVertex2f( 256.0f, 0.0f); - glTexCoord2f( 1.0f, 0.75f ); glVertex2f( 256.0f, 192.0f); - glTexCoord2f( 0.0f, 0.75f ); glVertex2f( 0.0f, 192.0f); - glEnd( ); - - if (gdk_gl_drawable_is_double_buffered (gldrawable)) - gdk_gl_drawable_swap_buffers (gldrawable); - else - glFlush (); - - - if ((errCode = glGetError()) != GL_NO_ERROR) { - GLubyte errString; - - errString = gluErrorString(errCode); - fprintf( stderr, "sub GL draw failed: %s\n", errString); - } - - gdk_gl_drawable_gl_end (gldrawable); - /*** OpenGL END ***/ - - return 1; -} - -static gboolean -common_configure_fn( GtkWidget *widget, - GdkEventConfigure *event ) { - if ( gtk_widget_is_gl_capable( widget) == FALSE) - return TRUE; - - GdkGLContext *glcontext = gtk_widget_get_gl_context (widget); - GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget); - - int comp_width = 3 * event->width; - int comp_height = 4 * event->height; - int use_width = 1; - GLenum errCode; - - /* Height / width ration */ - GLfloat ratio; - - //g_print("wdith %d, height %d\n", event->width, event->height); - - /*** OpenGL BEGIN ***/ - if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) - return FALSE; - - if ( comp_width > comp_height) { - use_width = 0; - } - - /* Protect against a divide by zero */ - if ( event->height == 0 ) - event->height = 1; - if ( event->width == 0) - event->width = 1; - - ratio = ( GLfloat )event->width / ( GLfloat )event->height; - - /* Setup our viewport. */ - glViewport( 0, 0, ( GLint )event->width, ( GLint )event->height ); - - /* - * change to the projection matrix and set - * our viewing volume. - */ - glMatrixMode( GL_PROJECTION ); - glLoadIdentity( ); - - { - double left; - double right; - double bottom; - double top; - double other_dimen; - - if ( use_width) { - left = 0.0; - right = 256.0; - - other_dimen = (double)event->width * 3.0 / 4.0; - - top = 0.0; - bottom = 192.0 * ((double)event->height / other_dimen); - } - else { - top = 0.0; - bottom = 192.0; - other_dimen = (double)event->height * 4.0 / 3.0; - - left = 0.0; - right = 256.0 * ((double)event->width / other_dimen); - } - - /* - printf("%d,%d\n", width, height); - printf("l %lf, r %lf, t %lf, b %lf, other dimen %lf\n", - left, right, top, bottom, other_dimen); - */ - - /* get the area (0,0) to (256,384) into the middle of the viewport */ - gluOrtho2D( left, right, bottom, top); - } - - /* Make sure we're chaning the model view and not the projection */ - glMatrixMode( GL_MODELVIEW ); - - /* Reset The View */ - glLoadIdentity( ); - - if ((errCode = glGetError()) != GL_NO_ERROR) { - GLubyte errString; - - errString = gluErrorString(errCode); - fprintf( stderr, "GL resie failed: %s\n", errString); - } - - gdk_gl_drawable_gl_end (gldrawable); - /*** OpenGL END ***/ - - return TRUE; -} - -#endif /* if HAVE_LIBGDKGLEXT_X11_1_0 */ +#endif /* if GTKGLEXT_AVAILABLE */ diff --git a/desmume/src/gtk-glade/gdk_gl.h b/desmume/src/gtk-glade/gdk_gl.h index d784e975d..8ee0f03cc 100755 --- a/desmume/src/gtk-glade/gdk_gl.h +++ b/desmume/src/gtk-glade/gdk_gl.h @@ -22,7 +22,7 @@ #include "globals.h" // comment for GL :D //#undef HAVE_LIBGDKGLEXT_X11_1_0 -#ifdef HAVE_LIBGDKGLEXT_X11_1_0 +#ifdef GTKGLEXT_AVAILABLE #include #include #include @@ -33,19 +33,12 @@ BOOL my_gl_Begin (int screen); void my_gl_End (int screen); void my_gl_Clear(int screen); -void my_gl_DrawBeautifulQuad(); +void my_gl_DrawBeautifulQuad( void); -void init_GL_capabilities(); +void init_GL_capabilities( int use_software_convert); void init_GL(GtkWidget * widget, int screen, int share_num); int init_GL_free_s(GtkWidget * widget, int share_num); int init_GL_free(GtkWidget * widget); void register_gl_fun(fun_gl_Begin beg,fun_gl_End end); -#ifdef HAVE_LIBGDKGLEXT_X11_1_0 -static void gtk_init_main_gl_area(GtkWidget *, gpointer); -static void gtk_init_sub_gl_area(GtkWidget *, gpointer); -static int top_screen_expose_fn(GtkWidget *, GdkEventExpose *, gpointer); -static int bottom_screen_expose_fn(GtkWidget *, GdkEventExpose *, gpointer); -static gboolean common_configure_fn( GtkWidget *, GdkEventConfigure *); -#endif void reshape (GtkWidget * widget, int screen); gboolean screen (GtkWidget * widget, int off); diff --git a/desmume/src/gtk-glade/main.c b/desmume/src/gtk-glade/main.c index 034350264..feb3fe796 100755 --- a/desmume/src/gtk-glade/main.c +++ b/desmume/src/gtk-glade/main.c @@ -25,11 +25,19 @@ #include "dTools/callbacks_dtools.h" #include "globals.h" -#ifdef HAVE_LIBGDKGLEXT_X11_1_0 +#ifdef GTKGLEXT_AVAILABLE +#include #include "../opengl_collector_3Demu.h" #include "gdk_3Demu.h" #endif +/* + * The frame limiter semaphore + */ +SDL_sem *glade_fps_limiter_semaphore; +int glade_fps_limiter_disabled = 0; + + GtkWidget * pWindow; GtkWidget * pDrawingArea, * pDrawingArea2; GladeXML * xml, * xml_tools; @@ -43,13 +51,98 @@ NULL GPU3DInterface *core3DList[] = { &gpu3DNull -#ifdef HAVE_LIBGDKGLEXT_X11_1_0 +#ifdef GTKGLEXT_AVAILABLE , &gpu3D_opengl_collector #endif }; +/* + * + * Command line handling + * + */ +struct configured_features { + int software_colour_convert; + int disable_3d; + int disable_limiter; + const char *nds_file; +}; + +static void +init_configured_features( struct configured_features *config) { + config->software_colour_convert = 0; + + config->disable_3d = 0; + + config->disable_limiter = 0; + + config->nds_file = NULL; +} + +static int +fill_configured_features( struct configured_features *config, + int argc, char ** argv) { + int good_args = 1; + int print_usage = 0; + int i; + + for ( i = 1; i < argc && good_args; i++) { + if ( strcmp( argv[i], "--help") == 0) { + g_print( "USAGE: %s [OPTIONS] [nds-file]\n", argv[0]); + g_print( "OPTIONS:\n"); +#ifdef GTKGLEXT_AVAILABLE + g_print( " --soft-convert Use software colour conversion during OpenGL\n"); + g_print( " screen rendering. May produce better or worse\n"); + g_print( " frame rates depending on hardware.\n"); + g_print( "\n"); + g_print( " --disable-3d Disables the 3D emulation\n"); + g_print( "\n"); +#endif + g_print( " --disable-limiter Disables the 60 fps limiter\n"); + g_print( "\n"); + g_print( " --help Display this message\n"); + good_args = 0; + } +#ifdef GTKGLEXT_AVAILABLE + else if ( strcmp( argv[i], "--soft-convert") == 0) { + config->software_colour_convert = 1; + } + else if ( strcmp( argv[i], "--disable-3d") == 0) { + config->disable_3d = 1; + } +#endif + else if ( strcmp( argv[i], "--disable-limiter") == 0) { + config->disable_limiter = 1; + } + else { + if ( config->nds_file == NULL) { + config->nds_file = argv[i]; + } + else { + g_print( "NDS file (\"%s\") already set\n", config->nds_file); + good_args = 0; + } + } + } + + if ( good_args) { + /* + * check if the configured features are consistant + */ + } + + if ( print_usage) { + g_print( "USAGE: %s [options] [nds-file]\n", argv[0]); + g_print( "USAGE: %s --help - for help\n", argv[0]); + } + + return good_args; +} + + + /* ***** ***** TOOLS ***** ***** */ GList * tools_to_update = NULL; @@ -220,39 +313,54 @@ void update_savestate(u8 num) desmume_resume(); } + +/** + * A SDL timer callback function. Signals the supplied SDL semaphore + * if its value is small. + * + * @param interval The interval since the last call (in ms) + * @param param The pointer to the semaphore. + * + * @return The interval to the next call (required by SDL) + */ +static Uint32 +glade_fps_limiter_fn( Uint32 interval, void *param) { + SDL_sem *sdl_semaphore = (SDL_sem *)param; + + /* signal the semaphore if it is getting low */ + if ( SDL_SemValue( sdl_semaphore) < 4) { + SDL_SemPost( sdl_semaphore); + } + + return interval; +} + /* ***** ***** MAIN ***** ***** */ -#ifdef WIN32 -int WinMain () -{ - main(0,NULL); -} -#endif +static int +common_gtk_glade_main( struct configured_features *my_config) { + SDL_TimerID limiter_timer; -int main(int argc, char *argv[]) { - - const char *commandLine_File = NULL; - gtk_init(&argc, &argv); -#ifdef HAVE_LIBGDKGLEXT_X11_1_0 +#ifdef GTKGLEXT_AVAILABLE // check if you have GTHREAD when running configure script -// g_thread_init(NULL); - gtk_gl_init(&argc, &argv); + //g_thread_init(NULL); register_gl_fun(my_gl_Begin,my_gl_End); #endif - if(argc == 2) commandLine_File = argv[1]; #ifdef DEBUG LogStart(); #endif init_keyvals(); - if(SDL_Init(SDL_INIT_VIDEO) == -1) + if(SDL_Init( SDL_INIT_TIMER | SDL_INIT_VIDEO) == -1) { fprintf(stderr, "Error trying to initialize SDL: %s\n", SDL_GetError()); return 1; } + + desmume_init(); /* Initialize joysticks */ if(!init_joy()) return 1; @@ -271,11 +379,11 @@ int main(int argc, char *argv[]) { glade_xml_signal_autoconnect_StringObject(xml); glade_xml_signal_autoconnect_StringObject(xml_tools); - init_GL_capabilities(); + init_GL_capabilities( my_config->software_colour_convert); /* check command line file */ - if(commandLine_File) { - if(desmume_open(commandLine_File) >= 0) { + if( my_config->nds_file) { + if(desmume_open( my_config->nds_file) >= 0) { desmume_resume(); enable_rom_features(); } else { @@ -283,7 +391,7 @@ int main(int argc, char *argv[]) { GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, - "Unable to load :\n%s", commandLine_File); + "Unable to load :\n%s", my_config->nds_file); gtk_dialog_run(GTK_DIALOG(pDialog)); gtk_widget_destroy(pDialog); } @@ -292,28 +400,66 @@ int main(int argc, char *argv[]) { gtk_widget_show(pDrawingArea); gtk_widget_show(pDrawingArea2); -#ifdef HAVE_LIBGDKGLEXT_X11_1_0 - /* setup the gdk 3D emulation */ - if ( init_opengl_gdk_3Demu()) { - NDS_3D_SetDriver(1); + { + int use_null_3d = my_config->disable_3d; - if (!gpu3D->NDS_3D_Init()) { - fprintf( stderr, "Failed to initialise openGL 3D emulation; " - "removing 3D support\n"); +#ifdef GTKGLEXT_AVAILABLE + if ( !use_null_3d) { + /* setup the gdk 3D emulation */ + if ( init_opengl_gdk_3Demu()) { + NDS_3D_SetDriver(1); + + if (!gpu3D->NDS_3D_Init()) { + fprintf( stderr, "Failed to initialise openGL 3D emulation; " + "removing 3D support\n"); + use_null_3d = 1; + } + } + else { + fprintf( stderr, "Failed to setup openGL 3D emulation; " + "removing 3D support\n"); + use_null_3d = 1; + } + } +#endif + if ( use_null_3d) { + NDS_3D_SetDriver ( 0); + gpu3D->NDS_3D_Init(); } } - else { - fprintf( stderr, "Failed to setup openGL 3D emulation; " - "removing 3D support\n"); - } -#endif // on_menu_tileview_activate(NULL,NULL); + /* setup the frame limiter and indicate if it is disabled */ + glade_fps_limiter_disabled = my_config->disable_limiter; + + if ( !glade_fps_limiter_disabled) { + /* create the semaphore used for fps limiting */ + glade_fps_limiter_semaphore = SDL_CreateSemaphore( 1); + + /* start a SDL timer for every FPS_LIMITER_FRAME_PERIOD + * frames to keep us at 60 fps */ + limiter_timer = SDL_AddTimer( 16 * FPS_LIMITER_FRAME_PERIOD, + glade_fps_limiter_fn, + glade_fps_limiter_semaphore); + if ( limiter_timer == NULL) { + fprintf( stderr, "Error trying to start FPS limiter timer: %s\n", + SDL_GetError()); + SDL_DestroySemaphore( glade_fps_limiter_semaphore); + glade_fps_limiter_disabled = 1; + } + } + /* start event loop */ gtk_main(); desmume_free(); + if ( !glade_fps_limiter_disabled) { + /* tidy up the FPS limiter timer and semaphore */ + SDL_RemoveTimer( limiter_timer); + SDL_DestroySemaphore( glade_fps_limiter_semaphore); + } + #ifdef DEBUG LogStop(); #endif @@ -325,3 +471,40 @@ int main(int argc, char *argv[]) { return EXIT_SUCCESS; } +int main(int argc, char *argv[]) { + struct configured_features my_config; + + init_configured_features( &my_config); + + gtk_init(&argc, &argv); + +#ifdef GTKGLEXT_AVAILABLE + gtk_gl_init( &argc, &argv); +#endif + + if ( !fill_configured_features( &my_config, argc, argv)) { + exit(0); + } + + return common_gtk_glade_main( &my_config); +} + + +#ifdef WIN32 +int WinMain ( HINSTANCE hThisInstance, HINSTANCE hPrevInstance, + LPSTR lpszArgument, int nFunsterStil) +{ + int argc = 0; + char *argv[] = NULL; + + /* + * FIXME: + * Emulate the argc and argv main parameters. Could do this using + * CommandLineToArgvW and then convert the wide chars to thin chars. + * Or parse the wide chars directly and call common_gtk_glade_main with a + * filled configuration structure. + */ + main( argc, argv); +} +#endif +