Skip to content

Commit

Permalink
Add new timer window and display options
Browse files Browse the repository at this point in the history
  • Loading branch information
Caladius committed Nov 18, 2024
1 parent 53e2fe4 commit 02a48c7
Show file tree
Hide file tree
Showing 4 changed files with 209 additions and 0 deletions.
134 changes: 134 additions & 0 deletions soh/soh/Enhancements/TimeDisplay/TimeDisplay.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
#include "TimeDisplay.h"
#include "soh/Enhancements/gameplaystats.h"
#include <global.h>

extern "C" {
#include "macros.h"
#include "functions.h"
#include "variables.h"
extern PlayState* gPlayState;
uint64_t GetUnixTimestamp();
}

float fontScale = 1.0f;
ImVec4 windowBG = ImVec4(0, 0, 0, 0.5f);

std::vector<TimeObject> timeDisplayList = {
{ DISPLAY_IN_GAME_TIMER, "Gameplay Time", CVAR_ENHANCEMENT("TimeDisplay.Timers.InGameTimer"), CVAR_ENHANCEMENT("TimeDisplay.Label.InGameTimer") },
{ DISPLAY_TIME_OF_DAY, "Time of Day", CVAR_ENHANCEMENT("TimeDisplay.Timers.TimeofDay"), CVAR_ENHANCEMENT("TimeDisplay.Label.TimeofDay") }
};

std::vector<TimeObject> activeTimers;

std::string convertDayTime(uint32_t dayTime) {
uint32_t totalSeconds = 24 * 60 * 60;
uint32_t ss = static_cast<uint32_t>(static_cast<double>(dayTime) * (totalSeconds - 1) / 65535);
uint32_t hh = ss / 3600;
uint32_t mm = (ss % 3600) / 60;
return fmt::format("{:0>2}:{:0>2}", hh, mm);
}

std::string formatTimeDisplay(uint32_t value) {
uint32_t sec = value / 10;
uint32_t hh = sec / 3600;
uint32_t mm = (sec - hh * 3600) / 60;
uint32_t ss = sec - hh * 3600 - mm * 60;
uint32_t ds = value % 10;
return fmt::format("{}:{:0>2}:{:0>2}.{}", hh, mm, ss, ds);
}

std::string timeDisplayGetTime(uint32_t timeID) {
std::string timeDisplayTime;
switch (timeID) {
case DISPLAY_IN_GAME_TIMER:
timeDisplayTime = formatTimeDisplay(GAMEPLAYSTAT_TOTAL_TIME).c_str();
break;
case DISPLAY_TIME_OF_DAY:
timeDisplayTime = convertDayTime(gSaveContext.dayTime).c_str();
break;
default:
break;
}
return timeDisplayTime;
}

void TimeDisplayUpdateDisplayOptions(uint32_t timeID, bool pushBack) {
if (pushBack) {
activeTimers.push_back(timeDisplayList[timeID]);
} else {
uint32_t index = 0;
for (auto& check : activeTimers) {
if (check.timeID == timeID) {
activeTimers.erase(activeTimers.begin() + index);
return;
}
index++;
}
}
}

void TimeDisplayWindow::Draw() {
if (!CVarGetInteger(CVAR_WINDOW("TimeDisplayEnabled"), 0)) {
return;
}
ImGui::PushStyleColor(ImGuiCol_WindowBg, windowBG);
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 4.0f);

ImGui::Begin("TimerDisplay", nullptr, ImGuiWindowFlags_AlwaysAutoResize |
ImGuiWindowFlags_NoNav |
ImGuiWindowFlags_NoFocusOnAppearing |
ImGuiWindowFlags_NoResize |
ImGuiWindowFlags_NoDocking |
ImGuiWindowFlags_NoTitleBar |
ImGuiWindowFlags_NoScrollWithMouse |
ImGuiWindowFlags_NoScrollbar);

if (activeTimers.size() == 0) {
ImGui::Text("No Enabled Timers...");
} else {
ImGui::SetWindowFontScale(fontScale);
ImGui::BeginTable("Timer List", 2);
for (auto& timers : activeTimers) {
ImGui::PushID(timers.timeID);
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
if (CVarGetInteger(timers.timeLabel, 0)) {
ImGui::Text(timers.timeName.c_str());
ImGui::TableNextColumn();
}
ImGui::Text(timeDisplayGetTime(timers.timeID).c_str());
ImGui::PopID();
}
ImGui::EndTable();
}
ImGui::End();

ImGui::PopStyleColor(2);
ImGui::PopStyleVar(1);
}

void TimeDisplayInitSettings() {
fontScale = CVarGetFloat(CVAR_ENHANCEMENT("TimeDisplay.FontScale"), 1.0f);
if (fontScale < 1.0f) {
fontScale = 1.0f;
}
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeDisplay.ShowWindowBG"), 0)) {
windowBG = ImVec4(0, 0, 0, 0);
} else {
windowBG = ImVec4(0, 0, 0, 0.5f);
}
}

void TimeDisplayInitTimers() {
for (auto& update : timeDisplayList) {
if (CVarGetInteger(update.timeEnable, 0)) {
activeTimers.push_back(update);
}
}
}

void TimeDisplayWindow::InitElement() {
TimeDisplayInitSettings();
TimeDisplayInitTimers();
}
26 changes: 26 additions & 0 deletions soh/soh/Enhancements/TimeDisplay/TimeDisplay.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include <libultraship/libultraship.h>

class TimeDisplayWindow : public Ship::GuiWindow {
public:
using GuiWindow::GuiWindow;

void InitElement() override;
void DrawElement() override {};
void Draw() override;
void UpdateElement() override {};
};

void TimeDisplayUpdateDisplayOptions(uint32_t timeID, bool pushBack);
void TimeDisplayInitSettings();

typedef enum {
DISPLAY_IN_GAME_TIMER,
DISPLAY_TIME_OF_DAY
};

typedef struct {
uint32_t timeID;
std::string timeName;
const char* timeEnable;
const char* timeLabel;
} TimeObject;
5 changes: 5 additions & 0 deletions soh/soh/SohGui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "Enhancements/resolution-editor/ResolutionEditor.h"
#include "Enhancements/debugger/MessageViewer.h"
#include "soh/Notification/Notification.h"
#include "soh/Enhancements/TimeDisplay/TimeDisplay.h"

bool isBetaQuestEnabled = false;

Expand Down Expand Up @@ -135,6 +136,7 @@ namespace SohGui {
std::shared_ptr<AdvancedResolutionSettings::AdvancedResolutionSettingsWindow> mAdvancedResolutionSettingsWindow;
std::shared_ptr<SohModalWindow> mModalWindow;
std::shared_ptr<Notification::Window> mNotificationWindow;
std::shared_ptr<TimeDisplayWindow> mTimeDisplayWindow;

void SetupGuiElements() {
auto gui = Ship::Context::GetInstance()->GetWindow()->GetGui();
Expand Down Expand Up @@ -218,6 +220,8 @@ namespace SohGui {
mNotificationWindow = std::make_shared<Notification::Window>(CVAR_WINDOW("Notifications"), "Notifications Window");
gui->AddGuiWindow(mNotificationWindow);
mNotificationWindow->Show();
mTimeDisplayWindow = std::make_shared<TimeDisplayWindow>(CVAR_WINDOW("TimeDisplayEnabled"), "Additional Timers");
gui->AddGuiWindow(mTimeDisplayWindow);
}

void Destroy() {
Expand Down Expand Up @@ -252,6 +256,7 @@ namespace SohGui {
mInputViewer = nullptr;
mInputViewerSettings = nullptr;
mTimeSplitWindow = nullptr;
mTimeDisplayWindow = nullptr;
}

void RegisterPopup(std::string title, std::string message, std::string button1, std::string button2, std::function<void()> button1callback, std::function<void()> button2callback) {
Expand Down
44 changes: 44 additions & 0 deletions soh/soh/SohMenuBar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include "Enhancements/resolution-editor/ResolutionEditor.h"
#include "Enhancements/enemyrandomizer.h"
#include "Enhancements/timesplits/TimeSplits.h"
#include "Enhancements/TimeDisplay/TimeDisplay.h"

// FA icons are kind of wonky, if they worked how I expected them to the "+ 2.0f" wouldn't be needed, but
// they don't work how I expect them to so I added that because it looked good when I eyeballed it
Expand Down Expand Up @@ -603,6 +604,7 @@ extern std::shared_ptr<AudioEditor> mAudioEditorWindow;
extern std::shared_ptr<CosmeticsEditorWindow> mCosmeticsEditorWindow;
extern std::shared_ptr<GameplayStatsWindow> mGameplayStatsWindow;
extern std::shared_ptr<TimeSplitWindow> mTimeSplitWindow;
extern std::shared_ptr<TimeDisplayWindow> mTimeDisplayWindow;

void DrawEnhancementsMenu() {
if (ImGui::BeginMenu("Enhancements"))
Expand Down Expand Up @@ -1689,6 +1691,48 @@ void DrawEnhancementsMenu() {
mTimeSplitWindow->ToggleVisibility();
}
}

if (mTimeDisplayWindow) {
if (ImGui::Button(GetWindowButtonText("Additional Timers", CVarGetInteger(CVAR_WINDOW("TimeDisplayEnabled"), 0)).c_str(), ImVec2(-1.0f, 0.0f))) {
mTimeDisplayWindow->ToggleVisibility();
}
}
if (mTimeDisplayWindow->IsVisible()) {
ImGui::SeparatorText("Timer Display Options");
ImGui::Text("Font Scale");
ImGui::SetNextItemWidth(150.0f);
if (UIWidgets::PaddedEnhancementSliderFloat("", "##TimeDisplayScale", CVAR_ENHANCEMENT("TimeDisplay.FontScale"),
1.0f, 5.0f, "%.2fx", 1.0f, false, true, false, false)) {
TimeDisplayInitSettings();
}
if (UIWidgets::PaddedEnhancementCheckbox("Hide Background", CVAR_ENHANCEMENT("TimeDisplay.ShowWindowBG"),
false, false)) {
TimeDisplayInitSettings();
}
ImGui::Separator();
if (UIWidgets::PaddedEnhancementCheckbox("Display Gameplay Timer", CVAR_ENHANCEMENT("TimeDisplay.Timers.InGameTimer"),
false, false)) {
TimeDisplayUpdateDisplayOptions(DISPLAY_IN_GAME_TIMER, CVarGetInteger(CVAR_ENHANCEMENT("TimeDisplay.Timers.InGameTimer"), 0));
}
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeDisplay.Timers.InGameTimer"), 0)) {
ImGui::PushID(DISPLAY_IN_GAME_TIMER);
UIWidgets::PaddedEnhancementCheckbox("Display Label", CVAR_ENHANCEMENT("TimeDisplay.Label.InGameTimer"),
false, false);
ImGui::Separator();
ImGui::PopID();
}
if (UIWidgets::PaddedEnhancementCheckbox("Display Time of Day", CVAR_ENHANCEMENT("TimeDisplay.Timers.TimeofDay"),
false, false)) {
TimeDisplayUpdateDisplayOptions(DISPLAY_TIME_OF_DAY, CVarGetInteger(CVAR_ENHANCEMENT("TimeDisplay.Timers.TimeofDay"), 0));
}
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeDisplay.Timers.TimeofDay"), 0)) {
ImGui::PushID(DISPLAY_TIME_OF_DAY);
UIWidgets::PaddedEnhancementCheckbox("Display Label", CVAR_ENHANCEMENT("TimeDisplay.Label.TimeofDay"),
false, false);
ImGui::Separator();
ImGui::PopID();
}
}
ImGui::PopStyleVar(3);
ImGui::PopStyleColor(1);

Expand Down

0 comments on commit 02a48c7

Please sign in to comment.