Skeleton of the multiplayer architecture

main
Cameron Murphy Reikes 2 years ago
parent e5cd725fc8
commit c27090fc53

@ -23,6 +23,8 @@
"xlocale": "c", "xlocale": "c",
"xlocbuf": "c", "xlocbuf": "c",
"xstring": "c", "xstring": "c",
"algorithm": "c" "algorithm": "c",
"sokol_gp.h": "c",
"stdbool.h": "c"
} }
} }

@ -7,4 +7,4 @@ IF %ERRORLEVEL% NEQ 0 ECHO ERROR download sokol-shdc from https://github.com/flo
@REM example of how to compile shaders: sokol-shdc.exe --input triangle.glsl --output triangle.gen.h --slang glsl330:hlsl5:metal_macos @REM example of how to compile shaders: sokol-shdc.exe --input triangle.glsl --output triangle.gen.h --slang glsl330:hlsl5:metal_macos
cl /MP /Zi /Fd"flight.pdb" /I"thirdparty" /Fe"flight" main.c cl /MP /Zi /Fd"flight.pdb" /I"thirdparty" /Fe"flight" main.c gamestate.c server.c

@ -0,0 +1,29 @@
#include "types.h"
// do not use any global variables to process gamestate
static void process_body(struct Body *body, float dt)
{
V2 current = body->position;
body->position = V2add(body->position, V2sub(current, body->old_position));
body->position = V2add(body->position, V2scale(body->acceleration, dt*dt));
body->old_position = current;
}
void process(struct GameState * gs, float dt) {
for(int i = 0; i < MAX_PLAYERS; i++)
{
struct Player * p = &gs->players[i];
if(!p->connected)
continue;
p->body.acceleration = V2scale(p->input, 5.0f);
process_body(&p->body, dt);
}
for(int i = 0; i < gs->num_boxes; i++)
{
process_body(&gs->boxes[i].body, dt);
}
}

@ -8,35 +8,16 @@
#include "sokol_gp.h" #include "sokol_gp.h"
#include "sokol_app.h" #include "sokol_app.h"
#include "sokol_glue.h" #include "sokol_glue.h"
#include <winsock.h>
#define MAX_BOXES 32 #include "types.h"
#define BOX_SIZE 0.5f
#define TIMESTEP 1.0f / 60.0f
struct Body
{
sgp_point position;
sgp_point old_position;
sgp_vec2 acceleration;
};
struct GameState
{
struct Player
{
struct Body body;
} player;
int num_boxes;
struct Box
{
struct Body body;
} boxes[MAX_BOXES];
};
struct GameState gs = {0}; static struct GameState gs = {0};
bool mouse_down = false; static int myplayer = -1;
bool keydown[SAPP_KEYCODE_MENU] = {0}; static bool mouse_down = false;
float funval = 0.0f; // easy to play with value controlled by left mouse button when held down @BeforeShip remove on release builds static bool keydown[SAPP_KEYCODE_MENU] = {0};
static float funval = 0.0f; // easy to play with value controlled by left mouse button when held down @BeforeShip remove on release builds
static bool is_host = false;
void init(void) void init(void)
{ {
@ -52,12 +33,12 @@ void init(void)
gs.boxes[0] = (struct Box){ gs.boxes[0] = (struct Box){
.body = (struct Body){ .body = (struct Body){
.position = (sgp_point){.x = 0.75f, .y = 0.0}}, .position = (P2){.x = 0.75f, .y = 0.0}},
}; };
gs.boxes[0].body.old_position = gs.boxes[0].body.position; gs.boxes[0].body.old_position = gs.boxes[0].body.position;
gs.boxes[1] = (struct Box){ gs.boxes[1] = (struct Box){
.body = (struct Body){ .body = (struct Body){
.position = (sgp_point){.x = 0.75f, .y = 0.5f}}, .position = (P2){.x = 0.75f, .y = 0.5f}},
}; };
gs.boxes[1].body.old_position = gs.boxes[1].body.position; gs.boxes[1].body.old_position = gs.boxes[1].body.position;
gs.num_boxes = 2; gs.num_boxes = 2;
@ -71,38 +52,6 @@ void init(void)
} }
} }
sgp_vec2 v2add(sgp_vec2 a, sgp_vec2 b)
{
return (sgp_vec2){
.x = a.x + b.x,
.y = a.y + b.y,
};
}
sgp_vec2 v2scale(sgp_vec2 a, float f)
{
return (sgp_vec2){
.x = a.x * f,
.y = a.y * f,
};
}
sgp_vec2 v2sub(sgp_vec2 a, sgp_vec2 b)
{
return (sgp_vec2){
.x = a.x - b.x,
.y = a.y - b.y,
};
}
void process_body(struct Body *body)
{
sgp_vec2 current = body->position;
body->position = v2add(body->position, v2sub(current, body->old_position));
body->position = v2add(body->position, v2scale(body->acceleration, TIMESTEP*TIMESTEP));
body->old_position = current;
}
void frame(void) void frame(void)
{ {
int width = sapp_width(), height = sapp_height(); int width = sapp_width(), height = sapp_height();
@ -110,18 +59,15 @@ void frame(void)
float time = sapp_frame_count() * sapp_frame_duration(); float time = sapp_frame_count() * sapp_frame_duration();
// gameplay // gameplay
struct ClientToServer curmsg = {0};
{ {
sgp_vec2 input = (sgp_vec2){ V2 input = (V2){
.x = (float)keydown[SAPP_KEYCODE_D] - (float)keydown[SAPP_KEYCODE_A], .x = (float)keydown[SAPP_KEYCODE_D] - (float)keydown[SAPP_KEYCODE_A],
.y = (float)keydown[SAPP_KEYCODE_S] - (float)keydown[SAPP_KEYCODE_W], .y = (float)keydown[SAPP_KEYCODE_S] - (float)keydown[SAPP_KEYCODE_W],
}; };
gs.player.body.acceleration = v2scale(input, 5.0f); curmsg.input = input;
process_body(&gs.player.body); process(&gs, (float)sapp_frame_duration());
for(int i = 0; i < gs.num_boxes; i++)
{
process_body(&gs.boxes[i].body);
}
} }
// drawing // drawing
@ -138,7 +84,10 @@ void frame(void)
// Drawing in world space now // Drawing in world space now
sgp_translate(width / 2, height / 2); sgp_translate(width / 2, height / 2);
sgp_scale_at(300.0f + funval, 300.0f + funval, 0.0f, 0.0f); sgp_scale_at(300.0f + funval, 300.0f + funval, 0.0f, 0.0f);
sgp_translate(-gs.player.body.position.x, -gs.player.body.position.y); if(myplayer != -1)
{
sgp_translate(-gs.players[myplayer].body.position.x, -gs.players[myplayer].body.position.y);
}
sgp_set_color(1.0f, 1.0f, 1.0f, 1.0f); sgp_set_color(1.0f, 1.0f, 1.0f, 1.0f);
sgp_draw_filled_rect(100.0f, 100.0f, 400.0f, 400.0f); sgp_draw_filled_rect(100.0f, 100.0f, 400.0f, 400.0f);
@ -156,9 +105,12 @@ void frame(void)
float halfbox = BOX_SIZE / 2.0f; float halfbox = BOX_SIZE / 2.0f;
// player // player
{ for(int i = 0; i < MAX_PLAYERS; i++){
struct Player * p = &gs.players[i];
if(!p->connected)
continue;
sgp_set_color(1.0f, 1.0f, 1.0f, 1.0f); sgp_set_color(1.0f, 1.0f, 1.0f, 1.0f);
sgp_draw_filled_rect(gs.player.body.position.x - halfbox, gs.player.body.position.y - halfbox, BOX_SIZE, BOX_SIZE); sgp_draw_filled_rect(p->body.position.x - halfbox, p->body.position.y - halfbox, BOX_SIZE, BOX_SIZE);
} }
// boxes // boxes
@ -220,7 +172,7 @@ void event(const sapp_event *e)
sapp_desc sokol_main(int argc, char *argv[]) sapp_desc sokol_main(int argc, char *argv[])
{ {
(void)argc; is_host = argc >= 1;
(void)argv; (void)argv;
return (sapp_desc){ return (sapp_desc){
.init_cb = init, .init_cb = init,

@ -0,0 +1,6 @@
#include <winsock.h>
// started in a thread from host
void server() {
// SOCKET s = socket();
}

@ -14,5 +14,5 @@ WinKill, Flight
WinActivate, flightbuild WinActivate, flightbuild
If WinActive("flightbuild") If WinActive("flightbuild")
{ {
Send, build_debug.bat && START /B flight.exe && flight.exe{Enter} Send, build_debug.bat && START /B flight.exe && flight.exe --host{Enter}
} }

@ -0,0 +1,100 @@
#pragma once
// including headers from headers bad
#ifndef SOKOL_GP_INCLUDED
typedef struct sgp_vec2
{
float x, y;
} sgp_vec2;
typedef sgp_vec2 sgp_point;
#endif
#include <stdbool.h>
#ifndef _STDBOOL
#define bool _Bool
#define false 0
#define true 1
#endif
typedef sgp_vec2 V2;
typedef sgp_point P2;
#define MAX_BOXES 32
#define MAX_PLAYERS 2
#define BOX_SIZE 0.5f
#define TIMESTEP 1.0f / 60.0f
struct Body
{
P2 position;
P2 old_position;
V2 acceleration;
};
struct Player
{
struct Body body;
bool connected;
V2 input;
};
struct GameState
{
struct Player players[MAX_PLAYERS];
int num_boxes;
struct Box
{
struct Body body;
} boxes[MAX_BOXES];
};
struct ServerToClient
{
struct GameState cur_gs;
int your_player;
};
struct ClientToServer
{
V2 input;
};
// server
void server();
// gamestate
void process(struct GameState * gs, float dt); // does in place
// all the math is static so that it can be defined in each compilation unit its included in
static V2 V2add(V2 a, V2 b)
{
return (V2){
.x = a.x + b.x,
.y = a.y + b.y,
};
}
static V2 V2scale(V2 a, float f)
{
return (V2){
.x = a.x * f,
.y = a.y * f,
};
}
static V2 V2sub(V2 a, V2 b)
{
return (V2){
.x = a.x - b.x,
.y = a.y - b.y,
};
}
Loading…
Cancel
Save