80e432e75bce807cf283ea02c9eb757419b8afdf
[mupen64plus-pandora.git] / source / mupen64plus-video-arachnoid / src / Combiner / AdvancedCombinerManager.cpp
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
35 static 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
43 static 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
51 static 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
63 static int aRGBExpanded[] = 
64 {
65     COMBINED,            TEXEL0,              TEXEL1,              PRIMITIVE,        
66     SHADE,               ENVIRONMENT,         ONE,                 ZERO
67 };
68
69 static int saAExpanded[] = 
70 {
71     COMBINED,            TEXEL0_ALPHA,        TEXEL1_ALPHA,        PRIMITIVE_ALPHA,        
72     SHADE_ALPHA,         ENV_ALPHA,           ONE,                 ZERO
73 };
74
75 static int sbAExpanded[] = 
76 {
77     COMBINED,            TEXEL0_ALPHA,        TEXEL1_ALPHA,        PRIMITIVE_ALPHA,        
78     SHADE_ALPHA,         ENV_ALPHA,           ONE,                 ZERO
79 };
80
81 static int mAExpanded[] = 
82 {
83     LOD_FRACTION,        TEXEL0_ALPHA,        TEXEL1_ALPHA,        PRIMITIVE_ALPHA,        
84     SHADE_ALPHA,         ENV_ALPHA,           PRIM_LOD_FRAC,       ZERO,
85 };
86
87 static int aAExpanded[] = 
88 {
89     COMBINED,            TEXEL0_ALPHA,        TEXEL1_ALPHA,        PRIMITIVE_ALPHA,        
90     SHADE_ALPHA,         ENV_ALPHA,           ONE,                 ZERO
91 };
92
93 //-----------------------------------------------------------------------------
94 //! Constructor
95 //-----------------------------------------------------------------------------
96 AdvancedCombinerManager::AdvancedCombinerManager()
97 {
98     currentTexEnv = 0;
99     m_combiner = 0;
100 }
101
102 //-----------------------------------------------------------------------------
103 //! Destructor
104 //-----------------------------------------------------------------------------
105 AdvancedCombinerManager::~AdvancedCombinerManager()
106 {
107     dispose();
108 }
109
110 //-----------------------------------------------------------------------------
111 //* Initialize
112 //! Selects sutible combiner and initializes it
113 //-----------------------------------------------------------------------------
114 void 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 //-----------------------------------------------------------------------------
142 void AdvancedCombinerManager::dispose()
143 {
144     if ( m_combiner ) { delete m_combiner; m_combiner = 0; }
145     m_combinerCache.dispose();
146 }
147
148 //-----------------------------------------------------------------------------
149 //! Select Combine
150 //-----------------------------------------------------------------------------
151 void 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 //-----------------------------------------------------------------------------
182 void AdvancedCombinerManager::updateCombineColors()
183 {
184     m_combiner->setTextureEnviromentColors( currentTexEnv );
185 }
186
187 //-----------------------------------------------------------------------------
188 //! Update 
189 //-----------------------------------------------------------------------------
190 void 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 //-----------------------------------------------------------------------------
265 void AdvancedCombinerManager::setMux(unsigned long long mux, unsigned int cycleType)
266 {
267     m_combineData.mux = mux;    
268 }
269
270 //-----------------------------------------------------------------------------
271 //! Set Mux
272 //-----------------------------------------------------------------------------
273 void 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 //-----------------------------------------------------------------------------
282 void AdvancedCombinerManager::beginTextureUpdate()
283 {
284     m_combiner->beginTextureUpdate();
285 }
286
287 //-----------------------------------------------------------------------------
288 //! End Texture Update
289 //-----------------------------------------------------------------------------
290 void 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 //-----------------------------------------------------------------------------
300 void 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 //-----------------------------------------------------------------------------
309 void 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 //-----------------------------------------------------------------------------
324 float* 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 //-----------------------------------------------------------------------------
333 float* 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 //-----------------------------------------------------------------------------
342 float* 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 //-----------------------------------------------------------------------------
354 void 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 //-----------------------------------------------------------------------------
366 void 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 //-----------------------------------------------------------------------------
378 void 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 //-----------------------------------------------------------------------------
390 void 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 //-----------------------------------------------------------------------------
399 void AdvancedCombinerManager::setPrimLodMin(unsigned int primLodMin) 
400
401     m_combiner->setPrimLodMin(primLodMin); 
402 };
403
404 //-----------------------------------------------------------------------------
405 //* Set Prim LOD Frac
406 //! @param primLodFrac
407 //-----------------------------------------------------------------------------
408 void AdvancedCombinerManager::setPrimLodFrac(float primLodFrac) 
409
410     m_combiner->setPrimLodFrac(primLodFrac); 
411 };