Răsfoiți Sursa

Game rendering in multiplayer

Aaro Saila 1 lună în urmă
părinte
comite
d2203cc8d7
7 a modificat fișierele cu 146 adăugiri și 29 ștergeri
  1. 1 0
      meson.build
  2. 40 12
      src/game/MultiPlayer.c
  3. 6 0
      src/game/MultiPlayer.h
  4. 73 0
      src/game/game_common.c
  5. 25 0
      src/game/game_common.h
  6. 1 2
      src/game/pong.c
  7. 0 15
      src/server/server.c

+ 1 - 0
meson.build

@@ -32,6 +32,7 @@ game = executable(
   'src/game/MainMenu.c',
   'src/game/MultiPlayer.c',
   'src/game/SinglePlayer.c',
+  'src/game/game_common.c',
   'src/game/pong.c',
   'src/game/screen.c',
   common_src,

+ 40 - 12
src/game/MultiPlayer.c

@@ -7,19 +7,27 @@
 #include <arpa/inet.h>
 #include <unistd.h>
 
-#include "networking.h"
 #include "scufeng/log.h"
+#include "scufeng/Shape.h"
 
+#include "networking.h"
 #include "MultiPlayer.h"
 #include "game.h"
+#include "game_common.h"
 
 MultiPlayer MultiPlayer_alloc(
+    const unsigned int screen_w,
+    const unsigned int screen_h,
     const char *server_host,
     const uint16_t server_port
 ) {
     MultiPlayer mp;
 
+    mp.screen_w = screen_w;
+    mp.screen_h = screen_h;
+
     mp.state = GameState_new(game_default_params);
+    mp.shapes = GameShapes_alloc(screen_w, screen_h, game_default_params);
 
     struct protoent *proto = getprotobyname("tcp");
     mp.sock = socket(AF_INET, SOCK_STREAM, proto->p_proto);
@@ -63,6 +71,35 @@ void MultiPlayer_free(MultiPlayer *const mp) {
     mp->conn = 0;
     close(mp->sock);
     mp->sock = 0;
+
+    GameShapes_free(&mp->shapes);
+}
+
+static void pos_convert(
+    vec3 render_pos,
+    const vec3 state_pos,
+    const unsigned int screen_w,
+    const unsigned int screen_h
+) {
+    render_pos[0] = state_pos[0] * screen_w;
+    render_pos[1] = (1.0f - state_pos[1]) * screen_h;
+}
+
+static void update_shapes(
+    const GameState *const state,
+    SEMesh *const paddle_l,
+    SEMesh *const paddle_r,
+    SEMesh *const ball,
+    const unsigned int screen_w,
+    const unsigned int screen_h
+) {
+
+    // Paddles
+    pos_convert(paddle_l->transform.pos, state->paddle_l.pos, screen_w, screen_h);
+    pos_convert(paddle_r->transform.pos, state->paddle_r.pos, screen_w, screen_h);
+
+    // Ball
+    pos_convert(ball->transform.pos, state->ball.pos, screen_w, screen_h);
 }
 
 void MultiPlayer_tick(MultiPlayer *const mp, const double delta) {
@@ -94,20 +131,11 @@ void MultiPlayer_tick(MultiPlayer *const mp, const double delta) {
         uint8_t buf[PADDLE_CHANGE_DIR_MSG_ENCODED_SIZE];
         PaddleChangeDirMsg_encode(&msg, buf, PADDLE_CHANGE_DIR_MSG_ENCODED_SIZE);
         send_msg(mp->conn_s, buf, PADDLE_CHANGE_DIR_MSG_ENCODED_SIZE);
-
-        // const size_t msg_len = PADDLE_CHANGE_DIR_MSG_ENCODED_SIZE;
-        // if (fwrite(&msg_len, sizeof(size_t), 1, mp->conn_s) < 1) {
-        //     LOG_FATAL("Failed to write msg_len");
-        // }
-        // if (fwrite(&msg.dir, sizeof(msg.dir), 1, mp->conn_s) < 1) {
-        //     LOG_FATAL("Failed to write msg");
-        // }
-        // if (fflush(mp->conn_s) != 0) {
-        //     LOG_FATAL("Failed to flush stream");
-        // }
     }
 
     // last_dir = new_direction;
 
     GameState_update(&mp->state, delta);
+    GameShapes_update(&mp->shapes, &mp->state, mp->screen_w, mp->screen_h);
+    GameShapes_render(&mp->shapes);
 }

+ 6 - 0
src/game/MultiPlayer.h

@@ -4,15 +4,21 @@
 #include <stdio.h>
 
 #include "game.h"
+#include "game_common.h"
 
 typedef struct {
+    unsigned int screen_w;
+    unsigned int screen_h;
     GameState state;
+    GameShapes shapes;
     int sock;
     int conn;
     FILE *conn_s;
 } MultiPlayer;
 
 MultiPlayer MultiPlayer_alloc(
+    const unsigned int screen_w,
+    const unsigned int screen_h,
     const char *server_host,
     const uint16_t server_port
 );

+ 73 - 0
src/game/game_common.c

@@ -0,0 +1,73 @@
+#include "cglm/vec4.h"
+#include "scufeng/Scene.h"
+
+#include "game_common.h"
+#include "game.h"
+
+static void pos_convert(
+    vec3 render_pos,
+    const vec3 state_pos,
+    const unsigned int screen_w,
+    const unsigned int screen_h
+) {
+    render_pos[0] = state_pos[0] * screen_w;
+    render_pos[1] = (1.0f - state_pos[1]) * screen_h;
+}
+
+void GameShapes_update(
+    GameShapes *const shapes,
+    const GameState *const state,
+    const unsigned int screen_w,
+    const unsigned int screen_h
+) {
+
+    // Paddles
+    pos_convert(shapes->paddle_l.transform.pos, state->paddle_l.pos, screen_w, screen_h);
+    pos_convert(shapes->paddle_r.transform.pos, state->paddle_r.pos, screen_w, screen_h);
+
+    // Ball
+    pos_convert(shapes->ball.transform.pos, state->ball.pos, screen_w, screen_h);
+}
+
+GameShapes GameShapes_alloc(
+    unsigned int screen_w,
+    unsigned int screen_h,
+    GameStateParameters params
+) {
+    GameShapes shapes = {
+        .paddle_l = SEMesh_rect_color_alloc(GLM_VEC4_ONE),
+        .paddle_r = SEMesh_rect_color_alloc(GLM_VEC4_ONE),
+        .ball = SEMesh_rect_color_alloc(GLM_VEC4_ONE),
+    };
+    shapes.paddle_l.transform.scale[0] = screen_w * params.paddles_w;
+    shapes.paddle_l.transform.scale[1] = screen_h * params.paddles_h;
+    shapes.paddle_l.transform.pos[0] = screen_w * params.paddle_l_x;
+    shapes.paddle_l.transform.pos[1] = screen_h / 2.0f;
+
+    shapes.paddle_r.transform.scale[0] = screen_w * params.paddles_w;
+    shapes.paddle_r.transform.scale[1] = screen_h * params.paddles_h;
+    shapes.paddle_r.transform.pos[0] = screen_w * (1.0f - params.paddle_l_x);
+    shapes.paddle_r.transform.pos[1] = screen_h / 2.0f;
+
+    shapes.ball.transform.scale[0] = screen_w * params.ball_w;
+    shapes.ball.transform.scale[1] = shapes.ball.transform.scale[0];
+    shapes.ball.transform.pos[0] = screen_w * params.ball_pos[0];
+    shapes.ball.transform.pos[1] = screen_h * params.ball_pos[1];
+
+    return shapes;
+}
+
+void GameShapes_free(GameShapes *shapes) {
+    SEMesh_free(&shapes->paddle_l);
+    SEMesh_free(&shapes->paddle_r);
+    SEMesh_free(&shapes->ball);
+}
+
+void GameShapes_render(GameShapes *shapes) {
+    SEMesh *meshes[] = {
+        &shapes->paddle_l,
+        &shapes->paddle_r,
+        &shapes->ball
+    };
+    se_render_meshes_2d(meshes, sizeof(meshes) / sizeof(meshes[0]));
+}

+ 25 - 0
src/game/game_common.h

@@ -0,0 +1,25 @@
+#pragma once
+
+#include "scufeng/Shape.h"
+
+#include "game.h"
+
+typedef struct {
+    SEMesh paddle_l;
+    SEMesh paddle_r;
+    SEMesh ball;
+} GameShapes;
+
+void GameShapes_update(
+    GameShapes *const shapes,
+    const GameState *const state,
+    const unsigned int screen_w,
+    const unsigned int screen_h
+);
+GameShapes GameShapes_alloc(
+    unsigned int screen_w,
+    unsigned int screen_h,
+    GameStateParameters params
+);
+void GameShapes_free(GameShapes *shapes);
+void GameShapes_render(GameShapes *shapes);

+ 1 - 2
src/game/pong.c

@@ -1,4 +1,3 @@
-#include "cglm/types.h"
 #include "scufeng/engine.h"
 #include "scufeng/text.h"
 
@@ -51,7 +50,7 @@ int main() {
                 );
                 break;
             case PONG_MULTIPLAYER:
-                mp = MultiPlayer_alloc("127.0.0.1", 8080);
+                mp = MultiPlayer_alloc(screen_w, screen_h, "127.0.0.1", 8080);
                 break;
             default:
                 break;

+ 0 - 15
src/server/server.c

@@ -70,18 +70,6 @@ static void server_game() {
         se_fps_lock_frame_start_s(current_time_s);
 
         // Player input
-        // size_t msg_len;
-        // if (fread(&msg_len, sizeof(msg_len), 1, p1_conn) < 1) {
-        //     printf("feof: %d ferror: %d errno: %d\n", feof(p1_conn), ferror(p1_conn), errno);
-        //     LOG_FATAL("Failed to read msg_len from p1_conn");
-        // }
-        // printf("msg_len: %zu\n", msg_len);
-        //
-        // uint8_t *buf = (uint8_t *) malloc(msg_len);
-        // if (fread(buf, msg_len, 1, p1_conn) < 1) {
-        //     printf("feof: %d ferror: %d errno: %d\n", feof(p1_conn), ferror(p1_conn), errno);
-        //     LOG_FATAL("Failed to read msg from p1_conn");
-        // }
         uint8_t buf[PADDLE_CHANGE_DIR_MSG_ENCODED_SIZE];
         if (!recv_msg(p1_conn, buf, PADDLE_CHANGE_DIR_MSG_ENCODED_SIZE)) {
             LOG_FATAL("Failed to receive message");
@@ -97,9 +85,6 @@ static void server_game() {
             printf("Message was not from player1\n");
         }
 
-        // free(buf);
-        // buf = nullptr;
-
         // Tick
         GameState_update(&state, delta);