| 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 __TEXTUREHANDLER_H__ |
| 21 | #define __TEXTUREHANDLER_H__ |
| 22 | |
| 23 | #ifndef SAFE_DELETE |
| 24 | #define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } } |
| 25 | #endif |
| 26 | |
| 27 | #ifndef SAFE_CHECK |
| 28 | # define SAFE_CHECK(a) if( (a) == NULL ) {DebugMessage(M64MSG_ERROR, "Creater out of memory"); throw new std::exception();} |
| 29 | #endif |
| 30 | |
| 31 | #include <string.h> |
| 32 | |
| 33 | #include "typedefs.h" |
| 34 | #include "Texture.h" |
| 35 | #define absi(x) ((x)>=0?(x):(-x)) |
| 36 | #define S_FLAG 0 |
| 37 | #define T_FLAG 1 |
| 38 | |
| 39 | class TxtrInfo |
| 40 | { |
| 41 | public: |
| 42 | uint32 WidthToCreate; |
| 43 | uint32 HeightToCreate; |
| 44 | |
| 45 | uint32 Address; |
| 46 | void *pPhysicalAddress; |
| 47 | |
| 48 | uint32 Format; |
| 49 | uint32 Size; |
| 50 | |
| 51 | int LeftToLoad; |
| 52 | int TopToLoad; |
| 53 | uint32 WidthToLoad; |
| 54 | uint32 HeightToLoad; |
| 55 | uint32 Pitch; |
| 56 | |
| 57 | uchar *PalAddress; |
| 58 | uint32 TLutFmt; |
| 59 | uint32 Palette; |
| 60 | |
| 61 | BOOL bSwapped; |
| 62 | |
| 63 | uint32 maskS; |
| 64 | uint32 maskT; |
| 65 | |
| 66 | BOOL clampS; |
| 67 | BOOL clampT; |
| 68 | BOOL mirrorS; |
| 69 | BOOL mirrorT; |
| 70 | |
| 71 | int tileNo; |
| 72 | |
| 73 | inline TxtrInfo& operator = (const TxtrInfo& src) |
| 74 | { |
| 75 | memcpy(this, &src, sizeof( TxtrInfo )); |
| 76 | return *this; |
| 77 | } |
| 78 | |
| 79 | inline TxtrInfo& operator = (const Tile& tile) |
| 80 | { |
| 81 | Format = tile.dwFormat; |
| 82 | Size = tile.dwSize; |
| 83 | Palette = tile.dwPalette; |
| 84 | |
| 85 | maskS = tile.dwMaskS; |
| 86 | maskT = tile.dwMaskT; |
| 87 | mirrorS = tile.bMirrorS; |
| 88 | mirrorT = tile.bMirrorT; |
| 89 | clampS = tile.bClampS; |
| 90 | clampT = tile.bClampT; |
| 91 | |
| 92 | return *this; |
| 93 | } |
| 94 | |
| 95 | inline bool operator == ( const TxtrInfo& sec) |
| 96 | { |
| 97 | return ( |
| 98 | Address == sec.Address && |
| 99 | WidthToLoad == sec.WidthToLoad && |
| 100 | HeightToLoad == sec.HeightToLoad && |
| 101 | WidthToCreate == sec.WidthToCreate && |
| 102 | HeightToCreate == sec.HeightToCreate && |
| 103 | maskS == sec.maskS && |
| 104 | maskT == sec.maskT && |
| 105 | TLutFmt == sec.TLutFmt && |
| 106 | PalAddress == sec.PalAddress && |
| 107 | Palette == sec.Palette && |
| 108 | LeftToLoad == sec.LeftToLoad && |
| 109 | TopToLoad == sec.TopToLoad && |
| 110 | Format == sec.Format && |
| 111 | Size == sec.Size && |
| 112 | Pitch == sec.Pitch && |
| 113 | bSwapped == sec.bSwapped && |
| 114 | mirrorS == sec.mirrorS && |
| 115 | mirrorT == sec.mirrorT && |
| 116 | clampS == sec.clampS && |
| 117 | clampT == sec.clampT |
| 118 | ); |
| 119 | } |
| 120 | |
| 121 | inline bool isEqual(const TxtrInfo& sec) |
| 122 | { |
| 123 | return (*this == sec); |
| 124 | } |
| 125 | |
| 126 | } ; |
| 127 | |
| 128 | |
| 129 | |
| 130 | typedef struct TxtrCacheEntry |
| 131 | { |
| 132 | TxtrCacheEntry(): |
| 133 | pTexture(NULL),pEnhancedTexture(NULL),txtrBufIdx(0) {} |
| 134 | |
| 135 | ~TxtrCacheEntry() |
| 136 | { |
| 137 | SAFE_DELETE(pTexture); |
| 138 | SAFE_DELETE(pEnhancedTexture); |
| 139 | } |
| 140 | |
| 141 | struct TxtrCacheEntry *pNext; // Must be first element! |
| 142 | |
| 143 | struct TxtrCacheEntry *pNextYoungest; |
| 144 | struct TxtrCacheEntry *pLastYoungest; |
| 145 | |
| 146 | TxtrInfo ti; |
| 147 | uint32 dwCRC; |
| 148 | uint32 dwPalCRC; |
| 149 | int maxCI; |
| 150 | |
| 151 | uint32 dwUses; // Total times used (for stats) |
| 152 | uint32 dwTimeLastUsed; // timeGetTime of time of last usage |
| 153 | uint32 FrameLastUsed; // Frame # that this was last used |
| 154 | uint32 FrameLastUpdated; |
| 155 | |
| 156 | CTexture *pTexture; |
| 157 | CTexture *pEnhancedTexture; |
| 158 | |
| 159 | uint32 dwEnhancementFlag; |
| 160 | int txtrBufIdx; |
| 161 | bool bExternalTxtrChecked; |
| 162 | |
| 163 | TxtrCacheEntry *lastEntry; |
| 164 | } TxtrCacheEntry; |
| 165 | |
| 166 | |
| 167 | //***************************************************************************** |
| 168 | // Texture cache implementation |
| 169 | //***************************************************************************** |
| 170 | class CTextureManager |
| 171 | { |
| 172 | protected: |
| 173 | TxtrCacheEntry * CreateNewCacheEntry(uint32 dwAddr, uint32 dwWidth, uint32 dwHeight); |
| 174 | void AddTexture(TxtrCacheEntry *pEntry); |
| 175 | void RemoveTexture(TxtrCacheEntry * pEntry); |
| 176 | void RecycleTexture(TxtrCacheEntry *pEntry); |
| 177 | TxtrCacheEntry * ReviveTexture( uint32 width, uint32 height ); |
| 178 | TxtrCacheEntry * GetTxtrCacheEntry(TxtrInfo * pti); |
| 179 | |
| 180 | void ConvertTexture(TxtrCacheEntry * pEntry, bool fromTMEM); |
| 181 | void ConvertTexture_16(TxtrCacheEntry * pEntry, bool fromTMEM); |
| 182 | |
| 183 | void ClampS32(uint32 *array, uint32 width, uint32 towidth, uint32 arrayWidth, uint32 rows); |
| 184 | void ClampS16(uint16 *array, uint32 width, uint32 towidth, uint32 arrayWidth, uint32 rows); |
| 185 | void ClampT32(uint32 *array, uint32 height, uint32 toheight, uint32 arrayWidth, uint32 cols); |
| 186 | void ClampT16(uint16 *array, uint32 height, uint32 toheight, uint32 arrayWidth, uint32 cols); |
| 187 | |
| 188 | void MirrorS32(uint32 *array, uint32 width, uint32 mask, uint32 towidth, uint32 arrayWidth, uint32 rows); |
| 189 | void MirrorS16(uint16 *array, uint32 width, uint32 mask, uint32 towidth, uint32 arrayWidth, uint32 rows); |
| 190 | void MirrorT32(uint32 *array, uint32 height, uint32 mask, uint32 toheight, uint32 arrayWidth, uint32 cols); |
| 191 | void MirrorT16(uint16 *array, uint32 height, uint32 mask, uint32 toheight, uint32 arrayWidth, uint32 cols); |
| 192 | |
| 193 | void WrapS32(uint32 *array, uint32 width, uint32 mask, uint32 towidth, uint32 arrayWidth, uint32 rows); |
| 194 | void WrapS16(uint16 *array, uint32 width, uint32 mask, uint32 towidth, uint32 arrayWidth, uint32 rows); |
| 195 | void WrapT32(uint32 *array, uint32 height, uint32 mask, uint32 toheight, uint32 arrayWidth, uint32 cols); |
| 196 | void WrapT16(uint16 *array, uint32 height, uint32 mask, uint32 toheight, uint32 arrayWidth, uint32 cols); |
| 197 | |
| 198 | void ExpandTextureS(TxtrCacheEntry * pEntry); |
| 199 | void ExpandTextureT(TxtrCacheEntry * pEntry); |
| 200 | void ExpandTexture(TxtrCacheEntry * pEntry, uint32 sizeOfLoad, uint32 sizeToCreate, uint32 sizeCreated, |
| 201 | int arrayWidth, int flag, int mask, int mirror, int clamp, uint32 otherSize); |
| 202 | |
| 203 | uint32 Hash(uint32 dwValue); |
| 204 | bool TCacheEntryIsLoaded(TxtrCacheEntry *pEntry); |
| 205 | |
| 206 | void updateColorTexture(CTexture *ptexture, uint32 color); |
| 207 | |
| 208 | public: |
| 209 | void Wrap(void *array, uint32 width, uint32 mask, uint32 towidth, uint32 arrayWidth, uint32 rows, int flag, int size ); |
| 210 | void Clamp(void *array, uint32 width, uint32 towidth, uint32 arrayWidth, uint32 rows, int flag, int size ); |
| 211 | void Mirror(void *array, uint32 width, uint32 mask, uint32 towidth, uint32 arrayWidth, uint32 rows, int flag, int size ); |
| 212 | |
| 213 | protected: |
| 214 | TxtrCacheEntry * m_pHead; |
| 215 | TxtrCacheEntry ** m_pCacheTxtrList; |
| 216 | uint32 m_numOfCachedTxtrList; |
| 217 | |
| 218 | TxtrCacheEntry m_blackTextureEntry; |
| 219 | TxtrCacheEntry m_PrimColorTextureEntry; |
| 220 | TxtrCacheEntry m_EnvColorTextureEntry; |
| 221 | TxtrCacheEntry m_LODFracTextureEntry; |
| 222 | TxtrCacheEntry m_PrimLODFracTextureEntry; |
| 223 | TxtrCacheEntry * GetPrimColorTexture(uint32 color); |
| 224 | TxtrCacheEntry * GetEnvColorTexture(uint32 color); |
| 225 | TxtrCacheEntry * GetLODFracTexture(uint8 fac); |
| 226 | TxtrCacheEntry * GetPrimLODFracTexture(uint8 fac); |
| 227 | |
| 228 | void MakeTextureYoungest(TxtrCacheEntry *pEntry); |
| 229 | unsigned int m_currentTextureMemUsage; |
| 230 | TxtrCacheEntry *m_pYoungestTexture; |
| 231 | TxtrCacheEntry *m_pOldestTexture; |
| 232 | |
| 233 | public: |
| 234 | CTextureManager(); |
| 235 | ~CTextureManager(); |
| 236 | |
| 237 | TxtrCacheEntry * GetBlackTexture(void); |
| 238 | TxtrCacheEntry * GetConstantColorTexture(uint32 constant); |
| 239 | TxtrCacheEntry * GetTexture(TxtrInfo * pgti, bool fromTMEM, bool doCRCCheck=true, bool AutoExtendTexture = false); |
| 240 | |
| 241 | void PurgeOldTextures(); |
| 242 | void RecycleAllTextures(); |
| 243 | void RecheckHiresForAllTextures(); |
| 244 | bool CleanUp(); |
| 245 | |
| 246 | #ifdef DEBUGGER |
| 247 | TxtrCacheEntry * GetCachedTexture(uint32 tex); |
| 248 | uint32 GetNumOfCachedTexture(); |
| 249 | #endif |
| 250 | }; |
| 251 | |
| 252 | extern CTextureManager gTextureManager; // The global instance of CTextureManager class |
| 253 | extern void DumpCachedTexture(TxtrCacheEntry &entry); |
| 254 | |
| 255 | #endif |
| 256 | |