Arachnoid GLESv1.1 plugin. Compile and run (a bit glitchy and no frameskip) on the...
[mupen64plus-pandora.git] / source / mupen64plus-video-arachnoid / src / Combiner / AdvancedCombinerManager.cpp
CommitLineData
22726e4d 1/******************************************************************************
2 * Arachnoid Graphics Plugin for Mupen64Plus
3 * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
4 *
5 * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
6 *
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.
11 *
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.
16 *
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 *****************************************************************************/
21
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"
32#include "m64p.h"
33#include "OpenGL.h"
34
35static int saRGBExpanded[] =
36{
37 COMBINED, TEXEL0, TEXEL1, PRIMITIVE,
38 SHADE, ENVIRONMENT, ONE, NOISE,
39 ZERO, ZERO, ZERO, ZERO,
40 ZERO, ZERO, ZERO, ZERO
41};
42
43static int sbRGBExpanded[] =
44{
45 COMBINED, TEXEL0, TEXEL1, PRIMITIVE,
46 SHADE, ENVIRONMENT, CENTER, K4,
47 ZERO, ZERO, ZERO, ZERO,
48 ZERO, ZERO, ZERO, ZERO
49};
50
51static int mRGBExpanded[] =
52{
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
61};
62
63static int aRGBExpanded[] =
64{
65 COMBINED, TEXEL0, TEXEL1, PRIMITIVE,
66 SHADE, ENVIRONMENT, ONE, ZERO
67};
68
69static int saAExpanded[] =
70{
71 COMBINED, TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA,
72 SHADE_ALPHA, ENV_ALPHA, ONE, ZERO
73};
74
75static int sbAExpanded[] =
76{
77 COMBINED, TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA,
78 SHADE_ALPHA, ENV_ALPHA, ONE, ZERO
79};
80
81static int mAExpanded[] =
82{
83 LOD_FRACTION, TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA,
84 SHADE_ALPHA, ENV_ALPHA, PRIM_LOD_FRAC, ZERO,
85};
86
87static int aAExpanded[] =
88{
89 COMBINED, TEXEL0_ALPHA, TEXEL1_ALPHA, PRIMITIVE_ALPHA,
90 SHADE_ALPHA, ENV_ALPHA, ONE, ZERO
91};
92
93//-----------------------------------------------------------------------------
94//! Constructor
95//-----------------------------------------------------------------------------
96AdvancedCombinerManager::AdvancedCombinerManager()
97{
98 currentTexEnv = 0;
99 m_combiner = 0;
100}
101
102//-----------------------------------------------------------------------------
103//! Destructor
104//-----------------------------------------------------------------------------
105AdvancedCombinerManager::~AdvancedCombinerManager()
106{
107 dispose();
108}
109
110//-----------------------------------------------------------------------------
111//* Initialize
112//! Selects sutible combiner and initializes it
113//-----------------------------------------------------------------------------
114void AdvancedCombinerManager::initialize()
115{
116 currentTexEnv = 0;
117
118 //Select Combiner
119 switch ( ROMDetector::getSingleton().getCombinerType() )
120 {
121 case CT_DUMMY:
122 m_combiner = new DummyCombiner();
123 break;
124
125 case CT_SIMPLE:
126 m_combiner = new SimpleTexEnvCombiner();
127 break;
128
129 case CT_ADVANCED:
130 default:
131 m_combiner = new AdvancedTexEnvCombiner();
132 break;
133 }
134
135 //init combiner
136 m_combiner->initialize();
137}
138
139//-----------------------------------------------------------------------------
140//! Dispose
141//-----------------------------------------------------------------------------
142void AdvancedCombinerManager::dispose()
143{
144 if ( m_combiner ) { delete m_combiner; m_combiner = 0; }
145 m_combinerCache.dispose();
146}
147
148//-----------------------------------------------------------------------------
149//! Select Combine
150//-----------------------------------------------------------------------------
151void AdvancedCombinerManager::selectCombine(unsigned int cycleType)
152{
153 //Hack for the Banjo-Tooie shadow
154 if ( cycleType == G_CYC_1CYCLE && m_combineData.mux == 0x00ffe7ffffcf9fcfLL )
155 {
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);
161 }
162
163 CachedCombiner* old = m_combinerCache.findCachedCombiner(m_combineData.mux);
164
165 if ( old == 0 )
166 {
167 //Cound not find an old combiner
168 this->update(cycleType); //Create a new combiner
169 }
170 else
171 {
172 currentTexEnv = old->compiled;
173 }
174
175 //Set Texture Enviroment
176 this->endTextureUpdate();
177}
178
179//-----------------------------------------------------------------------------
180//! Update Combine Colors
181//-----------------------------------------------------------------------------
182void AdvancedCombinerManager::updateCombineColors()
183{
184 m_combiner->setTextureEnviromentColors( currentTexEnv );
185}
186
187//-----------------------------------------------------------------------------
188//! Update
189//-----------------------------------------------------------------------------
190void AdvancedCombinerManager::update(unsigned int cycleType)
191{
192 int numCycles;
193
194 Combiner colorCombiner;
195 Combiner alphaCombiner;
196
197 //Set number of cycles
198 if ( cycleType == G_CYC_2CYCLE )
199 {
200 numCycles = 2;
201 colorCombiner.numStages = 2;
202 alphaCombiner.numStages = 2;
203 }
204 else
205 {
206 numCycles = 1;
207 colorCombiner.numStages = 1;
208 alphaCombiner.numStages = 1;
209 }
210
211 CombineCycle colorCycle[2];
212 CombineCycle alphaCycle[2];
213
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];
223
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];
232
233 //For each cycle
234 for (int i=0; i<numCycles; ++i)
235 {
236 //Set stages on color combiner
237 setStage(&colorCycle[i], &colorCombiner.stage[i]);
238
239 //Set stages on alpha combiner
240 setStage(&alphaCycle[i], &alphaCombiner.stage[i]);
241 }
242
243 if (numCycles == 2)
244 {
245 // Attempt to merge the two stages into one
246 mergeStages( &colorCombiner );
247 mergeStages( &alphaCombiner );
248 }
249
250 //Create New Enviroment
251 currentTexEnv = m_combiner->createNewTextureEnviroment(&colorCombiner, &alphaCombiner);
252
253 if ( !ROMDetector::getSingleton().getUseMultiTexture() )
254 {
255 currentTexEnv->usesT1 = false;
256 }
257
258 //Store combiner for reuse
259 m_combinerCache.newCompiledCombiner(m_combineData.mux, currentTexEnv);
260}
261
262//-----------------------------------------------------------------------------
263//! Set Mux
264//-----------------------------------------------------------------------------
265void AdvancedCombinerManager::setMux(unsigned long long mux, unsigned int cycleType)
266{
267 m_combineData.mux = mux;
268}
269
270//-----------------------------------------------------------------------------
271//! Set Mux
272//-----------------------------------------------------------------------------
273void AdvancedCombinerManager::setMux(unsigned int muxs0, unsigned int muxs1, unsigned int cycleType)
274{
275 m_combineData.muxs0 = muxs0;
276 m_combineData.muxs1 = muxs1;
277}
278
279//-----------------------------------------------------------------------------
280//! Begin Texture Update
281//-----------------------------------------------------------------------------
282void AdvancedCombinerManager::beginTextureUpdate()
283{
284 m_combiner->beginTextureUpdate();
285}
286
287//-----------------------------------------------------------------------------
288//! End Texture Update
289//-----------------------------------------------------------------------------
290void AdvancedCombinerManager::endTextureUpdate()
291{
292 //Set Texture Enviroment
293 m_combiner->setTextureEnviroment(currentTexEnv);
294}
295
296//-----------------------------------------------------------------------------
297//* Get Combiner Color
298//! Get Combiner Color which will be assigned to vertices
299//-----------------------------------------------------------------------------
300void AdvancedCombinerManager::getCombinerColor(float out[4])
301{
302 m_combiner->getCombinerColor(out, currentTexEnv->vertex.color, currentTexEnv->vertex.alpha);
303}
304
305//-----------------------------------------------------------------------------
306//* Get Secondary Combiner Color
307//! Get Secondary Combiner Color which will be assigned to vertices
308//-----------------------------------------------------------------------------
309void AdvancedCombinerManager::getSecondaryCombinerColor(float out[4])
310{
311 if ( !ROMDetector::getSingleton().getUseSecondaryColor() )
312 {
313 return;
314 }
315
316 //Get color
317 m_combiner->getCombinerColor(out, currentTexEnv->vertex.secondaryColor, ONE);
318}
319
320//-----------------------------------------------------------------------------
321//* Get Fill Color
322//! @return Fill Color as <r,g,b,a> (0.0 - 1.0)
323//-----------------------------------------------------------------------------
324float* AdvancedCombinerManager::getFillColor()
325{
326 return m_combiner->getFillColor();
327}
328
329//-----------------------------------------------------------------------------
330//* Get Blend Color
331//! @return Blend Color as <r,g,b,a> (0.0 - 1.0)
332//-----------------------------------------------------------------------------
333float* AdvancedCombinerManager::getBlendColor()
334{
335 return m_combiner->getBlendColor();
336}
337
338//-----------------------------------------------------------------------------
339//* Get Prim Color
340//! @return Prim Color as <r,g,b,a> (0.0 - 1.0)
341//-----------------------------------------------------------------------------
342float* AdvancedCombinerManager::getPrimColor()
343{
344 return m_combiner->getPrimColor();
345}
346
347//-----------------------------------------------------------------------------
348//! Set Fill Color
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//-----------------------------------------------------------------------------
354void AdvancedCombinerManager::setFillColor (float r, float g, float b, float a)
355{
356 m_combiner->setFillColor(r,g,b,a);
357}
358
359//-----------------------------------------------------------------------------
360//! Set Blend Color
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//-----------------------------------------------------------------------------
366void AdvancedCombinerManager::setBlendColor(float r, float g, float b, float a)
367{
368 m_combiner->setBlendColor(r,g,b,a);
369}
370
371//-----------------------------------------------------------------------------
372//! Set Prim Color
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//-----------------------------------------------------------------------------
378void AdvancedCombinerManager::setPrimColor (float r, float g, float b, float a)
379{
380 m_combiner->setPrimColor(r,g,b,a);
381}
382
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//-----------------------------------------------------------------------------
390void AdvancedCombinerManager::setEnvColor (float r, float g, float b, float a)
391{
392 m_combiner->setEnvColor(r,g,b,a);
393}
394
395//-----------------------------------------------------------------------------
396//* Set Prim LOD Min
397//! @param primLodMin
398//-----------------------------------------------------------------------------
399void AdvancedCombinerManager::setPrimLodMin(unsigned int primLodMin)
400{
401 m_combiner->setPrimLodMin(primLodMin);
402};
403
404//-----------------------------------------------------------------------------
405//* Set Prim LOD Frac
406//! @param primLodFrac
407//-----------------------------------------------------------------------------
408void AdvancedCombinerManager::setPrimLodFrac(float primLodFrac)
409{
410 m_combiner->setPrimLodFrac(primLodFrac);
411};