@@ -650,3 +650,101 @@ Gfx *geo_mirror_mario_backface_culling(s32 callContext, struct GraphNode *node,
650650 }
651651 return gfx ;
652652}
653+
654+ // @port: We can make this dynamic like on coop
655+ #define PLAYER_PART_MAX 8
656+
657+ struct PlayerColor {
658+ Lights1 parts [PLAYER_PART_MAX ];
659+ };
660+
661+ u8 gDefaultMarioColors [][3 ] = {
662+ { 0x00 , 0x00 , 0xff },
663+ { 0xff , 0x00 , 0x00 },
664+ { 0xff , 0xff , 0xff },
665+ { 0x72 , 0x1c , 0x0e },
666+ { 0x73 , 0x06 , 0x00 },
667+ { 0xfe , 0xc1 , 0x79 },
668+ { 0xff , 0x00 , 0x00 },
669+ { 0xff , 0x00 , 0x00 }
670+ };
671+
672+ static struct PlayerColor geo_mario_get_player_color (const u8 (* palette )[3 ]) {
673+ struct PlayerColor color = { 0 };
674+ u8 index = 0 ;
675+ struct MarioBodyState * bodyState = & gBodyStates [index ];
676+
677+ u8 shadeR = 127 ;
678+ u8 shadeG = 127 ;
679+ u8 shadeB = 127 ;
680+ u8 lightR = 127 ;
681+ u8 lightG = 127 ;
682+ u8 lightB = 127 ;
683+ f32 lightingDirX = 0.0f ;
684+ f32 lightingDirY = 0.0f ;
685+ f32 lightingDirZ = 0.0f ;
686+
687+ for (s32 part = 0 ; part != PLAYER_PART_MAX ; ++ part ) {
688+ color .parts [part ] = (Lights1 ) gdSPDefLights1 (
689+ // Shadow
690+ palette [part ][0 ] * shadeR / 255.0f ,
691+ palette [part ][1 ] * shadeG / 255.0f ,
692+ palette [part ][2 ] * shadeB / 255.0f ,
693+ // Light
694+ palette [part ][0 ] * lightR / 255.0f ,
695+ palette [part ][1 ] * lightG / 255.0f ,
696+ palette [part ][2 ] * lightB / 255.0f ,
697+ 0x28 + lightingDirX * 127.0f , 0x28 + lightingDirY * 127.0f , 0x28 + lightingDirZ * 127.0f
698+ );
699+ }
700+ return color ;
701+ }
702+
703+ static Gfx * geo_mario_create_player_colors_dl (s32 index , Gfx * capEnemyGfx , Gfx * capEnemyDecalGfx ) {
704+ s32 size = ((PLAYER_PART_MAX * 2 ) + 1 ) + (capEnemyGfx != NULL ) + (capEnemyDecalGfx != NULL );
705+ Gfx * gfx = alloc_display_list (size * sizeof (Gfx ));
706+ if (gfx ) {
707+ Gfx * gfxp = gfx ;
708+ static struct PlayerColor playerColor ;
709+ playerColor = geo_mario_get_player_color (gDefaultMarioColors );
710+ for (s32 part = 0 ; part != PLAYER_PART_MAX ; ++ part ) {
711+ Lights1 * light = alloc_display_list (sizeof (Lights1 ));
712+ if (!light ) { return NULL ; }
713+ * light = playerColor .parts [part ];
714+ gSPLight (gfxp ++ , & light -> l , (2 * (part + 1 )) + 1 );
715+ gSPLight (gfxp ++ , & light -> a , (2 * (part + 1 )) + 2 );
716+ }
717+ if (capEnemyGfx ) { gSPDisplayList (gfxp ++ , capEnemyGfx ); }
718+ if (capEnemyDecalGfx ) { gSPDisplayList (gfxp ++ , capEnemyDecalGfx ); }
719+ gSPEndDisplayList (gfxp );
720+ }
721+ return gfx ;
722+ }
723+
724+ /**
725+ * Generate DL that sets player color depending on player number.
726+ */
727+ Gfx * geo_mario_set_player_colors (s32 callContext , struct GraphNode * node , UNUSED Mat4 * c ) {
728+ struct GraphNodeGenerated * asGenerated = (struct GraphNodeGenerated * ) node ;
729+ Gfx * gfx = NULL ;
730+ u8 index = 0 ;
731+
732+ struct MarioBodyState * bodyState = & gBodyStates [index ];
733+
734+ if (callContext == GEO_CONTEXT_RENDER ) {
735+ gfx = geo_mario_create_player_colors_dl (index , NULL , NULL );
736+ u32 layer = LAYER_OPAQUE ;
737+ if (asGenerated -> parameter == 0 ) {
738+ // put on transparent layer if vanish effect, opaque otherwise
739+ layer = ((bodyState -> modelState >> 8 ) & 1 ) ? LAYER_TRANSPARENT : LAYER_OPAQUE ;
740+ } else if (asGenerated -> parameter == 1 ) {
741+ layer = LAYER_OPAQUE ;
742+ } else if (asGenerated -> parameter == 2 ) {
743+ layer = LAYER_TRANSPARENT ;
744+ } else if (asGenerated -> parameter >= 3 ) {
745+ layer = asGenerated -> parameter - 3 ;
746+ }
747+ asGenerated -> fnNode .node .flags = (asGenerated -> fnNode .node .flags & 0xFF ) | (layer << 8 );
748+ }
749+ return NULL ;
750+ }
0 commit comments