Current Working Tree On <2023-10-15>

This commit is contained in:
Barra Ó Catháin 2023-10-15 01:47:23 +01:00
parent 17401d3d02
commit bc446d457b
6 changed files with 134 additions and 32 deletions

View File

@ -79,6 +79,8 @@ int main(int argc, char ** argv)
{ {
titlescreenInput = true; titlescreenInput = true;
} }
// Check if Space was pressed:
if(keyboardState[SDL_SCANCODE_SPACE] == 1 && !runServer) if(keyboardState[SDL_SCANCODE_SPACE] == 1 && !runServer)
{ {
runServer = true; runServer = true;
@ -149,11 +151,12 @@ int main(int argc, char ** argv)
printf("Player Number: %u\n" printf("Player Number: %u\n"
"Secret Key: %u\n", playerNumber, secretKey); "Secret Key: %u\n", playerNumber, secretKey);
// Spawn network thread: // Spawn network input thread:
// Spawn game thread: // Spawn client-side-prediction thread:
while(keepRunning) if (!runServer)
{ {
pthread_t clientSidePredictionThread;
} }
// Spawn graphics thread: // Spawn graphics thread:

82
source/Spacewar-Physics.c Normal file
View File

@ -0,0 +1,82 @@
// =========================================
// | Spacewar-Physics.c |
// | Copyright (C) 2023, Barra Ó Catháin |
// | See end of file for copyright notice. |
// =========================================
#include "Spacewar-Physics.h"
void doPhysicsTick(SpacewarState * state)
{
double gravityMagnitude, gravityAcceleration;
for (int shipIndex = 0; shipIndex < 32; 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);
gravityAcceleration = 0;
// Some maths that felt okay:
if (gravityMagnitude >= 116)
{
gravityAcceleration = pow(2, (3000 / (gravityMagnitude << 1)))) >> 3;
}
// 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);
// Apply Inputs:
// Apply Gravity and Velocity to Position:
addXYVector(currentShip.position, currentShip.gravity);
// Wrap position to game field:
if (currentShip->position.xComponent > 8000)
{
state->playerStates[shipIndex].position.xComponent = -7999;
state->playerStates[shipIndex].velocity.xComponent *= 0.9;
}
if (currentShip->position.xComponent < -8000)
{
state->playerStates[shipIndex].position.xComponent = 7999;
state->playerStates[shipIndex].velocity.xComponent *= 0.9;
}
if (currentShip->position.yComponent > 8000)
{
state->playerStates[shipIndex].position.yComponent = -7999;
state->playerStates[shipIndex].velocity.yComponent *= 0.9;
}
if (currentShip->position.yComponent < -8000)
{
state->playerStates[shipIndex].position.xComponent = 7999;
state->playerStates[shipIndex].velocity.yComponent *= 0.9;
}
}
}
}
// ========================================================
// | End of Spacewar-Physics.c, copyright notice follows. |
// ========================================================
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

View File

@ -18,12 +18,18 @@ typedef struct SpacewarShipState
xyVector velocity; xyVector velocity;
} SpacewarShipState; } SpacewarShipState;
typedef struct SpacewarShipInput
{
double turningAmount, acceleratingAmount;
bool turningClockwise, turningAnticlockwise, accelerating;
} SpacewarShipInput;
typedef struct SpacewarClientInput typedef struct SpacewarClientInput
{ {
uint8_t playerNumber; uint8_t playerNumber;
uint32_t secret; uint32_t secret;
double turningAmount, acceleratingAmount; SpacewarShipInput input;
bool turningClockwise, turningAnticlockwise, accelerating;
} SpacewarClientInput; } SpacewarClientInput;
typedef struct SpacewarState typedef struct SpacewarState
@ -31,7 +37,7 @@ typedef struct SpacewarState
uint64_t tickNumber; uint64_t tickNumber;
struct timeval timestamp; struct timeval timestamp;
SpacewarShipState playerStates[32]; SpacewarShipState playerStates[32];
SpacewarClientInput playerInputs[32]; SpacewarShipInput playerInputs[32];
} SpacewarState; } SpacewarState;
// Does a single step of the physics: // Does a single step of the physics:

View File

@ -31,40 +31,30 @@ SpacewarConnection * getConnectionBySocket(SpacewarConnection * connections, siz
void * runServerPhysics(void * parameters) void * runServerPhysics(void * parameters)
{ {
SpacewarState * state = (SpacewarState *)parameters; SpacewarServerSharedState * sharedState = (SpacewarServerSharedState *)parameters;
while (true) while (true)
{ {
//doPhysicsTick(state); // doPhysicsTick(sharedState->physicsState);
//sendCurrentState(); // sendCurrentState(sharedState->physicsState, sharedState->connections);
usleep(15625); usleep(15625);
} }
return NULL; return NULL;
} }
void * runUDPSocket(void * parameters) void * runInputReceiver(void * parameters)
{ {
SpacewarServerSharedState * sharedState = (SpacewarServerSharedState *)parameters; SpacewarServerSharedState * sharedState = (SpacewarServerSharedState *)parameters;
int udpSocket, bytesRead; int bytesRead;
socklen_t socketAddressLength; socklen_t socketAddressLength;
struct sockaddr_in clientAddress, serverAddress; struct sockaddr_in clientAddress;
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(5200);
serverAddress.sin_addr.s_addr = INADDR_ANY;
SpacewarClientInput input; SpacewarClientInput input;
bind(udpSocket, (struct sockaddr *)&serverAddress, sizeof(struct sockaddr_in));
while (true) while (true)
{ {
bytesRead = recvfrom(udpSocket, &input, sizeof(SpacewarClientInput), 0, bytesRead = recvfrom(sharedState->udpSocket, &input, sizeof(SpacewarClientInput), 0,
(struct sockaddr *)&clientAddress, &socketAddressLength); (struct sockaddr *)&clientAddress, &socketAddressLength);
if (bytesRead == sizeof(SpacewarClientInput)) if (bytesRead == sizeof(SpacewarClientInput))
{ {
@ -72,10 +62,11 @@ void * runUDPSocket(void * parameters)
{ {
if (input.secret == sharedState->connections[input.playerNumber].playerSecret) if (input.secret == sharedState->connections[input.playerNumber].playerSecret)
{ {
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));
memcpy(&sharedState->state->playerInputs[input.playerNumber], &input, memcpy(&sharedState->physicsState->playerInputs[input.playerNumber], &(input.input),
sizeof(struct SpacewarClientInput)); sizeof(struct SpacewarShipInput));
} }
} }
} }
@ -145,14 +136,34 @@ void * runSpacewarServer(void * configuration)
connectedClients[index].active = false; connectedClients[index].active = false;
} }
// Begin the simulation: // Create a UDP socket:
pthread_t physicsThread, udpThread; int udpSocket = 0;
if ((udpSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
exit(EXIT_FAILURE);
}
// Create a struct to bind the UDP socket to a port:
struct sockaddr_in serverAddress;
memset(&serverAddress, 0, sizeof(serverAddress));
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(5200);
serverAddress.sin_addr.s_addr = INADDR_ANY;
// Bind it:
bind(udpSocket, (struct sockaddr *)&serverAddress, sizeof(struct sockaddr_in));
// Setup the server threads:
pthread_t physicsThread, inputThread;
SpacewarState * currentState = calloc(1, sizeof(SpacewarState)); SpacewarState * currentState = calloc(1, sizeof(SpacewarState));
SpacewarServerSharedState threadState; SpacewarServerSharedState threadState;
threadState.state = currentState; threadState.udpSocket = udpSocket;
threadState.physicsState = currentState;
threadState.connections = connectedClients; threadState.connections = connectedClients;
// Begin the simulation:
pthread_create(&inputThread, NULL, runInputReceiver, &threadState);
pthread_create(&physicsThread, NULL, runServerPhysics, &threadState); pthread_create(&physicsThread, NULL, runServerPhysics, &threadState);
pthread_create(&udpThread, NULL, runUDPSocket, &threadState);
// Manage clients and sending packets back and forth: // Manage clients and sending packets back and forth:
while (true) while (true)

View File

@ -32,7 +32,8 @@ typedef struct SpacewarServerConfiguration
typedef struct SpacewarServerSharedState typedef struct SpacewarServerSharedState
{ {
SpacewarState * state; int udpSocket;
SpacewarState * physicsState;
SpacewarConnection * connections; SpacewarConnection * connections;
} SpacewarServerSharedState; } SpacewarServerSharedState;

View File

@ -13,7 +13,6 @@ static inline double angleBetweenVectors(xyVector * vectorA, xyVector * vectorB)
{ {
double dotProduct = (vectorA->xComponent * vectorB->xComponent) + (vectorA->yComponent * vectorB->yComponent); double dotProduct = (vectorA->xComponent * vectorB->xComponent) + (vectorA->yComponent * vectorB->yComponent);
double determinant = (vectorA->xComponent * vectorB->yComponent) - (vectorA->yComponent * vectorB->xComponent); double determinant = (vectorA->xComponent * vectorB->yComponent) - (vectorA->yComponent * vectorB->xComponent);
return atan2(dotProduct, determinant) / 0.01745329; return atan2(dotProduct, determinant) / 0.01745329;
} }