commit c0c7e14aa64ebffc334ad4f08e49bad2591050a4 Author: Aadhavan Srinivasan Date: Thu Apr 11 11:28:08 2024 -0400 Moved serialization files to separate submodule diff --git a/includes/serialization.h b/includes/serialization.h new file mode 100644 index 0000000..d0dc00b --- /dev/null +++ b/includes/serialization.h @@ -0,0 +1,33 @@ +#ifndef _SERIALIZATION_H +#define _SERIALIZATION_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* Struct used to hold the data that will be sent between sockets */ +typedef struct { + uint16_t pad_x; // X-coordinate of sending paddle + uint16_t pad_y; // Y-coordinate of sending paddle + uint16_t ball_x; // X-coordinate of ball (only the server fills this in) + uint16_t ball_y; // Y-coordinate of ball (only the server fills this in) + bool should_quit; // Flag to indicate whether game should be quit or not +} Serial_Data; + +/* Create a Serial_Data struct from float values */ +Serial_Data Serial_create_data(float pad_x, float pad_y, float ball_x, float ball_y, bool should_quit); + +/* Serialize a struct into a byte array, that can be sent through a socket */ +uint8_t* Serial_serialize(Serial_Data data); + +/* Deserialize a byte array into a struct, and return the struct */ +Serial_Data Serial_deserialize(uint8_t* serialized); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/serialization.c b/serialization.c new file mode 100644 index 0000000..f48d8b9 --- /dev/null +++ b/serialization.c @@ -0,0 +1,87 @@ +#include +#include +#include +#include +#if defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)) + #include +#endif +#ifdef _WIN32 + #include +#endif +#include "includes/serialization.h" + + +/* Takes in float values, casts them to uint16_t and creates a Serial_Data struct */ +Serial_Data Serial_create_data(float pad_x, float pad_y, float ball_x, float ball_y, bool should_quit) { + Serial_Data data; + data.pad_x = (uint16_t)pad_x; + data.pad_y = (uint16_t)pad_y; + data.ball_x = (uint16_t)ball_x; + data.ball_y = (uint16_t)ball_y; + data.should_quit = should_quit; + return data; +} + +/* Serializes a 'Data' struct into a byte array, converted to network-byte order */ +uint8_t* Serial_serialize(Serial_Data data) { + /* Create a pointer that can fit the entire struct */ + uint8_t* serialized = malloc(sizeof(Serial_Data) + 1); + uint8_t* pad_x_ptr; + uint8_t* pad_y_ptr; + uint8_t* ball_x_ptr; + uint8_t* ball_y_ptr; + uint8_t* should_quit_ptr; + + memset(serialized, 0, sizeof(Serial_Data) + 1); // Zero out the memory + pad_x_ptr = serialized; + pad_y_ptr = pad_x_ptr + sizeof(uint16_t); + ball_x_ptr = pad_y_ptr + sizeof(uint16_t); + ball_y_ptr = ball_x_ptr + sizeof(uint16_t); + should_quit_ptr = ball_y_ptr + sizeof(uint16_t); + + *((uint16_t *)pad_x_ptr) = data.pad_x; + *((uint16_t *)pad_x_ptr) = htons(*((uint16_t *)pad_x_ptr)); + + *((uint16_t *)pad_y_ptr) = data.pad_y; + *((uint16_t *)pad_y_ptr) = htons(*((uint16_t *)pad_y_ptr)); + + *((uint16_t *)ball_x_ptr) = data.ball_x; + *((uint16_t *)ball_x_ptr) = htons(*((uint16_t *)ball_x_ptr)); + + *((uint16_t *)ball_y_ptr) = data.ball_y; + *((uint16_t *)ball_y_ptr) = htons(*((uint16_t *)ball_y_ptr)); + + *((bool *)should_quit_ptr) = data.should_quit; + *(should_quit_ptr + sizeof(bool)) = '\0'; + + return serialized; +} + +/* Deserialize a byte array into a 'Data' struct, converted to host byte order */ +Serial_Data Serial_deserialize(uint8_t* serialized) { + Serial_Data deserialized; + /* Use successive chunks of memory address to create pointers to the data */ + uint8_t* pad_x_ptr = serialized; + uint8_t* pad_y_ptr = serialized + sizeof(uint16_t); + uint8_t* ball_x_ptr = pad_y_ptr + sizeof(uint16_t); + uint8_t* ball_y_ptr = ball_x_ptr + sizeof(uint16_t); + uint8_t* should_quit_ptr = ball_y_ptr + sizeof(uint16_t); + + /* Dereference (and cast) the pointers, and store them into the struct */ + deserialized.pad_x = *((uint16_t *)pad_x_ptr); + deserialized.pad_x = ntohs(deserialized.pad_x); + + deserialized.pad_y = *((uint16_t *)pad_y_ptr); + deserialized.pad_y = ntohs(deserialized.pad_y); + + deserialized.ball_x = *((uint16_t *)ball_x_ptr); + deserialized.ball_x = ntohs(deserialized.ball_x); + + deserialized.ball_y = *((uint16_t *)ball_y_ptr); + deserialized.ball_y = ntohs(deserialized.ball_y); + + deserialized.should_quit = *((bool *)should_quit_ptr); + + return deserialized; +} +