141 lines
5 KiB
C#
141 lines
5 KiB
C#
using LibDgf.Txm;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
|
|
namespace LibDgf.Ps2.Gs
|
|
{
|
|
public static class PsmtMixer
|
|
{
|
|
static int[,] PSMCT32_TO_PSMT4_COL02_LOOKUP = new int[16, 8];
|
|
static int[,] PSMCT32_TO_PSMT4_COL13_LOOKUP = new int[16, 8];
|
|
static int[,] PSMCT32_TO_PSMT8_COL02_LOOKUP = new int[16, 4];
|
|
static int[,] PSMCT32_TO_PSMT8_COL13_LOOKUP = new int[16, 4];
|
|
|
|
static PsmtMixer()
|
|
{
|
|
FillLookup(PSMCT32_TO_PSMT4_COL02_LOOKUP, false);
|
|
FillOddLookup(PSMCT32_TO_PSMT4_COL02_LOOKUP, PSMCT32_TO_PSMT4_COL13_LOOKUP);
|
|
FillLookup(PSMCT32_TO_PSMT8_COL02_LOOKUP, false);
|
|
FillOddLookup(PSMCT32_TO_PSMT8_COL02_LOOKUP, PSMCT32_TO_PSMT8_COL13_LOOKUP);
|
|
|
|
//PrintLookup(PSMCT32_TO_PSMT4_COL02_LOOKUP, nameof(PSMCT32_TO_PSMT4_COL02_LOOKUP));
|
|
//PrintLookup(PSMCT32_TO_PSMT4_COL13_LOOKUP, nameof(PSMCT32_TO_PSMT4_COL13_LOOKUP));
|
|
//PrintLookup(PSMCT32_TO_PSMT8_COL02_LOOKUP, nameof(PSMCT32_TO_PSMT8_COL02_LOOKUP));
|
|
//PrintLookup(PSMCT32_TO_PSMT8_COL13_LOOKUP, nameof(PSMCT32_TO_PSMT8_COL13_LOOKUP));
|
|
}
|
|
|
|
static void PrintLookup(int[,] lookup, string name)
|
|
{
|
|
Console.WriteLine(name);
|
|
int rowNum = lookup.GetLength(0);
|
|
int colNum = lookup.GetLength(1);
|
|
for (int row = 0; row < rowNum; ++row)
|
|
{
|
|
for (int col = colNum - 1; col >= 0; --col)
|
|
{
|
|
Console.Write("{0,3} ", lookup[row, col]);
|
|
}
|
|
Console.WriteLine();
|
|
}
|
|
Console.WriteLine();
|
|
}
|
|
|
|
static void FillLookup(int[,] lookup, bool skipNonConsec)
|
|
{
|
|
int numCols = lookup.GetLength(1);
|
|
int num = 0;
|
|
|
|
// Phase 1: consecutive numbers
|
|
// Fill every second column
|
|
// Top half then bottom half
|
|
for (int half = 0; half < 2; ++half)
|
|
{
|
|
for (int col = 0; col < numCols; col += skipNonConsec ? 1 : 2)
|
|
{
|
|
for (int row = 0; row < 8; ++row)
|
|
{
|
|
lookup[half * 8 + row, col] = num++;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Phase 2: wrapped numbers
|
|
if (!skipNonConsec)
|
|
{
|
|
for (int half = 0; half < 2; ++half)
|
|
{
|
|
for (int col = 1; col < numCols; col += 2)
|
|
{
|
|
for (int row = 4; row < 12; ++row)
|
|
{
|
|
lookup[half * 8 + (row % 8), col] = num++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void FillOddLookup(int[,] evenLookup, int[,] oddLookup)
|
|
{
|
|
int numCols = evenLookup.GetLength(1);
|
|
for (int half = 0; half < 2; ++half)
|
|
{
|
|
for (int i = 0; i < 8; ++i)
|
|
{
|
|
for (int j = 0; j < numCols; ++j)
|
|
{
|
|
oddLookup[half * 8 + i, j] = evenLookup[half * 8 + ((i + 4) % 8), j];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static byte[] MixColumn(byte[] column, TxmPixelFormat srcFormat, TxmPixelFormat destFormat, bool isOdd)
|
|
{
|
|
if (srcFormat != TxmPixelFormat.PSMCT32)
|
|
throw new NotSupportedException("Only PSMCT32 supported as source format.");
|
|
switch (destFormat)
|
|
{
|
|
case TxmPixelFormat.PSMT4:
|
|
return MixColumn32To4(column, isOdd);
|
|
case TxmPixelFormat.PSMT8:
|
|
return MixColumn32To8(column, isOdd);
|
|
default:
|
|
throw new NotSupportedException($"{destFormat} not supported as destination format.");
|
|
}
|
|
}
|
|
|
|
static byte[] MixColumn32To4(byte[] column, bool isOdd)
|
|
{
|
|
int[,] lookup = isOdd ? PSMCT32_TO_PSMT4_COL13_LOOKUP : PSMCT32_TO_PSMT4_COL02_LOOKUP;
|
|
int numCol = lookup.GetLength(1);
|
|
byte[] dest = new byte[column.Length];
|
|
byte b = 0;
|
|
for (int i = 0; i < column.Length * 2; ++i)
|
|
{
|
|
if (i % 2 == 0)
|
|
b = column[i / 2];
|
|
else
|
|
b >>= 4;
|
|
|
|
int index = lookup[i / numCol, i % numCol];
|
|
dest[index / 2] |= (byte)((b & 0x0f) << (index % 2 * 4));
|
|
}
|
|
return dest;
|
|
}
|
|
|
|
static byte[] MixColumn32To8(byte[] column, bool isOdd)
|
|
{
|
|
int[,] lookup = isOdd ? PSMCT32_TO_PSMT8_COL13_LOOKUP : PSMCT32_TO_PSMT8_COL02_LOOKUP;
|
|
int numCol = lookup.GetLength(1);
|
|
byte[] dest = new byte[column.Length];
|
|
for (int i = 0; i < column.Length; ++i)
|
|
{
|
|
int index = lookup[i / numCol, i % numCol];
|
|
dest[index] = column[i];
|
|
}
|
|
return dest;
|
|
}
|
|
}
|
|
}
|