From b00df5e746b80f895b726105163d40b30aa937e2 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sat, 13 Sep 2008 19:34:08 +0000 Subject: [PATCH] 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. --- desmume/ChangeLog | 3 + desmume/INSTALL | 5 +- desmume/src/MMU.cpp | 103 +- desmume/src/Makefile.am | 2 +- desmume/src/NDSSystem.cpp | 6 +- desmume/src/gfx3d.cpp | 1472 +++++++++++ desmume/src/gfx3d.h | 160 ++ desmume/src/opengl_collector_3Demu.cpp | 3149 ----------------------- desmume/src/opengl_collector_3Demu.h | 65 - desmume/src/render3D.cpp | 86 +- desmume/src/render3D.h | 114 +- desmume/src/types.h | 8 + desmume/src/windows/DeSmuME_2005.vcproj | 8 + desmume/src/windows/DeSmuME_2008.vcproj | 8 + desmume/src/windows/OGLRender.cpp | 1601 +----------- desmume/src/windows/lightView.cpp | 8 +- desmume/src/windows/main.cpp | 3 +- desmume/src/windows/matrixView.cpp | 10 +- 18 files changed, 1834 insertions(+), 4977 deletions(-) create mode 100644 desmume/src/gfx3d.cpp create mode 100644 desmume/src/gfx3d.h delete mode 100644 desmume/src/opengl_collector_3Demu.cpp delete mode 100644 desmume/src/opengl_collector_3Demu.h diff --git a/desmume/ChangeLog b/desmume/ChangeLog index dd6c5f2d9..cbf51f587 100644 --- a/desmume/ChangeLog +++ b/desmume/ChangeLog @@ -53,6 +53,9 @@ - Added a bunch of crazy templates to the cpu and mmu which speed up a the emu little by optimizing variable accesses [zeromus] - Add an arm8 cpu load average calculator [zeromus] ? Fix a bug in texture transformation mode 1 [zeromus] + - 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] 0.7.3 -> 0.8 diff --git a/desmume/INSTALL b/desmume/INSTALL index d3c5b40a9..5458714e1 100644 --- a/desmume/INSTALL +++ b/desmume/INSTALL @@ -2,7 +2,7 @@ Installation Instructions ************************* Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, -2006, 2007 Free Software Foundation, Inc. +2006 Free Software Foundation, Inc. This file is free documentation; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. @@ -67,9 +67,6 @@ The simplest way to compile this package is: all sorts of other programs in order to regenerate files that came with the distribution. - 6. Often, you can also type `make uninstall' to remove the installed - files again. - Compilers and Options ===================== diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index 5658198d5..759692fc1 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -36,6 +36,7 @@ #include "wifi.h" #include "registers.h" #include "render3D.h" +#include "gfx3d.h" #define ROM_MASK 3 @@ -652,9 +653,9 @@ u16 FASTCALL _MMU_read16(u32 adr) switch(adr) { case 0x04000604: - return (gpu3D->NDS_3D_GetNumPolys()&2047); + return (gfx3d_GetNumPolys()&2047); case 0x04000606: - return (gpu3D->NDS_3D_GetNumVertex()&8191); + return (gfx3d_GetNumVertex()&8191); case REG_IPCFIFORECV : /* TODO (clear): ??? */ //printlog("Stopped IPCFIFORECV\n"); @@ -751,7 +752,7 @@ u32 FASTCALL _MMU_read32(u32 adr) case 0x0400067C: { //LOG("4000640h..67Fh - CLIPMTX_RESULT - Read Current Clip Coordinates Matrix (R)"); - return gpu3D->NDS_3D_GetClipMatrix ((adr-0x04000640)/4); + return gfx3d_GetClipMatrix ((adr-0x04000640)/4); } case 0x04000680: case 0x04000684: @@ -764,12 +765,12 @@ u32 FASTCALL _MMU_read32(u32 adr) case 0x040006A0: { //LOG("4000680h..6A3h - VECMTX_RESULT - Read Current Directional Vector Matrix (R)"); - return gpu3D->NDS_3D_GetDirectionalMatrix ((adr-0x04000680)/4); + return gfx3d_GetDirectionalMatrix ((adr-0x04000680)/4); } case 0x4000604: { - return (gpu3D->NDS_3D_GetNumPolys()&2047) & ((gpu3D->NDS_3D_GetNumVertex()&8191) << 16); + return (gfx3d_GetNumPolys()&2047) & ((gfx3d_GetNumVertex()&8191) << 16); //LOG ("read32 - RAM_COUNT -> 0x%X", ((u32 *)(MMU.MMU_MEM[proc][(adr>>20)&0xFF]))[(adr&MMU.MMU_MASK[proc][(adr>>20)&0xFF])>>2]); } @@ -1300,7 +1301,7 @@ void FASTCALL _MMU_write16(u32 adr, u16 val) { //toon table ((u16 *)(MMU.MMU_MEM[proc][0x40]))[(adr-0x04000000)>>1] = val; - gpu3D->NDS_3D_UpdateToonTable(&((MMU.MMU_MEM[proc][0x40]))[(0x380)]); + gfx3d_UpdateToonTable(&((MMU.MMU_MEM[proc][0x40]))[(0x380)]); } /* Adress is an IO register */ else switch(adr) @@ -1310,7 +1311,7 @@ void FASTCALL _MMU_write16(u32 adr, u16 val) ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x35C>>1] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_FogOffset (val); + gfx3d_glFogOffset (val); } return; } @@ -1319,7 +1320,7 @@ void FASTCALL _MMU_write16(u32 adr, u16 val) ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x340>>1] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_AlphaFunc(val); + gfx3d_glAlphaFunc(val); } return; } @@ -1328,7 +1329,7 @@ void FASTCALL _MMU_write16(u32 adr, u16 val) ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x060>>1] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_Control(val); + gfx3d_Control(val); } return; } @@ -1337,7 +1338,7 @@ void FASTCALL _MMU_write16(u32 adr, u16 val) ((u16 *)(MMU.MMU_MEM[proc][0x40]))[0x354>>1] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_ClearDepth(val); + gfx3d_glClearDepth(val); } return; } @@ -1957,14 +1958,14 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x400>>2] = val; if(proc==ARMCPU_ARM9) { - gpu3D->NDS_3D_CallList(val); + gfx3d_glCallList(val); } } else if(adr >= 0x04000380 && adr <= 0x040003BC) { //toon table ((u32 *)(MMU.MMU_MEM[proc][0x40]))[(adr-0x04000000)>>2] = val; - gpu3D->NDS_3D_UpdateToonTable(&((MMU.MMU_MEM[proc][0x40]))[(0x380)]); + gfx3d_UpdateToonTable(&((MMU.MMU_MEM[proc][0x40]))[(0x380)]); } else switch(adr) { @@ -1974,7 +1975,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x340>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_AlphaFunc(val); + gfx3d_glAlphaFunc(val); } return; } @@ -1984,7 +1985,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x350>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_ClearColor(val); + gfx3d_glClearColor(val); } return; } @@ -1994,7 +1995,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x354>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_ClearDepth(val); + gfx3d_glClearDepth(val); } return; } @@ -2004,7 +2005,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x358>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_FogColor(val); + gfx3d_glFogColor(val); } return; } @@ -2013,7 +2014,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x35C>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_FogOffset(val); + gfx3d_glFogOffset(val); } return; } @@ -2024,7 +2025,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_MatrixMode(val); + gfx3d_glMatrixMode(val); } return; } @@ -2034,7 +2035,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x444>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_PushMatrix(); + gfx3d_glPushMatrix(); } return; } @@ -2044,7 +2045,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x448>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_PopMatrix(val); + gfx3d_glPopMatrix(val); } return; } @@ -2054,7 +2055,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x44C>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_StoreMatrix(val); + gfx3d_glStoreMatrix(val); } return; } @@ -2064,7 +2065,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x450>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_RestoreMatrix(val); + gfx3d_glRestoreMatrix(val); } return; } @@ -2074,7 +2075,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x454>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_LoadIdentity(); + gfx3d_glLoadIdentity(); } return; } @@ -2084,7 +2085,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x458>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_LoadMatrix4x4(val); + gfx3d_glLoadMatrix4x4(val); } return; } @@ -2094,7 +2095,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x45C>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_LoadMatrix4x3(val); + gfx3d_glLoadMatrix4x3(val); } return; } @@ -2104,7 +2105,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x460>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_MultMatrix4x4(val); + gfx3d_glLoadMatrix4x4(val); } return; } @@ -2114,7 +2115,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x464>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_MultMatrix4x3(val); + gfx3d_glMultMatrix4x3(val); } return; } @@ -2124,7 +2125,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x468>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_MultMatrix3x3(val); + gfx3d_glMultMatrix3x3(val); } return; } @@ -2134,7 +2135,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x46C>>2] = val; if(proc==ARMCPU_ARM9) { - gpu3D->NDS_3D_Scale(val); + gfx3d_glScale(val); } return; } @@ -2144,7 +2145,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x470>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_Translate(val); + gfx3d_glTranslate(val); } return; } @@ -2154,7 +2155,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x480>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_Color3b(val); + gfx3d_glColor3b(val); } return; } @@ -2164,7 +2165,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x484>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_Normal(val); + gfx3d_glNormal(val); } return; } @@ -2174,7 +2175,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x488>>2] = val; if(proc==ARMCPU_ARM9) { - gpu3D->NDS_3D_TexCoord(val); + gfx3d_glTexCoord(val); } return; } @@ -2184,7 +2185,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x48C>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_Vertex16b(val); + gfx3d_glVertex16b(val); } return; } @@ -2194,7 +2195,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x490>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_Vertex10b(val); + gfx3d_glVertex10b(val); } return; } @@ -2204,7 +2205,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x494>>2] = val; if(proc==ARMCPU_ARM9) { - gpu3D->NDS_3D_Vertex3_cord(0,1,val); + gfx3d_glVertex3_cord(0,1,val); } return; } @@ -2214,7 +2215,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x498>>2] = val; if(proc==ARMCPU_ARM9) { - gpu3D->NDS_3D_Vertex3_cord(0,2,val); + gfx3d_glVertex3_cord(0,2,val); } return; } @@ -2224,7 +2225,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x49C>>2] = val; if(proc==ARMCPU_ARM9) { - gpu3D->NDS_3D_Vertex3_cord(1,2,val); + gfx3d_glVertex3_cord(1,2,val); } return; } @@ -2234,7 +2235,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4A0>>2] = val; if(proc==ARMCPU_ARM9) { - gpu3D->NDS_3D_Vertex_rel (val); + gfx3d_glVertex_rel (val); } return; } @@ -2244,7 +2245,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4A4>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_PolygonAttrib(val); + gfx3d_glPolygonAttrib(val); } return; } @@ -2254,7 +2255,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4A8>>2] = val; if(proc==ARMCPU_ARM9) { - gpu3D->NDS_3D_TexImage(val); + gfx3d_glTexImage(val); } return; } @@ -2264,7 +2265,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4AC>>2] = val&0x1FFF; if(proc==ARMCPU_ARM9) { - gpu3D->NDS_3D_TexPalette(val&0x1FFFF); + gfx3d_glTexPalette(val&0x1FFFF); } return; } @@ -2274,7 +2275,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4C0>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_Material0 (val); + gfx3d_glMaterial0 (val); } return; } @@ -2284,7 +2285,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4C4>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_Material1 (val); + gfx3d_glMaterial1 (val); } return; } @@ -2294,7 +2295,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4C8>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_LightDirection (val); + gfx3d_glLightColor (val); } return; } @@ -2304,7 +2305,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4CC>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_LightColor(val); + gfx3d_glLightColor(val); } return; } @@ -2314,7 +2315,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x4D0>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_Shininess(val); + gfx3d_glShininess(val); } return; } @@ -2324,7 +2325,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x500>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_Begin(val); + gfx3d_glBegin(val); } return; } @@ -2334,7 +2335,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x504>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_End(); + gfx3d_glEnd(); } return; } @@ -2344,7 +2345,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x540>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_Flush(val); + gfx3d_glFlush(val); } return; } @@ -2354,7 +2355,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) ((u32 *)(MMU.MMU_MEM[proc][0x40]))[0x580>>2] = val; if(proc == ARMCPU_ARM9) { - gpu3D->NDS_3D_ViewPort(val); + gfx3d_glViewPort(val); } return; } diff --git a/desmume/src/Makefile.am b/desmume/src/Makefile.am index 9bd73c56d..8544b8978 100644 --- a/desmume/src/Makefile.am +++ b/desmume/src/Makefile.am @@ -23,6 +23,6 @@ libdesmume_a_SOURCES = \ SPU.cpp SPU.h \ gdbstub.h \ matrix.cpp matrix.h \ - opengl_collector_3Demu.cpp opengl_collector_3Demu.h \ + gfx3d.cpp gfx3d.h \ thumb_instructions.cpp thumb_instructions.h types.h libdesmume_a_LIBADD = fs-$(desmume_arch).$(OBJEXT) diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index b8a7f7791..7ffb46177 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -30,7 +30,7 @@ #include "MMU.h" #include "cflash.h" #include "ROMReader.h" -#include "render3D.h" +#include "gfx3d.h" /* the count of bytes copied from the firmware into memory */ #define NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT 0x70 @@ -158,6 +158,8 @@ int NDS_Init( void) { if (Screen_Init(GFXCORE_DUMMY) != 0) return -1; + + gfx3d_init(); #ifdef GDB_STUB armcpu_new(&NDS_ARM7,1, arm7_mem_if, arm7_ctrl_iface); @@ -1027,7 +1029,7 @@ NDS_exec(s32 nb, BOOL force) nds.lignerendu = FALSE; if(nds.VCount==192) { - gpu3D->NDS_3D_VBlankSignal(); + gfx3d_VBlankSignal(); T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) | 1); T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) | 1); diff --git a/desmume/src/gfx3d.cpp b/desmume/src/gfx3d.cpp new file mode 100644 index 000000000..0c1fee912 --- /dev/null +++ b/desmume/src/gfx3d.cpp @@ -0,0 +1,1472 @@ +/* + Copyright (C) 2008 DeSmuME team + + This file is part of DeSmuME + + DeSmuME is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DeSmuME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +//This file implements the geometry engine hardware component. +//This handles almost all of the work of 3d rendering, leaving the renderer +// plugin responsible only for drawing primitives. + +#include "debug.h" +#include "gfx3d.h" +#include "matrix.h" +#include "bits.h" +#include "MMU.h" +#include "render3D.h" +#include "types.h" + +GFX3D gfx3d; + +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif + + +//tables that are provided to anyone +u32 color_15bit_to_24bit[32768]; + +//is this a crazy idea? this table spreads 5 bits evenly over 31 from exactly 0 to INT_MAX +const int material_5bit_to_31bit[] = { + 0x00000000, 0x04210842, 0x08421084, 0x0C6318C6, + 0x10842108, 0x14A5294A, 0x18C6318C, 0x1CE739CE, + 0x21084210, 0x25294A52, 0x294A5294, 0x2D6B5AD6, + 0x318C6318, 0x35AD6B5A, 0x39CE739C, 0x3DEF7BDE, + 0x42108421, 0x46318C63, 0x4A5294A5, 0x4E739CE7, + 0x5294A529, 0x56B5AD6B, 0x5AD6B5AD, 0x5EF7BDEF, + 0x6318C631, 0x6739CE73, 0x6B5AD6B5, 0x6F7BDEF7, + 0x739CE739, 0x77BDEF7B, 0x7BDEF7BD, 0x7FFFFFFF +}; + +const u8 material_5bit_to_8bit[] = { + 0x00, 0x08, 0x10, 0x18, 0x21, 0x29, 0x31, 0x39, + 0x42, 0x4A, 0x52, 0x5A, 0x63, 0x6B, 0x73, 0x7B, + 0x84, 0x8C, 0x94, 0x9C, 0xA5, 0xAD, 0xB5, 0xBD, + 0xC6, 0xCE, 0xD6, 0xDE, 0xE7, 0xEF, 0xF7, 0xFF +}; + + +const u8 material_3bit_to_8bit[] = { + 0x00, 0x24, 0x49, 0x6D, 0x92, 0xB6, 0xDB, 0xFF +}; + +//private acceleration tables +static float float16table[65536]; +static float float10Table[1024]; +static float float10RelTable[1024]; +static float normalTable[1024]; + +#define fix2float(v) (((float)((s32)(v))) / (float)(1<<12)) +#define fix10_2float(v) (((float)((s32)(v))) / (float)(1<<9)) + +// Matrix stack handling +static ALIGN(16) MatrixStack mtxStack[4]; +static ALIGN(16) float mtxCurrent [4][16]; +static ALIGN(16) float mtxTemporal[16]; +static short mode = 0; + +// Indexes for matrix loading/multiplication +static char ML4x4ind = 0; +static char ML4x3_c = 0, ML4x3_l = 0; +static char MM4x4ind = 0; +static char MM4x3_c = 0, MM4x3_l = 0; +static char MM3x3_c = 0, MM3x3_l = 0; + +// Data for vertex submission +static ALIGN(16) float coord[4] = {0.0, 0.0, 0.0, 0.0}; +static char coordind = 0; +static unsigned int vtxFormat; + +// Data for basic transforms +static ALIGN(16) float trans[4] = {0.0, 0.0, 0.0, 0.0}; +static char transind = 0; +static ALIGN(16) float scale[4] = {0.0, 0.0, 0.0, 0.0}; +static char scaleind = 0; + +//various other registers +static float fogColor[4] = {0.f}; +static float fogOffset = 0.f; +static float alphaTestRef = 0.01f; +static int colorRGB[4] = { 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}; +static int texCoordinateTransform = 0; +static int _t=0, _s=0; +static float last_t, last_s; +static float alphaTestBase = 0; +static unsigned long clCmd = 0; +static unsigned long clInd = 0; +static unsigned long clInd2 = 0; +static int alphaDepthWrite = 0; +static int colorAlpha=0; +static unsigned int polyID=0; +static unsigned int depthFuncMode=0; +static unsigned int envMode=0; +static unsigned int cullingMask=0; + +//raw ds format poly attributes +static u32 polyAttr=0,textureFormat=0, texturePalette=0; + +//------lighting state +struct LightInformation +{ + unsigned int color; // Color in hardware format + unsigned int direction; // Direction in hardware format + float floatDirection[4]; +} ; + +static LightInformation g_lightInfo[4] = { 0 }; +static unsigned int lightMask=0; + +static u16 dsDiffuse, dsAmbient, dsSpecular, dsEmission; +static int diffuse[4] = {0}, + ambient[4] = {0}, + specular[4] = {0}, + emission[4] = {0}; +//------------------ + +//-------------poly and vertex lists +POLYLIST polylists[2]; +POLYLIST* polylist = &polylists[0]; +VERTLIST vertlists[2]; +VERTLIST* vertlist = &vertlists[0]; + +int listTwiddle = 1; +int triStripToggle; + +//list-building state +VERTLIST tempVertList; + +static void twiddleLists() { + listTwiddle++; + listTwiddle &= 1; + polylist = &polylists[listTwiddle]; + vertlist = &vertlists[listTwiddle]; + polylist->count = 0; + vertlist->count = 0; +} + +//------------------------------------------------------------ + +static void makeTables() { + + //produce the color bits of a 32bpp color from a DS RGB15 using bit logic (internal use only) + #define RGB15TO24_BITLOGIC(col) ( (material_5bit_to_8bit[((col)>>10)&0x1F]<<16) | (material_5bit_to_8bit[((col)>>5)&0x1F]<<8) | material_5bit_to_8bit[(col)&0x1F] ) + + for(int i=0;i<32768;i++) + color_15bit_to_24bit[i] = RGB15TO24_BITLOGIC((u16)i); + + for (int i = 0; i < 65536; i++) + float16table[i] = fix2float((signed short)i); + + for (int i = 0; i < 1024; i++) + float10Table[i] = ((signed short)(i<<6)) / (float)(1<<12); + + for (int i = 0; i < 1024; i++) + float10RelTable[i] = ((signed short)(i<<6)) / (float)(1<<18); + + for (int i = 0; i < 1024; i++) + normalTable[i] = ((signed short)(i<<6)) / (float)(1<<15); +} + +void gfx3d_init() +{ + twiddleLists(); + + makeTables(); + + MatrixStackSetMaxSize(&mtxStack[0], 1); // Projection stack + MatrixStackSetMaxSize(&mtxStack[1], 31); // Coordinate stack + MatrixStackSetMaxSize(&mtxStack[2], 31); // Directional stack + MatrixStackSetMaxSize(&mtxStack[3], 1); // Texture stack + + MatrixInit (mtxCurrent[0]); + MatrixInit (mtxCurrent[1]); + MatrixInit (mtxCurrent[2]); + MatrixInit (mtxCurrent[3]); + MatrixInit (mtxTemporal); +} + +void gfx3d_glViewPort(unsigned long v) +{ + //zero: NHerve messed with this in mod2 and mod3, but im still not sure its perfect. need to research this. + //glViewport( (v&0xFF), ((v>>8)&0xFF), (((v>>16)&0xFF)+1)-(v&0xFF), ((v>>24)+1)-((v>>8)&0xFF)); + //TODO +} + + +void gfx3d_glClearColor(unsigned long v) +{ + //glClearColor( ((float)(v&0x1F))/31.0f, + // ((float)((v>>5)&0x1F))/31.0f, + // ((float)((v>>10)&0x1F))/31.0f, + // ((float)((v>>16)&0x1F))/31.0f); + //TODO +} + +void gfx3d_glFogColor(unsigned long v) +{ + fogColor[0] = ((float)((v )&0x1F))/31.0f; + fogColor[1] = ((float)((v>> 5)&0x1F))/31.0f; + fogColor[2] = ((float)((v>>10)&0x1F))/31.0f; + fogColor[3] = ((float)((v>>16)&0x1F))/31.0f; +} + +void gfx3d_glFogOffset (unsigned long v) +{ + fogOffset = (float)(v&0xffff); +} + +void gfx3d_glClearDepth(unsigned long v) +{ + //u32 depth24b; + + //v &= 0x7FFFF; + // + //// Thanks for NHerve + //depth24b = (v*0x200)+((v+1)/0x8000)*0x01FF; + //glClearDepth(depth24b / ((float)(1<<24))); + + //TODO +} + +void gfx3d_glMatrixMode(unsigned long v) +{ + mode = (short)(v&3); +} + + +void gfx3d_glLoadIdentity() +{ + MatrixIdentity (mtxCurrent[mode]); + + if (mode == 2) + MatrixIdentity (mtxCurrent[1]); +} + +void gfx3d_glLoadMatrix4x4(signed long v) +{ + mtxCurrent[mode][ML4x4ind] = fix2float(v); + + ++ML4x4ind; + if(ML4x4ind<16) return; + + if (mode == 2) + MatrixCopy (mtxCurrent[1], mtxCurrent[2]); + + ML4x4ind = 0; +} + +void gfx3d_glLoadMatrix4x3(signed long v) +{ + mtxCurrent[mode][(ML4x3_l<<2)+ML4x3_c] = fix2float(v); + + ++ML4x3_c; + if(ML4x3_c<3) return; + + ML4x3_c = 0; + ++ML4x3_l; + if(ML4x3_l<4) return; + ML4x3_l = 0; + + //fill in the unusued matrix values + mtxCurrent[mode][3] = mtxCurrent[mode][7] = mtxCurrent[mode][11] = 0; + mtxCurrent[mode][15] = 1; + + if (mode == 2) + MatrixCopy (mtxCurrent[1], mtxCurrent[2]); +} + +void gfx3d_glStoreMatrix(unsigned long v) +{ + //this command always works on both pos and vector when either pos or pos-vector are the current mtx mode + short mymode = (mode==1?2:mode); + + //for the projection matrix, the provided value is supposed to be reset to zero + if(mymode==0) + v = 0; + + MatrixStackLoadMatrix (&mtxStack[mymode], v&31, mtxCurrent[mymode]); + if(mymode==2) + MatrixStackLoadMatrix (&mtxStack[1], v&31, mtxCurrent[1]); +} + +void gfx3d_glRestoreMatrix(unsigned long v) +{ + //this command always works on both pos and vector when either pos or pos-vector are the current mtx mode + short mymode = (mode==1?2:mode); + + //for the projection matrix, the provided value is supposed to be reset to zero + if(mymode==0) + v = 0; + + MatrixCopy (mtxCurrent[mymode], MatrixStackGetPos(&mtxStack[mymode], v&31)); + if (mymode == 2) + MatrixCopy (mtxCurrent[1], MatrixStackGetPos(&mtxStack[1], v&31)); +} + +void gfx3d_glPushMatrix() +{ + //this command always works on both pos and vector when either pos or pos-vector are the current mtx mode + short mymode = (mode==1?2:mode); + + MatrixStackPushMatrix (&mtxStack[mymode], mtxCurrent[mymode]); + if(mymode==2) + MatrixStackPushMatrix (&mtxStack[1], mtxCurrent[1]); +} + +void gfx3d_glPopMatrix(signed long i) +{ + //this command always works on both pos and vector when either pos or pos-vector are the current mtx mode + short mymode = (mode==1?2:mode); + + MatrixCopy (mtxCurrent[mode], MatrixStackPopMatrix (&mtxStack[mode], i)); + + if (mymode == 2) + MatrixCopy (mtxCurrent[1], MatrixStackPopMatrix (&mtxStack[1], i)); +} + +void gfx3d_glTranslate(signed long v) +{ + trans[transind] = fix2float(v); + + ++transind; + + if(transind<3) + return; + + transind = 0; + + MatrixTranslate (mtxCurrent[mode], trans); + + if (mode == 2) + MatrixTranslate (mtxCurrent[1], trans); +} + +void gfx3d_glScale(signed long v) +{ + short mymode = (mode==2?1:mode); + + scale[scaleind] = fix2float(v); + + ++scaleind; + + if(scaleind<3) + return; + + scaleind = 0; + + MatrixScale (mtxCurrent[mymode], scale); + + //note: pos-vector mode should not cause both matrices to scale. + //the whole purpose is to keep the vector matrix orthogonal + //so, I am leaving this commented out as an example of what not to do. + //if (mode == 2) + // MatrixScale (mtxCurrent[1], scale); +} + +void gfx3d_glMultMatrix3x3(signed long v) +{ + mtxTemporal[(MM3x3_l<<2)+MM3x3_c] = fix2float(v); + + ++MM3x3_c; + if(MM3x3_c<3) return; + + MM3x3_c = 0; + ++MM3x3_l; + if(MM3x3_l<3) return; + MM3x3_l = 0; + + //fill in the unusued matrix values + mtxTemporal[3] = mtxTemporal[7] = mtxTemporal[11] = 0; + mtxTemporal[15] = 1; + mtxTemporal[12] = mtxTemporal[13] = mtxTemporal[14] = 0; + + MatrixMultiply (mtxCurrent[mode], mtxTemporal); + + if (mode == 2) + MatrixMultiply (mtxCurrent[1], mtxTemporal); + + //does this really need to be done? + MatrixIdentity (mtxTemporal); +} + +void gfx3d_glMultMatrix4x3(signed long v) +{ + mtxTemporal[(MM4x3_l<<2)+MM4x3_c] = fix2float(v); + + ++MM4x3_c; + if(MM4x3_c<3) return; + + MM4x3_c = 0; + ++MM4x3_l; + if(MM4x3_l<4) return; + MM4x3_l = 0; + + //fill in the unusued matrix values + mtxTemporal[3] = mtxTemporal[7] = mtxTemporal[11] = 0; + mtxTemporal[15] = 1; + + MatrixMultiply (mtxCurrent[mode], mtxTemporal); + if (mode == 2) + MatrixMultiply (mtxCurrent[1], mtxTemporal); + + //does this really need to be done? + MatrixIdentity (mtxTemporal); +} + +void gfx3d_glMultMatrix4x4(signed long v) +{ + mtxTemporal[MM4x4ind] = fix2float(v); + + ++MM4x4ind; + if(MM4x4ind<16) return; + + MM4x4ind = 0; + + MatrixMultiply (mtxCurrent[mode], mtxTemporal); + if (mode == 2) + MatrixMultiply (mtxCurrent[1], mtxTemporal); + + MatrixIdentity (mtxTemporal); +} + +void gfx3d_glBegin(unsigned long v) +{ + vtxFormat = v&0x03; + triStripToggle = 0; + tempVertList.count = 0; +} + +void gfx3d_glEnd(void) +{ + tempVertList.count = 0; +} + +void gfx3d_glColor3b(unsigned long v) +{ + colorRGB[0] = material_5bit_to_31bit[(v&0x1F)]; + colorRGB[1] = material_5bit_to_31bit[((v>>5)&0x1F)]; + colorRGB[2] = material_5bit_to_31bit[((v>>10)&0x1F)]; +} + +//Submit a vertex to the GE +static void SetVertex() +{ + ALIGN(16) float coordTransformed[4] = { coord[0], coord[1], coord[2], 1 }; + + if (texCoordinateTransform == 3) + { + last_s =((coord[0]*mtxCurrent[3][0] + + coord[1]*mtxCurrent[3][4] + + coord[2]*mtxCurrent[3][8]) + _s); + last_t =((coord[0]*mtxCurrent[3][1] + + coord[1]*mtxCurrent[3][5] + + coord[2]*mtxCurrent[3][9]) + _t); + } + + //refuse to do anything if we have too many verts or polys + if(vertlist->count >= VERTLIST_SIZE) + return; + if(polylist->count >= POLYLIST_SIZE) + return; + + //apply modelview matrix + MatrixMultVec4x4 (mtxCurrent[1], coordTransformed); + + //deferred rendering: + + //todo - we havent got the whole pipeline working yet, so lets save the projection matrix and let opengl do it + ////apply projection matrix + //MatrixMultVec4x4 (mtxCurrent[0], coordTransformed); + + ////perspective division + //coordTransformed[0] = (coordTransformed[0] + coordTransformed[3]) / 2 / coordTransformed[3]; + //coordTransformed[1] = (coordTransformed[1] + coordTransformed[3]) / 2 / coordTransformed[3]; + //coordTransformed[2] = (coordTransformed[2] + coordTransformed[3]) / 2 / coordTransformed[3]; + //coordTransformed[3] = 1; + + //TODO - culling should be done here. + //TODO - viewport transform + + + //record the vertex + tempVertList.list[tempVertList.count].texcoord[0] = last_s; + tempVertList.list[tempVertList.count].texcoord[1] = last_t; + tempVertList.list[tempVertList.count].coord[0] = coordTransformed[0]; + tempVertList.list[tempVertList.count].coord[1] = coordTransformed[1]; + tempVertList.list[tempVertList.count].coord[2] = coordTransformed[2]; + tempVertList.list[tempVertList.count].coord[3] = coordTransformed[3]; + tempVertList.list[tempVertList.count].color[0] = colorRGB[0]; + tempVertList.list[tempVertList.count].color[1] = colorRGB[1]; + tempVertList.list[tempVertList.count].color[2] = colorRGB[2]; + tempVertList.list[tempVertList.count].color[3] = colorRGB[3]; + tempVertList.list[tempVertList.count].depth = 0x7FFF * coordTransformed[2]; + tempVertList.count++; + + //possibly complete a polygon + { + #define SUBMITVERTEX(i,n) vertlist->list[polylist->list[polylist->count].vertIndexes[i] = vertlist->count++] = tempVertList.list[n]; + int completed=0; + switch(vtxFormat) { + case 0: //GL_TRIANGLES + if(tempVertList.count!=3) + break; + completed = 1; + SUBMITVERTEX(0,0); + SUBMITVERTEX(1,1); + SUBMITVERTEX(2,2); + polylist->list[polylist->count].type = 3; + tempVertList.count = 0; + break; + case 1: //GL_QUADS + if(tempVertList.count!=4) + break; + completed = 1; + SUBMITVERTEX(0,0); + SUBMITVERTEX(1,1); + SUBMITVERTEX(2,2); + SUBMITVERTEX(3,3); + polylist->list[polylist->count].type = 4; + tempVertList.count = 0; + break; + case 2: //GL_TRIANGLE_STRIP + if(tempVertList.count!=3) + break; + completed = 1; + SUBMITVERTEX(0,0); + SUBMITVERTEX(1,1); + SUBMITVERTEX(2,2); + polylist->list[polylist->count].type = 3; + if(triStripToggle) + tempVertList.list[1] = tempVertList.list[2]; + else + tempVertList.list[0] = tempVertList.list[2]; + triStripToggle ^= 1; + tempVertList.count = 2; + break; + case 3: //GL_QUAD_STRIP + if(tempVertList.count!=4) + break; + completed = 1; + SUBMITVERTEX(0,0); + SUBMITVERTEX(1,1); + SUBMITVERTEX(2,3); + SUBMITVERTEX(3,2); + polylist->list[polylist->count].type = 4; + tempVertList.list[0] = tempVertList.list[2]; + tempVertList.list[1] = tempVertList.list[3]; + tempVertList.count = 2; + break; + } + + if(completed) { + MatrixCopy(polylist->list[polylist->count].projMatrix,mtxCurrent[0]); + polylist->list[polylist->count].polyAttr = polyAttr; + polylist->list[polylist->count].texParam = textureFormat; + polylist->list[polylist->count].texPalette = texturePalette; + polylist->count++; + } + } +} + +void gfx3d_glVertex16b(unsigned int v) +{ + if(coordind==0) + { + coord[0] = float16table[v&0xFFFF]; + coord[1] = float16table[v>>16]; + + ++coordind; + return; + } + + coord[2] = float16table[v&0xFFFF]; + + coordind = 0; + SetVertex (); +} + +void gfx3d_glVertex10b(unsigned long v) +{ + coord[0] = float10Table[v&1023]; + coord[1] = float10Table[(v>>10)&1023]; + coord[2] = float10Table[(v>>20)&1023]; + + SetVertex (); +} + +void gfx3d_glVertex3_cord(unsigned int one, unsigned int two, unsigned int v) +{ + coord[one] = float16table[v&0xffff]; + coord[two] = float16table[v>>16]; + + SetVertex (); +} + +void gfx3d_glVertex_rel(unsigned long v) +{ + coord[0] += float10RelTable[v&1023]; + coord[1] += float10RelTable[(v>>10)&1023]; + coord[2] += float10RelTable[(v>>20)&1023]; + + SetVertex (); +} + +// Ignored for now +void gfx3d_glSwapScreen(unsigned int screen) +{ +} + + +int gfx3d_GetNumPolys() +{ + //so is this in the currently-displayed or currently-built list? + return 0; +} + +int gfx3d_GetNumVertex() +{ + //so is this in the currently-displayed or currently-built list? + return 0; +} + +static void InstallPolygonAttrib(unsigned long val) +{ + // Light enable/disable + lightMask = (val&0xF); + + // texture environment + //envMode = texEnv[(val&0x30)>>4]; + envMode = (val&0x30)>>4; + + //// overwrite depth on alpha pass + //alphaDepthWrite = BIT11(val); + + //// depth test function + //depthFuncMode = depthFunc[BIT14(val)]; + + //// back face culling + //cullingMask = (val&0xC0); + + // Alpha value, actually not well handled, 0 should be wireframe + colorRGB[3] = colorAlpha = material_5bit_to_31bit[((val>>16)&0x1F)]; + + //// polyID + //polyID = (val>>24)&0x1F; +} + +void gfx3d_glPolygonAttrib (unsigned long val) +{ + polyAttr = val; + InstallPolygonAttrib(polyAttr); +} + +/* + 0-4 Diffuse Reflection Red + 5-9 Diffuse Reflection Green + 10-14 Diffuse Reflection Blue + 15 Set Vertex Color (0=No, 1=Set Diffuse Reflection Color as Vertex Color) + 16-20 Ambient Reflection Red + 21-25 Ambient Reflection Green + 26-30 Ambient Reflection Blue +*/ +void gfx3d_glMaterial0(unsigned long val) +{ + dsDiffuse = val&0xFFFF; + dsAmbient = val>>16; + + diffuse[0] = material_5bit_to_31bit[(val)&0x1F]; + diffuse[1] = material_5bit_to_31bit[(val>>5)&0x1F]; + diffuse[2] = material_5bit_to_31bit[(val>>10)&0x1F]; + diffuse[3] = 0x7fffffff; + + ambient[0] = material_5bit_to_31bit[(val>>16)&0x1F]; + ambient[1] = material_5bit_to_31bit[(val>>21)&0x1F]; + ambient[2] = material_5bit_to_31bit[(val>>26)&0x1F]; + ambient[3] = 0x7fffffff; + + if (BIT15(val)) + { + colorRGB[0] = diffuse[0]; + colorRGB[1] = diffuse[1]; + colorRGB[2] = diffuse[2]; + } +} + +void gfx3d_glMaterial1(unsigned long val) +{ + dsSpecular = val&0xFFFF; + dsEmission = val>>16; + + specular[0] = material_5bit_to_31bit[(val)&0x1F]; + specular[1] = material_5bit_to_31bit[(val>>5)&0x1F]; + specular[2] = material_5bit_to_31bit[(val>>10)&0x1F]; + specular[3] = 0x7fffffff; + + emission[0] = material_5bit_to_31bit[(val>>16)&0x1F]; + emission[1] = material_5bit_to_31bit[(val>>21)&0x1F]; + emission[2] = material_5bit_to_31bit[(val>>26)&0x1F]; + emission[3] = 0x7fffffff; +} + +void gfx3d_glShininess (unsigned long val) +{ + //printlog("Shininess=%i\n",val); +} + +void gfx3d_UpdateToonTable(void* toonTable) +{ + u16* u16toonTable = (u16*)toonTable; + u32 rgbToonTable[32]; + int i; + for(i=0;i<32;i++) + rgbToonTable[i] = RGB15TO32(u16toonTable[i],255); + + //glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbToonTable); + //TODO +} + + +void gfx3d_glTexImage(unsigned long val) +{ + textureFormat = val; + texCoordinateTransform = (val>>30); +} + +void gfx3d_glTexPalette(unsigned long val) +{ + texturePalette = val; +} + +void gfx3d_glTexCoord(unsigned long val) +{ + _t = (s16)(val>>16); + _s = (s16)(val&0xFFFF); + + if (texCoordinateTransform == 1) + { + //last_s =_s*mtxCurrent[3][0] + _t*mtxCurrent[3][4] + + // 0.0625f*mtxCurrent[3][8] + 0.0625f*mtxCurrent[3][12]; + //last_t =_s*mtxCurrent[3][1] + _t*mtxCurrent[3][5] + + // 0.0625f*mtxCurrent[3][9] + 0.0625f*mtxCurrent[3][13]; + + //zero 9/11/08 - I dunno... I think it needs to be like this to make things look right + last_s =_s*mtxCurrent[3][0] + _t*mtxCurrent[3][4] + + mtxCurrent[3][8] + mtxCurrent[3][12]; + last_t =_s*mtxCurrent[3][1] + _t*mtxCurrent[3][5] + + mtxCurrent[3][9] + mtxCurrent[3][13]; + } + else + { + last_s=_s; + last_t=_t; + } +} + +void gfx3d_glNormal(unsigned long v) +{ + int i,c; + ALIGN(16) float normal[3] = { normalTable[v&1023], + normalTable[(v>>10)&1023], + normalTable[(v>>20)&1023]}; + + //find the line of sight vector + //TODO - only do this when the projection matrix changes + ALIGN(16) float lineOfSight[4] = { 0, 0, -1, 0 }; + MatrixMultVec4x4 (mtxCurrent[0], lineOfSight); + + if (texCoordinateTransform == 2) + { + last_s =( (normal[0] *mtxCurrent[3][0] + normal[1] *mtxCurrent[3][4] + + normal[2] *mtxCurrent[3][8]) + _s); + last_t =( (normal[0] *mtxCurrent[3][1] + normal[1] *mtxCurrent[3][5] + + normal[2] *mtxCurrent[3][9]) + _t); + } + + //use the current normal transform matrix + MatrixMultVec3x3 (mtxCurrent[2], normal); + + //apply lighting model + { + u8 diffuse[3] = { + (dsDiffuse)&0x1F, + (dsDiffuse>>5)&0x1F, + (dsDiffuse>>10)&0x1F }; + + u8 ambient[3] = { + (dsAmbient)&0x1F, + (dsAmbient>>5)&0x1F, + (dsAmbient>>10)&0x1F }; + + u8 emission[3] = { + (dsEmission)&0x1F, + (dsEmission>>5)&0x1F, + (dsEmission>>10)&0x1F }; + + u8 specular[3] = { + (dsSpecular)&0x1F, + (dsSpecular>>5)&0x1F, + (dsSpecular>>10)&0x1F }; + + int vertexColor[3] = { emission[0], emission[1], emission[2] }; + + //do we need to normalize lineOfSight? + Vector3Normalize(lineOfSight); + + for(i=0;i<4;i++) { + if(!((lightMask>>i)&1)) + continue; + + { + u8 lightColor[3] = { + (g_lightInfo[i].color)&0x1F, + (g_lightInfo[i].color>>5)&0x1F, + (g_lightInfo[i].color>>10)&0x1F }; + + float dot = Vector3Dot(g_lightInfo[i].floatDirection,normal); + float diffuseComponent = max(0,dot); + float specularComponent; + + //a specular formula which I couldnt get working + //float halfAngle[3] = { + // (lineOfSight[0] + g_lightInfo[i].floatDirection[0])/2, + // (lineOfSight[1] + g_lightInfo[i].floatDirection[1])/2, + // (lineOfSight[2] + g_lightInfo[i].floatDirection[2])/2}; + //float halfAngleLength = sqrt(halfAngle[0]*halfAngle[0]+halfAngle[1]*halfAngle[1]+halfAngle[2]*halfAngle[2]); + //float halfAngleNormalized[3] = { + // halfAngle[0]/halfAngleLength, + // halfAngle[1]/halfAngleLength, + // halfAngle[2]/halfAngleLength + //}; + // + //float specularAngle = -Vector3Dot(halfAngleNormalized,normal); + //specularComponent = max(0,cos(specularAngle)); + + //a specular formula which seems to work + float temp[4]; + float diff = Vector3Dot(normal,g_lightInfo[i].floatDirection); + Vector3Copy(temp,normal); + Vector3Scale(temp,-2*diff); + Vector3Add(temp,g_lightInfo[i].floatDirection); + Vector3Scale(temp,-1); + specularComponent = max(0,Vector3Dot(lineOfSight,temp)); + + //if the game isnt producing unit normals, then we can accidentally out of range components. so lets saturate them here + //so we can at least keep for crashing. we're not sure what the hardware does in this case, but the game shouldnt be doing this. + specularComponent = max(0,min(1,specularComponent)); + diffuseComponent = max(0,min(1,diffuseComponent)); + + for(c=0;c<3;c++) { + vertexColor[c] += (diffuseComponent*lightColor[c]*diffuse[c])/31; + vertexColor[c] += (specularComponent*lightColor[c]*specular[c])/31; + vertexColor[c] += ((float)lightColor[c]*ambient[c])/31; + } + } + } + + for(c=0;c<3;c++) + colorRGB[c] = material_5bit_to_31bit[min(31,vertexColor[c])]; + } +} + + +signed long gfx3d_GetClipMatrix (unsigned int index) +{ + float val = MatrixGetMultipliedIndex (index, mtxCurrent[0], mtxCurrent[1]); + + val *= (1<<12); + + return (signed long)val; +} + +signed long gfx3d_GetDirectionalMatrix (unsigned int index) +{ + index += (index/3); + + return (signed long)(mtxCurrent[2][(index)*(1<<12)]); +} + + +/* + 0-9 Directional Vector's X component (1bit sign + 9bit fractional part) + 10-19 Directional Vector's Y component (1bit sign + 9bit fractional part) + 20-29 Directional Vector's Z component (1bit sign + 9bit fractional part) + 30-31 Light Number (0..3) +*/ +void gfx3d_glLightDirection (unsigned long v) +{ + int index = v>>30; + float direction[4]; + + // Convert format into floating point value + g_lightInfo[index].floatDirection[0] = -normalTable[v&1023]; + g_lightInfo[index].floatDirection[1] = -normalTable[(v>>10)&1023]; + g_lightInfo[index].floatDirection[2] = -normalTable[(v>>20)&1023]; + g_lightInfo[index].floatDirection[3] = 0; + + // Keep information for fightDirection function + g_lightInfo[index].direction = v; +} + +void gfx3d_glLightColor (unsigned long v) +{ + int lightColor[4] = { ((v) &0x1F)<<26, + ((v>> 5)&0x1F)<<26, + ((v>>10)&0x1F)<<26, + 0x7fffffff}; + int index = v>>30; + + g_lightInfo[index].color = v; +} + +void gfx3d_glAlphaFunc(unsigned long v) +{ + gfx3d.alphaTestRef = (v&31)/31.f; +} + +void gfx3d_glBoxTest(unsigned long v) +{ +} + +void gfx3d_glPosTest(unsigned long v) +{ +} + +void gfx3d_glVecTest(unsigned long v) +{ + //printlog("NDS_glVecTest\n"); +} + +void gfx3d_glGetPosRes(unsigned int index) +{ + //printlog("NDS_glGetPosRes\n"); + //return 0; +} + +void gfx3d_glGetVecRes(unsigned int index) +{ + //printlog("NDS_glGetVecRes\n"); + //return 0; +} + +void gfx3d_glCallList(unsigned long v) +{ + //static unsigned long oldval = 0, shit = 0; + + if(!clInd) + { + clInd = 4; + clCmd = v; + return; + } + + for (;;) + { + switch ((clCmd&0xFF)) + { + case 0x0: + { + if (clInd > 0) + { + --clInd; + clCmd >>= 8; + continue; + } + break; + } + + case 0x11 : + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x444>>2] = v; + gfx3d_glPushMatrix(); + --clInd; + clCmd>>=8; + continue; + } + + case 0x15: + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x454>>2] = v; + gfx3d_glLoadIdentity(); + --clInd; + clCmd>>=8; + continue; + } + + case 0x41: + { + gfx3d_glEnd(); + --clInd; + clCmd>>=8; + continue; + } + } + + break; + } + + + if(!clInd) + { + clInd = 4; + clCmd = v; + return; + } + + switch(clCmd&0xFF) + { + case 0x10: + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x440>>2] = v; + gfx3d_glMatrixMode (v); + --clInd; + clCmd>>=8; + break; + } + + case 0x12: + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x448>>2] = v; + gfx3d_glPopMatrix(v); + --clInd; + clCmd>>=8; + break; + } + + case 0x13: + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x44C>>2] = v; + gfx3d_glStoreMatrix(v); + --clInd; + clCmd>>=8; + break; + } + + case 0x14: + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x450>>2] = v; + gfx3d_glRestoreMatrix (v); + --clInd; + clCmd>>=8; + break; + } + + case 0x16: + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x458>>2] = v; + gfx3d_glLoadMatrix4x4(v); + clInd2++; + if(clInd2==16) + { + --clInd; + clCmd>>=8; + clInd2 = 0; + } + break; + } + + case 0x17: + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x45C>>2] = v; + gfx3d_glLoadMatrix4x3(v); + clInd2++; + if(clInd2==12) + { + --clInd; + clCmd>>=8; + clInd2 = 0; + } + break; + } + + case 0x18: + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x460>>2] = v; + gfx3d_glMultMatrix4x4(v); + clInd2++; + if(clInd2==16) + { + --clInd; + clCmd>>=8; + clInd2 = 0; + } + break; + } + + case 0x19: + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x464>>2] = v; + gfx3d_glMultMatrix4x3(v); + clInd2++; + if(clInd2==12) + { + --clInd; + clCmd>>=8; + clInd2 = 0; + } + break; + } + + case 0x1A: + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x468>>2] = v; + gfx3d_glMultMatrix3x3(v); + clInd2++; + if(clInd2==9) + { + --clInd; + clCmd>>=8; + clInd2 = 0; + } + break; + } + + case 0x1B: + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x46C>>2] = v; + gfx3d_glScale (v); + clInd2++; + if(clInd2==3) + { + --clInd; + clCmd>>=8; + clInd2 = 0; + } + break; + } + + case 0x1C: + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x470>>2] = v; + gfx3d_glTranslate (v); + clInd2++; + if(clInd2==3) + { + --clInd; + clCmd>>=8; + clInd2 = 0; + } + break; + } + + case 0x20 : + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x480>>2] = v; + gfx3d_glColor3b(v); + --clInd; + clCmd>>=8; + break; + } + + case 0x21 : + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x484>>2] = v; + gfx3d_glNormal(v); + --clInd; + clCmd>>=8; + break; + } + + case 0x22 : + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x488>>2] = v; + gfx3d_glTexCoord(v); + --clInd; + clCmd>>=8; + break; + } + + case 0x23 : + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x48C>>2] = v; + gfx3d_glVertex16b(v); + clInd2++; + if(clInd2==2) + { + --clInd; + clCmd>>=8; + clInd2 = 0; + } + break; + } + + case 0x24: + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x490>>2] = v; + gfx3d_glVertex10b(v); + --clInd; + clCmd>>=8; + break; + } + + case 0x25:// GFX_VERTEX_XY + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x494>>2] = v; + gfx3d_glVertex3_cord(0,1,v); + --clInd; + clCmd>>=8; + break; + } + + case 0x26:// GFX_VERTEX_XZ + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x498>>2] = v; + gfx3d_glVertex3_cord(0,2,v); + --clInd; + clCmd>>=8; + break; + } + + case 0x27:// GFX_VERTEX_YZ + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x49C>>2] = v; + gfx3d_glVertex3_cord(1,2,v); + --clInd; + clCmd>>=8; + break; + } + + case 0x28: // GFX_VERTEX_DIFF + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x4A0>>2] = v; + gfx3d_glVertex_rel (v); + --clInd; + clCmd>>=8; + break; + } + + case 0x29: + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x4A4>>2] = v; + gfx3d_glPolygonAttrib (v); + --clInd; + clCmd>>=8; + break; + } + + case 0x2A: + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x4A8>>2] = v; + gfx3d_glTexImage (v); + --clInd; + clCmd>>=8; + break; + } + + case 0x2B: + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x4AC>>2] = v; + gfx3d_glTexPalette (v&0x1FFF); + --clInd; + clCmd>>=8; + break; + } + + case 0x30: // GFX_DIFFUSE_AMBIENT + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x4C0>>2] = v; + gfx3d_glMaterial0(v); + --clInd; + clCmd>>=8; + break; + } + + case 0x31: // GFX_SPECULAR_EMISSION + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x4C4>>2] = v; + gfx3d_glMaterial1(v); + --clInd; + clCmd>>=8; + break; + } + + case 0x32: + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x4C8>>2] = v; + gfx3d_glLightDirection(v); + --clInd; + clCmd>>=8; + break; + } + + case 0x33: + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x4CC>>2] = v; + gfx3d_glLightColor(v); + --clInd; + clCmd>>=8; + break; + } + + case 0x34: + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x4D0>>2] = v; + gfx3d_glShininess (v); + clInd2++; + if(clInd2==32) + { + --clInd; + clCmd>>=8; + clInd2 = 0; + } + break; + } + + case 0x40 : + { + //old_vtxFormat=((unsigned long *)ARM9Mem.ARM9_REG)[0x500>>2]; + ((unsigned long *)ARM9Mem.ARM9_REG)[0x500>>2] = v; + gfx3d_glBegin(v); + --clInd; + clCmd>>=8; + break; + } +/* + case 0x50: + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x540>>2] = v; + NDS_glFlush(v); + --clInd; + clCmd>>=8; + break; + } +*/ + case 0x60: + { + ((unsigned long *)ARM9Mem.ARM9_REG)[0x580>>2] = v; + gfx3d_glViewPort(v); + --clInd; + clCmd>>=8; + break; + } +/* + case 0x80: + { + clInd2++; + if(clInd2==7) + { + --clInd; + clCmd>>=8; + clInd2 = 0; + } + + break; + } +*/ + default: + { + LOG ("Unknown 3D command %02X\n", clCmd&0xFF); + --clInd; + clCmd>>=8; + break; + } + } + if((clCmd&0xFF)==0x41) + { + --clInd; + clCmd>>=8; + } +} + + +static bool flushPending = false; +static u32 flush_wbuffer; +static u32 flush_sortmode; + +void gfx3d_glFlush(unsigned long v) +{ + flushPending = true; + gfx3d.wbuffer = (v&1)!=0; + gfx3d.sortmode = ((v>>1)&1)!=0; + + //reset GE state + clCmd = 0; + clInd = 0; + + //the renderer wil lget the lists we just built + gfx3d.polylist = polylist; + gfx3d.vertlist = vertlist; + + //switch to the new lists + twiddleLists(); +} + +void gfx3d_VBlankSignal() +{ + //the 3d buffers are swapped when a vblank begins. + //so, if we have a redraw pending, now is a safe time to do it + if(!flushPending) return; + flushPending = false; + gpu3D->NDS_3D_Render(); +} + +void gfx3d_Control(unsigned long v) +{ + if(v&1) gfx3d.enableTexturing = true; + else gfx3d.enableTexturing = false; + + if((v>>1)&1) gfx3d.shading = GFX3D::HIGHLIGHT; + else gfx3d.shading = GFX3D::TOON; + + if((v>>2)&1) gfx3d.enableAlphaTest = true; + gfx3d.enableAlphaTest = false; + + if((v>>3)&1) gfx3d.enableAlphaBlending = true; + gfx3d.enableAlphaBlending = false; + + if((v>>4)&1) gfx3d.enableAntialiasing = true; + gfx3d.enableAntialiasing = false; + + if((v>>5)&1) gfx3d.enableEdgeMarking = true; + gfx3d.enableEdgeMarking = false; + + //other junk + + if (v&(1<<14)) + { + LOG("Enabled BITMAP background mode\n"); + } +} + +//-------------- +//other misc stuff +void gfx3d_glGetMatrix(unsigned int mode, unsigned int index, float* dest) +{ + //int n; + + if(index == -1) + { + MatrixCopy(dest, mtxCurrent[mode]); + return; + } + + MatrixCopy(dest, MatrixStackGetPos(&mtxStack[mode], index)); +} + +void gfx3d_glGetLightDirection(unsigned int index, unsigned int* dest) +{ + *dest = g_lightInfo[index].direction; +} + +void gfx3d_glGetLightColor(unsigned int index, unsigned int* dest) +{ + *dest = g_lightInfo[index].color; +} + diff --git a/desmume/src/gfx3d.h b/desmume/src/gfx3d.h new file mode 100644 index 000000000..9d06e59af --- /dev/null +++ b/desmume/src/gfx3d.h @@ -0,0 +1,160 @@ +/* + Copyright (C) 2008 DeSmuME team + + This file is part of DeSmuME + + DeSmuME is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DeSmuME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _GFX3D_H_ +#define _GFX3D_H_ + +#include "types.h" + +void gfx3d_init(); + +struct POLY { + int type; //tri or quad + int vertIndexes[4]; //up to four verts can be referenced by this poly + u32 polyAttr, texParam, texPalette; //the hardware rendering params + float projMatrix[16]; +}; + +#define POLYLIST_SIZE 6000 +//#define POLYLIST_SIZE 2048 +struct POLYLIST { + int count; + POLY list[POLYLIST_SIZE]; +}; + +struct VERT { + float coord[4]; + float texcoord[2]; + int color[4]; + u32 depth; +}; + +#define VERTLIST_SIZE 30000 +//#define VERTLIST_SIZE 10000 +struct VERTLIST { + int count; + VERT list[VERTLIST_SIZE]; +}; + +//used to communicate state to the renderer +struct GFX3D +{ + GFX3D() + : enableTexturing(true) + , shading(TOON) + , enableAlphaTest(true) + , enableAlphaBlending(true) + , enableAntialiasing(false) + , enableEdgeMarking(false) + , polylist(0) + , vertlist(0) + , alphaTestRef(0) + {} + bool enableTexturing, enableAlphaTest, enableAlphaBlending, enableAntialiasing, enableEdgeMarking; + + enum { + TOON, HIGHLIGHT + } shading; + + POLYLIST* polylist; + VERTLIST* vertlist; + + bool wbuffer, sortmode; + + float alphaTestRef; +}; +extern GFX3D gfx3d; + +//--------------------- + +//produce a 32bpp color from a DS RGB16 +#define RGB16TO32(col,alpha) (((alpha)<<24) | ((((col) & 0x7C00)>>7)<<16) | ((((col) & 0x3E0)>>2)<<8) | (((col) & 0x1F)<<3)) + +//produce a 32bpp color from a ds RGB15 plus an 8bit alpha, using a table +#define RGB15TO32(col,alpha8) ( ((alpha8)<<24) | color_15bit_to_24bit[col] ) + +//produce a 32bpp color from a ds RGB15 plus an 8bit alpha, not using a table (but using other tables) +#define RGB15TO32_DIRECT(col,alpha8) ( ((alpha8)<<24) | (material_5bit_to_8bit[((col)>>10)&0x1F]<<16) | (material_5bit_to_8bit[((col)>>5)&0x1F]<<8) | material_5bit_to_8bit[(col)&0x1F] ) + +extern u32 color_15bit_to_24bit[32768]; +extern const int material_5bit_to_31bit[32]; +extern const u8 material_5bit_to_8bit[32]; +extern const u8 material_3bit_to_8bit[8]; + +//GE commands: +void gfx3d_glViewPort(unsigned long v); +void gfx3d_glClearColor(unsigned long v); +void gfx3d_glFogColor(unsigned long v); +void gfx3d_glFogOffset (unsigned long v); +void gfx3d_glClearDepth(unsigned long v); +void gfx3d_glMatrixMode(unsigned long v); +void gfx3d_glLoadIdentity(); +void gfx3d_glLoadMatrix4x4(signed long v); +void gfx3d_glLoadMatrix4x3(signed long v); +void gfx3d_glStoreMatrix(unsigned long v); +void gfx3d_glRestoreMatrix(unsigned long v); +void gfx3d_glPushMatrix(void); +void gfx3d_glPopMatrix(signed long i); +void gfx3d_glTranslate(signed long v); +void gfx3d_glScale(signed long v); +void gfx3d_glMultMatrix3x3(signed long v); +void gfx3d_glMultMatrix4x3(signed long v); +void gfx3d_glMultMatrix4x4(signed long v); +void gfx3d_glBegin(unsigned long v); +void gfx3d_glEnd(void); +void gfx3d_glColor3b(unsigned long v); +void gfx3d_glVertex16b(unsigned int v); +void gfx3d_glVertex10b(unsigned long v); +void gfx3d_glVertex3_cord(unsigned int one, unsigned int two, unsigned int v); +void gfx3d_glVertex_rel(unsigned long v); +void gfx3d_glSwapScreen(unsigned int screen); +int gfx3d_GetNumPolys(); +int gfx3d_GetNumVertex(); +void gfx3d_glPolygonAttrib (unsigned long val); +void gfx3d_glMaterial0(unsigned long val); +void gfx3d_glMaterial1(unsigned long val); +void gfx3d_glShininess (unsigned long val); +void gfx3d_UpdateToonTable(void* toonTable); +void gfx3d_glTexImage(unsigned long val); +void gfx3d_glTexPalette(unsigned long val); +void gfx3d_glTexCoord(unsigned long val); +void gfx3d_glNormal(unsigned long v); +signed long gfx3d_GetClipMatrix (unsigned int index); +signed long gfx3d_GetDirectionalMatrix (unsigned int index); +void gfx3d_glLightDirection (unsigned long v); +void gfx3d_glLightColor (unsigned long v); +void gfx3d_glAlphaFunc(unsigned long v); +void gfx3d_glBoxTest(unsigned long v); +void gfx3d_glPosTest(unsigned long v); +void gfx3d_glVecTest(unsigned long v); +void gfx3d_glGetPosRes(unsigned int index); +void gfx3d_glGetVecRes(unsigned int index); +void gfx3d_glCallList(unsigned long v); +void gfx3d_glFlush(unsigned long v); +void gfx3d_VBlankSignal(); +void gfx3d_Control(unsigned long v); + +//other misc stuff +void gfx3d_glGetMatrix(unsigned int mode, unsigned int index, float* dest); +void gfx3d_glGetLightDirection(unsigned int index, unsigned int* dest); +void gfx3d_glGetLightColor(unsigned int index, unsigned int* dest); + + +#endif diff --git a/desmume/src/opengl_collector_3Demu.cpp b/desmume/src/opengl_collector_3Demu.cpp deleted file mode 100644 index 582f6b72c..000000000 --- a/desmume/src/opengl_collector_3Demu.cpp +++ /dev/null @@ -1,3149 +0,0 @@ -/* $Id: opengl_collector_3Demu.c,v 1.16 2007-06-27 14:48:07 masscat Exp $ - */ -/* - Copyright (C) 2006-2007 Ben Jaques, shash - - This file is part of DeSmuME - - DeSmuME is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - DeSmuME is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with DeSmuME; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * This is a 3D emulation plugin. It uses OpenGL to perform the rendering. - * There is no platform specific code. Platform specific code is executed - * via a set of helper functions that must be defined should a particular - * platform use this plugin. - * - * The NDS 3D commands are collected until the flush command is issued. At this - * point the OpenGL function calls that correspnd to the set of commands are called. - * This approach is taken to allowing simple OpenGL context switching should - * OpenGL also be being used for other purposes (for example rendering the screen). - */ - -/* - * FIXME: This is a Work In Progress - * - The NDS command set should be checked to to ensure that it corresponds to a - * valid OpenGL command sequence. - * - Two sets of matrices should be maintained (maybe). One for rendering and one - * for NDS test commands. Any matrix commands should be executed immediately on - * the NDS test matix set (as well as stored). - * - Most of the OpenGL/emulation stuff has been copied from shash's Windows - * 3D code. There maybe optimisations and/or problems arising from the change - * of approach or the cut and paste. - * - More of the 3D needs to be emulated (correctly or at all) :). - */ - -#ifdef HAVE_GL_GL_H -#ifdef HAVE_GL_GLU_H -#ifndef __MINGW32__ - -#include - -#include -#include - -#include "types.h" - -#include "render3D.h" -#include "matrix.h" -#include "MMU.h" -#include "bits.h" - -#include "opengl_collector_3Demu.h" - -#define LOG_ALWAYS( fmt, ...) fprintf( stdout, "OpenGL Collector: "); \ -fprintf( stdout, fmt, ##__VA_ARGS__) - -#if 0 -#define LOG( fmt, ...) fprintf( stdout, "OpenGL Collector: "); \ -fprintf( stdout, fmt, ##__VA_ARGS__) -#else -#define LOG( fmt, ...) -#endif - -#if 0 -#define LOG_TEXTURE( fmt, ...) fprintf( stdout, "OpenGL Collector texture: "); \ -fprintf( stdout, fmt, ##__VA_ARGS__) -#else -#define LOG_TEXTURE( fmt, ...) -#endif - -#if 0 -#define LOG_CALL_LIST( fmt, ...) fprintf( stdout, "OpenGL Collector: Call list: "); \ -fprintf( stdout, fmt, ##__VA_ARGS__) -#else -#define LOG_CALL_LIST( fmt, ...) -#endif - -#if 0 -#define LOG_ERROR( fmt, ...) fprintf( stdout, "OpenGL Collector error: "); \ -fprintf( stdout, fmt, ##__VA_ARGS__) -#else -#define LOG_ERROR( fmt, ...) -#endif - -#if 0 -#define LOG_MATRIX( matrix) \ -LOG_ALWAYS( "%f, %f, %f, %f\n", matrix[0], matrix[1], matrix[2], matrix[3]); \ -LOG_ALWAYS( "%f, %f, %f, %f\n", matrix[4], matrix[5], matrix[6], matrix[7]); \ -LOG_ALWAYS( "%f, %f, %f, %f\n", matrix[8], matrix[9], matrix[10], matrix[11]); \ -LOG_ALWAYS( "%f, %f, %f, %f\n", matrix[12], matrix[13], matrix[14], matrix[15]) -#else -#define LOG_MATRIX( matrix) -#endif - -#define USE_BGR_ORDER 1 - -/** - * Define this to use software vertex transformation. - * The NDS can handle commands to change the modelview matrix during - * primitive definitions (between the begin and end). OpenGL does - * not like this. - * When this is defined the Modelview matrix will be left as the - * identity matrix and vertices are transformed before being passed - * to OpenGL. - */ -#define USE_SOFTWARE_VERTEX_TRANSFORM 1 - -/** - * Define this to enable Alpha Blending emulation. - * How the NDS renders transulcent polygons (order) is not fully understood - * so some polygon may not be rendered or rendered incorrectly. - */ -#define ENABLE_ALPHA_BLENDING 1 - -/** the largest number of parameters used by any command */ -#define MAX_NUMBER_OF_PARMS 32 - -/* Define this if you want to perform the glReadPixel call - * immediately after the render completion. - * If undefined the glReadPixel is performed in get_line_3Dgl_collect - * when called for line 0. - * - * Reading the pixels immediately may cause change of frame during display. - * Not reading the pixels immediately may mean that a frame is displayed early. - */ -//#define READ_PIXELS_IMMEDIATELY 1 - -static int -not_set( void) { - LOG_ERROR( "platform code not setup\n"); - return 0; -} - -static void -nothingness( void) { -} - -static void -flush_only( void) { - glFlush(); -} - -int (*begin_opengl_ogl_collector_platform)( void) = not_set; -void (*end_opengl_ogl_collector_platform)( void) = nothingness; -int (*initialise_ogl_collector_platform)( void) = not_set; -void (*complete_render_ogl_collector_platform)( void) = flush_only; - - -#define fix2float(v) (((float)((s32)(v))) / (float)(1<<12)) -#define fix10_2float(v) (((float)((s32)(v))) / (float)(1<<9)) - - - -static u8 GPU_screen3D[256*256*4]={0}; - -static u8 stencil_buffer[256*192]; - -#ifndef READ_PIXELS_IMMEDIATELY -/** flag indicating if the 3D emulation has produced a new render */ -static int new_render_available = 0; -#endif - -/* - * The matrices - */ -static int current_matrix_mode = 0; -static MatrixStack mtxStack[4]; -static float mtxCurrent [4][16]; -static float mtxTemporal[16]; - -static u32 disp_3D_control = 0; - -static u32 textureFormat=0, texturePalette=0; -static u32 lastTextureFormat=0, lastTexturePalette=0; -static unsigned int oglTextureID=0; -static u8 texMAP[1024*2048*4], texMAP2[2048*2048*4]; -static float invTexWidth = 1.f; -static float invTexHeight = 1.f; -static int texCoordinateTransform = 0; -static int t_texture_coord = 0, s_texture_coord = 0; -static GLint colorRGB[4] = { 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}; -static float cur_vertex[3] = {0.0f, 0.0f, 0.0f}; - -static u32 alpha_function = 0; - -static float lightDirection[4][4]; -static int light_direction_valid = 0; -static GLint lightColor[4][4]; -static int light_colour_valid = 0; - -static u32 current_depth24b = 0; -static int depth24b_valid = 0; -static u32 current_clear_colour = 0; -static int clear_colour_valid = 0; - - -/** the current polygon attribute */ -static u32 current_polygon_attr = 0; - -/** flag set when a primitive is being defined */ -static int inside_primitive = 0; -/** the type of primitive being defined */ -static GLenum current_primitive_type; - - - -enum command_type { - NOP_CMD = 0x00, - MTX_MODE_CMD = 0x10, - MTX_PUSH_CMD = 0x11, - MTX_POP_CMD = 0x12, - MTX_STORE_CMD = 0x13, - MTX_RESTORE_CMD = 0x14, - MTX_IDENTITY_CMD = 0x15, - MTX_LOAD_4x4_CMD = 0x16, - MTX_LOAD_4x3_CMD = 0x17, - MTX_MULT_4x4_CMD = 0x18, - MTX_MULT_4x3_CMD = 0x19, - MTX_MULT_3x3_CMD = 0x1a, - MTX_SCALE_CMD = 0x1b, - MTX_TRANS_CMD = 0x1c, - COLOR_CMD = 0x20, - NORMAL_CMD = 0x21, - TEXCOORD_CMD = 0x22, - VTX_16_CMD = 0x23, - VTX_10_CMD = 0x24, - VTX_XY_CMD = 0x25, - VTX_XZ_CMD = 0x26, - VTX_YZ_CMD = 0x27, - VTX_DIFF_CMD = 0x28, - POLYGON_ATTR_CMD = 0x29, - TEXIMAGE_PARAM_CMD = 0x2a, - PLTT_BASE_CMD = 0x2b, - DIF_AMB_CMD = 0x30, - SPE_EMI_CMD = 0x31, - LIGHT_VECTOR_CMD = 0x32, - LIGHT_COLOR_CMD = 0x33, - SHININESS_CMD = 0x34, - BEGIN_VTXS_CMD = 0x40, - END_VTXS_CMD = 0x41, - SWAP_BUFFERS_CMD = 0x50, - VIEWPORT_CMD = 0x60, - BOX_TEST_CMD = 0x70, - POS_TEST_CMD = 0x71, - VEC_TEST_CMD = 0x72, - - /* The next ones are not NDS commands */ - CLEAR_COLOUR_CMD = 0x80, - CLEAR_DEPTH_CMD = 0x81, - FOG_COLOUR_CMD = 0x82, - FOG_OFFSET_CMD = 0x83, - CONTROL_CMD = 0x84, - ALPHA_FUNCTION_CMD = 0x85 -}; - -#define LAST_CMD_VALUE 0x84 - -#define ADD_RENDER_PARM_CMD( cmd) render_states[current_render_state].cmds[render_states[current_render_state].write_index++] = cmd - -static const char *primitive_type_names[] = { - "Triangles", - "Quads", - "Tri strip", - "Quad strip" -}; - -// Accelerationg tables -static float float16table[65536]; -static float float10Table[1024]; -static float float10RelTable[1024]; -static float normalTable[1024]; -static int numVertex = 0; - -#define NUM_RENDER_STATES 2 -int current_render_state; -static struct render_state { - int write_index; - - /* FIXME: how big to make this? */ - u32 cmds[100*1024]; - - //int cmds_drawn; -} render_states[NUM_RENDER_STATES]; - -#define GET_DRAW_STATE_INDEX( current_index) (((current_index) - 1) & (NUM_RENDER_STATES - 1)) -#define GET_NEXT_RENDER_STATE_INDEX( current_index) (((current_index) + 1) & (NUM_RENDER_STATES - 1)) - - -struct cmd_processor { - u32 num_parms; - void (*processor_fn)( struct render_state *state, - const u32 *parms); -}; -/*static int (*cmd_processors[LAST_CMD_VALUE+1])( struct render_state *state, - const u32 *parms); -*/ -static struct cmd_processor cmd_processors[LAST_CMD_VALUE+1]; - - - - - - - -static void -set_gl_matrix_mode( int mode) { - switch ( mode & 0x3) { - case 0: - glMatrixMode( GL_PROJECTION); - break; - - case 1: - glMatrixMode( GL_MODELVIEW); - break; - - case 2: - /* FIXME: more here? */ - glMatrixMode( GL_MODELVIEW); - break; - - case 3: - //glMatrixMode( GL_TEXTURE); - break; - } -} - -static void -loadMatrix( float *matrix) { -#ifdef USE_SOFTWARE_VERTEX_TRANSFORM - if ( current_matrix_mode == 0) -#endif - glLoadMatrixf( matrix); -} - - -static int -SetupTexture (unsigned int format, unsigned int palette) { - int alpha_texture = 0; - if(format == 0) // || disableTexturing) - { - LOG("Texture format is zero\n"); - glDisable (GL_TEXTURE_2D); - return 0; - } - else - { - unsigned short *pal = NULL; - unsigned int sizeX = (1<<(((format>>20)&0x7)+3)); - unsigned int sizeY = (1<<(((format>>23)&0x7)+3)); - unsigned int mode = (unsigned short)((format>>26)&0x7); - const unsigned char * adr; - //unsigned short param = (unsigned short)((format>>30)&0xF); - //unsigned short param2 = (unsigned short)((format>>16)&0xF); - unsigned int imageSize = sizeX*sizeY; - unsigned int paletteSize = 0; - unsigned int palZeroTransparent = BIT29(format) ? 0 : 255; - unsigned int x=0, y=0; - u32 bytes_in_slot; - u32 orig_bytes_in_slot; - int current_slot = (format >> 14) & 3; - - /* Get the address within the texture slot */ - adr = ARM9Mem.textureSlotAddr[current_slot]; - adr += (format&0x3FFF) << 3; - - bytes_in_slot = 0x20000 - ((format & 0x3fff) << 3); - orig_bytes_in_slot = bytes_in_slot; - - if ( BIT29(format) && mode != 0) { - alpha_texture = 1; - } - - LOG_TEXTURE("Texture %08x: size %d by %d\n", format, sizeX, sizeY); - - if (mode == 0) - glDisable (GL_TEXTURE_2D); - else - glEnable (GL_TEXTURE_2D); - - switch(mode) - { - case 1: - { - alpha_texture = 1; - paletteSize = 256; - pal = (unsigned short *)(ARM9Mem.texPalSlot[0] + (texturePalette<<4)); - break; - } - case 2: - { - paletteSize = 4; - pal = (unsigned short *)(ARM9Mem.texPalSlot[0] + (texturePalette<<3)); - imageSize >>= 2; - break; - } - case 3: - { - paletteSize = 16; - pal = (unsigned short *)(ARM9Mem.texPalSlot[0] + (texturePalette<<4)); - imageSize >>= 1; - break; - } - case 4: - { - paletteSize = 256; - pal = (unsigned short *)(ARM9Mem.texPalSlot[0] + (texturePalette<<4)); - break; - } - case 5: - { - alpha_texture = 1; - paletteSize = 0; - pal = (unsigned short *)(ARM9Mem.texPalSlot[0] + (texturePalette<<4)); - break; - } - case 6: - { - alpha_texture = 1; - paletteSize = 256; - pal = (unsigned short *)(ARM9Mem.texPalSlot[0] + (texturePalette<<4)); - break; - } - case 7: - { - alpha_texture = 1; - paletteSize = 0; - break; - } - } - - //if (!textureCache.IsCached((u8*)pal, paletteSize, adr, imageSize, mode, palZeroTransparent)) - { - unsigned char * dst = texMAP;// + sizeX*sizeY*3; - - LOG_TEXTURE("Setting up texture mode %d\n", mode); - - switch(mode) - { - case 1: - { - for(x = 0; x < imageSize; x++, dst += 4) - { - unsigned short c = pal[adr[x]&31], alpha = (adr[x]>>5); - dst[0] = (unsigned char)((c & 0x1F)<<3); - dst[1] = (unsigned char)((c & 0x3E0)>>2); - dst[2] = (unsigned char)((c & 0x7C00)>>7); - dst[3] = ((alpha<<2)+(alpha>>1))<<3; - if ( dst[3] != 0) { - /* full range alpha */ - dst[3] |= 0x7; - } - - /* transverse to the next texture slot if needs be */ - bytes_in_slot -= 1; - if ( bytes_in_slot == 0) { - current_slot += 1; - adr = ARM9Mem.textureSlotAddr[current_slot]; - adr -= orig_bytes_in_slot; - bytes_in_slot = 0x20000; - orig_bytes_in_slot = bytes_in_slot; - } - } - - break; - } - case 2: - { - for(x = 0; x < imageSize; ++x) - { - unsigned short c = pal[(adr[x])&0x3]; - dst[0] = ((c & 0x1F)<<3); - dst[1] = ((c & 0x3E0)>>2); - dst[2] = ((c & 0x7C00)>>7); - dst[3] = ((adr[x]&3) == 0) ? palZeroTransparent : 255;//(c>>15)*255; - dst += 4; - - c = pal[((adr[x])>>2)&0x3]; - dst[0] = ((c & 0x1F)<<3); - dst[1] = ((c & 0x3E0)>>2); - dst[2] = ((c & 0x7C00)>>7); - dst[3] = (((adr[x]>>2)&3) == 0) ? palZeroTransparent : 255;//(c>>15)*255; - dst += 4; - - c = pal[((adr[x])>>4)&0x3]; - dst[0] = ((c & 0x1F)<<3); - dst[1] = ((c & 0x3E0)>>2); - dst[2] = ((c & 0x7C00)>>7); - dst[3] = (((adr[x]>>4)&3) == 0) ? palZeroTransparent : 255;//(c>>15)*255; - dst += 4; - - c = pal[(adr[x])>>6]; - dst[0] = ((c & 0x1F)<<3); - dst[1] = ((c & 0x3E0)>>2); - dst[2] = ((c & 0x7C00)>>7); - dst[3] = (((adr[x]>>6)&3) == 0) ? palZeroTransparent : 255;//(c>>15)*255; - dst += 4; - - /* transverse to the next texture slot if needs be */ - bytes_in_slot -= 1; - if ( bytes_in_slot == 0) { - current_slot += 1; - adr = ARM9Mem.textureSlotAddr[current_slot]; - adr -= orig_bytes_in_slot; - bytes_in_slot = 0x20000; - orig_bytes_in_slot = bytes_in_slot; - } - } - } - break; - case 3: - { - for(x = 0; x < imageSize; x++) - { - unsigned short c = pal[adr[x]&0xF]; - dst[0] = ((c & 0x1F)<<3); - dst[1] = ((c & 0x3E0)>>2); - dst[2] = ((c & 0x7C00)>>7); - dst[3] = (((adr[x])&0xF) == 0) ? palZeroTransparent : 255;//(c>>15)*255; - dst += 4; - - c = pal[((adr[x])>>4)]; - dst[0] = ((c & 0x1F)<<3); - dst[1] = ((c & 0x3E0)>>2); - dst[2] = ((c & 0x7C00)>>7); - dst[3] = (((adr[x]>>4)&0xF) == 0) ? palZeroTransparent : 255;//(c>>15)*255; - dst += 4; - - /* transverse to the next texture slot if needs be */ - bytes_in_slot -= 1; - if ( bytes_in_slot == 0) { - current_slot += 1; - adr = ARM9Mem.textureSlotAddr[current_slot]; - adr -= orig_bytes_in_slot; - bytes_in_slot = 0x20000; - orig_bytes_in_slot = bytes_in_slot; - } - } - } - break; - - case 4: - { - for(x = 0; x < imageSize; ++x) - { - unsigned short c = pal[adr[x]]; - //LOG_TEXTURE("mode 4: x %d colour %04x index %d\n", x, c, adr[x]); - dst[0] = (unsigned char)((c & 0x1F)<<3); - dst[1] = (unsigned char)((c & 0x3E0)>>2); - dst[2] = (unsigned char)((c & 0x7C00)>>7); - dst[3] = (adr[x] == 0) ? palZeroTransparent : 255;//(c>>15)*255; - dst += 4; - - /* transverse to the next texture slot if needs be */ - bytes_in_slot -= 1; - if ( bytes_in_slot == 0) { - current_slot += 1; - adr = ARM9Mem.textureSlotAddr[current_slot]; - adr -= orig_bytes_in_slot; - bytes_in_slot = 0x20000; - orig_bytes_in_slot = bytes_in_slot; - } - } - } - break; - - case 5: - { - unsigned short * pal = - (unsigned short *)(ARM9Mem.texPalSlot[0] + (texturePalette<<4)); - const unsigned short * slot1; - const unsigned int * map = (const unsigned int *)adr; - unsigned int i = 0; - unsigned int * dst = (unsigned int *)texMAP; - - if ( (format & 0xc000) == 0x8000) { - /* texel are in slot 2 */ - slot1 = - (const unsigned short*) - &ARM9Mem.textureSlotAddr[1][((format&0x3FFF)<<2) + 0x10000]; - //LOG_TEXTURE("slot 2 compressed \n"); - } - else { - slot1 = - (const unsigned short*) - &ARM9Mem.textureSlotAddr[1][((format&0x3FFF)<<2) + 0x00000]; - //LOG_TEXTURE("slot 0 compressed\n"); - } - - //LOG_TEXTURE("Compressed texture\n"); - for (y = 0; y < (sizeY/4); y ++) - { - for (x = 0; x < (sizeX/4); x ++, i++) - { - u32 currBlock = map[i], sy; - u16 pal1 = slot1[i]; - u16 pal1offset = (pal1 & 0x3FFF)<<1; - u8 mode = pal1>>14; - u32 colours[4]; - - /* - * Setup the colours: - * In all modes the first two colours are read from - * the palette. - */ -#define RGB16TO32(col,alpha) (((alpha)<<24) | ((((col) & 0x7C00)>>7)<<16) | \ - ((((col) & 0x3E0)>>2)<<8) | (((col) & 0x1F)<<3)) - colours[0] = RGB16TO32( pal[pal1offset + 0], 255); - colours[1] = RGB16TO32( pal[pal1offset + 1], 255); - - switch ( mode) { - case 0: - /* colour 2 is read from the palette - * colour 3 is transparent - */ - colours[2] = RGB16TO32( pal[pal1offset+2], 255); - colours[3] = RGB16TO32( 0x7fff, 0); - break; - - case 1: - /* colour 2 is half colour 0 + half colour 1 - * colour 3 is transparent - */ - colours[2] = - /* RED */ - (((colours[0] & 0xff) + - (colours[1] & 0xff)) >> 1) | - /* GREEN */ - (((colours[0] & (0xff << 8)) + - (colours[1] & (0xff << 8))) >> 1) | - /* BLUE */ - (((colours[0] & (0xff << 16)) + - (colours[1] & (0xff << 16))) >> 1) | (0xff << 24); - colours[3] = RGB16TO32( 0x7fff, 0); - break; - - case 2: - /* colour 2 is read from the palette - * colour 3 is read from the palette - */ - colours[2] = RGB16TO32( pal[pal1offset+2], 255); - colours[3] = RGB16TO32( pal[pal1offset+3], 255); - break; - - case 3: { - /* colour 2 is (colour0 * 5 + colour1 * 3) / 8 - * colour 3 is (colour1 * 5 + colour0 * 3) / 8 - */ - u32 red0, red1; - u32 green0, green1; - u32 blue0, blue1; - u16 colour2, colour3; - - red0 = colours[0] & 0xff; - green0 = (colours[0] >> 8) & 0xff; - blue0 = (colours[0] >> 16) & 0xff; - - red1 = colours[1] & 0xff; - green1 = (colours[1] >> 8) & 0xff; - blue1 = (colours[1] >> 16) & 0xff; - - colour2 = - /* red */ - ((red0 * 5 + red1 * 3) >> 6) | - /* green */ - (((green0 * 5 + green1 * 3) >> 6) << 5) | - /* blue */ - (((blue0 * 5 + blue1 * 3) >> 6) << 10); - colour3 = - /* red */ - ((red1 * 5 + red0 * 3) >> 6) | - /* green */ - (((green1 * 5 + green0 * 3) >> 6) << 5) | - /* blue */ - (((blue1 * 5 + blue0 * 3) >> 6) << 10); - - colours[2] = RGB16TO32( colour2, 255); - colours[3] = RGB16TO32( colour3, 255); - break; - } - } - - for (sy = 0; sy < 4; sy++) - { - // Texture offset - u32 xAbs = (x<<2); - u32 yAbs = ((y<<2) + sy); - u32 currentPos = xAbs + yAbs*sizeX; - - // Palette - u8 currRow = (u8)((currBlock >> (sy*8)) & 0xFF); - - dst[currentPos+0] = colours[(currRow >> (2 * 0)) & 3]; - dst[currentPos+1] = colours[(currRow >> (2 * 1)) & 3]; - dst[currentPos+2] = colours[(currRow >> (2 * 2)) & 3]; - dst[currentPos+3] = colours[(currRow >> (2 * 3)) & 3]; - } - - /* transverse to the next texture slot if needs be */ - bytes_in_slot -= 4; - if ( bytes_in_slot == 0) { - current_slot += 1; - map = - (const unsigned int *)ARM9Mem.textureSlotAddr[current_slot]; - map -= orig_bytes_in_slot >> 2; - bytes_in_slot = 0x20000; - orig_bytes_in_slot = bytes_in_slot; - } - } - } - break; - } - case 6: - { - for(x = 0; x < imageSize; x++) - { - unsigned short c = pal[adr[x]&7]; - dst[0] = (unsigned char)((c & 0x1F)<<3); - dst[1] = (unsigned char)((c & 0x3E0)>>2); - dst[2] = (unsigned char)((c & 0x7C00)>>7); - dst[3] = (adr[x]&0xF8); - if ( dst[3] != 0) { - /* full range alpha */ - dst[3] |= 0x7; - } - dst += 4; - - /* transverse to the next texture slot if needs be */ - bytes_in_slot -= 1; - if ( bytes_in_slot == 0) { - current_slot += 1; - adr = ARM9Mem.textureSlotAddr[current_slot]; - adr -= orig_bytes_in_slot; - bytes_in_slot = 0x20000; - orig_bytes_in_slot = bytes_in_slot; - } - } - break; - } - case 7: - { - const unsigned short * map = ((const unsigned short *)adr); - for(x = 0; x < imageSize; ++x) - { - unsigned short c = map[x]; - dst[0] = ((c & 0x1F)<<3); - dst[1] = ((c & 0x3E0)>>2); - dst[2] = ((c & 0x7C00)>>7); - dst[3] = (c>>15)*255; - dst += 4; - - /* transverse to the next texture slot if needs be */ - bytes_in_slot -= 2; - if ( bytes_in_slot == 0) { - current_slot += 1; - map = (const unsigned short *)ARM9Mem.textureSlotAddr[current_slot]; - map -= orig_bytes_in_slot >> 1; - bytes_in_slot = 0x20000; - orig_bytes_in_slot = bytes_in_slot; - } - } - } - break; - } - - glBindTexture(GL_TEXTURE_2D, oglTextureID); - glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, sizeX, sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, texMAP); - //textureCache.SetTexture ( texMAP, sizeX, sizeY, (u8*)pal, paletteSize, adr, imageSize, mode, palZeroTransparent); - - /* - switch ((format>>18)&3) - { - case 0: - { - textureCache.SetTexture ( texMAP, sizeX, sizeY, (u8*)pal, paletteSize, adr, imageSize, mode); - break; - } - - case 1: - { - u32 *src = (u32*)texMAP, *dst = (u32*)texMAP2; - - for (int y = 0; y < sizeY; y++) - { - for (int x = 0; x < sizeX; x++) - { - dst[y*sizeX*2 + x] = dst[y*sizeX*2 + (sizeX*2-x-1)] = src[y*sizeX + x]; - } - } - - sizeX <<= 1; - textureCache.SetTexture ( texMAP2, sizeX, sizeY, (u8*)pal, paletteSize, adr, imageSize, mode); - break; - } - - case 2: - { - u32 *src = (u32*)texMAP; - - for (int y = 0; y < sizeY; y++) - { - memcpy (&src[(sizeY*2-y-1)*sizeX], &src[y*sizeX], sizeX*4); - } - - sizeY <<= 1; - textureCache.SetTexture ( texMAP, sizeX, sizeY, (u8*)pal, paletteSize, adr, imageSize, mode); - break; - } - - case 3: - { - u32 *src = (u32*)texMAP, *dst = (u32*)texMAP2; - - for (int y = 0; y < sizeY; y++) - { - for (int x = 0; x < sizeX; x++) - { - dst[y*sizeX*2 + x] = dst[y*sizeX*2 + (sizeX*2-x-1)] = src[y*sizeX + x]; - } - } - - sizeX <<= 1; - - for (int y = 0; y < sizeY; y++) - { - memcpy (&dst[(sizeY*2-y-1)*sizeX], &dst[y*sizeX], sizeX*4); - } - - sizeY <<= 1; - textureCache.SetTexture ( texMAP2, sizeX, sizeY, (u8*)pal, paletteSize, adr, imageSize, mode); - break; - } - } - */ - } - - invTexWidth = 1.f/((float)sizeX*(1<<4));//+ 1; - invTexHeight = 1.f/((float)sizeY*(1<<4));//+ 1; - - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - glMatrixMode (GL_TEXTURE); - glLoadIdentity (); - glScaled (invTexWidth, invTexHeight, 1.f); - - set_gl_matrix_mode( current_matrix_mode); - - // S Coordinate options - if (!BIT16(format)) - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP); - else { - if ( BIT18(format)) { - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_MIRRORED_REPEAT); - } - else { - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); - } - } - - // T Coordinate options - if (!BIT17(format)) - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP); - else { - if ( BIT19(format)) { - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_MIRRORED_REPEAT); - } - else { - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); - } - } - - texCoordinateTransform = (format>>30); - } - - return alpha_texture; -} - - -static void -setup_mode23_tex_coord( float *vertex) { - float *textureMatrix = mtxCurrent[3]; - int s2 = (int)(( vertex[0] * textureMatrix[0] + - vertex[1] * textureMatrix[4] + - vertex[2] * textureMatrix[8]) + s_texture_coord); - int t2 = (int)(( vertex[0] * textureMatrix[1] + - vertex[1] * textureMatrix[5] + - vertex[2] * textureMatrix[9]) + t_texture_coord); - - /*LOG_TEXTURE("mode23 texcoord %d,%d -> %d,%d\n", - s_texture_coord, t_texture_coord, - s2, t2);*/ - - glTexCoord2i( s2, t2); -} - - -static INLINE void -setup_vertex( float *vertex) { -#ifdef USE_SOFTWARE_VERTEX_TRANSFORM - float transformed_vertex[4]; -#endif - - LOG("vertex %f,%f,%f\n", vertex[0], vertex[1], vertex[2]); - - if (texCoordinateTransform == 3) - { - setup_mode23_tex_coord( vertex); - } - -#ifdef USE_SOFTWARE_VERTEX_TRANSFORM - /* - * Transform the vertex - */ - transformed_vertex[0] = vertex[0]; - transformed_vertex[1] = vertex[1]; - transformed_vertex[2] = vertex[2]; - transformed_vertex[3] = 1.0f; - MatrixMultVec4x4( mtxCurrent[1], transformed_vertex); - - glVertex4fv( transformed_vertex); -#else - glVertex3fv( vertex); -#endif - - numVertex += 1; -} - - -static INLINE void -handle_polygon_attribute( u32 attr, u32 control) { - static const int texEnv[4] = { GL_MODULATE, GL_DECAL, GL_MODULATE, GL_MODULATE }; - static const int depthFunc[2] = { GL_LESS, GL_EQUAL }; - static const unsigned short map3d_cull[4] = {GL_FRONT_AND_BACK, GL_FRONT, GL_BACK, 0}; - u32 light_mask = attr & 0xf; - u32 cullingMask; - GLint colorAlpha; - - //LOG_ALWAYS("poly attr %08x control %08x\n", attr, control); - /*LOG_ALWAYS("id %d alpha %d mode %d\n", - (attr >> 24) & 0x3f, - (attr >> 16) & 0x1f, - (attr >> 4) & 0x3);*/ - - /* - * lighting - * (should be done at the normal?) - */ - if ( light_mask) { - if ( light_mask & 1) { - LOG("enabling light 0\n"); - glEnable (GL_LIGHT0); - } - else { - LOG("disabling light 0\n"); - glDisable(GL_LIGHT0); - } - if ( light_mask & 2) { - LOG("enabling light 1\n"); - glEnable (GL_LIGHT1); - } - else { - LOG("disabling light 1\n"); - glDisable(GL_LIGHT1); - } - if ( light_mask & 4) { - LOG("enabling light 2\n"); - glEnable (GL_LIGHT2); - } - else { - LOG("disabling light 2\n"); - glDisable(GL_LIGHT2); - } - if ( light_mask & 8) { - LOG("enabling light 3\n"); - glEnable (GL_LIGHT3); - } - else { - LOG("disabling light 3\n"); - glDisable(GL_LIGHT3); - } - - glEnable (GL_LIGHTING); - //glEnable (GL_COLOR_MATERIAL); - } - else { - LOG( "Disabling lighting\n"); - glDisable (GL_LIGHTING); - } - - /* - * texture environment - */ - glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texEnv[(attr & 0x30)>>4]); - - /* - * depth function - */ - glDepthFunc( depthFunc[BIT14(attr)]); - - /* - * Cull face - */ - cullingMask = (attr & 0xC0); - if (cullingMask != 0xC0) { - glEnable(GL_CULL_FACE); - glCullFace(map3d_cull[cullingMask>>6]); - } - else { - glDisable(GL_CULL_FACE); - } - - /* - * Alpha value, actually not well handled, 0 should be wireframe - * - * FIXME: How are translucent polygons rendered? - * some use of polygon ID? - */ - glDepthMask( GL_TRUE); - colorAlpha = (attr>>16) & 0x1F; - if ( colorAlpha != 0) { - colorAlpha = (colorAlpha << 26) | 0x3ffffff; -#if 0 - if ( colorAlpha != 0x7fffffff) { - if ( !BIT11( attr)) { - glDepthMask( GL_FALSE); - } - } -#endif - colorRGB[3] = colorAlpha; - glColor4iv (colorRGB); - } - - - /* - * Alpha blending - */ -#ifdef ENABLE_ALPHA_BLENDING - if ( BIT3(control)) { - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable( GL_BLEND); - } - else { - glDisable( GL_BLEND); - } -#endif -} - - - -static void -process_begin_vtxs( struct render_state *state, - const u32 *parms) { - u32 prim_type = parms[0] & 0x3; - static int alpha_texture = 0; - - LOG("Begin: %s\n", primitive_type_names[prim_type]); - - if ( inside_primitive) { - LOG( "implicit primitive end\n"); - glEnd(); - } - - if ( depth24b_valid) { - glClearDepth( current_depth24b / ((float)(1<<24))); - depth24b_valid = 0; - } - - if ( clear_colour_valid) { - glClearColor( ((float)( current_clear_colour & 0x1F))/31.0f, - ((float)(( current_clear_colour >> 5)&0x1F))/31.0f, - ((float)(( current_clear_colour >> 10)&0x1F))/31.0f, - ((float)(( current_clear_colour >> 16)&0x1F))/31.0f); - clear_colour_valid = 0; - } - - if ( light_colour_valid) { - int light; - - for ( light = 0; light < 4; light++) { - if ( light_colour_valid & (1 << light)) { - glLightiv (GL_LIGHT0 + light, GL_AMBIENT, lightColor[light]); - glLightiv (GL_LIGHT0 + light, GL_DIFFUSE, lightColor[light]); - glLightiv (GL_LIGHT0 + light, GL_SPECULAR, lightColor[light]); - } - } - light_colour_valid = 0; - } - - if ( light_direction_valid) { - int light; - - for ( light = 0; light < 4; light++) { - if ( light_direction_valid & (1 << light)) { - glLightfv(GL_LIGHT0 + light, GL_POSITION, lightDirection[light]); - } - } - light_direction_valid = 0; - } - -#if 1 - /* FIXME: ignoring shadow polygons for now */ - if ( ((current_polygon_attr >> 4) & 0x3) == 3) { - return; - } -#endif - - if( disp_3D_control & (1<<2)) - { - LOG("Alpha test enabled\n"); - glEnable(GL_ALPHA_TEST); - glAlphaFunc (GL_GREATER, (alpha_function&31)/31.f); - } - else - { - glDisable(GL_ALPHA_TEST); - } - - - /* - * Setup for the current polygon attribute - */ - handle_polygon_attribute( current_polygon_attr, disp_3D_control); - - - /* setup the texture */ -#if 0 - glDisable (GL_TEXTURE_2D); -#else - if ( disp_3D_control & 0x1) { - if (textureFormat != lastTextureFormat || - texturePalette != lastTexturePalette) - { - LOG("Setting up texture %08x\n", textureFormat); - alpha_texture = SetupTexture (textureFormat, texturePalette); - - lastTextureFormat = textureFormat; - lastTexturePalette = texturePalette; - } - -#if 1 - /* FIXME: this is a hack to get some transparent textures to work */ - if ( alpha_texture) { - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, 0.0f); - } -#endif - - } - else { - glDisable (GL_TEXTURE_2D); - } -#endif - - inside_primitive = 1; - switch (prim_type) { - case 0: - current_primitive_type = GL_TRIANGLES; - glBegin( GL_TRIANGLES); - break; - case 1: - current_primitive_type = GL_QUADS; - glBegin( GL_QUADS); - break; - case 2: - current_primitive_type = GL_TRIANGLE_STRIP; - glBegin( GL_TRIANGLE_STRIP); - break; - case 3: - current_primitive_type = GL_QUAD_STRIP; - glBegin( GL_QUAD_STRIP); - break; - } -} - -static void -process_end_vtxs( struct render_state *state, - const u32 *parms) { - LOG("End\n"); - if ( inside_primitive) { - glEnd(); - } - else { - LOG("End whilst not inside primitive\n"); - } - inside_primitive = 0; -} - -static void -process_viewport( struct render_state *state, - const u32 *parms) { - LOG("Viewport %d,%d,%d,%d\n", parms[0] & 0xff, (parms[0] >> 8) & 0xff, - (parms[0] >> 16) & 0xff, (parms[0] >> 24) & 0xff); - glViewport( (parms[0]&0xFF), ((parms[0]>>8)&0xFF), - ((parms[0]>>16)&0xFF) + 1, (parms[0]>>24) + 1); - -} - -static void -process_polygon_attr( struct render_state *state, - const u32 *parms) { - LOG("polygon attr %08x\n", parms[0]); - - /* - * Save this until the next begin - */ - current_polygon_attr = parms[0]; -} - -static void -process_normal( struct render_state *state, - const u32 *parms) { - LOG("Normal %08x\n", parms[0]); - - float normal[3] = { - normalTable[parms[0] &1023], - normalTable[(parms[0]>>10)&1023], - normalTable[(parms[0]>>20)&1023] - }; - - if (texCoordinateTransform == 2) - { - setup_mode23_tex_coord( normal); - } - - /* transform the vector */ - MatrixMultVec3x3( mtxCurrent[2], normal); - - glNormal3fv(normal); -} - -static void -process_teximage_param( struct render_state *state, - const u32 *parms) { - LOG("texture param %08x\n", parms[0]); - - textureFormat = parms[0]; -} - -static void -process_pltt_base( struct render_state *state, - const u32 *parms) { - LOG("texture palette base %08x\n", parms[0]); - - texturePalette = parms[0]; -} - - -static void -process_dif_amb( struct render_state *state, - const u32 *parms) { - GLint diffuse[4] = { - (parms[0] & 0x1F) << 26, - ((parms[0] >> 5) & 0x1F) << 26, - ((parms[0] >> 10) & 0x1F) << 26, - 0x7fffffff }; - GLint ambient[4] = { - ((parms[0] >> 16) & 0x1F) << 26, - ((parms[0] >> 21) & 0x1F) << 26, - ((parms[0] >> 26) & 0x1F) << 26, - 0x7fffffff }; - - LOG("dif amb %08x\n", parms[0]); - - if ( diffuse[0] != 0) - diffuse[0] |= 0x3ffffff; - if ( diffuse[1] != 0) - diffuse[1] |= 0x3ffffff; - if ( diffuse[2] != 0) - diffuse[2] |= 0x3ffffff; - - if ( ambient[0] != 0) - ambient[0] |= 0x3ffffff; - if ( ambient[1] != 0) - ambient[1] |= 0x3ffffff; - if ( ambient[2] != 0) - ambient[2] |= 0x3ffffff; - - - if (BIT15(parms[0])) { - colorRGB[0] = diffuse[0]; - colorRGB[1] = diffuse[1]; - colorRGB[2] = diffuse[2]; - } - - glMaterialiv (GL_FRONT_AND_BACK, GL_AMBIENT, ambient); - glMaterialiv (GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); -} - - -static void -process_spe_emi( struct render_state *state, - const u32 *parms) { - GLint specular[4] = { - (parms[0]&0x1F) << 26, - ((parms[0]>>5)&0x1F) << 26, - ((parms[0]>>10)&0x1F) << 26, - 0x7fffffff }; - GLint emission[4] = { - ((parms[0]>>16)&0x1F) << 26, - ((parms[0]>>21)&0x1F) << 26, - ((parms[0]>>26)&0x1F) << 26, - 0x7fffffff }; - - if ( specular[0] != 0) - specular[0] |= 0x3ffffff; - if ( specular[1] != 0) - specular[1] |= 0x3ffffff; - if ( specular[2] != 0) - specular[2] |= 0x3ffffff; - - if ( emission[0] != 0) - emission[0] |= 0x3ffffff; - if ( emission[1] != 0) - emission[1] |= 0x3ffffff; - if ( emission[2] != 0) - emission[2] |= 0x3ffffff; - - - LOG("spe emi %08x\n", parms[0]); - - glMaterialiv (GL_FRONT_AND_BACK, GL_SPECULAR, specular); - glMaterialiv (GL_FRONT_AND_BACK, GL_EMISSION, emission); -} - -static void -process_light_vector( struct render_state *state, - const u32 *parms) { - int light = parms[0] >> 30; - lightDirection[light][0] = -normalTable[parms[0]&1023]; - lightDirection[light][1] = -normalTable[(parms[0]>>10)&1023]; - lightDirection[light][2] = -normalTable[(parms[0]>>20)&1023]; - lightDirection[light][3] = 0.0f; - - LOG("Light vector %f,%f,%f,%f (%08x)\n", - lightDirection[light][0], lightDirection[light][1], - lightDirection[light][2], lightDirection[light][3], - parms[0]); - - MatrixMultVec3x3( mtxCurrent[2], lightDirection[light]); - - /* - * FIXME: - * Delay until the next normal command. - * Can this change inside a primative? - */ - if ( inside_primitive) { - //LOG_ALWAYS( "Light vector change whilst inside primative\n"); - /* - * Save until the 'begin' command - */ - light_direction_valid |= 1 << light; - } - else { - glLightfv(GL_LIGHT0 + light, GL_POSITION, lightDirection[light]); - light_direction_valid &= ~(1 << light); - } -} - -static void -process_light_color( struct render_state *state, - const u32 *parms) { - int light = parms[0] >> 30; - lightColor[light][0] = ((parms[0]) & 0x1F)<<26; - lightColor[light][1] = ((parms[0]>> 5)&0x1F)<<26; - lightColor[light][2] = ((parms[0]>> 10)&0x1F)<<26; - lightColor[light][3] = 0x7fffffff; - - LOG("Light color %08x\n", parms[0]); - - /* - * FIXME: - * Delay until the next normal command. - * Can this change inside a primative? - */ - if ( inside_primitive) { - //LOG_ALWAYS( "Light colour change whilst inside primative\n"); - /* - * Save until the 'begin' command - */ - light_colour_valid |= 1 << light; - } - else { - glLightiv (GL_LIGHT0 + light, GL_AMBIENT, lightColor[light]); - glLightiv (GL_LIGHT0 + light, GL_DIFFUSE, lightColor[light]); - glLightiv (GL_LIGHT0 + light, GL_SPECULAR, lightColor[light]); - light_colour_valid &= ~(1 << light); - } -} - - -static void -process_texcoord( struct render_state *state, - const u32 *parms) { - LOG("texture coord %08x\n", parms[0]); - - t_texture_coord = (s16)(parms[0] >> 16); - s_texture_coord = (s16)(parms[0] & 0xFFFF); - - if ( texCoordinateTransform == 1) - { - float *textureMatrix = mtxCurrent[3]; - int s2 =(int)( s_texture_coord * textureMatrix[0] + - t_texture_coord * textureMatrix[4] + - (1.f/16.f) * textureMatrix[8] + - (1.f/16.f) * textureMatrix[12]); - int t2 =(int)( s_texture_coord * textureMatrix[1] + - t_texture_coord * textureMatrix[5] + - (1.f/16.f) * textureMatrix[9] + - (1.f/16.f) * textureMatrix[13]); - - /*LOG_TEXTURE("texture coord (pre-trans) s=%d t=%d\n", - s_texture_coord, t_texture_coord); - LOG_MATRIX( textureMatrix); - LOG_TEXTURE("texture coord (trans) s=%d t=%d\n", s2, t2);*/ - glTexCoord2i (s2, t2); - } - else - { - /*LOG_TEXTURE("texture coord s=%d t=%d\n", s_texture_coord, t_texture_coord);*/ - glTexCoord2i (s_texture_coord,t_texture_coord); - } -} - -static void -process_mtx_mode( struct render_state *state, - const u32 *parms) { - LOG("Set current matrix %08x\n", parms[0]); - - current_matrix_mode = parms[0] & 0x3; - - set_gl_matrix_mode( current_matrix_mode); -} - - -static void -process_mtx_identity( struct render_state *state, - const u32 *parms) { - LOG("Load identity (%d)\n", current_matrix_mode); - - MatrixIdentity (mtxCurrent[current_matrix_mode]); - - if (current_matrix_mode == 2) - MatrixIdentity (mtxCurrent[1]); - - if ( current_matrix_mode < 3) - glLoadIdentity(); -} - -static void -process_mtx_push( struct render_state *state, - const u32 *parms) { - LOG("Matrix push\n"); - - if ( current_matrix_mode == 2) { - /* copy the stack position and size from the Model matrix stack - * as they are shared and may have been updated whilst Model - * Matrix mode was selected. */ - mtxStack[2].position = mtxStack[1].position; - mtxStack[2].size = mtxStack[1].size; - } - - MatrixStackPushMatrix (&mtxStack[current_matrix_mode], - mtxCurrent[current_matrix_mode]); - - if ( current_matrix_mode == 2) { - /* push the model matrix as well */ - MatrixStackPushMatrix ( &mtxStack[1], - mtxCurrent[1]); - } -} - -static void -process_mtx_pop( struct render_state *state, - const u32 *parms) { - s32 index = parms[0]; - LOG("Matrix pop\n"); - - if ( current_matrix_mode == 2) { - /* copy the stack position and size from the Model matrix stack - * as they are shared and may have been updated whilst Model - * Matrix mode was selected. */ - mtxStack[2].position = mtxStack[1].position; - mtxStack[2].size = mtxStack[1].size; - } - - MatrixCopy ( mtxCurrent[current_matrix_mode], - MatrixStackPopMatrix (&mtxStack[current_matrix_mode], index)); - - if (current_matrix_mode == 2) { - MatrixCopy ( mtxCurrent[1], - MatrixStackPopMatrix( &mtxStack[1], index)); - } - - if ( current_matrix_mode < 3) { - if ( current_matrix_mode == 2) - loadMatrix( mtxCurrent[1]); - else - loadMatrix( mtxCurrent[current_matrix_mode]); - } -} - -static void -process_mtx_store( struct render_state *state, - const u32 *parms) { - LOG("Matrix store (%d)\n", parms[0]); - - if ( current_matrix_mode == 2) { - /* copy the stack position and size from the Model matrix stack - * as they are shared and may have been updated whilst Model - * Matrix mode was selected. */ - mtxStack[2].position = mtxStack[1].position; - mtxStack[2].size = mtxStack[1].size; - } - - MatrixStackLoadMatrix (&mtxStack[current_matrix_mode], - parms[0] & 31, - mtxCurrent[current_matrix_mode]); - - if ( current_matrix_mode == 2) { - /* store the model matrix as well */ - MatrixStackLoadMatrix (&mtxStack[1], - parms[0] & 31, - mtxCurrent[1]); - } -} - -static void -process_mtx_restore( struct render_state *state, - const u32 *parms) { - LOG("Matrix restore\n"); - - if ( current_matrix_mode == 2) { - /* copy the stack position and size from the Model matrix stack - * as they are shared and may have been updated whilst Model - * Matrix mode was selected. */ - mtxStack[2].position = mtxStack[1].position; - mtxStack[2].size = mtxStack[1].size; - } - - MatrixCopy (mtxCurrent[current_matrix_mode], - MatrixStackGetPos(&mtxStack[current_matrix_mode], parms[0]&31)); - - if (current_matrix_mode == 2) { - MatrixCopy (mtxCurrent[1], - MatrixStackGetPos(&mtxStack[1], parms[0]&31)); - } - - if ( current_matrix_mode < 3) { - if ( current_matrix_mode == 2) { - loadMatrix( mtxCurrent[1]); - } - else { - loadMatrix( mtxCurrent[current_matrix_mode]); - } - } -} - -static void -process_mtx_load_4x4( struct render_state *state, - const u32 *parms) { - int i; - LOG("Load 4x4 (%d):\n", current_matrix_mode); - LOG("%08x, %08x, %08x, %08x\n", parms[0], parms[1], parms[2], parms[3]); - LOG("%08x, %08x, %08x, %08x\n", parms[4], parms[5], parms[6], parms[7]); - LOG("%08x, %08x, %08x, %08x\n", parms[8], parms[9], parms[10], parms[11]); - LOG("%08x, %08x, %08x, %08x\n", parms[12], parms[13], parms[14], parms[15]); - - for ( i = 0; i < 16; i++) { - mtxCurrent[current_matrix_mode][i] = fix2float(parms[i]); - } - - if (current_matrix_mode == 2) - MatrixCopy (mtxCurrent[1], mtxCurrent[2]); - - LOG("%f, %f, %f, %f\n", - mtxCurrent[current_matrix_mode][0], mtxCurrent[current_matrix_mode][1], - mtxCurrent[current_matrix_mode][2], mtxCurrent[current_matrix_mode][3]); - LOG("%f, %f, %f, %f\n", - mtxCurrent[current_matrix_mode][4], mtxCurrent[current_matrix_mode][5], - mtxCurrent[current_matrix_mode][6], mtxCurrent[current_matrix_mode][7]); - LOG("%f, %f, %f, %f\n", - mtxCurrent[current_matrix_mode][8], mtxCurrent[current_matrix_mode][9], - mtxCurrent[current_matrix_mode][10], mtxCurrent[current_matrix_mode][11]); - LOG("%f, %f, %f, %f\n", - mtxCurrent[current_matrix_mode][12], mtxCurrent[current_matrix_mode][13], - mtxCurrent[current_matrix_mode][14], mtxCurrent[current_matrix_mode][15]); - - if ( current_matrix_mode < 3) - loadMatrix( mtxCurrent[current_matrix_mode]); -} - -static void -process_mtx_load_4x3( struct render_state *state, - const u32 *parms) { - int i; - - LOG("Load 4x3 (%d):\n", current_matrix_mode); - LOG("%08x, %08x, %08x, 0.0\n", parms[0], parms[1], parms[2]); - LOG("%08x, %08x, %08x, 0.0\n", parms[3], parms[4], parms[5]); - LOG("%08x, %08x, %08x, 0.0\n", parms[6], parms[7], parms[8]); - LOG("%08x, %08x, %08x, 1.0\n", parms[9], parms[10], parms[11]); - - mtxCurrent[current_matrix_mode][3] = mtxCurrent[current_matrix_mode][7] = - mtxCurrent[current_matrix_mode][11] = 0.0f; - mtxCurrent[current_matrix_mode][15] = 1.0f; - mtxCurrent[current_matrix_mode][0] = fix2float(parms[0]); - mtxCurrent[current_matrix_mode][1] = fix2float(parms[1]); - mtxCurrent[current_matrix_mode][2] = fix2float(parms[2]); - mtxCurrent[current_matrix_mode][4] = fix2float(parms[3]); - mtxCurrent[current_matrix_mode][5] = fix2float(parms[4]); - mtxCurrent[current_matrix_mode][6] = fix2float(parms[5]); - mtxCurrent[current_matrix_mode][8] = fix2float(parms[6]); - mtxCurrent[current_matrix_mode][9] = fix2float(parms[7]); - mtxCurrent[current_matrix_mode][10] = fix2float(parms[8]); - mtxCurrent[current_matrix_mode][12] = fix2float(parms[9]); - mtxCurrent[current_matrix_mode][13] = fix2float(parms[10]); - mtxCurrent[current_matrix_mode][14] = fix2float(parms[11]); - - if (current_matrix_mode == 2) - MatrixCopy (mtxCurrent[1], mtxCurrent[2]); - - LOG("%f, %f, %f, %f\n", - mtxCurrent[current_matrix_mode][0], mtxCurrent[current_matrix_mode][1], - mtxCurrent[current_matrix_mode][2], mtxCurrent[current_matrix_mode][3]); - LOG("%f, %f, %f, %f\n", - mtxCurrent[current_matrix_mode][4], mtxCurrent[current_matrix_mode][5], - mtxCurrent[current_matrix_mode][6], mtxCurrent[current_matrix_mode][7]); - LOG("%f, %f, %f, %f\n", - mtxCurrent[current_matrix_mode][8], mtxCurrent[current_matrix_mode][9], - mtxCurrent[current_matrix_mode][10], mtxCurrent[current_matrix_mode][11]); - LOG("%f, %f, %f, %f\n", - mtxCurrent[current_matrix_mode][12], mtxCurrent[current_matrix_mode][13], - mtxCurrent[current_matrix_mode][14], mtxCurrent[current_matrix_mode][15]); - - if ( current_matrix_mode < 3) - loadMatrix( mtxCurrent[current_matrix_mode]); -} - - -static void -process_mtx_trans( struct render_state *state, - const u32 *parms) { - float trans[3]; - - trans[0] = fix2float(parms[0]); - trans[1] = fix2float(parms[1]); - trans[2] = fix2float(parms[2]); - - LOG("translate %lf,%lf,%lf (%d)\n", trans[0], trans[1], trans[2], - current_matrix_mode); - - MatrixTranslate (mtxCurrent[current_matrix_mode], trans); - - if (current_matrix_mode == 2) - MatrixTranslate (mtxCurrent[1], trans); - - if ( current_matrix_mode == 2) { - LOG_MATRIX( mtxCurrent[1]); - loadMatrix( mtxCurrent[1]); - } - else if ( current_matrix_mode < 3) - loadMatrix( mtxCurrent[current_matrix_mode]); -} - -static void -process_mtx_scale( struct render_state *state, - const u32 *parms) { - float scale[3]; - - LOG("scale %08x, %08x, %08x (%d)\n", parms[0], parms[1], parms[2], - current_matrix_mode); - - scale[0] = fix2float(parms[0]); - scale[1] = fix2float(parms[1]); - scale[2] = fix2float(parms[2]); - - if (current_matrix_mode == 2) { - /* scaling does not happen against the drirection matrix */ - MatrixScale (mtxCurrent[1], scale); - } - else - MatrixScale (mtxCurrent[current_matrix_mode], scale); - - LOG("scale %f,%f,%f\n", scale[0], scale[1], scale[2]); - - if ( current_matrix_mode == 2) - loadMatrix( mtxCurrent[1]); - else if ( current_matrix_mode < 3) - loadMatrix( mtxCurrent[current_matrix_mode]); -} - -static void -process_mtx_mult_4x4( struct render_state *state, - const u32 *parms) { - static float mult_matrix[16]; - int i; - LOG("Mult 4x4 (%d):\n", current_matrix_mode); - - for ( i = 0; i < 16; i++) { - mult_matrix[i] = fix2float(parms[i]); - } - - LOG_MATRIX( mult_matrix); - - MatrixMultiply (mtxCurrent[current_matrix_mode], mult_matrix); - - if (current_matrix_mode == 2) - MatrixMultiply (mtxCurrent[1], mult_matrix); - - if ( current_matrix_mode == 2) - loadMatrix( mtxCurrent[1]); - else if ( current_matrix_mode < 3) - loadMatrix( mtxCurrent[current_matrix_mode]); -} - -static void -process_mtx_mult_4x3( struct render_state *state, - const u32 *parms) { - static float mult_matrix[16]; - - LOG("Mult 4x3 (%d):\n", current_matrix_mode); - - mult_matrix[3] = mult_matrix[7] = - mult_matrix[11] = 0.0f; - mult_matrix[15] = 1.0f; - mult_matrix[0] = fix2float(parms[0]); - mult_matrix[1] = fix2float(parms[1]); - mult_matrix[2] = fix2float(parms[2]); - mult_matrix[4] = fix2float(parms[3]); - mult_matrix[5] = fix2float(parms[4]); - mult_matrix[6] = fix2float(parms[5]); - mult_matrix[8] = fix2float(parms[6]); - mult_matrix[9] = fix2float(parms[7]); - mult_matrix[10] = fix2float(parms[8]); - mult_matrix[12] = fix2float(parms[9]); - mult_matrix[13] = fix2float(parms[10]); - mult_matrix[14] = fix2float(parms[11]); - - LOG_MATRIX( mult_matrix); - - MatrixMultiply (mtxCurrent[current_matrix_mode], mult_matrix); - - if (current_matrix_mode == 2) - MatrixMultiply (mtxCurrent[1], mult_matrix); - - if ( current_matrix_mode == 2) - loadMatrix( mtxCurrent[1]); - else if ( current_matrix_mode < 3) - loadMatrix( mtxCurrent[current_matrix_mode]); -} - -static void -process_mtx_mult_3x3( struct render_state *state, - const u32 *parms) { - static float mult_matrix[16]; - - LOG("Mult 3x3 (%d):\n", current_matrix_mode); - - mult_matrix[3] = mult_matrix[7] = - mult_matrix[11] = 0.0f; - mult_matrix[12] = mult_matrix[13] = - mult_matrix[14] = 0.0f; - mult_matrix[15] = 1.0f; - mult_matrix[0] = fix2float(parms[0]); - mult_matrix[1] = fix2float(parms[1]); - mult_matrix[2] = fix2float(parms[2]); - mult_matrix[4] = fix2float(parms[3]); - mult_matrix[5] = fix2float(parms[4]); - mult_matrix[6] = fix2float(parms[5]); - mult_matrix[8] = fix2float(parms[6]); - mult_matrix[9] = fix2float(parms[7]); - mult_matrix[10] = fix2float(parms[8]); - - LOG_MATRIX( mult_matrix); - - MatrixMultiply (mtxCurrent[current_matrix_mode], mult_matrix); - - if (current_matrix_mode == 2) - MatrixMultiply (mtxCurrent[1], mult_matrix); - - if ( current_matrix_mode == 2) - loadMatrix( mtxCurrent[1]); - else if ( current_matrix_mode < 3) - loadMatrix( mtxCurrent[current_matrix_mode]); -} - -static void -process_colour( struct render_state *state, - const u32 *parms) { - colorRGB[0] = (parms[0] & 0x1f) << 26; - colorRGB[1] = ((parms[0] >> 5) & 0x1f) << 26; - colorRGB[2] = ((parms[0] >> 10) & 0x1f) << 26; - - if ( colorRGB[0] != 0) - colorRGB[0] |= 0x3ffffff; - if ( colorRGB[1] != 0) - colorRGB[1] |= 0x3ffffff; - if ( colorRGB[2] != 0) - colorRGB[2] |= 0x3ffffff; - - LOG("colour %08x,%08x,%08x (%08x)\n", - colorRGB[0], colorRGB[1], colorRGB[2], - parms[0]); - glColor4iv( colorRGB); -} - -static void -process_vtx_16( struct render_state *state, - const u32 *parms) { - cur_vertex[0] = float16table[parms[0] & 0xFFFF]; - cur_vertex[1] = float16table[parms[0] >> 16]; - cur_vertex[2] = float16table[parms[1] & 0xFFFF]; - LOG("vtx16 %08x %08x\n", parms[0], parms[1]); - - setup_vertex( cur_vertex); -} - -static void -process_vtx_10( struct render_state *state, - const u32 *parms) { - cur_vertex[0] = float10Table[(parms[0]) & 0x3ff]; - cur_vertex[1] = float10Table[(parms[0] >> 10) & 0x3ff]; - cur_vertex[2] = float10Table[(parms[0] >> 20) & 0x3ff]; - LOG("vtx10 %08x\n", parms[0]); - - setup_vertex( cur_vertex); -} - -static void -process_vtx_xy( struct render_state *state, - const u32 *parms) { - cur_vertex[0] = float16table[(parms[0]) & 0xffff]; - cur_vertex[1] = float16table[(parms[0] >> 16) & 0xffff]; - LOG("vtx xy %08x\n", parms[0]); - - setup_vertex( cur_vertex); -} - -static void -process_vtx_xz( struct render_state *state, - const u32 *parms) { - cur_vertex[0] = float16table[(parms[0]) & 0xffff]; - cur_vertex[2] = float16table[(parms[0] >> 16) & 0xffff]; - LOG("vtx xz %08x\n", parms[0]); - - setup_vertex( cur_vertex); -} - -static void -process_vtx_yz( struct render_state *state, - const u32 *parms) { - cur_vertex[1] = float16table[(parms[0]) & 0xffff]; - cur_vertex[2] = float16table[(parms[0] >> 16) & 0xffff]; - LOG("vtx yz %08x\n", parms[0]); - - setup_vertex( cur_vertex); -} - -static void -process_vtx_diff( struct render_state *state, - const u32 *parms) { - cur_vertex[0] += float10RelTable[(parms[0]) & 0x3ff]; - cur_vertex[1] += float10RelTable[(parms[0] >> 10) & 0x3ff]; - cur_vertex[2] += float10RelTable[(parms[0] >> 20) & 0x3ff]; - LOG("vtx10 %08x\n", parms[0]); - - setup_vertex( cur_vertex); -} - - -static void -process_control( struct render_state *state, - const u32 *parms) { - LOG("Control set to %08x\n", parms[0]); - - /* - * Save for later. - * all control is handled at a 'begin' command - */ - disp_3D_control = parms[0]; -} - -static void -process_alpha_function( struct render_state *state, - const u32 *parms) { - LOG("Alpha function %08x\n", parms[0]); - /* - * Save for later - */ - alpha_function = parms[0]; -} - -static void -process_clear_depth( struct render_state *state, - const u32 *parms) { - //u32 depth24b; - u32 v = parms[0] & 0x7FFF; - LOG("Clear depth %08x\n", parms[0]); - - /* - * Save for later. - * handled at a 'begin' command - */ - current_depth24b = (v * 0x200) + ( (v+1) & 0x8000 ? 0x1ff : 0); - - if ( inside_primitive) { - depth24b_valid = 1; - } - else { - depth24b_valid = 0; - glClearDepth( current_depth24b / ((float)(1<<24))); - } -} - -static void -process_clear_colour( struct render_state *state, - const u32 *parms) { - u32 v = parms[0]; - LOG("Clear colour %08x\n", v); - - /* - * Save for later. - * handled at a 'begin' command - */ - current_clear_colour = v; - - if ( inside_primitive) { - clear_colour_valid = 1; - } - else { - glClearColor( ((float)( current_clear_colour & 0x1F))/31.0f, - ((float)(( current_clear_colour >> 5)&0x1F))/31.0f, - ((float)(( current_clear_colour >> 10)&0x1F))/31.0f, - ((float)(( current_clear_colour >> 16)&0x1F))/31.0f); - clear_colour_valid = 0; - } -} - - -/* - * The rendering function. - */ -static void -draw_3D_area( void) { - struct render_state *state = &render_states[GET_DRAW_STATE_INDEX(current_render_state)]; - int i; - GLenum errCode; - - - /*** OpenGL BEGIN ***/ - if ( !begin_opengl_ogl_collector_platform()) { - LOG_ERROR( "platform failed for begin opengl for draw\n"); - return; - } - -#ifndef READ_PIXELS_IMMEDIATELY - /* - * If there is a render which has not had its pixels read yet - * then read them now. - */ - if ( new_render_available) { - new_render_available = 0; - -#ifdef USE_BGR_ORDER - glReadPixels(0,0,256,192,GL_BGRA,GL_UNSIGNED_BYTE,GPU_screen3D); -#else - glReadPixels(0,0,256,192,GL_RGBA,GL_UNSIGNED_BYTE,GPU_screen3D); -#endif - } -#endif - - - LOG("\n------------------------------------\n"); - LOG("Start of render\n"); - glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - - /*if ( state->write_index > 10000) { - LOG_ALWAYS( "3d write index %d\n", state->write_index); - }*/ - - for ( i = 0; i < state->write_index; i++) { - u32 cmd = state->cmds[i]; - //LOG("Render cmd: %08x\n", state->cmds[i]); - - if ( cmd < LAST_CMD_VALUE + 1) { - if ( cmd_processors[cmd].processor_fn != NULL) { - cmd_processors[cmd].processor_fn( state, &state->cmds[i+1]); - } - else { - LOG_ERROR("Unhandled %02x\n", cmd); - } - i += cmd_processors[cmd].num_parms; - } - } - - /* - * Complete any primitive that may be left unended - */ - if ( inside_primitive) { - LOG( "implicit primitive end at end\n"); - glEnd(); - - inside_primitive = 0; - } - - complete_render_ogl_collector_platform(); - - if ((errCode = glGetError()) != GL_NO_ERROR) { - const GLubyte *errString; - - errString = gluErrorString(errCode); - LOG_ERROR( "openGL error during 3D emulation: %s\n", errString); - } - -#ifdef READ_PIXELS_IMMEDIATELY -#ifdef USE_BGR_ORDER - glReadPixels(0,0,256,192,GL_BGRA,GL_UNSIGNED_BYTE,GPU_screen3D); -#else - glReadPixels(0,0,256,192,GL_RGBA,GL_UNSIGNED_BYTE,GPU_screen3D); -#endif - - if ((errCode = glGetError()) != GL_NO_ERROR) { - const GLubyte *errString; - - errString = gluErrorString(errCode); - LOG_ERROR( "openGL error during glReadPixels: %s\n", errString); - } -#else - new_render_available = 1; -#endif - - - LOG("End of render\n------------------------------------\n"); - - end_opengl_ogl_collector_platform(); - return; -} - - -static void -init_openGL( void) { - /* OpenGL BEGIN */ - if ( !begin_opengl_ogl_collector_platform()) { - LOG_ERROR( "platform failed to begin opengl for initialisation\n"); - return; - } - - /* Set the background black */ - glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); - - /* Enables Depth Testing */ - glEnable( GL_DEPTH_TEST ); - glEnable(GL_TEXTURE_2D); - - glEnable( GL_STENCIL_TEST); - - // Always Passes, 1 Bit Plane, 1 As Mask - glStencilFunc( GL_ALWAYS, 1, 1); - glStencilOp( GL_KEEP, GL_REPLACE, GL_REPLACE); - - glGenTextures (1, &oglTextureID); - - glViewport (0, 0, 256, 192); - - end_opengl_ogl_collector_platform(); - /*** OpenGL END ***/ -} - - -static char -nullFunc1_3Dgl_collect(void) { - return 1; -} - -static void -nullFunc2_3Dgl_collect(void) { -} -static void -nullFunc3_3Dgl_collect(unsigned long v) { -} -static void nullFunc4_3Dgl_collect(signed long v){} -static void nullFunc5_3Dgl_collect(unsigned int v){} -static void nullFunc6_3Dgl_collect(unsigned int one, - unsigned int two, unsigned int v){} -static int nullFunc7_3Dgl_collect(void) {return 0;} -static long nullFunc8_3Dgl_collect(unsigned int index){ return 0; } -static void nullFunc9_3Dgl_collect(int line, unsigned short * DST) { }; - - -static int num_primitives[4]; - -static char -init_3Dgl_collect( void) { - int i; - - LOG("Initialising 3D renderer for OpenGL Collector\n"); - - if ( !initialise_ogl_collector_platform()) { - LOG_ERROR( "Platform initialisation failed\n"); - return 0; - } - - MatrixStackSetMaxSize(&mtxStack[0], 1); // Projection stack - MatrixStackSetMaxSize(&mtxStack[1], 31); // Coordinate stack - MatrixStackSetMaxSize(&mtxStack[2], 31); // Directional stack - MatrixStackSetMaxSize(&mtxStack[3], 1); // Texture stack - - MatrixInit (mtxCurrent[0]); - MatrixInit (mtxCurrent[1]); - MatrixInit (mtxCurrent[2]); - MatrixInit (mtxCurrent[3]); - MatrixInit (mtxTemporal); - - current_render_state = 0; - for ( i = 0; i < NUM_RENDER_STATES; i++) { - render_states[i].write_index = 0; - - } - - for ( i = 0; i < 4; i++) { - num_primitives[i] = 0; - } - - for ( i = 0; i < LAST_CMD_VALUE+1; i++) { - cmd_processors[i].processor_fn = NULL; - cmd_processors[i].num_parms = 0; - - switch ( i) { - case NOP_CMD: - cmd_processors[i].num_parms = 0; - break; - case MTX_MODE_CMD: - cmd_processors[i].processor_fn = process_mtx_mode; - cmd_processors[i].num_parms = 1; - break; - case MTX_PUSH_CMD: - cmd_processors[i].processor_fn = process_mtx_push; - cmd_processors[i].num_parms = 0; - break; - case MTX_POP_CMD: - cmd_processors[i].processor_fn = process_mtx_pop; - cmd_processors[i].num_parms = 1; - break; - case MTX_STORE_CMD: - cmd_processors[i].processor_fn = process_mtx_store; - cmd_processors[i].num_parms = 1; - break; - case MTX_RESTORE_CMD: - cmd_processors[i].processor_fn = process_mtx_restore; - cmd_processors[i].num_parms = 1; - break; - case MTX_IDENTITY_CMD: - cmd_processors[i].processor_fn = process_mtx_identity; - cmd_processors[i].num_parms = 0; - break; - case MTX_LOAD_4x4_CMD: - cmd_processors[i].processor_fn = process_mtx_load_4x4; - cmd_processors[i].num_parms = 16; - break; - case MTX_LOAD_4x3_CMD: - cmd_processors[i].processor_fn = process_mtx_load_4x3; - cmd_processors[i].num_parms = 12; - break; - case MTX_MULT_4x4_CMD: - cmd_processors[i].processor_fn = process_mtx_mult_4x4; - cmd_processors[i].num_parms = 16; - break; - case MTX_MULT_4x3_CMD: - cmd_processors[i].processor_fn = process_mtx_mult_4x3; - cmd_processors[i].num_parms = 12; - break; - case MTX_MULT_3x3_CMD: - cmd_processors[i].processor_fn = process_mtx_mult_3x3; - cmd_processors[i].num_parms = 9; - break; - case MTX_SCALE_CMD: - cmd_processors[i].processor_fn = process_mtx_scale; - cmd_processors[i].num_parms = 3; - break; - case MTX_TRANS_CMD: - cmd_processors[i].processor_fn = process_mtx_trans; - cmd_processors[i].num_parms = 3; - break; - case COLOR_CMD: - cmd_processors[i].processor_fn = process_colour; - cmd_processors[i].num_parms = 1; - break; - case NORMAL_CMD: - cmd_processors[i].processor_fn = process_normal; - cmd_processors[i].num_parms = 1; - break; - case TEXCOORD_CMD: - cmd_processors[i].processor_fn = process_texcoord; - cmd_processors[i].num_parms = 1; - break; - case VTX_16_CMD: - cmd_processors[i].processor_fn = process_vtx_16; - cmd_processors[i].num_parms = 2; - break; - case VTX_10_CMD: - cmd_processors[i].processor_fn = process_vtx_10; - cmd_processors[i].num_parms = 1; - break; - case VTX_XY_CMD: - cmd_processors[i].processor_fn = process_vtx_xy; - cmd_processors[i].num_parms = 1; - break; - case VTX_XZ_CMD: - cmd_processors[i].processor_fn = process_vtx_xz; - cmd_processors[i].num_parms = 1; - break; - case VTX_YZ_CMD: - cmd_processors[i].processor_fn = process_vtx_yz; - cmd_processors[i].num_parms = 1; - break; - case VTX_DIFF_CMD: - cmd_processors[i].processor_fn = process_vtx_diff; - cmd_processors[i].num_parms = 1; - break; - case POLYGON_ATTR_CMD: - cmd_processors[i].processor_fn = process_polygon_attr; - cmd_processors[i].num_parms = 1; - break; - case TEXIMAGE_PARAM_CMD: - cmd_processors[i].processor_fn = process_teximage_param; - cmd_processors[i].num_parms = 1; - break; - case PLTT_BASE_CMD: - cmd_processors[i].processor_fn = process_pltt_base; - cmd_processors[i].num_parms = 1; - break; - case DIF_AMB_CMD: - cmd_processors[i].processor_fn = process_dif_amb; - cmd_processors[i].num_parms = 1; - break; - case SPE_EMI_CMD: - cmd_processors[i].processor_fn = process_spe_emi; - cmd_processors[i].num_parms = 1; - break; - case LIGHT_VECTOR_CMD: - cmd_processors[i].processor_fn = process_light_vector; - cmd_processors[i].num_parms = 1; - break; - case LIGHT_COLOR_CMD: - cmd_processors[i].processor_fn = process_light_color; - cmd_processors[i].num_parms = 1; - break; - case SHININESS_CMD: - cmd_processors[i].num_parms = 32; - break; - case BEGIN_VTXS_CMD: - cmd_processors[i].processor_fn = process_begin_vtxs; - cmd_processors[i].num_parms = 1; - break; - case END_VTXS_CMD: - cmd_processors[i].processor_fn = process_end_vtxs; - cmd_processors[i].num_parms = 0; - break; - case SWAP_BUFFERS_CMD: - cmd_processors[i].num_parms = 1; - break; - case VIEWPORT_CMD: - cmd_processors[i].processor_fn = process_viewport; - cmd_processors[i].num_parms = 1; - break; - case BOX_TEST_CMD: - cmd_processors[i].num_parms = 3; - break; - case POS_TEST_CMD: - cmd_processors[i].num_parms = 2; - break; - case VEC_TEST_CMD: - cmd_processors[i].num_parms = 1; - break; - - /* The next ones are not NDS commands */ - case CLEAR_COLOUR_CMD: - cmd_processors[i].processor_fn = process_clear_colour; - cmd_processors[i].num_parms = 1; - break; - case CLEAR_DEPTH_CMD: - cmd_processors[i].processor_fn = process_clear_depth; - cmd_processors[i].num_parms = 1; - break; - - case FOG_COLOUR_CMD: - cmd_processors[i].num_parms = 1; - break; - case FOG_OFFSET_CMD: - cmd_processors[i].num_parms = 1; - break; - - case CONTROL_CMD: - cmd_processors[i].processor_fn = process_control; - cmd_processors[i].num_parms = 1; - break; - - case ALPHA_FUNCTION_CMD: - cmd_processors[i].processor_fn = process_alpha_function; - cmd_processors[i].num_parms = 1; - break; - - } - } - - for (i = 0; i < 65536; i++) - { - float16table[i] = fix2float((signed short)i); - } - - for (i = 0; i < 1024; i++) - { - float10RelTable[i] = ((signed short)(i<<6)) / (float)(1<<18); - float10Table[i] = ((signed short)(i<<6)) / (float)(1<<12); - normalTable[i] = ((signed short)(i<<6)) / (float)(1<<16); - } - - init_openGL(); - - return 1; -} - - - - -static void -Flush_3Dgl_collect( unsigned long val) { - int new_render_state = GET_NEXT_RENDER_STATE_INDEX(current_render_state); - //struct render_state *state = &render_states[current_render_state]; - struct render_state *new_state = &render_states[new_render_state]; - - LOG("Flush %lu %d %d\n", val, - state->write_index, render_states[new_render_state].write_index); - - current_render_state = new_render_state; - - draw_3D_area(); - new_state->write_index = 0; - - numVertex = 0; - //LOG("End of render\n"); -} - -static void -SwapScreen_3Dgl_collect( unsigned int screen) { - LOG("NEVER USED? SwapScreen %d\n", screen); -} - - -static void -call_list_3Dgl_collect(unsigned long v) { - static u32 call_list_command = 0; - static u32 total_num_parms = 0; - static u32 current_parm = 0; - static u32 parms[MAX_NUMBER_OF_PARMS]; - - LOG_CALL_LIST("call list - %08x (%08x cur %d tot %d)\n", v, - call_list_command, current_parm, total_num_parms); - - if ( call_list_command == 0) { - /* new call list command coming in */ - call_list_command = v; - - total_num_parms = cmd_processors[v & 0xff].num_parms; - current_parm = 0; - - LOG_CALL_LIST("new command %02x total parms %d\n", v & 0xff, - total_num_parms); - } - else { - LOG_CALL_LIST("Adding parm %d - %08x\n", current_parm, v); - parms[current_parm] = v; - current_parm += 1; - } - - if ( current_parm == total_num_parms) { - do { - u32 cmd = call_list_command & 0xff; - LOG_CALL_LIST("Current command is %02x\n", cmd); - if ( cmd != 0) { - unsigned int i; - - LOG_CALL_LIST("Cmd %02x complete:\n", cmd); - - if ( cmd == SWAP_BUFFERS_CMD) { - Flush_3Dgl_collect( parms[0]); - } - else { - /* put the command and parms on the list */ - ADD_RENDER_PARM_CMD( cmd); - - for ( i = 0; i < total_num_parms; i++) { - ADD_RENDER_PARM_CMD( parms[i]); - LOG_CALL_LIST("parm %08x\n", parms[i]); - } - } - } - call_list_command >>=8; - - total_num_parms = cmd_processors[call_list_command & 0xff].num_parms; - current_parm = 0; - - LOG_CALL_LIST("Next cmd %02x parms %d\n", call_list_command & 0xff, - total_num_parms); - } while ( call_list_command && total_num_parms == 0); - } -} - -static void -viewport_3Dgl_collect(unsigned long v) { - //LOG("Viewport\n"); - ADD_RENDER_PARM_CMD( VIEWPORT_CMD); - ADD_RENDER_PARM_CMD( v); -} - -static void -Begin_3Dgl_collect(unsigned long v) { - //LOG("Begin\n"); - ADD_RENDER_PARM_CMD( BEGIN_VTXS_CMD); - ADD_RENDER_PARM_CMD( v); -} - -static void -End_3Dgl_collect( void) { - //LOG("END\n"); - ADD_RENDER_PARM_CMD( END_VTXS_CMD); -} - - -static void -fog_colour_3Dgl_collect(unsigned long v) { - ADD_RENDER_PARM_CMD( FOG_COLOUR_CMD); - ADD_RENDER_PARM_CMD( v); -} - -static void -fog_offset_3Dgl_collect(unsigned long v) { - ADD_RENDER_PARM_CMD( FOG_OFFSET_CMD); - ADD_RENDER_PARM_CMD( v); -} - -static void -clear_depth_3Dgl_collect(unsigned long v) { - ADD_RENDER_PARM_CMD( CLEAR_DEPTH_CMD); - ADD_RENDER_PARM_CMD( v); -} - -static void -clear_colour_3Dgl_collect(unsigned long v) { - ADD_RENDER_PARM_CMD( CLEAR_COLOUR_CMD); - ADD_RENDER_PARM_CMD( v); -} - - - -static void -Vertex16b_3Dgl_collect( unsigned int v) { - static int vertex16_count = 0; - static u32 parm1; - - if ( vertex16_count == 0) { - vertex16_count += 1; - parm1 = v; - } - else { - ADD_RENDER_PARM_CMD( VTX_16_CMD); - ADD_RENDER_PARM_CMD( parm1); - ADD_RENDER_PARM_CMD( v); - vertex16_count = 0; - } -} - -static void -Vertex10b_3Dgl_collect(unsigned long v) { - ADD_RENDER_PARM_CMD( VTX_10_CMD); - ADD_RENDER_PARM_CMD( v); -} - -static void -Vertex3_cord_3Dgl_collect(unsigned int one, unsigned int two, unsigned int v) { - if ( one == 0) { - if ( two == 1) { - ADD_RENDER_PARM_CMD( VTX_XY_CMD); - } - else { - ADD_RENDER_PARM_CMD( VTX_XZ_CMD); - } - } - else { - ADD_RENDER_PARM_CMD( VTX_YZ_CMD); - } - ADD_RENDER_PARM_CMD( v); -} - -static void -Vertex_rel_3Dgl_collect(unsigned long v) { - ADD_RENDER_PARM_CMD( VTX_DIFF_CMD); - ADD_RENDER_PARM_CMD( v); -} - - -static void -matrix_mode_3Dgl_collect(unsigned long v) { - ADD_RENDER_PARM_CMD( MTX_MODE_CMD); - ADD_RENDER_PARM_CMD( v); -} - -static void -load_identity_matrix_3Dgl_collect(void) { - ADD_RENDER_PARM_CMD( MTX_IDENTITY_CMD); -} - - -static void -load_4x4_matrix_3Dgl_collect(signed long v) { - static int count_4x4 = 0; - static u32 parms[15]; - - if ( count_4x4 < 15) { - parms[count_4x4] = v; - count_4x4 += 1; - } - else { - int i; - - ADD_RENDER_PARM_CMD( MTX_LOAD_4x4_CMD); - - for ( i = 0; i < 15; i++) { - ADD_RENDER_PARM_CMD( parms[i]); - } - ADD_RENDER_PARM_CMD( v); - count_4x4 = 0; - } -} - -static void -load_4x3_matrix_3Dgl_collect(signed long v) { - static int count_4x3 = 0; - static u32 parms[11]; - - if ( count_4x3 < 11) { - parms[count_4x3] = v; - count_4x3 += 1; - } - else { - int i; - - ADD_RENDER_PARM_CMD( MTX_LOAD_4x3_CMD); - - for ( i = 0; i < 11; i++) { - ADD_RENDER_PARM_CMD( parms[i]); - } - ADD_RENDER_PARM_CMD( v); - count_4x3 = 0; - } -} - - -static void -multi_matrix_4x4_3Dgl_collect(signed long v) { - static int count_4x4 = 0; - static u32 parms[15]; - - if ( count_4x4 < 15) { - parms[count_4x4] = v; - count_4x4 += 1; - } - else { - int i; - - ADD_RENDER_PARM_CMD( MTX_MULT_4x4_CMD); - - for ( i = 0; i < 15; i++) { - ADD_RENDER_PARM_CMD( parms[i]); - } - ADD_RENDER_PARM_CMD( v); - count_4x4 = 0; - } -} - -static void -multi_matrix_4x3_3Dgl_collect(signed long v) { - static int count_4x3 = 0; - static u32 parms[11]; - - if ( count_4x3 < 11) { - parms[count_4x3] = v; - count_4x3 += 1; - } - else { - int i; - - ADD_RENDER_PARM_CMD( MTX_MULT_4x3_CMD); - - for ( i = 0; i < 11; i++) { - ADD_RENDER_PARM_CMD( parms[i]); - } - ADD_RENDER_PARM_CMD( v); - count_4x3 = 0; - } -} - -static void -multi_matrix_3x3_3Dgl_collect(signed long v) { - static int count_3x3 = 0; - static u32 parms[8]; - - if ( count_3x3 < 8) { - parms[count_3x3] = v; - count_3x3 += 1; - } - else { - int i; - - ADD_RENDER_PARM_CMD( MTX_MULT_3x3_CMD); - - for ( i = 0; i < 8; i++) { - ADD_RENDER_PARM_CMD( parms[i]); - } - ADD_RENDER_PARM_CMD( v); - count_3x3 = 0; - } -} - - - - -static void -store_matrix_3Dgl_collect(unsigned long v) { - ADD_RENDER_PARM_CMD( MTX_STORE_CMD); - ADD_RENDER_PARM_CMD( v); -} - -static void -restore_matrix_3Dgl_collect(unsigned long v) { - ADD_RENDER_PARM_CMD( MTX_RESTORE_CMD); - ADD_RENDER_PARM_CMD( v); -} - -static void -push_matrix_3Dgl_collect( void) { - ADD_RENDER_PARM_CMD( MTX_PUSH_CMD); -} - -static void -pop_matrix_3Dgl_collect(signed long v) { - ADD_RENDER_PARM_CMD( MTX_POP_CMD); - ADD_RENDER_PARM_CMD( v); -} - -static void -translate_3Dgl_collect(signed long v) { - static int count_trans = 0; - static u32 parms[2]; - - if ( count_trans < 2) { - parms[count_trans] = v; - count_trans += 1; - } - else { - int i; - - ADD_RENDER_PARM_CMD( MTX_TRANS_CMD); - - for ( i = 0; i < 2; i++) { - ADD_RENDER_PARM_CMD( parms[i]); - } - ADD_RENDER_PARM_CMD( v); - count_trans = 0; - } -} - -static void -scale_3Dgl_collect(signed long v) { - static int count_scale = 0; - static u32 parms[2]; - - if ( count_scale < 2) { - parms[count_scale] = v; - count_scale += 1; - } - else { - int i; - - ADD_RENDER_PARM_CMD( MTX_SCALE_CMD); - - for ( i = 0; i < 2; i++) { - ADD_RENDER_PARM_CMD( parms[i]); - } - ADD_RENDER_PARM_CMD( v); - count_scale = 0; - } -} - -static void -PolyAttr_3Dgl_collect(unsigned long v) { - ADD_RENDER_PARM_CMD( POLYGON_ATTR_CMD); - ADD_RENDER_PARM_CMD( v); -} - -static void -TextImage_3Dgl_collect(unsigned long v) { - ADD_RENDER_PARM_CMD( TEXIMAGE_PARAM_CMD); - ADD_RENDER_PARM_CMD( v); -} - -static void -Colour_3Dgl_collect(unsigned long v) { - ADD_RENDER_PARM_CMD( COLOR_CMD); - ADD_RENDER_PARM_CMD( v); -} - -static void -material0_3Dgl_collect(unsigned long v) { - ADD_RENDER_PARM_CMD( DIF_AMB_CMD); - ADD_RENDER_PARM_CMD( v); -} - -static void -material1_3Dgl_collect(unsigned long v) { - ADD_RENDER_PARM_CMD( SPE_EMI_CMD); - ADD_RENDER_PARM_CMD( v); -} - -static void -shininess_3Dgl_collect(unsigned long v) { - static int count_shine = 0; - static u32 parms[31]; - - if ( count_shine < 31) { - parms[count_shine] = v; - count_shine += 1; - } - else { - int i; - - ADD_RENDER_PARM_CMD( SHININESS_CMD); - - for ( i = 0; i < 31; i++) { - ADD_RENDER_PARM_CMD( parms[i]); - } - ADD_RENDER_PARM_CMD( v); - count_shine = 0; - } -} - -static void -texture_palette_3Dgl_collect(unsigned long v) { - ADD_RENDER_PARM_CMD( PLTT_BASE_CMD); - ADD_RENDER_PARM_CMD( v); -} - -static void -texture_coord_3Dgl_collect(unsigned long v) { - ADD_RENDER_PARM_CMD( TEXCOORD_CMD); - ADD_RENDER_PARM_CMD( v); -} - -static void -light_direction_3Dgl_collect(unsigned long v) { - ADD_RENDER_PARM_CMD( LIGHT_VECTOR_CMD); - ADD_RENDER_PARM_CMD( v); -} - -static void -light_colour_3Dgl_collect(unsigned long v) { - ADD_RENDER_PARM_CMD( LIGHT_COLOR_CMD); - ADD_RENDER_PARM_CMD( v); -} - -static void -normal_3Dgl_collect(unsigned long v) { - ADD_RENDER_PARM_CMD( NORMAL_CMD); - ADD_RENDER_PARM_CMD( v); -} - -static void -control_3Dgl_collect(unsigned long v) { - ADD_RENDER_PARM_CMD( CONTROL_CMD); - ADD_RENDER_PARM_CMD( v); -} - -static void -alpha_function_3Dgl_collect(unsigned long v) { - ADD_RENDER_PARM_CMD( ALPHA_FUNCTION_CMD); - ADD_RENDER_PARM_CMD( v); -} - -static int -get_num_polygons_3Dgl_collect( void) { - /* FIXME: this is a hack */ - LOG("Hacky get_num_polygons %d\n", numVertex/3); - - return numVertex/3; -} -static int -get_num_vertices_3Dgl_collect( void) { - LOG("get_num_vertices %d\n", numVertex); - - return numVertex; -} - -static long -get_clip_matrix_3Dgl_collect(unsigned int index) { - float val = MatrixGetMultipliedIndex (index, mtxCurrent[0], mtxCurrent[1]); - LOG("get_clip_matrix %d\n", index); - - val *= (1<<12); - - return (signed long)val; -} - -static long -get_direction_matrix_3Dgl_collect(unsigned int index) { - LOG("get_direction_matrix %d\n", index); - index += (index/3); - - return (signed long)(mtxCurrent[2][(index)*(1<<12)]); -} - - -//#define BITMAP_STENCIL 1 -static void -get_line_3Dgl_collect(int line, unsigned short *dst) { - int i; - u8 *screen3D = (u8 *)&GPU_screen3D[(192-(line%192))*256*4]; -#ifdef BITMAP_STENCIL - u8 *line_stencil = (u8 *)&stencil_buffer[(192-(line%192))*(256>>3)]; -#else - u8 *line_stencil = (u8 *)&stencil_buffer[(192-(line%192))*256]; -#endif - -#ifndef READ_PIXELS_IMMEDIATELY - if ( line == 0) { - if ( new_render_available) { - new_render_available = 0; - if ( !begin_opengl_ogl_collector_platform()) { - LOG_ERROR( "platform failed for begin opengl for get_line\n"); - return; - } - -#ifdef USE_BGR_ORDER - glReadPixels(0,0,256,192,GL_BGRA,GL_UNSIGNED_BYTE,GPU_screen3D); -#else - glReadPixels(0,0,256,192,GL_RGBA,GL_UNSIGNED_BYTE,GPU_screen3D); -#endif - -#ifdef BITMAP_STENCIL - glReadPixels(0,0, 256,192, GL_STENCIL_INDEX, GL_BITMAP, stencil_buffer); -#else - glReadPixels(0,0, 256,192, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, stencil_buffer); -#endif - - end_opengl_ogl_collector_platform(); - } - } -#endif - - -#ifdef BITMAP_STENCIL - for(i = 0; i < 256; i += 8) - { - u8 bitmap = *line_stencil++; - - if ( bitmap) { - if ( bitmap & 0x80) { -#ifdef USE_BGR_ORDER - u32 r = screen3D[0], g = screen3D[1], b = screen3D[2], a = screen3D[3]; -#else - u32 r = screen3D[2], g = screen3D[1], b = screen3D[0], a = screen3D[3]; -#endif - r = (r*(a+1)) >> 8; g = (g*(a+1)) >> 8; b = (b*(a+1)) >> 8; - *dst = (((r>>3)<<10) | ((g>>3)<<5) | (b>>3)); - } - dst += 1; - screen3D += 4; - if ( bitmap & 0x40) { -#ifdef USE_BGR_ORDER - u32 r = screen3D[0], g = screen3D[1], b = screen3D[2], a = screen3D[3]; -#else - u32 r = screen3D[2], g = screen3D[1], b = screen3D[0], a = screen3D[3]; -#endif - r = (r*(a+1)) >> 8; g = (g*(a+1)) >> 8; b = (b*(a+1)) >> 8; - *dst = (((r>>3)<<10) | ((g>>3)<<5) | (b>>3)); - } - dst += 1; - screen3D += 4; - if ( bitmap & 0x20) { -#ifdef USE_BGR_ORDER - u32 r = screen3D[0], g = screen3D[1], b = screen3D[2], a = screen3D[3]; -#else - u32 r = screen3D[2], g = screen3D[1], b = screen3D[0], a = screen3D[3]; -#endif - r = (r*(a+1)) >> 8; g = (g*(a+1)) >> 8; b = (b*(a+1)) >> 8; - *dst = (((r>>3)<<10) | ((g>>3)<<5) | (b>>3)); - } - dst += 1; - screen3D += 4; - if ( bitmap & 0x10) { -#ifdef USE_BGR_ORDER - u32 r = screen3D[0], g = screen3D[1], b = screen3D[2], a = screen3D[3]; -#else - u32 r = screen3D[2], g = screen3D[1], b = screen3D[0], a = screen3D[3]; -#endif - r = (r*(a+1)) >> 8; g = (g*(a+1)) >> 8; b = (b*(a+1)) >> 8; - *dst = (((r>>3)<<10) | ((g>>3)<<5) | (b>>3)); - } - dst += 1; - screen3D += 4; - if ( bitmap & 0x08) { -#ifdef USE_BGR_ORDER - u32 r = screen3D[0], g = screen3D[1], b = screen3D[2], a = screen3D[3]; -#else - u32 r = screen3D[2], g = screen3D[1], b = screen3D[0], a = screen3D[3]; -#endif - r = (r*(a+1)) >> 8; g = (g*(a+1)) >> 8; b = (b*(a+1)) >> 8; - *dst = (((r>>3)<<10) | ((g>>3)<<5) | (b>>3)); - } - dst += 1; - screen3D += 4; - if ( bitmap & 0x04) { -#ifdef USE_BGR_ORDER - u32 r = screen3D[0], g = screen3D[1], b = screen3D[2], a = screen3D[3]; -#else - u32 r = screen3D[2], g = screen3D[1], b = screen3D[0], a = screen3D[3]; -#endif - r = (r*(a+1)) >> 8; g = (g*(a+1)) >> 8; b = (b*(a+1)) >> 8; - *dst = (((r>>3)<<10) | ((g>>3)<<5) | (b>>3)); - } - dst += 1; - screen3D += 4; - if ( bitmap & 0x02) { -#ifdef USE_BGR_ORDER - u32 r = screen3D[0], g = screen3D[1], b = screen3D[2], a = screen3D[3]; -#else - u32 r = screen3D[2], g = screen3D[1], b = screen3D[0], a = screen3D[3]; -#endif - r = (r*(a+1)) >> 8; g = (g*(a+1)) >> 8; b = (b*(a+1)) >> 8; - *dst = (((r>>3)<<10) | ((g>>3)<<5) | (b>>3)); - } - dst += 1; - screen3D += 4; - if ( bitmap & 0x01) { -#ifdef USE_BGR_ORDER - u32 r = screen3D[0], g = screen3D[1], b = screen3D[2], a = screen3D[3]; -#else - u32 r = screen3D[2], g = screen3D[1], b = screen3D[0], a = screen3D[3]; -#endif - r = (r*(a+1)) >> 8; g = (g*(a+1)) >> 8; b = (b*(a+1)) >> 8; - *dst = (((r>>3)<<10) | ((g>>3)<<5) | (b>>3)); - } - dst += 1; - screen3D += 4; - } - else { - screen3D += 4 * 8; - dst += 8; - } - } -#else - for(i = 0; i < 256; i++) - { - if ( line_stencil[i]) { -#ifdef USE_BGR_ORDER - u32 r = screen3D[0], - g = screen3D[1], - b = screen3D[2], - a = screen3D[3]; -#else - u32 r = screen3D[2], - g = screen3D[1], - b = screen3D[0], - a = screen3D[3]; -#endif -#if 0 - r = (r*a)/255; - g = (g*a)/255; - b = (b*a)/255; -#else - r = (r*(a+1)) >> 8; - g = (g*(a+1)) >> 8; - b = (b*(a+1)) >> 8; -#endif - - *dst = (((r>>3)<<10) | ((g>>3)<<5) | (b>>3)); - } - dst += 1; - screen3D += 4; - } -#endif -} - - -GPU3DInterface gpu3D_opengl_collector = { - /* the Init function */ - init_3Dgl_collect, - - /* Reset */ - nullFunc2_3Dgl_collect, - - /* Close */ - nullFunc2_3Dgl_collect, - - /* Viewport */ - viewport_3Dgl_collect, - - /* Clear colour */ - clear_colour_3Dgl_collect, - - /* Fog colour */ - fog_colour_3Dgl_collect, - - /* Fog offset */ - fog_offset_3Dgl_collect, - - /* Clear Depth */ - clear_depth_3Dgl_collect, - - /* Matrix Mode */ - matrix_mode_3Dgl_collect, - - /* Load Identity */ - load_identity_matrix_3Dgl_collect, - - /* Load 4x4 Matrix */ - load_4x4_matrix_3Dgl_collect, - - /* Load 4x3 Matrix */ - load_4x3_matrix_3Dgl_collect, - - /* Store Matrix */ - store_matrix_3Dgl_collect, - - /* Restore Matrix */ - restore_matrix_3Dgl_collect, - - /* Push Matrix */ - push_matrix_3Dgl_collect, - - /* Pop Matrix */ - pop_matrix_3Dgl_collect, - - /* Translate */ - translate_3Dgl_collect, - - /* Scale */ - scale_3Dgl_collect, - - /* Multiply Matrix 3x3 */ - multi_matrix_3x3_3Dgl_collect, - - /* Multiply Matrix 4x3 */ - multi_matrix_4x3_3Dgl_collect, - - /* Multiply Matrix 4x4 */ - multi_matrix_4x4_3Dgl_collect, - - /* Begin primitive */ - Begin_3Dgl_collect, - /* End primitive */ - End_3Dgl_collect, - - /* Colour */ - Colour_3Dgl_collect, - - /* Vertex */ - Vertex16b_3Dgl_collect, - Vertex10b_3Dgl_collect, - Vertex3_cord_3Dgl_collect, - Vertex_rel_3Dgl_collect, - - /* Swap Screen */ - SwapScreen_3Dgl_collect, - - /* Get Number of polygons */ - get_num_polygons_3Dgl_collect, - - /* Get number of vertices */ - get_num_vertices_3Dgl_collect, - - /* Flush */ - Flush_3Dgl_collect, - - /* poly attribute */ - PolyAttr_3Dgl_collect, - - /* Material 0 */ - material0_3Dgl_collect, - - /* Material 1 */ - material1_3Dgl_collect, - - /* Shininess */ - shininess_3Dgl_collect, - - /* Texture attributes */ - TextImage_3Dgl_collect, - - /* Texture palette */ - texture_palette_3Dgl_collect, - - /* Texture coordinate */ - texture_coord_3Dgl_collect, - - /* Light direction */ - light_direction_3Dgl_collect, - - /* Light colour */ - light_colour_3Dgl_collect, - - /* Alpha function */ - alpha_function_3Dgl_collect, - - /* Control */ - control_3Dgl_collect, - - /* normal */ - normal_3Dgl_collect, - - /* Call list */ - call_list_3Dgl_collect, - - /* Get clip matrix */ - get_clip_matrix_3Dgl_collect, - - /* Get direction matrix */ - get_direction_matrix_3Dgl_collect, - - /* get line */ - get_line_3Dgl_collect -}; - - - -#endif /* End of __MINGW32__ */ -#endif /* End of HAVE_GL_GLU_H */ -#endif /* End of HAVE_GL_GL_H */ diff --git a/desmume/src/opengl_collector_3Demu.h b/desmume/src/opengl_collector_3Demu.h deleted file mode 100644 index d10c37d09..000000000 --- a/desmume/src/opengl_collector_3Demu.h +++ /dev/null @@ -1,65 +0,0 @@ -/* $Id: opengl_collector_3Demu.h,v 1.2 2007-04-20 12:42:58 masscat Exp $ - */ -#ifndef _OPENGL_COLLECTOR_3DEMU_H_ -#define _OPENGL_COLLECTOR_3DEMU_H_ 1 -/* - Copyright (C) 2006-2007 Ben Jaques - - This file is part of DeSmuME - - DeSmuME is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - DeSmuME is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with DeSmuME; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -extern GPU3DInterface gpu3D_opengl_collector; - - -/** - * This is called before a set of OpenGL functions are called. - * It is up to the platform code to switch to the correct context and similar. - * - * If the platform code is unsucessful then return 0 and the OpenGL functions - * will not be called. Return 1 otherwise. - * - * If this is not overridden then the call will always fail. - */ -extern int (*begin_opengl_ogl_collector_platform)( void); - -/** - * This is called after a set of OpenGL functions have been called, marking - * the end the OpenGL calls. - * - * If not overridden this function will do nothing. - */ -extern void (*end_opengl_ogl_collector_platform)( void); - -/** - * This is called during the OpenGL Collector's initialisation. - * - * If the platform code is unsucessful then return 0 and the initialisation - * will fail. Return 1 otherwise. - * - * If this is not overridden then the call will always fail. - */ -extern int (*initialise_ogl_collector_platform)( void); - -/** - * This is called when all the OpenGL functions comprising a single set - * have been called. - * - * If this is not overridden then a call to glFlush() is made. - */ -extern void (*complete_render_ogl_collector_platform)( void); - -#endif /* End of _OPENGL_COLLECTOR_3DEMU_H_ */ diff --git a/desmume/src/render3D.cpp b/desmume/src/render3D.cpp index ab296f881..dcaa3a9f5 100644 --- a/desmume/src/render3D.cpp +++ b/desmume/src/render3D.cpp @@ -20,85 +20,17 @@ #include "render3D.h" -char NDS_nullFunc1 (void){ return 1; } -void NDS_nullFunc2 (void){} -void NDS_nullFunc3 (unsigned long v){} -void NDS_nullFunc4 (signed long v) {} -void NDS_nullFunc5 (unsigned int v){} -void NDS_nullFunc6 (unsigned int one, unsigned int two, unsigned int v){} -int NDS_nullFunc7 (void) {return 0;} -long NDS_nullFunc8 (unsigned int index){ return 0; } -void NDS_nullFunc9 (int line, unsigned short * DST) { }; -void NDS_nullFunc10 (unsigned int mode, unsigned int index, float* dest) {}; // NDS_3D_GetMatrix -void NDS_nullFunc11 (unsigned int index, unsigned int* dest) {}; // NDS_glGetLightDirection -void NDS_nullFunc12 (void* v) {} +void NDS_nullFunc1 (void){} +char NDS_nullFunc2 (void){ return 1; } +void NDS_nullFunc3 (int,unsigned short*) {} GPU3DInterface gpu3DNull = { - NDS_nullFunc1, // NDS_3D_Init - NDS_nullFunc2, // NDS_3D_Reset - NDS_nullFunc2, // NDS_3D_Close - NDS_nullFunc3, // NDS_3D_ViewPort - NDS_nullFunc3, // NDS_3D_ClearColor - NDS_nullFunc3, // NDS_3D_FogColor - NDS_nullFunc3, // NDS_3D_FogOffset - NDS_nullFunc3, // NDS_3D_ClearDepth - NDS_nullFunc3, // NDS_3D_MatrixMode - NDS_nullFunc2, // NDS_3D_LoadIdentity - NDS_nullFunc4, // NDS_3D_LoadMatrix4x4 - NDS_nullFunc4, // NDS_3D_LoadMatrix4x3 - NDS_nullFunc3, // NDS_3D_StoreMatrix - NDS_nullFunc3, // NDS_3D_RestoreMatrix - NDS_nullFunc2, // NDS_3D_PushMatrix - NDS_nullFunc4, // NDS_3D_PopMatrix - NDS_nullFunc4, // NDS_3D_Translate - NDS_nullFunc4, // NDS_3D_Scale - NDS_nullFunc4, // NDS_3D_MultMatrix3x3 - NDS_nullFunc4, // NDS_3D_MultMatrix4x3 - NDS_nullFunc4, // NDS_3D_MultMatrix4x4 - NDS_nullFunc3, // NDS_3D_Begin - NDS_nullFunc2, // NDS_3D_End - NDS_nullFunc3, // NDS_3D_Color3b - NDS_nullFunc5, // NDS_3D_Vertex16b - NDS_nullFunc3, // NDS_3D_Vertex10b - NDS_nullFunc6, // NDS_3D_Vertex3_cord - NDS_nullFunc3, // NDS_3D_Vertex_rel - NDS_nullFunc5, // NDS_3D_SwapScreen - NDS_nullFunc7, // NDS_3D_GetNumPolys - NDS_nullFunc7, // NDS_3D_GetNumVertex - NDS_nullFunc3, // NDS_3D_Flush - NDS_nullFunc3, // NDS_3D_PolygonAttrib - NDS_nullFunc3, // NDS_3D_Material0 - NDS_nullFunc3, // NDS_3D_Material1 - NDS_nullFunc3, // NDS_3D_Shininess - NDS_nullFunc3, // NDS_3D_TexImage - NDS_nullFunc3, // NDS_3D_TexPalette - NDS_nullFunc3, // NDS_3D_TexCoord - NDS_nullFunc3, // NDS_3D_LightDirection - NDS_nullFunc3, // NDS_3D_LightColor - NDS_nullFunc3, // NDS_3D_AlphaFunc - NDS_nullFunc3, // NDS_3D_Control - NDS_nullFunc3, // NDS_3D_Normal - NDS_nullFunc3, // NDS_3D_CallList - - NDS_nullFunc8, // NDS_3D_GetClipMatrix - NDS_nullFunc8, // NDS_3D_GetDirectionalMatrix - NDS_nullFunc9, // NDS_3D_GetLine - - NDS_nullFunc10, // NDS_3D_GetMatrix - NDS_nullFunc11, // NDS_glGetLightDirection - NDS_nullFunc11, // NDS_glGetLightColor - - NDS_nullFunc3, // NDS_3D_BoxTest - NDS_nullFunc3, // NDS_3D_PosTest - NDS_nullFunc3, // NDS_3D_VecTest - - NDS_nullFunc8, // NDS_3D_GetPosRes - NDS_nullFunc8, // NDS_3D_GetVecRes - - NDS_nullFunc12, // NDS_3D_UpdateToonTable - - NDS_nullFunc2, // NDS_3D_VBlankSignal - NDS_nullFunc2 // NDS_3D_VramReconfigureSignal + NDS_nullFunc2, //NDS_3D_Init + NDS_nullFunc1, //NDS_3D_Reset + NDS_nullFunc1, //NDS_3D_Close + NDS_nullFunc1, //NDS_3D_Render + NDS_nullFunc1, //NDS_3D_VramReconfigureSignal + NDS_nullFunc3, //NDS_3D_GetLine }; GPU3DInterface *gpu3D = &gpu3DNull; diff --git a/desmume/src/render3D.h b/desmume/src/render3D.h index a598605d6..0f05b1df2 100644 --- a/desmume/src/render3D.h +++ b/desmume/src/render3D.h @@ -18,114 +18,32 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef GPU_3D -#define GPU_3D +#ifndef RENDER3D_H +#define RENDER3D_H //not using this right now #define CALL_CONVENTION -/* -enum DRIVER_3D -{ - DRIVER_NULL = 0, - DRIVER_OPENGL -}; -*/ - -typedef struct GPU3DInterface +typedef struct Render3DInterface { + //called once when the plugin starts up char (CALL_CONVENTION* NDS_3D_Init) (void); - void (CALL_CONVENTION* NDS_3D_Reset) (void); - void (CALL_CONVENTION* NDS_3D_Close) (void); - void (CALL_CONVENTION* NDS_3D_ViewPort) (unsigned long v); - void (CALL_CONVENTION* NDS_3D_ClearColor) (unsigned long v); - void (CALL_CONVENTION* NDS_3D_FogColor) (unsigned long v); - void (CALL_CONVENTION* NDS_3D_FogOffset) (unsigned long v); - void (CALL_CONVENTION* NDS_3D_ClearDepth) (unsigned long v); - void (CALL_CONVENTION* NDS_3D_MatrixMode) (unsigned long v); - void (CALL_CONVENTION* NDS_3D_LoadIdentity) (void); - void (CALL_CONVENTION* NDS_3D_LoadMatrix4x4) (signed long v); - void (CALL_CONVENTION* NDS_3D_LoadMatrix4x3) (signed long v); - void (CALL_CONVENTION* NDS_3D_StoreMatrix) (unsigned long v); - void (CALL_CONVENTION* NDS_3D_RestoreMatrix) (unsigned long v); - void (CALL_CONVENTION* NDS_3D_PushMatrix) (void); - void (CALL_CONVENTION* NDS_3D_PopMatrix) (signed long i); - void (CALL_CONVENTION* NDS_3D_Translate) (signed long v); - void (CALL_CONVENTION* NDS_3D_Scale) (signed long v); - void (CALL_CONVENTION* NDS_3D_MultMatrix3x3) (signed long v); - void (CALL_CONVENTION* NDS_3D_MultMatrix4x3) (signed long v); - void (CALL_CONVENTION* NDS_3D_MultMatrix4x4) (signed long v); - void (CALL_CONVENTION* NDS_3D_Begin) (unsigned long v); - void (CALL_CONVENTION* NDS_3D_End) (void); - void (CALL_CONVENTION* NDS_3D_Color3b) (unsigned long v); - void (CALL_CONVENTION* NDS_3D_Vertex16b) (unsigned int v); - void (CALL_CONVENTION* NDS_3D_Vertex10b) (unsigned long v); - void (CALL_CONVENTION* NDS_3D_Vertex3_cord) (unsigned int one, unsigned int two, unsigned int v); - void (CALL_CONVENTION* NDS_3D_Vertex_rel) (unsigned long v); - void (CALL_CONVENTION* NDS_3D_SwapScreen) (unsigned int screen); - int (CALL_CONVENTION* NDS_3D_GetNumPolys) (void); // THIS IS A HACK :D - int (CALL_CONVENTION* NDS_3D_GetNumVertex) (void); - void (CALL_CONVENTION* NDS_3D_Flush) (unsigned long v); - void (CALL_CONVENTION* NDS_3D_PolygonAttrib) (unsigned long val); - void (CALL_CONVENTION* NDS_3D_Material0) (unsigned long val); - void (CALL_CONVENTION* NDS_3D_Material1) (unsigned long val); - void (CALL_CONVENTION* NDS_3D_Shininess) (unsigned long val); - void (CALL_CONVENTION* NDS_3D_TexImage) (unsigned long val); - void (CALL_CONVENTION* NDS_3D_TexPalette) (unsigned long val); - void (CALL_CONVENTION* NDS_3D_TexCoord) (unsigned long val); - void (CALL_CONVENTION* NDS_3D_LightDirection) (unsigned long v); - void (CALL_CONVENTION* NDS_3D_LightColor) (unsigned long v); - void (CALL_CONVENTION* NDS_3D_AlphaFunc) (unsigned long v); - void (CALL_CONVENTION* NDS_3D_Control) (unsigned long v); - void (CALL_CONVENTION* NDS_3D_Normal) (unsigned long v); - void (CALL_CONVENTION* NDS_3D_CallList) (unsigned long v); - - long (CALL_CONVENTION* NDS_3D_GetClipMatrix) (unsigned int index); - long (CALL_CONVENTION* NDS_3D_GetDirectionalMatrix) (unsigned int index); - void (CALL_CONVENTION* NDS_3D_GetLine) (int line, unsigned short * DST); - - ////////////////////////////////////////////////////////////////////////////// - // NDS_3D_GetMatrix - // - // mode: 0 = projection - // 1 = coordinate - // 2 = direction - // 3 = texture - // - // index: the matrix stack index or -1 for current - // - // dest: pointer to the destination float[16] buffer - ////////////////////////////////////////////////////////////////////////////// - void (CALL_CONVENTION* NDS_3D_GetMatrix) (unsigned int mode, unsigned int index, float* dest); - - ////////////////////////////////////////////////////////////////////////////// - // NDS_glGetLightDirection - // - // index: light index - // - // dest: pointer to the destination variable - ////////////////////////////////////////////////////////////////////////////// - void (CALL_CONVENTION* NDS_glGetLightDirection) (unsigned int index, unsigned int* dest); - - ////////////////////////////////////////////////////////////////////////////// - // NDS_glGetLightColor - // - // index: light index - // - // dest: pointer to the destination variable - ////////////////////////////////////////////////////////////////////////////// - void (CALL_CONVENTION* NDS_glGetLightColor) (unsigned int index, unsigned int* dest); - void (CALL_CONVENTION* NDS_3D_BoxTest) (unsigned long v); - void (CALL_CONVENTION* NDS_3D_PosTest) (unsigned long v); - void (CALL_CONVENTION* NDS_3D_VecTest) (unsigned long v); - long (CALL_CONVENTION* NDS_3D_GetPosRes) (unsigned int index); - long (CALL_CONVENTION* NDS_3D_GetVecRes) (unsigned int index); + //called when the emulator resets (is this necessary?) + void (CALL_CONVENTION* NDS_3D_Reset) (void); + + //called when the plugin shuts down + void (CALL_CONVENTION* NDS_3D_Close) (void); + + //called when the renderer should do its job and render the current display lists + void (CALL_CONVENTION* NDS_3D_Render) (void); - void (CALL_CONVENTION* NDS_3D_UpdateToonTable) (void* toonTable); - void (CALL_CONVENTION* NDS_3D_VBlankSignal) (); + //called when the emulator reconfigures its vram. you may need to invalidate your texture cache. void (CALL_CONVENTION* NDS_3D_VramReconfigureSignal) (); + //Retrieves a line of color buffer data + void (CALL_CONVENTION* NDS_3D_GetLine) (int line, unsigned short* dst); + } GPU3DInterface; diff --git a/desmume/src/types.h b/desmume/src/types.h index 3af1c8a28..b0560d2d0 100644 --- a/desmume/src/types.h +++ b/desmume/src/types.h @@ -20,6 +20,14 @@ #ifndef TYPES_HPP #define TYPES_HPP +#ifdef _MSC_VER +#define ALIGN(X) __declspec(align(X)) +#elif __GNUC__ +#define ALIGN(X) __attribute__ ((aligned (X))) +#else +#define ALIGN(X) +#endif + #ifndef FASTCALL #ifdef __MINGW32__ #define FASTCALL __attribute__((fastcall)) diff --git a/desmume/src/windows/DeSmuME_2005.vcproj b/desmume/src/windows/DeSmuME_2005.vcproj index a5560c526..d99e01710 100644 --- a/desmume/src/windows/DeSmuME_2005.vcproj +++ b/desmume/src/windows/DeSmuME_2005.vcproj @@ -617,6 +617,10 @@ RelativePath="..\gdbstub\gdbstub.cpp" > + + @@ -962,6 +966,10 @@ RelativePath="..\gdbstub\gdbstub_internal.h" > + + diff --git a/desmume/src/windows/DeSmuME_2008.vcproj b/desmume/src/windows/DeSmuME_2008.vcproj index 05ce077a3..f0e7ec044 100644 --- a/desmume/src/windows/DeSmuME_2008.vcproj +++ b/desmume/src/windows/DeSmuME_2008.vcproj @@ -614,6 +614,10 @@ RelativePath="..\gdbstub\gdbstub.cpp" > + + @@ -931,6 +935,10 @@ RelativePath="..\gdbstub\gdbstub_internal.h" > + + diff --git a/desmume/src/windows/OGLRender.cpp b/desmume/src/windows/OGLRender.cpp index 7a1814e40..e8cef8610 100644 --- a/desmume/src/windows/OGLRender.cpp +++ b/desmume/src/windows/OGLRender.cpp @@ -48,195 +48,44 @@ #include "../matrix.h" #include "../NDSSystem.h" #include "OGLRender.h" +#include "../gfx3d.h" #ifndef CTASSERT #define CTASSERT(x) typedef char __assert ## y[(x) ? 1 : -1] #endif -#define fix2float(v) (((float)((s32)(v))) / (float)(1<<12)) -#define fix10_2float(v) (((float)((s32)(v))) / (float)(1<<9)) - static __declspec(align(16)) unsigned char GPU_screen3D [256*256*4]={0}; static __declspec(align(16)) unsigned char GPU_screenStencil[256*256]={0}; -// Matrix stack handling -static __declspec(align(16)) MatrixStack mtxStack[4]; -static __declspec(align(16)) float mtxCurrent [4][16]; -static __declspec(align(16)) float mtxTemporal[16]; - -// Indexes for matrix loading/multiplication -static char ML4x4ind = 0; -static char ML4x3_c = 0, ML4x3_l = 0; -static char MM4x4ind = 0; -static char MM4x3_c = 0, MM4x3_l = 0; -static char MM3x3_c = 0, MM3x3_l = 0; - -// Data for vertex submission -static __declspec(align(16)) float coord[4] = {0.0, 0.0, 0.0, 0.0}; -static char coordind = 0; - -// Data for basic transforms -static __declspec(align(16)) float trans[4] = {0.0, 0.0, 0.0, 0.0}; -static char transind = 0; - -static __declspec(align(16)) float scale[4] = {0.0, 0.0, 0.0, 0.0}; -static char scaleind = 0; - -static const unsigned short polyType[4] = {GL_TRIANGLES, GL_QUADS, GL_TRIANGLE_STRIP, GL_QUAD_STRIP}; 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 }; static const int depthFunc[2] = { GL_LESS, GL_EQUAL }; static bool needRefreshFramebuffer = false; -//is this a crazy idea? this table spreads 5 bits evenly over 31 from exactly 0 to INT_MAX -static const int material_5bit_to_31bit[] = { - 0x00000000, 0x04210842, 0x08421084, 0x0C6318C6, - 0x10842108, 0x14A5294A, 0x18C6318C, 0x1CE739CE, - 0x21084210, 0x25294A52, 0x294A5294, 0x2D6B5AD6, - 0x318C6318, 0x35AD6B5A, 0x39CE739C, 0x3DEF7BDE, - 0x42108421, 0x46318C63, 0x4A5294A5, 0x4E739CE7, - 0x5294A529, 0x56B5AD6B, 0x5AD6B5AD, 0x5EF7BDEF, - 0x6318C631, 0x6739CE73, 0x6B5AD6B5, 0x6F7BDEF7, - 0x739CE739, 0x77BDEF7B, 0x7BDEF7BD, 0x7FFFFFFF -}; -static const u8 material_5bit_to_8bit[] = { - 0x00, 0x08, 0x10, 0x18, 0x21, 0x29, 0x31, 0x39, - 0x42, 0x4A, 0x52, 0x5A, 0x63, 0x6B, 0x73, 0x7B, - 0x84, 0x8C, 0x94, 0x9C, 0xA5, 0xAD, 0xB5, 0xBD, - 0xC6, 0xCE, 0xD6, 0xDE, 0xE7, 0xEF, 0xF7, 0xFF -}; - - -static const u8 material_3bit_to_8bit[] = { - 0x00, 0x24, 0x49, 0x6D, 0x92, 0xB6, 0xDB, 0xFF -}; - -// Acceleration tables -static float float16table[65536]; -static float float10Table[1024]; -static float float10RelTable[1024]; -static float normalTable[1024]; -static u32 color_15bit_to_24bit[32768]; - - -//produce a 32bpp color from a DS RGB16 -#define RGB16TO32(col,alpha) (((alpha)<<24) | ((((col) & 0x7C00)>>7)<<16) | ((((col) & 0x3E0)>>2)<<8) | (((col) & 0x1F)<<3)) - - -//produce a 32bpp color from a ds RGB15 plus an 8bit alpha, using a table -#define RGB15TO32(col,alpha8) ( ((alpha8)<<24) | color_15bit_to_24bit[col] ) - -//produce a 32bpp color from a ds RGB15 plus an 8bit alpha, not using a table (but using other tables) -#define RGB15TO32_DIRECT(col,alpha8) ( ((alpha8)<<24) | (material_5bit_to_8bit[((col)>>10)&0x1F]<<16) | (material_5bit_to_8bit[((col)>>5)&0x1F]<<8) | material_5bit_to_8bit[(col)&0x1F] ) - - -void makeTables() { - - //produce the color bits of a 32bpp color from a DS RGB15 using bit logic (internal use only) - #define RGB15TO24_BITLOGIC(col) ( (material_5bit_to_8bit[((col)>>10)&0x1F]<<16) | (material_5bit_to_8bit[((col)>>5)&0x1F]<<8) | material_5bit_to_8bit[(col)&0x1F] ) - - for(int i=0;i<32768;i++) - color_15bit_to_24bit[i] = RGB15TO24_BITLOGIC((u16)i); - - for (int i = 0; i < 65536; i++) - float16table[i] = fix2float((signed short)i); - - for (int i = 0; i < 1024; i++) - float10Table[i] = ((signed short)(i<<6)) / (float)(1<<12); - - for (int i = 0; i < 1024; i++) - float10RelTable[i] = ((signed short)(i<<6)) / (float)(1<<18); - - for (int i = 0; i < 1024; i++) - normalTable[i] = ((signed short)(i<<6)) / (float)(1<<15); -} static unsigned short matrixMode[2] = {GL_PROJECTION, GL_MODELVIEW}; -static short mode = 0; -//raw ds format poly attributes -static u32 polyAttr=0,textureFormat=0, texturePalette=0; -static int colorAlpha=0; -static unsigned int polyID=0; -static unsigned int depthFuncMode=0; -static unsigned int lightMask=0; -static unsigned int envMode=0; -static unsigned int cullingMask=0; -static unsigned char texMAP[1024*2048*4]; -static float fogColor[4] = {0.f}; -static float fogOffset = 0.f; -static float alphaTestRef = 0.01f; +static unsigned char texMAP[1024*2048*4]; + -static float alphaTestBase = 0; -static unsigned long clCmd = 0; -static unsigned long clInd = 0; -static unsigned long clInd2 = 0; -static int alphaDepthWrite = 0; -static int colorRGB[4] = { 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}; -static int texCoordinateTransform = 0; -static int _t=0, _s=0; -static float last_t, last_s; -static unsigned int vtxFormat; -static unsigned int old_vtxFormat; static unsigned int textureMode=0; -static u16 dsDiffuse, dsAmbient, dsSpecular, dsEmission; -static int diffuse[4] = {0}, - ambient[4] = {0}, - specular[4] = {0}, - emission[4] = {0}; -typedef struct _POLY { - int type; //tri or quad - int vertIndexes[4]; //up to four verts can be referenced by this poly - u32 polyAttr, texParam, texPalette; //the hardware rendering params - float projMatrix[16]; -} POLY; - -#define POLYLIST_SIZE 6000 -//#define POLYLIST_SIZE 2048 -typedef struct _POLYLIST { - int count; - POLY list[POLYLIST_SIZE]; -} POLYLIST; -POLYLIST polylists[2]; -POLYLIST* polylist = &polylists[0]; - -typedef struct _VERT { - float coord[4]; - float texcoord[2]; - int color[4]; - u32 depth; -} VERT; - -#define VERTLIST_SIZE 30000 -//#define VERTLIST_SIZE 10000 -typedef struct _VERTLIST { - int count; - VERT list[VERTLIST_SIZE]; -} VERTLIST; -VERTLIST vertlists[2]; -VERTLIST* vertlist = &vertlists[0]; - -int listTwiddle = 1; -int triStripToggle; - -//list-building state -VERTLIST tempVertList; - -static void twiddleLists() { - listTwiddle++; - listTwiddle &= 1; - polylist = &polylists[listTwiddle]; - vertlist = &vertlists[listTwiddle]; - polylist->count = 0; - vertlist->count = 0; -} +//raw ds format poly attributes, installed from the display list +static u32 polyAttr=0,textureFormat=0, texturePalette=0; +//derived values extracted from polyattr +static bool wireframe=false, alpha31=false; +static unsigned int polyID=0; +static unsigned int depthFuncMode=0; +static unsigned int envMode=0; +static unsigned int cullingMask=0; +static int alphaDepthWrite = 0; +static unsigned int lightMask=0; //------------------------------------------------------------ @@ -262,6 +111,7 @@ OGLEXT(PFNGLGETSHADERINFOLOGPROC,glGetShaderInfoLog) #endif + //opengl state caching: //This is of dubious performance assistance, but it is easy to take out so I am leaving it for now. //every function that is xgl* can be replaced with gl* if we decide to rip this out or if anyone else @@ -344,7 +194,6 @@ struct TextureCache unsigned int sizeX; unsigned int sizeY; int coord; - unsigned int texenv; float invSizeX; float invSizeY; unsigned char texture[128*1024]; // 128Kb texture slot @@ -366,14 +215,7 @@ GLenum oglToonTableTextureID; u32 toonShader, toonProgram; //================================================= -typedef struct -{ - unsigned int color; // Color in hardware format - unsigned int direction; // Direction in hardware format - float floatDirection[4]; -} LightInformation; -LightInformation g_lightInfo[4] = { 0 }; #ifndef DESMUME_OBJ_C extern HWND hwnd; @@ -396,7 +238,7 @@ int CheckHardwareSupport(HDC hdc) } #endif -__forceinline void NDS_3D_Reset() +static void Reset() { int i; @@ -408,17 +250,7 @@ __forceinline void NDS_3D_Reset() texcache_stop=MAX_TEXTURE<<1; } -static void NDS_3D_UpdateToonTable(void* toonTable) { - u16* u16toonTable = (u16*)toonTable; - u32 rgbToonTable[32]; - int i; - for(i=0;i<32;i++) - rgbToonTable[i] = RGB15TO32(u16toonTable[i],255); - - glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbToonTable); -} - -char NDS_glInit(void) +static char Init(void) { int i; @@ -457,9 +289,9 @@ char NDS_glInit(void) if(!wglMakeCurrent(oglDC, hRC)) return 0; res=CheckHardwareSupport(oglDC); - if (res>=0&&res<=2) - printlog("OpenGL mode: %s\n",opengl_modes[res]); - else + 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); @@ -479,22 +311,6 @@ char NDS_glInit(void) if (glGetError() != GL_NO_ERROR) return 0; - twiddleLists(); - - // Precalculate some tables, to avoid pushing data to the FPU and back for conversion - makeTables(); - - MatrixStackSetMaxSize(&mtxStack[0], 1); // Projection stack - MatrixStackSetMaxSize(&mtxStack[1], 31); // Coordinate stack - MatrixStackSetMaxSize(&mtxStack[2], 31); // Directional stack - MatrixStackSetMaxSize(&mtxStack[3], 1); // Texture stack - - MatrixInit (mtxCurrent[0]); - MatrixInit (mtxCurrent[1]); - MatrixInit (mtxCurrent[2]); - MatrixInit (mtxCurrent[3]); - MatrixInit (mtxTemporal); - INITOGLEXT(PFNGLCREATESHADERPROC,glCreateShader) INITOGLEXT(X_PFNGLGETSHADERSOURCEPROC,glShaderSource) INITOGLEXT(PFNGLCOMPILESHADERPROC,glCompileShader) @@ -528,267 +344,26 @@ char NDS_glInit(void) //TODO - this should modulate or add depending on whether we are in highlight or toon mode - toonShader = glCreateShader(GL_FRAGMENT_SHADER); + toonShader = glCreateShader(GL_FRAGMENT_SHADER); toonProgram = glCreateProgram(); - glShaderSource(toonShader, 1, (const GLchar**)toonShaderSource, 0); + glShaderSource(toonShader, 1, (GLchar**)toonShaderSource, 0); glCompileShader(toonShader); glGetShaderInfoLog(toonShader,10000,0,buf); glAttachShader(toonProgram,toonShader); glLinkProgram(toonProgram); - toonShader = 0; + toonShader = 0; } } return 1; } -__forceinline void NDS_3D_Close() +void Close() { } -__forceinline void NDS_glViewPort(unsigned long v) -{ - //zero: NHerve messed with this in mod2 and mod3, but im still not sure its perfect. need to research this. - glViewport( (v&0xFF), ((v>>8)&0xFF), (((v>>16)&0xFF)+1)-(v&0xFF), ((v>>24)+1)-((v>>8)&0xFF)); -} - -__forceinline void NDS_glClearColor(unsigned long v) -{ - glClearColor( ((float)(v&0x1F))/31.0f, - ((float)((v>>5)&0x1F))/31.0f, - ((float)((v>>10)&0x1F))/31.0f, - ((float)((v>>16)&0x1F))/31.0f); -} - -__forceinline void NDS_glFogColor(unsigned long v) -{ - fogColor[0] = ((float)((v )&0x1F))/31.0f; - fogColor[1] = ((float)((v>> 5)&0x1F))/31.0f; - fogColor[2] = ((float)((v>>10)&0x1F))/31.0f; - fogColor[3] = ((float)((v>>16)&0x1F))/31.0f; -} - -__forceinline void NDS_glFogOffset (unsigned long v) -{ - fogOffset = (float)(v&0xffff); -} - -__forceinline void NDS_glClDepth() -{ - glClear(GL_DEPTH_BUFFER_BIT); -} - -__forceinline void NDS_glClearDepth(unsigned long v) -{ - u32 depth24b; - - v &= 0x7FFFF; - // Thanks for NHerve - depth24b = (v*0x200)+((v+1)/0x8000)*0x01FF; - glClearDepth(depth24b / ((float)(1<<24))); -} - -__forceinline void NDS_glMatrixMode(unsigned long v) -{ - mode = (short)(v&3); -} - -__forceinline void NDS_glLoadIdentity (void) -{ - MatrixIdentity (mtxCurrent[mode]); - - if (mode == 2) - MatrixIdentity (mtxCurrent[1]); -} - -__forceinline void NDS_glLoadMatrix4x4(signed long v) -{ - mtxCurrent[mode][ML4x4ind] = fix2float(v); - - ++ML4x4ind; - if(ML4x4ind<16) return; - - if (mode == 2) - MatrixCopy (mtxCurrent[1], mtxCurrent[2]); - - ML4x4ind = 0; -} - -__forceinline void NDS_glLoadMatrix4x3(signed long v) -{ - mtxCurrent[mode][(ML4x3_l<<2)+ML4x3_c] = fix2float(v); - - ++ML4x3_c; - if(ML4x3_c<3) return; - - ML4x3_c = 0; - ++ML4x3_l; - if(ML4x3_l<4) return; - ML4x3_l = 0; - - //fill in the unusued matrix values - mtxCurrent[mode][3] = mtxCurrent[mode][7] = mtxCurrent[mode][11] = 0; - mtxCurrent[mode][15] = 1; - - if (mode == 2) - MatrixCopy (mtxCurrent[1], mtxCurrent[2]); -} - -__forceinline void NDS_glStoreMatrix(unsigned long v) -{ - //this command always works on both pos and vector when either pos or pos-vector are the current mtx mode - short mymode = (mode==1?2:mode); - - //for the projection matrix, the provided value is supposed to be reset to zero - if(mymode==0) - v = 0; - - MatrixStackLoadMatrix (&mtxStack[mymode], v&31, mtxCurrent[mymode]); - if(mymode==2) - MatrixStackLoadMatrix (&mtxStack[1], v&31, mtxCurrent[1]); -} - -__forceinline void NDS_glRestoreMatrix(unsigned long v) -{ - //this command always works on both pos and vector when either pos or pos-vector are the current mtx mode - short mymode = (mode==1?2:mode); - - //for the projection matrix, the provided value is supposed to be reset to zero - if(mymode==0) - v = 0; - - MatrixCopy (mtxCurrent[mymode], MatrixStackGetPos(&mtxStack[mymode], v&31)); - if (mymode == 2) - MatrixCopy (mtxCurrent[1], MatrixStackGetPos(&mtxStack[1], v&31)); -} - -__forceinline void NDS_glPushMatrix (void) -{ - //this command always works on both pos and vector when either pos or pos-vector are the current mtx mode - short mymode = (mode==1?2:mode); - - MatrixStackPushMatrix (&mtxStack[mymode], mtxCurrent[mymode]); - if(mymode==2) - MatrixStackPushMatrix (&mtxStack[1], mtxCurrent[1]); -} - -__forceinline void NDS_glPopMatrix(signed long i) -{ - //this command always works on both pos and vector when either pos or pos-vector are the current mtx mode - short mymode = (mode==1?2:mode); - - MatrixCopy (mtxCurrent[mode], MatrixStackPopMatrix (&mtxStack[mode], i)); - - if (mymode == 2) - MatrixCopy (mtxCurrent[1], MatrixStackPopMatrix (&mtxStack[1], i)); -} - -__forceinline void NDS_glTranslate(signed long v) -{ - trans[transind] = fix2float(v); - - ++transind; - - if(transind<3) - return; - - transind = 0; - - MatrixTranslate (mtxCurrent[mode], trans); - - if (mode == 2) - MatrixTranslate (mtxCurrent[1], trans); -} - -__forceinline void NDS_glScale(signed long v) -{ - short mymode = (mode==2?1:mode); - - scale[scaleind] = fix2float(v); - - ++scaleind; - - if(scaleind<3) - return; - - scaleind = 0; - - MatrixScale (mtxCurrent[mymode], scale); - - //note: pos-vector mode should not cause both matrices to scale. - //the whole purpose is to keep the vector matrix orthogonal - //so, I am leaving this commented out as an example of what not to do. - //if (mode == 2) - // MatrixScale (mtxCurrent[1], scale); -} - -__forceinline void NDS_glMultMatrix3x3(signed long v) -{ - mtxTemporal[(MM3x3_l<<2)+MM3x3_c] = fix2float(v); - - ++MM3x3_c; - if(MM3x3_c<3) return; - - MM3x3_c = 0; - ++MM3x3_l; - if(MM3x3_l<3) return; - MM3x3_l = 0; - - //fill in the unusued matrix values - mtxTemporal[3] = mtxTemporal[7] = mtxTemporal[11] = 0; - mtxTemporal[15] = 1; - mtxTemporal[12] = mtxTemporal[13] = mtxTemporal[14] = 0; - - MatrixMultiply (mtxCurrent[mode], mtxTemporal); - - if (mode == 2) - MatrixMultiply (mtxCurrent[1], mtxTemporal); - - //does this really need to be done? - MatrixIdentity (mtxTemporal); -} - -__forceinline void NDS_glMultMatrix4x3(signed long v) -{ - mtxTemporal[(MM4x3_l<<2)+MM4x3_c] = fix2float(v); - - ++MM4x3_c; - if(MM4x3_c<3) return; - - MM4x3_c = 0; - ++MM4x3_l; - if(MM4x3_l<4) return; - MM4x3_l = 0; - - //fill in the unusued matrix values - mtxTemporal[3] = mtxTemporal[7] = mtxTemporal[11] = 0; - mtxTemporal[15] = 1; - - MatrixMultiply (mtxCurrent[mode], mtxTemporal); - if (mode == 2) - MatrixMultiply (mtxCurrent[1], mtxTemporal); - - //does this really need to be done? - MatrixIdentity (mtxTemporal); -} - -__forceinline void NDS_glMultMatrix4x4(signed long v) -{ - mtxTemporal[MM4x4ind] = fix2float(v); - - ++MM4x4ind; - if(MM4x4ind<16) return; - - MM4x4ind = 0; - - MatrixMultiply (mtxCurrent[mode], mtxTemporal); - if (mode == 2) - MatrixMultiply (mtxCurrent[1], mtxTemporal); - - MatrixIdentity (mtxTemporal); -} //zero 8/25/08 - i dont like this //#define CHECKSLOT txt_slot_current_size--;\ @@ -812,8 +387,8 @@ __forceinline void NDS_glMultMatrix4x4(signed long v) //todo - make all color conversions go through a properly spread table!! //I think this is slower than the regular memcmp.. doesnt make sense to me, but my -//asm optimization knowlege is 15 years old.. - +//asm optimization knowlege is 15 years old.. + #ifndef WORDS_BIGENDIAN __forceinline int memcmp_slow(const void* src, const void* dst, u32 count) { int retval; @@ -836,8 +411,8 @@ __forceinline void* memcpy_fast(void* dest, const void* src, size_t count) __asm { - mov esi, [src] - mov edi, [dest] + mov esi, [src] + mov edi, [dest] mov ecx, [blockCnt] test ecx, ecx @@ -846,7 +421,7 @@ __forceinline void* memcpy_fast(void* dest, const void* src, size_t count) copyloop: //prefetchnta [esi] mov eax, [esi] - + movq mm0, qword ptr [esi] movq mm1, qword ptr [esi+8] movq mm2, qword ptr [esi+16] @@ -879,10 +454,10 @@ __forceinline void* memcpy_fast(void* dest, const void* src, size_t count) } return dest; -} -#else -#define memcpy_fast(d,s,c) memcpy(d,s,c) -#endif +} +#else +#define memcpy_fast(d,s,c) memcpy(d,s,c) +#endif static void DebugDumpTexture(int which) { @@ -910,7 +485,7 @@ void setTexture(unsigned int format, unsigned int texpal) int i=0; unsigned int x=0, y=0; unsigned int palZeroTransparent; - + unsigned short *pal = NULL; unsigned char *dst = texMAP; unsigned int sizeX=(8 << ((format>>20)&0x07)); @@ -937,9 +512,9 @@ void setTexture(unsigned int format, unsigned int texpal) txt_slot_current=(format>>14)&0x03; adr=(unsigned char *)(ARM9Mem.textureSlotAddr[txt_slot_current]+((format&0x3FFF)<<3)); - + i=texcache_start; - + //if(false) while (TRUE) { @@ -965,12 +540,12 @@ void setTexture(unsigned int format, unsigned int texpal) } } i++; - if (i>MAX_TEXTURE) + if (i>MAX_TEXTURE) { texcache_stop=texcache_start; texcache[texcache_stop].frm=0; texcache_start++; - if (texcache_start>MAX_TEXTURE) + if (texcache_start>MAX_TEXTURE) { texcache_start=0; texcache_stop=MAX_TEXTURE<<1; @@ -990,7 +565,6 @@ void setTexture(unsigned int format, unsigned int texpal) texcache[i].coord=(format>>30); texcache[i].invSizeX=1.0f/((float)sizeX*(1<<4)); texcache[i].invSizeY=1.0f/((float)sizeY*(1<<4)); - texcache[i].texenv=envMode; //memcpy(texcache[i].texture,adr,imageSize); //======================= copy memcpy_fast(texcache[i].texture,adr,min(imageSize,sizeof(texcache[i].texture))); //======================= copy texcache[i].numcolors=palSize[texcache[i].mode]; @@ -1002,7 +576,7 @@ void setTexture(unsigned int format, unsigned int texpal) glScaled (texcache[i].invSizeX, texcache[i].invSizeY, 1.0f); //printlog("Texture %03i - format=%08X; pal=%04X (mode %X, width %04i, height %04i)\n",i, texcache[i].frm, texcache[i].pal, texcache[i].mode, sizeX, sizeY); - + //============================================================================ Texture render palZeroTransparent = (1-((format>>29)&1))*255; // shash: CONVERT THIS TO A TABLE :) txt_slot_size=(txt_slot_current_size=0x020000-((format & 0x3FFF)<<3)); @@ -1109,7 +683,7 @@ void setTexture(unsigned int format, unsigned int texpal) if ( (texcache[i].frm & 0xc000) == 0x8000) // texel are in slot 2 slot1=(unsigned short*)&ARM9Mem.textureSlotAddr[1][((texcache[i].frm&0x3FFF)<<2)+0x010000]; - else + else slot1=(unsigned short*)&ARM9Mem.textureSlotAddr[1][(texcache[i].frm&0x3FFF)<<2]; bool dead = false; @@ -1129,7 +703,7 @@ void setTexture(unsigned int format, unsigned int texpal) tmp_col[0]=RGB16TO32(pal[pal1offset],255); tmp_col[1]=RGB16TO32(pal[pal1offset+1],255); - switch (mode) + switch (mode) { case 0: tmp_col[2]=RGB16TO32(pal[pal1offset+2],255); @@ -1146,7 +720,7 @@ void setTexture(unsigned int format, unsigned int texpal) tmp_col[2]=RGB16TO32(pal[pal1offset+2],255); tmp_col[3]=RGB16TO32(pal[pal1offset+3],255); break; - case 3: + case 3: { u32 red1, red2; u32 green1, green2; @@ -1189,7 +763,7 @@ void setTexture(unsigned int format, unsigned int texpal) dst[currentPos+2] = 0; dst[currentPos+3] = 0; } - + txt_slot_current_size-=4;; if (txt_slot_current_size<=0) { @@ -1227,13 +801,13 @@ void setTexture(unsigned int format, unsigned int texpal) unsigned short * map = ((unsigned short *)adr); unsigned int * dst = (unsigned int *)texMAP; pal = (unsigned short *)(ARM9Mem.texPalSlot[0] + (texturePalette<<4)); - + for(x = 0; x < imageSize; ++x) { unsigned short c = map[x]; int alpha = ((c&0x8000)?255:0); *dst = RGB15TO32(c&0x7FFF,alpha); - + dst++; txt_slot_current_size-=2;; if (txt_slot_current_size<=0) @@ -1249,27 +823,22 @@ void setTexture(unsigned int format, unsigned int texpal) } - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, - texcache[i].sizeX, texcache[i].sizeY, 0, + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + texcache[i].sizeX, texcache[i].sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, texMAP); //============================================================================================ texcache_count=i; - - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texEnv[texcache[i].texenv]); + + //glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texEnv[texcache[i].texenv]); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (BIT16(texcache[i].frm) ? (BIT18(texcache[i].frm)?GL_MIRRORED_REPEAT:GL_REPEAT) : GL_CLAMP)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (BIT17(texcache[i].frm) ? (BIT18(texcache[i].frm)?GL_MIRRORED_REPEAT:GL_REPEAT) : GL_CLAMP)); } -__forceinline void NDS_glBegin(unsigned long v) -{ - vtxFormat = polyType[v&0x03]; - triStripToggle = 0; - tempVertList.count = 0; -} + //controls states: //glStencilFunc @@ -1293,13 +862,12 @@ static void BeginRenderPoly() else xglDisable(GL_CULL_FACE); - // Alpha value, actually not well handled, 0 should be wireframe - if (colorAlpha > 0) + if (!wireframe) { xglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); //non-31 alpha polys are translucent - if(colorAlpha != 0x7FFFFFFF) + if(!alpha31) enableDepthWrite = alphaDepthWrite; } else @@ -1366,200 +934,6 @@ static void BeginRenderPoly() xglDepthMask(enableDepthWrite?GL_TRUE:GL_FALSE); } -__forceinline void NDS_glEnd (void) -{ - tempVertList.count = 0; -} - -__forceinline void NDS_glColor3b(unsigned long v) -{ - colorRGB[0] = material_5bit_to_31bit[(v&0x1F)]; - colorRGB[1] = material_5bit_to_31bit[((v>>5)&0x1F)]; - colorRGB[2] = material_5bit_to_31bit[((v>>10)&0x1F)]; -} - -//Submit a vertex to the GE -static __forceinline void SetVertex() -{ - __declspec(align(16)) float coordTransformed[4] = { coord[0], coord[1], coord[2], 1 }; - - if (texCoordinateTransform == 3) - { - last_s =((coord[0]*mtxCurrent[3][0] + - coord[1]*mtxCurrent[3][4] + - coord[2]*mtxCurrent[3][8]) + _s); - last_t =((coord[0]*mtxCurrent[3][1] + - coord[1]*mtxCurrent[3][5] + - coord[2]*mtxCurrent[3][9]) + _t); - } - - //refuse to do anything if we have too many verts or polys - if(vertlist->count >= VERTLIST_SIZE) - return; - if(polylist->count >= POLYLIST_SIZE) - return; - - //apply modelview matrix - MatrixMultVec4x4 (mtxCurrent[1], coordTransformed); - - //deferred rendering: - - //todo - we havent got the whole pipeline working yet, so lets save the projection matrix and let opengl do it - ////apply projection matrix - //MatrixMultVec4x4 (mtxCurrent[0], coordTransformed); - - ////perspective division - //coordTransformed[0] = (coordTransformed[0] + coordTransformed[3]) / 2 / coordTransformed[3]; - //coordTransformed[1] = (coordTransformed[1] + coordTransformed[3]) / 2 / coordTransformed[3]; - //coordTransformed[2] = (coordTransformed[2] + coordTransformed[3]) / 2 / coordTransformed[3]; - //coordTransformed[3] = 1; - - //TODO - culling should be done here. - //TODO - viewport transform - - - //record the vertex - tempVertList.list[tempVertList.count].texcoord[0] = last_s; - tempVertList.list[tempVertList.count].texcoord[1] = last_t; - tempVertList.list[tempVertList.count].coord[0] = coordTransformed[0]; - tempVertList.list[tempVertList.count].coord[1] = coordTransformed[1]; - tempVertList.list[tempVertList.count].coord[2] = coordTransformed[2]; - tempVertList.list[tempVertList.count].coord[3] = coordTransformed[3]; - tempVertList.list[tempVertList.count].color[0] = colorRGB[0]; - tempVertList.list[tempVertList.count].color[1] = colorRGB[1]; - tempVertList.list[tempVertList.count].color[2] = colorRGB[2]; - tempVertList.list[tempVertList.count].color[3] = colorRGB[3]; - tempVertList.list[tempVertList.count].depth = 0x7FFF * coordTransformed[2]; - tempVertList.count++; - - //possibly complete a polygon - { - #define SUBMITVERTEX(i,n) vertlist->list[polylist->list[polylist->count].vertIndexes[i] = vertlist->count++] = tempVertList.list[n]; - int completed=0; - switch(vtxFormat) { - case GL_TRIANGLES: - if(tempVertList.count!=3) - break; - completed = 1; - SUBMITVERTEX(0,0); - SUBMITVERTEX(1,1); - SUBMITVERTEX(2,2); - polylist->list[polylist->count].type = 3; - tempVertList.count = 0; - break; - case GL_QUADS: - if(tempVertList.count!=4) - break; - completed = 1; - SUBMITVERTEX(0,0); - SUBMITVERTEX(1,1); - SUBMITVERTEX(2,2); - SUBMITVERTEX(3,3); - polylist->list[polylist->count].type = 4; - tempVertList.count = 0; - break; - case GL_TRIANGLE_STRIP: - if(tempVertList.count!=3) - break; - completed = 1; - SUBMITVERTEX(0,0); - SUBMITVERTEX(1,1); - SUBMITVERTEX(2,2); - polylist->list[polylist->count].type = 3; - if(triStripToggle) - tempVertList.list[1] = tempVertList.list[2]; - else - tempVertList.list[0] = tempVertList.list[2]; - triStripToggle ^= 1; - tempVertList.count = 2; - break; - case GL_QUAD_STRIP: - if(tempVertList.count!=4) - break; - completed = 1; - SUBMITVERTEX(0,0); - SUBMITVERTEX(1,1); - SUBMITVERTEX(2,3); - SUBMITVERTEX(3,2); - polylist->list[polylist->count].type = 4; - tempVertList.list[0] = tempVertList.list[2]; - tempVertList.list[1] = tempVertList.list[3]; - tempVertList.count = 2; - break; - } - - if(completed) { - MatrixCopy(polylist->list[polylist->count].projMatrix,mtxCurrent[0]); - polylist->list[polylist->count].polyAttr = polyAttr; - polylist->list[polylist->count].texParam = textureFormat; - polylist->list[polylist->count].texPalette = texturePalette; - polylist->count++; - } - } - -} - -__forceinline void NDS_glVertex16b(unsigned int v) -{ - if(coordind==0) - { - coord[0] = float16table[v&0xFFFF]; - coord[1] = float16table[v>>16]; - - ++coordind; - return; - } - - coord[2] = float16table[v&0xFFFF]; - - coordind = 0; - SetVertex (); -} - -__forceinline void NDS_glVertex10b(unsigned long v) -{ - coord[0] = float10Table[v&1023]; - coord[1] = float10Table[(v>>10)&1023]; - coord[2] = float10Table[(v>>20)&1023]; - - SetVertex (); -} - -__forceinline void NDS_glVertex3_cord(unsigned int one, unsigned int two, unsigned int v) -{ - coord[one] = float16table[v&0xffff]; - coord[two] = float16table[v>>16]; - - SetVertex (); -} - -__forceinline void NDS_glVertex_rel(unsigned long v) -{ - coord[0] += float10RelTable[v&1023]; - coord[1] += float10RelTable[(v>>10)&1023]; - coord[2] += float10RelTable[(v>>20)&1023]; - - SetVertex (); -} - -// Ignored for now -__forceinline void NDS_glSwapScreen(unsigned int screen) -{ -} - - -__forceinline int NDS_glGetNumPolys (void) -{ - //so is this in the currently-displayed or currently-built list? - return 0; -} - -__forceinline int NDS_glGetNumVertex (void) -{ - //so is this in the currently-displayed or currently-built list? - return 0; -} - static void InstallPolygonAttrib(unsigned long val) { // Light enable/disable @@ -1578,186 +952,26 @@ static void InstallPolygonAttrib(unsigned long val) // back face culling cullingMask = (val&0xC0); + alpha31 = ((val>>16)&0x1F)==31; + // Alpha value, actually not well handled, 0 should be wireframe - colorRGB[3] = colorAlpha = material_5bit_to_31bit[((val>>16)&0x1F)]; + wireframe = ((val>>16)&0x1F)==0; // polyID polyID = (val>>24)&0x1F; } -__forceinline void NDS_glPolygonAttrib (unsigned long val) +static void Control() { - polyAttr = val; - InstallPolygonAttrib(polyAttr); -} + if(gfx3d.enableTexturing) glEnable (GL_TEXTURE_2D); + else glDisable (GL_TEXTURE_2D); -/* - 0-4 Diffuse Reflection Red - 5-9 Diffuse Reflection Green - 10-14 Diffuse Reflection Blue - 15 Set Vertex Color (0=No, 1=Set Diffuse Reflection Color as Vertex Color) - 16-20 Ambient Reflection Red - 21-25 Ambient Reflection Green - 26-30 Ambient Reflection Blue -*/ -__forceinline void NDS_glMaterial0 (unsigned long val) -{ - dsDiffuse = val&0xFFFF; - dsAmbient = val>>16; - - diffuse[0] = material_5bit_to_31bit[(val)&0x1F]; - diffuse[1] = material_5bit_to_31bit[(val>>5)&0x1F]; - diffuse[2] = material_5bit_to_31bit[(val>>10)&0x1F]; - diffuse[3] = 0x7fffffff; - - ambient[0] = material_5bit_to_31bit[(val>>16)&0x1F]; - ambient[1] = material_5bit_to_31bit[(val>>21)&0x1F]; - ambient[2] = material_5bit_to_31bit[(val>>26)&0x1F]; - ambient[3] = 0x7fffffff; - - if (BIT15(val)) - { - colorRGB[0] = diffuse[0]; - colorRGB[1] = diffuse[1]; - colorRGB[2] = diffuse[2]; - } -} - -__forceinline void NDS_glMaterial1 (unsigned long val) -{ - dsSpecular = val&0xFFFF; - dsEmission = val>>16; - - specular[0] = material_5bit_to_31bit[(val)&0x1F]; - specular[1] = material_5bit_to_31bit[(val>>5)&0x1F]; - specular[2] = material_5bit_to_31bit[(val>>10)&0x1F]; - specular[3] = 0x7fffffff; - - emission[0] = material_5bit_to_31bit[(val>>16)&0x1F]; - emission[1] = material_5bit_to_31bit[(val>>21)&0x1F]; - emission[2] = material_5bit_to_31bit[(val>>26)&0x1F]; - emission[3] = 0x7fffffff; -} - -__forceinline void NDS_glShininess (unsigned long val) -{ - //printlog("Shininess=%i\n",val); -} - -__forceinline void NDS_glTexImage(unsigned long val) -{ - textureFormat = val; - texCoordinateTransform = (val>>30); -} - -__forceinline void NDS_glTexPalette(unsigned long val) -{ - texturePalette = val; -} - -__forceinline void NDS_glTexCoord(unsigned long val) -{ - _t = (s16)(val>>16); - _s = (s16)(val&0xFFFF); - - if (texCoordinateTransform == 1) - { - //last_s =_s*mtxCurrent[3][0] + _t*mtxCurrent[3][4] + - // 0.0625f*mtxCurrent[3][8] + 0.0625f*mtxCurrent[3][12]; - //last_t =_s*mtxCurrent[3][1] + _t*mtxCurrent[3][5] + - // 0.0625f*mtxCurrent[3][9] + 0.0625f*mtxCurrent[3][13]; - - //zero 9/11/08 - I dunno... I think it needs to be like this to make things look right - last_s =_s*mtxCurrent[3][0] + _t*mtxCurrent[3][4] + - mtxCurrent[3][8] + mtxCurrent[3][12]; - last_t =_s*mtxCurrent[3][1] + _t*mtxCurrent[3][5] + - mtxCurrent[3][9] + mtxCurrent[3][13]; - } + if(gfx3d.enableAlphaTest) + glAlphaFunc (GL_GREATER, gfx3d.alphaTestRef); else - { - last_s=_s; - last_t=_t; - } -} - -__forceinline signed long NDS_glGetClipMatrix (unsigned int index) -{ - float val = MatrixGetMultipliedIndex (index, mtxCurrent[0], mtxCurrent[1]); - - val *= (1<<12); - - return (signed long)val; -} - -__forceinline signed long NDS_glGetDirectionalMatrix (unsigned int index) -{ - index += (index/3); - - return (signed long)(mtxCurrent[2][(index)*(1<<12)]); -} - - -/* - 0-9 Directional Vector's X component (1bit sign + 9bit fractional part) - 10-19 Directional Vector's Y component (1bit sign + 9bit fractional part) - 20-29 Directional Vector's Z component (1bit sign + 9bit fractional part) - 30-31 Light Number (0..3) -*/ - -__forceinline void NDS_glLightDirection (unsigned long v) -{ - int index = v>>30; - float direction[4]; - - // Convert format into floating point value - g_lightInfo[index].floatDirection[0] = -normalTable[v&1023]; - g_lightInfo[index].floatDirection[1] = -normalTable[(v>>10)&1023]; - g_lightInfo[index].floatDirection[2] = -normalTable[(v>>20)&1023]; - g_lightInfo[index].floatDirection[3] = 0; - - // Keep information for fightDirection function - g_lightInfo[index].direction = v; -} - -__forceinline void NDS_glLightColor (unsigned long v) -{ - int lightColor[4] = { ((v) &0x1F)<<26, - ((v>> 5)&0x1F)<<26, - ((v>>10)&0x1F)<<26, - 0x7fffffff}; - int index = v>>30; - - g_lightInfo[index].color = v; -} - -__forceinline void NDS_glAlphaFunc(unsigned long v) -{ - alphaTestRef = (v&31)/31.f; - glAlphaFunc (GL_GREATER, alphaTestBase); -} - -__forceinline void NDS_glControl(unsigned long v) -{ - if(v&1) - { - glEnable (GL_TEXTURE_2D); - } - else - { - glDisable (GL_TEXTURE_2D); - } - - if(v&(1<<2)) - { - glAlphaFunc (GL_GREATER, alphaTestBase); - } - else - { glAlphaFunc (GL_GREATER, 0); - } - if(v&(1<<3)) - { + if(gfx3d.enableAlphaBlending) { glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable (GL_BLEND); } @@ -1765,132 +979,13 @@ __forceinline void NDS_glControl(unsigned long v) { glDisable (GL_BLEND); } - - if (v&(1<<14)) - { - printlog("Enabled BITMAP background mode\n"); - } } -__forceinline void NDS_glNormal(unsigned long v) + +static void Render() { - int i,c; - __declspec(align(16)) float normal[3] = { normalTable[v&1023], - normalTable[(v>>10)&1023], - normalTable[(v>>20)&1023]}; + Control(); - //find the line of sight vector - //TODO - only do this when the projection matrix changes - __declspec(align(16)) float lineOfSight[4] = { 0, 0, -1, 0 }; - MatrixMultVec4x4 (mtxCurrent[0], lineOfSight); - - if (texCoordinateTransform == 2) - { - last_s =( (normal[0] *mtxCurrent[3][0] + normal[1] *mtxCurrent[3][4] + - normal[2] *mtxCurrent[3][8]) + _s); - last_t =( (normal[0] *mtxCurrent[3][1] + normal[1] *mtxCurrent[3][5] + - normal[2] *mtxCurrent[3][9]) + _t); - } - - //use the current normal transform matrix - MatrixMultVec3x3 (mtxCurrent[2], normal); - - //apply lighting model - { - u8 diffuse[3] = { - (dsDiffuse)&0x1F, - (dsDiffuse>>5)&0x1F, - (dsDiffuse>>10)&0x1F }; - - u8 ambient[3] = { - (dsAmbient)&0x1F, - (dsAmbient>>5)&0x1F, - (dsAmbient>>10)&0x1F }; - - u8 emission[3] = { - (dsEmission)&0x1F, - (dsEmission>>5)&0x1F, - (dsEmission>>10)&0x1F }; - - u8 specular[3] = { - (dsSpecular)&0x1F, - (dsSpecular>>5)&0x1F, - (dsSpecular>>10)&0x1F }; - - int vertexColor[3] = { emission[0], emission[1], emission[2] }; - - //do we need to normalize lineOfSight? - Vector3Normalize(lineOfSight); - - for(i=0;i<4;i++) { - if(!((lightMask>>i)&1)) - continue; - - { - u8 lightColor[3] = { - (g_lightInfo[i].color)&0x1F, - (g_lightInfo[i].color>>5)&0x1F, - (g_lightInfo[i].color>>10)&0x1F }; - - float dot = Vector3Dot(g_lightInfo[i].floatDirection,normal); - float diffuseComponent = max(0,dot); - float specularComponent; - - //a specular formula which I couldnt get working - //float halfAngle[3] = { - // (lineOfSight[0] + g_lightInfo[i].floatDirection[0])/2, - // (lineOfSight[1] + g_lightInfo[i].floatDirection[1])/2, - // (lineOfSight[2] + g_lightInfo[i].floatDirection[2])/2}; - //float halfAngleLength = sqrt(halfAngle[0]*halfAngle[0]+halfAngle[1]*halfAngle[1]+halfAngle[2]*halfAngle[2]); - //float halfAngleNormalized[3] = { - // halfAngle[0]/halfAngleLength, - // halfAngle[1]/halfAngleLength, - // halfAngle[2]/halfAngleLength - //}; - // - //float specularAngle = -Vector3Dot(halfAngleNormalized,normal); - //specularComponent = max(0,cos(specularAngle)); - - //a specular formula which seems to work - float temp[4]; - float diff = Vector3Dot(normal,g_lightInfo[i].floatDirection); - Vector3Copy(temp,normal); - Vector3Scale(temp,-2*diff); - Vector3Add(temp,g_lightInfo[i].floatDirection); - Vector3Scale(temp,-1); - specularComponent = max(0,Vector3Dot(lineOfSight,temp)); - - //if the game isnt producing unit normals, then we can accidentally out of range components. so lets saturate them here - //so we can at least keep for crashing. we're not sure what the hardware does in this case, but the game shouldnt be doing this. - specularComponent = max(0,min(1,specularComponent)); - diffuseComponent = max(0,min(1,diffuseComponent)); - - for(c=0;c<3;c++) { - vertexColor[c] += (diffuseComponent*lightColor[c]*diffuse[c])/31; - vertexColor[c] += (specularComponent*lightColor[c]*specular[c])/31; - vertexColor[c] += ((float)lightColor[c]*ambient[c])/31; - } - } - } - - for(c=0;c<3;c++) - colorRGB[c] = material_5bit_to_31bit[min(31,vertexColor[c])]; - } -} - -static bool flushPending = false; -static u32 flush_wbuffer; -static u32 flush_sortmode; - -void NDS_glFlush(unsigned long v) -{ - flushPending = true; - flush_wbuffer = v&1; - flush_sortmode = (v>>1)&1; -} - -void GL_Draw() -{ xglDepthMask (GL_TRUE); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); @@ -1900,8 +995,8 @@ void GL_Draw() u32 lastTextureFormat, lastTexturePalette, lastPolyAttr; - for(int i=0;icount;i++) { - POLY *poly = &polylist->list[i]; + for(int i=0;icount;i++) { + POLY *poly = &gfx3d.polylist->list[i]; int type = poly->type; //a very macro-level state caching approach: @@ -1913,15 +1008,15 @@ void GL_Draw() lastTexturePalette = texturePalette = poly->texPalette; BeginRenderPoly(); } - + //since we havent got the whole pipeline working yet, lets use opengl for the projection glMatrixMode(GL_PROJECTION); glLoadMatrixf(poly->projMatrix); glBegin(type==3?GL_TRIANGLES:GL_QUADS); for(int j=0;jlist[poly->vertIndexes[j]]; - + VERT* vert = &gfx3d.vertlist->list[poly->vertIndexes[j]]; + //float tempCoord[4]; //Vector4Copy(tempCoord,vert->coord); //we havent got the whole pipeline working yet, so we cant do this @@ -1943,24 +1038,9 @@ void GL_Draw() //since we just redrew, we need to refresh the framebuffers needRefreshFramebuffer = true; - - twiddleLists(); - - //reset GE state - clCmd = 0; - clInd = 0; } -void NDS_3D_VBlankSignal() -{ - //the 3d buffers are swapped when a vblank begins. - //so, if we have a redraw pending, now is a safe time to do it - if(!flushPending) return; - flushPending = false; - GL_Draw(); -} - -void NDS_3D_VramReconfigureSignal() +static void VramReconfigureSignal() { //well, this is a very blunt instrument. //lets just flag all the textures as invalid. @@ -1971,7 +1051,7 @@ void NDS_3D_VramReconfigureSignal() void GL_ReadFramebuffer() { glFinish(); - glReadPixels(0,0,256,192,GL_RGBA, GL_UNSIGNED_BYTE, GPU_screen3D); + 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); //debug: view depth buffer via color buffer for debugging @@ -1997,7 +1077,7 @@ void GL_ReadFramebuffer() //NHerve mod3 - Fixed blending with 2D backgrounds (New Super Mario Bros looks better) //zeromus post-mod3: fix even better -static void NDS_glGetLine (int line, u16* dst) +static void GetLine (int line, u16* dst) { assert(line<192 && line>=0); @@ -2005,7 +1085,7 @@ static void NDS_glGetLine (int line, u16* dst) needRefreshFramebuffer = false; GL_ReadFramebuffer(); } - + u8 *screen3D = (u8*)GPU_screen3D+((191-line)<<10); u8 *screenStencil = (u8*)GPU_screenStencil+((191-line)<<8); @@ -2013,7 +1093,7 @@ static void NDS_glGetLine (int line, u16* dst) //then it sets it to 1 whenever it renders a pixel that passes the alpha test //(it also sets it to 2 under some circumstances when rendering shadow volumes) //so, we COULD use a zero stencil value to indicate that nothing should get composited. - //in fact, we are going to do that to fix some problems. + //in fact, we are going to do that to fix some problems. //but beware that it i figure it might could CAUSE some problems //this alpha compositing blending logic isnt thought through at all @@ -2049,539 +1129,20 @@ static void NDS_glGetLine (int line, u16* dst) } } -__forceinline void NDS_glBoxTest(unsigned long v) -{ -} - -__forceinline void NDS_glPosTest(unsigned long v) -{ -} - -__forceinline void NDS_glVecTest(unsigned long v) -{ - //printlog("NDS_glVecTest\n"); -} - -__forceinline long NDS_glGetPosRes(unsigned int index) -{ - //printlog("NDS_glGetPosRes\n"); - return 0; -} - -__forceinline long NDS_glGetVecRes(unsigned int index) -{ - //printlog("NDS_glGetVecRes\n"); - return 0; -} - -__forceinline void NDS_glCallList(unsigned long v) -{ - //static unsigned long oldval = 0, shit = 0; - - if(!clInd) - { - clInd = 4; - clCmd = v; - return; - } - - for (;;) - { - switch ((clCmd&0xFF)) - { - case 0x0: - { - if (clInd > 0) - { - --clInd; - clCmd >>= 8; - continue; - } - break; - } - - case 0x11 : - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x444>>2] = v; - NDS_glPushMatrix(); - --clInd; - clCmd>>=8; - continue; - } - - case 0x15: - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x454>>2] = v; - NDS_glLoadIdentity(); - --clInd; - clCmd>>=8; - continue; - } - - case 0x41: - { - NDS_glEnd(); - --clInd; - clCmd>>=8; - continue; - } - } - - break; - } - if(!clInd) - { - clInd = 4; - clCmd = v; - return; - } - switch(clCmd&0xFF) - { - case 0x10: - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x440>>2] = v; - NDS_glMatrixMode (v); - --clInd; - clCmd>>=8; - break; - } - case 0x12: - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x448>>2] = v; - NDS_glPopMatrix(v); - --clInd; - clCmd>>=8; - break; - } - - case 0x13: - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x44C>>2] = v; - NDS_glStoreMatrix(v); - --clInd; - clCmd>>=8; - break; - } - - case 0x14: - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x450>>2] = v; - NDS_glRestoreMatrix (v); - --clInd; - clCmd>>=8; - break; - } - - case 0x16: - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x458>>2] = v; - NDS_glLoadMatrix4x4(v); - clInd2++; - if(clInd2==16) - { - --clInd; - clCmd>>=8; - clInd2 = 0; - } - break; - } - - case 0x17: - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x45C>>2] = v; - NDS_glLoadMatrix4x3(v); - clInd2++; - if(clInd2==12) - { - --clInd; - clCmd>>=8; - clInd2 = 0; - } - break; - } - - case 0x18: - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x460>>2] = v; - NDS_glMultMatrix4x4(v); - clInd2++; - if(clInd2==16) - { - --clInd; - clCmd>>=8; - clInd2 = 0; - } - break; - } - - case 0x19: - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x464>>2] = v; - NDS_glMultMatrix4x3(v); - clInd2++; - if(clInd2==12) - { - --clInd; - clCmd>>=8; - clInd2 = 0; - } - break; - } - - case 0x1A: - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x468>>2] = v; - NDS_glMultMatrix3x3(v); - clInd2++; - if(clInd2==9) - { - --clInd; - clCmd>>=8; - clInd2 = 0; - } - break; - } - - case 0x1B: - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x46C>>2] = v; - NDS_glScale (v); - clInd2++; - if(clInd2==3) - { - --clInd; - clCmd>>=8; - clInd2 = 0; - } - break; - } - - case 0x1C: - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x470>>2] = v; - NDS_glTranslate (v); - clInd2++; - if(clInd2==3) - { - --clInd; - clCmd>>=8; - clInd2 = 0; - } - break; - } - - case 0x20 : - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x480>>2] = v; - NDS_glColor3b(v); - --clInd; - clCmd>>=8; - break; - } - - case 0x21 : - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x484>>2] = v; - NDS_glNormal(v); - --clInd; - clCmd>>=8; - break; - } - - case 0x22 : - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x488>>2] = v; - NDS_glTexCoord(v); - --clInd; - clCmd>>=8; - break; - } - - case 0x23 : - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x48C>>2] = v; - NDS_glVertex16b(v); - clInd2++; - if(clInd2==2) - { - --clInd; - clCmd>>=8; - clInd2 = 0; - } - break; - } - - case 0x24: - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x490>>2] = v; - NDS_glVertex10b(v); - --clInd; - clCmd>>=8; - break; - } - - case 0x25:// GFX_VERTEX_XY - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x494>>2] = v; - NDS_glVertex3_cord(0,1,v); - --clInd; - clCmd>>=8; - break; - } - - case 0x26:// GFX_VERTEX_XZ - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x498>>2] = v; - NDS_glVertex3_cord(0,2,v); - --clInd; - clCmd>>=8; - break; - } - - case 0x27:// GFX_VERTEX_YZ - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x49C>>2] = v; - NDS_glVertex3_cord(1,2,v); - --clInd; - clCmd>>=8; - break; - } - - case 0x28: // GFX_VERTEX_DIFF - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x4A0>>2] = v; - NDS_glVertex_rel (v); - --clInd; - clCmd>>=8; - break; - } - - case 0x29: - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x4A4>>2] = v; - NDS_glPolygonAttrib (v); - --clInd; - clCmd>>=8; - break; - } - - case 0x2A: - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x4A8>>2] = v; - NDS_glTexImage (v); - --clInd; - clCmd>>=8; - break; - } - - case 0x2B: - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x4AC>>2] = v; - NDS_glTexPalette (v&0x1FFF); - --clInd; - clCmd>>=8; - break; - } - - case 0x30: // GFX_DIFFUSE_AMBIENT - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x4C0>>2] = v; - NDS_glMaterial0(v); - --clInd; - clCmd>>=8; - break; - } - - case 0x31: // GFX_SPECULAR_EMISSION - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x4C4>>2] = v; - NDS_glMaterial1(v); - --clInd; - clCmd>>=8; - break; - } - - case 0x32: - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x4C8>>2] = v; - NDS_glLightDirection(v); - --clInd; - clCmd>>=8; - break; - } - - case 0x33: - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x4CC>>2] = v; - NDS_glLightColor(v); - --clInd; - clCmd>>=8; - break; - } - - case 0x34: - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x4D0>>2] = v; - NDS_glShininess (v); - clInd2++; - if(clInd2==32) - { - --clInd; - clCmd>>=8; - clInd2 = 0; - } - break; - } - - case 0x40 : - { - //old_vtxFormat=((unsigned long *)ARM9Mem.ARM9_REG)[0x500>>2]; - ((unsigned long *)ARM9Mem.ARM9_REG)[0x500>>2] = v; - NDS_glBegin(v); - --clInd; - clCmd>>=8; - break; - } -/* - case 0x50: - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x540>>2] = v; - NDS_glFlush(v); - --clInd; - clCmd>>=8; - break; - } -*/ - case 0x60: - { - ((unsigned long *)ARM9Mem.ARM9_REG)[0x580>>2] = v; - NDS_glViewPort(v); - --clInd; - clCmd>>=8; - break; - } -/* - case 0x80: - { - clInd2++; - if(clInd2==7) - { - --clInd; - clCmd>>=8; - clInd2 = 0; - } - - break; - } -*/ - default: - { - LOG ("Unknown 3D command %02X\n", clCmd&0xFF); - --clInd; - clCmd>>=8; - break; - } - } - if((clCmd&0xFF)==0x41) - { - --clInd; - clCmd>>=8; - } -} - -__forceinline void NDS_glGetMatrix(unsigned int mode, unsigned int index, float* dest) -{ - //int n; - - if(index == -1) - { - MatrixCopy(dest, mtxCurrent[mode]); - return; - } - - MatrixCopy(dest, MatrixStackGetPos(&mtxStack[mode], index)); -} - -__forceinline void NDS_glGetLightDirection(unsigned int index, unsigned int* dest) -{ - *dest = g_lightInfo[index].direction; -} - -__forceinline void NDS_glGetLightColor(unsigned int index, unsigned int* dest) -{ - *dest = g_lightInfo[index].color; -} - -GPU3DInterface gpu3Dgl = { NDS_glInit, - NDS_3D_Reset, - NDS_3D_Close, - - NDS_glViewPort, - NDS_glClearColor, - NDS_glFogColor, - NDS_glFogOffset, - NDS_glClearDepth, - NDS_glMatrixMode, - NDS_glLoadIdentity, - NDS_glLoadMatrix4x4, - NDS_glLoadMatrix4x3, - NDS_glStoreMatrix, - NDS_glRestoreMatrix, - NDS_glPushMatrix, - NDS_glPopMatrix, - NDS_glTranslate, - NDS_glScale, - NDS_glMultMatrix3x3, - NDS_glMultMatrix4x3, - NDS_glMultMatrix4x4, - NDS_glBegin, - NDS_glEnd, - NDS_glColor3b, - NDS_glVertex16b, - NDS_glVertex10b, - NDS_glVertex3_cord, - NDS_glVertex_rel, - NDS_glSwapScreen, - NDS_glGetNumPolys, - NDS_glGetNumVertex, - NDS_glFlush, - NDS_glPolygonAttrib, - NDS_glMaterial0, - NDS_glMaterial1, - NDS_glShininess, - NDS_glTexImage, - NDS_glTexPalette, - NDS_glTexCoord, - NDS_glLightDirection, - NDS_glLightColor, - NDS_glAlphaFunc, - NDS_glControl, - NDS_glNormal, - NDS_glCallList, - - NDS_glGetClipMatrix, - NDS_glGetDirectionalMatrix, - NDS_glGetLine, - - NDS_glGetMatrix, - NDS_glGetLightDirection, - NDS_glGetLightColor, - - NDS_glBoxTest, - NDS_glPosTest, - NDS_glVecTest, - NDS_glGetPosRes, - NDS_glGetVecRes, - NDS_3D_UpdateToonTable, - NDS_3D_VBlankSignal, - NDS_3D_VramReconfigureSignal, +GPU3DInterface gpu3Dgl = { + Init, + Reset, + Close, + Render, + VramReconfigureSignal, + GetLine }; //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 +//consider building a little state structure that looks exactly like this describes \ No newline at end of file diff --git a/desmume/src/windows/lightView.cpp b/desmume/src/windows/lightView.cpp index 3c1f49c31..f65810f95 100644 --- a/desmume/src/windows/lightView.cpp +++ b/desmume/src/windows/lightView.cpp @@ -22,7 +22,7 @@ #include "lightView.h" #include "resource.h" #include "matrix.h" -#include "render3d.h" +#include "gfx3d.h" #include "armcpu.h" #include "colorctrl.h" #include "colorconv.h" @@ -74,9 +74,9 @@ void LightView_OnPaintLight(lightview_struct* win, int index) ColorCtrl* colorCtrl; char buffer[128]; - // Get necessary information from render module - gpu3D->NDS_glGetLightColor(index, &color); - gpu3D->NDS_glGetLightDirection(index, &direction); + // Get necessary information from gfx3d module + gfx3d_glGetLightColor(index, &color); + gfx3d_glGetLightDirection(index, &direction); // Print Light Direction sprintf(buffer, "%.8x", direction); diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp index 1be9b9d44..f49059463 100644 --- a/desmume/src/windows/main.cpp +++ b/desmume/src/windows/main.cpp @@ -50,6 +50,7 @@ #include "FirmConfig.h" #include "AboutBox.h" #include "OGLRender.h" +#include "../gfx3d.h" #include "../render3D.h" #include "../gdbstub.h" #include "colorctrl.h" @@ -418,7 +419,7 @@ DWORD WINAPI run( LPVOID lpParameter) return -1; } - NDS_3D_SetDriver (GPU3D_OPENGL); + //NDS_3D_SetDriver (GPU3D_OPENGL); if (!gpu3D->NDS_3D_Init ()) { diff --git a/desmume/src/windows/matrixView.cpp b/desmume/src/windows/matrixView.cpp index 2bc9b1b55..11ab3563c 100644 --- a/desmume/src/windows/matrixView.cpp +++ b/desmume/src/windows/matrixView.cpp @@ -22,8 +22,8 @@ #include "matrixView.h" #include "resource.h" #include "matrix.h" -#include "render3d.h" #include "armcpu.h" +#include "gfx3d.h" ////////////////////////////////////////////////////////////////////////////// @@ -99,7 +99,7 @@ void MatrixView_OnPaintPositionMatrix(matrixview_struct* win) stackIndex = SendMessage(hStackCombo, CB_GETCURSEL, 0, 0) - 1; - gpu3D->NDS_3D_GetMatrix(1, stackIndex, matrix); + gfx3d_glGetMatrix(1, stackIndex, matrix); MatrixView_SetMatrix(win, idcGroup, matrix); } @@ -122,7 +122,7 @@ void MatrixView_OnPaintDirectionMatrix(matrixview_struct* win) stackIndex = SendMessage(hStackCombo, CB_GETCURSEL, 0, 0) - 1; - gpu3D->NDS_3D_GetMatrix(2, stackIndex, matrix); + gfx3d_glGetMatrix(2, stackIndex, matrix); MatrixView_SetMatrix(win, idcGroup, matrix); } @@ -141,7 +141,7 @@ void MatrixView_OnPaintProjectionMatrix(matrixview_struct* win) float mat[16]; - gpu3D->NDS_3D_GetMatrix(0, -1, mat); + gfx3d_glGetMatrix(0, -1, mat); MatrixView_SetMatrix(win, idcGroup, mat); } @@ -160,7 +160,7 @@ void MatrixView_OnPaintTextureMatrix(matrixview_struct* win) float mat[16]; - gpu3D->NDS_3D_GetMatrix(3, -1, mat); + gfx3d_glGetMatrix(3, -1, mat); MatrixView_SetMatrix(win, idcGroup, mat); }