Rice GLES2 (from mupen64plus-ae) plugin. Compile but doesn't works well on the OpenPa...
[mupen64plus-pandora.git] / source / gles2rice / src / RSP_GBI_Others.h
CommitLineData
292f9317 1/*
2Copyright (C) 2002 Rice1964
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18*/
19
20// A few ucode used in DKR and Others Special games
21
22#include <algorithm>
23
24#include "Render.h"
25#include "Timing.h"
26#include "osal_preproc.h"
27
28uint32 dwConkerVtxZAddr=0;
29
30static void RDP_GFX_DumpVtxInfoDKR(uint32 dwAddr, uint32 dwV0, uint32 dwN);
31
32void RDP_GFX_DLInMem(Gfx *gfx)
33{
34 uint32 dwLimit = ((gfx->words.w0) >> 16) & 0xFF;
35 uint32 dwPush = RSP_DLIST_PUSH; //((gfx->words.w0) >> 16) & 0xFF;
36 uint32 dwAddr = 0x00000000 | (gfx->words.w1); //RSPSegmentAddr((gfx->words.w1));
37
38 LOG_UCODE(" Address=0x%08x Push: 0x%02x", dwAddr, dwPush);
39
40 switch (dwPush)
41 {
42 case RSP_DLIST_PUSH:
43 LOG_UCODE(" Pushing DisplayList 0x%08x", dwAddr);
44 gDlistStackPointer++;
45 gDlistStack[gDlistStackPointer].pc = dwAddr;
46 gDlistStack[gDlistStackPointer].countdown = dwLimit;
47
48 break;
49 case RSP_DLIST_NOPUSH:
50 LOG_UCODE(" Jumping to DisplayList 0x%08x", dwAddr);
51 gDlistStack[gDlistStackPointer].pc = dwAddr;
52 gDlistStack[gDlistStackPointer].countdown = dwLimit;
53 break;
54 }
55
56 LOG_UCODE("");
57 LOG_UCODE("\\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/ \\/");
58 LOG_UCODE("#############################################");
59}
60
61extern Matrix ALIGN(16, dkrMatrixTransposed)
62void RSP_Mtx_DKR(Gfx *gfx)
63{
64 uint32 dwAddr = RSPSegmentAddr((gfx->words.w1));
65 uint32 dwCommand = ((gfx->words.w0)>>16)&0xFF;
66 //uint32 dwLength = ((gfx->words.w0)) &0xFFFF;
67
68 dwAddr = (gfx->words.w1)+RSPSegmentAddr(gRSP.dwDKRMatrixAddr);
69
70 //gRSP.DKRCMatrixIndex = ((gfx->words.w0)>>22)&3;
71 bool mul=false;
72 int index = 0;
73 switch( dwCommand )
74 {
75 case 0xC0: // DKR
76 gRSP.DKRCMatrixIndex = index = 3;
77 break;
78 case 0x80: // DKR
79 gRSP.DKRCMatrixIndex = index = 2;
80 break;
81 case 0x40: // DKR
82 gRSP.DKRCMatrixIndex = index = 1;
83 break;
84 case 0x20: // DKR
85 gRSP.DKRCMatrixIndex = index = 0;
86 break;
87 case 0x00:
88 gRSP.DKRCMatrixIndex = index = 0;
89 break;
90 case 0x01:
91 //mul = true;
92 gRSP.DKRCMatrixIndex = index = 1;
93 break;
94 case 0x02:
95 //mul = true;
96 gRSP.DKRCMatrixIndex = index = 2;
97 break;
98 case 0x03:
99 //mul = true;
100 gRSP.DKRCMatrixIndex = index = 3;
101 break;
102 case 0x81:
103 index = 1;
104 mul = true;
105 break;
106 case 0x82:
107 index = 2;
108 mul = true;
109 break;
110 case 0x83:
111 index = 3;
112 mul = true;
113 break;
114 default:
115 DebuggerAppendMsg("Fix me, mtx DKR, cmd=%08X", dwCommand);
116 break;
117 }
118
119 // Load matrix from dwAddr
120 Matrix &mat = gRSP.DKRMatrixes[index];
121 LoadMatrix(dwAddr);
122
123 if( mul )
124 {
125 mat = matToLoad*gRSP.DKRMatrixes[0];
126 }
127 else
128 {
129 mat = matToLoad;
130 }
131
132 if( status.isSSEEnabled )
133 MatrixTranspose(&dkrMatrixTransposed, &mat);
134
135 DEBUGGER_IF_DUMP(logMatrix,TRACE3("DKR Matrix: cmd=0x%X, idx = %d, mul=%d", dwCommand, index, mul));
136 LOG_UCODE(" DKR Loading Mtx: %d, command=%d", index, dwCommand);
137 DEBUGGER_PAUSE_AND_DUMP(NEXT_MATRIX_CMD,{TRACE0("Paused at DKR Matrix Cmd");});
138}
139
140void RSP_Vtx_DKR(Gfx *gfx)
141{
142 uint32 dwAddr = RSPSegmentAddr((gfx->words.w1));
143 uint32 dwV0 = (((gfx->words.w0) >> 9 )&0x1F);
144 uint32 dwN = (((gfx->words.w0) >>19 )&0x1F)+1;
145
146 if( gfx->words.w0 & 0x00010000 )
147 {
148 if( gRSP.DKRBillBoard )
149 gRSP.DKRVtxCount = 1;
150 }
151 else
152 {
153 gRSP.DKRVtxCount = 0;
154 }
155
156 dwV0 += gRSP.DKRVtxCount;
157
158 LOG_UCODE(" Address 0x%08x, v0: %d, Num: %d", dwAddr, dwV0, dwN);
159 DEBUGGER_ONLY_IF( (pauseAtNext && (eventToPause==NEXT_VERTEX_CMD||eventToPause==NEXT_MATRIX_CMD)), {DebuggerAppendMsg("DKR Vtx: Cmd0=%08X, Cmd1=%08X", (gfx->words.w0), (gfx->words.w1));});
160
161 VTX_DUMP(TRACE2("Vtx_DKR, cmd0=%08X cmd1=%08X", (gfx->words.w0), (gfx->words.w1)));
162 VTX_DUMP(TRACE2("Vtx_DKR, v0=%d n=%d", dwV0, dwN));
163
164 if (dwV0 >= 32)
165 dwV0 = 31;
166
167 if ((dwV0 + dwN) > 32)
168 {
169 WARNING(TRACE0("Warning, attempting to load into invalid vertex positions"));
170 dwN = 32 - dwV0;
171 }
172
173
174 //if( dwAddr == 0 || dwAddr < 0x2000)
175 {
176 dwAddr = (gfx->words.w1)+RSPSegmentAddr(gRSP.dwDKRVtxAddr);
177 }
178
179 // Check that address is valid...
180 if ((dwAddr + (dwN*16)) > g_dwRamSize)
181 {
182 WARNING(TRACE1("ProcessVertexData: Address out of range (0x%08x)", dwAddr));
183 }
184 else
185 {
186 ProcessVertexDataDKR(dwAddr, dwV0, dwN);
187
188 status.dwNumVertices += dwN;
189
190 RDP_GFX_DumpVtxInfoDKR(dwAddr, dwV0, dwN);
191 }
192}
193
194
195void RSP_Vtx_Gemini(Gfx *gfx)
196{
197 uint32 dwAddr = RSPSegmentAddr((gfx->words.w1));
198 uint32 dwV0 = (((gfx->words.w0)>>9)&0x1F);
199 uint32 dwN = (((gfx->words.w0) >>19 )&0x1F);
200
201 LOG_UCODE(" Address 0x%08x, v0: %d, Num: %d", dwAddr, dwV0, dwN);
202 DEBUGGER_ONLY_IF( (pauseAtNext && (eventToPause==NEXT_VERTEX_CMD||eventToPause==NEXT_MATRIX_CMD)), {DebuggerAppendMsg("DKR Vtx: Cmd0=%08X, Cmd1=%08X", (gfx->words.w0), (gfx->words.w1));});
203
204 VTX_DUMP(TRACE2("Vtx_DKR, cmd0=%08X cmd1=%08X", (gfx->words.w0), (gfx->words.w1)));
205
206 if (dwV0 >= 32)
207 dwV0 = 31;
208
209 if ((dwV0 + dwN) > 32)
210 {
211 TRACE0("Warning, attempting to load into invalid vertex positions");
212 dwN = 32 - dwV0;
213 }
214
215
216 //if( dwAddr == 0 || dwAddr < 0x2000)
217 {
218 dwAddr = (gfx->words.w1)+RSPSegmentAddr(gRSP.dwDKRVtxAddr);
219 }
220
221 // Check that address is valid...
222 if ((dwAddr + (dwN*16)) > g_dwRamSize)
223 {
224 TRACE1("ProcessVertexData: Address out of range (0x%08x)", dwAddr);
225 }
226 else
227 {
228 ProcessVertexDataDKR(dwAddr, dwV0, dwN);
229
230 status.dwNumVertices += dwN;
231
232 RDP_GFX_DumpVtxInfoDKR(dwAddr, dwV0, dwN);
233 }
234}
235
236// DKR verts are extra 4 bytes
237void RDP_GFX_DumpVtxInfoDKR(uint32 dwAddr, uint32 dwV0, uint32 dwN)
238{
239#ifdef DEBUGGER
240 uint32 dwV;
241 int i;
242
243 short * psSrc = (short *)(g_pRDRAMu8 + dwAddr);
244
245 i = 0;
246 for (dwV = dwV0; dwV < dwV0 + dwN; dwV++)
247 {
248 float x = (float)psSrc[(i + 0) ^ 1];
249 float y = (float)psSrc[(i + 1) ^ 1];
250 float z = (float)psSrc[(i + 2) ^ 1];
251
252 //uint16 wFlags = CRender::g_pRender->m_dwVecFlags[dwV]; //(uint16)psSrc[3^0x1];
253
254 uint16 wA = psSrc[(i + 3) ^ 1];
255 uint16 wB = psSrc[(i + 4) ^ 1];
256
257 uint8 a = wA>>8;
258 uint8 b = (uint8)wA;
259 uint8 c = wB>>8;
260 uint8 d = (uint8)wB;
261
262 XVECTOR4 & t = g_vecProjected[dwV];
263
264
265 LOG_UCODE(" #%02d Pos: {% 6f,% 6f,% 6f} Extra: %02x %02x %02x %02x (transf: {% 6f,% 6f,% 6f})",
266 dwV, x, y, z, a, b, c, d, t.x, t.y, t.z );
267
268 i+=5;
269 }
270
271
272 uint16 * pwSrc = (uint16 *)(g_pRDRAMu8 + dwAddr);
273 i = 0;
274 for (dwV = dwV0; dwV < dwV0 + dwN; dwV++)
275 {
276 LOG_UCODE(" #%02d %04x %04x %04x %04x %04x",
277 dwV, pwSrc[(i + 0) ^ 1],
278 pwSrc[(i + 1) ^ 1],
279 pwSrc[(i + 2) ^ 1],
280 pwSrc[(i + 3) ^ 1],
281 pwSrc[(i + 4) ^ 1]);
282
283 i += 5;
284 }
285
286#endif // DEBUGGER
287}
288
289void DLParser_Set_Addr_Ucode6(Gfx *gfx)
290{
291 gRSP.dwDKRMatrixAddr = (gfx->words.w0)&0x00FFFFFF;
292 gRSP.dwDKRVtxAddr = (gfx->words.w1)&0x00FFFFFF;
293 gRSP.DKRVtxCount=0;
294}
295
296
297
298void RSP_Vtx_WRUS(Gfx *gfx)
299{
300 uint32 dwAddr = RSPSegmentAddr((gfx->words.w1));
301 uint32 dwLength = ((gfx->words.w0))&0xFFFF;
302
303 uint32 dwN= (dwLength + 1) / 0x210;
304 //uint32 dwN= (dwLength >> 9);
305 //uint32 dwV0 = (((gfx->words.w0)>>16)&0x3f)/5;
306 uint32 dwV0 = (((gfx->words.w0)>>16)&0xFF)/5;
307
308 LOG_UCODE(" Address 0x%08x, v0: %d, Num: %d, Length: 0x%04x", dwAddr, dwV0, dwN, dwLength);
309
310 if (dwV0 >= 32)
311 dwV0 = 31;
312
313 if ((dwV0 + dwN) > 32)
314 {
315 TRACE0("Warning, attempting to load into invalid vertex positions");
316 dwN = 32 - dwV0;
317 }
318
319 ProcessVertexData(dwAddr, dwV0, dwN);
320
321 status.dwNumVertices += dwN;
322
323 DisplayVertexInfo(dwAddr, dwV0, dwN);
324}
325
326void RSP_Vtx_ShadowOfEmpire(Gfx *gfx)
327{
328 uint32 dwAddr = RSPSegmentAddr((gfx->words.w1));
329 uint32 dwLength = ((gfx->words.w0))&0xFFFF;
330
331 uint32 dwN= (((gfx->words.w0) >> 4) & 0xFFF) / 33 + 1;
332 uint32 dwV0 = 0;
333
334 LOG_UCODE(" Address 0x%08x, v0: %d, Num: %d, Length: 0x%04x", dwAddr, dwV0, dwN, dwLength);
335
336 if (dwV0 >= 32)
337 dwV0 = 31;
338
339 if ((dwV0 + dwN) > 32)
340 {
341 TRACE0("Warning, attempting to load into invalid vertex positions");
342 dwN = 32 - dwV0;
343 }
344
345 ProcessVertexData(dwAddr, dwV0, dwN);
346
347 status.dwNumVertices += dwN;
348
349 DisplayVertexInfo(dwAddr, dwV0, dwN);
350}
351
352
353void RSP_DL_In_MEM_DKR(Gfx *gfx)
354{
355 // This cmd is likely to execute number of ucode at the given address
356 uint32 dwAddr = (gfx->words.w1);//RSPSegmentAddr((gfx->words.w1));
357 {
358 gDlistStackPointer++;
359 gDlistStack[gDlistStackPointer].pc = dwAddr;
360 gDlistStack[gDlistStackPointer].countdown = (((gfx->words.w0)>>16)&0xFF);
361 }
362}
363uint16 ConvertYUVtoR5G5B5X1(int y, int u, int v)
364{
365 float r = y + (1.370705f * (v-128));
366 float g = y - (0.698001f * (v-128)) - (0.337633f * (u-128));
367 float b = y + (1.732446f * (u-128));
368 r *= 0.125f;
369 g *= 0.125f;
370 b *= 0.125f;
371
372 //clipping the result
373 if (r > 32) r = 32;
374 if (g > 32) g = 32;
375 if (b > 32) b = 32;
376 if (r < 0) r = 0;
377 if (g < 0) g = 0;
378 if (b < 0) b = 0;
379
380 uint16 c = (uint16)(((uint16)(r) << 11) |
381 ((uint16)(g) << 6) |
382 ((uint16)(b) << 1) | 1);
383 return c;
384}
385
386void TexRectToN64FrameBuffer_YUV_16b(uint32 x0, uint32 y0, uint32 width, uint32 height)
387{
388 // Convert YUV image at TImg and Copy the texture into the N64 RDRAM framebuffer memory
389
390 uint32 n64CIaddr = g_CI.dwAddr;
391 uint32 n64CIwidth = g_CI.dwWidth;
392
393 for (uint32 y = 0; y < height; y++)
394 {
395 uint32* pN64Src = (uint32*)(g_pRDRAMu8+(g_TI.dwAddr&(g_dwRamSize-1)))+y*(g_TI.dwWidth>>1);
396 uint16* pN64Dst = (uint16*)(g_pRDRAMu8+(n64CIaddr&(g_dwRamSize-1)))+(y+y0)*n64CIwidth;
397
398 for (uint32 x = 0; x < width; x+=2)
399 {
400 uint32 val = *pN64Src++;
401 int y0 = (uint8)val&0xFF;
402 int v = (uint8)(val>>8)&0xFF;
403 int y1 = (uint8)(val>>16)&0xFF;
404 int u = (uint8)(val>>24)&0xFF;
405
406 pN64Dst[x+x0] = ConvertYUVtoR5G5B5X1(y0,u,v);
407 pN64Dst[x+x0+1] = ConvertYUVtoR5G5B5X1(y1,u,v);
408 }
409 }
410}
411
412extern uObjMtxReal gObjMtxReal;
413void DLParser_OgreBatter64BG(Gfx *gfx)
414{
415#ifdef DEBUGGER
416uint32 dwAddr = RSPSegmentAddr((gfx->words.w1));
417uObjTxSprite *ptr = (uObjTxSprite*)(g_pRDRAMu8+dwAddr);
418#endif
419
420PrepareTextures();
421
422CTexture *ptexture = g_textures[0].m_pCTexture;
423TexRectToN64FrameBuffer_16b( (uint32)gObjMtxReal.X, (uint32)gObjMtxReal.Y, ptexture->m_dwWidth, ptexture->m_dwHeight, gRSP.curTile);
424
425#ifdef DEBUGGER
426CRender::g_pRender->DrawSpriteR(*ptr, false);
427
428DEBUGGER_PAUSE_AT_COND_AND_DUMP_COUNT_N((pauseAtNext &&
429(eventToPause==NEXT_OBJ_TXT_CMD|| eventToPause==NEXT_FLUSH_TRI)),
430{DebuggerAppendMsg("OgreBatter 64 BG: Addr=%08X\n", dwAddr);});
431#endif
432}
433
434void DLParser_Bomberman2TextRect(Gfx *gfx)
435{
436 // Bomberman 64 - The Second Attack! (U) [!]
437 // The 0x02 cmd, list a TexRect cmd
438
439 if( options.enableHackForGames == HACK_FOR_OGRE_BATTLE && gRDP.tiles[7].dwFormat == TXT_FMT_YUV )
440 {
441 TexRectToN64FrameBuffer_YUV_16b( (uint32)gObjMtxReal.X, (uint32)gObjMtxReal.Y, 16, 16);
442 //DLParser_OgreBatter64BG((gfx->words.w0), (gfx->words.w1));
443 return;
444 }
445
446 uint32 dwAddr = RSPSegmentAddr((gfx->words.w1));
447 uObjSprite *info = (uObjSprite*)(g_pRDRAMu8+dwAddr);
448
449 uint32 dwTile = gRSP.curTile;
450
451 PrepareTextures();
452
453 //CRender::g_pRender->SetCombinerAndBlender();
454
455 uObjTxSprite drawinfo;
456 memcpy( &(drawinfo.sprite), info, sizeof(uObjSprite));
457 CRender::g_pRender->DrawSpriteR(drawinfo, false, dwTile, 0, 0, drawinfo.sprite.imageW/32, drawinfo.sprite.imageH/32);
458
459 DEBUGGER_PAUSE_AT_COND_AND_DUMP_COUNT_N((pauseAtNext && (eventToPause==NEXT_TRIANGLE|| eventToPause==NEXT_FLUSH_TRI)),
460 {
461 DebuggerAppendMsg("Bomberman 64 - TextRect: Addr=%08X\n", dwAddr);
462 dwAddr &= (g_dwRamSize-1);
463 DebuggerAppendMsg("%08X-%08X-%08X-%08X-%08X-%08X\n", RDRAM_UWORD(dwAddr), RDRAM_UWORD(dwAddr+4),
464 RDRAM_UWORD(dwAddr+8), RDRAM_UWORD(dwAddr+12), RDRAM_UWORD(dwAddr+16), RDRAM_UWORD(dwAddr+20) );
465 }
466 );
467}
468
469
470void RSP_MoveWord_DKR(Gfx *gfx)
471{
472 SP_Timing(RSP_GBI1_MoveWord);
473 uint32 dwNumLights;
474
475 switch ((gfx->words.w0) & 0xFF)
476 {
477 case RSP_MOVE_WORD_NUMLIGHT:
478 dwNumLights = (gfx->words.w1)&0x7;
479 LOG_UCODE(" RSP_MOVE_WORD_NUMLIGHT: Val:%d", dwNumLights);
480
481 gRSP.ambientLightIndex = dwNumLights;
482 SetNumLights(dwNumLights);
483 //gRSP.DKRBillBoard = (gfx->words.w1)&0x1 ? true : false;
484 gRSP.DKRBillBoard = (gfx->words.w1)&0x7 ? true : false;
485
486 LOG_UCODE(" gRSP.DKRBillBoard = %d", gRSP.DKRBillBoard);
487 DEBUGGER_PAUSE_AND_DUMP_COUNT_N(NEXT_MATRIX_CMD, {DebuggerAppendMsg("DKR Moveword, select gRSP.DKRBillBoard %s, cmd0=%08X, cmd1=%08X", gRSP.DKRBillBoard?"true":"false", (gfx->words.w0), (gfx->words.w1));});
488 break;
489 case RSP_MOVE_WORD_LIGHTCOL:
490 gRSP.DKRCMatrixIndex = ((gfx->words.w1)>>6)&7;
491 //gRSP.DKRCMatrixIndex = ((gfx->words.w1)>>6)&3;
492 LOG_UCODE(" gRSP.DKRCMatrixIndex = %d", gRSP.DKRCMatrixIndex);
493 DEBUGGER_PAUSE_AND_DUMP_COUNT_N(NEXT_MATRIX_CMD, {DebuggerAppendMsg("DKR Moveword, select matrix %d, cmd0=%08X, cmd1=%08X", gRSP.DKRCMatrixIndex, (gfx->words.w0), (gfx->words.w1));});
494 break;
495 default:
496 RSP_GBI1_MoveWord(gfx);
497 break;
498 }
499}
500
501
502void RSP_DMA_Tri_DKR(Gfx *gfx)
503{
504 BOOL bTrisAdded = FALSE;
505 uint32 dwAddr = RSPSegmentAddr((gfx->words.w1));
506 uint32 flag = ((gfx->words.w0) & 0xFF0000) >> 16;
507 if (flag&1)
508 CRender::g_pRender->SetCullMode(false,true);
509 else
510 CRender::g_pRender->SetCullMode(false,false);
511
512 uint32 dwNum = (((gfx->words.w0) & 0xFFF0) >>4 );
513 uint32 * pData = (uint32*)&g_pRDRAMu32[dwAddr/4];
514
515 if( dwAddr+16*dwNum >= g_dwRamSize )
516 {
517 TRACE0("DMATRI invalid memory pointer");
518 return;
519 }
520
521 TRI_DUMP(TRACE2("DMATRI, addr=%08X, Cmd0=%08X\n", dwAddr, (gfx->words.w0)));
522
523 status.primitiveType = PRIM_DMA_TRI;
524
525 for (uint32 i = 0; i < dwNum; i++)
526 {
527 LOG_UCODE(" 0x%08x: %08x %08x %08x %08x", dwAddr + i*16,
528 pData[0], pData[1], pData[2], pData[3]);
529
530 uint32 dwInfo = pData[0];
531
532 uint32 dwV0 = (dwInfo >> 16) & 0x1F;
533 uint32 dwV1 = (dwInfo >> 8) & 0x1F;
534 uint32 dwV2 = (dwInfo ) & 0x1F;
535
536 TRI_DUMP(TRACE5("DMATRI: %d, %d, %d (%08X-%08X)", dwV0,dwV1,dwV2,(gfx->words.w0),(gfx->words.w1)));
537
538 //if (IsTriangleVisible(dwV0, dwV1, dwV2))
539 {
540 DEBUG_DUMP_VERTEXES("DmaTri", dwV0, dwV1, dwV2);
541 LOG_UCODE(" Tri: %d,%d,%d", dwV0, dwV1, dwV2);
542 if (!bTrisAdded )//&& CRender::g_pRender->IsTextureEnabled())
543 {
544 PrepareTextures();
545 InitVertexTextureConstants();
546 }
547
548 // Generate texture coordinates
549 short s0 = ((short)(pData[1]>>16));
550 short t0 = ((short)(pData[1]&0xFFFF));
551 short s1 = ((short)(pData[2]>>16));
552 short t1 = ((short)(pData[2]&0xFFFF));
553 short s2 = ((short)(pData[3]>>16));
554 short t2 = ((short)(pData[3]&0xFFFF));
555
556 TRI_DUMP(
557 {
558 DebuggerAppendMsg(" (%d,%d), (%d,%d), (%d,%d)",s0,t0,s1,t1,s2,t2);
559 DebuggerAppendMsg(" (%08X), (%08X), (%08X), (%08X)",pData[0],pData[1],pData[2],pData[3]);
560 });
561 CRender::g_pRender->SetVtxTextureCoord(dwV0, s0, t0);
562 CRender::g_pRender->SetVtxTextureCoord(dwV1, s1, t1);
563 CRender::g_pRender->SetVtxTextureCoord(dwV2, s2, t2);
564
565 if( !bTrisAdded )
566 {
567 CRender::g_pRender->SetCombinerAndBlender();
568 }
569
570 bTrisAdded = true;
571 PrepareTriangle(dwV0, dwV1, dwV2);
572 }
573
574 pData += 4;
575
576 }
577
578 if (bTrisAdded)
579 {
580 CRender::g_pRender->DrawTriangles();
581 }
582 gRSP.DKRVtxCount=0;
583}
584
585uint32 dwPDCIAddr = 0;
586void ProcessVertexDataPD(uint32 dwAddr, uint32 dwV0, uint32 dwNum);
587void RSP_Vtx_PD(Gfx *gfx)
588{
589 SP_Timing(RSP_GBI0_Vtx);
590
591 uint32 dwAddr = RSPSegmentAddr((gfx->words.w1));
592 uint32 dwV0 = ((gfx->words.w0)>>16)&0x0F;
593 uint32 dwN = (((gfx->words.w0)>>20)&0x0F)+1;
594 //uint32 dwLength = ((gfx->words.w0))&0xFFFF;
595
596 LOG_UCODE(" Address 0x%08x, v0: %d, Num: %d", dwAddr, dwV0, dwN);
597
598 ProcessVertexDataPD(dwAddr, dwV0, dwN);
599 status.dwNumVertices += dwN;
600}
601
602void RSP_Set_Vtx_CI_PD(Gfx *gfx)
603{
604 // Color index buf address
605 dwPDCIAddr = RSPSegmentAddr((gfx->words.w1));
606}
607
608void RSP_Tri4_PD(Gfx *gfx)
609{
610 uint32 w0 = gfx->words.w0;
611 uint32 w1 = gfx->words.w1;
612
613 status.primitiveType = PRIM_TRI2;
614
615 // While the next command pair is Tri2, add vertices
616 uint32 dwPC = gDlistStack[gDlistStackPointer].pc;
617
618 BOOL bTrisAdded = FALSE;
619
620 do {
621 uint32 dwFlag = (w0>>16)&0xFF;
622 LOG_UCODE(" PD Tri4: 0x%08x 0x%08x Flag: 0x%02x", w0, w1, dwFlag);
623
624 BOOL bVisible;
625 for( uint32 i=0; i<4; i++)
626 {
627 uint32 v0 = (w1>>(4+(i<<3))) & 0xF;
628 uint32 v1 = (w1>>( (i<<3))) & 0xF;
629 uint32 v2 = (w0>>( (i<<2))) & 0xF;
630 bVisible = IsTriangleVisible(v0, v2, v1);
631 LOG_UCODE(" (%d, %d, %d) %s", v0, v1, v2, bVisible ? "": "(clipped)");
632 if (bVisible)
633 {
634 DEBUG_DUMP_VERTEXES("Tri4_PerfectDark 1/2", v0, v1, v2);
635 if (!bTrisAdded && CRender::g_pRender->IsTextureEnabled())
636 {
637 PrepareTextures();
638 InitVertexTextureConstants();
639 }
640
641 if( !bTrisAdded )
642 {
643 CRender::g_pRender->SetCombinerAndBlender();
644 }
645
646 bTrisAdded = true;
647 PrepareTriangle(v0, v2, v1);
648 }
649 }
650
651 w0 = *(uint32 *)(g_pRDRAMu8 + dwPC+0);
652 w1 = *(uint32 *)(g_pRDRAMu8 + dwPC+4);
653 dwPC += 8;
654
655#ifdef DEBUGGER
656 } while (!(pauseAtNext && eventToPause==NEXT_TRIANGLE) && (w0>>24) == (uint8)RSP_TRI2);
657#else
658 } while ((w0>>24) == (uint8)RSP_TRI2);
659#endif
660
661 gDlistStack[gDlistStackPointer].pc = dwPC-8;
662
663 if (bTrisAdded)
664 {
665 CRender::g_pRender->DrawTriangles();
666 }
667
668 DEBUG_TRIANGLE(TRACE0("Pause at PD Tri4"));
669}
670
671
672void DLParser_Tri4_Conker(Gfx *gfx)
673{
674 uint32 w0 = gfx->words.w0;
675 uint32 w1 = gfx->words.w1;
676
677 status.primitiveType = PRIM_TRI2;
678
679 // While the next command pair is Tri2, add vertices
680 uint32 dwPC = gDlistStack[gDlistStackPointer].pc;
681
682 BOOL bTrisAdded = FALSE;
683
684 do {
685 LOG_UCODE(" Conker Tri4: 0x%08x 0x%08x", w0, w1);
686 uint32 idx[12];
687 idx[0] = (w1 )&0x1F;
688 idx[1] = (w1>> 5)&0x1F;
689 idx[2] = (w1>>10)&0x1F;
690 idx[3] = (w1>>15)&0x1F;
691 idx[4] = (w1>>20)&0x1F;
692 idx[5] = (w1>>25)&0x1F;
693
694 idx[6] = (w0 )&0x1F;
695 idx[7] = (w0>> 5)&0x1F;
696 idx[8] = (w0>>10)&0x1F;
697
698 idx[ 9] = (((w0>>15)&0x7)<<2)|(w1>>30);
699 idx[10] = (w0>>18)&0x1F;
700 idx[11] = (w0>>23)&0x1F;
701
702 BOOL bVisible;
703 for( uint32 i=0; i<4; i++)
704 {
705 uint32 v0=idx[i*3 ];
706 uint32 v1=idx[i*3+1];
707 uint32 v2=idx[i*3+2];
708 bVisible = IsTriangleVisible(v0, v1, v2);
709 LOG_UCODE(" (%d, %d, %d) %s", v0, v1, v2, bVisible ? "": "(clipped)");
710 if (bVisible)
711 {
712 DEBUG_DUMP_VERTEXES("Tri4 Conker:", v0, v1, v2);
713 if (!bTrisAdded && CRender::g_pRender->IsTextureEnabled())
714 {
715 PrepareTextures();
716 InitVertexTextureConstants();
717 }
718
719 if( !bTrisAdded )
720 {
721 CRender::g_pRender->SetCombinerAndBlender();
722 }
723
724 bTrisAdded = true;
725 PrepareTriangle(v0, v1, v2);
726 }
727 }
728
729 w0 = *(uint32 *)(g_pRDRAMu8 + dwPC+0);
730 w1 = *(uint32 *)(g_pRDRAMu8 + dwPC+4);
731 dwPC += 8;
732
733#ifdef DEBUGGER
734 } while (!(pauseAtNext && eventToPause==NEXT_TRIANGLE) && (w0>>28) == 1 );
735#else
736 } while ((w0>>28) == 1);
737#endif
738
739 gDlistStack[gDlistStackPointer].pc = dwPC-8;
740
741 if (bTrisAdded)
742 {
743 CRender::g_pRender->DrawTriangles();
744 }
745
746 DEBUG_TRIANGLE(TRACE0("Pause at Conker Tri4"));
747}
748
749void RDP_GFX_Force_Vertex_Z_Conker(uint32 dwAddr)
750{
751 VTX_DUMP(
752 {
753 s8 * pcBase = g_pRDRAMs8 + (dwAddr&(g_dwRamSize-1));
754 uint32 * pdwBase = (uint32 *)pcBase;
755
756 for (int i = 0; i < 4; i++)
757 {
758 DebuggerAppendMsg(" %08x %08x %08x %08x", pdwBase[0], pdwBase[1], pdwBase[2], pdwBase[3]);
759 pdwBase+=4;
760 }
761 });
762
763 dwConkerVtxZAddr = dwAddr;
764 DEBUGGER_PAUSE_AND_DUMP(NEXT_VERTEX_CMD,{TRACE0("Paused at RDP_GFX_Force_Matrix_Conker Cmd");});
765}
766
767
768
769void DLParser_MoveMem_Conker(Gfx *gfx)
770{
771 uint32 dwType = ((gfx->words.w0) ) & 0xFE;
772 uint32 dwAddr = RSPSegmentAddr((gfx->words.w1));
773 if( dwType == RSP_GBI2_MV_MEM__MATRIX )
774 {
775 LOG_UCODE(" DLParser_MoveMem_Conker");
776 RDP_GFX_Force_Vertex_Z_Conker(dwAddr);
777 }
778 else if( dwType == RSP_GBI2_MV_MEM__LIGHT )
779 {
780 LOG_UCODE(" MoveMem Light Conker");
781 uint32 dwOffset2 = ((gfx->words.w0) >> 5) & 0x3FFF;
782 uint32 dwLight=0xFF;
783 if( dwOffset2 >= 0x30 )
784 {
785 dwLight = (dwOffset2 - 0x30)/0x30;
786 LOG_UCODE(" Light %d:", dwLight);
787 RSP_MoveMemLight(dwLight, dwAddr);
788 }
789 else
790 {
791 // fix me
792 //TRACE0("Check me in DLParser_MoveMem_Conker - MoveMem Light");
793 }
794 DEBUGGER_PAUSE_AND_DUMP_COUNT_N( NEXT_SET_LIGHT,
795 {
796 DebuggerAppendMsg("RSP_MoveMemLight: %d, Addr=%08X, cmd0=%08X", dwLight, dwAddr, (gfx->words.w0));
797 TRACE0("Pause after MoveMemLight");
798 });
799 }
800 else
801 {
802 RSP_GBI2_MoveMem(gfx);
803 }
804}
805
806extern void ProcessVertexDataConker(uint32 dwAddr, uint32 dwV0, uint32 dwNum);
807void RSP_Vtx_Conker(Gfx *gfx)
808{
809 uint32 dwAddr = RSPSegmentAddr((gfx->words.w1));
810 uint32 dwVEnd = (((gfx->words.w0) )&0xFFF)/2;
811 uint32 dwN = (((gfx->words.w0)>>12)&0xFFF);
812 uint32 dwV0 = dwVEnd - dwN;
813
814 LOG_UCODE(" Vtx: Address 0x%08x, vEnd: %d, v0: %d, Num: %d", dwAddr, dwVEnd, dwV0, dwN);
815
816 ProcessVertexDataConker(dwAddr, dwV0, dwN);
817 status.dwNumVertices += dwN;
818 DisplayVertexInfo(dwAddr, dwV0, dwN);
819}
820
821
822void DLParser_MoveWord_Conker(Gfx *gfx)
823{
824 uint32 dwType = ((gfx->words.w0) >> 16) & 0xFF;
825 if( dwType != RSP_MOVE_WORD_NUMLIGHT )
826 {
827 RSP_GBI2_MoveWord(gfx);
828 }
829 else
830 {
831 uint32 dwNumLights = ((gfx->words.w1)/48);
832 LOG_UCODE("Conker RSP_MOVE_WORD_NUMLIGHT: %d", dwNumLights);
833 gRSP.ambientLightIndex = dwNumLights+1;
834 SetNumLights(dwNumLights);
835 DEBUGGER_PAUSE_AND_DUMP_COUNT_N( NEXT_SET_LIGHT,
836 {
837 DebuggerAppendMsg("SetNumLights: %d", dwNumLights);
838 TRACE0("Pause after SetNumLights");
839 });
840 }
841}
842
843void DLParser_Ucode8_0x0(Gfx *gfx)
844{
845 LOG_UCODE("DLParser_Ucode8_0x0");
846
847 if( (gfx->words.w0) == 0 && (gfx->words.w1) )
848 {
849 uint32 newaddr = RSPSegmentAddr((gfx->words.w1));
850
851 if( newaddr && newaddr < g_dwRamSize)
852 {
853 if( gDlistStackPointer < MAX_DL_STACK_SIZE-1 )
854 {
855 gDlistStackPointer++;
856 gDlistStack[gDlistStackPointer].pc = newaddr+8; // Always skip the first 2 entries
857 gDlistStack[gDlistStackPointer].countdown = MAX_DL_COUNT;
858 }
859 else
860 {
861 DebuggerAppendMsg("Error, gDlistStackPointer overflow");
862 }
863 }
864 }
865 else
866 {
867 LOG_UCODE("DLParser_Ucode8_0x0, skip 0x%08X, 0x%08x", (gfx->words.w0), (gfx->words.w1));
868 gDlistStack[gDlistStackPointer].pc += 8;
869 }
870}
871
872
873uint32 Rogue_Squadron_Vtx_XYZ_Cmd;
874uint32 Rogue_Squadron_Vtx_XYZ_Addr;
875uint32 Rogue_Squadron_Vtx_Color_Cmd;
876uint32 Rogue_Squadron_Vtx_Color_Addr;
877uint32 GSBlkAddrSaves[100][2];
878
879void ProcessVertexData_Rogue_Squadron(uint32 dwXYZAddr, uint32 dwColorAddr, uint32 dwXYZCmd, uint32 dwColorCmd);
880
881void DLParser_RS_Color_Buffer(Gfx *gfx)
882{
883 uint32 dwPC = gDlistStack[gDlistStackPointer].pc-8;
884 uint32 dwAddr = RSPSegmentAddr((gfx->words.w1));
885
886 if( dwAddr > g_dwRamSize )
887 {
888 TRACE0("DL, addr is wrong");
889 dwAddr = (gfx->words.w1)&(g_dwRamSize-1);
890 }
891
892 Rogue_Squadron_Vtx_Color_Cmd = (gfx->words.w0);
893 Rogue_Squadron_Vtx_Color_Addr = dwAddr;
894
895 LOG_UCODE("Vtx_Color at PC=%08X: 0x%08x 0x%08x\n", dwPC-8, (gfx->words.w0), (gfx->words.w1));
896#ifdef DEBUGGER
897 if( pauseAtNext && (eventToPause == NEXT_VERTEX_CMD ) )
898 {
899 DebuggerAppendMsg("Vtx_Color at PC=%08X: 0x%08x 0x%08x\n", dwPC-8, (gfx->words.w0), (gfx->words.w1));
900 if( dwAddr < g_dwRamSize )
901 {
902 DumpHex(dwAddr, min(64, g_dwRamSize-dwAddr));
903 }
904 }
905#endif
906
907 ProcessVertexData_Rogue_Squadron(Rogue_Squadron_Vtx_XYZ_Addr, Rogue_Squadron_Vtx_Color_Addr, Rogue_Squadron_Vtx_XYZ_Cmd, Rogue_Squadron_Vtx_Color_Cmd);
908
909}
910
911
912void DLParser_RS_Vtx_Buffer(Gfx *gfx)
913{
914 uint32 dwPC = gDlistStack[gDlistStackPointer].pc-8;
915 uint32 dwAddr = RSPSegmentAddr((gfx->words.w1));
916 if( dwAddr > g_dwRamSize )
917 {
918 TRACE0("DL, addr is wrong");
919 dwAddr = (gfx->words.w1)&(g_dwRamSize-1);
920 }
921
922 LOG_UCODE("Vtx_XYZ at PC=%08X: 0x%08x 0x%08x\n", dwPC-8, (gfx->words.w0), (gfx->words.w1));
923 Rogue_Squadron_Vtx_XYZ_Cmd = (gfx->words.w0);
924 Rogue_Squadron_Vtx_XYZ_Addr = dwAddr;
925
926#ifdef DEBUGGER
927 if( pauseAtNext && (eventToPause == NEXT_VERTEX_CMD ) )
928 {
929 DebuggerAppendMsg("Vtx_XYZ at PC=%08X: 0x%08x 0x%08x\n", dwPC-8, (gfx->words.w0), (gfx->words.w1));
930 if( dwAddr < g_dwRamSize )
931 {
932 DumpHex(dwAddr, min(64, g_dwRamSize-dwAddr));
933 }
934 }
935#endif
936}
937
938
939void DLParser_RS_Block(Gfx *gfx)
940{
941 uint32 dwPC = gDlistStack[gDlistStackPointer].pc-8;
942 LOG_UCODE("ucode 0x80 at PC=%08X: 0x%08x 0x%08x\n", dwPC, (gfx->words.w0), (gfx->words.w1));
943}
944
945void DLParser_RS_MoveMem(Gfx *gfx)
946{
947 //uint32 dwPC = gDlistStack[gDlistStackPointer].pc;
948 //uint32 cmd1 = ((dwPC)&0x00FFFFFF)|0x80000000;
949 RSP_GBI1_MoveMem(gfx);
950 /*
951 LOG_UCODE("RS_MoveMem", ((gfx->words.w0)>>24));
952 LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x", dwPC, (gfx->words.w0), (gfx->words.w1));
953 dwPC+=8;
954 uint32 dwCmd2 = *(uint32 *)(g_pRDRAMu8 + dwPC);
955 uint32 dwCmd3 = *(uint32 *)(g_pRDRAMu8 + dwPC+4);
956 LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x", dwPC, dwCmd2, dwCmd3);
957 dwPC+=8;
958 uint32 dwCmd4 = *(uint32 *)(g_pRDRAMu8 + dwPC);
959 uint32 dwCmd5 = *(uint32 *)(g_pRDRAMu8 + dwPC+4);
960 LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x\n", dwPC, dwCmd4, dwCmd5);
961 */
962 gDlistStack[gDlistStackPointer].pc += 16;
963
964 //DEBUGGER_PAUSE_AND_DUMP(NEXT_SET_MODE_CMD, {
965 // DebuggerAppendMsg("Pause after RS_MoveMem at: %08X\n", dwPC-8);
966 //});
967
968}
969
970void DLParser_RS_0xbe(Gfx *gfx)
971{
972 uint32 dwPC = gDlistStack[gDlistStackPointer].pc-8;
973 LOG_UCODE("ucode %02X, skip 1", ((gfx->words.w0)>>24));
974 LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x", dwPC, (gfx->words.w0), (gfx->words.w1));
975 dwPC+=8;
976 uint32 dwCmd2 = *(uint32 *)(g_pRDRAMu8 + dwPC);
977 uint32 dwCmd3 = *(uint32 *)(g_pRDRAMu8 + dwPC+4);
978 LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x\n", dwPC, dwCmd2, dwCmd3);
979 gDlistStack[gDlistStackPointer].pc += 8;
980
981 DEBUGGER_PAUSE_AND_DUMP(NEXT_SET_MODE_CMD, {
982 DebuggerAppendMsg("Pause after RS_0xbe at: %08X\n", dwPC-8);
983 DebuggerAppendMsg("\t0x%08x 0x%08x", (gfx->words.w0), (gfx->words.w1));
984 DebuggerAppendMsg("\t0x%08x 0x%08x", dwCmd2, dwCmd3);
985 });
986}
987
988
989void DLParser_Ucode8_EndDL(Gfx *gfx)
990{
991#ifdef DEBUGGER
992 uint32 dwPC = gDlistStack[gDlistStackPointer].pc-8;
993#endif
994
995 RDP_GFX_PopDL();
996 DEBUGGER_PAUSE_AND_DUMP(NEXT_DLIST, DebuggerAppendMsg("PC=%08X: EndDL, return to %08X\n\n", dwPC, gDlistStack[gDlistStackPointer].pc));
997}
998
999void DLParser_Ucode8_DL(Gfx *gfx) // DL Function Call
1000{
1001#ifdef DEBUGGER
1002 uint32 dwPC = gDlistStack[gDlistStackPointer].pc-8;
1003#endif
1004
1005 uint32 dwAddr = RSPSegmentAddr((gfx->words.w1));
1006 uint32 dwCmd2 = *(uint32 *)(g_pRDRAMu8 + dwAddr);
1007 uint32 dwCmd3 = *(uint32 *)(g_pRDRAMu8 + dwAddr+4);
1008
1009 if( dwAddr > g_dwRamSize )
1010 {
1011 TRACE0("DL, addr is wrong");
1012 dwAddr = (gfx->words.w1)&(g_dwRamSize-1);
1013 }
1014
1015 // Detect looping
1016 /*if(gDlistStackPointer>0 )
1017 {
1018 for( int i=0; i<gDlistStackPointer; i++ )
1019 {
1020 if(gDlistStack[i].addr == dwAddr+8)
1021 {
1022 TRACE1("Detected DL looping, PC=%08X", dwPC );
1023 DLParser_Ucode8_EndDL(0,0);
1024 return;
1025 }
1026 }
1027 }*/
1028
1029 if( gDlistStackPointer < MAX_DL_STACK_SIZE-1 )
1030 {
1031 gDlistStackPointer++;
1032 gDlistStack[gDlistStackPointer].pc = dwAddr+16;
1033 gDlistStack[gDlistStackPointer].countdown = MAX_DL_COUNT;
1034 }
1035 else
1036 {
1037 DebuggerAppendMsg("Error, gDlistStackPointer overflow");
1038 RDP_GFX_PopDL();
1039 }
1040
1041 GSBlkAddrSaves[gDlistStackPointer][0]=GSBlkAddrSaves[gDlistStackPointer][1]=0;
1042 if( (dwCmd2>>24) == 0x80 )
1043 {
1044 GSBlkAddrSaves[gDlistStackPointer][0] = dwCmd2;
1045 GSBlkAddrSaves[gDlistStackPointer][1] = dwCmd3;
1046 }
1047
1048 DEBUGGER_PAUSE_AND_DUMP(NEXT_DLIST,
1049 DebuggerAppendMsg("\nPC=%08X: Call DL at Address %08X - %08X, %08X\n\n",
1050 dwPC, dwAddr, dwCmd2, dwCmd3));
1051}
1052
1053void DLParser_Ucode8_JUMP(Gfx *gfx) // DL Function Call
1054{
1055 if( ((gfx->words.w0)&0x00FFFFFF) == 0 )
1056 {
1057#ifdef DEBUGGER
1058 uint32 dwPC = gDlistStack[gDlistStackPointer].pc-8;
1059#endif
1060
1061 uint32 dwAddr = RSPSegmentAddr((gfx->words.w1));
1062
1063 if( dwAddr > g_dwRamSize )
1064 {
1065 TRACE0("DL, addr is wrong");
1066 dwAddr = (gfx->words.w1)&(g_dwRamSize-1);
1067 }
1068
1069#ifdef DEBUGGER
1070 uint32 dwCmd2 = *(uint32 *)(g_pRDRAMu8 + dwAddr);
1071 uint32 dwCmd3 = *(uint32 *)(g_pRDRAMu8 + dwAddr+4);
1072#endif
1073
1074 gDlistStack[gDlistStackPointer].pc = dwAddr+8; // Jump to new address
1075 DEBUGGER_PAUSE_AND_DUMP(NEXT_DLIST,
1076 DebuggerAppendMsg("\nPC=%08X: Jump to Address %08X - %08X, %08X\n\n", dwPC, dwAddr, dwCmd2, dwCmd3));
1077 }
1078 else
1079 {
1080 uint32 dwPC = gDlistStack[gDlistStackPointer].pc-8;
1081 LOG_UCODE("ucode 0x07 at PC=%08X: 0x%08x 0x%08x\n", dwPC, (gfx->words.w0), (gfx->words.w1));
1082 }
1083}
1084
1085void DLParser_Ucode8_Unknown(Gfx *gfx)
1086{
1087 uint32 dwPC = gDlistStack[gDlistStackPointer].pc-8;
1088 LOG_UCODE("ucode %02X at PC=%08X: 0x%08x 0x%08x\n", ((gfx->words.w0)>>24), dwPC, (gfx->words.w0), (gfx->words.w1));
1089}
1090
1091void DLParser_Unknown_Skip1(Gfx *gfx)
1092{
1093 uint32 dwPC = gDlistStack[gDlistStackPointer].pc-8;
1094 LOG_UCODE("ucode %02X, skip 1", ((gfx->words.w0)>>24));
1095 gfx++;
1096 LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x", dwPC, (gfx->words.w0), (gfx->words.w1));
1097 dwPC+=8;
1098 gfx++;
1099 LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x\n", dwPC, (gfx->words.w0), (gfx->words.w1));
1100 gDlistStack[gDlistStackPointer].pc += 8;
1101}
1102
1103void DLParser_Unknown_Skip2(Gfx *gfx)
1104{
1105 uint32 dwPC = gDlistStack[gDlistStackPointer].pc-8;
1106 LOG_UCODE("ucode %02X, skip 2", ((gfx->words.w0)>>24));
1107 gfx++;
1108 LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x", dwPC, (gfx->words.w0), (gfx->words.w1));
1109 dwPC+=8;
1110 gfx++;
1111 LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x", dwPC, (gfx->words.w0), (gfx->words.w1));
1112 dwPC+=8;
1113 gfx++;
1114 LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x\n", dwPC, (gfx->words.w0), (gfx->words.w1));
1115 gDlistStack[gDlistStackPointer].pc += 16;
1116}
1117
1118void DLParser_Unknown_Skip3(Gfx *gfx)
1119{
1120 uint32 dwPC = gDlistStack[gDlistStackPointer].pc-8;
1121 LOG_UCODE("ucode %02X, skip 3", ((gfx->words.w0)>>24));
1122 gfx++;
1123 LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x", dwPC, (gfx->words.w0), (gfx->words.w1));
1124 dwPC+=8;
1125 gfx++;
1126 LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x", dwPC, (gfx->words.w0), (gfx->words.w1));
1127 dwPC+=8;
1128 gfx++;
1129 LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x", dwPC, (gfx->words.w0), (gfx->words.w1));
1130 dwPC+=8;
1131 gfx++;
1132 LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x\n", dwPC, (gfx->words.w0), (gfx->words.w1));
1133 gDlistStack[gDlistStackPointer].pc += 24;
1134}
1135
1136void DLParser_Unknown_Skip4(Gfx *gfx)
1137{
1138 uint32 dwPC = gDlistStack[gDlistStackPointer].pc-8;
1139 LOG_UCODE("ucode %02X, skip 4", ((gfx->words.w0)>>24));
1140 gfx++;
1141 LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x", dwPC, (gfx->words.w0), (gfx->words.w1));
1142 dwPC+=8;
1143 gfx++;
1144 LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x", dwPC, (gfx->words.w0), (gfx->words.w1));
1145 dwPC+=8;
1146 gfx++;
1147 LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x", dwPC, (gfx->words.w0), (gfx->words.w1));
1148 dwPC+=8;
1149 gfx++;
1150 LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x", dwPC, (gfx->words.w0), (gfx->words.w1));
1151 dwPC+=8;
1152 gfx++;
1153 LOG_UCODE("\tPC=%08X: 0x%08x 0x%08x\n", dwPC, (gfx->words.w0), (gfx->words.w1));
1154 gDlistStack[gDlistStackPointer].pc += 32;
1155}
1156
1157void DLParser_Ucode8_0x05(Gfx *gfx)
1158{
1159 // Be careful, 0x05 is variable length ucode
1160 /*
1161 0028E4E0: 05020088, 04D0000F - Reserved1
1162 0028E4E8: 6BDC0306, 00000000 - G_NOTHING
1163 0028E4F0: 05010130, 01B0000F - Reserved1
1164 0028E4F8: 918A01CA, 1EC5FF3B - G_NOTHING
1165 0028E500: 05088C68, F5021809 - Reserved1
1166 0028E508: 04000405, 00000000 - RSP_VTX
1167 0028E510: 102ECE60, 202F2AA0 - G_NOTHING
1168 0028E518: 05088C90, F5021609 - Reserved1
1169 0028E520: 04050405, F0F0F0F0 - RSP_VTX
1170 0028E528: 102ED0C0, 202F2D00 - G_NOTHING
1171 0028E530: B5000000, 00000000 - RSP_LINE3D
1172 0028E538: 8028E640, 8028E430 - G_NOTHING
1173 0028E540: 00000000, 00000000 - RSP_SPNOOP
1174 */
1175
1176 if((gfx->words.w1) == 0)
1177 return;
1178 else
1179 DLParser_Unknown_Skip4(gfx);
1180}
1181
1182void DLParser_Ucode8_0xb4(Gfx *gfx)
1183{
1184#ifdef DEBUGGER
1185 uint32 dwPC = gDlistStack[gDlistStackPointer].pc;
1186#endif
1187
1188 if(((gfx->words.w0)&0xFF) == 0x06)
1189 DLParser_Unknown_Skip3(gfx);
1190 else if(((gfx->words.w0)&0xFF) == 0x04)
1191 DLParser_Unknown_Skip1(gfx);
1192 else if(((gfx->words.w0)&0xFFF) == 0x600)
1193 DLParser_Unknown_Skip3(gfx);
1194 else
1195 {
1196#ifdef DEBUGGER
1197 if(pauseAtNext)
1198 {
1199 DebuggerAppendMsg("ucode 0xb4 at PC=%08X: 0x%08x 0x%08x\n", dwPC-8,
1200 (gfx->words.w0), (gfx->words.w1));
1201 }
1202#endif
1203 DLParser_Unknown_Skip3(gfx);
1204 }
1205}
1206
1207void DLParser_Ucode8_0xb5(Gfx *gfx)
1208{
1209 uint32 dwPC = gDlistStack[gDlistStackPointer].pc-8;
1210 LOG_UCODE("ucode 0xB5 at PC=%08X: 0x%08x 0x%08x\n", dwPC-8, (gfx->words.w0), (gfx->words.w1));
1211
1212 uint32 dwCmd2 = *(uint32 *)(g_pRDRAMu8 + dwPC+8);
1213 uint32 dwCmd3 = *(uint32 *)(g_pRDRAMu8 + dwPC+12);
1214 LOG_UCODE(" : 0x%08x 0x%08x\n", dwCmd2, dwCmd3);
1215
1216 //if( dwCmd2 == 0 && dwCmd3 == 0 )
1217 {
1218 DLParser_Ucode8_EndDL(gfx); // Check me
1219 return;
1220 }
1221
1222 gDlistStack[gDlistStackPointer].pc += 8;
1223 return;
1224
1225
1226 if( GSBlkAddrSaves[gDlistStackPointer][0] == 0 || GSBlkAddrSaves[gDlistStackPointer][1] == 0 )
1227 {
1228#ifdef DEBUGGER
1229 if( pauseAtNext && eventToPause == NEXT_DLIST)
1230 {
1231 DebuggerAppendMsg("PC=%08X: 0xB5 - %08X : %08X, %08X, EndDL, no next blk\n", dwPC, (gfx->words.w1), dwCmd2, dwCmd3);
1232 }
1233#endif
1234 DLParser_Ucode8_EndDL(gfx); // Check me
1235 return;
1236 }
1237
1238 if( ((dwCmd2>>24)!=0x80 && (dwCmd2>>24)!=0x00 ) || ((dwCmd3>>24)!=0x80 && (dwCmd3>>24)!=0x00 ) )
1239 {
1240#ifdef DEBUGGER
1241 if( pauseAtNext && eventToPause == NEXT_DLIST)
1242 {
1243 DebuggerAppendMsg("PC=%08X: 0xB5 - %08X : %08X, %08X, EndDL, Unknown\n", dwPC, (gfx->words.w1), dwCmd2, dwCmd3);
1244 }
1245#endif
1246 DLParser_Ucode8_EndDL(gfx); // Check me
1247 return;
1248 }
1249
1250 if( (dwCmd2>>24)!= (dwCmd3>>24) )
1251 {
1252#ifdef DEBUGGER
1253 if( pauseAtNext && eventToPause == NEXT_DLIST)
1254 {
1255 DebuggerAppendMsg("PC=%08X: 0xB5 - %08X : %08X, %08X, EndDL, Unknown\n", dwPC, (gfx->words.w1), dwCmd2, dwCmd3);
1256 }
1257#endif
1258 DLParser_Ucode8_EndDL(gfx); // Check me
1259 return;
1260 }
1261
1262
1263 if( (dwCmd2>>24)==0x80 && (dwCmd3>>24)==0x80 )
1264 {
1265 if( dwCmd2 < dwCmd3 )
1266 {
1267 // All right, the next block is not ucode, but data
1268#ifdef DEBUGGER
1269 if( pauseAtNext && eventToPause == NEXT_DLIST)
1270 {
1271 DebuggerAppendMsg("PC=%08X: 0xB5 - %08X : %08X, %08X, EndDL, next blk is data\n", dwPC, (gfx->words.w1), dwCmd2, dwCmd3);
1272 }
1273#endif
1274 DLParser_Ucode8_EndDL(gfx); // Check me
1275 return;
1276 }
1277
1278 uint32 dwCmd4 = *(uint32 *)(g_pRDRAMu8 + (dwCmd2&0x00FFFFFF));
1279 uint32 dwCmd5 = *(uint32 *)(g_pRDRAMu8 + (dwCmd2&0x00FFFFFF)+4);
1280 uint32 dwCmd6 = *(uint32 *)(g_pRDRAMu8 + (dwCmd3&0x00FFFFFF));
1281 uint32 dwCmd7 = *(uint32 *)(g_pRDRAMu8 + (dwCmd3&0x00FFFFFF)+4);
1282 if( (dwCmd4>>24) != 0x80 || (dwCmd5>>24) != 0x80 || (dwCmd6>>24) != 0x80 || (dwCmd7>>24) != 0x80 || dwCmd4 < dwCmd5 || dwCmd6 < dwCmd7 )
1283 {
1284 // All right, the next block is not ucode, but data
1285#ifdef DEBUGGER
1286 if( pauseAtNext && eventToPause == NEXT_DLIST)
1287 {
1288 DebuggerAppendMsg("PC=%08X: 0xB5 - %08X : %08X, %08X, EndDL, next blk is data\n", dwPC, (gfx->words.w1), dwCmd2, dwCmd3);
1289 DebuggerAppendMsg("%08X, %08X %08X,%08X\n", dwCmd4, dwCmd5, dwCmd6, dwCmd7);
1290 }
1291#endif
1292 DLParser_Ucode8_EndDL(gfx); // Check me
1293 return;
1294 }
1295
1296 gDlistStack[gDlistStackPointer].pc += 8;
1297 DEBUGGER_PAUSE_AND_DUMP(NEXT_DLIST,
1298 DebuggerAppendMsg("PC=%08X: 0xB5 - %08X : %08X, %08X, continue\n", dwPC, (gfx->words.w1), dwCmd2, dwCmd3);
1299 );
1300 return;
1301 }
1302 else if( (dwCmd2>>24)==0x00 && (dwCmd3>>24)==0x00 )
1303 {
1304#ifdef DEBUGGER
1305 if( pauseAtNext && eventToPause == NEXT_DLIST)
1306 {
1307 DebuggerAppendMsg("PC=%08X: 0xB5 - %08X : %08X, %08X, EndDL, next blk is data\n", dwPC, (gfx->words.w1), dwCmd2, dwCmd3);
1308 }
1309#endif
1310 DLParser_Ucode8_EndDL(gfx); // Check me
1311 return;
1312 }
1313 else if( (dwCmd2>>24)==0x00 && (dwCmd3>>24)==0x00 )
1314 {
1315 dwCmd2 = *(uint32 *)(g_pRDRAMu8 + dwPC+16);
1316 dwCmd3 = *(uint32 *)(g_pRDRAMu8 + dwPC+20);
1317 if( (dwCmd2>>24)==0x80 && (dwCmd3>>24)==0x80 && dwCmd2 < dwCmd3 )
1318 {
1319 // All right, the next block is not ucode, but data
1320#ifdef DEBUGGER
1321 if( pauseAtNext && eventToPause == NEXT_DLIST)
1322 {
1323 DebuggerAppendMsg("PC=%08X: 0xB5 - %08X : %08X, %08X, EndDL, next blk is data\n", dwPC, (gfx->words.w1), dwCmd2, dwCmd3);
1324 }
1325#endif
1326 DLParser_Ucode8_EndDL(gfx); // Check me
1327 return;
1328 }
1329 else
1330 {
1331 gDlistStack[gDlistStackPointer].pc += 8;
1332 DEBUGGER_PAUSE_AND_DUMP(NEXT_DLIST,
1333 DebuggerAppendMsg("PC=%08X: 0xB5 - %08X : %08X, %08X, continue\n", dwPC, (gfx->words.w1), dwCmd2, dwCmd3)
1334 );
1335 return;
1336 }
1337 }
1338
1339#ifdef DEBUGGER
1340uint32 dwAddr1 = RSPSegmentAddr(dwCmd2);
1341uint32 dwAddr2 = RSPSegmentAddr(dwCmd3);
1342
1343 if( (gfx->words.w1) != 0 )
1344 {
1345 DebuggerAppendMsg("!!!! PC=%08X: 0xB5 - %08X : %08X, %08X\n", dwPC, (gfx->words.w1), dwCmd2, dwCmd3);
1346 }
1347#endif
1348
1349 DEBUGGER_PAUSE_AND_DUMP(NEXT_DLIST,
1350 DebuggerAppendMsg("PC=%08X: 0xB5 - %08X : %08X, %08X, continue\n", dwPC, (gfx->words.w1), dwAddr1, dwAddr2)
1351 );
1352
1353 return;
1354}
1355
1356void DLParser_Ucode8_0xbc(Gfx *gfx)
1357{
1358 if( ((gfx->words.w0)&0xFFF) == 0x58C )
1359 {
1360 DLParser_Ucode8_DL(gfx);
1361 }
1362 else
1363 {
1364 uint32 dwPC = gDlistStack[gDlistStackPointer].pc-8;
1365 LOG_UCODE("ucode 0xBC at PC=%08X: 0x%08x 0x%08x\n", dwPC, (gfx->words.w0), (gfx->words.w1));
1366 }
1367}
1368
1369void DLParser_Ucode8_0xbd(Gfx *gfx)
1370{
1371 /*
1372 00359A68: BD000000, DB5B0077 - RSP_POPMTX
1373 00359A70: C8C0A000, 00240024 - RDP_TriFill
1374 00359A78: 01000100, 00000000 - RSP_MTX
1375 00359A80: BD000501, DB5B0077 - RSP_POPMTX
1376 00359A88: C8C0A000, 00240024 - RDP_TriFill
1377 00359A90: 01000100, 00000000 - RSP_MTX
1378 00359A98: BD000A02, DB5B0077 - RSP_POPMTX
1379 00359AA0: C8C0A000, 00240024 - RDP_TriFill
1380 00359AA8: 01000100, 00000000 - RSP_MTX
1381 00359AB0: BD000F04, EB6F0087 - RSP_POPMTX
1382 00359AB8: C8C0A000, 00280028 - RDP_TriFill
1383 00359AC0: 01000100, 00000000 - RSP_MTX
1384 00359AC8: BD001403, DB5B0077 - RSP_POPMTX
1385 00359AD0: C8C0A000, 00240024 - RDP_TriFill
1386 00359AD8: 01000100, 00000000 - RSP_MTX
1387 00359AE0: B5000000, 00000000 - RSP_LINE3D
1388 00359AE8: 1A000000, 16000200 - G_NOTHING
1389 */
1390
1391 if( (gfx->words.w1) != 0 )
1392 {
1393 DLParser_Unknown_Skip2(gfx);
1394 return;
1395 }
1396
1397 uint32 dwPC = gDlistStack[gDlistStackPointer].pc;
1398 LOG_UCODE("ucode 0xbd at PC=%08X: 0x%08x 0x%08x\n", dwPC-8, (gfx->words.w0), (gfx->words.w1));
1399}
1400
1401void DLParser_Ucode8_0xbf(Gfx *gfx)
1402{
1403 if( ((gfx->words.w0)&0xFF) == 0x02 )
1404 DLParser_Unknown_Skip3(gfx);
1405 else
1406 DLParser_Unknown_Skip1(gfx);
1407}
1408
1409void PD_LoadMatrix_0xb4(uint32 addr)
1410{
1411 const float fRecip = 1.0f / 65536.0f;
1412
1413 uint32 data[16];
1414 data[0] = *(uint32*)(g_pRDRAMu8+addr+4+ 0);
1415 data[1] = *(uint32*)(g_pRDRAMu8+addr+4+ 8);
1416 data[2] = *(uint32*)(g_pRDRAMu8+addr+4+16);
1417 data[3] = *(uint32*)(g_pRDRAMu8+addr+4+24);
1418
1419 data[8] = *(uint32*)(g_pRDRAMu8+addr+4+32);
1420 data[9] = *(uint32*)(g_pRDRAMu8+addr+4+40);
1421 data[10] = *(uint32*)(g_pRDRAMu8+addr+4+48);
1422 data[11] = *(uint32*)(g_pRDRAMu8+addr+4+56);
1423
1424 data[4] = *(uint32*)(g_pRDRAMu8+addr+4+ 0+64);
1425 data[5] = *(uint32*)(g_pRDRAMu8+addr+4+ 8+64);
1426 data[6] = *(uint32*)(g_pRDRAMu8+addr+4+16+64);
1427 data[7] = *(uint32*)(g_pRDRAMu8+addr+4+24+64);
1428
1429 data[12] = *(uint32*)(g_pRDRAMu8+addr+4+32+64);
1430 data[13] = *(uint32*)(g_pRDRAMu8+addr+4+40+64);
1431 data[14] = *(uint32*)(g_pRDRAMu8+addr+4+48+64);
1432 data[15] = *(uint32*)(g_pRDRAMu8+addr+4+56+64);
1433
1434
1435 for (int i = 0; i < 4; i++)
1436 {
1437 for (int j = 0; j < 4; j++)
1438 {
1439 int hi = *(short *)((unsigned char*)data + (((i<<3)+(j<<1) )^0x2));
1440 int lo = *(uint16*)((unsigned char*)data + (((i<<3)+(j<<1) + 32)^0x2));
1441 matToLoad.m[i][j] = (float)((hi<<16) | lo) * fRecip;
1442 }
1443 }
1444
1445
1446#ifdef DEBUGGER
1447 LOG_UCODE(
1448 " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\r\n"
1449 " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\r\n"
1450 " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\r\n"
1451 " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\r\n",
1452 matToLoad.m[0][0], matToLoad.m[0][1], matToLoad.m[0][2], matToLoad.m[0][3],
1453 matToLoad.m[1][0], matToLoad.m[1][1], matToLoad.m[1][2], matToLoad.m[1][3],
1454 matToLoad.m[2][0], matToLoad.m[2][1], matToLoad.m[2][2], matToLoad.m[2][3],
1455 matToLoad.m[3][0], matToLoad.m[3][1], matToLoad.m[3][2], matToLoad.m[3][3]);
1456#endif // DEBUGGER
1457}
1458
1459void DLParser_RDPHalf_1_0xb4_GoldenEye(Gfx *gfx)
1460{
1461 SP_Timing(RSP_GBI1_RDPHalf_1);
1462 if( ((gfx->words.w1)>>24) == 0xce )
1463 {
1464 PrepareTextures();
1465 CRender::g_pRender->SetCombinerAndBlender();
1466
1467 uint32 dwPC = gDlistStack[gDlistStackPointer].pc; // This points to the next instruction
1468
1469 //PD_LoadMatrix_0xb4(dwPC + 8*16 - 8);
1470
1471 uint32 dw1 = *(uint32 *)(g_pRDRAMu8 + dwPC+8*0+4);
1472 //uint32 dw2 = *(uint32 *)(g_pRDRAMu8 + dwPC+8*1+4);
1473 //uint32 dw3 = *(uint32 *)(g_pRDRAMu8 + dwPC+8*2+4);
1474 //uint32 dw4 = *(uint32 *)(g_pRDRAMu8 + dwPC+8*3+4);
1475 //uint32 dw5 = *(uint32 *)(g_pRDRAMu8 + dwPC+8*4+4);
1476 //uint32 dw6 = *(uint32 *)(g_pRDRAMu8 + dwPC+8*5+4);
1477 //uint32 dw7 = *(uint32 *)(g_pRDRAMu8 + dwPC+8*6+4);
1478 uint32 dw8 = *(uint32 *)(g_pRDRAMu8 + dwPC+8*7+4);
1479 uint32 dw9 = *(uint32 *)(g_pRDRAMu8 + dwPC+8*8+4);
1480
1481 uint32 r = (dw8>>16)&0xFF;
1482 uint32 g = (dw8 )&0xFF;
1483 uint32 b = (dw9>>16)&0xFF;
1484 uint32 a = (dw9 )&0xFF;
1485 uint32 color = COLOR_RGBA(r, g, b, a);
1486
1487 //int x0 = 0;
1488 //int x1 = gRDP.scissor.right;
1489 int x0 = gRSP.nVPLeftN;
1490 int x1 = gRSP.nVPRightN;
1491 int y0 = int(dw1&0xFFFF)/4;
1492 int y1 = int(dw1>>16)/4;
1493
1494 float xscale = g_textures[0].m_pCTexture->m_dwWidth / (float)(x1-x0);
1495 float yscale = g_textures[0].m_pCTexture->m_dwHeight / (float)(y1-y0);
1496 //float fs0 = (short)(dw3&0xFFFF)/32768.0f*g_textures[0].m_pCTexture->m_dwWidth;
1497 //float ft0 = (short)(dw3>>16)/32768.0f*256;
1498 CRender::g_pRender->TexRect(x0,y0,x1,y1,0,0,xscale,yscale,true,color);
1499
1500 gDlistStack[gDlistStackPointer].pc += 312;
1501
1502#ifdef DEBUGGER
1503 if( logUcodes)
1504 {
1505 dwPC -= 8;
1506 LOG_UCODE("GoldenEye Sky at PC=%08X: 0x%08x 0x%08x", dwPC, (gfx->words.w0), (gfx->words.w1));
1507 uint32 *ptr = (uint32 *)(g_pRDRAMu8 + dwPC);
1508 for( int i=0; i<21; i++, dwPC+=16,ptr+=4 )
1509 {
1510 LOG_UCODE("%08X: %08X %08X %08X %08X", dwPC, ptr[0], ptr[1], ptr[2], ptr[3]);
1511 }
1512 }
1513#endif
1514
1515 DEBUGGER_PAUSE_AND_DUMP_COUNT_N(NEXT_FLUSH_TRI, {
1516 TRACE0("Pause after Golden Sky Drawing\n");
1517 });
1518 }
1519}
1520
1521void DLParser_RSP_DL_WorldDriver(Gfx *gfx)
1522{
1523 uint32 dwAddr = RSPSegmentAddr((gfx->words.w1));
1524 if( dwAddr > g_dwRamSize )
1525 {
1526 RSP_RDP_NOIMPL("Error: DL addr = %08X out of range, PC=%08X", dwAddr, gDlistStack[gDlistStackPointer].pc );
1527 dwAddr &= (g_dwRamSize-1);
1528 DebuggerPauseCountN( NEXT_DLIST );
1529 }
1530
1531 LOG_UCODE(" WorldDriver DisplayList 0x%08x", dwAddr);
1532 gDlistStackPointer++;
1533 gDlistStack[gDlistStackPointer].pc = dwAddr;
1534 gDlistStack[gDlistStackPointer].countdown = MAX_DL_COUNT;
1535
1536 LOG_UCODE("Level=%d", gDlistStackPointer+1);
1537 LOG_UCODE("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
1538}
1539
1540void DLParser_RSP_Pop_DL_WorldDriver(Gfx *gfx)
1541{
1542 RDP_GFX_PopDL();
1543}
1544
1545void DLParser_RSP_Last_Legion_0x80(Gfx *gfx)
1546{
1547 gDlistStack[gDlistStackPointer].pc += 16;
1548 LOG_UCODE("DLParser_RSP_Last_Legion_0x80");
1549}
1550
1551void DLParser_RSP_Last_Legion_0x00(Gfx *gfx)
1552{
1553 LOG_UCODE("DLParser_RSP_Last_Legion_0x00");
1554 gDlistStack[gDlistStackPointer].pc += 16;
1555
1556 if( (gfx->words.w0) == 0 && (gfx->words.w1) )
1557 {
1558 uint32 newaddr = RSPSegmentAddr((gfx->words.w1));
1559 if( newaddr >= g_dwRamSize )
1560 {
1561 RDP_GFX_PopDL();
1562 return;
1563 }
1564
1565 //uint32 dw1 = *(uint32 *)(g_pRDRAMu8 + newaddr+8*0+4);
1566 uint32 pc1 = *(uint32 *)(g_pRDRAMu8 + newaddr+8*1+4);
1567 uint32 pc2 = *(uint32 *)(g_pRDRAMu8 + newaddr+8*4+4);
1568 pc1 = RSPSegmentAddr(pc1);
1569 pc2 = RSPSegmentAddr(pc2);
1570
1571 if( pc1 && pc1 != 0xffffff && pc1 < g_dwRamSize)
1572 {
1573 // Need to call both DL
1574 gDlistStackPointer++;
1575 gDlistStack[gDlistStackPointer].pc = pc1;
1576 gDlistStack[gDlistStackPointer].countdown = MAX_DL_COUNT;
1577 }
1578
1579 if( pc2 && pc2 != 0xffffff && pc2 < g_dwRamSize )
1580 {
1581 gDlistStackPointer++;
1582 gDlistStack[gDlistStackPointer].pc = pc2;
1583 gDlistStack[gDlistStackPointer].countdown = MAX_DL_COUNT;
1584 }
1585 }
1586 else if( (gfx->words.w1) == 0 )
1587 {
1588 RDP_GFX_PopDL();
1589 }
1590 else
1591 {
1592 // (gfx->words.w0) != 0
1593 RSP_RDP_Nothing(gfx);
1594 RDP_GFX_PopDL();
1595 }
1596}
1597
1598void DLParser_TexRect_Last_Legion(Gfx *gfx)
1599{
1600 if( !status.bCIBufferIsRendered )
1601 g_pFrameBufferManager->ActiveTextureBuffer();
1602
1603 status.primitiveType = PRIM_TEXTRECT;
1604
1605 // This command used 128bits, and not 64 bits. This means that we have to look one
1606 // Command ahead in the buffer, and update the PC.
1607 uint32 dwPC = gDlistStack[gDlistStackPointer].pc; // This points to the next instruction
1608 uint32 dwCmd2 = *(uint32 *)(g_pRDRAMu8 + dwPC);
1609 uint32 dwCmd3 = *(uint32 *)(g_pRDRAMu8 + dwPC+4);
1610
1611 gDlistStack[gDlistStackPointer].pc += 8;
1612
1613
1614 LOG_UCODE("0x%08x: %08x %08x", dwPC, *(uint32 *)(g_pRDRAMu8 + dwPC+0), *(uint32 *)(g_pRDRAMu8 + dwPC+4));
1615
1616 uint32 dwXH = (((gfx->words.w0)>>12)&0x0FFF)/4;
1617 uint32 dwYH = (((gfx->words.w0) )&0x0FFF)/4;
1618 uint32 tileno = ((gfx->words.w1)>>24)&0x07;
1619 uint32 dwXL = (((gfx->words.w1)>>12)&0x0FFF)/4;
1620 uint32 dwYL = (((gfx->words.w1) )&0x0FFF)/4;
1621
1622
1623 if( (int)dwXL >= gRDP.scissor.right || (int)dwYL >= gRDP.scissor.bottom || (int)dwXH < gRDP.scissor.left || (int)dwYH < gRDP.scissor.top )
1624 {
1625 // Clipping
1626 return;
1627 }
1628
1629 uint16 uS = (uint16)( dwCmd2>>16)&0xFFFF;
1630 uint16 uT = (uint16)( dwCmd2 )&0xFFFF;
1631 short s16S = *(short*)(&uS);
1632 short s16T = *(short*)(&uT);
1633
1634 uint16 uDSDX = (uint16)(( dwCmd3>>16)&0xFFFF);
1635 uint16 uDTDY = (uint16)(( dwCmd3 )&0xFFFF);
1636 short s16DSDX = *(short*)(&uDSDX);
1637 short s16DTDY = *(short*)(&uDTDY);
1638
1639 uint32 curTile = gRSP.curTile;
1640 ForceMainTextureIndex(tileno);
1641
1642 float fS0 = s16S / 32.0f;
1643 float fT0 = s16T / 32.0f;
1644
1645 float fDSDX = s16DSDX / 1024.0f;
1646 float fDTDY = s16DTDY / 1024.0f;
1647
1648 uint32 cycletype = gRDP.otherMode.cycle_type;
1649
1650 if (cycletype == CYCLE_TYPE_COPY)
1651 {
1652 fDSDX /= 4.0f; // In copy mode 4 pixels are copied at once.
1653 dwXH++;
1654 dwYH++;
1655 }
1656 else if (cycletype == CYCLE_TYPE_FILL)
1657 {
1658 dwXH++;
1659 dwYH++;
1660 }
1661
1662 if( fDSDX == 0 ) fDSDX = 1;
1663 if( fDTDY == 0 ) fDTDY = 1;
1664
1665 float fS1 = fS0 + (fDSDX * (dwXH - dwXL));
1666 float fT1 = fT0 + (fDTDY * (dwYH - dwYL));
1667
1668 LOG_UCODE(" Tile:%d Screen(%d,%d) -> (%d,%d)", tileno, dwXL, dwYL, dwXH, dwYH);
1669 LOG_UCODE(" Tex:(%#5f,%#5f) -> (%#5f,%#5f) (DSDX:%#5f DTDY:%#5f)",
1670 fS0, fT0, fS1, fT1, fDSDX, fDTDY);
1671 LOG_UCODE("");
1672
1673 float t0u0 = (fS0-gRDP.tiles[tileno].hilite_sl) * gRDP.tiles[tileno].fShiftScaleS;
1674 float t0v0 = (fT0-gRDP.tiles[tileno].hilite_tl) * gRDP.tiles[tileno].fShiftScaleT;
1675 float t0u1 = t0u0 + (fDSDX * (dwXH - dwXL))*gRDP.tiles[tileno].fShiftScaleS;
1676 float t0v1 = t0v0 + (fDTDY * (dwYH - dwYL))*gRDP.tiles[tileno].fShiftScaleT;
1677
1678 if( dwXL==0 && dwYL==0 && dwXH==windowSetting.fViWidth-1 && dwYH==windowSetting.fViHeight-1 &&
1679 t0u0 == 0 && t0v0==0 && t0u1==0 && t0v1==0 )
1680 {
1681 //Using TextRect to clear the screen
1682 }
1683 else
1684 {
1685 if( status.bHandleN64RenderTexture && //status.bDirectWriteIntoRDRAM &&
1686 g_pRenderTextureInfo->CI_Info.dwFormat == gRDP.tiles[tileno].dwFormat &&
1687 g_pRenderTextureInfo->CI_Info.dwSize == gRDP.tiles[tileno].dwSize &&
1688 gRDP.tiles[tileno].dwFormat == TXT_FMT_CI && gRDP.tiles[tileno].dwSize == TXT_SIZE_8b )
1689 {
1690 if( options.enableHackForGames == HACK_FOR_YOSHI )
1691 {
1692 // Hack for Yoshi background image
1693 PrepareTextures();
1694 TexRectToFrameBuffer_8b(dwXL, dwYL, dwXH, dwYH, t0u0, t0v0, t0u1, t0v1, tileno);
1695 DEBUGGER_PAUSE_AT_COND_AND_DUMP_COUNT_N((eventToPause == NEXT_FLUSH_TRI || eventToPause == NEXT_TEXTRECT), {
1696 DebuggerAppendMsg("TexRect: tile=%d, X0=%d, Y0=%d, X1=%d, Y1=%d,\nfS0=%f, fT0=%f, ScaleS=%f, ScaleT=%f\n",
1697 gRSP.curTile, dwXL, dwYL, dwXH, dwYH, fS0, fT0, fDSDX, fDTDY);
1698 DebuggerAppendMsg("Pause after TexRect for Yoshi\n");
1699 });
1700 }
1701 else
1702 {
1703 if( frameBufferOptions.bUpdateCIInfo )
1704 {
1705 PrepareTextures();
1706 TexRectToFrameBuffer_8b(dwXL, dwYL, dwXH, dwYH, t0u0, t0v0, t0u1, t0v1, tileno);
1707 }
1708
1709 if( !status.bDirectWriteIntoRDRAM )
1710 {
1711 CRender::g_pRender->TexRect(dwXL, dwYL, dwXH, dwYH, fS0, fT0, fDSDX, fDTDY);
1712
1713 status.dwNumTrisRendered += 2;
1714 }
1715 }
1716 }
1717 else
1718 {
1719 CRender::g_pRender->TexRect(dwXL, dwYL, dwXH, dwYH, fS0, fT0, fDSDX, fDTDY);
1720 status.bFrameBufferDrawnByTriangles = true;
1721
1722 status.dwNumTrisRendered += 2;
1723 }
1724 }
1725
1726 if( status.bHandleN64RenderTexture )
1727 g_pRenderTextureInfo->maxUsedHeight = max(g_pRenderTextureInfo->maxUsedHeight,(int)dwYH);
1728
1729 ForceMainTextureIndex(curTile);
1730}
1731