Added command line options. Added frame rate limiter.
This commit is contained in:
parent
22d1317576
commit
fb0ff7e4da
|
@ -129,6 +129,7 @@ gboolean EmuLoop(gpointer data)
|
||||||
|
|
||||||
if(desmume_running()) /* Si on est en train d'executer le programme ... */
|
if(desmume_running()) /* Si on est en train d'executer le programme ... */
|
||||||
{
|
{
|
||||||
|
static int limiter_frame_counter = 0;
|
||||||
fps_FrameCount += Frameskip + 1;
|
fps_FrameCount += Frameskip + 1;
|
||||||
if(!fps_SecStart) fps_SecStart = SDL_GetTicks();
|
if(!fps_SecStart) fps_SecStart = SDL_GetTicks();
|
||||||
if(SDL_GetTicks() - fps_SecStart >= 1000)
|
if(SDL_GetTicks() - fps_SecStart >= 1000)
|
||||||
|
@ -150,6 +151,17 @@ gboolean EmuLoop(gpointer data)
|
||||||
notify_Tools();
|
notify_Tools();
|
||||||
gtk_widget_queue_draw(pDrawingArea);
|
gtk_widget_queue_draw(pDrawingArea);
|
||||||
gtk_widget_queue_draw(pDrawingArea2);
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
gtk_widget_queue_draw(pDrawingArea);
|
gtk_widget_queue_draw(pDrawingArea);
|
||||||
|
|
|
@ -22,6 +22,11 @@
|
||||||
|
|
||||||
#include "globals.h"
|
#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_init();
|
||||||
extern void desmume_free();
|
extern void desmume_free();
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,10 @@
|
||||||
|
|
||||||
#include "gdk_gl.h"
|
#include "gdk_gl.h"
|
||||||
|
|
||||||
#ifdef HAVE_LIBGDKGLEXT_X11_1_0
|
#ifdef GTKGLEXT_AVAILABLE
|
||||||
|
|
||||||
|
#include <GL/gl.h>
|
||||||
|
#include <GL/glu.h>
|
||||||
|
|
||||||
#define _DUP8(a) a,a,a,a, a,a,a,a
|
#define _DUP8(a) a,a,a,a, a,a,a,a
|
||||||
#define _DUP4(a) a,a,a,a
|
#define _DUP4(a) a,a,a,a
|
||||||
|
@ -37,6 +40,9 @@ GtkWidget *pDrawingTexArea;
|
||||||
|
|
||||||
GLuint screen_texture[1];
|
GLuint screen_texture[1];
|
||||||
|
|
||||||
|
/* enable software colour format conversion */
|
||||||
|
static int gtk_glade_use_software_colour_convert;
|
||||||
|
|
||||||
#undef _DUP8
|
#undef _DUP8
|
||||||
#undef _DUP4
|
#undef _DUP4
|
||||||
#undef _DUP2
|
#undef _DUP2
|
||||||
|
@ -80,7 +86,7 @@ void my_gl_Identity() {
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
}
|
}
|
||||||
|
|
||||||
void my_gl_DrawBeautifulQuad() {
|
void my_gl_DrawBeautifulQuad( void) {
|
||||||
// beautiful quad
|
// beautiful quad
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
glColor3ub(255,0,0); glVertex2d(-0.75,-0.75);
|
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) {
|
void init_GL(GtkWidget * widget, int screen, int share_num) {
|
||||||
int n;
|
|
||||||
// for (n=gtk_events_pending(); n>0; n--)
|
// for (n=gtk_events_pending(); n>0; n--)
|
||||||
// gtk_main_iteration();
|
// gtk_main_iteration();
|
||||||
// init GL capability
|
// init GL capability
|
||||||
|
@ -166,13 +171,16 @@ int init_GL_free(GtkWidget * widget) {
|
||||||
return r;
|
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 (
|
my_glConfig = gdk_gl_config_new_by_mode (
|
||||||
GDK_GL_MODE_RGBA
|
GDK_GL_MODE_RGBA
|
||||||
| GDK_GL_MODE_DEPTH
|
| GDK_GL_MODE_DEPTH
|
||||||
| GDK_GL_MODE_DOUBLE
|
| GDK_GL_MODE_DOUBLE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
gtk_glade_use_software_colour_convert = use_software_convert;
|
||||||
// initialize 1st drawing area
|
// initialize 1st drawing area
|
||||||
init_GL(pDrawingArea,0,0);
|
init_GL(pDrawingArea,0,0);
|
||||||
my_gl_Clear(0);
|
my_gl_Clear(0);
|
||||||
|
@ -181,30 +189,18 @@ void init_GL_capabilities() {
|
||||||
// generate ONE texture (display)
|
// generate ONE texture (display)
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
glGenTextures(2, Textures);
|
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);
|
my_gl_End(0);
|
||||||
|
|
||||||
// initialize 2nd drawing area (sharing context)
|
// initialize 2nd drawing area (sharing context)
|
||||||
init_GL(pDrawingArea2,1,0);
|
init_GL(pDrawingArea2,1,0);
|
||||||
my_gl_Clear(1);
|
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
|
#undef MyFILTER
|
||||||
}
|
}
|
||||||
|
|
||||||
void my_gl_ScreenTex() {
|
static void
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
|
my_gl_ScreenTex( int software_convert) {
|
||||||
// pause effect
|
if ( software_convert) {
|
||||||
// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
|
u8 converted[256 * 384 * 3];
|
||||||
256, 512, 0, GL_RGBA,
|
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,
|
GL_UNSIGNED_SHORT_1_5_5_5_REV,
|
||||||
// GL_UNSIGNED_SHORT_5_5_5_1,
|
&GPU_screen);
|
||||||
GPU_screen);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void my_gl_ScreenTexApply(int screen) {
|
void my_gl_ScreenTexApply(int screen) {
|
||||||
|
@ -260,7 +271,7 @@ void my_gl_ScreenTexApply(int screen) {
|
||||||
/************************************************/
|
/************************************************/
|
||||||
|
|
||||||
gboolean screen (GtkWidget * widget, int viewportscreen) {
|
gboolean screen (GtkWidget * widget, int viewportscreen) {
|
||||||
int H,W,screen;
|
int screen;
|
||||||
GPU * gpu;
|
GPU * gpu;
|
||||||
float bright_color = 0.0f; // blend with black
|
float bright_color = 0.0f; // blend with black
|
||||||
float bright_alpha = 0.0f; // don't blend
|
float bright_alpha = 0.0f; // don't blend
|
||||||
|
@ -303,7 +314,7 @@ gboolean screen (GtkWidget * widget, int viewportscreen) {
|
||||||
// create the texture for both display
|
// create the texture for both display
|
||||||
my_gl_Texture2D();
|
my_gl_Texture2D();
|
||||||
if (viewportscreen==0) {
|
if (viewportscreen==0) {
|
||||||
my_gl_ScreenTex();
|
my_gl_ScreenTex( gtk_glade_use_software_colour_convert);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// pause
|
// pause
|
||||||
|
@ -333,324 +344,4 @@ gboolean screen (GtkWidget * widget, int viewportscreen) {
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 3D Rendering */
|
#endif /* if GTKGLEXT_AVAILABLE */
|
||||||
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 */
|
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
// comment for GL :D
|
// comment for GL :D
|
||||||
//#undef HAVE_LIBGDKGLEXT_X11_1_0
|
//#undef HAVE_LIBGDKGLEXT_X11_1_0
|
||||||
#ifdef HAVE_LIBGDKGLEXT_X11_1_0
|
#ifdef GTKGLEXT_AVAILABLE
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
#include <GL/glext.h>
|
#include <GL/glext.h>
|
||||||
#include <gdk/gdkgl.h>
|
#include <gdk/gdkgl.h>
|
||||||
|
@ -33,19 +33,12 @@
|
||||||
BOOL my_gl_Begin (int screen);
|
BOOL my_gl_Begin (int screen);
|
||||||
void my_gl_End (int screen);
|
void my_gl_End (int screen);
|
||||||
void my_gl_Clear(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);
|
void init_GL(GtkWidget * widget, int screen, int share_num);
|
||||||
int init_GL_free_s(GtkWidget * widget, int share_num);
|
int init_GL_free_s(GtkWidget * widget, int share_num);
|
||||||
int init_GL_free(GtkWidget * widget);
|
int init_GL_free(GtkWidget * widget);
|
||||||
void register_gl_fun(fun_gl_Begin beg,fun_gl_End end);
|
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);
|
void reshape (GtkWidget * widget, int screen);
|
||||||
gboolean screen (GtkWidget * widget, int off);
|
gboolean screen (GtkWidget * widget, int off);
|
||||||
|
|
|
@ -25,11 +25,19 @@
|
||||||
#include "dTools/callbacks_dtools.h"
|
#include "dTools/callbacks_dtools.h"
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
|
||||||
#ifdef HAVE_LIBGDKGLEXT_X11_1_0
|
#ifdef GTKGLEXT_AVAILABLE
|
||||||
|
#include <gtk/gtkgl.h>
|
||||||
#include "../opengl_collector_3Demu.h"
|
#include "../opengl_collector_3Demu.h"
|
||||||
#include "gdk_3Demu.h"
|
#include "gdk_3Demu.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The frame limiter semaphore
|
||||||
|
*/
|
||||||
|
SDL_sem *glade_fps_limiter_semaphore;
|
||||||
|
int glade_fps_limiter_disabled = 0;
|
||||||
|
|
||||||
|
|
||||||
GtkWidget * pWindow;
|
GtkWidget * pWindow;
|
||||||
GtkWidget * pDrawingArea, * pDrawingArea2;
|
GtkWidget * pDrawingArea, * pDrawingArea2;
|
||||||
GladeXML * xml, * xml_tools;
|
GladeXML * xml, * xml_tools;
|
||||||
|
@ -43,13 +51,98 @@ NULL
|
||||||
|
|
||||||
GPU3DInterface *core3DList[] = {
|
GPU3DInterface *core3DList[] = {
|
||||||
&gpu3DNull
|
&gpu3DNull
|
||||||
#ifdef HAVE_LIBGDKGLEXT_X11_1_0
|
#ifdef GTKGLEXT_AVAILABLE
|
||||||
,
|
,
|
||||||
&gpu3D_opengl_collector
|
&gpu3D_opengl_collector
|
||||||
#endif
|
#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 ***** ***** */
|
/* ***** ***** TOOLS ***** ***** */
|
||||||
|
|
||||||
GList * tools_to_update = NULL;
|
GList * tools_to_update = NULL;
|
||||||
|
@ -220,39 +313,54 @@ void update_savestate(u8 num)
|
||||||
desmume_resume();
|
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 ***** ***** */
|
/* ***** ***** MAIN ***** ***** */
|
||||||
|
|
||||||
#ifdef WIN32
|
static int
|
||||||
int WinMain ()
|
common_gtk_glade_main( struct configured_features *my_config) {
|
||||||
{
|
SDL_TimerID limiter_timer;
|
||||||
main(0,NULL);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
|
|
||||||
const char *commandLine_File = NULL;
|
#ifdef GTKGLEXT_AVAILABLE
|
||||||
gtk_init(&argc, &argv);
|
|
||||||
|
|
||||||
#ifdef HAVE_LIBGDKGLEXT_X11_1_0
|
|
||||||
// check if you have GTHREAD when running configure script
|
// check if you have GTHREAD when running configure script
|
||||||
// g_thread_init(NULL);
|
//g_thread_init(NULL);
|
||||||
gtk_gl_init(&argc, &argv);
|
|
||||||
register_gl_fun(my_gl_Begin,my_gl_End);
|
register_gl_fun(my_gl_Begin,my_gl_End);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(argc == 2) commandLine_File = argv[1];
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
LogStart();
|
LogStart();
|
||||||
#endif
|
#endif
|
||||||
init_keyvals();
|
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",
|
fprintf(stderr, "Error trying to initialize SDL: %s\n",
|
||||||
SDL_GetError());
|
SDL_GetError());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
desmume_init();
|
desmume_init();
|
||||||
/* Initialize joysticks */
|
/* Initialize joysticks */
|
||||||
if(!init_joy()) return 1;
|
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);
|
||||||
glade_xml_signal_autoconnect_StringObject(xml_tools);
|
glade_xml_signal_autoconnect_StringObject(xml_tools);
|
||||||
|
|
||||||
init_GL_capabilities();
|
init_GL_capabilities( my_config->software_colour_convert);
|
||||||
|
|
||||||
/* check command line file */
|
/* check command line file */
|
||||||
if(commandLine_File) {
|
if( my_config->nds_file) {
|
||||||
if(desmume_open(commandLine_File) >= 0) {
|
if(desmume_open( my_config->nds_file) >= 0) {
|
||||||
desmume_resume();
|
desmume_resume();
|
||||||
enable_rom_features();
|
enable_rom_features();
|
||||||
} else {
|
} else {
|
||||||
|
@ -283,7 +391,7 @@ int main(int argc, char *argv[]) {
|
||||||
GTK_DIALOG_MODAL,
|
GTK_DIALOG_MODAL,
|
||||||
GTK_MESSAGE_INFO,
|
GTK_MESSAGE_INFO,
|
||||||
GTK_BUTTONS_OK,
|
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_dialog_run(GTK_DIALOG(pDialog));
|
||||||
gtk_widget_destroy(pDialog);
|
gtk_widget_destroy(pDialog);
|
||||||
}
|
}
|
||||||
|
@ -292,7 +400,11 @@ int main(int argc, char *argv[]) {
|
||||||
gtk_widget_show(pDrawingArea);
|
gtk_widget_show(pDrawingArea);
|
||||||
gtk_widget_show(pDrawingArea2);
|
gtk_widget_show(pDrawingArea2);
|
||||||
|
|
||||||
#ifdef HAVE_LIBGDKGLEXT_X11_1_0
|
{
|
||||||
|
int use_null_3d = my_config->disable_3d;
|
||||||
|
|
||||||
|
#ifdef GTKGLEXT_AVAILABLE
|
||||||
|
if ( !use_null_3d) {
|
||||||
/* setup the gdk 3D emulation */
|
/* setup the gdk 3D emulation */
|
||||||
if ( init_opengl_gdk_3Demu()) {
|
if ( init_opengl_gdk_3Demu()) {
|
||||||
NDS_3D_SetDriver(1);
|
NDS_3D_SetDriver(1);
|
||||||
|
@ -300,20 +412,54 @@ int main(int argc, char *argv[]) {
|
||||||
if (!gpu3D->NDS_3D_Init()) {
|
if (!gpu3D->NDS_3D_Init()) {
|
||||||
fprintf( stderr, "Failed to initialise openGL 3D emulation; "
|
fprintf( stderr, "Failed to initialise openGL 3D emulation; "
|
||||||
"removing 3D support\n");
|
"removing 3D support\n");
|
||||||
|
use_null_3d = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf( stderr, "Failed to setup openGL 3D emulation; "
|
fprintf( stderr, "Failed to setup openGL 3D emulation; "
|
||||||
"removing 3D support\n");
|
"removing 3D support\n");
|
||||||
|
use_null_3d = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if ( use_null_3d) {
|
||||||
|
NDS_3D_SetDriver ( 0);
|
||||||
|
gpu3D->NDS_3D_Init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// on_menu_tileview_activate(NULL,NULL);
|
// 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 */
|
/* start event loop */
|
||||||
gtk_main();
|
gtk_main();
|
||||||
desmume_free();
|
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
|
#ifdef DEBUG
|
||||||
LogStop();
|
LogStop();
|
||||||
#endif
|
#endif
|
||||||
|
@ -325,3 +471,40 @@ int main(int argc, char *argv[]) {
|
||||||
return EXIT_SUCCESS;
|
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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue