2 Copyright (C) 2002 Rice1964
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 #include "osal_opengl.h"
22 #include "FrameBuffer.h"
25 extern uObjMtxReal gObjMtxReal;
26 extern Matrix g_MtxReal;
28 //========================================================================
30 void CRender::LoadFrameBuffer(bool useVIreg, uint32 left, uint32 top, uint32 width, uint32 height)
32 uint32 VIwidth = *g_GraphicsInfo.VI_WIDTH_REG;
36 gti.clampS = gti.clampT = 0;
37 gti.maskS = gti.maskT = gti.mirrorS = gti.mirrorT = 0;
38 gti.TLutFmt = TLUT_FMT_RGBA16; //RGBA16
42 if( useVIreg && *g_GraphicsInfo.VI_ORIGIN_REG > VIwidth*2 )
47 gti.Address = (*g_GraphicsInfo.VI_ORIGIN_REG & (g_dwRamSize-1) ) - VIwidth*2;
51 gti.PalAddress = (uchar *) &g_wRDPTlut[0];
53 gti.WidthToCreate = windowSetting.uViWidth;;
54 gti.HeightToCreate = windowSetting.uViHeight;
56 if( gti.WidthToCreate == 0 || gti.HeightToCreate == 0 )
58 TRACE0("Loading frame buffer: size = 0 x 0");
62 gti.Pitch = VIwidth << gti.Size >> 1;
66 gti.Format = g_CI.dwFormat;
67 gti.Size = g_CI.dwSize;
68 gti.PalAddress = (uchar *) &g_wRDPTlut[0];
70 gti.Address = RSPSegmentAddr(g_CI.dwAddr);
72 if( width == 0 || height == 0 )
77 gti.WidthToCreate = g_CI.dwWidth;
78 gti.HeightToCreate = g_CI.dwWidth*3/4;
82 gti.LeftToLoad = left;
85 gti.WidthToCreate = width;
86 gti.HeightToCreate = height;
89 if( gti.Size == TXT_SIZE_4b )
91 gti.Pitch = g_CI.dwWidth >> 1;
95 gti.Pitch = g_CI.dwWidth << (gti.Size-1);
100 if( gti.Address + gti.Pitch*gti.HeightToCreate > g_dwRamSize )
102 TRACE0("Skip frame buffer loading, memory out of bound");
109 DebuggerAppendMsg("Load Frame Buffer Imag at: %08X, (%d, %d) - (%d, %d)", gti.Address,
110 gti.LeftToLoad, gti.TopToLoad, gti.WidthToCreate, gti.HeightToCreate );
115 gti.HeightToLoad = gti.HeightToCreate;
116 gti.WidthToLoad = gti.WidthToCreate;
118 gti.pPhysicalAddress = ((uint8*)g_pRDRAMu32)+gti.Address;
120 TxtrCacheEntry *pEntry = gTextureManager.GetTexture(>i, false, true, false);
121 if( pEntry ) SetCurrentTexture( 0, pEntry->pTexture, pEntry->ti.WidthToCreate, pEntry->ti.HeightToCreate, pEntry);
124 void CRender::LoadTextureFromMemory(void *buf, uint32 left, uint32 top, uint32 width, uint32 height, uint32 pitch, uint32 format)
127 gti.Format = g_CI.dwFormat;
128 gti.Size = g_CI.dwSize;
130 gti.TLutFmt = TLUT_FMT_RGBA16; //RGBA16
132 gti.bSwapped = FALSE;
136 gti.WidthToCreate = width;
137 gti.HeightToCreate = height;
141 gti.HeightToLoad = height;
142 gti.WidthToLoad = width;
143 gti.pPhysicalAddress = (uint8*)buf;
146 TxtrCacheEntry *pEntry = gTextureManager.GetTexture(>i, false);
147 //Upto here, the texture is loaded wrong because the format is wrong
150 if( pEntry->pTexture->StartUpdate(&info) )
152 for( uint32 i=0; i<height; i++)
154 uint32 *psrc = (uint32*)((uint8*)buf+pitch*(i+top))+left;
155 uint32 *pdst = (uint32*)((uint8*)info.lpSurface+i*info.lPitch);
156 for( uint32 j=0; j<width; j++)
161 pEntry->pTexture->EndUpdate(&info);
163 SetCurrentTexture( 0, pEntry->pTexture, width, height, pEntry);
166 void CRender::LoadObjBGCopy(uObjBg &info)
169 gti.Format = info.imageFmt;
170 gti.Size = info.imageSiz;
171 gti.Address = RSPSegmentAddr(info.imagePtr);
174 gti.Palette = info.imagePal;
176 gti.PalAddress = (uchar *) &g_wRDPTlut[0];
177 gti.bSwapped = FALSE;
178 gti.TLutFmt = TLUT_FMT_RGBA16; //RGBA16
180 gti.WidthToCreate = info.imageW/4;
181 gti.HeightToCreate = info.imageH/4;
183 if( options.bEnableHacks )
185 if( g_CI.dwWidth == 0x200 && gti.Format == g_CI.dwFormat && gti.Size == g_CI.dwSize &&
186 gti.WidthToCreate == 0x200 )
189 uint32 w = *g_GraphicsInfo.VI_WIDTH_REG & 0xFFF;
190 gti.HeightToCreate = (gti.WidthToCreate*gti.HeightToCreate)/w;
191 gti.WidthToCreate = w;
195 gti.Pitch = gti.WidthToCreate << gti.Size >> 1;
196 gti.Pitch = (gti.Pitch>>3)<<3; // Align to 8 bytes
198 if( gti.Address + gti.Pitch*gti.HeightToCreate > g_dwRamSize )
200 TRACE0("Skip BG copy loading, memory out of bound");
204 gti.HeightToLoad = gti.HeightToCreate;
205 gti.WidthToLoad = gti.WidthToCreate;
206 gti.pPhysicalAddress = ((uint8*)g_pRDRAMu32)+gti.Address;
208 TxtrCacheEntry *pEntry = gTextureManager.GetTexture(>i, false);
209 SetCurrentTexture(0,pEntry);
211 DEBUGGER_IF_DUMP((pauseAtNext && (eventToPause == NEXT_OBJ_TXT_CMD||eventToPause == NEXT_FLUSH_TRI||eventToPause == NEXT_OBJ_BG)),
213 TRACE0("Load Obj BG Copy:\n");
214 DebuggerAppendMsg("Addr=0x%08X, W=%d, H=%d, Left=%d, Top=%d\n",
215 gti.Address, gti.WidthToCreate, gti.HeightToCreate, gti.LeftToLoad, gti.TopToLoad);
216 DebuggerAppendMsg("Fmt=%s-%db, Pal=%d\n",
217 pszImgFormat[gti.Format], pnImgSize[gti.Size], gti.Palette);
222 void CRender::LoadTxtrBufIntoTexture(void)
226 gti.Format = g_pRenderTextureInfo->CI_Info.dwFormat;
227 gti.Size = g_pRenderTextureInfo->CI_Info.dwSize;
229 gti.Address = RSPSegmentAddr(g_pRenderTextureInfo->CI_Info.dwAddr);
234 gti.PalAddress = (uchar *) &g_wRDPTlut[0];
235 gti.bSwapped = FALSE;
237 gti.WidthToCreate = g_pRenderTextureInfo->N64Width;
238 gti.HeightToCreate = g_pRenderTextureInfo->N64Height;
239 gti.TLutFmt = TLUT_FMT_RGBA16; //RGBA16
241 gti.Pitch = gti.WidthToCreate << (gti.Size-1);
243 gti.HeightToLoad = gti.HeightToCreate;
244 gti.WidthToLoad = gti.WidthToCreate;
245 gti.pPhysicalAddress = ((uint8*)g_pRDRAMu32)+gti.Address;
247 TxtrCacheEntry *pEntry = gTextureManager.GetTexture(>i, false);
248 SetCurrentTexture(0,pEntry);
251 void CRender::LoadSprite2D(Sprite2DInfo &info, uint32 ucode)
255 gti.Format = info.spritePtr->SourceImageType;
256 gti.Size = info.spritePtr->SourceImageBitSize;
258 gti.Address = RSPSegmentAddr(info.spritePtr->SourceImagePointer);
260 gti.PalAddress = (uchar *) (g_pRDRAMu8 + RSPSegmentAddr(info.spritePtr->TlutPointer));
262 if( options.enableHackForGames == HACK_FOR_NITRO )
264 gti.WidthToCreate = (uint32)(info.spritePtr->SubImageWidth/info.scaleX);
265 gti.HeightToCreate = (uint32)(info.spritePtr->SubImageHeight/info.scaleY);
266 gti.LeftToLoad = (uint32)(info.spritePtr->SourceImageOffsetS/info.scaleX);
267 gti.TopToLoad = (uint32)(info.spritePtr->SourceImageOffsetT/info.scaleY);
268 gti.Pitch = info.spritePtr->Stride << gti.Size >> 1;
269 gti.Pitch = (uint32)(gti.Pitch*info.scaleY);
273 gti.WidthToCreate = info.spritePtr->SubImageWidth;
274 gti.HeightToCreate = info.spritePtr->SubImageHeight;
275 gti.LeftToLoad = info.spritePtr->SourceImageOffsetS;
276 gti.TopToLoad = info.spritePtr->SourceImageOffsetT;
277 gti.Pitch = info.spritePtr->Stride << gti.Size >> 1;
280 if( gti.Address + gti.Pitch*gti.HeightToCreate > g_dwRamSize )
282 TRACE0("Skip Sprite image decompress, memory out of bound");
286 gti.HeightToLoad = gti.HeightToCreate;
287 gti.WidthToLoad = gti.WidthToCreate;
289 gti.TLutFmt = TLUT_FMT_RGBA16; //RGBA16
290 gti.bSwapped = FALSE;
292 gti.pPhysicalAddress = ((uint8*)g_pRDRAMu32)+gti.Address;
294 TxtrCacheEntry *pEntry = gTextureManager.GetTexture(>i, false);
295 SetCurrentTexture(0,pEntry);
297 DEBUGGER_IF_DUMP((pauseAtNext && (eventToPause == NEXT_OBJ_TXT_CMD||eventToPause == NEXT_FLUSH_TRI||eventToPause == NEXT_SPRITE_2D)),
299 TRACE0("Load Sprite 2D\n");
300 DebuggerAppendMsg("Addr=0x%08X, W=%d, H=%d, Left=%d, Top=%d\n",
301 gti.Address, gti.WidthToCreate, gti.HeightToCreate, gti.LeftToLoad, gti.TopToLoad);
302 DebuggerAppendMsg("Fmt=%s-%db, Pal=%d, Pitch=%d\n",
303 pszImgFormat[gti.Format], pnImgSize[gti.Size], gti.Palette, gti.Pitch);
309 void CRender::DrawSprite2D(Sprite2DInfo &info, uint32 ucode)
311 if( !status.bCIBufferIsRendered ) g_pFrameBufferManager->ActiveTextureBuffer();
313 if( status.bHandleN64RenderTexture )
315 g_pRenderTextureInfo->maxUsedHeight = g_pRenderTextureInfo->N64Height;
316 if( !status.bDirectWriteIntoRDRAM )
318 status.bFrameBufferIsDrawn = true;
319 status.bFrameBufferDrawnByTriangles = true;
322 LoadSprite2D(info, ucode);
324 info.scaleX = 1/info.scaleX;
325 info.scaleY = 1/info.scaleY;
328 float t0, s0, t1, s1;
332 //x0 = info.px*info.scaleX + info.spritePtr->SubImageWidth*info.scaleX;
333 //x1 = info.px*info.scaleX;
334 x0 = info.px + int(info.spritePtr->SubImageWidth*info.scaleX);
339 //x0 = info.px*info.scaleX;
340 //x1 = info.px*info.scaleX + info.spritePtr->SubImageWidth*info.scaleX;
342 x1 = info.px + int(info.spritePtr->SubImageWidth*info.scaleX);
347 //y0 = info.py*info.scaleY + info.spritePtr->SubImageHeight*info.scaleY;
348 //y1 = info.py*info.scaleY;
349 y0 = info.py + int(info.spritePtr->SubImageHeight*info.scaleY);
354 //y0 = info.py*info.scaleY;
355 //y1 = info.py*info.scaleY + info.spritePtr->SubImageHeight*info.scaleY;
357 y1 = info.py + int(info.spritePtr->SubImageHeight*info.scaleY);
361 if( options.enableHackForGames == HACK_FOR_NITRO )
363 t1 = info.spritePtr->SubImageWidth*info.scaleX/g_textures[0].m_fTexWidth;
364 s1 = info.spritePtr->SubImageHeight*info.scaleY/g_textures[0].m_fTexHeight;
368 t1 = info.spritePtr->SubImageWidth/g_textures[0].m_fTexWidth;
369 s1 = info.spritePtr->SubImageHeight/g_textures[0].m_fTexHeight;
372 //InitCombinerBlenderForSimpleTextureDraw();
373 SetCombinerAndBlender();
374 SetAddressUAllStages( 0, TEXTURE_UV_FLAG_CLAMP );
375 SetAddressVAllStages( 0, TEXTURE_UV_FLAG_CLAMP );
377 COLOR speColor = PostProcessSpecularColor();
378 COLOR difColor = PostProcessDiffuseColor(0xffffffff);
380 float depth = ( gRDP.otherMode.depth_source == 1 ) ? gRDP.fPrimitiveDepth : 0;
381 DrawSimple2DTexture((float)x0, (float)y0, (float)x1, (float)y1, t0, s0, t1, s1, speColor, difColor, depth, 1.0f);
385 void CRender::DrawSpriteR(uObjTxSprite &sprite, bool initCombiner, uint32 tile, uint32 left, uint32 top, uint32 width, uint32 height) // With Rotation
387 if( !status.bCIBufferIsRendered ) g_pFrameBufferManager->ActiveTextureBuffer();
389 if( status.bHandleN64RenderTexture )
391 g_pRenderTextureInfo->maxUsedHeight = g_pRenderTextureInfo->N64Height;
392 if( !status.bDirectWriteIntoRDRAM )
394 status.bFrameBufferIsDrawn = true;
395 status.bFrameBufferDrawnByTriangles = true;
398 SetCombinerAndBlender();
400 float scaleX = sprite.sprite.scaleW/1024.0f;
401 float scaleY = sprite.sprite.scaleH/1024.0f;
403 if( width == 0 || height == 0 )
405 width = g_textures[tile].m_dwTileWidth;
406 height = g_textures[tile].m_dwTileHeight;
409 //RECT src = {left,top,width, height};
411 if (gRDP.otherMode.depth_source==1)
412 depth = gRDP.fPrimitiveDepth;
414 float x0 = sprite.sprite.objX/4.0f;
415 float y0 = sprite.sprite.objY/4.0f;
416 float x1 = sprite.sprite.imageW / 32.0f / scaleX + x0;
417 float y1 = sprite.sprite.imageH / 32.0f / scaleY + y0;
419 if( sprite.sprite.imageFlags&1 ) { float temp = x0; x0 = x1; x1 = temp; } // flip X
420 if( sprite.sprite.imageFlags&0x10 ) { float temp = y0; y0 = y1; y1 = temp; } // flip Y
422 g_texRectTVtx[0].x = (gObjMtxReal.A*x0 + gObjMtxReal.B*y0 + gObjMtxReal.X)*windowSetting.fMultX;
423 g_texRectTVtx[0].y = (gObjMtxReal.C*x0 + gObjMtxReal.D*y0 + gObjMtxReal.Y)*windowSetting.fMultY;
424 g_texRectTVtx[0].z = depth;
425 g_texRectTVtx[0].rhw = 1;
426 g_texRectTVtx[1].x = (gObjMtxReal.A*x1 + gObjMtxReal.B*y0 + gObjMtxReal.X)*windowSetting.fMultX;
427 g_texRectTVtx[1].y = (gObjMtxReal.C*x1 + gObjMtxReal.D*y0 + gObjMtxReal.Y)*windowSetting.fMultY;
428 g_texRectTVtx[1].z = depth;
429 g_texRectTVtx[1].rhw = 1;
430 g_texRectTVtx[2].x = (gObjMtxReal.A*x1 + gObjMtxReal.B*y1 + gObjMtxReal.X)*windowSetting.fMultX;
431 g_texRectTVtx[2].y = (gObjMtxReal.C*x1 + gObjMtxReal.D*y1 + gObjMtxReal.Y)*windowSetting.fMultY;
432 g_texRectTVtx[2].z = depth;
433 g_texRectTVtx[2].rhw = 1;
434 g_texRectTVtx[3].x = (gObjMtxReal.A*x0 + gObjMtxReal.B*y1 + gObjMtxReal.X)*windowSetting.fMultX;
435 g_texRectTVtx[3].y = (gObjMtxReal.C*x0 + gObjMtxReal.D*y1 + gObjMtxReal.Y)*windowSetting.fMultY;
436 g_texRectTVtx[3].z = depth;
437 g_texRectTVtx[3].rhw = 1;
439 g_texRectTVtx[0].tcord[0].u = left/g_textures[tile].m_fTexWidth;
440 g_texRectTVtx[0].tcord[0].v = top/g_textures[tile].m_fTexHeight;
441 g_texRectTVtx[1].tcord[0].u = (left+width)/g_textures[tile].m_fTexWidth;
442 g_texRectTVtx[1].tcord[0].v = top/g_textures[tile].m_fTexHeight;
443 g_texRectTVtx[2].tcord[0].u = (left+width)/g_textures[tile].m_fTexWidth;
444 g_texRectTVtx[2].tcord[0].v = (top+height)/g_textures[tile].m_fTexHeight;
445 g_texRectTVtx[3].tcord[0].u = left/g_textures[tile].m_fTexWidth;
446 g_texRectTVtx[3].tcord[0].v = (top+height)/g_textures[tile].m_fTexHeight;
448 //COLOR speColor = PostProcessSpecularColor();
449 COLOR difColor = PostProcessDiffuseColor(0xffffffff);
451 g_texRectTVtx[0].dcDiffuse = g_texRectTVtx[1].dcDiffuse
452 = g_texRectTVtx[2].dcDiffuse = g_texRectTVtx[3].dcDiffuse = difColor;
453 g_texRectTVtx[0].dcSpecular = g_texRectTVtx[1].dcSpecular
454 = g_texRectTVtx[2].dcSpecular = g_texRectTVtx[3].dcSpecular = difColor;
456 DrawSpriteR_Render();
459 void CRender::DrawFrameBuffer(bool useVIreg, uint32 left, uint32 top, uint32 width, uint32 height)
463 LoadFrameBuffer(useVIreg, left, top, width, height);
465 m_pColorCombiner->InitCombinerBlenderForSimpleTextureDraw(0);
467 ZBufferEnable(FALSE);
470 SetAlphaTestEnable(FALSE);
472 SetAlphaTestEnable(TRUE); // use Alpha Test for partial frame buffer draw, for Dr. Mario 64
474 m_pAlphaBlender->Disable();
476 CTexture *pTexture = g_textures[0].m_pCTexture;
481 // Draw the whole frame buffer
482 DrawSimple2DTexture(0, 0, windowSetting.uViWidth, windowSetting.uViHeight,
483 0, 0, 1/pTexture->m_fXScale, 1/pTexture->m_fYScale, 0xFFFFFFFF, 0xFFFFFFFF, 0, 1);
487 // Draw a small texture in frame buffer
488 DrawSimple2DTexture((float)left, (float)top, (float)(left+width), (float)(top+height),
489 0, 0, 1/pTexture->m_fXScale, 1/pTexture->m_fYScale, 0xFFFFFFFF, 0xFFFFFFFF, 0, 1);
493 TXTRBUF_OR_CI_DUMP(TRACE0("Draw Frame Buffer Img"));
495 if( pauseAtNext && ( eventToPause == NEXT_FRAME || eventToPause == NEXT_FLUSH_TRI ) )
497 TRACE0("Draw Frame Buffer Img");
498 debuggerPause = true;
506 void CRender::DrawObjBGCopy(uObjBg &info)
508 if( !status.bCIBufferIsRendered ) g_pFrameBufferManager->ActiveTextureBuffer();
510 if( status.bHandleN64RenderTexture )
512 g_pRenderTextureInfo->maxUsedHeight = g_pRenderTextureInfo->N64Height;
513 if( !status.bDirectWriteIntoRDRAM )
515 status.bFrameBufferIsDrawn = true;
516 status.bFrameBufferDrawnByTriangles = true;
519 SetCombinerAndBlender();
521 uint32 frameH = info.frameH;
522 uint32 frameW = info.frameW;
523 uint32 imageH = info.imageH;
524 uint32 imageW = info.imageW;
526 if( options.bEnableHacks )
528 if( g_CI.dwWidth == 0x200 && info.imageFmt == g_CI.dwFormat && info.imageSiz == g_CI.dwSize &&
532 uint32 width = *g_GraphicsInfo.VI_WIDTH_REG & 0xFFF;
533 imageH = frameH = (frameW/4*frameH/4)/width*4;
534 imageW = frameW = width*4;
538 float x0 = info.frameX / 4.0f;
539 float y0 = info.frameY / 4.0f;
540 float x1 = frameW / 4.0f + x0;
541 float y1 = frameH / 4.0f + y0;
543 float s0 = info.imageX / 32.0f;
544 float t0 = info.imageY / 32.0f;
546 float texwidth = imageW/4.0f;
547 float texheight = imageH/4.0f;
549 float u0 = s0/g_textures[0].m_fTexWidth;
550 float v0 = t0/g_textures[0].m_fTexHeight;
551 float maxu = texwidth/g_textures[0].m_fTexWidth;
552 float maxv = texheight/g_textures[0].m_fTexHeight;
554 float x2 = x0 + (texwidth-s0);
555 float y2 = y0 + (texheight-t0);
556 float u1 = (x1-x2)/g_textures[0].m_fTexWidth;
557 float v1 = (y1-y2)/g_textures[0].m_fTexHeight;
559 float depth = (gRDP.otherMode.depth_source == 1 ? gRDP.fPrimitiveDepth : 0.0f);
561 COLOR speColor = PostProcessSpecularColor();
562 COLOR difColor = PostProcessDiffuseColor(0xffffffff);
564 if( options.enableHackForGames == HACK_FOR_COMMANDCONQUER )
566 float s1 = (x1-x0) + s0;
567 float t1 = (y1-y0) + t0;
568 DrawSimple2DTexture(x0, y0, x1, y1, u0, v0,
569 s1/g_textures[0].m_fTexWidth, t1/g_textures[0].m_fTexHeight, difColor, speColor, depth, 1);
573 float s1 = (x1-x0) + s0;
576 float t1 = (y1-y0) + t0;
577 DrawSimple2DTexture(x0, y0, x1, y1, u0, v0,
578 s1/g_textures[0].m_fTexWidth, t1/g_textures[0].m_fTexHeight, difColor, speColor, depth, 1);
582 DrawSimple2DTexture(x0, y0, x1, y2, u0, v0,
583 s1/g_textures[0].m_fTexWidth, maxv, difColor, speColor, depth, 1);
584 DrawSimple2DTexture(x0, y2, x1, y1, u0, 0,
585 s1/g_textures[0].m_fTexWidth, v1, difColor, speColor, depth, 1);
592 float t1 = (y1-y0) + t0;
593 DrawSimple2DTexture(x0, y0, x2, y1, u0, v0,
594 maxu, t1/g_textures[0].m_fTexHeight, difColor, speColor, depth, 1);
595 DrawSimple2DTexture(x2, y0, x1, y1, 0, v0,
596 u1, t1/g_textures[0].m_fTexHeight, difColor, speColor, depth, 1);
600 DrawSimple2DTexture(x0, y0, x2, y2, u0, v0, maxu, maxv, difColor, speColor, depth, 1);
601 DrawSimple2DTexture(x2, y0, x1, y2, 0, v0, u1, maxv, difColor, speColor, depth, 1);
602 DrawSimple2DTexture(x0, y2, x2, y1, u0, 0, maxu, v1, difColor, speColor, depth, 1);
603 DrawSimple2DTexture(x2, y2, x1, y1, 0, 0, u1, v1, difColor, speColor, depth, 1);
607 DEBUGGER_PAUSE_AT_COND_AND_DUMP_COUNT_N(
608 (pauseAtNext&&(eventToPause==NEXT_OBJ_BG||eventToPause==NEXT_FLUSH_TRI||eventToPause==NEXT_OBJ_TXT_CMD)),
610 TRACE0("Pause ObjBG Copy");
615 void CRender::DrawObjBG1CYC(uObjScaleBg &bg, bool scaled) //Without Ratation
617 if( !status.bCIBufferIsRendered ) g_pFrameBufferManager->ActiveTextureBuffer();
619 if( g_curRomInfo.bDisableObjBG )
622 if( status.bHandleN64RenderTexture )
624 g_pRenderTextureInfo->maxUsedHeight = g_pRenderTextureInfo->N64Height;
625 if( !status.bDirectWriteIntoRDRAM )
627 status.bFrameBufferIsDrawn = true;
628 status.bFrameBufferDrawnByTriangles = true;
632 SetCombinerAndBlender();
634 float depth = (gRDP.otherMode.depth_source == 1 ? gRDP.fPrimitiveDepth : 0.0f);
636 float x0 = bg.frameX / 4.0f;
637 float y0 = bg.frameY / 4.0f;
638 float x1 = bg.frameW / 4.0f + x0;
639 float y1 = bg.frameH / 4.0f + y0;
641 float s0 = bg.imageX / 32.0f;
642 float t0 = bg.imageY / 32.0f;
644 float scaleX = bg.scaleW/1024.0f;
645 float scaleY = bg.scaleH/1024.0f;
647 float texwidth = bg.imageW/4.0f;
648 float texheight = bg.imageH/4.0f;
650 float u0 = s0/g_textures[0].m_fTexWidth;
651 float v0 = t0/g_textures[0].m_fTexHeight;
652 float maxu = texwidth/g_textures[0].m_fTexWidth;
653 float maxv = texheight/g_textures[0].m_fTexHeight;
655 float x2 = x0 + (texwidth-s0)/scaleX;
656 float y2 = y0 + (texheight-t0)/scaleY;
657 float u1 = (x1-x2)*scaleX/g_textures[0].m_fTexWidth;
658 float v1 = (y1-y2)*scaleY/g_textures[0].m_fTexHeight;
660 COLOR speColor = PostProcessSpecularColor();
661 COLOR difColor = PostProcessDiffuseColor(0xffffffff);
663 SetAlphaTestEnable(FALSE);
665 if( options.enableHackForGames != HACK_FOR_YOSHI )
667 float s1 = (x1-x0)*scaleX + s0;
668 float t1 = (y1-y0)*scaleY + t0;
669 DrawSimple2DTexture(x0, y0, x1, y1, u0, v0,
670 s1/g_textures[0].m_fTexWidth, t1/g_textures[0].m_fTexHeight, difColor, speColor, depth, 1);
674 float s1 = (x1-x0)*scaleX + s0;
677 float t1 = (y1-y0)*scaleY + t0;
678 DrawSimple2DTexture(x0, y0, x1, y1, u0, v0,
679 s1/g_textures[0].m_fTexWidth, t1/g_textures[0].m_fTexHeight, difColor, speColor, depth, 1);
683 DrawSimple2DTexture(x0, y0, x1, y2, u0, v0,
684 s1/g_textures[0].m_fTexWidth, maxv, difColor, speColor, depth, 1);
685 DrawSimple2DTexture(x0, y2, x1, y1, u0, 0,
686 s1/g_textures[0].m_fTexWidth, v1, difColor, speColor, depth, 1);
693 float t1 = (y1-y0)*scaleY + t0;
694 DrawSimple2DTexture(x0, y0, x2, y1, u0, v0,
695 maxu, t1/g_textures[0].m_fTexHeight, difColor, speColor, depth, 1);
696 DrawSimple2DTexture(x2, y0, x1, y1, 0, v0,
697 u1, t1/g_textures[0].m_fTexHeight, difColor, speColor, depth, 1);
701 DrawSimple2DTexture(x0, y0, x2, y2, u0, v0, maxu, maxv, difColor, speColor, depth, 1);
702 DrawSimple2DTexture(x2, y0, x1, y2, 0, v0, u1, maxv, difColor, speColor, depth, 1);
703 DrawSimple2DTexture(x0, y2, x2, y1, u0, 0, maxu, v1, difColor, speColor, depth, 1);
704 DrawSimple2DTexture(x2, y2, x1, y1, 0, 0, u1, v1, difColor, speColor, depth, 1);
708 DEBUGGER_PAUSE_AT_COND_AND_DUMP_COUNT_N(
709 (pauseAtNext&&(eventToPause==NEXT_OBJ_BG||eventToPause==NEXT_FLUSH_TRI||eventToPause==NEXT_OBJ_TXT_CMD)),
711 DebuggerAppendMsg("Pause BG 1CYC: (%.0f,%.0f - %.0f,%.0f), \ntex (%.2f,%.2f), scale (%.2f,%.2f)",x0,y0,x1,y1,s0,t0,scaleX,scaleY);
717 void CRender::DrawSprite(uObjTxSprite &sprite, bool rectR) //Without Ratation
719 if( !status.bCIBufferIsRendered ) g_pFrameBufferManager->ActiveTextureBuffer();
721 if( status.bHandleN64RenderTexture )
723 g_pRenderTextureInfo->maxUsedHeight = g_pRenderTextureInfo->N64Height;
724 if( !status.bDirectWriteIntoRDRAM )
726 status.bFrameBufferIsDrawn = true;
727 status.bFrameBufferDrawnByTriangles = true;
730 SetCombinerAndBlender();
731 COLOR speColor = PostProcessSpecularColor();
732 COLOR difColor = PostProcessDiffuseColor(0xffffffff);
735 float objX = sprite.sprite.objX/4.0f;
736 float objY = sprite.sprite.objY/4.0f;
737 float width = sprite.sprite.imageW / 32.0f;
738 float high = sprite.sprite.imageH / 32.0f;
739 float scaleW = sprite.sprite.scaleW/1024.0f;
740 float scaleH = sprite.sprite.scaleH/1024.0f;
742 if( g_curRomInfo.bIncTexRectEdge )
748 float x0, y0, x1, y1;
751 // Upper-left coordinate
752 // ( X + objX / BaseScaleX, Y+objY/BaseScaleY )
753 // Lower-right coordinate
754 // ( X + (objX + imageW / scaleW) / BaseScaleX - 1, Y + (objY + imageH / scaleH) / BaseScaleY - 1 )
756 x0 = gObjMtxReal.X + objX/gObjMtxReal.BaseScaleX;
757 y0 = gObjMtxReal.Y + objY/gObjMtxReal.BaseScaleY;
758 x1 = gObjMtxReal.X + (objX + width / scaleW) / gObjMtxReal.BaseScaleX;
759 y1 = gObjMtxReal.Y + (objY + high / scaleH) / gObjMtxReal.BaseScaleY;
763 // (objX, objY) - ( objX+imageW/scaleW-1, objY+imageH/scaleH-1)
766 x1 = objX + width / scaleW;
767 y1 = objY + high / scaleH;
769 if( (sprite.sprite.imageFlags&1) ) // flipX
776 if( (sprite.sprite.imageFlags&0x10) ) // flipY
784 // save the current clamp type
785 GLint iClampS, iClampT;
786 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, &iClampS);
788 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, &iClampT);
790 // force clamp type to CLAMP_EDGE (experiments show sometimes this is set to hex 0x2901 - invalid value)
791 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
793 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
795 // draw the 2D sprite as 2 triangles
796 float depth = (gRDP.otherMode.depth_source == 1 ? gRDP.fPrimitiveDepth : 0.0f);
797 CTexture *pTexture = g_textures[0].m_pCTexture;
798 DrawSimple2DTexture(x0, y0, x1, y1, 0, 0, 1/pTexture->m_fXScale, 1/pTexture->m_fYScale,
799 difColor, speColor, depth, 1);
800 // return clamp type to original setting
801 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampS);
803 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampT);
808 void CRender::LoadObjBG1CYC(uObjScaleBg &bg)
810 uint32 imageWidth = bg.imageW/4;
811 uint32 imageHeight = bg.imageH/4;
814 gti.Format = bg.imageFmt;
815 gti.Size = bg.imageSiz;
817 //uint8* img = (uint8*)(g_pRDRAMu8+RSPSegmentAddr(bg.imagePtr));
819 uchar *palAddr = (uchar *) &g_wRDPTlut[0];
820 gti.Address = RSPSegmentAddr(bg.imagePtr);
825 gti.WidthToCreate = imageWidth;
826 gti.HeightToCreate = imageHeight;
828 gti.clampS = gti.clampT = 1;
829 gti.maskS = gti.maskT = 0;
831 gti.Palette = bg.imagePal;
832 gti.PalAddress = palAddr;
834 gti.Pitch = imageWidth << gti.Size >> 1;
835 gti.Pitch = (gti.Pitch>>3)<<3; // Align to 8 bytes
837 if( gti.Address + gti.Pitch*gti.HeightToCreate > g_dwRamSize )
839 TRACE0("Skip BG 1CYC loading, memory out of bound");
843 gti.TLutFmt = TLUT_FMT_RGBA16; //RGBA16
844 gti.bSwapped = FALSE;
846 gti.HeightToLoad = gti.HeightToCreate;
847 gti.WidthToLoad = gti.WidthToCreate;
848 gti.pPhysicalAddress = ((uint8*)g_pRDRAMu32)+gti.Address;
850 TxtrCacheEntry *pEntry = gTextureManager.GetTexture(>i, false,true,false);
851 SetCurrentTexture(0,pEntry);
853 DEBUGGER_IF_DUMP((pauseAtNext && (eventToPause == NEXT_OBJ_TXT_CMD||eventToPause == NEXT_FLUSH_TRI||eventToPause == NEXT_OBJ_BG)),
855 TRACE0("Load Obj BG 1CYC:\n");
856 DebuggerAppendMsg("Addr=0x%08X, W=%d, H=%d, Left=%d, Top=%d\n",
857 gti.Address, gti.WidthToCreate, gti.HeightToCreate, gti.LeftToLoad, gti.TopToLoad);
858 DebuggerAppendMsg("Fmt=%s-%db, Pal=%d\n",
859 pszImgFormat[gti.Format], pnImgSize[gti.Size], gti.Palette);
864 void CRender::LoadObjSprite(uObjTxSprite &sprite, bool useTIAddr)
867 gti.Format = sprite.sprite.imageFmt;
868 gti.Size = sprite.sprite.imageSiz;
870 uchar *palAddr = (uchar *) &g_wRDPTlut[0];
872 gti.Address = RSPSegmentAddr(sprite.txtr.block.image);
873 gti.Address += sprite.sprite.imageAdrs<<3;
876 gti.Palette = sprite.sprite.imagePal;
877 gti.PalAddress = palAddr;
879 if( sprite.txtr.block.type == S2DEX_OBJLT_TXTRBLOCK )
881 gti.WidthToCreate = sprite.sprite.imageW/32;
882 if( sprite.sprite.imageW >= 0x8000 )
884 gti.WidthToCreate = (0x10000-sprite.sprite.imageW)/32;
886 gti.HeightToCreate = sprite.sprite.imageH/32;
887 if( sprite.sprite.imageH >= 0x8000 )
889 gti.HeightToCreate = (0x10000-sprite.sprite.imageH)/32;
891 gti.Pitch = (2047/(sprite.txtr.block.tline-1)) << 3;
893 else if( sprite.txtr.block.type == S2DEX_OBJLT_TXTRTILE )
895 //#define GS_PIX2TMEM(pix, siz) ((pix)>>(4-(siz)))
896 //#define GS_TT_TWIDTH(pix,siz) ((GS_PIX2TMEM((pix), (siz))<<2)-1)
897 //#define GS_TT_THEIGHT(pix,siz) (((pix)<<2)-1)
899 gti.WidthToCreate = ((sprite.txtr.tile.twidth+1)>>2)<<(4-gti.Size);
900 gti.HeightToCreate = (sprite.txtr.tile.theight+1)>>2;
902 if( gti.Size == TXT_SIZE_4b )
904 gti.Pitch = gti.WidthToCreate >> 1;
907 //gti.Pitch = (sprite.txtr.tile.twidth+1) << 3;
908 gti.Pitch = gti.WidthToCreate << (gti.Size-1);
911 if( gti.Address + gti.Pitch*gti.HeightToCreate > g_dwRamSize )
913 TRACE0("Skip Obj sprite loading, memory out of bound");
917 gti.TLutFmt = TLUT_FMT_RGBA16; //RGBA16
918 gti.bSwapped = FALSE;
920 gti.HeightToLoad = gti.HeightToCreate;
921 gti.WidthToLoad = gti.WidthToCreate;
922 gti.pPhysicalAddress = ((uint8*)g_pRDRAMu32)+gti.Address;
924 TxtrCacheEntry *pEntry = gTextureManager.GetTexture(>i, false);
925 SetCurrentTexture(0,pEntry);