Current Working Tree on <2023-10-15>
This commit is contained in:
parent
bc446d457b
commit
11b568550c
|
@ -15,6 +15,47 @@
|
||||||
#include "Spacewar-Server.h"
|
#include "Spacewar-Server.h"
|
||||||
|
|
||||||
const char * messageStrings[] = {"HELLO", "GOODBYE", "PING", "PONG", "SECRET"};
|
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)
|
int main(int argc, char ** argv)
|
||||||
{
|
{
|
||||||
|
@ -126,7 +167,7 @@ int main(int argc, char ** argv)
|
||||||
printf("Connected.\n");
|
printf("Connected.\n");
|
||||||
|
|
||||||
bool playerNumberSet, secretKeySet;
|
bool playerNumberSet, secretKeySet;
|
||||||
uint32_t playerNumber, secretKey;
|
SpacewarNetworkConfig networkConfiguration;
|
||||||
SpacewarMessage message;
|
SpacewarMessage message;
|
||||||
|
|
||||||
while (!playerNumberSet || !secretKeySet)
|
while (!playerNumberSet || !secretKeySet)
|
||||||
|
@ -137,21 +178,25 @@ int main(int argc, char ** argv)
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
playerNumberSet = true;
|
playerNumberSet = true;
|
||||||
playerNumber = message.content;
|
networkConfiguration.playerNumber = message.content;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 4:
|
case 4:
|
||||||
{
|
{
|
||||||
secretKeySet = true;
|
secretKeySet = true;
|
||||||
secretKey = message.content;
|
networkConfiguration.secretKey = message.content;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
networkConfiguration.state = calloc(1, sizeof(SpacewarState));
|
||||||
|
|
||||||
printf("Player Number: %u\n"
|
printf("Player Number: %u\n"
|
||||||
"Secret Key: %u\n", playerNumber, secretKey);
|
"Secret Key: %u\n", networkConfiguration.playerNumber, networkConfiguration.secretKey);
|
||||||
|
|
||||||
// Spawn network input thread:
|
// Spawn network thread:
|
||||||
|
pthread_t networkThread;
|
||||||
|
pthread_create(&networkThread, NULL, runNetworkThread, &networkConfiguration);
|
||||||
|
|
||||||
// Spawn client-side-prediction thread:
|
// Spawn client-side-prediction thread:
|
||||||
if (!runServer)
|
if (!runServer)
|
||||||
|
@ -160,6 +205,20 @@ int main(int argc, char ** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spawn graphics thread:
|
// 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
// | Copyright (C) 2023, Barra Ó Catháin |
|
// | Copyright (C) 2023, Barra Ó Catháin |
|
||||||
// | See end of file for copyright notice. |
|
// | See end of file for copyright notice. |
|
||||||
// =========================================
|
// =========================================
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include "Spacewar-Physics.h"
|
#include "Spacewar-Physics.h"
|
||||||
|
|
||||||
void doPhysicsTick(SpacewarState * state)
|
void doPhysicsTick(SpacewarState * state)
|
||||||
|
@ -10,57 +13,59 @@ void doPhysicsTick(SpacewarState * state)
|
||||||
double gravityMagnitude, gravityAcceleration;
|
double gravityMagnitude, gravityAcceleration;
|
||||||
for (int shipIndex = 0; shipIndex < 32; shipIndex++)
|
for (int shipIndex = 0; shipIndex < 32; shipIndex++)
|
||||||
{
|
{
|
||||||
SpacewarShipState * currentShip = state->playerStates[shipIndex];
|
SpacewarShipState * currentShip = &state->playerStates[shipIndex];
|
||||||
if (currentShip->inPlay)
|
if (currentShip->inPlay)
|
||||||
{
|
{
|
||||||
// Calculate Gravity:
|
// Calculate Gravity:
|
||||||
xyVectorBetweenPoints(currentShip->position.xComponent, currentShip->position.yComponent,
|
xyVectorBetweenPoints(currentShip->position.xComponent, currentShip->position.yComponent,
|
||||||
0, 0, currentShip.gravity);
|
0.0, 0.0, ¤tShip->gravity);
|
||||||
gravityMagnitude = normalizeXYVector(currentShip.gravity);
|
gravityMagnitude = normalizeXYVector(¤tShip->gravity);
|
||||||
gravityAcceleration = 0;
|
gravityAcceleration = 0;
|
||||||
|
|
||||||
// Some maths that felt okay:
|
// 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:
|
// We're actually in the black hole; teleport:
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ship->position.xComponent = random() % 8000;
|
currentShip->position.xComponent = (double)(random() % 7500);
|
||||||
ship->position.yComponent = random() % 8000;
|
currentShip->position.yComponent = (double)(random() % 7500);
|
||||||
ship->velocity.xComponent *= 0.01;
|
currentShip->velocity.xComponent *= 0.01;
|
||||||
ship->velocity.yComponent *= 0.01;
|
currentShip->velocity.yComponent *= 0.01;
|
||||||
}
|
}
|
||||||
|
|
||||||
multiplyXYVector(currentShip.gravity, gravityAcceleration);
|
multiplyXYVector(¤tShip->gravity, gravityAcceleration);
|
||||||
|
|
||||||
// Apply Inputs:
|
// Apply Inputs:
|
||||||
|
|
||||||
// Apply Gravity and Velocity to Position:
|
// 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:
|
// 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;
|
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;
|
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;
|
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;
|
state->playerStates[shipIndex].velocity.yComponent *= 0.9;
|
||||||
}
|
}
|
||||||
|
printf("%f %f\n", currentShip->position.xComponent, currentShip->position.yComponent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,14 +29,25 @@ SpacewarConnection * getConnectionBySocket(SpacewarConnection * connections, siz
|
||||||
return NULL;
|
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)
|
void * runServerPhysics(void * parameters)
|
||||||
{
|
{
|
||||||
SpacewarServerSharedState * sharedState = (SpacewarServerSharedState *)parameters;
|
SpacewarServerSharedState * sharedState = (SpacewarServerSharedState *)parameters;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
// doPhysicsTick(sharedState->physicsState);
|
doPhysicsTick(sharedState->physicsState);
|
||||||
// sendCurrentState(sharedState->physicsState, sharedState->connections);
|
sendCurrentState(sharedState->physicsState, sharedState->connections, sharedState->udpSocket);
|
||||||
usleep(15625);
|
usleep(15625);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,12 +67,16 @@ void * runInputReceiver(void * parameters)
|
||||||
{
|
{
|
||||||
bytesRead = recvfrom(sharedState->udpSocket, &input, sizeof(SpacewarClientInput), 0,
|
bytesRead = recvfrom(sharedState->udpSocket, &input, sizeof(SpacewarClientInput), 0,
|
||||||
(struct sockaddr *)&clientAddress, &socketAddressLength);
|
(struct sockaddr *)&clientAddress, &socketAddressLength);
|
||||||
|
// printf("Read an input... ");
|
||||||
if (bytesRead == sizeof(SpacewarClientInput))
|
if (bytesRead == sizeof(SpacewarClientInput))
|
||||||
{
|
{
|
||||||
|
// printf("It's the right size... ");
|
||||||
if (input.playerNumber < 32)
|
if (input.playerNumber < 32)
|
||||||
{
|
{
|
||||||
|
// printf("Valid player number... ");
|
||||||
if (input.secret == sharedState->connections[input.playerNumber].playerSecret)
|
if (input.secret == sharedState->connections[input.playerNumber].playerSecret)
|
||||||
{
|
{
|
||||||
|
// printf("Valid input for player %d!\n", index);
|
||||||
sharedState->physicsState->playerStates[input.playerNumber].inPlay = true;
|
sharedState->physicsState->playerStates[input.playerNumber].inPlay = true;
|
||||||
memcpy(&sharedState->connections[input.playerNumber].clientAddress,
|
memcpy(&sharedState->connections[input.playerNumber].clientAddress,
|
||||||
&clientAddress, sizeof(struct sockaddr_in));
|
&clientAddress, sizeof(struct sockaddr_in));
|
||||||
|
|
Loading…
Reference in New Issue