diff --git a/include/sk_lobby.h b/include/sk_lobby.h
new file mode 100644
index 0000000..212b584
--- /dev/null
+++ b/include/sk_lobby.h
@@ -0,0 +1,41 @@
+/*
+ * GNU Sparky --- A 5v5 character-based libre tactical shooter
+ * Copyright (C) 2024 Wasym A. Alonso
+ *
+ * This file is part of Sparky.
+ *
+ * Sparky is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Sparky is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Sparky. If not, see .
+ */
+
+
+#pragma once
+
+#include
+#include
+
+#define SK_LOBBY_MAX_PLAYERS 10
+
+typedef struct {
+ u8 id;
+ u8 players_count;
+ sk_player players[SK_LOBBY_MAX_PLAYERS];
+} sk_lobby;
+
+sk_lobby sk_lobby_create(u8 id);
+
+void sk_lobby_destroy(sk_lobby *l);
+
+u8 sk_lobby_add(sk_lobby *l, sk_player p);
+
+u8 sk_lobby_kick(sk_lobby *l, i8 p_idx);
diff --git a/include/sk_renderer.h b/include/sk_renderer.h
index d530ce5..ae65d27 100644
--- a/include/sk_renderer.h
+++ b/include/sk_renderer.h
@@ -22,7 +22,7 @@
#pragma once
#include
-#include
+#include
#define sk_renderer_loop while (!WindowShouldClose())
@@ -30,6 +30,6 @@ void sk_renderer_create(void);
void sk_renderer_destroy(void);
-void sk_renderer_update(State *s);
+void sk_renderer_update(sk_state *s);
-void sk_renderer_draw(State *s);
+void sk_renderer_draw(sk_state *s);
diff --git a/include/sk_gametypes.h b/include/sk_scene.h
similarity index 83%
rename from include/sk_gametypes.h
rename to include/sk_scene.h
index c0c340c..216a132 100644
--- a/include/sk_gametypes.h
+++ b/include/sk_scene.h
@@ -21,15 +21,11 @@
#pragma once
-#include
-
typedef enum {
- SCENE_MAIN_MENU,
- SCENE_GAMEPLAY
-} Scene;
+ SK_SCENE_KIND_MAIN_MENU,
+ SK_SCENE_KIND_GAMEPLAY
+} sk_scene_kind;
-typedef struct State {
- Scene current_scene;
- sk_player player;
- u8 is_online;
-} State;
+typedef struct {
+ sk_scene_kind kind;
+} sk_scene;
diff --git a/include/sk_server.h b/include/sk_server.h
index 25178be..7bc26d1 100644
--- a/include/sk_server.h
+++ b/include/sk_server.h
@@ -27,7 +27,7 @@
#define SK_SERVER_PORT 27015
#define SK_SERVER_TICK_RATE 128
#define SK_SERVER_MSG_MAX_SIZE 1024
-#define SK_SERVER_MSG_CONN_REQ "ping::" SK_SERVER_NAME
-#define SK_SERVER_MSG_CONN_RES "pong::" SK_SERVER_NAME
+#define SK_SERVER_MSG_CONN_REQ SK_SERVER_NAME "::ping"
+#define SK_SERVER_MSG_CONN_RES SK_SERVER_NAME "::pong::%u/%u"
u8 sk_server_run(void);
diff --git a/include/sk_state.h b/include/sk_state.h
new file mode 100644
index 0000000..7989357
--- /dev/null
+++ b/include/sk_state.h
@@ -0,0 +1,45 @@
+/*
+ * GNU Sparky --- A 5v5 character-based libre tactical shooter
+ * Copyright (C) 2024 Wasym A. Alonso
+ *
+ * This file is part of Sparky.
+ *
+ * Sparky is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Sparky is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Sparky. If not, see .
+ */
+
+
+#pragma once
+
+#include
+#include
+
+#define SK_STATE_MAX_LOBBIES 256
+
+typedef struct {
+ u8 is_online;
+ sk_scene curr_scene;
+ union {
+ struct {
+ u8 lobbies_count;
+ sk_lobby lobbies[SK_STATE_MAX_LOBBIES];
+ };
+ struct {
+ sk_player player;
+ };
+ };
+} sk_state;
+
+sk_state sk_state_create(u8 is_online);
+
+void sk_state_destroy(sk_state *s);
diff --git a/src/sk_client.c b/src/sk_client.c
index 6805b60..dc40f82 100644
--- a/src/sk_client.c
+++ b/src/sk_client.c
@@ -23,18 +23,17 @@
#include
#include
#include
+#include
#include
#include
#include
#include
#include
#include
-#include
-
-static State state = {0};
u8 sk_client_run(const char *ip) {
TraceLog(LOG_INFO, "Initializing %s", SK_CLIENT_NAME);
+ u8 is_online = 0;
int sock_fd;
if (!ip) TraceLog(LOG_WARNING, "Running in offline mode");
else {
@@ -68,9 +67,9 @@ u8 sk_client_run(const char *ip) {
}
pong_msg[pong_msg_n] = 0;
if (!strcmp(pong_msg, SK_SERVER_MSG_CONN_RES)) {
- state.is_online = 1;
+ is_online = 1;
}
- if (!state.is_online) {
+ if (!is_online) {
TraceLog(LOG_ERROR, "Unable to communicate with `%s`. Exiting...", ip);
close(sock_fd);
return 1;
@@ -80,16 +79,20 @@ u8 sk_client_run(const char *ip) {
if (!ChangeDirectory(GetApplicationDirectory())) {
TraceLog(LOG_WARNING, "Could not change CWD to the game's root directory");
}
- sk_renderer_create();
- state.current_scene = SCENE_MAIN_MENU;
- state.player = sk_player_create(SK_PLAYER_KIND_JETT);
- sk_renderer_loop {
- sk_renderer_update(&state);
- sk_renderer_draw(&state);
+ sk_state state = sk_state_create(is_online);
+ if (!is_online) {
+ sk_renderer_create();
+ sk_renderer_loop {
+ sk_renderer_update(&state);
+ sk_renderer_draw(&state);
+ }
+ sk_player_destroy(&state.player);
+ sk_renderer_destroy();
+ }
+ else {
+ TraceLog(LOG_WARNING, "Not implemented yet");
}
- sk_player_destroy(&state.player);
- sk_renderer_destroy();
- if (state.is_online) close(sock_fd);
+ if (is_online) close(sock_fd);
TraceLog(LOG_INFO, "%s closed successfully", SK_CLIENT_NAME);
return 0;
}
diff --git a/src/sk_lobby.c b/src/sk_lobby.c
new file mode 100644
index 0000000..b0fa760
--- /dev/null
+++ b/src/sk_lobby.c
@@ -0,0 +1,76 @@
+/*
+ * GNU Sparky --- A 5v5 character-based libre tactical shooter
+ * Copyright (C) 2024 Wasym A. Alonso
+ *
+ * This file is part of Sparky.
+ *
+ * Sparky is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Sparky is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Sparky. If not, see .
+ */
+
+
+#include
+
+sk_lobby sk_lobby_create(u8 id) {
+ sk_lobby l = {
+ .id = id,
+ .players_count = 0
+ };
+ for (u8 i = 0; i < SK_LOBBY_MAX_PLAYERS; ++i) {
+ l.players[i] = (sk_player) {
+ .lobby_id = -1,
+ .lobby_slot_idx = -1
+ };
+ }
+ return l;
+}
+
+void sk_lobby_destroy(sk_lobby *l) {
+ (void) l;
+}
+
+u8 sk_lobby_add(sk_lobby *l, sk_player p) {
+ if (l->players_count == SK_LOBBY_MAX_PLAYERS) {
+ TraceLog(LOG_DEBUG, "Lobby %u :: unable to add more players (full)", l->id);
+ return false;
+ }
+ for (u8 i = 0; i < SK_LOBBY_MAX_PLAYERS; ++i) {
+ if (l->players[i].lobby_id != -1 &&
+ l->players[i].lobby_slot_idx != -1 ) continue;
+ p.lobby_id = l->id;
+ p.lobby_slot_idx = i;
+ l->players[i] = p;
+ TraceLog(LOG_INFO, "Lobby %u :: added new player to slot %u/%u",
+ l->id,
+ i + 1,
+ SK_LOBBY_MAX_PLAYERS);
+ }
+ ++l->players_count;
+ return true;
+}
+
+u8 sk_lobby_kick(sk_lobby *l, i8 p_idx) {
+ if (p_idx >= l->players_count ||
+ l->players[p_idx].lobby_id != l->id ||
+ l->players[p_idx].lobby_slot_idx != p_idx) {
+ TraceLog(LOG_DEBUG, "Lobby %u :: unable to kick non-existant player", l->id);
+ return false;
+ }
+ l->players[p_idx].lobby_id = -1;
+ l->players[p_idx].lobby_slot_idx = -1;
+ l->players[p_idx] = (sk_player) {
+ .lobby_id = -1,
+ .lobby_slot_idx = -1
+ };
+ return true;
+}
diff --git a/src/sk_renderer_draw.c b/src/sk_renderer_draw.c
index 1a0411a..4abe4d8 100644
--- a/src/sk_renderer_draw.c
+++ b/src/sk_renderer_draw.c
@@ -60,7 +60,7 @@ static inline void __draw_walls(void) {
DrawCube((Vector3) { 0, 2.5f, 16 }, 32, 5, 1, GOLD);
}
-static void __draw_gameplay_world(State *s) {
+static void __draw_gameplay_world(sk_state *s) {
ClearBackground(SKYBLUE);
BeginMode3D(s->player.camera);
sk_player_draw(&s->player);
@@ -101,7 +101,7 @@ static inline void __draw_crosshair(void) {
WHITE);
}
-static void __draw_gameplay_hud(State *s) {
+static void __draw_gameplay_hud(sk_state *s) {
__draw_fps();
__draw_frametime();
if (s->is_online) {
@@ -111,13 +111,13 @@ static void __draw_gameplay_hud(State *s) {
__draw_crosshair();
}
-void sk_renderer_draw(State *s) {
+void sk_renderer_draw(sk_state *s) {
BeginDrawing();
- switch (s->current_scene) {
- case SCENE_MAIN_MENU:
+ switch (s->curr_scene.kind) {
+ case SK_SCENE_KIND_MAIN_MENU:
__draw_main_menu();
break;
- case SCENE_GAMEPLAY:
+ case SK_SCENE_KIND_GAMEPLAY:
__draw_gameplay_world(s);
__draw_gameplay_hud(s);
break;
diff --git a/src/sk_renderer_update.c b/src/sk_renderer_update.c
index cd9a249..78afa3a 100644
--- a/src/sk_renderer_update.c
+++ b/src/sk_renderer_update.c
@@ -24,20 +24,20 @@
#include
#include
-static void __update_main_menu(State *s) {
+static void __update_main_menu(sk_state *s) {
if (IsKeyPressed(KEY_ENTER)) {
- s->current_scene = SCENE_GAMEPLAY;
+ s->curr_scene.kind = SK_SCENE_KIND_GAMEPLAY;
sk_player_load(&s->player, SK_WEAPON_KIND_7MM);
DisableCursor();
}
}
-void sk_renderer_update(State *s) {
- switch (s->current_scene) {
- case SCENE_MAIN_MENU:
+void sk_renderer_update(sk_state *s) {
+ switch (s->curr_scene.kind) {
+ case SK_SCENE_KIND_MAIN_MENU:
__update_main_menu(s);
break;
- case SCENE_GAMEPLAY:
+ case SK_SCENE_KIND_GAMEPLAY:
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) sk_weapon_shoot(&s->player.weapon);
sk_player_jump(&s->player);
sk_player_move(&s->player, sk_player_peek(&s->player));
diff --git a/src/sk_scene.c b/src/sk_scene.c
new file mode 100644
index 0000000..6d644ee
--- /dev/null
+++ b/src/sk_scene.c
@@ -0,0 +1,22 @@
+/*
+ * GNU Sparky --- A 5v5 character-based libre tactical shooter
+ * Copyright (C) 2024 Wasym A. Alonso
+ *
+ * This file is part of Sparky.
+ *
+ * Sparky is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Sparky is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Sparky. If not, see .
+ */
+
+
+#include
diff --git a/src/sk_server.c b/src/sk_server.c
index f64c6c9..72ebd96 100644
--- a/src/sk_server.c
+++ b/src/sk_server.c
@@ -19,6 +19,7 @@
*/
+#include
#include
#include
#include
@@ -98,8 +99,14 @@ u8 sk_server_run(void) {
msg[msg_n] = 0;
if (!strcmp(msg, SK_SERVER_MSG_CONN_REQ)) {
TraceLog(LOG_INFO, "Connection from client (%s:%d) requested", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
+ // TODO: check if there is a free slot in a lobby
+ u8 lobby_id = 0;
+ u8 lobby_slot_id = 0;
+ // TODO: assign him a lobby and a player slot inside it
+ memset(msg, 0, sizeof(msg));
+ sprintf(msg, SK_SERVER_MSG_CONN_RES, lobby_id, lobby_slot_id);
if (sendto(sock_fd,
- SK_SERVER_MSG_CONN_RES,
+ msg,
strlen(SK_SERVER_MSG_CONN_RES),
0,
(struct sockaddr *) &client_addr,
@@ -108,7 +115,6 @@ u8 sk_server_run(void) {
continue;
}
TraceLog(LOG_INFO, "Connection from client (%s:%d) accepted", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
- // TODO: assign him a lobby with a free slot to be in
}
wait_next_tick(dt);
}
diff --git a/src/sk_state.c b/src/sk_state.c
new file mode 100644
index 0000000..e42188a
--- /dev/null
+++ b/src/sk_state.c
@@ -0,0 +1,43 @@
+/*
+ * GNU Sparky --- A 5v5 character-based libre tactical shooter
+ * Copyright (C) 2024 Wasym A. Alonso
+ *
+ * This file is part of Sparky.
+ *
+ * Sparky is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Sparky is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Sparky. If not, see .
+ */
+
+
+#include
+
+sk_state sk_state_create(u8 is_online) {
+ sk_state s = {
+ .is_online = is_online,
+ .curr_scene = (sk_scene) { .kind = SK_SCENE_KIND_MAIN_MENU }
+ };
+ if (is_online) {
+ s.lobbies_count = 0;
+ for (u16 i = 0; i < SK_STATE_MAX_LOBBIES; ++i) {
+ s.lobbies[i] = sk_lobby_create(i);
+ }
+ }
+ else {
+ s.player = sk_player_create(SK_PLAYER_KIND_JETT);
+ }
+ return s;
+}
+
+void sk_state_destroy(sk_state *s) {
+ (void) s;
+}