1
0
Aaro Saila 4 долоо хоног өмнө
parent
commit
24224ff0df

+ 1 - 0
meson.build

@@ -14,6 +14,7 @@ c_args = [
 ]
 
 common_src = [
+  'src/common/GameState_net.c',
   'src/common/game.c',
   'src/common/networking.c'
 ]

+ 48 - 0
src/common/GameState_net.c

@@ -0,0 +1,48 @@
+#include "GameState_net.h"
+#include "game.h"
+
+static void MovingObject_to_MovingObjectMsg(const MovingObject *const src, MovingObjectMsg *const dst) {
+    dst->pos_x = src->pos[0];
+    dst->pos_y = src->pos[1];
+    dst->w = src->w;
+    dst->h = src->h;
+    dst->dirv_x = src->dirv[0];
+    dst->dirv_y = src->dirv[1];
+    dst->speed = src->speed;
+}
+
+void GameState_to_GameStateMsg(const GameState *const src, GameStateMsg *const dst) {
+    dst->ai_enabled = (uint8_t) src->ai_enabled;
+    MovingObject_to_MovingObjectMsg(&src->paddle_l, &dst->paddle_l);
+    MovingObject_to_MovingObjectMsg(&src->paddle_r, &dst->paddle_r);
+    MovingObject_to_MovingObjectMsg(&src->ball, &dst->ball);
+    dst->ball_start_pos_x = src->ball_start_pos[0];
+    dst->ball_start_pos_y = src->ball_start_pos[1];
+    dst->ball_start_dir_x = src->ball_start_dir[0];
+    dst->ball_start_dir_y = src->ball_start_dir[1];
+    dst->score_l = src->score_l;
+    dst->score_r = src->score_r;
+}
+
+static void MovingObjectMsg_to_MovingObject(const MovingObjectMsg *const src, MovingObject *const dst) {
+    dst->pos[0] = src->pos_x;
+    dst->pos[1] = src->pos_y;
+    dst->w = src->w;
+    dst->h = src->h;
+    dst->dirv[0] = src->dirv_x;
+    dst->dirv[1] = src->dirv_y;
+    dst->speed = src->speed;
+}
+
+void GameStateMsg_to_GameState(const GameStateMsg *const src, GameState *const dst) {
+    dst->ai_enabled = (bool) src->ai_enabled;
+    MovingObjectMsg_to_MovingObject(&src->paddle_l, &dst->paddle_l);
+    MovingObjectMsg_to_MovingObject(&src->paddle_r, &dst->paddle_r);
+    MovingObjectMsg_to_MovingObject(&src->ball, &dst->ball);
+    dst->ball_start_pos[0] = src->ball_start_pos_x;
+    dst->ball_start_pos[1] = src->ball_start_pos_y;
+    dst->ball_start_dir[0] = src->ball_start_dir_x;
+    dst->ball_start_dir[1] = src->ball_start_dir_y;
+    dst->score_l = src->score_l;
+    dst->score_r = src->score_r;
+}

+ 31 - 0
src/common/GameState_net.h

@@ -0,0 +1,31 @@
+#pragma once
+
+#include <stdint.h>
+
+#include "game.h"
+
+typedef struct [[gnu::packed]] {
+    float pos_x;
+    float pos_y;
+    float w;
+    float h;
+    float dirv_x;
+    float dirv_y;
+    float speed;
+} MovingObjectMsg;
+
+typedef struct [[gnu::packed]] {
+    uint8_t ai_enabled;
+    MovingObjectMsg paddle_l;
+    MovingObjectMsg paddle_r;
+    MovingObjectMsg ball;
+    float ball_start_pos_x;
+    float ball_start_pos_y;
+    float ball_start_dir_x;
+    float ball_start_dir_y;
+    uint8_t score_l;
+    uint8_t score_r;
+} GameStateMsg;
+
+void GameState_to_GameStateMsg(const GameState *const src, GameStateMsg *const dst);
+void GameStateMsg_to_GameState(const GameStateMsg *const src, GameState *const dst);

+ 7 - 3
src/common/networking.c

@@ -5,6 +5,7 @@
 #include "scufeng/log.h"
 
 #include "networking.h"
+#include "GameState_net.h"
 
 static const uint8_t fb = 0xfb;
 
@@ -14,9 +15,11 @@ static size_t NetMsgType_to_buf_size(const NetMsgType type) {
         return sizeof(PaddleChangeDirMsg);
     case NET_MSG_PADDLE_POS:
         return sizeof(PaddlePosMsg);
-    default:
-        LOG_FATALF("Invalid msg type: %u", type);
+    case NET_MSG_GAME_STATE:
+        return sizeof(GameStateMsg);
     }
+
+    LOG_FATALF("Invalid msg type: %u", type);
 }
 
 // buf is a pointer to one of the packed *Msg structs from networking.h
@@ -78,9 +81,10 @@ bool recv_msg_type(FILE *s, NetMsgType *const type) {
     switch (*type) {
     case NET_MSG_PADDLE_CHANGE_DIR:
     case NET_MSG_PADDLE_POS:
+    case NET_MSG_GAME_STATE:
         break;
     default:
-        LOG_FATALF("[recv_msg_type] Invalid msg type: %u", type);
+        LOG_FATALF("[recv_msg_type] Invalid msg type: %u", *type);
     }
 
     return type;

+ 2 - 11
src/common/networking.h

@@ -10,7 +10,8 @@
 
 typedef enum : uint8_t {
     NET_MSG_PADDLE_CHANGE_DIR,
-    NET_MSG_PADDLE_POS
+    NET_MSG_PADDLE_POS,
+    NET_MSG_GAME_STATE
 } NetMsgType;
 
 typedef struct [[gnu::packed]] {
@@ -24,16 +25,6 @@ typedef struct [[gnu::packed]] {
     uint8_t player1; // bool
 } PaddlePosMsg;
 
-typedef struct [[gnu::packed]] {
-    float pos_x;
-    float pos_y;
-    float w;
-    float h;
-    float dirv_x;
-    float dirv_y;
-    float speed;
-} MovingObjectMsg;
-
 void send_msg(FILE *s, const NetMsgType type, const uint8_t *const buf);
 bool recv_msg_type(FILE *s, NetMsgType *const type);
 void recv_msg(FILE *s, const NetMsgType type, uint8_t *const buf);

+ 33 - 13
src/game/MultiPlayer.c

@@ -16,6 +16,7 @@
 #include "MultiPlayer.h"
 #include "game.h"
 #include "game_common.h"
+#include "GameState_net.h"
 
 MultiPlayer MultiPlayer_alloc(
     const unsigned int screen_w,
@@ -28,7 +29,7 @@ MultiPlayer MultiPlayer_alloc(
     mp.screen_w = screen_w;
     mp.screen_h = screen_h;
 
-    mp.state = GameState_new(game_default_params, false);
+    // mp.state = GameState_new(game_default_params, false);
     mp.shapes = GameShapes_alloc(screen_w, screen_h, game_default_params);
 
     struct protoent *proto = getprotobyname("tcp");
@@ -80,7 +81,38 @@ void MultiPlayer_free(MultiPlayer *const mp) {
     GameShapes_free(&mp->shapes);
 }
 
+static void handle_paddle_pos_msg(MultiPlayer *const mp) {
+    PaddlePosMsg msg;
+    recv_msg(mp->conn_s, NET_MSG_PADDLE_POS, (uint8_t *) &msg);
+    vec2 pos = { msg.pos_x, msg.pos_y };
+    const bool player1 = (bool) msg.player1;
+    printf("Got msg from server: player1: %d, pos: (%.2lf, %.2lf)\n", player1, pos[0], pos[1]);
+    glmc_vec2_copy(pos, mp->state.paddle_l.pos);
+    mp->state.paddle_l.pos[0] = pos[0];
+    mp->state.paddle_l.pos[1] = pos[1];
+}
+
+static void handle_game_state_msg(MultiPlayer *const mp) {
+    GameStateMsg msg;
+    recv_msg(mp->conn_s, NET_MSG_GAME_STATE, (uint8_t *) &msg);
+    GameStateMsg_to_GameState(&msg, &mp->state);
+}
+
 void MultiPlayer_tick(MultiPlayer *const mp, const double delta) {
+    NetMsgType msg_type;
+    if (recv_msg_type(mp->conn_s, &msg_type)) {
+        switch (msg_type) {
+        case NET_MSG_PADDLE_CHANGE_DIR:
+            break;
+        case NET_MSG_PADDLE_POS:
+            handle_paddle_pos_msg(mp);
+            break;
+        case NET_MSG_GAME_STATE:
+            handle_game_state_msg(mp);
+            break;
+        }
+    }
+
     SEDirection new_dir = SE_NONE;
     bool dir_changed = false;
     const SEDirection current_dir = GameState_paddle_l_dir_get(&mp->state);
@@ -109,18 +141,6 @@ void MultiPlayer_tick(MultiPlayer *const mp, const double delta) {
         send_msg(mp->conn_s, NET_MSG_PADDLE_CHANGE_DIR, (uint8_t *) &msg);
     }
 
-    NetMsgType msg_type;
-    if (recv_msg_type(mp->conn_s, &msg_type)) {
-        PaddlePosMsg msg;
-        recv_msg(mp->conn_s, msg_type, (uint8_t *) &msg);
-        vec2 pos = { msg.pos_x, msg.pos_y };
-        const bool player1 = (bool) msg.player1;
-        printf("Got msg from server: player1: %d, pos: (%.2lf, %.2lf)\n", player1, pos[0], pos[1]);
-        glmc_vec2_copy(pos, mp->state.paddle_l.pos);
-        mp->state.paddle_l.pos[0] = pos[0];
-        mp->state.paddle_l.pos[1] = pos[1];
-    }
-
     GameState_update(&mp->state, delta);
     GameShapes_update(&mp->shapes, &mp->state, mp->screen_w, mp->screen_h);
     GameShapes_render(&mp->shapes);

+ 33 - 17
src/server/server.c

@@ -13,6 +13,7 @@
 #include "scufeng/log.h"
 #include "game.h"
 #include "networking.h"
+#include "GameState_net.h"
 
 #define SERVER_HOST "127.0.0.1"
 #define SERVER_PORT 8080
@@ -29,6 +30,12 @@ static ServerState server_state = SS_LOBBY;
 
 static GameState game_state;
 
+static void send_game_state(FILE *conn) {
+    GameStateMsg msg;
+    GameState_to_GameStateMsg(&game_state, &msg);
+    send_msg(conn, NET_MSG_GAME_STATE, (uint8_t *) &msg);
+}
+
 static void server_lobby(const int sock) {
     game_state = GameState_new(game_default_params, false);
 
@@ -61,9 +68,31 @@ static void server_lobby(const int sock) {
     // }
 }
 
+static void handle_paddle_change_dir_msg() {
+    PaddleChangeDirMsg msg;
+    recv_msg(p1_conn, NET_MSG_PADDLE_CHANGE_DIR, (uint8_t *) &msg);
+    SEDirection dir = (SEDirection) msg.dir;
+    bool player1 = (bool) msg.player1;
+    if (player1) {
+        const char *dir_str = dir == SE_UP ? "UP" : (dir == SE_DOWN ? "DOWN" : (dir == SE_NONE ? "NONE" : "INVALID"));
+        printf("Player 1 moves paddle to direction: %s\n", dir_str);
+        GameState_paddle_l_change_dir(&game_state, dir);
+        PaddlePosMsg res_msg = {
+            .pos_x = game_state.paddle_l.pos[0],
+            .pos_y = game_state.paddle_l.pos[1],
+            .player1 = (uint8_t) true
+        };
+        send_msg(p1_conn, NET_MSG_PADDLE_POS, (uint8_t *) &res_msg);
+    } else {
+        printf("Message was not from player1\n");
+    }
+}
+
 static void server_game() {
     se_fps_lock_set_fps(60);
 
+    send_game_state(p1_conn);
+
     double last_frame_time_s = 0.0;
     while (true) {
         const double current_time_s = se_get_time();
@@ -75,23 +104,10 @@ static void server_game() {
         if (recv_msg_type(p1_conn, &msg_type)) {
             switch (msg_type) {
             case NET_MSG_PADDLE_CHANGE_DIR:
-                PaddleChangeDirMsg msg;
-                recv_msg(p1_conn, msg_type, (uint8_t *) &msg);
-                SEDirection dir = (SEDirection) msg.dir;
-                bool player1 = (bool) msg.player1;
-                if (player1) {
-                    const char *dir_str = dir == SE_UP ? "UP" : (dir == SE_DOWN ? "DOWN" : (dir == SE_NONE ? "NONE" : "INVALID"));
-                    printf("Player 1 moves paddle to direction: %s\n", dir_str);
-                    GameState_paddle_l_change_dir(&game_state, dir);
-                    PaddlePosMsg res_msg = {
-                        .pos_x = game_state.paddle_l.pos[0],
-                        .pos_y = game_state.paddle_l.pos[1],
-                        .player1 = (uint8_t) true
-                    };
-                    send_msg(p1_conn, NET_MSG_PADDLE_POS, (uint8_t *) &res_msg);
-                } else {
-                    printf("Message was not from player1\n");
-                }
+                handle_paddle_change_dir_msg();
+                break;
+            case NET_MSG_PADDLE_POS:
+            case NET_MSG_GAME_STATE:
                 break;
             }
         }