mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-12-22 16:30:23 +00:00
Started adding networking
This commit is contained in:
parent
0ad65c87da
commit
34b1ec76f6
12 changed files with 227 additions and 10 deletions
4
Makefile
4
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_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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
14
cgdb.exe.stackdump
Normal 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
|
|
@ -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
5
network.sh
Normal 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'
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
140
src/pc/network/network.c
Normal 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
13
src/pc/network/network.h
Normal 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
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in a new issue