소스 검색

Synced paddle movement

Aaro Saila 3 주 전
부모
커밋
f2f4088598
6개의 변경된 파일과 127개의 추가작업 그리고 74개의 파일을 삭제
  1. 15 4
      src/common/networking.c
  2. 11 5
      src/common/networking.h
  3. 36 12
      src/game/MultiPlayer.c
  4. 1 0
      src/game/MultiPlayer.h
  5. 1 8
      src/game/pong.c
  6. 63 45
      src/server/server.c

+ 15 - 4
src/common/networking.c

@@ -14,9 +14,13 @@ size_t NetMsgType_to_buf_size(const NetMsgType type) {
     case NET_MSG_PADDLE_CHANGE_DIR:
         return sizeof(PaddleChangeDirMsg);
     case NET_MSG_PADDLE_POS:
-        return sizeof(PaddlePosMsg);
+        return sizeof(PaddleUpdateMsg);
     case NET_MSG_GAME_STATE:
         return sizeof(GameStateMsg);
+    case NET_MSG_IS_PLAYER_1:
+        return sizeof(IsPlayer1Msg);
+    case NET_MSG_GAME_START:
+        return 0;
     }
 
     LOG_FATALF("Invalid msg type: %u", type);
@@ -40,7 +44,7 @@ void send_msg(FILE *s, const NetMsgType type, const uint8_t *const buf) {
     if (fwrite(&type, sizeof(NetMsgType), 1, s) < 1) {
         LOG_FATAL("[send_msg] Failed to write msg type");
     }
-    if (fwrite(buf_cpy, buf_size, 1, s) < 1) {
+    if (buf_size != 0 && fwrite(buf_cpy, buf_size, 1, s) < 1) {
         LOG_FATAL("[send_msg] Failed to write msg");
     }
     if (fflush(s) != 0) {
@@ -78,12 +82,19 @@ bool recv_msg_type(FILE *s, NetMsgType *const type) {
         LOG_FATAL("[recv_msg] Failed to read msg type");
     }
 
+    // Taking advantage of 'X not handled in switch' warning to make sure that
+    // every type is checked for and that msg type is valid.
+    bool valid_type = false;
     switch (*type) {
-    case NET_MSG_PADDLE_CHANGE_DIR:
     case NET_MSG_PADDLE_POS:
     case NET_MSG_GAME_STATE:
+    case NET_MSG_GAME_START:
+    case NET_MSG_PADDLE_CHANGE_DIR:
+    case NET_MSG_IS_PLAYER_1:
+        valid_type = true;
         break;
-    default:
+    }
+    if (!valid_type) {
         LOG_FATALF("[recv_msg_type] Invalid msg type: %u", *type);
     }
 

+ 11 - 5
src/common/networking.h

@@ -11,19 +11,25 @@
 typedef enum : uint8_t {
     NET_MSG_PADDLE_CHANGE_DIR,
     NET_MSG_PADDLE_POS,
-    NET_MSG_GAME_STATE
+    NET_MSG_GAME_STATE,
+    NET_MSG_GAME_START,
+    NET_MSG_IS_PLAYER_1
 } NetMsgType;
 
 typedef struct [[gnu::packed]] {
     uint8_t dir;     // SEDirection
-    uint8_t player1; // bool
 } PaddleChangeDirMsg;
 
 typedef struct [[gnu::packed]] {
-    float pos_x;
-    float pos_y;
+    float l_pos_y;
+    float l_dirv_y;
+    float r_pos_y;
+    float r_dirv_y;
+} PaddleUpdateMsg;
+
+typedef struct [[gnu::packed]] {
     uint8_t player1; // bool
-} PaddlePosMsg;
+} IsPlayer1Msg;
 
 size_t NetMsgType_to_buf_size(const NetMsgType type);
 void send_msg(FILE *s, const NetMsgType type, const uint8_t *const buf);

+ 36 - 12
src/game/MultiPlayer.c

@@ -58,15 +58,39 @@ MultiPlayer MultiPlayer_alloc(
     if (res == -1) {
         LOG_FATALF("connect failed: %d %s", errno, strerror(errno));
     }
-    if (fcntl(mp.sock, F_SETFL, O_NONBLOCK) != 0) {
-        LOG_FATALF("fcntl failed on mp.sock: (%d) %s", errno, strerror(errno));
-    }
+
+    LOG("Connected to server");
 
     mp.conn_s = fdopen(mp.sock, "r+");
     if (mp.conn_s == nullptr) {
         LOG_FATALF("fdopen failed: (%d) %s", errno, strerror(errno));
     }
 
+    NetMsgType msg_type;
+    recv_msg_type(mp.conn_s, &msg_type);
+    if (msg_type != NET_MSG_IS_PLAYER_1) {
+        LOG_FATALF("Did not get IS_PLAYER_1 msg, got: %u", msg_type);
+    }
+    IsPlayer1Msg p1_msg = { 0 };
+    recv_msg(mp.conn_s, NET_MSG_IS_PLAYER_1, (uint8_t *) &p1_msg);
+    mp.is_player_1 = (bool) p1_msg.player1;
+    if (mp.is_player_1) {
+        LOG("I am player 1");
+    } else {
+        LOG("I am player 2");
+    }
+
+    LOG("Waiting for game start");
+
+    recv_msg_type(mp.conn_s, &msg_type);
+    if (msg_type != NET_MSG_GAME_START) {
+        LOG_FATALF("[MultiPlayer_alloc] Did not get GAME_START msg, got: %u", msg_type);
+    }
+
+    if (fcntl(mp.sock, F_SETFL, O_NONBLOCK) != 0) {
+        LOG_FATALF("fcntl failed on mp.sock: (%d) %s", errno, strerror(errno));
+    }
+
     return mp;
 }
 
@@ -82,14 +106,12 @@ void MultiPlayer_free(MultiPlayer *const mp) {
 }
 
 static void handle_paddle_pos_msg(MultiPlayer *const mp) {
-    PaddlePosMsg msg;
+    PaddleUpdateMsg 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];
+    mp->state.paddle_l.pos[1] = msg.l_pos_y;
+    mp->state.paddle_l.dirv[1] = msg.l_dirv_y;
+    mp->state.paddle_r.pos[1] = msg.r_pos_y;
+    mp->state.paddle_r.dirv[1] = msg.r_dirv_y;
 }
 
 static void handle_game_state_msg(MultiPlayer *const mp) {
@@ -110,6 +132,9 @@ void MultiPlayer_tick(MultiPlayer *const mp, const double delta) {
         case NET_MSG_GAME_STATE:
             handle_game_state_msg(mp);
             break;
+        case NET_MSG_IS_PLAYER_1:
+        case NET_MSG_GAME_START:
+            break;
         }
     }
 
@@ -134,8 +159,7 @@ void MultiPlayer_tick(MultiPlayer *const mp, const double delta) {
     if (dir_changed) {
         GameState_paddle_l_change_dir(&mp->state, new_dir);
         const PaddleChangeDirMsg msg = {
-            .dir = (uint8_t) new_dir,
-            .player1 = (uint8_t) true
+            .dir = (uint8_t) new_dir
         };
 
         send_msg(mp->conn_s, NET_MSG_PADDLE_CHANGE_DIR, (uint8_t *) &msg);

+ 1 - 0
src/game/MultiPlayer.h

@@ -11,6 +11,7 @@ typedef struct {
     unsigned int screen_h;
     GameState state;
     GameShapes shapes;
+    bool is_player_1;
     int sock;
     int conn;
     FILE *conn_s;

+ 1 - 8
src/game/pong.c

@@ -5,15 +5,8 @@
 #include "SinglePlayer.h"
 #include "MultiPlayer.h"
 
-static const unsigned int screen_w = 1200;
+static const unsigned int screen_w = 1200 / 2;
 static const unsigned int screen_h = 600;
-// static const float paddles_w = 0.01f;
-// static const float paddles_h = 0.10f;
-// static const float paddle_l_x = (1.0f / 16);
-// static const float ball_w = paddles_w * 0.5f;
-// static vec2 ball_pos = { 0.5f, 0.5f };
-// static const float paddle_speed = 0.7f;
-// static const float ball_speed = 0.7f;
 
 int main() {
     se_init(true);

+ 63 - 45
src/server/server.c

@@ -78,15 +78,25 @@ static void send_out_msgs() {
         OutgoingMsg out_msg = pop_out_msg();
         switch (out_msg.type) {
         case NET_MSG_PADDLE_POS:
-            const PaddlePosMsg msg = {
-                .player1 = true,
-                .pos_x = game_state.paddle_l.pos[0],
-                .pos_y = game_state.paddle_l.pos[1],
+            // p1
+            PaddleUpdateMsg msg = {
+                .l_pos_y = game_state.paddle_l.pos[1],
+                .l_dirv_y = game_state.paddle_l.dirv[1],
+                .r_pos_y = game_state.paddle_r.pos[1],
+                .r_dirv_y = game_state.paddle_r.dirv[1]
             };
             send_msg(p1_conn, NET_MSG_PADDLE_POS, (uint8_t *) &msg);
+            // p2
+            msg.l_pos_y = game_state.paddle_r.pos[1];
+            msg.l_dirv_y = game_state.paddle_r.dirv[1];
+            msg.r_pos_y = game_state.paddle_l.pos[1];
+            msg.r_dirv_y = game_state.paddle_l.dirv[1];
+            send_msg(p2_conn, NET_MSG_PADDLE_POS, (uint8_t *) &msg);
             break;
         case NET_MSG_PADDLE_CHANGE_DIR:
         case NET_MSG_GAME_STATE:
+        case NET_MSG_GAME_START:
+        case NET_MSG_IS_PLAYER_1:
             break;
         }
 
@@ -118,47 +128,65 @@ static void server_lobby(const int sock) {
         LOG_FATAL("fdoepn failed for p1");
     }
 
-    // int player2 = accept(sock, nullptr, nullptr);
-    // if (player2 == -1) {
-    //     LOG_FATALF("accept failed: %s", strerror(errno));
-    // }
-    // if (fcntl(player2, F_SETFL, O_NONBLOCK) != 0) {
-    //     LOG_FATALF("fcntl failed on player2: (%d) %s", errno, strerror(errno));
-    // }
-    // printf("Player 2 connected\n");
+    IsPlayer1Msg p1_msg = {
+        .player1 = 1u
+    };
+    send_msg(p1_conn, NET_MSG_IS_PLAYER_1, (uint8_t *) &p1_msg);
 
-    // p2_conn = fdopen(player2, "r+");
-    // if (p2_conn == nullptr) {
-    //     LOG_FATAL("fdoepn failed for p2");
-    // }
+    int player2 = accept(sock, nullptr, nullptr);
+    if (player2 == -1) {
+        LOG_FATALF("accept failed: %s", strerror(errno));
+    }
+    if (fcntl(player2, F_SETFL, O_NONBLOCK) != 0) {
+        LOG_FATALF("fcntl failed on player2: (%d) %s", errno, strerror(errno));
+    }
+    printf("Player 2 connected\n");
+
+    p2_conn = fdopen(player2, "r+");
+    if (p2_conn == nullptr) {
+        LOG_FATAL("fdoepn failed for p2");
+    }
+
+    p1_msg.player1 = 0u;
+    send_msg(p2_conn, NET_MSG_IS_PLAYER_1, (uint8_t *) &p1_msg);
 }
 
-static void handle_paddle_change_dir_msg() {
+static void handle_paddle_change_dir_msg(FILE* conn, const bool p1) {
     PaddleChangeDirMsg msg;
-    recv_msg(p1_conn, NET_MSG_PADDLE_CHANGE_DIR, (uint8_t *) &msg);
+    recv_msg(conn, NET_MSG_PADDLE_CHANGE_DIR, (uint8_t *) &msg);
     SEDirection dir = (SEDirection) msg.dir;
-    GameState_paddle_l_change_dir(&game_state, dir);
+    if (p1) {
+        GameState_paddle_l_change_dir(&game_state, dir);
+    } else {
+        GameState_paddle_r_change_dir(&game_state, dir);
+    }
     push_out_msg(NET_MSG_PADDLE_POS, nullptr);
-    // 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 handle_player_input(const bool p1) {
+    FILE *conn = p1 ? p1_conn : p2_conn;
+    NetMsgType msg_type;
+    if (recv_msg_type(conn, &msg_type)) {
+        switch (msg_type) {
+        case NET_MSG_PADDLE_CHANGE_DIR:
+            handle_paddle_change_dir_msg(conn, p1);
+            break;
+        case NET_MSG_PADDLE_POS:
+        case NET_MSG_GAME_STATE:
+        case NET_MSG_GAME_START:
+        case NET_MSG_IS_PLAYER_1:
+            break;
+        }
+    }
 }
 
 static void server_game() {
     se_fps_lock_set_fps(60);
 
+    send_msg(p1_conn, NET_MSG_GAME_START, nullptr);
+    send_msg(p2_conn, NET_MSG_GAME_START, nullptr);
     send_game_state(p1_conn);
+    send_game_state(p2_conn);
 
     double last_frame_time_s = 0.0;
     while (true) {
@@ -168,20 +196,10 @@ static void server_game() {
         se_fps_lock_frame_start_s(current_time_s);
 
         // Player input
-        NetMsgType msg_type;
-        if (recv_msg_type(p1_conn, &msg_type)) {
-            switch (msg_type) {
-            case NET_MSG_PADDLE_CHANGE_DIR:
-                handle_paddle_change_dir_msg();
-                break;
-            case NET_MSG_PADDLE_POS:
-            case NET_MSG_GAME_STATE:
-                break;
-            }
-        }
+        handle_player_input(true);
+        handle_player_input(false);
 
         // Tick
-        printf("delta: %lf\n", delta);
         GameState_update(&game_state, delta);
 
         // Player output