Arachnoid GLESv1.1 plugin. Compile and run (a bit glitchy and no frameskip) on the...
[mupen64plus-pandora.git] / source / mupen64plus-video-arachnoid / src / RSP / RSP.cpp
CommitLineData
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 "RSP.h"
23#include "../UCodeDefs.h"
24#include "../RDP/RDP.h"
25#include <cmath>
26#include "GBIDefs.h"
27#include "VI.h"
28#include "Memory.h"
29#include "Logger.h"
30#include "OpenGLRenderer.h"
31#include "OpenGLManager.h"
32#include "RSPLightManager.h"
33#include "FogManager.h"
34#include "DisplayListParser.h"
35#include "MathLib.h"
36#include "MathLib.h"
37
38#define MI_INTR_SP 0x00000001 //!< RSP Interrupt signal
39
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
48
49//-----------------------------------------------------------------------------
50//! Constructor
51//-----------------------------------------------------------------------------
52RSP::RSP()
53{
54 m_texturesChanged = false;
55 m_matrixMgr = 0;
56 m_vertexMgr = 0;
57 m_lightMgr = 0;
58}
59
60//-----------------------------------------------------------------------------
61//! Destructor
62//-----------------------------------------------------------------------------
63RSP::~RSP()
64{
65 dispose();
66}
67
68//-----------------------------------------------------------------------------
69//* Initialize
70//-----------------------------------------------------------------------------
71bool RSP::initialize(GFX_INFO* graphicsInfo, RDP* rdp, Memory* memory, VI* vi, DisplayListParser* dlp, FogManager* fogMgr)
72{
73 //Save pointers
74 m_graphicsInfo = graphicsInfo;
75 m_rdp = rdp;
76 m_vi = vi;
77 m_memory = memory;
78 m_displayListParser = dlp;
79 m_fogMgr = fogMgr;
80
81 //Initialize Matrix Manager
82 m_matrixMgr = new RSPMatrixManager();
83 if ( !m_matrixMgr->initialize(m_memory) ) {
84 return false;
85 }
86
87 //Initialzie Light Manager
88 m_lightMgr = new RSPLightManager();
89 if ( !m_lightMgr->initialize(m_memory) ) {
90 return false;
91 }
92
93 //Initialzie Vertex Manager
94 m_vertexMgr = new RSPVertexManager();
95 if ( !m_vertexMgr->initialize(&OpenGLManager::getSingleton(), m_memory, m_matrixMgr, m_lightMgr) ) {
96 return false;
97 }
98
99 m_textureTiles[0] = m_rdp->getTile(0);
100 m_textureTiles[1] = m_rdp->getTile(1);
101
102 return true;
103}
104
105//-----------------------------------------------------------------------------
106//* Dispose
107//-----------------------------------------------------------------------------
108void RSP::dispose()
109{
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; }
113}
114
115//-----------------------------------------------------------------------------
116//* Update Geometry States
117//-----------------------------------------------------------------------------
118void RSP::updateGeometryStates()
119{
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;
126
127 //Update states
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);
133}
134
135//-----------------------------------------------------------------------------
136// Reset
137//-----------------------------------------------------------------------------
138void RSP::reset()
139{
140 m_matrixMgr->resetMatrices();
141}
142
143//-----------------------------------------------------------------------------
144//* Trigger Interupt
145//-----------------------------------------------------------------------------
146void RSP::triggerInterrupt()
147{
148 *(m_graphicsInfo->MI_INTR_REG) |= MI_INTR_SP;
149 m_graphicsInfo->CheckInterrupts();
150}
151
152//-----------------------------------------------------------------------------
153//* Move Segment
154//-----------------------------------------------------------------------------
155void RSP::moveSegment(int segmentID, int value)
156{
157 m_memory->setSegment(segmentID, value);
158}
159
160//-----------------------------------------------------------------------------
161// Set Viewport
162// FIXME
163//-----------------------------------------------------------------------------
164void RSP::moveMemViewport(unsigned int segmentAddress)
165{
166 //Get Adress
167 unsigned int rdramAddress = m_memory->getRDRAMAddress(segmentAddress);
168
169 //Error controll
170 if ( rdramAddress + 16 > m_memory->getRDRAMSize() )
171 {
172 Logger::getSingleton().printMsg("MoveMem Viewport, accessed invalid memory", M64MSG_ERROR);
173 return;
174 }
175
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);
184
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]) ;
191
192 /*
193 //Set Viewport
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 );
202 */
203}
204
205//-----------------------------------------------------------------------------
206//* Load UCode Ex
207//! @todo Change ucode while running
208//-----------------------------------------------------------------------------
209void RSP::RSP_LoadUcodeEx( unsigned int uc_start, unsigned int uc_dstart, unsigned short uc_dsize )
210{
211 Logger::getSingleton().printMsg("RSP_LoadUcodeEx - Unimplemented", M64MSG_WARNING);
212 //TODO or skip
213
214 /*
215
216 RSP.PCi = 0;
217 gSP.matrix.modelViewi = 0;
218 gSP.changed |= CHANGED_MATRIX;
219 gSP.status[0] = gSP.status[1] = gSP.status[2] = gSP.status[3] = 0;
220
221 if ((((uc_start & 0x1FFFFFFF) + 4096) > RDRAMSize) || (((uc_dstart & 0x1FFFFFFF) + uc_dsize) > RDRAMSize))
222 {
223 return;
224 }
225
226 MicrocodeInfo *ucode = GBI_DetectMicrocode( uc_start, uc_dstart, uc_dsize );
227
228 if (ucode->type != NONE)
229 GBI_MakeCurrent( ucode );
230 else
231 SetEvent( RSP.threadMsg[RSPMSG_CLOSE] );
232 */
233}
234
235//*****************************************************************************
236// Matrix Functions
237//*****************************************************************************
238
239//-----------------------------------------------------------------------------
240// RSP Matrix
241//-----------------------------------------------------------------------------
242void RSP::RSP_Matrix( unsigned int segmentAddress, bool projectionMatrix, bool push, bool replace )
243{
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
249}
250
251//-----------------------------------------------------------------------------
252// RSP DMA Matrix
253//-----------------------------------------------------------------------------
254void RSP::RSP_DMAMatrix( unsigned int matrix, unsigned char index, unsigned char multiply )
255{
256 m_matrixMgr->DMAMatrix(m_memory->getRDRAMAddress(matrix), index, multiply);
257}
258
259//-----------------------------------------------------------------------------
260// RSP Force Matrix
261//-----------------------------------------------------------------------------
262void RSP::RSP_ForceMatrix( unsigned int segmentAddress )
263{
264 // Logger::getSingleton().printMsg("RSP_ForceMatrix", M64MSG_WARNING);
265 m_matrixMgr->ForceMatrix( m_memory->getRDRAMAddress(segmentAddress));
266}
267
268//-----------------------------------------------------------------------------
269// Pop Matrix
270//-----------------------------------------------------------------------------
271void RSP::RSP_PopMatrix( )
272{
273 m_matrixMgr->popMatrix();
274}
275
276//-----------------------------------------------------------------------------
277//* Pop Matrix N
278//! Pop Matrix from stack N number of times
279//! @param num The number of matrices to pop from matrix-stack
280//-----------------------------------------------------------------------------
281void RSP::RSP_PopMatrixN( unsigned int num )
282{
283 m_matrixMgr->popMatrixN(num);
284}
285
286//-----------------------------------------------------------------------------
287// Insert Matrix
288//-----------------------------------------------------------------------------
289void RSP::RSP_InsertMatrix(unsigned int where, unsigned int num)
290{
291 m_matrixMgr->insertMatrix(where, num);
292}
293
294//*****************************************************************************
295// Misc
296//*****************************************************************************
297
298//-----------------------------------------------------------------------------
299// Fog Factor
300//-----------------------------------------------------------------------------
301void RSP::RSP_FogFactor(short fogMultiplier, short fogOffset)
302{
303 m_fogMgr->setFogSettings((float)fogMultiplier, (float)fogOffset);
304}
305
306//-----------------------------------------------------------------------------
307// Texture
308//-----------------------------------------------------------------------------
309void RSP::RSP_Texture( float scaleS, float scaleT, int level, int tile, int on )
310{
311 //Set Texture
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;
315 m_texture.on = on;
316 m_texture.tile = tile;
317
318 //Set Tiles (note: There are max 8 tiles)
319 if ( tile < 7 )
320 {
321 m_textureTiles[0] = m_rdp->getTile(tile);
322 m_textureTiles[1] = m_rdp->getTile(tile+1);
323 }
324 else
325 {
326 m_textureTiles[0] = m_rdp->getTile(tile);
327 m_textureTiles[1] = m_rdp->getTile(tile);
328 }
329
330 m_texturesChanged = true;
331}
332
333//-----------------------------------------------------------------------------
334// Set DMA Offsets
335//-----------------------------------------------------------------------------
336void RSP::RSP_SetDMAOffsets( unsigned int mtxoffset, unsigned int vtxoffset )
337{
338 m_matrixMgr->setRDRAMOffset(mtxoffset);
339 m_vertexMgr->setRDRAMOffset(vtxoffset);
340}
341
342//*****************************************************************************
343// Light
344//*****************************************************************************
345
346//-----------------------------------------------------------------------------
347// RSP Light
348//-----------------------------------------------------------------------------
349void RSP::RSP_Light( unsigned int lightIndex, unsigned int segmentAddress )
350{
351 m_lightMgr->setLight(lightIndex, m_memory->getRDRAMAddress(segmentAddress) );
352}
353
354//-----------------------------------------------------------------------------
355// Num Lights
356//-----------------------------------------------------------------------------
357void RSP::RSP_NumLights( int numLights )
358{
359 m_lightMgr->setNumLights(numLights);
360}
361
362//-----------------------------------------------------------------------------
363// Light Color
364//-----------------------------------------------------------------------------
365void RSP::RSP_LightColor( unsigned int lightIndex, unsigned int packedColor )
366{
367 m_lightMgr->setLightColor(lightIndex, packedColor);
368}
369
370//*****************************************************************************
371// Vertex
372//*****************************************************************************
373
374//-----------------------------------------------------------------------------
375// Vertex
376//-----------------------------------------------------------------------------
377void RSP::RSP_Vertex( unsigned int segmentAddress, unsigned int numVertices, unsigned int firstVertexIndex )
378{
379 m_vertexMgr->setVertices(m_memory->getRDRAMAddress(segmentAddress), numVertices, firstVertexIndex);
380}
381
382//-----------------------------------------------------------------------------
383// Modify Vertex
384//-----------------------------------------------------------------------------
385void RSP::RSP_ModifyVertex( unsigned int vtx, unsigned int where, unsigned int val )
386{
387 m_vertexMgr->modifyVertex(vtx, where, val);
388}
389
390void RSP::RSP_SetVertexColor( unsigned int vtx, float r, float g, float b, float a)
391{
392 m_vertexMgr->setVertexColor(vtx, r,g,b,a);
393}
394
395void RSP::RSP_SetVertexTexCoord( unsigned int vtx, float s, float t)
396{
397 m_vertexMgr->setVertexTextureCoord(vtx, s,t);
398}
399
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//-----------------------------------------------------------------------------
407void RSP::RSP_CIVertex(unsigned int segmentAddress, unsigned int numVertices, unsigned int firstVertexIndex )
408{
409 m_vertexMgr->ciVertex(segmentAddress, numVertices, firstVertexIndex);
410}
411
412//-----------------------------------------------------------------------------
413// DMA Vertex
414//-----------------------------------------------------------------------------
415void RSP::RSP_DMAVertex( unsigned int v, unsigned int n, unsigned int v0 )
416{
417 m_vertexMgr->DMAVertex(v, n, v0);
418}
419
420//-----------------------------------------------------------------------------
421// Set Vertex Color Base
422//-----------------------------------------------------------------------------
423void RSP::RSP_SetVertexColorBase(unsigned int segmentAddress)
424{
425 m_vertexMgr->setVertexColorBase( m_memory->getRDRAMAddress(segmentAddress) );
426}
427
428//*****************************************************************************
429// Display List
430//*****************************************************************************
431
432//-----------------------------------------------------------------------------
433// Display List
434//-----------------------------------------------------------------------------
435void RSP::RSP_DisplayList(unsigned int segmentAddress)
436{
437 m_displayListParser->displayList(segmentAddress);
438}
439
440//-----------------------------------------------------------------------------
441// DMA Display List
442//-----------------------------------------------------------------------------
443void RSP::RSP_DMADisplayList( unsigned int w0, unsigned int w1 )
444{
445 m_displayListParser->DMADisplayList(w0, w1);
446}
447
448//-----------------------------------------------------------------------------
449// Branch Display List
450//-----------------------------------------------------------------------------
451void RSP::RSP_BranchList( unsigned int dl )
452{
453 m_displayListParser->branchDisplayList(dl);
454}
455
456//-----------------------------------------------------------------------------
457// Branch Display List Z
458//-----------------------------------------------------------------------------
459void RSP::RSP_BranchLessZ( unsigned int branchdl, unsigned int vtx, float zval )
460{
461 if ( m_vertexMgr->getVertex(vtx)->z <= zval ) {
462 m_displayListParser->branchDisplayList(branchdl);
463 }
464}
465
466//-----------------------------------------------------------------------------
467// End Display List
468//-----------------------------------------------------------------------------
469void RSP::RSP_EndDisplayList()
470{
471 m_displayListParser->endDisplayList();
472}
473
474//-----------------------------------------------------------------------------
475//* Cull Display List
476//! @todo Cull Display List
477//-----------------------------------------------------------------------------
478void RSP::RSP_CullDisplayList( unsigned int v0, unsigned int vn )
479{
480 //Logger::getSingleton().printMsg("RSP_CullDisplayList - Unimplemented", M64MSG_WARNING);
481 //TODO
482}
483
484//*****************************************************************************
485// Indices
486//*****************************************************************************
487
488//-----------------------------------------------------------------------------
489// 1 Triangle
490//-----------------------------------------------------------------------------
491void RSP::RSP_1Triangle( int v0, int v1, int v2)
492{
493 m_vertexMgr->add1Triangle(v0, v1, v2);
494}
495
496//-----------------------------------------------------------------------------
497// 2 Trangles
498//-----------------------------------------------------------------------------
499void RSP::RSP_2Triangles( int v00, int v01, int v02, int flag0,
500 int v10, int v11, int v12, int flag1 )
501{
502 m_vertexMgr->add1Triangle(v00, v01, v02);
503 m_vertexMgr->add1Triangle(v10, v11, v12);
504}
505
506//-----------------------------------------------------------------------------
507// 4 Triangles
508//-----------------------------------------------------------------------------
509void 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 )
513{
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);
518}
519
520//-----------------------------------------------------------------------------
521// DMA Triangel
522//-----------------------------------------------------------------------------
523void RSP::RSP_DMATriangles( unsigned int tris, unsigned int n )
524{
525 m_vertexMgr->addDMATriangles(tris, n);
526}
527
528//-----------------------------------------------------------------------------
529// Quadrangle
530//-----------------------------------------------------------------------------
531void RSP::RSP_1Quadrangle( int v0, int v1, int v2, int v3 )
532{
533 m_vertexMgr->add1Triangle(v0, v1, v2);
534 m_vertexMgr->add1Triangle(v0, v2, v3);
535}
536
537//*****************************************************************************
538// Geometry Mode
539//*****************************************************************************
540
541//-----------------------------------------------------------------------------
542// Geometry Mode
543//-----------------------------------------------------------------------------
544void RSP::RSP_GeometryMode(unsigned int clear, unsigned int set)
545{
546 RSP_ClearGeometryMode(clear);
547 RSP_SetGeometryMode(set);
548}
549
550//-----------------------------------------------------------------------------
551// Set Geometry Mode
552//-----------------------------------------------------------------------------
553void RSP::RSP_SetGeometryMode( unsigned int mode )
554{
555 m_geometryMode |= mode;
556 updateGeometryStates();
557}
558
559//-----------------------------------------------------------------------------
560// Clear Geometry Mode
561//-----------------------------------------------------------------------------
562void RSP::RSP_ClearGeometryMode( unsigned int mode )
563{
564 m_geometryMode &= ~mode;
565 updateGeometryStates();
566}
567
568//*****************************************************************************
569// Other
570//*****************************************************************************
571
572void RSP::RSP_Line3D( int v0, int v1, int flag )
573{
574 Logger::getSingleton().printMsg("RSP_Line3D - Unimplemented", M64MSG_WARNING);
575}
576void RSP::RSP_LineW3D( int v0, int v1, int wd, int flag )
577{
578 Logger::getSingleton().printMsg("RSP_LineW3D - Unimplemented", M64MSG_WARNING);
579}
580void RSP::RSP_ObjRectangle( unsigned int sp )
581{
582 Logger::getSingleton().printMsg("RSP_ObjRectangle - Unimplemented", M64MSG_WARNING);
583}
584void RSP::RSP_ObjSprite( unsigned int sp )
585{
586 Logger::getSingleton().printMsg("RSP_ObjSprite - Unimplemented", M64MSG_WARNING);
587}
588void RSP::RSP_ObjLoadTxtr( unsigned int tx )
589{
590 Logger::getSingleton().printMsg("RSP_ObjLoadTxtr - Unimplemented", M64MSG_WARNING);
591}
592void RSP::RSP_ObjLoadTxSprite( unsigned int txsp )
593{
594 Logger::getSingleton().printMsg("RSP_ObjLoadTxSprite - Unimplemented", M64MSG_WARNING);
595}
596void RSP::RSP_ObjLoadTxRectR( unsigned int txsp )
597{
598 Logger::getSingleton().printMsg("RSP_ObjLoadTxRectR - Unimplemented", M64MSG_WARNING);
599}
600void RSP::RSP_BgRect1Cyc( unsigned int bg )
601{
602 Logger::getSingleton().printMsg("RSP_BgRect1Cyc - Unimplemented", M64MSG_WARNING);
603}
604void RSP::RSP_BgRectCopy( unsigned int bg )
605{
606 Logger::getSingleton().printMsg("RSP_BgRectCopy - Unimplemented", M64MSG_WARNING);
607}
608void RSP::RSP_ObjMatrix( unsigned int mtx )
609{
610 Logger::getSingleton().printMsg("RSP_ObjMatrix - Unimplemented", M64MSG_WARNING);
611}
612void RSP::RSP_ObjSubMatrix( unsigned int mtx )
613{
614 Logger::getSingleton().printMsg("RSP_ObjSubMatrix - Unimplemented", M64MSG_WARNING);
615}
616
617//*****************************************************************************
618// Non important functions
619//*****************************************************************************
620
621void RSP::RSP_Sprite2DBase( unsigned int base ) {
622 Logger::getSingleton().printMsg("RSP_Sprite2DBase - Unimplemented", M64MSG_WARNING);
623}
624
625void RSP::RSP_LookAt( unsigned int l ) {
626 Logger::getSingleton().printMsg("RSP_LookAt - Unimplemented", M64MSG_WARNING);
627}
628
629void RSP::RSP_ClipRatio( unsigned int r ) {
630 Logger::getSingleton().printMsg("RSP_ClipRatio - Unimplemented", M64MSG_WARNING);
631}
632
633void RSP::RSP_PerspNormalize( unsigned short scale ) {
634 Logger::getSingleton().printMsg("RSP_PerspNormalize - Unimplemented", M64MSG_WARNING);
635}