00001
00003 #include <assert.h>
00004 #include <sps2lib.h>
00005 #include <sps2tags.h>
00006 #include <memory.h>
00007
00008 #include "PS2Utils.h"
00009 #include "TextureManager.h"
00010
00011 #define DEBUG
00012
00025 NablaPS2Utils::TextureManager::TextureManager(const char *FileName, int SPS2Descriptor) {
00026
00027
00028 m_status = false;
00029 m_imageData = NULL;
00030 m_clutData = NULL;
00031
00032
00033 FILE * fp = NULL;
00034 fp = fopen(FileName, "rb");
00035 if (fp) {
00036
00037
00038 TextureFileHeader TFH;
00039 int Read = fread(&TFH, sizeof(TFH), 1, fp);
00040 assert(1 == Read);
00041 UpdateImageData(TFH);
00042
00043
00044
00045 m_SPS2Desc = SPS2Descriptor;
00046 m_numMemBlocks = (TFH.DataSize + 4095) / 4096;
00047 m_imageData = sps2Allocate(4096 * m_numMemBlocks,
00048 SPS2_MAP_BLOCK_4K | SPS2_MAP_UNCACHED, m_SPS2Desc);
00049 fread(m_imageData->pvStart, 1, TFH.DataSize, fp);
00050 #ifdef DEBUG
00051 printf("Image size = %d Bytes, Num of 4096 block = %d\n", TFH.DataSize, m_numMemBlocks);
00052 #endif
00053
00054 if (PSM_PSMT8 == TFH.PixelFormat) {
00055
00056
00057 m_clutData = sps2Allocate(4096,
00058 SPS2_MAP_BLOCK_4K | SPS2_MAP_UNCACHED, m_SPS2Desc);
00059 fread(m_clutData->pvStart, 1, 1024, fp);
00060 }
00061 else if (PSM_PSMT4 == TFH.PixelFormat) {
00062
00063
00064
00065 m_clutData = sps2Allocate(4096,
00066 SPS2_MAP_BLOCK_4K | SPS2_MAP_UNCACHED, m_SPS2Desc);
00067 fread(m_clutData, 1, 64, fp);
00068 }
00069
00070
00071 m_status = true;
00072 }
00073 }
00074
00078 NablaPS2Utils::TextureManager::~TextureManager() {
00079
00080 SPS2_SAFE_FREE(m_imageData);
00081 SPS2_SAFE_FREE(m_clutData);
00082 }
00083
00100 void NablaPS2Utils::TextureManager::SendTexture(
00101 sps2uint32 GSAddress,
00102 sps2Memory_t *DMAMemory) {
00103
00105 m_UploadAddress = GSAddress;
00106
00107
00108
00109
00110
00111 PS2_QWORD *DMAPacket = (PS2_QWORD *) DMAMemory->pvStart;
00112 DMAPacket++->ul128 = PS2_DMA_SET_HEADER(6, 0, DMA_ID_SOURCE_CNT, 0, 0, 0);
00113
00114
00115
00116
00117 sceGifTag *GifTag = (sceGifTag *) DMAPacket;
00118 memset(GifTag, 0, sizeof(sceGifTag));
00119 DMAPacket++->ul64[0] = PS2_GIF_SET_TAG(4,
00120 GS_GIF_EOP_WITHFOLLOWINGPRIM,
00121 GS_GIF_PRE_IGNOREPRIM,
00122 0,
00123 GIF_FLG_PACKED,
00124 1);
00125 GifTag->REGS0 = GIF_REG_A_D;
00126
00127
00128 int BufferWidth = (m_width + 63) / 64;
00129 DMAPacket->ul64[0] = PS2_GIF_SET_BITBLTBUF(0, 0, 0, GSAddress, BufferWidth, m_pixelFormat);
00130 DMAPacket++->ul64[1] = GIF_A_D_REG_BITBLTBUF;
00131 DMAPacket->ul64[0] = PS2_GIF_SET_TRXPOS(0, 0, 0, 0, 0);
00132 DMAPacket++->ul64[1] = GIF_A_D_REG_TRXPOS;
00133 DMAPacket->ul64[0] = PS2_GIF_SET_TRXREG(m_width, m_height);
00134 DMAPacket++->ul64[1] = GIF_A_D_REG_TRXREG;
00135
00136 DMAPacket->ul64[0] = PS2_GIF_SET_TRXDIR(0);
00137 DMAPacket++->ul64[1] = GIF_A_D_REG_TRXDIR;
00138
00139
00140
00141
00142
00143 GifTag = (sceGifTag *) DMAPacket;
00144 memset(GifTag, 0, sizeof(sceGifTag));
00145 DMAPacket++->ul64[0] = PS2_GIF_SET_TAG(m_imageSize >> 4,
00146 GS_GIF_EOP_WITHFOLLOWINGPRIM,
00147 GS_GIF_PRE_IGNOREPRIM,
00148 0,
00149 GIF_FLG_IMAGE,
00150 0);
00151
00152 sps2uint32 PhyAddress;
00153 for (int pageNum = 0; pageNum < m_numMemBlocks - 1; ++pageNum) {
00154
00155 PhyAddress = sps2GetPhysicalAddress(
00156 (char *) m_imageData->pvStart + 4096 * pageNum, m_imageData);
00157 DMAPacket++->ul128 = PS2_DMA_SET_HEADER(
00158 256, 0, DMA_ID_SOURCE_REF, 0, PhyAddress, 0);
00159 }
00160
00161 int lastPageSize = (m_imageSize & 0x0FFF) >> 4;
00162 if (0 == lastPageSize) lastPageSize = 256;
00163 printf("lastPageSize = %d\n", lastPageSize);
00164 PhyAddress = sps2GetPhysicalAddress(
00165 (char *) m_imageData->pvStart + 4096 * (m_numMemBlocks - 1), m_imageData);
00166 DMAPacket++->ul128 = PS2_DMA_SET_HEADER(
00167 lastPageSize, 0, DMA_ID_SOURCE_REF, 0, PhyAddress, 0);
00168
00169
00170 assert(m_pixelFormat == PSM_PSMCT32 || m_pixelFormat == PSM_PSMCT24);
00171
00172
00173
00174
00175 DMAPacket++->ul128 = PS2_DMA_SET_HEADER(2, 0, DMA_ID_SOURCE_END, 0, 0, 0);
00176 GifTag = (sceGifTag *) DMAPacket;
00177 memset(GifTag, 0, sizeof(sceGifTag));
00178
00179
00180 DMAPacket++->ul64[0] = PS2_GIF_SET_TAG(1,
00181 GS_GIF_EOP_WITHOUTFOLLOWINGPRIM,
00182 GS_GIF_PRE_IGNOREPRIM,
00183 0,
00184 GIF_FLG_PACKED,
00185 1);
00186 GifTag->REGS0 = GIF_REG_A_D;
00187 DMAPacket->ul64[0] = 0;
00188 DMAPacket++->ul64[1] = GIF_A_D_REG_TEXFLUSH;
00189
00190
00191
00192
00193
00194 *EE_D2_QWC = 0;
00195
00196
00197 *EE_D2_TADR = PS2_DMA_SET_TADR(
00198 sps2GetPhysicalAddress(DMAMemory->pvStart, DMAMemory), 0);
00199
00200 *EE_D2_CHCR = PS2_DMA_SET_CHCR(DMA_CHCR_DIR_TOMEMORY,
00201 DMA_CHCR_MOD_CHAIN,
00202 DMA_CHCR_ASP_NOADDRESS,
00203 DMA_CHCR_TTE_NOTRANSFER_DMATAG,
00204 DMA_CHCR_TIE_INTDISABLE,
00205 DMA_CHCR_STR_STARTTRANSFER,
00206 0);
00207
00208 sps2WaitForDMA(2, m_SPS2Desc);
00209 }
00210
00217 sps2uint64 NablaPS2Utils::TextureManager::BuildTEX0(int TextureFunction) const {
00218
00219 sps2GIFRegTEX0_n_t TEX0;
00220 TEX0.s.TBP0 = m_UploadAddress;
00221 TEX0.s.TBW = m_width / 64;
00222 TEX0.s.PSM = m_pixelFormat;
00223 TEX0.s.TW = IntLog2(m_width);
00224 TEX0.s.TH = IntLog2(m_height);
00225 TEX0.s.TCC = GS_TEX0_TCC_RGB;
00226 TEX0.s.TFX = TextureFunction;
00227 TEX0.s.CBP = 0;
00228 TEX0.s.CPSM = 0;
00229 TEX0.s.CSM = 0;
00230 TEX0.s.CSA = 0;
00231 TEX0.s.CLD = 0;
00232 return (sps2uint64) TEX0.i64;
00233 }
00234
00244 sps2uint64 NablaPS2Utils::TextureManager::BuildTEX1(int FilteringMode) const {
00245
00246 sps2GIFRegTEX1_n_t TEX1;
00247 TEX1.s.LCM = 0;
00248 TEX1.s.MXL = 0;
00249 TEX1.s.MMAG = FilteringMode;
00250 TEX1.s.MMIN = FilteringMode;
00251 TEX1.s.MTBA = 0;
00252 TEX1.s.L = 0;
00253 TEX1.s.K = 0;
00254 return TEX1.i64;
00255 }
00259 void NablaPS2Utils::TextureManager::UpdateImageData(const TextureFileHeader &TFH) {
00260
00261 m_height = TFH.Height;
00262 m_width = TFH.Width;
00263 m_pixelFormat = TFH.PixelFormat;
00264 m_swizzled = TFH.Swizzled;
00265 m_imageSize = TFH.DataSize;
00266 #ifdef DEBUG
00267 printf("Loaded Texture image");
00268 printf("Height\t\t = %d \n", m_height);
00269 printf("Width\t\t = %d \n", m_width);
00270 printf("PixelFormat\t = %d \n", m_pixelFormat);
00271 printf("Swizzled\t = %d \n", m_swizzled);
00272 printf("DataSize\t = %d \n", m_imageSize);
00273 #endif
00274 }
00275
00280 int NablaPS2Utils::GetPixelSizeInBytes(PSM_t Format) {
00281
00282 switch (Format) {
00283
00284 case PSM_PSMCT32:
00285 return 4;
00286
00287 case PSM_PSMCT24:
00288 return 3;
00289
00290 case PSM_PSMCT16:
00291 case PSM_PSMCT16S:
00292 return 2;
00293
00294 case PSM_PSMT8:
00295 case PSM_PSMT8H:
00296 case PSM_PSMT4:
00297 return 1;
00298
00299
00300 default:
00301 return 0;
00302 }
00303 }