Normalized imgui and added texture filter (#271)

* Normalized imgui and added texture filter and fixed develop

* Fixed incorrect separator title
This commit is contained in:
KiritoDev 2022-05-11 09:59:56 -05:00 committed by GitHub
parent 091983b3e3
commit 2e1a0b5144
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 221 additions and 182 deletions

View File

@ -10,13 +10,12 @@
#include "Cvar.h"
#include "GlobalCtx2.h"
#include "SohImGuiImpl.h"
#include "stox.h"
#include "../../soh/include/z64audio.h"
#include <string>
#include "SohHooks.h"
#include "../../soh/soh/Enhancements/debugconsole.h"
#include "Window.h"
#include "Lib/Fast3D/gfx_rendering_api.h"
#define ABS(var) var < 0 ? -(var) : var
@ -25,14 +24,6 @@ using namespace Ship;
namespace Game {
bool DeSyncAudio = false;
SoHConfigType Settings;
const std::string ConfSection = DEBUG_SECTION;
const std::string AudioSection = AUDIO_SECTION;
const std::string ControllerSection = CONTROLLER_SECTION;
const std::string EnhancementSection = ENHANCEMENTS_SECTION;
const std::string CosmeticsSection = COSMETICS_SECTION;
const std::string CheatSection = CHEATS_SECTION;
const std::string LanguagesSection = LANGUAGES_SECTION;
void UpdateAudio() {
Audio_SetGameVolume(SEQ_BGM_MAIN, CVar_GetFloat("gMainMusicVolume", 1));
@ -41,18 +32,6 @@ namespace Game {
Audio_SetGameVolume(SEQ_SFX, CVar_GetFloat("gFanfareVolume", 1));
}
void LoadSettings() {
const std::shared_ptr<ConfigFile> pConf = GlobalCtx2::GetInstance()->GetConfig();
ConfigFile& Conf = *pConf;
// Debug
SohImGui::console->opened = stob(Conf[ConfSection]["console"]);
Settings.debug.menu_bar = stob(Conf[ConfSection]["menu_bar"]);
Settings.debug.soh = stob(Conf[ConfSection]["soh_debug"]);
UpdateAudio();
}
void LoadPadSettings() {
const std::shared_ptr<ConfigFile> pConf = GlobalCtx2::GetInstance()->GetConfig();
ConfigFile& Conf = *pConf;
@ -65,16 +44,11 @@ namespace Game {
}
}
void LoadSettings() {
DebugConsole_LoadCVars();
}
void SaveSettings() {
const std::shared_ptr<ConfigFile> pConf = GlobalCtx2::GetInstance()->GetConfig();
ConfigFile& Conf = *pConf;
// Debug
Conf[ConfSection]["console"] = std::to_string(SohImGui::console->opened);
Conf[ConfSection]["menu_bar"] = std::to_string(Settings.debug.menu_bar);
Conf[ConfSection]["soh_debug"] = std::to_string(Settings.debug.soh);
Conf.Save();
DebugConsole_SaveCVars();
}
@ -82,6 +56,11 @@ namespace Game {
ModInternal::registerHookListener({ AUDIO_INIT, [](HookEvent ev) {
UpdateAudio();
}});
ModInternal::registerHookListener({ GFX_INIT, [](HookEvent ev) {
gfx_get_current_rendering_api()->set_texture_filter((FilteringMode) CVar_GetS32("gTextureFilter", THREE_POINT));
SohImGui::console->opened = CVar_GetS32("gConsoleEnabled", 0);
UpdateAudio();
}});
}
void SetSeqPlayerVolume(SeqPlayers playerId, float volume) {

View File

@ -1,19 +1,5 @@
#pragma once
struct SoHConfigType {
// Debug
struct {
bool soh = false;
bool menu_bar = false;
bool soh_sink = true;
} debug;
// Graphics
struct {
bool show = false;
} graphics;
};
enum SeqPlayers {
/* 0 */ SEQ_BGM_MAIN,
/* 1 */ SEQ_FANFARE,
@ -22,16 +8,7 @@ enum SeqPlayers {
/* 4 */ SEQ_MAX
};
#define DEBUG_SECTION "DEBUG SETTINGS"
#define AUDIO_SECTION "AUDIO SETTINGS"
#define CONTROLLER_SECTION "CONTROLLER SECTION"
#define ENHANCEMENTS_SECTION "ENHANCEMENT SETTINGS"
#define COSMETICS_SECTION "COSMETIC SETTINGS"
#define CHEATS_SECTION "CHEATS SETTINGS"
#define LANGUAGES_SECTION "LANGUAGES SETTINGS"
namespace Game {
extern SoHConfigType Settings;
void InitSettings();
void LoadSettings();
void LoadPadSettings();

View File

@ -15,11 +15,9 @@
#ifndef _LANGUAGE_C
#define _LANGUAGE_C
#endif
#include <PR/ultra64/gbi.h>
#include "PR/ultra64/gbi.h"
#include "gfx_cc.h"
#include "gfx_window_manager_api.h"
#include "gfx_rendering_api.h"
#include "gfx_direct3d_common.h"
#define DECLARE_GFX_DXGI_FUNCTIONS
@ -28,7 +26,9 @@
#include "gfx_screen_config.h"
#include "../../SohImGuiImpl.h"
#define THREE_POINT_FILTERING 0
#include "gfx_cc.h"
#include "gfx_rendering_api.h"
#include "gfx_pc.h"
#define DEBUG_D3D 0
using namespace Microsoft::WRL; // For ComPtr
@ -135,6 +135,7 @@ static struct {
//uint32_t current_width, current_height;
uint32_t render_target_height;
int current_framebuffer;
FilteringMode current_filter_mode = NONE;
int8_t depth_test;
int8_t depth_mask;
@ -397,7 +398,7 @@ static struct ShaderProgram *gfx_d3d11_create_and_load_new_shader(uint64_t shade
char buf[4096];
size_t len, num_floats;
gfx_direct3d_common_build_shader(buf, len, num_floats, cc_features, false, THREE_POINT_FILTERING);
gfx_direct3d_common_build_shader(buf, len, num_floats, cc_features, false, d3d.current_filter_mode == THREE_POINT);
ComPtr<ID3DBlob> vs, ps;
ComPtr<ID3DBlob> error_blob;
@ -564,11 +565,8 @@ static void gfx_d3d11_set_sampler_parameters(int tile, bool linear_filter, uint3
D3D11_SAMPLER_DESC sampler_desc;
ZeroMemory(&sampler_desc, sizeof(D3D11_SAMPLER_DESC));
#if THREE_POINT_FILTERING
sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
#else
sampler_desc.Filter = linear_filter ? D3D11_FILTER_MIN_MAG_MIP_LINEAR : D3D11_FILTER_MIN_MAG_MIP_POINT;
#endif
sampler_desc.Filter = linear_filter && d3d.current_filter_mode == LINEAR ? D3D11_FILTER_MIN_MAG_MIP_LINEAR : D3D11_FILTER_MIN_MAG_MIP_POINT;
sampler_desc.AddressU = gfx_cm_to_d3d11(cms);
sampler_desc.AddressV = gfx_cm_to_d3d11(cmt);
sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
@ -672,12 +670,12 @@ static void gfx_d3d11_draw_triangles(float buf_vbo[], size_t buf_vbo_len, size_t
d3d.last_resource_views[i] = d3d.textures[d3d.current_texture_ids[i]].resource_view.Get();
d3d.context->PSSetShaderResources(i, 1, d3d.textures[d3d.current_texture_ids[i]].resource_view.GetAddressOf());
#if THREE_POINT_FILTERING
d3d.per_draw_cb_data.textures[i].width = d3d.textures[d3d.current_texture_ids[i]].width;
d3d.per_draw_cb_data.textures[i].height = d3d.textures[d3d.current_texture_ids[i]].height;
d3d.per_draw_cb_data.textures[i].linear_filtering = d3d.textures[d3d.current_texture_ids[i]].linear_filtering;
textures_changed = true;
#endif
if (d3d.current_filter_mode == THREE_POINT) {
d3d.per_draw_cb_data.textures[i].width = d3d.textures[d3d.current_texture_ids[i]].width;
d3d.per_draw_cb_data.textures[i].height = d3d.textures[d3d.current_texture_ids[i]].height;
d3d.per_draw_cb_data.textures[i].linear_filtering = d3d.textures[d3d.current_texture_ids[i]].linear_filtering;
textures_changed = true;
}
if (d3d.last_sampler_states[i].Get() != d3d.textures[d3d.current_texture_ids[i]].sampler_state.Get()) {
d3d.last_sampler_states[i] = d3d.textures[d3d.current_texture_ids[i]].sampler_state.Get();
@ -880,6 +878,15 @@ void gfx_d3d11_select_texture_fb(int fbID) {
gfx_d3d11_select_texture(tile, d3d.framebuffers[fbID].texture_id);
}
void gfx_d3d11_set_texture_filter(FilteringMode mode) {
d3d.current_filter_mode = mode;
gfx_texture_cache_clear();
}
FilteringMode gfx_d3d11_get_texture_filter(void) {
return d3d.current_filter_mode;
}
std::map<std::pair<float, float>, uint16_t> gfx_d3d11_get_pixel_depth(int fb_id, const std::set<std::pair<float, float>>& coordinates) {
Framebuffer& fb = d3d.framebuffers[fb_id];
TextureData& td = d3d.textures[fb.texture_id];
@ -1019,7 +1026,9 @@ struct GfxRenderingAPI gfx_direct3d11_api = {
gfx_d3d11_get_pixel_depth,
gfx_d3d11_get_framebuffer_texture_id,
gfx_d3d11_select_texture_fb,
gfx_d3d11_delete_texture
gfx_d3d11_delete_texture,
gfx_d3d11_set_texture_filter,
gfx_d3d11_get_texture_filter
};
#endif

View File

@ -73,6 +73,7 @@ static uint32_t frame_count;
static vector<Framebuffer> framebuffers;
static size_t current_framebuffer;
static float current_noise_scale;
static FilteringMode current_filter_mode = THREE_POINT;
GLuint pixel_depth_rb, pixel_depth_fb;
size_t pixel_depth_rb_size;
@ -211,7 +212,7 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
gfx_cc_get_features(shader_id0, shader_id1, &cc_features);
char vs_buf[1024];
char fs_buf[1024];
char fs_buf[3000];
size_t vs_len = 0;
size_t fs_len = 0;
size_t num_floats = 4;
@ -312,21 +313,42 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
append_line(fs_buf, &fs_len, "}");
}
if (current_filter_mode == THREE_POINT) {
append_line(fs_buf, &fs_len, "#define TEX_OFFSET(off) texture2D(tex, texCoord - (off)/texSize)");
append_line(fs_buf, &fs_len, "vec4 filter3point(in sampler2D tex, in vec2 texCoord, in vec2 texSize) {");
append_line(fs_buf, &fs_len, " vec2 offset = fract(texCoord*texSize - vec2(0.5));");
append_line(fs_buf, &fs_len, " offset -= step(1.0, offset.x + offset.y);");
append_line(fs_buf, &fs_len, " vec4 c0 = TEX_OFFSET(offset);");
append_line(fs_buf, &fs_len, " vec4 c1 = TEX_OFFSET(vec2(offset.x - sign(offset.x), offset.y));");
append_line(fs_buf, &fs_len, " vec4 c2 = TEX_OFFSET(vec2(offset.x, offset.y - sign(offset.y)));");
append_line(fs_buf, &fs_len, " return c0 + abs(offset.x)*(c1-c0) + abs(offset.y)*(c2-c0);");
append_line(fs_buf, &fs_len, "}");
append_line(fs_buf, &fs_len, "vec4 hookTexture2D(in sampler2D tex, in vec2 uv, in vec2 texSize) {");
append_line(fs_buf, &fs_len, " return filter3point(tex, uv, texSize);");
append_line(fs_buf, &fs_len, "}");
} else {
append_line(fs_buf, &fs_len, "vec4 hookTexture2D(in sampler2D tex, in vec2 uv, in vec2 texSize) {");
append_line(fs_buf, &fs_len, " return texture2D(tex, uv);");
append_line(fs_buf, &fs_len, "}");
}
append_line(fs_buf, &fs_len, "void main() {");
for (int i = 0; i < 2; i++) {
if (cc_features.used_textures[i]) {
bool s = cc_features.clamp[i][0], t = cc_features.clamp[i][1];
fs_len += sprintf(fs_buf + fs_len, "vec2 texSize%d = textureSize(uTex%d, 0);\n", i, i);
if (!s && !t) {
fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = texture2D(uTex%d, vTexCoord%d);\n", i, i, i);
fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, vTexCoord%d, texSize%d);\n", i, i, i, i);
} else {
fs_len += sprintf(fs_buf + fs_len, "vec2 texSize%d = textureSize(uTex%d, 0);\n", i, i);
if (s && t) {
fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = texture2D(uTex%d, clamp(vTexCoord%d, 0.5 / texSize%d, vec2(vTexClampS%d, vTexClampT%d)));\n", i, i, i, i, i, i);
fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, clamp(vTexCoord%d, 0.5 / texSize%d, vec2(vTexClampS%d, vTexClampT%d)), texSize%d);\n", i, i, i, i, i, i, i);
} else if (s) {
fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = texture2D(uTex%d, vec2(clamp(vTexCoord%d.s, 0.5 / texSize%d.s, vTexClampS%d), vTexCoord%d.t));\n", i, i, i, i, i, i);
fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, vec2(clamp(vTexCoord%d.s, 0.5 / texSize%d.s, vTexClampS%d), vTexCoord%d.t), texSize%d);\n", i, i, i, i, i, i, i);
} else {
fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = texture2D(uTex%d, vec2(vTexCoord%d.s, clamp(vTexCoord%d.t, 0.5 / texSize%d.t, vTexClampT%d)));\n", i, i, i, i, i, i);
fs_len += sprintf(fs_buf + fs_len, "vec4 texVal%d = hookTexture2D(uTex%d, vec2(vTexCoord%d.s, clamp(vTexCoord%d.t, 0.5 / texSize%d.t, vTexClampT%d)), texSize%d);\n", i, i, i, i, i, i, i);
}
}
}
@ -422,9 +444,9 @@ static struct ShaderProgram* gfx_opengl_create_and_load_new_shader(uint64_t shad
GLint max_length = 0;
glGetShaderiv(fragment_shader, GL_INFO_LOG_LENGTH, &max_length);
char error_log[1024];
//fprintf(stderr, "Fragment shader compilation failed\n");
fprintf(stderr, "Fragment shader compilation failed\n");
glGetShaderInfoLog(fragment_shader, max_length, &max_length, &error_log[0]);
//fprintf(stderr, "%s\n", &error_log[0]);
fprintf(stderr, "%s\n", &error_log[0]);
abort();
}
@ -552,9 +574,10 @@ static uint32_t gfx_cm_to_opengl(uint32_t val) {
}
static void gfx_opengl_set_sampler_parameters(int tile, bool linear_filter, uint32_t cms, uint32_t cmt) {
const GLint filter = linear_filter && current_filter_mode == LINEAR ? GL_LINEAR : GL_NEAREST;
glActiveTexture(GL_TEXTURE0 + tile);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, linear_filter ? GL_LINEAR : GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linear_filter ? GL_LINEAR : GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gfx_cm_to_opengl(cms));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gfx_cm_to_opengl(cmt));
}
@ -823,6 +846,15 @@ static std::map<std::pair<float, float>, uint16_t> gfx_opengl_get_pixel_depth(in
return res;
}
void gfx_opengl_set_texture_filter(FilteringMode mode) {
current_filter_mode = mode;
gfx_texture_cache_clear();
}
FilteringMode gfx_opengl_get_texture_filter(void) {
return current_filter_mode;
}
struct GfxRenderingAPI gfx_opengl_api = {
gfx_opengl_get_clip_parameters,
gfx_opengl_unload_shader,
@ -853,7 +885,9 @@ struct GfxRenderingAPI gfx_opengl_api = {
gfx_opengl_get_pixel_depth,
gfx_opengl_get_framebuffer_texture_id,
gfx_opengl_select_texture_fb,
gfx_opengl_delete_texture
gfx_opengl_delete_texture,
gfx_opengl_set_texture_filter,
gfx_opengl_get_texture_filter
};
#endif

View File

@ -15,6 +15,12 @@ struct GfxClipParameters {
bool invert_y;
};
enum FilteringMode {
THREE_POINT,
LINEAR,
NONE
};
struct GfxRenderingAPI {
struct GfxClipParameters (*get_clip_parameters)(void);
void (*unload_shader)(struct ShaderProgram *old_prg);
@ -46,6 +52,8 @@ struct GfxRenderingAPI {
void *(*get_framebuffer_texture_id)(int fb_id);
void (*select_texture_fb)(int fb_id);
void (*delete_texture)(uint32_t texID);
void (*set_texture_filter)(FilteringMode mode);
FilteringMode(*get_texture_filter)(void);
};
#endif

View File

@ -10,6 +10,7 @@
#include <spdlog/details/synchronous_factory.h>
#include "SohImGuiImpl.h"
#include "GameSettings.h"
#include "Cvar.h"
#include <chrono>
#include <mutex>
#include <string>
@ -45,7 +46,7 @@ protected:
}
formatted.push_back('\0');
const char *msg_output = formatted.data();
if (Game::Settings.debug.soh_sink && SohImGui::console->opened)
if (CVar_GetS32("gSinkEnabled", 0) && SohImGui::console->opened)
SohImGui::console->Append("SoH Logging", priority, msg_output);
}

View File

@ -106,7 +106,7 @@ void Console::Draw() {
if (!this->opened) return;
ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver);
ImGui::Begin("Console", &this->opened);
ImGui::Begin("Console", nullptr);
const ImVec2 pos = ImGui::GetWindowPos();
const ImVec2 size = ImGui::GetWindowSize();

View File

@ -43,6 +43,11 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPAR
using namespace Ship;
bool oldCursorState = true;
#define EXPERIMENTAL() \
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 50, 50, 255)); \
ImGui::Text("Experimental"); \
ImGui::PopStyleColor(); \
ImGui::Separator();
#define TOGGLE_BTN ImGuiKey_F1
#define HOOK(b) if(b) needs_save = true;
OSContPad* pads;
@ -73,6 +78,12 @@ namespace SohImGui {
float navi_prop_i_col[3] = { 0.0f, 0.0f, 0.0f };
float navi_prop_o_col[3] = { 0.0f, 0.0f, 0.0f };
const char* filters[3] = {
"Three-Point",
"Linear",
"None"
};
std::map<std::string, std::vector<std::string>> windowCategories;
std::map<std::string, CustomWindow> customWindows;
@ -85,7 +96,7 @@ namespace SohImGui {
ImGui_ImplWin32_Init(impl.dx11.window);
break;
}
// OTRTODO: This gameplay specific stuff should not be in libultraship. This needs to be moved to soh and use sTunicColors
kokiri_col[0] = 30 / 255.0f;
kokiri_col[1] = 105 / 255.0f;
@ -94,7 +105,7 @@ namespace SohImGui {
goron_col[0] = 100 / 255.0f;
goron_col[1] = 20 / 255.0f;
goron_col[2] = 0;
zora_col[0] = 0;
zora_col[1] = 60 / 255.0f;
zora_col[2] = 100 / 255.0f;
@ -201,7 +212,7 @@ namespace SohImGui {
return;
}
if (d == Dialogues::dConsole && Game::Settings.debug.menu_bar) {
if (d == Dialogues::dConsole && CVar_GetS32("gOpenMenuBar", 0)) {
return;
}
if (!GlobalCtx2::GetInstance()->GetWindow()->IsFullscreen()) {
@ -280,8 +291,8 @@ namespace SohImGui {
}
void Init(WindowImpl window_impl) {
impl = window_impl;
Game::LoadSettings();
impl = window_impl;
ImGuiContext* ctx = ImGui::CreateContext();
ImGui::SetCurrentContext(ctx);
io = &ImGui::GetIO();
@ -296,7 +307,7 @@ namespace SohImGui {
ModInternal::registerHookListener({ GFX_INIT, [](const HookEvent ev) {
if (GlobalCtx2::GetInstance()->GetWindow()->IsFullscreen())
ShowCursor(Game::Settings.debug.menu_bar, Dialogues::dLoadSettings);
ShowCursor(CVar_GetS32("gOpenMenuBar", 0), Dialogues::dLoadSettings);
LoadTexture("Game_Icon", "assets/ship_of_harkinian/icons/gSohIcon.png");
LoadTexture("A-Btn", "assets/ship_of_harkinian/buttons/ABtn.png");
@ -320,7 +331,7 @@ namespace SohImGui {
ModInternal::registerHookListener({ CONTROLLER_READ, [](const HookEvent ev) {
pads = static_cast<OSContPad*>(ev->baseArgs["cont_pad"]);
} });
}});
Game::InitSettings();
}
@ -334,7 +345,7 @@ namespace SohImGui {
#define BindButton(btn, status) ImGui::Image(GetTextureByID(DefaultAssets[btn]->textureId), ImVec2(16.0f * scale, 16.0f * scale), ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, (status) ? 255 : 0));
void BindAudioSlider(const char* name, const char* key, float defaultValue, SeqPlayers playerId)
void BindAudioSlider(const char* name, const char* key, float defaultValue, SeqPlayers playerId)
{
float value = CVar_GetFloat(key, defaultValue);
@ -380,7 +391,7 @@ namespace SohImGui {
ImGui::Text(text.c_str(), val);
if (ImGui::SliderInt(id.c_str(), &val, min, max, format.c_str()))
if (ImGui::SliderInt(id.c_str(), &val, min, max, format.c_str()))
{
CVar_SetS32(cvarName.c_str(), val);
needs_save = true;
@ -443,7 +454,7 @@ namespace SohImGui {
colors[2] = b / 255.0f;
{
if (ImGui::ColorEdit3(text.c_str(), colors))
if (ImGui::ColorEdit3(text.c_str(), colors))
{
CVar_SetS32((cvarName + "_Red").c_str(), (int)(colors[0] * 255));
CVar_SetS32((cvarName + "_Green").c_str(), (int)(colors[1] * 255));
@ -463,7 +474,7 @@ namespace SohImGui {
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoBackground |
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_NoResize;
if (Game::Settings.debug.menu_bar) window_flags |= ImGuiWindowFlags_MenuBar;
if (CVar_GetS32("gOpenMenuBar", 0)) window_flags |= ImGuiWindowFlags_MenuBar;
const ImGuiViewport* viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(viewport->WorkPos);
@ -491,10 +502,11 @@ namespace SohImGui {
ImGui::DockSpace(dockId, ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_None);
if (ImGui::IsKeyPressed(TOGGLE_BTN)) {
Game::Settings.debug.menu_bar = !Game::Settings.debug.menu_bar;
bool menu_bar = CVar_GetS32("gOpenMenuBar", 0);
CVar_SetS32("gOpenMenuBar", !menu_bar);
needs_save = true;
GlobalCtx2::GetInstance()->GetWindow()->dwMenubar = Game::Settings.debug.menu_bar;
ShowCursor(Game::Settings.debug.menu_bar, Dialogues::dMenubar);
GlobalCtx2::GetInstance()->GetWindow()->dwMenubar = menu_bar;
ShowCursor(menu_bar, Dialogues::dMenubar);
}
if (ImGui::BeginMenuBar()) {
@ -563,9 +575,41 @@ namespace SohImGui {
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Graphics"))
{
EnhancementSliderInt("Internal Resolution: %dx", "##IMul", "gInternalResolution", 1, 8, "");
gfx_current_dimensions.internal_mul = CVar_GetS32("gInternalResolution", 1);
EnhancementSliderInt("MSAA: %d", "##IMSAA", "gMSAAValue", 1, 8, "");
gfx_msaa_level = CVar_GetS32("gMSAAValue", 1);
EXPERIMENTAL();
ImGui::Text("Texture Filter (Needs reload)");
GfxRenderingAPI* gapi = gfx_get_current_rendering_api();
if (ImGui::BeginCombo("##filters", filters[gapi->get_texture_filter()])) {
for (int fId = 0; fId <= FilteringMode::NONE; fId++) {
if (ImGui::Selectable(filters[fId], fId == gapi->get_texture_filter())) {
INFO("New Filter: %s", filters[fId]);
gapi->set_texture_filter((FilteringMode)fId);
CVar_SetS32("gTextureFilter", (int) fId);
needs_save = true;
}
}
ImGui::EndCombo();
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Languages")) {
EnhancementRadioButton("English", "gLanguages", 0);
EnhancementRadioButton("German", "gLanguages", 1);
EnhancementRadioButton("French", "gLanguages", 2);
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Enhancements"))
{
ImGui::Text("Gameplay");
ImGui::Separator();
@ -583,62 +627,22 @@ namespace SohImGui {
EnhancementCheckbox("N64 Mode", "gN64Mode");
EnhancementCheckbox("Animated Link in Pause Menu", "gPauseLiveLink");
EnhancementCheckbox("Disable LOD", "gDisableLOD");
EnhancementCheckbox("Enable 3D Dropped items", "gNewDrops");
EnhancementCheckbox("Dynamic Wallet Icon", "gDynamicWalletIcon");
EnhancementCheckbox("Always show dungeon entrances", "gAlwaysShowDungeonMinimapIcon");
if (ImGui::BeginMenu("Fixes")) {
EnhancementCheckbox("Fix L&R Pause menu", "gUniformLR");
EnhancementCheckbox("Fix Dungeon entrances", "gFixDungeonMinimapIcon");
ImGui::EndMenu();
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Developer Tools"))
{
HOOK(ImGui::MenuItem("Stats", nullptr, &Game::Settings.debug.soh));
HOOK(ImGui::MenuItem("Console", nullptr, &console->opened));
ImGui::Text("Debug");
ImGui::Text("Fixes");
ImGui::Separator();
EnhancementCheckbox("Fix L&R Pause menu", "gUniformLR");
EnhancementCheckbox("Fix Dungeon entrances", "gFixDungeonMinimapIcon");
EnhancementCheckbox("Debug Mode", "gDebugEnabled");
EXPERIMENTAL();
EnhancementCheckbox("Disable LOD", "gDisableLOD");
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Graphics"))
{
HOOK(ImGui::MenuItem("Anti-aliasing", nullptr, &Game::Settings.graphics.show));
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Cheats"))
{
if (ImGui::BeginMenu("Infinite...")) {
EnhancementCheckbox("Money", "gInfiniteMoney");
EnhancementCheckbox("Health", "gInfiniteHealth");
EnhancementCheckbox("Ammo", "gInfiniteAmmo");
EnhancementCheckbox("Magic", "gInfiniteMagic");
EnhancementCheckbox("Nayru's Love", "gInfiniteNayru");
ImGui::EndMenu();
}
EnhancementCheckbox("No Clip", "gNoClip");
EnhancementCheckbox("Climb Everything", "gClimbEverything");
EnhancementCheckbox("Moon Jump on L", "gMoonJumpOnL");
EnhancementCheckbox("Super Tunic", "gSuperTunic");
EnhancementCheckbox("Easy ISG", "gEzISG");
EnhancementCheckbox("Unrestricted Items", "gNoRestrictItems");
EnhancementCheckbox("Freeze Time", "gFreezeTime");
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Cosmetics"))
{
ImGui::Text("Tunics");
@ -663,24 +667,48 @@ namespace SohImGui {
ImGui::EndMenu();
}
if (CVar_GetS32("gLanguages", 0) == 0) {
SelectedLanguage = 0;
} else if (CVar_GetS32("gLanguages", 0) == 1) {
SelectedLanguage = 1;
} else if (CVar_GetS32("gLanguages", 0) == 2) {
SelectedLanguage = 2;
if (ImGui::BeginMenu("Cheats"))
{
if (ImGui::BeginMenu("Infinite...")) {
EnhancementCheckbox("Money", "gInfiniteMoney");
EnhancementCheckbox("Health", "gInfiniteHealth");
EnhancementCheckbox("Ammo", "gInfiniteAmmo");
EnhancementCheckbox("Magic", "gInfiniteMagic");
EnhancementCheckbox("Nayru's Love", "gInfiniteNayru");
ImGui::EndMenu();
}
EnhancementCheckbox("No Clip", "gNoClip");
EnhancementCheckbox("Climb Everything", "gClimbEverything");
EnhancementCheckbox("Moon Jump on L", "gMoonJumpOnL");
EnhancementCheckbox("Super Tunic", "gSuperTunic");
EnhancementCheckbox("Easy ISG", "gEzISG");
EnhancementCheckbox("Unrestricted Items", "gNoRestrictItems");
EnhancementCheckbox("Freeze Time", "gFreezeTime");
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Languages")) {
EnhancementRadioButton("English", "gLanguages", 0);
EnhancementRadioButton("German", "gLanguages", 1);
EnhancementRadioButton("French", "gLanguages", 2);
if (ImGui::BeginMenu("Developer Tools"))
{
EnhancementCheckbox("Stats", "gStatsEnabled");
EnhancementCheckbox("Console", "gConsoleEnabled");
console->opened = CVar_GetS32("gConsoleEnabled", 0);
EnhancementCheckbox("OoT Debug Mode", "gDebugEnabled");
ImGui::EndMenu();
}
for (const auto& category : windowCategories) {
if (ImGui::BeginMenu(category.first.c_str())) {
for (const std::string& name : category.second) {
HOOK(ImGui::MenuItem(name.c_str(), nullptr, &customWindows[name].enabled));
std::string varName(name);
varName.erase(std::ranges::remove_if(varName, isspace).begin(), varName.end());
std::string toggleName = "g" + varName + "Enabled";
EnhancementCheckbox(name, toggleName);
customWindows[name].enabled = CVar_GetS32(toggleName.c_str(), 0);
}
ImGui::EndMenu();
}
@ -691,7 +719,7 @@ namespace SohImGui {
ImGui::End();
if (Game::Settings.debug.soh) {
if (CVar_GetS32("gStatsEnabled", 0)) {
const float framerate = ImGui::GetIO().Framerate;
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
ImGui::Begin("Debug Stats", nullptr, ImGuiWindowFlags_None);
@ -702,17 +730,6 @@ namespace SohImGui {
ImGui::PopStyleColor();
}
if (Game::Settings.graphics.show) {
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
ImGui::Begin("Anti-aliasing settings", nullptr, ImGuiWindowFlags_None);
ImGui::Text("Internal Resolution:");
ImGui::SliderInt("Mul", reinterpret_cast<int*>(&gfx_current_dimensions.internal_mul), 1, 8);
ImGui::Text("MSAA:");
ImGui::SliderInt("MSAA", reinterpret_cast<int*>(&gfx_msaa_level), 1, 8);
ImGui::End();
ImGui::PopStyleColor();
}
console->Draw();
for (auto& windowIter : customWindows) {

View File

@ -122,7 +122,7 @@ static bool RuppeHandler(const std::vector<std::string>& args) {
try {
rupeeAmount = std::stoi(args[1]);
}
catch (std::invalid_argument const& ex) {
catch (std::invalid_argument const& ex) {
ERROR("[SOH] Rupee count must be an integer.");
return CMD_FAILED;
}
@ -168,13 +168,13 @@ static bool ResetHandler(std::vector<std::string> args) {
ERROR("GlobalCtx == nullptr");
return CMD_FAILED;
}
SET_NEXT_GAMESTATE(&gGlobalCtx->state, TitleSetup_Init, GameState);
gGlobalCtx->state.running = false;
return CMD_SUCCESS;
}
const static std::map<std::string, uint16_t> ammoItems{
const static std::map<std::string, uint16_t> ammoItems{
{ "sticks", ITEM_STICK }, { "deku_sticks", ITEM_STICK },
{ "nuts", ITEM_NUT }, { "deku_nuts", ITEM_NUT },
{ "bombs", ITEM_BOMB }, { "arrows", ITEM_BOW },
@ -194,7 +194,7 @@ static bool AmmoHandler(const std::vector<std::string>& args) {
try {
count = std::stoi(args[2]);
} catch (std::invalid_argument const& ex) {
} catch (std::invalid_argument const& ex) {
ERROR("Ammo count must be an integer");
return CMD_FAILED;
}
@ -203,7 +203,7 @@ static bool AmmoHandler(const std::vector<std::string>& args) {
ERROR("Ammo count must be positive");
return CMD_FAILED;
}
const auto& it = ammoItems.find(args[1]);
if (it == ammoItems.end()) {
@ -213,7 +213,7 @@ static bool AmmoHandler(const std::vector<std::string>& args) {
// I dont think you can do OOB with just this
AMMO(it->second) = count;
//To use a change by uncomment this
//Inventory_ChangeAmmo(it->second, count);
}
@ -236,7 +236,7 @@ static bool BottleHandler(const std::vector<std::string>& args) {
unsigned int slot;
try {
slot = std::stoi(args[2]);
} catch (std::invalid_argument const& ex) {
} catch (std::invalid_argument const& ex) {
ERROR("[SOH] Bottle slot must be an integer.");
return CMD_FAILED;
}
@ -275,7 +275,7 @@ static bool ItemHandler(const std::vector<std::string>& args) {
return CMD_FAILED;
}
gSaveContext.inventory.items[std::stoi(args[1])] = std::stoi(args[2]);
gSaveContext.inventory.items[std::stoi(args[1])] = std::stoi(args[2]);
return CMD_SUCCESS;
}
@ -414,8 +414,11 @@ void DebugConsole_Init(void) {
{ { "slot", ArgumentType::NUMBER }, { "item id", ArgumentType::NUMBER } } });
CMD_REGISTER("entrance",
{ EntranceHandler, "Sends player to the entered entrance (hex)", { { "entrance", ArgumentType::NUMBER } } });
}
DebugConsole_LoadCVars();
template <typename Numeric> bool is_number(const std::string& s) {
Numeric n;
return ((std::istringstream(s) >> n >> std::ws).eof());
}
void DebugConsole_LoadCVars()
@ -424,7 +427,18 @@ void DebugConsole_LoadCVars()
const auto lines = File::ReadAllLines("cvars.cfg");
for (const std::string& line : lines) {
SohImGui::console->Dispatch(line);
std::vector<std::string> cfg = StringHelper::Split(line, " = ");
if (line.empty()) continue;
if (cfg.size() < 2) continue;
if (cfg[1].find("\"") != std::string::npos) {
CVar_SetString(cfg[0].c_str(), const_cast<char*>(cfg[1].c_str()));
}
if (is_number<float>(cfg[1])) {
CVar_SetFloat(cfg[0].c_str(), std::stof(cfg[1]));
}
if (is_number<int>(cfg[1])) {
CVar_SetS32(cfg[0].c_str(), std::stoi(cfg[1]));
}
}
}
}
@ -435,11 +449,11 @@ void DebugConsole_SaveCVars()
for (const auto &cvar : cvars) {
if (cvar.second->type == CVAR_TYPE_STRING)
output += StringHelper::Sprintf("set %s %s\n", cvar.first.c_str(), cvar.second->value.valueStr);
output += StringHelper::Sprintf("%s = \"%s\"\n", cvar.first.c_str(), cvar.second->value.valueStr);
else if (cvar.second->type == CVAR_TYPE_S32)
output += StringHelper::Sprintf("set %s %i\n", cvar.first.c_str(), cvar.second->value.valueS32);
output += StringHelper::Sprintf("%s = %i\n", cvar.first.c_str(), cvar.second->value.valueS32);
else if (cvar.second->type == CVAR_TYPE_FLOAT)
output += StringHelper::Sprintf("set %s %f\n", cvar.first.c_str(), cvar.second->value.valueFloat);
output += StringHelper::Sprintf("%s = %f\n", cvar.first.c_str(), cvar.second->value.valueFloat);
}
File::WriteAllText("cvars.cfg", output);

View File

@ -322,7 +322,7 @@ void CreateSphereData() {
}
void InitColViewer() {
SohImGui::AddWindow("Debug", "Collision Viewer", DrawColViewerWindow);
SohImGui::AddWindow("Developer Tools", "Collision Viewer", DrawColViewerWindow);
CreateCylinderData();
CreateSphereData();

View File

@ -1101,7 +1101,7 @@ void DrawSaveEditor(bool& open) {
}
void InitSaveEditor() {
SohImGui::AddWindow("Debug", "Save Editor", DrawSaveEditor);
SohImGui::AddWindow("Developer Tools", "Save Editor", DrawSaveEditor);
// Load item icons into ImGui
for (const auto& entry : itemMapping) {