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 *****************************************************************************/
22 #include "AdvancedCombinerManager.h"
23 #include "CombinerStructs.h"
24 #include "ExtensionChecker.h"
25 #include "MultiTexturingExt.h"
26 #include "AdvancedTexEnvCombiner.h"
27 #include "SimpleTexEnvCombiner.h"
28 #include "DummyCombiner.h"
29 #include "CombinerStageMerger.h"
30 #include "CombinerStageCreator.h"
31 #include "RomDetector.h"
35 static int saRGBExpanded[] =
37 COMBINED, TEXEL0, TEXEL1, PRIMITIVE,
38 SHADE, ENVIRONMENT, ONE, NOISE,
39 ZERO, ZERO, ZERO, ZERO,
40 ZERO, ZERO, ZERO, ZERO
43 static int sbRGBExpanded[] =
45 COMBINED, TEXEL0, TEXEL1, PRIMITIVE,
46 SHADE, ENVIRONMENT, CENTER, K4,
47 ZERO, ZERO, ZERO, ZERO,
48 ZERO, ZERO, ZERO, ZERO
51 static int mRGBExpanded[] =
53 COMBINED, TEXEL0, TEXEL1, PRIMITIVE,
54 SHADE, ENVIRONMENT, SCALE, COMBINED_ALPHA,
55 TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA, SHADE_ALPHA,
56 ENV_ALPHA, LOD_FRACTION, PRIM_LOD_FRAC, K5,
57 ZERO, ZERO, ZERO, ZERO,
58 ZERO, ZERO, ZERO, ZERO,
59 ZERO, ZERO, ZERO, ZERO,
60 ZERO, ZERO, ZERO, ZERO
63 static int aRGBExpanded[] =
65 COMBINED, TEXEL0, TEXEL1, PRIMITIVE,
66 SHADE, ENVIRONMENT, ONE, ZERO
69 static int saAExpanded[] =
71 COMBINED, TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA,
72 SHADE_ALPHA, ENV_ALPHA, ONE, ZERO
75 static int sbAExpanded[] =
77 COMBINED, TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA,
78 SHADE_ALPHA, ENV_ALPHA, ONE, ZERO
81 static int mAExpanded[] =
83 LOD_FRACTION, TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA,
84 SHADE_ALPHA, ENV_ALPHA, PRIM_LOD_FRAC, ZERO,
87 static int aAExpanded[] =
89 COMBINED, TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA,
90 SHADE_ALPHA, ENV_ALPHA, ONE, ZERO
93 //-----------------------------------------------------------------------------
95 //-----------------------------------------------------------------------------
96 AdvancedCombinerManager::AdvancedCombinerManager()
102 //-----------------------------------------------------------------------------
104 //-----------------------------------------------------------------------------
105 AdvancedCombinerManager::~AdvancedCombinerManager()
110 //-----------------------------------------------------------------------------
112 //! Selects sutible combiner and initializes it
113 //-----------------------------------------------------------------------------
114 void AdvancedCombinerManager::initialize()
119 switch ( ROMDetector::getSingleton().getCombinerType() )
122 m_combiner = new DummyCombiner();
126 m_combiner = new SimpleTexEnvCombiner();
131 m_combiner = new AdvancedTexEnvCombiner();
136 m_combiner->initialize();
139 //-----------------------------------------------------------------------------
141 //-----------------------------------------------------------------------------
142 void AdvancedCombinerManager::dispose()
144 if ( m_combiner ) { delete m_combiner; m_combiner = 0; }
145 m_combinerCache.dispose();
148 //-----------------------------------------------------------------------------
150 //-----------------------------------------------------------------------------
151 void AdvancedCombinerManager::selectCombine(unsigned int cycleType)
153 //Hack for the Banjo-Tooie shadow
154 if ( cycleType == G_CYC_1CYCLE && m_combineData.mux == 0x00ffe7ffffcf9fcfLL )
156 m_combineData.mux = 71943244815007743LL;
157 m_combiner->setBlendColor(0,0,0,0);
158 m_combiner->setPrimColor(0,0,0,0);
159 m_combiner->setEnvColor(0,0,0,0);
160 m_combiner->setFillColor(0,0,0,0);
163 CachedCombiner* old = m_combinerCache.findCachedCombiner(m_combineData.mux);
167 //Cound not find an old combiner
168 this->update(cycleType); //Create a new combiner
172 currentTexEnv = old->compiled;
175 //Set Texture Enviroment
176 this->endTextureUpdate();
179 //-----------------------------------------------------------------------------
180 //! Update Combine Colors
181 //-----------------------------------------------------------------------------
182 void AdvancedCombinerManager::updateCombineColors()
184 m_combiner->setTextureEnviromentColors( currentTexEnv );
187 //-----------------------------------------------------------------------------
189 //-----------------------------------------------------------------------------
190 void AdvancedCombinerManager::update(unsigned int cycleType)
194 Combiner colorCombiner;
195 Combiner alphaCombiner;
197 //Set number of cycles
198 if ( cycleType == G_CYC_2CYCLE )
201 colorCombiner.numStages = 2;
202 alphaCombiner.numStages = 2;
207 colorCombiner.numStages = 1;
208 alphaCombiner.numStages = 1;
211 CombineCycle colorCycle[2];
212 CombineCycle alphaCycle[2];
214 // Decode and expand the combine mode into a more general form
215 colorCycle[0].loadValue = saRGBExpanded[m_combineData.saRGB0];
216 colorCycle[0].subValue = sbRGBExpanded[m_combineData.sbRGB0];
217 colorCycle[0].multValue = mRGBExpanded[m_combineData.mRGB0];
218 colorCycle[0].addValue = aRGBExpanded[m_combineData.aRGB0];
219 colorCycle[1].loadValue = saRGBExpanded[m_combineData.saRGB1];
220 colorCycle[1].subValue = sbRGBExpanded[m_combineData.sbRGB1];
221 colorCycle[1].multValue = mRGBExpanded[m_combineData.mRGB1];
222 colorCycle[1].addValue = aRGBExpanded[m_combineData.aRGB1];
224 alphaCycle[0].loadValue = saAExpanded[m_combineData.saA0];
225 alphaCycle[0].subValue = sbAExpanded[m_combineData.sbA0];
226 alphaCycle[0].multValue = mAExpanded[m_combineData.mA0];
227 alphaCycle[0].addValue = aAExpanded[m_combineData.aA0];
228 alphaCycle[1].loadValue = saAExpanded[m_combineData.saA1];
229 alphaCycle[1].subValue = sbAExpanded[m_combineData.sbA1];
230 alphaCycle[1].multValue = mAExpanded[m_combineData.mA1];
231 alphaCycle[1].addValue = aAExpanded[m_combineData.aA1];
234 for (int i=0; i<numCycles; ++i)
236 //Set stages on color combiner
237 setStage(&colorCycle[i], &colorCombiner.stage[i]);
239 //Set stages on alpha combiner
240 setStage(&alphaCycle[i], &alphaCombiner.stage[i]);
245 // Attempt to merge the two stages into one
246 mergeStages( &colorCombiner );
247 mergeStages( &alphaCombiner );
250 //Create New Enviroment
251 currentTexEnv = m_combiner->createNewTextureEnviroment(&colorCombiner, &alphaCombiner);
253 if ( !ROMDetector::getSingleton().getUseMultiTexture() )
255 currentTexEnv->usesT1 = false;
258 //Store combiner for reuse
259 m_combinerCache.newCompiledCombiner(m_combineData.mux, currentTexEnv);
262 //-----------------------------------------------------------------------------
264 //-----------------------------------------------------------------------------
265 void AdvancedCombinerManager::setMux(unsigned long long mux, unsigned int cycleType)
267 m_combineData.mux = mux;
270 //-----------------------------------------------------------------------------
272 //-----------------------------------------------------------------------------
273 void AdvancedCombinerManager::setMux(unsigned int muxs0, unsigned int muxs1, unsigned int cycleType)
275 m_combineData.muxs0 = muxs0;
276 m_combineData.muxs1 = muxs1;
279 //-----------------------------------------------------------------------------
280 //! Begin Texture Update
281 //-----------------------------------------------------------------------------
282 void AdvancedCombinerManager::beginTextureUpdate()
284 m_combiner->beginTextureUpdate();
287 //-----------------------------------------------------------------------------
288 //! End Texture Update
289 //-----------------------------------------------------------------------------
290 void AdvancedCombinerManager::endTextureUpdate()
292 //Set Texture Enviroment
293 m_combiner->setTextureEnviroment(currentTexEnv);
296 //-----------------------------------------------------------------------------
297 //* Get Combiner Color
298 //! Get Combiner Color which will be assigned to vertices
299 //-----------------------------------------------------------------------------
300 void AdvancedCombinerManager::getCombinerColor(float out[4])
302 m_combiner->getCombinerColor(out, currentTexEnv->vertex.color, currentTexEnv->vertex.alpha);
305 //-----------------------------------------------------------------------------
306 //* Get Secondary Combiner Color
307 //! Get Secondary Combiner Color which will be assigned to vertices
308 //-----------------------------------------------------------------------------
309 void AdvancedCombinerManager::getSecondaryCombinerColor(float out[4])
311 if ( !ROMDetector::getSingleton().getUseSecondaryColor() )
317 m_combiner->getCombinerColor(out, currentTexEnv->vertex.secondaryColor, ONE);
320 //-----------------------------------------------------------------------------
322 //! @return Fill Color as <r,g,b,a> (0.0 - 1.0)
323 //-----------------------------------------------------------------------------
324 float* AdvancedCombinerManager::getFillColor()
326 return m_combiner->getFillColor();
329 //-----------------------------------------------------------------------------
331 //! @return Blend Color as <r,g,b,a> (0.0 - 1.0)
332 //-----------------------------------------------------------------------------
333 float* AdvancedCombinerManager::getBlendColor()
335 return m_combiner->getBlendColor();
338 //-----------------------------------------------------------------------------
340 //! @return Prim Color as <r,g,b,a> (0.0 - 1.0)
341 //-----------------------------------------------------------------------------
342 float* AdvancedCombinerManager::getPrimColor()
344 return m_combiner->getPrimColor();
347 //-----------------------------------------------------------------------------
349 //! @param r Red component of color (0.0 - 1.0)
350 //! @param g Green component of color (0.0 - 1.0)
351 //! @param b Blue component of color (0.0 - 1.0)
352 //! @param a Alpha component of color (0.0 - 1.0)
353 //-----------------------------------------------------------------------------
354 void AdvancedCombinerManager::setFillColor (float r, float g, float b, float a)
356 m_combiner->setFillColor(r,g,b,a);
359 //-----------------------------------------------------------------------------
361 //! @param r Red component of color (0.0 - 1.0)
362 //! @param g Green component of color (0.0 - 1.0)
363 //! @param b Blue component of color (0.0 - 1.0)
364 //! @param a Alpha component of color (0.0 - 1.0)
365 //-----------------------------------------------------------------------------
366 void AdvancedCombinerManager::setBlendColor(float r, float g, float b, float a)
368 m_combiner->setBlendColor(r,g,b,a);
371 //-----------------------------------------------------------------------------
373 //! @param r Red component of color (0.0 - 1.0)
374 //! @param g Green component of color (0.0 - 1.0)
375 //! @param b Blue component of color (0.0 - 1.0)
376 //! @param a Alpha component of color (0.0 - 1.0)
377 //-----------------------------------------------------------------------------
378 void AdvancedCombinerManager::setPrimColor (float r, float g, float b, float a)
380 m_combiner->setPrimColor(r,g,b,a);
383 //-----------------------------------------------------------------------------
384 //! Set Environment Color
385 //! @param r Red component of color (0.0 - 1.0)
386 //! @param g Green component of color (0.0 - 1.0)
387 //! @param b Blue component of color (0.0 - 1.0)
388 //! @param a Alpha component of color (0.0 - 1.0)
389 //-----------------------------------------------------------------------------
390 void AdvancedCombinerManager::setEnvColor (float r, float g, float b, float a)
392 m_combiner->setEnvColor(r,g,b,a);
395 //-----------------------------------------------------------------------------
397 //! @param primLodMin
398 //-----------------------------------------------------------------------------
399 void AdvancedCombinerManager::setPrimLodMin(unsigned int primLodMin)
401 m_combiner->setPrimLodMin(primLodMin);
404 //-----------------------------------------------------------------------------
405 //* Set Prim LOD Frac
406 //! @param primLodFrac
407 //-----------------------------------------------------------------------------
408 void AdvancedCombinerManager::setPrimLodFrac(float primLodFrac)
410 m_combiner->setPrimLodFrac(primLodFrac);