Skip to content

Commit ad78f7e

Browse files
fix ini saving and high dpi support for imgui
Manually set imgui.ini file location to a safe place, as the default just drops it into whatever the working directory is currently. Also set a new default font and add support for scaling font and ui for high dpi and high pixel density screens.
1 parent c74c3ed commit ad78f7e

6 files changed

Lines changed: 117 additions & 0 deletions

File tree

34.5 KB
Binary file not shown.

code/osapi/osapi.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,11 @@ namespace
159159
case SDL_EVENT_WINDOW_RESIZED:
160160
gr_screen_resize(e.window.data1, e.window.data2);
161161
break;
162+
163+
case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED:
164+
auto vp = os::getMainViewport();
165+
if (vp) vp->updateScaling();
166+
break;
162167
}
163168

164169
gr_activate(fAppActive);
@@ -442,6 +447,7 @@ void os_init(const char * wclass, const char * title, const char * app_name)
442447
os::events::addEventListener(SDL_EVENT_WINDOW_FOCUS_LOST, os::events::DEFAULT_LISTENER_WEIGHT, window_event_handler);
443448
os::events::addEventListener(SDL_EVENT_WINDOW_FOCUS_GAINED, os::events::DEFAULT_LISTENER_WEIGHT, window_event_handler);
444449
os::events::addEventListener(SDL_EVENT_WINDOW_CLOSE_REQUESTED, os::events::DEFAULT_LISTENER_WEIGHT, window_event_handler);
450+
os::events::addEventListener(SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED, os::events::DEFAULT_LISTENER_WEIGHT, window_event_handler);
445451

446452
os::events::addEventListener(SDL_EVENT_QUIT, os::events::DEFAULT_LISTENER_WEIGHT, quit_handler);
447453

code/osapi/osapi.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,27 @@ namespace os
282282
* @note Implementation may ignore invocations of this function
283283
*/
284284
virtual void restore() = 0;
285+
286+
/**
287+
* @brief Get coordinate scale value for high-dpi displays
288+
*
289+
* @return Scale value as float
290+
*/
291+
virtual float getCoordScale() { return 1.0f; }
292+
293+
/**
294+
* @brief Returns passed value scaled for high-dpi
295+
*
296+
* @param val The value to be scaled
297+
*
298+
* @return Scaled value as float
299+
*/
300+
virtual float getScaled(float val) { return val; }
301+
302+
/**
303+
* @brief Updates scaling setup based on dpi changes
304+
*/
305+
virtual void updateScaling() {};
285306
};
286307

287308
/**

code/source_groups.cmake

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,10 @@ add_file_folder("Default files\\\\data\\\\effects"
280280
def_files/data/effects/volumetric-f.sdr
281281
)
282282

283+
add_file_folder("Default files\\\\data\\\\fonts"
284+
def_files/data/fonts/BankGothic-BT-Light.ttf
285+
)
286+
283287
add_file_folder("Default files\\\\data\\\\maps"
284288
def_files/data/maps/app_icon.png
285289
def_files/data/maps/app_icon_d.png
@@ -315,6 +319,7 @@ add_file_folder("Default files\\\\builtin"
315319
set(default_files_files
316320
${files_Default_files_data}
317321
${files_Default_files_data_effects}
322+
${files_Default_files_data_fonts}
318323
${files_Default_files_data_maps}
319324
${files_Default_files_data_scripts}
320325
${files_Default_files_data_tables}

freespace2/SDLGraphicsOperations.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,40 @@ class SDLOpenGLContext: public os::OpenGLContext {
8282
class SDLWindowViewPort: public os::Viewport {
8383
SDL_Window* _window;
8484
os::ViewPortProperties _props;
85+
86+
float coord_scale;
87+
float content_scale;
88+
float scale_factor;
89+
ImGuiStyle styleOrig;
90+
91+
void setDPIScaling() {
92+
int window_w, window_h;
93+
int framebuffer_w, framebuffer_h;
94+
95+
SDL_GetWindowSize(_window, &window_w, &window_h);
96+
SDL_GetWindowSizeInPixels(_window, &framebuffer_w, &framebuffer_h);
97+
98+
float sx = framebuffer_w / static_cast<float>(window_w);
99+
float sy = framebuffer_h / static_cast<float>(window_h);
100+
101+
coord_scale = std::max(sx, sy);
102+
content_scale = SDL_GetWindowDisplayScale(_window);
103+
scale_factor = content_scale / coord_scale;
104+
}
105+
106+
void initDPIScaling() {
107+
// save initial imgui style
108+
styleOrig = ImGui::GetStyle();
109+
// update dpi scaling values
110+
setDPIScaling();
111+
// scale imgui style
112+
ImGui::GetStyle().ScaleAllSizes(scale_factor);
113+
}
85114
public:
86115
SDLWindowViewPort(SDL_Window* window, const os::ViewPortProperties& props) : _window(window), _props(props) {
87116
Assertion(window != nullptr, "Invalid window specified");
117+
// scaling for imgui high dpi stuff
118+
initDPIScaling();
88119
}
89120
~SDLWindowViewPort() override {
90121
SDL_DestroyWindow(_window);
@@ -136,6 +167,23 @@ class SDLWindowViewPort: public os::Viewport {
136167
void restore() override {
137168
SDL_RestoreWindow(_window);
138169
}
170+
171+
float getCoordScale() override {
172+
return coord_scale;
173+
}
174+
175+
float getScaled(float val) override {
176+
return val * scale_factor;
177+
}
178+
179+
void updateScaling() override {
180+
// restore original imgui style
181+
ImGui::GetStyle() = styleOrig;
182+
// update dpi scaling values
183+
setDPIScaling();
184+
// scale imgui style
185+
ImGui::GetStyle().ScaleAllSizes(scale_factor);
186+
}
139187
};
140188

141189
SDLGraphicsOperations::SDLGraphicsOperations() {

freespace2/freespace.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1820,6 +1820,8 @@ void game_init()
18201820
Random::seed(static_cast<unsigned int>(time(nullptr)));
18211821

18221822
ImGui::CreateContext();
1823+
ImGui::GetIO().IniFilename = nullptr;
1824+
ImGui::LoadIniSettingsFromDisk(os_get_config_path("imgui.ini").c_str());
18231825

18241826
Framerate_delay = 0;
18251827

@@ -1968,6 +1970,35 @@ void game_init()
19681970
return;
19691971
}
19701972

1973+
// if not standalone then setup scalable font for imgui to use
1974+
if ( !Is_standalone ) {
1975+
ImGuiIO &io = ImGui::GetIO();
1976+
ImFontConfig fontConfig;
1977+
1978+
// improves font clarity on high density displays
1979+
fontConfig.RasterizerDensity = os::getMainViewport()->getCoordScale();;
1980+
1981+
auto file = cfopen("BankGothic-BT-Light.ttf", "rb", CF_TYPE_FONT);
1982+
1983+
if (file) {
1984+
// clear out default font
1985+
io.Fonts->Clear();
1986+
1987+
const auto size = cfilelength(file);
1988+
1989+
// NOTE: ImGui will free this memory on shutdown
1990+
auto font = reinterpret_cast<uint8_t*>(IM_ALLOC(size * (sizeof(uint8_t))));
1991+
1992+
cfread(font, 1, size, file);
1993+
1994+
cfclose(file);
1995+
file = nullptr;
1996+
1997+
io.Fonts->AddFontFromMemoryTTF(font, size, os::getMainViewport()->getScaled(12.f),
1998+
&fontConfig);
1999+
}
2000+
}
2001+
19712002
if (LoggingEnabled && Cmdline_debug_window) {
19722003
outwnd_debug_window_init();
19732004
}
@@ -7000,6 +7031,11 @@ int game_main(int argc, char *argv[])
70007031
break;
70017032
}
70027033

7034+
if (ImGui::GetIO().WantSaveIniSettings) {
7035+
ImGui::SaveIniSettingsToDisk(os_get_config_path("imgui.ini").c_str());
7036+
ImGui::GetIO().WantSaveIniSettings = false;
7037+
}
7038+
70037039
// Since tracing is always active this needs to happen in the main loop
70047040
tracing::process_events();
70057041
}
@@ -7110,6 +7146,7 @@ void game_shutdown(void)
71107146
std_deinit_standalone();
71117147
}
71127148

7149+
ImGui::SaveIniSettingsToDisk(os_get_config_path("imgui.ini").c_str());
71137150
ImGui::DestroyContext();
71147151

71157152
os_cleanup();

0 commit comments

Comments
 (0)