Merge pull request #103 from fgsfdsfgs/coop-dev
custom player colors (and other "unstable 3" changes)
This commit is contained in:
commit
cb0c742514
|
@ -2,6 +2,8 @@
|
|||
Online cooperative multiplayer mod for SM64, aiming to synchronize all entities and every level for two players.
|
||||
Fork of [sm64pc/sm64ex](https://github.com/sm64pc/sm64ex).
|
||||
|
||||
Build instructions are available on the [sm64ex wiki](https://github.com/sm64pc/sm64ex/wiki).
|
||||
|
||||
Feel free to report bugs and contribute, but remember, there must be **no upload of any copyrighted asset**.
|
||||
Run `./extract_assets.py --clean && make clean` or `make distclean` to remove ROM-originated content.
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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(),
|
||||
};
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -3974,6 +3974,7 @@
|
|||
<ClCompile Include="..\src\pc\network\packets\packet_keep_alive.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_leaving.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_level_warp.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_level_warp_2.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_network_players.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_object.c" />
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_player.c" />
|
||||
|
|
|
@ -15087,6 +15087,9 @@
|
|||
<ClCompile Include="..\src\game\characters.c">
|
||||
<Filter>Source Files\src\game</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\network\packets\packet_level_warp_2.c">
|
||||
<Filter>Source Files\src\pc\network\packets</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\actors\common0.h">
|
||||
|
|
|
@ -18,9 +18,9 @@ fi
|
|||
#exit
|
||||
|
||||
# no debug, direct
|
||||
#$FILE --server 27015 --configfile sm64config_server.txt &
|
||||
#$FILE --client 127.0.0.1 27015 --configfile sm64config_client.txt &
|
||||
#exit
|
||||
$FILE --server 27015 --configfile sm64config_server.txt &
|
||||
$FILE --client 127.0.0.1 27015 --configfile sm64config_client.txt &
|
||||
exit
|
||||
|
||||
# debug on server
|
||||
#$FILE --client 127.0.0.1 27015 --configfile sm64config_client.txt &
|
||||
|
|
|
@ -12,26 +12,6 @@ if [ ! -f "$FILE" ]; then
|
|||
FILE=./build/us_pc/sm64.us.f3dex2e
|
||||
fi
|
||||
|
||||
# no debug, discord
|
||||
#$FILE --discord 2 --configfile sm64config_server.txt &
|
||||
#$FILE --discord 1 --configfile sm64config_client.txt &
|
||||
#exit
|
||||
|
||||
# no debug, direct
|
||||
#$FILE --server 27015 --configfile sm64config_server.txt &
|
||||
#$FILE --client 127.0.0.1 27015 --configfile sm64config_client.txt &
|
||||
#exit
|
||||
|
||||
# debug on server
|
||||
#$FILE --client 127.0.0.1 27015 --configfile sm64config_client.txt &
|
||||
#winpty cgdb $FILE -ex 'break debug_breakpoint_here' -ex 'run --server 27015 --configfile sm64config_server.txt' -ex 'quit'
|
||||
#exit
|
||||
|
||||
###################
|
||||
# debug on client #
|
||||
###################
|
||||
|
||||
#winpty cgdb $FILE -ex 'break debug_breakpoint_here' -ex 'run --server 27015 --configfile sm64config_p1.txt' -ex 'quit'
|
||||
$FILE --server 27015 --configfile sm64config_p1.txt &
|
||||
sleep 2
|
||||
$FILE --client 127.0.0.1 27015 --configfile sm64config_p2.txt &
|
||||
|
@ -39,4 +19,7 @@ sleep 2
|
|||
$FILE --client 127.0.0.1 27015 --configfile sm64config_p3.txt &
|
||||
sleep 2
|
||||
$FILE --client 127.0.0.1 27015 --configfile sm64config_p4.txt &
|
||||
|
||||
#sleep 2
|
||||
#winpty cgdb $FILE -ex 'break debug_breakpoint_here' -ex 'run --server 27015 --configfile sm64config_p1.txt' -ex 'quit'
|
||||
#winpty cgdb $FILE -ex 'break debug_breakpoint_here' -ex 'run --client 127.0.0.1 27015 --configfile sm64config_p4.txt' -ex 'quit'
|
||||
|
|
|
@ -118,6 +118,11 @@
|
|||
#define G_SPECIAL_2 0xd4
|
||||
#define G_SPECIAL_3 0xd3
|
||||
|
||||
#ifdef F3DEX_GBI_2E
|
||||
/* extended commands */
|
||||
#define G_COPYMEM 0xd2
|
||||
#endif
|
||||
|
||||
#define G_VTX 0x01
|
||||
#define G_MODIFYVTX 0x02
|
||||
#define G_CULLDL 0x03
|
||||
|
@ -1790,6 +1795,22 @@ typedef union {
|
|||
(uintptr_t)(adrs) \
|
||||
}}
|
||||
|
||||
#ifdef F3DEX_GBI_2E
|
||||
#define gCopyMemEXT(pkt, c, idx, dst, src, len) \
|
||||
{ \
|
||||
Gfx *_g = (Gfx *)(pkt); \
|
||||
_g->words.w0 = (_SHIFTL((c),24,8)|_SHIFTL((src)/8,16,8)| \
|
||||
_SHIFTL((dst)/8,8,8)|_SHIFTL((idx),0,8)); \
|
||||
_g->words.w1 = (uintptr_t)(((len)-1)/8); \
|
||||
}
|
||||
#define gsCopyMemEXT(c, idx, dst, src, len) \
|
||||
{{ \
|
||||
(_SHIFTL((c),24,8)|_SHIFTL((src)/8,16,8)| \
|
||||
_SHIFTL((dst)/8,8,8)|_SHIFTL((idx),0,8)), \
|
||||
(uintptr_t)(((len)-1)/8) \
|
||||
}}
|
||||
#endif
|
||||
|
||||
#define gSPNoOp(pkt) gDma0p(pkt, G_SPNOOP, 0, 0)
|
||||
#define gsSPNoOp() gsDma0p(G_SPNOOP, 0, 0)
|
||||
|
||||
|
@ -2541,6 +2562,17 @@ typedef union {
|
|||
gsDma1p( G_MOVEMEM, l, sizeof(Light),((n)-1)*2+G_MV_L0)
|
||||
#endif /* F3DEX_GBI_2 */
|
||||
|
||||
/*
|
||||
* EXTENDED COMMAND
|
||||
* Copy one light's parameters to the other.
|
||||
*/
|
||||
#ifdef F3DEX_GBI_2E
|
||||
# define gSPCopyLightEXT(pkt, dst, src) \
|
||||
gCopyMemEXT((pkt),G_COPYMEM,G_MV_LIGHT,(dst)*24+24,(src)*24+24,sizeof(Light))
|
||||
# define gsSPCopyLightEXT(dst, src) \
|
||||
gsCopyMemEXT( G_COPYMEM,G_MV_LIGHT,(dst)*24+24,(src)*24+24,sizeof(Light))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* gSPLightColor changes color of light without recalculating light direction
|
||||
* col is a 32 bit word with r,g,b,a (alpha is ignored)
|
||||
|
|
|
@ -392,7 +392,7 @@ struct MarioState
|
|||
// HOWEVER, simply increasing this to 3 will not magically work
|
||||
// many things will have to be overhauled!
|
||||
#ifdef UNSTABLE_BRANCH
|
||||
#define MAX_PLAYERS 4
|
||||
#define MAX_PLAYERS 16
|
||||
#else
|
||||
#define MAX_PLAYERS 2
|
||||
#endif
|
||||
|
|
|
@ -257,6 +257,15 @@ void load_area(s32 index) {
|
|||
load_obj_warp_nodes();
|
||||
geo_call_global_function_nodes(&gCurrentArea->unk04->node, GEO_CONTEXT_AREA_LOAD);
|
||||
}
|
||||
|
||||
if (!network_is_warp_2_duplicate()) {
|
||||
if (gNetworkType != NT_NONE) {
|
||||
network_send_level_warp_2(TRUE, gNetworkPlayerLocal->globalIndex);
|
||||
}
|
||||
if (gNetworkType == NT_CLIENT) {
|
||||
sCurrPlayMode = PLAY_MODE_SYNC_LEVEL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void unload_area(void) {
|
||||
|
@ -442,16 +451,9 @@ void render_game(void) {
|
|||
}
|
||||
|
||||
// only render 'synchronizing' text if we've been waiting for a while
|
||||
static u8 syncLevelTime = 0;
|
||||
if (sCurrPlayMode == PLAY_MODE_SYNC_LEVEL) {
|
||||
if (syncLevelTime < 30) {
|
||||
syncLevelTime++;
|
||||
} else {
|
||||
render_sync_level_screen();
|
||||
}
|
||||
} else {
|
||||
syncLevelTime = 0;
|
||||
}
|
||||
|
||||
D_8032CE74 = NULL;
|
||||
D_8032CE78 = 0;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "chat.h"
|
||||
#include "game_init.h"
|
||||
#include "ingame_menu.h"
|
||||
#include "mario_misc.h"
|
||||
#include "segment2.h"
|
||||
#include "gfx_dimensions.h"
|
||||
#include "config.h"
|
||||
|
@ -23,6 +24,7 @@ struct ChatMessage {
|
|||
u8 dialog[CHAT_DIALOG_MAX];
|
||||
enum ChatMessageType type;
|
||||
u16 life;
|
||||
u8 color[3];
|
||||
};
|
||||
|
||||
static char inputMessage[CHAT_DIALOG_MAX] = { 0 };
|
||||
|
@ -73,18 +75,31 @@ static void render_chat_message(struct ChatMessage* chatMessage, u8 index) {
|
|||
case CMT_LOCAL: textR = 200; textG = 200; textB = 255; break;
|
||||
case CMT_INPUT: textR = 0; textG = 0; textB = 0; break;
|
||||
case CMT_SYSTEM: textR = 255; textG = 255; textB = 190; break;
|
||||
default: textR = 255; textG = 255; textB = 255;
|
||||
default: textR = 255; textG = 255; textB = 255; break;
|
||||
}
|
||||
|
||||
gSPDisplayList(gDisplayListHead++, dl_ia_text_begin);
|
||||
|
||||
gDPSetEnvColor(gDisplayListHead++, textR, textG, textB, 255 * alphaScale);
|
||||
print_generic_string(CHAT_X, CHAT_Y, chatMessage->dialog);
|
||||
|
||||
if (chatMessage->type == CMT_REMOTE || chatMessage->type == CMT_SYSTEM) {
|
||||
// if it's someone else's message, highlight the icon with their color
|
||||
u8 starR = chatMessage->color[0];
|
||||
u8 starG = chatMessage->color[1];
|
||||
u8 starB = chatMessage->color[2];
|
||||
gDPSetEnvColor(gDisplayListHead++, starR, starG, starB, 255 * alphaScale);
|
||||
create_dl_translation_matrix(MENU_MTX_PUSH, CHAT_X, CHAT_Y, 0.0f);
|
||||
render_generic_char(chatMessage->dialog[0]);
|
||||
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
||||
}
|
||||
|
||||
gSPDisplayList(gDisplayListHead++, dl_ia_text_end);
|
||||
|
||||
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
||||
}
|
||||
|
||||
void chat_add_message(char* ascii, enum ChatMessageType chatMessageType) {
|
||||
void chat_add_message_ext(char* ascii, enum ChatMessageType chatMessageType, const u8 color[3]) {
|
||||
u8 character = '?';
|
||||
switch (chatMessageType) {
|
||||
case CMT_INPUT:
|
||||
|
@ -98,10 +113,18 @@ void chat_add_message(char* ascii, enum ChatMessageType chatMessageType) {
|
|||
str_ascii_to_dialog(ascii, &msg->dialog[2], MIN(strlen(ascii), CHAT_DIALOG_MAX - 3));
|
||||
msg->life = (sSelectedFileNum != 0) ? CHAT_LIFE_MAX : CHAT_LIFE_MAX / 3;
|
||||
msg->type = chatMessageType;
|
||||
msg->color[0] = color[0];
|
||||
msg->color[1] = color[1];
|
||||
msg->color[2] = color[2];
|
||||
onMessageIndex = (onMessageIndex + 1) % CHAT_MESSAGES_MAX;
|
||||
play_sound((msg->type == CMT_LOCAL) ? SOUND_MENU_MESSAGE_DISAPPEAR : SOUND_MENU_MESSAGE_APPEAR, gDefaultSoundArgs);
|
||||
}
|
||||
|
||||
void chat_add_message(char* ascii, enum ChatMessageType chatMessageType) {
|
||||
const u8 defaultColor[3] = { 255, 255, 255 };
|
||||
chat_add_message_ext(ascii, chatMessageType, defaultColor);
|
||||
}
|
||||
|
||||
static void chat_stop_input(void) {
|
||||
sInChatInput = FALSE;
|
||||
keyboard_stop_text_input();
|
||||
|
@ -112,7 +135,8 @@ static void chat_send_input(void) {
|
|||
keyboard_stop_text_input();
|
||||
if (strlen(gTextInput) == 0) { return; }
|
||||
chat_add_message(gTextInput, CMT_LOCAL);
|
||||
network_send_chat(gTextInput);
|
||||
// our message has the same color as our shirt
|
||||
network_send_chat(gTextInput, get_player_color(gNetworkPlayerLocal->globalIndex, 0));
|
||||
}
|
||||
|
||||
void chat_start_input(void) {
|
||||
|
|
|
@ -10,6 +10,7 @@ enum ChatMessageType {
|
|||
|
||||
void render_chat(void);
|
||||
void chat_add_message(char* ascii, enum ChatMessageType chatMessageType);
|
||||
void chat_add_message_ext(char* ascii, enum ChatMessageType chatMessageType, const u8 color[3]);
|
||||
void chat_start_input(void);
|
||||
|
||||
#endif
|
|
@ -53,6 +53,10 @@ u8 gControlledWarpGlobalIndex = 0;
|
|||
extern s8 sReceivedLoadedActNum;
|
||||
u8 gRejectInstantWarp = 0;
|
||||
|
||||
s16 gChangeLevel = -1;
|
||||
s16 gChangeAreaIndex = -1;
|
||||
s16 gChangeActNum = -1;
|
||||
|
||||
#ifdef VERSION_JP
|
||||
const char *credits01[] = { "1GAME DIRECTOR", "SHIGERU MIYAMOTO" };
|
||||
const char *credits02[] = { "2ASSISTANT DIRECTORS", "YOSHIAKI KOIZUMI", "TAKASHI TEZUKA" };
|
||||
|
@ -1090,15 +1094,9 @@ s32 play_mode_normal(void) {
|
|||
}
|
||||
} else if (!gReceiveWarp.received) {
|
||||
if (sWarpDest.type == WARP_TYPE_CHANGE_LEVEL) {
|
||||
set_play_mode(PLAY_MODE_SYNC_LEVEL);
|
||||
network_send_level_warp_begin();
|
||||
set_play_mode(PLAY_MODE_CHANGE_LEVEL);
|
||||
} else if (sTransitionTimer != 0) {
|
||||
if (sWarpDest.type == WARP_TYPE_CHANGE_AREA) {
|
||||
set_play_mode(PLAY_MODE_SYNC_LEVEL);
|
||||
network_send_level_warp_begin();
|
||||
} else {
|
||||
set_play_mode(PLAY_MODE_CHANGE_AREA);
|
||||
}
|
||||
} else if (sCurrPlayMode == PLAY_MODE_NORMAL && pressed_pause()) {
|
||||
lower_background_noise(1);
|
||||
cancel_rumble();
|
||||
|
@ -1129,8 +1127,7 @@ s32 play_mode_paused(void) {
|
|||
fade_into_special_warp(0, 0);
|
||||
gSavedCourseNum = COURSE_NONE;
|
||||
}
|
||||
set_play_mode(PLAY_MODE_SYNC_LEVEL);
|
||||
network_send_level_warp_begin();
|
||||
set_play_mode(PLAY_MODE_CHANGE_LEVEL);
|
||||
} else if (gPauseScreenMode == 3) {
|
||||
// We should only be getting "int 3" to here
|
||||
initiate_warp(LEVEL_CASTLE, 1, 0x1F, 0);
|
||||
|
@ -1150,7 +1147,7 @@ s32 play_mode_sync_level(void) {
|
|||
set_menu_mode(-1);
|
||||
gCameraMovementFlags &= ~CAM_MOVE_PAUSE_SCREEN;
|
||||
|
||||
check_received_warp();
|
||||
//check_received_warp();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1262,6 +1259,15 @@ static s32 play_mode_unused(void) {
|
|||
s32 update_level(void) {
|
||||
s32 changeLevel = 0;
|
||||
|
||||
if (gChangeLevel != -1) {
|
||||
gHudDisplay.flags = HUD_DISPLAY_NONE;
|
||||
sTransitionTimer = 0;
|
||||
sTransitionUpdate = NULL;
|
||||
changeLevel = gChangeLevel;
|
||||
gChangeLevel = -1;
|
||||
return changeLevel;
|
||||
}
|
||||
|
||||
switch (sCurrPlayMode) {
|
||||
case PLAY_MODE_NORMAL:
|
||||
changeLevel = play_mode_normal();
|
||||
|
|
|
@ -76,6 +76,10 @@ extern s16 sTransitionTimer;
|
|||
extern void (*sTransitionUpdate)(s16 *);
|
||||
extern u8 unused3[4];
|
||||
|
||||
extern s16 gChangeLevel;
|
||||
extern s16 gChangeAreaIndex;
|
||||
extern s16 gChangeActNum;
|
||||
|
||||
struct WarpDest {
|
||||
u8 type;
|
||||
u8 levelNum;
|
||||
|
|
|
@ -2123,7 +2123,7 @@ static void init_single_mario(struct MarioState* m) {
|
|||
}
|
||||
|
||||
// set mario/luigi model
|
||||
enum CharacterType characterType = (gNetworkPlayers[0].globalIndex == 1) ? CT_LUIGI : CT_MARIO;
|
||||
enum CharacterType characterType = (globalIndex == 0) ? CT_MARIO : CT_LUIGI;
|
||||
m->character = &gCharacters[characterType];
|
||||
m->marioObj->header.gfx.sharedChild = gLoadedGraphNodes[m->character->modelId];
|
||||
}
|
||||
|
|
|
@ -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 shirt;
|
||||
Lights1 pants;
|
||||
};
|
||||
|
||||
/**
|
||||
* The eye texture on succesive frames of Mario's blink animation.
|
||||
* He intentionally blinks twice each time.
|
||||
|
@ -72,12 +78,76 @@ 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
|
||||
|
||||
// ambient color is always half the diffuse color, so we can pull a macro
|
||||
#define DEFINE_PLAYER_COLOR(sr, sg, sb, pr, pg, pb) \
|
||||
{ \
|
||||
gdSPDefLights1((sr >> 1), (sg >> 1), (sb >> 1), sr, sg, sb, 0x28, 0x28, 0x28), \
|
||||
gdSPDefLights1((pr >> 1), (pg >> 1), (pb >> 1), pr, pg, pb, 0x28, 0x28, 0x28), \
|
||||
}
|
||||
|
||||
struct PlayerColor gPlayerColors[] = {
|
||||
// default mario
|
||||
DEFINE_PLAYER_COLOR(0xff, 0x00, 0x00, /**/ 0x00, 0x00, 0xff),
|
||||
// default luigi
|
||||
DEFINE_PLAYER_COLOR(0x00, 0x98, 0x00, /**/ 0x00, 0x00, 0xfe),
|
||||
#if MAX_PLAYERS > 2
|
||||
// fake waluigi
|
||||
DEFINE_PLAYER_COLOR(0x6d, 0x3c, 0x9a, /**/ 0x2c, 0x26, 0x3f),
|
||||
// fake wario
|
||||
DEFINE_PLAYER_COLOR(0xf9, 0xeb, 0x30, /**/ 0x7f, 0x20, 0x7a),
|
||||
// light blue
|
||||
DEFINE_PLAYER_COLOR(0x00, 0xdf, 0xff, /**/ 0x00, 0x00, 0xf0),
|
||||
// sponge
|
||||
DEFINE_PLAYER_COLOR(0xff, 0x7f, 0x00, /**/ 0x00, 0x7f, 0xa0),
|
||||
// blue man group
|
||||
DEFINE_PLAYER_COLOR(0x00, 0x00, 0xf0, /**/ 0x00, 0x00, 0x4f),
|
||||
// thanks doc
|
||||
DEFINE_PLAYER_COLOR(0xff, 0x00, 0xff, /**/ 0x00, 0xff, 0x00),
|
||||
// white
|
||||
DEFINE_PLAYER_COLOR(0xff, 0xff, 0xff, /**/ 0x10, 0x10, 0x10),
|
||||
// grey
|
||||
DEFINE_PLAYER_COLOR(0x6f, 0x6f, 0x6f, /**/ 0xe0, 0xe0, 0xe0),
|
||||
#endif
|
||||
};
|
||||
|
||||
static const size_t gNumPlayerColors = sizeof(gPlayerColors) / sizeof(*gPlayerColors);
|
||||
|
||||
// This whole file is weirdly organized. It has to be the same file due
|
||||
// to rodata boundaries and function aligns, which means the programmer
|
||||
// treated this like a "misc" file for vaguely Mario related things
|
||||
// (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 shirt[4], const u8 pants[4]) {
|
||||
// choose the last color in the table for extra players
|
||||
if (globalIndex >= gNumPlayerColors) globalIndex = gNumPlayerColors - 1;
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the specified color for player globalIndex.
|
||||
* 0 = shirt, 1 = pants
|
||||
* Returns RGB, not RGBA!
|
||||
*/
|
||||
u8 *get_player_color(u8 globalIndex, const int which) {
|
||||
// choose the last color in the table for extra players
|
||||
if (globalIndex >= gNumPlayerColors) globalIndex = gNumPlayerColors - 1;
|
||||
if (which == 0)
|
||||
return gPlayerColors[globalIndex].shirt.l[0].l.col;
|
||||
else
|
||||
return gPlayerColors[globalIndex].pants.l[0].l.col;
|
||||
}
|
||||
|
||||
/**
|
||||
* Geo node script that draws Mario's head on the title screen.
|
||||
*/
|
||||
|
@ -405,7 +475,8 @@ Gfx* geo_switch_mario_eyes(s32 callContext, struct GraphNode* node, UNUSED Mat4*
|
|||
Gfx* geo_mario_tilt_torso(s32 callContext, struct GraphNode* node, Mat4* mtx) {
|
||||
Mat4 * curTransform = mtx;
|
||||
struct GraphNodeGenerated* asGenerated = (struct GraphNodeGenerated*) node;
|
||||
struct MarioBodyState* bodyState = geo_get_body_state();
|
||||
u8 plrIdx = geo_get_processing_object_index();
|
||||
struct MarioBodyState* bodyState = &gBodyStates[plrIdx];
|
||||
s32 action = bodyState->action;
|
||||
|
||||
if (callContext == GEO_CONTEXT_RENDER) {
|
||||
|
@ -418,6 +489,11 @@ Gfx* geo_mario_tilt_torso(s32 callContext, struct GraphNode* node, Mat4* mtx) {
|
|||
rotNode->rotation[0] = bodyState->torsoAngle[1];
|
||||
rotNode->rotation[1] = bodyState->torsoAngle[2];
|
||||
rotNode->rotation[2] = bodyState->torsoAngle[0];
|
||||
if (plrIdx != 0) {
|
||||
// only interpolate angles for the local player
|
||||
vec3s_copy(rotNode->prevRotation, rotNode->rotation);
|
||||
rotNode->prevTimestamp = gGlobalTimer;
|
||||
}
|
||||
// update torso position in bodyState
|
||||
get_pos_from_transform_mtx(bodyState->torsoPos, *curTransform, *gCurGraphNodeCamera->matrixPtr);
|
||||
}
|
||||
|
@ -429,7 +505,8 @@ Gfx* geo_mario_tilt_torso(s32 callContext, struct GraphNode* node, Mat4* mtx) {
|
|||
*/
|
||||
Gfx* geo_mario_head_rotation(s32 callContext, struct GraphNode* node, UNUSED Mat4* c) {
|
||||
struct GraphNodeGenerated* asGenerated = (struct GraphNodeGenerated*) node;
|
||||
struct MarioBodyState* bodyState = geo_get_body_state();
|
||||
u8 plrIdx = geo_get_processing_object_index();
|
||||
struct MarioBodyState* bodyState = &gBodyStates[plrIdx];
|
||||
s32 action = bodyState->action;
|
||||
|
||||
if (callContext == GEO_CONTEXT_RENDER) {
|
||||
|
@ -449,6 +526,12 @@ Gfx* geo_mario_head_rotation(s32 callContext, struct GraphNode* node, UNUSED Mat
|
|||
vec3s_set(bodyState->headAngle, 0, 0, 0);
|
||||
vec3s_set(rotNode->rotation, 0, 0, 0);
|
||||
}
|
||||
|
||||
if (plrIdx != 0) {
|
||||
// only interpolate angles for the local player
|
||||
vec3s_copy(rotNode->prevRotation, rotNode->rotation);
|
||||
rotNode->prevTimestamp = gGlobalTimer;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -708,3 +791,31 @@ Gfx* geo_mirror_mario_backface_culling(s32 callContext, struct GraphNode* node,
|
|||
}
|
||||
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) {
|
||||
// extra players get last color
|
||||
if (colorIndex >= gNumPlayerColors) colorIndex = gNumPlayerColors - 1;
|
||||
gfx = alloc_display_list(5 * sizeof(*gfx));
|
||||
// put the player colors into lights 3, 4, 5, 6
|
||||
// they will be later copied to lights 1, 2 with gsSPCopyLightEXT
|
||||
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 layer 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;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
extern struct GraphNodeObject gMirrorMario[MAX_PLAYERS];
|
||||
extern struct MarioBodyState gBodyStates[MAX_PLAYERS];
|
||||
|
||||
void set_player_colors(u8 globalIndex, const u8 shirt[4], const u8 pants[4]);
|
||||
u8 *get_player_color(u8 globalIndex, const int which);
|
||||
|
||||
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 +30,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
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
#define RATIO_Y (gfx_current_dimensions.height / (2.0f * HALF_SCREEN_HEIGHT))
|
||||
|
||||
#define MAX_BUFFERED 256
|
||||
#define MAX_LIGHTS 2
|
||||
#define MAX_LIGHTS 8
|
||||
#define MAX_VERTICES 64
|
||||
|
||||
#ifdef EXTERNAL_DATA
|
||||
|
@ -1123,6 +1123,10 @@ static void gfx_sp_movemem(uint8_t index, uint8_t offset, const void* data) {
|
|||
case G_MV_L0:
|
||||
case G_MV_L1:
|
||||
case G_MV_L2:
|
||||
case G_MV_L3:
|
||||
case G_MV_L4:
|
||||
case G_MV_L5:
|
||||
case G_MV_L6:
|
||||
// NOTE: reads out of bounds if it is an ambient light
|
||||
memcpy(rsp.current_lights + (index - G_MV_L0) / 2, data, sizeof(Light_t));
|
||||
break;
|
||||
|
@ -1130,6 +1134,18 @@ static void gfx_sp_movemem(uint8_t index, uint8_t offset, const void* data) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef F3DEX_GBI_2E
|
||||
static void gfx_sp_copymem(uint8_t idx, uint8_t dstofs, uint8_t srcofs, uint8_t words) {
|
||||
if (idx == G_MV_LIGHT) {
|
||||
const int srcidx = srcofs / 24 - 2;
|
||||
const int dstidx = dstofs / 24 - 2;
|
||||
if (srcidx <= MAX_LIGHTS && dstidx <= MAX_LIGHTS) {
|
||||
memcpy(rsp.current_lights + dstidx, rsp.current_lights + srcidx, sizeof(Light_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void gfx_sp_moveword(uint8_t index, uint16_t offset, uint32_t data) {
|
||||
switch (index) {
|
||||
case G_MW_NUMLIGHT:
|
||||
|
@ -1538,6 +1554,11 @@ static void gfx_run_dl(Gfx* cmd) {
|
|||
gfx_sp_moveword(C0(0, 8), C0(8, 16), cmd->words.w1);
|
||||
#endif
|
||||
break;
|
||||
#ifdef F3DEX_GBI_2E
|
||||
case (uint8_t)G_COPYMEM:
|
||||
gfx_sp_copymem(C0(0, 8), C0(8, 8) * 8, C0(16, 8) * 8, C1(0, 8));
|
||||
break;
|
||||
#endif
|
||||
case (uint8_t)G_TEXTURE:
|
||||
#ifdef F3DEX_GBI_2
|
||||
gfx_sp_texture(C1(16, 16), C1(0, 16), C0(11, 3), C0(8, 3), C0(1, 7));
|
||||
|
|
|
@ -18,7 +18,7 @@ static void on_lobby_create_callback(UNUSED void* data, enum EDiscordResult resu
|
|||
gCurActivity.type = DiscordActivityType_Playing;
|
||||
snprintf(gCurActivity.party.id, 128, "%lld", lobby->id);
|
||||
gCurActivity.party.size.current_size = 1;
|
||||
gCurActivity.party.size.max_size = 2;
|
||||
gCurActivity.party.size.max_size = MAX_PLAYERS;
|
||||
|
||||
char secretJoin[128] = "";
|
||||
snprintf(secretJoin, 128, "%lld:%s", lobby->id, lobby->secret);
|
||||
|
@ -59,7 +59,7 @@ void discord_lobby_create(void) {
|
|||
struct IDiscordLobbyTransaction* txn = { 0 };
|
||||
|
||||
DISCORD_REQUIRE(app.lobbies->get_lobby_create_transaction(app.lobbies, &txn));
|
||||
txn->set_capacity(txn, 2);
|
||||
txn->set_capacity(txn, MAX_PLAYERS);
|
||||
txn->set_type(txn, DiscordLobbyType_Public);
|
||||
//txn->set_metadata(txn, "a", "123");
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <stdio.h>
|
||||
#include "network_player.h"
|
||||
#include "game/chat.h"
|
||||
#include "game/mario_misc.h"
|
||||
#include "pc/debuglog.h"
|
||||
|
||||
struct NetworkPlayer gNetworkPlayers[MAX_PLAYERS] = { 0 };
|
||||
|
@ -105,7 +106,7 @@ u8 network_player_connected(enum NetworkPlayerType type, u8 globalIndex) {
|
|||
gNetworkSystem->save_id(i);
|
||||
for (int j = 0; j < MAX_SYNC_OBJECTS; j++) { gSyncObjects[j].rxEventId[i] = 0; }
|
||||
if (type == NPT_SERVER) { gNetworkPlayerServer = np; }
|
||||
else { chat_add_message("player connected", CMT_SYSTEM); }
|
||||
else { chat_add_message_ext("player connected", CMT_SYSTEM, get_player_color(np->globalIndex, 0)); }
|
||||
LOG_INFO("player connected, local %d, global %d", i, np->globalIndex);
|
||||
extern s16 sCurrPlayMode;
|
||||
if (gNetworkType == NT_SERVER && sCurrPlayMode == PLAY_MODE_SYNC_LEVEL) {
|
||||
|
@ -142,7 +143,7 @@ u8 network_player_disconnected(u8 globalIndex) {
|
|||
gNetworkSystem->clear_id(i);
|
||||
for (int j = 0; j < MAX_SYNC_OBJECTS; j++) { gSyncObjects[j].rxEventId[i] = 0; }
|
||||
LOG_INFO("player disconnected, local %d, global %d", i, globalIndex);
|
||||
chat_add_message("player disconnected", CMT_SYSTEM);
|
||||
chat_add_message_ext("player disconnected", CMT_SYSTEM, get_player_color(globalIndex, 0));
|
||||
return i;
|
||||
}
|
||||
return UNKNOWN_GLOBAL_INDEX;
|
||||
|
|
|
@ -56,6 +56,7 @@ void packet_receive(struct Packet* p) {
|
|||
case PACKET_INSTANT_WARP: network_receive_instant_warp(p); break;
|
||||
case PACKET_NETWORK_PLAYERS: network_receive_network_players(p); break;
|
||||
case PACKET_DEATH: network_receive_death(p); break;
|
||||
case PACKET_LEVEL_WARP_2: network_receive_level_warp_2(p); break;
|
||||
///
|
||||
case PACKET_CUSTOM: network_receive_custom(p); break;
|
||||
default: LOG_ERROR("received unknown packet: %d", p->buffer[0]);
|
||||
|
|
|
@ -33,6 +33,7 @@ enum PacketType {
|
|||
PACKET_INSTANT_WARP,
|
||||
PACKET_NETWORK_PLAYERS,
|
||||
PACKET_DEATH,
|
||||
PACKET_LEVEL_WARP_2,
|
||||
///
|
||||
PACKET_CUSTOM = 255,
|
||||
};
|
||||
|
@ -140,7 +141,7 @@ void network_send_custom(u8 customId, bool reliable, bool levelAreaMustMatch, vo
|
|||
void network_receive_custom(struct Packet* p);
|
||||
|
||||
// packet_chat.c
|
||||
void network_send_chat(char* message);
|
||||
void network_send_chat(char* message, u8 rgb[3]);
|
||||
void network_receive_chat(struct Packet* p);
|
||||
|
||||
// packet_kick.c
|
||||
|
@ -171,4 +172,9 @@ void network_receive_network_players(struct Packet* p);
|
|||
void network_send_death(void);
|
||||
void network_receive_death(struct Packet* p);
|
||||
|
||||
// packet_level_warp_2.c
|
||||
void network_send_level_warp_2(u8 eventBegins, u8 controlledGlobalIndex);
|
||||
void network_receive_level_warp_2(struct Packet* p);
|
||||
u8 network_is_warp_2_duplicate(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,10 +17,11 @@ static void print_sync_object_table(void) {
|
|||
}
|
||||
#endif
|
||||
|
||||
void network_send_chat(char* message) {
|
||||
void network_send_chat(char* message, u8 rgb[3]) {
|
||||
u16 messageLength = strlen(message);
|
||||
struct Packet p;
|
||||
packet_init(&p, PACKET_CHAT, true, false);
|
||||
packet_write(&p, rgb, 3 * sizeof(u8));
|
||||
packet_write(&p, &messageLength, sizeof(u16));
|
||||
packet_write(&p, message, messageLength * sizeof(u8));
|
||||
network_send(&p);
|
||||
|
@ -34,13 +35,15 @@ void network_send_chat(char* message) {
|
|||
void network_receive_chat(struct Packet* p) {
|
||||
u16 remoteMessageLength = 0;
|
||||
char remoteMessage[255] = { 0 };
|
||||
u8 rgb[3] = { 255, 255, 255};
|
||||
|
||||
packet_read(p, rgb, 3 * sizeof(u8));
|
||||
packet_read(p, &remoteMessageLength, sizeof(u16));
|
||||
if (remoteMessageLength > 255) { remoteMessageLength = 254; }
|
||||
packet_read(p, &remoteMessage, remoteMessageLength * sizeof(u8));
|
||||
|
||||
// add the message
|
||||
chat_add_message(remoteMessage, CMT_REMOTE);
|
||||
chat_add_message_ext(remoteMessage, CMT_REMOTE, rgb);
|
||||
LOG_INFO("rx chat: %s", remoteMessage);
|
||||
|
||||
#ifdef DEVELOPMENT
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
#include "../network.h"
|
||||
#include "game/level_update.h"
|
||||
#include "game/object_list_processor.h"
|
||||
//#define DISABLE_MODULE_LOG
|
||||
#include "pc/debuglog.h"
|
||||
|
||||
#define SERVER_RETAIN_WARP_SECONDS 1
|
||||
|
||||
extern u8 gControlledWarpGlobalIndex;
|
||||
extern float gPaintingMarioYEntry;
|
||||
|
||||
#pragma pack(1)
|
||||
struct PacketLevelWarp2Data {
|
||||
s16 levelNum;
|
||||
s16 areaIndex;
|
||||
s16 actNum;
|
||||
|
||||
u8 warpType;
|
||||
u8 warpLevelNum;
|
||||
u8 warpAreaIdx;
|
||||
u8 warpNodeId;
|
||||
u32 warpArg;
|
||||
|
||||
s8 inWarpCheckpoint;
|
||||
s16 ttcSpeedSetting;
|
||||
s16 D_80339EE0;
|
||||
f32 paintingMarioYEntry;
|
||||
u8 controlledWarpGlobalIndex;
|
||||
};
|
||||
|
||||
struct PacketLevelWarp2Data sSavedLevelWarp2Data = { 0 };
|
||||
static clock_t sSavedClockTime = 0;
|
||||
|
||||
static void populate_packet_data(struct PacketLevelWarp2Data* data) {
|
||||
data->levelNum = gCurrLevelNum;
|
||||
data->areaIndex = gCurrAreaIndex;
|
||||
data->actNum = gCurrActNum;
|
||||
|
||||
data->warpType = sWarpDest.type;
|
||||
data->warpLevelNum = sWarpDest.levelNum;
|
||||
data->warpAreaIdx = sWarpDest.areaIdx;
|
||||
data->warpNodeId = sWarpDest.nodeId;
|
||||
data->warpArg = sWarpDest.arg;
|
||||
|
||||
data->inWarpCheckpoint = gInWarpCheckpoint;
|
||||
data->ttcSpeedSetting = gTTCSpeedSetting;
|
||||
data->D_80339EE0 = D_80339EE0;
|
||||
data->paintingMarioYEntry = gPaintingMarioYEntry;
|
||||
data->controlledWarpGlobalIndex = gControlledWarpGlobalIndex;
|
||||
}
|
||||
|
||||
void network_send_level_warp_2(u8 eventBegins, u8 controlledGlobalIndex) {
|
||||
struct PacketLevelWarp2Data data = { 0 };
|
||||
if (eventBegins) {
|
||||
gControlledWarpGlobalIndex = controlledGlobalIndex;
|
||||
populate_packet_data(&data);
|
||||
if (gNetworkType == NT_SERVER) {
|
||||
sSavedLevelWarp2Data = data;
|
||||
sSavedClockTime = clock();
|
||||
}
|
||||
} else {
|
||||
data = sSavedLevelWarp2Data;
|
||||
}
|
||||
|
||||
struct Packet p;
|
||||
packet_init(&p, PACKET_LEVEL_WARP_2, true, false);
|
||||
packet_write(&p, &data, sizeof(struct PacketLevelWarp2Data));
|
||||
|
||||
if (gNetworkType == NT_SERVER) {
|
||||
network_send(&p);
|
||||
} else {
|
||||
network_send_to(gNetworkPlayerServer->localIndex, &p);
|
||||
}
|
||||
|
||||
LOG_INFO("send warp: %d, %d, %d", gCurrLevelNum, gCurrAreaIndex, gCurrActNum);
|
||||
}
|
||||
|
||||
static void do_warp(struct PacketLevelWarp2Data* data) {
|
||||
if (gCurrLevelNum != data->levelNum ) { gChangeLevel = data->levelNum; }
|
||||
|
||||
sWarpDest.type = data->warpType;
|
||||
sWarpDest.levelNum = data->warpLevelNum;
|
||||
sWarpDest.areaIdx = data->warpAreaIdx;
|
||||
sWarpDest.nodeId = data->warpNodeId;
|
||||
sWarpDest.arg = data->warpArg;
|
||||
|
||||
gInWarpCheckpoint = data->inWarpCheckpoint;
|
||||
gTTCSpeedSetting = data->ttcSpeedSetting;
|
||||
D_80339EE0 = data->D_80339EE0;
|
||||
gPaintingMarioYEntry = data->paintingMarioYEntry;
|
||||
gControlledWarpGlobalIndex = data->controlledWarpGlobalIndex;
|
||||
|
||||
gCurrLevelNum = data->levelNum;
|
||||
gCurrAreaIndex = data->areaIndex;
|
||||
gCurrActNum = data->actNum;
|
||||
|
||||
LOG_INFO("do warp: %d, %d, %d", gCurrLevelNum, gCurrAreaIndex, gCurrActNum);
|
||||
}
|
||||
|
||||
void network_receive_level_warp_2(struct Packet* p) {
|
||||
struct PacketLevelWarp2Data remote = { 0 };
|
||||
packet_read(p, &remote, sizeof(struct PacketLevelWarp2Data));
|
||||
LOG_INFO("rx warp: %d, %d, %d", remote.levelNum, remote.areaIndex, remote.actNum);
|
||||
|
||||
u8 levelOrAreaDifference = (gCurrLevelNum != remote.levelNum) || (gCurrAreaIndex != remote.areaIndex);
|
||||
|
||||
if (gNetworkType == NT_SERVER) {
|
||||
f32 elapsed = (clock() - sSavedClockTime) / (f32)CLOCKS_PER_SEC;
|
||||
if (elapsed < SERVER_RETAIN_WARP_SECONDS || !levelOrAreaDifference) {
|
||||
network_send_level_warp_2(FALSE, gNetworkPlayerLocal->globalIndex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (levelOrAreaDifference) {
|
||||
do_warp(&remote);
|
||||
}
|
||||
|
||||
if (gNetworkType == NT_CLIENT) {
|
||||
sSavedLevelWarp2Data = remote;
|
||||
sSavedClockTime = clock();
|
||||
}
|
||||
|
||||
if (gNetworkType == NT_SERVER) {
|
||||
network_send_level_warp_2(TRUE, remote.controlledWarpGlobalIndex);
|
||||
} else {
|
||||
sCurrPlayMode = PLAY_MODE_NORMAL;
|
||||
network_on_init_level();
|
||||
}
|
||||
}
|
||||
|
||||
u8 network_is_warp_2_duplicate(void) {
|
||||
struct PacketLevelWarp2Data data = { 0 };
|
||||
populate_packet_data(&data);
|
||||
|
||||
if (data.levelNum == 1 && data.areaIndex == 1) { return TRUE; }
|
||||
|
||||
if (gNetworkType == NT_SERVER) {
|
||||
f32 elapsed = (clock() - sSavedClockTime) / (f32)CLOCKS_PER_SEC;
|
||||
if (elapsed >= SERVER_RETAIN_WARP_SECONDS) { return FALSE; }
|
||||
}
|
||||
return (memcmp(&sSavedLevelWarp2Data, &data, sizeof(struct PacketLevelWarp2Data)) == 0);
|
||||
}
|
|
@ -10,6 +10,7 @@
|
|||
#include "engine/surface_collision.h"
|
||||
#include "game/object_list_processor.h"
|
||||
#include "game/chat.h"
|
||||
#include "game/mario_misc.h"
|
||||
#include "pc/configfile.h"
|
||||
|
||||
#pragma pack(1)
|
||||
|
@ -336,7 +337,7 @@ void network_receive_player(struct Packet* p) {
|
|||
|
||||
// inform of player death
|
||||
if (oldData.action != ACT_BUBBLED && data.action == ACT_BUBBLED) {
|
||||
chat_add_message("player died", CMT_SYSTEM);
|
||||
chat_add_message_ext("player died", CMT_SYSTEM, get_player_color(globalIndex, 0));
|
||||
}
|
||||
|
||||
// action changed, reset timer
|
||||
|
@ -345,7 +346,7 @@ void network_receive_player(struct Packet* p) {
|
|||
}
|
||||
|
||||
// set model
|
||||
enum CharacterType characterType = (np->globalIndex == 1) ? CT_LUIGI : CT_MARIO;
|
||||
enum CharacterType characterType = (np->globalIndex == 0) ? CT_MARIO : CT_LUIGI;
|
||||
m->character = &gCharacters[characterType];
|
||||
m->marioObj->header.gfx.sharedChild = gLoadedGraphNodes[m->character->modelId];
|
||||
}
|
||||
|
|
|
@ -27,6 +27,17 @@ SOCKET socket_initialize(void) {
|
|||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
#if MAX_PLAYERS > 4
|
||||
// on windows, the send buffer for the socket needs to be increased
|
||||
// for the many players case to avoid WSAEWOULDBLOCK on send
|
||||
// not actually sure this is the "proper" way to fix it
|
||||
int bufsiz = 128 * 1024; // 128kb, default is apparently 8kb or 16kb
|
||||
rc = setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (const char *)&bufsiz, sizeof(bufsiz));
|
||||
if (rc != NO_ERROR) {
|
||||
LOG_ERROR("setsockopt(SO_SNDBUF) failed with error: %d", rc);
|
||||
}
|
||||
#endif
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define VERSION_H
|
||||
|
||||
#define UNSTABLE_BRANCH
|
||||
#define VERSION_NUMBER 2
|
||||
#define VERSION_NUMBER 3
|
||||
|
||||
#define MAX_VERSION_LENGTH 10
|
||||
char* get_version(void);
|
||||
|
|
Loading…
Reference in New Issue