Fix texture matrices
scurest opened this issue · 2 comments
scurest commented
Fix texture matrices
scurest commented
The sun and some gates in the Agrabah gates from Days are wrong.
The UVs are wrong. The sun material should have a texture matrix. DS sends
[GXS:88000000] 0x10, 0x00000003
[GXS:88000000] 0x16, 0x00002000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00002000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFF00000, 0x00000000, 0x00001000,
scurest commented
Notes:
Hex dump
al_02c
material sun
0x17C4 +0x00 00 00 dummy
0x17C6 +0x02 3C 00 size
0x17C8 +0x04 FF FF FF 7F dif amb
0x17CC +0x08 9C 73 00 00 spe emi
0x17D0 +0x0C 80 00 1F 00 polygon attr
0x17D4 +0x10 FF F8 1F 3F polygon attr mask
0x17D8 +0x14 00 00 0F 40 teximage param
0x17DC +0x18 FF FF FF FF ?
0x17E0 +0x1C 00 00 palette base
0x17E2 +0x1E C5 1F flags
0x17E4 +0x20 10 00 texture width(?)
0x17E6 +0x22 10 00 texture height(?)
0x17E8 +0x24 00 10 00 00 ?
0x17EC +0x28 00 10 00 00 ?
0x17F0 +0x2C 00 20 00 00 ?
0x17F4 +0x30 00 20 00 00 ?
0x17F8 +0x34 00 FC FF FF ?
0x17FC +0x38 00 FC FF FF ?
Some GHIDRA decompilation, taken from a memory dump while in Agrabah Gates
// Function that gets called when running command 0x4 (Material Setup)
void FUN_01ffbbf0(int *param_1,int param_2,undefined4 param_3,undefined4 param_4)
{
undefined2 *puVar1;
byte bVar2;
ushort uVar3;
uint uVar4;
uint *puVar5;
uint uVar6;
int *piVar7;
int iVar8;
int iVar9;
int iVar10;
uint uVar11;
int iVar12;
uint *puVar13;
int iVar14;
bool bVar15;
uint local_34;
uint local_30;
uint local_2c;
undefined *local_28;
uint local_24;
uint local_20;
undefined4 uStack28;
uVar6 = param_1[2];
if ((uVar6 & 0x200) != 0) goto LAB_01ffc0a0;
bVar2 = *(byte *)(*param_1 + 1);
uVar11 = (uint)bVar2;
if ((((uVar6 & 1) == 0) && ((uVar6 & 8) != 0)) && (uVar11 == *(byte *)((int)param_1 + 0xad)))
goto LAB_01ffc0a0;
iVar12 = param_1[0x36];
if (iVar12 == 0) {
LAB_01ffbc78:
iVar12 = 0;
}
else {
iVar9 = iVar12 + 4;
if ((iVar9 == 0) || (*(byte *)(iVar12 + 5) <= uVar11)) {
piVar7 = (int *)0x0;
}
else {
piVar7 = (int *)(*(ushort *)(iVar9 + (uint)*(ushort *)(iVar12 + 10)) * uVar11 +
iVar9 + (uint)*(ushort *)(iVar12 + 10) + 4);
}
if (piVar7 == (int *)0x0) goto LAB_01ffbc78;
iVar12 = iVar12 + *piVar7;
}
*(byte *)((int)param_1 + 0xad) = bVar2;
param_1[2] = param_1[2] | 8;
iVar8 = param_1[1];
iVar9 = *(int *)(iVar8 + 0x38);
uStack28 = param_4;
if ((iVar9 == 0) || ((param_1[2] & 0x80U) != 0)) {
if ((param_2 == 0x20 || param_2 == 0x40) &&
((param_1[(bVar2 >> 5) + 0x2f] & 1 << (uVar11 & 0x1f)) != 0)) {
if (iVar9 == 0) {
puVar13 = (uint *)(PTR_DAT_01ffc0b4 + uVar11 * 0x38);
}
else {
puVar13 = (uint *)(uVar11 * 0x38 + iVar9);
}
}
else {
if (iVar9 == 0) {
if (param_2 == 0x40) {
puVar13 = (uint *)(PTR_DAT_01ffc0b4 + uVar11 * 0x38);
param_1[(bVar2 >> 5) + 0x2f] = param_1[(bVar2 >> 5) + 0x2f] | 1 << (uVar11 & 0x1f);
}
else {
puVar13 = (uint *)(param_1 + 0x3d);
}
}
else {
param_1[(bVar2 >> 5) + 0x2f] = param_1[(bVar2 >> 5) + 0x2f] | 1 << (uVar11 & 0x1f);
puVar13 = (uint *)(uVar11 * 0x38 + *(int *)(iVar8 + 0x38));
}
*puVar13 = 0;
iVar9 = _FUN_01ffc0b8;
iVar14 = param_1[0x36];
if (iVar14 == 0) {
LAB_01ffbdb4:
iVar14 = 0;
}
else {
iVar10 = iVar14 + 4;
if ((iVar10 == 0) || (*(byte *)(iVar14 + 5) <= uVar11)) {
piVar7 = (int *)0x0;
}
else {
piVar7 = (int *)(*(ushort *)(iVar10 + (uint)*(ushort *)(iVar14 + 10)) * uVar11 +
iVar10 + (uint)*(ushort *)(iVar14 + 10) + 4);
}
if (piVar7 == (int *)0x0) goto LAB_01ffbdb4;
iVar14 = iVar14 + *piVar7;
}
if ((*(ushort *)(iVar14 + 0x1e) & 0x20) != 0) {
*puVar13 = *puVar13 | 0x20;
}
///////////
// This loads some GPU commands into a buffer?
// iVar12 points to the start of the material (dummy)
01ffbdd0:
iVar14 = iRam01ffc0bc;
uVar6 = *(uint *)(iRam01ffc0bc + ((int)(uint)*(ushort *)(iVar12 + 0x1e) >> 6 & 7U) * 4);
puVar13[1] = *(uint *)(iVar9 + 0x80) & ~uVar6 | *(uint *)(iVar12 + 4) & uVar6;
// *(ushort*)(iVar12 + 0x1e) is flags
// so (flags >> 6)&7 is an index into a table that gives a mask for dif amb
// presumably *(uint *)(iVar9 + 0x80) lets you control the dif amb from outside,
// eg for animation, programmatic control
uVar6 = *(uint *)(iVar14 + ((int)(uint)*(ushort *)(iVar12 + 0x1e) >> 9 & 7U) * 4);
puVar13[2] = *(uint *)(iVar9 + 0x84) & ~uVar6 | *(uint *)(iVar12 + 8) & uVar6;
// same thing for spe emi, (flags >> 9)&7 is the mask index (note: same table)
uVar6 = *(uint *)(iVar9 + 0x88) & ~*(uint *)(iVar12 + 0x10);
puVar13[3] = uVar6 | *(uint *)(iVar12 + 0xc) & *(uint *)(iVar12 + 0x10);
// polygon attr and mask
puVar13[4] = *(uint *)(iVar12 + 0x14);
// teximage param
puVar13[5] = (uint)*(ushort *)(iVar12 + 0x1c);
// palette base
////////////
if ((*(ushort *)(iVar12 + 0x1e) & 1) != 0) { // if (flags & 1) NOTE: this is true for sun
bVar15 = (*(ushort *)(iVar12 + 0x1e) & 2) != 0;
if (bVar15) { // if (flags & 2) NOTE: false for sun
uVar6 = *puVar13;
}
puVar5 = (uint *)(iVar12 + 0x2c);
if (bVar15) {
*puVar13 = uVar6 | 1;
}
else {
puVar13[6] = *puVar5;
puVar5 = (uint *)(iVar12 + 0x34);
puVar13[7] = *(uint *)(iVar12 + 0x30);
}
// if (flags & 2) then puVar13[0] |= 1
// else puVar13[6] = next u32() (starting at *(iVar12 + 0x2c))
// puVar13[7] = next u32()
if ((*(ushort *)(iVar12 + 0x1e) & 4) == 0) {
*(undefined2 *)(puVar13 + 8) = *(undefined2 *)puVar5;
puVar1 = (undefined2 *)((int)puVar5 + 2);
puVar5 = puVar5 + 1;
*(undefined2 *)((int)puVar13 + 0x22) = *puVar1;
}
else {
*puVar13 = *puVar13 | 2;
}
// if (flags & 4) then puVar13[0] |= 2
// else puVar13[8] = next u16() | (next u16() << 16) (?)
if ((*(ushort *)(iVar12 + 0x1e) & 8) == 0) {
puVar13[9] = *puVar5;
puVar13[10] = puVar5[1];
}
else {
*puVar13 = *puVar13 | 4;
}
// if (flags & 8) then puVar13[0] |= 4
// else puVar13[9] = next u32()
// puVar13[10] = next u32()
*puVar13 = *puVar13 | 8;
}
uVar6 = *(uint *)(iVar8 + 8);
if (uVar6 != 0) {
uVar4 = *(uint *)(iVar8 + (uint)(bVar2 >> 5) * 4 + 0x3c) & 1 << (uVar11 & 0x1f);
while (uVar4 != 0) {
if (((uVar11 < *(byte *)(uVar6 + 0x19)) &&
(uVar3 = *(ushort *)(uVar6 + uVar11 * 2 + 0x1a), (uVar3 & 0x300) == 0x100)) &&
(*(code **)(uVar6 + 0xc) != Reset)) {
(**(code **)(uVar6 + 0xc))(puVar13,uVar6,uVar3 & 0xff);
}
uVar6 = *(uint *)(uVar6 + 0x10);
uVar4 = uVar6;
}
}
if ((*puVar13 & 0x18) != 0) {
*(undefined2 *)(puVar13 + 0xb) = *(undefined2 *)(iVar12 + 0x20);
*(undefined2 *)((int)puVar13 + 0x2e) = *(undefined2 *)(iVar12 + 0x22);
puVar13[0xc] = *(uint *)(iVar12 + 0x24);
puVar13[0xd] = *(uint *)(iVar12 + 0x28);
}
}
}
else {
puVar13 = (uint *)(uVar11 * 0x38 + iVar9);
}
param_1[0x2c] = (int)puVar13;
if ((puVar13[3] & 0x1f0000) == 0) {
param_1[2] = param_1[2] | 2;
}
else {
if ((*puVar13 & 0x20) != 0) {
puVar13[3] = puVar13[3] & 0xffe0ffff;
}
uVar6 = param_1[2];
param_1[2] = uVar6 & 0xfffffffd;
if ((uVar6 & 0x100) == 0) {
local_34 = puVar13[1];
if (*(short *)PTR_DAT_01ffc0c0 != 0) {
local_34 = local_34 & 0xffff8000 |
(local_34 & 0x1f) * (uint)*(ushort *)PTR_DAT_01ffc0c8 * 0x800 >> 0x10 |
(uint)(((int)((local_34 >> 5 & 0x1f) * (uint)*(ushort *)(PTR_DAT_01ffc0c8 + 2))
>> 5) << 0x10) >> 0xb |
(uint)(((int)((local_34 >> 10 & 0x1f) * (uint)*(ushort *)(PTR_DAT_01ffc0c8 + 4))
>> 5) << 0x10) >> 6;
}
local_30 = puVar13[2];
local_2c = puVar13[3];
local_28 = PTR_DAT_01ffc0cc;
local_24 = puVar13[4];
local_20 = puVar13[5];
FUN_01ff9f00(PTR_LAB_01ffc0c4,&local_34,6);
if ((*puVar13 & 0x18) != 0) {
(*(code *)param_1[0x3c])(puVar13); // this calls FUN_01ffa5dc
}
}
}
LAB_01ffc0a0:
*param_1 = *param_1 + 2;
return;
}
void FUN_01ffa5dc(uint *param_1,undefined4 param_2,undefined4 param_3,undefined4 param_4)
{
longlong lVar1;
undefined *local_58;
undefined4 local_54;
uint local_50;
uint local_4c;
undefined4 local_48;
undefined4 local_44;
uint local_40;
uint local_3c;
undefined4 local_38;
undefined4 local_34;
undefined4 local_30;
undefined4 local_2c;
undefined4 local_28;
undefined4 local_24;
uint local_20;
uint local_1c;
undefined4 local_18;
undefined4 local_14;
undefined4 local_10;
undefined4 uStack12;
if ((*param_1 & 8) == 0) {
local_58 = DAT_01ffa71c;
}
else {
local_58 = PTR_LAB_01ffa718;
}
// looks like this is setting up the texture matrix on the stack?
local_14 = 0x1000;
local_54 = 3;
local_10 = 2;
local_18 = 0;
local_24 = 0;
local_28 = 0;
local_2c = 0;
local_30 = 0;
local_34 = 0;
local_38 = 0;
local_44 = 0;
local_48 = 0;
uStack12 = param_4;
(**(code **)(PTR_PTR_LAB_01ffa720 + (*param_1 & 7) * 4))(&local_50,param_1);
if (param_1[0xc] != 0x1000) {
lVar1 = (longlong)(int)param_1[0xc] * (longlong)(int)local_50;
local_50 = (uint)lVar1 >> 0xc | (int)((ulonglong)lVar1 >> 0x20) << 0x14;
local_4c = (uint)((longlong)(int)param_1[0xc] * (longlong)(int)local_4c) >> 0xc |
(int)((ulonglong)((longlong)(int)param_1[0xc] * (longlong)(int)local_4c) >> 0x20) <<
0x14;
local_20 = (uint)((longlong)(int)param_1[0xc] * (longlong)(int)local_20) >> 0xc |
(int)((ulonglong)((longlong)(int)param_1[0xc] * (longlong)(int)local_20) >> 0x20) <<
0x14;
}
if (param_1[0xd] != 0x1000) {
lVar1 = (longlong)(int)param_1[0xd] * (longlong)(int)local_40;
local_40 = (uint)lVar1 >> 0xc | (int)((ulonglong)lVar1 >> 0x20) << 0x14;
local_3c = (uint)((longlong)(int)param_1[0xd] * (longlong)(int)local_3c) >> 0xc |
(int)((ulonglong)((longlong)(int)param_1[0xd] * (longlong)(int)local_3c) >> 0x20) <<
0x14;
local_1c = (uint)((longlong)(int)param_1[0xd] * (longlong)(int)local_1c) >> 0xc |
(int)((ulonglong)((longlong)(int)param_1[0xd] * (longlong)(int)local_1c) >> 0x20) <<
0x14;
}
FUN_01ff9f00(local_58,&local_54,0x12);
return;
}