DEADSOFTWARE

Изменён способ передачи does команд и исправлены адские тормоза
authorDeaDDooMER <deaddoomer@deadsoftware.ru>
Fri, 31 Mar 2017 21:14:02 +0000 (00:14 +0300)
committerDeaDDooMER <deaddoomer@deadsoftware.ru>
Fri, 31 Mar 2017 21:14:02 +0000 (00:14 +0300)
.gitignore
client.c
client.h
dedicated.c
game.c
game.h
makefile
netwar.c
protocol.h
server.c

index cbac3ede270141561bf31dc604c989e719aa8f30..f53483fa21bbf0732b89e2767bc1d70468557975 100644 (file)
@@ -2,3 +2,4 @@
 *.dll
 netwar
 dedicated
+gmon.out
index c1c9a557c7368229b647ebea1467f47c2d6c0207..6c00cd29460d141be8b819193194005c95a7ec36 100644 (file)
--- a/client.c
+++ b/client.c
@@ -6,12 +6,17 @@
 #include "network.h"
 #include "protocol.h"
 
-int cl_playerid;
+int cl_playerid = -1;
 
-static bool      run;
 static IPaddress addr;
 static UDPsocket sock;
-static char      nickname[32] = "Anonymous";    
+static char      nickname[32] = "Anonymous";
+
+static Uint32 lastTime;
+static Uint32 currTime;
+
+static DoesBits does;
+static bool     does_updated;
 
 static void cl_kill_client(ProtocolMessage m) {
        SDL_Log("Connection refused by server: %.*s\n", (int) sizeof(m.sv.kill.message), m.sv.kill.message);
@@ -51,8 +56,37 @@ static void cl_update_svbullet(ProtocolMessage m) {
        );
 }
 
+static void cl_recv() {
+       IPaddress address;
+       ProtocolMessage m;
+       if(!RecvMessage(sock, &address, &m))
+               return;
+
+       switch(m.type) {
+       case SV_INFO: cl_update_svinfo(m); break;
+       case SV_KILL: cl_kill_client(m); break;
+       case SV_SPLR: cl_update_svplayer(m); break;
+       case SV_SBUL: cl_update_svbullet(m); break;
+       default:      SDL_Log("invalid message %i", m.type);
+       }
+}
+
+static void cl_send() {
+       if(does_updated) {
+               SendMessage(sock, addr, cl_does(does));
+
+               does.bits = 0;
+               does_updated = false;
+       }
+}
+
+void cl_move(DoesBits code) {
+       does_updated = true;
+       does.bits |= code.bits;
+}
+
 void cl_connect(const char * host, uint16_t port) {
-       if(SDLNet_ResolveHost(&addr, host, (port) ? (port) : (DEFAULT_PORT)) != 0) {
+       if(SDLNet_ResolveHost(&addr, host, (port) ? (port) : (PROTOCOL_PORT)) != 0) {
                SDL_Log("Unable to resolve host: %s\n", SDLNet_GetError());
                exit(1);
        }
@@ -67,39 +101,19 @@ void cl_connect(const char * host, uint16_t port) {
                exit(1);
        }
 
-       run = true;     
        if(m.type == SV_KILL) {
                cl_kill_client(m);
        } else if(m.type == SV_INFO) {
                cl_update_svinfo(m);
        } else {
-               SDL_Log("Invalid first message %i\n", m.type);
-               run = false;
+               SDL_Log("Invalid first message %i", m.type);
+               exit(1);
        }
 }
 
-void cl_move(DoesCode code) {
-       g_player_does(cl_playerid, code);
-       SendMessage(sock, addr, cl_does(code));
-}
-
-void cl_recv() {
-       IPaddress address;
-       ProtocolMessage m;
-       if(!RecvMessage(sock, &address, &m))
-               return;
-
-       switch(m.type) {
-       case SV_INFO: cl_update_svinfo(m); break;
-       case SV_KILL: cl_kill_client(m); break;
-       case SV_SPLR: cl_update_svplayer(m); break;
-       case SV_SBUL: cl_update_svbullet(m); break;
-       default:      SDL_Log("invalid message %i", m.type);
-       }
-}
 
 void cl_disconnect(bool force) {
-       if(!run)
+       if(cl_playerid < 0)
                return;
 
        if(!force)
@@ -107,9 +121,21 @@ void cl_disconnect(bool force) {
 
        ClosePort(sock);
 
-       run = false;
+       cl_playerid = -1;
 }
 
-bool cl_isrun() {
-       return run;
+void cl_handle() {
+       cl_recv();
+
+       if(currTime - lastTime >= TICK_DELAY) {
+               if(does_updated)
+                       g_player_does(cl_playerid, does);
+
+               g_update();
+
+               cl_send();
+
+               lastTime = SDL_GetTicks();
+       }
+       currTime = SDL_GetTicks();
 }
index 1a85a2385820b94d088841f34ac4e450cdf00fb1..fba109b91ff44104fce3bb92aaa0191d4b4a622e 100644 (file)
--- a/client.h
+++ b/client.h
@@ -4,6 +4,5 @@ extern int cl_playerid;
 
 void cl_connect(const char * host, uint16_t port);
 void cl_disconnect(bool force);
-void cl_move(DoesCode code);
-void cl_recv();
-bool cl_isrun();
+void cl_move(DoesBits code);
+void cl_handle();
index bef813c39c8029c1306e53c698c174cf2bd5752a..d2610c0ab6c7b4d1798c9ac3f6b8ca8c9e42d086 100644 (file)
@@ -6,7 +6,7 @@
 #include "server.h"
 #include "protocol.h"
 
-static uint16_t port = DEFAULT_PORT;
+static uint16_t port = PROTOCOL_PORT;
 
 static void argverr() {
        SDL_Log("Invalid argument\n");
diff --git a/game.c b/game.c
index 219141884dd23ba9a59b2643135c78fcd83568e5..9b7f2391ddc78d4aa3fdb7ef0777ba46c9001e61 100644 (file)
--- a/game.c
+++ b/game.c
@@ -81,16 +81,19 @@ static bool collide(float x1, float y1, float r1, float x2, float y2, float r2)
        return ((l - r1 - r2) <= 0);
 }
 
-void g_player_does(unsigned int id, DoesCode code) {
+void g_player_does(unsigned int id, DoesBits code) {
        assert(id < MAX_PLAYERS);
-       g_player[id].updated = true;
-       switch(code) {
-       case DOES_UP:    moveplayer(id, SPEED); break;
-       case DOES_DOWN:  moveplayer(id, -SPEED); break;
-       case DOES_LEFT:  roteplayer(id, -ROTATE); break;
-       case DOES_RIGHT: roteplayer(id, ROTATE); break;
-       case DOES_FIRE:  fireplayer(id); break;
-       }
+
+       if(code.up)
+               moveplayer(id, SPEED);
+       if(code.down)
+               moveplayer(id, -SPEED);
+       if(code.left)
+               roteplayer(id, -ROTATE);
+       if(code.right)
+               roteplayer(id, ROTATE);
+       if(code.fire)
+               fireplayer(id);
 }
 
 void g_update() {
diff --git a/game.h b/game.h
index 7bf9d1e5621aa8838cb760bb39e4e0df0e54820e..44bad6348d2dfe74d980270ad03bd066bba26473 100644 (file)
--- a/game.h
+++ b/game.h
@@ -4,7 +4,7 @@
 
 #define MAX_PLAYERS 32
 #define MAX_BULLETS (MAX_PLAYERS * 8)
-#define TICK_DELAY  (1000 / 30)
+#define TICK_DELAY  (1000 / 40)
 #define BULLET_TIME (TICK_DELAY * 6)
 #define PLAYER_SIZE 0.01785
 
@@ -35,5 +35,5 @@ extern Bullet g_bullet[MAX_BULLETS];
 
 void g_player_set(unsigned int id, bool live, float x, float y, float r, float vx, float vy, float vr);
 void g_bullet_set(unsigned int id, unsigned int owner, bool live, float x, float y, float vx, float vy, int tick);
-void g_player_does(unsigned int id, DoesCode code);
+void g_player_does(unsigned int id, DoesBits code);
 void g_update();
index 973189bf8ee2ea53dbf61ff509485ab190bbeb24..506bebf4f1a468a53794a0d7263b97c56579699a 100644 (file)
--- a/makefile
+++ b/makefile
@@ -5,7 +5,7 @@ ifdef WIN32
        OUTPOSTFIX := .exe
 else
        CC := gcc
-       CFLAGS := -g -std=gnu11 -Wall
+       CFLAGS := -pg -std=gnu11 -Wall
        LDFLAGS := -lSDL2_net -lSDL2 -lm
 endif
 
index b18f8ac9d7a5f288d546dcacbd8de65f30a3629e..88ff5c7ba766b2e9f27bc044d45291ad23706da7 100644 (file)
--- a/netwar.c
+++ b/netwar.c
@@ -20,7 +20,7 @@ static const float ship[] = {
 
 static char     * host = "localhost";
 static char     * nick = "Anonymous";
-static uint16_t   port = DEFAULT_PORT;
+static uint16_t   port = PROTOCOL_PORT;
 
 static SDL_Window   * window;
 static SDL_Renderer * renderer;
@@ -129,16 +129,16 @@ static void paintwindow() {
 static void keyboardhandle() {
        SDL_PumpEvents();
        const Uint8 * key = SDL_GetKeyboardState(NULL);
-       if(key[SDL_SCANCODE_UP])
-               cl_move(DOES_UP);
-       if(key[SDL_SCANCODE_DOWN])
-               cl_move(DOES_DOWN);
-       if(key[SDL_SCANCODE_LEFT])
-               cl_move(DOES_LEFT);
-       if(key[SDL_SCANCODE_RIGHT])
-               cl_move(DOES_RIGHT);
-       if(key[SDL_SCANCODE_LCTRL])
-               cl_move(DOES_FIRE);     
+       cl_move((DoesBits) {
+               .up    = key[SDL_SCANCODE_UP],
+               .down  = key[SDL_SCANCODE_DOWN],
+               .left  = key[SDL_SCANCODE_LEFT],
+               .right = key[SDL_SCANCODE_RIGHT],
+       });
+}
+
+static void fire() {
+       cl_move((DoesBits) { .fire = true });
 }
 
 int main(int argc, char ** argv) {
@@ -148,23 +148,17 @@ int main(int argc, char ** argv) {
 
        cl_connect(host, port);
 
-       Uint32 lastTime = SDL_GetTicks();
-       Uint32 currTime = SDL_GetTicks();
-
-       while(cl_isrun()) {
+       while(cl_playerid >= 0) {
                SDL_Event event;
                while(SDL_PollEvent(&event))
                        if(event.type == SDL_QUIT)
                                goto cleanup;
+                       else if(event.type == SDL_KEYDOWN && event.key.keysym.scancode == SDL_SCANCODE_LCTRL)
+                               fire();
 
-               cl_recv();
+               keyboardhandle();
 
-               if(currTime - lastTime >= TICK_DELAY) {
-                       keyboardhandle();
-                       g_update();
-                       lastTime = SDL_GetTicks();
-               }
-               currTime = SDL_GetTicks();
+               cl_handle();
 
                paintwindow();
 
index a20c773d16fbe0751ac5fcb6b6f9da3c4f05b233..68ec54a55aaa9a7c44b2a1af22c74c6c66a71652 100644 (file)
@@ -5,8 +5,8 @@
 #include <stdbool.h>
 #include <string.h>
 
-#define DEFAULT_PORT     29386
-#define PROTOCOL_VERSION 1
+#define PROTOCOL_PORT    29386
+#define PROTOCOL_VERSION 2
 #define PROTOCOL_F8FRAC  (1 << 7)
 
 #define PACKED __attribute__((__packed__))
@@ -24,13 +24,16 @@ typedef enum {
        SV_SBUL = 131,
 } MessageType;
 
-typedef enum {
-       DOES_UP    = 0,
-       DOES_DOWN  = 1,
-       DOES_LEFT  = 2,
-       DOES_RIGHT = 3,
-       DOES_FIRE  = 4,
-} DoesCode;
+typedef union DoesBits {
+       uint8_t bits;
+       struct PACKED {
+               uint8_t up    : 1;
+               uint8_t down  : 1;
+               uint8_t left  : 1;
+               uint8_t right : 1;
+               uint8_t fire  : 1;
+       };
+} DoesBits;
 
 typedef struct PACKED ClInfo {
        uint8_t type;
@@ -43,8 +46,8 @@ typedef struct PACKED ClKill {
 } ClKill;
 
 typedef struct PACKED ClDoes {
-       uint8_t type;
-       uint8_t code;
+       uint8_t  type;
+       DoesBits code;
 } ClDoes;
 
 typedef struct PACKED SvInfo {
@@ -135,7 +138,7 @@ static inline ProtocolMessage cl_kill() {
        };
 }
 
-static inline ProtocolMessage cl_does(DoesCode code) {
+static inline ProtocolMessage cl_does(DoesBits code) {
        return (ProtocolMessage) (ClMessage) (ClDoes) {
                .type = CL_DOES,
                .code = code,
index d6cbfcc3b3c07cb1670bb914466dd414dca5136d..5e4823451f706e01bb394d6312de50135bf40436 100644 (file)
--- a/server.c
+++ b/server.c
@@ -111,14 +111,13 @@ static void sv_register_player(IPaddress address, ProtocolMessage m) {
 static void sv_recv() {
        IPaddress address;
        ProtocolMessage m;
-       if(!RecvMessage(sock, &address, &m))
-               return;
-
-       switch(m.type) {
-       case CL_INFO: sv_register_player(address, m); break;
-       case CL_KILL: sv_kill_player(sv_find_client(address), false, ""); break;
-       case CL_DOES: sv_move_player(sv_find_client(address), m); break;
-       default:      SDL_Log("invalid message %i", m.type);
+       while(RecvMessage(sock, &address, &m)) {
+               switch(m.type) {
+               case CL_INFO: sv_register_player(address, m); break;
+               case CL_KILL: sv_kill_player(sv_find_client(address), false, ""); break;
+               case CL_DOES: sv_move_player(sv_find_client(address), m); break;
+               default:      SDL_Log("invalid message %i", m.type);
+               }
        }
 }