Engineer h3x3r Posted March 5 Engineer Share Posted March 5 Hello there! Can somebody please help update my noesis script to support this format? SCE_GS_PSMT8 = 19, // 8-bit indexed, packing 4 pixels per 32-bit. So far I came across 4 formats and this one is something... Don't know how to process it in noesis. Here is 010 Template from Nenkai Spoiler //------------------------------------------------ //--- 010 Editor v10.0.2 Binary Template // // File: PGLUTexSet // Authors: Nenkai#9075 // Version: // Purpose: Texture Set for PS2 PDI Games // Category: Game Sprites // File Mask: // ID Bytes: // History: //------------------------------------------------ BitfieldDisablePadding(); string PrintBufferSize(int64 val) { string s; SPrintf(s, "Same as tbp/cbp, gets remapped at runtime - offset: 0x%x (0x%x * 64)", val * 64, val); return s; } typedef enum <byte> { SCE_GS_NEAREST = 0, SCE_GS_LINEAR = 1, SCE_GS_NEAREST_MIPMAP_NEAREST = 2, SCE_GS_NEAREST_MIPMAP_LINEAR = 3, SCE_GS_LINEAR_MIPMAP_NEAREST = 4, SCE_GS_LINEAR_MIPMAP_LINEAR = 5, } SCE_GS_MAG; typedef enum <byte> { SCE_GS_PSMCT32 = 0, // RGBA32, uses 32-bit per pixel. SCE_GS_PSMCT24 = 1, // RGB24, uses 24-bit per pixel with the upper 8 bit unused. SCE_GS_PSMCT16 = 2, // RGBA16 unsigned, pack two pixels in 32-bit in little endian order. SCE_GS_PSMCT16S = 10, // RGBA16 signed, pack two pixels in 32-bit in little endian order. SCE_GS_PSMT8 = 19, // 8-bit indexed, packing 4 pixels per 32-bit. SCE_GS_PSMT4 = 20, // 4-bit indexed, packing 8 pixels per 32-bit. SCE_GS_PSMT8H = 27, // 8-bit indexed, but the upper 24-bit are unused. SCE_GS_PSMT4HL = 36, // 4-bit indexed, but the upper 24-bit are unused. SCE_GS_PSMT4HH = 44, SCE_GS_PSMZ32 = 48, // 32-bit Z buffer SCE_GS_PSMZ24 = 49, // 24-bit Z buffer with the upper 8-bit unused SCE_GS_PSMZ16 = 50, // 16-bit unsigned Z buffer, pack two pixels in 32-bit in little endian order. SCE_GS_PSMZ16S = 58, // 16-bit signed Z buffer, pack two pixels in 32-bit in little endian order. } SCE_GS_PSM; typedef enum <byte> { SCE_GS_REPEAT = 0, SCE_GS_CLAMP = 1, SCE_GS_REGION_CLAMP = 2, SCE_GS_REGION_REPEAT = 3, } SCE_GS_CLAMP_PARAMS; typedef enum <byte> { CSM1, CSM2 } SCE_GS_CSM; typedef struct { struct { int64 TBP0_TextureBasePointer : 14 <format=hex, comment="address / 64 (words aka 4) - this is the block offset to the texture">; int64 TBW_TextureBufferWidth : 6 <format=hex, comment="Texel Unit Width / 64 (words aka 4)">; SCE_GS_PSM PSM_TexturePixelStorageFormat : 6 <comment="Texture pixel storage format">; int64 TW_TextureWidth : 4 <comment="Texture width - Actual size will be 2^w and 2^h">; int64 TH_TextureHeight : 4 <comment="Texture height - Actual size will be 2^w and 2^h">; int64 TCC_TextureColorComponent : 1 <comment="Texture color component, 0 = RGB, 1 = RGBA">; int64 TFX_TextureFunction : 2 <comment="Texture function">; int64 CBP_CLUTBufferBasePointer : 14 <format=hex, comment="Base address of CLUT data (actual address will be cbp x 64)">; SCE_GS_PSM CPSM_ClutPixelStorageFormat : 4 <comment="Format in which CLUT entries are saved">; SCE_GS_CSM CSM_ClutStorageMode : 1 <comment="CLUT storage mode">; int64 CSA_ClutEntryOffset : 5 <comment="CLUT entry offset - CSA = Offset / 16, In CSM2, CSA must be 0">; // 0 = Temporary buffer contents not changed // 1 = Load performed to CSA position of buffer // 2 = Load is performed to CSA position of buffer and CBP is copied to CBP0. (*2) // 3 = Load is performed to CSA position of buffer and CBP is copied to CBP1. (*2) // 4 = If CBP0 != CBP, load is performed and CBP is copied to CBP0. (*2) // 5 = If CBP1 != CBP, load is performed and CBP is copied to CBP1. (*2) int64 CLD_ClutBufferLoadControl : 3 <comment="Check template comment">; } sceGsTex0; struct { int64 LCM_LODCalculationMethod : 1 <comment="0 = (LOD = (log2(1/|Q|)<<L+K), 1 = Fixed value (LOD = K)">; int64 pad01 : 1; int64 MXL_MaximumMIPLevel : 3 <comment="0-6">; SCE_GS_MAG MMAG : 1 <comment="Filter when Texture is Expanded (LOD < 0) - Max LINEAR">; SCE_GS_MAG MMIN : 3 <comment="Filter when Texture is Reduced (LOD >= 0)">; // 0 = Value specified by MIPTBP1 and MIPTBP2 is used // 1 = Base address of TBP1 - TBP3 is automatically set int64 MTBA_unknown : 1 <comment="Base Address specification of Mipmap Texture of Level 1 or more">; int64 pad10 : 9; int64 L : 2 <comment="LOD Parameter Value L">; int64 pad21 : 11; int64 K : 12 <comment="LOD Parameter Value K">; int64 pad44 :20; } sceGsTex1; struct sceGsMiptbp1 { unsigned long TBP1:14; unsigned long TBW1:6; unsigned long TBP2:14; unsigned long TBW2:6; unsigned long TBP3:14; unsigned long TBW3:6; unsigned long pad60:4; } MipTable1; struct sceGsMiptbp2 { unsigned long TBP4:14; unsigned long TBW4:6; unsigned long TBP5:14; unsigned long TBW5:6; unsigned long TBP6:14; unsigned long TBW6:6; unsigned long pad60:4; } MipTable2; struct { SCE_GS_CLAMP_PARAMS WMS_WrapModeS:2 <comment="Wrap Mode in Horizontal (S) Direction">; SCE_GS_CLAMP_PARAMS WMT_VrapModeT:2 <comment="Wrap Mode in Horizontal (T) Direction">; unsigned long MINU:10 <comment="Clamp U Direction - Lower Limit">; unsigned long MAXU:10 <comment="Clamp U Direction - Upper Limit">; unsigned long MINV:10 <comment="Clamp Y Direction - Lower Limit">; unsigned long MAXV:10 <comment="Clamp Y Direction - Upper Limit">; Printf("%dx%d (%s, %s)\n", MAXU+1, MAXV+1, EnumToString(WMS_WrapModeS), EnumToString(WMT_VrapModeT)); unsigned long pad44:20; } sceGsClamp <optimize=false>; } PGLUTexture <optimize=false>; typedef struct { int FileDataOffset <format=hex, fgcolor=cRed>; struct { short BlockOffset <format=hex, comment=PrintBufferSize>; byte BufferWidth <comment="Same as TBW">; SCE_GS_PSM PixelFormat; } Params; short Width; short Height; } TransferInfo <optimize=false, comment="Declares a buffer for textures or palettes to use">; // GS's Users Manual - Page 161 to 170 are useful for understanding blocks and pages typedef struct TextureSet1 { local int BasePos = FTell(); struct { char Magic[4]; int RelocPtr; int unkptr; int FileSize <format=hex>; short BaseTBPOffset <comment="Remapped at runtime, multiplied by 64 for absolute">; short TotalBlockSize <format=hex, comment="Total blocks taken by all textures">; short PGLUTextureCount <fgcolor=cGreen>; short TransferCount <fgcolor=cGreen>; int PGLUTextureMapOffset <format=hex, fgcolor=cRed>; int TransferInfosOffset <format=hex, fgcolor=cRed>; int ClutPatchesOffset <format=hex, fgcolor=cRed, comment="Used for cars">; int clutAnimationOffset <format=hex, fgcolor=cRed>; // TODO - havent seen any texture that uses that yet int unkOffset4 <format=hex, fgcolor=cRed>; } Header <size=0x30 , bgcolor=cPurple>; FSeek(BasePos + Header.PGLUTextureMapOffset); PGLUTexture Textures[Header.PGLUTextureCount]; FSeek(BasePos + Header.TransferInfosOffset); TransferInfo Transfers[Header.TransferCount]; if (Header.ClutPatchesOffset != 0) { FSeek(BasePos + Header.ClutPatchesOffset); struct { int ClutPatchCount; int ClutPatchOffsets[ClutPatchCount] <format=hex>; local int i = 0; for (i = 0; i < ClutPatchCount; i++) { FSeek(BasePos + ClutPatchOffsets); struct { int NumPGLUTexturesToPatch; struct { int CSA_ClutEntryOffset : 5; int CBP_CLUTBufferBasePointer : 14 <format=hex>; SCE_GS_PSM Format : 4; int PGLUTextureIndex : 9; } PGLUTex0TexturePatch[NumPGLUTexturesToPatch] <optimize=false>; } ClutPatch; } } ClutPatches; } }; local int LastTexSetOffset; typedef struct Images { char Magic[4]; int RelocPtr; int TextureCount; int TextureDataOffset; LastTexSetOffset = TextureDataOffset; struct { char Name[0x3C]; int TexSetIndex; local int texSetSize = ReadInt(LastTexSetOffset + 0x0C); local int lastPos = FTell(); FSeek(LastTexSetOffset); TextureSet1 TexSet; LastTexSetOffset += texSetSize; FSeek(lastPos); } TextureName[TextureCount] <optimize=false>; }; // GT3 'imgs' if (ReadInt(0x00) == 0x53474D49) Images imgs; else if (ReadInt(0x00) == 0x31786554) TextureSet1 tex1; And here is my noesis script... Thanks in advance! from inc_noesis import * import noesis import rapi import os def registerNoesisTypes(): handle = noesis.register("Gran Turismo 4 - Texture", ".img") noesis.setHandlerTypeCheck(handle, noepyCheckType) noesis.setHandlerLoadRGBA(handle, noepyLoadRGBA) noesis.logPopup() return 1 def noepyCheckType(data): bs = NoeBitStream(data) if len(data) < 20: return 0 if bs.readUInt() != 0x31786554: return 0 return 1 def noepyLoadRGBA(data, texList): bs = NoeBitStream(data) baseName = rapi.getExtensionlessName(rapi.getLocalFileName(rapi.getInputName())) print(baseName) Magic = bs.readUInt() bs.readBytes(8) FileSize = bs.readUInt() bs.readBytes(2) TotalBlockSize = bs.readUShort() PGLUTextureCount = bs.readUShort() TransferCount = bs.readUShort() PGLUTextureMapOffset = bs.readUInt() TransferInfosOffset = bs.readUInt() ClutPatchesOffset = bs.readUInt() ClutAnimationOffset = bs.readUInt() UnknownOffset = bs.readUInt() bs.readBytes(4) # End of Header # Texture Table for i in range(PGLUTextureCount): bs.readBytes(40) # Transfer Table bs.seek(TransferInfosOffset, NOESEEK_ABS) if TransferCount == 1: TexDataOffset = bs.readUInt() BlockOffset = bs.readUShort() BufferWidth = bs.readUByte() PixelFormat = bs.readUByte() TexWidth = bs.readUShort() TexHeight = bs.readUShort() else: TexDataOffset = bs.readUInt() BlockOffset = bs.readUShort() BufferWidth = bs.readUByte() PixelFormat = bs.readUByte() TexWidth = bs.readUShort() TexHeight = bs.readUShort() PalDataOffset = bs.readUInt() PalBlockOffset = bs.readUShort() PalBufferWidth = bs.readUByte() PalPixelFormat = bs.readUByte() PalTexWidth = bs.readUShort() PalTexHeight = bs.readUShort() if PixelFormat == 20: bs.seek(PalDataOffset, NOESEEK_ABS) Palette = bs.readBytes(64) elif PixelFormat == 19: bs.seek(PalDataOffset, NOESEEK_ABS) Palette = bs.readBytes(1024) if TransferCount == 2: TexSize = PalDataOffset - TexDataOffset else: TexSize = FileSize - TexDataOffset bs.seek(TexDataOffset, NOESEEK_ABS) data = bs.readBytes(TexSize) if PixelFormat == 20: data = rapi.imageDecodeRawPal(data, Palette, TexWidth, TexHeight, 4, "r8 g8 b8 a8") texFmt = noesis.NOESISTEX_RGBA32 elif PixelFormat == 19: data = rapi.imageDecodeRawPal(data, Palette, TexWidth, TexHeight, 8, "r8 g8 b8 a8") # I have no idea how to process texFmt = noesis.NOESISTEX_RGBA32 elif PixelFormat == 0: texFmt = noesis.NOESISTEX_RGBA32 elif PixelFormat == 1: texFmt = noesis.NOESISTEX_RGB24 texList.append(NoeTexture(rapi.getInputName(), TexWidth, TexHeight, data, texFmt)) return 1 gt4img.7z Link to comment Share on other sites More sharing options...
Solution DKDave Posted March 5 Solution Share Posted March 5 1 hour ago, h3x3r said: Hello there! Can somebody please help update my noesis script to support this format? SCE_GS_PSMT8 = 19, // 8-bit indexed, packing 4 pixels per 32-bit. So far I came across 4 formats and this one is something... Don't know how to process it in noesis. Here is 010 Template from Nenkai Reveal hidden contents //------------------------------------------------ //--- 010 Editor v10.0.2 Binary Template // // File: PGLUTexSet // Authors: Nenkai#9075 // Version: // Purpose: Texture Set for PS2 PDI Games // Category: Game Sprites // File Mask: // ID Bytes: // History: //------------------------------------------------ BitfieldDisablePadding(); string PrintBufferSize(int64 val) { string s; SPrintf(s, "Same as tbp/cbp, gets remapped at runtime - offset: 0x%x (0x%x * 64)", val * 64, val); return s; } typedef enum <byte> { SCE_GS_NEAREST = 0, SCE_GS_LINEAR = 1, SCE_GS_NEAREST_MIPMAP_NEAREST = 2, SCE_GS_NEAREST_MIPMAP_LINEAR = 3, SCE_GS_LINEAR_MIPMAP_NEAREST = 4, SCE_GS_LINEAR_MIPMAP_LINEAR = 5, } SCE_GS_MAG; typedef enum <byte> { SCE_GS_PSMCT32 = 0, // RGBA32, uses 32-bit per pixel. SCE_GS_PSMCT24 = 1, // RGB24, uses 24-bit per pixel with the upper 8 bit unused. SCE_GS_PSMCT16 = 2, // RGBA16 unsigned, pack two pixels in 32-bit in little endian order. SCE_GS_PSMCT16S = 10, // RGBA16 signed, pack two pixels in 32-bit in little endian order. SCE_GS_PSMT8 = 19, // 8-bit indexed, packing 4 pixels per 32-bit. SCE_GS_PSMT4 = 20, // 4-bit indexed, packing 8 pixels per 32-bit. SCE_GS_PSMT8H = 27, // 8-bit indexed, but the upper 24-bit are unused. SCE_GS_PSMT4HL = 36, // 4-bit indexed, but the upper 24-bit are unused. SCE_GS_PSMT4HH = 44, SCE_GS_PSMZ32 = 48, // 32-bit Z buffer SCE_GS_PSMZ24 = 49, // 24-bit Z buffer with the upper 8-bit unused SCE_GS_PSMZ16 = 50, // 16-bit unsigned Z buffer, pack two pixels in 32-bit in little endian order. SCE_GS_PSMZ16S = 58, // 16-bit signed Z buffer, pack two pixels in 32-bit in little endian order. } SCE_GS_PSM; typedef enum <byte> { SCE_GS_REPEAT = 0, SCE_GS_CLAMP = 1, SCE_GS_REGION_CLAMP = 2, SCE_GS_REGION_REPEAT = 3, } SCE_GS_CLAMP_PARAMS; typedef enum <byte> { CSM1, CSM2 } SCE_GS_CSM; typedef struct { struct { int64 TBP0_TextureBasePointer : 14 <format=hex, comment="address / 64 (words aka 4) - this is the block offset to the texture">; int64 TBW_TextureBufferWidth : 6 <format=hex, comment="Texel Unit Width / 64 (words aka 4)">; SCE_GS_PSM PSM_TexturePixelStorageFormat : 6 <comment="Texture pixel storage format">; int64 TW_TextureWidth : 4 <comment="Texture width - Actual size will be 2^w and 2^h">; int64 TH_TextureHeight : 4 <comment="Texture height - Actual size will be 2^w and 2^h">; int64 TCC_TextureColorComponent : 1 <comment="Texture color component, 0 = RGB, 1 = RGBA">; int64 TFX_TextureFunction : 2 <comment="Texture function">; int64 CBP_CLUTBufferBasePointer : 14 <format=hex, comment="Base address of CLUT data (actual address will be cbp x 64)">; SCE_GS_PSM CPSM_ClutPixelStorageFormat : 4 <comment="Format in which CLUT entries are saved">; SCE_GS_CSM CSM_ClutStorageMode : 1 <comment="CLUT storage mode">; int64 CSA_ClutEntryOffset : 5 <comment="CLUT entry offset - CSA = Offset / 16, In CSM2, CSA must be 0">; // 0 = Temporary buffer contents not changed // 1 = Load performed to CSA position of buffer // 2 = Load is performed to CSA position of buffer and CBP is copied to CBP0. (*2) // 3 = Load is performed to CSA position of buffer and CBP is copied to CBP1. (*2) // 4 = If CBP0 != CBP, load is performed and CBP is copied to CBP0. (*2) // 5 = If CBP1 != CBP, load is performed and CBP is copied to CBP1. (*2) int64 CLD_ClutBufferLoadControl : 3 <comment="Check template comment">; } sceGsTex0; struct { int64 LCM_LODCalculationMethod : 1 <comment="0 = (LOD = (log2(1/|Q|)<<L+K), 1 = Fixed value (LOD = K)">; int64 pad01 : 1; int64 MXL_MaximumMIPLevel : 3 <comment="0-6">; SCE_GS_MAG MMAG : 1 <comment="Filter when Texture is Expanded (LOD < 0) - Max LINEAR">; SCE_GS_MAG MMIN : 3 <comment="Filter when Texture is Reduced (LOD >= 0)">; // 0 = Value specified by MIPTBP1 and MIPTBP2 is used // 1 = Base address of TBP1 - TBP3 is automatically set int64 MTBA_unknown : 1 <comment="Base Address specification of Mipmap Texture of Level 1 or more">; int64 pad10 : 9; int64 L : 2 <comment="LOD Parameter Value L">; int64 pad21 : 11; int64 K : 12 <comment="LOD Parameter Value K">; int64 pad44 :20; } sceGsTex1; struct sceGsMiptbp1 { unsigned long TBP1:14; unsigned long TBW1:6; unsigned long TBP2:14; unsigned long TBW2:6; unsigned long TBP3:14; unsigned long TBW3:6; unsigned long pad60:4; } MipTable1; struct sceGsMiptbp2 { unsigned long TBP4:14; unsigned long TBW4:6; unsigned long TBP5:14; unsigned long TBW5:6; unsigned long TBP6:14; unsigned long TBW6:6; unsigned long pad60:4; } MipTable2; struct { SCE_GS_CLAMP_PARAMS WMS_WrapModeS:2 <comment="Wrap Mode in Horizontal (S) Direction">; SCE_GS_CLAMP_PARAMS WMT_VrapModeT:2 <comment="Wrap Mode in Horizontal (T) Direction">; unsigned long MINU:10 <comment="Clamp U Direction - Lower Limit">; unsigned long MAXU:10 <comment="Clamp U Direction - Upper Limit">; unsigned long MINV:10 <comment="Clamp Y Direction - Lower Limit">; unsigned long MAXV:10 <comment="Clamp Y Direction - Upper Limit">; Printf("%dx%d (%s, %s)\n", MAXU+1, MAXV+1, EnumToString(WMS_WrapModeS), EnumToString(WMT_VrapModeT)); unsigned long pad44:20; } sceGsClamp <optimize=false>; } PGLUTexture <optimize=false>; typedef struct { int FileDataOffset <format=hex, fgcolor=cRed>; struct { short BlockOffset <format=hex, comment=PrintBufferSize>; byte BufferWidth <comment="Same as TBW">; SCE_GS_PSM PixelFormat; } Params; short Width; short Height; } TransferInfo <optimize=false, comment="Declares a buffer for textures or palettes to use">; // GS's Users Manual - Page 161 to 170 are useful for understanding blocks and pages typedef struct TextureSet1 { local int BasePos = FTell(); struct { char Magic[4]; int RelocPtr; int unkptr; int FileSize <format=hex>; short BaseTBPOffset <comment="Remapped at runtime, multiplied by 64 for absolute">; short TotalBlockSize <format=hex, comment="Total blocks taken by all textures">; short PGLUTextureCount <fgcolor=cGreen>; short TransferCount <fgcolor=cGreen>; int PGLUTextureMapOffset <format=hex, fgcolor=cRed>; int TransferInfosOffset <format=hex, fgcolor=cRed>; int ClutPatchesOffset <format=hex, fgcolor=cRed, comment="Used for cars">; int clutAnimationOffset <format=hex, fgcolor=cRed>; // TODO - havent seen any texture that uses that yet int unkOffset4 <format=hex, fgcolor=cRed>; } Header <size=0x30 , bgcolor=cPurple>; FSeek(BasePos + Header.PGLUTextureMapOffset); PGLUTexture Textures[Header.PGLUTextureCount]; FSeek(BasePos + Header.TransferInfosOffset); TransferInfo Transfers[Header.TransferCount]; if (Header.ClutPatchesOffset != 0) { FSeek(BasePos + Header.ClutPatchesOffset); struct { int ClutPatchCount; int ClutPatchOffsets[ClutPatchCount] <format=hex>; local int i = 0; for (i = 0; i < ClutPatchCount; i++) { FSeek(BasePos + ClutPatchOffsets); struct { int NumPGLUTexturesToPatch; struct { int CSA_ClutEntryOffset : 5; int CBP_CLUTBufferBasePointer : 14 <format=hex>; SCE_GS_PSM Format : 4; int PGLUTextureIndex : 9; } PGLUTex0TexturePatch[NumPGLUTexturesToPatch] <optimize=false>; } ClutPatch; } } ClutPatches; } }; local int LastTexSetOffset; typedef struct Images { char Magic[4]; int RelocPtr; int TextureCount; int TextureDataOffset; LastTexSetOffset = TextureDataOffset; struct { char Name[0x3C]; int TexSetIndex; local int texSetSize = ReadInt(LastTexSetOffset + 0x0C); local int lastPos = FTell(); FSeek(LastTexSetOffset); TextureSet1 TexSet; LastTexSetOffset += texSetSize; FSeek(lastPos); } TextureName[TextureCount] <optimize=false>; }; // GT3 'imgs' if (ReadInt(0x00) == 0x53474D49) Images imgs; else if (ReadInt(0x00) == 0x31786554) TextureSet1 tex1; And here is my noesis script... Thanks in advance! from inc_noesis import * import noesis import rapi import os def registerNoesisTypes(): handle = noesis.register("Gran Turismo 4 - Texture", ".img") noesis.setHandlerTypeCheck(handle, noepyCheckType) noesis.setHandlerLoadRGBA(handle, noepyLoadRGBA) noesis.logPopup() return 1 def noepyCheckType(data): bs = NoeBitStream(data) if len(data) < 20: return 0 if bs.readUInt() != 0x31786554: return 0 return 1 def noepyLoadRGBA(data, texList): bs = NoeBitStream(data) baseName = rapi.getExtensionlessName(rapi.getLocalFileName(rapi.getInputName())) print(baseName) Magic = bs.readUInt() bs.readBytes(8) FileSize = bs.readUInt() bs.readBytes(2) TotalBlockSize = bs.readUShort() PGLUTextureCount = bs.readUShort() TransferCount = bs.readUShort() PGLUTextureMapOffset = bs.readUInt() TransferInfosOffset = bs.readUInt() ClutPatchesOffset = bs.readUInt() ClutAnimationOffset = bs.readUInt() UnknownOffset = bs.readUInt() bs.readBytes(4) # End of Header # Texture Table for i in range(PGLUTextureCount): bs.readBytes(40) # Transfer Table bs.seek(TransferInfosOffset, NOESEEK_ABS) if TransferCount == 1: TexDataOffset = bs.readUInt() BlockOffset = bs.readUShort() BufferWidth = bs.readUByte() PixelFormat = bs.readUByte() TexWidth = bs.readUShort() TexHeight = bs.readUShort() else: TexDataOffset = bs.readUInt() BlockOffset = bs.readUShort() BufferWidth = bs.readUByte() PixelFormat = bs.readUByte() TexWidth = bs.readUShort() TexHeight = bs.readUShort() PalDataOffset = bs.readUInt() PalBlockOffset = bs.readUShort() PalBufferWidth = bs.readUByte() PalPixelFormat = bs.readUByte() PalTexWidth = bs.readUShort() PalTexHeight = bs.readUShort() if PixelFormat == 20: bs.seek(PalDataOffset, NOESEEK_ABS) Palette = bs.readBytes(64) elif PixelFormat == 19: bs.seek(PalDataOffset, NOESEEK_ABS) Palette = bs.readBytes(1024) if TransferCount == 2: TexSize = PalDataOffset - TexDataOffset else: TexSize = FileSize - TexDataOffset bs.seek(TexDataOffset, NOESEEK_ABS) data = bs.readBytes(TexSize) if PixelFormat == 20: data = rapi.imageDecodeRawPal(data, Palette, TexWidth, TexHeight, 4, "r8 g8 b8 a8") texFmt = noesis.NOESISTEX_RGBA32 elif PixelFormat == 19: data = rapi.imageDecodeRawPal(data, Palette, TexWidth, TexHeight, 8, "r8 g8 b8 a8") # I have no idea how to process texFmt = noesis.NOESISTEX_RGBA32 elif PixelFormat == 0: texFmt = noesis.NOESISTEX_RGBA32 elif PixelFormat == 1: texFmt = noesis.NOESISTEX_RGB24 texList.append(NoeTexture(rapi.getInputName(), TexWidth, TexHeight, data, texFmt)) return 1 gt4img.7z 51.28 kB · 2 downloads If you change your line in the script to: data = rapi.imageDecodeRawPal(data, Palette, TexWidth, TexHeight, 8, "r8 g8 b8 a8", noesis.DECODEFLAG_PS2SHIFT) Seems to look correct with that flag enabled. 1 1 Link to comment Share on other sites More sharing options...
Engineer h3x3r Posted March 5 Author Engineer Share Posted March 5 Woaw thank you so much DKDave! Link to comment Share on other sites More sharing options...
Engineer h3x3r Posted March 25 Author Engineer Share Posted March 25 Well seems like i can't get over these. It looks like they are stored as blocks. I noticed that file 0x0005da40.img is constructed from 2 images leads to single one. Also can't believe it that file 0x0002cb40.img store over 70+ textures. But maybe yes since they are all low res. Use template to show more info. If anyone know a way please post a solution. Noesis script would be perfect but anything else also. Thanks in advance! gt4_tex.7z Link to comment Share on other sites More sharing options...
Engineer Nenkai Posted April 19 Engineer Share Posted April 19 (edited) Late answer, but I have already gone through PS2 textures myself. They're an extreme pain (multiple ps2 transfers for many textures all arranged for size optimizations, & more). It's not perfect, but code is here. https://github.com/Nenkai/PDTools/tree/master/PDTools.Files/Textures Edited April 19 by Nenkai Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now