From a6d27ecfa4295ab7b18a8d083a798915bc3d7a3a Mon Sep 17 00:00:00 2001 From: Barry Kane Date: Sun, 2 Jul 2023 13:23:07 +0100 Subject: [PATCH] Basic stubs for graphical output and UDP thread. --- src/client/cspt-client.c | 102 ++++++++++++++++++++++++++++++++++++--- src/cspt-message.h | 6 ++- src/cspt-state.c | 59 ++++++++++++++++++++++ src/cspt-state.h | 25 ++++++++++ src/server/cspt-server.c | 34 ++++++++++--- 5 files changed, 209 insertions(+), 17 deletions(-) create mode 100644 src/cspt-state.c create mode 100644 src/cspt-state.h diff --git a/src/client/cspt-client.c b/src/client/cspt-client.c index f76c5bc..b244b2f 100644 --- a/src/client/cspt-client.c +++ b/src/client/cspt-client.c @@ -7,22 +7,109 @@ #include #include #include +#include #include #include #include #include +#include +#include +#include +#include "../cspt-state.h" #include "../cspt-message.h" +void DrawCircle(SDL_Renderer * renderer, int32_t centreX, int32_t centreY, int32_t radius) +{ + const int32_t diameter = (radius * 2); + + int32_t x = (radius - 1); + int32_t y = 0; + int32_t tx = 1; + int32_t ty = 1; + int32_t error = (tx - diameter); + + while (x >= y) + { + // Each of the following renders an octant of the circle + SDL_RenderDrawPoint(renderer, centreX + x, centreY - y); + SDL_RenderDrawPoint(renderer, centreX + x, centreY + y); + SDL_RenderDrawPoint(renderer, centreX - x, centreY - y); + SDL_RenderDrawPoint(renderer, centreX - x, centreY + y); + SDL_RenderDrawPoint(renderer, centreX + y, centreY - x); + SDL_RenderDrawPoint(renderer, centreX + y, centreY + x); + SDL_RenderDrawPoint(renderer, centreX - y, centreY - x); + SDL_RenderDrawPoint(renderer, centreX - y, centreY + x); + + if (error <= 0) + { + ++y; + error += ty; + ty += 2; + } + + if (error > 0) + { + --x; + tx += 2; + error += (tx - diameter); + } + } +} + +void * graphicsThreadHandler(void * parameters) +{ + struct gameState * state = (struct gameState *)parameters; + uint32_t rendererFlags = SDL_RENDERER_ACCELERATED; + + // Create an SDL window and rendering context in that window: + SDL_Window * window = SDL_CreateWindow("CSPT-Client", SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, 640, 640, 0); + SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, rendererFlags); + + // Enable resizing the window: + SDL_SetWindowResizable(window, SDL_TRUE); + state->clients[0].xPosition = 300; + state->clients[0].yPosition = 300; + +// while (parameters->keepRunning) + while (true) + { + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + // Clear the screen, filling it with black: + SDL_RenderClear(renderer); + + SDL_SetRenderDrawColor(renderer, 255, 255, 0, 255); + + for (int index = 0; index < 16; index++) + { + if (state->clients[index].registered == true) + { + DrawCircle(renderer, (int)state->clients[index].xPosition, (int)state->clients[index].yPosition, + 10); + } + } + + // Present the rendered graphics: + SDL_RenderPresent(renderer); + SDL_Delay(1000/60); + } + + return NULL; +} + int main(int argc, char ** argv) { - uint8_t currentPlayerNumber = 0; int serverSocket = 0; + pthread_t graphicsThread; + struct CsptMessage currentMessage; bool continueRunning = true; - CsptMessage currentMessage; + struct gameState currentState; + uint8_t currentPlayerNumber = 0; struct sockaddr_in serverAddress; - printf("Client-Side Prediction Test - Client Starting.\n"); + bzero(¤tState, sizeof(struct gameState)); + // Give me a socket, and make sure it's working: serverSocket = socket(AF_INET, SOCK_STREAM, 0); if (serverSocket == -1) @@ -46,8 +133,8 @@ int main(int argc, char ** argv) currentMessage.type = 0; currentMessage.content = 0; - send(serverSocket, ¤tMessage, sizeof(CsptMessage), 0); - recv(serverSocket, ¤tMessage, sizeof(CsptMessage), 0); + send(serverSocket, ¤tMessage, sizeof(struct CsptMessage), 0); + recv(serverSocket, ¤tMessage, sizeof(struct CsptMessage), 0); if (currentMessage.type == 0) { @@ -57,9 +144,10 @@ int main(int argc, char ** argv) printf("Registered as: %u\n", currentPlayerNumber); printf("%-7s | %u\n", messageStrings[currentMessage.type], currentMessage.content); + pthread_create(&graphicsThread, NULL, graphicsThreadHandler, ¤tState); while (continueRunning) { - if (recv(serverSocket, ¤tMessage, sizeof(CsptMessage), 0) > 0) + if (recv(serverSocket, ¤tMessage, sizeof(struct CsptMessage), 0) > 0) { printf("%-7s | %u\n", messageStrings[currentMessage.type], currentMessage.content); switch (currentMessage.type) @@ -77,7 +165,7 @@ int main(int argc, char ** argv) // Pinged, so we now must pong. currentMessage.type = 3; currentMessage.content = 0; - send(serverSocket, ¤tMessage, sizeof(CsptMessage), 0); + send(serverSocket, ¤tMessage, sizeof(struct CsptMessage), 0); break; } } diff --git a/src/cspt-message.h b/src/cspt-message.h index 8033cf4..6b088c1 100644 --- a/src/cspt-message.h +++ b/src/cspt-message.h @@ -2,11 +2,12 @@ #define CSPT_MESSAGE_H #include const char * messageStrings[] = {"HELLO", "GOODBYE", "PING", "PONG"}; -typedef struct CsptMessage + +struct CsptMessage { uint8_t type; uint8_t content; -} CsptMessage; +}; /* Message Types: 0 - HELLO: Contents sent to client indicate a given player number. @@ -14,4 +15,5 @@ typedef struct CsptMessage 2 - PING: Contents indicate the missed amount of pongs. 3 - PONG: No contents. */ + #endif diff --git a/src/cspt-state.c b/src/cspt-state.c new file mode 100644 index 0000000..9c4e63a --- /dev/null +++ b/src/cspt-state.c @@ -0,0 +1,59 @@ +#include "cspt-state.h" + +void doGameTick(struct gameState * state) +{ + state->timestamp = time(NULL); + for (int index = 0; index < 16; index++) + { + if (state->clients[index].registered == true) + { + // Calculate acceleration: + if (state->clients[index].leftAcceleration) + { + state->clients[index].xVelocity -= 0.1; + } + if (state->clients[index].rightAcceleration) + { + state->clients[index].xVelocity += 0.1; + } + if (state->clients[index].upAcceleration) + { + state->clients[index].yVelocity += 0.1; + } + if (state->clients[index].downAcceleration) + { + state->clients[index].yVelocity += 0.1; + } + if (!state->clients[index].leftAcceleration && !state->clients[index].rightAcceleration) + { + state->clients[index].xVelocity *= 0.1; + } + if (!state->clients[index].upAcceleration && !state->clients[index].downAcceleration) + { + state->clients[index].yVelocity *= 0.1; + } + + // Clamp speed: + if (state->clients[index].xVelocity > 10) + { + state->clients[index].xVelocity = 10; + } + if (state->clients[index].xVelocity < -10) + { + state->clients[index].xVelocity = -10; + } + if (state->clients[index].yVelocity > 10) + { + state->clients[index].yVelocity = 10; + } + if (state->clients[index].yVelocity < -10) + { + state->clients[index].yVelocity = -10; + } + + // Do movement: + state->clients[index].xPosition += state->clients[index].xVelocity; + state->clients[index].yPosition += state->clients[index].yVelocity; + } + } +} diff --git a/src/cspt-state.h b/src/cspt-state.h new file mode 100644 index 0000000..5a5cbe4 --- /dev/null +++ b/src/cspt-state.h @@ -0,0 +1,25 @@ +#ifndef CSPT_STATE_H +#define CSPT_STATE_H +#include +#include + +struct clientMovement +{ + double xPosition, yPosition, xVelocity, yVelocity; + bool leftAcceleration, rightAcceleration, upAcceleration, downAcceleration, registered; +}; + +struct clientInput +{ + bool left, right, up, down; +}; + +struct gameState +{ + time_t timestamp; + struct clientMovement clients[16]; +}; + +void doGameTick(struct gameState * state); + +#endif diff --git a/src/server/cspt-server.c b/src/server/cspt-server.c index 5e73af4..bd16f66 100644 --- a/src/server/cspt-server.c +++ b/src/server/cspt-server.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -15,7 +16,7 @@ #include #include "../cspt-message.h" bool keepRunning = true; - +const int PORT = 5200; struct connectionStatus { uint8_t remainingPongs; @@ -26,6 +27,23 @@ void sigintHandler(int signal) keepRunning = false; } +void * networkThreadHandler(void * arguments) +{ + int udpSocket; + struct sockaddr_in serverAddress; + if ((udpSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + { + exit(EXIT_FAILURE); + } + + memset(&serverAddress, 0, sizeof(serverAddress)); + serverAddress.sin_family = AF_INET; + serverAddress.sin_port = htons(PORT); + serverAddress.sin_addr.s_addr = INADDR_ANY; + + return NULL; +} + int main(int argc, char ** argv) { int returnValue = 0; @@ -34,7 +52,7 @@ int main(int argc, char ** argv) fd_set connectedClients; struct connectionStatus clientStatus[16]; struct sockaddr_in serverAddress, clientAddress; - CsptMessage currentMessage; + struct CsptMessage currentMessage; printf("Client-Side Prediction Test - Server Starting.\n"); // Setup the sigint handler: @@ -152,7 +170,7 @@ int main(int argc, char ** argv) if (FD_ISSET(clientSockets[index], &connectedClients)) { // The client has sent a message, recieve it and process: - if ((returnValue = recv(clientSockets[index], ¤tMessage, sizeof(CsptMessage), 0)) > 0) + if ((returnValue = recv(clientSockets[index], ¤tMessage, sizeof(struct CsptMessage), 0)) > 0) { printf("%s, %u\n", messageStrings[currentMessage.type], currentMessage.content); switch (currentMessage.type) @@ -162,7 +180,7 @@ int main(int argc, char ** argv) { currentMessage.type = 0; currentMessage.content = (uint8_t)random() % 16; - send(clientSockets[index], ¤tMessage, sizeof(CsptMessage), 0); + send(clientSockets[index], ¤tMessage, sizeof(struct CsptMessage), 0); break; } // Goodbye: @@ -193,7 +211,7 @@ int main(int argc, char ** argv) currentMessage.type = 1; currentMessage.content = 0; FD_CLR(clientSockets[index], &connectedClients); - send(clientSockets[index], ¤tMessage, sizeof(CsptMessage), 0); + send(clientSockets[index], ¤tMessage, sizeof(struct CsptMessage), 0); shutdown(clientSockets[index], SHUT_RDWR); clientSockets[index] = 0; } @@ -208,13 +226,13 @@ int main(int argc, char ** argv) { currentMessage.type = 2; currentMessage.content = 0; - send(clientSockets[index], ¤tMessage, sizeof(CsptMessage), 0); + send(clientSockets[index], ¤tMessage, sizeof(struct CsptMessage), 0); clientStatus[index].remainingPongs++; if (clientStatus[index].remainingPongs >= 10) { currentMessage.type = 1; currentMessage.content = 0; - send(clientSockets[index], ¤tMessage, sizeof(CsptMessage), 0); + send(clientSockets[index], ¤tMessage, sizeof(struct CsptMessage), 0); shutdown(clientSockets[index], SHUT_RDWR); clientSockets[index] = 0; } @@ -228,7 +246,7 @@ int main(int argc, char ** argv) { currentMessage.type = 1; currentMessage.content = 0; - send(clientSockets[index], ¤tMessage, sizeof(CsptMessage), 0); + send(clientSockets[index], ¤tMessage, sizeof(struct CsptMessage), 0); shutdown(clientSockets[index], SHUT_RDWR); clientSockets[index] = 0; }