X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=source%2Frice_gles%2Fsrc%2FCombiner.cpp;fp=source%2Frice_gles%2Fsrc%2FCombiner.cpp;h=bc121c6f0fc920e7bc9fc8bdc3be841a090a7136;hb=d07c171fa694cae985ad7045f9ce2b2f1a5699b4;hp=0000000000000000000000000000000000000000;hpb=ca22e7b76883b946060a6b40bb8709c1981e1cf6;p=mupen64plus-pandora.git diff --git a/source/rice_gles/src/Combiner.cpp b/source/rice_gles/src/Combiner.cpp new file mode 100644 index 0000000..bc121c6 --- /dev/null +++ b/source/rice_gles/src/Combiner.cpp @@ -0,0 +1,465 @@ +/* +Copyright (C) 2002 Rice1964 + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "Combiner.h" +#include "Config.h" +#include "RenderBase.h" + +//static BOOL g_bHiliteRGBAHack = FALSE; + + +#ifdef DEBUGGER +const char *constStrs[] = { + "MUX_0", + "MUX_1", + "MUX_COMBINED", + "MUX_TEXEL0", + "MUX_TEXEL1", + "MUX_PRIM", + "MUX_SHADE", + "MUX_ENV", + "MUX_COMBALPHA", + "MUX_T0_ALPHA", + "MUX_T1_ALPHA", + "MUX_PRIM_ALPHA", + "MUX_SHADE_ALPHA", + "MUX_ENV_ALPHA", + "MUX_LODFRAC", + "MUX_PRIMLODFRAC", + "MUX_K5", + "MUX_UNK", +}; + +const char *cycleTypeStrs[] = { + "1 Cycle", + "2 Cycle", + "Copy Mode", + "Fill Mode" +}; + +const char* constStr(uint32 op) +{ +if(op<=MUX_UNK) + return constStrs[op]; +else + return "Invalid-Const"; +} +#endif + +void swap(uint8 &a, uint8 &b) +{ + uint8 c=a; + a=b; + b=c; +} + + +//======================================================================== + +//======================================================================== + +inline IColor GetIColor(uint8 flag, uint32 curCol) +{ + IColor newc; + switch(flag&MUX_MASK) + { + case MUX_0: + newc = 0; + break; + case MUX_1: + newc = 0xFFFFFFFF; + break; + case MUX_PRIM: + newc = gRDP.primitiveColor; + break; + case MUX_ENV: + newc = gRDP.envColor; + break; + case MUX_COMBINED: + case MUX_SHADE: + newc = curCol; + break; + case MUX_K5: + newc = 0xFFFFFFFF; + break; + case MUX_UNK: + newc = curCol; + if( options.enableHackForGames == HACK_FOR_CONKER ) + newc = 0xFFFFFFFF; + break; + default: + newc = curCol; + break; + } + + if( flag&MUX_COMPLEMENT ) + { + newc.Complement(); + } + + if( flag&MUX_ALPHAREPLICATE ) + { + newc.AlphaReplicate(); + } + + return newc; +} + +COLOR CalculateConstFactor(uint32 colorOp, uint32 alphaOp, uint32 curCol) +{ + N64CombinerType m; + IColor color(curCol); + IColor alpha(curCol); + + // For color channel + *(uint32*)&m = colorOp; + if( m.c != MUX_0 && m.a!=m.b) + { + if( m.a != MUX_0 ) color = GetIColor(m.a, curCol); + if( m.b != MUX_0 ) color -= GetIColor(m.b, curCol); + if( m.c != MUX_1 ) color *= GetIColor(m.c, curCol); + } + if( m.d != MUX_0 ) color += GetIColor(m.d, curCol); + + // For alpha channel + *(uint32*)&m = alphaOp; + if( m.c != MUX_0 && m.a!=m.b) + { + if( m.a != MUX_0 ) alpha = GetIColor(m.a, curCol); + if( m.b != MUX_0 ) alpha -= GetIColor(m.b, curCol); + if( m.c != MUX_1 ) alpha *= GetIColor(m.c, curCol); + } + if( m.d != MUX_0 ) alpha += GetIColor(m.d, curCol); + + return (COLOR)(((uint32)color&0x00FFFFFF)|((uint32)alpha&0xFF000000)); +} + + +COLOR CColorCombiner::GetConstFactor(uint32 colorFlag, uint32 alphaFlag, uint32 defaultColor) +{ + // Allows a combine mode to select what TFACTOR should be + uint32 color = defaultColor; + uint32 alpha = defaultColor; + + switch (colorFlag&MUX_MASK) + { + case MUX_0: + break; + case MUX_FORCE_0: + color = 0; + break; + case MUX_1: + color = 0xFFFFFFFF; + break; + case MUX_PRIM: + color = gRDP.primitiveColor; + break; + case MUX_ENV: + color = gRDP.envColor; + break; + case MUX_LODFRAC: + color = COLOR_RGBA(gRDP.LODFrac, gRDP.LODFrac, gRDP.LODFrac, gRDP.LODFrac); + break; + case MUX_PRIMLODFRAC: + color = COLOR_RGBA(gRDP.primLODFrac, gRDP.primLODFrac, gRDP.primLODFrac, gRDP.primLODFrac); + break; + case MUX_PRIM_ALPHA: + { + IColor col(gRDP.primitiveColor); + col.AlphaReplicate(); + color = (COLOR)col; + } + break; + case MUX_ENV_ALPHA: + { + IColor col(gRDP.envColor); + col.AlphaReplicate(); + color = (COLOR)col; + } + break; + case MUX_K5: + color = 0xFFFFFFFF; + break; + case MUX_UNK: + color = defaultColor; + if( options.enableHackForGames == HACK_FOR_CONKER ) color = 0xFFFFFFFF; + break; + default: + color = defaultColor; + break; + } + + if( colorFlag & MUX_COMPLEMENT ) + { + color = 0xFFFFFFFF - color; + } + if( colorFlag & MUX_ALPHAREPLICATE ) + { + color = color>>24; + color = color | (color<<8) | (color <<16) | (color<<24); + } + + color &= 0x00FFFFFF; // For color channel only, not the alpha channel + + + switch (alphaFlag&MUX_MASK) + { + case MUX_0: + break; + case MUX_FORCE_0: + alpha = 0; + break; + case MUX_1: + alpha = 0xFFFFFFFF; + break; + case MUX_PRIM: + alpha = gRDP.primitiveColor; + break; + case MUX_ENV: + alpha = gRDP.envColor; + break; + case MUX_LODFRAC: + alpha = COLOR_RGBA(gRDP.LODFrac, gRDP.LODFrac, gRDP.LODFrac, gRDP.LODFrac); + break; + case MUX_PRIMLODFRAC: + alpha = COLOR_RGBA(gRDP.primLODFrac, gRDP.primLODFrac, gRDP.primLODFrac, gRDP.primLODFrac); + break; + case MUX_PRIM_ALPHA: + { + IColor col(gRDP.primitiveColor); + col.AlphaReplicate(); + alpha = (COLOR)col; + } + break; + case MUX_ENV_ALPHA: + { + IColor col(gRDP.envColor); + col.AlphaReplicate(); + alpha = (COLOR)col; + } + break; + default: + alpha = defaultColor; + break; + } + + if( alphaFlag & MUX_COMPLEMENT ) + { + alpha = 0xFFFFFFFF - alpha; + } + + alpha &= 0xFF000000; + + return (color|alpha); +} + +//***************************************************************************** +// +//***************************************************************************** +bool gUsingPrimColour = false; +bool gUsingEnvColour = false; + +int CountTexel1Cycle(N64CombinerType &m) +{ + int hasTexel[2]; + uint8 *p = (uint8*)&m; + + for( int i=0; i<2; i++) + { + hasTexel[i]=0; + for( int j=0; j<4; j++) + { + if( (p[j]&MUX_MASK) == MUX_TEXEL0+i ) + { + hasTexel[i]=1; + break; + } + } + } + + return hasTexel[0]+hasTexel[1]; +} + +uint32 GetTexelNumber(N64CombinerType &m) +{ + if( (m.a&MUX_MASK) == MUX_TEXEL1 || (m.b&MUX_MASK) == MUX_TEXEL1 || (m.c&MUX_MASK) == MUX_TEXEL1 || (m.d&MUX_MASK) == MUX_TEXEL1 ) + return TEX_1; + else + return TEX_0; +} + +bool IsTxtrUsed(N64CombinerType &m) +{ + if( (m.a&MUX_MASK) == MUX_TEXEL1 || (m.b&MUX_MASK) == MUX_TEXEL1 || (m.c&MUX_MASK) == MUX_TEXEL1 || (m.d&MUX_MASK) == MUX_TEXEL1 ) + return true; + if( (m.a&MUX_MASK) == MUX_TEXEL0 || (m.b&MUX_MASK) == MUX_TEXEL0 || (m.c&MUX_MASK) == MUX_TEXEL0 || (m.d&MUX_MASK) == MUX_TEXEL0 ) + return true; + else + return false; +} + +//======================================================================== + +void CColorCombiner::InitCombinerMode(void) +{ +#ifdef DEBUGGER + LOG_UCODE(cycleTypeStrs[gRDP.otherMode.cycle_type]); + if( debuggerDropDecodedMux ) + { + UpdateCombiner(m_pDecodedMux->m_dwMux0, m_pDecodedMux->m_dwMux1); + } +#endif + + if( currentRomOptions.bNormalCombiner ) + { + DisableCombiner(); + } + else if( gRDP.otherMode.cycle_type == CYCLE_TYPE_COPY ) + { + InitCombinerCycleCopy(); + m_bCycleChanged = true; + } + else if ( gRDP.otherMode.cycle_type == CYCLE_TYPE_FILL ) + //else if ( gRDP.otherMode.cycle_type == CYCLE_TYPE_FILL && gRSP.ucode != 5 ) //hack + { + InitCombinerCycleFill(); + m_bCycleChanged = true; + } + else + { + InitCombinerCycle12(); + m_bCycleChanged = false; + } +} + + +bool bConkerHideShadow=false; +void CColorCombiner::UpdateCombiner(uint32 dwMux0, uint32 dwMux1) +{ +#ifdef DEBUGGER + if( debuggerDropDecodedMux ) + { + debuggerDropDecodedMux = false; + m_pDecodedMux->m_dwMux0 = m_pDecodedMux->m_dwMux1 = 0; + m_DecodedMuxList.clear(); + } +#endif + + DecodedMux &m_decodedMux = *m_pDecodedMux; + if( m_decodedMux.m_dwMux0 != dwMux0 || m_decodedMux.m_dwMux1 != dwMux1 ) + { + if( options.enableHackForGames == HACK_FOR_DR_MARIO ) + { + // Hack for Dr. Mario + if( dwMux1 == 0xfffcf239 && + ((m_decodedMux.m_dwMux0 == dwMux0 && dwMux0 == 0x00ffffff && + m_decodedMux.m_dwMux1 != dwMux1 && m_decodedMux.m_dwMux1 == 0xfffcf279 ) || + (m_decodedMux.m_dwMux0 == 0x00ffb3ff && m_decodedMux.m_dwMux1 == 0xff64fe7f && dwMux0 == 0x00ffffff ) )) + { + //dwMux1 = 0xffcf23A; + dwMux1 = 0xfffcf438; + } + } + uint64 mux64 = (((uint64)dwMux1)<<32)+dwMux0; + int index=m_DecodedMuxList.find(mux64); + + if( options.enableHackForGames == HACK_FOR_CONKER ) + { + // Conker's shadow, to disable the shadow + //Mux=0x00ffe9ff Used in CONKER BFD + //Color0: (0 - 0) * 0 + SHADE + //Color1: (0 - 0) * 0 + SHADE + //Alpha0: (1 - TEXEL0) * SHADE + 0 + //Alpha1: (1 - TEXEL0) * SHADE + 0 + if( dwMux1 == 0xffd21f0f && dwMux0 == 0x00ffe9ff ) + { + bConkerHideShadow = true; + } + else + { + bConkerHideShadow = false; + } + } + + if( index >= 0 ) + { + m_decodedMux = m_DecodedMuxList[index]; + } + else + { + m_decodedMux.Decode(dwMux0, dwMux1); + m_decodedMux.splitType[0] = CM_FMT_TYPE_NOT_CHECKED; + m_decodedMux.splitType[1] = CM_FMT_TYPE_NOT_CHECKED; + m_decodedMux.splitType[2] = CM_FMT_TYPE_NOT_CHECKED; + m_decodedMux.splitType[3] = CM_FMT_TYPE_NOT_CHECKED; + + m_decodedMux.Hack(); + + if( !m_bSupportMultiTexture ) + { + m_decodedMux.ReplaceVal(MUX_TEXEL1, MUX_TEXEL0); + m_decodedMux.ReplaceVal(MUX_LODFRAC,1); + m_decodedMux.ReplaceVal(MUX_PRIMLODFRAC,1); + } + + m_decodedMux.Simplify(); + if( m_supportedStages>1) + m_decodedMux.SplitComplexStages(); + + m_DecodedMuxList.add(m_decodedMux.m_u64Mux, *m_pDecodedMux); +#ifdef DEBUGGER + if( logCombiners ) + { + TRACE0("Add a new mux"); + DisplayMuxString(); + } +#endif + } + + m_bTex0Enabled = m_decodedMux.m_bTexel0IsUsed; + m_bTex1Enabled = m_decodedMux.m_bTexel1IsUsed; + m_bTexelsEnable = m_bTex0Enabled||m_bTex1Enabled; + + gRSP.bProcessDiffuseColor = (m_decodedMux.m_dwShadeColorChannelFlag != MUX_0 || m_decodedMux.m_dwShadeAlphaChannelFlag != MUX_0); + gRSP.bProcessSpecularColor = false; + } +} + + +#ifdef DEBUGGER +void CColorCombiner::DisplayMuxString(void) +{ + if( gRDP.otherMode.cycle_type == CYCLE_TYPE_COPY) + { + TRACE0("COPY Mode\n"); + } + else if( gRDP.otherMode.cycle_type == CYCLE_TYPE_FILL) + { + TRACE0("FILL Mode\n"); + } + + m_pDecodedMux->DisplayMuxString("Used"); +} + +void CColorCombiner::DisplaySimpleMuxString(void) +{ + m_pDecodedMux->DisplaySimpliedMuxString("Used"); +} +#endif +