fc4766a5d3c60c94f0a60ae13bf59c76f46e2874
[mupen64plus-pandora.git] / source / mupen64plus-video-arachnoid / src / RDP / RDPInstructions.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 "RDPInstructions.h"
23 #include "RDPUCodeStructs.h"
24 #include "RDP.h"
25 #include "DisplayListParser.h"
26 #include "Logger.h"
27
28 //-----------------------------------------------------------------------------
29 // Static Variables
30 //-----------------------------------------------------------------------------
31
32 RDP*               RDPInstructions::m_rdp               = 0;
33 DisplayListParser* RDPInstructions::m_displayListParser = 0;
34
35 //-----------------------------------------------------------------------------
36 //! Constructor
37 //-----------------------------------------------------------------------------
38 RDPInstructions::RDPInstructions()
39 {
40 }
41
42 //-----------------------------------------------------------------------------
43 //! Destructor
44 //-----------------------------------------------------------------------------
45 RDPInstructions::~RDPInstructions()
46 {
47 }
48
49 //-----------------------------------------------------------------------------
50 //* Initialize
51 //-----------------------------------------------------------------------------
52 bool RDPInstructions::initialize(RDP* rdp, DisplayListParser* displayListParser)
53 {
54     m_rdp = rdp;
55     m_displayListParser = displayListParser;
56     return true;
57 }
58
59 //-----------------------------------------------------------------------------
60 //! Set Color Image
61 //! @param ucode instruction from displaylist with input data
62 //-----------------------------------------------------------------------------
63 void RDPInstructions::RDP_SetCImg(MicrocodeArgument* ucode)
64
65     Logger::getSingleton().printMsg("RDP_SetCImg");
66     RDPUCodeSetImage* temp = (RDPUCodeSetImage*)ucode;
67
68     //Set Color Image
69     m_rdp->RDP_SetCImg(temp->format, temp->size, temp->width, temp->segmentAddress);
70 }
71
72 //-----------------------------------------------------------------------------
73 //! Set Z Image
74 //! @param ucode instruction from displaylist with input data
75 //-----------------------------------------------------------------------------
76 void RDPInstructions::RDP_SetZImg(MicrocodeArgument* ucode)
77
78     Logger::getSingleton().printMsg("RDP_SetZImg");
79     RDPUCodeSetImage* temp = (RDPUCodeSetImage*)ucode;
80
81     //Set Depth Image
82     m_rdp->RDP_SetZImg(temp->format, temp->size, temp->width, temp->segmentAddress);
83 }
84
85 //-----------------------------------------------------------------------------
86 //! Set Texture Image
87 //! @param ucode instruction from displaylist with input data
88 //-----------------------------------------------------------------------------
89 void RDPInstructions::RDP_SetTImg(MicrocodeArgument* ucode)
90
91     Logger::getSingleton().printMsg("RDP_SetTImg");
92     RDPUCodeSetImage* temp = (RDPUCodeSetImage*)ucode;
93
94     //Set Texture Image
95     m_rdp->RDP_SetTImg(temp->format, temp->size, temp->width, temp->segmentAddress);
96 }
97
98 //-----------------------------------------------------------------------------
99 //! Set Tile
100 //! @param ucode instruction from displaylist with input data
101 //-----------------------------------------------------------------------------
102 void RDPInstructions::RDP_SetTile(MicrocodeArgument* ucode)
103
104     Logger::getSingleton().printMsg("RDP_SetTile");
105     RDPUCodeSetTile* temp = (RDPUCodeSetTile*)ucode;
106
107     //Set Tile
108     m_rdp->RDP_SetTile( temp->format, temp->size, temp->line, temp->tmem, temp->tile, 
109         temp->palette, temp->clampS, temp->clampT, temp->mirrorS, temp->mirrorT, 
110         temp->maskS, temp->maskT, temp->shiftS, temp->shiftT
111     );
112 }
113
114 //-----------------------------------------------------------------------------
115 //! Load Tile
116 //! @param ucode instruction from displaylist with input data
117 //-----------------------------------------------------------------------------
118 void RDPInstructions::RDP_LoadTile(MicrocodeArgument* ucode)
119
120     Logger::getSingleton().printMsg("RDP_LoadTile");
121     RDPUCodeTileSize* temp = (RDPUCodeTileSize*)ucode;
122
123     //Load Tile
124     m_rdp->RDP_LoadTile(temp->tile, temp->s0, temp->t0, temp->s1, temp->t1);
125 }
126
127 //-----------------------------------------------------------------------------
128 //! Load Block
129 //! @param ucode instruction from displaylist with input data
130 //-----------------------------------------------------------------------------
131 void RDPInstructions::RDP_LoadBlock(MicrocodeArgument* ucode)
132 {  
133     Logger::getSingleton().printMsg("RDP_LoadBlock");
134     RDPUCodeTileSize* temp = (RDPUCodeTileSize*)ucode;
135
136     //Load Block
137     m_rdp->RDP_LoadBlock(temp->tile, temp->s0, temp->t0, temp->s1, temp->t1);
138 }
139
140 //-----------------------------------------------------------------------------
141 //! Sets the size of tile
142 //! @param ucode instruction from displaylist with input data
143 //-----------------------------------------------------------------------------
144 void RDPInstructions::RDP_SetTileSize(MicrocodeArgument* ucode)
145 {  
146     Logger::getSingleton().printMsg("RDP_SetTileSize");
147     RDPUCodeTileSize* temp = (RDPUCodeTileSize*)ucode;
148
149     //Set Tile Size
150     m_rdp->RDP_SetTileSize(temp->tile, temp->s0, temp->t0, temp->s1, temp->t1);
151 }
152
153 //-----------------------------------------------------------------------------
154 //! Set Texture Look Up Table
155 //! @param ucode instruction from displaylist with input data
156 //-----------------------------------------------------------------------------
157 void RDPInstructions::RDP_LoadTLUT(MicrocodeArgument* ucode)
158 {   
159     Logger::getSingleton().printMsg("RDP_LoadTLUT");
160     RDPUCodeTileSize* temp = (RDPUCodeTileSize*)ucode;
161
162     //Load Texture Look Up Table
163     m_rdp->RDP_LoadTLUT(temp->tile, temp->s0, temp->t0, temp->s1, temp->t1);
164 }
165
166 //-----------------------------------------------------------------------------
167 //* Fill Rect
168 //! Renders a rectangle
169 //! @param ucode instruction from displaylist with input data
170 //-----------------------------------------------------------------------------
171 void RDPInstructions::RDP_FillRect(MicrocodeArgument* ucode)
172
173     Logger::getSingleton().printMsg("RDP_FillRect");
174     RDPUCodeRectangle* temp = (RDPUCodeRectangle*)ucode;
175
176     //Render a Rectangle
177     m_rdp->RDP_FillRect(temp->x0, temp->y0, temp->x1, temp->y1);
178 }
179
180 //-----------------------------------------------------------------------------
181 //* Texture Rectangle Flipped
182 //! Renders a textured rectangle
183 //! @todo Better extraction of data
184 //! @param ucode instruction from displaylist with input data
185 //-----------------------------------------------------------------------------
186 void RDPInstructions::RDP_TexRectFlip(MicrocodeArgument* ucode)
187 {   
188     Logger::getSingleton().printMsg("RDP_TexRectFlip");
189     RDPUCodeTextureRectangle* temp = (RDPUCodeTextureRectangle*)ucode;
190
191     //Get Extra Words
192     unsigned int w2 = m_displayListParser->getNextWord();
193     unsigned int w3 = m_displayListParser->getNextWord();
194
195     //Extract Data
196     unsigned int dwS        = (  w2>>16)&0xFFFF;
197     unsigned int dwT        = (  w2    )&0xFFFF;
198     int nDSDX                   = (int)(short)((  w3>>16)&0xFFFF);
199     int nDTDY                  = (int)(short)((  w3    )&0xFFFF);
200
201     //Render Texture Rectangle Flipped
202     m_rdp->RDP_TexRectFlip(temp->x1 / 4, temp->y1 / 4, 
203                            temp->x0 / 4, temp->y0 / 4,
204                            temp->tile,                            
205                            dwS, dwT, 
206                            nDSDX, nDTDY);
207 }
208
209 //-----------------------------------------------------------------------------
210 //* Texture Rect
211 //! Not this command use 128bits and not 64 bits wich could cause some
212 //! problems with the program counter.
213 //! @todo Better extraction of data
214 //! @param ucode instruction from displaylist with input data
215 //-----------------------------------------------------------------------------
216 void RDPInstructions::RDP_TexRect(MicrocodeArgument* ucode)
217
218     Logger::getSingleton().printMsg("RDP_TexRect");    
219     RDPUCodeTextureRectangle* temp = (RDPUCodeTextureRectangle*)ucode;
220
221     unsigned int w2 = m_displayListParser->getNextWord();
222     unsigned int w3 = m_displayListParser->getNextWord();
223
224     //Extract Data
225     unsigned short uS     = (unsigned short)(  w2>>16)&0xFFFF;
226     unsigned short uT     = (unsigned short)(  w2    )&0xFFFF;
227     unsigned short uDSDX = (unsigned short)((  w3>>16)&0xFFFF);
228     unsigned short uDTDY = (unsigned short)((  w3    )&0xFFFF);
229
230     //Render Texture Rectangle
231     m_rdp->RDP_TexRect( temp->x0 / 4, temp->y0 / 4, 
232                         temp->x1 / 4, temp->y1 / 4, 
233                         temp->tile, 
234                         uS, uT, 
235                         uDSDX, uDTDY);
236 }
237
238 //-----------------------------------------------------------------------------
239 //! Set Enviroment Color
240 //! @param ucode instruction from displaylist with input data
241 //-----------------------------------------------------------------------------
242 void RDPInstructions::RDP_SetEnvColor(MicrocodeArgument* ucode)
243
244     Logger::getSingleton().printMsg("RDP_SetEnvColor");
245     RDPUCodeSetColor* temp = (RDPUCodeSetColor*)ucode;
246
247     //Set enviorment color
248     m_rdp->RDP_SetEnvColor(temp->r / 255.0f, temp->g / 255.0f, temp->b / 255.0f, temp->a / 255.0f);
249 }
250
251 //-----------------------------------------------------------------------------
252 //! Set Blend Color
253 //! @param ucode instruction from displaylist with input data
254 //-----------------------------------------------------------------------------
255 void RDPInstructions::RDP_SetBlendColor(MicrocodeArgument* ucode)
256
257     Logger::getSingleton().printMsg("RDP_SetBlendColor");
258     RDPUCodeSetColor* temp = (RDPUCodeSetColor*)ucode;
259
260     //Set blend color
261     m_rdp->RDP_SetBlendColor(temp->r / 255.0f, temp->g / 255.0f, temp->b / 255.0f, temp->a / 255.0f);
262 }
263
264 //-----------------------------------------------------------------------------
265 //! Set Prim Color
266 //! @param ucode instruction from displaylist with input data
267 //-----------------------------------------------------------------------------
268 void RDPInstructions::RDP_SetPrimColor(MicrocodeArgument* ucode)
269
270     Logger::getSingleton().printMsg("RDP_SetPrimColor");
271     RDPUCodeSetColor* temp = (RDPUCodeSetColor*)ucode;
272
273     //Set primitive color
274     m_rdp->RDP_SetPrimColor( temp->r / 255.0f,    //red
275                              temp->g / 255.0f,    //green 
276                              temp->b / 255.0f,    //blue
277                              temp->a / 255.0f,    //alpha
278                              temp->prim_min_level, 
279                              temp->prim_level );
280 }
281
282 //-----------------------------------------------------------------------------
283 //! Set Fog Color
284 //! @param ucode instruction from displaylist with input data
285 //-----------------------------------------------------------------------------
286 void RDPInstructions::RDP_SetFogColor(MicrocodeArgument* ucode)
287
288     Logger::getSingleton().printMsg("RDPInstructions_SetFogColor");
289     RDPUCodeSetColor* temp = (RDPUCodeSetColor*)ucode;
290
291     //Set fog color
292     m_rdp->RDP_SetFogColor(temp->r / 255.0f, temp->g / 255.0f, temp->b / 255.0f, temp->a / 255.0f);
293 }
294
295 //-----------------------------------------------------------------------------
296 //! Set Fill Color
297 //! Note: Fill color is stored diffrently from the other types of colors
298 //! @param ucode instruction from displaylist with input data
299 //-----------------------------------------------------------------------------
300 void RDPInstructions::RDP_SetFillColor(MicrocodeArgument* ucode)
301
302     Logger::getSingleton().printMsg("RDP_SetFillColor");
303     RDPUCodeSetFillColor* temp = (RDPUCodeSetFillColor*)ucode;
304
305     //Set fill color (Note: alpha is 0.0 or 1.0) FIXME: 32 or 31? 31 seems to work better with Super Mario 64
306     m_rdp->RDP_SetFillColor(temp->r / 31.0f, temp->g / 31.0f, temp->b / 31.0f, (float)temp->a);  
307 }
308
309 //-----------------------------------------------------------------------------
310 //! Set Combine
311 //! @todo Extract data
312 //! @param ucode instruction from displaylist with input data
313 //-----------------------------------------------------------------------------
314 void RDPInstructions::RDP_SetCombine(MicrocodeArgument* ucode)
315
316     Logger::getSingleton().printMsg("RDP_SetCombine");
317     m_rdp->RDP_SetCombine(ucode);
318 }
319
320 //-----------------------------------------------------------------------------
321 //! Set Other Mode
322 //! @todo Extract data
323 //! @param ucode instruction from displaylist with input data
324 //-----------------------------------------------------------------------------
325 void RDPInstructions::RDP_SetOtherMode(MicrocodeArgument* ucode)
326 {  
327     Logger::getSingleton().printMsg("RDP_SetOtherMode");
328     m_rdp->RDP_SetOtherMode(ucode);
329 }
330
331 //-----------------------------------------------------------------------------
332 //! Set Prim Depth
333 //! @param ucode instruction from displaylist with input data
334 //-----------------------------------------------------------------------------
335 void RDPInstructions::RDP_SetPrimDepth(MicrocodeArgument* ucode)
336 {  
337     Logger::getSingleton().printMsg("RDP_SetPrimDepth");
338     RDPUCodeSetPrimDepth* temp = (RDPUCodeSetPrimDepth*)ucode;
339
340     //Set Prim Depth
341     m_rdp->RDP_SetPrimDepth(temp->z, temp->dz);
342 }
343
344 //-----------------------------------------------------------------------------
345 //! Set Scissor
346 //! @param ucode instruction from displaylist with input data
347 //-----------------------------------------------------------------------------
348 void RDPInstructions::RDP_SetScissor(MicrocodeArgument* ucode)
349 {  
350     Logger::getSingleton().printMsg("RDP_SetScissor");
351     RDPUCodeScissor* temp = (RDPUCodeScissor*)ucode;
352
353     //Set Scissor
354     m_rdp->RDP_SetScissor(temp->x0 / 4, temp->y0 / 4, temp->x1 / 4, temp->y1 / 4, temp->mode);
355 }
356
357 //-----------------------------------------------------------------------------
358 //* Full Sync
359 //! Function that signals end of a frame.
360 //-----------------------------------------------------------------------------
361 void RDPInstructions::RDP_FullSync(MicrocodeArgument* ucode)
362
363     Logger::getSingleton().printMsg("RDP_FullSync");
364     m_rdp->RDP_FullSync();
365 }
366
367 //-----------------------------------------------------------------------------
368 //* Tile Sync
369 //! Ignored (Function that signals synchronize of texture tile change)
370 //-----------------------------------------------------------------------------
371 void RDPInstructions::RDP_TileSync(MicrocodeArgument* ucode)
372 {   
373     //Ignore
374
375     static bool warned = false;
376     if ( warned ) {
377         Logger::getSingleton().printMsg("RDP_TileSync - Ignored", M64MSG_WARNING);
378         warned = true;
379     }
380 }
381
382 //-----------------------------------------------------------------------------
383 //* Pipe Sync 
384 //! Ignored (Function that signals synchronize of RDP attribute change)
385 //-----------------------------------------------------------------------------
386 void RDPInstructions::RDP_PipeSync(MicrocodeArgument* ucode)
387 {   
388     //Ignore
389
390     static bool warned = false;
391     if ( warned ) {
392         Logger::getSingleton().printMsg("RDP_PipeSync - Ignored", M64MSG_WARNING);
393         warned = true;
394     }    
395 }
396
397 //-----------------------------------------------------------------------------
398 //* Load Sync
399 //! Ignored (Function that signals synchronize of textureloading Ignored)
400 //-----------------------------------------------------------------------------
401 void RDPInstructions::RDP_LoadSync(MicrocodeArgument* ucode)
402 {   
403     //Ignored
404
405     static bool warned = false;
406     if ( warned ) {
407         Logger::getSingleton().printMsg("RDP_LoadSync - Ignored", M64MSG_WARNING);
408         warned = true;
409     }   
410 }
411
412 //-----------------------------------------------------------------------------
413 //* Set Convert
414 //! Unimplemented
415 //-----------------------------------------------------------------------------
416 void RDPInstructions::RDP_SetConvert(MicrocodeArgument* ucode)
417 {   
418     static bool warned = false;
419     if ( warned ) {
420         Logger::getSingleton().printMsg("RDP_SetConvert - Unimplemented", M64MSG_WARNING);
421         warned = true;
422     }
423 }
424
425 //-----------------------------------------------------------------------------
426 //* Set Key Red
427 //! Unimplemented
428 //-----------------------------------------------------------------------------
429 void RDPInstructions::RDP_SetKeyR(MicrocodeArgument* ucode)
430 {   
431     Logger::getSingleton().printMsg("RDP_SetKeyR");
432
433     static bool warned = false;
434     if ( warned ) {
435         Logger::getSingleton().printMsg("RDP_SetKeyR - Unimplemented", M64MSG_WARNING);
436         warned = true;
437     }
438 }
439
440 //-----------------------------------------------------------------------------
441 //* Set Key Green Blue
442 //! Unimplemented
443 //-----------------------------------------------------------------------------
444 void RDPInstructions::RDP_SetKeyGB(MicrocodeArgument* ucode)
445 {
446     static bool warned = false;
447     if ( warned ) {
448         Logger::getSingleton().printMsg("RDP_SetKeyGB - Unimplemented", M64MSG_WARNING);
449         warned = true;
450     }
451 }
452
453 //-----------------------------------------------------------------------------
454 //* Unknown
455 //! This function gets called when the GBI recives an unknown instruction.
456 //-----------------------------------------------------------------------------
457 void RDPInstructions::RDP_Unknown(MicrocodeArgument* ucode)
458
459     //Ignore
460
461     static bool warned = false;
462     if ( warned ) {
463         Logger::getSingleton().printMsg("RDP_Unknown - Ignored", M64MSG_WARNING);
464         warned = true;
465     }
466 }
467
468 //-----------------------------------------------------------------------------
469 //* No Operation
470 //! Do nothing
471 //-----------------------------------------------------------------------------
472 void RDPInstructions::RDP_NoOp(MicrocodeArgument* ucode)
473
474     //Ignore
475
476     static bool warned = false;
477     if ( warned ) {
478         Logger::getSingleton().printMsg("RDP_NoOp - Ignored", M64MSG_WARNING);
479         warned = true;
480     }
481 }