mirror of https://github.com/n64decomp/mk64
more documentation on displaylist_packer (#749)
* more documentation on displaylist_packer * add enum --------- Co-authored-by: MegaMech <MegaMech@users.noreply.github.com>
This commit is contained in:
parent
6647a83a29
commit
6839dbe4df
|
|
@ -25,6 +25,47 @@ struct UnkStruct_802B8CD4 D_802B8CD4[] = { 0 };
|
|||
s32 D_802B8CE4 = 0; // pad
|
||||
s32 memoryPadding[2];
|
||||
|
||||
enum PackedOp {
|
||||
PG_LIGHTS_0 = 0x00, /* 0..0x14 mappés sur unpack_lights */
|
||||
/* Presets de combine renommés pour refléter les macros G_CC_* */
|
||||
PG_SETCOMBINE_CC_MODULATERGBA = 0x15,
|
||||
PG_SETCOMBINE_CC_MODULATERGBDECALA = 0x16,
|
||||
PG_SETCOMBINE_CC_SHADE = 0x17,
|
||||
PG_RMODE_OPA = 0x18,
|
||||
PG_RMODE_TEXEDGE = 0x19,
|
||||
PG_TILECFG_A = 0x1A,
|
||||
PG_TILECFG_B = 0x1B,
|
||||
PG_TILECFG_C = 0x1C,
|
||||
PG_TILECFG_D = 0x1D,
|
||||
PG_TILECFG_E = 0x1E,
|
||||
PG_TILECFG_F = 0x1F,
|
||||
PG_TIMG_LOADBLOCK_0 = 0x20,
|
||||
PG_TIMG_LOADBLOCK_1 = 0x21,
|
||||
PG_TIMG_LOADBLOCK_2 = 0x22,
|
||||
PG_TIMG_LOADBLOCK_3 = 0x23,
|
||||
PG_TIMG_LOADBLOCK_4 = 0x24,
|
||||
PG_TIMG_LOADBLOCK_5 = 0x25,
|
||||
PG_TEXTURE_ON = 0x26,
|
||||
PG_TEXTURE_OFF = 0x27,
|
||||
PG_VTX1 = 0x28,
|
||||
PG_TRI1 = 0x29,
|
||||
PG_ENDDL = 0x2A,
|
||||
PG_DL = 0x2B,
|
||||
PG_TILECFG_G = 0x2C,
|
||||
PG_CULLDL = 0x2D,
|
||||
PG_SETCOMBINE_ALT = 0x2E,
|
||||
PG_RMODE_XLU = 0x2F,
|
||||
PG_SPLINE3D = 0x30,
|
||||
PG_VTX_BASE = 0x32, /* 0x33..0x52 → variant vtx2 */
|
||||
PG_SETCOMBINE_CC_DECALRGBA = 0x53,
|
||||
PG_RMODE_OPA_DECAL = 0x54,
|
||||
PG_RMODE_XLU_DECAL = 0x55,
|
||||
PG_SETGEOMETRYMODE = 0x56,
|
||||
PG_CLEARGEOMETRYMODE = 0x57,
|
||||
PG_TRI2 = 0x58,
|
||||
PG_EOF = 0xFF,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Returns the address of the next available memory location and updates the memory pointer
|
||||
* to reference the next location of available memory based provided size to allocate.
|
||||
|
|
@ -625,38 +666,38 @@ void unpack_tile_sync(Gfx* gfx, u8* args, s8 opcode) {
|
|||
|
||||
tmem = 0;
|
||||
switch (opcode) {
|
||||
case 26:
|
||||
case PG_TILECFG_A:
|
||||
width = 32;
|
||||
height = 32;
|
||||
fmt = 0;
|
||||
break;
|
||||
case 44:
|
||||
case PG_TILECFG_G:
|
||||
width = 32;
|
||||
height = 32;
|
||||
fmt = 0;
|
||||
tmem = 256;
|
||||
break;
|
||||
case 27:
|
||||
case PG_TILECFG_B:
|
||||
width = 64;
|
||||
height = 32;
|
||||
fmt = 0;
|
||||
break;
|
||||
case 28:
|
||||
case PG_TILECFG_C:
|
||||
width = 32;
|
||||
height = 64;
|
||||
fmt = 0;
|
||||
break;
|
||||
case 29:
|
||||
case PG_TILECFG_D:
|
||||
width = 32;
|
||||
height = 32;
|
||||
fmt = 3;
|
||||
break;
|
||||
case 30:
|
||||
case PG_TILECFG_E:
|
||||
width = 64;
|
||||
height = 32;
|
||||
fmt = 3;
|
||||
break;
|
||||
case 31:
|
||||
case PG_TILECFG_F:
|
||||
width = 32;
|
||||
height = 64;
|
||||
fmt = 3;
|
||||
|
|
@ -717,32 +758,32 @@ void unpack_tile_load_sync(Gfx* gfx, u8* args, s8 opcode) {
|
|||
uintptr_t tile;
|
||||
|
||||
switch (opcode) {
|
||||
case 32:
|
||||
case PG_TIMG_LOADBLOCK_0:
|
||||
width = 32;
|
||||
height = 32;
|
||||
fmt = 0;
|
||||
break;
|
||||
case 33:
|
||||
case PG_TIMG_LOADBLOCK_1:
|
||||
width = 64;
|
||||
height = 32;
|
||||
fmt = 0;
|
||||
break;
|
||||
case 34:
|
||||
case PG_TIMG_LOADBLOCK_2:
|
||||
width = 32;
|
||||
height = 64;
|
||||
fmt = 0;
|
||||
break;
|
||||
case 35:
|
||||
case PG_TIMG_LOADBLOCK_3:
|
||||
width = 32;
|
||||
height = 32;
|
||||
fmt = 3;
|
||||
break;
|
||||
case 36:
|
||||
case PG_TIMG_LOADBLOCK_4:
|
||||
width = 64;
|
||||
height = 32;
|
||||
fmt = 3;
|
||||
break;
|
||||
case 37:
|
||||
case PG_TIMG_LOADBLOCK_5:
|
||||
width = 32;
|
||||
height = 64;
|
||||
fmt = 3;
|
||||
|
|
@ -833,7 +874,7 @@ void unpack_vtx2(Gfx* gfx, u8* args, s8 arg2) {
|
|||
temp_v1 = args[sPackedSeekPosition++];
|
||||
temp_v2 = ((args[sPackedSeekPosition++] << 8) | temp_v1) * 0x10;
|
||||
|
||||
temp_t9 = arg2 - 50;
|
||||
temp_t9 = arg2 - PG_VTX_BASE;
|
||||
|
||||
gfx[sGfxSeekPosition].words.w0 = ((uintptr_t) (uint8_t) G_VTX << 24) | ((temp_t9 << 10) + (((temp_t9) * 0x10) - 1));
|
||||
gfx[sGfxSeekPosition].words.w1 = 0x4000000 + temp_v2;
|
||||
|
|
@ -988,265 +1029,265 @@ void displaylist_unpack(uintptr_t* data, uintptr_t finalDisplaylistOffset, u32 a
|
|||
}
|
||||
|
||||
switch (opcode) {
|
||||
case 0x0:
|
||||
case PG_LIGHTS_0 + 0x0:
|
||||
unpack_lights(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x1:
|
||||
case PG_LIGHTS_0 + 0x1:
|
||||
unpack_lights(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x2:
|
||||
case PG_LIGHTS_0 + 0x2:
|
||||
unpack_lights(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x3:
|
||||
case PG_LIGHTS_0 + 0x3:
|
||||
unpack_lights(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x4:
|
||||
case PG_LIGHTS_0 + 0x4:
|
||||
unpack_lights(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x5:
|
||||
case PG_LIGHTS_0 + 0x5:
|
||||
unpack_lights(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x6:
|
||||
case PG_LIGHTS_0 + 0x6:
|
||||
unpack_lights(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x7:
|
||||
case PG_LIGHTS_0 + 0x7:
|
||||
unpack_lights(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x8:
|
||||
case PG_LIGHTS_0 + 0x8:
|
||||
unpack_lights(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x9:
|
||||
case PG_LIGHTS_0 + 0x9:
|
||||
unpack_lights(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0xA:
|
||||
case PG_LIGHTS_0 + 0xA:
|
||||
unpack_lights(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0xB:
|
||||
case PG_LIGHTS_0 + 0xB:
|
||||
unpack_lights(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0xC:
|
||||
case PG_LIGHTS_0 + 0xC:
|
||||
unpack_lights(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0xD:
|
||||
case PG_LIGHTS_0 + 0xD:
|
||||
unpack_lights(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0xE:
|
||||
case PG_LIGHTS_0 + 0xE:
|
||||
unpack_lights(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0xF:
|
||||
case PG_LIGHTS_0 + 0xF:
|
||||
unpack_lights(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x10:
|
||||
case PG_LIGHTS_0 + 0x10:
|
||||
unpack_lights(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x11:
|
||||
case PG_LIGHTS_0 + 0x11:
|
||||
unpack_lights(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x12:
|
||||
case PG_LIGHTS_0 + 0x12:
|
||||
unpack_lights(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x13:
|
||||
case PG_LIGHTS_0 + 0x13:
|
||||
unpack_lights(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x14:
|
||||
case PG_LIGHTS_0 + 0x14:
|
||||
unpack_lights(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x15:
|
||||
case PG_SETCOMBINE_CC_MODULATERGBA:
|
||||
unpack_combine_mode1(gfx, packed_dl, arg2);
|
||||
break;
|
||||
case 0x16:
|
||||
case PG_SETCOMBINE_CC_MODULATERGBDECALA:
|
||||
unpack_combine_mode2(gfx, packed_dl, arg2);
|
||||
break;
|
||||
case 0x17:
|
||||
case PG_SETCOMBINE_CC_SHADE:
|
||||
unpack_combine_mode_shade(gfx, packed_dl, arg2);
|
||||
break;
|
||||
case 0x2E:
|
||||
unpack_combine_mode4(gfx, packed_dl, arg2);
|
||||
break;
|
||||
case 0x53:
|
||||
case PG_SETCOMBINE_CC_DECALRGBA:
|
||||
unpack_combine_mode5(gfx, packed_dl, arg2);
|
||||
break;
|
||||
case 0x18:
|
||||
case PG_RMODE_OPA:
|
||||
unpack_render_mode_opaque(gfx, packed_dl, arg2);
|
||||
break;
|
||||
case 0x19:
|
||||
case PG_RMODE_TEXEDGE:
|
||||
unpack_render_mode_tex_edge(gfx, packed_dl, arg2);
|
||||
break;
|
||||
case 0x2F:
|
||||
case PG_RMODE_XLU:
|
||||
unpack_render_mode_translucent(gfx, packed_dl, arg2);
|
||||
break;
|
||||
case 0x54:
|
||||
case PG_RMODE_OPA_DECAL:
|
||||
unpack_render_mode_opaque_decal(gfx, packed_dl, arg2);
|
||||
break;
|
||||
case 0x55:
|
||||
case PG_RMODE_XLU_DECAL:
|
||||
unpack_render_mode_translucent_decal(gfx, packed_dl, arg2);
|
||||
break;
|
||||
case 0x1A:
|
||||
case PG_TILECFG_A:
|
||||
unpack_tile_sync(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x2C:
|
||||
case PG_TILECFG_G:
|
||||
unpack_tile_sync(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x1B:
|
||||
case PG_TILECFG_B:
|
||||
unpack_tile_sync(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x1C:
|
||||
case PG_TILECFG_C:
|
||||
unpack_tile_sync(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x1D:
|
||||
case PG_TILECFG_D:
|
||||
unpack_tile_sync(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x1E:
|
||||
case PG_TILECFG_E:
|
||||
unpack_tile_sync(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x1F:
|
||||
case PG_TILECFG_F:
|
||||
unpack_tile_sync(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x20:
|
||||
case PG_TIMG_LOADBLOCK_0:
|
||||
unpack_tile_load_sync(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x21:
|
||||
case PG_TIMG_LOADBLOCK_1:
|
||||
unpack_tile_load_sync(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x22:
|
||||
case PG_TIMG_LOADBLOCK_2:
|
||||
unpack_tile_load_sync(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x23:
|
||||
case PG_TIMG_LOADBLOCK_3:
|
||||
unpack_tile_load_sync(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x24:
|
||||
case PG_TIMG_LOADBLOCK_4:
|
||||
unpack_tile_load_sync(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x25:
|
||||
case PG_TIMG_LOADBLOCK_5:
|
||||
unpack_tile_load_sync(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x26:
|
||||
case PG_TEXTURE_ON:
|
||||
unpack_texture_on(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x27:
|
||||
case PG_TEXTURE_OFF:
|
||||
unpack_texture_off(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x28:
|
||||
case PG_VTX1:
|
||||
unpack_vtx1(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x33:
|
||||
case PG_VTX_BASE + 0x01:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x34:
|
||||
case PG_VTX_BASE + 0x02:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x35:
|
||||
case PG_VTX_BASE + 0x03:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x36:
|
||||
case PG_VTX_BASE + 0x04:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x37:
|
||||
case PG_VTX_BASE + 0x05:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x38:
|
||||
case PG_VTX_BASE + 0x06:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x39:
|
||||
case PG_VTX_BASE + 0x07:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x3A:
|
||||
case PG_VTX_BASE + 0x08:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x3B:
|
||||
case PG_VTX_BASE + 0x09:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x3C:
|
||||
case PG_VTX_BASE + 0x0A:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x3D:
|
||||
case PG_VTX_BASE + 0x0B:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x3E:
|
||||
case PG_VTX_BASE + 0x0C:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x3F:
|
||||
case PG_VTX_BASE + 0x0D:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x40:
|
||||
case PG_VTX_BASE + 0x0E:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x41:
|
||||
case PG_VTX_BASE + 0x0F:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x42:
|
||||
case PG_VTX_BASE + 0x10:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x43:
|
||||
case PG_VTX_BASE + 0x11:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x44:
|
||||
case PG_VTX_BASE + 0x12:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x45:
|
||||
case PG_VTX_BASE + 0x13:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x46:
|
||||
case PG_VTX_BASE + 0x14:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x47:
|
||||
case PG_VTX_BASE + 0x15:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x48:
|
||||
case PG_VTX_BASE + 0x16:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x49:
|
||||
case PG_VTX_BASE + 0x17:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x4A:
|
||||
case PG_VTX_BASE + 0x18:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x4B:
|
||||
case PG_VTX_BASE + 0x19:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x4C:
|
||||
case PG_VTX_BASE + 0x1A:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x4D:
|
||||
case PG_VTX_BASE + 0x1B:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x4E:
|
||||
case PG_VTX_BASE + 0x1C:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x4F:
|
||||
case PG_VTX_BASE + 0x1D:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x50:
|
||||
case PG_VTX_BASE + 0x1E:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x51:
|
||||
case PG_VTX_BASE + 0x1F:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x52:
|
||||
case PG_VTX_BASE + 0x20:
|
||||
unpack_vtx2(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x29:
|
||||
case PG_TRI1:
|
||||
unpack_triangle(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x58:
|
||||
case PG_TRI2:
|
||||
unpack_quadrangle(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x30:
|
||||
case PG_SPLINE3D:
|
||||
unpack_spline_3D(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x2D:
|
||||
case PG_CULLDL:
|
||||
unpack_cull_displaylist(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x2A:
|
||||
case PG_ENDDL:
|
||||
unpack_end_displaylist(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x56:
|
||||
case PG_SETGEOMETRYMODE:
|
||||
unpack_set_geometry_mode(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x57:
|
||||
case PG_CLEARGEOMETRYMODE:
|
||||
unpack_clear_geometry_mode(gfx, packed_dl, opcode);
|
||||
break;
|
||||
case 0x2B:
|
||||
case PG_DL:
|
||||
unpack_displaylist(gfx, packed_dl, opcode);
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ n64graphics_SOURCES := n64graphics.c utils.c
|
|||
n64graphics_CFLAGS := -DN64GRAPHICS_STANDALONE
|
||||
|
||||
displaylist_packer_SOURCES := displaylist_packer.c
|
||||
displaylist_packer_CFLAGS := -Wno-unused-result
|
||||
displaylist_packer_CFLAGS := -Wno-unused-result -I ../include -DF3DEX_GBI=1 -D_LANGUAGE_C=1
|
||||
|
||||
mio0_SOURCES := libmio0.c
|
||||
mio0_CFLAGS := -DMIO0_STANDALONE
|
||||
|
|
|
|||
|
|
@ -3,9 +3,60 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../include/PR/gbi.h"
|
||||
|
||||
/* Fallbacks for symbols that may be hidden behind ucode/asm guards in gbi.h */
|
||||
|
||||
#define MAX_STRING_LENGTH 256
|
||||
#define MAX_STRING_OUTPUT 10000
|
||||
|
||||
/* Named constants to replace magic comparisons */
|
||||
/* gSPSetOtherModeL presets (low 16 bits), rewritten using gbi.h flags */
|
||||
/* 0x2078 = AA_EN | Z_CMP | Z_UPD | IM_RD | ALPHA_CVG_SEL */
|
||||
/* Explicit name for readability: Anti-Aliasing + Z Compare/Update + Image Read + Alpha Coverage Select */
|
||||
#define OML_AA_ZCMP_ZUPD_IMRD_ALPHA_CVG_SEL (AA_EN | Z_CMP | Z_UPD | IM_RD | ALPHA_CVG_SEL)
|
||||
/* 0x3078 = AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_X_ALPHA | ALPHA_CVG_SEL */
|
||||
/* Explicit name: same as above, with Coverage x Alpha enabled */
|
||||
#define OML_AA_ZCMP_ZUPD_IMRD_CVG_X_ALPHA_ALPHA_CVG_SEL (AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_X_ALPHA | ALPHA_CVG_SEL)
|
||||
|
||||
/* gSPTexture parameters (low 16 bits) */
|
||||
#define TEX_PARAM_ON 0x0001
|
||||
#define TEX_PARAM_OFF 0xFFFF
|
||||
|
||||
/* gDPSetCombine presets (low 16 bits).
|
||||
* Nommage en fonction des macros GBI G_CC_* utilisées côté runtime (memory.c):
|
||||
* - 0xFFFF → G_CC_MODULATERGBA
|
||||
* - 0xF3F9 → G_CC_MODULATERGBDECALA
|
||||
* - 0x793C → G_CC_SHADE
|
||||
* - 0xFFFD → G_CC_DECALRGBA
|
||||
*/
|
||||
#define COMB_CC_MODULATERGBA 0xFFFF
|
||||
#define COMB_CC_MODULATERGBDECALA 0xF3F9
|
||||
#define COMB_CC_SHADE 0x793C
|
||||
#define COMB_CC_DECALRGBA 0xFFFD
|
||||
/* Variante « ALT » vue dans certains exports (reste une heuristique) */
|
||||
#define COMB_PRESET_ALT1 0xF9FC
|
||||
/* (aliases retirés pour éviter la confusion et favoriser les noms G_CC_ explicites) */
|
||||
|
||||
/* gDPSetTextureImage quirks (kept for context; not used after gbi refactor) */
|
||||
/* #define SETTIMG_P4_EXPECT 0x70 */
|
||||
/* #define LOADBLOCK_CMD_OR 0x300000000ULL */
|
||||
|
||||
/* Segmented base addresses (common segment bases used in MK64) */
|
||||
#define SEG_BASE_4 0x04000000ULL
|
||||
#define SEG_BASE_5 0x05000000ULL
|
||||
|
||||
/* G_LOADBLOCK variants are detected by decoding tile/lrs/dxt */
|
||||
|
||||
/* Tile/size configurations are detected by decoding SETTILE/SETTILESIZE */
|
||||
|
||||
/*
|
||||
* Non standard/special input opcode observed (0xD0):
|
||||
* Note: There is no official PR/gbi.h opcode for 0xD0. Keep this as a
|
||||
* project-specific remap for rare/unknown commands encountered in inputs.
|
||||
*/
|
||||
#define G_OP_D0 0xD0
|
||||
|
||||
// Compile using gcc -o tools/displaylist_packer tools/displaylist_packer.c
|
||||
// Run using ./displaylist_packer input.bin output.bin
|
||||
|
||||
|
|
@ -55,6 +106,80 @@ uint32_t compressB1(uint8_t a, uint8_t b, uint8_t c) {
|
|||
#define ARG2WORD(val) ((val) >> 32)
|
||||
#define OPCODE(val) (uint8_t)((val) >> 56)
|
||||
|
||||
enum packed_op {
|
||||
/* Set combine presets (renommés en fonction des macros G_CC_*) */
|
||||
PG_SETCOMBINE_CC_MODULATERGBA = 0x15, /* ex-PG_SETCOMBINE_PRESET_FFFF */
|
||||
PG_SETCOMBINE_CC_MODULATERGBDECALA = 0x16, /* ex-PG_SETCOMBINE_PRESET_F3F9 */
|
||||
PG_SETCOMBINE_CC_SHADE = 0x17, /* ex-PG_SETCOMBINE_PRESET_793C */
|
||||
|
||||
/* Render modes via gSPSetOtherModeL shortcuts (parité memory.c) */
|
||||
PG_RMODE_OPA = 0x18, /* ex-PG_SETOTHERMODE_L_2078 */
|
||||
PG_RMODE_TEXEDGE = 0x19, /* ex-PG_SETOTHERMODE_L_3078 */
|
||||
|
||||
/* Tile/tile size configurations following RDPTILESYNC+SETTILE+SETTILESIZE */
|
||||
PG_TILECFG_A = 0x1A, /* 0xF51010000007C07C */
|
||||
PG_TILECFG_B = 0x1B, /* 0xF5102000000FC07C */
|
||||
PG_TILECFG_C = 0x1C, /* 0xF51010000007C0FC */
|
||||
PG_TILECFG_D = 0x1D, /* 0xF57010000007C07C */
|
||||
PG_TILECFG_E = 0x1E, /* 0xF5702000000FC07C */
|
||||
PG_TILECFG_F = 0x1F, /* 0xF57010000007C0FC */
|
||||
|
||||
/* Texture loadblock variants after gDPSetTextureImage */
|
||||
PG_TIMG_LOADBLOCK_0 = 0x20, /* 0xF3000000073FF100 */
|
||||
PG_TIMG_LOADBLOCK_1 = 0x21, /* 0xF3000000077FF080 */
|
||||
PG_TIMG_LOADBLOCK_2 = 0x22, /* 0xF3000000077FF100 */
|
||||
PG_TIMG_LOADBLOCK_3 = 0x23, /* 0xF3000003073FF100 */
|
||||
PG_TIMG_LOADBLOCK_4 = 0x24, /* 0xF3000003077FF080 */
|
||||
PG_TIMG_LOADBLOCK_5 = 0x25, /* 0xF3000003077FF100 */
|
||||
|
||||
/* gSPTexture on/off */
|
||||
PG_TEXTURE_OFF = 0x26,
|
||||
PG_TEXTURE_ON = 0x27,
|
||||
|
||||
/* VTX compact op (bank/count encoded) */
|
||||
PG_VTX1 = 0x28,
|
||||
|
||||
/* Display list ops */
|
||||
PG_TRI1 = 0x29,
|
||||
PG_ENDDL = 0x2A,
|
||||
PG_DL = 0x2B,
|
||||
PG_TILECFG_G = 0x2C, /* 0xF51011000007C07C */
|
||||
PG_CULLDL = 0x2D,
|
||||
|
||||
/* Alternate combine preset used in memory.c */
|
||||
PG_SETCOMBINE_ALT = 0x2E,
|
||||
|
||||
/* XLU render mode (not currently emitted) */
|
||||
PG_RMODE_XLU = 0x2F,
|
||||
|
||||
/* Project-specific primitive (spline), not currently emitted here */
|
||||
PG_SPLINE3D = 0x30,
|
||||
|
||||
/* Vertex packet base (computed as base + bank index) */
|
||||
PG_VTX_BASE = 0x32,
|
||||
|
||||
/* Extra combine preset used by memory.c */
|
||||
PG_SETCOMBINE_CC_DECALRGBA = 0x53, /* ex-PG_SETCOMBINE_DECALRGBA */
|
||||
|
||||
/* Render mode decal variants (not currently emitted) */
|
||||
PG_RMODE_OPA_DECAL = 0x54,
|
||||
PG_RMODE_XLU_DECAL = 0x55,
|
||||
|
||||
/* Geometry mode */
|
||||
PG_SETGEOMETRYMODE = 0x56,
|
||||
PG_CLEARGEOMETRYMODE = 0x57,
|
||||
|
||||
/* Triangle pair */
|
||||
PG_TRI2 = 0x58,
|
||||
|
||||
/* Special remap */
|
||||
PG_D0_REMAP = 0xDD,
|
||||
|
||||
/* Fallback/terminators */
|
||||
PG_UNKNOWN = 0xEE,
|
||||
PG_EOF = 0xFF,
|
||||
};
|
||||
|
||||
void pack(FILE *input_file, FILE *output_file) {
|
||||
|
||||
// Initialize the string to an empty string
|
||||
|
|
@ -62,11 +187,8 @@ void pack(FILE *input_file, FILE *output_file) {
|
|||
uint8_t p1;
|
||||
uint8_t p2;
|
||||
uint8_t p3;
|
||||
uint8_t p4;
|
||||
uint32_t p5;
|
||||
uint32_t p6;
|
||||
/* temporary vars */
|
||||
uint16_t p7;
|
||||
uint64_t compare;
|
||||
|
||||
|
||||
// Read every u32 in the input file and concatenate a string based on the value
|
||||
|
|
@ -77,21 +199,39 @@ void pack(FILE *input_file, FILE *output_file) {
|
|||
// Warning: Static variable size may result in overflow if input file is too large.
|
||||
// Solution: Increase array size.
|
||||
uint8_t data[50000];
|
||||
int debug = getenv("DLPACKER_DEBUG") != NULL;
|
||||
int lb_bias = 0; /* 0 for RGBA (A/B/C/G), 3 for IA (D/E/F) */
|
||||
while (fread(&cmd, sizeof(uint64_t), 1, input_file) == 1) {
|
||||
cmd = swap_endian(cmd);
|
||||
opCode = OPCODE(cmd);
|
||||
//printf("%X \n", opCode);
|
||||
switch (opCode) {
|
||||
case 0xB9:
|
||||
case (uint8_t)G_SETOTHERMODE_L:
|
||||
p7 = (uint16_t) cmd;
|
||||
if (p7 == 0x2078) {
|
||||
data[count++] = 0x18;
|
||||
} else if (p7 == 0x3078) {
|
||||
data[count++] = 0x19;
|
||||
if (p7 == OML_AA_ZCMP_ZUPD_IMRD_ALPHA_CVG_SEL) {
|
||||
data[count++] = PG_RMODE_OPA;
|
||||
if (debug) fprintf(stderr, "@%u PG_RMODE_OPA\n", count-1);
|
||||
} else if (p7 == OML_AA_ZCMP_ZUPD_IMRD_CVG_X_ALPHA_ALPHA_CVG_SEL) {
|
||||
data[count++] = PG_RMODE_TEXEDGE;
|
||||
if (debug) fprintf(stderr, "@%u PG_RMODE_TEXEDGE\n", count-1);
|
||||
} else if ((p7 & ZMODE_XLU) == ZMODE_XLU) {
|
||||
/* Any render mode with ZMODE_XLU set maps to translucent; refine as DECAL if ALPHA_CVG_SEL is set */
|
||||
if ((p7 & ALPHA_CVG_SEL) == ALPHA_CVG_SEL) {
|
||||
data[count++] = PG_RMODE_XLU_DECAL;
|
||||
if (debug) fprintf(stderr, "@%u PG_RMODE_XLU_DECAL (ZMODE_XLU|ALPHA_CVG_SEL)\n", count-1);
|
||||
} else {
|
||||
data[count++] = PG_RMODE_XLU;
|
||||
if (debug) fprintf(stderr, "@%u PG_RMODE_XLU (ZMODE_XLU)\n", count-1);
|
||||
}
|
||||
} else if ((p7 & ALPHA_CVG_SEL) == ALPHA_CVG_SEL) {
|
||||
/* Opaque decal variant (no ZMODE_XLU, but with ALPHA_CVG_SEL) */
|
||||
data[count++] = PG_RMODE_OPA_DECAL;
|
||||
if (debug) fprintf(stderr, "@%u PG_RMODE_OPA_DECAL (ALPHA_CVG_SEL)\n", count-1);
|
||||
}
|
||||
break;
|
||||
case 0xBF:
|
||||
data[count++] = 0x29;
|
||||
case (uint8_t)G_TRI1:
|
||||
data[count++] = PG_TRI1;
|
||||
if (debug) fprintf(stderr, "@%u PG_TRI1\n", count-1);
|
||||
p1 = (uint8_t) (cmd >> 16) / 2;
|
||||
p2 = (uint8_t) (cmd >> 8) / 2;
|
||||
p3 = (uint8_t) (cmd) / 2;
|
||||
|
|
@ -99,140 +239,291 @@ void pack(FILE *input_file, FILE *output_file) {
|
|||
*(uint16_t*) (data + count) = (uint16_t) (p1 | (p2 << 5) | (p3 << 10));
|
||||
count++; count++;
|
||||
break;
|
||||
case 0x06:
|
||||
data[count++] = 0x2B;
|
||||
case G_DL:
|
||||
data[count++] = PG_DL;
|
||||
if (debug) fprintf(stderr, "@%u PG_DL\n", count-1);
|
||||
*(uint16_t*) (data + count) = (uint16_t)(((uint32_t)cmd) / 8);
|
||||
count++; count++;
|
||||
break;
|
||||
case 0xB1:
|
||||
data[count++] = 0x58;
|
||||
case (uint8_t)G_QUAD: {
|
||||
/* Pack MK64 quad into compact SPLINE3D triplet, mirroring unpack_spline_3D expectations */
|
||||
data[count++] = PG_SPLINE3D;
|
||||
if (debug) fprintf(stderr, "@%u PG_SPLINE3D\n", count-1);
|
||||
uint32_t w1 = (uint32_t)cmd;
|
||||
uint8_t a0 = (uint8_t)(w1 >> 24) / 2;
|
||||
uint8_t t0 = (uint8_t)(w1 >> 16) / 2;
|
||||
uint8_t a3 = (uint8_t)(w1 >> 8) / 2;
|
||||
uint8_t a2 = (uint8_t)(w1) / 2;
|
||||
/* Build three packed bytes (non-mirror path in memory.c):
|
||||
* P0: [a3 bits2:0]<<5 | (t0 & 0x1F)
|
||||
* P1: [a0 bit0]<<7 | (a2 & 0x1F)<<2 | [a3 bits4:3]
|
||||
* P2: (a0 >> 1) & 0x0F
|
||||
*/
|
||||
uint8_t P0 = ((a3 & 0x7) << 5) | (t0 & 0x1F);
|
||||
uint8_t P1 = ((a0 & 0x1) << 7) | ((a2 & 0x1F) << 2) | ((a3 >> 3) & 0x3);
|
||||
uint8_t P2 = (a0 >> 1) & 0x0F;
|
||||
data[count++] = P0;
|
||||
data[count++] = P1;
|
||||
data[count++] = P2;
|
||||
if (debug) fprintf(stderr, " quad a0=%u t0=%u a3=%u a2=%u -> P0=%02X P1=%02X P2=%02X\n", a0, t0, a3, a2, P0, P1, P2);
|
||||
break;
|
||||
}
|
||||
case (uint8_t)G_TRI2:
|
||||
data[count++] = PG_TRI2;
|
||||
if (debug) fprintf(stderr, "@%u PG_TRI2\n", count-1);
|
||||
*(uint16_t*) (data + count) = compressB1(ARG1(cmd), ARG2(cmd), cmd >> 32);
|
||||
count++; count++;
|
||||
*(uint16_t*) (data + count) = compressB1(cmd >> 16, cmd >> 8, cmd);
|
||||
count++; count++;
|
||||
break;
|
||||
case 0x04:
|
||||
case G_VTX:
|
||||
// Skip the opcode and read bytes 2/3 from the u64 (Byte 1 is the opcode 0x04).
|
||||
data[count++] = (uint8_t)(((((uint16_t)ARG1WORD(cmd)) + 1) / 0x410) + 0x32);
|
||||
data[count++] = (uint8_t)(((((uint16_t)ARG1WORD(cmd)) + 1) / 0x410) + PG_VTX_BASE);
|
||||
if (debug) fprintf(stderr, "@%u PG_VTX_%u\n", count-1, data[count-1]-PG_VTX_BASE);
|
||||
// Read the right side of the u64 (as a u32).
|
||||
*(uint16_t*) (data + count) = (uint16_t)(((uint32_t)cmd - 0x04000000) / 16);
|
||||
*(uint16_t*) (data + count) = (uint16_t)(((uint32_t)cmd - (uint32_t)SEG_BASE_4) / 16);
|
||||
count++; count++;
|
||||
break;
|
||||
case 0xFD:
|
||||
p1 = (uint32_t)(cmd - 0x05000000) >> 11;
|
||||
p2 = 0x00;
|
||||
p3 = 0x70;
|
||||
case G_SETTIMG: {
|
||||
/* Texture image parameters (usually segment 0x05) */
|
||||
p1 = (uint32_t)(cmd - SEG_BASE_5) >> 11; /* address >> 11, compacted */
|
||||
p2 = 0x00; /* reserved in the existing packed format */
|
||||
p3 = 0x70; /* expected format/siz on the packed side */
|
||||
|
||||
p4 = (uint8_t)ARG1(cmd);
|
||||
|
||||
|
||||
fseek(input_file, 24, SEEK_CUR);
|
||||
fread(&cmd, sizeof(uint64_t), 1, input_file);
|
||||
cmd = swap_endian(cmd);
|
||||
|
||||
if (p4 == 0x70) {
|
||||
cmd |= 0x300000000;
|
||||
|
||||
/* Look ahead for the corresponding G_LOADBLOCK, consuming SETTILE/LOADSYNC */
|
||||
{
|
||||
uint64_t next;
|
||||
int found = 0;
|
||||
for (int i = 0; i < 12; i++) {
|
||||
if (fread(&next, sizeof(uint64_t), 1, input_file) != 1) {
|
||||
printf("Error: Unexpected EOF scanning after G_SETTIMG\n");
|
||||
break;
|
||||
}
|
||||
next = swap_endian(next);
|
||||
uint8_t nop = OPCODE(next);
|
||||
if (nop == (uint8_t)G_LOADBLOCK) {
|
||||
cmd = next;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
if (nop == (uint8_t)G_SETTILE || nop == (uint8_t)G_RDPLOADSYNC || nop == (uint8_t)G_RDPPIPESYNC) {
|
||||
continue; /* consumed, keep scanning */
|
||||
}
|
||||
/* Unexpected: keep scanning a few opcodes anyway */
|
||||
}
|
||||
if (!found) {
|
||||
printf("Error: Did not find G_LOADBLOCK after G_SETTIMG\n");
|
||||
/* Emit a default value and exit this case */
|
||||
data[count++] = PG_TIMG_LOADBLOCK_0;
|
||||
data[count++] = p1;
|
||||
data[count++] = p2;
|
||||
data[count++] = p3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd == 0xF3000000073FF100) {
|
||||
data[count++] = 0x20;
|
||||
} else if (cmd == 0xF3000000077FF080) {
|
||||
data[count++] = 0x21;
|
||||
} else if (cmd == 0xF3000000077FF100) {
|
||||
data[count++] = 0x22;
|
||||
} else if (cmd == 0xF3000003073FF100) {
|
||||
data[count++] = 0x23;
|
||||
} else if (cmd == 0xF3000003077FF080) {
|
||||
data[count++] = 0x24;
|
||||
} else if (cmd == 0xF3000003077FF100) {
|
||||
data[count++] = 0x25;
|
||||
} else {
|
||||
printf("Error: %s\n", "Unknown FD");
|
||||
/* Classify by (lrs,dxt) then apply a bias from the last TILECFG (RGBA=+0, IA=+3) */
|
||||
{
|
||||
uint32_t lb_w0 = (uint32_t)(cmd >> 32);
|
||||
uint32_t lb_w1 = (uint32_t)(cmd);
|
||||
uint16_t uls = (lb_w0 >> 12) & 0xFFF;
|
||||
uint16_t ult = (lb_w0 >> 0) & 0xFFF;
|
||||
uint8_t tile = (lb_w1 >> 24) & 0x7;
|
||||
uint16_t lrs = (lb_w1 >> 12) & 0xFFF;
|
||||
uint16_t dxt = (lb_w1 >> 0) & 0xFFF;
|
||||
int base = -1;
|
||||
if (tile == G_TX_LOADTILE && uls == 0 && (ult == 0 || ult == 3)) {
|
||||
if (lrs == 0x3FF && dxt == 0x0100) base = 0;
|
||||
else if (lrs == 0x7FF && dxt == 0x0080) base = 1;
|
||||
else if (lrs == 0x7FF && dxt == 0x0100) base = 2;
|
||||
}
|
||||
if (base < 0) {
|
||||
printf("Error: Unrecognized/Unexpected G_LOADBLOCK (tile=%u uls=%u ult=%u lrs=%03X dxt=%03X)\n", tile, uls, ult, lrs, dxt);
|
||||
base = 0;
|
||||
}
|
||||
uint8_t variant = (uint8_t)(PG_TIMG_LOADBLOCK_0 + base + lb_bias);
|
||||
data[count++] = variant;
|
||||
if (debug) fprintf(stderr, "@%u PG_TIMG_LOADBLOCK_%d (base=%d,bias=%d) cmd=%016llX\n", count-1, (int)(variant-PG_TIMG_LOADBLOCK_0), base, lb_bias, (unsigned long long)cmd);
|
||||
}
|
||||
|
||||
data[count++] = p1;
|
||||
data[count++] = p2;
|
||||
data[count++] = p3;
|
||||
break;
|
||||
case 0xE8:
|
||||
|
||||
// Read 0xF5
|
||||
fread(&cmd, sizeof(uint64_t), 1, input_file);
|
||||
}
|
||||
case G_RDPTILESYNC: {
|
||||
/* Read G_SETTILE (0xF5) */
|
||||
if (fread(&cmd, sizeof(uint64_t), 1, input_file) != 1) {
|
||||
printf("Error: Unexpected EOF after G_RDPTILESYNC (SETTILE)\n");
|
||||
break;
|
||||
}
|
||||
cmd = swap_endian(cmd);
|
||||
p5 = ARG1WORD(cmd);
|
||||
|
||||
p1 = (((cmd >> 14) & 0xF) << 4) | ((cmd >> 18) & 0xF);
|
||||
p2 = (((cmd >> 4) & 0xF) << 4) | ((cmd >> 8) & 0xF);
|
||||
|
||||
// Read 0xF2
|
||||
fread(&cmd, sizeof(uint64_t), 1, input_file);
|
||||
cmd = swap_endian(cmd);
|
||||
p6 = (uint32_t)cmd;
|
||||
|
||||
compare = ((uint64_t) p5 << 32 ) | p6;
|
||||
|
||||
switch (compare) {
|
||||
case 0xF51011000007C07C:
|
||||
data[count++] = 0x2C;
|
||||
break;
|
||||
case 0xF51010000007C07C:
|
||||
data[count++] = 0x1A;
|
||||
break;
|
||||
case 0xF5102000000FC07C:
|
||||
data[count++] = 0x1B;
|
||||
break;
|
||||
case 0xF51010000007C0FC:
|
||||
data[count++] = 0x1C;
|
||||
break;
|
||||
case 0xF57010000007C07C:
|
||||
data[count++] = 0x1D;
|
||||
break;
|
||||
case 0xF5702000000FC07C:
|
||||
data[count++] = 0x1E;
|
||||
break;
|
||||
case 0xF57010000007C0FC:
|
||||
data[count++] = 0x1F;
|
||||
break;
|
||||
if ((uint8_t)OPCODE(cmd) != (uint8_t)G_SETTILE) {
|
||||
printf("Error: Expected G_SETTILE after G_RDPTILESYNC, got 0x%02X\n", OPCODE(cmd));
|
||||
break;
|
||||
}
|
||||
|
||||
data[count++] = p2;
|
||||
uint32_t st_w0 = (uint32_t)(cmd >> 32);
|
||||
uint32_t st_w1 = (uint32_t)cmd;
|
||||
uint8_t fmt = (st_w0 >> 21) & 0x7;
|
||||
uint8_t siz = (st_w0 >> 19) & 0x3;
|
||||
uint16_t line = (st_w0 >> 9) & 0x1FF;
|
||||
uint16_t tmem = (st_w0 >> 0) & 0x1FF;
|
||||
uint8_t tile = (st_w1 >> 24) & 0x7;
|
||||
uint8_t pal = (st_w1 >> 20) & 0xF;
|
||||
uint8_t cmt = (st_w1 >> 18) & 0x3;
|
||||
uint8_t maskt = (st_w1 >> 14) & 0xF;
|
||||
uint8_t shiftt= (st_w1 >> 10) & 0xF;
|
||||
uint8_t cms = (st_w1 >> 8) & 0x3;
|
||||
uint8_t masks = (st_w1 >> 4) & 0xF;
|
||||
uint8_t shifts= (st_w1 >> 0) & 0xF;
|
||||
|
||||
/* p1/p2 stay as before (re-encodes 2 nibbles of clamp/mirror flags) */
|
||||
p1 = (((cmd >> 14) & 0xF) << 4) | ((cmd >> 18) & 0xF); /* shiftt|cmt */
|
||||
p2 = (((cmd >> 4) & 0xF) << 4) | ((cmd >> 8) & 0xF); /* masks|cms */
|
||||
|
||||
/* Read G_SETTILESIZE (0xF2), skipping syncs if present */
|
||||
{
|
||||
int found = 0;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (fread(&cmd, sizeof(uint64_t), 1, input_file) != 1) {
|
||||
printf("Error: Unexpected EOF after G_SETTILE (SETTILESIZE)\n");
|
||||
break;
|
||||
}
|
||||
cmd = swap_endian(cmd);
|
||||
uint8_t op2 = OPCODE(cmd);
|
||||
if (op2 == (uint8_t)G_SETTILESIZE) { found = 1; break; }
|
||||
if (op2 == (uint8_t)G_RDPLOADSYNC || op2 == (uint8_t)G_RDPPIPESYNC) {
|
||||
continue;
|
||||
}
|
||||
/* something else: stop */
|
||||
break;
|
||||
}
|
||||
if (!found) {
|
||||
printf("Error: Expected G_SETTILESIZE after G_SETTILE, got 0x%02X\n", OPCODE(cmd));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ss_w0 = (uint32_t)(cmd >> 32);
|
||||
uint32_t ss_w1 = (uint32_t)cmd;
|
||||
uint16_t uls = (ss_w0 >> 12) & 0xFFF;
|
||||
uint16_t ult = (ss_w0 >> 0) & 0xFFF;
|
||||
/* ss_tile not used in the current packed format */
|
||||
uint16_t lrs = (ss_w1 >> 12) & 0xFFF;
|
||||
uint16_t lrt = (ss_w1 >> 0) & 0xFFF;
|
||||
|
||||
/* Classification A..G based on (fmt,siz) and (lrs,lrt), without constraining cmt/cms/masks/line/etc. */
|
||||
if (fmt == G_IM_FMT_RGBA && lrs == 0x07C && lrt == 0x07C) {
|
||||
/* G-variant: legacy hint only (w0 byte[1] == 0x11). Do not rely on p1/p2 mask/shift patterns. */
|
||||
uint8_t w0_b1 = (uint8_t)((st_w0 >> 8) & 0xFF);
|
||||
if (debug) fprintf(stderr, "#TILE RGBA7C7C st_w0=%08X ss_w1=%08X p2=%02X p1=%02X w0_b1=%02X\n", st_w0, ss_w1, p2, p1, w0_b1);
|
||||
if (w0_b1 == 0x11) {
|
||||
data[count++] = PG_TILECFG_G; /* legacy G variant */
|
||||
if (debug) fprintf(stderr, "@%u PG_TILECFG_G p2=%02X p1=%02X\n", count-1, p2, p1);
|
||||
} else {
|
||||
data[count++] = PG_TILECFG_A; /* default RGBA16 tile */
|
||||
if (debug) fprintf(stderr, "@%u PG_TILECFG_A p2=%02X p1=%02X\n", count-1, p2, p1);
|
||||
}
|
||||
lb_bias = 0;
|
||||
} else if (fmt == G_IM_FMT_RGBA && lrs == 0x0FC && lrt == 0x07C) {
|
||||
data[count++] = PG_TILECFG_B; /* F5102000000FC07C */
|
||||
if (debug) fprintf(stderr, "@%u PG_TILECFG_B p2=%02X p1=%02X\n", count-1, p2, p1);
|
||||
lb_bias = 0;
|
||||
} else if (fmt == G_IM_FMT_RGBA && lrs == 0x07C && lrt == 0x0FC) {
|
||||
data[count++] = PG_TILECFG_C; /* F51010000007C0FC */
|
||||
if (debug) fprintf(stderr, "@%u PG_TILECFG_C p2=%02X p1=%02X\n", count-1, p2, p1);
|
||||
lb_bias = 0;
|
||||
} else if (fmt == G_IM_FMT_IA && lrs == 0x07C && lrt == 0x07C) {
|
||||
data[count++] = PG_TILECFG_D; /* F57010000007C07C */
|
||||
if (debug) fprintf(stderr, "@%u PG_TILECFG_D p2=%02X p1=%02X\n", count-1, p2, p1);
|
||||
lb_bias = 3;
|
||||
} else if (fmt == G_IM_FMT_IA && lrs == 0x0FC && lrt == 0x07C) {
|
||||
data[count++] = PG_TILECFG_E; /* F5702000000FC07C */
|
||||
if (debug) fprintf(stderr, "@%u PG_TILECFG_E p2=%02X p1=%02X\n", count-1, p2, p1);
|
||||
lb_bias = 3;
|
||||
} else if (fmt == G_IM_FMT_IA && lrs == 0x07C && lrt == 0x0FC) {
|
||||
data[count++] = PG_TILECFG_F; /* F57010000007C0FC */
|
||||
if (debug) fprintf(stderr, "@%u PG_TILECFG_F p2=%02X p1=%02X\n", count-1, p2, p1);
|
||||
lb_bias = 3;
|
||||
} else {
|
||||
/* Unrecognized: choose A by default (rare) and trace in debug */
|
||||
if (debug) fprintf(stderr, "@%u PG_TILECFG_A (default) fmt=%u siz=%u line=%u tmem=%u tile=%u pal=%u cmt=%u cms=%u uls=%03X ult=%03X lrs=%03X lrt=%03X maskt=%u masks=%u shiftt=%u shifts=%u\n",
|
||||
count, fmt, siz, line, tmem, tile, pal, cmt, cms, uls, ult, lrs, lrt, maskt, masks, shiftt, shifts);
|
||||
data[count++] = PG_TILECFG_A; lb_bias = 0;
|
||||
}
|
||||
|
||||
/* Keep p2/p1 as historically encoded */
|
||||
data[count++] = p2;
|
||||
data[count++] = p1;
|
||||
break;
|
||||
case 0xBB:
|
||||
if ((uint16_t)cmd == 0x0001) {
|
||||
data[count++] = 0x27;
|
||||
} else if ((uint16_t)cmd == 0xFFFF) {
|
||||
data[count++] = 0x26;
|
||||
} else {
|
||||
printf("Error: %s\n", "Unknown BB");
|
||||
}
|
||||
case (uint8_t)G_TEXTURE: {
|
||||
/* Parity with the legacy packer: primary test on t (low16 of w1) */
|
||||
uint16_t t = (uint16_t)cmd;
|
||||
if (t == 0x0001) {
|
||||
data[count++] = PG_TEXTURE_ON;
|
||||
if (debug) fprintf(stderr, "@%u PG_TEXTURE_ON (t==0001)\n", count-1);
|
||||
break;
|
||||
}
|
||||
if (t == 0xFFFF) {
|
||||
data[count++] = PG_TEXTURE_OFF;
|
||||
if (debug) fprintf(stderr, "@%u PG_TEXTURE_OFF (t==FFFF)\n", count-1);
|
||||
break;
|
||||
}
|
||||
/* Fallback: decode the 'on' flag via gbi.h for robustness */
|
||||
uint32_t w0 = (uint32_t)(cmd >> 32);
|
||||
uint8_t on8 = (uint8_t)(w0 & 0xFF);
|
||||
uint8_t on7 = (uint8_t)((w0 >> 1) & 0x7F);
|
||||
data[count++] = ((on8 != 0) || (on7 != 0)) ? PG_TEXTURE_ON : PG_TEXTURE_OFF;
|
||||
if (debug) fprintf(stderr, "@%u PG_TEXTURE_%s (decoded) on8=%u on7=%u\n", count-1, (((on8!=0)||(on7!=0))?"ON":"OFF"), on8, on7);
|
||||
break;
|
||||
case 0xB8:
|
||||
data[count++] = 0x2A;
|
||||
}
|
||||
case (uint8_t)G_ENDDL:
|
||||
data[count++] = PG_ENDDL;
|
||||
if (debug) fprintf(stderr, "@%u PG_ENDDL\n", count-1);
|
||||
break;
|
||||
case 0xBE:
|
||||
data[count++] = 0x2D;
|
||||
case (uint8_t)G_RDPLOADSYNC: /* 0xE6 */
|
||||
case (uint8_t)G_RDPPIPESYNC: /* 0xE7 */
|
||||
/* ignored in the packed stream */
|
||||
break;
|
||||
case 0xD0:
|
||||
data[count++] = 0xDD;
|
||||
case (uint8_t)G_LOADBLOCK: /* Fallback: if encountered outside SETTIMG flow, ignore */
|
||||
break;
|
||||
case 0xFC:
|
||||
case (uint8_t)G_CULLDL:
|
||||
data[count++] = PG_CULLDL;
|
||||
if (debug) fprintf(stderr, "@%u PG_CULLDL\n", count-1);
|
||||
break;
|
||||
case G_OP_D0:
|
||||
data[count++] = PG_D0_REMAP;
|
||||
if (debug) fprintf(stderr, "@%u PG_D0_REMAP\n", count-1);
|
||||
break;
|
||||
case G_SETCOMBINE:
|
||||
p7 = (uint16_t)cmd;
|
||||
if (p7 == 0xF3F9) {
|
||||
data[count++] = 0x16;
|
||||
} else if (p7 == 0xFFFF) {
|
||||
data[count++] = 0x15;
|
||||
} else if (p7 == 0x793C) {
|
||||
data[count++] = 0x17;
|
||||
if (p7 == COMB_CC_MODULATERGBDECALA) {
|
||||
data[count++] = PG_SETCOMBINE_CC_MODULATERGBDECALA; /* was: PRESET_F3F9 */
|
||||
if (debug) fprintf(stderr, "@%u PG_SETCOMBINE_PRESET_F3F9\n", count-1);
|
||||
} else if (p7 == COMB_CC_MODULATERGBA) {
|
||||
data[count++] = PG_SETCOMBINE_CC_MODULATERGBA; /* was: PRESET_FFFF */
|
||||
if (debug) fprintf(stderr, "@%u PG_SETCOMBINE_PRESET_FFFF\n", count-1);
|
||||
} else if (p7 == COMB_CC_SHADE) {
|
||||
data[count++] = PG_SETCOMBINE_CC_SHADE; /* was: PRESET_793C */
|
||||
if (debug) fprintf(stderr, "@%u PG_SETCOMBINE_PRESET_793C\n", count-1);
|
||||
} else if (p7 == COMB_CC_DECALRGBA) {
|
||||
data[count++] = PG_SETCOMBINE_CC_DECALRGBA;
|
||||
if (debug) fprintf(stderr, "@%u PG_SETCOMBINE_DECALRGBA\n", count-1);
|
||||
} else if (p7 == COMB_PRESET_ALT1) {
|
||||
data[count++] = PG_SETCOMBINE_ALT;
|
||||
if (debug) fprintf(stderr, "@%u PG_SETCOMBINE_ALT\n", count-1);
|
||||
}
|
||||
//data[count++] = 0x53;
|
||||
break;
|
||||
case 0xB7:
|
||||
data[count++] = 0x56;
|
||||
case (uint8_t)G_SETGEOMETRYMODE:
|
||||
data[count++] = PG_SETGEOMETRYMODE;
|
||||
if (debug) fprintf(stderr, "@%u PG_SETGEOMETRYMODE\n", count-1);
|
||||
break;
|
||||
case 0xB6:
|
||||
data[count++] = 0x57;
|
||||
case (uint8_t)G_CLEARGEOMETRYMODE:
|
||||
data[count++] = PG_CLEARGEOMETRYMODE;
|
||||
if (debug) fprintf(stderr, "@%u PG_CLEARGEOMETRYMODE\n", count-1);
|
||||
break;
|
||||
//case 0xFF:
|
||||
// data[count++] = 0xFF;
|
||||
|
|
@ -241,14 +532,14 @@ void pack(FILE *input_file, FILE *output_file) {
|
|||
default:
|
||||
printf("Error: Unknown Opcode: 0x%X\n", opCode);
|
||||
printf("Opcode written to file as 0xEE\n");
|
||||
data[count++] = 0xEE;
|
||||
data[count++] = PG_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
offset += 4;
|
||||
}
|
||||
//eos: ;
|
||||
data[count++] = 0xFF;
|
||||
data[count++] = PG_EOF;
|
||||
size_t num_elements_written = fwrite(data, sizeof(uint8_t), count, output_file);
|
||||
if (num_elements_written != count) {
|
||||
printf("Failed to write data to file.\n");
|
||||
|
|
|
|||
Loading…
Reference in New Issue