From 11b568550c45d21cfd302fd1b32f69f5e0cefaf5 Mon Sep 17 00:00:00 2001 From: Barry Kane Date: Sun, 15 Oct 2023 23:54:02 +0100 Subject: [PATCH] Current Working Tree on <2023-10-15> --- source/Spacewar-Client.c | 73 +++++++++++++++++++++++++++++++++++---- source/Spacewar-Physics.c | 49 ++++++++++++++------------ source/Spacewar-Server.c | 19 ++++++++-- 3 files changed, 110 insertions(+), 31 deletions(-) diff --git a/source/Spacewar-Client.c b/source/Spacewar-Client.c index a79362a..927a2bb 100644 --- a/source/Spacewar-Client.c +++ b/source/Spacewar-Client.c @@ -15,6 +15,47 @@ #include "Spacewar-Server.h" const char * messageStrings[] = {"HELLO", "GOODBYE", "PING", "PONG", "SECRET"}; +typedef struct SpacewarNetworkConfig +{ + uint8_t playerNumber; + uint32_t secretKey; + SpacewarState * state; +} SpacewarNetworkConfig; + +void * runNetworkThread (void * parameters) +{ + SpacewarNetworkConfig * configuration = (SpacewarNetworkConfig *)parameters; + int udpSocket = 0; + udpSocket = socket(AF_INET, SOCK_DGRAM, 0); + + // Configure a timeout for receiving: + struct timeval receiveTimeout; + receiveTimeout.tv_sec = 0; + receiveTimeout.tv_usec = 1000; + setsockopt(udpSocket, SOL_SOCKET, SO_RCVTIMEO, &receiveTimeout, sizeof(struct timeval)); + + // Point at the server: + struct sockaddr_in serverAddress; + serverAddress.sin_family = AF_INET; + serverAddress.sin_addr.s_addr = inet_addr("127.0.0.1"); + serverAddress.sin_port = htons(5200); + + // A structure to store the most recent state from the network: + SpacewarState * updatedState = calloc(1, sizeof(SpacewarState)); + + SpacewarClientInput input; + input.secret = configuration->secretKey; + input.playerNumber = configuration->playerNumber; + + while (true) + { + sendto(udpSocket, &input, sizeof(SpacewarClientInput), 0, (struct sockaddr *)&serverAddress, sizeof(struct sockaddr_in)); + recvfrom(udpSocket, updatedState, sizeof(SpacewarState), 0, NULL, NULL); + memcpy(configuration->state, updatedState, sizeof(SpacewarState)); +// printf("Received, %f\t%f\n", updatedState->playerStates[0].position.xComponent, +// updatedState->playerStates[0].position.yComponent); + } +} int main(int argc, char ** argv) { @@ -126,7 +167,7 @@ int main(int argc, char ** argv) printf("Connected.\n"); bool playerNumberSet, secretKeySet; - uint32_t playerNumber, secretKey; + SpacewarNetworkConfig networkConfiguration; SpacewarMessage message; while (!playerNumberSet || !secretKeySet) @@ -137,21 +178,25 @@ int main(int argc, char ** argv) case 0: { playerNumberSet = true; - playerNumber = message.content; + networkConfiguration.playerNumber = message.content; break; } case 4: { secretKeySet = true; - secretKey = message.content; + networkConfiguration.secretKey = message.content; } } } - printf("Player Number: %u\n" - "Secret Key: %u\n", playerNumber, secretKey); + networkConfiguration.state = calloc(1, sizeof(SpacewarState)); - // Spawn network input thread: + printf("Player Number: %u\n" + "Secret Key: %u\n", networkConfiguration.playerNumber, networkConfiguration.secretKey); + + // Spawn network thread: + pthread_t networkThread; + pthread_create(&networkThread, NULL, runNetworkThread, &networkConfiguration); // Spawn client-side-prediction thread: if (!runServer) @@ -160,7 +205,21 @@ int main(int argc, char ** argv) } // Spawn graphics thread: - + int width, height; + while (true) + { + SDL_PumpEvents(); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + SDL_RenderClear(renderer); + SDL_SetRenderDrawColor(renderer, 255, 255, 0, 255); + SDL_GetWindowSize(window, &width, &height); + SDL_RenderDrawLine(renderer, width/2, height/2, + width/2 + (long)(networkConfiguration.state->playerStates[0].velocity.xComponent), + height/2 + (long)(networkConfiguration.state->playerStates[0].velocity.yComponent)); + SDL_RenderPresent(renderer); + } + pthread_join(networkThread, NULL); + return 0; } // ======================================================= diff --git a/source/Spacewar-Physics.c b/source/Spacewar-Physics.c index 5b11cc5..3e1cc6a 100644 --- a/source/Spacewar-Physics.c +++ b/source/Spacewar-Physics.c @@ -3,6 +3,9 @@ // | Copyright (C) 2023, Barra Ó Catháin | // | See end of file for copyright notice. | // ========================================= +#include +#include +#include #include "Spacewar-Physics.h" void doPhysicsTick(SpacewarState * state) @@ -10,57 +13,59 @@ void doPhysicsTick(SpacewarState * state) double gravityMagnitude, gravityAcceleration; for (int shipIndex = 0; shipIndex < 32; shipIndex++) { - SpacewarShipState * currentShip = state->playerStates[shipIndex]; + SpacewarShipState * currentShip = &state->playerStates[shipIndex]; if (currentShip->inPlay) { // Calculate Gravity: xyVectorBetweenPoints(currentShip->position.xComponent, currentShip->position.yComponent, - 0, 0, currentShip.gravity); - gravityMagnitude = normalizeXYVector(currentShip.gravity); + 0.0, 0.0, ¤tShip->gravity); + gravityMagnitude = normalizeXYVector(¤tShip->gravity); gravityAcceleration = 0; // Some maths that felt okay: - if (gravityMagnitude >= 116) + if (gravityMagnitude >= 116) { - gravityAcceleration = pow(2, (3000 / (gravityMagnitude << 1)))) >> 3; + gravityAcceleration = pow(2, (3000 / (gravityMagnitude / 2))) / 16; } // We're actually in the black hole; teleport: else { - ship->position.xComponent = random() % 8000; - ship->position.yComponent = random() % 8000; - ship->velocity.xComponent *= 0.01; - ship->velocity.yComponent *= 0.01; - } - - multiplyXYVector(currentShip.gravity, gravityAcceleration); + currentShip->position.xComponent = (double)(random() % 7500); + currentShip->position.yComponent = (double)(random() % 7500); + currentShip->velocity.xComponent *= 0.01; + currentShip->velocity.yComponent *= 0.01; + } + + multiplyXYVector(¤tShip->gravity, gravityAcceleration); // Apply Inputs: // Apply Gravity and Velocity to Position: - addXYVector(currentShip.position, currentShip.gravity); + addXYVector(¤tShip->velocity, ¤tShip->gravity); + addXYVector(¤tShip->position, ¤tShip->velocity); // Wrap position to game field: - if (currentShip->position.xComponent > 8000) + if (currentShip->position.xComponent > 8000.0) { - state->playerStates[shipIndex].position.xComponent = -7999; + state->playerStates[shipIndex].position.xComponent = -7999.0; state->playerStates[shipIndex].velocity.xComponent *= 0.9; } - if (currentShip->position.xComponent < -8000) + if (currentShip->position.xComponent < -8000.0) { - state->playerStates[shipIndex].position.xComponent = 7999; + state->playerStates[shipIndex].position.xComponent = 7999.0; state->playerStates[shipIndex].velocity.xComponent *= 0.9; } - if (currentShip->position.yComponent > 8000) + if (currentShip->position.yComponent > 8000.0) { - state->playerStates[shipIndex].position.yComponent = -7999; + state->playerStates[shipIndex].position.yComponent = -7999.0; state->playerStates[shipIndex].velocity.yComponent *= 0.9; } - if (currentShip->position.yComponent < -8000) + if (currentShip->position.yComponent < -8000.0) { - state->playerStates[shipIndex].position.xComponent = 7999; + state->playerStates[shipIndex].position.yComponent = 7999.0; state->playerStates[shipIndex].velocity.yComponent *= 0.9; - } + } + printf("%f %f\n", currentShip->position.xComponent, currentShip->position.yComponent); } } } diff --git a/source/Spacewar-Server.c b/source/Spacewar-Server.c index b563d34..3ff0a95 100644 --- a/source/Spacewar-Server.c +++ b/source/Spacewar-Server.c @@ -29,14 +29,25 @@ SpacewarConnection * getConnectionBySocket(SpacewarConnection * connections, siz return NULL; } +void sendCurrentState(SpacewarState * state, SpacewarConnection * connections, int udpSocket) +{ + for (int connectionIndex = 0; connectionIndex < 32; connectionIndex++) + { + if (connections[connectionIndex].active) + { + sendto(udpSocket, state, sizeof(SpacewarState), 0, + (struct sockaddr *)&connections[connectionIndex].clientAddress, sizeof(struct sockaddr_in)); + } + } +} void * runServerPhysics(void * parameters) { SpacewarServerSharedState * sharedState = (SpacewarServerSharedState *)parameters; while (true) { -// doPhysicsTick(sharedState->physicsState); -// sendCurrentState(sharedState->physicsState, sharedState->connections); + doPhysicsTick(sharedState->physicsState); + sendCurrentState(sharedState->physicsState, sharedState->connections, sharedState->udpSocket); usleep(15625); } @@ -56,12 +67,16 @@ void * runInputReceiver(void * parameters) { bytesRead = recvfrom(sharedState->udpSocket, &input, sizeof(SpacewarClientInput), 0, (struct sockaddr *)&clientAddress, &socketAddressLength); +// printf("Read an input... "); if (bytesRead == sizeof(SpacewarClientInput)) { +// printf("It's the right size... "); if (input.playerNumber < 32) { +// printf("Valid player number... "); if (input.secret == sharedState->connections[input.playerNumber].playerSecret) { +// printf("Valid input for player %d!\n", index); sharedState->physicsState->playerStates[input.playerNumber].inPlay = true; memcpy(&sharedState->connections[input.playerNumber].clientAddress, &clientAddress, sizeof(struct sockaddr_in));