| 1 | /* |
| 2 | Copyright (C) 2003 Rice1964 |
| 3 | |
| 4 | This program is free software; you can redistribute it and/or |
| 5 | modify it under the terms of the GNU General Public License |
| 6 | as published by the Free Software Foundation; either version 2 |
| 7 | of the License, or (at your option) any later version. |
| 8 | |
| 9 | This program is distributed in the hope that it will be useful, |
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | GNU General Public License for more details. |
| 13 | |
| 14 | You should have received a copy of the GNU General Public License |
| 15 | along with this program; if not, write to the Free Software |
| 16 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| 17 | |
| 18 | */ |
| 19 | |
| 20 | #ifndef _RICE_RENDER_H |
| 21 | #define _RICE_RENDER_H |
| 22 | |
| 23 | #include "Blender.h" |
| 24 | #include "Combiner.h" |
| 25 | #include "Config.h" |
| 26 | #include "Debugger.h" |
| 27 | #include "RenderBase.h" |
| 28 | #include "ExtendedRender.h" |
| 29 | #include "RSP_Parser.h" |
| 30 | #include "RSP_S2DEX.h" |
| 31 | |
| 32 | enum TextureChannel |
| 33 | { |
| 34 | TXT_RGB, |
| 35 | TXT_ALPHA, |
| 36 | TXT_RGBA, |
| 37 | }; |
| 38 | |
| 39 | class CRender : public CExtendedRender |
| 40 | { |
| 41 | protected: |
| 42 | CRender(); |
| 43 | |
| 44 | TextureUVFlag TileUFlags[8]; |
| 45 | TextureUVFlag TileVFlags[8]; |
| 46 | |
| 47 | public: |
| 48 | |
| 49 | float m_fScreenViewportMultX; |
| 50 | float m_fScreenViewportMultY; |
| 51 | |
| 52 | |
| 53 | uint32 m_dwTexturePerspective; |
| 54 | BOOL m_bAlphaTestEnable; |
| 55 | |
| 56 | BOOL m_bZUpdate; |
| 57 | BOOL m_bZCompare; |
| 58 | uint32 m_dwZBias; |
| 59 | |
| 60 | TextureFilter m_dwMinFilter; |
| 61 | TextureFilter m_dwMagFilter; |
| 62 | |
| 63 | uint32 m_dwAlpha; |
| 64 | |
| 65 | uint64 m_Mux; |
| 66 | BOOL m_bBlendModeValid; |
| 67 | |
| 68 | CColorCombiner *m_pColorCombiner; |
| 69 | CBlender *m_pAlphaBlender; |
| 70 | |
| 71 | |
| 72 | virtual ~CRender(); |
| 73 | |
| 74 | inline bool IsTexel0Enable() {return m_pColorCombiner->m_bTex0Enabled;} |
| 75 | inline bool IsTexel1Enable() {return m_pColorCombiner->m_bTex1Enabled;} |
| 76 | inline bool IsTextureEnabled() { return (m_pColorCombiner->m_bTex0Enabled||m_pColorCombiner->m_bTex1Enabled); } |
| 77 | |
| 78 | inline RenderTexture& GetCurrentTexture() { return g_textures[gRSP.curTile]; } |
| 79 | inline RenderTexture& GetTexture(uint32 dwTile) { return g_textures[dwTile]; } |
| 80 | void SetViewport(int nLeft, int nTop, int nRight, int nBottom, int maxZ); |
| 81 | virtual void SetViewportRender() {} |
| 82 | virtual void SetClipRatio(uint32 type, uint32 value); |
| 83 | virtual void UpdateScissor() {} |
| 84 | virtual void ApplyRDPScissor(bool force=false) {} |
| 85 | virtual void UpdateClipRectangle(); |
| 86 | virtual void UpdateScissorWithClipRatio(); |
| 87 | virtual void ApplyScissorWithClipRatio(bool force=false) {} |
| 88 | |
| 89 | void SetTextureEnableAndScale(int dwTile, bool enable, float fScaleX, float fScaleY); |
| 90 | |
| 91 | virtual void SetFogEnable(bool bEnable) |
| 92 | { |
| 93 | DEBUGGER_IF_DUMP( (gRSP.bFogEnabled != bEnable && logFog ), TRACE1("Set Fog %s", bEnable? "enable":"disable")); |
| 94 | gRSP.bFogEnabled = bEnable&&(options.fogMethod > 0); |
| 95 | } |
| 96 | virtual void SetFogMinMax(float fMin, float fMax) = 0; |
| 97 | virtual void TurnFogOnOff(bool flag)=0; |
| 98 | bool m_bFogStateSave; |
| 99 | void SetFogFlagForNegativeW(); |
| 100 | void RestoreFogFlag(); |
| 101 | |
| 102 | virtual void SetFogColor(uint32 r, uint32 g, uint32 b, uint32 a) |
| 103 | { |
| 104 | gRDP.fogColor = COLOR_RGBA(r, g, b, a); |
| 105 | } |
| 106 | uint32 GetFogColor() { return gRDP.fogColor; } |
| 107 | |
| 108 | void SetProjection(const Matrix & mat, bool bPush, bool bReplace); |
| 109 | void SetWorldView(const Matrix & mat, bool bPush, bool bReplace); |
| 110 | inline int GetProjectMatrixLevel(void) { return gRSP.projectionMtxTop; } |
| 111 | inline int GetWorldViewMatrixLevel(void) { return gRSP.modelViewMtxTop; } |
| 112 | |
| 113 | inline void PopProjection() |
| 114 | { |
| 115 | if (gRSP.projectionMtxTop > 0) |
| 116 | gRSP.projectionMtxTop--; |
| 117 | else |
| 118 | TRACE0("Popping past projection stack limits"); |
| 119 | } |
| 120 | |
| 121 | void PopWorldView(); |
| 122 | Matrix & GetWorldProjectMatrix(void); |
| 123 | void SetWorldProjectMatrix(Matrix &mtx); |
| 124 | |
| 125 | void ResetMatrices(); |
| 126 | |
| 127 | inline RenderShadeMode GetShadeMode() { return gRSP.shadeMode; } |
| 128 | |
| 129 | void SetVtxTextureCoord(uint32 dwV, float tu, float tv) |
| 130 | { |
| 131 | g_fVtxTxtCoords[dwV].x = tu; |
| 132 | g_fVtxTxtCoords[dwV].y = tv; |
| 133 | } |
| 134 | |
| 135 | virtual void RenderReset(); |
| 136 | virtual void SetCombinerAndBlender(); |
| 137 | virtual void SetMux(uint32 dwMux0, uint32 dwMux1); |
| 138 | virtual void SetCullMode(bool bCullFront, bool bCullBack) { gRSP.bCullFront = bCullFront; gRSP.bCullBack = bCullBack; } |
| 139 | |
| 140 | virtual void BeginRendering(void) {CRender::gRenderReferenceCount++;} // For DirectX only |
| 141 | virtual void EndRendering(void) |
| 142 | { |
| 143 | if( CRender::gRenderReferenceCount > 0 ) |
| 144 | CRender::gRenderReferenceCount--; |
| 145 | } |
| 146 | |
| 147 | virtual void ClearBuffer(bool cbuffer, bool zbuffer)=0; |
| 148 | virtual void ClearZBuffer(float depth)=0; |
| 149 | virtual void ClearBuffer(bool cbuffer, bool zbuffer, COORDRECT &rect) |
| 150 | { |
| 151 | ClearBuffer(cbuffer, zbuffer); |
| 152 | } |
| 153 | virtual void ZBufferEnable(BOOL bZBuffer)=0; |
| 154 | virtual void SetZCompare(BOOL bZCompare)=0; |
| 155 | virtual void SetZUpdate(BOOL bZUpdate)=0; |
| 156 | virtual void SetZBias(int bias)=0; |
| 157 | virtual void SetAlphaTestEnable(BOOL bAlphaTestEnable)=0; |
| 158 | |
| 159 | void SetTextureFilter(uint32 dwFilter); |
| 160 | virtual void ApplyTextureFilter() {} |
| 161 | |
| 162 | virtual void SetShadeMode(RenderShadeMode mode)=0; |
| 163 | |
| 164 | virtual void SetAlphaRef(uint32 dwAlpha)=0; |
| 165 | virtual void ForceAlphaRef(uint32 dwAlpha)=0; |
| 166 | |
| 167 | virtual void InitOtherModes(void); |
| 168 | |
| 169 | void SetVertexTextureUVCoord(TLITVERTEX &v, float fTex0S, float fTex0T, float fTex1S, float fTex1T); |
| 170 | void SetVertexTextureUVCoord(TLITVERTEX &v, float fTex0S, float fTex0T); |
| 171 | virtual COLOR PostProcessDiffuseColor(COLOR curDiffuseColor)=0; |
| 172 | virtual COLOR PostProcessSpecularColor()=0; |
| 173 | |
| 174 | bool DrawTriangles(); |
| 175 | virtual bool RenderFlushTris()=0; |
| 176 | |
| 177 | bool TexRect(int nX0, int nY0, int nX1, int nY1, float fS0, float fT0, float fScaleS, float fScaleT, bool colorFlag=false, uint32 difcolor=0xFFFFFFFF); |
| 178 | bool TexRectFlip(int nX0, int nY0, int nX1, int nY1, float fS0, float fT0, float fS1, float fT1); |
| 179 | bool FillRect(int nX0, int nY0, int nX1, int nY1, uint32 dwColor); |
| 180 | bool Line3D(uint32 dwV0, uint32 dwV1, uint32 dwWidth); |
| 181 | |
| 182 | virtual void SetAddressUAllStages(uint32 dwTile, TextureUVFlag dwFlag); // For DirectX only, fix me |
| 183 | virtual void SetAddressVAllStages(uint32 dwTile, TextureUVFlag dwFlag); // For DirectX only, fix me |
| 184 | virtual void SetTextureUFlag(TextureUVFlag dwFlag, uint32 tile)=0; |
| 185 | virtual void SetTextureVFlag(TextureUVFlag dwFlag, uint32 tile)=0; |
| 186 | virtual void SetTexelRepeatFlags(uint32 dwTile); |
| 187 | virtual void SetAllTexelRepeatFlag(); |
| 188 | |
| 189 | virtual bool SetCurrentTexture(int tile, TxtrCacheEntry *pTextureEntry)=0; |
| 190 | virtual bool SetCurrentTexture(int tile, CTexture *handler, uint32 dwTileWidth, uint32 dwTileHeight, TxtrCacheEntry *pTextureEntry) = 0; |
| 191 | |
| 192 | virtual bool InitDeviceObjects()=0; |
| 193 | virtual bool ClearDeviceObjects()=0; |
| 194 | virtual void Initialize(void); |
| 195 | virtual void CleanUp(void); |
| 196 | |
| 197 | virtual void SetFillMode(FillMode mode)=0; |
| 198 | |
| 199 | #ifdef DEBUGGER |
| 200 | virtual bool DrawTexture(int tex, TextureChannel channel = TXT_RGB ); |
| 201 | virtual void SaveTextureToFile(int tex, TextureChannel channel = TXT_RGB, bool bShow = false); |
| 202 | #endif |
| 203 | |
| 204 | virtual void SaveTextureToFile(CTexture &texture, char *filename, TextureChannel channel = TXT_RGB, bool bShow = false, bool bWholeTexture = true, int width = -1, int height = -1); |
| 205 | |
| 206 | void LoadSprite2D(Sprite2DInfo &info, uint32 ucode); |
| 207 | void LoadObjBGCopy(uObjBg &info); |
| 208 | void LoadObjBG1CYC(uObjScaleBg &info); |
| 209 | void LoadObjSprite(uObjTxSprite &info, bool useTIAddr=false); |
| 210 | |
| 211 | void LoadFrameBuffer(bool useVIreg=false, uint32 left=0, uint32 top=0, uint32 width=0, uint32 height=0); |
| 212 | void LoadTextureFromMemory(void *buf, uint32 left, uint32 top, uint32 width, uint32 height, uint32 pitch, uint32 format); |
| 213 | void LoadTxtrBufIntoTexture(void); |
| 214 | void DrawSprite2D(Sprite2DInfo &info, uint32 ucode); |
| 215 | void DrawSpriteR(uObjTxSprite &sprite, bool initCombiner=true, uint32 tile=0, uint32 left=0, uint32 top=0, uint32 width=0, uint32 height=0); |
| 216 | void DrawSprite(uObjTxSprite &sprite, bool rectR = true); |
| 217 | void DrawObjBGCopy(uObjBg &info); |
| 218 | virtual void DrawSpriteR_Render(){}; |
| 219 | virtual void DrawSimple2DTexture(float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, COLOR dif, COLOR spe, float z, float rhw)=0; |
| 220 | void DrawFrameBuffer(bool useVIreg=false, uint32 left=0, uint32 top=0, uint32 width=0, uint32 height=0); |
| 221 | void DrawObjBG1CYC(uObjScaleBg &bg, bool scaled=true); |
| 222 | |
| 223 | static CRender * g_pRender; |
| 224 | static int gRenderReferenceCount; |
| 225 | static CRender * GetRender(void); |
| 226 | static bool IsAvailable(); |
| 227 | |
| 228 | |
| 229 | protected: |
| 230 | BOOL m_savedZBufferFlag; |
| 231 | uint32 m_savedMinFilter; |
| 232 | uint32 m_savedMagFilter; |
| 233 | |
| 234 | // FillRect |
| 235 | virtual bool RenderFillRect(uint32 dwColor, float depth)=0; |
| 236 | VECTOR2 m_fillRectVtx[2]; |
| 237 | |
| 238 | // Line3D |
| 239 | virtual bool RenderLine3D()=0; |
| 240 | |
| 241 | LITVERTEX m_line3DVtx[2]; |
| 242 | VECTOR2 m_line3DVector[4]; |
| 243 | |
| 244 | // TexRect |
| 245 | virtual bool RenderTexRect()=0; |
| 246 | |
| 247 | TexCord m_texRectTex1UV[2]; |
| 248 | TexCord m_texRectTex2UV[2]; |
| 249 | |
| 250 | // DrawSimple2DTexture |
| 251 | virtual void StartDrawSimple2DTexture(float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, COLOR dif, COLOR spe, float z, float rhw); |
| 252 | |
| 253 | // DrawSimpleRect |
| 254 | virtual void StartDrawSimpleRect(int nX0, int nY0, int nX1, int nY1, uint32 dwColor, float depth, float rhw); |
| 255 | VECTOR2 m_simpleRectVtx[2]; |
| 256 | |
| 257 | bool RemapTextureCoordinate(float s0, float s1, uint32 tileWidth, uint32 mask, float textureWidth, |
| 258 | float &u0, float &u1); |
| 259 | |
| 260 | }; |
| 261 | |
| 262 | #define ffloor(a) (((int(a))<=(a))?(float)(int(a)):((float)(int(a))-1)) |
| 263 | |
| 264 | bool SaveRGBBufferToFile(char *filename, unsigned char *buf, int width, int height, int pitch = -1); |
| 265 | bool SaveRGBABufferToPNGFile(char *filename, unsigned char *buf, int width, int height, int pitch = -1); |
| 266 | |
| 267 | #endif //_RICE_RENDER_H |
| 268 | |