summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRitabrata Das <[email protected]>2026-09-09 21:07:21 +0530
committerRitabrata Das <[email protected]>2026-09-09 21:07:21 +0530
commitffd968a26826108ca9fb23d46ed5789260852eb7 (patch)
tree3861d08dae1c28f547952dbcc16e04ae7b5286b5 /lib
intial commit
Diffstat (limited to 'lib')
-rw-r--r--lib/CMakeLists.txt13
-rw-r--r--lib/assetManager.cpp60
-rw-r--r--lib/assetManager.hpp18
-rw-r--r--lib/button.cpp149
-rw-r--r--lib/button.hpp32
-rw-r--r--lib/dialogue.cpp94
-rw-r--r--lib/dialogue.hpp11
-rw-r--r--lib/gameState.hpp110
-rw-r--r--lib/standard.cpp93
-rw-r--r--lib/standard.hpp14
10 files changed, 594 insertions, 0 deletions
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
new file mode 100644
index 0000000..3758ed0
--- /dev/null
+++ b/lib/CMakeLists.txt
@@ -0,0 +1,13 @@
+file(GLOB LIB_SOURCES CONFIGURE_DEPENDS
+ "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp"
+ "${CMAKE_CURRENT_SOURCE_DIR}/*.cc"
+ "${CMAKE_CURRENT_SOURCE_DIR}/*.cxx"
+)
+
+file(GLOB LIB_HEADERS CONFIGURE_DEPENDS
+ "${CMAKE_CURRENT_SOURCE_DIR}/*.hpp"
+ "${CMAKE_CURRENT_SOURCE_DIR}/*.h"
+ "${CMAKE_CURRENT_SOURCE_DIR}/*.hh"
+)
+
+target_sources(cirno_day PRIVATE ${LIB_SOURCES} ${LIB_HEADERS})
diff --git a/lib/assetManager.cpp b/lib/assetManager.cpp
new file mode 100644
index 0000000..9c60f9c
--- /dev/null
+++ b/lib/assetManager.cpp
@@ -0,0 +1,60 @@
+#include "assetManager.hpp"
+
+#include <filesystem>
+#include <iostream>
+
+assetManager::assetManager() = default;
+
+assetManager::~assetManager()
+{
+ cleanup();
+}
+
+void assetManager::init(const std::string& dirPath)
+{
+ if (!std::filesystem::exists(dirPath) || !std::filesystem::is_directory(dirPath)) {
+ std::cerr << "assetmanager: directory not found: " << dirPath << std::endl;
+ return;
+ }
+
+ for (const auto& entry : std::filesystem::recursive_directory_iterator(dirPath)) {
+ if (entry.is_regular_file()) {
+ std::string ext = entry.path().extension().string();
+
+ if (ext == ".png" || ext == ".jpg" || ext == ".jpeg") {
+ std::string key = entry.path().stem().string();
+ std::string fullPath = entry.path().string();
+
+ Texture2D tex = LoadTexture(fullPath.c_str());
+
+ if (tex.id != 0) {
+ textures[key] = tex;
+ std::cout << "success loading texture: " << key << std::endl;
+ } else {
+ std::cerr << "failed to load texture: " << key << std::endl;
+ }
+ }
+ }
+ }
+}
+
+Texture2D assetManager::load(const std::string& texName)
+{
+ const auto tex = textures.find(texName);
+ if (tex != textures.end()) {
+ return tex->second;
+ }
+
+ std::cerr << "asset not found: " << texName << std::endl;
+ return Texture2D{0};
+}
+
+void assetManager::cleanup()
+{
+ for (auto& pair : textures) {
+ if (pair.second.id != 0) {
+ UnloadTexture(pair.second);
+ }
+ }
+ textures.clear();
+}
diff --git a/lib/assetManager.hpp b/lib/assetManager.hpp
new file mode 100644
index 0000000..7b15f5a
--- /dev/null
+++ b/lib/assetManager.hpp
@@ -0,0 +1,18 @@
+#pragma once
+
+#include <string>
+#include <unordered_map>
+#include <raylib.h>
+
+class assetManager
+{
+private:
+ std::unordered_map<std::string, Texture2D> textures;
+public:
+ assetManager();
+ ~assetManager();
+
+ void init(const std::string& dirPath = "../assets");
+ Texture2D load(const std::string& texName);
+ void cleanup();
+};
diff --git a/lib/button.cpp b/lib/button.cpp
new file mode 100644
index 0000000..9000b09
--- /dev/null
+++ b/lib/button.cpp
@@ -0,0 +1,149 @@
+#include "button.hpp"
+#include "raylib.h"
+#include <raymath.h>
+
+constexpr Color HOVER_COLOR = Color{140, 0, 23, 255};
+constexpr Color FILL_COLOR = Color{148, 35, 67, 255};
+constexpr Color BORDER_COLOR = Color{204, 0, 57, 255};
+
+namespace ui {
+namespace {
+
+constexpr const char* kUIFontPath = "../assets/font/font.otf";
+constexpr const char* kUIClickSfxPath = "../assets/audio/sfx/buttonClick.wav";
+
+bool g_initialized = false;
+bool g_loaded_font = false;
+Font g_ui_font = {};
+Sound g_ui_clickSfx ;
+
+} // namespace
+
+Font GetActiveFont() { return g_loaded_font ? g_ui_font : GetFontDefault(); }
+
+void Init() {
+ if (g_initialized) return;
+
+ if (FileExists(kUIFontPath)) {
+ g_ui_font = LoadFontEx(kUIFontPath, 256, nullptr, 0);
+ g_loaded_font = g_ui_font.texture.id != 0;
+ }
+ g_ui_clickSfx = LoadSound(kUIClickSfxPath);
+
+ g_initialized = true;
+}
+
+void Shutdown() {
+ if (!g_initialized) return;
+
+ if (g_loaded_font) {
+ UnloadFont(g_ui_font);
+ g_loaded_font = false;
+ }
+
+ g_initialized = false;
+}
+
+void DrawText(const char* text, int pos_x, int pos_y, int font_size,
+ Color color) {
+ if (g_loaded_font) {
+ DrawTextEx(g_ui_font, text, {static_cast<float>(pos_x), static_cast<float>(pos_y)},
+ static_cast<float>(font_size), 1.0f, color);
+ return;
+ }
+
+ ::DrawText(text, pos_x, pos_y, font_size, color);
+}
+
+void DrawTextV(const char* text, Vector2 position, int font_size,
+ Color color) {
+ if (g_loaded_font) {
+ DrawTextEx(g_ui_font, text, {static_cast<float>(position.x), static_cast<float>(position.y)},
+ static_cast<float>(font_size), 1.0f, color);
+ return;
+ }
+
+ ::DrawText(text, position.x, position.y, font_size, color);
+}
+
+void DrawTextRotationV(const char* text, Vector2 position, int font_size, float rotInDeg, Color color) {
+ if (g_loaded_font) {
+ DrawTextPro(g_ui_font, text, position, {0,0},rotInDeg,font_size,1.0f,color);
+ return;
+ }
+ DrawTextPro(GetFontDefault(), text, position, {0,0},rotInDeg,font_size,1.0f,color);
+}
+
+void DrawButton(float x, float y, float width, float height, const char* text,
+ int font_size, const ButtonCallback& on_click, Vector2 mousePos) {
+ Rectangle bounds = {x, y, width, height};
+ const bool is_hovered = CheckCollisionPointRec(mousePos, bounds);
+ const Color fill_color = is_hovered ? HOVER_COLOR : FILL_COLOR;
+
+ DrawRectangleRounded(bounds, 0.14f, 8, fill_color);
+ DrawRectangleRoundedLinesEx(bounds, 0.14f, 4, 4.0f, BORDER_COLOR);
+
+ const Font font = GetActiveFont();
+ const Vector2 text_size = MeasureTextEx(font, text, static_cast<float>(font_size), 1.0f);
+ const float text_x = x + (width - text_size.x) * 0.5f;
+ const float text_y = y + (height - text_size.y) * 0.5f;
+ ui::DrawText(text, static_cast<int>(text_x), static_cast<int>(text_y), font_size, BLACK);
+
+ if (is_hovered && IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) {
+ PlaySound(g_ui_clickSfx);
+ if (on_click) {
+ on_click();
+ }
+ }
+}
+
+void DrawButtonNoHover(float x, float y, float width, float height, const char* text,
+ int font_size, const ButtonCallback& on_click, Vector2 mousePos, Color fillColor) {
+ Rectangle bounds = {x, y, width, height};
+ const bool is_hovered = CheckCollisionPointRec(mousePos, bounds);
+
+ DrawRectangleRounded(bounds, 0.14f, 8, fillColor);
+ DrawRectangleRoundedLinesEx(bounds, 0.14f, 8, 2.0f, BORDER_COLOR);
+
+ const Font font = GetActiveFont();
+ const Vector2 text_size = MeasureTextEx(font, text, static_cast<float>(font_size), 1.0f);
+ const float text_x = x + (width - text_size.x) * 0.5f;
+ const float text_y = y + (height - text_size.y) * 0.5f;
+ ui::DrawText(text, static_cast<int>(text_x), static_cast<int>(text_y), font_size, BLACK);
+
+ if (is_hovered && IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) {
+ // auto& asset_manager = assets::AssetManager::Instance();
+ // PlaySound(asset_manager.SoundEffect("switch"));
+ if (on_click) {
+ on_click();
+ }
+ }
+}
+
+
+void DrawTextVClickable(const char* text, Vector2 position, int font_size,
+ const ButtonCallback& on_click, Vector2 mousePos) {
+ Vector2 text_size;
+ if (g_loaded_font) {
+ text_size = MeasureTextEx(g_ui_font, text, static_cast<float>(font_size), 1.0f);
+ } else {
+ // Default Raylib font measurement
+ text_size.x = static_cast<float>(MeasureText(text, font_size));
+ text_size.y = static_cast<float>(font_size);
+ }
+ Rectangle bounds = {position.x, position.y, text_size.x, text_size.y};
+ const bool is_hovered = CheckCollisionPointRec(mousePos, bounds);
+
+ // Apply hover colors
+ const Color text_color = is_hovered ? WHITE : YELLOW;
+
+ ui::DrawTextV(text, position, font_size, text_color);
+
+ if (is_hovered && IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) {
+ if (on_click) {
+ on_click();
+ }
+ }
+}
+
+} // namespace ui
diff --git a/lib/button.hpp b/lib/button.hpp
new file mode 100644
index 0000000..8459cdc
--- /dev/null
+++ b/lib/button.hpp
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <functional>
+
+#include "raylib.h"
+
+namespace ui {
+
+using ButtonCallback = std::function<void()>;
+
+void Init();
+void Shutdown();
+
+void DrawText(const char* text, int pos_x, int pos_y, int font_size,
+ Color color);
+
+void DrawTextV(const char* text, Vector2 position, int font_size,
+ Color color);
+
+void DrawTextVClickable(const char* text, Vector2 position, int font_size,
+ const ButtonCallback& on_click, Vector2 mousePos);
+
+void DrawTextRotationV(const char* text, Vector2 position, int font_size, float rotInDeg, Color color);
+
+void DrawButton(float x, float y, float width, float height, const char* text,
+ int font_size, const ButtonCallback& on_click, Vector2 mousePos);
+
+void DrawButtonNoHover(float x, float y, float width, float height, const char* text,
+ int font_size, const ButtonCallback& on_click, Vector2 mousePos, Color fillColor = RAYWHITE);
+
+Font GetActiveFont();
+} // namespace ui
diff --git a/lib/dialogue.cpp b/lib/dialogue.cpp
new file mode 100644
index 0000000..3c9735b
--- /dev/null
+++ b/lib/dialogue.cpp
@@ -0,0 +1,94 @@
+#include "dialogue.hpp"
+#include "button.hpp"
+#include "lib/gameState.hpp"
+#include <raylib.h>
+
+void SayDialog(GameState &gs, const std::vector<Dialogues> &conversation) {
+ gs.currentDialog = conversation;
+ gs.currentLineIndex = 0;
+ gs.visibleChar = 0;
+ gs.dialogueTimer = 0.0f;
+ gs.dialogState = gs.currentDialog.empty() ? DIALOGUE_OFF : DIALOGUE_SCROLLING;
+}
+
+// void wait_for(GameState &gs, float time) {
+// gs.timeUntilStory = time;
+// gs.inStory = false;
+// gs.storyPosition += 1;
+// }
+
+void UpdateDialog(GameState &gs) {
+ if (gs.dialogState == DIALOGUE_OFF || gs.currentDialog.empty()) {
+ return;
+ }
+
+ if (gs.dialogState == DIALOGUE_SCROLLING) {
+ gs.dialogueTimer += GetFrameTime();
+ const float speed = gs.currentDialog[gs.currentLineIndex].textSpeed;
+ if (gs.dialogueTimer >= speed) {
+ gs.dialogueTimer = 0.0f;
+ gs.visibleChar += 1;
+
+ if (gs.visibleChar >= (int)(gs.currentDialog[gs.currentLineIndex].text.length())) {
+ gs.dialogState = DIALOGUE_WAITING;
+ }
+ }
+
+ if (IsKeyPressed(KEY_Z) || IsKeyPressed(KEY_SPACE) || IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
+ gs.visibleChar = (int)(gs.currentDialog[gs.currentLineIndex].text.length());
+ gs.dialogState = DIALOGUE_WAITING;
+ }
+ return;
+ }
+
+ if (gs.dialogState == DIALOGUE_WAITING && (IsKeyPressed(KEY_Z)) || IsKeyPressed(KEY_SPACE) || IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
+ gs.currentLineIndex += 1;
+ gs.visibleChar = 0;
+ gs.dialogueTimer = 0.0f;
+ if (gs.currentLineIndex >= (int)(gs.currentDialog.size())) {
+ gs.dialogState = DIALOGUE_OFF;
+ gs.currentDialog.clear();
+ } else {
+ gs.dialogState = DIALOGUE_SCROLLING;
+ }
+ }
+}
+
+void DrawDialog(GameState &gs) {
+ gs.curExp = gs.currentDialog[gs.currentLineIndex].curExp;
+ if (gs.dialogState == DIALOGUE_OFF || gs.currentDialog.empty()) {
+ return;
+ }
+ if (gs.currentLineIndex < 0 || gs.currentLineIndex >= (int)(gs.currentDialog.size())) {
+ return;
+ }
+
+ const int screenWidth = VIRTUAL_SCREEN_W;
+ const int screenHeight =VIRTUAL_SCREEN_H;
+ Dialogues &currentLine = gs.currentDialog[gs.currentLineIndex];
+
+ const int padding = 10;
+ const int boxWidth = VIRTUAL_SCREEN_W-2*padding;
+ const int boxHeight = 90;
+ const int boxX = padding;
+ const int boxY = screenHeight - boxHeight - 30;
+
+ DrawRectangle(boxX, boxY, boxWidth, boxHeight, Fade(BLACK, 0.8f));
+ // DrawRectangleLinesEx({boxX, boxY, boxWidth, boxHeight}, 2, WHITE);
+
+ // DrawTexturePro(currentLine.portrait, srcRect, dstRect, {0.0f, 0.0f}, 0.0f, WHITE);
+ // DrawRectangleLinesEx(dstRect, 2, RAYWHITE);
+
+ // ui::DrawText(currentLine.characterName.c_str(), boxX + padding, boxY - 15, 18, YELLOW);
+
+ std::string displayString = currentLine.text.substr(0, gs.visibleChar);
+ ui::DrawText(displayString.c_str(), boxX + padding, boxY + 15, 14, RAYWHITE);
+
+ if (gs.dialogState == DIALOGUE_WAITING && ((int)(GetTime() * 3) % 2 == 0)) {
+ ui::DrawText(gs.touchScreenMode?"Touch anywhere to proceed":"Press 'Z' to proceed", boxX + padding, boxY + boxHeight - 2*padding, 8, WHITE);
+ }
+}
+
+bool IsDialogRunning(const GameState &gs) {
+ return gs.dialogState == DIALOGUE_SCROLLING || gs.dialogState == DIALOGUE_WAITING;
+}
diff --git a/lib/dialogue.hpp b/lib/dialogue.hpp
new file mode 100644
index 0000000..3b53aeb
--- /dev/null
+++ b/lib/dialogue.hpp
@@ -0,0 +1,11 @@
+#pragma once
+
+#include <raylib.h>
+#include <vector>
+#include "gameState.hpp"
+
+void SayDialog(GameState &gs, const std::vector<Dialogues> &conversation);
+// void wait_for(GameState &gs, float time);
+void UpdateDialog(GameState &gs);
+void DrawDialog(GameState &gs);
+bool IsDialogRunning(const GameState &gs);
diff --git a/lib/gameState.hpp b/lib/gameState.hpp
new file mode 100644
index 0000000..5c718f4
--- /dev/null
+++ b/lib/gameState.hpp
@@ -0,0 +1,110 @@
+#pragma once
+#include <raylib.h>
+#include <string>
+#include <vector>
+#include <set>
+
+#include "assetManager.hpp"
+
+constexpr int MAX_USERNAME_LENGTH = 16;
+constexpr int VIRTUAL_SCREEN_W = 225;
+constexpr int VIRTUAL_SCREEN_H = 400;
+constexpr float WEB_RENDER_SCALE = 2.0f;
+constexpr Vector2 ZERO_VEC = {0,0};
+
+inline Music g_bgMusic;
+
+enum DialogueState {
+ DIALOGUE_OFF,
+ DIALOGUE_SCROLLING,
+ DIALOGUE_WAITING,
+};
+
+enum screen {
+ MAIN_MENU,
+ GAMEPLAY,
+};
+
+
+enum EXPRESSION {
+ NEUTRAL,
+ PISSED,
+ HURT,
+ JOY,
+ LAUGH,
+ RELAXED,
+ TIERED,
+ WOW,
+};
+
+struct Dialogues
+{
+ // Texture2D portrait;
+ std::string characterName;
+ EXPRESSION curExp;
+ std::string text;
+ // Sound scrollSound;
+ float textSpeed;
+};
+
+enum POSITION {
+ INSIDE,
+ OUTSIDE,
+ FOREST,
+ MENU
+};
+
+
+struct GameState {
+ screen current_screen = MAIN_MENU; // TODO : Change before prod
+ int gameScore = 0;
+ int highScore = 0;
+ bool paused = false;
+ bool gameOver = false;
+ /*
+ * We use a cartesian system that is right handed
+ * right is posetive x and up is posetive y
+ * The origin is at the bottom left corner of the
+ * playable area.
+ * Max limit is 100, 100 (note that this scale is as percentage)
+ * x = y wont give a straight line with 45 degree angle
+ * ^ +y
+ * |
+ * |
+ * |_________ > +x
+ */
+
+ /* Dialogue specific */
+ DialogueState dialogState = DIALOGUE_OFF;
+ std::vector<Dialogues> currentDialog;
+ float dialogueTimer = 0.0f;
+ int currentLineIndex = 0;
+ int visibleChar = 0;
+
+ short storyStage = 1;
+
+ /* Asset Manager */
+ assetManager AssetManager;
+
+ float scale = 1.0f;
+ float renderScale = 1.0f;
+ Vector2 currentMousePos = {0,0};
+ Font numberFont;
+ RenderTexture screenTex;
+
+ bool touchScreenMode = false;
+
+ POSITION curPos = MENU;
+ EXPRESSION curExp = NEUTRAL;
+
+ float timeSinceSceneChange = -1;
+ POSITION prevPos = INSIDE;
+
+ short flickCount = 0;
+ short chestCount = 0;
+ bool flowerOnHead = false;
+ bool riceCakeEaten = false;
+ bool frogDialogDone = false;
+ bool usedTalkButton = false;
+ std::set<int> explored = {};
+};
diff --git a/lib/standard.cpp b/lib/standard.cpp
new file mode 100644
index 0000000..35dfa9f
--- /dev/null
+++ b/lib/standard.cpp
@@ -0,0 +1,93 @@
+#include "standard.hpp"
+#include "gameState.hpp"
+#include <cstdlib>
+#include <cmath>
+#include <raylib.h>
+#include <raymath.h>
+
+constexpr float CARTESIAN_MIN = 0.0f;
+constexpr float CARTESIAN_MAX = 100.0f;
+constexpr float CARTESIAN_SCALE = 100.0f;
+
+float maxOfTwo(float a, float b) {
+ if (a > b) {return a;}
+ else {return b;}
+}
+
+float minOfTwo(float a, float b) {
+ if (a < b) {return a;}
+ else {return b;}
+}
+
+float genRandBw(float min,float max) {
+ return (((float)rand()/RAND_MAX)*(max-min))+min;
+}
+
+Vector2 rotatePoint(Vector2 point, Vector2 pivot, float angleDegree) {
+ float rad = angleDegree * DEG2RAD;
+ float s = sinf(rad);
+ float c = cosf(rad);
+ point.x -= pivot.x;
+ point.y -= pivot.y;
+ float xNew = point.x * c - point.y * s;
+ float yNew = point.x * s + point.y * c;
+ return (Vector2){ xNew + pivot.x, yNew + pivot.y };
+}
+
+Vector2 C2SProj(Vector2 cartesian_cordinates, Vector4 rectangle_space, Vector2 object_size,
+ Vector2 absolute_deviation_bias,bool use_clamp) {
+ /*Cartesian to Screen Projection */
+ float y_axis_length = rectangle_space.w - rectangle_space.y;
+ float x_axis_length = rectangle_space.z - rectangle_space.x;
+ float usable_width = maxOfTwo(0.0f, x_axis_length - object_size.x);
+ float usable_height = maxOfTwo(0.0f, y_axis_length - object_size.y);
+ float normalized_x;
+ float normalized_y;
+ if (use_clamp) {
+ normalized_x = Clamp(cartesian_cordinates.x, CARTESIAN_MIN, CARTESIAN_MAX)/CARTESIAN_SCALE;
+ normalized_y = Clamp(cartesian_cordinates.y, CARTESIAN_MIN, CARTESIAN_MAX)/CARTESIAN_SCALE;
+ } else {
+ normalized_x = cartesian_cordinates.x/CARTESIAN_SCALE;
+ normalized_y = cartesian_cordinates.y/CARTESIAN_SCALE;
+ }
+ float y_pos = (1 - normalized_y)*usable_height;
+ float x_pos = normalized_x*usable_width;
+ return {rectangle_space.x + x_pos + absolute_deviation_bias.x,
+ rectangle_space.y + y_pos + absolute_deviation_bias.y};
+}
+
+float S2CYaxis(float yValue, Vector4 rectangle_space) {
+ float y_axis_length = rectangle_space.w - rectangle_space.y;
+ return ((yValue/y_axis_length) * 100);
+}
+
+float S2CXaxis(float xValue, Vector4 rectangle_space) {
+ float x_axis_length = rectangle_space.z - rectangle_space.x;
+ return ((xValue/x_axis_length)*100);
+}
+
+void newGame(GameState& gs){
+ gs.gameScore = 0;
+ gs.paused = false;
+ gs.gameOver = false;
+ gs.dialogState = DIALOGUE_OFF;
+ gs.dialogueTimer = 0.0f;
+ gs.currentLineIndex = 0;
+ gs.visibleChar = 0;
+}
+
+bool returnTrueProbPerc(float percentageTrue){
+ float i = genRandBw(0, 1);
+ if (i < (percentageTrue/100)) {
+ return true;
+ }
+ return false;
+}
+
+Vector2 ScreenToVirtual(Vector2 screenPos, Vector2 offset, float scale)
+{
+ return Vector2{
+ (screenPos.x - offset.x) / scale,
+ (screenPos.y - offset.y) / scale
+ };
+}
diff --git a/lib/standard.hpp b/lib/standard.hpp
new file mode 100644
index 0000000..dc2ec75
--- /dev/null
+++ b/lib/standard.hpp
@@ -0,0 +1,14 @@
+#pragma once
+#include "gameState.hpp"
+#include <raylib.h>
+
+float maxOfTwo(float a, float b);
+float minOfTwo(float a, float b);
+float genRandBw(float min, float max);
+Vector2 rotatePoint(Vector2 point, Vector2 pivot, float angleDegree);
+Vector2 C2SProj(Vector2 cartesian_cordinates, Vector4 rectangle_space, Vector2 object_size = {0, 0}, Vector2 absolute_deviation_bias={0,0},bool use_clamp = true);
+float S2CYaxis(float yValue, Vector4 rectangle_space);
+float S2CXaxis(float xValue, Vector4 rectangle_space);
+void newGame(GameState& gs);
+bool returnTrueProbPerc(float percentageTrue);
+Vector2 ScreenToVirtual(Vector2 screenPos, Vector2 offset, float scale);