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 | |
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 | }; |