Added an experimental shared memory interface to allow for the video window to be a separate process.
This commit is contained in:
parent
6b406e411f
commit
76df04d830
|
@ -13,6 +13,7 @@ source_list = Split(
|
|||
memview.cpp
|
||||
ramwatch.cpp
|
||||
debugger.cpp
|
||||
glxwin.cpp
|
||||
sdl.cpp
|
||||
sdl-joystick.cpp
|
||||
sdl-sound.cpp
|
||||
|
|
|
@ -0,0 +1,330 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glx.h>
|
||||
#include <GL/glu.h>
|
||||
|
||||
#include "glxwin.h"
|
||||
|
||||
static Display *dpy = NULL;
|
||||
static Window root;
|
||||
static GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
|
||||
static XVisualInfo *vi = NULL;
|
||||
static Colormap cmap;
|
||||
static XSetWindowAttributes swa;
|
||||
static Window win;
|
||||
static GLXContext glc;
|
||||
static XWindowAttributes gwa;
|
||||
static XEvent xev;
|
||||
|
||||
static GLuint gltexture = 0;
|
||||
|
||||
glxwin_shm_t *glx_shm = NULL;
|
||||
|
||||
static int screen_width = 512;
|
||||
static int screen_height = 512;
|
||||
//************************************************************************
|
||||
static glxwin_shm_t *open_shm(void)
|
||||
{
|
||||
int shmId;
|
||||
glxwin_shm_t *vaddr;
|
||||
struct shmid_ds ds;
|
||||
|
||||
shmId = shmget( IPC_PRIVATE, sizeof(struct glxwin_shm_t), IPC_CREAT | S_IRWXU | S_IRWXG );
|
||||
|
||||
if ( shmId == -1 )
|
||||
{
|
||||
perror("Error: GLX shmget Failed:");
|
||||
return NULL;
|
||||
}
|
||||
printf("Created ShmID: %i \n", shmId );
|
||||
|
||||
vaddr = (glxwin_shm_t*)shmat( shmId, NULL, 0);
|
||||
|
||||
if ( vaddr == (glxwin_shm_t*)-1 )
|
||||
{
|
||||
perror("Error: GLX shmat Failed:");
|
||||
return NULL;
|
||||
}
|
||||
memset( vaddr, 0, sizeof(struct glxwin_shm_t));
|
||||
|
||||
if ( shmctl( shmId, IPC_RMID, &ds ) != 0 )
|
||||
{
|
||||
perror("Error: GLX shmctl IPC_RMID Failed:");
|
||||
}
|
||||
|
||||
sem_init( &vaddr->sem, 1, 1 );
|
||||
|
||||
return vaddr;
|
||||
}
|
||||
//************************************************************************
|
||||
static void genTextures(void)
|
||||
{
|
||||
int ipolate = 1;
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glGenTextures(1, &gltexture);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, gltexture);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,ipolate?GL_LINEAR:GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,ipolate?GL_LINEAR:GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
|
||||
|
||||
}
|
||||
//************************************************************************
|
||||
static int open_window(void)
|
||||
{
|
||||
|
||||
dpy = XOpenDisplay(NULL);
|
||||
|
||||
if (dpy == NULL) {
|
||||
printf("\n\tcannot connect to X server\n\n");
|
||||
exit(0);
|
||||
}
|
||||
root = DefaultRootWindow(dpy);
|
||||
|
||||
vi = glXChooseVisual(dpy, 0, att);
|
||||
|
||||
if (vi == NULL)
|
||||
{
|
||||
printf("\n\tno appropriate visual found\n\n");
|
||||
exit(0);
|
||||
}
|
||||
else {
|
||||
printf("\n\tvisual %p selected\n", (void *)vi->visualid); /* %p creates hexadecimal output like in glxinfo */
|
||||
}
|
||||
|
||||
cmap = XCreateColormap(dpy, root, vi->visual, AllocNone);
|
||||
|
||||
swa.colormap = cmap;
|
||||
swa.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask;
|
||||
|
||||
win = XCreateWindow(dpy, root, 0, 0, screen_width, screen_height, 0,
|
||||
vi->depth, InputOutput, vi->visual,
|
||||
CWColormap | CWEventMask, &swa);
|
||||
|
||||
XMapWindow(dpy, win);
|
||||
|
||||
XStoreName(dpy, win, "FCEUX VIEWPORT");
|
||||
|
||||
glc = glXCreateContext(dpy, vi, NULL, GL_TRUE);
|
||||
glXMakeCurrent(dpy, win, glc);
|
||||
|
||||
genTextures();
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Background color to black.
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
// In a double buffered setup with page flipping, be sure to clear both buffers.
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
//************************************************************************
|
||||
static void print_pixbuf(void)
|
||||
{
|
||||
for (int x=0; x<256; x++)
|
||||
{
|
||||
for (int y=0; y<256; y++)
|
||||
{
|
||||
printf("(%i,%i) = %08X \n", x, y, glx_shm->pixbuf[x*256+y] );
|
||||
}
|
||||
}
|
||||
}
|
||||
//************************************************************************
|
||||
static void render_image(void)
|
||||
{
|
||||
int l=0, r=GLX_NES_WIDTH;
|
||||
int t=0, b=GLX_NES_HEIGHT;
|
||||
|
||||
float xscale = (float)screen_width / (float)GLX_NES_WIDTH;
|
||||
float yscale = (float)screen_height / (float)GLX_NES_HEIGHT;
|
||||
if (xscale < yscale )
|
||||
{
|
||||
yscale = xscale;
|
||||
}
|
||||
else
|
||||
{
|
||||
xscale = yscale;
|
||||
}
|
||||
int rw=(int)((r-l)*xscale);
|
||||
int rh=(int)((b-t)*yscale);
|
||||
int sx=(screen_width-rw)/2;
|
||||
int sy=(screen_height-rh)/2;
|
||||
|
||||
glXMakeCurrent(dpy, win, glc);
|
||||
//printf("Viewport: (%i,%i) %i %i %i %i \n",
|
||||
// screen_width, screen_height, sx, sy, rw, rh );
|
||||
//glViewport(sx, sy, rw, rh);
|
||||
glViewport( 0, 0, screen_width, screen_height);
|
||||
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glClearColor( 0.0, 0.0f, 0.0f, 0.0f); // Background color to black.
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
//glBindTexture(GL_TEXTURE_2D, gltexture);
|
||||
glBindTexture(GL_TEXTURE_2D, gltexture);
|
||||
|
||||
//print_pixbuf();
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, glx_shm->pixbuf );
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(1.0f*l/256, 1.0f*b/256); // Bottom left of picture.
|
||||
glVertex2f(-1.0f, -1.0f); // Bottom left of target.
|
||||
|
||||
glTexCoord2f(1.0f*r/256, 1.0f*b/256);// Bottom right of picture.
|
||||
glVertex2f( 1.0f, -1.0f); // Bottom right of target.
|
||||
|
||||
glTexCoord2f(1.0f*r/256, 1.0f*t/256); // Top right of our picture.
|
||||
glVertex2f( 1.0f, 1.0f); // Top right of target.
|
||||
|
||||
glTexCoord2f(1.0f*l/256, 1.0f*t/256); // Top left of our picture.
|
||||
glVertex2f(-1.0f, 1.0f); // Top left of target.
|
||||
glEnd();
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
glColor4f( 1.0, 1.0, 1.0, 1.0 );
|
||||
glLineWidth(5.0);
|
||||
glBegin(GL_LINES);
|
||||
glVertex2f(-1.0f, -1.0f); // Bottom left of target.
|
||||
glVertex2f( 1.0f, 1.0f); // Top right of target.
|
||||
glEnd();
|
||||
|
||||
glFlush();
|
||||
|
||||
glXSwapBuffers( dpy, win );
|
||||
}
|
||||
//************************************************************************
|
||||
static int mainWindowLoop(void)
|
||||
{
|
||||
|
||||
while( glx_shm->run )
|
||||
{
|
||||
while ( XPending( dpy ) )
|
||||
{
|
||||
XNextEvent(dpy, &xev);
|
||||
|
||||
if (xev.type == Expose)
|
||||
{
|
||||
XGetWindowAttributes(dpy, win, &gwa);
|
||||
//glViewport(0, 0, gwa.width, gwa.height);
|
||||
//DrawAQuad();
|
||||
glXSwapBuffers(dpy, win);
|
||||
printf("Expose\n");
|
||||
}
|
||||
else if (xev.type == ConfigureNotify)
|
||||
{
|
||||
//XGetWindowAttributes(dpy, win, &gwa);
|
||||
|
||||
screen_width = xev.xconfigure.width;
|
||||
screen_height = xev.xconfigure.height;
|
||||
|
||||
//if (gltexture) {
|
||||
// glDeleteTextures(1, &gltexture);
|
||||
//}
|
||||
//gltexture=0;
|
||||
|
||||
//genTextures();
|
||||
|
||||
printf("Resize Request: (%i,%i)\n", screen_width, screen_height );
|
||||
render_image();
|
||||
//glViewport(0, 0, gwa.width, gwa.height);
|
||||
//DrawAQuad();
|
||||
//glXSwapBuffers(dpy, win);
|
||||
}
|
||||
else if (xev.type == KeyPress)
|
||||
{
|
||||
printf("Key press: %i %08X \n", xev.xkey.keycode, xev.xkey.state );
|
||||
|
||||
}
|
||||
else if (xev.type == DestroyNotify)
|
||||
{
|
||||
printf("DestroyNotify\n");
|
||||
glx_shm->run = 0;
|
||||
//glXMakeCurrent(dpy, None, NULL);
|
||||
//glXDestroyContext(dpy, glc);
|
||||
//XDestroyWindow(dpy, win);
|
||||
//XCloseDisplay(dpy);
|
||||
//exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
if ( glx_shm->blit_count != glx_shm->render_count )
|
||||
{
|
||||
render_image();
|
||||
glx_shm->render_count++;
|
||||
}
|
||||
|
||||
usleep(10000);
|
||||
}
|
||||
|
||||
glXMakeCurrent(dpy, None, NULL);
|
||||
glXDestroyContext(dpy, glc);
|
||||
XDestroyWindow(dpy, win);
|
||||
XCloseDisplay(dpy);
|
||||
exit(0);
|
||||
return 0;
|
||||
}
|
||||
//************************************************************************
|
||||
int spawn_glxwin( int flags )
|
||||
{
|
||||
int pid;
|
||||
|
||||
glx_shm = open_shm();
|
||||
|
||||
pid = fork();
|
||||
|
||||
if ( pid == 0 )
|
||||
{
|
||||
// Child Process
|
||||
glx_shm->run = 1;
|
||||
glx_shm->pid = getpid();
|
||||
|
||||
printf("Child Process Running: %i\n", glx_shm->pid );
|
||||
|
||||
open_window();
|
||||
|
||||
mainWindowLoop();
|
||||
|
||||
exit(0);
|
||||
}
|
||||
else if ( pid > 0 )
|
||||
{ // Parent Process
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Error
|
||||
printf("Error: Failed to Fork GLX Window Process\n");
|
||||
}
|
||||
|
||||
return pid;
|
||||
}
|
||||
//************************************************************************
|
||||
|
||||
//************************************************************************
|
|
@ -0,0 +1,59 @@
|
|||
// glxwin.cpp
|
||||
//
|
||||
|
||||
#ifndef __GLXWIN_H__
|
||||
#define __GLXWIN_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <semaphore.h>
|
||||
|
||||
int spawn_glxwin( int flags );
|
||||
|
||||
#define GLX_NES_WIDTH 256
|
||||
#define GLX_NES_HEIGHT 256
|
||||
|
||||
struct glxwin_shm_t
|
||||
{
|
||||
int pid;
|
||||
int run;
|
||||
uint32_t render_count;
|
||||
uint32_t blit_count;
|
||||
sem_t sem;
|
||||
|
||||
// Pass Key Events back to GTK Gui
|
||||
struct
|
||||
{
|
||||
int head;
|
||||
int tail;
|
||||
|
||||
struct {
|
||||
int type;
|
||||
int keycode;
|
||||
int state;
|
||||
} data[64];
|
||||
|
||||
} keyEventBuf;
|
||||
|
||||
// Gui Command Event Queue
|
||||
struct
|
||||
{
|
||||
int head;
|
||||
int tail;
|
||||
|
||||
struct {
|
||||
int id;
|
||||
|
||||
union {
|
||||
int i32[4];
|
||||
float f32[4];
|
||||
} param;
|
||||
} cmd[64];
|
||||
} guiEvent;
|
||||
|
||||
uint32_t pixbuf[65536]; // 256 x 256
|
||||
};
|
||||
|
||||
extern glxwin_shm_t *glx_shm;
|
||||
|
||||
#endif
|
|
@ -34,11 +34,23 @@
|
|||
#include <gdk/gdkkeysyms-compat.h>
|
||||
#endif
|
||||
|
||||
#ifdef APPLEOPENGL
|
||||
#include <OpenGL/gl.h>
|
||||
#include <OpenGL/glu.h>
|
||||
#include <OpenGL/glext.h>
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <GL/glext.h>
|
||||
#endif
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <list>
|
||||
|
||||
#include "glxwin.h"
|
||||
|
||||
// Fix compliation errors for older version of GTK (Ubuntu 10.04 LTS)
|
||||
#if GTK_MINOR_VERSION < 24 && GTK_MAJOR_VERSION == 2
|
||||
#define GTK_COMBO_BOX_TEXT GTK_COMBO_BOX
|
||||
|
@ -66,6 +78,9 @@ static GtkRadioMenuItem *stateSlot[10] = { NULL };
|
|||
bool gtkIsStarted = false;
|
||||
bool menuTogglingEnabled = false;
|
||||
|
||||
static int drawAreaGL = 0;
|
||||
static GLuint gltexture = 0;
|
||||
static uint32_t *drawAreaGLpixBuf = NULL;
|
||||
unsigned int gtk_draw_area_width = NES_WIDTH;
|
||||
unsigned int gtk_draw_area_height = NES_HEIGHT;
|
||||
static unsigned int gtk_win_width = 0;
|
||||
|
@ -3085,6 +3100,15 @@ gint handleMouseClick (GtkWidget * widget, GdkEvent * event,
|
|||
|
||||
uint32_t *getGuiPixelBuffer( int *w, int *h, int *s )
|
||||
{
|
||||
if ( drawAreaGL )
|
||||
{
|
||||
if ( w ) *w = 256;
|
||||
if ( h ) *h = 256;
|
||||
if ( s ) *s = 256*4;
|
||||
|
||||
//return NULL;
|
||||
return glx_shm->pixbuf;
|
||||
}
|
||||
|
||||
if ( cairo_surface == NULL )
|
||||
{
|
||||
|
@ -3114,6 +3138,13 @@ uint32_t *getGuiPixelBuffer( int *w, int *h, int *s )
|
|||
|
||||
int guiPixelBufferReDraw(void)
|
||||
{
|
||||
glx_shm->blit_count++;
|
||||
|
||||
if ( drawAreaGL )
|
||||
{
|
||||
gtk_gl_area_queue_render( (GtkGLArea*)evbox);
|
||||
return 0;
|
||||
}
|
||||
if ( cairo_surface != NULL )
|
||||
{
|
||||
cairo_surface_mark_dirty( cairo_surface );
|
||||
|
@ -3148,20 +3179,30 @@ int guiClearSurface(void)
|
|||
|
||||
static void setPixels(void)
|
||||
{
|
||||
int32_t *p;
|
||||
uint32_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);
|
||||
if ( drawAreaGL )
|
||||
{
|
||||
width = 256;
|
||||
height = 256;
|
||||
//p = (uint32_t*)drawAreaGLpixBuf;
|
||||
p = (uint32_t*)glx_shm->pixbuf;
|
||||
}
|
||||
else
|
||||
{
|
||||
width = cairo_image_surface_get_width (cairo_surface);
|
||||
height = cairo_image_surface_get_height (cairo_surface);
|
||||
|
||||
cairo_surface_flush( cairo_surface );
|
||||
cairo_surface_flush( cairo_surface );
|
||||
|
||||
p = (int32_t*)cairo_image_surface_get_data (cairo_surface);
|
||||
p = (uint32_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 );
|
||||
//printf("W:%i H:%i W/2:%i H/2:%i\n", width, height, w2, h2 );
|
||||
|
||||
i=0;
|
||||
for (y=0; y<height; y++)
|
||||
|
@ -3193,9 +3234,16 @@ static void setPixels(void)
|
|||
i++;
|
||||
}
|
||||
}
|
||||
cairo_surface_mark_dirty( cairo_surface );
|
||||
//cairo_surface_mark_dirty( cairo_surface );
|
||||
|
||||
gtk_widget_queue_draw( evbox );
|
||||
if ( drawAreaGL )
|
||||
{
|
||||
gtk_gl_area_queue_render( (GtkGLArea*)evbox);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_queue_draw( evbox );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -3294,6 +3342,209 @@ gboolean handle_resize (GtkWindow * win, GdkEvent * event, gpointer data)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
glwin_resize (GtkGLArea *area,
|
||||
gint width,
|
||||
gint height,
|
||||
gpointer user_data)
|
||||
{
|
||||
//char sizeChange = 0;
|
||||
//printf("GL Resize: %ix%i \n", width, height );
|
||||
|
||||
//sizeChange = (width != gtk_draw_area_width) || (height != gtk_draw_area_height);
|
||||
|
||||
//if ( sizeChange )
|
||||
//{
|
||||
// if ( drawAreaGLpixBuf != NULL)
|
||||
// {
|
||||
// free( drawAreaGLpixBuf ); drawAreaGLpixBuf = NULL;
|
||||
// }
|
||||
//}
|
||||
gtk_draw_area_width = width;
|
||||
gtk_draw_area_height = height;
|
||||
|
||||
if ( drawAreaGLpixBuf == NULL )
|
||||
{
|
||||
int bufSize;
|
||||
|
||||
bufSize = 256 * 256 * sizeof(uint32_t);
|
||||
|
||||
drawAreaGLpixBuf = (uint32_t*)malloc ( bufSize );
|
||||
|
||||
if ( drawAreaGLpixBuf )
|
||||
{
|
||||
memset( drawAreaGLpixBuf, 0, bufSize );
|
||||
}
|
||||
}
|
||||
glViewport(0, 0, gtk_draw_area_width, gtk_draw_area_height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
glwin_render (GtkGLArea *area,
|
||||
GdkGLContext *context,
|
||||
gpointer user_data)
|
||||
{
|
||||
int l=0, r=256;
|
||||
int t=0, b=256;
|
||||
|
||||
float xscale = 1.0;
|
||||
float yscale = 1.0;
|
||||
int rw=(int)((r-l)*xscale);
|
||||
int rh=(int)((b-t)*yscale);
|
||||
int sx=(gtk_draw_area_width-rw)/2; // Start x
|
||||
int sy=(gtk_draw_area_height-rh)/2; // Start y
|
||||
static float red = 1.0;
|
||||
static int dir = 0;
|
||||
|
||||
if ( dir )
|
||||
{
|
||||
red += 0.01;
|
||||
if ( red > 1.0 )
|
||||
{
|
||||
red = 1.0; dir = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
red -= 0.01;
|
||||
if ( red < 0.0 )
|
||||
{
|
||||
red = 0.0; dir = 1;
|
||||
}
|
||||
}
|
||||
//if(stretchx) { sx=0; rw=screen->w; }
|
||||
//if(stretchy) { sy=0; rh=screen->h; }
|
||||
//glViewport(sx, sy, rw, rh);
|
||||
//glViewport(0, 0, gtk_draw_area_width, gtk_draw_area_height);
|
||||
|
||||
//glLoadIdentity();
|
||||
//glPushMatrix();
|
||||
//glLoadIdentity();
|
||||
//glMatrixMode(GL_MODELVIEW);
|
||||
//glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
|
||||
|
||||
//printf("GL Render!\n");
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glClearColor( red, 0.0f, 0.0f, 0.0f); // Background color to black.
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
//glEnable(GL_TEXTURE_2D);
|
||||
//glBindTexture(GL_TEXTURE_2D, gltexture);
|
||||
glBindTexture(GL_TEXTURE_2D, gltexture);
|
||||
|
||||
|
||||
//setPixels();
|
||||
|
||||
//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0,
|
||||
// GL_RGBA, GL_UNSIGNED_BYTE, drawAreaGLpixBuf );
|
||||
|
||||
//glBegin(GL_QUADS);
|
||||
//glTexCoord2f(1.0f*l/256, 1.0f*b/256); // Bottom left of picture.
|
||||
//glVertex2f(-1.0f, -1.0f); // Bottom left of target.
|
||||
|
||||
//glTexCoord2f(1.0f*r/256, 1.0f*b/256);// Bottom right of picture.
|
||||
//glVertex2f( 1.0f, -1.0f); // Bottom right of target.
|
||||
|
||||
//glTexCoord2f(1.0f*r/256, 1.0f*t/256); // Top right of our picture.
|
||||
//glVertex2f( 1.0f, 1.0f); // Top right of target.
|
||||
|
||||
//glTexCoord2f(1.0f*l/256, 1.0f*t/256); // Top left of our picture.
|
||||
//glVertex2f(-1.0f, 1.0f); // Top left of target.
|
||||
//glEnd();
|
||||
|
||||
//glPushMatrix();
|
||||
|
||||
//glColor4f( 1.0, 1.0, 1.0, 1.0 );
|
||||
//glLineWidth(5.0);
|
||||
//glBegin(GL_LINES);
|
||||
//glVertex2f(-1.0f, -1.0f); // Bottom left of target.
|
||||
//glVertex2f( 1.0f, 1.0f); // Top right of target.
|
||||
//glEnd();
|
||||
|
||||
//glPopMatrix();
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
glFlush();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
glwin_realize (GtkGLArea *area)
|
||||
{
|
||||
int ipolate = 0;
|
||||
gboolean has_alpha;
|
||||
|
||||
printf("GL Realize!\n");
|
||||
// We need to make the context current if we want to
|
||||
// call GL API
|
||||
gtk_gl_area_make_current (area);
|
||||
|
||||
// If there were errors during the initialization or
|
||||
// when trying to make the context current, this
|
||||
// function will return a #GError for you to catch
|
||||
if (gtk_gl_area_get_error (area) != NULL)
|
||||
{
|
||||
printf("GL Realize Error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ( drawAreaGLpixBuf == NULL )
|
||||
{
|
||||
int bufSize;
|
||||
|
||||
bufSize = 256 * 256 * sizeof(uint32_t);
|
||||
|
||||
drawAreaGLpixBuf = (uint32_t*)malloc ( bufSize );
|
||||
|
||||
if ( drawAreaGLpixBuf )
|
||||
{
|
||||
memset( drawAreaGLpixBuf, 0, bufSize );
|
||||
}
|
||||
}
|
||||
|
||||
has_alpha = gtk_gl_area_get_has_alpha( area );
|
||||
|
||||
printf("Has Alpha: %i \n", has_alpha );
|
||||
|
||||
if ( has_alpha )
|
||||
{
|
||||
gtk_gl_area_set_has_alpha( area, 0 );
|
||||
}
|
||||
// Enable depth buffer:
|
||||
gtk_gl_area_set_has_depth_buffer(area, TRUE);
|
||||
|
||||
has_alpha = gtk_gl_area_get_has_alpha( area );
|
||||
|
||||
printf("Has Alpha: %i \n", has_alpha );
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glGenTextures(1, &gltexture);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, gltexture);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,ipolate?GL_LINEAR:GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,ipolate?GL_LINEAR:GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glClearColor(1.0f, 0.0f, 0.0f, 0.0f); // Background color to black.
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
// In a double buffered setup with page flipping, be sure to clear both buffers.
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
}
|
||||
|
||||
/* Redraw the screen from the surface. Note that the ::draw
|
||||
* signal receives a ready-to-be-used cairo_t that is already
|
||||
* clipped to only draw the exposed areas of the widget
|
||||
|
@ -3335,6 +3586,8 @@ static gboolean draw_cb (GtkWidget * widget, cairo_t * cr, gpointer data)
|
|||
|
||||
int InitGTKSubsystem (int argc, char **argv)
|
||||
{
|
||||
|
||||
int s_useOpenGL=0;
|
||||
GtkWidget *vbox;
|
||||
|
||||
MainWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
|
@ -3367,8 +3620,22 @@ int InitGTKSubsystem (int argc, char **argv)
|
|||
//
|
||||
// prg - Bryan Cain, you are the man!
|
||||
|
||||
//evbox = gtk_event_box_new();
|
||||
evbox = gtk_drawing_area_new ();
|
||||
#ifdef OPENGL
|
||||
g_config->getOption("SDL.OpenGL", &s_useOpenGL);
|
||||
#endif
|
||||
|
||||
drawAreaGL = s_useOpenGL;
|
||||
|
||||
if ( drawAreaGL )
|
||||
{
|
||||
evbox = gtk_gl_area_new ();
|
||||
gtk_gl_area_set_has_alpha( GTK_GL_AREA(evbox), TRUE);
|
||||
gtk_gl_area_set_has_depth_buffer( GTK_GL_AREA(evbox), TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
evbox = gtk_drawing_area_new ();
|
||||
}
|
||||
gtk_box_pack_start (GTK_BOX (vbox), evbox, TRUE, TRUE, 0);
|
||||
|
||||
double xscale, yscale;
|
||||
|
@ -3394,9 +3661,19 @@ 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 (evbox, "configure-event",
|
||||
G_CALLBACK (handle_resize), NULL);
|
||||
g_signal_connect (evbox, "draw", G_CALLBACK (draw_cb), NULL);
|
||||
if ( s_useOpenGL )
|
||||
{
|
||||
g_signal_connect (evbox, "resize" , G_CALLBACK (glwin_resize ), NULL);
|
||||
g_signal_connect (evbox, "realize", G_CALLBACK (glwin_realize), NULL);
|
||||
g_signal_connect (evbox, "render" , G_CALLBACK (glwin_render ), NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_signal_connect (evbox, "configure-event",
|
||||
G_CALLBACK (handle_resize), NULL);
|
||||
|
||||
g_signal_connect (evbox, "draw", G_CALLBACK (draw_cb), NULL);
|
||||
}
|
||||
|
||||
gtk_widget_set_size_request (evbox, NES_WIDTH * xscale,
|
||||
NES_HEIGHT * yscale);
|
||||
|
|
|
@ -252,8 +252,8 @@ int InitVideo(FCEUGI *gi)
|
|||
g_config->getOption("SDL.YScale", &s_eys);
|
||||
uint32_t rmask, gmask, bmask;
|
||||
|
||||
//s_exs = 1.0;
|
||||
//s_eys = 1.0;
|
||||
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
|
||||
|
@ -277,12 +277,12 @@ int InitVideo(FCEUGI *gi)
|
|||
FCEUI_SetShowFPS(show_fps);
|
||||
|
||||
#ifdef LSB_FIRST
|
||||
//rmask = 0x000000FF;
|
||||
//gmask = 0x0000FF00;
|
||||
//bmask = 0x00FF0000;
|
||||
rmask = 0x00FF0000;
|
||||
rmask = 0x000000FF;
|
||||
gmask = 0x0000FF00;
|
||||
bmask = 0x000000FF;
|
||||
bmask = 0x00FF0000;
|
||||
//rmask = 0x00FF0000;
|
||||
//gmask = 0x0000FF00;
|
||||
//bmask = 0x000000FF;
|
||||
#else
|
||||
rmask = 0x00FF0000;
|
||||
gmask = 0x0000FF00;
|
||||
|
@ -866,11 +866,11 @@ FCEUD_GetPalette(uint8 index,
|
|||
*/
|
||||
static void RedoPalette()
|
||||
{
|
||||
#ifdef OPENGL
|
||||
if(s_useOpenGL)
|
||||
SetOpenGLPalette((uint8*)s_psdl);
|
||||
else
|
||||
#endif
|
||||
//#ifdef OPENGL
|
||||
// if(s_useOpenGL)
|
||||
// SetOpenGLPalette((uint8*)s_psdl);
|
||||
// else
|
||||
//#endif
|
||||
{
|
||||
if(s_curbpp > 8) {
|
||||
SetPaletteBlitToHigh((uint8*)s_psdl);
|
||||
|
@ -913,13 +913,13 @@ BlitScreen(uint8 *XBuf)
|
|||
s_paletterefresh = 0;
|
||||
}
|
||||
|
||||
#ifdef OPENGL
|
||||
// OpenGL is handled separately
|
||||
if(s_useOpenGL) {
|
||||
BlitOpenGL(XBuf);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
//#ifdef OPENGL
|
||||
// // OpenGL is handled separately
|
||||
// if(s_useOpenGL) {
|
||||
// BlitOpenGL(XBuf);
|
||||
// return;
|
||||
// }
|
||||
//#endif
|
||||
|
||||
// XXX soules - not entirely sure why this is being done yet
|
||||
XBuf += s_srendline * 256;
|
||||
|
@ -956,7 +956,7 @@ BlitScreen(uint8 *XBuf)
|
|||
// XXX soules - again, I'm surprised SDL can't handle this
|
||||
// perform the blit, converting bpp if necessary
|
||||
if(s_curbpp > 8) {
|
||||
if(s_BlitBuf) {
|
||||
if(s_useOpenGL) {
|
||||
Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines,
|
||||
pitch, 1, 1);
|
||||
} else {
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "sdl.h"
|
||||
#include "sdl-video.h"
|
||||
#include "unix-netplay.h"
|
||||
#include "glxwin.h"
|
||||
|
||||
#include "../common/configSys.h"
|
||||
#include "../../oldmovie.h"
|
||||
|
@ -857,6 +858,7 @@ int main(int argc, char *argv[])
|
|||
#ifdef _GTK
|
||||
if(noGui == 0)
|
||||
{
|
||||
int glxwin_pid = spawn_glxwin(0);
|
||||
gtk_init(&argc, &argv);
|
||||
InitGTKSubsystem(argc, argv);
|
||||
while(gtk_events_pending())
|
||||
|
|
Loading…
Reference in New Issue