Move the windows/cocoa OGLRender to the emu core and replace ogl_collector. Now every platform shares the same 3d code. I fixed GTK to use it, but I may have broken cocoa.

This commit is contained in:
zeromus 2008-09-14 05:21:06 +00:00
parent c0b228007b
commit 649a4c49ac
10 changed files with 120 additions and 118 deletions

View File

@ -11,9 +11,8 @@
- Make matrix 4x4 multiply routines use W-coordinate. [zeromus]
- Add many matrix and vector functions to matrix.c [zeromus]
- Convert to c++!
- Added gfx3d module which emulates the whole GE as part of the core emu.
This is step 1 of making every platform share the same 3d code.
Step 2 will be to bring down the windows/cocoa OGLRenderer and make it act as the ogl_collector did. [zeromus]
- Added gfx3d module which emulates the whole GE as part of the core emu. Moved the windows/cocoa OGLRender to the
emu core and replace ogl_collector. Now every platform shares the same 3d code. [zeromus]
Mac OS X port:
- Fixed: Filenames and paths with unicode characters now work. [Jeff]
- Fixed: Load state from file button works again. [Jeff]

View File

@ -17,6 +17,7 @@ libdesmume_a_SOURCES = \
mem.h mc.cpp mc.h \
wifi.cpp wifi.h \
MMU.cpp MMU.h NDSSystem.cpp NDSSystem.h registers.h \
OGLRender.cpp OGLRender.h \
ROMReader.cpp ROMReader.h \
render3D.cpp render3D.h \
saves.cpp saves.h \

View File

@ -29,33 +29,49 @@
#include <string.h>
#include <assert.h>
#ifndef DESMUME_OBJ_C
bool (*oglrender_init)() = 0;
bool (*oglrender_beginOpenGL)() = 0;
void (*oglrender_endOpenGL)() = 0;
bool BEGINGL() {
if(oglrender_beginOpenGL)
return oglrender_beginOpenGL();
else return true;
}
void ENDGL() {
if(oglrender_endOpenGL)
oglrender_endOpenGL();
}
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <gl/gl.h>
#include <gl/glext.h>
#include "console.h"
#else
#define __forceinline
#include <GL/gl.h>
#include <GL/glext.h>
#elif DESMUME_OBJ_C
#include <OpenGL/gl.h>
#include <OpenGL/glext.h>
#else
#include <GL/gl.h>
#include <GL/glext.h>
#endif
#include "../types.h"
#include "../debug.h"
#include "../MMU.h"
#include "../bits.h"
#include "../matrix.h"
#include "../NDSSystem.h"
#include "types.h"
#include "debug.h"
#include "MMU.h"
#include "bits.h"
#include "matrix.h"
#include "NDSSystem.h"
#include "OGLRender.h"
#include "../gfx3d.h"
#include "gfx3d.h"
#ifndef CTASSERT
#define CTASSERT(x) typedef char __assert ## y[(x) ? 1 : -1]
#endif
static __declspec(align(16)) unsigned char GPU_screen3D [256*256*4]={0};
static __declspec(align(16)) unsigned char GPU_screenStencil[256*256]={0};
static ALIGN(16) unsigned char GPU_screen3D [256*256*4]={0};
static ALIGN(16) unsigned char GPU_screenStencil[256*256]={0};
static const unsigned short map3d_cull[4] = {GL_FRONT_AND_BACK, GL_FRONT, GL_BACK, 0};
static const int texEnv[4] = { GL_MODULATE, GL_DECAL, GL_MODULATE, GL_MODULATE };
@ -64,8 +80,6 @@ static const int depthFunc[2] = { GL_LESS, GL_EQUAL };
static bool needRefreshFramebuffer = false;
static unsigned short matrixMode[2] = {GL_PROJECTION, GL_MODELVIEW};
@ -89,9 +103,9 @@ static unsigned int lightMask=0;
//------------------------------------------------------------
#ifndef DESMUME_OBJ_C
#ifdef _WIN32
#define OGLEXT(x,y) x y;
#define OGLEXT(x,y) x y = 0;
#define INITOGLEXT(x,y) y = (x)wglGetProcAddress(#y);
OGLEXT(PFNGLCREATESHADERPROC,glCreateShader)
@ -107,7 +121,7 @@ OGLEXT(PFNGLGETSHADERINFOLOGPROC,glGetShaderInfoLog)
#else
#define INITOGLEXT(x,y)
#define INITOGLEXT(x,y) y = 0;
#endif
@ -133,10 +147,15 @@ void xglPolygonMode(GLenum face,GLenum mode) {
}
void xglUseProgram(GLuint program) {
#ifdef _WIN32
if(!glUseProgram) return;
static GLuint oldprogram = -1;
if(oldprogram==program) return;
glUseProgram(oldprogram=program);
#else
(void)program;
return;
#endif
}
void xglDepthMask (GLboolean flag) {
@ -216,28 +235,6 @@ u32 toonShader, toonProgram;
//=================================================
#ifndef DESMUME_OBJ_C
extern HWND hwnd;
int CheckHardwareSupport(HDC hdc)
{
int PixelFormat = GetPixelFormat(hdc);
PIXELFORMATDESCRIPTOR pfd;
DescribePixelFormat(hdc,PixelFormat,sizeof(PIXELFORMATDESCRIPTOR),&pfd);
if ((pfd.dwFlags & PFD_GENERIC_FORMAT) && !(pfd.dwFlags & PFD_GENERIC_ACCELERATED))
return 0; // Software acceleration OpenGL
else if ((pfd.dwFlags & PFD_GENERIC_FORMAT) && (pfd.dwFlags & PFD_GENERIC_ACCELERATED))
return 1; // Half hardware acceleration OpenGL (MCD driver)
else if ( !(pfd.dwFlags & PFD_GENERIC_FORMAT) && !(pfd.dwFlags & PFD_GENERIC_ACCELERATED))
return 2; // Full hardware acceleration OpenGL
return -1; // check error
}
#endif
static void Reset()
{
int i;
@ -252,48 +249,14 @@ static void Reset()
static char Init(void)
{
int i;
#ifndef DESMUME_OBJ_C
HDC oglDC = NULL;
HGLRC hRC = NULL;
int pixelFormat;
PIXELFORMATDESCRIPTOR pfd;
int res;
char *opengl_modes[3]={"software","half hardware (MCD driver)","hardware"};
oglDC = GetDC (hwnd);
memset(&pfd,0, sizeof(PIXELFORMATDESCRIPTOR));
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 24;
pfd.cAlphaBits = 8;
pfd.cStencilBits = 8;
pfd.iLayerType = PFD_MAIN_PLANE ;
pixelFormat = ChoosePixelFormat(oglDC, &pfd);
if (pixelFormat == 0)
if(!oglrender_init)
return 0;
if(!oglrender_init())
return 0;
if(!SetPixelFormat(oglDC, pixelFormat, &pfd))
if(!BEGINGL())
return 0;
hRC = wglCreateContext(oglDC);
if (!hRC)
return 0;
if(!wglMakeCurrent(oglDC, hRC))
return 0;
res=CheckHardwareSupport(oglDC);
if (res>=0&&res<=2)
printlog("OpenGL mode: %s\n",opengl_modes[res]);
else
printlog("OpenGL mode: uknown\n");
#endif
glClearColor (0.f, 0.f, 0.f, 1.f);
glPixelStorei(GL_PACK_ALIGNMENT,8);
@ -311,6 +274,7 @@ static char Init(void)
if (glGetError() != GL_NO_ERROR)
return 0;
#ifdef _WIN32
INITOGLEXT(PFNGLCREATESHADERPROC,glCreateShader)
INITOGLEXT(X_PFNGLGETSHADERSOURCEPROC,glShaderSource)
INITOGLEXT(PFNGLCOMPILESHADERPROC,glCompileShader)
@ -356,6 +320,9 @@ static char Init(void)
toonShader = 0;
}
}
#endif
ENDGL();
return 1;
}
@ -389,8 +356,8 @@ void Close()
//I think this is slower than the regular memcmp.. doesnt make sense to me, but my
//asm optimization knowlege is 15 years old..
#ifndef WORDS_BIGENDIAN
__forceinline int memcmp_slow(const void* src, const void* dst, u32 count) {
#ifdef _MSC_VER
int memcmp_slow(const void* src, const void* dst, u32 count) {
int retval;
__asm {
mov [retval], 0;
@ -404,7 +371,7 @@ __forceinline int memcmp_slow(const void* src, const void* dst, u32 count) {
return retval;
}
__forceinline void* memcpy_fast(void* dest, const void* src, size_t count)
void* memcpy_fast(void* dest, const void* src, size_t count)
{
size_t blockCnt = count / 64;
size_t remainder = count % 64;
@ -925,11 +892,13 @@ static void BeginRenderPoly()
}
//handle toon rendering
#ifdef _WIN32
if(glUseProgram) {
if(envMode == 2) {
xglUseProgram(toonProgram);
} else xglUseProgram(0);
}
#endif
xglDepthMask(enableDepthWrite?GL_TRUE:GL_FALSE);
}
@ -984,6 +953,8 @@ static void Control()
static void Render()
{
if(!BEGINGL()) return;
Control();
xglDepthMask (GL_TRUE);
@ -1038,6 +1009,8 @@ static void Render()
//since we just redrew, we need to refresh the framebuffers
needRefreshFramebuffer = true;
ENDGL();
}
static void VramReconfigureSignal()
@ -1050,9 +1023,11 @@ static void VramReconfigureSignal()
void GL_ReadFramebuffer()
{
if(!BEGINGL()) return;
glFinish();
glReadPixels(0,0,256,192,GL_RGBA, GL_UNSIGNED_BYTE, GPU_screen3D);
glReadPixels(0,0,256,192,GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, GPU_screenStencil);
ENDGL();
//debug: view depth buffer via color buffer for debugging
//int ctr=0;
@ -1143,6 +1118,4 @@ GPU3DInterface gpu3Dgl = {
};
//http://www.opengl.org/documentation/specs/version1.1/glspec1.1/node17.html
//talks about the state required to process verts in quadlists etc. helpful ideas.
//consider building a little state structure that looks exactly like this describes

View File

@ -22,10 +22,20 @@
#ifndef OGLRENDER_H
#define OGLRENDER_H
#include "../render3D.h"
#define GPU3D_OPENGL 1
#include "render3D.h"
extern GPU3DInterface gpu3Dgl;
//This is called by OGLRender whenever it initializes.
//Platforms, please be sure to set this up.
//return true if you successfully init.
extern bool (*oglrender_init)();
//This is called by OGLRender before it uses opengl.
//return true if youre OK with using opengl
extern bool (*oglrender_beginOpenGL)();
//This is called by OGLRender after it is done using opengl.
extern void (*oglrender_endOpenGL)();
#endif

View File

@ -539,17 +539,17 @@ u32 armcpu_exec()
u32 c = 1;
#ifdef GDB_STUB
if ( armcpu->stalled)
if (ARMPROC.stalled)
return STALLED_CYCLE_COUNT;
/* check for interrupts */
if ( armcpu->irq_flag) {
armcpu_irqExeption( armcpu);
if ( ARMPROC.irq_flag) {
armcpu_irqExeption( &ARMPROC);
}
c = armcpu_prefetch(armcpu);
c = armcpu_prefetch(&ARMPROC);
if ( armcpu->stalled) {
if ( ARMPROC.stalled) {
return c;
}
#endif
@ -566,10 +566,10 @@ u32 armcpu_exec()
}
#ifdef GDB_STUB
if ( armcpu->post_ex_fn != NULL) {
if ( ARMPROC.post_ex_fn != NULL) {
/* call the external post execute function */
armcpu->post_ex_fn( armcpu->post_ex_fn_data,
armcpu->instruct_adr, 0);
ARMPROC.post_ex_fn( ARMPROC.post_ex_fn_data,
ARMPROC.instruct_adr, 0);
}
#else
c += armcpu_prefetch<PROCNUM>();
@ -583,9 +583,9 @@ u32 armcpu_exec()
c += thumb_instructions_set_1[ARMPROC.instruction>>6]();
#ifdef GDB_STUB
if ( armcpu->post_ex_fn != NULL) {
if ( ARMPROC.post_ex_fn != NULL) {
/* call the external post execute function */
armcpu->post_ex_fn( armcpu->post_ex_fn_data, armcpu->instruct_adr, 1);
ARMPROC.post_ex_fn( ARMPROC.post_ex_fn_data, ARMPROC.instruct_adr, 1);
}
#else
c += armcpu_prefetch<PROCNUM>();

View File

@ -1470,3 +1470,7 @@ void gfx3d_glGetLightColor(unsigned int index, unsigned int* dest)
*dest = g_lightInfo[index].color;
}
//http://www.opengl.org/documentation/specs/version1.1/glspec1.1/node17.html
//talks about the state required to process verts in quadlists etc. helpful ideas.
//consider building a little state structure that looks exactly like this describes

View File

@ -25,7 +25,7 @@
#include "../types.h"
#include "../render3D.h"
#include "../opengl_collector_3Demu.h"
#include "../OGLRender.h"
#include "gdk_3Demu.h"
/*
@ -122,8 +122,8 @@ examine_gl_config_attrib (GdkGLConfig *glconfig)
}
static int
begin_opengl_region_gdk_3d( void) {
static bool
_oglrender_beginOpenGL( void) {
if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext)) {
return 0;
@ -133,14 +133,14 @@ begin_opengl_region_gdk_3d( void) {
}
static void
end_opengl_region_gdk_3d( void) {
_oglrender_endOpenGL( void) {
gdk_gl_drawable_gl_end (gldrawable);
}
static int
initialise_gdk_3d( void) {
static bool
_oglrender_init( void) {
/* this does nothing */
return 1;
return true;
}
int
@ -188,9 +188,10 @@ init_opengl_gdk_3Demu( void) {
return 0;
}
begin_opengl_ogl_collector_platform = begin_opengl_region_gdk_3d;
end_opengl_ogl_collector_platform = end_opengl_region_gdk_3d;
initialise_ogl_collector_platform = initialise_gdk_3d;
oglrender_init = _oglrender_init;
oglrender_beginOpenGL = _oglrender_beginOpenGL;
oglrender_endOpenGL = _oglrender_endOpenGL;
return 1;

View File

@ -30,7 +30,7 @@
#include "../gdbstub.h"
#ifdef GTKGLEXT_AVAILABLE
#include "../opengl_collector_3Demu.h"
#include "../OGLRender.h"
#include "gdk_3Demu.h"
#endif
@ -91,7 +91,7 @@ GPU3DInterface *core3DList[] = {
&gpu3DNull
#ifdef GTKGLEXT_AVAILABLE
,
&gpu3D_opengl_collector
&gpu3Dgl
#endif
};
@ -2124,4 +2124,3 @@ int WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgumen
}
#endif

View File

@ -140,7 +140,7 @@
EnableFiberSafeOptimizations="true"
WholeProgramOptimization="true"
AdditionalIncludeDirectories="..;.\zlib123;.\zziplib"
PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;VERSION=\&quot;0.8.0b2\&quot;;WIN32;HAVE_LIBZ;HAVE_LIBZZIP;BETA_VERSION"
PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;VERSION=\&quot;0.8.0b2\&quot;;WIN32;HAVE_LIBZ;HAVE_LIBZZIP;BETA_VERSION;GDB_STUB"
StringPooling="true"
ExceptionHandling="0"
BufferSecurityCheck="false"
@ -228,7 +228,7 @@
EnableFiberSafeOptimizations="true"
WholeProgramOptimization="true"
AdditionalIncludeDirectories="..;.\zlib123;.\zziplib"
PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;VERSION=\&quot;0.8.0b2 SSE2\&quot;;WIN32;HAVE_LIBZ;HAVE_LIBZZIP;SSE2;BETA_VERSION"
PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;VERSION=\&quot;0.8.0b2 SSE2\&quot;;WIN32;HAVE_LIBZ;HAVE_LIBZZIP;SSE2;BETA_VERSION;GDB_STUB"
StringPooling="true"
ExceptionHandling="0"
BufferSecurityCheck="false"
@ -805,7 +805,11 @@
>
</File>
<File
RelativePath=".\OGLRender.cpp"
RelativePath=".\ogl.cpp"
>
</File>
<File
RelativePath="..\OGLRender.cpp"
>
</File>
<File
@ -1026,6 +1030,10 @@
RelativePath=".\oamView.h"
>
</File>
<File
RelativePath="..\OGLRender.h"
>
</File>
<File
RelativePath=".\palView.h"
>

View File

@ -60,6 +60,10 @@
#include "snddx.h"
#include <ddraw.h>
#define GPU3D_NULL 0
#define GPU3D_OPENGL 1
//===================== Init DirectDraw
LPDIRECTDRAW7 lpDDraw=NULL;
LPDIRECTDRAWSURFACE7 lpPrimarySurface=NULL;
@ -765,6 +769,9 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
#endif
struct configured_features my_config;
extern bool windows_opengl_init();
oglrender_init = windows_opengl_init;
MSG messages; /* Here messages to the application are saved */
char text[80];