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