Skip to content

Instantly share code, notes, and snippets.

@Fireboyd78
Created November 7, 2017 08:20
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Fireboyd78/1546f5c86ebce52ce05e7837c697dc72 to your computer and use it in GitHub Desktop.
Save Fireboyd78/1546f5c86ebce52ce05e7837c697dc72 to your computer and use it in GitHub Desktop.
[PS2] 4-bit Texture Unswizzling Code
public static byte[] UnSwizzle4(byte[] buffer, int width, int height, int where)
{
// HUGE THANKS TO:
// L33TMasterJacob for finding the information on unswizzling 4-bit textures
// Dageron for his 4-bit unswizzling code; he's truly a genius!
//
// Source: https://gta.nick7.com/ps2/swizzling/unswizzle_delphi.txt
byte[] InterlaceMatrix = {
0x00, 0x10, 0x02, 0x12,
0x11, 0x01, 0x13, 0x03,
};
int[] Matrix = { 0, 1, -1, 0 };
int[] TileMatrix = { 4, -4 };
var pixels = new byte[width * height];
var newPixels = new byte[width * height];
var d = 0;
var s = where;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < (width >> 1); x++)
{
var p = buffer[s++];
pixels[d++] = (byte)(p & 0xF);
pixels[d++] = (byte)(p >> 4);
}
}
// not sure what this was for, but it actually causes issues
// we can just use width directly without issues!
//var mw = width;
//if ((mw % 32) > 0)
// mw = ((mw / 32) * 32) + 32;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
var oddRow = ((y & 1) != 0);
var num1 = (byte)((y / 4) & 1);
var num2 = (byte)((x / 4) & 1);
var num3 = (y % 4);
var num4 = ((x / 4) % 4);
if (oddRow)
num4 += 4;
var num5 = ((x * 4) % 16);
var num6 = ((x / 16) * 32);
var num7 = (oddRow) ? ((y - 1) * width) : (y * width);
var xx = x + num1 * TileMatrix[num2];
var yy = y + Matrix[num3];
var i = InterlaceMatrix[num4] + num5 + num6 + num7;
var j = yy * width + xx;
newPixels[j] = pixels[i];
}
}
#if UNSWIZZLE_TO_4BIT
var result = new byte[width * height];
s = 0;
d = 0;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < (width >> 1); x++)
result[d++] = (byte)((newPixels[s++] & 0xF) | (newPixels[s++] << 4));
}
return result;
#else
// return an 8-bit texture
return newPixels;
#endif
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment