1 /******************************************************************************
2 * Arachnoid Graphics Plugin for Mupen64Plus
3 * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
5 * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
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.
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.
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 *****************************************************************************/
26 #include "DisplayListParser.h"
27 #include "assembler.h"
28 #include "OpenGLRenderer.h"
29 #include "TextureCache.h"
32 #include "OpenGLManager.h"
33 #include "OpenGL2DRenderer.h"
34 #include "AdvancedCombinerManager.h"
35 #include "FogManager.h"
38 #include "RomDetector.h"
44 //-----------------------------------------------------------------------------
46 //-----------------------------------------------------------------------------
47 #define MI_INTR_DP 0x00000020 //!< RDP Interrupt signal
49 //-----------------------------------------------------------------------------
51 //-----------------------------------------------------------------------------
52 Memory* RDP::m_memory = 0;
54 //-----------------------------------------------------------------------------
56 //-----------------------------------------------------------------------------
60 m_changedTiles = false;
61 m_textureMode = TM_NORMAL;
62 m_loadType = LOADTYPE_BLOCK;
63 m_tmemChanged = false;
67 m_displayListParser = 0;
71 m_openGL2DRenderer = 0;
72 m_screenUpdatePending= false;
75 //-----------------------------------------------------------------------------
77 //-----------------------------------------------------------------------------
82 //-----------------------------------------------------------------------------
84 //! Sets pointers to managers and initializes objects
85 //-----------------------------------------------------------------------------
86 bool RDP::initialize(GFX_INFO* graphicsInfo, RSP* rsp, Memory* memory, GBI* gbi, TextureCache* textureCache, VI* vi, DisplayListParser* displayListParser, FogManager* fogMgr)
89 m_graphicsInfo = graphicsInfo;
93 m_displayListParser = displayListParser;
94 m_textureCache = textureCache;
97 //Create combiner manager
98 m_combinerMgr = new AdvancedCombinerManager();
99 m_combinerMgr->initialize();
101 //Create texture loader
102 m_textureLoader = new TextureLoader();
103 m_textureLoader->initialize(this, m_memory);
105 //Create OpenGL 2D Renderer
106 m_openGL2DRenderer = new OpenGL2DRenderer();
107 m_openGL2DRenderer->initialize(vi);
112 //-----------------------------------------------------------------------------
114 //! Delets all allocated memory
115 //-----------------------------------------------------------------------------
118 if ( m_combinerMgr ) { delete m_combinerMgr; m_combinerMgr = 0; }
119 if ( m_textureLoader ) { delete m_textureLoader; m_textureLoader = 0; }
120 if ( m_openGL2DRenderer ) { delete m_openGL2DRenderer; m_openGL2DRenderer = 0; }
123 //-----------------------------------------------------------------------------
125 //! Sets OpenGL states, updates combiner, activates textures, sets blender
126 //-----------------------------------------------------------------------------
127 void RDP::updateStates()
130 if (m_otherMode.depthCompare)
131 glDepthFunc( GL_LEQUAL );
133 glDepthFunc( GL_ALWAYS );
136 if (m_otherMode.depthUpdate)
139 glDepthMask( false );
142 if (m_otherMode.depthMode == ZMODE_DEC)
144 glEnable( GL_POLYGON_OFFSET_FILL );
145 glPolygonOffset( -3.0f, -3.0f );
149 glDisable( GL_POLYGON_OFFSET_FILL );
153 if ((m_otherMode.alphaCompare == G_AC_THRESHOLD) && !(m_otherMode.alphaCvgSel))
155 glEnable( GL_ALPHA_TEST );
156 glAlphaFunc( (m_combinerMgr->getBlendColor()[3] > 0.0f) ? GL_GEQUAL : GL_GREATER, m_combinerMgr->getBlendColor()[3] );
158 // Used in TEX_EDGE and similar render modes
159 else if (m_otherMode.cvgXAlpha)
161 glEnable( GL_ALPHA_TEST );
162 glAlphaFunc( GL_GEQUAL, 0.5f ); // Arbitrary number -- gives nice results though
165 glDisable( GL_ALPHA_TEST );
168 if ( m_updateCombiner )
170 if ( m_otherMode.cycleType == G_CYC_COPY)
172 m_combinerMgr->setMux(72057594037727865LL, m_otherMode.cycleType); //Only normal texturing
173 m_combinerMgr->selectCombine(m_otherMode.cycleType);
175 else if ( m_otherMode.cycleType == G_CYC_FILL )
177 m_combinerMgr->setMux( 72057594037828926LL, m_otherMode.cycleType );
178 m_combinerMgr->selectCombine(m_otherMode.cycleType);
182 m_combinerMgr->selectCombine(m_otherMode.cycleType);
184 m_updateCombiner = false;
185 m_updateCombineColors = true;
188 if ( m_updateCombineColors )
190 m_combinerMgr->updateCombineColors();
191 m_updateCombineColors = false;
195 if ( m_changedTiles || m_tmemChanged || m_rsp->getTexturesChanged() )
197 m_combinerMgr->beginTextureUpdate();
199 //Update Texture channel 0
200 if ( m_combinerMgr->getUsesTexture0() )
203 m_textureCache->update(0);
204 m_rsp->setTexturesChanged(false);
205 m_changedTiles = false;
206 m_tmemChanged = false;
211 glActiveTextureARB( GL_TEXTURE0_ARB + 0 );
212 glDisable(GL_TEXTURE_2D);
215 //Update Texture channel 1
216 if ( m_combinerMgr->getUsesTexture1() )
219 m_textureCache->update(1);
220 m_rsp->setTexturesChanged(false);
221 m_changedTiles = false;
222 m_tmemChanged = false;
226 //Disable textureing 1
227 glActiveTextureARB( GL_TEXTURE0_ARB + 1 );
228 glDisable(GL_TEXTURE_2D);
231 m_combinerMgr->endTextureUpdate();
235 if ( (m_otherMode.forceBlender) &&
236 (m_otherMode.cycleType != G_CYC_COPY) &&
237 (m_otherMode.cycleType != G_CYC_FILL) &&
238 !(m_otherMode.alphaCvgSel))
240 glEnable( GL_BLEND );
241 switch (m_otherMode.l >> 16)
245 glBlendFunc( GL_ONE, GL_ONE );
247 case 0x0C08: // 1080 Sky
248 case 0x0F0A: // Used LOTS of places
249 glBlendFunc( GL_ONE, GL_ZERO );
251 case 0xC810: // Blends fog
252 case 0xC811: // Blends fog
253 case 0x0C18: // Standard interpolated blend
254 case 0x0C19: // Used for antialiasing
255 case 0x0050: // Standard interpolated blend
256 case 0x0055: // Used for antialiasing
257 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
259 case 0x0FA5: // Seems to be doing just blend color - maybe combiner can be used for this?
260 case 0x5055: // Used in Paper Mario intro, I'm not sure if this is right...
261 glBlendFunc( GL_ZERO, GL_ONE );
264 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
269 glDisable( GL_BLEND );
271 if (m_otherMode.cycleType == G_CYC_FILL)
273 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
274 glEnable( GL_BLEND );
278 //-----------------------------------------------------------------------------
280 //! Resets all states on RDP
281 //-----------------------------------------------------------------------------
284 setTextureFiltering( G_TF_POINT );
288 //-----------------------------------------------------------------------------
289 //* Trigger Interrupt
290 //! Tell emulator that the RDP is idle
291 //-----------------------------------------------------------------------------
292 void RDP::triggerInterrupt()
294 *(m_graphicsInfo->MI_INTR_REG) |= MI_INTR_DP;
295 m_graphicsInfo->CheckInterrupts();
298 //-----------------------------------------------------------------------------
299 //* Set Alpha Compare Mode
300 //-----------------------------------------------------------------------------
301 void RDP::setAlphaCompareMode(unsigned int mode)
303 m_otherMode.alphaCompare = mode;
304 OpenGLManager::getSingleton().setAlphaTest( m_otherMode.alphaCompare != 0 );
307 //-----------------------------------------------------------------------------
309 //-----------------------------------------------------------------------------
310 void RDP::setRenderMode(unsigned int w1)
312 unsigned int mode1 = (w1 & 0xCCCCFFFF);
313 unsigned int mode2 = (w1 & 0x3333FFFF);
315 m_otherMode.l &= 0x00000007;
316 m_otherMode.l |= mode1 | mode2;
319 //#############################################################################
321 //#############################################################################
323 //*****************************************************************************
325 //*****************************************************************************
327 //-----------------------------------------------------------------------------
329 //! Sets all combiner variables on combiner that tells it how to combine
330 //! the diffrent colors and textures.
331 //-----------------------------------------------------------------------------
332 void RDP::RDP_SetCombine(MicrocodeArgument* ucode)
334 int mux0 = _SHIFTR( ucode->w0, 0, 24 );
335 int mux1 = ucode->w1;
336 m_combinerMgr->setMux(mux0, mux1, (G_CYCLE_TYPE)m_otherMode.cycleType);
338 m_updateCombiner = true;
341 //*****************************************************************************
343 //*****************************************************************************
345 //-----------------------------------------------------------------------------
346 //* Set Environment Color
347 //! Sets Environment Color on combiner
348 //! @param r Red component of color (0.0 - 1.0)
349 //! @param g Green component of color (0.0 - 1.0)
350 //! @param b Blue component of color (0.0 - 1.0)
351 //! @param a Alpha component of color (0.0 - 1.0)
352 //-----------------------------------------------------------------------------
353 void RDP::RDP_SetEnvColor(float r, float g, float b, float a)
355 m_combinerMgr->setEnvColor(r, g, b, a);
356 m_updateCombineColors = true;
359 //-----------------------------------------------------------------------------
361 //! Sets Prim Color on combiner
362 //! @param r Red component of color (0.0 - 1.0)
363 //! @param g Green component of color (0.0 - 1.0)
364 //! @param b Blue component of color (0.0 - 1.0)
365 //! @param a Alpha component of color (0.0 - 1.0)
366 //! @param primLodMin
368 //-----------------------------------------------------------------------------
369 void RDP::RDP_SetPrimColor(float r, float g, float b, float a, unsigned int primLodMin, unsigned int primLevel)
371 int primLodFrac = max(primLevel, primLodMin);
372 m_combinerMgr->setPrimLodMin(primLodMin);
373 m_combinerMgr->setPrimLodFrac(primLodFrac / 255.0f);
374 m_combinerMgr->setPrimColor(r, g, b, a);
375 m_updateCombineColors = true;
378 //-----------------------------------------------------------------------------
380 //! Sets Blend Color on combiner
381 //! @param r Red component of color (0.0 - 1.0)
382 //! @param g Green component of color (0.0 - 1.0)
383 //! @param b Blue component of color (0.0 - 1.0)
384 //! @param a Alpha component of color (0.0 - 1.0)
385 //-----------------------------------------------------------------------------
386 void RDP::RDP_SetBlendColor(float r, float g, float b, float a)
388 m_combinerMgr->setBlendColor(r, g, b, a);
389 m_updateCombineColors = true;
392 //-----------------------------------------------------------------------------
394 //! Sets Fill Color on combiner
395 //! @param r Red component of color (0.0 - 1.0)
396 //! @param g Green component of color (0.0 - 1.0)
397 //! @param b Blue component of color (0.0 - 1.0)
398 //! @param a Alpha component of color (0.0 - 1.0)
399 //-----------------------------------------------------------------------------
400 void RDP::RDP_SetFillColor(float r, float g, float b, float a)
402 m_combinerMgr->setFillColor(r, g, b, a);
403 m_updateCombineColors = true;
406 //-----------------------------------------------------------------------------
408 //! Sets fog color used when rendering fog
409 //! @param r Red component of color (0.0 - 1.0)
410 //! @param g Green component of color (0.0 - 1.0)
411 //! @param b Blue component of color (0.0 - 1.0)
412 //! @param a Alpha component of color (0.0 - 1.0)
413 //-----------------------------------------------------------------------------
414 void RDP::RDP_SetFogColor(float r, float g, float b, float a)
416 m_fogMgr->setFogColor(r, g, b, a);
419 //*****************************************************************************
421 //*****************************************************************************
423 //-----------------------------------------------------------------------------
425 //-----------------------------------------------------------------------------
426 void RDP::RDP_SetOtherMode(MicrocodeArgument* ucode)
428 unsigned int mode0 = _SHIFTR( ucode->w0, 0, 24 );
429 unsigned int mode1 = ucode->w1;
431 m_otherMode.h = mode0;
432 m_otherMode.l = mode1;
435 //-----------------------------------------------------------------------------
437 //-----------------------------------------------------------------------------
438 void RDP::RDP_SetPrimDepth(unsigned int dwZ, unsigned int dwDZ)
440 unsigned int primitiveDepth = dwZ & 0x7FFF;
443 m_primitiveZ = (float)(primitiveDepth)/(float)0x8000;
446 //-----------------------------------------------------------------------------
448 //-----------------------------------------------------------------------------
449 void RDP::RDP_SetScissor(int x0, int y0, int x1, int y1, int mode)
452 float vsx = OpenGLManager::getSingleton().getViewScaleX();
453 float vsy = OpenGLManager::getSingleton().getViewScaleY();
456 int offset = 0; //TODO: height offset?
459 OpenGLManager::getSingleton().setScissor(
461 (m_vi->getHeight() - y1) * vsy + offset,
467 //-----------------------------------------------------------------------------
469 //! Called when RDP is finished
470 //-----------------------------------------------------------------------------
471 void RDP::RDP_FullSync()
473 this->triggerInterrupt();
476 //*****************************************************************************
478 //*****************************************************************************
480 //-----------------------------------------------------------------------------
482 //! Renders a rectangle
483 //-----------------------------------------------------------------------------
484 void RDP::RDP_FillRect(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1)
486 //Logger::getSingleton() << "RDP_FillRect: " << (int)x0 << " " << (int)y0 << " " << (int)x1 << " " << (int)y1 << "\n";
488 //Increase rectangle size?
489 if( m_otherMode.cycleType >= G_CYC_COPY )
495 //Clear Depth Buffer?
496 if ( m_depthImageInfo.rdramAddress == m_colorImageInfo.rdramAddress )
501 glClear(GL_DEPTH_BUFFER_BIT);
504 if (m_otherMode.depthUpdate)
506 glDepthMask(GL_TRUE);
510 glDepthMask(GL_FALSE);
516 //Clear Color Buffer?
517 if ( m_otherMode.cycleType == G_CYC_FILL)
519 if ( x0 == 0 && y0 == 0 && x1 == m_vi->getWidth() && y1 == m_vi->getHeight() )
521 const float* fillColor = m_combinerMgr->getFillColor();
522 glClearColor(fillColor[0], fillColor[1], fillColor[2], fillColor[3]);
523 bool scissor = OpenGLManager::getSingleton().getScissorEnabled();
524 OpenGLManager::getSingleton().setScissorEnabled(false);
525 glClear(GL_COLOR_BUFFER_BIT);
526 OpenGLManager::getSingleton().setScissorEnabled(scissor);
532 this->updateStates();
535 if ( ROMDetector::getSingleton().getIgnoreFillRects() )
541 glDisable( GL_SCISSOR_TEST );
544 //int oldViewport[4];
545 //glGetIntegerv(GL_VIEWPORT, oldViewport);
546 //glViewport(0, 0, OpenGLManager::getSingleton().getWidth(), OpenGLManager::getSingleton().getHeight() );
547 glDepthRange(0.0f, 1.0f);
549 //Get depth and color
550 float depth = m_otherMode.depthSource == 1 ? m_primitiveZ : 0; //TODO: Use RSP viewport nearz?
551 float* color = m_otherMode.cycleType == G_CYC_FILL ? m_combinerMgr->getFillColor() : m_combinerMgr->getPrimColor();
554 m_openGL2DRenderer->renderQuad(color, x0, y0, x1, y1, depth);
557 //glViewport(oldViewport[0], oldViewport[1], oldViewport[2], oldViewport[3]);
560 glEnable( GL_SCISSOR_TEST );
563 //-----------------------------------------------------------------------------
564 // Texture Rectangle Flip
565 //-----------------------------------------------------------------------------
566 void RDP::RDP_TexRectFlip(unsigned int dwXH, unsigned int dwYH, unsigned int dwXL, unsigned int dwYL,
567 unsigned int tileno, unsigned int dwS, unsigned int dwT, int nDSDX, int nDTDY)
569 Logger::getSingleton().printMsg("RDP_TexRect");
571 float fS0 = (float)dwS / 32.0f;
572 float fT0 = (float)dwT / 32.0f;
574 float fDSDX = (float)nDSDX / 1024.0f;
575 float fDTDY = (float)nDTDY / 1024.0f;
577 if (m_otherMode.cycleType == G_CYC_COPY)
579 fDSDX /= 4.0f; // In copy mode 4 pixels are copied at once.
583 else if (m_otherMode.cycleType == G_CYC_FILL )
589 float fS1 = fS0 + (fDSDX * (dwYH - dwYL));
590 float fT1 = fT0 + (fDTDY * (dwXH - dwXL));
592 //Set Current Texture tiles
593 m_rsp->setTile( m_textureLoader->getTile(tileno), 0);
596 m_rsp->setTile( m_textureLoader->getTile(tileno + 1), 1);
599 m_rsp->setTile( m_textureLoader->getTile(tileno), 1);
602 m_texRectWidth = (unsigned int)fS1;
603 m_texRectHeight = (unsigned int)fT1;
606 this->updateStates();
608 float t0u0 = 0, t0v0 = 0, t0u1 =0, t0v1 = 0;
609 if ( m_textureCache->getCurrentTexture(0) )
611 t0u0 = (fS0) * m_textureCache->getCurrentTexture(0)->shiftScaleS - m_textureLoader->getTile(tileno)->uls;
612 t0v0 = (fT0) * m_textureCache->getCurrentTexture(0)->shiftScaleT - m_textureLoader->getTile(tileno)->ult;
613 t0u1 = t0u0 + (fDSDX * (dwYH - dwYL))*m_textureCache->getCurrentTexture(0)->shiftScaleS;
614 t0v1 = t0v0 + (fDTDY * (dwXH - dwXL))*m_textureCache->getCurrentTexture(0)->shiftScaleT;
617 _textureRectangleFlip(dwXL, dwYL, dwXH, dwYH, t0u0, t0v0, t0u1, t0v1, tileno);
620 int rspTile = m_rsp->getTexture().tile;
621 m_rsp->setTile( m_textureLoader->getTile(tileno), 0);
622 m_rsp->setTile( m_textureLoader->getTile(rspTile < 7 ? rspTile + 1 : rspTile), 1);
625 //-----------------------------------------------------------------------------
627 //! Not this command use 128bits and not 64 bits wich could cause some
628 //! problems with the program counter.
629 //-----------------------------------------------------------------------------
630 void RDP::RDP_TexRect(unsigned int dwXH, unsigned int dwYH, unsigned int dwXL, unsigned int dwYL,
631 unsigned int tileno, unsigned short dwS, unsigned short dwT, unsigned short nDSDX, unsigned short nDTDY)
633 Logger::getSingleton().printMsg("RDP_TexRect");
635 glEnable(GL_TEXTURE_2D);
638 short s16S = *(short*)(&dwS);
639 short s16T = *(short*)(&dwT);
640 short s16DSDX = *(short*)(&nDSDX);
641 short s16DTDY = *(short*)(&nDTDY);
644 float s = s16S / 32.0f;
645 float t = s16T / 32.0f;
646 float dsdx = s16DSDX / 1024.0f;
647 float dtdy = s16DTDY / 1024.0f;
650 float ulx = (float)dwXH;
651 float uly = (float)dwYH;
652 float lrx = (float)dwXL;
653 float lry = (float)dwYL;
657 _textureRectangle(ulx, uly, lrx, lry, tile, s, t, dsdx, dtdy, false);
660 //*****************************************************************************
662 //*****************************************************************************
664 //-----------------------------------------------------------------------------
666 //! Sets information about color image
667 //-----------------------------------------------------------------------------
668 void RDP::RDP_SetCImg(unsigned int format, unsigned int size, unsigned int width, unsigned int segmentAddress)
670 m_colorImageInfo.rdramAddress = m_memory->getRDRAMAddress( segmentAddress );
671 m_colorImageInfo.format = format;
672 m_colorImageInfo.size = size;
673 m_colorImageInfo.width = width + 1; //Note: add plus one
674 m_colorImageInfo.bpl = m_colorImageInfo.width << m_colorImageInfo.size >> 1;
676 if (m_screenUpdatePending)
678 OpenGLManager::getSingleton().endRendering();
679 m_screenUpdatePending = false;
683 //-----------------------------------------------------------------------------
685 //! Sets information about depth image
686 //-----------------------------------------------------------------------------
687 void RDP::RDP_SetZImg(unsigned int format, unsigned int size, unsigned int width, unsigned int segmentAddress)
689 m_depthImageInfo.rdramAddress = m_memory->getRDRAMAddress( segmentAddress );
690 m_depthImageInfo.format = format;
691 m_depthImageInfo.size = size;
692 m_depthImageInfo.width = width + 1; //Note: add plus one
693 m_depthImageInfo.bpl = m_colorImageInfo.width << m_colorImageInfo.size >> 1;
696 //-----------------------------------------------------------------------------
697 //* Set Texture Image
698 //! Sets information about texture image
699 //-----------------------------------------------------------------------------
700 void RDP::RDP_SetTImg(unsigned int format, unsigned int size, unsigned int width, unsigned int segmentAddress)
702 m_textureLoader->setTextureImage(format, size, width, segmentAddress);
705 //-----------------------------------------------------------------------------
707 //-----------------------------------------------------------------------------
708 void RDP::RDP_SetTile(int format, int size, int line, int tmem, int tile,
709 int palette, int clampS, int clampT, int mirrorS,
710 int mirrorT, int maskS, int maskT, int shiftS, int shiftT )
713 m_textureLoader->setTile( format, size, line, tmem, tile, palette,
714 clampS, clampT, mirrorS, mirrorT, maskS, maskT,
717 //m_changedTiles = true; ??? Not needed?
720 //-----------------------------------------------------------------------------
722 //-----------------------------------------------------------------------------
723 void RDP::RDP_LoadTile(int tile, int s0, int t0, int s1, int t1)
726 m_textureLoader->loadTile(tile, s0, t0, s1, t1);
728 m_textureMode = TM_NORMAL;
729 m_loadType = LOADTYPE_TILE;
730 m_tmemChanged = true;
733 //-----------------------------------------------------------------------------
735 //-----------------------------------------------------------------------------
736 void RDP::RDP_LoadBlock(int tile, int s0, int t0, int s1, int t1)
739 m_textureLoader->loadBlock(tile, s0, t0, s1, t1);
741 m_textureMode = TM_NORMAL;
742 m_loadType = LOADTYPE_BLOCK;
743 m_tmemChanged = true;
746 //-----------------------------------------------------------------------------
747 //! Sets the size of tile
748 //! @Param tile Index of the tile to set size on
749 //! @param s0 Texture Coordinats for first vertex coordinate
750 //! @param t0 Texture Coordinats for first vertex coordinate
751 //! @param s1 Texture Coordinats for second vertex coordinate
752 //! @param t1 Texture Coordinats for second vertex coordinate
753 //-----------------------------------------------------------------------------
754 void RDP::RDP_SetTileSize(int tile, unsigned int s0, unsigned int t0, unsigned int s1, unsigned int t1)
756 m_textureLoader->setTileSize( tile, s0, t0, s1, t1);
758 m_changedTiles = true;
761 //-----------------------------------------------------------------------------
762 // Load Texture Look Up Table
763 //-----------------------------------------------------------------------------
764 void RDP::RDP_LoadTLUT(int tile, int s0, int t0, int s1, int t1)
766 m_textureLoader->loadTLUT(tile, s0, t0, s1, t1);
768 m_tmemChanged = true;
771 //*****************************************************************************
773 //*****************************************************************************
775 //-----------------------------------------------------------------------------
777 //-----------------------------------------------------------------------------
778 void RDP::_textureRectangle(float ulx, float uly, float lrx, float lry, int tile, float s, float t, float dsdx, float dtdy,bool flip)
780 bool zEnabled = OpenGLManager::getSingleton().getZBufferEnabled();
781 OpenGLManager::getSingleton().setZBufferEnabled(false);
784 if ( m_otherMode.cycleType == G_CYC_COPY )
790 else if (m_otherMode.cycleType == G_CYC_FILL )
796 //Set Current Texture tiles
797 m_rsp->setTile( m_textureLoader->getTile(tile), 0);
798 m_rsp->setTile( m_textureLoader->getTile(tile < 7 ? tile + 1 : tile), 1);
801 float lrs = s + (lrx - ulx - 1) * dsdx;
802 float lrt = t + (lry - uly - 1) * dtdy;
804 //Change mode to texture rectangle
805 if ( m_textureMode == TM_NORMAL )
806 m_textureMode = TM_TEXRECT;
808 m_texRectWidth = (unsigned int)(max( lrs, s ) + dsdx);
809 m_texRectHeight = (unsigned int)(max( lrt, t ) + dtdy);
812 this->updateStates();
814 //glViewport( 0, 0, OpenGLManager::getSingleton().getWidth(), OpenGLManager::getSingleton().getHeight() );
816 glDisable(GL_SCISSOR_TEST);
821 OpenGLRenderer::getSingleton().renderTexRect( ulx, uly, lrx, lry, s, t, lrs, lrt, flip );
823 OpenGLRenderer::getSingleton().renderTexRect( ulx, lry, lrx, uly, s, lrt, lrs, t, flip );
828 OpenGLRenderer::getSingleton().renderTexRect( lrx, uly, ulx, lry, lrs, t, s, lrt, flip );
830 OpenGLRenderer::getSingleton().renderTexRect( lrx, lry, ulx, uly, lrs, lrt, s, t, flip );
834 int rspTile = m_rsp->getTexture().tile;
835 m_rsp->setTile( m_textureLoader->getTile( rspTile ), 0);
836 m_rsp->setTile( m_textureLoader->getTile(rspTile < 7 ? rspTile + 1 : rspTile), 1);
838 //glViewport( 0, m_windowMgr->getHeightOffset(), OpenGLManager::getSingleton().getWidth(), OpenGLManager::getSingleton().getHeight() );
840 glEnable(GL_SCISSOR_TEST);
841 OpenGLManager::getSingleton().setZBufferEnabled(zEnabled);
844 //-----------------------------------------------------------------------------
845 //* Texture Rectangle Flip
846 //! @todo: Clamp Tile
847 //-----------------------------------------------------------------------------
848 void RDP::_textureRectangleFlip(int nX0, int nY0, int nX1, int nY1, float fS0, float fT0, float fS1, float fT1, int tile)
851 bool zEnabled = OpenGLManager::getSingleton().getZBufferEnabled();
852 OpenGLManager::getSingleton().setZBufferEnabled(false);
854 float widthDiv = (float)m_textureLoader->getTile( m_rsp->getTexture().tile )->getWidth();
855 float heightDiv = (float)m_textureLoader->getTile( m_rsp->getTexture().tile )->getHeight();
857 float t0u0 = fS0 / widthDiv;
858 float t0v0 = fT0 / heightDiv;
859 float t0u1 = (fS1 - fS0)/ widthDiv + t0u0;
860 float t0v1 = (fT1 - fT0)/ heightDiv + t0v0;
862 float depth = m_otherMode.depthSource == 1 ? m_primitiveZ : 0; //TODO: Use RSP viewport nearz?
864 static bool warned = false;
865 if( t0u0 >= 0 && t0u1 <= 1 && t0u1 >= t0u0 )
871 Logger::getSingleton().printMsg("_textureRectangleFlip - unimplemented", M64MSG_WARNING);
874 if( t0v0 >= 0 && t0v1 <= 1 && t0v1 >= t0v0 )
880 Logger::getSingleton().printMsg("_textureRectangleFlip - unimplemented", M64MSG_WARNING);
885 if ( ROMDetector::getSingleton().getRomID() == SUPER_MARIO_64 )
893 //glViewport( 0, m_windowMgr->getHeightOffset(), OpenGLManager::getSingleton().getWidth(), OpenGLManager::getSingleton().getHeight() );
896 float color[4] = { 1,1,1,0 };
897 this->getCombinerMgr()->getCombinerColor( &color[0] );
898 float secondaryColor[4] = { 1,1,1,1 };
900 if ( m_otherMode.cycleType == G_CYC_COPY )
902 glActiveTextureARB( GL_TEXTURE0_ARB );
903 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
904 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
908 glDisable( GL_SCISSOR_TEST );
911 m_openGL2DRenderer->renderFlippedTexturedQuad( color, secondaryColor,
912 (float)nX0, (float)nY0,
913 (float)nX1, (float)nY1,
921 glEnable(GL_SCISSOR_TEST);
922 OpenGLManager::getSingleton().setZBufferEnabled(zEnabled);