1 /******************************************************************************
2 * Arachnoid Graphics Plugin for Mupen64Plus
3 * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
5 * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
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.
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.
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 *****************************************************************************/
27 #include "UCodeDefs.h"
30 #include "DisplayListParser.h"
32 //-----------------------------------------------------------------------------
34 //-----------------------------------------------------------------------------
35 RSP* UCode0::m_rsp = 0; //!< Pointer to Reality Signal Processor
36 RDP* UCode0::m_rdp = 0; //!< Pointer to Reality Drawing Processor
37 DisplayListParser* UCode0::m_displayListParser = 0;
38 Memory* UCode0::m_memory = 0;
40 //-----------------------------------------------------------------------------
42 //-----------------------------------------------------------------------------
47 //-----------------------------------------------------------------------------
49 //-----------------------------------------------------------------------------
54 //-----------------------------------------------------------------------------
56 //-----------------------------------------------------------------------------
57 void UCode0::initialize(RSP* rsp, RDP* rdp, Memory* memory, DisplayListParser* dlp)
62 m_displayListParser = dlp;
65 //-----------------------------------------------------------------------------
67 //! Assigns functions to the GBI
68 //-----------------------------------------------------------------------------
69 void UCode0::initializeGBI(GBI* gbi)
71 // Set GeometryMode flags
74 //GBI Command Command Value Target Command Function
75 GBI_SetGBI( GBI::G_SPNOOP, F3D_SPNOOP, gbi->m_cmds, F3D_SPNoOp );
76 GBI_SetGBI( GBI::G_MTX, F3D_MTX, gbi->m_cmds, F3D_Mtx );
77 GBI_SetGBI( GBI::G_RESERVED0, F3D_RESERVED0, gbi->m_cmds, F3D_Reserved0 );
78 GBI_SetGBI( GBI::G_MOVEMEM, F3D_MOVEMEM, gbi->m_cmds, F3D_MoveMem );
79 GBI_SetGBI( GBI::G_VTX, F3D_VTX, gbi->m_cmds, F3D_Vtx );
80 GBI_SetGBI( GBI::G_RESERVED1, F3D_RESERVED1, gbi->m_cmds, F3D_Reserved1 );
81 GBI_SetGBI( GBI::G_DL, F3D_DL, gbi->m_cmds, F3D_DList );
82 GBI_SetGBI( GBI::G_RESERVED2, F3D_RESERVED2, gbi->m_cmds, F3D_Reserved2 );
83 GBI_SetGBI( GBI::G_RESERVED3, F3D_RESERVED3, gbi->m_cmds, F3D_Reserved3 );
84 GBI_SetGBI( GBI::G_SPRITE2D_BASE, F3D_SPRITE2D_BASE, gbi->m_cmds, F3D_Sprite2D_Base );
85 GBI_SetGBI( GBI::G_MOVEWORD, F3D_MOVEWORD, gbi->m_cmds, F3D_MoveWord );
86 GBI_SetGBI( GBI::G_TRI1, F3D_TRI1, gbi->m_cmds, F3D_Tri1 );
87 GBI_SetGBI( GBI::G_CULLDL, F3D_CULLDL, gbi->m_cmds, F3D_CullDL );
88 GBI_SetGBI( GBI::G_POPMTX, F3D_POPMTX, gbi->m_cmds, F3D_PopMtx );
89 GBI_SetGBI( GBI::G_TEXTURE, F3D_TEXTURE, gbi->m_cmds, F3D_Texture );
90 GBI_SetGBI( GBI::G_SETOTHERMODE_H, F3D_SETOTHERMODE_H, gbi->m_cmds, F3D_SetOtherMode_H );
91 GBI_SetGBI( GBI::G_SETOTHERMODE_L, F3D_SETOTHERMODE_L, gbi->m_cmds, F3D_SetOtherMode_L );
92 GBI_SetGBI( GBI::G_ENDDL, F3D_ENDDL, gbi->m_cmds, F3D_EndDL );
93 GBI_SetGBI( GBI::G_SETGEOMETRYMODE, F3D_SETGEOMETRYMODE, gbi->m_cmds, F3D_SetGeometryMode );
94 GBI_SetGBI( GBI::G_CLEARGEOMETRYMODE, F3D_CLEARGEOMETRYMODE,gbi->m_cmds, F3D_ClearGeometryMode );
95 GBI_SetGBI( GBI::G_QUAD, F3D_QUAD, gbi->m_cmds, F3D_Quad );
96 GBI_SetGBI( GBI::G_RDPHALF_1, F3D_RDPHALF_1, gbi->m_cmds, F3D_RDPHalf_1 );
97 GBI_SetGBI( GBI::G_RDPHALF_2, F3D_RDPHALF_2, gbi->m_cmds, F3D_RDPHalf_2 );
98 GBI_SetGBI( GBI::G_RDPHALF_CONT, F3D_RDPHALF_CONT, gbi->m_cmds, F3D_RDPHalf_Cont );
99 GBI_SetGBI( GBI::G_TRI4, F3D_TRI4, gbi->m_cmds, F3D_Tri4 );
102 //*****************************************************************************
104 //*****************************************************************************
106 //-----------------------------------------------------------------------------
108 //! @param ucode instruction from displaylist with input data
109 //-----------------------------------------------------------------------------
110 void UCode0::F3D_Mtx(MicrocodeArgument* ucode)
112 Logger::getSingleton().printMsg("F3D_Mtx", M64MSG_VERBOSE);
113 RSPUCodeAddMatrix0* temp = (RSPUCodeAddMatrix0*)ucode;
116 m_rsp->RSP_Matrix( temp->segmentAddress, //Segment adress
117 temp->projection, //Projection or view matrix?
118 temp->push, //Save Current Matrix?
119 temp->load ); //Replace aka Load or Mult
122 //-----------------------------------------------------------------------------
124 //! @param ucode instruction from displaylist with input data
125 //-----------------------------------------------------------------------------
126 void UCode0::F3D_PopMtx(MicrocodeArgument* ucode)
128 Logger::getSingleton().printMsg("F3D_PopMtx", M64MSG_VERBOSE);
131 m_rsp->RSP_PopMatrix();
134 //*****************************************************************************
136 //*****************************************************************************
138 //-----------------------------------------------------------------------------
140 //! @param ucode instruction from displaylist with input data
141 //-----------------------------------------------------------------------------
142 void UCode0::F3D_Vtx(MicrocodeArgument* ucode)
144 Logger::getSingleton().printMsg("F3D_Vtx", M64MSG_VERBOSE);
145 RSPUCodeAddVertices0* temp = (RSPUCodeAddVertices0*)ucode;
148 m_rsp->RSP_Vertex(temp->segmentAddress, temp->numVertices + 1, temp->firstVertex);
151 //-----------------------------------------------------------------------------
152 //* F3D Render 1 Triangle
153 //! @param ucode instruction from displaylist with input data
154 //! @todo Triangle flag?
155 //-----------------------------------------------------------------------------
156 void UCode0::F3D_Tri1(MicrocodeArgument* ucode)
158 Logger::getSingleton().printMsg("F3D_Tri1", M64MSG_VERBOSE);
159 RSPUCodeAddOneTriangleF3D* temp = (RSPUCodeAddOneTriangleF3D*)ucode;
161 //Add one triangle //TODO Flag?
162 m_rsp->RSP_1Triangle(temp->index0 / 10, temp->index1 / 10, temp->index2 / 10);
165 //-----------------------------------------------------------------------------
166 //* F3D Render 4 Triangles
167 //! @param ucode instruction from displaylist with input data
168 //-----------------------------------------------------------------------------
169 void UCode0::F3D_Tri4(MicrocodeArgument* ucode)
171 Logger::getSingleton().printMsg("F3D_Tri4", M64MSG_VERBOSE);
172 RSPUCodeAddFourTrianglesF3D* temp = (RSPUCodeAddFourTrianglesF3D*)ucode;
175 m_rsp->RSP_4Triangles( temp->v0, temp->v1, temp->v2,
176 temp->v3, temp->v4, temp->v5,
177 temp->v6, temp->v7, temp->v8,
178 temp->v9, temp->v10, temp->v11);
181 //-----------------------------------------------------------------------------
182 //* F3D Render 1 Quad
183 //! @param ucode instruction from displaylist with input data
184 //-----------------------------------------------------------------------------
185 void UCode0::F3D_Quad(MicrocodeArgument* ucode)
187 Logger::getSingleton().printMsg("F3D_Quad", M64MSG_VERBOSE);
188 RSPUCodeAddOneQuadF3D* temp = (RSPUCodeAddOneQuadF3D*)ucode;
191 m_rsp->RSP_1Quadrangle(temp->index0 / 10, temp->index1 / 10, temp->index2 / 10, temp->index3 / 10);
194 //*****************************************************************************
195 // Display List Functions
196 //*****************************************************************************
198 //-----------------------------------------------------------------------------
200 //! @param ucode instruction from displaylist with input data
201 //-----------------------------------------------------------------------------
202 void UCode0::F3D_DList(MicrocodeArgument* ucode)
204 Logger::getSingleton().printMsg("F3D_DList", M64MSG_VERBOSE);
205 RSPUCodeDisplayList* temp = (RSPUCodeDisplayList*)ucode;
207 switch ( temp->param )
209 case G_DL_PUSH : m_rsp->RSP_DisplayList( temp->segmentAddress ); break;
210 case G_DL_NOPUSH : m_rsp->RSP_BranchList( temp->segmentAddress ); break;
214 //-----------------------------------------------------------------------------
216 //! @param ucode instruction from displaylist with input data
217 //-----------------------------------------------------------------------------
218 void UCode0::F3D_EndDL(MicrocodeArgument* ucode)
220 Logger::getSingleton().printMsg("F3D_EndDL", M64MSG_VERBOSE);
223 m_rsp->RSP_EndDisplayList();
226 //-----------------------------------------------------------------------------
228 //! @todo Cull Display List
229 //-----------------------------------------------------------------------------
230 void UCode0::F3D_CullDL(MicrocodeArgument* ucode)
232 Logger::getSingleton().printMsg("F3D_CullDL", M64MSG_VERBOSE);
236 //*****************************************************************************
238 //*****************************************************************************
240 //-----------------------------------------------------------------------------
242 //-----------------------------------------------------------------------------
243 void UCode0::F3D_Texture(MicrocodeArgument* ucode)
245 Logger::getSingleton().printMsg("F3D_Texture", M64MSG_VERBOSE);
246 RSPUCodeTexture* temp = (RSPUCodeTexture*)ucode;
248 float scaleS = _FIXED2FLOAT( _SHIFTR( ucode->w1, 16, 16 ), 16 );
249 float scaleT = _FIXED2FLOAT( _SHIFTR( ucode->w1, 0, 16 ), 16 );
250 int on = _SHIFTR( ucode->w0, 0, 8 );
252 m_rsp->RSP_Texture(scaleS, scaleT, (int)temp->level, (int)temp->tile, on);
255 //*****************************************************************************
257 //*****************************************************************************
259 //-----------------------------------------------------------------------------
261 //! @param ucode instruction from displaylist with input data
262 //-----------------------------------------------------------------------------
263 void UCode0::F3D_RDPHalf_1(MicrocodeArgument* ucode)
265 Logger::getSingleton().printMsg("F3D_RDPHalf_1", M64MSG_VERBOSE);
266 m_rdp->setHalf1( ucode->w1 );
269 //-----------------------------------------------------------------------------
271 //! @param ucode instruction from displaylist with input data
272 //-----------------------------------------------------------------------------
273 void UCode0::F3D_RDPHalf_2(MicrocodeArgument* ucode)
275 Logger::getSingleton().printMsg("F3D_RDPHalf_2", M64MSG_VERBOSE);
276 m_rdp->setHalf2( ucode->w1 );
278 //-----------------------------------------------------------------------------
280 //-----------------------------------------------------------------------------
281 void UCode0::F3D_RDPHalf_Cont(MicrocodeArgument* ucode)
283 Logger::getSingleton().printMsg("F3D_RDPHalf_Cont", M64MSG_VERBOSE);
287 //*****************************************************************************
289 //*****************************************************************************
291 //-----------------------------------------------------------------------------
293 //-----------------------------------------------------------------------------
294 void UCode0::F3D_SetGeometryMode(MicrocodeArgument* ucode)
296 Logger::getSingleton().printMsg("F3D_SetGeometryMode", M64MSG_VERBOSE);
297 m_rsp->RSP_SetGeometryMode(ucode->w1);
300 //-----------------------------------------------------------------------------
301 // Clear Geometry Mode
302 //-----------------------------------------------------------------------------
303 void UCode0::F3D_ClearGeometryMode(MicrocodeArgument* ucode)
305 Logger::getSingleton().printMsg("F3D_ClearGeometryMode", M64MSG_VERBOSE);
306 m_rsp->RSP_ClearGeometryMode(ucode->w1);
309 //*****************************************************************************
311 //*****************************************************************************
313 //-----------------------------------------------------------------------------
315 //-----------------------------------------------------------------------------
316 void UCode0::F3D_SetOtherMode_H(MicrocodeArgument* ucode)
318 Logger::getSingleton().printMsg("F3D_SetOtherMode_H", M64MSG_VERBOSE);
320 unsigned int otherModeType = _SHIFTR(ucode->w0, 8, 8);
321 unsigned int w1 = ucode->w1;
323 switch ( otherModeType )
325 case G_MDSFT_PIPELINE:
326 //gDPPipelineMode( w1 >> G_MDSFT_PIPELINE );
328 case G_MDSFT_CYCLETYPE:
329 m_rdp->setCycleType( G_CYCLE_TYPE(w1 >> G_MDSFT_CYCLETYPE) );
332 case G_MDSFT_TEXTPERSP:
333 //gDPSetTexturePersp( w1 >> G_MDSFT_TEXTPERSP );
335 case G_MDSFT_TEXTDETAIL:
336 //gDPSetTextureDetail( w1 >> G_MDSFT_TEXTDETAIL );
338 case G_MDSFT_TEXTLOD:
339 //gDPSetTextureLOD( w1 >> G_MDSFT_TEXTLOD );
341 case G_MDSFT_TEXTLUT:
342 m_rdp->setTextureLUT( w1 >> G_MDSFT_TEXTLUT );
344 case G_MDSFT_TEXTFILT:
345 m_rdp->setTextureFiltering(w1 >> G_MDSFT_TEXTFILT);
347 case G_MDSFT_TEXTCONV:
348 //gDPSetTextureConvert( w1 >> G_MDSFT_TEXTCONV );
350 case G_MDSFT_COMBKEY:
351 //gDPSetCombineKey( w1 >> G_MDSFT_COMBKEY );
353 case G_MDSFT_RGBDITHER:
354 //gDPSetColorDither( w1 >> G_MDSFT_RGBDITHER );
356 case G_MDSFT_ALPHADITHER:
357 //gDPSetAlphaDither( w1 >> G_MDSFT_ALPHADITHER );
360 unsigned int shift = _SHIFTR( ucode->w0, 8, 8 );
361 unsigned int length = _SHIFTR( ucode->w0, 0, 8 );
362 unsigned int mask = ((1 << length) - 1) << shift;
363 m_rdp->m_otherMode.h &= ~mask;
364 m_rdp->m_otherMode.h |= w1 & mask;
365 m_rdp->setUpdateCombiner(true);
370 //-----------------------------------------------------------------------------
372 //-----------------------------------------------------------------------------
373 void UCode0::F3D_SetOtherMode_L(MicrocodeArgument* ucode)
375 Logger::getSingleton().printMsg("F3D_SetOtherMode_L", M64MSG_VERBOSE);
377 switch (_SHIFTR( ucode->w0, 8, 8 ))
379 case G_MDSFT_ALPHACOMPARE:
380 m_rdp->setAlphaCompareMode(ucode->w1 >> G_MDSFT_ALPHACOMPARE);
382 case G_MDSFT_ZSRCSEL:
383 m_rdp->setDepthSource( ucode->w1 >> G_MDSFT_ZSRCSEL );
385 case G_MDSFT_RENDERMODE:
386 m_rdp->setRenderMode(ucode->w1);
389 unsigned int shift = _SHIFTR( ucode->w0, 8, 8 );
390 unsigned int length = _SHIFTR( ucode->w0, 0, 8 );
391 unsigned int mask = ((1 << length) - 1) << shift;
393 m_rdp->m_otherMode.l &= ~mask;
394 m_rdp->m_otherMode.l |= ucode->w1 & mask;
400 //*****************************************************************************
402 //*****************************************************************************
404 //-----------------------------------------------------------------------------
406 //! @todo Add more case in switch, Like Force Matrix
407 //-----------------------------------------------------------------------------
408 void UCode0::F3D_MoveMem(MicrocodeArgument* ucode)
410 Logger::getSingleton().printMsg("F3D_MoveMem", M64MSG_VERBOSE);
412 unsigned int type = ((ucode->w0)>>16)&0xFF;
413 unsigned int segmentAddress = ucode->w1;
418 case F3D_MV_VIEWPORT:
419 m_rsp->moveMemViewport(segmentAddress);
423 m_rsp->RSP_ForceMatrix(segmentAddress);
424 m_displayListParser->increasePC(24); //// force matrix takes four commands
428 case G_MV_L0: m_rsp->RSP_Light(0, segmentAddress); break;
429 case G_MV_L1: m_rsp->RSP_Light(1, segmentAddress); break;
430 case G_MV_L2: m_rsp->RSP_Light(2, segmentAddress); break;
431 case G_MV_L3: m_rsp->RSP_Light(3, segmentAddress); break;
432 case G_MV_L4: m_rsp->RSP_Light(4, segmentAddress); break;
433 case G_MV_L5: m_rsp->RSP_Light(5, segmentAddress); break;
434 case G_MV_L6: m_rsp->RSP_Light(6, segmentAddress); break;
435 case G_MV_L7: m_rsp->RSP_Light(7, segmentAddress); break;
446 //case RSP_GBI1_MV_MEM_LOOKATY:
449 //case RSP_GBI1_MV_MEM_LOOKATX:
454 //case RSP_GBI1_MV_MEM_TXTATT: break;
455 //case RSP_GBI1_MV_MEM_MATRIX_1:
456 // RSP_GFX_Force_Matrix(addr);
458 //case RSP_GBI1_MV_MEM_MATRIX_2: break;
459 //case RSP_GBI1_MV_MEM_MATRIX_3: break;
460 //case RSP_GBI1_MV_MEM_MATRIX_4: break;
463 Logger::getSingleton().printMsg("F3D_MoveMem: Unknown type", M64MSG_WARNING);
468 //-----------------------------------------------------------------------------
469 //* F3D Sprite2D Base
470 //! @todo F3D Sprite2D Base
471 //-----------------------------------------------------------------------------
472 void UCode0::F3D_Sprite2D_Base(MicrocodeArgument* ucode)
474 Logger::getSingleton().printMsg("F3D_Sprite2D_Base - Unimplemented", M64MSG_WARNING);
478 //-----------------------------------------------------------------------------
480 //-----------------------------------------------------------------------------
481 void UCode0::F3D_MoveWord(MicrocodeArgument* ucode)
483 Logger::getSingleton().printMsg("F3D_MoveWord");
484 RSPUCodeMoveWordF3D* temp = (RSPUCodeMoveWordF3D*)ucode;
486 switch ( temp->type )
489 m_rsp->RSP_InsertMatrix(temp->offset, temp->value);
493 m_rsp->RSP_FogFactor( (short)temp->fm, (short)temp->fo );
497 m_rsp->RSP_NumLights( (unsigned int)(((ucode->w1 - 0x80000000) >> 5) - 1) );
501 m_rsp->moveSegment((temp->offset >> 2) & 0xF, temp->value);
505 if ( (temp->offset & 0x7) == 0 )
507 m_rsp->RSP_LightColor(temp->offset / 0x20, temp->value);
512 m_rsp->RSP_ModifyVertex( _SHIFTR( ucode->w0, 8, 16 ) / 40, _SHIFTR( ucode->w0, 0, 8 ) % 40, ucode->w1);
516 //gSPClipRatio( w1 );
520 //gSPPerspNormalize( w1 );
525 //*****************************************************************************
526 // Non important functions
527 //*****************************************************************************
529 void UCode0::F3D_SPNoOp(MicrocodeArgument* ucode){
530 Logger::getSingleton().printMsg("F3D_SPNoOp", M64MSG_VERBOSE);
532 //If next command is a no-operation then skip displaylist for some ucodes.
533 //if( (ucode+1)->words.cmd == 0x00 && gRSP.ucode >= 17 )
535 // m_rsp->RSP_EndDisplayList();
539 void UCode0::F3D_Reserved0(MicrocodeArgument* ucode) {
540 Logger::getSingleton().printMsg("F3D_Reserved0", M64MSG_VERBOSE);
543 void UCode0::F3D_Reserved1(MicrocodeArgument* ucode){
544 Logger::getSingleton().printMsg("F3D_Reserved1", M64MSG_VERBOSE);
547 void UCode0::F3D_Reserved2(MicrocodeArgument* ucode){
548 Logger::getSingleton().printMsg("F3D_Reserved2", M64MSG_VERBOSE);
551 void UCode0::F3D_Reserved3(MicrocodeArgument* ucode){
552 Logger::getSingleton().printMsg("F3D_Reserved3", M64MSG_VERBOSE);