102 Patches: Detours to the Rescue
C reference for DttR maintainers and modders.
Loading...
Searching...
No Matches
gui_tab_modding.c
Go to the documentation of this file.
1#include "gui_internal.h"
2
3static const char *TOOLTIP_HOT_RELOAD = "Hot-reload mod DLLs while the game runs. "
4 "Default: false.";
5static const char *TOOLTIP_MOD_ENABLE = "Load this mod DLL on the next game launch. "
6 "Default: enabled.";
7static const char *MODDING_WARNING_TEXT = "The DttR modding API is currently experimental and may change "
8 "without warning.";
9
10#define DTTR_CONFIG_UI_MOD_ENABLE_W 4.0f
11
12typedef struct {
13 int count;
16
21
22static bool is_shadow_mod_dll(const char *filename) {
23 return strncmp(filename, DTTR_MODS_SHADOW_PREFIX, sizeof(DTTR_MODS_SHADOW_PREFIX) - 1)
24 == 0;
25}
26
28 memset(out, 0, sizeof(*out));
29
30 if (!state || !state->mods_dir[0]) {
31 return;
32 }
33
34 char search_pattern[MAX_PATH];
35 const int written = snprintf(
36 search_pattern,
37 sizeof(search_pattern),
38 "%s\\*.dll",
39 state->mods_dir
40 );
41 if (written <= 0 || (size_t)written >= sizeof(search_pattern)) {
42 return;
43 }
44
45 WIN32_FIND_DATAA find_data;
46 HANDLE find_handle = FindFirstFileA(search_pattern, &find_data);
47 if (find_handle == INVALID_HANDLE_VALUE) {
48 return;
49 }
50
51 do {
52 if ((find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
53 || is_shadow_mod_dll(find_data.cFileName)) {
54 continue;
55 }
56
58 break;
59 }
60
62 out->names[out->count],
63 sizeof(out->names[out->count]),
64 find_data.cFileName
65 )) {
66 continue;
67 }
68
69 out->count++;
70 } while (FindNextFileA(find_handle, &find_data));
71
72 FindClose(find_handle);
73}
74
76 const ImGuiTableFlags flags = (CONFIG_TABLE_FLAGS & ~ImGuiTableFlags_PadOuterX)
77 | ImGuiTableFlags_NoPadOuterX;
78 if (!igBeginTable("##modding_mod_table", 2, flags, (ImVec2_c){0.0f, 0.0f}, 0.0f)) {
79 return false;
80 }
81
82 igTableSetupColumn(
83 "On",
84 ImGuiTableColumnFlags_WidthFixed,
86 0
87 );
88 igTableSetupColumn("DLL", ImGuiTableColumnFlags_WidthStretch, 0.0f, 0);
89 igTableHeadersRow();
90 return true;
91}
92
96 const char *mod_name,
97 int row_index
98) {
100 igTableNextColumn();
101
102 bool enabled = !DTTR_Config_IsModDisabled(&state->config, mod_name);
103 igPushID_Int(row_index);
104 const bool changed = igCheckbox("##mod_enabled", &enabled);
105 igPopID();
106
107 if (changed && !DTTR_Config_SetModEnabled(&state->config, mod_name, enabled)) {
108 set_status(state, "Could not update mod toggle.");
109 }
110
112
113 igTableNextColumn();
114 igBeginDisabled(!enabled);
115 igTextUnformatted(mod_name, NULL);
116 igEndDisabled();
117}
118
124
126 igPushStyleColor_Vec4(ImGuiCol_Text, DTTR_CONFIG_UI_WARNING_TEXT_COLOR);
127 igTextWrapped("%s", MODDING_WARNING_TEXT);
128 igPopStyleColor(1);
130
132 ctx,
133 "##modding_settings_table",
135 )) {
136 return;
137 }
138
140 ctx,
141 "Hot Reload",
142 "##hot_reload",
143 &state->config.hot_reload,
145 FIELD_LABEL_STATE(state, hot_reload)
146 );
148
150 scan_mod_dlls(state, &mods);
151
153
154 if (mods.count == 0) {
155 igTextWrapped(
156 "No mod DLLs found in %s",
157 state->mods_dir[0] ? state->mods_dir : "mods"
158 );
159 return;
160 }
161
162 if (!begin_mod_table(ctx)) {
163 return;
164 }
165
166 for (int i = 0; i < mods.count; i++) {
167 draw_mod_toggle_row(ctx, state, mods.names[i], i);
168 }
169
170 igEndTable();
171}
const DTTR_BackendState * state
void void * ctx
DTTR_Graphics_COM_Direct3DDevice7 void DWORD flags DWORD void DWORD flags
DTTR_Graphics_COM_DirectDrawSurface7 DWORD flags void NULL
#define DTTR_MODS_SHADOW_PREFIX
Definition dttr_config.h:57
bool DTTR_Config_SetModEnabled(DTTR_Config *config, const char *mod_filename, bool enabled)
Definition defaults.c:145
bool DTTR_Config_IsModDisabled(const DTTR_Config *config, const char *mod_filename)
Definition defaults.c:98
#define DTTR_CONFIG_DISABLED_MODS_MAX
Definition dttr_config.h:56
float DTTR_ImGuiDialog_ScaledFloat(const DTTR_ImGuiDialogContext *ctx, float value)
bool DTTR_Path_CopyString(char *out, size_t out_size, const char *value)
Definition path.c:68
bool labeled_checkbox(const DTTR_ImGuiDialogContext *ctx, const char *label, const char *id, bool *value, const char *tooltip, config_label_state label_state)
void show_tooltip(const char *text)
void add_scaled_vertical_spacing(const DTTR_ImGuiDialogContext *ctx, float height)
Definition gui_widgets.c:12
#define DTTR_CONFIG_UI_SECTION_SPACING
void begin_config_table_row()
void end_settings_table()
#define DTTR_CONFIG_UI_WARNING_TEXT_COLOR
#define FIELD_LABEL_STATE(state, field)
#define DTTR_CONFIG_UI_INPUT_W
bool begin_tab_settings_table(const DTTR_ImGuiDialogContext *ctx, const char *id, float input_width)
Definition gui_tabs.c:13
#define CONFIG_TABLE_FLAGS
void set_status(config_ui_state *state, const char *status)
Definition gui_state.c:96
#define DTTR_CONFIG_UI_MOD_ENABLE_W
static bool is_shadow_mod_dll(const char *filename)
static bool begin_mod_table(const DTTR_ImGuiDialogContext *ctx)
static void scan_mod_dlls(const config_ui_state *state, config_mod_dll_list *out)
static float mod_enable_column_width(const DTTR_ImGuiDialogContext *ctx)
static void draw_mod_section_header(const DTTR_ImGuiDialogContext *ctx)
static const char * MODDING_WARNING_TEXT
static const char * TOOLTIP_MOD_ENABLE
static void draw_mod_toggle_row(const DTTR_ImGuiDialogContext *ctx, config_ui_state *state, const char *mod_name, int row_index)
void draw_modding_tab(const DTTR_ImGuiDialogContext *ctx, config_ui_state *state)
static const char * TOOLTIP_HOT_RELOAD
char names[DTTR_CONFIG_DISABLED_MODS_MAX][MAX_PATH]