implement changeable model colors

in a very dumb way:

the custom colors are set for lights 3, 4, 5, 6 in a GEO_ASM callback, then copied to lights 1, 2 using gsSPCopyLightEXT
This commit is contained in:
fgsfds 2021-04-06 00:21:51 +03:00
parent 798389b527
commit 109e713689
6 changed files with 107 additions and 45 deletions

View file

@ -788,6 +788,7 @@ const GeoLayout luigi_geo[] = {
GEO_OPEN_NODE(),
GEO_SCALE(0, 17202),
GEO_OPEN_NODE(),
GEO_ASM(0, geo_mario_set_player_colors),
GEO_ASM(0, geo_mirror_mario_backface_culling),
GEO_ASM(0, geo_mirror_mario_set_alpha),
GEO_SWITCH_CASE(0, geo_switch_mario_stand_run),

View file

@ -3225,7 +3225,8 @@ Gfx mat_luigi_body[] = {
gsDPPipeSync(),
gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, 0, 0, 0, G_TX_WRAP | G_TX_NOMIRROR, 5, 0, G_TX_WRAP | G_TX_NOMIRROR, 5, 0),
gsDPSetTileSize(0, 0, 0, 124, 124),
gsSPSetLights1(luigi_body_lights),
gsSPCopyLightEXT(1, 3), // gsSPSetLights1(luigi_body_lights)
gsSPCopyLightEXT(2, 4), //
gsSPEndDisplayList(),
};
@ -3265,7 +3266,8 @@ Gfx mat_luigi_cap[] = {
gsDPPipeSync(),
gsDPSetTile(G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, 0, 0, 0, G_TX_CLAMP | G_TX_NOMIRROR, 5, 0, G_TX_CLAMP | G_TX_NOMIRROR, 5, 0),
gsDPSetTileSize(0, 0, 0, 124, 124),
gsSPSetLights1(luigi_cap_lights),
gsSPCopyLightEXT(1, 5), // gsSPSetLights1(luigi_cap_lights)
gsSPCopyLightEXT(2, 6), //
gsSPEndDisplayList(),
};

View file

@ -1811,6 +1811,7 @@ const GeoLayout mario_geo[] = {
GEO_OPEN_NODE(),
GEO_SCALE(0x00, 16384),
GEO_OPEN_NODE(),
GEO_ASM(0, geo_mario_set_player_colors),
GEO_ASM(0, geo_mirror_mario_backface_culling),
GEO_ASM(0, geo_mirror_mario_set_alpha),
GEO_SWITCH_CASE(0, geo_switch_mario_stand_run),

View file

@ -381,8 +381,8 @@ const Gfx mario_butt_dl[] = {
const Gfx mario_butt[] = {
gsDPPipeSync(),
gsDPSetCombineMode(G_CC_SHADEFADEA, G_CC_SHADEFADEA),
gsSPLight(&mario_blue_lights_group.l, 1),
gsSPLight(&mario_blue_lights_group.a, 2),
gsSPCopyLightEXT(1, 3), // gsSPLight(&mario_blue_lights_group.l, 1),
gsSPCopyLightEXT(2, 4), // gsSPLight(&mario_blue_lights_group.a, 2),
gsSPDisplayList(mario_butt_dl),
gsSPEndDisplayList(),
};
@ -499,8 +499,8 @@ const Gfx mario_left_arm_shared_dl[] = {
// 0x0400D1D8 - 0x0400D1F8
const Gfx mario_left_arm[] = {
gsSPLight(&mario_red_lights_group.l, 1),
gsSPLight(&mario_red_lights_group.a, 2),
gsSPCopyLightEXT(1, 5), // gsSPLight(&mario_red_lights_group.l, 1),
gsSPCopyLightEXT(2, 6), // gsSPLight(&mario_red_lights_group.a, 2),
gsSPDisplayList(mario_left_arm_shared_dl),
gsSPEndDisplayList(),
};
@ -760,8 +760,8 @@ const Gfx mario_right_arm_shared_dl[] = {
// 0x0400DDE8 - 0x0400DE08
const Gfx mario_right_arm[] = {
gsSPLight(&mario_red_lights_group.l, 1),
gsSPLight(&mario_red_lights_group.a, 2),
gsSPCopyLightEXT(1, 5), // gsSPLight(&mario_red_lights_group.l, 1),
gsSPCopyLightEXT(2, 6), // gsSPLight(&mario_red_lights_group.a, 2),
gsSPDisplayList(mario_right_arm_shared_dl),
gsSPEndDisplayList(),
};
@ -979,8 +979,8 @@ const Gfx mario_left_thigh_dl[] = {
const Gfx mario_left_thigh[] = {
gsDPPipeSync(),
gsDPSetCombineMode(G_CC_SHADEFADEA, G_CC_SHADEFADEA),
gsSPLight(&mario_blue_lights_group.l, 1),
gsSPLight(&mario_blue_lights_group.a, 2),
gsSPCopyLightEXT(1, 3), // gsSPLight(&mario_blue_lights_group.l, 1),
gsSPCopyLightEXT(2, 4), // gsSPLight(&mario_blue_lights_group.a, 2),
gsSPDisplayList(mario_left_thigh_dl),
gsSPEndDisplayList(),
};
@ -1160,8 +1160,8 @@ const Gfx mario_right_thigh_shared_dl[] = {
// 0x0400EFB8 - 0x0400EFD8
const Gfx mario_right_thigh[] = {
gsSPLight(&mario_blue_lights_group.l, 1),
gsSPLight(&mario_blue_lights_group.a, 2),
gsSPCopyLightEXT(1, 3), // gsSPLight(&mario_blue_lights_group.l, 1),
gsSPCopyLightEXT(2, 4), // gsSPLight(&mario_blue_lights_group.a, 2),
gsSPDisplayList(mario_right_thigh_shared_dl),
gsSPEndDisplayList(),
};
@ -1589,8 +1589,8 @@ const Gfx mario_tshirt_shared_dl[] = {
// 0x04010348 - 0x04010370
const Gfx mario_torso_dl[] = {
gsSPDisplayList(mario_pants_overalls_shared_dl),
gsSPLight(&mario_red_lights_group.l, 1),
gsSPLight(&mario_red_lights_group.a, 2),
gsSPCopyLightEXT(1, 5), // gsSPLight(&mario_red_lights_group.l, 1),
gsSPCopyLightEXT(2, 6), // gsSPLight(&mario_red_lights_group.a, 2),
gsSPDisplayList(mario_tshirt_shared_dl),
gsSPEndDisplayList(),
};
@ -2080,8 +2080,8 @@ const Gfx mario_face_back_hair_cap_on_dl[] = {
// 0x04011960 - 0x040119A0
const Gfx mario_face_cap_on_dl[] = {
gsSPDisplayList(mario_face_part_cap_on_dl),
gsSPLight(&mario_red_lights_group.l, 1),
gsSPLight(&mario_red_lights_group.a, 2),
gsSPCopyLightEXT(1, 5), // gsSPLight(&mario_red_lights_group.l, 1),
gsSPCopyLightEXT(2, 6), // gsSPLight(&mario_red_lights_group.a, 2),
gsSPDisplayList(mario_face_cap_dl),
gsSPLight(&mario_brown2_lights_group.l, 1),
gsSPLight(&mario_brown2_lights_group.a, 2),
@ -3270,8 +3270,8 @@ const Gfx mario_medium_poly_butt_dl[] = {
const Gfx mario_medium_poly_butt[] = {
gsDPPipeSync(),
gsDPSetCombineMode(G_CC_SHADEFADEA, G_CC_SHADEFADEA),
gsSPLight(&mario_blue_lights_group.l, 1),
gsSPLight(&mario_blue_lights_group.a, 2),
gsSPCopyLightEXT(1, 3), // gsSPLight(&mario_blue_lights_group.l, 1),
gsSPCopyLightEXT(2, 4), // gsSPLight(&mario_blue_lights_group.a, 2),
gsSPDisplayList(mario_medium_poly_butt_dl),
gsSPEndDisplayList(),
};
@ -3322,8 +3322,8 @@ const Gfx mario_medium_poly_left_arm_shared_dl[] = {
// 0x04014840 - 0x04014860
const Gfx mario_medium_poly_left_arm[] = {
gsSPLight(&mario_red_lights_group.l, 1),
gsSPLight(&mario_red_lights_group.a, 2),
gsSPCopyLightEXT(1, 5), // gsSPLight(&mario_red_lights_group.l, 1),
gsSPCopyLightEXT(2, 6), // gsSPLight(&mario_red_lights_group.a, 2),
gsSPDisplayList(mario_medium_poly_left_arm_shared_dl),
gsSPEndDisplayList(),
};
@ -3483,8 +3483,8 @@ const Gfx mario_medium_poly_right_arm_shared_dl[] = {
// 0x04014F40 - 0x04014F60
const Gfx mario_medium_poly_right_arm[] = {
gsSPLight(&mario_red_lights_group.l, 1),
gsSPLight(&mario_red_lights_group.a, 2),
gsSPCopyLightEXT(1, 5), // gsSPLight(&mario_red_lights_group.l, 1),
gsSPCopyLightEXT(2, 6), // gsSPLight(&mario_red_lights_group.a, 2),
gsSPDisplayList(mario_medium_poly_right_arm_shared_dl),
gsSPEndDisplayList(),
};
@ -3659,8 +3659,8 @@ const Gfx mario_medium_poly_left_thigh_dl[] = {
const Gfx mario_medium_poly_left_thigh[] = {
gsDPPipeSync(),
gsDPSetCombineMode(G_CC_SHADEFADEA, G_CC_SHADEFADEA),
gsSPLight(&mario_blue_lights_group.l, 1),
gsSPLight(&mario_blue_lights_group.a, 2),
gsSPCopyLightEXT(1, 3), // gsSPLight(&mario_blue_lights_group.l, 1),
gsSPCopyLightEXT(2, 4), // gsSPLight(&mario_blue_lights_group.a, 2),
gsSPDisplayList(mario_medium_poly_left_thigh_dl),
gsSPEndDisplayList(),
};
@ -3808,8 +3808,8 @@ const Gfx mario_medium_poly_right_thigh_shared_dl[] = {
// 0x04015D00 - 0x04015D20
const Gfx mario_medium_poly_right_thigh[] = {
gsSPLight(&mario_blue_lights_group.l, 1),
gsSPLight(&mario_blue_lights_group.a, 2),
gsSPCopyLightEXT(1, 3), // gsSPLight(&mario_blue_lights_group.l, 1),
gsSPCopyLightEXT(2, 4), // gsSPLight(&mario_blue_lights_group.a, 2),
gsSPDisplayList(mario_medium_poly_right_thigh_shared_dl),
gsSPEndDisplayList(),
};
@ -4081,8 +4081,8 @@ const Gfx mario_medium_poly_tshirt_shared_dl[] = {
// 0x040168A0 - 0x040168C8
const Gfx mario_medium_poly_torso_dl[] = {
gsSPDisplayList(mario_medium_poly_pants_overalls_shared_dl),
gsSPLight(&mario_red_lights_group.l, 1),
gsSPLight(&mario_red_lights_group.a, 2),
gsSPCopyLightEXT(1, 5), // gsSPLight(&mario_red_lights_group.l, 1),
gsSPCopyLightEXT(2, 6), // gsSPLight(&mario_red_lights_group.a, 2),
gsSPDisplayList(mario_medium_poly_tshirt_shared_dl),
gsSPEndDisplayList(),
};
@ -4149,8 +4149,8 @@ const Gfx mario_low_poly_butt_dl[] = {
const Gfx mario_low_poly_butt[] = {
gsDPPipeSync(),
gsDPSetCombineMode(G_CC_SHADEFADEA, G_CC_SHADEFADEA),
gsSPLight(&mario_blue_lights_group.l, 1),
gsSPLight(&mario_blue_lights_group.a, 2),
gsSPCopyLightEXT(1, 3), // gsSPLight(&mario_blue_lights_group.l, 1),
gsSPCopyLightEXT(2, 4), // gsSPLight(&mario_blue_lights_group.a, 2),
gsSPDisplayList(mario_low_poly_butt_dl),
gsSPEndDisplayList(),
};
@ -4196,8 +4196,8 @@ const Gfx mario_low_poly_left_arm_shared_dl[] = {
// 0x04016C70 - 0x04016C90
const Gfx mario_low_poly_left_arm[] = {
gsSPLight(&mario_red_lights_group.l, 1),
gsSPLight(&mario_red_lights_group.a, 2),
gsSPCopyLightEXT(1, 5), // gsSPLight(&mario_red_lights_group.l, 1),
gsSPCopyLightEXT(2, 6), // gsSPLight(&mario_red_lights_group.a, 2),
gsSPDisplayList(mario_low_poly_left_arm_shared_dl),
gsSPEndDisplayList(),
};
@ -4287,8 +4287,8 @@ const Gfx mario_low_poly_right_arm_shared_dl[] = {
// 0x04016FB0 - 0x04016FD0
const Gfx mario_low_poly_right_arm[] = {
gsSPLight(&mario_red_lights_group.l, 1),
gsSPLight(&mario_red_lights_group.a, 2),
gsSPCopyLightEXT(1, 5), // gsSPLight(&mario_red_lights_group.l, 1),
gsSPCopyLightEXT(2, 6), // gsSPLight(&mario_red_lights_group.a, 2),
gsSPDisplayList(mario_low_poly_right_arm_shared_dl),
gsSPEndDisplayList(),
};
@ -4394,8 +4394,8 @@ const Gfx mario_low_poly_left_thigh_dl[] = {
const Gfx mario_low_poly_left_thigh[] = {
gsDPPipeSync(),
gsDPSetCombineMode(G_CC_SHADEFADEA, G_CC_SHADEFADEA),
gsSPLight(&mario_blue_lights_group.l, 1),
gsSPLight(&mario_blue_lights_group.a, 2),
gsSPCopyLightEXT(1, 3), // gsSPLight(&mario_blue_lights_group.l, 1),
gsSPCopyLightEXT(2, 4), // gsSPLight(&mario_blue_lights_group.a, 2),
gsSPDisplayList(mario_low_poly_left_thigh_dl),
gsSPEndDisplayList(),
};
@ -4513,8 +4513,8 @@ const Gfx mario_low_poly_right_thigh_shared_dl[] = {
// 0x04017818 - 0x04017838
const Gfx mario_low_poly_right_thigh[] = {
gsSPLight(&mario_blue_lights_group.l, 1),
gsSPLight(&mario_blue_lights_group.a, 2),
gsSPCopyLightEXT(1, 3), // gsSPLight(&mario_blue_lights_group.l, 1),
gsSPCopyLightEXT(2, 4), // gsSPLight(&mario_blue_lights_group.a, 2),
gsSPDisplayList(mario_low_poly_right_thigh_shared_dl),
gsSPEndDisplayList(),
};
@ -4684,8 +4684,8 @@ const Gfx mario_low_poly_tshirt_shared_dl[] = {
// 0x04017E78 - 0x04017EA0
const Gfx mario_low_poly_torso_dl[] = {
gsSPDisplayList(mario_low_poly_pants_overalls_shared_dl),
gsSPLight(&mario_red_lights_group.l, 1),
gsSPLight(&mario_red_lights_group.a, 2),
gsSPCopyLightEXT(1, 5), // gsSPLight(&mario_red_lights_group.l, 1),
gsSPCopyLightEXT(2, 6), // gsSPLight(&mario_red_lights_group.a, 2),
gsSPDisplayList(mario_low_poly_tshirt_shared_dl),
gsSPEndDisplayList(),
};
@ -4854,8 +4854,8 @@ const Gfx mario_low_poly_face_back_hair_cap_on_dl[] = {
// 0x04018420 - 0x04018460
const Gfx mario_low_poly_face_cap_on_dl[] = {
gsSPDisplayList(mario_low_poly_face_part_cap_on_dl),
gsSPLight(&mario_red_lights_group.l, 1),
gsSPLight(&mario_red_lights_group.a, 2),
gsSPCopyLightEXT(1, 5), // gsSPLight(&mario_red_lights_group.l, 1),
gsSPCopyLightEXT(2, 6), // gsSPLight(&mario_red_lights_group.a, 2),
gsSPDisplayList(mario_low_poly_face_cap_dl),
gsSPLight(&mario_brown2_lights_group.l, 1),
gsSPLight(&mario_brown2_lights_group.a, 2),
@ -6625,8 +6625,8 @@ const Gfx mario_cap_unused_dl[] = {
gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, mario_texture_m_logo),
gsDPLoadSync(),
gsDPLoadBlock(G_TX_LOADTILE, 0, 0, 32 * 32 - 1, CALC_DXT(32, G_IM_SIZ_16b_BYTES)),
gsSPLight(&mario_red_lights_group.l, 1),
gsSPLight(&mario_red_lights_group.a, 2),
gsSPCopyLightEXT(1, 5), // gsSPLight(&mario_red_lights_group.l, 1),
gsSPCopyLightEXT(2, 6), // gsSPLight(&mario_red_lights_group.a, 2),
gsSPDisplayList(mario_cap_unused_m_logo_dl),
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF),
gsDPPipeSync(),

View file

@ -23,6 +23,7 @@
#include "save_file.h"
#include "skybox.h"
#include "sound_init.h"
#include "pc/network/network.h"
#define TOAD_STAR_1_REQUIREMENT 12
#define TOAD_STAR_2_REQUIREMENT 25
@ -51,6 +52,11 @@ enum UnlockDoorStarStates {
UNLOCK_DOOR_STAR_DONE
};
struct PlayerColor {
Lights1 pants;
Lights1 shirt;
};
/**
* The eye texture on succesive frames of Mario's blink animation.
* He intentionally blinks twice each time.
@ -71,6 +77,18 @@ static s8 gMarioAttackScaleAnimation[3 * 6] = {
struct MarioBodyState gBodyStates[MAX_PLAYERS];
struct GraphNodeObject gMirrorMario[MAX_PLAYERS]; // copy of Mario's geo node for drawing mirror Mario
struct PlayerColor gPlayerColors[MAX_PLAYERS] = {
// default mario
{
gdSPDefLights1(0x00, 0x00, 0x7f, 0x00, 0x00, 0xff, 0x28, 0x28, 0x28),
gdSPDefLights1(0x7f, 0x00, 0x00, 0xff, 0x00, 0x00, 0x28, 0x28, 0x28),
},
// default luigi
{
gdSPDefLights1(0x00, 0x00, 0x7f, 0x00, 0x00, 0xfe, 0x28, 0x28, 0x28),
gdSPDefLights1(0x00, 0x4c, 0x00, 0x00, 0x98, 0x00, 0x28, 0x28, 0x28),
},
};
// This whole file is weirdly organized. It has to be the same file due
// to rodata boundaries and function aligns, which means the programmer
@ -78,6 +96,20 @@ struct GraphNodeObject gMirrorMario[MAX_PLAYERS]; // copy of Mario's geo node f
// (message NPC related things, the Mario head geo, and Mario geo
// functions)
/**
* Set the Light1 struct from player colors.
* The 4th component is the shade factor (difference between ambient and diffuse),
* usually set to 1.
*/
void set_player_colors(u8 globalIndex, const u8 pants[4], const u8 shirt[4]) {
const u8 pAmb[3] = { pants[0] >> pants[4], pants[1] >> pants[4], pants[2] >> pants[4] };
const u8 sAmb[3] = { shirt[0] >> shirt[4], shirt[1] >> shirt[4], shirt[2] >> shirt[4] };
gPlayerColors[globalIndex].pants =
(Lights1) gdSPDefLights1(pAmb[0], pAmb[1], pAmb[2], pants[0], pants[1], pants[2], 0x28, 0x28, 0x28);
gPlayerColors[globalIndex].shirt =
(Lights1) gdSPDefLights1(sAmb[0], sAmb[1], sAmb[2], shirt[0], shirt[1], shirt[2], 0x28, 0x28, 0x28);
}
/**
* Geo node script that draws Mario's head on the title screen.
*/
@ -720,4 +752,28 @@ Gfx* geo_mirror_mario_backface_culling(s32 callContext, struct GraphNode* node,
asGenerated->fnNode.node.flags = (asGenerated->fnNode.node.flags & 0xFF) | (LAYER_OPAQUE << 8);
}
return gfx;
}
}
/**
* Generate DL that sets player color depending on player number.
*/
Gfx* geo_mario_set_player_colors(s32 callContext, struct GraphNode* node, UNUSED Mat4* c) {
struct GraphNodeGenerated* asGenerated = (struct GraphNodeGenerated*) node;
Gfx* gfx = NULL;
u8 index = geo_get_processing_object_index();
u8 colorIndex = gNetworkPlayers[index].globalIndex;
struct MarioBodyState* bodyState = &gBodyStates[index];
if (callContext == GEO_CONTEXT_RENDER) {
gfx = alloc_display_list(5 * sizeof(*gfx));
gSPLight(gfx + 0, &gPlayerColors[colorIndex].pants.l, 3);
gSPLight(gfx + 1, &gPlayerColors[colorIndex].pants.a, 4);
gSPLight(gfx + 2, &gPlayerColors[colorIndex].shirt.l, 5);
gSPLight(gfx + 3, &gPlayerColors[colorIndex].shirt.a, 6);
gSPEndDisplayList(gfx + 4);
// put on transparent if vanish effect, opaque otherwise
const u32 layer = ((bodyState->modelState >> 8) & 1) ? LAYER_TRANSPARENT : LAYER_OPAQUE;
asGenerated->fnNode.node.flags = (asGenerated->fnNode.node.flags & 0xFF) | (layer << 8);
}
return gfx;
}

View file

@ -9,6 +9,7 @@
extern struct GraphNodeObject gMirrorMario[MAX_PLAYERS];
extern struct MarioBodyState gBodyStates[MAX_PLAYERS];
void set_player_colors(u8 globalIndex, const u8 pants[4], const u8 shirt[4]);
Gfx *geo_draw_mario_head_goddard(s32 callContext, struct GraphNode *node, Mat4 *c);
void bhv_toad_message_loop(void);
void bhv_toad_message_init(void);
@ -27,5 +28,6 @@ Gfx *geo_mario_rotate_wing_cap_wings(s32 callContext, struct GraphNode *node, UN
Gfx *geo_switch_mario_hand_grab_pos(s32 callContext, struct GraphNode *b, Mat4 *mtx);
Gfx *geo_render_mirror_mario(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c);
Gfx *geo_mirror_mario_backface_culling(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c);
Gfx *geo_mario_set_player_colors(s32 callContext, struct GraphNode *node, UNUSED Mat4 *c);
#endif // MARIO_MISC_H