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 "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 | } |