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 *****************************************************************************/
23 #include "../UCodeDefs.h"
24 #include "../RDP/RDP.h"
30 #include "OpenGLRenderer.h"
31 #include "OpenGLManager.h"
32 #include "RSPLightManager.h"
33 #include "FogManager.h"
34 #include "DisplayListParser.h"
38 #define MI_INTR_SP 0x00000001 //!< RSP Interrupt signal
40 //Geometry Mode Definitions
41 #define G_ZBUFFER 0x00000001
42 #define G_SHADE 0x00000004
43 #define G_FOG 0x00010000
44 #define G_LIGHTING 0x00020000
45 #define G_TEXTURE_GEN 0x00040000
46 #define G_TEXTURE_GEN_LINEAR 0x00080000
47 #define G_LOD 0x00100000
49 //-----------------------------------------------------------------------------
51 //-----------------------------------------------------------------------------
54 m_texturesChanged = false;
60 //-----------------------------------------------------------------------------
62 //-----------------------------------------------------------------------------
68 //-----------------------------------------------------------------------------
70 //-----------------------------------------------------------------------------
71 bool RSP::initialize(GFX_INFO* graphicsInfo, RDP* rdp, Memory* memory, VI* vi, DisplayListParser* dlp, FogManager* fogMgr)
74 m_graphicsInfo = graphicsInfo;
78 m_displayListParser = dlp;
81 //Initialize Matrix Manager
82 m_matrixMgr = new RSPMatrixManager();
83 if ( !m_matrixMgr->initialize(m_memory) ) {
87 //Initialzie Light Manager
88 m_lightMgr = new RSPLightManager();
89 if ( !m_lightMgr->initialize(m_memory) ) {
93 //Initialzie Vertex Manager
94 m_vertexMgr = new RSPVertexManager();
95 if ( !m_vertexMgr->initialize(&OpenGLManager::getSingleton(), m_memory, m_matrixMgr, m_lightMgr) ) {
99 m_textureTiles[0] = m_rdp->getTile(0);
100 m_textureTiles[1] = m_rdp->getTile(1);
105 //-----------------------------------------------------------------------------
107 //-----------------------------------------------------------------------------
110 if ( m_matrixMgr ) { delete m_matrixMgr; m_matrixMgr = 0; }
111 if ( m_vertexMgr ) { delete m_vertexMgr; m_vertexMgr = 0; }
112 if ( m_lightMgr ) { delete m_lightMgr ; m_lightMgr = 0; }
115 //-----------------------------------------------------------------------------
116 //* Update Geometry States
117 //-----------------------------------------------------------------------------
118 void RSP::updateGeometryStates()
120 bool cullFront = (m_geometryMode & GBI::G_CULL_FRONT ) != 0;
121 bool cullBack = (m_geometryMode & GBI::G_CULL_BACK ) != 0;
122 bool fog = (m_geometryMode & G_FOG ) != 0;
123 bool textureGen = (m_geometryMode & G_TEXTURE_GEN ) != 0;
124 bool lighting = (m_geometryMode & G_LIGHTING ) != 0;
125 bool zBuffer = (m_geometryMode & G_ZBUFFER ) != 0;
128 m_lightMgr->setLightEnabled(lighting);
129 m_vertexMgr->setTexCoordGenType( textureGen ? TCGT_LINEAR : TCGT_NONE);
130 OpenGLManager::getSingleton().setZBufferEnabled(zBuffer);
131 OpenGLManager::getSingleton().setCullMode(cullFront, cullBack);
132 OpenGLManager::getSingleton().setFogEnabled(fog);
135 //-----------------------------------------------------------------------------
137 //-----------------------------------------------------------------------------
140 m_matrixMgr->resetMatrices();
143 //-----------------------------------------------------------------------------
145 //-----------------------------------------------------------------------------
146 void RSP::triggerInterrupt()
148 *(m_graphicsInfo->MI_INTR_REG) |= MI_INTR_SP;
149 m_graphicsInfo->CheckInterrupts();
152 //-----------------------------------------------------------------------------
154 //-----------------------------------------------------------------------------
155 void RSP::moveSegment(int segmentID, int value)
157 m_memory->setSegment(segmentID, value);
160 //-----------------------------------------------------------------------------
163 //-----------------------------------------------------------------------------
164 void RSP::moveMemViewport(unsigned int segmentAddress)
167 unsigned int rdramAddress = m_memory->getRDRAMAddress(segmentAddress);
170 if ( rdramAddress + 16 > m_memory->getRDRAMSize() )
172 Logger::getSingleton().printMsg("MoveMem Viewport, accessed invalid memory", M64MSG_ERROR);
176 m_viewport.vscale[0] = _FIXED2FLOAT( *(short*)m_memory->getRDRAM(rdramAddress + 2), 2 );
177 m_viewport.vscale[1] = _FIXED2FLOAT( *(short*)m_memory->getRDRAM(rdramAddress ), 2 );
178 m_viewport.vscale[2] = _FIXED2FLOAT( *(short*)m_memory->getRDRAM(rdramAddress + 6), 10 );// * 0.00097847357f;
179 m_viewport.vscale[3] = *(short*)m_memory->getRDRAM(rdramAddress + 4);
180 m_viewport.vtrans[0] = _FIXED2FLOAT( *(short*)m_memory->getRDRAM(rdramAddress + 10), 2 );
181 m_viewport.vtrans[1] = _FIXED2FLOAT( *(short*)m_memory->getRDRAM(rdramAddress + 8), 2 );
182 m_viewport.vtrans[2] = _FIXED2FLOAT( *(short*)m_memory->getRDRAM(rdramAddress + 14), 10 );// * 0.00097847357f;
183 m_viewport.vtrans[3] = *(short*)m_memory->getRDRAM(rdramAddress + 12);
185 m_viewport.x = m_viewport.vtrans[0] - m_viewport.vscale[0];
186 m_viewport.y = m_viewport.vtrans[1] - m_viewport.vscale[1];
187 m_viewport.width = m_viewport.vscale[0] * 2;
188 m_viewport.height = m_viewport.vscale[1] * 2;
189 m_viewport.nearz = m_viewport.vtrans[2] - m_viewport.vscale[2];
190 m_viewport.farz = (m_viewport.vtrans[2] + m_viewport.vscale[2]) ;
194 OpenGLManager::getSingleton().setViewport(
195 m_viewport.x, // * OGL.scaleX,
196 m_viewport.y, //(VI.height - (gSP.viewport.y + gSP.viewport.height)) * OGL.scaleY + OGL.heightOffset,
197 //(m_vi->getHeight() - (m_viewport.y + m_viewport.height)),
198 m_viewport.width, // * OGL.scaleX,
199 m_viewport.height, // * OGL.scaleY,
200 0.0f, //m_viewport.nearz,
201 1.0f ); //m_viewport.farz );
205 //-----------------------------------------------------------------------------
207 //! @todo Change ucode while running
208 //-----------------------------------------------------------------------------
209 void RSP::RSP_LoadUcodeEx( unsigned int uc_start, unsigned int uc_dstart, unsigned short uc_dsize )
211 Logger::getSingleton().printMsg("RSP_LoadUcodeEx - Unimplemented", M64MSG_WARNING);
217 gSP.matrix.modelViewi = 0;
218 gSP.changed |= CHANGED_MATRIX;
219 gSP.status[0] = gSP.status[1] = gSP.status[2] = gSP.status[3] = 0;
221 if ((((uc_start & 0x1FFFFFFF) + 4096) > RDRAMSize) || (((uc_dstart & 0x1FFFFFFF) + uc_dsize) > RDRAMSize))
226 MicrocodeInfo *ucode = GBI_DetectMicrocode( uc_start, uc_dstart, uc_dsize );
228 if (ucode->type != NONE)
229 GBI_MakeCurrent( ucode );
231 SetEvent( RSP.threadMsg[RSPMSG_CLOSE] );
235 //*****************************************************************************
237 //*****************************************************************************
239 //-----------------------------------------------------------------------------
241 //-----------------------------------------------------------------------------
242 void RSP::RSP_Matrix( unsigned int segmentAddress, bool projectionMatrix, bool push, bool replace )
244 Logger::getSingleton().printMsg("RSP_Matrix");
245 m_matrixMgr->addMatrix( segmentAddress, //Segment adress
246 projectionMatrix, //Projection or view matrix?
247 push, //Save Current Matrix?
248 replace ); //Replace aka Load or Mult
251 //-----------------------------------------------------------------------------
253 //-----------------------------------------------------------------------------
254 void RSP::RSP_DMAMatrix( unsigned int matrix, unsigned char index, unsigned char multiply )
256 m_matrixMgr->DMAMatrix(m_memory->getRDRAMAddress(matrix), index, multiply);
259 //-----------------------------------------------------------------------------
261 //-----------------------------------------------------------------------------
262 void RSP::RSP_ForceMatrix( unsigned int segmentAddress )
264 // Logger::getSingleton().printMsg("RSP_ForceMatrix", M64MSG_WARNING);
265 m_matrixMgr->ForceMatrix( m_memory->getRDRAMAddress(segmentAddress));
268 //-----------------------------------------------------------------------------
270 //-----------------------------------------------------------------------------
271 void RSP::RSP_PopMatrix( )
273 m_matrixMgr->popMatrix();
276 //-----------------------------------------------------------------------------
278 //! Pop Matrix from stack N number of times
279 //! @param num The number of matrices to pop from matrix-stack
280 //-----------------------------------------------------------------------------
281 void RSP::RSP_PopMatrixN( unsigned int num )
283 m_matrixMgr->popMatrixN(num);
286 //-----------------------------------------------------------------------------
288 //-----------------------------------------------------------------------------
289 void RSP::RSP_InsertMatrix(unsigned int where, unsigned int num)
291 m_matrixMgr->insertMatrix(where, num);
294 //*****************************************************************************
296 //*****************************************************************************
298 //-----------------------------------------------------------------------------
300 //-----------------------------------------------------------------------------
301 void RSP::RSP_FogFactor(short fogMultiplier, short fogOffset)
303 m_fogMgr->setFogSettings((float)fogMultiplier, (float)fogOffset);
306 //-----------------------------------------------------------------------------
308 //-----------------------------------------------------------------------------
309 void RSP::RSP_Texture( float scaleS, float scaleT, int level, int tile, int on )
312 m_texture.scaleS = (scaleS != 0.0f) ? scaleS : 1.0f;
313 m_texture.scaleT = (scaleT != 0.0f) ? scaleT : 1.0f;
314 m_texture.level = level;
316 m_texture.tile = tile;
318 //Set Tiles (note: There are max 8 tiles)
321 m_textureTiles[0] = m_rdp->getTile(tile);
322 m_textureTiles[1] = m_rdp->getTile(tile+1);
326 m_textureTiles[0] = m_rdp->getTile(tile);
327 m_textureTiles[1] = m_rdp->getTile(tile);
330 m_texturesChanged = true;
333 //-----------------------------------------------------------------------------
335 //-----------------------------------------------------------------------------
336 void RSP::RSP_SetDMAOffsets( unsigned int mtxoffset, unsigned int vtxoffset )
338 m_matrixMgr->setRDRAMOffset(mtxoffset);
339 m_vertexMgr->setRDRAMOffset(vtxoffset);
342 //*****************************************************************************
344 //*****************************************************************************
346 //-----------------------------------------------------------------------------
348 //-----------------------------------------------------------------------------
349 void RSP::RSP_Light( unsigned int lightIndex, unsigned int segmentAddress )
351 m_lightMgr->setLight(lightIndex, m_memory->getRDRAMAddress(segmentAddress) );
354 //-----------------------------------------------------------------------------
356 //-----------------------------------------------------------------------------
357 void RSP::RSP_NumLights( int numLights )
359 m_lightMgr->setNumLights(numLights);
362 //-----------------------------------------------------------------------------
364 //-----------------------------------------------------------------------------
365 void RSP::RSP_LightColor( unsigned int lightIndex, unsigned int packedColor )
367 m_lightMgr->setLightColor(lightIndex, packedColor);
370 //*****************************************************************************
372 //*****************************************************************************
374 //-----------------------------------------------------------------------------
376 //-----------------------------------------------------------------------------
377 void RSP::RSP_Vertex( unsigned int segmentAddress, unsigned int numVertices, unsigned int firstVertexIndex )
379 m_vertexMgr->setVertices(m_memory->getRDRAMAddress(segmentAddress), numVertices, firstVertexIndex);
382 //-----------------------------------------------------------------------------
384 //-----------------------------------------------------------------------------
385 void RSP::RSP_ModifyVertex( unsigned int vtx, unsigned int where, unsigned int val )
387 m_vertexMgr->modifyVertex(vtx, where, val);
390 void RSP::RSP_SetVertexColor( unsigned int vtx, float r, float g, float b, float a)
392 m_vertexMgr->setVertexColor(vtx, r,g,b,a);
395 void RSP::RSP_SetVertexTexCoord( unsigned int vtx, float s, float t)
397 m_vertexMgr->setVertexTextureCoord(vtx, s,t);
400 //-----------------------------------------------------------------------------
401 //! Color Index Vertex
402 //! param segmentAddress Address to register where there is an RDRAM address
403 //! used to retrieve vertices from RDRAM.
404 //! param numVertices Number of vertices to retrive from RDRAM.
405 //! param firstVertexIndex Index of first vertex
406 //-----------------------------------------------------------------------------
407 void RSP::RSP_CIVertex(unsigned int segmentAddress, unsigned int numVertices, unsigned int firstVertexIndex )
409 m_vertexMgr->ciVertex(segmentAddress, numVertices, firstVertexIndex);
412 //-----------------------------------------------------------------------------
414 //-----------------------------------------------------------------------------
415 void RSP::RSP_DMAVertex( unsigned int v, unsigned int n, unsigned int v0 )
417 m_vertexMgr->DMAVertex(v, n, v0);
420 //-----------------------------------------------------------------------------
421 // Set Vertex Color Base
422 //-----------------------------------------------------------------------------
423 void RSP::RSP_SetVertexColorBase(unsigned int segmentAddress)
425 m_vertexMgr->setVertexColorBase( m_memory->getRDRAMAddress(segmentAddress) );
428 //*****************************************************************************
430 //*****************************************************************************
432 //-----------------------------------------------------------------------------
434 //-----------------------------------------------------------------------------
435 void RSP::RSP_DisplayList(unsigned int segmentAddress)
437 m_displayListParser->displayList(segmentAddress);
440 //-----------------------------------------------------------------------------
442 //-----------------------------------------------------------------------------
443 void RSP::RSP_DMADisplayList( unsigned int w0, unsigned int w1 )
445 m_displayListParser->DMADisplayList(w0, w1);
448 //-----------------------------------------------------------------------------
449 // Branch Display List
450 //-----------------------------------------------------------------------------
451 void RSP::RSP_BranchList( unsigned int dl )
453 m_displayListParser->branchDisplayList(dl);
456 //-----------------------------------------------------------------------------
457 // Branch Display List Z
458 //-----------------------------------------------------------------------------
459 void RSP::RSP_BranchLessZ( unsigned int branchdl, unsigned int vtx, float zval )
461 if ( m_vertexMgr->getVertex(vtx)->z <= zval ) {
462 m_displayListParser->branchDisplayList(branchdl);
466 //-----------------------------------------------------------------------------
468 //-----------------------------------------------------------------------------
469 void RSP::RSP_EndDisplayList()
471 m_displayListParser->endDisplayList();
474 //-----------------------------------------------------------------------------
475 //* Cull Display List
476 //! @todo Cull Display List
477 //-----------------------------------------------------------------------------
478 void RSP::RSP_CullDisplayList( unsigned int v0, unsigned int vn )
480 //Logger::getSingleton().printMsg("RSP_CullDisplayList - Unimplemented", M64MSG_WARNING);
484 //*****************************************************************************
486 //*****************************************************************************
488 //-----------------------------------------------------------------------------
490 //-----------------------------------------------------------------------------
491 void RSP::RSP_1Triangle( int v0, int v1, int v2)
493 m_vertexMgr->add1Triangle(v0, v1, v2);
496 //-----------------------------------------------------------------------------
498 //-----------------------------------------------------------------------------
499 void RSP::RSP_2Triangles( int v00, int v01, int v02, int flag0,
500 int v10, int v11, int v12, int flag1 )
502 m_vertexMgr->add1Triangle(v00, v01, v02);
503 m_vertexMgr->add1Triangle(v10, v11, v12);
506 //-----------------------------------------------------------------------------
508 //-----------------------------------------------------------------------------
509 void RSP::RSP_4Triangles( int v00, int v01, int v02,
510 int v10, int v11, int v12,
511 int v20, int v21, int v22,
512 int v30, int v31, int v32 )
514 m_vertexMgr->add1Triangle(v00, v01, v02);
515 m_vertexMgr->add1Triangle(v10, v11, v12);
516 m_vertexMgr->add1Triangle(v20, v21, v22);
517 m_vertexMgr->add1Triangle(v30, v31, v32);
520 //-----------------------------------------------------------------------------
522 //-----------------------------------------------------------------------------
523 void RSP::RSP_DMATriangles( unsigned int tris, unsigned int n )
525 m_vertexMgr->addDMATriangles(tris, n);
528 //-----------------------------------------------------------------------------
530 //-----------------------------------------------------------------------------
531 void RSP::RSP_1Quadrangle( int v0, int v1, int v2, int v3 )
533 m_vertexMgr->add1Triangle(v0, v1, v2);
534 m_vertexMgr->add1Triangle(v0, v2, v3);
537 //*****************************************************************************
539 //*****************************************************************************
541 //-----------------------------------------------------------------------------
543 //-----------------------------------------------------------------------------
544 void RSP::RSP_GeometryMode(unsigned int clear, unsigned int set)
546 RSP_ClearGeometryMode(clear);
547 RSP_SetGeometryMode(set);
550 //-----------------------------------------------------------------------------
552 //-----------------------------------------------------------------------------
553 void RSP::RSP_SetGeometryMode( unsigned int mode )
555 m_geometryMode |= mode;
556 updateGeometryStates();
559 //-----------------------------------------------------------------------------
560 // Clear Geometry Mode
561 //-----------------------------------------------------------------------------
562 void RSP::RSP_ClearGeometryMode( unsigned int mode )
564 m_geometryMode &= ~mode;
565 updateGeometryStates();
568 //*****************************************************************************
570 //*****************************************************************************
572 void RSP::RSP_Line3D( int v0, int v1, int flag )
574 Logger::getSingleton().printMsg("RSP_Line3D - Unimplemented", M64MSG_WARNING);
576 void RSP::RSP_LineW3D( int v0, int v1, int wd, int flag )
578 Logger::getSingleton().printMsg("RSP_LineW3D - Unimplemented", M64MSG_WARNING);
580 void RSP::RSP_ObjRectangle( unsigned int sp )
582 Logger::getSingleton().printMsg("RSP_ObjRectangle - Unimplemented", M64MSG_WARNING);
584 void RSP::RSP_ObjSprite( unsigned int sp )
586 Logger::getSingleton().printMsg("RSP_ObjSprite - Unimplemented", M64MSG_WARNING);
588 void RSP::RSP_ObjLoadTxtr( unsigned int tx )
590 Logger::getSingleton().printMsg("RSP_ObjLoadTxtr - Unimplemented", M64MSG_WARNING);
592 void RSP::RSP_ObjLoadTxSprite( unsigned int txsp )
594 Logger::getSingleton().printMsg("RSP_ObjLoadTxSprite - Unimplemented", M64MSG_WARNING);
596 void RSP::RSP_ObjLoadTxRectR( unsigned int txsp )
598 Logger::getSingleton().printMsg("RSP_ObjLoadTxRectR - Unimplemented", M64MSG_WARNING);
600 void RSP::RSP_BgRect1Cyc( unsigned int bg )
602 Logger::getSingleton().printMsg("RSP_BgRect1Cyc - Unimplemented", M64MSG_WARNING);
604 void RSP::RSP_BgRectCopy( unsigned int bg )
606 Logger::getSingleton().printMsg("RSP_BgRectCopy - Unimplemented", M64MSG_WARNING);
608 void RSP::RSP_ObjMatrix( unsigned int mtx )
610 Logger::getSingleton().printMsg("RSP_ObjMatrix - Unimplemented", M64MSG_WARNING);
612 void RSP::RSP_ObjSubMatrix( unsigned int mtx )
614 Logger::getSingleton().printMsg("RSP_ObjSubMatrix - Unimplemented", M64MSG_WARNING);
617 //*****************************************************************************
618 // Non important functions
619 //*****************************************************************************
621 void RSP::RSP_Sprite2DBase( unsigned int base ) {
622 Logger::getSingleton().printMsg("RSP_Sprite2DBase - Unimplemented", M64MSG_WARNING);
625 void RSP::RSP_LookAt( unsigned int l ) {
626 Logger::getSingleton().printMsg("RSP_LookAt - Unimplemented", M64MSG_WARNING);
629 void RSP::RSP_ClipRatio( unsigned int r ) {
630 Logger::getSingleton().printMsg("RSP_ClipRatio - Unimplemented", M64MSG_WARNING);
633 void RSP::RSP_PerspNormalize( unsigned short scale ) {
634 Logger::getSingleton().printMsg("RSP_PerspNormalize - Unimplemented", M64MSG_WARNING);