Started adding networking

This commit is contained in:
MysterD 2020-08-01 20:22:24 -07:00
parent 0ad65c87da
commit 34b1ec76f6
12 changed files with 227 additions and 10 deletions

View file

@ -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_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
ASM_DIRS :=
ifeq ($(DISCORDRPC),1)
@ -617,7 +617,7 @@ ifeq ($(TARGET_WEB),1)
LDFLAGS := -lm -lGL -lSDL2 -no-pie -s TOTAL_MEMORY=20MB -g4 --source-map-base http://localhost:8080/ -s "EXTRA_EXPORTED_RUNTIME_METHODS=['callMain']"
else ifeq ($(WINDOWS_BUILD),1)
LDFLAGS := $(BITS) -march=$(TARGET_ARCH) -Llib -lpthread $(BACKEND_LDFLAGS) -static
LDFLAGS := $(BITS) -march=$(TARGET_ARCH) -Llib -L"ws2_32" -lwsock32 -lpthread $(BACKEND_LDFLAGS) -static
ifeq ($(CROSS),)
LDFLAGS += -no-pie
endif

View file

@ -3943,6 +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\pc_main.c" />
<ClCompile Include="..\src\pc\platform.c" />
<ClCompile Include="..\src\pc\ultra_reimplementation.c" />
@ -4280,6 +4281,10 @@
<ClCompile Include="..\tools\utf8.h" />
<ClCompile Include="..\tools\utils.h" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\pc\network\network_api.h" />
<ClInclude Include="..\src\pc\network\network_pc.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

View file

@ -3412,6 +3412,12 @@
<Filter Include="Header Files\tools\sdk-tools\tabledesign">
<UniqueIdentifier>{c3e4f1bd-5aac-4a18-90cf-7a3e74132018}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\src\pc\network">
<UniqueIdentifier>{4c8b8213-2929-496d-8b5b-2a06d5880d2b}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\src\pc\network">
<UniqueIdentifier>{1c96986a-a883-42fa-adb0-1f0998af2961}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\actors\amp\anims\anim_0800401C.inc.c">
@ -14931,6 +14937,9 @@
<ClCompile Include="..\actors\mario\geo2.inc.c">
<Filter>Source Files\actors\mario</Filter>
</ClCompile>
<ClCompile Include="..\src\pc\network\network_pc.c">
<Filter>Source Files\src\pc\network</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\actors\common0.h">
@ -15831,4 +15840,12 @@
<Filter>Header Files\tools</Filter>
</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">
<Filter>Header Files\src\pc\network</Filter>
</ClInclude>
</ItemGroup>
</Project>

14
cgdb.exe.stackdump Normal file
View file

@ -0,0 +1,14 @@
Stack trace:
Frame Function Args
000FFFFB418 00180063480 (000FFFFB638, 00000000002, 00000000000, 000FFFFDE50)
000FFFFDE50 0018006563C (000FFFFBC70, 00000000000, 0000000032C, 00000000000)
000FFFFBB40 00180147028 (7FFEB01920AA, 00000000000, 7FFEB285B55F, 00000000000)
000FFFFBE80 00180170764 (00000000000, 00000000000, 00000000000, 00000000000)
000FFFFBE80 0018014332B (00180269458, 00180148F2E, 0010042D040, 000000002D8)
000FFFFBE80 00180215058 (0010042D040, 0010042D08F, 000000002D8, 001802693DF)
000FFFFBE80 00180043517 (000FFFFBEF0, 00000000004, 00000000000, 00100000000)
000FFFFC710 00100408373 (00000000000, 00000000000, 001801C7B4B, 00000000000)
000FFFFC710 00180065505 (008000DF9CC, 00180000000, 7FFEB016B80D, 00000000000)
000FFFFC710 0018013E4D0 (008000DF9CC, 00180000000, 7FFEB016B80D, 00000000000)
000FFFFC710 005FCB3C5E4 (008000DF9CC, 00180000000, 7FFEB016B80D, 00000000000)
End of stack trace

View file

@ -90,8 +90,8 @@ 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_NONE, /*pos*/ -2028, 260, 3264, /*angle*/ 0, 0, 0, /*behParam*/ 0x00000000, /*beh*/ bhvGoombaTripletSpawner),
//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(),
};

5
network.sh Normal file
View file

@ -0,0 +1,5 @@
set -e
make BETTERCAMERA=1 NODRAWINGDISTANCE=1 DEBUG=1 IMMEDIATELOAD=1
./build/us_pc/sm64.us.f3dex2e.exe --server --configfile sm64config_server.txt &
./build/us_pc/sm64.us.f3dex2e.exe --client --configfile sm64config_client.txt &
#winpty cgdb ./build/us_pc/sm64.us.f3dex2e.exe -ex 'b act_jump_kick' -ex 'run --client --configfile sm64config_client.txt' -ex 'quit'

View file

@ -39,6 +39,8 @@
#include "bettercamera.h"
#endif
#include "../pc/network/network.h"
u32 unused80339F10;
s8 filler80339F1C[20];
@ -1276,8 +1278,8 @@ void debug_print_speed_action_normal(struct MarioState *m) {
* Update the button inputs for Mario.
*/
void update_mario_button_inputs(struct MarioState *m) {
// disable Luigi inputs
//if (m != &gMarioStates[1]) { return; }
// don't update Luigi inputs
if (m != &gMarioStates[0]) { return; }
if (m->controller->buttonPressed & A_BUTTON) {
m->input |= INPUT_A_PRESSED;
@ -1319,8 +1321,8 @@ void update_mario_button_inputs(struct MarioState *m) {
* Updates the joystick intended magnitude.
*/
void update_mario_joystick_inputs(struct MarioState *m) {
// disable Luigi inputs
//if (m != &gMarioStates[1]) { return; }
// don't update Luigi inputs
if (m != &gMarioStates[0]) { return; }
struct Controller *controller = m->controller;
f32 mag = ((controller->stickMag / 64.0f) * (controller->stickMag / 64.0f)) * 64.0f;
@ -1410,7 +1412,8 @@ void update_mario_geometry_inputs(struct MarioState *m) {
*/
void update_mario_inputs(struct MarioState *m) {
m->particleFlags = 0;
m->input = 0;
if (m == &gMarioStates[0]) { m->input = 0; }
m->collidedObjInteractTypes = m->marioObj->collidedObjInteractTypes;
m->flags &= 0xFFFFFF;
@ -1937,6 +1940,8 @@ skippy:
init_mario();
gMarioState = &gMarioStates[0];
}
network_track(gMarioStates);
}
void init_mario_from_save_file(void) {
@ -1948,7 +1953,7 @@ void init_mario_from_save_file(void) {
gMarioState->spawnInfo = &gPlayerSpawnInfos[i];
gMarioState->statusForCamera = &gPlayerCameraState[i];
gMarioState->marioBodyState = &gBodyStates[i];
gMarioState->controller = &gControllers[0];
gMarioState->controller = &gControllers[i];
gMarioState->animation = &D_80339D10[i];
gMarioState->numCoins = 0;

View file

@ -48,6 +48,12 @@ void parse_cli_opts(int argc, char* argv[]) {
else if (strcmp(argv[i], "--windowed") == 0) // Open game in windowed mode
gCLIOpts.FullScreen = 2;
else if (strcmp(argv[i], "--server") == 0) // Host server
gCLIOpts.Network = NT_SERVER;
else if (strcmp(argv[i], "--client") == 0) // Join server
gCLIOpts.Network = NT_CLIENT;
else if (strcmp(argv[i], "--cheats") == 0) // Enable cheats menu
Cheats.EnableCheats = true;

View file

@ -3,9 +3,16 @@
#include "platform.h"
enum NetworkType {
NT_NONE,
NT_SERVER,
NT_CLIENT
};
struct PCCLIOptions {
unsigned int SkipIntro;
unsigned int FullScreen;
enum NetworkType Network;
char ConfigFile[SYS_MAX_PATH];
char SavePath[SYS_MAX_PATH];
char GameDir[SYS_MAX_PATH];

140
src/pc/network/network.c Normal file
View file

@ -0,0 +1,140 @@
//////////////////////////
// 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;
if (networkType == NT_NONE) { return; }
//-----------------------------------------------
// Initialize Winsock
WSADATA wsaData;
int rc = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (rc != NO_ERROR) {
wprintf(L"%s WSAStartup failed with error %d\n", NETWORKTYPESTR, rc);
return;
}
//-----------------------------------------------
// Create a receiver socket to receive datagrams
gSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (gSocket == INVALID_SOCKET) {
wprintf(L"%s socket failed with error %d\n", NETWORKTYPESTR, WSAGetLastError());
return;
}
// Set non-blocking mode
u_long iMode = 1;
rc = ioctlsocket(gSocket, FIONBIO, &iMode);
if (rc != NO_ERROR) {
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);
}
}
void network_track(struct MarioState *inMarioStates) {
marioStates = inMarioStates;
}
void network_send(char* buffer, int buffer_length) {
if (networkType == NT_NONE) { return; }
struct sockaddr_in txAddr;
txAddr.sin_family = AF_INET;
txAddr.sin_port = txPort;
txAddr.sin_addr.s_addr = inet_addr(txIpAddr);
int rc = sendto(gSocket, buffer, buffer_length, 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);
}
do {
int rc = recvfrom(gSocket, buffer, BUFFER_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;
}
} while (1);
}
void network_shutdown(void) {
if (networkType == NT_NONE) { return; }
int rc = closesocket(gSocket);
if (rc == SOCKET_ERROR) {
wprintf(L"%s closesocket failed with error %d\n", NETWORKTYPESTR, WSAGetLastError());
}
WSACleanup();
}

13
src/pc/network/network.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef NETWORK_H
#define NETWORK_H
#include <types.h>
#include "../cliopts.h"
void network_init(enum NetworkType networkType);
void network_track(struct MarioState *marioStates);
void network_send(char* buffer, int buffer_length);
void network_update(void);
void network_shutdown(void);
#endif

View file

@ -11,6 +11,8 @@
#include "game/memory.h"
#include "audio/external.h"
#include "network/network.h"
#include "gfx/gfx_pc.h"
#include "gfx/gfx_opengl.h"
@ -103,6 +105,7 @@ static inline void patch_interpolations(void) {
}
void produce_one_frame(void) {
network_update();
gfx_start_frame();
const f32 master_mod = (f32)configMasterVolume / 127.0f;
@ -151,6 +154,7 @@ void game_deinit(void) {
controller_shutdown();
audio_shutdown();
gfx_shutdown();
network_shutdown();
inited = false;
}
@ -253,6 +257,7 @@ void main_func(void) {
audio_api = &audio_null;
}
network_init(gCLIOpts.Network);
audio_init();
sound_init();