From 352d3f26f1bb7c41e1b9955b8f41f87e0199ddb1 Mon Sep 17 00:00:00 2001 From: Aadhavan Srinivasan Date: Fri, 8 Mar 2024 14:46:30 -0500 Subject: [PATCH] Moved struct definition to separate file, and added check for displaying GUI I moved the GameType struct (and the Mode enum) to a separate file, as I will need to use it in the check_server and check_client functions as well. I also added the signum function (which was previously in sign.hpp) to this file, since it was the only function in sign.hpp. Finally, I added a check, that will only display the GUI, if the user didn't provide any command-line arguments. --- main.cpp | 182 +++++++++++++++++++++++++++---------------------------- 1 file changed, 89 insertions(+), 93 deletions(-) diff --git a/main.cpp b/main.cpp index 629d0d1..a407dd7 100644 --- a/main.cpp +++ b/main.cpp @@ -23,15 +23,14 @@ #define RAYGUI_IMPLEMENTATION #include "includes/raygui/raygui.h" #include "includes/raygui/style_dark.h" - #include "includes/paddle.hpp" #include "includes/ball.hpp" -#include "includes/easysock.hpp" -#include "includes/sign.hpp" #include "includes/connect_code.hpp" +#include "includes/easysock.hpp" #include "includes/client.hpp" #include "includes/server.hpp" #include "includes/exception_consts.hpp" +#include "includes/check_input.hpp" #include "includes/serialization.h" #include "includes/timer.h" @@ -47,18 +46,12 @@ const float BASE_BOUNCE_RAD = (BASE_BOUNCE_DEG / 180.0) * M_PI; const float BASE_SPEED_COMPONENTS = 15; const float BASE_SPEED = sqrt(powf(BASE_SPEED_COMPONENTS, 2) * 2); -typedef enum {M_SINGLE, M_CLIENT, M_SERVER} Mode; - -/* This struct contains a Mode enum, which indicates the type of game we are - playing (Single player, client mode or server mode). The netsock parameter is - a 'Sock' object - Client and Server classes inherit from this object, so this - parameter can be instantiated to either a client or server, depending on the - game type. */ - -typedef struct { - Mode mode; - Sock* netsock; -} GameType; +/* Simple function to return 1 if a value is positive, and -1 if it is negative */ +int signum(int num) { + int retval = 0; + (num > 0) ? retval = 1 : retval = -1; + return retval; +} raylib::Vector2 changeVelocityAfterCollision(Paddle paddle, Ball ball) { float paddle_mid_y = (paddle.getRect().y + paddle.getRect().GetHeight()) / 2.0; /* Middle y value of rectangle */ @@ -223,93 +216,96 @@ int main(int argc, char** argv) { bool game_started = false; srand(std::time(NULL)); - - - /* Display a drop-down menu, to allow user to pick between Single player, server and client. This section of the code uses the raygui library, and is written in C. */ - - GuiLoadStyleDark(); // Load the dark theme style - /* Modify the default style, by changing font size and spacing */ - int font_size = 25; - int font_spacing = 2; - GuiSetStyle(DEFAULT, TEXT_SIZE, font_size); - GuiSetStyle(DEFAULT, TEXT_SPACING, font_spacing); - - /* Set variables to position objects on screen */ - int selected_item = 0; // variable to hold the index of the selected item - const char* text_to_display = "Select Game Mode"; // Text to display - /* Size of the label, drop down box and button */ - Vector2 label_size = MeasureTextEx(GetFontDefault(), text_to_display, font_size, font_spacing); // Set the size based on the width of the string to print, the font size and the text spacing. I added 1 to font_size and font_spacing, to account for any possible rounding errors, since the function expects floats. - Vector2 box_size = Vector2{label_size.x, HEIGHT / 20}; - bool is_being_edited = false; // Indicates whether the drop-down menu is being 'edited' i.e. whether an option is being selected - bool button_pressed = false; // Indicates whether the submit button has been pressed - - while (button_pressed == false) { - BeginDrawing(); - ClearBackground(BLACK); - GuiLabel(Rectangle{(WIDTH/2)-(label_size.x/2), (HEIGHT/8), label_size.x, label_size.y}, text_to_display); // Label to display text on top - - if (is_being_edited) { - GuiLock(); // If the drop-down menu is being 'edited', we need to prevent the user from modifying any other aspect of the UI - } - - /* Button that allows user to proceed */ - button_pressed = GuiButton(Rectangle{(WIDTH/2)-(box_size.x/2), (HEIGHT/2) + (HEIGHT/8), box_size.x, box_size.y}, "Continue"); - - /* Drop-down menu, that allows user to select game mode */ - if (GuiDropdownBox(Rectangle{(WIDTH/2) - (box_size.x/2), (HEIGHT/2) - (HEIGHT/8), box_size.x, box_size.y}, "SINGLE;CLIENT;SERVER", &selected_item, is_being_edited)) { // This function returns != 0 if there was a mouse click inside the dropdown area - is_being_edited = !is_being_edited; // If the dropdown menu was selected, then it is being edited (or not being edited, if it previously was). - } - - GuiUnlock(); - EndDrawing(); - } - - /* Single player mode */ - if (selected_item == M_SINGLE) { - GuiSetStyle(DEFAULT, TEXT_WRAP_MODE, TEXT_WRAP_WORD); // Enable text wrapping so that the long text, displayed below, will be wrapped - BeginDrawing(); - ClearBackground(BLACK); - GuiLabel(Rectangle{(WIDTH/2)-(WIDTH/8), (HEIGHT/2)-(HEIGHT/8), WIDTH/4, HEIGHT/4}, "W and S control left paddle, Up and Down arrow keys control right paddle. Good luck!"); - EndDrawing(); - Timer timer = timer_init(5); - while (!timer_done(timer)); - } - - /* Server mode, ask user to input IP address and port */ - if (selected_item == M_SERVER) { - button_pressed = false; // Whether submit button is pressed - char* ip_text = (char *)calloc(100, sizeof(char)); // Holds input of IP text box - char* port_text = (char *)calloc(20, sizeof(char)); // Holds input of port text box - const char* ip_label = "Local IP address"; - const char* port_label = "Port number (1024 - 65535)"; - int port_label_x_size = MeasureTextEx(GetFontDefault(), port_label, font_size, font_spacing).x; // Custom size for port label, because it's long - bool editing_ip = false; // Indicates whether the IP address text box is being edited - bool editing_port = false; // Indicates whether the port text box is being edited + /* If there were no command-line arguments, the user is prompted in the GUI */ + if (argc == 1) { + /* Display a drop-down menu, to allow user to pick between Single player, server and client. This section of the code uses the raygui library, and is written in C. */ + + GuiLoadStyleDark(); // Load the dark theme style + /* Modify the default style, by changing font size and spacing */ + int font_size = 25; + int font_spacing = 2; + GuiSetStyle(DEFAULT, TEXT_SIZE, font_size); + GuiSetStyle(DEFAULT, TEXT_SPACING, font_spacing); + + /* Set variables to position objects on screen */ + int selected_item = 0; // variable to hold the index of the selected item + const char* text_to_display = "Select Game Mode"; // Text to display + /* Size of the label, drop down box and button */ + Vector2 label_size = MeasureTextEx(GetFontDefault(), text_to_display, font_size, font_spacing); // Set the size based on the width of the string to print, the font size and the text spacing. I added 1 to font_size and font_spacing, to account for any possible rounding errors, since the function expects floats. + Vector2 box_size = Vector2{label_size.x, HEIGHT / 20}; + bool is_being_edited = false; // Indicates whether the drop-down menu is being 'edited' i.e. whether an option is being selected + bool button_pressed = false; // Indicates whether the submit button has been pressed + while (button_pressed == false) { BeginDrawing(); ClearBackground(BLACK); - /* Label and text box for IP address */ - GuiLabel(Rectangle{(WIDTH/2)-(label_size.x/2), (HEIGHT/2) - (HEIGHT/6) - label_size.y - 10, label_size.x, label_size.y}, ip_label); // Label to display text on top - /* The reason this if statement exists, is largely the same as the reasoning for the drop-down menu. We want to make the text box editable - if it has been clicked. If it is already editable, we want to make it read-only if the user clicks outside the box. This functionality - is mostly handled in the GuiTextBox function. If the text box is in edit mode, this function returns nonzero if the user clicks INSIDE - the box. If the text box is in editable mode, this function returns nonzero if the user clicks OUTSIDE the box. */ - if (GuiTextBox(Rectangle{(WIDTH/2) - (box_size.x/2), (HEIGHT/2) - (HEIGHT/6), box_size.x, box_size.y}, ip_text, 100, editing_ip)) { - editing_ip = !editing_ip; + GuiLabel(Rectangle{(WIDTH/2)-(label_size.x/2), (HEIGHT/8), label_size.x, label_size.y}, text_to_display); // Label to display text on top + + if (is_being_edited) { + GuiLock(); // If the drop-down menu is being 'edited', we need to prevent the user from modifying any other aspect of the UI } - - /* Label and text box for port. See above for explanation of if statement. */ - GuiLabel(Rectangle{(WIDTH/2)-(label_size.x/2), (HEIGHT/2) - label_size.y, port_label_x_size }, port_label); // Label to display text on top - if (GuiTextBox(Rectangle{(WIDTH/2) - (box_size.x/2), (HEIGHT/2), box_size.x, box_size.y}, port_text, 100, editing_port)) { - editing_port = !editing_port; + + /* Button that allows user to proceed */ + button_pressed = GuiButton(Rectangle{(WIDTH/2)-(box_size.x/2), (HEIGHT/2) + (HEIGHT/8), box_size.x, box_size.y}, "Continue"); + + /* Drop-down menu, that allows user to select game mode */ + if (GuiDropdownBox(Rectangle{(WIDTH/2) - (box_size.x/2), (HEIGHT/2) - (HEIGHT/8), box_size.x, box_size.y}, "SINGLE;CLIENT;SERVER", &selected_item, is_being_edited)) { // This function returns != 0 if there was a mouse click inside the dropdown area + is_being_edited = !is_being_edited; // If the dropdown menu was selected, then it is being edited (or not being edited, if it previously was). } - - button_pressed = GuiButton(Rectangle{(WIDTH/2) - (box_size.x/2), (HEIGHT/2) + (HEIGHT/6), box_size.x, box_size.y}, "Start Server"); + GuiUnlock(); EndDrawing(); } - GameType type = check_server(ip_text, port_text); + /* Single player mode */ + if (selected_item == M_SINGLE) { + GuiSetStyle(DEFAULT, TEXT_WRAP_MODE, TEXT_WRAP_WORD); // Enable text wrapping so that the long text, displayed below, will be wrapped + BeginDrawing(); + ClearBackground(BLACK); + GuiLabel(Rectangle{(WIDTH/2)-(WIDTH/8), (HEIGHT/2)-(HEIGHT/8), WIDTH/4, HEIGHT/4}, "W and S control left paddle, Up and Down arrow keys control right paddle. Good luck!"); + EndDrawing(); + Timer timer = timer_init(5); + while (!timer_done(timer)); + } + + /* Server mode, ask user to input IP address and port */ + if (selected_item == M_SERVER) { + button_pressed = false; // Whether submit button is pressed + char* ip_text = (char *)calloc(100, sizeof(char)); // Holds input of IP text box + char* port_text = (char *)calloc(20, sizeof(char)); // Holds input of port text box + const char* ip_label = "Local IP address"; + const char* port_label = "Port number (1024 - 65535)"; + int port_label_x_size = MeasureTextEx(GetFontDefault(), port_label, font_size, font_spacing).x; // Custom size for port label, because it's long + bool editing_ip = false; // Indicates whether the IP address text box is being edited + bool editing_port = false; // Indicates whether the port text box is being edited + while (button_pressed == false) { + BeginDrawing(); + ClearBackground(BLACK); + /* Label and text box for IP address */ + GuiLabel(Rectangle{(WIDTH/2)-(label_size.x/2), (HEIGHT/2) - (HEIGHT/6) - label_size.y - 10, label_size.x, label_size.y}, ip_label); // Label to display text on top + /* The reason this if statement exists, is largely the same as the reasoning for the drop-down menu. We want to make the text box editable + if it has been clicked. If it is already editable, we want to make it read-only if the user clicks outside the box. This functionality + is mostly handled in the GuiTextBox function. If the text box is in edit mode, this function returns nonzero if the user clicks INSIDE + the box. If the text box is in editable mode, this function returns nonzero if the user clicks OUTSIDE the box. */ + if (GuiTextBox(Rectangle{(WIDTH/2) - (box_size.x/2), (HEIGHT/2) - (HEIGHT/6), box_size.x, box_size.y}, ip_text, 100, editing_ip)) { + editing_ip = !editing_ip; + } + + /* Label and text box for port. See above for explanation of if statement. */ + GuiLabel(Rectangle{(WIDTH/2)-(label_size.x/2), (HEIGHT/2) - label_size.y, port_label_x_size }, port_label); // Label to display text on top + if (GuiTextBox(Rectangle{(WIDTH/2) - (box_size.x/2), (HEIGHT/2), box_size.x, box_size.y}, port_text, 100, editing_port)) { + editing_port = !editing_port; + } + + button_pressed = GuiButton(Rectangle{(WIDTH/2) - (box_size.x/2), (HEIGHT/2) + (HEIGHT/6), box_size.x, box_size.y}, "Start Server"); + + EndDrawing(); + } + + type = check_server(ip_text, port_text); + free(ip_text); + free(port_text); + } } /* Variable to store the response given by the other player */