d07c171f |
1 | /* |
2 | Copyright (C) 2003 Rice1964 |
3 | |
4 | This program is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU General Public License |
6 | as published by the Free Software Foundation; either version 2 |
7 | of the License, or (at your option) any later version. |
8 | |
9 | This program is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | GNU General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU General Public License |
15 | along with this program; if not, write to the Free Software |
16 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
17 | */ |
18 | |
19 | #ifndef _GENERAL_COMBINER_H_ |
20 | #define _GENERAL_COMBINER_H_ |
21 | |
22 | #include <vector> |
23 | |
24 | #include "DecodedMux.h" |
25 | |
26 | class GeneralCombineStage |
27 | { |
28 | public: |
29 | StageOperate colorOp; |
30 | StageOperate alphaOp; |
31 | uint32 dwTexture; //Which texture to apply, 0 or 1 |
32 | bool bTextureUsed; |
33 | |
34 | BOOL operator!=(const GeneralCombineStage & cs) const { return !(operator==(cs)); } |
35 | BOOL operator==(const GeneralCombineStage & cs) const |
36 | { |
37 | return ( |
38 | cs.colorOp.Arg1 == colorOp.Arg1 && |
39 | cs.colorOp.Arg2 == colorOp.Arg2 && |
40 | cs.colorOp.Arg0 == colorOp.Arg0 && |
41 | cs.alphaOp.Arg1 == alphaOp.Arg1 && |
42 | cs.alphaOp.Arg2 == alphaOp.Arg2 && |
43 | cs.alphaOp.Arg0 == alphaOp.Arg0 && |
44 | cs.colorOp.op == colorOp.op && |
45 | cs.alphaOp.op == alphaOp.op && |
46 | cs.dwTexture == dwTexture&& |
47 | cs.bTextureUsed==bTextureUsed); |
48 | } |
49 | }; |
50 | |
51 | class GeneralCombinerInfo |
52 | { |
53 | public: |
54 | uint32 muxDWords[4]; // Simplified Mux |
55 | uint32 dwMux0; |
56 | uint32 dwMux1; |
57 | int nStages; |
58 | |
59 | BlendingFunc blendingFunc; |
60 | uint32 TFactor; |
61 | uint32 m_dwShadeColorChannelFlag; |
62 | uint32 m_dwShadeAlphaChannelFlag; |
63 | uint32 specularPostOp; |
64 | uint32 colorTextureFlag[2]; |
65 | |
66 | GeneralCombineStage stages[8]; |
67 | |
68 | bool bResultIsGoodWithinStages; |
69 | |
70 | BOOL operator!=(const GeneralCombinerInfo & sci) const { return !(operator==(sci)); } |
71 | BOOL operator==(const GeneralCombinerInfo & sci) const |
72 | { |
73 | int i; |
74 | |
75 | if (sci.nStages != nStages) |
76 | return FALSE; |
77 | if (sci.blendingFunc != blendingFunc) |
78 | return FALSE; |
79 | |
80 | for (i = 0; i < nStages; i++) |
81 | { |
82 | if (sci.stages[i] != stages[i]) |
83 | return FALSE; |
84 | } |
85 | |
86 | if( sci.TFactor != TFactor ) |
87 | return FALSE; |
88 | if( sci.specularPostOp != specularPostOp ) |
89 | return FALSE; |
90 | if( sci.m_dwShadeColorChannelFlag != m_dwShadeColorChannelFlag ) |
91 | return FALSE; |
92 | if( sci.m_dwShadeAlphaChannelFlag != m_dwShadeAlphaChannelFlag ) |
93 | return FALSE; |
94 | if( sci.colorTextureFlag[0] != colorTextureFlag[0] ) |
95 | return FALSE; |
96 | if( sci.colorTextureFlag[1] != colorTextureFlag[1] ) |
97 | return FALSE; |
98 | |
99 | return TRUE; |
100 | } |
101 | }; |
102 | |
103 | enum CombinerOp |
104 | { |
105 | CM_REPLACE, |
106 | CM_MODULATE, |
107 | CM_ADD, |
108 | CM_SUBTRACT, |
109 | CM_INTERPOLATE, // == LERP in DirectX, INTERPOLATE = OpenGL |
110 | |
111 | CM_ADDSMOOTH, // For DirectX only, for OpenGL, use INTERPOLATE |
112 | CM_BLENDCURRENTALPHA, // For DirectX only, for OpenGL, use INTERPOLATE |
113 | CM_BLENDDIFFUSEALPHA, // For DirectX only, for OpenGL, use INTERPOLATE |
114 | CM_BLENDFACTORALPHA, // For DirectX only, for OpenGL, use INTERPOLATE |
115 | CM_BLENDTEXTUREALPHA, // For DirectX only, for OpenGL, use INTERPOLATE |
116 | CM_MULTIPLYADD, // For DirectX only |
117 | }; |
118 | |
119 | #define CM_IGNORE 0 |
120 | #define CM_IGNORE_BYTE 0xFF |
121 | |
122 | /************************************************************************/ |
123 | /* This general combiner class is designed for general DirectX combiner */ |
124 | /* and OpenGL 1.2/1.3 combiner. Such combiners have the following */ |
125 | /* limitions and conditions: */ |
126 | /* */ |
127 | /* - Supporting at least 2 textures */ |
128 | /* - Supporting at least 2 combiner stages */ |
129 | /* - At each combiner stages, only 1 texture can be used */ |
130 | /* - Supporting only 1 constant color */ |
131 | /* - Supporting more or less texture combine operations, depending */ |
132 | /* on devices caps */ |
133 | /* */ |
134 | /* Before using this class, device caps boolean flags must be set */ |
135 | /* externally by owner of the class object (or a subclass object). */ |
136 | /* */ |
137 | /* */ |
138 | /************************************************************************/ |
139 | class CGeneralCombiner |
140 | { |
141 | protected: |
142 | CGeneralCombiner(); |
143 | |
144 | int FindCompiledMux(); |
145 | int ParseDecodedMux(); |
146 | void ParseDecodedMuxForConstants(GeneralCombinerInfo &res); |
147 | int SaveParserResult(GeneralCombinerInfo &result); |
148 | |
149 | int m_lastGeneralIndex; |
150 | DecodedMux **m_ppGeneralDecodedMux; |
151 | |
152 | /* |
153 | * Texture ops flags |
154 | */ |
155 | |
156 | bool m_bTxtOpAdd; |
157 | bool m_bTxtOpSub; |
158 | bool m_bTxtOpLerp; // LERP is for DirectX, INTERPOLATE is for OpenGL |
159 | |
160 | bool m_bTxtOpAddSmooth; // For DirectX only, for OpenGL, use INTERPOLATE |
161 | bool m_bTxtOpBlendCurAlpha; // For DirectX only, for OpenGL, use INTERPOLATE |
162 | bool m_bTxtOpBlendDifAlpha; // For DirectX only, for OpenGL, use INTERPOLATE |
163 | bool m_bTxtOpBlendFacAlpha; // For DirectX only, for OpenGL, use INTERPOLATE |
164 | bool m_bTxtOpBlendTxtAlpha; // For DirectX only, for OpenGL, use INTERPOLATE |
165 | bool m_bTxtOpMulAdd; // For DirectX only |
166 | |
167 | int m_dwGeneralMaxStages; |
168 | |
169 | std::vector<GeneralCombinerInfo> m_vCompiledCombinerStages; |
170 | |
171 | protected: |
172 | // combiner info generating functions |
173 | void GenCI_Init(GeneralCombinerInfo &ci); |
174 | void SkipStage(StageOperate &op, int &curStage); |
175 | void NextStage(int &curStage); |
176 | void Check1TxtrForAlpha(int curN64Stage, int &curStage, GeneralCombinerInfo &ci, int tex); |
177 | int Check2TxtrForAlpha(int curN64Stage, int &curStage, GeneralCombinerInfo &ci, int tex1, int tex2); |
178 | int CheckWhichTexToUseInThisStage(int curN64Stage, int curStage, GeneralCombinerInfo &ci); |
179 | |
180 | int GenCI_Type_D(int curN64Stage, int curStage, GeneralCombinerInfo &ci); |
181 | int GenCI_Type_A_MOD_C(int curN64Stage, int curStage, GeneralCombinerInfo &ci, uint32 dxop=CM_MODULATE); |
182 | int GenCI_Type_A_ADD_D(int curN64Stage, int curStage, GeneralCombinerInfo &ci); |
183 | int GenCI_Type_A_SUB_B(int curN64Stage, int curStage, GeneralCombinerInfo &ci); |
184 | int GenCI_Type_A_LERP_B_C(int curN64Stage, int curStage, GeneralCombinerInfo &ci); |
185 | int GenCI_Type_A_MOD_C_ADD_D(int curN64Stage, int curStage, GeneralCombinerInfo &ci); |
186 | int GenCI_Type_A_SUB_B_ADD_D(int curN64Stage, int curStage, GeneralCombinerInfo &ci); |
187 | int GenCI_Type_A_SUB_B_MOD_C(int curN64Stage, int curStage, GeneralCombinerInfo &ci); |
188 | int GenCI_Type_A_ADD_B_MOD_C(int curN64Stage, int curStage, GeneralCombinerInfo &ci); |
189 | int GenCI_Type_A_B_C_D(int curN64Stage, int curStage, GeneralCombinerInfo &ci); |
190 | int GenCI_Type_A_B_C_A(int curN64Stage, int curStage, GeneralCombinerInfo &ci); |
191 | |
192 | |
193 | // New functions, generate stages within the stage limition |
194 | // And return the number of stages used |
195 | // channel = 0 for color channel |
196 | // channel = 1 for alpha channel |
197 | // checktexture = true, need to use if texture matching in the stage |
198 | // checktexture = false, no check, just use any texture in the stage (since this stage hasn't been used) |
199 | int LM_GenCI_Type_D(N64CombinerType &m, int curStage, int limit, int channel, bool checktexture, GeneralCombinerInfo &ci); |
200 | int LM_GenCI_Type_A_MOD_C(N64CombinerType &m, int curStage, int limit, int channel, bool checktexture, GeneralCombinerInfo &ci, uint32 dxop=CM_MODULATE); |
201 | int LM_GenCI_Type_A_ADD_D(N64CombinerType &m, int curStage, int limit, int channel, bool checktexture, GeneralCombinerInfo &ci); |
202 | int LM_GenCI_Type_A_SUB_B(N64CombinerType &m, int curStage, int limit, int channel, bool checktexture, GeneralCombinerInfo &ci); |
203 | int LM_GenCI_Type_A_LERP_B_C(N64CombinerType &m, int curStage, int limit, int channel, bool checktexture, GeneralCombinerInfo &ci); |
204 | int LM_GenCI_Type_A_MOD_C_ADD_D(N64CombinerType &m, int curStage, int limit, int channel, bool checktexture, GeneralCombinerInfo &ci); |
205 | int LM_GenCI_Type_A_SUB_B_ADD_D(N64CombinerType &m, int curStage, int limit, int channel, bool checktexture, GeneralCombinerInfo &ci); |
206 | int LM_GenCI_Type_A_SUB_B_MOD_C(N64CombinerType &m, int curStage, int limit, int channel, bool checktexture, GeneralCombinerInfo &ci); |
207 | int LM_GenCI_Type_A_ADD_B_MOD_C(N64CombinerType &m, int curStage, int limit, int channel, bool checktexture, GeneralCombinerInfo &ci); |
208 | int LM_GenCI_Type_A_B_C_D(N64CombinerType &m, int curStage, int limit, int channel, bool checktexture, GeneralCombinerInfo &ci); |
209 | int LM_GenCI_Type_A_B_C_A(N64CombinerType &m, int curStage, int limit, int channel, bool checktexture, GeneralCombinerInfo &ci); |
210 | void LM_GenCI_Init(GeneralCombinerInfo &ci); |
211 | int LM_ParseDecodedMux(); |
212 | bool LM_Check1TxtrForAlpha(int curStage, GeneralCombinerInfo &ci, uint32 val); |
213 | void LM_SkipStage(StageOperate &op); |
214 | |
215 | |
216 | bool IsTextureUsedInStage(GeneralCombineStage &stage); |
217 | |
218 | #ifdef DEBUGGER |
219 | void General_DisplayBlendingStageInfo(GeneralCombinerInfo &ci); |
220 | #endif |
221 | |
222 | }; |
223 | |
224 | #endif |
225 | |