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
1 /******************************************************************************
2  * Arachnoid Graphics Plugin for Mupen64Plus
3  * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
4  *
5  * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20  *****************************************************************************/
21
22 #include "GBI.h"
23 #include "GBIDefs.h"
24 #include "RSP.h"
25 #include "RDP.h"
26 #include "UCodeSelector.h"
27 #include "UCodeIdentificationData.h"
28 #include "OpenGLManager.h"
29 #include "Logger.h"
30 #include "m64p.h"
31
32 //-----------------------------------------------------------------------------
33 //! Static Variables
34 //-----------------------------------------------------------------------------
35 unsigned int GBI::G_MOVEMEM, GBI::G_MOVEWORD;
36 unsigned int GBI::G_RDPHALF_1, GBI::G_RDPHALF_2, GBI::G_RDPHALF_CONT;
37 unsigned int GBI::G_SPNOOP;
38 unsigned int GBI::G_SETOTHERMODE_H, GBI::G_SETOTHERMODE_L;
39 unsigned int GBI::G_DL, GBI::G_ENDDL, GBI::G_CULLDL, GBI::G_BRANCH_Z;
40 unsigned int GBI::G_LOAD_UCODE;
41
42 unsigned int GBI::G_MTX, GBI::G_POPMTX;
43 unsigned int GBI::G_GEOMETRYMODE, GBI::G_SETGEOMETRYMODE, GBI::G_CLEARGEOMETRYMODE;
44 unsigned int GBI::G_TEXTURE;
45 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;
46 unsigned int GBI::G_SPECIAL_1, GBI::G_SPECIAL_2, GBI::G_SPECIAL_3;
47 unsigned int GBI::G_VTX, GBI::G_MODIFYVTX, GBI::G_VTXCOLORBASE;
48 unsigned int GBI::G_TRI1, GBI::G_TRI2, GBI::G_TRI4;
49 unsigned int GBI::G_QUAD, GBI::G_LINE3D;
50 unsigned int GBI::G_RESERVED0, GBI::G_RESERVED1, GBI::G_RESERVED2, GBI::G_RESERVED3;
51 unsigned int GBI::G_SPRITE2D_BASE;
52 unsigned int GBI::G_BG_1CYC, GBI::G_BG_COPY;
53 unsigned int GBI::G_OBJ_RECTANGLE, GBI::G_OBJ_SPRITE, GBI::G_OBJ_MOVEMEM;
54 unsigned int GBI::G_SELECT_DL, GBI::G_OBJ_RENDERMODE, GBI::G_OBJ_RECTANGLE_R;
55 unsigned int GBI::G_OBJ_LOADTXTR, GBI::G_OBJ_LDTX_SPRITE, GBI::G_OBJ_LDTX_RECT, GBI::G_OBJ_LDTX_RECT_R;
56 unsigned int GBI::G_RDPHALF_0;
57
58 unsigned int GBI::G_MTX_STACKSIZE;
59 unsigned int GBI::G_MTX_MODELVIEW;
60 unsigned int GBI::G_MTX_PROJECTION;
61 unsigned int GBI::G_MTX_MUL;
62 unsigned int GBI::G_MTX_LOAD;
63 unsigned int GBI::G_MTX_NOPUSH;
64 unsigned int GBI::G_MTX_PUSH;
65
66 unsigned int GBI::G_TEXTURE_ENABLE;
67 unsigned int GBI::G_SHADING_SMOOTH;
68 unsigned int GBI::G_CULL_FRONT;
69 unsigned int GBI::G_CULL_BACK;
70 unsigned int GBI::G_CULL_BOTH;
71 unsigned int GBI::G_CLIPPING;
72
73 unsigned int GBI::G_MV_VIEWPORT;
74
75 unsigned int GBI::G_MWO_aLIGHT_1, GBI::G_MWO_bLIGHT_1;
76 unsigned int GBI::G_MWO_aLIGHT_2, GBI::G_MWO_bLIGHT_2;
77 unsigned int GBI::G_MWO_aLIGHT_3, GBI::G_MWO_bLIGHT_3;
78 unsigned int GBI::G_MWO_aLIGHT_4, GBI::G_MWO_bLIGHT_4;
79 unsigned int GBI::G_MWO_aLIGHT_5, GBI::G_MWO_bLIGHT_5;
80 unsigned int GBI::G_MWO_aLIGHT_6, GBI::G_MWO_bLIGHT_6;
81 unsigned int GBI::G_MWO_aLIGHT_7, GBI::G_MWO_bLIGHT_7;
82 unsigned int GBI::G_MWO_aLIGHT_8, GBI::G_MWO_bLIGHT_8;
83
84 //-----------------------------------------------------------------------------
85 //! Constructor
86 //-----------------------------------------------------------------------------
87 GBI::GBI()
88 {
89     m_ucodeSelector = 0;
90 }
91
92 //-----------------------------------------------------------------------------
93 //! Destructor
94 //-----------------------------------------------------------------------------
95 GBI::~GBI()
96 {
97     dispose();
98 }
99
100 //-----------------------------------------------------------------------------
101 //* Initialize
102 //-----------------------------------------------------------------------------
103 bool GBI::initialize(RSP* rsp, RDP* rdp, Memory* memory, DisplayListParser* dlp)
104 {
105     m_rsp = rsp;
106     m_rdp = rdp;
107     m_memory = memory;
108
109     //Reset Binary Interface
110     for(int i=0; i<256; ++i)
111     {
112         m_cmds[i] = (GBIFunc)GBI::unknownInstruction;
113     }
114
115     //Add RDP Instructions
116     m_rdpInsructions.initialize(m_rdp, dlp);
117
118     m_cmds[G_SETCIMG]            = (GBIFunc)RDPInstructions::RDP_SetCImg;
119     m_cmds[G_SETZIMG]            = (GBIFunc)RDPInstructions::RDP_SetZImg;
120     m_cmds[G_SETTIMG]            = (GBIFunc)RDPInstructions::RDP_SetTImg;
121     m_cmds[G_SETTILE]            = (GBIFunc)RDPInstructions::RDP_SetTile;
122     m_cmds[G_LOADTILE]           = (GBIFunc)RDPInstructions::RDP_LoadTile;
123     m_cmds[G_LOADBLOCK]          = (GBIFunc)RDPInstructions::RDP_LoadBlock;
124     m_cmds[G_SETTILESIZE]        = (GBIFunc)RDPInstructions::RDP_SetTileSize;
125     m_cmds[G_LOADTLUT]           = (GBIFunc)RDPInstructions::RDP_LoadTLUT;
126     m_cmds[G_FILLRECT]           = (GBIFunc)RDPInstructions::RDP_FillRect;
127     m_cmds[G_TEXRECTFLIP]        = (GBIFunc)RDPInstructions::RDP_TexRectFlip;
128     m_cmds[G_TEXRECT]            = (GBIFunc)RDPInstructions::RDP_TexRect;
129     m_cmds[G_SETENVCOLOR]        = (GBIFunc)RDPInstructions::RDP_SetEnvColor;
130     m_cmds[G_SETPRIMCOLOR]       = (GBIFunc)RDPInstructions::RDP_SetPrimColor;
131     m_cmds[G_SETBLENDCOLOR]      = (GBIFunc)RDPInstructions::RDP_SetBlendColor;
132     m_cmds[G_SETFOGCOLOR]        = (GBIFunc)RDPInstructions::RDP_SetFogColor;
133     m_cmds[G_SETFILLCOLOR]       = (GBIFunc)RDPInstructions::RDP_SetFillColor;
134     m_cmds[G_SETCOMBINE]         = (GBIFunc)RDPInstructions::RDP_SetCombine;
135     m_cmds[G_RDPSETOTHERMODE]    = (GBIFunc)RDPInstructions::RDP_SetOtherMode;
136     m_cmds[G_SETPRIMDEPTH]       = (GBIFunc)RDPInstructions::RDP_SetPrimDepth;
137     m_cmds[G_SETSCISSOR]         = (GBIFunc)RDPInstructions::RDP_SetScissor;
138     m_cmds[G_SETCONVERT]         = (GBIFunc)RDPInstructions::RDP_SetConvert;
139     m_cmds[G_SETKEYR]            = (GBIFunc)RDPInstructions::RDP_SetKeyR;
140     m_cmds[G_SETKEYGB]           = (GBIFunc)RDPInstructions::RDP_SetKeyGB;
141     m_cmds[G_NOOP]               = (GBIFunc)RDPInstructions::RDP_NoOp;
142     m_cmds[G_RDPFULLSYNC]        = (GBIFunc)RDPInstructions::RDP_FullSync;
143     m_cmds[G_RDPTILESYNC]        = (GBIFunc)RDPInstructions::RDP_TileSync;
144     m_cmds[G_RDPPIPESYNC]        = (GBIFunc)RDPInstructions::RDP_PipeSync;
145     m_cmds[G_RDPLOADSYNC]        = (GBIFunc)RDPInstructions::RDP_LoadSync;
146
147     m_ucodeSelector = new UCodeSelector();
148     if ( !m_ucodeSelector->initialize(memory) ) {
149         return false;
150     }
151
152     //Initilize Ucode
153
154     m_ucode0.initialize(m_rsp, m_rdp, memory, dlp);        //F3D
155     m_ucode1.initialize(this, m_rsp, m_rdp, memory);       //F3DEX
156     m_ucode2.initialize(this, m_rsp, m_rdp, memory, dlp);  //Golden Eye
157     m_ucode4.initialize(this, m_rsp);                      //Wave Race 64
158     m_ucode5.initialize(this, m_rsp, m_rdp, memory, dlp);  //F3DEX2
159     m_ucode6.initialize(this, m_rsp, m_rdp, memory, dlp);  //Diddy Kong Racing
160     m_ucode7.initialize(m_rsp);
161     m_ucode9.initialize(m_rsp);                            //Perfect Dark
162     m_ucode10.initialize(this, m_rsp, m_rdp, memory, dlp);
163
164     m_previusUCodeStart = -1;
165
166     return true;
167 }
168
169 //-----------------------------------------------------------------------------
170 // Dispose
171 //-----------------------------------------------------------------------------
172 void GBI::dispose()
173 {
174     if ( m_ucodeSelector ) { delete m_ucodeSelector; m_ucodeSelector = 0; }
175
176     m_previusUCodeStart = -1;
177 }
178
179 //-----------------------------------------------------------------------------
180 // Select UCode
181 //-----------------------------------------------------------------------------
182 void GBI::selectUCode( unsigned int ucStart, 
183                     unsigned int ucDStart, 
184                     unsigned int ucSize, 
185                     unsigned int ucDSize)
186 {
187     if ( m_previusUCodeStart == ucStart )
188     {
189         return; //Already have correct ucode no need to find one
190     }
191     m_previusUCodeStart = ucStart;
192
193     //Identify ucode
194     unsigned int ucode = m_ucodeSelector->checkUCode(ucStart, ucDStart, ucSize, ucDSize);
195
196     //Unsupported ucodes
197     if ( ucode >= 6 || ucode == 3 )
198     {
199         //MessageBox(0, 
200         //    "This graphics plugin does not support this game, please try another.", 
201         //    "Arachnoid Graphics Plugin", 
202         //    MB_OK|MB_SETFOREGROUND );
203     }
204
205     //if ( ucode == 5 )
206     //{
207     //    OpenGLManager::getSingleton().setForceDisableCulling(true);  //Do not support Face Culling?
208     //}
209
210     //Set Ucode
211     switch ( ucode )
212     {
213         case 0   : m_ucode0.initializeGBI(this); break;  //F3D    - Super Mario 64
214         case 1   : m_ucode1.initializeGBI();     break;  //F3DEX  - Mario Kart, Star Fox 64, Bomberman 64, ...
215         case 2   : m_ucode2.initializeGBI();     break;  //       - Golden Eye
216         case 3   :                                       //S2DEX  - Chou Snobow Kids, V-Rally Edition 99, Zelda Majoras Mask
217         case 4   : m_ucode4.initializeGBI();     break;  //       - Wave Racer 64
218         case 5   : m_ucode5.initializeGBI();     break;  //F3DEX2 - Donkey Kong 64, Fighter's Destiny 2, Mario Golf 64, F-Zero X, Paper Mario, ...
219         case 6   : m_ucode6.initializeGBI();     break;  //       - Diddy Kong Racing
220         case 7   : m_ucode7.initializeGBI(this); break;  //       - Yoshi's Story
221         case 8   :                                       //       - Puzzle Master 64
222         case 9   : m_ucode9.initializeGBI(this); break;  //       - Perfect Dark
223         case 10  : m_ucode10.initializeGBI();            //       - Conker The Bad Fur Day
224         case 11  : m_ucode6.initializeGBI();     break;  //       - Jet Force Gemini
225         case 12  : m_ucode1.initializeGBI();     break;  //       - 1080
226         default  : 
227             //m_ucode5.initializeGBI(this); break;  //F3DEX2
228             //m_ucode1.initializeGBI(this); 
229             m_ucode0.initializeGBI(this); 
230             break;
231     }
232
233 }
234
235 //-----------------------------------------------------------------------------
236 //! Unknown Instruction
237 //! This function will be called when the GBI can't find the correct function
238 //! to call.
239 //-----------------------------------------------------------------------------
240 void GBI::unknownInstruction(MicrocodeArgument* arg)
241 {
242     static bool warned = false;
243     if ( !warned ) {
244         Logger::getSingleton().printMsg("GBI - Unknown Function", M64MSG_WARNING);
245         warned = true;
246     }
247 }