Arachnoid GLESv1.1 plugin. Compile and run (a bit glitchy and no frameskip) on the...
[mupen64plus-pandora.git] / source / mupen64plus-video-arachnoid / src / GBI / GBI.cpp
diff --git a/source/mupen64plus-video-arachnoid/src/GBI/GBI.cpp b/source/mupen64plus-video-arachnoid/src/GBI/GBI.cpp
new file mode 100755 (executable)
index 0000000..8a99ee4
--- /dev/null
@@ -0,0 +1,247 @@
+/******************************************************************************
+ * Arachnoid Graphics Plugin for Mupen64Plus
+ * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
+ *
+ * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *****************************************************************************/
+
+#include "GBI.h"
+#include "GBIDefs.h"
+#include "RSP.h"
+#include "RDP.h"
+#include "UCodeSelector.h"
+#include "UCodeIdentificationData.h"
+#include "OpenGLManager.h"
+#include "Logger.h"
+#include "m64p.h"
+
+//-----------------------------------------------------------------------------
+//! Static Variables
+//-----------------------------------------------------------------------------
+unsigned int GBI::G_MOVEMEM, GBI::G_MOVEWORD;
+unsigned int GBI::G_RDPHALF_1, GBI::G_RDPHALF_2, GBI::G_RDPHALF_CONT;
+unsigned int GBI::G_SPNOOP;
+unsigned int GBI::G_SETOTHERMODE_H, GBI::G_SETOTHERMODE_L;
+unsigned int GBI::G_DL, GBI::G_ENDDL, GBI::G_CULLDL, GBI::G_BRANCH_Z;
+unsigned int GBI::G_LOAD_UCODE;
+
+unsigned int GBI::G_MTX, GBI::G_POPMTX;
+unsigned int GBI::G_GEOMETRYMODE, GBI::G_SETGEOMETRYMODE, GBI::G_CLEARGEOMETRYMODE;
+unsigned int GBI::G_TEXTURE;
+unsigned int GBI::G_DMA_IO, GBI::G_DMA_DL, GBI::G_DMA_TRI, GBI::G_DMA_MTX, GBI::G_DMA_VTX, GBI::G_DMA_OFFSETS;
+unsigned int GBI::G_SPECIAL_1, GBI::G_SPECIAL_2, GBI::G_SPECIAL_3;
+unsigned int GBI::G_VTX, GBI::G_MODIFYVTX, GBI::G_VTXCOLORBASE;
+unsigned int GBI::G_TRI1, GBI::G_TRI2, GBI::G_TRI4;
+unsigned int GBI::G_QUAD, GBI::G_LINE3D;
+unsigned int GBI::G_RESERVED0, GBI::G_RESERVED1, GBI::G_RESERVED2, GBI::G_RESERVED3;
+unsigned int GBI::G_SPRITE2D_BASE;
+unsigned int GBI::G_BG_1CYC, GBI::G_BG_COPY;
+unsigned int GBI::G_OBJ_RECTANGLE, GBI::G_OBJ_SPRITE, GBI::G_OBJ_MOVEMEM;
+unsigned int GBI::G_SELECT_DL, GBI::G_OBJ_RENDERMODE, GBI::G_OBJ_RECTANGLE_R;
+unsigned int GBI::G_OBJ_LOADTXTR, GBI::G_OBJ_LDTX_SPRITE, GBI::G_OBJ_LDTX_RECT, GBI::G_OBJ_LDTX_RECT_R;
+unsigned int GBI::G_RDPHALF_0;
+
+unsigned int GBI::G_MTX_STACKSIZE;
+unsigned int GBI::G_MTX_MODELVIEW;
+unsigned int GBI::G_MTX_PROJECTION;
+unsigned int GBI::G_MTX_MUL;
+unsigned int GBI::G_MTX_LOAD;
+unsigned int GBI::G_MTX_NOPUSH;
+unsigned int GBI::G_MTX_PUSH;
+
+unsigned int GBI::G_TEXTURE_ENABLE;
+unsigned int GBI::G_SHADING_SMOOTH;
+unsigned int GBI::G_CULL_FRONT;
+unsigned int GBI::G_CULL_BACK;
+unsigned int GBI::G_CULL_BOTH;
+unsigned int GBI::G_CLIPPING;
+
+unsigned int GBI::G_MV_VIEWPORT;
+
+unsigned int GBI::G_MWO_aLIGHT_1, GBI::G_MWO_bLIGHT_1;
+unsigned int GBI::G_MWO_aLIGHT_2, GBI::G_MWO_bLIGHT_2;
+unsigned int GBI::G_MWO_aLIGHT_3, GBI::G_MWO_bLIGHT_3;
+unsigned int GBI::G_MWO_aLIGHT_4, GBI::G_MWO_bLIGHT_4;
+unsigned int GBI::G_MWO_aLIGHT_5, GBI::G_MWO_bLIGHT_5;
+unsigned int GBI::G_MWO_aLIGHT_6, GBI::G_MWO_bLIGHT_6;
+unsigned int GBI::G_MWO_aLIGHT_7, GBI::G_MWO_bLIGHT_7;
+unsigned int GBI::G_MWO_aLIGHT_8, GBI::G_MWO_bLIGHT_8;
+
+//-----------------------------------------------------------------------------
+//! Constructor
+//-----------------------------------------------------------------------------
+GBI::GBI()
+{
+    m_ucodeSelector = 0;
+}
+
+//-----------------------------------------------------------------------------
+//! Destructor
+//-----------------------------------------------------------------------------
+GBI::~GBI()
+{
+    dispose();
+}
+
+//-----------------------------------------------------------------------------
+//* Initialize
+//-----------------------------------------------------------------------------
+bool GBI::initialize(RSP* rsp, RDP* rdp, Memory* memory, DisplayListParser* dlp)
+{
+    m_rsp = rsp;
+    m_rdp = rdp;
+    m_memory = memory;
+
+    //Reset Binary Interface
+    for(int i=0; i<256; ++i)
+    {
+        m_cmds[i] = (GBIFunc)GBI::unknownInstruction;
+    }
+
+    //Add RDP Instructions
+    m_rdpInsructions.initialize(m_rdp, dlp);
+
+    m_cmds[G_SETCIMG]            = (GBIFunc)RDPInstructions::RDP_SetCImg;
+    m_cmds[G_SETZIMG]            = (GBIFunc)RDPInstructions::RDP_SetZImg;
+    m_cmds[G_SETTIMG]            = (GBIFunc)RDPInstructions::RDP_SetTImg;
+    m_cmds[G_SETTILE]            = (GBIFunc)RDPInstructions::RDP_SetTile;
+    m_cmds[G_LOADTILE]           = (GBIFunc)RDPInstructions::RDP_LoadTile;
+    m_cmds[G_LOADBLOCK]          = (GBIFunc)RDPInstructions::RDP_LoadBlock;
+    m_cmds[G_SETTILESIZE]        = (GBIFunc)RDPInstructions::RDP_SetTileSize;
+    m_cmds[G_LOADTLUT]           = (GBIFunc)RDPInstructions::RDP_LoadTLUT;
+    m_cmds[G_FILLRECT]           = (GBIFunc)RDPInstructions::RDP_FillRect;
+    m_cmds[G_TEXRECTFLIP]        = (GBIFunc)RDPInstructions::RDP_TexRectFlip;
+    m_cmds[G_TEXRECT]            = (GBIFunc)RDPInstructions::RDP_TexRect;
+    m_cmds[G_SETENVCOLOR]        = (GBIFunc)RDPInstructions::RDP_SetEnvColor;
+    m_cmds[G_SETPRIMCOLOR]       = (GBIFunc)RDPInstructions::RDP_SetPrimColor;
+    m_cmds[G_SETBLENDCOLOR]      = (GBIFunc)RDPInstructions::RDP_SetBlendColor;
+    m_cmds[G_SETFOGCOLOR]        = (GBIFunc)RDPInstructions::RDP_SetFogColor;
+    m_cmds[G_SETFILLCOLOR]       = (GBIFunc)RDPInstructions::RDP_SetFillColor;
+    m_cmds[G_SETCOMBINE]         = (GBIFunc)RDPInstructions::RDP_SetCombine;
+    m_cmds[G_RDPSETOTHERMODE]    = (GBIFunc)RDPInstructions::RDP_SetOtherMode;
+    m_cmds[G_SETPRIMDEPTH]       = (GBIFunc)RDPInstructions::RDP_SetPrimDepth;
+    m_cmds[G_SETSCISSOR]         = (GBIFunc)RDPInstructions::RDP_SetScissor;
+    m_cmds[G_SETCONVERT]         = (GBIFunc)RDPInstructions::RDP_SetConvert;
+    m_cmds[G_SETKEYR]            = (GBIFunc)RDPInstructions::RDP_SetKeyR;
+    m_cmds[G_SETKEYGB]           = (GBIFunc)RDPInstructions::RDP_SetKeyGB;
+    m_cmds[G_NOOP]               = (GBIFunc)RDPInstructions::RDP_NoOp;
+    m_cmds[G_RDPFULLSYNC]        = (GBIFunc)RDPInstructions::RDP_FullSync;
+    m_cmds[G_RDPTILESYNC]        = (GBIFunc)RDPInstructions::RDP_TileSync;
+    m_cmds[G_RDPPIPESYNC]        = (GBIFunc)RDPInstructions::RDP_PipeSync;
+    m_cmds[G_RDPLOADSYNC]        = (GBIFunc)RDPInstructions::RDP_LoadSync;
+
+    m_ucodeSelector = new UCodeSelector();
+    if ( !m_ucodeSelector->initialize(memory) ) {
+        return false;
+    }
+
+    //Initilize Ucode
+
+    m_ucode0.initialize(m_rsp, m_rdp, memory, dlp);        //F3D
+    m_ucode1.initialize(this, m_rsp, m_rdp, memory);       //F3DEX
+    m_ucode2.initialize(this, m_rsp, m_rdp, memory, dlp);  //Golden Eye
+    m_ucode4.initialize(this, m_rsp);                      //Wave Race 64
+    m_ucode5.initialize(this, m_rsp, m_rdp, memory, dlp);  //F3DEX2
+    m_ucode6.initialize(this, m_rsp, m_rdp, memory, dlp);  //Diddy Kong Racing
+    m_ucode7.initialize(m_rsp);
+    m_ucode9.initialize(m_rsp);                            //Perfect Dark
+    m_ucode10.initialize(this, m_rsp, m_rdp, memory, dlp);
+
+    m_previusUCodeStart = -1;
+
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+// Dispose
+//-----------------------------------------------------------------------------
+void GBI::dispose()
+{
+    if ( m_ucodeSelector ) { delete m_ucodeSelector; m_ucodeSelector = 0; }
+
+    m_previusUCodeStart = -1;
+}
+
+//-----------------------------------------------------------------------------
+// Select UCode
+//-----------------------------------------------------------------------------
+void GBI::selectUCode( unsigned int ucStart, 
+                    unsigned int ucDStart, 
+                    unsigned int ucSize, 
+                    unsigned int ucDSize)
+{
+    if ( m_previusUCodeStart == ucStart )
+    {
+        return; //Already have correct ucode no need to find one
+    }
+    m_previusUCodeStart = ucStart;
+
+    //Identify ucode
+    unsigned int ucode = m_ucodeSelector->checkUCode(ucStart, ucDStart, ucSize, ucDSize);
+
+    //Unsupported ucodes
+    if ( ucode >= 6 || ucode == 3 )
+    {
+        //MessageBox(0, 
+        //    "This graphics plugin does not support this game, please try another.", 
+        //    "Arachnoid Graphics Plugin", 
+        //    MB_OK|MB_SETFOREGROUND );
+    }
+
+    //if ( ucode == 5 )
+    //{
+    //    OpenGLManager::getSingleton().setForceDisableCulling(true);  //Do not support Face Culling?
+    //}
+
+    //Set Ucode
+    switch ( ucode )
+    {
+        case 0   : m_ucode0.initializeGBI(this); break;  //F3D    - Super Mario 64
+        case 1   : m_ucode1.initializeGBI();     break;  //F3DEX  - Mario Kart, Star Fox 64, Bomberman 64, ...
+        case 2   : m_ucode2.initializeGBI();     break;  //       - Golden Eye
+        case 3   :                                       //S2DEX  - Chou Snobow Kids, V-Rally Edition 99, Zelda Majoras Mask
+        case 4   : m_ucode4.initializeGBI();     break;  //       - Wave Racer 64
+        case 5   : m_ucode5.initializeGBI();     break;  //F3DEX2 - Donkey Kong 64, Fighter's Destiny 2, Mario Golf 64, F-Zero X, Paper Mario, ...
+        case 6   : m_ucode6.initializeGBI();     break;  //       - Diddy Kong Racing
+        case 7   : m_ucode7.initializeGBI(this); break;  //       - Yoshi's Story
+        case 8   :                                       //       - Puzzle Master 64
+        case 9   : m_ucode9.initializeGBI(this); break;  //       - Perfect Dark
+        case 10  : m_ucode10.initializeGBI();            //       - Conker The Bad Fur Day
+        case 11  : m_ucode6.initializeGBI();     break;  //       - Jet Force Gemini
+        case 12  : m_ucode1.initializeGBI();     break;  //       - 1080
+        default  : 
+            //m_ucode5.initializeGBI(this); break;  //F3DEX2
+            //m_ucode1.initializeGBI(this); 
+            m_ucode0.initializeGBI(this); 
+            break;
+    }
+
+}
+
+//-----------------------------------------------------------------------------
+//! Unknown Instruction
+//! This function will be called when the GBI can't find the correct function
+//! to call.
+//-----------------------------------------------------------------------------
+void GBI::unknownInstruction(MicrocodeArgument* arg)
+{
+    static bool warned = false;
+    if ( !warned ) {
+        Logger::getSingleton().printMsg("GBI - Unknown Function", M64MSG_WARNING);
+        warned = true;
+    }
+}