Started synchronizing objects, refactored networking
This commit is contained in:
parent
42a52ad936
commit
579415dca9
2
Makefile
2
Makefile
|
@ -286,7 +286,7 @@ LEVEL_DIRS := $(patsubst levels/%,%,$(dir $(wildcard levels/*/header.h)))
|
|||
# Directories containing source files
|
||||
|
||||
# Hi, I'm a PC
|
||||
SRC_DIRS := src src/engine src/game src/audio src/menu src/buffers actors levels bin data assets src/pc src/pc/gfx src/pc/audio src/pc/controller src/pc/fs src/pc/fs/packtypes src/pc/network
|
||||
SRC_DIRS := src src/engine src/game src/audio src/menu src/buffers actors levels bin data assets src/pc src/pc/gfx src/pc/audio src/pc/controller src/pc/fs src/pc/fs/packtypes src/pc/network src/pc/network/packets
|
||||
ASM_DIRS :=
|
||||
|
||||
ifeq ($(DISCORDRPC),1)
|
||||
|
|
|
@ -3943,7 +3943,7 @@
|
|||
<ClCompile Include="..\src\pc\gfx\gfx_sdl2.c" />
|
||||
<ClCompile Include="..\src\pc\ini.c" />
|
||||
<ClCompile Include="..\src\pc\mixer.c" />
|
||||
<ClCompile Include="..\src\pc\network\network_pc.c" />
|
||||
<ClCompile Include="..\src\pc\network\network.c" />
|
||||
<ClCompile Include="..\src\pc\pc_main.c" />
|
||||
<ClCompile Include="..\src\pc\platform.c" />
|
||||
<ClCompile Include="..\src\pc\ultra_reimplementation.c" />
|
||||
|
@ -3979,6 +3979,7 @@
|
|||
<ClCompile Include="..\tools\textconv.c" />
|
||||
<ClCompile Include="..\tools\utf8.c" />
|
||||
<ClCompile Include="..\tools\utils.c" />
|
||||
<ClCompile Include="packet_player.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\actors\common0.h" />
|
||||
|
@ -4282,8 +4283,7 @@
|
|||
<ClCompile Include="..\tools\utils.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\pc\network\network_api.h" />
|
||||
<ClInclude Include="..\src\pc\network\network_pc.h" />
|
||||
<ClInclude Include="..\src\pc\network\network.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
|
|
@ -3418,6 +3418,9 @@
|
|||
<Filter Include="Header Files\src\pc\network">
|
||||
<UniqueIdentifier>{1c96986a-a883-42fa-adb0-1f0998af2961}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\src\pc\network\packets">
|
||||
<UniqueIdentifier>{f7dcd9e2-f84f-4c82-96c5-0dc32d408693}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\actors\amp\anims\anim_0800401C.inc.c">
|
||||
|
@ -14937,9 +14940,12 @@
|
|||
<ClCompile Include="..\actors\mario\geo2.inc.c">
|
||||
<Filter>Source Files\actors\mario</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\pc\network\network_pc.c">
|
||||
<ClCompile Include="..\src\pc\network\network.c">
|
||||
<Filter>Source Files\src\pc\network</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="packet_player.c">
|
||||
<Filter>Source Files\src\pc\network\packets</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\actors\common0.h">
|
||||
|
@ -15841,10 +15847,7 @@
|
|||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\pc\network\network_api.h">
|
||||
<Filter>Header Files\src\pc\network</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\pc\network\network_pc.h">
|
||||
<ClInclude Include="..\src\pc\network\network.h">
|
||||
<Filter>Header Files\src\pc\network</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
#define /*0x090*/ oDialogResponse OBJECT_FIELD_S16(0x02, 0)
|
||||
#define /*0x092*/ oDialogState OBJECT_FIELD_S16(0x02, 1)
|
||||
#define /*0x094*/ oUnk94 OBJECT_FIELD_U32(0x03)
|
||||
// 0x98 unused/removed.
|
||||
#define /*0x098*/ oSyncID OBJECT_FIELD_U32(0x04)
|
||||
#define /*0x09C*/ oIntangibleTimer OBJECT_FIELD_S32(0x05)
|
||||
#define /*0x0A0*/ O_POS_INDEX 0x06
|
||||
#define /*0x0A0*/ oPosX OBJECT_FIELD_F32(O_POS_INDEX + 0)
|
||||
|
|
|
@ -90,7 +90,7 @@ static const LevelScript script_func_local_4[] = {
|
|||
OBJECT(/*model*/ MODEL_BUTTERFLY, /*pos*/ -1204, 326, 3296, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvButterfly),
|
||||
OBJECT(/*model*/ MODEL_YOSHI, /*pos*/ 0, 3174, -5625, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvYoshi),
|
||||
// TESTING BELOW
|
||||
//OBJECT(/*model*/ MODEL_BLACK_BOBOMB, /*pos*/ -2028, 260, 4664, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvBobomb),
|
||||
OBJECT(/*model*/ MODEL_BLACK_BOBOMB, /*pos*/ -2028, 260, 4664, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvBobomb),
|
||||
//OBJECT(/*model*/ MODEL_NONE, /*pos*/ -2028, 260, 3264, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvGoombaTripletSpawner),
|
||||
RETURN(),
|
||||
};
|
||||
|
|
|
@ -17,6 +17,7 @@ void bhv_bobomb_init(void) {
|
|||
o->oFriction = 0.8;
|
||||
o->oBuoyancy = 1.3;
|
||||
o->oInteractionSubtype = INT_SUBTYPE_KICKABLE;
|
||||
network_init_object(o);
|
||||
}
|
||||
|
||||
void bobomb_spawn_coin(void) {
|
||||
|
@ -139,7 +140,7 @@ void generic_bobomb_free_loop(void) {
|
|||
bobomb_check_interactions();
|
||||
|
||||
if (o->oBobombFuseTimer >= 151)
|
||||
o->oAction = 3;
|
||||
o->oAction = BOBOMB_ACT_EXPLODE;
|
||||
}
|
||||
|
||||
void stationary_bobomb_free_loop(void) {
|
||||
|
|
|
@ -39,8 +39,6 @@
|
|||
#include "bettercamera.h"
|
||||
#endif
|
||||
|
||||
#include "../pc/network/network.h"
|
||||
|
||||
u32 unused80339F10;
|
||||
s8 filler80339F1C[20];
|
||||
|
||||
|
@ -1940,8 +1938,6 @@ skippy:
|
|||
init_mario();
|
||||
gMarioState = &gMarioStates[0];
|
||||
}
|
||||
|
||||
network_track(gMarioStates);
|
||||
}
|
||||
|
||||
void init_mario_from_save_file(void) {
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "save_file.h"
|
||||
#include "spawn_object.h"
|
||||
#include "spawn_sound.h"
|
||||
#include "pc/network/network.h"
|
||||
|
||||
/**
|
||||
* @file obj_behaviors.c
|
||||
|
|
|
@ -1,30 +1,20 @@
|
|||
#include <stdio.h>
|
||||
#include "network.h"
|
||||
#include "object_fields.h"
|
||||
#include "object_constants.h"
|
||||
|
||||
// Winsock includes
|
||||
#include <winsock2.h>
|
||||
#include <Ws2tcpip.h>
|
||||
//#pragma comment(lib, "Ws2_32.lib")
|
||||
|
||||
//////////////////////////
|
||||
// TODO: port to linux! //
|
||||
//////////////////////////
|
||||
|
||||
#ifndef UNICODE
|
||||
#define UNICODE
|
||||
#endif
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <Ws2tcpip.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// Link with ws2_32.lib
|
||||
#pragma comment(lib, "Ws2_32.lib")
|
||||
|
||||
#include "network.h"
|
||||
|
||||
#define NETWORKTYPESTR (networkType == NT_CLIENT ? "Client" : "Server")
|
||||
enum NetworkType networkType;
|
||||
SOCKET gSocket;
|
||||
#define BUFFER_LENGTH 1024
|
||||
unsigned short txPort;
|
||||
char* txIpAddr = "127.0.0.1";
|
||||
|
||||
struct MarioState *marioStates = NULL;
|
||||
|
||||
void network_init(enum NetworkType inNetworkType) {
|
||||
networkType = inNetworkType;
|
||||
|
@ -53,78 +43,62 @@ void network_init(enum NetworkType inNetworkType) {
|
|||
printf("%s ioctlsocket failed with error: %ld\n", NETWORKTYPESTR, rc);
|
||||
}
|
||||
|
||||
if (networkType == NT_SERVER) {
|
||||
//-----------------------------------------------
|
||||
// Bind the socket to any address and the specified port.
|
||||
struct sockaddr_in rxAddr;
|
||||
rxAddr.sin_family = AF_INET;
|
||||
rxAddr.sin_port = htons(27015);
|
||||
rxAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
rc = bind(gSocket, (SOCKADDR *)& rxAddr, sizeof(rxAddr));
|
||||
if (rc != 0) {
|
||||
wprintf(L"%s bind failed with error %d\n", NETWORKTYPESTR, WSAGetLastError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (networkType == NT_CLIENT) {
|
||||
txPort = htons(27015);
|
||||
// Bind the socket to any address and the specified port.
|
||||
struct sockaddr_in rxAddr;
|
||||
rxAddr.sin_family = AF_INET;
|
||||
rxAddr.sin_port = htons(networkType == NT_SERVER ? 27015 : 27016);
|
||||
rxAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
rc = bind(gSocket, (SOCKADDR *)& rxAddr, sizeof(rxAddr));
|
||||
if (rc != 0) {
|
||||
wprintf(L"%s bind failed with error %d\n", NETWORKTYPESTR, WSAGetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
// Save the port to send to
|
||||
txPort = htons(networkType == NT_SERVER ? 27016 : 27015);
|
||||
}
|
||||
|
||||
void network_track(struct MarioState *inMarioStates) {
|
||||
marioStates = inMarioStates;
|
||||
}
|
||||
|
||||
void network_send(char* buffer, int buffer_length) {
|
||||
void network_send(struct Packet* p) {
|
||||
if (networkType == NT_NONE) { return; }
|
||||
if (p->error) { printf("%s packet error!\n", NETWORKTYPESTR); return; }
|
||||
struct sockaddr_in txAddr;
|
||||
txAddr.sin_family = AF_INET;
|
||||
txAddr.sin_port = txPort;
|
||||
txAddr.sin_addr.s_addr = inet_addr(txIpAddr);
|
||||
txAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||
|
||||
int rc = sendto(gSocket, buffer, buffer_length, 0, (SOCKADDR *)& txAddr, sizeof(txAddr));
|
||||
int rc = sendto(gSocket, p->buffer, p->cursor, 0, (SOCKADDR *)& txAddr, sizeof(txAddr));
|
||||
if (rc == SOCKET_ERROR) {
|
||||
wprintf(L"%s sendto failed with error: %d\n", NETWORKTYPESTR, WSAGetLastError());
|
||||
closesocket(gSocket);
|
||||
WSACleanup();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void network_update(void) {
|
||||
if (networkType == NT_NONE) { return; }
|
||||
char buffer[BUFFER_LENGTH];
|
||||
struct sockaddr_in rxAddr;
|
||||
int rxAddrSize = sizeof(rxAddr);
|
||||
|
||||
if (marioStates != NULL) {
|
||||
memcpy(&buffer[0], &marioStates[0], 96);
|
||||
memcpy(&buffer[96], marioStates[0].controller, 20);
|
||||
memcpy(&buffer[96 + 20], marioStates[0].marioObj->rawData.asU32, 320);
|
||||
network_send(buffer, 96 + 20 + 320);
|
||||
}
|
||||
network_send_player();
|
||||
network_send_object(NULL);
|
||||
|
||||
do {
|
||||
int rc = recvfrom(gSocket, buffer, BUFFER_LENGTH, 0, (SOCKADDR *)&rxAddr, &rxAddrSize);
|
||||
struct sockaddr_in rxAddr;
|
||||
int rxAddrSize = sizeof(rxAddr);
|
||||
struct Packet p = { .cursor = 1 };
|
||||
int rc = recvfrom(gSocket, p.buffer, PACKET_LENGTH, 0, (SOCKADDR *)&rxAddr, &rxAddrSize);
|
||||
if (rc == SOCKET_ERROR) {
|
||||
int error = WSAGetLastError();
|
||||
if (error != WSAEWOULDBLOCK && error != WSAECONNRESET) {
|
||||
wprintf(L"%s recvfrom failed with error %d\n", NETWORKTYPESTR, WSAGetLastError());
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (networkType == NT_SERVER) { txPort = rxAddr.sin_port; }
|
||||
|
||||
if (rc != 96 + 20 + 320) {
|
||||
printf("%s received error: %s\n", NETWORKTYPESTR, rc);
|
||||
break;
|
||||
} else if (marioStates != NULL) {
|
||||
int oldActionState = marioStates[1].actionState;
|
||||
memcpy(&marioStates[1], &buffer[0], 96);
|
||||
memcpy(marioStates[1].controller, &buffer[96], 20);
|
||||
memcpy(&marioStates[1].marioObj->rawData.asU32, &buffer[96 + 20], 320);
|
||||
marioStates[1].actionState = oldActionState;
|
||||
}
|
||||
if (rc == 0) { break; }
|
||||
|
||||
switch (p.buffer[0]) {
|
||||
case PACKET_PLAYER: network_receive_player(&p); break;
|
||||
case PACKET_OBJECT: network_receive_object(&p); break;
|
||||
default: printf("%s received unknown packet: %d\n", NETWORKTYPESTR, p.buffer[0]);
|
||||
}
|
||||
|
||||
} while (1);
|
||||
|
||||
}
|
||||
|
|
|
@ -4,10 +4,39 @@
|
|||
#include <types.h>
|
||||
#include "../cliopts.h"
|
||||
|
||||
#define PACKET_LENGTH 1024
|
||||
#define NETWORKTYPESTR (networkType == NT_CLIENT ? "Client" : "Server")
|
||||
|
||||
extern struct MarioState gMarioStates[];
|
||||
extern enum NetworkType networkType;
|
||||
|
||||
enum PacketType {
|
||||
PACKET_PLAYER,
|
||||
PACKET_OBJECT
|
||||
};
|
||||
|
||||
struct Packet {
|
||||
int cursor;
|
||||
bool error;
|
||||
char buffer[PACKET_LENGTH];
|
||||
};
|
||||
|
||||
void network_init(enum NetworkType networkType);
|
||||
void network_track(struct MarioState *marioStates);
|
||||
void network_send(char* buffer, int buffer_length);
|
||||
void network_init_object(struct Object *object);
|
||||
void network_send(struct Packet* p);
|
||||
void network_update(void);
|
||||
void network_shutdown(void);
|
||||
|
||||
// packet read / write
|
||||
void packet_init(struct Packet* packet, enum PacketType packetType);
|
||||
void packet_write(struct Packet* packet, void* data, int length);
|
||||
void packet_read(struct Packet* packet, void* data, int length);
|
||||
|
||||
// packet headers
|
||||
void network_send_player(void);
|
||||
void network_receive_player(struct Packet* p);
|
||||
|
||||
void network_send_object(struct Object* o);
|
||||
void network_receive_object(struct Packet* p);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
#include <stdio.h>
|
||||
#include "../network.h"
|
||||
#include "object_fields.h"
|
||||
#include "object_constants.h"
|
||||
|
||||
u32 nextSyncID = 1;
|
||||
struct Object* syncObject = NULL;
|
||||
|
||||
float player_distance(struct MarioState* marioState, struct Object* obj) {
|
||||
if (marioState->marioObj == NULL) { return 0; }
|
||||
f32 mx = marioState->marioObj->header.gfx.pos[0] - obj->oPosX;
|
||||
f32 my = marioState->marioObj->header.gfx.pos[1] - obj->oPosY;
|
||||
f32 mz = marioState->marioObj->header.gfx.pos[2] - obj->oPosZ;
|
||||
mx *= mx;
|
||||
my *= my;
|
||||
mz *= mz;
|
||||
return sqrt(mx + my + mz);
|
||||
}
|
||||
|
||||
void network_init_object(struct Object *object) {
|
||||
object->oSyncID = nextSyncID++;
|
||||
syncObject = object;
|
||||
}
|
||||
|
||||
void network_send_object(struct Object* o) {
|
||||
o = syncObject;
|
||||
if (o == NULL) { return; }
|
||||
if (o->activeFlags == ACTIVE_FLAG_DEACTIVATED) { return; }
|
||||
if (player_distance(&gMarioStates[0], o) > player_distance(&gMarioStates[1], o)) { return; }
|
||||
|
||||
struct Packet p;
|
||||
packet_init(&p, PACKET_OBJECT);
|
||||
packet_write(&p, &o->oSyncID, 4);
|
||||
packet_write(&p, &o->oPosX, 28);
|
||||
packet_write(&p, &o->oAction, 4);
|
||||
packet_write(&p, &o->oHeldState, 4);
|
||||
packet_write(&p, &o->oMoveAngleYaw, 4);
|
||||
|
||||
network_send(&p);
|
||||
}
|
||||
|
||||
void network_receive_object(struct Packet* p) {
|
||||
if (syncObject == NULL) { return; }
|
||||
u32 syncId;
|
||||
packet_read(p, &syncId, 4);
|
||||
packet_read(p, &syncObject->oPosX, 28);
|
||||
packet_read(p, &syncObject->oAction, 4);
|
||||
packet_read(p, &syncObject->oHeldState, 4);
|
||||
packet_read(p, &syncObject->oMoveAngleYaw, 4);
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
#include <stdio.h>
|
||||
#include "../network.h"
|
||||
|
||||
void network_send_player(void) {
|
||||
if (gMarioStates[0].marioObj == NULL) { return; }
|
||||
struct Packet p;
|
||||
packet_init(&p, PACKET_PLAYER);
|
||||
packet_write(&p, &gMarioStates[0], 96);
|
||||
packet_write(&p, gMarioStates[0].controller, 20);
|
||||
packet_write(&p, gMarioStates[0].marioObj->rawData.asU32, 320);
|
||||
network_send(&p);
|
||||
}
|
||||
|
||||
void network_receive_player(struct Packet* p) {
|
||||
if (gMarioStates[1].marioObj == NULL) { return; }
|
||||
int oldActionState = gMarioStates[1].actionState;
|
||||
|
||||
packet_read(p, &gMarioStates[1], 96);
|
||||
packet_read(p, gMarioStates[1].controller, 20);
|
||||
packet_read(p, &gMarioStates[1].marioObj->rawData.asU32, 320);
|
||||
|
||||
// restore action state, needed for jump kicking
|
||||
gMarioStates[1].actionState = oldActionState;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
#include "../network.h"
|
||||
|
||||
void packet_init(struct Packet* packet, enum PacketType packetType) {
|
||||
memset(packet->buffer, 0, PACKET_LENGTH);
|
||||
packet->buffer[0] = (char)packetType;
|
||||
packet->cursor = 1;
|
||||
packet->error = false;
|
||||
}
|
||||
|
||||
void packet_write(struct Packet* packet, void* data, int length) {
|
||||
if (data == NULL) { packet->error = true; return; }
|
||||
memcpy(&packet->buffer[packet->cursor], data, length);
|
||||
packet->cursor += length;
|
||||
}
|
||||
|
||||
void packet_read(struct Packet* packet, void* data, int length) {
|
||||
if (data == NULL) { packet->error = true; return; }
|
||||
memcpy(data, &packet->buffer[packet->cursor], length);
|
||||
packet->cursor += length;
|
||||
}
|
Loading…
Reference in New Issue