From 23a796b04fbd578220d28f6b49f1e73f6aa8eb6b Mon Sep 17 00:00:00 2001 From: NarrikSynthfox <80410683+NarrikSynthfox@users.noreply.github.com> Date: Fri, 12 Apr 2024 14:09:46 -0400 Subject: [PATCH] ui changes part 1 --- Encore/Assets/fonts/Rubik-Regular.ttf | Bin 0 -> 207632 bytes Encore/include/game/assets.h | 5 + Encore/include/game/settings.h | 2 + Encore/include/song/song.h | 10 +- Encore/src/main.cpp | 1259 ++++++++++++++----------- 5 files changed, 700 insertions(+), 576 deletions(-) create mode 100644 Encore/Assets/fonts/Rubik-Regular.ttf diff --git a/Encore/Assets/fonts/Rubik-Regular.ttf b/Encore/Assets/fonts/Rubik-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..8b7b632f9c05c3da44447cc0773d355e45f442c0 GIT binary patch literal 207632 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 Q+S7U!`%OL({X~E8zqP+`hyVZp literal 0 HcmV?d00001 diff --git a/Encore/include/game/assets.h b/Encore/include/game/assets.h index 81c950fd..223fe7ec 100644 --- a/Encore/include/game/assets.h +++ b/Encore/include/game/assets.h @@ -50,6 +50,9 @@ class Assets { Texture2D emitTextureOD; Model liftModel; Model liftModelOD; + + Font rubik; + //Sound clapOD; void loadAssets(std::filesystem::path directory) { smasherReg = LoadModel((directory / "Assets/highway/smasher.obj").string().c_str()); @@ -133,6 +136,8 @@ class Assets { liftModel.materials[0].maps[MATERIAL_MAP_ALBEDO].color = Color{ 172,82,217,127 }; liftModelOD = LoadModel((directory / "Assets/notes/lift.obj").string().c_str()); liftModelOD.materials[0].maps[MATERIAL_MAP_ALBEDO].color = Color{ 217, 183, 82 ,127 }; + + rubik = LoadFontEx((directory / "Assets/fonts/Rubik-Regular.ttf").string().c_str(), 100, 0, 0); //clapOD = LoadSound((directory / "Assets/highway/clap.ogg").string().c_str()); //SetSoundVolume(clapOD, 0.375); } diff --git a/Encore/include/game/settings.h b/Encore/include/game/settings.h index 456ef71f..afce0385 100644 --- a/Encore/include/game/settings.h +++ b/Encore/include/game/settings.h @@ -815,6 +815,8 @@ class Settings { overdriveControllerMember->value.SetInt(controllerOverdrive); rapidjson::Value::MemberIterator overdriveControllerDirMember = settings["controllerbinds"].FindMember("overdrive_direction"); overdriveControllerDirMember->value.SetInt(controllerOverdriveAxisDirection); + rapidjson::Value::MemberIterator controllerTypeMember = settings["controllerbinds"].FindMember("type"); + controllerTypeMember->value.SetInt(controllerType); char writeBuffer[8192]; FILE* fp = fopen(settingsFile.string().c_str(), "wb"); diff --git a/Encore/include/song/song.h b/Encore/include/song/song.h index 7272d965..8108eab5 100644 --- a/Encore/include/song/song.h +++ b/Encore/include/song/song.h @@ -110,9 +110,13 @@ class Song public: bool midiParsed=false; std::string title; - + float titleXOffset = 0; + float titleTextWidth = 0; + double titleScrollTime = 0.0; std::string artist; - + float artistXOffset = 0; + float artistTextWidth = 0; + double artistScrollTime = 0.0; Texture albumArt; int length = 0; @@ -141,7 +145,7 @@ class Song } std::string jsonString((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); - + rapidjson::Document document; document.Parse(jsonString.c_str()); diff --git a/Encore/src/main.cpp b/Encore/src/main.cpp index ec1e7427..8584e79d 100644 --- a/Encore/src/main.cpp +++ b/Encore/src/main.cpp @@ -1,4 +1,8 @@ -#include "rapidjson/document.h" + +#if defined(WIN32) && defined(NDEBUG) +#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup") +#endif +#include "rapidjson/document.h" #include "rapidjson/filewritestream.h" #include "rapidjson/writer.h" #include "raylib.h" @@ -29,10 +33,11 @@ static bool compareNotes(const Note& a, const Note& b) { } + bool midiLoaded = false; bool isPlaying = false; bool streamsLoaded = false; -int selectStage = 0; + std::vector> loadedStreams; int curPlayingSong = 0; int curNoteIdx = 0; @@ -40,6 +45,7 @@ int curODPhrase = 0; int curBeatLine = 0; int curBPM = 0; int selLane = 0; +int songSelectOffset = 0; bool changingKey = false; bool changingOverdrive = false; double startedPlayingSong = 0.0; @@ -49,6 +55,17 @@ Rectangle view = { 0 }; std::string trackSpeedButton; +enum Screens { + MENU, + SONG_SELECT, + INSTRUMENT_SELECT, + DIFFICULTY_SELECT, + GAMEPLAY, + RESULTS, + SETTINGS +}; + +int currentScreen = MENU; std::vector heldFrets{ false,false,false,false,false }; std::vector heldFretsAlt{ false,false,false,false,false }; @@ -71,6 +88,15 @@ std::vector axesValues2{ 0.0f,0.0f,0.0f,0.0f,0.0f,0.0f }; int pressedGamepadInput = -999; int axisDirection = -1; int controllerID = -1; + +static void DrawTextRubik(const char* text, float posX, float posY, int fontSize, Color color) { + DrawTextEx(assets.rubik, text, { posX,posY }, fontSize, 2, color); +} + +static int MeasureTextRubik(const char* text, int fontSize) { + return MeasureTextEx(assets.rubik, text, fontSize, 2).x; +} + static void handleInputs(int lane, int action){ if (settings.mirrorMode) { lane = (diff == 3 ? 4 : 3) - lane; @@ -371,6 +397,7 @@ static void gamepadStateCallback(int jid, GLFWgamepadstate state) { } } } + static void gamepadStateCallbackSetControls(int jid, GLFWgamepadstate state) { for (int i = 0; i < 6; i++) { axesValues2[i] = state.axes[i]; @@ -412,17 +439,24 @@ static void gamepadStateCallbackSetControls(int jid, GLFWgamepadstate state) { pressedGamepadInput = -999; } } + +int minWidth = 640; +int minHeight = 480; + + int main(int argc, char* argv[]) { SetConfigFlags(FLAG_MSAA_4X_HINT); SetConfigFlags(FLAG_WINDOW_RESIZABLE); SetConfigFlags(FLAG_VSYNC_HINT); + SetTraceLogLevel(LOG_NONE); // 800 , 600 InitWindow(1, 1, "Encore"); - SetWindowPosition(50, 50); SetWindowSize(GetMonitorWidth(GetCurrentMonitor()) * 0.75, GetMonitorHeight(GetCurrentMonitor()) * 0.75); + SetWindowPosition((GetMonitorWidth(GetCurrentMonitor())*0.5)-(GetMonitorWidth(GetCurrentMonitor())*0.375), (GetMonitorHeight(GetCurrentMonitor()) * 0.5) - (GetMonitorHeight(GetCurrentMonitor()) * 0.375)); + bool windowToggle = true; ArgumentList::InitArguments(argc, argv); @@ -498,242 +532,291 @@ int main(int argc, char* argv[]) glfwSetGamepadStateCallback(origGamepadCallback); GuiSetStyle(DEFAULT, BACKGROUND_COLOR, 0x505050ff); GuiSetStyle(DEFAULT, TEXT_SIZE, 20); + GuiSetFont(assets.rubik); while (!WindowShouldClose()) { + double curTime = GetTime(); + if (GetScreenWidth() < minWidth) { + if (GetScreenHeight() < minHeight) + SetWindowSize(minWidth, minHeight); + else + SetWindowSize(minWidth, GetScreenHeight()); + } + if (GetScreenHeight() < minHeight) { + if (GetScreenWidth() < minWidth) + SetWindowSize(minWidth, minHeight); + else + SetWindowSize(GetScreenWidth(), minHeight); + } float diffDistance = diff == 3 ? 2.0f : 1.5f; float lineDistance = diff == 3 ? 1.5f : 1.0f; BeginDrawing(); ClearBackground(DARKGRAY); - if (!isPlaying) { - if (selectStage == -2) { - if (GuiButton({ ((float)GetScreenWidth() / 2) - 350,((float)GetScreenHeight() - 60),100,60 }, "Cancel") && !(changingKey||changingOverdrive)) { - glfwSetGamepadStateCallback(origGamepadCallback); - selectStage = 0; - settings.controller4K = settings.prevController4K; - settings.controller4KAxisDirection = settings.prevController4KAxisDirection; - settings.controller5K = settings.prevController5K; - settings.controller5KAxisDirection = settings.prevController5KAxisDirection; - settings.controllerOverdrive = settings.prevControllerOverdrive; - settings.controllerOverdriveAxisDirection = settings.prevControllerOverdriveAxisDirection; - settings.controllerType = settings.prevControllerType; + switch (currentScreen) { + case MENU: { + if (GuiButton({ ((float)GetScreenWidth() / 2) - 100,((float)GetScreenHeight() / 2) - 120,200, 60 }, "Play")) { + for (Song& song : songList.songs) { + song.titleScrollTime = GetTime(); + song.titleTextWidth = MeasureTextRubik(song.title.c_str(), 30); + song.artistScrollTime = GetTime(); + song.artistTextWidth = MeasureTextRubik(song.artist.c_str(), 20); + } + currentScreen = SONG_SELECT; } - if (GuiButton({ ((float)GetScreenWidth() / 2) + 250,((float)GetScreenHeight() - 60),100,60 }, "Apply") && !(changingKey || changingOverdrive)) { - glfwSetGamepadStateCallback(origGamepadCallback); - selectStage = 0; - settings.prevController4K = settings.controller4K; - settings.prevController4KAxisDirection = settings.controller4KAxisDirection; - settings.prevController5K = settings.controller5K; - settings.prevController5KAxisDirection = settings.controller5KAxisDirection; - settings.prevControllerOverdrive = settings.controllerOverdrive; - settings.prevControllerOverdriveAxisDirection = settings.controllerOverdriveAxisDirection; - settings.prevControllerType = settings.controllerType; - settings.saveSettings(directory / "settings.json"); + if (GuiButton({ ((float)GetScreenWidth() / 2) - 100,((float)GetScreenHeight() / 2) - 30,200, 60 }, "Options")) { + glfwSetGamepadStateCallback(gamepadStateCallbackSetControls); + currentScreen = SETTINGS; + } + if (GuiButton({ ((float)GetScreenWidth() / 2) - 100,((float)GetScreenHeight() / 2) + 60,200, 60 }, "Quit")) { + exit(0); } + break; + } + case SETTINGS: { if (settings.controllerType == -1 && controllerID != -1) { std::string gamepadName = std::string(glfwGetGamepadName(controllerID)); settings.controllerType = getControllerType(gamepadName); } - for (int i = 0; i < 5; i++) { - float j = i - 2.0f; - if (GuiButton({ ((float)GetScreenWidth() / 2) - 40 + (80 * j),(float)GetScreenHeight() / 2,80,60 }, getControllerStr(controllerID, settings.controller5K[i], settings.controllerType, settings.controller5KAxisDirection[i]).c_str())) { - settings.changing4k = false; - selLane = i; - changingKey = true; - } - } - for (int i = 0; i < 4; i++) { - float j = i - 1.5f; - if (GuiButton({ ((float)GetScreenWidth() / 2) - 40 + (80 * j),(float)GetScreenHeight() / 2 + 140,80,60 }, getControllerStr(controllerID, settings.controller4K[i], settings.controllerType, settings.controller4KAxisDirection[i]).c_str())) { - settings.changing4k = true; - selLane = i; - changingKey = true; - } - } - if (GuiButton({ ((float)GetScreenWidth() / 2) - 40,(float)GetScreenHeight() / 2 + 280,80,60 }, getControllerStr(controllerID, settings.controllerOverdrive,settings.controllerType, settings.controllerOverdriveAxisDirection).c_str())) { - changingKey = false; - changingOverdrive = true; - } - if (changingKey) { - std::vector& bindsToChange = (settings.changing4k ? settings.controller4K : settings.controller5K); - std::vector& directionToChange = (settings.changing4k ? settings.controller4KAxisDirection : settings.controller5KAxisDirection); - DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), { 0,0,0,200 }); - std::string keyString = (settings.changing4k ? "4k" : "5k"); - std::string changeString = "Press a button/axis for controller " + keyString + " lane " + std::to_string(selLane + 1); - DrawText(changeString.c_str(), (GetScreenWidth() - MeasureText(changeString.c_str(), 20)) / 2, GetScreenHeight() / 2 - 10, 20, WHITE); - if (pressedGamepadInput != -999) { - bindsToChange[selLane] = pressedGamepadInput; - if (pressedGamepadInput < 0) { - directionToChange[selLane] = axisDirection; - } - selLane = 0; - changingKey = false; - pressedGamepadInput = -999; - } - } - if (changingOverdrive) { - DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), { 0,0,0,200 }); - std::string changeString = "Press a button/axis for controller overdrive"; - DrawText(changeString.c_str(), (GetScreenWidth() - MeasureText(changeString.c_str(), 20)) / 2, GetScreenHeight() / 2 - 10, 20, WHITE); - - if (pressedGamepadInput != -999) { - settings.controllerOverdrive = pressedGamepadInput; - if (pressedGamepadInput < 0) { - settings.controllerOverdriveAxisDirection = axisDirection; - } - changingOverdrive = false; - pressedGamepadInput = -999; - } - } - } - else if (selectStage == -1) { if (GuiButton({ ((float)GetScreenWidth() / 2) - 350,((float)GetScreenHeight() - 60),100,60 }, "Cancel") && !(changingKey || changingOverdrive)) { - selectStage = 0; + glfwSetGamepadStateCallback(origGamepadCallback); settings.keybinds4K = settings.prev4K; settings.keybinds5K = settings.prev5K; settings.keybinds4KAlt = settings.prev4KAlt; settings.keybinds5KAlt = settings.prev5KAlt; settings.keybindOverdrive = settings.prevOverdrive; settings.keybindOverdriveAlt = settings.prevOverdriveAlt; + + settings.controller4K = settings.prevController4K; + settings.controller4KAxisDirection = settings.prevController4KAxisDirection; + settings.controller5K = settings.prevController5K; + settings.controller5KAxisDirection = settings.prevController5KAxisDirection; + settings.controllerOverdrive = settings.prevControllerOverdrive; + settings.controllerOverdriveAxisDirection = settings.prevControllerOverdriveAxisDirection; + settings.controllerType = settings.prevControllerType; + settings.trackSpeed = settings.prevTrackSpeed; settings.inputOffsetMS = settings.prevInputOffsetMS; settings.avOffsetMS = settings.prevAvOffsetMS; - settings.missHighwayDefault = settings.prevMissHighwayColor; + settings.missHighwayDefault = settings.prevMissHighwayColor; settings.mirrorMode = settings.prevMirrorMode; + + settings.saveSettings(directory / "settings.json"); + + currentScreen = MENU; } if (GuiButton({ ((float)GetScreenWidth() / 2) + 250,((float)GetScreenHeight() - 60),100,60 }, "Apply") && !(changingKey || changingOverdrive)) { - selectStage = 0; + glfwSetGamepadStateCallback(origGamepadCallback); settings.prev4K = settings.keybinds4K; settings.prev5K = settings.keybinds5K; settings.prev4KAlt = settings.keybinds4KAlt; settings.prev5KAlt = settings.keybinds5KAlt; settings.prevOverdrive = settings.keybindOverdrive; settings.prevOverdriveAlt = settings.keybindOverdriveAlt; + + settings.prevController4K = settings.controller4K; + settings.prevController4KAxisDirection = settings.controller4KAxisDirection; + settings.prevController5K = settings.controller5K; + settings.prevController5KAxisDirection = settings.controller5KAxisDirection; + settings.prevControllerOverdrive = settings.controllerOverdrive; + settings.prevControllerOverdriveAxisDirection = settings.controllerOverdriveAxisDirection; + settings.prevControllerType = settings.controllerType; + settings.prevTrackSpeed = settings.trackSpeed; settings.prevInputOffsetMS = settings.inputOffsetMS; settings.prevAvOffsetMS = settings.avOffsetMS; - settings.prevMissHighwayColor = settings.missHighwayDefault; + settings.prevMissHighwayColor = settings.missHighwayDefault; settings.prevMirrorMode = settings.mirrorMode; + settings.saveSettings(directory / "settings.json"); + + currentScreen = MENU; } - if (GuiButton({ (float)GetScreenWidth() / 2 - 125,(float)GetScreenHeight() / 2 - 320,250,60 }, "")) { - if (settings.trackSpeed == settings.trackSpeedOptions.size() - 1) settings.trackSpeed = 0; else settings.trackSpeed++; - trackSpeedButton = "Track Speed " + truncateFloatString(settings.trackSpeedOptions[settings.trackSpeed]) + "x"; - } - DrawText(trackSpeedButton.c_str(), (float)GetScreenWidth() / 2 - MeasureText(trackSpeedButton.c_str(), 20) / 2, (float)GetScreenHeight() / 2 - 300, 20, BLACK); - float avOffsetFloat = (float)settings.avOffsetMS; - DrawText("A/V Offset", (float)GetScreenWidth() / 2 - MeasureText("A/V Offset", 20) / 2, (float)GetScreenHeight() / 2 - 240, 20, WHITE); - DrawText(" -500 ", (float)GetScreenWidth() / 2 - 125 - MeasureText(" -500 ", 20), (float)GetScreenHeight() / 2 - 210, 20, WHITE); - DrawText(" 500 ", (float)GetScreenWidth() / 2 + 125, (float)GetScreenHeight() / 2 - 210, 20, WHITE); - if (GuiSliderBar({ (float)GetScreenWidth() / 2 - 125,(float)GetScreenHeight() / 2 - 220,250,40 }, "", "", &avOffsetFloat, -500.0f, 500.0f)) { - settings.avOffsetMS = (int)avOffsetFloat; - } - if (GuiButton({ (float)GetScreenWidth() / 2 - 125 - MeasureText(" -500 ", 20) - 60,(float)GetScreenHeight() / 2 - 240,60,60 }, "-1")) { - settings.avOffsetMS--; - } - if (GuiButton({ (float)GetScreenWidth() / 2 + 125 + MeasureText(" -500 ", 20) ,(float)GetScreenHeight() / 2 - 240,60,60 }, "+1")) { - settings.avOffsetMS++; - } - DrawText(std::to_string(settings.avOffsetMS).c_str(), (float)GetScreenWidth() / 2 - (MeasureText(std::to_string(settings.avOffsetMS).c_str(), 20) / 2), (float)GetScreenHeight() / 2 - 210, 20, BLACK); - - if (GuiButton({(float) GetScreenWidth()/2 + 250, (float) GetScreenHeight()/2,250,60}, TextFormat("Miss Highway Color: %s", MissHighwayColor ? "True" : "False" ))) { - settings.missHighwayDefault = !settings.missHighwayDefault; - MissHighwayColor = settings.missHighwayDefault; - }; - if (GuiButton({ (float)GetScreenWidth() / 2 + 250, (float)GetScreenHeight() / 2+90,250,60 }, TextFormat("Mirror mode: %s", settings.mirrorMode ? "True" : "False"))) { - settings.mirrorMode = !settings.mirrorMode; - }; - float inputOffsetFloat = (float)settings.inputOffsetMS; - DrawText("Input Offset", (float)GetScreenWidth() / 2 - MeasureText("Input Offset", 20) / 2, (float)GetScreenHeight() / 2 - 160, 20, WHITE); - DrawText(" -500 ", (float)GetScreenWidth() / 2 - 125 - MeasureText(" -500 ", 20), (float)GetScreenHeight() / 2 - 130, 20, WHITE); - DrawText(" 500 ", (float)GetScreenWidth() / 2 + 125, (float)GetScreenHeight() / 2 - 130, 20, WHITE); - if (GuiSliderBar({ (float)GetScreenWidth() / 2 - 125,(float)GetScreenHeight() / 2 - 140,250,40 }, "", "", &inputOffsetFloat, -500.0f, 500.0f)) { - settings.inputOffsetMS = (int)inputOffsetFloat; - } - if (GuiButton({ (float)GetScreenWidth() / 2 - 125 - MeasureText(" -500 ", 20) - 60,(float)GetScreenHeight() / 2 - 160,60,60 }, "-1")) { - settings.inputOffsetMS--; - } - if (GuiButton({ (float)GetScreenWidth() / 2 + 125 + MeasureText(" -500 ", 20),(float)GetScreenHeight() / 2 - 160,60,60 }, "+1")) { - settings.inputOffsetMS++; - } - DrawText(std::to_string(settings.inputOffsetMS).c_str(), (float)GetScreenWidth() / 2 - (MeasureText(std::to_string(settings.inputOffsetMS).c_str(), 20) / 2), (float)GetScreenHeight() / 2 - 130, 20, BLACK); + static int selectedTab = 0; + GuiToggleGroup({ 0,0,(float)GetScreenWidth() / 3,60 }, "Main;Keyboard Controls;Gamepad Controls", &selectedTab); + if (selectedTab == 0) { //Main settings tab + if (GuiButton({ (float)GetScreenWidth() / 2 - 125,(float)GetScreenHeight() / 2 - 320,250,60 }, "")) { + if (settings.trackSpeed == settings.trackSpeedOptions.size() - 1) settings.trackSpeed = 0; else settings.trackSpeed++; + trackSpeedButton = "Track Speed " + truncateFloatString(settings.trackSpeedOptions[settings.trackSpeed]) + "x"; + } + DrawTextRubik(trackSpeedButton.c_str(), (float)GetScreenWidth() / 2 - MeasureTextRubik(trackSpeedButton.c_str(), 20) / 2, (float)GetScreenHeight() / 2 - 300, 20, BLACK); + float avOffsetFloat = (float)settings.avOffsetMS; + DrawTextRubik("A/V Offset", (float)GetScreenWidth() / 2 - MeasureTextRubik("A/V Offset", 20) / 2, (float)GetScreenHeight() / 2 - 240, 20, WHITE); + DrawTextRubik(" -500 ", (float)GetScreenWidth() / 2 - 125 - MeasureTextRubik(" -500 ", 20), (float)GetScreenHeight() / 2 - 210, 20, WHITE); + DrawTextRubik(" 500 ", (float)GetScreenWidth() / 2 + 125, (float)GetScreenHeight() / 2 - 210, 20, WHITE); + if (GuiSliderBar({ (float)GetScreenWidth() / 2 - 125,(float)GetScreenHeight() / 2 - 220,250,40 }, "", "", &avOffsetFloat, -500.0f, 500.0f)) { + settings.avOffsetMS = (int)avOffsetFloat; + } + if (GuiButton({ (float)GetScreenWidth() / 2 - 125 - MeasureTextRubik(" -500 ", 20) - 60,(float)GetScreenHeight() / 2 - 230,60,60 }, "-1")) { + settings.avOffsetMS--; + } + if (GuiButton({ (float)GetScreenWidth() / 2 + 125 + MeasureTextRubik(" -500 ", 20) ,(float)GetScreenHeight() / 2 - 230,60,60 }, "+1")) { + settings.avOffsetMS++; + } + DrawTextRubik(std::to_string(settings.avOffsetMS).c_str(), (float)GetScreenWidth() / 2 - (MeasureTextRubik(std::to_string(settings.avOffsetMS).c_str(), 20) / 2), (float)GetScreenHeight() / 2 - 210, 20, BLACK); - for (int i = 0; i < 5; i++) { - float j = i - 2.0f; - if (GuiButton({ ((float)GetScreenWidth() / 2) - 40 + (80 * j),(float)GetScreenHeight() / 2,80,60 }, getKeyStr(settings.keybinds5K[i]).c_str())) { - settings.changing4k = false; - settings.changingAlt = false; - selLane = i; - changingKey = true; + if (GuiButton({ (float)GetScreenWidth() / 2 - 125, (float)GetScreenHeight() / 2,250,60 }, TextFormat("Miss Highway Color: %s", MissHighwayColor ? "True" : "False"))) { + settings.missHighwayDefault = !settings.missHighwayDefault; + MissHighwayColor = settings.missHighwayDefault; + }; + if (GuiButton({ (float)GetScreenWidth() / 2 - 125, (float)GetScreenHeight() / 2 + 90,250,60 }, TextFormat("Mirror mode: %s", settings.mirrorMode ? "True" : "False"))) { + settings.mirrorMode = !settings.mirrorMode; + }; + float inputOffsetFloat = (float)settings.inputOffsetMS; + DrawTextRubik("Input Offset", (float)GetScreenWidth() / 2 - MeasureTextRubik("Input Offset", 20) / 2, (float)GetScreenHeight() / 2 - 160, 20, WHITE); + DrawTextRubik(" -500 ", (float)GetScreenWidth() / 2 - 125 - MeasureTextRubik(" -500 ", 20), (float)GetScreenHeight() / 2 - 130, 20, WHITE); + DrawTextRubik(" 500 ", (float)GetScreenWidth() / 2 + 125, (float)GetScreenHeight() / 2 - 130, 20, WHITE); + if (GuiSliderBar({ (float)GetScreenWidth() / 2 - 125,(float)GetScreenHeight() / 2 - 140,250,40 }, "", "", &inputOffsetFloat, -500.0f, 500.0f)) { + settings.inputOffsetMS = (int)inputOffsetFloat; } - if (GuiButton({ ((float)GetScreenWidth() / 2) - 40 + (80 * j),(float)GetScreenHeight() / 2 + 60,80,60 }, getKeyStr(settings.keybinds5KAlt[i]).c_str())) { - settings.changing4k = false; - settings.changingAlt = true; - selLane = i; - changingKey = true; + if (GuiButton({ (float)GetScreenWidth() / 2 - 125 - MeasureTextRubik(" -500 ", 20) - 60,(float)GetScreenHeight() / 2 - 150,60,60 }, "-1")) { + settings.inputOffsetMS--; + } + if (GuiButton({ (float)GetScreenWidth() / 2 + 125 + MeasureTextRubik(" -500 ", 20),(float)GetScreenHeight() / 2 - 150,60,60 }, "+1")) { + settings.inputOffsetMS++; } + DrawTextRubik(std::to_string(settings.inputOffsetMS).c_str(), (float)GetScreenWidth() / 2 - (MeasureTextRubik(std::to_string(settings.inputOffsetMS).c_str(), 20) / 2), (float)GetScreenHeight() / 2 - 130, 20, BLACK); } - for (int i = 0; i < 4; i++) { - float j = i - 1.5f; - if (GuiButton({ ((float)GetScreenWidth() / 2) - 40 + (80 * j),(float)GetScreenHeight() / 2 + 140,80,60 }, getKeyStr(settings.keybinds4K[i]).c_str())) { + else if (selectedTab == 1) { //Keyboard bindings tab + for (int i = 0; i < 5; i++) { + float j = i - 2.0f; + if (GuiButton({ ((float)GetScreenWidth() / 2) - 40 + (80 * j),120,80,60 }, getKeyStr(settings.keybinds5K[i]).c_str())) { + settings.changing4k = false; + settings.changingAlt = false; + selLane = i; + changingKey = true; + } + if (GuiButton({ ((float)GetScreenWidth() / 2) - 40 + (80 * j),180,80,60 }, getKeyStr(settings.keybinds5KAlt[i]).c_str())) { + settings.changing4k = false; + settings.changingAlt = true; + selLane = i; + changingKey = true; + } + } + for (int i = 0; i < 4; i++) { + float j = i - 1.5f; + if (GuiButton({ ((float)GetScreenWidth() / 2) - 40 + (80 * j),300,80,60 }, getKeyStr(settings.keybinds4K[i]).c_str())) { + settings.changingAlt = false; + settings.changing4k = true; + selLane = i; + changingKey = true; + } + if (GuiButton({ ((float)GetScreenWidth() / 2) - 40 + (80 * j),360,80,60 }, getKeyStr(settings.keybinds4KAlt[i]).c_str())) { + settings.changingAlt = true; + settings.changing4k = true; + selLane = i; + changingKey = true; + } + } + if (GuiButton({ ((float)GetScreenWidth() / 2) - 100,480,80,60 }, getKeyStr(settings.keybindOverdrive).c_str())) { settings.changingAlt = false; - settings.changing4k = true; - selLane = i; - changingKey = true; + changingKey = false; + changingOverdrive = true; } - if (GuiButton({ ((float)GetScreenWidth() / 2) - 40 + (80 * j),(float)GetScreenHeight() / 2 + 200,80,60 }, getKeyStr(settings.keybinds4KAlt[i]).c_str())) { + if (GuiButton({ ((float)GetScreenWidth() / 2) + 20,480,80,60 }, getKeyStr(settings.keybindOverdriveAlt).c_str())) { settings.changingAlt = true; - settings.changing4k = true; - selLane = i; - changingKey = true; + changingKey = false; + changingOverdrive = true; + } + if (changingKey) { + std::vector& bindsToChange = settings.changingAlt ? (settings.changing4k ? settings.keybinds4KAlt : settings.keybinds5KAlt) : (settings.changing4k ? settings.keybinds4K : settings.keybinds5K); + DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), { 0,0,0,200 }); + std::string keyString = (settings.changing4k ? "4k" : "5k"); + std::string altString = (settings.changingAlt ? " alt" : ""); + std::string changeString = "Press a key for " + keyString + altString + " lane "; + DrawTextRubik(changeString.c_str(), (GetScreenWidth() - MeasureTextRubik(changeString.c_str(), 20)) / 2, GetScreenHeight() / 2 - 30, 20, WHITE); + DrawTextRubik("Or press escape to remove bound key", (GetScreenWidth() - MeasureTextRubik("Or press escape to remove bound key", 20)) / 2, GetScreenHeight() / 2 + 30, 20, WHITE); + int pressedKey = GetKeyPressed(); + if (pressedKey != 0) { + if (pressedKey == KEY_ESCAPE) + pressedKey = -1; + bindsToChange[selLane] = pressedKey; + selLane = 0; + changingKey = false; + } + } + if (changingOverdrive) { + DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), { 0,0,0,200 }); + std::string altString = (settings.changingAlt ? " alt" : ""); + std::string changeString = "Press a key for " + altString + " overdrive"; + DrawTextRubik(changeString.c_str(), (GetScreenWidth() - MeasureTextRubik(changeString.c_str(), 20)) / 2, GetScreenHeight() / 2 - 30, 20, WHITE); + DrawTextRubik("Or press escape to remove bound key", (GetScreenWidth() - MeasureTextRubik("Or press escape to remove bound key", 20)) / 2, GetScreenHeight() / 2 + 30, 20, WHITE); + int pressedKey = GetKeyPressed(); + if (pressedKey != 0) { + if (pressedKey == KEY_ESCAPE) + pressedKey = -1; + if (settings.changingAlt) + settings.keybindOverdriveAlt = pressedKey; + else + settings.keybindOverdrive = pressedKey; + changingOverdrive = false; + } } } - if (GuiButton({ ((float)GetScreenWidth() / 2) - 100,(float)GetScreenHeight() / 2 + 280,80,60 }, getKeyStr(settings.keybindOverdrive).c_str())) { - settings.changingAlt = false; - changingKey = false; - changingOverdrive = true; - } - if (GuiButton({ ((float)GetScreenWidth() / 2) + 20,(float)GetScreenHeight() / 2 + 280,80,60 }, getKeyStr(settings.keybindOverdriveAlt).c_str())) { - settings.changingAlt = true; - changingKey = false; - changingOverdrive = true; - } - if (changingKey) { - std::vector& bindsToChange = settings.changingAlt ? (settings.changing4k ? settings.keybinds4KAlt : settings.keybinds5KAlt) : (settings.changing4k ? settings.keybinds4K : settings.keybinds5K); - DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), { 0,0,0,200 }); - std::string keyString = (settings.changing4k ? "4k" : "5k"); - std::string altString = (settings.changingAlt ? " alt" : ""); - std::string changeString = "Press a key for " + keyString + altString + " lane " + std::to_string(selLane + 1); - DrawText(changeString.c_str(), (GetScreenWidth() - MeasureText(changeString.c_str(), 20)) / 2, GetScreenHeight() / 2 - 10, 20, WHITE); - int pressedKey = GetKeyPressed(); - if (pressedKey != 0) { - if (pressedKey == KEY_ESCAPE) - pressedKey = -1; - bindsToChange[selLane] = pressedKey; - selLane = 0; + else if (selectedTab == 2) { //Controller bindings tab + for (int i = 0; i < 5; i++) { + float j = i - 2.0f; + if (GuiButton({ ((float)GetScreenWidth() / 2) - 40 + (80 * j),240,80,60 }, getControllerStr(controllerID, settings.controller5K[i], settings.controllerType, settings.controller5KAxisDirection[i]).c_str())) { + settings.changing4k = false; + selLane = i; + changingKey = true; + } + } + for (int i = 0; i < 4; i++) { + float j = i - 1.5f; + if (GuiButton({ ((float)GetScreenWidth() / 2) - 40 + (80 * j),360,80,60 }, getControllerStr(controllerID, settings.controller4K[i], settings.controllerType, settings.controller4KAxisDirection[i]).c_str())) { + settings.changing4k = true; + selLane = i; + changingKey = true; + } + } + if (GuiButton({ ((float)GetScreenWidth() / 2) - 40,480,80,60 }, getControllerStr(controllerID, settings.controllerOverdrive, settings.controllerType, settings.controllerOverdriveAxisDirection).c_str())) { changingKey = false; + changingOverdrive = true; } - } - if (changingOverdrive) { - DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), { 0,0,0,200 }); - std::string altString = (settings.changingAlt ? " alt" : ""); - std::string changeString = "Press a key for " + altString + " overdrive"; - DrawText(changeString.c_str(), (GetScreenWidth() - MeasureText(changeString.c_str(), 20)) / 2, GetScreenHeight() / 2 - 10, 20, WHITE); - int pressedKey = GetKeyPressed(); - if (pressedKey != 0) { - if (pressedKey == KEY_ESCAPE) - pressedKey = -1; - if (settings.changingAlt) - settings.keybindOverdriveAlt = pressedKey; - else - settings.keybindOverdrive = pressedKey; + if (changingKey) { + std::vector& bindsToChange = (settings.changing4k ? settings.controller4K : settings.controller5K); + std::vector& directionToChange = (settings.changing4k ? settings.controller4KAxisDirection : settings.controller5KAxisDirection); + DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), { 0,0,0,200 }); + std::string keyString = (settings.changing4k ? "4k" : "5k"); + std::string changeString = "Press a button/axis for controller " + keyString + " lane " + std::to_string(selLane + 1); + DrawTextRubik(changeString.c_str(), (GetScreenWidth() - MeasureTextRubik(changeString.c_str(), 20)) / 2, GetScreenHeight() / 2 - 30, 20, WHITE); + DrawTextRubik("Or press escape to cancel", (GetScreenWidth() - MeasureTextRubik("Or press escape to cancel", 20)) / 2, GetScreenHeight() / 2 + 30, 20, WHITE); + if (pressedGamepadInput != -999) { + bindsToChange[selLane] = pressedGamepadInput; + if (pressedGamepadInput < 0) { + directionToChange[selLane] = axisDirection; + } + selLane = 0; + changingKey = false; + pressedGamepadInput = -999; + } + } + if (changingOverdrive) { + DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), { 0,0,0,200 }); + std::string changeString = "Press a button/axis for controller overdrive"; + DrawTextRubik(changeString.c_str(), (GetScreenWidth() - MeasureTextRubik(changeString.c_str(), 20)) / 2, GetScreenHeight() / 2 - 30, 20, WHITE); + DrawTextRubik("Or press escape to cancel", (GetScreenWidth() - MeasureTextRubik("Or press escape to cancel", 20)) / 2, GetScreenHeight() / 2 + 30, 20, WHITE); + + if (pressedGamepadInput != -999) { + settings.controllerOverdrive = pressedGamepadInput; + if (pressedGamepadInput < 0) { + settings.controllerOverdriveAxisDirection = axisDirection; + } + changingOverdrive = false; + pressedGamepadInput = -999; + } + } + if (IsKeyPressed(KEY_ESCAPE)) { + pressedGamepadInput = -999; + changingKey = false; changingOverdrive = false; } } + break; } - //song select - else if (selectStage == 0) { + case SONG_SELECT: { streamsLoaded = false; midiLoaded = false; isPlaying = false; @@ -744,43 +827,65 @@ int main(int argc, char* argv[]) curBPM = 0; instrument = 0; diff = 0; - float curSong = 0.0f; - if (GuiButton({ (float)GetScreenWidth() - 260,0,60,60 }, "Exit")) { - exit(0); - } - if (GuiButton({ (float)GetScreenWidth() - 200,0,200,60 }, "Settings")) { - selectStage = -1; - } - if (GuiButton({ (float)GetScreenWidth() - 200,60,200,60 }, "Fullscreen")) { - windowToggle = !windowToggle; - ToggleBorderlessWindowed(); - if (windowToggle) { - SetWindowPosition(50, 50); - SetWindowSize(GetMonitorWidth(GetCurrentMonitor()) / 2, GetMonitorHeight(GetCurrentMonitor()) / 2); + if (GuiButton({ 0,0,60,60 }, "<")) { + for (Song& song : songList.songs) { + song.titleXOffset = 0; + song.artistXOffset = 0; } - else { - SetWindowSize(GetMonitorWidth(GetCurrentMonitor()), GetMonitorHeight(GetCurrentMonitor())); - }; + currentScreen = MENU; } - if (GuiButton({ (float)GetScreenWidth() - 200,120,200,60 }, "Controller Binds")) { - glfwSetGamepadStateCallback(gamepadStateCallbackSetControls); - selectStage = -2; + Vector2 mouseWheel = GetMouseWheelMoveV(); + if (songSelectOffset <= songList.songs.size() + 2 - (GetScreenHeight() / 60) && songSelectOffset >= 0) { + songSelectOffset -= mouseWheel.y; } - GuiScrollPanel({ 0, 0, (float)GetScreenWidth() * (3.0f / 5.0f) + 15, (float)GetScreenHeight() }, NULL, { 0, 0, (float)GetScreenWidth() * (3.0f / 5.0f), 60.0f * songList.songs.size() }, &viewScroll, &view); - for (Song song : songList.songs) { + if (songSelectOffset < 0) songSelectOffset = 0; + if (songSelectOffset > songList.songs.size() + 2 - (GetScreenHeight() / 60)) songSelectOffset = songList.songs.size() + 2 - (GetScreenHeight() / 60); + if (songSelectOffset >= songList.songs.size()) songSelectOffset = songList.songs.size() - 1; - if (GuiButton(Rectangle{ 0,viewScroll.y + (60 * curSong),((float)GetScreenWidth() * (3.0f / 5.0f)) + 2 , 60 }, "")) { - curPlayingSong = (int)curSong; - selectStage = 1; + for (int i = songSelectOffset; i < songSelectOffset + (GetScreenHeight() / 60) - 2; i++) { + if (i == songList.songs.size()) { + break; + } + Song& song = songList.songs[i]; + float songYPos = 60 + (60 * (i - songSelectOffset)); + if (GuiButton(Rectangle{ 0, songYPos,((float)GetScreenWidth() * (3.0f / 5.0f)) , 60 }, "")) { + curPlayingSong = i; + currentScreen = INSTRUMENT_SELECT; + } + DrawTexturePro(song.albumArt, Rectangle{ 0,0,(float)song.albumArt.width,(float)song.albumArt.height }, { 5,songYPos + 5,50,50 }, Vector2{ 0,0 }, 0.0f, RAYWHITE); + int songTitleWidth = (GetScreenWidth() * (2.0 / 5.0) - 100); + int songArtistWidth = (GetScreenWidth() * (1.0 / 5.0) - 65); + if (song.titleTextWidth >= songTitleWidth) { + if (curTime > song.titleScrollTime && curTime < song.titleScrollTime + 3.0) + song.titleXOffset = 0; + if (curTime > song.titleScrollTime + 3.0) { + song.titleXOffset -= 1; + if (song.titleXOffset < -(song.titleTextWidth - songTitleWidth)) { + song.titleXOffset = -(song.titleTextWidth - songTitleWidth); + song.titleScrollTime = curTime + 3.0; + } + } + } + BeginScissorMode(65, songYPos + 15, songTitleWidth, 30); + DrawTextRubik(song.title.c_str(), song.titleXOffset + 65, songYPos + 15, 30, BLACK); + EndScissorMode(); + if (song.artistTextWidth > songArtistWidth) { + if (curTime > song.artistScrollTime && curTime < song.artistScrollTime + 3.0) + song.artistXOffset = 0; + if (curTime > song.artistScrollTime + 3.0) { + song.artistXOffset -= 1; + if (song.artistXOffset < -(song.artistTextWidth - songArtistWidth)) { + song.artistScrollTime = curTime + 3.0; + } + } } - DrawTextureEx(song.albumArt, Vector2{ 5,viewScroll.y + (60 * curSong) + 5 }, 0.0f, 0.1f, RAYWHITE); - DrawText(song.title.c_str(), 65, viewScroll.y + (60 * curSong) + 15, 30, BLACK); - DrawText(song.artist.c_str(), ((float)GetScreenWidth() * (1.5f / 4.0f)), viewScroll.y + (60 * curSong) + 20, 20, BLACK); - curSong++; + BeginScissorMode(65 + songTitleWidth + 20, songYPos + 20, songArtistWidth, 20); + DrawTextRubik(song.artist.c_str(), 65 + songTitleWidth + song.artistXOffset + 20, songYPos + 20, 20, BLACK); + EndScissorMode(); } + break; } - //instrument select - else if (selectStage == 1) { + case INSTRUMENT_SELECT: { if (!midiLoaded) { if (!songList.songs[curPlayingSong].midiParsed) { smf::MidiFile midiFile; @@ -805,7 +910,7 @@ int main(int argc, char* argv[]) if (songPart != SongParts::Invalid) { for (int diff = 0; diff < 4; diff++) { Chart newChart; - newChart.parseNotes(midiFile, i, midiFile[i], diff,(int)songPart); + newChart.parseNotes(midiFile, i, midiFile[i], diff, (int)songPart); if (newChart.notes.size() > 0) { songList.songs[curPlayingSong].parts[(int)songPart]->hasPart = true; } @@ -825,7 +930,7 @@ int main(int argc, char* argv[]) else { if (GuiButton({ 0,0,60,60 }, "<")) { midiLoaded = false; - selectStage = 0; + currentScreen = SONG_SELECT; } for (int i = 0; i < 4; i++) { if (songList.songs[curPlayingSong].parts[i]->hasPart) { @@ -836,469 +941,477 @@ int main(int argc, char* argv[]) isBassOrVocal = 1; } SetShaderValue(assets.odMultShader, assets.isBassOrVocalLoc, &isBassOrVocal, SHADER_UNIFORM_INT); - selectStage = 2; + currentScreen = DIFFICULTY_SELECT; } - DrawText(songPartsList[i].c_str(), 20, 75 + (60 * (float)i), 30, BLACK); - DrawText((std::to_string(songList.songs[curPlayingSong].parts[i]->diff + 1) + "/7").c_str(), 220, 75 + (60 * (float)i), 30, BLACK); + DrawTextRubik(songPartsList[i].c_str(), 20, 75 + (60 * (float)i), 30, BLACK); + DrawTextRubik((std::to_string(songList.songs[curPlayingSong].parts[i]->diff + 1) + "/7").c_str(), 220, 75 + (60 * (float)i), 30, BLACK); } } } - + break; } - else if (selectStage == 2) { + case DIFFICULTY_SELECT: { for (int i = 0; i < 4; i++) { if (GuiButton({ 0,0,60,60 }, "<")) { - selectStage = 1; + currentScreen = SONG_SELECT; } if (songList.songs[curPlayingSong].parts[instrument]->charts[i].notes.size() > 0) { if (GuiButton({ 0,60 + (60 * (float)i),300,60 }, "")) { diff = i; - selectStage = 3; + currentScreen = GAMEPLAY; isPlaying = true; startedPlayingSong = GetTime(); glfwSetKeyCallback(glfwGetCurrentContext(), keyCallback); glfwSetGamepadStateCallback(gamepadStateCallback); } - DrawText(diffList[i].c_str(), 150 - (MeasureText(diffList[i].c_str(), 30) / 2), 75 + (60 * (float)i), 30, BLACK); + DrawTextRubik(diffList[i].c_str(), 150 - (MeasureTextRubik(diffList[i].c_str(), 30) / 2), 75 + (60 * (float)i), 30, BLACK); } } + break; } - else if (selectStage == 4) { + case GAMEPLAY: { + char* starsDisplay = (char*)""; int starsval = stars(songList.songs[curPlayingSong].parts[instrument]->charts[diff].baseScore); - char* starsDisplay = (char*) ""; - if (starsval == 5) { - starsDisplay = (char*) "*****"; - } else if (starsval == 4) { - starsDisplay = (char*) "****"; - } else if (starsval == 3) { - starsDisplay = (char*) "***"; - } else if (starsval == 2) { - starsDisplay = (char*) "**"; - } else if (starsval == 1) { - starsDisplay = (char*) "*";; - } else { - starsDisplay = (char*) ""; - } - DrawText("Results", GetScreenWidth() / 2 - (MeasureText("Results", 36) / 2), 0, 36, WHITE); - DrawText((songList.songs[curPlayingSong].artist + " - " + songList.songs[curPlayingSong].title).c_str(), GetScreenWidth() / 2 - (MeasureText((songList.songs[curPlayingSong].artist + " - " + songList.songs[curPlayingSong].title).c_str(), 24) / 2), 48, 24, WHITE); - if (FC) { - DrawText("Flawless!", GetScreenWidth() / 2 - (MeasureText("Flawless!", 24) / 2), 84, 24, GOLD); + if (starsval == 5) { + starsDisplay = (char*)"*****"; } - DrawText(TextFormat("%01i", score), (GetScreenWidth() / 2 - MeasureText(TextFormat("%01i", score), 24) / 2), 128, 24, WHITE); - DrawText(TextFormat("%s", starsDisplay) , (GetScreenWidth() / 2 - MeasureText(TextFormat("%s", starsDisplay), 24) / 2), 160, 24, goldStars ? GOLD : WHITE); - DrawText(TextFormat("Perfect Notes : %01i/%02i", perfectHit, songList.songs[curPlayingSong].parts[instrument]->charts[diff].notes.size()), (GetScreenWidth() / 2 - MeasureText(TextFormat("Perfect Notes: %01i/%02i", perfectHit, songList.songs[curPlayingSong].parts[instrument]->charts[diff].notes.size()), 24) / 2), 192, 24, WHITE); - DrawText(TextFormat("Good Notes : %01i/%02i", notesHit-perfectHit, songList.songs[curPlayingSong].parts[instrument]->charts[diff].notes.size()), (GetScreenWidth() / 2 - MeasureText(TextFormat("Good Notes: %01i/%02i", notesHit - perfectHit, songList.songs[curPlayingSong].parts[instrument]->charts[diff].notes.size()), 24) / 2), 224, 24, WHITE); - DrawText(TextFormat("Missed Notes: %01i/%02i", notesMissed, songList.songs[curPlayingSong].parts[instrument]->charts[diff].notes.size()), (GetScreenWidth() / 2 - MeasureText(TextFormat("Missed Notes: %01i/%02i", notesMissed, songList.songs[curPlayingSong].parts[instrument]->charts[diff].notes.size()), 24) / 2), 256, 24, WHITE); - DrawText(TextFormat("Strikes: %01i", playerOverhits), (GetScreenWidth() / 2 - MeasureText(TextFormat("Strikes: %01i", playerOverhits), 24) / 2), 288, 24, WHITE); - DrawText(TextFormat("Longest Streak: %01i", maxCombo), (GetScreenWidth() / 2 - MeasureText(TextFormat("Longest Streak: %01i", maxCombo), 24) / 2), 320, 24, WHITE); - if (GuiButton({ 0,0,60,60 }, "<")) { - selectStage = 0; + else if (starsval == 4) { + starsDisplay = (char*)"****"; } - } - } - else { - char* starsDisplay = (char*) ""; - int starsval = stars(songList.songs[curPlayingSong].parts[instrument]->charts[diff].baseScore); - if (starsval == 5) { - starsDisplay = (char*) "*****"; - } else if (starsval == 4) { - starsDisplay = (char*) "****"; - } else if (starsval == 3) { - starsDisplay = (char*) "***"; - } else if (starsval == 2) { - starsDisplay = (char*) "**"; - } else if (starsval == 1) { - starsDisplay = (char*) "*";; - } else { - starsDisplay = (char*) ""; - } - DrawText(TextFormat("%s", starsDisplay), 5, GetScreenHeight() - 470, 48, goldStars ? GOLD : WHITE); - DrawText(TextFormat("%01i", score + sustainScoreBuffer[0] + sustainScoreBuffer[1] + sustainScoreBuffer[2] + sustainScoreBuffer[3] + sustainScoreBuffer[4]), 5, GetScreenHeight() - 420, 48, WHITE); - DrawText(TextFormat("%01i", combo), 5, GetScreenHeight() - 330, 30, FC ? GOLD : (combo <= 3) ? RED : WHITE); - DrawText(TextFormat("%s", FC ? "FC" : ""), 5, GetScreenHeight() - 40, 36, GOLD); - DrawText(TextFormat("%s", lastNotePerfect ? "Perfect" : ""), 5, (GetScreenHeight() - 370), 30, GOLD); - - float multFill = (!overdrive ? (float)(multiplier(instrument) - 1) : ((float)(multiplier(instrument) / 2) - 1)) / (float)maxMultForMeter(instrument); - SetShaderValue(assets.odMultShader, assets.multLoc, &multFill, SHADER_UNIFORM_FLOAT); - SetShaderValue(assets.multNumberShader, assets.uvOffsetXLoc, &uvOffsetX, SHADER_UNIFORM_FLOAT); - SetShaderValue(assets.multNumberShader, assets.uvOffsetYLoc, &uvOffsetY, SHADER_UNIFORM_FLOAT); - float comboFill = comboFillCalc(instrument); - SetShaderValue(assets.odMultShader, assets.comboCounterLoc, &comboFill, SHADER_UNIFORM_FLOAT); - SetShaderValue(assets.odMultShader, assets.odLoc, &overdriveFill, SHADER_UNIFORM_FLOAT); - if (extraGameplayStats) { - DrawText(TextFormat("Perfect Hit: %01i", perfectHit), 5, GetScreenHeight() - 280, 24, - (perfectHit > 0) ? GOLD : WHITE); - DrawText(TextFormat("Max Combo: %01i", maxCombo), 5, GetScreenHeight() - 130, 24, WHITE); - DrawText(TextFormat("Multiplier: %01i", multiplier(instrument)), 5, GetScreenHeight() - 100, 24, - (multiplier(instrument) >= 4) ? SKYBLUE : WHITE); - DrawText(TextFormat("Notes Hit: %01i", notesHit), 5, GetScreenHeight() - 250, 24, FC ? GOLD : WHITE); - DrawText(TextFormat("Notes Missed: %01i", notesMissed), 5, GetScreenHeight() - 220, 24, - ((combo == 0) && (!FC)) ? RED : WHITE); - DrawText(TextFormat("Strikes: %01i", playerOverhits), 5, GetScreenHeight() - 40, 24, FC ? GOLD : WHITE); - } - - - if (GuiButton({ 0,0,60,60 }, "<")) { - for (Note& note : songList.songs[curPlayingSong].parts[instrument]->charts[diff].notes) { - note.accounted = false; - note.hit = false; - note.miss = false; - note.held = false; - note.heldTime = 0; - note.hitTime = 0; - note.perfect = false; - note.countedForODPhrase = false; + else if (starsval == 3) { + starsDisplay = (char*)"***"; } - glfwSetKeyCallback(glfwGetCurrentContext(), origKeyCallback); - glfwSetGamepadStateCallback(origGamepadCallback); - // notes = songList.songs[curPlayingSong].parts[instrument]->charts[diff].notes.size(); - // notes = songList.songs[curPlayingSong].parts[instrument]->charts[diff]; - for (odPhrase& phrase : songList.songs[curPlayingSong].parts[instrument]->charts[diff].odPhrases) { - phrase.missed = false; - phrase.notesHit = 0; - phrase.added = false; + else if (starsval == 2) { + starsDisplay = (char*)"**"; } - selectStage = 0; - overdrive = false; - overdriveFill = 0.0f; - overdriveActiveFill = 0.0f; - overdriveActiveTime = 0.0; - curODPhrase = 0; - assets.expertHighway.materials[0].maps[MATERIAL_MAP_ALBEDO].texture = assets.highwayTexture; - assets.emhHighway.materials[0].maps[MATERIAL_MAP_ALBEDO].texture = assets.highwayTexture; - assets.multBar.materials[0].maps[MATERIAL_MAP_EMISSION].texture = assets.odMultFill; - assets.multCtr3.materials[0].maps[MATERIAL_MAP_EMISSION].texture = assets.odMultFill; - assets.multCtr5.materials[0].maps[MATERIAL_MAP_EMISSION].texture = assets.odMultFill; - assets.expertHighway.materials[0].maps[MATERIAL_MAP_ALBEDO].color = WHITE; - isPlaying = false; - midiLoaded = false; - streamsLoaded = false; - } - if (!streamsLoaded) { - loadedStreams = LoadStems(songList.songs[curPlayingSong].stemsPath); - for (auto& stream : loadedStreams) { - std::cout << GetMusicTimeLength(stream.first) << std::endl; + else if (starsval == 1) { + starsDisplay = (char*)"*";; + } + else { + starsDisplay = (char*)""; + } + DrawTextRubik(TextFormat("%s", starsDisplay), 5, GetScreenHeight() - 470, 48, goldStars ? GOLD : WHITE); + DrawTextRubik(TextFormat("%01i", score + sustainScoreBuffer[0] + sustainScoreBuffer[1] + sustainScoreBuffer[2] + sustainScoreBuffer[3] + sustainScoreBuffer[4]), 5, GetScreenHeight() - 420, 48, WHITE); + DrawTextRubik(TextFormat("%01i", combo), 5, GetScreenHeight() - 330, 30, FC ? GOLD : (combo <= 3) ? RED : WHITE); + DrawTextRubik(TextFormat("%s", FC ? "FC" : ""), 5, GetScreenHeight() - 40, 36, GOLD); + DrawTextRubik(TextFormat("%s", lastNotePerfect ? "Perfect" : ""), 5, (GetScreenHeight() - 370), 30, GOLD); + + float multFill = (!overdrive ? (float)(multiplier(instrument) - 1) : ((float)(multiplier(instrument) / 2) - 1)) / (float)maxMultForMeter(instrument); + SetShaderValue(assets.odMultShader, assets.multLoc, &multFill, SHADER_UNIFORM_FLOAT); + SetShaderValue(assets.multNumberShader, assets.uvOffsetXLoc, &uvOffsetX, SHADER_UNIFORM_FLOAT); + SetShaderValue(assets.multNumberShader, assets.uvOffsetYLoc, &uvOffsetY, SHADER_UNIFORM_FLOAT); + float comboFill = comboFillCalc(instrument); + SetShaderValue(assets.odMultShader, assets.comboCounterLoc, &comboFill, SHADER_UNIFORM_FLOAT); + SetShaderValue(assets.odMultShader, assets.odLoc, &overdriveFill, SHADER_UNIFORM_FLOAT); + if (extraGameplayStats) { + DrawTextRubik(TextFormat("Perfect Hit: %01i", perfectHit), 5, GetScreenHeight() - 280, 24, + (perfectHit > 0) ? GOLD : WHITE); + DrawTextRubik(TextFormat("Max Combo: %01i", maxCombo), 5, GetScreenHeight() - 130, 24, WHITE); + DrawTextRubik(TextFormat("Multiplier: %01i", multiplier(instrument)), 5, GetScreenHeight() - 100, 24, + (multiplier(instrument) >= 4) ? SKYBLUE : WHITE); + DrawTextRubik(TextFormat("Notes Hit: %01i", notesHit), 5, GetScreenHeight() - 250, 24, FC ? GOLD : WHITE); + DrawTextRubik(TextFormat("Notes Missed: %01i", notesMissed), 5, GetScreenHeight() - 220, 24, + ((combo == 0) && (!FC)) ? RED : WHITE); + DrawTextRubik(TextFormat("Strikes: %01i", playerOverhits), 5, GetScreenHeight() - 40, 24, FC ? GOLD : WHITE); } - streamsLoaded = true; - player::resetPlayerStats(); - } - else { - if (GetTime() >= GetMusicTimeLength(loadedStreams[0].first) + startedPlayingSong) { + + if (GuiButton({ 0,0,60,60 }, "<")) { for (Note& note : songList.songs[curPlayingSong].parts[instrument]->charts[diff].notes) { note.accounted = false; note.hit = false; note.miss = false; note.held = false; note.heldTime = 0; - note.hitTime = 0; + note.hitTime = 0; note.perfect = false; - note.countedForODPhrase = false; - // notes += 1; + note.countedForODPhrase = false; } glfwSetKeyCallback(glfwGetCurrentContext(), origKeyCallback); glfwSetGamepadStateCallback(origGamepadCallback); - // notes = (int)songList.songs[curPlayingSong].parts[instrument]->charts[diff].notes.size(); + // notes = songList.songs[curPlayingSong].parts[instrument]->charts[diff].notes.size(); + // notes = songList.songs[curPlayingSong].parts[instrument]->charts[diff]; for (odPhrase& phrase : songList.songs[curPlayingSong].parts[instrument]->charts[diff].odPhrases) { phrase.missed = false; phrase.notesHit = 0; phrase.added = false; } + currentScreen = SONG_SELECT; overdrive = false; overdriveFill = 0.0f; overdriveActiveFill = 0.0f; overdriveActiveTime = 0.0; - isPlaying = false; - midiLoaded = false; - streamsLoaded = false; - curODPhrase = 0; + curODPhrase = 0; assets.expertHighway.materials[0].maps[MATERIAL_MAP_ALBEDO].texture = assets.highwayTexture; assets.emhHighway.materials[0].maps[MATERIAL_MAP_ALBEDO].texture = assets.highwayTexture; assets.multBar.materials[0].maps[MATERIAL_MAP_EMISSION].texture = assets.odMultFill; assets.multCtr3.materials[0].maps[MATERIAL_MAP_EMISSION].texture = assets.odMultFill; assets.multCtr5.materials[0].maps[MATERIAL_MAP_EMISSION].texture = assets.odMultFill; - assets.expertHighway.materials[0].maps[MATERIAL_MAP_ALBEDO].color = WHITE; - selectStage = 4; - + assets.expertHighway.materials[0].maps[MATERIAL_MAP_ALBEDO].color = WHITE; + isPlaying = false; + midiLoaded = false; + streamsLoaded = false; } - for (auto& stream : loadedStreams) { - stream.first.looping = false; - UpdateMusicStream(stream.first); - PlayMusicStream(stream.first); - if (instrument == stream.second) - SetAudioStreamVolume(stream.first.stream, mute ? missVolume : selInstVolume); - else - SetAudioStreamVolume(stream.first.stream, otherInstVolume); + if (!streamsLoaded) { + loadedStreams = LoadStems(songList.songs[curPlayingSong].stemsPath); + for (auto& stream : loadedStreams) { + std::cout << GetMusicTimeLength(stream.first) << std::endl; + } + streamsLoaded = true; + player::resetPlayerStats(); } - } - - double musicTime = GetMusicTimePlayed(loadedStreams[0].first); - if (overdrive) { - assets.expertHighway.materials[0].maps[MATERIAL_MAP_ALBEDO].texture = assets.highwayTextureOD; - assets.emhHighway.materials[0].maps[MATERIAL_MAP_ALBEDO].texture = assets.highwayTextureOD; - assets.multBar.materials[0].maps[MATERIAL_MAP_EMISSION].texture = assets.odMultFillActive; - assets.multCtr3.materials[0].maps[MATERIAL_MAP_EMISSION].texture = assets.odMultFillActive; - assets.multCtr5.materials[0].maps[MATERIAL_MAP_EMISSION].texture = assets.odMultFillActive; - + else { + if (GetTime() >= GetMusicTimeLength(loadedStreams[0].first) + startedPlayingSong) { + for (Note& note : songList.songs[curPlayingSong].parts[instrument]->charts[diff].notes) { + note.accounted = false; + note.hit = false; + note.miss = false; + note.held = false; + note.heldTime = 0; + note.hitTime = 0; + note.perfect = false; + note.countedForODPhrase = false; + // notes += 1; + } + glfwSetKeyCallback(glfwGetCurrentContext(), origKeyCallback); + glfwSetGamepadStateCallback(origGamepadCallback); + // notes = (int)songList.songs[curPlayingSong].parts[instrument]->charts[diff].notes.size(); + for (odPhrase& phrase : songList.songs[curPlayingSong].parts[instrument]->charts[diff].odPhrases) { + phrase.missed = false; + phrase.notesHit = 0; + phrase.added = false; + } + overdrive = false; + overdriveFill = 0.0f; + overdriveActiveFill = 0.0f; + overdriveActiveTime = 0.0; + isPlaying = false; + midiLoaded = false; + streamsLoaded = false; + curODPhrase = 0; + assets.expertHighway.materials[0].maps[MATERIAL_MAP_ALBEDO].texture = assets.highwayTexture; + assets.emhHighway.materials[0].maps[MATERIAL_MAP_ALBEDO].texture = assets.highwayTexture; + assets.multBar.materials[0].maps[MATERIAL_MAP_EMISSION].texture = assets.odMultFill; + assets.multCtr3.materials[0].maps[MATERIAL_MAP_EMISSION].texture = assets.odMultFill; + assets.multCtr5.materials[0].maps[MATERIAL_MAP_EMISSION].texture = assets.odMultFill; + assets.expertHighway.materials[0].maps[MATERIAL_MAP_ALBEDO].color = WHITE; + currentScreen = RESULTS; - overdriveFill = overdriveActiveFill - ((musicTime - overdriveActiveTime) / (1920 / songList.songs[curPlayingSong].bpms[curBPM].bpm)); - if (overdriveFill <= 0) { - overdrive = false; - overdriveActiveFill = 0; - overdriveActiveTime = 0.0; - assets.expertHighway.materials[0].maps[MATERIAL_MAP_ALBEDO].texture = assets.highwayTexture; - assets.emhHighway.materials[0].maps[MATERIAL_MAP_ALBEDO].texture = assets.highwayTexture; - assets.multBar.materials[0].maps[MATERIAL_MAP_EMISSION].texture = assets.odMultFill; - assets.multCtr3.materials[0].maps[MATERIAL_MAP_EMISSION].texture = assets.odMultFill; - assets.multCtr5.materials[0].maps[MATERIAL_MAP_EMISSION].texture = assets.odMultFill; + } + for (auto& stream : loadedStreams) { + stream.first.looping = false; + UpdateMusicStream(stream.first); + PlayMusicStream(stream.first); + if (instrument == stream.second) + SetAudioStreamVolume(stream.first.stream, mute ? missVolume : selInstVolume); + else + SetAudioStreamVolume(stream.first.stream, otherInstVolume); + } } - } - for (int i = curBPM; i < songList.songs[curPlayingSong].bpms.size(); i++) { - if (musicTime > songList.songs[curPlayingSong].bpms[i].time && i < songList.songs[curPlayingSong].bpms.size() - 1) - curBPM++; - } - if (musicTime < 5.0) { - DrawText(songList.songs[curPlayingSong].title.c_str(), 5, 65, 30, WHITE); - DrawText(songList.songs[curPlayingSong].artist.c_str(), 5, 100, 24, WHITE); - } + double musicTime = GetMusicTimePlayed(loadedStreams[0].first); + if (overdrive) { + assets.expertHighway.materials[0].maps[MATERIAL_MAP_ALBEDO].texture = assets.highwayTextureOD; + assets.emhHighway.materials[0].maps[MATERIAL_MAP_ALBEDO].texture = assets.highwayTextureOD; + assets.multBar.materials[0].maps[MATERIAL_MAP_EMISSION].texture = assets.odMultFillActive; + assets.multCtr3.materials[0].maps[MATERIAL_MAP_EMISSION].texture = assets.odMultFillActive; + assets.multCtr5.materials[0].maps[MATERIAL_MAP_EMISSION].texture = assets.odMultFillActive; + + + overdriveFill = overdriveActiveFill - ((musicTime - overdriveActiveTime) / (1920 / songList.songs[curPlayingSong].bpms[curBPM].bpm)); + if (overdriveFill <= 0) { + overdrive = false; + overdriveActiveFill = 0; + overdriveActiveTime = 0.0; + assets.expertHighway.materials[0].maps[MATERIAL_MAP_ALBEDO].texture = assets.highwayTexture; + assets.emhHighway.materials[0].maps[MATERIAL_MAP_ALBEDO].texture = assets.highwayTexture; + assets.multBar.materials[0].maps[MATERIAL_MAP_EMISSION].texture = assets.odMultFill; + assets.multCtr3.materials[0].maps[MATERIAL_MAP_EMISSION].texture = assets.odMultFill; + assets.multCtr5.materials[0].maps[MATERIAL_MAP_EMISSION].texture = assets.odMultFill; - BeginMode3D(camera); - if (diff == 3) { - DrawModel(assets.expertHighway, Vector3{ 0,0,0 }, 1.0f, WHITE); - for (int i = 0; i < 5; i++) { - if (heldFrets[i] || heldFretsAlt[i]) { - DrawModel(assets.smasherPressed, Vector3{ diffDistance - (float)(i), 0.01f, smasherPos }, 1.0f, WHITE); - } - else { - DrawModel(assets.smasherReg, Vector3{ diffDistance - (float)(i), 0.01f, smasherPos }, 1.0f, WHITE); } } - for (int i = 0; i < 4; i++) { - float radius = (i == (settings.mirrorMode?2:1)) ? 0.05 : 0.02; + for (int i = curBPM; i < songList.songs[curPlayingSong].bpms.size(); i++) { + if (musicTime > songList.songs[curPlayingSong].bpms[i].time && i < songList.songs[curPlayingSong].bpms.size() - 1) + curBPM++; + } - DrawCylinderEx(Vector3{ lineDistance - i, 0, smasherPos + 0.5f }, Vector3{ lineDistance - i, 0, 20 }, radius, radius, 15, Color{ 128,128,128,128 }); + if (musicTime < 5.0) { + DrawTextRubik(songList.songs[curPlayingSong].title.c_str(), 5, 65, 30, WHITE); + DrawTextRubik(songList.songs[curPlayingSong].artist.c_str(), 5, 100, 24, WHITE); } - DrawModel(assets.smasherBoard, Vector3{ 0, 0.001f, 0 }, 1.04f, WHITE); - } - else { - DrawModel(assets.emhHighway, Vector3{ 0, 0, 0 }, 1.0f, WHITE); - for (int i = 0; i < 4; i++) { - if (heldFrets[i] || heldFretsAlt[i]) { - DrawModel(assets.smasherPressed, Vector3{ diffDistance - (float)(i), 0, smasherPos }, 1.0f, WHITE); + BeginMode3D(camera); + if (diff == 3) { + DrawModel(assets.expertHighway, Vector3{ 0,0,0 }, 1.0f, WHITE); + for (int i = 0; i < 5; i++) { + if (heldFrets[i] || heldFretsAlt[i]) { + DrawModel(assets.smasherPressed, Vector3{ diffDistance - (float)(i), 0.01f, smasherPos }, 1.0f, WHITE); + } + else { + DrawModel(assets.smasherReg, Vector3{ diffDistance - (float)(i), 0.01f, smasherPos }, 1.0f, WHITE); + } } - else { - DrawModel(assets.smasherReg, Vector3{ diffDistance - (float)(i), 0, smasherPos }, 1.0f, WHITE); + for (int i = 0; i < 4; i++) { + float radius = (i == (settings.mirrorMode ? 2 : 1)) ? 0.05 : 0.02; + DrawCylinderEx(Vector3{ lineDistance - i, 0, smasherPos + 0.5f }, Vector3{ lineDistance - i, 0, 20 }, radius, radius, 15, Color{ 128,128,128,128 }); } + + DrawModel(assets.smasherBoard, Vector3{ 0, 0.001f, 0 }, 1.04f, WHITE); } - for (int i = 0; i < 3; i++) { - float radius = (i == 1) ? 0.03 : 0.01; - DrawCylinderEx(Vector3{ lineDistance - (float)i, 0, smasherPos }, Vector3{ lineDistance - (float)i, 0, highwayLength }, radius, - radius, 4.0f, Color{ 128, 128, 128, 128 }); - } - DrawModel(assets.smasherBoard, Vector3{ 0, 0.001f, 0 }, 1.04f, WHITE); - } - if (songList.songs[curPlayingSong].beatLines.size() >= 0) { - for (int i = curBeatLine; i < songList.songs[curPlayingSong].beatLines.size(); i++) { - if (songList.songs[curPlayingSong].beatLines[i].first >= songList.songs[curPlayingSong].music_start && songList.songs[curPlayingSong].beatLines[i].first <= songList.songs[curPlayingSong].end) { - double relTime = ((songList.songs[curPlayingSong].beatLines[i].first - musicTime) + VideoOffset) * settings.trackSpeedOptions[settings.trackSpeed]; - if (relTime > 1.5) break; - float radius = songList.songs[curPlayingSong].beatLines[i].second ? 0.03f : 0.0075f; - DrawCylinderEx(Vector3{ -diffDistance - 0.5f,0,smasherPos + (highwayLength * (float)relTime) }, Vector3{ diffDistance + 0.5f,0,smasherPos + (highwayLength * (float)relTime) }, radius, radius, 4, Color{ 128,128,128,128 }); - if (relTime < -1 && curBeatLine < songList.songs[curPlayingSong].beatLines.size() - 1) { - curBeatLine++; + else { + DrawModel(assets.emhHighway, Vector3{ 0, 0, 0 }, 1.0f, WHITE); + for (int i = 0; i < 4; i++) { + if (heldFrets[i] || heldFretsAlt[i]) { + DrawModel(assets.smasherPressed, Vector3{ diffDistance - (float)(i), 0, smasherPos }, 1.0f, WHITE); + } + else { + DrawModel(assets.smasherReg, Vector3{ diffDistance - (float)(i), 0, smasherPos }, 1.0f, WHITE); } } + for (int i = 0; i < 3; i++) { + float radius = (i == 1) ? 0.03 : 0.01; + DrawCylinderEx(Vector3{ lineDistance - (float)i, 0, smasherPos }, Vector3{ lineDistance - (float)i, 0, highwayLength }, radius, + radius, 4.0f, Color{ 128, 128, 128, 128 }); + } + DrawModel(assets.smasherBoard, Vector3{ 0, 0.001f, 0 }, 1.04f, WHITE); + } + if (songList.songs[curPlayingSong].beatLines.size() >= 0) { + for (int i = curBeatLine; i < songList.songs[curPlayingSong].beatLines.size(); i++) { + if (songList.songs[curPlayingSong].beatLines[i].first >= songList.songs[curPlayingSong].music_start && songList.songs[curPlayingSong].beatLines[i].first <= songList.songs[curPlayingSong].end) { + double relTime = ((songList.songs[curPlayingSong].beatLines[i].first - musicTime) + VideoOffset) * settings.trackSpeedOptions[settings.trackSpeed]; + if (relTime > 1.5) break; + float radius = songList.songs[curPlayingSong].beatLines[i].second ? 0.03f : 0.0075f; + DrawCylinderEx(Vector3{ -diffDistance - 0.5f,0,smasherPos + (highwayLength * (float)relTime) }, Vector3{ diffDistance + 0.5f,0,smasherPos + (highwayLength * (float)relTime) }, radius, radius, 4, Color{ 128,128,128,128 }); + if (relTime < -1 && curBeatLine < songList.songs[curPlayingSong].beatLines.size() - 1) { + curBeatLine++; + } + } + + } } - } - // DrawTriangle3D(Vector3{ 2.5f,0.0f,0.0f }, Vector3{ -2.5f,0.0f,0.0f }, Vector3{ -2.5f,0.0f,20.0f }, BLACK); - // DrawTriangle3D(Vector3{ 2.5f,0.0f,0.0f }, Vector3{ -2.5f,0.0f,20.0f }, Vector3{ 2.5f,0.0f,20.0f }, BLACK); + // DrawTriangle3D(Vector3{ 2.5f,0.0f,0.0f }, Vector3{ -2.5f,0.0f,0.0f }, Vector3{ -2.5f,0.0f,20.0f }, BLACK); + // DrawTriangle3D(Vector3{ 2.5f,0.0f,0.0f }, Vector3{ -2.5f,0.0f,20.0f }, Vector3{ 2.5f,0.0f,20.0f }, BLACK); - notes = songList.songs[curPlayingSong].parts[instrument]->charts[diff].notes.size(); - DrawModel(assets.odFrame, Vector3{ 0,1.0f,0 }, 0.75f, WHITE); - DrawModel(assets.odBar, Vector3{ 0,1.0f,0 }, 0.75f, WHITE); - DrawModel(assets.multFrame, Vector3{ 0,1.0f,0 }, 0.75f, WHITE); - DrawModel(assets.multBar, Vector3{ 0,1.0f,0 }, 0.75f, WHITE); - if (instrument == 1 || instrument == 3) { + notes = songList.songs[curPlayingSong].parts[instrument]->charts[diff].notes.size(); + DrawModel(assets.odFrame, Vector3{ 0,1.0f,0 }, 0.75f, WHITE); + DrawModel(assets.odBar, Vector3{ 0,1.0f,0 }, 0.75f, WHITE); + DrawModel(assets.multFrame, Vector3{ 0,1.0f,0 }, 0.75f, WHITE); + DrawModel(assets.multBar, Vector3{ 0,1.0f,0 }, 0.75f, WHITE); + if (instrument == 1 || instrument == 3) { - DrawModel(assets.multCtr5, Vector3{ 0,1.0f,0 }, 0.75f, WHITE); - } - else { + DrawModel(assets.multCtr5, Vector3{ 0,1.0f,0 }, 0.75f, WHITE); + } + else { - DrawModel(assets.multCtr3, Vector3{ 0,1.0f,0 }, 0.75f, WHITE); - } - DrawModel(assets.multNumber, Vector3{ 0,1.0f,0 }, 0.75f, WHITE); + DrawModel(assets.multCtr3, Vector3{ 0,1.0f,0 }, 0.75f, WHITE); + } + DrawModel(assets.multNumber, Vector3{ 0,1.0f,0 }, 0.75f, WHITE); - // DrawLine3D(Vector3{ 2.5f, 0.05f, 2.0f }, Vector3{ -2.5f, 0.05f, 2.0f}, WHITE); - Chart& curChart = songList.songs[curPlayingSong].parts[instrument]->charts[diff]; - if (curChart.odPhrases.size() > 0 && curODPhrase < curChart.odPhrases.size()) { - if (curChart.notes[curNoteIdx].time + curChart.notes[curNoteIdx].len > curChart.odPhrases[curODPhrase].end && curODPhrase < curChart.odPhrases.size() - 1) curODPhrase++; - } - for (int i = curNoteIdx; i < curChart.notes.size(); i++) { - Note& curNote = curChart.notes[i]; - - if (curChart.odPhrases.size() > 0) { - if (curNote.time >= curChart.odPhrases[curODPhrase].start && curNote.time <= curChart.odPhrases[curODPhrase].end && !curChart.odPhrases[curODPhrase].missed) { - if (curNote.miss) { - curChart.odPhrases[curODPhrase].missed = true; + // DrawLine3D(Vector3{ 2.5f, 0.05f, 2.0f }, Vector3{ -2.5f, 0.05f, 2.0f}, WHITE); + Chart& curChart = songList.songs[curPlayingSong].parts[instrument]->charts[diff]; + if (curChart.odPhrases.size() > 0 && curODPhrase < curChart.odPhrases.size()) { + if (curChart.notes[curNoteIdx].time + curChart.notes[curNoteIdx].len > curChart.odPhrases[curODPhrase].end && curODPhrase < curChart.odPhrases.size() - 1) curODPhrase++; + } + for (int i = curNoteIdx; i < curChart.notes.size(); i++) { + Note& curNote = curChart.notes[i]; + + if (curChart.odPhrases.size() > 0) { + if (curNote.time >= curChart.odPhrases[curODPhrase].start && curNote.time <= curChart.odPhrases[curODPhrase].end && !curChart.odPhrases[curODPhrase].missed) { + if (curNote.miss) { + curChart.odPhrases[curODPhrase].missed = true; + } + else { + if (curNote.hit && !curNote.countedForODPhrase) { + curChart.odPhrases[curODPhrase].notesHit++; + curNote.countedForODPhrase = true; + } + } + curNote.renderAsOD = true; } - else { - if (curNote.hit && !curNote.countedForODPhrase) { - curChart.odPhrases[curODPhrase].notesHit++; - curNote.countedForODPhrase = true; + if (curChart.odPhrases[curODPhrase].notesHit == curChart.odPhrases[curODPhrase].noteCount && !curChart.odPhrases[curODPhrase].added && overdriveFill < 1.0f) { + overdriveFill += 0.25f; + if (overdriveFill > 1.0f) overdriveFill = 1.0f; + if (overdrive) { + overdriveActiveFill = overdriveFill; + overdriveActiveTime = musicTime; } + curChart.odPhrases[curODPhrase].added = true; } - curNote.renderAsOD = true; } - if (curChart.odPhrases[curODPhrase].notesHit == curChart.odPhrases[curODPhrase].noteCount && !curChart.odPhrases[curODPhrase].added && overdriveFill < 1.0f) { - overdriveFill += 0.25f; - if (overdriveFill > 1.0f) overdriveFill = 1.0f; - if (overdrive) { - overdriveActiveFill = overdriveFill; - overdriveActiveTime = musicTime; + if (!curNote.hit && !curNote.accounted && curNote.time + 0.1 < musicTime) { + curNote.miss = true; + player::MissNote(); + if (curChart.odPhrases.size() > 0) { + curChart.odPhrases[curODPhrase].missed = true; } - curChart.odPhrases[curODPhrase].added = true; + curNote.accounted = true; } - } - if (!curNote.hit && !curNote.accounted && curNote.time + 0.1 < musicTime) { - curNote.miss = true; - player::MissNote(); - if (curChart.odPhrases.size() > 0) { - curChart.odPhrases[curODPhrase].missed = true; - } - curNote.accounted = true; - } - double relTime = ((curNote.time - musicTime) + VideoOffset) * settings.trackSpeedOptions[settings.trackSpeed]; - double relEnd = (((curNote.time + curNote.len) - musicTime) + VideoOffset) * settings.trackSpeedOptions[settings.trackSpeed]; - float notePosX = diffDistance - (1.0f * (settings.mirrorMode ? (diff == 3 ? 4 : 3) - curNote.lane : curNote.lane)); - if (relTime > 1.5) { - break; - } - if (relEnd > 1.5) relEnd = 1.5; - if (curNote.lift && !curNote.hit) { - // lifts // distance between notes - // (furthest left - lane distance) - if (curNote.renderAsOD) // 1.6f 0.8 - DrawModel(assets.liftModelOD, Vector3{ notePosX,0,smasherPos + (highwayLength * (float)relTime) }, 1.1f, WHITE); - // energy phrase - else - DrawModel(assets.liftModel, Vector3{ notePosX,0,smasherPos + (highwayLength * (float)relTime) }, 1.1f, WHITE); - // regular - } - else { - // sustains - if ((curNote.len) > 0) { - if (curNote.hit && curNote.held) { - if (curNote.heldTime < (curNote.len * settings.trackSpeedOptions[settings.trackSpeed])) { - curNote.heldTime = 0.0 - relTime; - sustainScoreBuffer[curNote.lane] = (curNote.heldTime / curNote.len) * (12 * curNote.beatsLen) * multiplier(instrument); - if (relTime < 0.0) relTime = 0.0; + double relTime = ((curNote.time - musicTime) + VideoOffset) * settings.trackSpeedOptions[settings.trackSpeed]; + double relEnd = (((curNote.time + curNote.len) - musicTime) + VideoOffset) * settings.trackSpeedOptions[settings.trackSpeed]; + float notePosX = diffDistance - (1.0f * (settings.mirrorMode ? (diff == 3 ? 4 : 3) - curNote.lane : curNote.lane)); + if (relTime > 1.5) { + break; + } + if (relEnd > 1.5) relEnd = 1.5; + if (curNote.lift && !curNote.hit) { + // lifts // distance between notes + // (furthest left - lane distance) + if (curNote.renderAsOD) // 1.6f 0.8 + DrawModel(assets.liftModelOD, Vector3{ notePosX,0,smasherPos + (highwayLength * (float)relTime) }, 1.1f, WHITE); + // energy phrase + else + DrawModel(assets.liftModel, Vector3{ notePosX,0,smasherPos + (highwayLength * (float)relTime) }, 1.1f, WHITE); + // regular + } + else { + // sustains + if ((curNote.len) > 0) { + if (curNote.hit && curNote.held) { + if (curNote.heldTime < (curNote.len * settings.trackSpeedOptions[settings.trackSpeed])) { + curNote.heldTime = 0.0 - relTime; + sustainScoreBuffer[curNote.lane] = (curNote.heldTime / curNote.len) * (12 * curNote.beatsLen) * multiplier(instrument); + if (relTime < 0.0) relTime = 0.0; + } + if (relEnd <= 0.0) { + if (relTime < 0.0) relTime = relEnd; + score += sustainScoreBuffer[curNote.lane]; + sustainScoreBuffer[curNote.lane] = 0; + curNote.held = false; + } } - if (relEnd <= 0.0) { - if (relTime < 0.0) relTime = relEnd; - score += sustainScoreBuffer[curNote.lane]; - sustainScoreBuffer[curNote.lane] = 0; - curNote.held = false; + else if (curNote.hit && !curNote.held) { + relTime = relTime + curNote.heldTime; } - } - else if (curNote.hit && !curNote.held) { - relTime = relTime + curNote.heldTime; - } - /*Color SustainColor = Color{ 69,69,69,255 }; - if (curNote.held) { - if (od) { - Color SustainColor = Color{ 217, 183, 82 ,255 }; + /*Color SustainColor = Color{ 69,69,69,255 }; + if (curNote.held) { + if (od) { + Color SustainColor = Color{ 217, 183, 82 ,255 }; + } + Color SustainColor = Color{ 172,82,217,255 }; + }*/ + + if (curNote.held && !curNote.renderAsOD) { + DrawCylinderEx(Vector3{ notePosX, 0.05f, smasherPos + (highwayLength * (float)relTime) }, Vector3{ notePosX,0.05f, smasherPos + (highwayLength * (float)relEnd) }, 0.1f, 0.1f, 15, Color{ 230,100,230,255 }); + } + if (curNote.renderAsOD && curNote.held) { + DrawCylinderEx(Vector3{ notePosX, 0.05f, smasherPos + (highwayLength * (float)relTime) }, Vector3{ notePosX,0.05f, smasherPos + (highwayLength * (float)relEnd) }, 0.1f, 0.1f, 15, Color{ 255, 255, 180 ,255 }); + } + if (!curNote.held && curNote.hit || curNote.miss) { + DrawCylinderEx(Vector3{ notePosX, 0.05f, smasherPos + (highwayLength * (float)relTime) }, Vector3{ notePosX,0.05f, smasherPos + (highwayLength * (float)relEnd) }, 0.1f, 0.1f, 15, Color{ 69,69,69,255 }); + } + if (!curNote.hit && !curNote.accounted && !curNote.miss) { + if (curNote.renderAsOD) { + DrawCylinderEx(Vector3{ notePosX, 0.05f, smasherPos + (highwayLength * (float)relTime) }, Vector3{ notePosX,0.05f, smasherPos + (highwayLength * (float)relEnd) }, 0.1f, 0.1f, 15, Color{ 200, 170, 70 ,255 }); + } + else { + DrawCylinderEx(Vector3{ notePosX, 0.05f, + smasherPos + (highwayLength * (float)relTime) }, + Vector3{ notePosX, 0.05f, + smasherPos + (highwayLength * (float)relEnd) }, 0.1f, 0.1f, 15, + Color{ 150, 19, 150, 255 }); + } } - Color SustainColor = Color{ 172,82,217,255 }; - }*/ - if (curNote.held && !curNote.renderAsOD) { - DrawCylinderEx(Vector3{ notePosX, 0.05f, smasherPos + (highwayLength * (float)relTime) }, Vector3{ notePosX,0.05f, smasherPos + (highwayLength * (float)relEnd) }, 0.1f, 0.1f, 15, Color{ 230,100,230,255 }); - } - if (curNote.renderAsOD && curNote.held) { - DrawCylinderEx(Vector3{ notePosX, 0.05f, smasherPos + (highwayLength * (float)relTime) }, Vector3{ notePosX,0.05f, smasherPos + (highwayLength * (float)relEnd) }, 0.1f, 0.1f, 15, Color{ 255, 255, 180 ,255 }); - } - if (!curNote.held && curNote.hit || curNote.miss) { - DrawCylinderEx(Vector3{ notePosX, 0.05f, smasherPos + (highwayLength * (float)relTime) }, Vector3{ notePosX,0.05f, smasherPos + (highwayLength * (float)relEnd) }, 0.1f, 0.1f, 15, Color{ 69,69,69,255 }); + + // DrawLine3D(Vector3{ diffDistance - (1.0f * curNote.lane),0.05f,smasherPos + (12.5f * (float)relTime) }, Vector3{ diffDistance - (1.0f * curNote.lane),0.05f,smasherPos + (12.5f * (float)relEnd) }, Color{ 172,82,217,255 }); } - if (!curNote.hit && !curNote.accounted && !curNote.miss) { + // regular notes + if (((curNote.len) > 0 && (curNote.held || !curNote.hit)) || ((curNote.len) == 0 && !curNote.hit)) { if (curNote.renderAsOD) { - DrawCylinderEx(Vector3{ notePosX, 0.05f, smasherPos + (highwayLength * (float)relTime) }, Vector3{ notePosX,0.05f, smasherPos + (highwayLength * (float)relEnd) }, 0.1f, 0.1f, 15, Color{ 200, 170, 70 ,255 }); + if ((!curNote.held && !curNote.miss) || !curNote.hit) { + DrawModel(assets.noteModelOD, Vector3{ notePosX,0,smasherPos + (highwayLength * (float)relTime) }, 1.1f, WHITE); + }; + } else { - DrawCylinderEx(Vector3{ notePosX, 0.05f, - smasherPos + (highwayLength * (float)relTime) }, - Vector3{ notePosX, 0.05f, - smasherPos + (highwayLength * (float)relEnd) }, 0.1f, 0.1f, 15, - Color{ 150, 19, 150, 255 }); - } - } + if ((!curNote.held && !curNote.miss) || !curNote.hit) { + DrawModel(assets.noteModel, Vector3{ notePosX,0,smasherPos + (highwayLength * (float)relTime) }, 1.1f, WHITE); + }; + } - // DrawLine3D(Vector3{ diffDistance - (1.0f * curNote.lane),0.05f,smasherPos + (12.5f * (float)relTime) }, Vector3{ diffDistance - (1.0f * curNote.lane),0.05f,smasherPos + (12.5f * (float)relEnd) }, Color{ 172,82,217,255 }); + } } - // regular notes - if (((curNote.len) > 0 && (curNote.held || !curNote.hit)) || ((curNote.len) == 0 && !curNote.hit)) { - if (curNote.renderAsOD) { - if ((!curNote.held && !curNote.miss) || !curNote.hit) { - DrawModel(assets.noteModelOD, Vector3{ notePosX,0,smasherPos + (highwayLength * (float)relTime) }, 1.1f, WHITE); - }; - + if (curNote.miss) { + DrawModel(curNote.lift ? assets.liftModel : assets.noteModel, Vector3{ notePosX,0,smasherPos + (highwayLength * (float)relTime) }, 1.0f, RED); + if (GetMusicTimePlayed(loadedStreams[0].first) < curNote.time + 0.4 && MissHighwayColor) { + assets.expertHighway.materials[0].maps[MATERIAL_MAP_ALBEDO].color = RED; } else { - if ((!curNote.held && !curNote.miss) || !curNote.hit) { - DrawModel(assets.noteModel, Vector3{ notePosX,0,smasherPos + (highwayLength * (float)relTime) }, 1.1f, WHITE); - }; - + assets.expertHighway.materials[0].maps[MATERIAL_MAP_ALBEDO].color = WHITE; } + } + if (curNote.hit && GetMusicTimePlayed(loadedStreams[0].first) < curNote.hitTime + 0.15f) { + DrawCube(Vector3{ notePosX, 0, smasherPos }, 1.0f, 0.5f, 0.5f, curNote.perfect ? Color{ 255,215,0,64 } : Color{ 255,255,255,64 }); + if (curNote.perfect) { + DrawCube(Vector3{ 3.25, 0, smasherPos }, 1.0f, 0.01f, 0.5f, ORANGE); + } } - } - if (curNote.miss) { - DrawModel(curNote.lift ? assets.liftModel : assets.noteModel, Vector3{ notePosX,0,smasherPos + (highwayLength * (float)relTime) }, 1.0f, RED); - if (GetMusicTimePlayed(loadedStreams[0].first) < curNote.time + 0.4 && MissHighwayColor) { - assets.expertHighway.materials[0].maps[MATERIAL_MAP_ALBEDO].color = RED; - } else { - assets.expertHighway.materials[0].maps[MATERIAL_MAP_ALBEDO].color = WHITE; - } - } - if (curNote.hit && GetMusicTimePlayed(loadedStreams[0].first) < curNote.hitTime + 0.15f) { - DrawCube(Vector3{ notePosX, 0, smasherPos }, 1.0f, 0.5f, 0.5f, curNote.perfect ? Color{ 255,215,0,64 } : Color{ 255,255,255,64 }); - if (curNote.perfect) { - DrawCube(Vector3{ 3.25, 0, smasherPos }, 1.0f, 0.01f, 0.5f, ORANGE); - - } - } - if (relEnd < -1 && curNoteIdx < curChart.notes.size() - 1) curNoteIdx = i + 1; + if (relEnd < -1 && curNoteIdx < curChart.notes.size() - 1) curNoteIdx = i + 1; + } + #ifndef NDEBUG + // DrawTriangle3D(Vector3{ -diffDistance - 0.5f,0.05f,smasherPos + (highwayLength * goodFrontend * trackSpeed[speedSelection]) }, Vector3{ diffDistance + 0.5f,0.05f,smasherPos + (highwayLength * goodFrontend * trackSpeed[speedSelection]) }, Vector3{ diffDistance + 0.5f,0.05f,smasherPos - (highwayLength * goodBackend * trackSpeed[speedSelection]) }, Color{ 0,255,0,80 }); + // DrawTriangle3D(Vector3{ diffDistance + 0.5f,0.05f,smasherPos - (highwayLength * goodBackend * trackSpeed[speedSelection]) }, Vector3{ -diffDistance - 0.5f,0.05f,smasherPos - (highwayLength * goodBackend * trackSpeed[speedSelection]) }, Vector3{ -diffDistance - 0.5f,0.05f,smasherPos + (highwayLength * goodFrontend * trackSpeed[speedSelection]) }, Color{ 0,255,0,80 }); + + // DrawTriangle3D(Vector3{ -diffDistance - 0.5f,0.05f,smasherPos + (highwayLength * perfectFrontend * trackSpeed[speedSelection]) }, Vector3{ diffDistance + 0.5f,0.05f,smasherPos + (highwayLength * perfectFrontend * trackSpeed[speedSelection]) }, Vector3{ diffDistance + 0.5f,0.05f,smasherPos - (highwayLength * perfectBackend * trackSpeed[speedSelection]) }, Color{ 190,255,0,80 }); + // DrawTriangle3D(Vector3{ diffDistance + 0.5f,0.05f,smasherPos - (highwayLength * perfectBackend * trackSpeed[speedSelection]) }, Vector3{ -diffDistance - 0.5f,0.05f,smasherPos - (highwayLength * perfectBackend * trackSpeed[speedSelection]) }, Vector3{ -diffDistance - 0.5f,0.05f,smasherPos + (highwayLength * perfectFrontend * trackSpeed[speedSelection]) }, Color{ 190,255,0,80 }); + #endif + EndMode3D(); + break; + } + case RESULTS: { + int starsval = stars(songList.songs[curPlayingSong].parts[instrument]->charts[diff].baseScore); + char* starsDisplay = (char*)""; + if (starsval == 5) { + starsDisplay = (char*)"*****"; + } + else if (starsval == 4) { + starsDisplay = (char*)"****"; + } + else if (starsval == 3) { + starsDisplay = (char*)"***"; + } + else if (starsval == 2) { + starsDisplay = (char*)"**"; + } + else if (starsval == 1) { + starsDisplay = (char*)"*";; + } + else { + starsDisplay = (char*)""; + } + DrawTextRubik("Results", GetScreenWidth() / 2 - (MeasureTextRubik("Results", 36) / 2), 0, 36, WHITE); + DrawTextRubik((songList.songs[curPlayingSong].artist + " - " + songList.songs[curPlayingSong].title).c_str(), GetScreenWidth() / 2 - (MeasureTextRubik((songList.songs[curPlayingSong].artist + " - " + songList.songs[curPlayingSong].title).c_str(), 24) / 2), 48, 24, WHITE); + if (FC) { + DrawTextRubik("Flawless!", GetScreenWidth() / 2 - (MeasureTextRubik("Flawless!", 24) / 2), 84, 24, GOLD); + } + DrawTextRubik(TextFormat("%01i", score), (GetScreenWidth() / 2 - MeasureTextRubik(TextFormat("%01i", score), 24) / 2), 128, 24, WHITE); + DrawTextRubik(TextFormat("%s", starsDisplay), (GetScreenWidth() / 2 - MeasureTextRubik(TextFormat("%s", starsDisplay), 24) / 2), 160, 24, goldStars ? GOLD : WHITE); + DrawTextRubik(TextFormat("Perfect Notes : %01i/%02i", perfectHit, songList.songs[curPlayingSong].parts[instrument]->charts[diff].notes.size()), (GetScreenWidth() / 2 - MeasureTextRubik(TextFormat("Perfect Notes: %01i/%02i", perfectHit, songList.songs[curPlayingSong].parts[instrument]->charts[diff].notes.size()), 24) / 2), 192, 24, WHITE); + DrawTextRubik(TextFormat("Good Notes : %01i/%02i", notesHit - perfectHit, songList.songs[curPlayingSong].parts[instrument]->charts[diff].notes.size()), (GetScreenWidth() / 2 - MeasureTextRubik(TextFormat("Good Notes: %01i/%02i", notesHit - perfectHit, songList.songs[curPlayingSong].parts[instrument]->charts[diff].notes.size()), 24) / 2), 224, 24, WHITE); + DrawTextRubik(TextFormat("Missed Notes: %01i/%02i", notesMissed, songList.songs[curPlayingSong].parts[instrument]->charts[diff].notes.size()), (GetScreenWidth() / 2 - MeasureTextRubik(TextFormat("Missed Notes: %01i/%02i", notesMissed, songList.songs[curPlayingSong].parts[instrument]->charts[diff].notes.size()), 24) / 2), 256, 24, WHITE); + DrawTextRubik(TextFormat("Strikes: %01i", playerOverhits), (GetScreenWidth() / 2 - MeasureTextRubik(TextFormat("Strikes: %01i", playerOverhits), 24) / 2), 288, 24, WHITE); + DrawTextRubik(TextFormat("Longest Streak: %01i", maxCombo), (GetScreenWidth() / 2 - MeasureTextRubik(TextFormat("Longest Streak: %01i", maxCombo), 24) / 2), 320, 24, WHITE); + if (GuiButton({ 0,0,60,60 }, "<")) { + currentScreen = SONG_SELECT; + } + break; } -#ifndef NDEBUG - // DrawTriangle3D(Vector3{ -diffDistance - 0.5f,0.05f,smasherPos + (highwayLength * goodFrontend * trackSpeed[speedSelection]) }, Vector3{ diffDistance + 0.5f,0.05f,smasherPos + (highwayLength * goodFrontend * trackSpeed[speedSelection]) }, Vector3{ diffDistance + 0.5f,0.05f,smasherPos - (highwayLength * goodBackend * trackSpeed[speedSelection]) }, Color{ 0,255,0,80 }); - // DrawTriangle3D(Vector3{ diffDistance + 0.5f,0.05f,smasherPos - (highwayLength * goodBackend * trackSpeed[speedSelection]) }, Vector3{ -diffDistance - 0.5f,0.05f,smasherPos - (highwayLength * goodBackend * trackSpeed[speedSelection]) }, Vector3{ -diffDistance - 0.5f,0.05f,smasherPos + (highwayLength * goodFrontend * trackSpeed[speedSelection]) }, Color{ 0,255,0,80 }); - - // DrawTriangle3D(Vector3{ -diffDistance - 0.5f,0.05f,smasherPos + (highwayLength * perfectFrontend * trackSpeed[speedSelection]) }, Vector3{ diffDistance + 0.5f,0.05f,smasherPos + (highwayLength * perfectFrontend * trackSpeed[speedSelection]) }, Vector3{ diffDistance + 0.5f,0.05f,smasherPos - (highwayLength * perfectBackend * trackSpeed[speedSelection]) }, Color{ 190,255,0,80 }); - // DrawTriangle3D(Vector3{ diffDistance + 0.5f,0.05f,smasherPos - (highwayLength * perfectBackend * trackSpeed[speedSelection]) }, Vector3{ -diffDistance - 0.5f,0.05f,smasherPos - (highwayLength * perfectBackend * trackSpeed[speedSelection]) }, Vector3{ -diffDistance - 0.5f,0.05f,smasherPos + (highwayLength * perfectFrontend * trackSpeed[speedSelection]) }, Color{ 190,255,0,80 }); -#endif - EndMode3D(); - - - - DrawFPS(5, 60); } - - EndDrawing(); //SwapScreenBuffer();