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
//-----------------------------------------------------------------------------
37
//-----------------------------------------------------------------------------
38
AdvancedCombinerManager::AdvancedCombinerManager()
44
//-----------------------------------------------------------------------------
46
//-----------------------------------------------------------------------------
47
AdvancedCombinerManager::~AdvancedCombinerManager()
52
//-----------------------------------------------------------------------------
54
//! Selects sutible combiner and initializes it
55
//-----------------------------------------------------------------------------
56
void AdvancedCombinerManager::initialize()
61
switch ( ROMDetector::getSingleton().getCombinerType() )
64
m_combiner = new DummyCombiner();
68
m_combiner = new SimpleTexEnvCombiner();
73
m_combiner = new AdvancedTexEnvCombiner();
78
m_combiner->initialize();
81
//-----------------------------------------------------------------------------
83
//-----------------------------------------------------------------------------
84
void AdvancedCombinerManager::dispose()
86
if ( m_combiner ) { delete m_combiner; m_combiner = 0; }
87
m_combinerCache.dispose();
90
//-----------------------------------------------------------------------------
92
//-----------------------------------------------------------------------------
93
void AdvancedCombinerManager::selectCombine(unsigned int cycleType)
95
//Hack for the Banjo-Tooie shadow
96
if ( cycleType == G_CYC_1CYCLE && m_combineData.mux == 0x00ffe7ffffcf9fcfLL )
98
m_combineData.mux = 71943244815007743LL;
99
m_combiner->setBlendColor(0,0,0,0);
100
m_combiner->setPrimColor(0,0,0,0);
101
m_combiner->setEnvColor(0,0,0,0);
102
m_combiner->setFillColor(0,0,0,0);
105
CachedCombiner* old = m_combinerCache.findCachedCombiner(m_combineData.mux);
109
//Cound not find an old combiner
110
this->update(cycleType); //Create a new combiner
114
currentTexEnv = old->compiled;
117
//Set Texture Enviroment
118
this->endTextureUpdate();
121
//-----------------------------------------------------------------------------
122
//! Update Combine Colors
123
//-----------------------------------------------------------------------------
124
void AdvancedCombinerManager::updateCombineColors()
126
m_combiner->setTextureEnviromentColors( currentTexEnv );
129
//-----------------------------------------------------------------------------
131
//-----------------------------------------------------------------------------
132
void AdvancedCombinerManager::update(unsigned int cycleType)
136
Combiner colorCombiner;
137
Combiner alphaCombiner;
139
//Set number of cycles
140
if ( cycleType == G_CYC_2CYCLE )
143
colorCombiner.numStages = 2;
144
alphaCombiner.numStages = 2;
149
colorCombiner.numStages = 1;
150
alphaCombiner.numStages = 1;
153
CombineCycle colorCycle[2];
154
CombineCycle alphaCycle[2];
156
// Decode and expand the combine mode into a more general form
157
colorCycle[0].loadValue = saRGBExpanded[m_combineData.saRGB0];
158
colorCycle[0].subValue = sbRGBExpanded[m_combineData.sbRGB0];
159
colorCycle[0].multValue = mRGBExpanded[m_combineData.mRGB0];
160
colorCycle[0].addValue = aRGBExpanded[m_combineData.aRGB0];
161
colorCycle[1].loadValue = saRGBExpanded[m_combineData.saRGB1];
162
colorCycle[1].subValue = sbRGBExpanded[m_combineData.sbRGB1];
163
colorCycle[1].multValue = mRGBExpanded[m_combineData.mRGB1];
164
colorCycle[1].addValue = aRGBExpanded[m_combineData.aRGB1];
166
alphaCycle[0].loadValue = saAExpanded[m_combineData.saA0];
167
alphaCycle[0].subValue = sbAExpanded[m_combineData.sbA0];
168
alphaCycle[0].multValue = mAExpanded[m_combineData.mA0];
169
alphaCycle[0].addValue = aAExpanded[m_combineData.aA0];
170
alphaCycle[1].loadValue = saAExpanded[m_combineData.saA1];
171
alphaCycle[1].subValue = sbAExpanded[m_combineData.sbA1];
172
alphaCycle[1].multValue = mAExpanded[m_combineData.mA1];
173
alphaCycle[1].addValue = aAExpanded[m_combineData.aA1];
176
for (int i=0; i<numCycles; ++i)
178
//Set stages on color combiner
179
setStage(&colorCycle[i], &colorCombiner.stage[i]);
181
//Set stages on alpha combiner
182
setStage(&alphaCycle[i], &alphaCombiner.stage[i]);
187
// Attempt to merge the two stages into one
188
mergeStages( &colorCombiner );
189
mergeStages( &alphaCombiner );
192
//Create New Enviroment
193
currentTexEnv = m_combiner->createNewTextureEnviroment(&colorCombiner, &alphaCombiner);
195
if ( !ROMDetector::getSingleton().getUseMultiTexture() )
197
currentTexEnv->usesT1 = false;
200
//Store combiner for reuse
201
m_combinerCache.newCompiledCombiner(m_combineData.mux, currentTexEnv);
204
//-----------------------------------------------------------------------------
206
//-----------------------------------------------------------------------------
207
void AdvancedCombinerManager::setMux(unsigned long long mux, unsigned int cycleType)
209
m_combineData.mux = mux;
212
//-----------------------------------------------------------------------------
214
//-----------------------------------------------------------------------------
215
void AdvancedCombinerManager::setMux(unsigned int muxs0, unsigned int muxs1, unsigned int cycleType)
217
m_combineData.muxs0 = muxs0;
218
m_combineData.muxs1 = muxs1;
221
//-----------------------------------------------------------------------------
222
//! Begin Texture Update
223
//-----------------------------------------------------------------------------
224
void AdvancedCombinerManager::beginTextureUpdate()
226
m_combiner->beginTextureUpdate();
229
//-----------------------------------------------------------------------------
230
//! End Texture Update
231
//-----------------------------------------------------------------------------
232
void AdvancedCombinerManager::endTextureUpdate()
234
//Set Texture Enviroment
235
m_combiner->setTextureEnviroment(currentTexEnv);
238
//-----------------------------------------------------------------------------
239
//* Get Combiner Color
240
//! Get Combiner Color which will be assigned to vertices
241
//-----------------------------------------------------------------------------
242
void AdvancedCombinerManager::getCombinerColor(float out[4])
244
m_combiner->getCombinerColor(out, currentTexEnv->vertex.color, currentTexEnv->vertex.alpha);
247
//-----------------------------------------------------------------------------
248
//* Get Secondary Combiner Color
249
//! Get Secondary Combiner Color which will be assigned to vertices
250
//-----------------------------------------------------------------------------
251
void AdvancedCombinerManager::getSecondaryCombinerColor(float out[4])
253
if ( !ROMDetector::getSingleton().getUseSecondaryColor() )
259
m_combiner->getCombinerColor(out, currentTexEnv->vertex.secondaryColor, ONE);
262
//-----------------------------------------------------------------------------
264
//! @return Fill Color as <r,g,b,a> (0.0 - 1.0)
265
//-----------------------------------------------------------------------------
266
float* AdvancedCombinerManager::getFillColor()
268
return m_combiner->getFillColor();
271
//-----------------------------------------------------------------------------
273
//! @return Blend Color as <r,g,b,a> (0.0 - 1.0)
274
//-----------------------------------------------------------------------------
275
float* AdvancedCombinerManager::getBlendColor()
277
return m_combiner->getBlendColor();
280
//-----------------------------------------------------------------------------
282
//! @return Prim Color as <r,g,b,a> (0.0 - 1.0)
283
//-----------------------------------------------------------------------------
284
float* AdvancedCombinerManager::getPrimColor()
286
return m_combiner->getPrimColor();
289
//-----------------------------------------------------------------------------
291
//! @param r Red component of color (0.0 - 1.0)
292
//! @param g Green component of color (0.0 - 1.0)
293
//! @param b Blue component of color (0.0 - 1.0)
294
//! @param a Alpha component of color (0.0 - 1.0)
295
//-----------------------------------------------------------------------------
296
void AdvancedCombinerManager::setFillColor (float r, float g, float b, float a)
298
m_combiner->setFillColor(r,g,b,a);
301
//-----------------------------------------------------------------------------
303
//! @param r Red component of color (0.0 - 1.0)
304
//! @param g Green component of color (0.0 - 1.0)
305
//! @param b Blue component of color (0.0 - 1.0)
306
//! @param a Alpha component of color (0.0 - 1.0)
307
//-----------------------------------------------------------------------------
308
void AdvancedCombinerManager::setBlendColor(float r, float g, float b, float a)
310
m_combiner->setBlendColor(r,g,b,a);
313
//-----------------------------------------------------------------------------
315
//! @param r Red component of color (0.0 - 1.0)
316
//! @param g Green component of color (0.0 - 1.0)
317
//! @param b Blue component of color (0.0 - 1.0)
318
//! @param a Alpha component of color (0.0 - 1.0)
319
//-----------------------------------------------------------------------------
320
void AdvancedCombinerManager::setPrimColor (float r, float g, float b, float a)
322
m_combiner->setPrimColor(r,g,b,a);
325
//-----------------------------------------------------------------------------
326
//! Set Environment Color
327
//! @param r Red component of color (0.0 - 1.0)
328
//! @param g Green component of color (0.0 - 1.0)
329
//! @param b Blue component of color (0.0 - 1.0)
330
//! @param a Alpha component of color (0.0 - 1.0)
331
//-----------------------------------------------------------------------------
332
void AdvancedCombinerManager::setEnvColor (float r, float g, float b, float a)
334
m_combiner->setEnvColor(r,g,b,a);
337
//-----------------------------------------------------------------------------
339
//! @param primLodMin
340
//-----------------------------------------------------------------------------
341
void AdvancedCombinerManager::setPrimLodMin(unsigned int primLodMin)
343
m_combiner->setPrimLodMin(primLodMin);
346
//-----------------------------------------------------------------------------
347
//* Set Prim LOD Frac
348
//! @param primLodFrac
349
//-----------------------------------------------------------------------------
350
void AdvancedCombinerManager::setPrimLodFrac(float primLodFrac)
352
m_combiner->setPrimLodFrac(primLodFrac);