Original C0 0BB801 F8 074 DA6 GETexture(SettileSize=2, ShiftS=4, ShiftT=4, Type=Detail, Detail=074, Base=DA6) //32x32x4bitI Detail and 32x32x15bitRGB base (Padded to 16bitRGBA in TMEM) Expanded FD 90 00 00 80 7D FF 68 SetTextureImage(16bit I, Width=0, Address=80:7D FF 68) // Are these dynamic? How are they defined? E6 00 00 00 00 00 00 00 loadsync() F3 00 00 00 07 0F F0 00 LoadBlock(uls=0, ult=0, tile=7, lrs=255, dxt=0) // load 255 texels total. Possibly 16x16? // so neither image is 16x16. both are 32x32. // Since loadblock loads as 16bit texels and we know the texture is 4bit, we // multiply 256 * 4 giving 1024. the sqrt then = 32, the correct size. // So, this loadblock loads 512bit of data for detail. E8 00 00 00 00 00 00 00 TileSync() FD 10 00 00 80 7E 01 88 SetTextureImage(16bit RGBA, width=64(or 32 or 63?), Address=80:7E 01 88) // since type is 32x32x16, width=32 F5 10 00 40 05 00 00 00 SetTile(16bit RGBA, line=0, TMEM=64, tile=5, palette=0, clampt=0, mirrort=0, maskt=0, shiftt=1[0], clamps=0, mirrors=0, masks=0, shifts=1[0]) E6 00 00 00 00 00 00 00 loadsync() F3 00 00 00 05 55 70 00 LoadBlock(uls=0, ult=0, tile=5, lrs=1367, dxt=0) //load 1367 texels total, no width known at this time, this includes mip-maps //as above, loadblock is loading a string of 16bits. Tile Widths are determined later. // Knowing the texture is 32x32x16, we can see that 1024+256+64+16+4=1364 texels FA 00 F8 00 FF FF FF FF SetPrimColour(MIN_LEVEL=0.97, PRIM_LOD_FRAC=0, R=255, G=255, B=255, A=255) BA 00 0E 02 00 00 00 00 SetTextureLUT(None) //set up 6 tiles, Detail-Base-+1-+2-+3+4 //Detail F5 80 04 00 00 01 78 5E SetTile(4bit I, line=2, TMEM=0, tile=0, palette=0, clampt=0, mirrort=0, maskt=5, shiftt=4[E], clamps=0, mirrors=0, masks=5, shifts=4) F2 00 20 02 00 07 E0 7E gsDPSetTileSize(uls=2, ult=2, tile=0, lrs=126, lrt=126) //126+2=128 see GridDetailExp.png // Base F5 10 10 40 01 01 40 50 SetTile(16bit rgba, line=8, TMEM=64, tile=1, palette=0, clampt=0, mirrort=0, maskt=5, shiftt=1[0], clamps=0, mirrors=0, masks=5, shifts=1) //Offset TMEM by 64words ((32x32x4)/64 = 64) to avoid overwriting detail tile. F2 00 20 02 01 07 E0 7E gsDPSetTileSize(uls=2, ult=2, tile=1, lrs=126, lrt=126) // basically, U/V of 1 = 128 not 32 since detail is lowest level and each Base texel is filled // 4 times in both S and T with detail (see detail Shift above). // Max UV = 7.9 (since max texels = 1023.96875 [texel co-ords in 10.5 bit format]) // Base+1 F5 10 09 40 02 01 04 41 SetTile(16bit rgba, line=4, TMEM=320, tile=2, palette=0, clampt=0, mirrort=0, maskt=4, shiftt=0.5[1], clamps=0, mirrors=0, masks=4, shifts=0.5[1]) //Offset TMEM by 320words ((32x32x16)/64 = 256 + 64) to avoid overwriting previous tiles. F2 00 20 02 02 03 E0 3E gsDPSetTileSize(uls=2, ult=2, tile=2, lrs=62, lrt=62) // Now each U/V = 64 texels since the texture has 1/2 resolution and covers same area. // Base+2 F5 10 05 80 03 00 C8 32 SetTile(16bit rgba, line=2, TMEM=384, tile=3, palette=0, clampt=0, mirrort=0, maskt=3, shiftt=0.25[2], clamps=0, mirrors=0, masks=3, shifts=0.25[2]) F2 00 20 02 03 01 E0 1E gsDPSetTileSize(uls=2, ult=2, tile=3, lrs=30, lrt=30) // Base+3 F5 10 03 90 04 00 8C 23 SetTile(16bit rgba, line=1, TMEM=400, tile=4, palette=0, clampt=0, mirrort=0, maskt=2, shiftt=0.125[3], clamps=0, mirrors=0, masks=2, shifts=0.125[3]) F2 00 20 02 04 00 E0 0E gsDPSetTileSize(uls=2, ult=2, tile=4, lrs=14, lrt=14) // Base+4 F5 10 03 94 05 00 50 14 SetTile(16bit rgba, line=1, TMEM=404, tile=5, palette=0, clampt=0, mirrort=0, maskt=1, shiftt=0.0625[4], clamps=0, mirrors=0, masks=1, shifts=0.0625[4]) F2 00 20 02 05 00 60 06 gsDPSetTileSize(uls=2, ult=2, tile=5, lrs=6, lrt=6) E7 00 00 00 00 00 00 00 PipeSync() OK, so Grid uses a 4Bit I texture for detail and a 16bit rgba texture, both 32x32. 512+(2048+512+128+32+8) = 3,240 This works because nether texture is CI and all tiles fit within 4096 bytes. So, what we need to do is find out if there are any other detail maps in PD.