No declaring data inside of switch statement

main
Cameron Murphy Reikes 2 years ago
parent e6e3e68a52
commit 30321fd068

1437
main.c

File diff suppressed because it is too large Load Diff

@ -6,204 +6,214 @@
#include <stdlib.h> #include <stdlib.h>
// started in a thread from host // started in a thread from host
void server(void *data) void server(void* data)
{ {
(void)data; (void)data;
stm_setup(); stm_setup();
struct GameState gs = {0}; struct GameState gs = { 0 };
size_t entities_size = (sizeof(Entity) * MAX_ENTITIES); size_t entities_size = (sizeof(Entity) * MAX_ENTITIES);
Entity *entity_data = malloc(entities_size); Entity* entity_data = malloc(entities_size);
initialize(&gs, entity_data, entities_size); initialize(&gs, entity_data, entities_size);
Log("Allocated %zu bytes for entities\n", entities_size); Log("Allocated %zu bytes for entities\n", entities_size);
// one box policy // one box policy
if (true) if (true)
{ {
Entity * grid = new_entity(&gs); Entity* grid = new_entity(&gs);
grid_create(&gs, grid); grid_create(&gs, grid);
entity_set_pos(grid, (V2){-BOX_SIZE*2, 0.0f}); entity_set_pos(grid, (V2) { -BOX_SIZE * 2, 0.0f });
Entity * box = new_entity(&gs); Entity* box = new_entity(&gs);
box_create(&gs, box, grid, (V2){0}); box_create(&gs, box, grid, (V2) { 0 });
} }
if (enet_initialize() != 0) if (enet_initialize() != 0)
{ {
fprintf(stderr, "An error occurred while initializing ENet.\n"); fprintf(stderr, "An error occurred while initializing ENet.\n");
exit(-1); exit(-1);
} }
ENetAddress address; ENetAddress address;
ENetHost *server; ENetHost* server;
int sethost = enet_address_set_host_ip(&address, LOCAL_SERVER_ADDRESS); int sethost = enet_address_set_host_ip(&address, LOCAL_SERVER_ADDRESS);
if (sethost != 0) if (sethost != 0)
{ {
Log("Fishy return value from set host: %d\n", sethost); Log("Fishy return value from set host: %d\n", sethost);
} }
/* Bind the server to port 1234. */ /* Bind the server to port 1234. */
address.port = SERVER_PORT; address.port = SERVER_PORT;
server = enet_host_create(&address /* the address to bind the server host to */, server = enet_host_create(&address /* the address to bind the server host to */,
32 /* allow up to 32 clients and/or outgoing connections */, 32 /* allow up to 32 clients and/or outgoing connections */,
2 /* allow up to 2 channels to be used, 0 and 1 */, 2 /* allow up to 2 channels to be used, 0 and 1 */,
0 /* assume any amount of incoming bandwidth */, 0 /* assume any amount of incoming bandwidth */,
0 /* assume any amount of outgoing bandwidth */); 0 /* assume any amount of outgoing bandwidth */);
if (server == NULL) if (server == NULL)
{ {
fprintf(stderr, fprintf(stderr,
"An error occurred while trying to create an ENet server host.\n"); "An error occurred while trying to create an ENet server host.\n");
exit(-1); exit(-1);
} }
Log("Serving on port %d...\n", SERVER_PORT); Log("Serving on port %d...\n", SERVER_PORT);
ENetEvent event; ENetEvent event;
uint64_t last_processed_time = stm_now(); uint64_t last_processed_time = stm_now();
float total_time = 0.0f; float total_time = 0.0f;
uint64_t player_to_latest_tick_processed[MAX_PLAYERS] = {0}; uint64_t player_to_latest_tick_processed[MAX_PLAYERS] = { 0 };
while (true) while (true)
{ {
// @Speed handle enet messages and simulate gamestate in parallel, then sync... must clone gamestate for this // @Speed handle enet messages and simulate gamestate in parallel, then sync... must clone gamestate for this
while (true) while (true)
{ {
int ret = enet_host_service(server, &event, 0); int ret = enet_host_service(server, &event, 0);
if (ret == 0) if (ret == 0)
break; break;
if (ret < 0) if (ret < 0)
{ {
fprintf(stderr, "Enet host service error %d\n", ret); fprintf(stderr, "Enet host service error %d\n", ret);
} }
if (ret > 0) if (ret > 0)
{ {
switch (event.type) switch (event.type)
{ {
case ENET_EVENT_TYPE_CONNECT: case ENET_EVENT_TYPE_CONNECT:
Log("A new client connected from %x:%u.\n", {
event.peer->address.host, Log("A new client connected from %x:%u.\n",
event.peer->address.port); event.peer->address.host,
event.peer->address.port);
int64_t player_slot = -1;
for (int i = 0; i < MAX_PLAYERS; i++) int64_t player_slot = -1;
{ for (int i = 0; i < MAX_PLAYERS; i++)
if (!gs.players[i].connected) {
{ if (!gs.players[i].connected)
player_slot = i; {
break; player_slot = i;
} break;
} }
}
if (player_slot == -1)
{ if (player_slot == -1)
enet_peer_disconnect_now(event.peer, 69); {
} enet_peer_disconnect_now(event.peer, 69);
else }
{ else
event.peer->data = (void *)player_slot; {
gs.players[player_slot] = (struct Player){0}; event.peer->data = (void*)player_slot;
gs.players[player_slot].connected = true; gs.players[player_slot] = (struct Player){ 0 };
} gs.players[player_slot].connected = true;
}
break;
case ENET_EVENT_TYPE_RECEIVE: break;
// Log("A packet of length %zu was received on channel %u.\n", }
// event.packet->dataLength,
// event.channelID); case ENET_EVENT_TYPE_RECEIVE:
{
size_t length = event.packet->dataLength; // Log("A packet of length %zu was received on channel %u.\n",
if (length != sizeof(struct ClientToServer)) // event.packet->dataLength,
{ // event.channelID);
Log("Length did not match up...\n");
} size_t length = event.packet->dataLength;
else if (length != sizeof(struct ClientToServer))
{ {
struct ClientToServer received = {0}; Log("Length did not match up...\n");
memcpy(&received, event.packet->data, length); }
int64_t player_slot = (int64_t)event.peer->data; else
uint64_t latest_tick = player_to_latest_tick_processed[player_slot]; {
struct ClientToServer received = { 0 };
if (received.inputs[0].tick > latest_tick) memcpy(&received, event.packet->data, length);
{ int64_t player_slot = (int64_t)event.peer->data;
for (int i = INPUT_BUFFER - 1; i >= 0; i--) uint64_t latest_tick = player_to_latest_tick_processed[player_slot];
{
if (received.inputs[i].tick == 0) // empty input if (received.inputs[0].tick > latest_tick)
continue; {
if (received.inputs[i].tick <= latest_tick) for (int i = INPUT_BUFFER - 1; i >= 0; i--)
continue; // don't reprocess inputs already processed {
struct InputFrame cur_input = received.inputs[i]; if (received.inputs[i].tick == 0) // empty input
gs.players[player_slot].input.movement = cur_input.movement; continue;
if (received.inputs[i].tick <= latest_tick)
// for these "event" inputs, only modify the current input if the event is true. continue; // don't reprocess inputs already processed
// while processing the gamestate, will mark it as false once processed. This struct InputFrame cur_input = received.inputs[i];
// prevents setting the event input to false before it's been processed. gs.players[player_slot].input.movement = cur_input.movement;
if (cur_input.inhabit)
{ // for these "event" inputs, only modify the current input if the event is true.
gs.players[player_slot].input.inhabit = cur_input.inhabit; // while processing the gamestate, will mark it as false once processed. This
} // prevents setting the event input to false before it's been processed.
if (cur_input.dobuild) if (cur_input.inhabit)
{ {
gs.players[player_slot].input.grid_to_build_on = cur_input.grid_to_build_on; gs.players[player_slot].input.inhabit = cur_input.inhabit;
gs.players[player_slot].input.build = cur_input.build; }
gs.players[player_slot].input.dobuild = cur_input.dobuild; if (cur_input.dobuild)
gs.players[player_slot].input.build_type = cur_input.build_type; {
gs.players[player_slot].input.build_rotation = cur_input.build_rotation; gs.players[player_slot].input.grid_to_build_on = cur_input.grid_to_build_on;
} gs.players[player_slot].input.build = cur_input.build;
} gs.players[player_slot].input.dobuild = cur_input.dobuild;
player_to_latest_tick_processed[player_slot] = received.inputs[0].tick; gs.players[player_slot].input.build_type = cur_input.build_type;
} gs.players[player_slot].input.build_rotation = cur_input.build_rotation;
} }
}
/* Clean up the packet now that we're done using it. */ player_to_latest_tick_processed[player_slot] = received.inputs[0].tick;
enet_packet_destroy(event.packet); }
}
break;
/* Clean up the packet now that we're done using it. */
case ENET_EVENT_TYPE_DISCONNECT: enet_packet_destroy(event.packet);
int player_index = (int64_t)event.peer->data;
Log("%" PRId64 " disconnected player index %d.\n", (int64_t)event.peer->data, player_index); break;
gs.players[player_index].connected = false; }
// box_destroy(&gs.players[player_index].box);
event.peer->data = NULL;
} case ENET_EVENT_TYPE_DISCONNECT:
} {
} int player_index = (int64_t)event.peer->data;
Log("%" PRId64 " disconnected player index %d.\n", (int64_t)event.peer->data, player_index);
total_time += (float)stm_sec(stm_diff(stm_now(), last_processed_time)); gs.players[player_index].connected = false;
last_processed_time = stm_now(); // box_destroy(&gs.players[player_index].box);
// @Robost @BeforeShip if can't process quick enough will be stuck being lagged behind, think of a solution for this... event.peer->data = NULL;
bool processed = false; break;
while (total_time > TIMESTEP) }
{
processed = true; }
process(&gs, TIMESTEP); }
total_time -= TIMESTEP; }
}
total_time += (float)stm_sec(stm_diff(stm_now(), last_processed_time));
if (processed) last_processed_time = stm_now();
{ // @Robost @BeforeShip if can't process quick enough will be stuck being lagged behind, think of a solution for this...
bool processed = false;
while (total_time > TIMESTEP)
{
processed = true;
process(&gs, TIMESTEP);
total_time -= TIMESTEP;
}
if (processed)
{
#define MAX_BYTES_SIZE 2048 * 2 #define MAX_BYTES_SIZE 2048 * 2
static char bytes_buffer[MAX_BYTES_SIZE] = {0}; static char bytes_buffer[MAX_BYTES_SIZE] = { 0 };
for (int i = 0; i < server->peerCount; i++) for (int i = 0; i < server->peerCount; i++)
{ {
// @Speed don't recreate the packet for every peer, gets expensive copying gamestate over and over again // @Speed don't recreate the packet for every peer, gets expensive copying gamestate over and over again
if (server->peers[i].state != ENET_PEER_STATE_CONNECTED) if (server->peers[i].state != ENET_PEER_STATE_CONNECTED)
{ {
continue; continue;
} }
struct ServerToClient to_send; struct ServerToClient to_send;
to_send.cur_gs = &gs; to_send.cur_gs = &gs;
to_send.your_player = (int)(int64_t)server->peers[i].data; to_send.your_player = (int)(int64_t)server->peers[i].data;
int len = 0; int len = 0;
into_bytes(&to_send, bytes_buffer, &len, MAX_BYTES_SIZE); into_bytes(&to_send, bytes_buffer, &len, MAX_BYTES_SIZE);
ENetPacket *gamestate_packet = enet_packet_create((void *)bytes_buffer, len, ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT); ENetPacket* gamestate_packet = enet_packet_create((void*)bytes_buffer, len, ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT);
enet_peer_send(&server->peers[i], 0, gamestate_packet); enet_peer_send(&server->peers[i], 0, gamestate_packet);
} }
} }
} }
destroy(&gs); destroy(&gs);
free(entity_data); free(entity_data);
enet_host_destroy(server); enet_host_destroy(server);
enet_deinitialize(); enet_deinitialize();
} }
Loading…
Cancel
Save