/[pcsx2_0.9.7]/trunk/plugins/zzogl-pg/opengl/ZZoglFlush.cpp
ViewVC logotype

Diff of /trunk/plugins/zzogl-pg/opengl/ZZoglFlush.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 62 by william, Tue Sep 7 11:08:22 2010 UTC revision 133 by william, Fri Sep 10 12:49:21 2010 UTC
# Line 1  Line 1 
1  /*  ZZ Open GL graphics plugin  /*  ZZ Open GL graphics plugin
2   *  Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com   *  Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
3   *  Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008   *  Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
4   *   *
5   *  This program is free software; you can redistribute it and/or modify   *  This program is free software; you can redistribute it and/or modify
6   *  it under the terms of the GNU General Public License as published by   *  it under the terms of the GNU General Public License as published by
7   *  the Free Software Foundation; either version 2 of the License, or   *  the Free Software Foundation; either version 2 of the License, or
8   *  (at your option) any later version.   *  (at your option) any later version.
9   *   *
10   *  This program is distributed in the hope that it will be useful,   *  This program is distributed in the hope that it will be useful,
11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   *  GNU General Public License for more details.   *  GNU General Public License for more details.
14   *   *
15   *  You should have received a copy of the GNU General Public License   *  You should have received a copy of the GNU General Public License
16   *  along with this program; if not, write to the Free Software   *  along with this program; if not, write to the Free Software
17   *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA   *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18   */   */
19    
20  // Realization of Flush -- drawing function of GS  // Realization of Flush -- drawing function of GS
21    
22  #include <stdlib.h>  #include <stdlib.h>
23    
24  #include "GS.h"  #include "GS.h"
25  #include "Mem.h"  #include "Mem.h"
26  #include "zerogs.h"  #include "zerogs.h"
27  #include "targets.h"  #include "targets.h"
28    
29  using namespace ZeroGS;  using namespace ZeroGS;
30    
31  //------------------ Defines  //------------------ Defines
32  #ifndef ZEROGS_DEVBUILD  #ifndef ZEROGS_DEVBUILD
33    
34  #define INC_GENVARS()  #define INC_GENVARS()
35  #define INC_TEXVARS()  #define INC_TEXVARS()
36  #define INC_ALPHAVARS()  #define INC_ALPHAVARS()
37  #define INC_RESOLVE()  #define INC_RESOLVE()
38    
39  #define g_bUpdateEffect 0  #define g_bUpdateEffect 0
40  #define g_bSaveTex 0  #define g_bSaveTex 0
41  bool g_bSaveTrans = 0;  bool g_bSaveTrans = 0;
42  #define g_bSaveResolved 0  #define g_bSaveResolved 0
43    
44  #else // defined(ZEROGS_DEVBUILD)  #else // defined(ZEROGS_DEVBUILD)
45    
46  #define INC_GENVARS() ++g_nGenVars  #define INC_GENVARS() ++g_nGenVars
47  #define INC_TEXVARS() ++g_nTexVars  #define INC_TEXVARS() ++g_nTexVars
48  #define INC_ALPHAVARS() ++g_nAlphaVars  #define INC_ALPHAVARS() ++g_nAlphaVars
49  #define INC_RESOLVE() ++g_nResolve  #define INC_RESOLVE() ++g_nResolve
50    
51  bool g_bSaveTrans = 0;  bool g_bSaveTrans = 0;
52  bool g_bUpdateEffect = 0;  bool g_bUpdateEffect = 0;
53  bool g_bSaveTex = 0;    // saves the curent texture  bool g_bSaveTex = 0;    // saves the curent texture
54  bool g_bSaveResolved = 0;  bool g_bSaveResolved = 0;
55  #endif // !defined(ZEROGS_DEVBUILD)  #endif // !defined(ZEROGS_DEVBUILD)
56    
57  #define STENCIL_ALPHABIT        1          // if set, dest alpha >= 0x80  #define STENCIL_ALPHABIT        1          // if set, dest alpha >= 0x80
58  #define STENCIL_PIXELWRITE  2      // if set, pixel just written (reset after every Flush)  #define STENCIL_PIXELWRITE  2      // if set, pixel just written (reset after every Flush)
59  #define STENCIL_FBA              4         // if set, just written pixel's alpha >= 0 (reset after every Flush)  #define STENCIL_FBA              4         // if set, just written pixel's alpha >= 0 (reset after every Flush)
60  #define STENCIL_SPECIAL  8         // if set, indicates that pixel passed its alpha test (reset after every Flush)  #define STENCIL_SPECIAL  8         // if set, indicates that pixel passed its alpha test (reset after every Flush)
61  //#define STENCIL_PBE              16  //#define STENCIL_PBE              16
62  #define STENCIL_CLEAR      (2|4|8|16)  #define STENCIL_CLEAR      (2|4|8|16)
63    
64  void Draw(const VB& curvb)  void Draw(const VB& curvb)
65  {  {
66          glDrawArrays(primtype[curvb.curprim.prim], 0, curvb.nCount);          glDrawArrays(primtype[curvb.curprim.prim], 0, curvb.nCount);
67  }  }
68    
69  #define GL_BLEND_RGB(src, dst) { \  #define GL_BLEND_RGB(src, dst) { \
70          s_srcrgb = src; \          s_srcrgb = src; \
71          s_dstrgb = dst; \          s_dstrgb = dst; \
72          zgsBlendFuncSeparateEXT(s_srcrgb, s_dstrgb, s_srcalpha, s_dstalpha); \          zgsBlendFuncSeparateEXT(s_srcrgb, s_dstrgb, s_srcalpha, s_dstalpha); \
73  }  }
74    
75  #define GL_BLEND_ALPHA(src, dst) { \  #define GL_BLEND_ALPHA(src, dst) { \
76          s_srcalpha = src; \          s_srcalpha = src; \
77          s_dstalpha = dst; \          s_dstalpha = dst; \
78          zgsBlendFuncSeparateEXT(s_srcrgb, s_dstrgb, s_srcalpha, s_dstalpha); \          zgsBlendFuncSeparateEXT(s_srcrgb, s_dstrgb, s_srcalpha, s_dstalpha); \
79  }  }
80    
81  #define GL_BLEND_ALL(srcrgb, dstrgb, srcalpha, dstalpha) { \  #define GL_BLEND_ALL(srcrgb, dstrgb, srcalpha, dstalpha) { \
82          s_srcrgb = srcrgb; \          s_srcrgb = srcrgb; \
83          s_dstrgb = dstrgb; \          s_dstrgb = dstrgb; \
84          s_srcalpha = srcalpha; \          s_srcalpha = srcalpha; \
85          s_dstalpha = dstalpha; \          s_dstalpha = dstalpha; \
86          zgsBlendFuncSeparateEXT(s_srcrgb, s_dstrgb, s_srcalpha, s_dstalpha); \          zgsBlendFuncSeparateEXT(s_srcrgb, s_dstrgb, s_srcalpha, s_dstalpha); \
87  }  }
88    
89  #define GL_ZTEST(enable) { \  #define GL_ZTEST(enable) { \
90          if (enable) glEnable(GL_DEPTH_TEST); \          if (enable) glEnable(GL_DEPTH_TEST); \
91          else glDisable(GL_DEPTH_TEST); \          else glDisable(GL_DEPTH_TEST); \
92  }  }
93    
94  #define GL_ALPHATEST(enable) { \  #define GL_ALPHATEST(enable) { \
95          if( enable ) glEnable(GL_ALPHA_TEST); \          if( enable ) glEnable(GL_ALPHA_TEST); \
96          else glDisable(GL_ALPHA_TEST); \          else glDisable(GL_ALPHA_TEST); \
97  }  }
98    
99  #define GL_BLENDEQ_RGB(eq) { \  #define GL_BLENDEQ_RGB(eq) { \
100          s_rgbeq = eq; \          s_rgbeq = eq; \
101          zgsBlendEquationSeparateEXT(s_rgbeq, s_alphaeq); \          zgsBlendEquationSeparateEXT(s_rgbeq, s_alphaeq); \
102  }  }
103    
104  #define GL_BLENDEQ_ALPHA(eq) { \  #define GL_BLENDEQ_ALPHA(eq) { \
105          s_alphaeq = eq; \          s_alphaeq = eq; \
106          zgsBlendEquationSeparateEXT(s_rgbeq, s_alphaeq); \          zgsBlendEquationSeparateEXT(s_rgbeq, s_alphaeq); \
107  }  }
108    
109  #define COLORMASK_RED           1  #define COLORMASK_RED           1
110  #define COLORMASK_GREEN         2  #define COLORMASK_GREEN         2
111  #define COLORMASK_BLUE          4  #define COLORMASK_BLUE          4
112  #define COLORMASK_ALPHA         8  #define COLORMASK_ALPHA         8
113  #define GL_COLORMASK(mask) glColorMask(!!((mask)&COLORMASK_RED), !!((mask)&COLORMASK_GREEN), !!((mask)&COLORMASK_BLUE), !!((mask)&COLORMASK_ALPHA))  #define GL_COLORMASK(mask) glColorMask(!!((mask)&COLORMASK_RED), !!((mask)&COLORMASK_GREEN), !!((mask)&COLORMASK_BLUE), !!((mask)&COLORMASK_ALPHA))
114    
115  // ----------------- Types  // ----------------- Types
116  //------------------ Dummies  //------------------ Dummies
117    
118  //------------------ variables  //------------------ variables
119    
120  extern int g_nDepthBias;  extern int g_nDepthBias;
121  extern float g_fBlockMult;  extern float g_fBlockMult;
122  bool g_bUpdateStencil = 1;  bool g_bUpdateStencil = 1;
123  //u32 g_SaveFrameNum = 0;                                                                       // ZZ  //u32 g_SaveFrameNum = 0;                                                                       // ZZ
124    
125  int GPU_TEXWIDTH = 512;  int GPU_TEXWIDTH = 512;
126  float g_fiGPU_TEXWIDTH = 1 / 512.0f;  float g_fiGPU_TEXWIDTH = 1 / 512.0f;
127    
128  extern CGprogram g_psprog;                                                      // 2 -- ZZ  extern CGprogram g_psprog;                                                      // 2 -- ZZ
129    
130  // local alpha blending settings  // local alpha blending settings
131  static GLenum s_rgbeq, s_alphaeq; // set by zgsBlendEquationSeparateEXT                 // ZZ  static GLenum s_rgbeq, s_alphaeq; // set by zgsBlendEquationSeparateEXT                 // ZZ
132    
133    
134  static const u32 blendalpha[3] = { GL_SRC_ALPHA, GL_DST_ALPHA, GL_CONSTANT_COLOR_EXT }; // ZZ  static const u32 blendalpha[3] = { GL_SRC_ALPHA, GL_DST_ALPHA, GL_CONSTANT_COLOR_EXT }; // ZZ
135  static const u32 blendinvalpha[3] = { GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_CONSTANT_COLOR_EXT }; //ZZ  static const u32 blendinvalpha[3] = { GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_CONSTANT_COLOR_EXT }; //ZZ
136  static const u32 g_dwAlphaCmp[] = { GL_NEVER, GL_ALWAYS, GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GEQUAL, GL_GREATER, GL_NOTEQUAL };    // ZZ  static const u32 g_dwAlphaCmp[] = { GL_NEVER, GL_ALWAYS, GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GEQUAL, GL_GREATER, GL_NOTEQUAL };    // ZZ
137    
138  // used for afail case  // used for afail case
139  static const u32 g_dwReverseAlphaCmp[] = { GL_ALWAYS, GL_NEVER, GL_GEQUAL, GL_GREATER, GL_NOTEQUAL, GL_LESS, GL_LEQUAL, GL_EQUAL };  static const u32 g_dwReverseAlphaCmp[] = { GL_ALWAYS, GL_NEVER, GL_GEQUAL, GL_GREATER, GL_NOTEQUAL, GL_LESS, GL_LEQUAL, GL_EQUAL };
140  static const u32 g_dwZCmp[] = { GL_NEVER, GL_ALWAYS, GL_GEQUAL, GL_GREATER };  static const u32 g_dwZCmp[] = { GL_NEVER, GL_ALWAYS, GL_GEQUAL, GL_GREATER };
141    
142  /////////////////////  /////////////////////
143  // graphics resources  // graphics resources
144  #define s_bForceTexFlush 1                                      // ZZ  #define s_bForceTexFlush 1                                      // ZZ
145  static u32 s_ptexCurSet[2] = {0};  static u32 s_ptexCurSet[2] = {0};
146  static u32 s_ptexNextSet[2] = {0};                              // ZZ  static u32 s_ptexNextSet[2] = {0};                              // ZZ
147    
148    
149  extern vector<u32> s_vecTempTextures;              // temporary textures, released at the end of every frame  extern vector<u32> s_vecTempTextures;              // temporary textures, released at the end of every frame
150  extern bool s_bTexFlush;  extern bool s_bTexFlush;
151  bool s_bWriteDepth = false;  bool s_bWriteDepth = false;
152  bool s_bDestAlphaTest = false;  bool s_bDestAlphaTest = false;
153  int s_ClutResolve = 0;                                          // ZZ  int s_ClutResolve = 0;                                          // ZZ
154  int g_nDepthUsed = 0;                                           // ffx2 pal movies  int g_nDepthUsed = 0;                                           // ffx2 pal movies
155  int s_nWriteDepthCount = 0;                                     // ZZ  int s_nWriteDepthCount = 0;                                     // ZZ
156  int s_nWriteDestAlphaTest = 0;                                  // ZZ  int s_nWriteDestAlphaTest = 0;                                  // ZZ
157    
158  ////////////////////  ////////////////////
159  // State parameters  // State parameters
160  static Vector vAlphaBlendColor;  // used for GPU_COLOR  static Vector vAlphaBlendColor;  // used for GPU_COLOR
161    
162  static bool bNeedBlendFactorInAlpha;      // set if the output source alpha is different from the real source alpha (only when blend factor > 0x80)  static bool bNeedBlendFactorInAlpha;      // set if the output source alpha is different from the real source alpha (only when blend factor > 0x80)
163  static u32 s_dwColorWrite = 0xf;                        // the color write mask of the current target  static u32 s_dwColorWrite = 0xf;                        // the color write mask of the current target
164    
165  typedef union  typedef union
166  {  {
167          struct          struct
168          {          {
169                  u8 _bNeedAlphaColor;            // set if vAlphaBlendColor needs to be set                  u8 _bNeedAlphaColor;            // set if vAlphaBlendColor needs to be set
170                  u8 _b2XAlphaTest;                  // Only valid when bNeedAlphaColor is set. if 1st bit set set, double all alpha testing values                  u8 _b2XAlphaTest;                  // Only valid when bNeedAlphaColor is set. if 1st bit set set, double all alpha testing values
171                  // otherwise alpha testing needs to be done separately.                  // otherwise alpha testing needs to be done separately.
172                  u8 _bDestAlphaColor;            // set to 1 if blending with dest color (process only one tri at a time). If 2, dest alpha is always 1.                  u8 _bDestAlphaColor;            // set to 1 if blending with dest color (process only one tri at a time). If 2, dest alpha is always 1.
173                  u8 _bAlphaClamping;      // if first bit is set, do min; if second bit, do max                  u8 _bAlphaClamping;      // if first bit is set, do min; if second bit, do max
174          };          };
175    
176          u32 _bAlphaState;          u32 _bAlphaState;
177  } g_flag_vars;  } g_flag_vars;
178    
179  g_flag_vars g_vars;  g_flag_vars g_vars;
180    
181  //#define bNeedAlphaColor g_vars._bNeedAlphaColor  //#define bNeedAlphaColor g_vars._bNeedAlphaColor
182  #define b2XAlphaTest g_vars._b2XAlphaTest  #define b2XAlphaTest g_vars._b2XAlphaTest
183  #define bDestAlphaColor g_vars._bDestAlphaColor  #define bDestAlphaColor g_vars._bDestAlphaColor
184  #define bAlphaClamping g_vars._bAlphaClamping  #define bAlphaClamping g_vars._bAlphaClamping
185    
186  int g_PrevBitwiseTexX = -1, g_PrevBitwiseTexY = -1; // textures stored in SAMP_BITWISEANDX and SAMP_BITWISEANDY         // ZZ  int g_PrevBitwiseTexX = -1, g_PrevBitwiseTexY = -1; // textures stored in SAMP_BITWISEANDX and SAMP_BITWISEANDY         // ZZ
187    
188  //static alphaInfo s_alphaInfo;                                                                                         // ZZ  //static alphaInfo s_alphaInfo;                                                                                         // ZZ
189    
190  extern u8* g_pbyGSClut;  extern u8* g_pbyGSClut;
191  extern int ppf;  extern int ppf;
192    
193  int s_nWireframeCount = 0;  int s_nWireframeCount = 0;
194    
195  //------------------ Namespace  //------------------ Namespace
196    
197  namespace ZeroGS  namespace ZeroGS
198  {  {
199    
200  VB vb[2];  VB vb[2];
201  float fiTexWidth[2], fiTexHeight[2];    // current tex width and height  float fiTexWidth[2], fiTexHeight[2];    // current tex width and height
202    
203  u8 s_AAx = 0, s_AAy = 0; // if AAy is set, then AAx has to be set  u8 s_AAx = 0, s_AAy = 0; // if AAy is set, then AAx has to be set
204  u8 s_AAz = 0, s_AAw = 0; // if AAy is set, then AAx has to be set  u8 s_AAz = 0, s_AAw = 0; // if AAy is set, then AAx has to be set
205    
206  int icurctx = -1;  int icurctx = -1;
207    
208  extern CRangeManager s_RangeMngr; // manages overwritten memory                         // zz  extern CRangeManager s_RangeMngr; // manages overwritten memory                         // zz
209  void FlushTransferRanges(const tex0Info* ptex);                                         //zz  void FlushTransferRanges(const tex0Info* ptex);                                         //zz
210    
211  RenderFormatType GetRenderFormat() { return g_RenderFormatType; }                                       //zz  RenderFormatType GetRenderFormat() { return g_RenderFormatType; }                                       //zz
212    
213  // use to update the state  // use to update the state
214  void SetTexVariables(int context, FRAGMENTSHADER* pfragment);                   // zz  void SetTexVariables(int context, FRAGMENTSHADER* pfragment);                   // zz
215  void SetTexInt(int context, FRAGMENTSHADER* pfragment, int settexint);          // zz  void SetTexInt(int context, FRAGMENTSHADER* pfragment, int settexint);          // zz
216  void SetAlphaVariables(const alphaInfo& ainfo);                                 // zzz  void SetAlphaVariables(const alphaInfo& ainfo);                                 // zzz
217  void ResetAlphaVariables();  void ResetAlphaVariables();
218    
219  inline void SetAlphaTestInt(pixTest curtest);  inline void SetAlphaTestInt(pixTest curtest);
220    
221  inline void RenderAlphaTest(const VB& curvb, CGparameter sOneColor);  inline void RenderAlphaTest(const VB& curvb, CGparameter sOneColor);
222  inline void RenderStencil(const VB& curvb, u32 dwUsingSpecialTesting);  inline void RenderStencil(const VB& curvb, u32 dwUsingSpecialTesting);
223  inline void ProcessStencil(const VB& curvb);  inline void ProcessStencil(const VB& curvb);
224  inline void RenderFBA(const VB& curvb, CGparameter sOneColor);  inline void RenderFBA(const VB& curvb, CGparameter sOneColor);
225  inline void ProcessFBA(const VB& curvb, CGparameter sOneColor);                 // zz  inline void ProcessFBA(const VB& curvb, CGparameter sOneColor);                 // zz
226    
227    
228  }  }
229    
230  //------------------ Code  //------------------ Code
231    
232  inline float AlphaReferedValue(int aref)  inline float AlphaReferedValue(int aref)
233  {  {
234          return b2XAlphaTest ? min(1.0f, (float)aref / 127.5f) : (float)aref / 255.0f ;          return b2XAlphaTest ? min(1.0f, (float)aref / 127.5f) : (float)aref / 255.0f ;
235  }  }
236    
237  inline void SetAlphaTest(const pixTest& curtest)  inline void SetAlphaTest(const pixTest& curtest)
238  {  {
239          // if s_dwColorWrite is nontrivial, than we should not off alphatest.          // if s_dwColorWrite is nontrivial, than we should not off alphatest.
240          // This fix GOW and Okami.          // This fix GOW and Okami.
241          if (!curtest.ate && USEALPHATESTING && (s_dwColorWrite != 2 && s_dwColorWrite != 14))          if (!curtest.ate && USEALPHATESTING && (s_dwColorWrite != 2 && s_dwColorWrite != 14))
242          {          {
243                  glDisable(GL_ALPHA_TEST);                  glDisable(GL_ALPHA_TEST);
244          }          }
245          else          else
246          {          {
247                  glEnable(GL_ALPHA_TEST);                  glEnable(GL_ALPHA_TEST);
248                  glAlphaFunc(g_dwAlphaCmp[curtest.atst], AlphaReferedValue(curtest.aref));                  glAlphaFunc(g_dwAlphaCmp[curtest.atst], AlphaReferedValue(curtest.aref));
249          }          }
250  }  }
251    
252  // Switch wireframe rendering off for first flush, so it's draw few solid primitives  // Switch wireframe rendering off for first flush, so it's draw few solid primitives
253  inline void SwitchWireframeOff()  inline void SwitchWireframeOff()
254  {  {
255          if (conf.wireframe())          if (conf.wireframe())
256          {          {
257                  if (s_nWireframeCount > 0)                  if (s_nWireframeCount > 0)
258                  {                  {
259                          glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);                          glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
260                  }                  }
261          }          }
262  }  }
263    
264  // Switch wireframe rendering on, look at previous function  // Switch wireframe rendering on, look at previous function
265  inline void SwitchWireframeOn()  inline void SwitchWireframeOn()
266  {  {
267          if (conf.wireframe())          if (conf.wireframe())
268          {          {
269                  if (s_nWireframeCount > 0)                  if (s_nWireframeCount > 0)
270                  {                  {
271                          glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);                          glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
272                          --s_nWireframeCount;                          --s_nWireframeCount;
273                  }                  }
274          }          }
275  }  }
276    
277  int GetTexFilter(const tex1Info& tex1)  int GetTexFilter(const tex1Info& tex1)
278  {  {
279          // always force          // always force
280          if (conf.bilinear == 2) return 1;          if (conf.bilinear == 2) return 1;
281    
282          int texfilter = 0;          int texfilter = 0;
283    
284          if (conf.bilinear && ptexBilinearBlocks != 0)          if (conf.bilinear && ptexBilinearBlocks != 0)
285          {          {
286                  if (tex1.mmin <= 1)                  if (tex1.mmin <= 1)
287                          texfilter = tex1.mmin | tex1.mmag;                          texfilter = tex1.mmin | tex1.mmag;
288                  else                  else
289                          texfilter = tex1.mmag ? ((tex1.mmin + 2) & 5) : tex1.mmin;                          texfilter = tex1.mmag ? ((tex1.mmin + 2) & 5) : tex1.mmin;
290    
291                  texfilter = texfilter == 1 || texfilter == 4 || texfilter == 5;                  texfilter = texfilter == 1 || texfilter == 4 || texfilter == 5;
292          }          }
293    
294          return texfilter;          return texfilter;
295  }  }
296    
297  void ZeroGS::ReloadEffects()  void ZeroGS::ReloadEffects()
298  {  {
299  #ifdef ZEROGS_DEVBUILD  #ifdef ZEROGS_DEVBUILD
300    
301          for (int i = 0; i < ARRAY_SIZE(ppsTexture); ++i)          for (int i = 0; i < ARRAY_SIZE(ppsTexture); ++i)
302          {          {
303                  SAFE_RELEASE_PROG(ppsTexture[i].prog);                  SAFE_RELEASE_PROG(ppsTexture[i].prog);
304          }          }
305    
306          memset(ppsTexture, 0, sizeof(ppsTexture));          memset(ppsTexture, 0, sizeof(ppsTexture));
307    
308          LoadExtraEffects();          LoadExtraEffects();
309  #endif  #endif
310  }  }
311    
312  long BufferNumber = 0;  long BufferNumber = 0;
313    
314  // This is a debug function. It prints all buffer info and save current texture into the file, then prints the file name.  // This is a debug function. It prints all buffer info and save current texture into the file, then prints the file name.
315  inline void VisualBufferMessage(int context)  inline void VisualBufferMessage(int context)
316  {  {
317  #if defined(WRITE_PRIM_LOGS) && defined(_DEBUG)  #if defined(WRITE_PRIM_LOGS) && defined(_DEBUG)
318          BufferNumber++;          BufferNumber++;
319          ZeroGS::VB& curvb = vb[context];          ZeroGS::VB& curvb = vb[context];
320          static const char* patst[8] = { "NEVER", "ALWAYS", "LESS", "LEQUAL", "EQUAL", "GEQUAL", "GREATER", "NOTEQUAL"};          static const char* patst[8] = { "NEVER", "ALWAYS", "LESS", "LEQUAL", "EQUAL", "GEQUAL", "GREATER", "NOTEQUAL"};
321          static const char* pztst[4] = { "NEVER", "ALWAYS", "GEQUAL", "GREATER" };          static const char* pztst[4] = { "NEVER", "ALWAYS", "GEQUAL", "GREATER" };
322          static const char* pafail[4] = { "KEEP", "FB_ONLY", "ZB_ONLY", "RGB_ONLY" };          static const char* pafail[4] = { "KEEP", "FB_ONLY", "ZB_ONLY", "RGB_ONLY" };
323          ZZLog::Debug_Log("**Drawing ctx %d, num %d, fbp: 0x%x, zbp: 0x%x, fpsm: %d, zpsm: %d, fbw: %d", context, vb[context].nCount, curvb.prndr->fbp, curvb.zbuf.zbp, curvb.prndr->psm, curvb.zbuf.psm, curvb.prndr->fbw);          ZZLog::Debug_Log("**Drawing ctx %d, num %d, fbp: 0x%x, zbp: 0x%x, fpsm: %d, zpsm: %d, fbw: %d", context, vb[context].nCount, curvb.prndr->fbp, curvb.zbuf.zbp, curvb.prndr->psm, curvb.zbuf.psm, curvb.prndr->fbw);
324          ZZLog::Debug_Log("prim: prim=%x iip=%x tme=%x fge=%x abe=%x aa1=%x fst=%x ctxt=%x fix=%x",          ZZLog::Debug_Log("prim: prim=%x iip=%x tme=%x fge=%x abe=%x aa1=%x fst=%x ctxt=%x fix=%x",
325                                           curvb.curprim.prim, curvb.curprim.iip, curvb.curprim.tme, curvb.curprim.fge, curvb.curprim.abe, curvb.curprim.aa1, curvb.curprim.fst, curvb.curprim.ctxt, curvb.curprim.fix);                                           curvb.curprim.prim, curvb.curprim.iip, curvb.curprim.tme, curvb.curprim.fge, curvb.curprim.abe, curvb.curprim.aa1, curvb.curprim.fst, curvb.curprim.ctxt, curvb.curprim.fix);
326          ZZLog::Debug_Log("test: ate:%d, atst: %s, aref: %d, afail: %s, date: %d, datm: %d, zte: %d, ztst: %s, fba: %d",          ZZLog::Debug_Log("test: ate:%d, atst: %s, aref: %d, afail: %s, date: %d, datm: %d, zte: %d, ztst: %s, fba: %d",
327                                           curvb.test.ate, patst[curvb.test.atst], curvb.test.aref, pafail[curvb.test.afail], curvb.test.date, curvb.test.datm, curvb.test.zte, pztst[curvb.test.ztst], curvb.fba.fba);                                           curvb.test.ate, patst[curvb.test.atst], curvb.test.aref, pafail[curvb.test.afail], curvb.test.date, curvb.test.datm, curvb.test.zte, pztst[curvb.test.ztst], curvb.fba.fba);
328          ZZLog::Debug_Log("alpha: A%d B%d C%d D%d FIX:%d pabe: %d; aem: %d, ta0: %d, ta1: %d\n", curvb.alpha.a, curvb.alpha.b, curvb.alpha.c, curvb.alpha.d, curvb.alpha.fix, gs.pabe, gs.texa.aem, gs.texa.ta[0], gs.texa.ta[1]);          ZZLog::Debug_Log("alpha: A%d B%d C%d D%d FIX:%d pabe: %d; aem: %d, ta0: %d, ta1: %d\n", curvb.alpha.a, curvb.alpha.b, curvb.alpha.c, curvb.alpha.d, curvb.alpha.fix, gs.pabe, gs.texa.aem, gs.texa.ta[0], gs.texa.ta[1]);
329          ZZLog::Debug_Log("tex0: tbp0=0x%x, tbw=%d, psm=0x%x, tw=%d, th=%d, tcc=%d, tfx=%d, cbp=0x%x, cpsm=0x%x, csm=%d, csa=%d, cld=%d",          ZZLog::Debug_Log("tex0: tbp0=0x%x, tbw=%d, psm=0x%x, tw=%d, th=%d, tcc=%d, tfx=%d, cbp=0x%x, cpsm=0x%x, csm=%d, csa=%d, cld=%d",
330                                           curvb.tex0.tbp0, curvb.tex0.tbw, curvb.tex0.psm, curvb.tex0.tw,                                           curvb.tex0.tbp0, curvb.tex0.tbw, curvb.tex0.psm, curvb.tex0.tw,
331                                           curvb.tex0.th, curvb.tex0.tcc, curvb.tex0.tfx, curvb.tex0.cbp,                                           curvb.tex0.th, curvb.tex0.tcc, curvb.tex0.tfx, curvb.tex0.cbp,
332                                           curvb.tex0.cpsm, curvb.tex0.csm, curvb.tex0.csa, curvb.tex0.cld);                                           curvb.tex0.cpsm, curvb.tex0.csm, curvb.tex0.csa, curvb.tex0.cld);
333          char* Name;          char* Name;
334  //      if (g_bSaveTex) {  //      if (g_bSaveTex) {
335  //              if (g_bSaveTex == 1)  //              if (g_bSaveTex == 1)
336          Name = NamedSaveTex(&curvb.tex0, 1);          Name = NamedSaveTex(&curvb.tex0, 1);
337  //              else  //              else
338  //                      Name = NamedSaveTex(&curvb.tex0, 0);  //                      Name = NamedSaveTex(&curvb.tex0, 0);
339          ZZLog::Error_Log("TGA name '%s'.", Name);          ZZLog::Error_Log("TGA name '%s'.", Name);
340          free(Name);          free(Name);
341  //      }  //      }
342  //      ZZLog::Debug_Log("frame: %d, buffer %ld.\n", g_SaveFrameNum, BufferNumber);  //      ZZLog::Debug_Log("frame: %d, buffer %ld.\n", g_SaveFrameNum, BufferNumber);
343          ZZLog::Debug_Log("buffer %ld.\n", BufferNumber);          ZZLog::Debug_Log("buffer %ld.\n", BufferNumber);
344  #endif  #endif
345  }  }
346    
347  inline void SaveRendererTarget(VB& curvb)  inline void SaveRendererTarget(VB& curvb)
348  {  {
349  #ifdef _DEBUG  #ifdef _DEBUG
350    
351  //      if (g_bSaveFlushedFrame & 0x80000000)  //      if (g_bSaveFlushedFrame & 0x80000000)
352  //      {  //      {
353  //              char str[255];  //              char str[255];
354  //              sprintf(str, "rndr%d.tga", g_SaveFrameNum);  //              sprintf(str, "rndr%d.tga", g_SaveFrameNum);
355  //              SaveRenderTarget(str, curvb.prndr->fbw, curvb.prndr->fbh, 0);  //              SaveRenderTarget(str, curvb.prndr->fbw, curvb.prndr->fbh, 0);
356  //      }  //      }
357    
358  #endif  #endif
359  }  }
360    
361  // Stop effects in Developers mode  // Stop effects in Developers mode
362  inline void FlushUpdateEffect()  inline void FlushUpdateEffect()
363  {  {
364  #if defined(DEVBUILD)  #if defined(DEVBUILD)
365    
366          if (g_bUpdateEffect)          if (g_bUpdateEffect)
367          {          {
368                  ReloadEffects();                  ReloadEffects();
369                  g_bUpdateEffect = 0;                  g_bUpdateEffect = 0;
370          }          }
371    
372  #endif  #endif
373  }  }
374    
375  // Check, maybe we cold skip flush  // Check, maybe we cold skip flush
376  inline bool IsFlushNoNeed(VB& curvb, const pixTest& curtest)  inline bool IsFlushNoNeed(VB& curvb, const pixTest& curtest)
377  {  {
378          if (curvb.nCount == 0 || (curtest.zte && curtest.ztst == 0))          if (curvb.nCount == 0 || (curtest.zte && curtest.ztst == 0))
379          {          {
380                  curvb.nCount = 0;                  curvb.nCount = 0;
381                  return true;                  return true;
382          }          }
383    
384          return false;          return false;
385  }  }
386    
387  // Transfer targets, that are located in current texture.  // Transfer targets, that are located in current texture.
388  inline void FlushTransferRangesHelper(VB& curvb)  inline void FlushTransferRangesHelper(VB& curvb)
389  {  {
390          if (s_RangeMngr.ranges.size() > 0)          if (s_RangeMngr.ranges.size() > 0)
391          {          {
392                  // don't want infinite loop, so set nCount to 0.                  // don't want infinite loop, so set nCount to 0.
393                  u32 prevcount = curvb.nCount;                  u32 prevcount = curvb.nCount;
394                  curvb.nCount = 0;                  curvb.nCount = 0;
395    
396                  FlushTransferRanges(curvb.curprim.tme ? &curvb.tex0 : NULL);                  FlushTransferRanges(curvb.curprim.tme ? &curvb.tex0 : NULL);
397    
398                  curvb.nCount += prevcount;                  curvb.nCount += prevcount;
399          }          }
400  }  }
401    
402  // If set bit for texture checking, do it. Maybe it's all.  // If set bit for texture checking, do it. Maybe it's all.
403  inline bool FushTexDataHelper(VB& curvb)  inline bool FushTexDataHelper(VB& curvb)
404  {  {
405          if (curvb.bNeedFrameCheck || curvb.bNeedZCheck)          if (curvb.bNeedFrameCheck || curvb.bNeedZCheck)
406          {          {
407                  curvb.CheckFrame(curvb.curprim.tme ? curvb.tex0.tbp0 : 0);                  curvb.CheckFrame(curvb.curprim.tme ? curvb.tex0.tbp0 : 0);
408          }          }
409    
410          if (curvb.bNeedTexCheck)    // Zeydlitz want to try this          if (curvb.bNeedTexCheck)    // Zeydlitz want to try this
411          {          {
412                  curvb.FlushTexData();                  curvb.FlushTexData();
413    
414                  if (curvb.nCount == 0) return true;                  if (curvb.nCount == 0) return true;
415          }          }
416    
417          return false;          return false;
418  }  }
419    
420  // Null target mean that we do something really bad.  // Null target mean that we do something really bad.
421  inline bool FlushCheckForNULLTarget(VB& curvb, int context)  inline bool FlushCheckForNULLTarget(VB& curvb, int context)
422  {  {
423          if ((curvb.prndr == NULL) || (curvb.pdepth == NULL))          if ((curvb.prndr == NULL) || (curvb.pdepth == NULL))
424          {          {
425                  ERROR_LOG_SPAMA("Current render target NULL (ctx: %d)", context);                  ERROR_LOG_SPAMA("Current render target NULL (ctx: %d)", context);
426                  curvb.nCount = 0;                  curvb.nCount = 0;
427                  return true;                  return true;
428          }          }
429    
430          return false;          return false;
431  }  }
432    
433  // O.k. A set of resolutions, we do before real flush. We do RangeManager, FrameCheck and  // O.k. A set of resolutions, we do before real flush. We do RangeManager, FrameCheck and
434  // ZCheck before this.  // ZCheck before this.
435  inline bool FlushInitialTest(VB& curvb, const pixTest& curtest, int context)  inline bool FlushInitialTest(VB& curvb, const pixTest& curtest, int context)
436  {  {
437          GL_REPORT_ERRORD();          GL_REPORT_ERRORD();
438          assert(context >= 0 && context <= 1);          assert(context >= 0 && context <= 1);
439    
440          FlushUpdateEffect();          FlushUpdateEffect();
441    
442          if (IsFlushNoNeed(curvb, curtest)) return true;          if (IsFlushNoNeed(curvb, curtest)) return true;
443    
444          FlushTransferRangesHelper(curvb);          FlushTransferRangesHelper(curvb);
445    
446          if (FushTexDataHelper(curvb)) return true;          if (FushTexDataHelper(curvb)) return true;
447    
448          GL_REPORT_ERRORD();          GL_REPORT_ERRORD();
449    
450          if (FlushCheckForNULLTarget(curvb, context)) return true;          if (FlushCheckForNULLTarget(curvb, context)) return true;
451    
452          return false;          return false;
453  }  }
454    
455  // Try to different approach if texture target was not found  // Try to different approach if texture target was not found
456  inline CRenderTarget* FlushReGetTarget(int& tbw, int& tbp0, int& tpsm, VB& curvb)  inline CRenderTarget* FlushReGetTarget(int& tbw, int& tbp0, int& tpsm, VB& curvb)
457  {  {
458          // This was incorrect code          // This was incorrect code
459          CRenderTarget* ptextarg = NULL;          CRenderTarget* ptextarg = NULL;
460    
461          if ((ptextarg == NULL) && (tpsm == PSMT8) && (conf.settings().reget))          if ((ptextarg == NULL) && (tpsm == PSMT8) && (conf.settings().reget))
462          {          {
463                  // check for targets with half the width. Break Valkyrie Chronicles                  // check for targets with half the width. Break Valkyrie Chronicles
464                  ptextarg = s_RTs.GetTarg(tbp0, tbw / 2, curvb);                  ptextarg = s_RTs.GetTarg(tbp0, tbw / 2, curvb);
465    
466                  if (ptextarg == NULL)                  if (ptextarg == NULL)
467                  {                  {
468                          tbp0 &= ~0x7ff;                          tbp0 &= ~0x7ff;
469                          ptextarg = s_RTs.GetTarg(tbp0, tbw / 2, curvb); // mgs3 hack                          ptextarg = s_RTs.GetTarg(tbp0, tbw / 2, curvb); // mgs3 hack
470    
471                          if (ptextarg == NULL)                          if (ptextarg == NULL)
472                          {                          {
473                                  // check the next level (mgs3)                                  // check the next level (mgs3)
474                                  tbp0 &= ~0xfff;                                  tbp0 &= ~0xfff;
475                                  ptextarg = s_RTs.GetTarg(tbp0, tbw / 2, curvb); // mgs3 hack                                  ptextarg = s_RTs.GetTarg(tbp0, tbw / 2, curvb); // mgs3 hack
476                          }                          }
477    
478                          if (ptextarg != NULL && ptextarg->start > tbp0*256)                          if (ptextarg != NULL && ptextarg->start > tbp0*256)
479                          {                          {
480                                  // target beyond range, so ignore                                  // target beyond range, so ignore
481                                  ptextarg = NULL;                                  ptextarg = NULL;
482                          }                          }
483                  }                  }
484          }          }
485    
486    
487          if (PSMT_ISZTEX(tpsm) && (ptextarg == NULL))          if (PSMT_ISZTEX(tpsm) && (ptextarg == NULL))
488          {          {
489                  // try depth                  // try depth
490                  ptextarg = s_DepthRTs.GetTarg(tbp0, tbw, curvb);                  ptextarg = s_DepthRTs.GetTarg(tbp0, tbw, curvb);
491          }          }
492    
493          if ((ptextarg == NULL) && (conf.settings().texture_targs))          if ((ptextarg == NULL) && (conf.settings().texture_targs))
494          {          {
495                  // check if any part of the texture intersects the current target                  // check if any part of the texture intersects the current target
496                  if (!PSMT_ISCLUT(tpsm) && (curvb.tex0.tbp0 >= curvb.frame.fbp) && ((curvb.tex0.tbp0) < curvb.prndr->end))                  if (!PSMT_ISCLUT(tpsm) && (curvb.tex0.tbp0 >= curvb.frame.fbp) && ((curvb.tex0.tbp0) < curvb.prndr->end))
497                  {                  {
498                          ptextarg = curvb.prndr;                          ptextarg = curvb.prndr;
499                  }                  }
500          }          }
501    
502  #ifdef _DEBUG  #ifdef _DEBUG
503          if (tbp0 == 0x3600 && tbw == 0x100)          if (tbp0 == 0x3600 && tbw == 0x100)
504          {          {
505                  if (ptextarg == NULL)                  if (ptextarg == NULL)
506                  {                  {
507                          printf("Miss %x 0x%x %d\n", tbw, tbp0, tpsm);                          printf("Miss %x 0x%x %d\n", tbw, tbp0, tpsm);
508    
509                          typedef map<u32, CRenderTarget*> MAPTARGETS;                          typedef map<u32, CRenderTarget*> MAPTARGETS;
510    
511                          for (MAPTARGETS::iterator itnew = s_RTs.mapTargets.begin(); itnew != s_RTs.mapTargets.end(); ++itnew)                          for (MAPTARGETS::iterator itnew = s_RTs.mapTargets.begin(); itnew != s_RTs.mapTargets.end(); ++itnew)
512                          {                          {
513                                  printf("\tRender %x 0x%x %x\n", itnew->second->fbw, itnew->second->fbp, itnew->second->psm);                                  printf("\tRender %x 0x%x %x\n", itnew->second->fbw, itnew->second->fbp, itnew->second->psm);
514                          }                          }
515    
516                          for (MAPTARGETS::iterator itnew = s_DepthRTs.mapTargets.begin(); itnew != s_DepthRTs.mapTargets.end(); ++itnew)                          for (MAPTARGETS::iterator itnew = s_DepthRTs.mapTargets.begin(); itnew != s_DepthRTs.mapTargets.end(); ++itnew)
517                          {                          {
518                                  printf("\tDepth %x 0x%x %x\n", itnew->second->fbw, itnew->second->fbp, itnew->second->psm);                                  printf("\tDepth %x 0x%x %x\n", itnew->second->fbw, itnew->second->fbp, itnew->second->psm);
519                          }                          }
520    
521                          printf("\tCurvb 0x%x 0x%x 0x%x %x\n", curvb.frame.fbp, curvb.prndr->end, curvb.prndr->fbp, curvb.prndr->fbw);                          printf("\tCurvb 0x%x 0x%x 0x%x %x\n", curvb.frame.fbp, curvb.prndr->end, curvb.prndr->fbp, curvb.prndr->fbw);
522                  }                  }
523                  else                  else
524                          printf("Hit  %x 0x%x %x\n", tbw, tbp0, tpsm);                          printf("Hit  %x 0x%x %x\n", tbw, tbp0, tpsm);
525          }          }
526    
527  #endif  #endif
528    
529          return ptextarg;          return ptextarg;
530  }  }
531    
532  // Find target to draw a texture, it's highly p  // Find target to draw a texture, it's highly p
533  inline CRenderTarget* FlushGetTarget(VB& curvb)  inline CRenderTarget* FlushGetTarget(VB& curvb)
534  {  {
535          int tbw, tbp0, tpsm;          int tbw, tbp0, tpsm;
536    
537          CRenderTarget* ptextarg = NULL;          CRenderTarget* ptextarg = NULL;
538    
539          if (!curvb.curprim.tme) return ptextarg;          if (!curvb.curprim.tme) return ptextarg;
540    
541          if (curvb.bNeedTexCheck)          if (curvb.bNeedTexCheck)
542          {          {
543                  printf("How it is possible?\n");                  printf("How it is possible?\n");
544                  // not yet initied, but still need to get correct target! (xeno3 ingame)                  // not yet initied, but still need to get correct target! (xeno3 ingame)
545                  tbp0 = ZZOglGet_tbp0_TexBits(curvb.uNextTex0Data[0]);                  tbp0 = ZZOglGet_tbp0_TexBits(curvb.uNextTex0Data[0]);
546                  tbw  = ZZOglGet_tbw_TexBitsMult(curvb.uNextTex0Data[0]);                  tbw  = ZZOglGet_tbw_TexBitsMult(curvb.uNextTex0Data[0]);
547                  tpsm = ZZOglGet_psm_TexBitsFix(curvb.uNextTex0Data[0]);                  tpsm = ZZOglGet_psm_TexBitsFix(curvb.uNextTex0Data[0]);
548          }          }
549          else          else
550          {          {
551                  tbw = curvb.tex0.tbw;                  tbw = curvb.tex0.tbw;
552                  tbp0 = curvb.tex0.tbp0;                  tbp0 = curvb.tex0.tbp0;
553                  tpsm = curvb.tex0.psm;                  tpsm = curvb.tex0.psm;
554          }          }
555    
556          ptextarg = s_RTs.GetTarg(tbp0, tbw, curvb);          ptextarg = s_RTs.GetTarg(tbp0, tbw, curvb);
557    
558          if (ptextarg == NULL)          if (ptextarg == NULL)
559                  ptextarg = FlushReGetTarget(tbw, tbp0, tpsm, curvb);                  ptextarg = FlushReGetTarget(tbw, tbp0, tpsm, curvb);
560    
561          if ((ptextarg != NULL) && !(ptextarg->status & CRenderTarget::TS_NeedUpdate))          if ((ptextarg != NULL) && !(ptextarg->status & CRenderTarget::TS_NeedUpdate))
562          {          {
563                  if (PSMT_BITMODE(tpsm) == 4)   // handle 8h cluts                  if (PSMT_BITMODE(tpsm) == 4)   // handle 8h cluts
564                  {                  {
565                          // don't support clut targets, read from mem                          // don't support clut targets, read from mem
566                          // 4hl - kh2 check - from dx version -- arcum42                          // 4hl - kh2 check - from dx version -- arcum42
567    
568                          if (tpsm == PSMT4 && s_ClutResolve <= 1)                          if (tpsm == PSMT4 && s_ClutResolve <= 1)
569                          {                          {
570                                  // xenosaga requires 2 resolves                                  // xenosaga requires 2 resolves
571                                  u32 prevcount = curvb.nCount;                                  u32 prevcount = curvb.nCount;
572                                  curvb.nCount = 0;                                  curvb.nCount = 0;
573                                  ptextarg->Resolve();                                  ptextarg->Resolve();
574                                  s_ClutResolve++;                                  s_ClutResolve++;
575                                  curvb.nCount += prevcount;                                  curvb.nCount += prevcount;
576                          }                          }
577    
578                          ptextarg = NULL;                          ptextarg = NULL;
579                  }                  }
580                  else                  else
581                  {                  {
582                          if (ptextarg == curvb.prndr)                          if (ptextarg == curvb.prndr)
583                          {                          {
584                                  // need feedback                                  // need feedback
585                                  curvb.prndr->CreateFeedback();                                  curvb.prndr->CreateFeedback();
586    
587                                  if (s_bWriteDepth && (curvb.pdepth != NULL))                                  if (s_bWriteDepth && (curvb.pdepth != NULL))
588                                          curvb.pdepth->SetRenderTarget(1);                                          curvb.pdepth->SetRenderTarget(1);
589                                  else                                  else
590                                          ResetRenderTarget(1);                                          ResetRenderTarget(1);
591                          }                          }
592                  }                  }
593          }          }
594          else          else
595          {          {
596                  ptextarg = NULL;                  ptextarg = NULL;
597          }          }
598    
599          return ptextarg;          return ptextarg;
600  }  }
601    
602  // Set target for current context  // Set target for current context
603  inline void FlushSetContextTarget(VB& curvb, int context)  inline void FlushSetContextTarget(VB& curvb, int context)
604  {  {
605          if (!curvb.bVarsSetTarg)          if (!curvb.bVarsSetTarg)
606          {          {
607                  SetContextTarget(context);                  SetContextTarget(context);
608          }          }
609          else          else
610          {          {
611                  assert(curvb.pdepth != NULL);                  assert(curvb.pdepth != NULL);
612    
613                  if (curvb.pdepth->status & CRenderTarget::TS_Virtual)                  if (curvb.pdepth->status & CRenderTarget::TS_Virtual)
614                  {                  {
615                          if (!curvb.zbuf.zmsk)                          if (!curvb.zbuf.zmsk)
616                          {                          {
617                                  CRenderTarget* ptemp = s_DepthRTs.Promote(GetFrameKey(curvb.pdepth));                                  CRenderTarget* ptemp = s_DepthRTs.Promote(GetFrameKey(curvb.pdepth));
618                                  assert(ptemp == curvb.pdepth);                                  assert(ptemp == curvb.pdepth);
619                          }                          }
620                          else                          else
621                          {                          {
622                                  curvb.pdepth->status &= ~CRenderTarget::TS_NeedUpdate;                                  curvb.pdepth->status &= ~CRenderTarget::TS_NeedUpdate;
623                          }                          }
624                  }                  }
625    
626                  if ((curvb.pdepth->status & CRenderTarget::TS_NeedUpdate) || (curvb.prndr->status & CRenderTarget::TS_NeedUpdate))                  if ((curvb.pdepth->status & CRenderTarget::TS_NeedUpdate) || (curvb.prndr->status & CRenderTarget::TS_NeedUpdate))
627                          SetContextTarget(context);                          SetContextTarget(context);
628          }          }
629    
630          assert(!(curvb.prndr->status&CRenderTarget::TS_NeedUpdate));          assert(!(curvb.prndr->status&CRenderTarget::TS_NeedUpdate));
631    
632          curvb.prndr->status = 0;          curvb.prndr->status = 0;
633    
634          if (curvb.pdepth != NULL)          if (curvb.pdepth != NULL)
635          {          {
636  #ifdef _DEBUG  #ifdef _DEBUG
637                  // Reduce an assert to a warning.                  // Reduce an assert to a warning.
638                  if (curvb.pdepth->status & CRenderTarget::TS_NeedUpdate)                  if (curvb.pdepth->status & CRenderTarget::TS_NeedUpdate)
639                  {                  {
640                          ZZLog::Debug_Log("In FlushSetContextTarget, pdepth has TS_NeedUpdate set.");                          ZZLog::Debug_Log("In FlushSetContextTarget, pdepth has TS_NeedUpdate set.");
641                  }                  }
642  #endif  #endif
643                  if (!curvb.zbuf.zmsk)                  if (!curvb.zbuf.zmsk)
644                  {                  {
645                          assert(!(curvb.pdepth->status & CRenderTarget::TS_Virtual));                          assert(!(curvb.pdepth->status & CRenderTarget::TS_Virtual));
646                          curvb.pdepth->status = 0;                          curvb.pdepth->status = 0;
647                  }                  }
648          }          }
649  }  }
650    
651  inline void FlushSetStream(VB& curvb)  inline void FlushSetStream(VB& curvb)
652  {  {
653          glBindBuffer(GL_ARRAY_BUFFER, g_vboBuffers[g_nCurVBOIndex]);          glBindBuffer(GL_ARRAY_BUFFER, g_vboBuffers[g_nCurVBOIndex]);
654          g_nCurVBOIndex = (g_nCurVBOIndex + 1) % g_vboBuffers.size();          g_nCurVBOIndex = (g_nCurVBOIndex + 1) % g_vboBuffers.size();
655          glBufferData(GL_ARRAY_BUFFER, curvb.nCount * sizeof(VertexGPU), curvb.pBufferData, GL_STREAM_DRAW);          glBufferData(GL_ARRAY_BUFFER, curvb.nCount * sizeof(VertexGPU), curvb.pBufferData, GL_STREAM_DRAW);
656  //      void* pdata = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);  //      void* pdata = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
657  //      memcpy_amd(pdata, curvb.pBufferData, curvb.nCount * sizeof(VertexGPU));  //      memcpy_amd(pdata, curvb.pBufferData, curvb.nCount * sizeof(VertexGPU));
658  //      glUnmapBuffer(GL_ARRAY_BUFFER);  //      glUnmapBuffer(GL_ARRAY_BUFFER);
659          SET_STREAM();          SET_STREAM();
660                    
661          GL_REPORT_ERRORD();          GL_REPORT_ERRORD();
662  }  }
663    
664  int SetMaskR = 0x0;  int SetMaskR = 0x0;
665  int SetMaskG = 0x0;  int SetMaskG = 0x0;
666  int SetMaskB = 0x0;  int SetMaskB = 0x0;
667  // Set color mask. Really, it's not as good as PS2 one.  // Set color mask. Really, it's not as good as PS2 one.
668  inline void FlushSetColorMask(VB& curvb)  inline void FlushSetColorMask(VB& curvb)
669  {  {
670          s_dwColorWrite = (PSMT_BITMODE(curvb.prndr->psm) == 1) ? (COLORMASK_BLUE | COLORMASK_GREEN | COLORMASK_RED) : 0xf;          s_dwColorWrite = (PSMT_BITMODE(curvb.prndr->psm) == 1) ? (COLORMASK_BLUE | COLORMASK_GREEN | COLORMASK_RED) : 0xf;
671    
672          int maskR = ZZOglGet_fbmRed_FrameBits(curvb.frame.fbm);          int maskR = ZZOglGet_fbmRed_FrameBits(curvb.frame.fbm);
673          int maskG = ZZOglGet_fbmGreen_FrameBits(curvb.frame.fbm);          int maskG = ZZOglGet_fbmGreen_FrameBits(curvb.frame.fbm);
674          int maskB = ZZOglGet_fbmBlue_FrameBits(curvb.frame.fbm);          int maskB = ZZOglGet_fbmBlue_FrameBits(curvb.frame.fbm);
675          int maskA = ZZOglGet_fbmAlpha_FrameBits(curvb.frame.fbm);          int maskA = ZZOglGet_fbmAlpha_FrameBits(curvb.frame.fbm);
676    
677          if (maskR == 0xff) s_dwColorWrite &= ~COLORMASK_RED;          if (maskR == 0xff) s_dwColorWrite &= ~COLORMASK_RED;
678          if (maskG == 0xff) s_dwColorWrite &= ~COLORMASK_GREEN;          if (maskG == 0xff) s_dwColorWrite &= ~COLORMASK_GREEN;
679          if (maskB == 0xff) s_dwColorWrite &= ~COLORMASK_BLUE;          if (maskB == 0xff) s_dwColorWrite &= ~COLORMASK_BLUE;
680    
681          if ((maskA == 0xff) || (curvb.curprim.abe && (curvb.test.atst == 2 && curvb.test.aref == 128)))          if ((maskA == 0xff) || (curvb.curprim.abe && (curvb.test.atst == 2 && curvb.test.aref == 128)))
682                  s_dwColorWrite &= ~COLORMASK_ALPHA;                  s_dwColorWrite &= ~COLORMASK_ALPHA;
683    
684          GL_COLORMASK(s_dwColorWrite);          GL_COLORMASK(s_dwColorWrite);
685  }  }
686    
687  // Set Scissors for scissor test.  // Set Scissors for scissor test.
688  inline void FlushSetScissorRect(VB& curvb)  inline void FlushSetScissorRect(VB& curvb)
689  {  {
690          Rect& scissor = curvb.prndr->scissorrect;          Rect& scissor = curvb.prndr->scissorrect;
691          glScissor(scissor.x, scissor.y, scissor.w, scissor.h);          glScissor(scissor.x, scissor.y, scissor.w, scissor.h);
692  }  }
693    
694  // Prior really doing something check context  // Prior really doing something check context
695  inline void FlushDoContextJob(VB& curvb, int context)  inline void FlushDoContextJob(VB& curvb, int context)
696  {  {
697          SaveRendererTarget(curvb);          SaveRendererTarget(curvb);
698    
699          FlushSetContextTarget(curvb, context);          FlushSetContextTarget(curvb, context);
700          icurctx = context;          icurctx = context;
701    
702          FlushSetStream(curvb);          FlushSetStream(curvb);
703          FlushSetColorMask(curvb);          FlushSetColorMask(curvb);
704          FlushSetScissorRect(curvb);          FlushSetScissorRect(curvb);
705  }  }
706    
707  // Set 1 is Alpha test is EQUAL and alpha should be proceed with care.  // Set 1 is Alpha test is EQUAL and alpha should be proceed with care.
708  inline int FlushGetExactcolor(const pixTest curtest)  inline int FlushGetExactcolor(const pixTest curtest)
709  {  {
710          if (!(g_nPixelShaderVer&SHADER_REDUCED))          if (!(g_nPixelShaderVer&SHADER_REDUCED))
711                  // ffx2 breaks when ==7                  // ffx2 breaks when ==7
712                  return ((curtest.ate && curtest.aref <= 128) && (curtest.atst == 4));//||curtest.atst==7);                  return ((curtest.ate && curtest.aref <= 128) && (curtest.atst == 4));//||curtest.atst==7);
713    
714          return 0;          return 0;
715  }  }
716    
717  // fill the buffer by decoding the clut  // fill the buffer by decoding the clut
718  inline void FlushDecodeClut(VB& curvb, GLuint& ptexclut)  inline void FlushDecodeClut(VB& curvb, GLuint& ptexclut)
719  {  {
720          glGenTextures(1, &ptexclut);          glGenTextures(1, &ptexclut);
721          glBindTexture(GL_TEXTURE_2D, ptexclut);          glBindTexture(GL_TEXTURE_2D, ptexclut);
722          vector<char> data(PSMT_ISHALF_STORAGE(curvb.tex0) ? 512 : 1024);          vector<char> data(PSMT_ISHALF_STORAGE(curvb.tex0) ? 512 : 1024);
723    
724          if (ptexclut != 0)          if (ptexclut != 0)
725          {          {
726    
727                  int nClutOffset = 0, clutsize;                  int nClutOffset = 0, clutsize;
728                  int entries = PSMT_IS8CLUT(curvb.tex0.psm) ? 256 : 16;                  int entries = PSMT_IS8CLUT(curvb.tex0.psm) ? 256 : 16;
729    
730                  if (curvb.tex0.csm && curvb.tex0.csa)                  if (curvb.tex0.csm && curvb.tex0.csa)
731                          printf("ERROR, csm1\n");                          printf("ERROR, csm1\n");
732    
733                  if (PSMT_IS32BIT(curvb.tex0.cpsm))   // 32 bit                  if (PSMT_IS32BIT(curvb.tex0.cpsm))   // 32 bit
734                  {                  {
735                          nClutOffset = 64 * curvb.tex0.csa;                          nClutOffset = 64 * curvb.tex0.csa;
736                          clutsize = min(entries, 256 - curvb.tex0.csa * 16) * 4;                          clutsize = min(entries, 256 - curvb.tex0.csa * 16) * 4;
737                  }                  }
738                  else                  else
739                  {                  {
740                          nClutOffset = 64 * (curvb.tex0.csa & 15) + (curvb.tex0.csa >= 16 ? 2 : 0);                          nClutOffset = 64 * (curvb.tex0.csa & 15) + (curvb.tex0.csa >= 16 ? 2 : 0);
741                          clutsize = min(entries, 512 - curvb.tex0.csa * 16) * 2;                          clutsize = min(entries, 512 - curvb.tex0.csa * 16) * 2;
742                  }                  }
743    
744                  if (PSMT_IS32BIT(curvb.tex0.cpsm))   // 32 bit                  if (PSMT_IS32BIT(curvb.tex0.cpsm))   // 32 bit
745                  {                  {
746                          memcpy_amd(&data[0], g_pbyGSClut + nClutOffset, clutsize);                          memcpy_amd(&data[0], g_pbyGSClut + nClutOffset, clutsize);
747                  }                  }
748                  else                  else
749                  {                  {
750                          u16* pClutBuffer = (u16*)(g_pbyGSClut + nClutOffset);                          u16* pClutBuffer = (u16*)(g_pbyGSClut + nClutOffset);
751                          u16* pclut = (u16*) & data[0];                          u16* pclut = (u16*) & data[0];
752                          int left = ((u32)nClutOffset & 2) ? 0 : ((nClutOffset & 0x3ff) / 2) + clutsize - 512;                          int left = ((u32)nClutOffset & 2) ? 0 : ((nClutOffset & 0x3ff) / 2) + clutsize - 512;
753    
754                          if (left > 0) clutsize -= left;                          if (left > 0) clutsize -= left;
755    
756                          while (clutsize > 0)                          while (clutsize > 0)
757                          {                          {
758                                  pclut[0] = pClutBuffer[0];                                  pclut[0] = pClutBuffer[0];
759                                  pclut++;                                  pclut++;
760                                  pClutBuffer += 2;                                  pClutBuffer += 2;
761                                  clutsize -= 2;                                  clutsize -= 2;
762                          }                          }
763    
764                          if (left > 0)                          if (left > 0)
765                          {                          {
766                                  pClutBuffer = (u16*)(g_pbyGSClut + 2);                                  pClutBuffer = (u16*)(g_pbyGSClut + 2);
767    
768                                  while (left > 0)                                  while (left > 0)
769                                  {                                  {
770                                          pclut[0] = pClutBuffer[0];                                          pclut[0] = pClutBuffer[0];
771                                          left -= 2;                                          left -= 2;
772                                          pClutBuffer += 2;                                          pClutBuffer += 2;
773                                          pclut++;                                          pclut++;
774                                  }                                  }
775                          }                          }
776                  }                  }
777    
778                  GLenum tempType = PSMT_ISHALF_STORAGE(curvb.tex0) ? GL_UNSIGNED_SHORT_5_5_5_1 : GL_UNSIGNED_BYTE;                  GLenum tempType = PSMT_ISHALF_STORAGE(curvb.tex0) ? GL_UNSIGNED_SHORT_5_5_5_1 : GL_UNSIGNED_BYTE;
779                  Texture2D(4, 256, 1, GL_RGBA, tempType, &data[0]);                  Texture2D(4, 256, 1, GL_RGBA, tempType, &data[0]);
780                                    
781                  s_vecTempTextures.push_back(ptexclut);                  s_vecTempTextures.push_back(ptexclut);
782    
783                  if (g_bSaveTex) SaveTexture("clut.tga", GL_TEXTURE_2D, ptexclut, 256, 1);                  if (g_bSaveTex) SaveTexture("clut.tga", GL_TEXTURE_2D, ptexclut, 256, 1);
784    
785                  setTex2DWrap(GL_REPEAT);                  setTex2DWrap(GL_REPEAT);
786                  setTex2DFilters(GL_LINEAR);                  setTex2DFilters(GL_LINEAR);
787          }          }
788  }  }
789    
790  inline int FlushGetShaderType(VB& curvb, CRenderTarget* ptextarg, GLuint& ptexclut)  inline int FlushGetShaderType(VB& curvb, CRenderTarget* ptextarg, GLuint& ptexclut)
791  {  {
792          if (PSMT_ISCLUT(curvb.tex0.psm) && !(conf.settings().no_target_clut))          if (PSMT_ISCLUT(curvb.tex0.psm) && !(conf.settings().no_target_clut))
793          {          {
794                  FlushDecodeClut(curvb, ptexclut);                  FlushDecodeClut(curvb, ptexclut);
795    
796                  if (!(g_nPixelShaderVer&SHADER_REDUCED) && PSMT_ISHALF(ptextarg->psm))                  if (!(g_nPixelShaderVer&SHADER_REDUCED) && PSMT_ISHALF(ptextarg->psm))
797                  {                  {
798                          return 4;                          return 4;
799                  }                  }
800                  else                  else
801                  {                  {
802                          // Valkyrie                          // Valkyrie
803                          return 2;                          return 2;
804                  }                  }
805          }          }
806    
807          if (PSMT_ISHALF_STORAGE(curvb.tex0) != PSMT_ISHALF(ptextarg->psm) && (!(g_nPixelShaderVer&SHADER_REDUCED) || !curvb.curprim.fge))          if (PSMT_ISHALF_STORAGE(curvb.tex0) != PSMT_ISHALF(ptextarg->psm) && (!(g_nPixelShaderVer&SHADER_REDUCED) || !curvb.curprim.fge))
808          {          {
809                  if (PSMT_ISHALF_STORAGE(curvb.tex0))                  if (PSMT_ISHALF_STORAGE(curvb.tex0))
810                  {                  {
811                          // converting from 32->16                          // converting from 32->16
812                          // Radiata Chronicles                          // Radiata Chronicles
813                          return 3;                          return 3;
814                  }                  }
815                  else                  else
816                  {                  {
817                          // converting from 16->32                          // converting from 16->32
818                          // Star Ward: Force                          // Star Ward: Force
819                          return 0;                          return 0;
820                  }                  }
821          }          }
822    
823          return 1;          return 1;
824  }  }
825    
826    
827  //Set page offsets depends on shader type.  //Set page offsets depends on shader type.
828  inline Vector FlushSetPageOffset(FRAGMENTSHADER* pfragment, int shadertype, CRenderTarget* ptextarg)  inline Vector FlushSetPageOffset(FRAGMENTSHADER* pfragment, int shadertype, CRenderTarget* ptextarg)
829  {  {
830          SetShaderCaller("FlushSetPageOffset");          SetShaderCaller("FlushSetPageOffset");
831    
832          Vector vpageoffset;          Vector vpageoffset;
833          vpageoffset.w = 0;          vpageoffset.w = 0;
834    
835          switch (shadertype)          switch (shadertype)
836          {          {
837                  case 3:                  case 3:
838                          vpageoffset.x = -0.1f / 256.0f;                          vpageoffset.x = -0.1f / 256.0f;
839                          vpageoffset.y = -0.001f / 256.0f;                          vpageoffset.y = -0.001f / 256.0f;
840                          vpageoffset.z = -0.1f / (ptextarg->fbh);                          vpageoffset.z = -0.1f / (ptextarg->fbh);
841                          vpageoffset.w = 0.0f;                          vpageoffset.w = 0.0f;
842                          break;                          break;
843    
844                  case 4:                  case 4:
845                          vpageoffset.x = 2;                          vpageoffset.x = 2;
846                          vpageoffset.y = 1;                          vpageoffset.y = 1;
847                          vpageoffset.z = 0;                          vpageoffset.z = 0;
848                          vpageoffset.w = 0.0001f;                          vpageoffset.w = 0.0001f;
849                          break;                          break;
850          }          }
851    
852          // zoe2          // zoe2
853          if (PSMT_ISZTEX(ptextarg->psm)) vpageoffset.w = -1.0f;          if (PSMT_ISZTEX(ptextarg->psm)) vpageoffset.w = -1.0f;
854    
855          ZZcgSetParameter4fv(pfragment->fPageOffset, vpageoffset, "g_fPageOffset");          ZZcgSetParameter4fv(pfragment->fPageOffset, vpageoffset, "g_fPageOffset");
856    
857          return vpageoffset;          return vpageoffset;
858  }  }
859    
860  //Set texture offsets depends omn shader type.  //Set texture offsets depends omn shader type.
861  inline Vector FlushSetTexOffset(FRAGMENTSHADER* pfragment, int shadertype, VB& curvb, CRenderTarget* ptextarg)  inline Vector FlushSetTexOffset(FRAGMENTSHADER* pfragment, int shadertype, VB& curvb, CRenderTarget* ptextarg)
862  {  {
863          SetShaderCaller("FlushSetTexOffset");          SetShaderCaller("FlushSetTexOffset");
864          Vector v;          Vector v;
865    
866          if (shadertype == 3)          if (shadertype == 3)
867          {          {
868                  Vector v;                  Vector v;
869                  v.x = 16.0f / (float)curvb.tex0.tw;                  v.x = 16.0f / (float)curvb.tex0.tw;
870                  v.y = 16.0f / (float)curvb.tex0.th;                  v.y = 16.0f / (float)curvb.tex0.th;
871                  v.z = 0.5f * v.x;                  v.z = 0.5f * v.x;
872                  v.w = 0.5f * v.y;                  v.w = 0.5f * v.y;
873                  ZZcgSetParameter4fv(pfragment->fTexOffset, v, "g_fTexOffset");                  ZZcgSetParameter4fv(pfragment->fTexOffset, v, "g_fTexOffset");
874          }          }
875          else if (shadertype == 4)          else if (shadertype == 4)
876          {          {
877                  Vector v;                  Vector v;
878                  v.x = 16.0f / (float)ptextarg->fbw;                  v.x = 16.0f / (float)ptextarg->fbw;
879                  v.y = 16.0f / (float)ptextarg->fbh;                  v.y = 16.0f / (float)ptextarg->fbh;
880                  v.z = -1;                  v.z = -1;
881                  v.w = 8.0f / (float)ptextarg->fbh;                  v.w = 8.0f / (float)ptextarg->fbh;
882                  ZZcgSetParameter4fv(pfragment->fTexOffset, v, "g_fTexOffset");                  ZZcgSetParameter4fv(pfragment->fTexOffset, v, "g_fTexOffset");
883          }          }
884    
885          return v;          return v;
886  }  }
887    
888  // Set dimension (Real!) of texture. z and w  // Set dimension (Real!) of texture. z and w
889  inline Vector FlushTextureDims(FRAGMENTSHADER* pfragment, int shadertype, VB& curvb, CRenderTarget* ptextarg)  inline Vector FlushTextureDims(FRAGMENTSHADER* pfragment, int shadertype, VB& curvb, CRenderTarget* ptextarg)
890  {  {
891          SetShaderCaller("FlushTextureDims");          SetShaderCaller("FlushTextureDims");
892          Vector vTexDims;          Vector vTexDims;
893          vTexDims.x = (float)RW(curvb.tex0.tw) ;          vTexDims.x = (float)RW(curvb.tex0.tw) ;
894          vTexDims.y = (float)RH(curvb.tex0.th) ;          vTexDims.y = (float)RH(curvb.tex0.th) ;
895    
896          // look at the offset of tbp0 from fbp          // look at the offset of tbp0 from fbp
897    
898          if (curvb.tex0.tbp0 <= ptextarg->fbp)          if (curvb.tex0.tbp0 <= ptextarg->fbp)
899          {          {
900                  vTexDims.z = 0;//-0.5f/(float)ptextarg->fbw;                  vTexDims.z = 0;//-0.5f/(float)ptextarg->fbw;
901                  vTexDims.w = 0;//0.2f/(float)ptextarg->fbh;                  vTexDims.w = 0;//0.2f/(float)ptextarg->fbh;
902          }          }
903          else          else
904          {          {
905                  //u32 tbp0 = curvb.tex0.tbp0 >> 5; // align to a page                  //u32 tbp0 = curvb.tex0.tbp0 >> 5; // align to a page
906                  int blockheight =  PSMT_ISHALF(ptextarg->psm) ? 64 : 32;                  int blockheight =  PSMT_ISHALF(ptextarg->psm) ? 64 : 32;
907                  int ycoord = ((curvb.tex0.tbp0 - ptextarg->fbp) / (32 * (ptextarg->fbw >> 6))) * blockheight;                  int ycoord = ((curvb.tex0.tbp0 - ptextarg->fbp) / (32 * (ptextarg->fbw >> 6))) * blockheight;
908                  int xcoord = (((curvb.tex0.tbp0 - ptextarg->fbp) % (32 * (ptextarg -> fbw >> 6)))) * 2;                  int xcoord = (((curvb.tex0.tbp0 - ptextarg->fbp) % (32 * (ptextarg -> fbw >> 6)))) * 2;
909                  vTexDims.z = (float)xcoord;                  vTexDims.z = (float)xcoord;
910                  vTexDims.w = (float)ycoord;                  vTexDims.w = (float)ycoord;
911          }          }
912    
913          if (shadertype == 4)          if (shadertype == 4)
914                  vTexDims.z += 8.0f;                  vTexDims.z += 8.0f;
915    
916          ZZcgSetParameter4fv(pfragment->fTexDims, vTexDims, "g_fTexDims");          ZZcgSetParameter4fv(pfragment->fTexDims, vTexDims, "g_fTexDims");
917    
918          return vTexDims;          return vTexDims;
919  }  }
920    
921  // Apply TEX1 mmag and mmin -- filter for expanding/reducing texture  // Apply TEX1 mmag and mmin -- filter for expanding/reducing texture
922  // We ignore all settings, only NEAREST (0) is used  // We ignore all settings, only NEAREST (0) is used
923  inline void FlushApplyResizeFilter(VB& curvb, u32& dwFilterOpts, CRenderTarget* ptextarg, int context)  inline void FlushApplyResizeFilter(VB& curvb, u32& dwFilterOpts, CRenderTarget* ptextarg, int context)
924  {  {
925          u32 ptexset = (ptextarg == curvb.prndr) ? ptextarg->ptexFeedback : ptextarg->ptex;          u32 ptexset = (ptextarg == curvb.prndr) ? ptextarg->ptexFeedback : ptextarg->ptex;
926          s_ptexCurSet[context] = ptexset;          s_ptexCurSet[context] = ptexset;
927    
928          if ((!curvb.tex1.mmag) || (!curvb.tex1.mmin))          if ((!curvb.tex1.mmag) || (!curvb.tex1.mmin))
929                  glBindTexture(GL_TEXTURE_RECTANGLE_NV, ptexset);                  glBindTexture(GL_TEXTURE_RECTANGLE_NV, ptexset);
930    
931          if (!curvb.tex1.mmag)          if (!curvb.tex1.mmag)
932          {          {
933                  glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST);                  glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
934                  dwFilterOpts |= 1;                  dwFilterOpts |= 1;
935          }          }
936    
937          if (!curvb.tex1.mmin)          if (!curvb.tex1.mmin)
938          {          {
939                  glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);                  glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
940                  dwFilterOpts |= 2;                  dwFilterOpts |= 2;
941          }          }
942  }  }
943    
944    
945  // Usage existing targets depends on several tricks, 32-16 conversion and CLUTing, so we need to handle it.  // Usage existing targets depends on several tricks, 32-16 conversion and CLUTing, so we need to handle it.
946  inline FRAGMENTSHADER* FlushUseExistRenderTarget(VB& curvb, CRenderTarget* ptextarg, u32& dwFilterOpts, int exactcolor, int context)  inline FRAGMENTSHADER* FlushUseExistRenderTarget(VB& curvb, CRenderTarget* ptextarg, u32& dwFilterOpts, int exactcolor, int context)
947  {  {
948          if (ptextarg->IsDepth())          if (ptextarg->IsDepth())
949                  SetWriteDepth();                  SetWriteDepth();
950    
951          GLuint ptexclut = 0;          GLuint ptexclut = 0;
952    
953          //int psm = GetTexCPSM(curvb.tex0);          //int psm = GetTexCPSM(curvb.tex0);
954          int shadertype = FlushGetShaderType(curvb, ptextarg, ptexclut);          int shadertype = FlushGetShaderType(curvb, ptextarg, ptexclut);
955    
956          FRAGMENTSHADER* pfragment = LoadShadeEffect(shadertype, 0, curvb.curprim.fge,          FRAGMENTSHADER* pfragment = LoadShadeEffect(shadertype, 0, curvb.curprim.fge,
957                                                                  IsAlphaTestExpansion(curvb), exactcolor, curvb.clamp, context, NULL);                                                                  IsAlphaTestExpansion(curvb), exactcolor, curvb.clamp, context, NULL);
958    
959          Vector vpageoffset = FlushSetPageOffset(pfragment, shadertype, ptextarg);          Vector vpageoffset = FlushSetPageOffset(pfragment, shadertype, ptextarg);
960    
961          Vector v = FlushSetTexOffset(pfragment, shadertype, curvb, ptextarg);          Vector v = FlushSetTexOffset(pfragment, shadertype, curvb, ptextarg);
962    
963          Vector vTexDims = FlushTextureDims(pfragment, shadertype, curvb, ptextarg);          Vector vTexDims = FlushTextureDims(pfragment, shadertype, curvb, ptextarg);
964    
965          if (pfragment->sCLUT != NULL && ptexclut != 0)          if (pfragment->sCLUT != NULL && ptexclut != 0)
966          {          {
967                  cgGLSetTextureParameter(pfragment->sCLUT, ptexclut);                  cgGLSetTextureParameter(pfragment->sCLUT, ptexclut);
968                  cgGLEnableTextureParameter(pfragment->sCLUT);                  cgGLEnableTextureParameter(pfragment->sCLUT);
969          }          }
970    
971          FlushApplyResizeFilter(curvb, dwFilterOpts, ptextarg, context);          FlushApplyResizeFilter(curvb, dwFilterOpts, ptextarg, context);
972    
973          if (g_bSaveTex)          if (g_bSaveTex)
974                  SaveTexture("tex.tga", GL_TEXTURE_RECTANGLE_NV,                  SaveTexture("tex.tga", GL_TEXTURE_RECTANGLE_NV,
975                                          ptextarg == curvb.prndr ? ptextarg->ptexFeedback : ptextarg->ptex, RW(ptextarg->fbw), RH(ptextarg->fbh));                                          ptextarg == curvb.prndr ? ptextarg->ptexFeedback : ptextarg->ptex, RW(ptextarg->fbw), RH(ptextarg->fbh));
976    
977          return pfragment;          return pfragment;
978  }  }
979    
980  // Usage most major shader.  // Usage most major shader.
981  inline FRAGMENTSHADER* FlushMadeNewTarget(VB& curvb, int exactcolor, int context)  inline FRAGMENTSHADER* FlushMadeNewTarget(VB& curvb, int exactcolor, int context)
982  {  {
983          // save the texture          // save the texture
984          if (g_bSaveTex)          if (g_bSaveTex)
985          {          {
986                  if (g_bSaveTex == 1)                  if (g_bSaveTex == 1)
987                  {                  {
988                          SaveTex(&curvb.tex0, 1);                          SaveTex(&curvb.tex0, 1);
989                          /*CMemoryTarget* pmemtarg = */                          /*CMemoryTarget* pmemtarg = */
990                          g_MemTargs.GetMemoryTarget(curvb.tex0, 0);                          g_MemTargs.GetMemoryTarget(curvb.tex0, 0);
991                  }                  }
992                  else                  else
993                  {                  {
994                          SaveTex(&curvb.tex0, 0);                          SaveTex(&curvb.tex0, 0);
995                  }                  }
996          }          }
997    
998          FRAGMENTSHADER* pfragment = LoadShadeEffect(0, GetTexFilter(curvb.tex1), curvb.curprim.fge,          FRAGMENTSHADER* pfragment = LoadShadeEffect(0, GetTexFilter(curvb.tex1), curvb.curprim.fge,
999                                                                  IsAlphaTestExpansion(curvb), exactcolor, curvb.clamp, context, NULL);                                                                  IsAlphaTestExpansion(curvb), exactcolor, curvb.clamp, context, NULL);
1000    
1001          if (pfragment == NULL)          if (pfragment == NULL)
1002                  ZZLog::Error_Log("Could not find memory target shader.");                  ZZLog::Error_Log("Could not find memory target shader.");
1003    
1004          return pfragment;          return pfragment;
1005  }  }
1006    
1007  // We made an shader, so now need to put all common variables.  // We made an shader, so now need to put all common variables.
1008  inline void FlushSetTexture(VB& curvb, FRAGMENTSHADER* pfragment, CRenderTarget* ptextarg, int context)  inline void FlushSetTexture(VB& curvb, FRAGMENTSHADER* pfragment, CRenderTarget* ptextarg, int context)
1009  {  {
1010          SetTexVariables(context, pfragment);          SetTexVariables(context, pfragment);
1011          SetTexInt(context, pfragment, ptextarg == NULL);          SetTexInt(context, pfragment, ptextarg == NULL);
1012    
1013          // have to enable the texture parameters(curtest.atst=          // have to enable the texture parameters(curtest.atst=
1014    
1015          if (curvb.ptexClamp[0] != 0)          if (curvb.ptexClamp[0] != 0)
1016          {          {
1017                  cgGLSetTextureParameter(pfragment->sBitwiseANDX, curvb.ptexClamp[0]);                  cgGLSetTextureParameter(pfragment->sBitwiseANDX, curvb.ptexClamp[0]);
1018                  cgGLEnableTextureParameter(pfragment->sBitwiseANDX);                  cgGLEnableTextureParameter(pfragment->sBitwiseANDX);
1019          }          }
1020    
1021          if (curvb.ptexClamp[1] != 0)          if (curvb.ptexClamp[1] != 0)
1022          {          {
1023                  cgGLSetTextureParameter(pfragment->sBitwiseANDY, curvb.ptexClamp[1]);                  cgGLSetTextureParameter(pfragment->sBitwiseANDY, curvb.ptexClamp[1]);
1024                  cgGLEnableTextureParameter(pfragment->sBitwiseANDY);                  cgGLEnableTextureParameter(pfragment->sBitwiseANDY);
1025          }          }
1026    
1027          if (pfragment->sMemory != NULL && s_ptexCurSet[context] != 0)          if (pfragment->sMemory != NULL && s_ptexCurSet[context] != 0)
1028          {          {
1029                  cgGLSetTextureParameter(pfragment->sMemory, s_ptexCurSet[context]);                  cgGLSetTextureParameter(pfragment->sMemory, s_ptexCurSet[context]);
1030                  cgGLEnableTextureParameter(pfragment->sMemory);                  cgGLEnableTextureParameter(pfragment->sMemory);
1031          }          }
1032  }  }
1033    
1034  // Reset programm and texture variables;  // Reset programm and texture variables;
1035  inline void FlushBindProgramm(FRAGMENTSHADER* pfragment, int context)  inline void FlushBindProgramm(FRAGMENTSHADER* pfragment, int context)
1036  {  {
1037          vb[context].bTexConstsSync = 0;          vb[context].bTexConstsSync = 0;
1038          vb[context].bVarsTexSync = 0;          vb[context].bVarsTexSync = 0;
1039    
1040          cgGLBindProgram(pfragment->prog);          cgGLBindProgram(pfragment->prog);
1041          g_psprog = pfragment->prog;          g_psprog = pfragment->prog;
1042  }  }
1043    
1044  inline FRAGMENTSHADER* FlushRendererStage(VB& curvb, u32& dwFilterOpts, CRenderTarget* ptextarg, int exactcolor, int context)  inline FRAGMENTSHADER* FlushRendererStage(VB& curvb, u32& dwFilterOpts, CRenderTarget* ptextarg, int exactcolor, int context)
1045  {  {
1046    
1047          FRAGMENTSHADER* pfragment = NULL;          FRAGMENTSHADER* pfragment = NULL;
1048    
1049          // set the correct pixel shaders          // set the correct pixel shaders
1050    
1051          if (curvb.curprim.tme)          if (curvb.curprim.tme)
1052          {          {
1053                  if (ptextarg != NULL)                  if (ptextarg != NULL)
1054                          pfragment = FlushUseExistRenderTarget(curvb, ptextarg, dwFilterOpts, exactcolor, context);                          pfragment = FlushUseExistRenderTarget(curvb, ptextarg, dwFilterOpts, exactcolor, context);
1055                  else                  else
1056                          pfragment = FlushMadeNewTarget(curvb, exactcolor, context);                          pfragment = FlushMadeNewTarget(curvb, exactcolor, context);
1057    
1058                  if (pfragment == NULL)                  if (pfragment == NULL)
1059                  {                  {
1060                          ZZLog::Error_Log("Shader is not found.");                          ZZLog::Error_Log("Shader is not found.");
1061  //                      return NULL;  //                      return NULL;
1062                  }                  }
1063    
1064                  FlushSetTexture(curvb, pfragment, ptextarg, context);                  FlushSetTexture(curvb, pfragment, ptextarg, context);
1065          }          }
1066          else          else
1067          {          {
1068                  pfragment = &ppsRegular[curvb.curprim.fge + 2 * s_bWriteDepth];                  pfragment = &ppsRegular[curvb.curprim.fge + 2 * s_bWriteDepth];
1069          }          }
1070    
1071          GL_REPORT_ERRORD();          GL_REPORT_ERRORD();
1072    
1073          // set the shaders          // set the shaders
1074          SetShaderCaller("FlushRendererStage")   ;          SetShaderCaller("FlushRendererStage")   ;
1075          SETVERTEXSHADER(pvs[2 * ((curvb.curprim._val >> 1) & 3) + 8 * s_bWriteDepth + context]);          SETVERTEXSHADER(pvs[2 * ((curvb.curprim._val >> 1) & 3) + 8 * s_bWriteDepth + context]);
1076          FlushBindProgramm(pfragment, context);          FlushBindProgramm(pfragment, context);
1077    
1078          GL_REPORT_ERRORD();          GL_REPORT_ERRORD();
1079          return pfragment;          return pfragment;
1080  }  }
1081    
1082  inline bool AlphaCanRenderStencil(VB& curvb)  inline bool AlphaCanRenderStencil(VB& curvb)
1083  {  {
1084          return g_bUpdateStencil && (PSMT_BITMODE(curvb.prndr->psm) != 1) &&          return g_bUpdateStencil && (PSMT_BITMODE(curvb.prndr->psm) != 1) &&
1085                     !ZZOglGet_fbmHighByte(curvb.frame.fbm) && !(conf.settings().no_stencil);                     !ZZOglGet_fbmHighByte(curvb.frame.fbm) && !(conf.settings().no_stencil);
1086  }  }
1087    
1088  inline void AlphaSetStencil(bool DoIt)  inline void AlphaSetStencil(bool DoIt)
1089  {  {
1090          if (DoIt)          if (DoIt)
1091          {          {
1092                  glEnable(GL_STENCIL_TEST);                  glEnable(GL_STENCIL_TEST);
1093                  GL_STENCILFUNC(GL_ALWAYS, 0, 0);                  GL_STENCILFUNC(GL_ALWAYS, 0, 0);
1094                  glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);                  glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
1095          }          }
1096          else glDisable(GL_STENCIL_TEST);          else glDisable(GL_STENCIL_TEST);
1097  }  }
1098    
1099  inline void AlphaSetDepthTest(VB& curvb, const pixTest curtest, FRAGMENTSHADER* pfragment)  inline void AlphaSetDepthTest(VB& curvb, const pixTest curtest, FRAGMENTSHADER* pfragment)
1100  {  {
1101          glDepthMask(!curvb.zbuf.zmsk && curtest.zte);          glDepthMask(!curvb.zbuf.zmsk && curtest.zte);
1102          //      && curtest.zte &&  (curtest.ztst > 1) );          //      && curtest.zte &&  (curtest.ztst > 1) );
1103    
1104          if (curtest.zte)          if (curtest.zte)
1105          {          {
1106                  if (curtest.ztst > 1) g_nDepthUsed = 2;                  if (curtest.ztst > 1) g_nDepthUsed = 2;
1107                  if ((curtest.ztst == 2) ^(g_nDepthBias != 0))                  if ((curtest.ztst == 2) ^(g_nDepthBias != 0))
1108                  {                  {
1109                          g_nDepthBias = (curtest.ztst == 2);                          g_nDepthBias = (curtest.ztst == 2);
1110                          //SETRS(D3DRS_DEPTHBIAS, g_nDepthBias?FtoDW(0.0003f):FtoDW(0.000015f));                          //SETRS(D3DRS_DEPTHBIAS, g_nDepthBias?FtoDW(0.0003f):FtoDW(0.000015f));
1111                  }                  }
1112    
1113                  glDepthFunc(g_dwZCmp[curtest.ztst]);                  glDepthFunc(g_dwZCmp[curtest.ztst]);
1114          }          }
1115    
1116          GL_ZTEST(curtest.zte);          GL_ZTEST(curtest.zte);
1117    
1118  //      glEnable (GL_POLYGON_OFFSET_FILL);  //      glEnable (GL_POLYGON_OFFSET_FILL);
1119  //        glPolygonOffset (-1., -1.);  //        glPolygonOffset (-1., -1.);
1120    
1121          if (s_bWriteDepth)          if (s_bWriteDepth)
1122          {          {
1123                  if (!curvb.zbuf.zmsk)                  if (!curvb.zbuf.zmsk)
1124                          curvb.pdepth->SetRenderTarget(1);                          curvb.pdepth->SetRenderTarget(1);
1125                  else                  else
1126                          ResetRenderTarget(1);                          ResetRenderTarget(1);
1127          }          }
1128  }  }
1129    
1130  inline u32 AlphaSetupBlendTest(VB& curvb)  inline u32 AlphaSetupBlendTest(VB& curvb)
1131  {  {
1132          if (curvb.curprim.abe)          if (curvb.curprim.abe)
1133                  SetAlphaVariables(curvb.alpha);                  SetAlphaVariables(curvb.alpha);
1134          else          else
1135                  glDisable(GL_BLEND);                  glDisable(GL_BLEND);
1136    
1137          u32 oldabe = curvb.curprim.abe;          u32 oldabe = curvb.curprim.abe;
1138    
1139          if (gs.pabe)          if (gs.pabe)
1140          {          {
1141                  //ZZLog::Error_Log("PABE!");                  //ZZLog::Error_Log("PABE!");
1142                  curvb.curprim.abe = 1;                  curvb.curprim.abe = 1;
1143                  glEnable(GL_BLEND);                  glEnable(GL_BLEND);
1144          }          }
1145    
1146          return oldabe;          return oldabe;
1147  }  }
1148    
1149  inline void AlphaRenderFBA(VB& curvb, FRAGMENTSHADER* pfragment, bool s_bDestAlphaTest, bool bCanRenderStencil)  inline void AlphaRenderFBA(VB& curvb, FRAGMENTSHADER* pfragment, bool s_bDestAlphaTest, bool bCanRenderStencil)
1150  {  {
1151          // needs to be before RenderAlphaTest          // needs to be before RenderAlphaTest
1152          if ((gs.pabe) || (curvb.fba.fba && !ZZOglGet_fbmHighByte(curvb.frame.fbm)) || (s_bDestAlphaTest && bCanRenderStencil))          if ((gs.pabe) || (curvb.fba.fba && !ZZOglGet_fbmHighByte(curvb.frame.fbm)) || (s_bDestAlphaTest && bCanRenderStencil))
1153          {          {
1154                  RenderFBA(curvb, pfragment->sOneColor);                  RenderFBA(curvb, pfragment->sOneColor);
1155          }          }
1156    
1157  }  }
1158    
1159  inline u32 AlphaRenderAlpha(VB& curvb, const pixTest curtest, FRAGMENTSHADER* pfragment, int exactcolor)  inline u32 AlphaRenderAlpha(VB& curvb, const pixTest curtest, FRAGMENTSHADER* pfragment, int exactcolor)
1160  {  {
1161          SetShaderCaller("AlphaRenderAlpha");          SetShaderCaller("AlphaRenderAlpha");
1162          u32 dwUsingSpecialTesting = 0;          u32 dwUsingSpecialTesting = 0;
1163    
1164          if (curvb.curprim.abe)          if (curvb.curprim.abe)
1165          {          {
1166                  if ((bNeedBlendFactorInAlpha || ((curtest.ate && curtest.atst > 1) && (curtest.aref > 0x80))))                  if ((bNeedBlendFactorInAlpha || ((curtest.ate && curtest.atst > 1) && (curtest.aref > 0x80))))
1167                  {                  {
1168                          // need special stencil processing for the alpha                          // need special stencil processing for the alpha
1169                          RenderAlphaTest(curvb, pfragment->sOneColor);                          RenderAlphaTest(curvb, pfragment->sOneColor);
1170                          dwUsingSpecialTesting = 1;                          dwUsingSpecialTesting = 1;
1171                  }                  }
1172    
1173                  // harvest fishing                  // harvest fishing
1174                  Vector v = vAlphaBlendColor;                  Vector v = vAlphaBlendColor;
1175    
1176                  if (exactcolor)                  if (exactcolor)
1177                  {                  {
1178                          v.y *= 255;                          v.y *= 255;
1179                          v.w *= 255;                          v.w *= 255;
1180                  }                  }
1181    
1182                  ZZcgSetParameter4fv(pfragment->sOneColor, v, "g_fOneColor");                  ZZcgSetParameter4fv(pfragment->sOneColor, v, "g_fOneColor");
1183          }          }
1184          else          else
1185          {          {
1186                  // not using blending so set to defaults                  // not using blending so set to defaults
1187                  Vector v = exactcolor ? Vector(1, 510 * 255.0f / 256.0f, 0, 0) : Vector(1, 2 * 255.0f / 256.0f, 0, 0);                  Vector v = exactcolor ? Vector(1, 510 * 255.0f / 256.0f, 0, 0) : Vector(1, 2 * 255.0f / 256.0f, 0, 0);
1188                  ZZcgSetParameter4fv(pfragment->sOneColor, v, "g_fOneColor");                  ZZcgSetParameter4fv(pfragment->sOneColor, v, "g_fOneColor");
1189    
1190          }          }
1191    
1192          return dwUsingSpecialTesting;          return dwUsingSpecialTesting;
1193  }  }
1194    
1195  inline void AlphaRenderStencil(VB& curvb, bool s_bDestAlphaTest, bool bCanRenderStencil, u32 dwUsingSpecialTesting)  inline void AlphaRenderStencil(VB& curvb, bool s_bDestAlphaTest, bool bCanRenderStencil, u32 dwUsingSpecialTesting)
1196  {  {
1197          if (s_bDestAlphaTest && bCanRenderStencil)          if (s_bDestAlphaTest && bCanRenderStencil)
1198          {          {
1199                  // if not 24bit and can write to high alpha bit                  // if not 24bit and can write to high alpha bit
1200                  RenderStencil(curvb, dwUsingSpecialTesting);                  RenderStencil(curvb, dwUsingSpecialTesting);
1201          }          }
1202          else          else
1203          {          {
1204                  s_stencilref = STENCIL_SPECIAL;                  s_stencilref = STENCIL_SPECIAL;
1205                  s_stencilmask = STENCIL_SPECIAL;                  s_stencilmask = STENCIL_SPECIAL;
1206    
1207                  // setup the stencil to only accept the test pixels                  // setup the stencil to only accept the test pixels
1208    
1209                  if (dwUsingSpecialTesting)                  if (dwUsingSpecialTesting)
1210                  {                  {
1211                          glEnable(GL_STENCIL_TEST);                          glEnable(GL_STENCIL_TEST);
1212                          glStencilMask(STENCIL_PIXELWRITE);                          glStencilMask(STENCIL_PIXELWRITE);
1213                          GL_STENCILFUNC(GL_EQUAL, STENCIL_SPECIAL | STENCIL_PIXELWRITE, STENCIL_SPECIAL);                          GL_STENCILFUNC(GL_EQUAL, STENCIL_SPECIAL | STENCIL_PIXELWRITE, STENCIL_SPECIAL);
1214                          glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);                          glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
1215                  }                  }
1216          }          }
1217    
1218  #ifdef _DEBUG  #ifdef _DEBUG
1219          if (bDestAlphaColor == 1)          if (bDestAlphaColor == 1)
1220          {          {
1221                  ZZLog::Debug_Log("Dest alpha blending! Manipulate alpha here.");                  ZZLog::Debug_Log("Dest alpha blending! Manipulate alpha here.");
1222          }          }
1223    
1224  #endif  #endif
1225    
1226          if (bCanRenderStencil && gs.pabe)          if (bCanRenderStencil && gs.pabe)
1227          {          {
1228                  // only render the pixels with alpha values >= 0x80                  // only render the pixels with alpha values >= 0x80
1229                  GL_STENCILFUNC(GL_EQUAL, s_stencilref | STENCIL_FBA, s_stencilmask | STENCIL_FBA);                  GL_STENCILFUNC(GL_EQUAL, s_stencilref | STENCIL_FBA, s_stencilmask | STENCIL_FBA);
1230          }          }
1231    
1232          GL_REPORT_ERRORD();          GL_REPORT_ERRORD();
1233  }  }
1234    
1235  inline void AlphaTest(VB& curvb)  inline void AlphaTest(VB& curvb)
1236  {  {
1237  //      printf ("%d %d %d %d %d\n", curvb.test.date, curvb.test.datm, gs.texa.aem, curvb.test.ate, curvb.test.atst );  //      printf ("%d %d %d %d %d\n", curvb.test.date, curvb.test.datm, gs.texa.aem, curvb.test.ate, curvb.test.atst );
1238    
1239  //      return;  //      return;
1240          // Zeydlitz changed this with a reason! It's an "Alpha more than 1 hack."          // Zeydlitz changed this with a reason! It's an "Alpha more than 1 hack."
1241          if (curvb.test.ate == 1 && curvb.test.atst == 1 && curvb.test.date == 1)          if (curvb.test.ate == 1 && curvb.test.atst == 1 && curvb.test.date == 1)
1242          {          {
1243                  if (curvb.test.datm == 1)                  if (curvb.test.datm == 1)
1244                  {                  {
1245                          glAlphaFunc(GL_GREATER, 1.0f);                          glAlphaFunc(GL_GREATER, 1.0f);
1246                  }                  }
1247                  else                  else
1248                  {                  {
1249                          glAlphaFunc(GL_LESS, 1.0f);                          glAlphaFunc(GL_LESS, 1.0f);
1250                          printf("%d %d %d\n", curvb.test.date, curvb.test.datm, gs.texa.aem);                          printf("%d %d %d\n", curvb.test.date, curvb.test.datm, gs.texa.aem);
1251                  }                  }
1252          }          }
1253    
1254          if (!curvb.test.ate || curvb.test.atst > 0)          if (!curvb.test.ate || curvb.test.atst > 0)
1255          {          {
1256                  Draw(curvb);                  Draw(curvb);
1257          }          }
1258    
1259          GL_REPORT_ERRORD();          GL_REPORT_ERRORD();
1260  }  }
1261    
1262  inline void AlphaPabe(VB& curvb, FRAGMENTSHADER* pfragment, int exactcolor)  inline void AlphaPabe(VB& curvb, FRAGMENTSHADER* pfragment, int exactcolor)
1263  {  {
1264          if (gs.pabe)          if (gs.pabe)
1265          {          {
1266                  SetShaderCaller("AlphaPabe");                  SetShaderCaller("AlphaPabe");
1267                  // only render the pixels with alpha values < 0x80                  // only render the pixels with alpha values < 0x80
1268                  glDisable(GL_BLEND);                  glDisable(GL_BLEND);
1269                  GL_STENCILFUNC_SET();                  GL_STENCILFUNC_SET();
1270    
1271                  Vector v;                  Vector v;
1272                  v.x = 1;                  v.x = 1;
1273                  v.y = 2;                  v.y = 2;
1274                  v.z = 0;                  v.z = 0;
1275                  v.w = 0;                  v.w = 0;
1276    
1277                  if (exactcolor) v.y *= 255;                  if (exactcolor) v.y *= 255;
1278    
1279                  ZZcgSetParameter4fv(pfragment->sOneColor, v, "g_fOneColor");                  ZZcgSetParameter4fv(pfragment->sOneColor, v, "g_fOneColor");
1280    
1281                  Draw(curvb);                  Draw(curvb);
1282    
1283                  // reset                  // reset
1284                  if (!s_stencilmask) s_stencilfunc = GL_ALWAYS;                  if (!s_stencilmask) s_stencilfunc = GL_ALWAYS;
1285    
1286                  GL_STENCILFUNC_SET();                  GL_STENCILFUNC_SET();
1287          }          }
1288    
1289          GL_REPORT_ERRORD();          GL_REPORT_ERRORD();
1290  }  }
1291    
1292  // Alpha Failure does not work properly on this cases. True means that no failure job should be done.  // Alpha Failure does not work properly on this cases. True means that no failure job should be done.
1293  // First three cases are trivial manual.  // First three cases are trivial manual.
1294  inline bool AlphaFailureIgnore(const pixTest curtest)  inline bool AlphaFailureIgnore(const pixTest curtest)
1295  {  {
1296          if ((!curtest.ate) || (curtest.atst == 1) || (curtest.afail == 0)) return true;          if ((!curtest.ate) || (curtest.atst == 1) || (curtest.afail == 0)) return true;
1297    
1298          if (conf.settings().no_alpha_fail && ((s_dwColorWrite < 8) || (s_dwColorWrite == 15 && curtest.atst == 5 && (curtest.aref == 64))))          if (conf.settings().no_alpha_fail && ((s_dwColorWrite < 8) || (s_dwColorWrite == 15 && curtest.atst == 5 && (curtest.aref == 64))))
1299                  return true;                  return true;
1300    
1301  //      old and seemingly incorrect code.  //      old and seemingly incorrect code.
1302  //      if ((s_dwColorWrite < 8 && s_dwColorWrite !=8) && curtest.afail == 1)  //      if ((s_dwColorWrite < 8 && s_dwColorWrite !=8) && curtest.afail == 1)
1303  //              return true;  //              return true;
1304  //      if ((s_dwColorWrite == 0xf) && curtest.atst == 5 && curtest.afail == 1 && !(conf.settings() & GAME_REGETHACK))  //      if ((s_dwColorWrite == 0xf) && curtest.atst == 5 && curtest.afail == 1 && !(conf.settings() & GAME_REGETHACK))
1305  //              return true;  //              return true;
1306          return false;          return false;
1307  }  }
1308    
1309  // more work on alpha failure case  // more work on alpha failure case
1310  inline void AlphaFailureTestJob(VB& curvb, const pixTest curtest,  FRAGMENTSHADER* pfragment, int exactcolor, bool bCanRenderStencil, int oldabe)  inline void AlphaFailureTestJob(VB& curvb, const pixTest curtest,  FRAGMENTSHADER* pfragment, int exactcolor, bool bCanRenderStencil, int oldabe)
1311  {  {
1312          // Note, case when ate == 1, atst == 0 and afail > 0 in documentation wrote as failure case. But it seems that          // Note, case when ate == 1, atst == 0 and afail > 0 in documentation wrote as failure case. But it seems that
1313          // either doc's are incorrect or this case has some issues.          // either doc's are incorrect or this case has some issues.
1314          if (AlphaFailureIgnore(curtest)) return;          if (AlphaFailureIgnore(curtest)) return;
1315    
1316  #ifdef NOALFAFAIL  #ifdef NOALFAFAIL
1317          ZZLog::Error_Log("Alpha job here %d %d %d %d %d %d", s_dwColorWrite, curtest.atst, curtest.afail, curtest.aref, gs.pabe, s_bWriteDepth);          ZZLog::Error_Log("Alpha job here %d %d %d %d %d %d", s_dwColorWrite, curtest.atst, curtest.afail, curtest.aref, gs.pabe, s_bWriteDepth);
1318    
1319  //      return;  //      return;
1320  #endif  #endif
1321    
1322          SetShaderCaller("AlphaFailureTestJob");          SetShaderCaller("AlphaFailureTestJob");
1323    
1324          // need to reverse the test and disable some targets          // need to reverse the test and disable some targets
1325          glAlphaFunc(g_dwReverseAlphaCmp[curtest.atst], AlphaReferedValue(curtest.aref));          glAlphaFunc(g_dwReverseAlphaCmp[curtest.atst], AlphaReferedValue(curtest.aref));
1326    
1327          if (curtest.afail & 1)     // front buffer update only          if (curtest.afail & 1)     // front buffer update only
1328          {          {
1329                  if (curtest.afail == 3) glColorMask(1, 1, 1, 0);// disable alpha                  if (curtest.afail == 3) glColorMask(1, 1, 1, 0);// disable alpha
1330    
1331                  glDepthMask(0);                  glDepthMask(0);
1332    
1333                  if (s_bWriteDepth) ResetRenderTarget(1);                  if (s_bWriteDepth) ResetRenderTarget(1);
1334          }          }
1335          else          else
1336          {          {
1337                  // zbuffer update only                  // zbuffer update only
1338                  glColorMask(0, 0, 0, 0);                  glColorMask(0, 0, 0, 0);
1339          }          }
1340    
1341          if (gs.pabe && bCanRenderStencil)          if (gs.pabe && bCanRenderStencil)
1342          {          {
1343                  // only render the pixels with alpha values >= 0x80                  // only render the pixels with alpha values >= 0x80
1344                  Vector v = vAlphaBlendColor;                  Vector v = vAlphaBlendColor;
1345    
1346                  if (exactcolor) { v.y *= 255; v.w *= 255; }                  if (exactcolor) { v.y *= 255; v.w *= 255; }
1347    
1348                  ZZcgSetParameter4fv(pfragment->sOneColor, v, "g_fOneColor");                  ZZcgSetParameter4fv(pfragment->sOneColor, v, "g_fOneColor");
1349    
1350                  glEnable(GL_BLEND);                  glEnable(GL_BLEND);
1351                  GL_STENCILFUNC(GL_EQUAL, s_stencilref | STENCIL_FBA, s_stencilmask | STENCIL_FBA);                  GL_STENCILFUNC(GL_EQUAL, s_stencilref | STENCIL_FBA, s_stencilmask | STENCIL_FBA);
1352          }          }
1353    
1354          Draw(curvb);          Draw(curvb);
1355    
1356          GL_REPORT_ERRORD();          GL_REPORT_ERRORD();
1357    
1358          if (gs.pabe)          if (gs.pabe)
1359          {          {
1360                  // only render the pixels with alpha values < 0x80                  // only render the pixels with alpha values < 0x80
1361                  glDisable(GL_BLEND);                  glDisable(GL_BLEND);
1362                  GL_STENCILFUNC_SET();                  GL_STENCILFUNC_SET();
1363    
1364                  Vector v;                  Vector v;
1365                  v.x = 1;                  v.x = 1;
1366                  v.y = 2;                  v.y = 2;
1367                  v.z = 0;                  v.z = 0;
1368                  v.w = 0;                  v.w = 0;
1369    
1370                  if (exactcolor) v.y *= 255;                  if (exactcolor) v.y *= 255;
1371    
1372                  ZZcgSetParameter4fv(pfragment->sOneColor, v, "g_fOneColor");                  ZZcgSetParameter4fv(pfragment->sOneColor, v, "g_fOneColor");
1373    
1374                  Draw(curvb);                  Draw(curvb);
1375    
1376                  // reset                  // reset
1377                  if (oldabe) glEnable(GL_BLEND);                  if (oldabe) glEnable(GL_BLEND);
1378    
1379                  if (!s_stencilmask) s_stencilfunc = GL_ALWAYS;                  if (!s_stencilmask) s_stencilfunc = GL_ALWAYS;
1380    
1381                  GL_STENCILFUNC_SET();                  GL_STENCILFUNC_SET();
1382          }          }
1383    
1384          // restore          // restore
1385          if ((curtest.afail & 1) && !curvb.zbuf.zmsk)          if ((curtest.afail & 1) && !curvb.zbuf.zmsk)
1386          {          {
1387                  glDepthMask(1);                  glDepthMask(1);
1388    
1389                  if (s_bWriteDepth)                  if (s_bWriteDepth)
1390                  {                  {
1391                          assert(curvb.pdepth != NULL);                          assert(curvb.pdepth != NULL);
1392                          curvb.pdepth->SetRenderTarget(1);                          curvb.pdepth->SetRenderTarget(1);
1393                  }                  }
1394          }          }
1395    
1396          GL_COLORMASK(s_dwColorWrite);          GL_COLORMASK(s_dwColorWrite);
1397    
1398          // not needed anymore since rest of ops concentrate on image processing          // not needed anymore since rest of ops concentrate on image processing
1399    
1400          GL_REPORT_ERRORD();          GL_REPORT_ERRORD();
1401  }  }
1402    
1403  inline void AlphaSpecialTesting(VB& curvb, FRAGMENTSHADER* pfragment, u32 dwUsingSpecialTesting, int exactcolor)  inline void AlphaSpecialTesting(VB& curvb, FRAGMENTSHADER* pfragment, u32 dwUsingSpecialTesting, int exactcolor)
1404  {  {
1405          if (dwUsingSpecialTesting)          if (dwUsingSpecialTesting)
1406          {          {
1407                  SetShaderCaller("AlphaSpecialTesting");                  SetShaderCaller("AlphaSpecialTesting");
1408    
1409                  // render the real alpha                  // render the real alpha
1410                  glDisable(GL_ALPHA_TEST);                  glDisable(GL_ALPHA_TEST);
1411                  glColorMask(0, 0, 0, 1);                  glColorMask(0, 0, 0, 1);
1412    
1413                  if (s_bWriteDepth)                  if (s_bWriteDepth)
1414                  {                  {
1415                          ResetRenderTarget(1);                          ResetRenderTarget(1);
1416                  }                  }
1417    
1418                  glDepthMask(0);                  glDepthMask(0);
1419    
1420                  glStencilFunc(GL_EQUAL, STENCIL_SPECIAL | STENCIL_PIXELWRITE, STENCIL_SPECIAL | STENCIL_PIXELWRITE);                  glStencilFunc(GL_EQUAL, STENCIL_SPECIAL | STENCIL_PIXELWRITE, STENCIL_SPECIAL | STENCIL_PIXELWRITE);
1421                  glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);                  glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
1422    
1423                  Vector v = Vector(0, exactcolor ? 510.0f : 2.0f, 0, 0);                  Vector v = Vector(0, exactcolor ? 510.0f : 2.0f, 0, 0);
1424                  ZZcgSetParameter4fv(pfragment->sOneColor, v, "g_fOneColor");                  ZZcgSetParameter4fv(pfragment->sOneColor, v, "g_fOneColor");
1425                  Draw(curvb);                  Draw(curvb);
1426    
1427                  // don't need to restore                  // don't need to restore
1428          }          }
1429    
1430          GL_REPORT_ERRORD();          GL_REPORT_ERRORD();
1431  }  }
1432    
1433  inline void AlphaDestinationTest(VB& curvb, FRAGMENTSHADER* pfragment, bool s_bDestAlphaTest, bool bCanRenderStencil)  inline void AlphaDestinationTest(VB& curvb, FRAGMENTSHADER* pfragment, bool s_bDestAlphaTest, bool bCanRenderStencil)
1434  {  {
1435          if (s_bDestAlphaTest)          if (s_bDestAlphaTest)
1436          {          {
1437                  if ((s_dwColorWrite & COLORMASK_ALPHA))                  if ((s_dwColorWrite & COLORMASK_ALPHA))
1438                  {                  {
1439                          if (curvb.fba.fba)                          if (curvb.fba.fba)
1440                                  ProcessFBA(curvb, pfragment->sOneColor);                                  ProcessFBA(curvb, pfragment->sOneColor);
1441                          else if (bCanRenderStencil)                          else if (bCanRenderStencil)
1442                                  // finally make sure all entries are 1 when the dest alpha >= 0x80 (if fba is 1, this is already the case)                                  // finally make sure all entries are 1 when the dest alpha >= 0x80 (if fba is 1, this is already the case)
1443                                  ProcessStencil(curvb);                                  ProcessStencil(curvb);
1444                  }                  }
1445          }          }
1446          else if ((s_dwColorWrite & COLORMASK_ALPHA) && curvb.fba.fba)          else if ((s_dwColorWrite & COLORMASK_ALPHA) && curvb.fba.fba)
1447                  ProcessFBA(curvb, pfragment->sOneColor);                  ProcessFBA(curvb, pfragment->sOneColor);
1448    
1449          if (bDestAlphaColor == 1)          if (bDestAlphaColor == 1)
1450          {          {
1451                  // need to reset the dest colors to their original counter parts                  // need to reset the dest colors to their original counter parts
1452                  //WARN_LOG("Need to reset dest alpha color\n");                  //WARN_LOG("Need to reset dest alpha color\n");
1453          }          }
1454  }  }
1455    
1456  inline void AlphaSaveTarget(VB& curvb)  inline void AlphaSaveTarget(VB& curvb)
1457  {  {
1458  #ifdef _DEBUG  #ifdef _DEBUG
1459          return; // Do nothing          return; // Do nothing
1460    
1461  //      if( g_bSaveFlushedFrame & 0xf ) {  //      if( g_bSaveFlushedFrame & 0xf ) {
1462  //#ifdef _WIN32  //#ifdef _WIN32
1463  //              CreateDirectory("frames", NULL);  //              CreateDirectory("frames", NULL);
1464  //#else  //#else
1465  //              char* strdir="";  //              char* strdir="";
1466  //              sprintf(strdir, "mkdir %s", "frames");  //              sprintf(strdir, "mkdir %s", "frames");
1467  //              system(strdir);  //              system(strdir);
1468  //#endif  //#endif
1469  //              char str[255];  //              char str[255];
1470  //              sprintf(str, "frames/frame%.4d.tga", g_SaveFrameNum++);  //              sprintf(str, "frames/frame%.4d.tga", g_SaveFrameNum++);
1471  //              if( (g_bSaveFlushedFrame & 2) ) {  //              if( (g_bSaveFlushedFrame & 2) ) {
1472  //                      //glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); // switch to the backbuffer  //                      //glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); // switch to the backbuffer
1473  //                      //glFlush();  //                      //glFlush();
1474  //                      //SaveTexture("tex.jpg", GL_TEXTURE_RECTANGLE_NV, curvb.prndr->ptex, RW(curvb.prndr->fbw), RH(curvb.prndr->fbh));  //                      //SaveTexture("tex.jpg", GL_TEXTURE_RECTANGLE_NV, curvb.prndr->ptex, RW(curvb.prndr->fbw), RH(curvb.prndr->fbh));
1475  //                      SaveRenderTarget(str, RW(curvb.prndr->fbw), RH(curvb.prndr->fbh), 0);  //                      SaveRenderTarget(str, RW(curvb.prndr->fbw), RH(curvb.prndr->fbh), 0);
1476  //              }  //              }
1477  //      }  //      }
1478  #endif  #endif
1479  }  }
1480    
1481  inline void AlphaColorClamping(VB& curvb, const pixTest curtest)  inline void AlphaColorClamping(VB& curvb, const pixTest curtest)
1482  {  {
1483          // clamp the final colors, when enabled ffx2 credits mess up          // clamp the final colors, when enabled ffx2 credits mess up
1484          //if (gs.colclamp) ZZLog::Error_Log("ColClamp!");          //if (gs.colclamp) ZZLog::Error_Log("ColClamp!");
1485          if ((curvb.curprim.abe && bAlphaClamping) && (GetRenderFormat() != RFT_byte8) && !(conf.settings().no_color_clamp))   // if !colclamp, skip          if ((curvb.curprim.abe && bAlphaClamping) && (GetRenderFormat() != RFT_byte8) && !(conf.settings().no_color_clamp))   // if !colclamp, skip
1486          {          {
1487                  //ZZLog::Error_Log("Clamped.");                  //ZZLog::Error_Log("Clamped.");
1488                  ResetAlphaVariables();                  ResetAlphaVariables();
1489    
1490                  // if processing the clamping case, make sure can write to the front buffer                  // if processing the clamping case, make sure can write to the front buffer
1491                  glDisable(GL_STENCIL_TEST);                  glDisable(GL_STENCIL_TEST);
1492                  glEnable(GL_BLEND);                  glEnable(GL_BLEND);
1493                  glDisable(GL_ALPHA_TEST);                  glDisable(GL_ALPHA_TEST);
1494                  glDisable(GL_DEPTH_TEST);                  glDisable(GL_DEPTH_TEST);
1495                  glDepthMask(0);                  glDepthMask(0);
1496                  glColorMask(1, 1, 1, 0);                  glColorMask(1, 1, 1, 0);
1497    
1498                  if (s_bWriteDepth) ResetRenderTarget(1);                  if (s_bWriteDepth) ResetRenderTarget(1);
1499    
1500                  SetShaderCaller("AlphaColorClamping");                  SetShaderCaller("AlphaColorClamping");
1501    
1502                  SETPIXELSHADER(ppsOne.prog);                  SETPIXELSHADER(ppsOne.prog);
1503                  GL_BLEND_RGB(GL_ONE, GL_ONE);                  GL_BLEND_RGB(GL_ONE, GL_ONE);
1504    
1505                  float f;                  float f;
1506    
1507                  if (bAlphaClamping & 1)    // min                  if (bAlphaClamping & 1)    // min
1508                  {                  {
1509                          f = 0;                          f = 0;
1510                          ZZcgSetParameter4fv(ppsOne.sOneColor, &f, "g_fOneColor");                          ZZcgSetParameter4fv(ppsOne.sOneColor, &f, "g_fOneColor");
1511                          GL_BLENDEQ_RGB(GL_MAX_EXT);                          GL_BLENDEQ_RGB(GL_MAX_EXT);
1512                          Draw(curvb);                          Draw(curvb);
1513                  }                  }
1514    
1515                  // bios shows white screen                  // bios shows white screen
1516                  if (bAlphaClamping & 2)    // max                  if (bAlphaClamping & 2)    // max
1517                  {                  {
1518                          f = 1;                          f = 1;
1519                          ZZcgSetParameter4fv(ppsOne.sOneColor, &f, "g_fOneColor");                          ZZcgSetParameter4fv(ppsOne.sOneColor, &f, "g_fOneColor");
1520                          GL_BLENDEQ_RGB(GL_MIN_EXT);                          GL_BLENDEQ_RGB(GL_MIN_EXT);
1521                          Draw(curvb);                          Draw(curvb);
1522                  }                  }
1523    
1524                  if (!curvb.zbuf.zmsk)                  if (!curvb.zbuf.zmsk)
1525                  {                  {
1526                          glDepthMask(1);                          glDepthMask(1);
1527    
1528                          if (s_bWriteDepth)                          if (s_bWriteDepth)
1529                          {                          {
1530                                  assert(curvb.pdepth != NULL);                                  assert(curvb.pdepth != NULL);
1531                                  curvb.pdepth->SetRenderTarget(1);                                  curvb.pdepth->SetRenderTarget(1);
1532                          }                          }
1533                  }                  }
1534    
1535                  if (curvb.test.ate && USEALPHATESTING) glEnable(GL_ALPHA_TEST);                  if (curvb.test.ate && USEALPHATESTING) glEnable(GL_ALPHA_TEST);
1536    
1537                  GL_ZTEST(curtest.zte);                  GL_ZTEST(curtest.zte);
1538          }          }
1539  }  }
1540    
1541  inline void FlushUndoFiter(u32 dwFilterOpts)  inline void FlushUndoFiter(u32 dwFilterOpts)
1542  {  {
1543          if (dwFilterOpts)          if (dwFilterOpts)
1544          {          {
1545                  // undo filter changes (binding didn't change)                  // undo filter changes (binding didn't change)
1546                  if (dwFilterOpts & 1) glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_LINEAR);                  if (dwFilterOpts & 1) glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1547                  if (dwFilterOpts & 2) glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_LINEAR);                  if (dwFilterOpts & 2) glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1548          }          }
1549  }  }
1550    
1551  // This is the most important function! It draws all collected info onscreen.  // This is the most important function! It draws all collected info onscreen.
1552  void ZeroGS::Flush(int context)  void ZeroGS::Flush(int context)
1553  {  {
1554          FUNCLOG          FUNCLOG
1555          VB& curvb = vb[context];          VB& curvb = vb[context];
1556          const pixTest curtest = curvb.test;          const pixTest curtest = curvb.test;
1557    
1558          if (FlushInitialTest(curvb, curtest, context)) return;          if (FlushInitialTest(curvb, curtest, context)) return;
1559    
1560          VisualBufferMessage(context);          VisualBufferMessage(context);
1561    
1562          GL_REPORT_ERRORD();          GL_REPORT_ERRORD();
1563    
1564          CRenderTarget* ptextarg = FlushGetTarget(curvb);          CRenderTarget* ptextarg = FlushGetTarget(curvb);
1565    
1566          SwitchWireframeOff();          SwitchWireframeOff();
1567          FlushDoContextJob(curvb, context);          FlushDoContextJob(curvb, context);
1568    
1569          u32 dwUsingSpecialTesting = 0, dwFilterOpts = 0;          u32 dwUsingSpecialTesting = 0, dwFilterOpts = 0;
1570          int exactcolor = FlushGetExactcolor(curtest);          int exactcolor = FlushGetExactcolor(curtest);
1571    
1572          FRAGMENTSHADER* pfragment = FlushRendererStage(curvb, dwFilterOpts, ptextarg, exactcolor, context);          FRAGMENTSHADER* pfragment = FlushRendererStage(curvb, dwFilterOpts, ptextarg, exactcolor, context);
1573    
1574          bool bCanRenderStencil = AlphaCanRenderStencil(curvb);          bool bCanRenderStencil = AlphaCanRenderStencil(curvb);
1575    
1576          if (curtest.date || gs.pabe) SetDestAlphaTest();          if (curtest.date || gs.pabe) SetDestAlphaTest();
1577    
1578          AlphaSetStencil(s_bDestAlphaTest && bCanRenderStencil);          AlphaSetStencil(s_bDestAlphaTest && bCanRenderStencil);
1579          AlphaSetDepthTest(curvb, curtest, pfragment);                                           // Error!          AlphaSetDepthTest(curvb, curtest, pfragment);                                           // Error!
1580          SetAlphaTest(curtest);          SetAlphaTest(curtest);
1581    
1582          u32 oldabe = AlphaSetupBlendTest(curvb);                                        // Unavoidable          u32 oldabe = AlphaSetupBlendTest(curvb);                                        // Unavoidable
1583    
1584          // needs to be before RenderAlphaTest          // needs to be before RenderAlphaTest
1585          AlphaRenderFBA(curvb, pfragment, s_bDestAlphaTest, bCanRenderStencil);          AlphaRenderFBA(curvb, pfragment, s_bDestAlphaTest, bCanRenderStencil);
1586    
1587          dwUsingSpecialTesting = AlphaRenderAlpha(curvb, curtest, pfragment, exactcolor);                        // Unavoidable          dwUsingSpecialTesting = AlphaRenderAlpha(curvb, curtest, pfragment, exactcolor);                        // Unavoidable
1588          AlphaRenderStencil(curvb, s_bDestAlphaTest, bCanRenderStencil, dwUsingSpecialTesting);          AlphaRenderStencil(curvb, s_bDestAlphaTest, bCanRenderStencil, dwUsingSpecialTesting);
1589          AlphaTest(curvb);                                                               // Unavoidable          AlphaTest(curvb);                                                               // Unavoidable
1590          AlphaPabe(curvb, pfragment, exactcolor);          AlphaPabe(curvb, pfragment, exactcolor);
1591          AlphaFailureTestJob(curvb, curtest, pfragment, exactcolor, bCanRenderStencil, oldabe);          AlphaFailureTestJob(curvb, curtest, pfragment, exactcolor, bCanRenderStencil, oldabe);
1592          AlphaSpecialTesting(curvb, pfragment, dwUsingSpecialTesting, exactcolor);          AlphaSpecialTesting(curvb, pfragment, dwUsingSpecialTesting, exactcolor);
1593          AlphaDestinationTest(curvb, pfragment, s_bDestAlphaTest, bCanRenderStencil);          AlphaDestinationTest(curvb, pfragment, s_bDestAlphaTest, bCanRenderStencil);
1594          AlphaSaveTarget(curvb);          AlphaSaveTarget(curvb);
1595                    
1596          GL_REPORT_ERRORD();          GL_REPORT_ERRORD();
1597    
1598          AlphaColorClamping(curvb, curtest);          AlphaColorClamping(curvb, curtest);
1599          FlushUndoFiter(dwFilterOpts);          FlushUndoFiter(dwFilterOpts);
1600    
1601          ppf += curvb.nCount + 0x100000;          ppf += curvb.nCount + 0x100000;
1602    
1603          curvb.nCount = 0;          curvb.nCount = 0;
1604          curvb.curprim.abe = oldabe;          curvb.curprim.abe = oldabe;
1605    
1606          SwitchWireframeOn();          SwitchWireframeOn();
1607    
1608          GL_REPORT_ERRORD();          GL_REPORT_ERRORD();
1609  }  }
1610    
1611  void ZeroGS::FlushBoth()  void ZeroGS::FlushBoth()
1612  {  {
1613          Flush(0);          Flush(0);
1614          Flush(1);          Flush(1);
1615  }  }
1616    
1617  inline void ZeroGS::RenderFBA(const VB& curvb, CGparameter sOneColor)  inline void ZeroGS::RenderFBA(const VB& curvb, CGparameter sOneColor)
1618  {  {
1619          // add fba to all pixels          // add fba to all pixels
1620          GL_STENCILFUNC(GL_ALWAYS, STENCIL_FBA, 0xff);          GL_STENCILFUNC(GL_ALWAYS, STENCIL_FBA, 0xff);
1621          glStencilMask(STENCIL_CLEAR);          glStencilMask(STENCIL_CLEAR);
1622          glStencilOp(GL_ZERO, GL_KEEP, GL_REPLACE);          glStencilOp(GL_ZERO, GL_KEEP, GL_REPLACE);
1623    
1624          glDisable(GL_DEPTH_TEST);          glDisable(GL_DEPTH_TEST);
1625          glDepthMask(0);          glDepthMask(0);
1626          glColorMask(0, 0, 0, 0);          glColorMask(0, 0, 0, 0);
1627    
1628          if (s_bWriteDepth) ResetRenderTarget(1);          if (s_bWriteDepth) ResetRenderTarget(1);
1629    
1630          SetShaderCaller("RenderFBA");          SetShaderCaller("RenderFBA");
1631    
1632          glEnable(GL_ALPHA_TEST);          glEnable(GL_ALPHA_TEST);
1633    
1634          glAlphaFunc(GL_GEQUAL, 1);          glAlphaFunc(GL_GEQUAL, 1);
1635    
1636          Vector v(1,2,0,0);          Vector v(1,2,0,0);
1637    
1638          ZZcgSetParameter4fv(sOneColor, v, "g_fOneColor");          ZZcgSetParameter4fv(sOneColor, v, "g_fOneColor");
1639    
1640          Draw(curvb);          Draw(curvb);
1641    
1642          SetAlphaTest(curvb.test);          SetAlphaTest(curvb.test);
1643    
1644          // reset (not necessary)          // reset (not necessary)
1645          GL_COLORMASK(s_dwColorWrite);          GL_COLORMASK(s_dwColorWrite);
1646    
1647          glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);          glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
1648    
1649          if (!curvb.zbuf.zmsk)          if (!curvb.zbuf.zmsk)
1650          {          {
1651                  glDepthMask(1);                  glDepthMask(1);
1652    
1653                  assert(curvb.pdepth != NULL);                  assert(curvb.pdepth != NULL);
1654    
1655                  if (s_bWriteDepth) curvb.pdepth->SetRenderTarget(1);                  if (s_bWriteDepth) curvb.pdepth->SetRenderTarget(1);
1656          }          }
1657    
1658          GL_ZTEST(curvb.test.zte);          GL_ZTEST(curvb.test.zte);
1659  }  }
1660    
1661  __forceinline void ZeroGS::RenderAlphaTest(const VB& curvb, CGparameter sOneColor)  __forceinline void ZeroGS::RenderAlphaTest(const VB& curvb, CGparameter sOneColor)
1662  {  {
1663          if (!g_bUpdateStencil) return;          if (!g_bUpdateStencil) return;
1664    
1665          if ((curvb.test.ate) && (curvb.test.afail == 1)) glDisable(GL_ALPHA_TEST);          if ((curvb.test.ate) && (curvb.test.afail == 1)) glDisable(GL_ALPHA_TEST);
1666    
1667          glDepthMask(0);          glDepthMask(0);
1668    
1669          glColorMask(0, 0, 0, 0);          glColorMask(0, 0, 0, 0);
1670    
1671          if (s_bWriteDepth) ResetRenderTarget(1);          if (s_bWriteDepth) ResetRenderTarget(1);
1672    
1673          SetShaderCaller("RenderAlphaTest");          SetShaderCaller("RenderAlphaTest");
1674    
1675          Vector v(1,2,0,0);          Vector v(1,2,0,0);
1676    
1677          ZZcgSetParameter4fv(sOneColor, v, "g_fOneColor");          ZZcgSetParameter4fv(sOneColor, v, "g_fOneColor");
1678    
1679          // or a 1 to the stencil buffer wherever alpha passes          // or a 1 to the stencil buffer wherever alpha passes
1680          glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);          glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
1681    
1682          s_stencilfunc = GL_ALWAYS;          s_stencilfunc = GL_ALWAYS;
1683    
1684          glEnable(GL_STENCIL_TEST);          glEnable(GL_STENCIL_TEST);
1685    
1686          if (!s_bDestAlphaTest)          if (!s_bDestAlphaTest)
1687          {          {
1688                  // clear everything                  // clear everything
1689                  s_stencilref = 0;                  s_stencilref = 0;
1690                  glStencilMask(STENCIL_CLEAR);                  glStencilMask(STENCIL_CLEAR);
1691                  glDisable(GL_ALPHA_TEST);                  glDisable(GL_ALPHA_TEST);
1692                  GL_STENCILFUNC_SET();                  GL_STENCILFUNC_SET();
1693                  Draw(curvb);                  Draw(curvb);
1694    
1695                  if (curvb.test.ate && curvb.test.afail != 1 && USEALPHATESTING) glEnable(GL_ALPHA_TEST);                  if (curvb.test.ate && curvb.test.afail != 1 && USEALPHATESTING) glEnable(GL_ALPHA_TEST);
1696          }          }
1697    
1698          if (curvb.test.ate && curvb.test.atst > 1 && curvb.test.aref > 0x80)          if (curvb.test.ate && curvb.test.atst > 1 && curvb.test.aref > 0x80)
1699          {          {
1700                  v = Vector(1,1,0,0);                  v = Vector(1,1,0,0);
1701                  ZZcgSetParameter4fv(sOneColor, v, "g_fOneColor");                  ZZcgSetParameter4fv(sOneColor, v, "g_fOneColor");
1702                  glAlphaFunc(g_dwAlphaCmp[curvb.test.atst], AlphaReferedValue(curvb.test.aref));                  glAlphaFunc(g_dwAlphaCmp[curvb.test.atst], AlphaReferedValue(curvb.test.aref));
1703          }          }
1704    
1705          s_stencilref = STENCIL_SPECIAL;          s_stencilref = STENCIL_SPECIAL;
1706    
1707          glStencilMask(STENCIL_SPECIAL);          glStencilMask(STENCIL_SPECIAL);
1708          GL_STENCILFUNC_SET();          GL_STENCILFUNC_SET();
1709          glDisable(GL_DEPTH_TEST);          glDisable(GL_DEPTH_TEST);
1710    
1711          Draw(curvb);          Draw(curvb);
1712    
1713          if (curvb.test.zte) glEnable(GL_DEPTH_TEST);          if (curvb.test.zte) glEnable(GL_DEPTH_TEST);
1714    
1715          GL_ALPHATEST(0);          GL_ALPHATEST(0);
1716    
1717          GL_COLORMASK(s_dwColorWrite);          GL_COLORMASK(s_dwColorWrite);
1718    
1719          if (!curvb.zbuf.zmsk)          if (!curvb.zbuf.zmsk)
1720          {          {
1721                  glDepthMask(1);                  glDepthMask(1);
1722    
1723                  // set rt next level                  // set rt next level
1724    
1725                  if (s_bWriteDepth) curvb.pdepth->SetRenderTarget(1);                  if (s_bWriteDepth) curvb.pdepth->SetRenderTarget(1);
1726          }          }
1727  }  }
1728    
1729  inline void ZeroGS::RenderStencil(const VB& curvb, u32 dwUsingSpecialTesting)  inline void ZeroGS::RenderStencil(const VB& curvb, u32 dwUsingSpecialTesting)
1730  {  {
1731          //NOTE: This stencil hack for dest alpha testing ONLY works when          //NOTE: This stencil hack for dest alpha testing ONLY works when
1732          // the geometry in one DrawPrimitive call does not overlap          // the geometry in one DrawPrimitive call does not overlap
1733    
1734          // mark the stencil buffer for the new data's bits (mark 4 if alpha is >= 0xff)          // mark the stencil buffer for the new data's bits (mark 4 if alpha is >= 0xff)
1735          // mark 4 if a pixel was written (so that the stencil buf can be changed with new values)          // mark 4 if a pixel was written (so that the stencil buf can be changed with new values)
1736          glStencilMask(STENCIL_PIXELWRITE);          glStencilMask(STENCIL_PIXELWRITE);
1737          glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);          glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
1738    
1739          s_stencilmask = (curvb.test.date ? STENCIL_ALPHABIT : 0) | (dwUsingSpecialTesting ? STENCIL_SPECIAL : 0);          s_stencilmask = (curvb.test.date ? STENCIL_ALPHABIT : 0) | (dwUsingSpecialTesting ? STENCIL_SPECIAL : 0);
1740          s_stencilfunc = s_stencilmask ? GL_EQUAL : GL_ALWAYS;          s_stencilfunc = s_stencilmask ? GL_EQUAL : GL_ALWAYS;
1741    
1742          s_stencilref = curvb.test.date * curvb.test.datm | STENCIL_PIXELWRITE | (dwUsingSpecialTesting ? STENCIL_SPECIAL : 0);          s_stencilref = curvb.test.date * curvb.test.datm | STENCIL_PIXELWRITE | (dwUsingSpecialTesting ? STENCIL_SPECIAL : 0);
1743          GL_STENCILFUNC_SET();          GL_STENCILFUNC_SET();
1744  }  }
1745    
1746  inline void ZeroGS::ProcessStencil(const VB& curvb)  inline void ZeroGS::ProcessStencil(const VB& curvb)
1747  {  {
1748          assert(!curvb.fba.fba);          assert(!curvb.fba.fba);
1749    
1750          // set new alpha bit          // set new alpha bit
1751          glStencilMask(STENCIL_ALPHABIT);          glStencilMask(STENCIL_ALPHABIT);
1752          GL_STENCILFUNC(GL_EQUAL, STENCIL_PIXELWRITE, STENCIL_PIXELWRITE | STENCIL_FBA);          GL_STENCILFUNC(GL_EQUAL, STENCIL_PIXELWRITE, STENCIL_PIXELWRITE | STENCIL_FBA);
1753          glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);          glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
1754    
1755          glDisable(GL_DEPTH_TEST);          glDisable(GL_DEPTH_TEST);
1756          glDepthMask(0);          glDepthMask(0);
1757          glColorMask(0, 0, 0, 0);          glColorMask(0, 0, 0, 0);
1758    
1759          if (s_bWriteDepth) ResetRenderTarget(1);          if (s_bWriteDepth) ResetRenderTarget(1);
1760    
1761          GL_ALPHATEST(0);          GL_ALPHATEST(0);
1762    
1763          SetShaderCaller("ProcessStencil");          SetShaderCaller("ProcessStencil");
1764    
1765          SETPIXELSHADER(ppsOne.prog);          SETPIXELSHADER(ppsOne.prog);
1766          Draw(curvb);          Draw(curvb);
1767    
1768          // process when alpha >= 0xff          // process when alpha >= 0xff
1769          GL_STENCILFUNC(GL_EQUAL, STENCIL_PIXELWRITE | STENCIL_FBA | STENCIL_ALPHABIT, STENCIL_PIXELWRITE | STENCIL_FBA);          GL_STENCILFUNC(GL_EQUAL, STENCIL_PIXELWRITE | STENCIL_FBA | STENCIL_ALPHABIT, STENCIL_PIXELWRITE | STENCIL_FBA);
1770          Draw(curvb);          Draw(curvb);
1771    
1772          // clear STENCIL_PIXELWRITE bit          // clear STENCIL_PIXELWRITE bit
1773          glStencilMask(STENCIL_CLEAR);          glStencilMask(STENCIL_CLEAR);
1774    
1775          GL_STENCILFUNC(GL_ALWAYS, 0, STENCIL_PIXELWRITE | STENCIL_FBA);          GL_STENCILFUNC(GL_ALWAYS, 0, STENCIL_PIXELWRITE | STENCIL_FBA);
1776          Draw(curvb);          Draw(curvb);
1777    
1778          // restore state          // restore state
1779          GL_COLORMASK(s_dwColorWrite);          GL_COLORMASK(s_dwColorWrite);
1780    
1781          if (curvb.test.ate && USEALPHATESTING) glEnable(GL_ALPHA_TEST);          if (curvb.test.ate && USEALPHATESTING) glEnable(GL_ALPHA_TEST);
1782    
1783          if (!curvb.zbuf.zmsk)          if (!curvb.zbuf.zmsk)
1784          {          {
1785                  glDepthMask(1);                  glDepthMask(1);
1786    
1787                  if (s_bWriteDepth)                  if (s_bWriteDepth)
1788                  {                  {
1789                          assert(curvb.pdepth != NULL);                          assert(curvb.pdepth != NULL);
1790                          curvb.pdepth->SetRenderTarget(1);                          curvb.pdepth->SetRenderTarget(1);
1791                  }                  }
1792          }          }
1793    
1794          GL_ZTEST(curvb.test.zte);          GL_ZTEST(curvb.test.zte);
1795    
1796          glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);          glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
1797  }  }
1798    
1799  __forceinline void ZeroGS::ProcessFBA(const VB& curvb, CGparameter sOneColor)  __forceinline void ZeroGS::ProcessFBA(const VB& curvb, CGparameter sOneColor)
1800  {  {
1801          if ((curvb.frame.fbm&0x80000000)) return;          if ((curvb.frame.fbm&0x80000000)) return;
1802    
1803          // add fba to all pixels that were written and alpha was less than 0xff          // add fba to all pixels that were written and alpha was less than 0xff
1804          glStencilMask(STENCIL_ALPHABIT);          glStencilMask(STENCIL_ALPHABIT);
1805          glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);          glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
1806          GL_STENCILFUNC(GL_EQUAL, STENCIL_FBA | STENCIL_PIXELWRITE | STENCIL_ALPHABIT, STENCIL_PIXELWRITE | STENCIL_FBA);          GL_STENCILFUNC(GL_EQUAL, STENCIL_FBA | STENCIL_PIXELWRITE | STENCIL_ALPHABIT, STENCIL_PIXELWRITE | STENCIL_FBA);
1807          glDisable(GL_DEPTH_TEST);          glDisable(GL_DEPTH_TEST);
1808    
1809          glDepthMask(0);          glDepthMask(0);
1810          glColorMask(0, 0, 0, 1);          glColorMask(0, 0, 0, 1);
1811    
1812          if (s_bWriteDepth) ResetRenderTarget(1);          if (s_bWriteDepth) ResetRenderTarget(1);
1813    
1814          SetShaderCaller("ProcessFBA");          SetShaderCaller("ProcessFBA");
1815    
1816          // processes the pixels with ALPHA < 0x80*2          // processes the pixels with ALPHA < 0x80*2
1817          glEnable(GL_ALPHA_TEST);          glEnable(GL_ALPHA_TEST);
1818          glAlphaFunc(GL_LEQUAL, 1);          glAlphaFunc(GL_LEQUAL, 1);
1819    
1820          // add 1 to dest          // add 1 to dest
1821          GL_BLEND_ALPHA(GL_ONE, GL_ONE);          GL_BLEND_ALPHA(GL_ONE, GL_ONE);
1822          GL_BLENDEQ_ALPHA(GL_FUNC_ADD);          GL_BLENDEQ_ALPHA(GL_FUNC_ADD);
1823    
1824          float f = 1;          float f = 1;
1825          ZZcgSetParameter4fv(sOneColor, &f, "g_fOneColor");          ZZcgSetParameter4fv(sOneColor, &f, "g_fOneColor");
1826          SETPIXELSHADER(ppsOne.prog);          SETPIXELSHADER(ppsOne.prog);
1827          Draw(curvb);          Draw(curvb);
1828          glDisable(GL_ALPHA_TEST);          glDisable(GL_ALPHA_TEST);
1829    
1830          // reset bits          // reset bits
1831          glStencilMask(STENCIL_CLEAR);          glStencilMask(STENCIL_CLEAR);
1832          GL_STENCILFUNC(GL_GREATER, 0, STENCIL_PIXELWRITE | STENCIL_FBA);          GL_STENCILFUNC(GL_GREATER, 0, STENCIL_PIXELWRITE | STENCIL_FBA);
1833          glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO);          glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO);
1834          Draw(curvb);          Draw(curvb);
1835    
1836          if (curvb.test.atst && USEALPHATESTING)          if (curvb.test.atst && USEALPHATESTING)
1837          {          {
1838                  glEnable(GL_ALPHA_TEST);                  glEnable(GL_ALPHA_TEST);
1839                  glAlphaFunc(g_dwAlphaCmp[curvb.test.atst], AlphaReferedValue(curvb.test.aref));                  glAlphaFunc(g_dwAlphaCmp[curvb.test.atst], AlphaReferedValue(curvb.test.aref));
1840          }          }
1841    
1842          // restore (SetAlphaVariables)          // restore (SetAlphaVariables)
1843          GL_BLEND_ALPHA(GL_ONE, GL_ZERO);          GL_BLEND_ALPHA(GL_ONE, GL_ZERO);
1844    
1845          if (vAlphaBlendColor.y < 0) GL_BLENDEQ_ALPHA(GL_FUNC_REVERSE_SUBTRACT);          if (vAlphaBlendColor.y < 0) GL_BLENDEQ_ALPHA(GL_FUNC_REVERSE_SUBTRACT);
1846    
1847          // reset (not necessary)          // reset (not necessary)
1848          GL_COLORMASK(s_dwColorWrite);          GL_COLORMASK(s_dwColorWrite);
1849    
1850          if (!curvb.zbuf.zmsk)          if (!curvb.zbuf.zmsk)
1851          {          {
1852                  glDepthMask(1);                  glDepthMask(1);
1853    
1854                  if (s_bWriteDepth) curvb.pdepth->SetRenderTarget(1);                  if (s_bWriteDepth) curvb.pdepth->SetRenderTarget(1);
1855          }          }
1856    
1857          GL_ZTEST(curvb.test.zte);          GL_ZTEST(curvb.test.zte);
1858  }  }
1859    
1860  void ZeroGS::SetContextTarget(int context)  void ZeroGS::SetContextTarget(int context)
1861  {  {
1862          FUNCLOG          FUNCLOG
1863          VB& curvb = vb[context];          VB& curvb = vb[context];
1864          GL_REPORT_ERRORD();          GL_REPORT_ERRORD();
1865    
1866          if (curvb.prndr == NULL)          if (curvb.prndr == NULL)
1867                  curvb.prndr = s_RTs.GetTarg(curvb.frame, 0, get_maxheight(curvb.gsfb.fbp, curvb.gsfb.fbw, curvb.gsfb.psm));                  curvb.prndr = s_RTs.GetTarg(curvb.frame, 0, get_maxheight(curvb.gsfb.fbp, curvb.gsfb.fbw, curvb.gsfb.psm));
1868    
1869          // make sure targets are valid          // make sure targets are valid
1870          if (curvb.pdepth == NULL)          if (curvb.pdepth == NULL)
1871          {          {
1872                  frameInfo f;                  frameInfo f;
1873                  f.fbp = curvb.zbuf.zbp;                  f.fbp = curvb.zbuf.zbp;
1874                  f.fbw = curvb.frame.fbw;                  f.fbw = curvb.frame.fbw;
1875                  f.fbh = curvb.prndr->fbh;                  f.fbh = curvb.prndr->fbh;
1876                  f.psm = curvb.zbuf.psm;                  f.psm = curvb.zbuf.psm;
1877                  f.fbm = 0;                  f.fbm = 0;
1878                  curvb.pdepth = (CDepthTarget*)s_DepthRTs.GetTarg(f, CRenderTargetMngr::TO_DepthBuffer | CRenderTargetMngr::TO_StrictHeight |                  curvb.pdepth = (CDepthTarget*)s_DepthRTs.GetTarg(f, CRenderTargetMngr::TO_DepthBuffer | CRenderTargetMngr::TO_StrictHeight |
1879                                             (curvb.zbuf.zmsk ? CRenderTargetMngr::TO_Virtual : 0), get_maxheight(curvb.zbuf.zbp, curvb.gsfb.fbw, 0));                                             (curvb.zbuf.zmsk ? CRenderTargetMngr::TO_Virtual : 0), get_maxheight(curvb.zbuf.zbp, curvb.gsfb.fbw, 0));
1880          }          }
1881    
1882          assert(curvb.prndr != NULL && curvb.pdepth != NULL);          assert(curvb.prndr != NULL && curvb.pdepth != NULL);
1883    
1884          if (curvb.pdepth->fbh != curvb.prndr->fbh) ZZLog::Debug_Log("(curvb.pdepth->fbh(0x%x) != curvb.prndr->fbh(0x%x))", curvb.pdepth->fbh, curvb.prndr->fbh);          if (curvb.pdepth->fbh != curvb.prndr->fbh) ZZLog::Debug_Log("(curvb.pdepth->fbh(0x%x) != curvb.prndr->fbh(0x%x))", curvb.pdepth->fbh, curvb.prndr->fbh);
1885          //assert(curvb.pdepth->fbh == curvb.prndr->fbh);          //assert(curvb.pdepth->fbh == curvb.prndr->fbh);
1886    
1887          if (curvb.pdepth->status & CRenderTarget::TS_Virtual)          if (curvb.pdepth->status & CRenderTarget::TS_Virtual)
1888          {          {
1889    
1890                  if (!curvb.zbuf.zmsk)                  if (!curvb.zbuf.zmsk)
1891                  {                  {
1892                          CRenderTarget* ptemp = s_DepthRTs.Promote(curvb.pdepth->fbp | (curvb.pdepth->fbw << 16));                          CRenderTarget* ptemp = s_DepthRTs.Promote(curvb.pdepth->fbp | (curvb.pdepth->fbw << 16));
1893                          assert(ptemp == curvb.pdepth);                          assert(ptemp == curvb.pdepth);
1894                  }                  }
1895                  else                  else
1896                  {                  {
1897                          curvb.pdepth->status &= ~CRenderTarget::TS_NeedUpdate;                          curvb.pdepth->status &= ~CRenderTarget::TS_NeedUpdate;
1898                  }                  }
1899          }          }
1900    
1901          bool bSetTarg = 1;          bool bSetTarg = 1;
1902    
1903          if (curvb.pdepth->status & CRenderTarget::TS_NeedUpdate)          if (curvb.pdepth->status & CRenderTarget::TS_NeedUpdate)
1904          {          {
1905                  assert(!(curvb.pdepth->status & CRenderTarget::TS_Virtual));                  assert(!(curvb.pdepth->status & CRenderTarget::TS_Virtual));
1906    
1907                  // don't update if virtual                  // don't update if virtual
1908                  curvb.pdepth->Update(context, curvb.prndr);                  curvb.pdepth->Update(context, curvb.prndr);
1909                  bSetTarg = 0;                  bSetTarg = 0;
1910          }          }
1911    
1912          GL_REPORT_ERRORD();          GL_REPORT_ERRORD();
1913    
1914          if (curvb.prndr->status & CRenderTarget::TS_NeedUpdate)          if (curvb.prndr->status & CRenderTarget::TS_NeedUpdate)
1915          {          {
1916                  /*              if(bSetTarg) {                  /*              if(bSetTarg) {
1917                  *                       printf ( " Here\n ");                  *                       printf ( " Here\n ");
1918                  *                       if(s_bWriteDepth) {                  *                       if(s_bWriteDepth) {
1919                  *                               curvb.pdepth->SetRenderTarget(1);                  *                               curvb.pdepth->SetRenderTarget(1);
1920                  *                               curvb.pdepth->SetDepthStencilSurface();                  *                               curvb.pdepth->SetDepthStencilSurface();
1921                  *                       }                  *                       }
1922                  *                       else                  *                       else
1923                  *                               curvb.pdepth->SetDepthStencilSurface();                  *                               curvb.pdepth->SetDepthStencilSurface();
1924                  *               }*/                  *               }*/
1925                  curvb.prndr->Update(context, curvb.pdepth);                  curvb.prndr->Update(context, curvb.pdepth);
1926          }          }
1927          else          else
1928          {          {
1929    
1930                  //if( (vb[0].prndr != vb[1].prndr && vb[!context].bVarsSetTarg) || !vb[context].bVarsSetTarg )                  //if( (vb[0].prndr != vb[1].prndr && vb[!context].bVarsSetTarg) || !vb[context].bVarsSetTarg )
1931                  curvb.prndr->SetRenderTarget(0);                  curvb.prndr->SetRenderTarget(0);
1932                  //if( bSetTarg && ((vb[0].pdepth != vb[1].pdepth && vb[!context].bVarsSetTarg) || !vb[context].bVarsSetTarg) )                  //if( bSetTarg && ((vb[0].pdepth != vb[1].pdepth && vb[!context].bVarsSetTarg) || !vb[context].bVarsSetTarg) )
1933                  curvb.pdepth->SetDepthStencilSurface();                  curvb.pdepth->SetDepthStencilSurface();
1934    
1935                  if (conf.mrtdepth && ZeroGS::IsWriteDepth()) curvb.pdepth->SetRenderTarget(1);                  if (conf.mrtdepth && ZeroGS::IsWriteDepth()) curvb.pdepth->SetRenderTarget(1);
1936                  if (s_ptexCurSet[0] == curvb.prndr->ptex) s_ptexCurSet[0] = 0;                  if (s_ptexCurSet[0] == curvb.prndr->ptex) s_ptexCurSet[0] = 0;
1937                  if (s_ptexCurSet[1] == curvb.prndr->ptex) s_ptexCurSet[1] = 0;                  if (s_ptexCurSet[1] == curvb.prndr->ptex) s_ptexCurSet[1] = 0;
1938    
1939                  curvb.prndr->SetViewport();                  curvb.prndr->SetViewport();
1940          }          }
1941    
1942          curvb.prndr->SetTarget(curvb.frame.fbp, curvb.scissor, context);          curvb.prndr->SetTarget(curvb.frame.fbp, curvb.scissor, context);
1943    
1944          if ((curvb.zbuf.zbp - curvb.pdepth->fbp) != (curvb.frame.fbp - curvb.prndr->fbp) && curvb.test.zte)          if ((curvb.zbuf.zbp - curvb.pdepth->fbp) != (curvb.frame.fbp - curvb.prndr->fbp) && curvb.test.zte)
1945                  ZZLog::Warn_Log("Frame and zbuf not aligned.");                  ZZLog::Warn_Log("Frame and zbuf not aligned.");
1946    
1947          curvb.bVarsSetTarg = true;          curvb.bVarsSetTarg = true;
1948    
1949          if (vb[!context].prndr != curvb.prndr) vb[!context].bVarsSetTarg = false;          if (vb[!context].prndr != curvb.prndr) vb[!context].bVarsSetTarg = false;
1950    
1951  #ifdef _DEBUG  #ifdef _DEBUG
1952          // These conditions happen often enough that we'll just warn about it rather then abort in Debug mode.          // These conditions happen often enough that we'll just warn about it rather then abort in Debug mode.
1953          if (curvb.prndr->status & CRenderTarget::TS_NeedUpdate)          if (curvb.prndr->status & CRenderTarget::TS_NeedUpdate)
1954          {          {
1955                  ZZLog::Debug_Log("In SetContextTarget, prndr is ending with TS_NeedUpdate set.");                  ZZLog::Debug_Log("In SetContextTarget, prndr is ending with TS_NeedUpdate set.");
1956          }          }
1957                    
1958          if (curvb.pdepth != NULL && (curvb.pdepth->status & CRenderTarget::TS_NeedUpdate))          if (curvb.pdepth != NULL && (curvb.pdepth->status & CRenderTarget::TS_NeedUpdate))
1959          {          {
1960                  ZZLog::Debug_Log("In SetContextTarget, pdepth is ending with TS_NeedUpdate set.");                  ZZLog::Debug_Log("In SetContextTarget, pdepth is ending with TS_NeedUpdate set.");
1961          }          }
1962  #endif  #endif
1963    
1964          GL_REPORT_ERRORD();          GL_REPORT_ERRORD();
1965  }  }
1966    
1967    
1968  void ZeroGS::SetTexInt(int context, FRAGMENTSHADER* pfragment, int settexint)  void ZeroGS::SetTexInt(int context, FRAGMENTSHADER* pfragment, int settexint)
1969  {  {
1970          FUNCLOG          FUNCLOG
1971    
1972          if (settexint)          if (settexint)
1973          {          {
1974                  tex0Info& tex0 = vb[context].tex0;                  tex0Info& tex0 = vb[context].tex0;
1975    
1976                  CMemoryTarget* pmemtarg = g_MemTargs.GetMemoryTarget(tex0, 1);                  CMemoryTarget* pmemtarg = g_MemTargs.GetMemoryTarget(tex0, 1);
1977    
1978                  if (vb[context].bVarsTexSync)                  if (vb[context].bVarsTexSync)
1979                  {                  {
1980                          if (vb[context].pmemtarg != pmemtarg)                          if (vb[context].pmemtarg != pmemtarg)
1981                          {                          {
1982                                  SetTexVariablesInt(context, GetTexFilter(vb[context].tex1), tex0, pmemtarg, pfragment, s_bForceTexFlush);                                  SetTexVariablesInt(context, GetTexFilter(vb[context].tex1), tex0, pmemtarg, pfragment, s_bForceTexFlush);
1983                                  vb[context].bVarsTexSync = true;                                  vb[context].bVarsTexSync = true;
1984                          }                          }
1985                  }                  }
1986                  else                  else
1987                  {                  {
1988                          SetTexVariablesInt(context, GetTexFilter(vb[context].tex1), tex0, pmemtarg, pfragment, s_bForceTexFlush);                          SetTexVariablesInt(context, GetTexFilter(vb[context].tex1), tex0, pmemtarg, pfragment, s_bForceTexFlush);
1989                          vb[context].bVarsTexSync = true;                          vb[context].bVarsTexSync = true;
1990    
1991                          INC_TEXVARS();                          INC_TEXVARS();
1992                  }                  }
1993          }          }
1994          else          else
1995          {          {
1996                  vb[context].bVarsTexSync = false;                  vb[context].bVarsTexSync = false;
1997          }          }
1998  }  }
1999    
2000  // clamp relies on texture width  // clamp relies on texture width
2001  void ZeroGS::SetTexClamping(int context, FRAGMENTSHADER* pfragment)  void ZeroGS::SetTexClamping(int context, FRAGMENTSHADER* pfragment)
2002  {  {
2003          FUNCLOG          FUNCLOG
2004          SetShaderCaller("SetTexClamping");          SetShaderCaller("SetTexClamping");
2005          clampInfo* pclamp = &ZeroGS::vb[context].clamp;          clampInfo* pclamp = &ZeroGS::vb[context].clamp;
2006          Vector v, v2;          Vector v, v2;
2007          v.x = v.y = 0;          v.x = v.y = 0;
2008          u32* ptex = ZeroGS::vb[context].ptexClamp;          u32* ptex = ZeroGS::vb[context].ptexClamp;
2009          ptex[0] = ptex[1] = 0;          ptex[0] = ptex[1] = 0;
2010    
2011          float fw = ZeroGS::vb[context].tex0.tw ;          float fw = ZeroGS::vb[context].tex0.tw ;
2012          float fh = ZeroGS::vb[context].tex0.th ;          float fh = ZeroGS::vb[context].tex0.th ;
2013    
2014          switch (pclamp->wms)          switch (pclamp->wms)
2015          {          {
2016                  case 0:                  case 0:
2017                          v2.x = -1e10;                          v2.x = -1e10;
2018                          v2.z = 1e10;                          v2.z = 1e10;
2019                          break;                          break;
2020    
2021                  case 1: // pclamp                  case 1: // pclamp
2022                          // suikoden5 movie text                          // suikoden5 movie text
2023                          v2.x = 0;                          v2.x = 0;
2024                          v2.z = 1 - 0.5f / fw;                          v2.z = 1 - 0.5f / fw;
2025                          break;                          break;
2026    
2027                  case 2: // reg pclamp                  case 2: // reg pclamp
2028                          v2.x = (pclamp->minu + 0.5f) / fw;                          v2.x = (pclamp->minu + 0.5f) / fw;
2029                          v2.z = (pclamp->maxu - 0.5f) / fw;                          v2.z = (pclamp->maxu - 0.5f) / fw;
2030                          break;                          break;
2031    
2032                  case 3: // region rep x                  case 3: // region rep x
2033                          v.x = 0.9999f;                          v.x = 0.9999f;
2034                          v.z = (float)fw;                          v.z = (float)fw;
2035                          v2.x = (float)GPU_TEXMASKWIDTH / fw;                          v2.x = (float)GPU_TEXMASKWIDTH / fw;
2036                          v2.z = pclamp->maxu / fw;                          v2.z = pclamp->maxu / fw;
2037                          int correctMinu = pclamp->minu & (~pclamp->maxu);               // (A && B) || C == (A && (B && !C)) + C                          int correctMinu = pclamp->minu & (~pclamp->maxu);               // (A && B) || C == (A && (B && !C)) + C
2038    
2039                          if (correctMinu != g_PrevBitwiseTexX)                          if (correctMinu != g_PrevBitwiseTexX)
2040                          {                          {
2041                                  g_PrevBitwiseTexX = correctMinu;                                  g_PrevBitwiseTexX = correctMinu;
2042                                  ptex[0] = ZeroGS::s_BitwiseTextures.GetTex(correctMinu, 0);                                  ptex[0] = ZeroGS::s_BitwiseTextures.GetTex(correctMinu, 0);
2043                          }                          }
2044    
2045                          break;                          break;
2046          }          }
2047    
2048          switch (pclamp->wmt)          switch (pclamp->wmt)
2049          {          {
2050    
2051                  case 0:                  case 0:
2052                          v2.y = -1e10;                          v2.y = -1e10;
2053                          v2.w = 1e10;                          v2.w = 1e10;
2054                          break;                          break;
2055    
2056                  case 1: // pclamp                  case 1: // pclamp
2057                          // suikoden5 movie text                          // suikoden5 movie text
2058                          v2.y = 0;                          v2.y = 0;
2059                          v2.w = 1 - 0.5f / fh;                          v2.w = 1 - 0.5f / fh;
2060                          break;                          break;
2061    
2062                  case 2: // reg pclamp                  case 2: // reg pclamp
2063                          v2.y = (pclamp->minv + 0.5f) / fh;                          v2.y = (pclamp->minv + 0.5f) / fh;
2064                          v2.w = (pclamp->maxv - 0.5f) / fh;                          v2.w = (pclamp->maxv - 0.5f) / fh;
2065                          break;                          break;
2066    
2067                  case 3: // region rep y                  case 3: // region rep y
2068                          v.y = 0.9999f;                          v.y = 0.9999f;
2069                          v.w = (float)fh;                          v.w = (float)fh;
2070                          v2.y = (float)GPU_TEXMASKWIDTH / fh;                          v2.y = (float)GPU_TEXMASKWIDTH / fh;
2071                          v2.w = pclamp->maxv / fh;                          v2.w = pclamp->maxv / fh;
2072                          int correctMinv = pclamp->minv & (~pclamp->maxv);               // (A && B) || C == (A && (B && !C)) + C                          int correctMinv = pclamp->minv & (~pclamp->maxv);               // (A && B) || C == (A && (B && !C)) + C
2073    
2074                          if (correctMinv != g_PrevBitwiseTexY)                          if (correctMinv != g_PrevBitwiseTexY)
2075                          {                          {
2076                                  g_PrevBitwiseTexY = correctMinv;                                  g_PrevBitwiseTexY = correctMinv;
2077                                  ptex[1] = ZeroGS::s_BitwiseTextures.GetTex(correctMinv, ptex[0]);                                  ptex[1] = ZeroGS::s_BitwiseTextures.GetTex(correctMinv, ptex[0]);
2078                          }                          }
2079                          break;                          break;
2080          }          }
2081    
2082          if (pfragment->fTexWrapMode != 0)          if (pfragment->fTexWrapMode != 0)
2083                  ZZcgSetParameter4fv(pfragment->fTexWrapMode, v, "g_fTexWrapMode");                  ZZcgSetParameter4fv(pfragment->fTexWrapMode, v, "g_fTexWrapMode");
2084    
2085          if (pfragment->fClampExts != 0)          if (pfragment->fClampExts != 0)
2086                  ZZcgSetParameter4fv(pfragment->fClampExts, v2, "g_fClampExts");                  ZZcgSetParameter4fv(pfragment->fClampExts, v2, "g_fClampExts");
2087    
2088    
2089  }  }
2090    
2091  // Fixme should be in Vector lib  // Fixme should be in Vector lib
2092  inline bool equal_vectors(Vector a, Vector b)  inline bool equal_vectors(Vector a, Vector b)
2093  {  {
2094          if (abs(a.x - b.x) + abs(a.y - b.y) + abs(a.z - b.z) + abs(a.w - b.w) < 0.01)          if (abs(a.x - b.x) + abs(a.y - b.y) + abs(a.z - b.z) + abs(a.w - b.w) < 0.01)
2095                  return true;                  return true;
2096          else          else
2097                  return false;                  return false;
2098  }  }
2099    
2100  int CheckTexArray[4][2][2][2] = {{{{0, }}}};  int CheckTexArray[4][2][2][2] = {{{{0, }}}};
2101  void ZeroGS::SetTexVariables(int context, FRAGMENTSHADER* pfragment)  void ZeroGS::SetTexVariables(int context, FRAGMENTSHADER* pfragment)
2102  {  {
2103          FUNCLOG          FUNCLOG
2104    
2105          if (!vb[context].curprim.tme) return;          if (!vb[context].curprim.tme) return;
2106    
2107          assert(!vb[context].bNeedTexCheck);          assert(!vb[context].bNeedTexCheck);
2108    
2109          Vector v, v2;          Vector v, v2;
2110    
2111          tex0Info& tex0 = vb[context].tex0;          tex0Info& tex0 = vb[context].tex0;
2112    
2113          //float fw = (float)tex0.tw;          //float fw = (float)tex0.tw;
2114          //float fh = (float)tex0.th;          //float fh = (float)tex0.th;
2115    
2116          if (!vb[context].bTexConstsSync)          if (!vb[context].bTexConstsSync)
2117          {          {
2118                  SetShaderCaller("SetTexVariables");                  SetShaderCaller("SetTexVariables");
2119    
2120                  // alpha and texture highlighting                  // alpha and texture highlighting
2121                  Vector valpha, valpha2 ;                  Vector valpha, valpha2 ;
2122    
2123                  // if clut, use the frame format                  // if clut, use the frame format
2124                  int psm = GetTexCPSM(tex0);                  int psm = GetTexCPSM(tex0);
2125    
2126  //              printf ( "A %d psm, is-clut %d. cpsm %d | %d %d\n", psm,  PSMT_ISCLUT(psm), tex0.cpsm,  tex0.tfx, tex0.tcc );  //              printf ( "A %d psm, is-clut %d. cpsm %d | %d %d\n", psm,  PSMT_ISCLUT(psm), tex0.cpsm,  tex0.tfx, tex0.tcc );
2127    
2128                  Vector vblack;                  Vector vblack;
2129                  vblack.x = vblack.y = vblack.z = vblack.w = 10;                  vblack.x = vblack.y = vblack.z = vblack.w = 10;
2130    
2131                  /* tcc -- Tecture Color Component 0=RGB, 1=RGBA + use Alpha from TEXA reg when not in PSM                  /* tcc -- Tecture Color Component 0=RGB, 1=RGBA + use Alpha from TEXA reg when not in PSM
2132                   * tfx -- Texture Function (0=modulate, 1=decal, 2=hilight, 3=hilight2)                   * tfx -- Texture Function (0=modulate, 1=decal, 2=hilight, 3=hilight2)
2133                   *                   *
2134                   * valpha2 =  0 0 2 1     0 0 2 1                   * valpha2 =  0 0 2 1     0 0 2 1
2135                   *            1 0 0 0     1 1 0 0                   *            1 0 0 0     1 1 0 0
2136                   *            0 0 2 0     0 1 2 0                   *            0 0 2 0     0 1 2 0
2137                   *            0 0 2 0     0 1 2 0                   *            0 0 2 0     0 1 2 0
2138                   *                   *
2139                   *              0        1,!nNeed         1, psm=2, 10                1, psm=1                   *              0        1,!nNeed         1, psm=2, 10                1, psm=1
2140                   * valpha =   0 0 0 1     0 2 0 0        2ta0  2ta1-2ta0 0 0          2ta0 0 0 0                   * valpha =   0 0 0 1     0 2 0 0        2ta0  2ta1-2ta0 0 0          2ta0 0 0 0
2141                   *            0 0 0 1     0 1 0 0         ta0   ta1-ta0  0 0           ta0 0 0 0                   *            0 0 0 1     0 1 0 0         ta0   ta1-ta0  0 0           ta0 0 0 0
2142                   *            0 0 1 1     0 1 1 1                        1 1           ta0 0 1 1                   *            0 0 1 1     0 1 1 1                        1 1           ta0 0 1 1
2143                   *            0 0 1 1     0 1 1 0                        1 0           ta0 0 1 0                   *            0 0 1 1     0 1 1 0                        1 0           ta0 0 1 0
2144                  */                  */
2145    
2146                  valpha2.x = (tex0.tfx == 1) ;                  valpha2.x = (tex0.tfx == 1) ;
2147                  valpha2.y = (tex0.tcc == 1) && (tex0.tfx != 0) ;                  valpha2.y = (tex0.tcc == 1) && (tex0.tfx != 0) ;
2148                  valpha2.z = (tex0.tfx != 1) * 2 ;                  valpha2.z = (tex0.tfx != 1) * 2.0f ;
2149                  valpha2.w = (tex0.tfx == 0) ;                  valpha2.w = (tex0.tfx == 0) ;
2150    
2151                  if (tex0.tcc == 0 || !nNeedAlpha(psm))                  if (tex0.tcc == 0 || !nNeedAlpha(psm))
2152                  {                  {
2153                          valpha.x = 0 ;                          valpha.x = 0 ;
2154                          valpha.y = (!!tex0.tcc) * (1 + (tex0.tfx == 0)) ;                          valpha.y = (!!tex0.tcc) * (1.0f + (tex0.tfx == 0)) ;
2155                  }                  }
2156                  else                  else
2157                  {                  {
2158                          valpha.x = (gs.texa.fta[0])  * (1 + (tex0.tfx == 0)) ;                          valpha.x = (gs.texa.fta[0])  * (1.0f + (tex0.tfx == 0)) ;
2159                          valpha.y = (gs.texa.fta[psm!=1] - gs.texa.fta[0]) * (1 + (tex0.tfx == 0))  ;                          valpha.y = (gs.texa.fta[psm!=1] - gs.texa.fta[0]) * (1.0f + (tex0.tfx == 0))  ;
2160                  }                  }
2161    
2162                  valpha.z = (tex0.tfx >= 3) ;                  valpha.z = (tex0.tfx >= 3) ;
2163    
2164                  valpha.w = (tex0.tcc == 0) || (tex0.tcc == 1 && tex0.tfx == 2) ;                  valpha.w = (tex0.tcc == 0) || (tex0.tcc == 1 && tex0.tfx == 2) ;
2165    
2166                  if (tex0.tcc && gs.texa.aem && psm == PSMCT24)                  if (tex0.tcc && gs.texa.aem && psm == PSMCT24)
2167                          vblack.w = 0;                          vblack.w = 0;
2168    
2169                  /*                  /*
2170                  // Test, old code.                  // Test, old code.
2171                                  Vector valpha3, valpha4;                                  Vector valpha3, valpha4;
2172                                  switch(tex0.tfx) {                                  switch(tex0.tfx) {
2173                                          case 0:                                          case 0:
2174                                                  valpha3.z = 0; valpha3.w = 0;                                                  valpha3.z = 0; valpha3.w = 0;
2175                                                  valpha4.x = 0; valpha4.y = 0;                                                  valpha4.x = 0; valpha4.y = 0;
2176                                                  valpha4.z = 2; valpha4.w = 1;                                                  valpha4.z = 2; valpha4.w = 1;
2177    
2178                                                  break;                                                  break;
2179                                          case 1:                                          case 1:
2180                                                  valpha3.z = 0; valpha3.w = 1;                                                  valpha3.z = 0; valpha3.w = 1;
2181                                                  valpha4.x = 1; valpha4.y = 0;                                                  valpha4.x = 1; valpha4.y = 0;
2182                                                  valpha4.z = 0; valpha4.w = 0;                                                  valpha4.z = 0; valpha4.w = 0;
2183    
2184                                                  break;                                                  break;
2185                                          case 2:                                          case 2:
2186                                                  valpha3.z = 1; valpha3.w = 1.0f;                                                  valpha3.z = 1; valpha3.w = 1.0f;
2187                                                  valpha4.x = 0; valpha4.y = tex0.tcc ? 1.0f : 0.0f;                                                  valpha4.x = 0; valpha4.y = tex0.tcc ? 1.0f : 0.0f;
2188                                                  valpha4.z = 2; valpha4.w = 0;                                                  valpha4.z = 2; valpha4.w = 0;
2189    
2190                                                  break;                                                  break;
2191    
2192                                          case 3:                                          case 3:
2193                                                  valpha3.z = 1; valpha3.w = tex0.tcc ? 0.0f : 1.0f;                                                  valpha3.z = 1; valpha3.w = tex0.tcc ? 0.0f : 1.0f;
2194                                                  valpha4.x = 0; valpha4.y = tex0.tcc ? 1.0f : 0.0f;                                                  valpha4.x = 0; valpha4.y = tex0.tcc ? 1.0f : 0.0f;
2195                                                  valpha4.z = 2; valpha4.w = 0;                                                  valpha4.z = 2; valpha4.w = 0;
2196    
2197                                                  break;                                                  break;
2198                                  }                                  }
2199                                  if( tex0.tcc ) {                                  if( tex0.tcc ) {
2200    
2201                                          if( tex0.tfx == 1 ) {                                          if( tex0.tfx == 1 ) {
2202                                                  //mode.x = 10;                                                  //mode.x = 10;
2203                                                  valpha3.z = 0; valpha3.w = 0;                                                  valpha3.z = 0; valpha3.w = 0;
2204                                                  valpha4.x = 1; valpha4.y = 1;                                                  valpha4.x = 1; valpha4.y = 1;
2205                                                  valpha4.z = 0; valpha4.w = 0;                                                  valpha4.z = 0; valpha4.w = 0;
2206                                          }                                          }
2207    
2208                                          if( nNeedAlpha(psm) ) {                                          if( nNeedAlpha(psm) ) {
2209    
2210                                                  if( tex0.tfx == 0 ) {                                                  if( tex0.tfx == 0 ) {
2211                                                          // make sure alpha is mult by two when the output is Cv = Ct*Cf                                                          // make sure alpha is mult by two when the output is Cv = Ct*Cf
2212                                                          valpha3.x = 2*gs.texa.fta[0];                                                          valpha3.x = 2*gs.texa.fta[0];
2213                                                          // if 24bit, always choose ta[0]                                                          // if 24bit, always choose ta[0]
2214                                                          valpha3.y = 2*gs.texa.fta[psm != 1];                                                          valpha3.y = 2*gs.texa.fta[psm != 1];
2215                                                          valpha3.y -= valpha.x;                                                          valpha3.y -= valpha.x;
2216                                                  }                                                  }
2217                                                  else {                                                  else {
2218                                                          valpha3.x = gs.texa.fta[0];                                                          valpha3.x = gs.texa.fta[0];
2219                                                          // if 24bit, always choose ta[0]                                                          // if 24bit, always choose ta[0]
2220                                                          valpha3.y = gs.texa.fta[psm != 1];                                                          valpha3.y = gs.texa.fta[psm != 1];
2221                                                          valpha3.y -= valpha.x;                                                          valpha3.y -= valpha.x;
2222                                                  }                                                  }
2223                                          }                                          }
2224                                          else {                                          else {
2225                                                  if( tex0.tfx == 0 ) {                                                  if( tex0.tfx == 0 ) {
2226                                                          valpha3.x = 0;                                                          valpha3.x = 0;
2227                                                          valpha3.y = 2;                                                          valpha3.y = 2;
2228                                                  }                                                  }
2229                                                  else {                                                  else {
2230                                                          valpha3.x = 0;                                                          valpha3.x = 0;
2231                                                          valpha3.y = 1;                                                          valpha3.y = 1;
2232                                                  }                                                  }
2233                                          }                                          }
2234                                  }                                  }
2235                                  else {                                  else {
2236    
2237                                          // reset alpha to color                                          // reset alpha to color
2238                                          valpha3.x = valpha3.y = 0;                                          valpha3.x = valpha3.y = 0;
2239                                          valpha3.w = 1;                                          valpha3.w = 1;
2240                                  }                                  }
2241    
2242                                  if ( equal_vectors(valpha, valpha3) && equal_vectors(valpha2, valpha4) ) {                                  if ( equal_vectors(valpha, valpha3) && equal_vectors(valpha2, valpha4) ) {
2243                                          if (CheckTexArray[tex0.tfx][tex0.tcc][psm!=1][nNeedAlpha(psm)] == 0) {                                          if (CheckTexArray[tex0.tfx][tex0.tcc][psm!=1][nNeedAlpha(psm)] == 0) {
2244                                                  printf ( "Good issue %d %d %d %d\n", tex0.tfx,  tex0.tcc, psm, nNeedAlpha(psm) );                                                  printf ( "Good issue %d %d %d %d\n", tex0.tfx,  tex0.tcc, psm, nNeedAlpha(psm) );
2245                                                  CheckTexArray[tex0.tfx][tex0.tcc][psm!=1][nNeedAlpha(psm) ] = 1;                                                  CheckTexArray[tex0.tfx][tex0.tcc][psm!=1][nNeedAlpha(psm) ] = 1;
2246                                          }                                          }
2247                                  }                                  }
2248                                  else if (CheckTexArray[tex0.tfx][tex0.tcc][psm!=1][nNeedAlpha(psm)] == -1) {                                  else if (CheckTexArray[tex0.tfx][tex0.tcc][psm!=1][nNeedAlpha(psm)] == -1) {
2249                                          printf ("Bad array, %d %d %d %d\n\tolf valpha %f, %f, %f, %f : valpha2 %f %f %f %f\n\tnew valpha %f, %f, %f, %f : valpha2 %f %f %f %f\n",                                          printf ("Bad array, %d %d %d %d\n\tolf valpha %f, %f, %f, %f : valpha2 %f %f %f %f\n\tnew valpha %f, %f, %f, %f : valpha2 %f %f %f %f\n",
2250                                                   tex0.tfx,  tex0.tcc, psm, nNeedAlpha(psm),                                                   tex0.tfx,  tex0.tcc, psm, nNeedAlpha(psm),
2251                                                  valpha3.x, valpha3.y, valpha3.z, valpha3.w, valpha4.x, valpha4.y, valpha4.z, valpha4.w,                                                  valpha3.x, valpha3.y, valpha3.z, valpha3.w, valpha4.x, valpha4.y, valpha4.z, valpha4.w,
2252                                                  valpha.x, valpha.y, valpha.z, valpha.w,  valpha2.x, valpha2.y, valpha2.z, valpha2.w);                                                  valpha.x, valpha.y, valpha.z, valpha.w,  valpha2.x, valpha2.y, valpha2.z, valpha2.w);
2253                                          CheckTexArray[tex0.tfx][tex0.tcc][psm!=1][nNeedAlpha(psm)] = -1 ;                                          CheckTexArray[tex0.tfx][tex0.tcc][psm!=1][nNeedAlpha(psm)] = -1 ;
2254                                  }                                  }
2255    
2256                  // Test;*/                  // Test;*/
2257    
2258                  ZZcgSetParameter4fv(pfragment->fTexAlpha, valpha, "g_fTexAlpha");                  ZZcgSetParameter4fv(pfragment->fTexAlpha, valpha, "g_fTexAlpha");
2259                  ZZcgSetParameter4fv(pfragment->fTexAlpha2, valpha2, "g_fTexAlpha2");                  ZZcgSetParameter4fv(pfragment->fTexAlpha2, valpha2, "g_fTexAlpha2");
2260    
2261                  if (tex0.tcc && gs.texa.aem && nNeedAlpha(psm))                  if (tex0.tcc && gs.texa.aem && nNeedAlpha(psm))
2262                          ZZcgSetParameter4fv(pfragment->fTestBlack, vblack, "g_fTestBlack");                          ZZcgSetParameter4fv(pfragment->fTestBlack, vblack, "g_fTestBlack");
2263    
2264                  SetTexClamping(context, pfragment);                  SetTexClamping(context, pfragment);
2265    
2266                  vb[context].bTexConstsSync = true;                  vb[context].bTexConstsSync = true;
2267          }          }
2268    
2269          if (s_bTexFlush)          if (s_bTexFlush)
2270          {          {
2271                  if (PSMT_ISCLUT(tex0.psm))                  if (PSMT_ISCLUT(tex0.psm))
2272                          texClutWrite(context);                          texClutWrite(context);
2273                  else                  else
2274                          s_bTexFlush = false;                          s_bTexFlush = false;
2275          }          }
2276  }  }
2277    
2278  void ZeroGS::SetTexVariablesInt(int context, int bilinear, const tex0Info& tex0, CMemoryTarget* pmemtarg, FRAGMENTSHADER* pfragment, int force)  void ZeroGS::SetTexVariablesInt(int context, int bilinear, const tex0Info& tex0, CMemoryTarget* pmemtarg, FRAGMENTSHADER* pfragment, int force)
2279  {  {
2280          FUNCLOG          FUNCLOG
2281          Vector v;          Vector v;
2282          assert(pmemtarg != NULL && pfragment != NULL && pmemtarg->ptex != NULL);          assert(pmemtarg != NULL && pfragment != NULL && pmemtarg->ptex != NULL);
2283    
2284          if (pmemtarg == NULL || pfragment == NULL || pmemtarg->ptex == NULL)          if (pmemtarg == NULL || pfragment == NULL || pmemtarg->ptex == NULL)
2285          {          {
2286                  printf("SetTexVariablesInt error\n");                  printf("SetTexVariablesInt error\n");
2287                  return;                  return;
2288          }          }
2289    
2290          SetShaderCaller("SetTexVariablesInt");          SetShaderCaller("SetTexVariablesInt");
2291    
2292          float fw = (float)tex0.tw;          float fw = (float)tex0.tw;
2293          float fh = (float)tex0.th;          float fh = (float)tex0.th;
2294    
2295          bool bUseBilinear = bilinear > 1 || (bilinear && conf.bilinear);          bool bUseBilinear = bilinear > 1 || (bilinear && conf.bilinear);
2296    
2297          if (bUseBilinear)          if (bUseBilinear)
2298          {          {
2299                  v.x = (float)fw;                  v.x = (float)fw;
2300                  v.y = (float)fh;                  v.y = (float)fh;
2301                  v.z = 1.0f / (float)fw;                  v.z = 1.0f / (float)fw;
2302                  v.w = 1.0f / (float)fh;                  v.w = 1.0f / (float)fh;
2303    
2304                  if (pfragment->fRealTexDims)                  if (pfragment->fRealTexDims)
2305                          ZZcgSetParameter4fv(pfragment->fRealTexDims, v, "g_fRealTexDims");                          ZZcgSetParameter4fv(pfragment->fRealTexDims, v, "g_fRealTexDims");
2306                  else                  else
2307                          ZZcgSetParameter4fv(cgGetNamedParameter(pfragment->prog, "g_fRealTexDims"), v, "g_fRealTexDims");                          ZZcgSetParameter4fv(cgGetNamedParameter(pfragment->prog, "g_fRealTexDims"), v, "g_fRealTexDims");
2308          }          }
2309    
2310          if (m_Blocks[tex0.psm].bpp == 0)          if (m_Blocks[tex0.psm].bpp == 0)
2311          {          {
2312                  ZZLog::Error_Log("Undefined tex psm 0x%x!", tex0.psm);                  ZZLog::Error_Log("Undefined tex psm 0x%x!", tex0.psm);
2313                  return;                  return;
2314          }          }
2315    
2316          const BLOCK& b = m_Blocks[tex0.psm];          const BLOCK& b = m_Blocks[tex0.psm];
2317    
2318          float fbw = (float)tex0.tbw;          float fbw = (float)tex0.tbw;
2319    
2320          Vector vTexDims;          Vector vTexDims;
2321    
2322          vTexDims.x = b.vTexDims.x * (fw);          vTexDims.x = b.vTexDims.x * (fw);
2323          vTexDims.y = b.vTexDims.y * (fh);          vTexDims.y = b.vTexDims.y * (fh);
2324          vTexDims.z = (float)BLOCK_TEXWIDTH * (0.002f / 64.0f + 0.01f / 128.0f);          vTexDims.z = (float)BLOCK_TEXWIDTH * (0.002f / 64.0f + 0.01f / 128.0f);
2325          vTexDims.w = (float)BLOCK_TEXHEIGHT * 0.1f / 512.0f;          vTexDims.w = (float)BLOCK_TEXHEIGHT * 0.1f / 512.0f;
2326    
2327          if (bUseBilinear)          if (bUseBilinear)
2328          {          {
2329                  vTexDims.x *= 1 / 128.0f;                  vTexDims.x *= 1 / 128.0f;
2330                  vTexDims.y *= 1 / 512.0f;                  vTexDims.y *= 1 / 512.0f;
2331                  vTexDims.z *= 1 / 128.0f;                  vTexDims.z *= 1 / 128.0f;
2332                  vTexDims.w *= 1 / 512.0f;                  vTexDims.w *= 1 / 512.0f;
2333          }          }
2334    
2335          float g_fitexwidth = g_fiGPU_TEXWIDTH / (float)pmemtarg->widthmult;          float g_fitexwidth = g_fiGPU_TEXWIDTH / (float)pmemtarg->widthmult;
2336    
2337          //float g_texwidth = GPU_TEXWIDTH*(float)pmemtarg->widthmult;          //float g_texwidth = GPU_TEXWIDTH*(float)pmemtarg->widthmult;
2338    
2339          float fpage = tex0.tbp0 * (64.0f * g_fitexwidth);// + 0.05f * g_fitexwidth;          float fpage = tex0.tbp0 * (64.0f * g_fitexwidth);// + 0.05f * g_fitexwidth;
2340          float fpageint = floorf(fpage);          float fpageint = floorf(fpage);
2341          //int starttbp = (int)fpage;          //int starttbp = (int)fpage;
2342    
2343          // 2048 is number of words to span one page          // 2048 is number of words to span one page
2344          //float fblockstride = (2048.0f /(float)(g_texwidth*BLOCK_TEXWIDTH)) * b.vTexDims.x * fbw;          //float fblockstride = (2048.0f /(float)(g_texwidth*BLOCK_TEXWIDTH)) * b.vTexDims.x * fbw;
2345    
2346          float fblockstride = (2048.0f / (float)(GPU_TEXWIDTH * (float)pmemtarg->widthmult * BLOCK_TEXWIDTH)) * b.vTexDims.x * fbw;          float fblockstride = (2048.0f / (float)(GPU_TEXWIDTH * (float)pmemtarg->widthmult * BLOCK_TEXWIDTH)) * b.vTexDims.x * fbw;
2347    
2348          assert(fblockstride >= 1.0f);          assert(fblockstride >= 1.0f);
2349    
2350          v.x = (float)(2048 * g_fitexwidth);          v.x = (float)(2048 * g_fitexwidth);
2351          v.y = fblockstride;          v.y = fblockstride;
2352          v.z = g_fBlockMult / (float)pmemtarg->widthmult;          v.z = g_fBlockMult / (float)pmemtarg->widthmult;
2353          v.w = fpage - fpageint ;          v.w = fpage - fpageint ;
2354    
2355          if (g_fBlockMult > 1)          if (g_fBlockMult > 1)
2356          {          {
2357                  // make sure to divide by mult (since the G16R16 texture loses info)                  // make sure to divide by mult (since the G16R16 texture loses info)
2358                  v.z *= b.bpp * (1 / 32.0f);                  v.z *= b.bpp * (1 / 32.0f);
2359          }          }
2360    
2361          ZZcgSetParameter4fv(pfragment->fTexDims, vTexDims, "g_fTexDims");          ZZcgSetParameter4fv(pfragment->fTexDims, vTexDims, "g_fTexDims");
2362    
2363  //      ZZcgSetParameter4fv(pfragment->fTexBlock, b.vTexBlock, "g_fTexBlock"); // I change it, and it's working. Seems casting from Vector to float[4] is ok.  //      ZZcgSetParameter4fv(pfragment->fTexBlock, b.vTexBlock, "g_fTexBlock"); // I change it, and it's working. Seems casting from Vector to float[4] is ok.
2364          ZZcgSetParameter4fv(pfragment->fTexBlock, &b.vTexBlock.x, "g_fTexBlock");          ZZcgSetParameter4fv(pfragment->fTexBlock, &b.vTexBlock.x, "g_fTexBlock");
2365          ZZcgSetParameter4fv(pfragment->fTexOffset, v, "g_fTexOffset");          ZZcgSetParameter4fv(pfragment->fTexOffset, v, "g_fTexOffset");
2366    
2367          // get hardware texture dims          // get hardware texture dims
2368          //int texheight = (pmemtarg->realheight+pmemtarg->widthmult-1)/pmemtarg->widthmult;          //int texheight = (pmemtarg->realheight+pmemtarg->widthmult-1)/pmemtarg->widthmult;
2369          int texwidth = GPU_TEXWIDTH * pmemtarg->widthmult * pmemtarg->channels;          int texwidth = GPU_TEXWIDTH * pmemtarg->widthmult * pmemtarg->channels;
2370    
2371          v.y = 1.0f;          v.y = 1.0f;
2372          v.x = (fpageint - (float)pmemtarg->realy / (float)pmemtarg->widthmult + 0.5f);//*v.y;          v.x = (fpageint - (float)pmemtarg->realy / (float)pmemtarg->widthmult + 0.5f);//*v.y;
2373          v.z = (float)texwidth;          v.z = (float)texwidth;
2374    
2375          /*      if( !(g_nPixelShaderVer & SHADER_ACCURATE) || bUseBilinear ) {          /*      if( !(g_nPixelShaderVer & SHADER_ACCURATE) || bUseBilinear ) {
2376                          if (tex0.psm == PSMT4 )                          if (tex0.psm == PSMT4 )
2377                                  v.w = 0.0f;                                  v.w = 0.0f;
2378                          else                          else
2379                                  v.w = 0.25f;                                  v.w = 0.25f;
2380                          }                          }
2381                  else                  else
2382                          v.w = 0.5f;*/                          v.w = 0.5f;*/
2383          v.w = 0.5f;          v.w = 0.5f;
2384    
2385          ZZcgSetParameter4fv(pfragment->fPageOffset, v, "g_fPageOffset");          ZZcgSetParameter4fv(pfragment->fPageOffset, v, "g_fPageOffset");
2386    
2387          if (force)          if (force)
2388                  s_ptexCurSet[context] = pmemtarg->ptex->tex;                  s_ptexCurSet[context] = pmemtarg->ptex->tex;
2389          else          else
2390                  s_ptexNextSet[context] = pmemtarg->ptex->tex;                  s_ptexNextSet[context] = pmemtarg->ptex->tex;
2391    
2392          vb[context].pmemtarg = pmemtarg;          vb[context].pmemtarg = pmemtarg;
2393    
2394          vb[context].bVarsTexSync = false;          vb[context].bVarsTexSync = false;
2395  }  }
2396    
2397  #define SET_ALPHA_COLOR_FACTOR(sign) \  #define SET_ALPHA_COLOR_FACTOR(sign) \
2398  { \  { \
2399          switch(a.c) \          switch(a.c) \
2400          { \          { \
2401                  case 0: \                  case 0: \
2402                          vAlphaBlendColor.y = (sign) ? 2.0f*255.0f/256.0f : -2.0f*255.0f/256.0f; \                          vAlphaBlendColor.y = (sign) ? 2.0f*255.0f/256.0f : -2.0f*255.0f/256.0f; \
2403                          s_srcalpha = GL_ONE; \                          s_srcalpha = GL_ONE; \
2404                          s_alphaeq = (sign) ? GL_FUNC_ADD : GL_FUNC_REVERSE_SUBTRACT; \                          s_alphaeq = (sign) ? GL_FUNC_ADD : GL_FUNC_REVERSE_SUBTRACT; \
2405                          break; \                          break; \
2406                          \                          \
2407                  case 1: \                  case 1: \
2408                          /* if in 24 bit mode, dest alpha should be one */ \                          /* if in 24 bit mode, dest alpha should be one */ \
2409                          switch(PSMT_BITMODE(vb[icurctx].prndr->psm)) \                          switch(PSMT_BITMODE(vb[icurctx].prndr->psm)) \
2410                          { \                          { \
2411                                  case 0: \                                  case 0: \
2412                                          bDestAlphaColor = (a.d!=2)&&((a.a==a.d)||(a.b==a.d)); \                                          bDestAlphaColor = (a.d!=2)&&((a.a==a.d)||(a.b==a.d)); \
2413                                          break; \                                          break; \
2414                                          \                                          \
2415                                  case 1: \                                  case 1: \
2416                                          /* dest alpha should be one */ \                                          /* dest alpha should be one */ \
2417                                          bDestAlphaColor = 2; \                                          bDestAlphaColor = 2; \
2418                                          break; \                                          break; \
2419                                          /* default: 16bit surface, so returned alpha is ok */ \                                          /* default: 16bit surface, so returned alpha is ok */ \
2420                          } \                          } \
2421                  break; \                  break; \
2422                  \                  \
2423                  case 2: \                  case 2: \
2424                          bNeedBlendFactorInAlpha = true; /* should disable alpha channel writing */ \                          bNeedBlendFactorInAlpha = true; /* should disable alpha channel writing */ \
2425                          vAlphaBlendColor.y = 0; \                          vAlphaBlendColor.y = 0; \
2426                          vAlphaBlendColor.w = (sign) ? (float)a.fix * (2.0f/255.0f) : (float)a.fix * (-2.0f/255.0f); \                          vAlphaBlendColor.w = (sign) ? (float)a.fix * (2.0f/255.0f) : (float)a.fix * (-2.0f/255.0f); \
2427                          usec = 0; /* change so that alpha comes from source*/ \                          usec = 0; /* change so that alpha comes from source*/ \
2428                  break; \                  break; \
2429          } \          } \
2430  } \  } \
2431    
2432  //if( a.fix <= 0x80 ) { \  //if( a.fix <= 0x80 ) { \
2433  // dwTemp = (a.fix*2)>255?255:(a.fix*2); \  // dwTemp = (a.fix*2)>255?255:(a.fix*2); \
2434  // dwTemp = dwTemp|(dwTemp<<8)|(dwTemp<<16)|0x80000000; \  // dwTemp = dwTemp|(dwTemp<<8)|(dwTemp<<16)|0x80000000; \
2435  // printf("bfactor: %8.8x\n", dwTemp); \  // printf("bfactor: %8.8x\n", dwTemp); \
2436  // glBlendColorEXT(dwTemp); \  // glBlendColorEXT(dwTemp); \
2437  // } \  // } \
2438  // else { \  // else { \
2439    
2440  void ZeroGS::ResetAlphaVariables() {  void ZeroGS::ResetAlphaVariables() {
2441          FUNCLOG          FUNCLOG
2442  }  }</