Current Working Tree on <2023-10-15>

This commit is contained in:
Barra Ó Catháin 2023-10-15 23:54:02 +01:00
parent bc446d457b
commit 11b568550c
3 changed files with 110 additions and 31 deletions

View File

@ -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;
}
// =======================================================

View File

@ -3,6 +3,9 @@
// | Copyright (C) 2023, Barra Ó Catháin |
// | See end of file for copyright notice. |
// =========================================
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#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, &currentShip->gravity);
gravityMagnitude = normalizeXYVector(&currentShip->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(&currentShip->gravity, gravityAcceleration);
// Apply Inputs:
// Apply Gravity and Velocity to Position:
addXYVector(currentShip.position, currentShip.gravity);
addXYVector(&currentShip->velocity, &currentShip->gravity);
addXYVector(&currentShip->position, &currentShip->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);
}
}
}

View File

@ -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));