Path: blob/master/libmupen64plus/mupen64plus-video-rice/src/CNvTNTCombiner.cpp
2 views
/*1Copyright (C) 2003 Rice196423This program is free software; you can redistribute it and/or4modify it under the terms of the GNU General Public License5as published by the Free Software Foundation; either version 26of the License, or (at your option) any later version.78This program is distributed in the hope that it will be useful,9but WITHOUT ANY WARRANTY; without even the implied warranty of10MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the11GNU General Public License for more details.1213You should have received a copy of the GNU General Public License14along with this program; if not, write to the Free Software15Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.16*/1718#include <SDL_opengl.h>1920#include "CNvTNTCombiner.h"2122CNvTNTCombiner::CNvTNTCombiner()23{24m_lastIndexTNT = 0;25}2627CNvTNTCombiner::~CNvTNTCombiner()28{29}303132int CNvTNTCombiner::FindCompiledMux( )33{34for( uint32 i=0; i<m_vCompiledTNTSettings.size(); i++ )35{36if( m_vCompiledTNTSettings[i].dwMux0 == (*m_ppDecodedMux)->m_dwMux0 && m_vCompiledTNTSettings[i].dwMux1 == (*m_ppDecodedMux)->m_dwMux1 )37{38m_lastIndexTNT = i;39return i;40}41}4243return -1;44}4546bool isTex(uint32 val);47bool isComb(uint32 val);4849int CNvTNTCombiner::ParseDecodedMux()50{51TNT2CombinerSaveType res;52res.numOfUnits = 2;5354(*m_ppDecodedMux)->To_AB_Add_CD_Format();5556for( int i=0; i<res.numOfUnits*2; i++ ) // Set combiner for each texture unit57{58// For each texture unit, set both RGB and Alpha channel59// Keep in mind that the m_pDecodeMux has been reformated and simplified very well6061TNT2CombinerType &unit = res.units[i/2];62TNT2CombType &comb = unit.Combs[i%2];6364CombinerFormatType type = (*m_ppDecodedMux)->splitType[i];65N64CombinerType &m = (*m_ppDecodedMux)->m_n64Combiners[i];6667comb.arg0 = comb.arg1 = comb.arg2 = comb.arg3 = MUX_0;68unit.ops[i%2] = 0x0104; //Add;69//Subtract7071switch( type )72{73case CM_FMT_TYPE_NOT_USED:74comb.arg0 = MUX_COMBINED;75comb.arg1 = MUX_1;76comb.arg2 = MUX_0;77comb.arg3 = MUX_1;78case CM_FMT_TYPE_D: // = A79comb.arg0 = m.d;80comb.arg1 = MUX_1;81comb.arg2 = MUX_0;82comb.arg3 = MUX_0;83break;84case CM_FMT_TYPE_A_ADD_D: // = A+D85comb.arg0 = m.a;86comb.arg1 = MUX_1;87comb.arg2 = m.d;88comb.arg3 = MUX_1;89if( isComb(m.d) )90{91swap(comb.arg0, comb.arg2);92swap(comb.arg1, comb.arg3);93}94break;95case CM_FMT_TYPE_A_SUB_B: // = A-B96comb.arg0 = m.a^MUX_COMPLEMENT;97comb.arg1 = MUX_1;98unit.ops[i%2] = GL_SUBTRACT_ARB;99comb.arg2 = m.b;100comb.arg3 = MUX_1;101break;102case CM_FMT_TYPE_A_MOD_C: // = A*C103comb.arg0 = m.a;104comb.arg1 = m.c;105comb.arg2 = MUX_0;106comb.arg3 = MUX_0;107break;108case CM_FMT_TYPE_A_MOD_C_ADD_D: // = A*C+D109comb.arg0 = m.a;110comb.arg1 = m.c;111comb.arg2 = m.d;112comb.arg3 = MUX_1;113if( isComb(m.d) )114{115swap(comb.arg0, comb.arg2);116swap(comb.arg1, comb.arg3);117}118break;119case CM_FMT_TYPE_A_LERP_B_C: // = (A-B)*C+B120comb.arg0 = m.a;121comb.arg1 = m.c;122comb.arg2 = m.c^MUX_COMPLEMENT;123comb.arg3 = m.b;124if( isComb(m.b) )125{126swap(comb.arg0, comb.arg2);127swap(comb.arg1, comb.arg3);128}129break;130case CM_FMT_TYPE_A_SUB_B_ADD_D: // = A-B+D131// fix me, to use 2 texture units132if( isTex(m.b) && isTex(m.d) )133{134comb.arg0 = m.a;135comb.arg1 = m.b;136comb.arg2 = m.d;137comb.arg3 = MUX_1;138if( isComb(m.d) )139{140swap(comb.arg0, comb.arg2);141swap(comb.arg1, comb.arg3);142}143}144else if( isTex(m.b) && !isComb(m.d) )145{146comb.arg0 = m.a^MUX_COMPLEMENT;147comb.arg1 = MUX_1;148comb.arg2 = m.b;149comb.arg3 = MUX_1;150unit.ops[i%2] = GL_SUBTRACT_ARB;151}152else if( !isTex(m.b) && isTex(m.d) )153{154comb.arg0 = m.a;155comb.arg1 = MUX_1;156comb.arg2 = m.d;157comb.arg3 = MUX_1;158if( isComb(m.d) )159{160swap(comb.arg0, comb.arg2);161swap(comb.arg1, comb.arg3);162}163}164else165{166comb.arg0 = m.a;167comb.arg1 = m.b;168comb.arg2 = m.d;169comb.arg3 = MUX_1;170if( isComb(m.d) )171{172swap(comb.arg0, comb.arg2);173swap(comb.arg1, comb.arg3);174}175}176break;177case CM_FMT_TYPE_A_SUB_B_MOD_C: // = (A-B)*C178comb.arg0 = m.a^MUX_COMPLEMENT;179comb.arg1 = m.c;180comb.arg2 = m.c;181comb.arg3 = m.b;182unit.ops[i%2] = GL_SUBTRACT_ARB;183break;184case CM_FMT_TYPE_AB_ADD_CD: // = AB+CD185comb.arg0 = m.a;186comb.arg1 = m.b;187comb.arg2 = m.c;188comb.arg3 = m.d;189if( isComb(m.d) || isComb(m.c) )190{191swap(comb.arg0, comb.arg2);192swap(comb.arg1, comb.arg3);193}194195break;196case CM_FMT_TYPE_AB_SUB_CD: // = AB-CD197comb.arg0 = m.a^MUX_COMPLEMENT;198comb.arg1 = m.b;199unit.ops[i%2] = GL_SUBTRACT_ARB;200comb.arg2 = m.c;201comb.arg3 = m.d;202break;203case CM_FMT_TYPE_A_B_C_D: // = (A-B)*C+D204default:205if( !isComb(m.d) && !isTex(m.d) )206{207comb.arg0 = m.a^MUX_COMPLEMENT;208comb.arg1 = m.c;209unit.ops[i%2] = GL_SUBTRACT_ARB;210comb.arg2 = m.c;211comb.arg3 = m.b;212}213else if( !isComb(m.b) && !isTex(m.b) )214{215comb.arg0 = m.a;216comb.arg1 = m.c;217comb.arg2 = m.d;218comb.arg3 = MUX_1;219if( isComb(m.d) )220{221swap(comb.arg0, comb.arg2);222swap(comb.arg1, comb.arg3);223}224}225else if( !isComb(m.c) && !isTex(m.c) )226{227comb.arg0 = m.a;228comb.arg1 = m.b;229comb.arg2 = m.d;230comb.arg3 = MUX_1;231if( isComb(m.d) )232{233swap(comb.arg0, comb.arg2);234swap(comb.arg1, comb.arg3);235}236}237else238{239comb.arg0 = m.a;240comb.arg1 = m.c;241comb.arg2 = m.d;242comb.arg3 = MUX_1;243if( isComb(m.d) )244{245swap(comb.arg0, comb.arg2);246swap(comb.arg1, comb.arg3);247}248}249break;250}251}252253ParseDecodedMuxForConstants(res);254return SaveParserResult(res);255}256257int CNvTNTCombiner::SaveParserResult(TNT2CombinerSaveType &result)258{259result.dwMux0 = (*m_ppDecodedMux)->m_dwMux0;260result.dwMux1 = (*m_ppDecodedMux)->m_dwMux1;261262m_vCompiledTNTSettings.push_back(result);263m_lastIndexTNT = m_vCompiledTNTSettings.size()-1;264265#ifdef DEBUGGER266if( logCombiners )267{268DisplaySimpleMuxString();269}270#endif271272return m_lastIndexTNT;273}274275void CNvTNTCombiner::ParseDecodedMuxForConstants(TNT2CombinerSaveType &res)276{277res.unit1.constant = MUX_0;278res.unit2.constant = MUX_0;279280for( int i=0; i<2; i++ )281{282if( (*m_ppDecodedMux)->isUsedInCycle(MUX_PRIM, i,COLOR_CHANNEL) || (*m_ppDecodedMux)->isUsedInCycle(MUX_PRIM, i,ALPHA_CHANNEL) )283{284res.units[i].constant = MUX_PRIM;285}286else if( (*m_ppDecodedMux)->isUsedInCycle(MUX_ENV, i,COLOR_CHANNEL) || (*m_ppDecodedMux)->isUsedInCycle(MUX_ENV, i,ALPHA_CHANNEL) )287{288res.units[i].constant = MUX_ENV;289}290else if( (*m_ppDecodedMux)->isUsedInCycle(MUX_LODFRAC, i,COLOR_CHANNEL) || (*m_ppDecodedMux)->isUsedInCycle(MUX_LODFRAC, i,ALPHA_CHANNEL) )291{292res.units[i].constant = MUX_LODFRAC;293}294else if( (*m_ppDecodedMux)->isUsedInCycle(MUX_PRIMLODFRAC, i,COLOR_CHANNEL) || (*m_ppDecodedMux)->isUsedInCycle(MUX_PRIMLODFRAC, i,ALPHA_CHANNEL) )295{296res.units[i].constant = MUX_PRIMLODFRAC;297}298}299}300301#ifdef DEBUGGER302extern const char *translatedCombTypes[];303void CNvTNTCombiner::DisplaySimpleMuxString()304{305char buf0[30];306char buf1[30];307char buf2[30];308char buf3[30];309310TNT2CombinerSaveType &result = m_vCompiledTNTSettings[m_lastIndexTNT];311312TRACE0("\nNVidia TNT2+ Combiner\n");313DebuggerAppendMsg("//aRGB0:\t(%s * %s) %s (%s * %s)\n", DecodedMux::FormatStr(result.unit1.rgbArg0,buf0), DecodedMux::FormatStr(result.unit1.rgbArg1,buf1), result.unit1.rgbOp==0x0104?"+":"-", DecodedMux::FormatStr(result.unit1.rgbArg2,buf2), DecodedMux::FormatStr(result.unit1.rgbArg3,buf3));314DebuggerAppendMsg("//aRGB1:\t(%s * %s) %s (%s * %s)\n", DecodedMux::FormatStr(result.unit2.rgbArg0,buf0), DecodedMux::FormatStr(result.unit2.rgbArg1,buf1), result.unit2.rgbOp==0x0104?"+":"-", DecodedMux::FormatStr(result.unit2.rgbArg2,buf2), DecodedMux::FormatStr(result.unit2.rgbArg3,buf3));315DebuggerAppendMsg("//aAlpha0:\t(%s * %s) %s (%s * %s)\n", DecodedMux::FormatStr(result.unit1.alphaArg0,buf0), DecodedMux::FormatStr(result.unit1.alphaArg1,buf1), result.unit1.alphaOp==0x0104?"+":"-", DecodedMux::FormatStr(result.unit1.alphaArg2,buf2), DecodedMux::FormatStr(result.unit1.alphaArg3,buf3));316DebuggerAppendMsg("//aAlpha1:\t(%s * %s) %s (%s * %s)\n", DecodedMux::FormatStr(result.unit2.alphaArg0,buf0), DecodedMux::FormatStr(result.unit2.alphaArg1,buf1), result.unit2.alphaOp==0x0104?"+":"-", DecodedMux::FormatStr(result.unit2.alphaArg2,buf2), DecodedMux::FormatStr(result.unit2.alphaArg3,buf3));317if( result.unit1.constant != MUX_0 )318DebuggerAppendMsg("//Constant for unit 1:\t%s\n", DecodedMux::FormatStr(result.unit1.constant,buf0));319if( result.unit2.constant != MUX_0 )320DebuggerAppendMsg("//Constant for unit 2:\t%s\n", DecodedMux::FormatStr(result.unit2.constant,buf0));321TRACE0("\n\n");322}323#endif324325326327