22726e4d |
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 | } |