The painting texture for Luigi's Mansion in JMC's FIFO on frame 0 is object 373 and 374. Object 373 shows Mario, while Object 374 shows Bowser; a lot of the early objects are rendering either Mario or Bowser (and both are rendered, even though Bowser only shows up in the ending cutscene). This is presumably done by fading BPMEM_TEV_COLOR_RA's alpha from 0xff to 0 for object 373 and from 0 to 0xff for object 374; it is at 0 for 374 in the given frame in any case.
I dumped textures while using playing back the FIFO using the software renderer, and got tar364_stage0_map0_mip0.png, tar365_stage0_map0_mip0.png, and tar364_ind0_map1_mip0.png (and an identical copy as tar365_ind0_map1_mip0.png). Although that last file may appear invisible, it has contents; its alpha channel just happens to be all zeros so it doesn't show up properly. noise.png shows what it looks like with the alpha channel removed.
Lots of objects
Obj 372 @ 000e2b99:
XF register XFMEM_SETNUMTEXGENS
Number of tex gens: 1
Obj 373 @ 000e2d67:
BP register BPMEM_IREF
Stage 0 ntexmap: 1
Stage 0 ntexcoord: 1
Stage 1 ntexmap: 0
Stage 1 ntexcoord: 0
Stage 2 ntexmap: 0
Stage 2 ntexcoord: 0
Stage 3 ntexmap: 0
Stage 3 ntexcoord: 0
BP register BPMEM_RAS1_SS0
Indirect texture stages 0 and 1:
Even stage S scale: 0 (1)
Even stage T scale: 0 (1)
Odd stage S scale: 0 (1)
Odd stage T scale: 0 (1)
BP register BPMEM_IND_CMD command 0
Indirect tex stage ID: 0
Format: ITF_8 (0)
Bias: STU (7)
Bump alpha: Off (0)
Offset matrix ID: 1
Regular coord S wrapping factor: Off (0)
Regular coord T wrapping factor: Off (0)
Use modified texture coordinates for LOD computation: No
Add texture coordinates from previous TEV stage: No
BP register BPMEM_TEV_COLOR_RA Tev register 1
Type: Color (0)
Alpha: 0ff (this one varies; object 374 (bowser) has it at 0)
Red: 0ff
Obj 373 @ 000e2dab:
BP register BPMEM_TREF number 0
Stage 0 texmap: 0
Stage 0 tex coord: 0
Stage 0 enable texmap: Yes
Stage 0 color channel: Zero (7)
Stage 1 texmap: 0
Stage 1 tex coord: 0
Stage 1 enable texmap: No
Stage 1 color channel: Zero (7)
Obj 373 @ 000e2df1:
BP register BPMEM_IND_IMASK
No description available [parameter is 2]
BP register BPMEM_GENMODE
Num tex gens: 1
Num color channels: 1
Unused bit: 0
Flat shading (unconfirmed): No
Multisampling: No
Num TEV stages: 0
Cull mode: Back-facing primitives only (1)
Num indirect stages: 1
ZFreeze: No
CP register VCD_LO
Position and normal matrix index: Not present
Texture Coord 0 matrix index: Not present
Texture Coord 1 matrix index: Not present
Texture Coord 2 matrix index: Not present
Texture Coord 3 matrix index: Not present
Texture Coord 4 matrix index: Not present
Texture Coord 5 matrix index: Not present
Texture Coord 6 matrix index: Not present
Texture Coord 7 matrix index: Not present
Position: Direct (1)
Normal: Not present (0)
Color 0: Not present (0)
Color 1: Not present (0)
CP register VCD_HI
Texture Coord 0: Direct (1)
Texture Coord 1: Direct (1)
Texture Coord 2: Not present (0)
Texture Coord 3: Not present (0)
Texture Coord 4: Not present (0)
Texture Coord 5: Not present (0)
Texture Coord 6: Not present (0)
Texture Coord 7: Not present (0)
XF register XFMEM_VTXSPECS
Num colors: 0
Num normals: None (0)
Num textures: 2
CP register CP_VAT_REG_A - Format 0
Position elements: 3 (x, y, z) (1)
Position format: Float (4)
Position shift: 0 (1)
Normal elements: 1 (n) (0)
Normal format: Float (4)
Color 0 elements: 4 (r, g, b, a) (1)
Color 0 format: RGBA 32 bits 8888 (5)
Color 1 elements: 4 (r, g, b, a) (1)
Color 1 format: RGBA 32 bits 8888 (5)
Texture coord 0 elements: 2 (s, t) (1)
Texture coord 0 format: Float (4)
Texture coord 0 shift: 0 (1)
Byte dequant: shift applies to u8/s8 components
Normal index 3: single index per normal
CP register CP_VAT_REG_B - Format 0
Texture coord 1 elements: 2 (s, t) (1)
Texture coord 1 format: Float (4)
Texture coord 1 shift: 0 (1)
Texture coord 2 elements: 2 (s, t) (1)
Texture coord 2 format: Float (4)
Texture coord 2 shift: 0 (1)
Texture coord 3 elements: 2 (s, t) (1)
Texture coord 3 format: Float (4)
Texture coord 3 shift: 0 (1)
Texture coord 4 elements: 2 (s, t) (1)
Texture coord 4 format: Float (4)
Enhance VCache (must always be on): Yes
CP register CP_VAT_REG_C - Format 0
Texture coord 4 shift: 0 (1)
Texture coord 5 elements: 2 (s, t) (1)
Texture coord 5 format: Float (4)
Texture coord 5 shift: 0 (1)
Texture coord 6 elements: 2 (s, t) (1)
Texture coord 6 format: Float (4)
Texture coord 6 shift: 0 (1)
Texture coord 7 elements: 2 (s, t) (1)
Texture coord 7 format: Float (4)
Texture coord 7 shift: 0 (1)
Primitive GX_DRAW_TRIANGLES VAT 0
450ac000c3340000c5e45000 3dcccccd00000000 0000000000000000
45147000c3bb8000c5e45000 3f6666663f800000 3f8000003f800000
450ac000c3bb8000c5e45000 3dcccccd3f800000 000000003f800000
Primitive GX_DRAW_TRIANGLES VAT 0
450ac000c3340000c5e45000 3dcccccd00000000 0000000000000000
45147000c3340000c5e45000 3f66666600000000 3f80000000000000
45147000c3bb8000c5e45000 3f6666663f800000 3f8000003f800000
The above primitives decoded (https://godbolt.org/z/EE6qbdWhY), basically just a rectangle (but they didn't use a quad for some reason):
2220 -180 -7306 0.1 0 0 0
2375 -375 -7306 0.9 1 1 1
2220 -375 -7306 0.1 1 0 1
2220 -180 -7306 0.1 0 0 0
2375 -180 -7306 0.9 0 1 0
2375 -375 -7306 0.9 1 1 1
VCD_HI specifies 2 texture coords, XFMEM_VTXSPECS specifies 2 textures, but BPMEM_GENMODE and XFMEM_SETNUMTEXGENS specify 1 tex gen. (the latter is a leftover from object 372 and may not be relevant though; I think the BP one is more likely. The current patch uses the BP one, though my initial software renderer implementation used the XF one because I didn't realize that both existed.) And in case it's not clear, this effect is achieved through an indirect texture, which to my understanding serves to implement bump mapping — one texture acts as offsets to another texture, which with the noise image gives the scrambling effect.
The one thing that seems important is the use of BPMEM_IND_IMASK
, which dolphin doesn't have implemented. It's not entirely clear what it does, but from looking at Kirby's Dream Collection's __GXSetIndirectMask
(relevant code is at 80037b60 and 800320d4) it seems that it takes a byte as a parameter, and the default value is 0 (though the variable starts at 0xff). Setting it to 0x02 is thus suspicious; there are up to 8 texture coordinates so maybe it has one bit for each?