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 "Cvar.h"
#include "GlobalCtx2.h" #include "GlobalCtx2.h"
#include "SohImGuiImpl.h" #include "SohImGuiImpl.h"
#include "stox.h"
#include "../../soh/include/z64audio.h" #include "../../soh/include/z64audio.h"
#include <string>
#include "SohHooks.h" #include "SohHooks.h"
#include "../../soh/soh/Enhancements/debugconsole.h" #include "../../soh/soh/Enhancements/debugconsole.h"
#include "Window.h" #include "Window.h"
#include "Lib/Fast3D/gfx_rendering_api.h"
#define ABS(var) var < 0 ? -(var) : var #define ABS(var) var < 0 ? -(var) : var
@ -25,14 +24,6 @@ using namespace Ship;
namespace Game { namespace Game {
bool DeSyncAudio = false; 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() { void UpdateAudio() {
Audio_SetGameVolume(SEQ_BGM_MAIN, CVar_GetFloat("gMainMusicVolume", 1)); Audio_SetGameVolume(SEQ_BGM_MAIN, CVar_GetFloat("gMainMusicVolume", 1));
@ -41,18 +32,6 @@ namespace Game {
Audio_SetGameVolume(SEQ_SFX, CVar_GetFloat("gFanfareVolume", 1)); 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() { void LoadPadSettings() {
const std::shared_ptr<ConfigFile> pConf = GlobalCtx2::GetInstance()->GetConfig(); const std::shared_ptr<ConfigFile> pConf = GlobalCtx2::GetInstance()->GetConfig();
ConfigFile& Conf = *pConf; ConfigFile& Conf = *pConf;
@ -65,16 +44,11 @@ namespace Game {
} }
} }
void LoadSettings() {
DebugConsole_LoadCVars();
}
void SaveSettings() { 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(); DebugConsole_SaveCVars();
} }
@ -82,6 +56,11 @@ namespace Game {
ModInternal::registerHookListener({ AUDIO_INIT, [](HookEvent ev) { ModInternal::registerHookListener({ AUDIO_INIT, [](HookEvent ev) {
UpdateAudio(); 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) { void SetSeqPlayerVolume(SeqPlayers playerId, float volume) {

View File

@ -1,19 +1,5 @@
#pragma once #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 { enum SeqPlayers {
/* 0 */ SEQ_BGM_MAIN, /* 0 */ SEQ_BGM_MAIN,
/* 1 */ SEQ_FANFARE, /* 1 */ SEQ_FANFARE,
@ -22,16 +8,7 @@ enum SeqPlayers {
/* 4 */ SEQ_MAX /* 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 { namespace Game {
extern SoHConfigType Settings;
void InitSettings(); void InitSettings();
void LoadSettings(); void LoadSettings();
void LoadPadSettings(); void LoadPadSettings();

View File

@ -15,11 +15,9 @@
#ifndef _LANGUAGE_C #ifndef _LANGUAGE_C
#define _LANGUAGE_C #define _LANGUAGE_C
#endif #endif
#include <PR/ultra64/gbi.h> #include "PR/ultra64/gbi.h"
#include "gfx_cc.h"
#include "gfx_window_manager_api.h" #include "gfx_window_manager_api.h"
#include "gfx_rendering_api.h"
#include "gfx_direct3d_common.h" #include "gfx_direct3d_common.h"
#define DECLARE_GFX_DXGI_FUNCTIONS #define DECLARE_GFX_DXGI_FUNCTIONS
@ -28,7 +26,9 @@
#include "gfx_screen_config.h" #include "gfx_screen_config.h"
#include "../../SohImGuiImpl.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 #define DEBUG_D3D 0
using namespace Microsoft::WRL; // For ComPtr using namespace Microsoft::WRL; // For ComPtr
@ -135,6 +135,7 @@ static struct {
//uint32_t current_width, current_height; //uint32_t current_width, current_height;
uint32_t render_target_height; uint32_t render_target_height;
int current_framebuffer; int current_framebuffer;
FilteringMode current_filter_mode = NONE;
int8_t depth_test; int8_t depth_test;
int8_t depth_mask; int8_t depth_mask;
@ -397,7 +398,7 @@ static struct ShaderProgram *gfx_d3d11_create_and_load_new_shader(uint64_t shade
char buf[4096]; char buf[4096];
size_t len, num_floats; 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> vs, ps;
ComPtr<ID3DBlob> error_blob; 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; D3D11_SAMPLER_DESC sampler_desc;
ZeroMemory(&sampler_desc, sizeof(D3D11_SAMPLER_DESC)); ZeroMemory(&sampler_desc, sizeof(D3D11_SAMPLER_DESC));
#if THREE_POINT_FILTERING sampler_desc.Filter = linear_filter && d3d.current_filter_mode == LINEAR ? D3D11_FILTER_MIN_MAG_MIP_LINEAR : D3D11_FILTER_MIN_MAG_MIP_POINT;
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.AddressU = gfx_cm_to_d3d11(cms); sampler_desc.AddressU = gfx_cm_to_d3d11(cms);
sampler_desc.AddressV = gfx_cm_to_d3d11(cmt); sampler_desc.AddressV = gfx_cm_to_d3d11(cmt);
sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; 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.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()); d3d.context->PSSetShaderResources(i, 1, d3d.textures[d3d.current_texture_ids[i]].resource_view.GetAddressOf());
#if THREE_POINT_FILTERING 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].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].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; d3d.per_draw_cb_data.textures[i].linear_filtering = d3d.textures[d3d.current_texture_ids[i]].linear_filtering;
textures_changed = true; textures_changed = true;
#endif }
if (d3d.last_sampler_states[i].Get() != d3d.textures[d3d.current_texture_ids[i]].sampler_state.Get()) { 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(); 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); 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) { 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]; Framebuffer& fb = d3d.framebuffers[fb_id];
TextureData& td = d3d.textures[fb.texture_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_pixel_depth,
gfx_d3d11_get_framebuffer_texture_id, gfx_d3d11_get_framebuffer_texture_id,
gfx_d3d11_select_texture_fb, gfx_d3d11_select_texture_fb,
gfx_d3d11_delete_texture gfx_d3d11_delete_texture,
gfx_d3d11_set_texture_filter,
gfx_d3d11_get_texture_filter
}; };
#endif #endif

View File

@ -73,6 +73,7 @@ static uint32_t frame_count;
static vector<Framebuffer> framebuffers; static vector<Framebuffer> framebuffers;
static size_t current_framebuffer; static size_t current_framebuffer;
static float current_noise_scale; static float current_noise_scale;
static FilteringMode current_filter_mode = THREE_POINT;
GLuint pixel_depth_rb, pixel_depth_fb; GLuint pixel_depth_rb, pixel_depth_fb;
size_t pixel_depth_rb_size; 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); gfx_cc_get_features(shader_id0, shader_id1, &cc_features);
char vs_buf[1024]; char vs_buf[1024];
char fs_buf[1024]; char fs_buf[3000];
size_t vs_len = 0; size_t vs_len = 0;
size_t fs_len = 0; size_t fs_len = 0;
size_t num_floats = 4; 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, "}"); 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() {"); append_line(fs_buf, &fs_len, "void main() {");
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
if (cc_features.used_textures[i]) { if (cc_features.used_textures[i]) {
bool s = cc_features.clamp[i][0], t = cc_features.clamp[i][1]; 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) { 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 { } else {
fs_len += sprintf(fs_buf + fs_len, "vec2 texSize%d = textureSize(uTex%d, 0);\n", i, i);
if (s && t) { 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) { } 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 { } 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; GLint max_length = 0;
glGetShaderiv(fragment_shader, GL_INFO_LOG_LENGTH, &max_length); glGetShaderiv(fragment_shader, GL_INFO_LOG_LENGTH, &max_length);
char error_log[1024]; 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]); 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(); 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) { 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); glActiveTexture(GL_TEXTURE0 + tile);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, linear_filter ? GL_LINEAR : GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linear_filter ? GL_LINEAR : GL_NEAREST); 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_S, gfx_cm_to_opengl(cms));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gfx_cm_to_opengl(cmt)); 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; 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 = { struct GfxRenderingAPI gfx_opengl_api = {
gfx_opengl_get_clip_parameters, gfx_opengl_get_clip_parameters,
gfx_opengl_unload_shader, gfx_opengl_unload_shader,
@ -853,7 +885,9 @@ struct GfxRenderingAPI gfx_opengl_api = {
gfx_opengl_get_pixel_depth, gfx_opengl_get_pixel_depth,
gfx_opengl_get_framebuffer_texture_id, gfx_opengl_get_framebuffer_texture_id,
gfx_opengl_select_texture_fb, gfx_opengl_select_texture_fb,
gfx_opengl_delete_texture gfx_opengl_delete_texture,
gfx_opengl_set_texture_filter,
gfx_opengl_get_texture_filter
}; };
#endif #endif

View File

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

View File

@ -10,6 +10,7 @@
#include <spdlog/details/synchronous_factory.h> #include <spdlog/details/synchronous_factory.h>
#include "SohImGuiImpl.h" #include "SohImGuiImpl.h"
#include "GameSettings.h" #include "GameSettings.h"
#include "Cvar.h"
#include <chrono> #include <chrono>
#include <mutex> #include <mutex>
#include <string> #include <string>
@ -45,7 +46,7 @@ protected:
} }
formatted.push_back('\0'); formatted.push_back('\0');
const char *msg_output = formatted.data(); 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); SohImGui::console->Append("SoH Logging", priority, msg_output);
} }

View File

@ -106,7 +106,7 @@ void Console::Draw() {
if (!this->opened) return; if (!this->opened) return;
ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver);
ImGui::Begin("Console", &this->opened); ImGui::Begin("Console", nullptr);
const ImVec2 pos = ImGui::GetWindowPos(); const ImVec2 pos = ImGui::GetWindowPos();
const ImVec2 size = ImGui::GetWindowSize(); 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; using namespace Ship;
bool oldCursorState = true; 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 TOGGLE_BTN ImGuiKey_F1
#define HOOK(b) if(b) needs_save = true; #define HOOK(b) if(b) needs_save = true;
OSContPad* pads; OSContPad* pads;
@ -73,6 +78,12 @@ namespace SohImGui {
float navi_prop_i_col[3] = { 0.0f, 0.0f, 0.0f }; float navi_prop_i_col[3] = { 0.0f, 0.0f, 0.0f };
float navi_prop_o_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, std::vector<std::string>> windowCategories;
std::map<std::string, CustomWindow> customWindows; std::map<std::string, CustomWindow> customWindows;
@ -201,7 +212,7 @@ namespace SohImGui {
return; return;
} }
if (d == Dialogues::dConsole && Game::Settings.debug.menu_bar) { if (d == Dialogues::dConsole && CVar_GetS32("gOpenMenuBar", 0)) {
return; return;
} }
if (!GlobalCtx2::GetInstance()->GetWindow()->IsFullscreen()) { if (!GlobalCtx2::GetInstance()->GetWindow()->IsFullscreen()) {
@ -280,8 +291,8 @@ namespace SohImGui {
} }
void Init(WindowImpl window_impl) { void Init(WindowImpl window_impl) {
impl = window_impl;
Game::LoadSettings(); Game::LoadSettings();
impl = window_impl;
ImGuiContext* ctx = ImGui::CreateContext(); ImGuiContext* ctx = ImGui::CreateContext();
ImGui::SetCurrentContext(ctx); ImGui::SetCurrentContext(ctx);
io = &ImGui::GetIO(); io = &ImGui::GetIO();
@ -296,7 +307,7 @@ namespace SohImGui {
ModInternal::registerHookListener({ GFX_INIT, [](const HookEvent ev) { ModInternal::registerHookListener({ GFX_INIT, [](const HookEvent ev) {
if (GlobalCtx2::GetInstance()->GetWindow()->IsFullscreen()) 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("Game_Icon", "assets/ship_of_harkinian/icons/gSohIcon.png");
LoadTexture("A-Btn", "assets/ship_of_harkinian/buttons/ABtn.png"); LoadTexture("A-Btn", "assets/ship_of_harkinian/buttons/ABtn.png");
@ -320,7 +331,7 @@ namespace SohImGui {
ModInternal::registerHookListener({ CONTROLLER_READ, [](const HookEvent ev) { ModInternal::registerHookListener({ CONTROLLER_READ, [](const HookEvent ev) {
pads = static_cast<OSContPad*>(ev->baseArgs["cont_pad"]); pads = static_cast<OSContPad*>(ev->baseArgs["cont_pad"]);
} }); }});
Game::InitSettings(); Game::InitSettings();
} }
@ -463,7 +474,7 @@ namespace SohImGui {
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoBackground |
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_NoResize; 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(); const ImGuiViewport* viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(viewport->WorkPos); ImGui::SetNextWindowPos(viewport->WorkPos);
@ -491,10 +502,11 @@ namespace SohImGui {
ImGui::DockSpace(dockId, ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_None); ImGui::DockSpace(dockId, ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_None);
if (ImGui::IsKeyPressed(TOGGLE_BTN)) { 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; needs_save = true;
GlobalCtx2::GetInstance()->GetWindow()->dwMenubar = Game::Settings.debug.menu_bar; GlobalCtx2::GetInstance()->GetWindow()->dwMenubar = menu_bar;
ShowCursor(Game::Settings.debug.menu_bar, Dialogues::dMenubar); ShowCursor(menu_bar, Dialogues::dMenubar);
} }
if (ImGui::BeginMenuBar()) { if (ImGui::BeginMenuBar()) {
@ -563,9 +575,41 @@ namespace SohImGui {
ImGui::EndMenu(); 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")) if (ImGui::BeginMenu("Enhancements"))
{ {
ImGui::Text("Gameplay"); ImGui::Text("Gameplay");
ImGui::Separator(); ImGui::Separator();
@ -583,62 +627,22 @@ namespace SohImGui {
EnhancementCheckbox("N64 Mode", "gN64Mode"); EnhancementCheckbox("N64 Mode", "gN64Mode");
EnhancementCheckbox("Animated Link in Pause Menu", "gPauseLiveLink"); EnhancementCheckbox("Animated Link in Pause Menu", "gPauseLiveLink");
EnhancementCheckbox("Disable LOD", "gDisableLOD");
EnhancementCheckbox("Enable 3D Dropped items", "gNewDrops"); EnhancementCheckbox("Enable 3D Dropped items", "gNewDrops");
EnhancementCheckbox("Dynamic Wallet Icon", "gDynamicWalletIcon"); EnhancementCheckbox("Dynamic Wallet Icon", "gDynamicWalletIcon");
EnhancementCheckbox("Always show dungeon entrances", "gAlwaysShowDungeonMinimapIcon"); EnhancementCheckbox("Always show dungeon entrances", "gAlwaysShowDungeonMinimapIcon");
if (ImGui::BeginMenu("Fixes")) { ImGui::Text("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::Separator(); 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(); 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")) if (ImGui::BeginMenu("Cosmetics"))
{ {
ImGui::Text("Tunics"); ImGui::Text("Tunics");
@ -663,24 +667,48 @@ namespace SohImGui {
ImGui::EndMenu(); ImGui::EndMenu();
} }
if (CVar_GetS32("gLanguages", 0) == 0) { if (ImGui::BeginMenu("Cheats"))
SelectedLanguage = 0; {
} else if (CVar_GetS32("gLanguages", 0) == 1) { if (ImGui::BeginMenu("Infinite...")) {
SelectedLanguage = 1; EnhancementCheckbox("Money", "gInfiniteMoney");
} else if (CVar_GetS32("gLanguages", 0) == 2) { EnhancementCheckbox("Health", "gInfiniteHealth");
SelectedLanguage = 2; 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); if (ImGui::BeginMenu("Developer Tools"))
EnhancementRadioButton("German", "gLanguages", 1); {
EnhancementRadioButton("French", "gLanguages", 2); EnhancementCheckbox("Stats", "gStatsEnabled");
EnhancementCheckbox("Console", "gConsoleEnabled");
console->opened = CVar_GetS32("gConsoleEnabled", 0);
EnhancementCheckbox("OoT Debug Mode", "gDebugEnabled");
ImGui::EndMenu(); ImGui::EndMenu();
} }
for (const auto& category : windowCategories) { for (const auto& category : windowCategories) {
if (ImGui::BeginMenu(category.first.c_str())) { if (ImGui::BeginMenu(category.first.c_str())) {
for (const std::string& name : category.second) { 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(); ImGui::EndMenu();
} }
@ -691,7 +719,7 @@ namespace SohImGui {
ImGui::End(); ImGui::End();
if (Game::Settings.debug.soh) { if (CVar_GetS32("gStatsEnabled", 0)) {
const float framerate = ImGui::GetIO().Framerate; const float framerate = ImGui::GetIO().Framerate;
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0)); ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
ImGui::Begin("Debug Stats", nullptr, ImGuiWindowFlags_None); ImGui::Begin("Debug Stats", nullptr, ImGuiWindowFlags_None);
@ -702,17 +730,6 @@ namespace SohImGui {
ImGui::PopStyleColor(); 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(); console->Draw();
for (auto& windowIter : customWindows) { for (auto& windowIter : customWindows) {

View File

@ -414,8 +414,11 @@ void DebugConsole_Init(void) {
{ { "slot", ArgumentType::NUMBER }, { "item id", ArgumentType::NUMBER } } }); { { "slot", ArgumentType::NUMBER }, { "item id", ArgumentType::NUMBER } } });
CMD_REGISTER("entrance", CMD_REGISTER("entrance",
{ EntranceHandler, "Sends player to the entered entrance (hex)", { { "entrance", ArgumentType::NUMBER } } }); { 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() void DebugConsole_LoadCVars()
@ -424,7 +427,18 @@ void DebugConsole_LoadCVars()
const auto lines = File::ReadAllLines("cvars.cfg"); const auto lines = File::ReadAllLines("cvars.cfg");
for (const std::string& line : lines) { 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) { for (const auto &cvar : cvars) {
if (cvar.second->type == CVAR_TYPE_STRING) 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) 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) 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); File::WriteAllText("cvars.cfg", output);

View File

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

View File

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