1
1
#include " gui.h"
2
2
#include < fmt/core.h>
3
3
#include < imgui.h>
4
+ #include < platform/windows/utils/platform_tools.h>
4
5
#include " config.h"
5
6
#include " imgui/imgui_impl_opengl3.h"
6
7
#include " imgui/imgui_impl_sdl.h"
7
8
#include " platform/windows/input/key.h"
8
9
#include " platform/windows/gui/icons.h"
9
10
#include " system.h"
11
+ #include " state/state.h"
10
12
#include " utils/file.h"
11
13
#include " utils/string.h"
14
+ #include " images.h"
15
+
16
+ float GUI::scale = 1 .f;
12
17
13
18
GUI::GUI (SDL_Window* window, void * glContext) : window(window) {
14
19
ImGui::CreateContext ();
@@ -21,19 +26,19 @@ GUI::GUI(SDL_Window* window, void* glContext) : window(window) {
21
26
io.ConfigFlags |= ImGuiConfigFlags_IsTouchScreen;
22
27
#endif
23
28
24
- float scaleFactor = 1 .f ;
29
+ scale = 1 .f ;
25
30
#ifdef ANDROID
26
31
float dpi = 1 .f ;
27
32
if (SDL_GetDisplayDPI (0 , &dpi, nullptr , nullptr ) == 0 ) {
28
- scaleFactor = dpi / 160 .f ;
33
+ scale = dpi / 160 .f ;
29
34
}
30
35
#endif
31
- float fontSize = 16 .f * scaleFactor ;
36
+ float fontSize = 16 .f * scale ;
32
37
33
38
ImGuiStyle& style = ImGui::GetStyle ();
34
39
style.GrabRounding = 6 .f ;
35
40
style.FrameRounding = 6 .f ;
36
- style.ScaleAllSizes (scaleFactor );
41
+ style.ScaleAllSizes (scale );
37
42
#ifdef ANDROID
38
43
style.TouchExtraPadding = ImVec2 (10 .f , 10 .f );
39
44
#endif
@@ -51,7 +56,7 @@ GUI::GUI(SDL_Window* window, void* glContext) : window(window) {
51
56
52
57
{
53
58
ImFontConfig config;
54
- config.SizePixels = 13 .f * scaleFactor ;
59
+ config.SizePixels = 13 .f * scale ;
55
60
io.Fonts ->AddFontDefault (&config);
56
61
}
57
62
@@ -85,6 +90,13 @@ void GUI::mainMenu(std::unique_ptr<System>& sys) {
85
90
}
86
91
if (ImGui::BeginMenu (" File" )) {
87
92
ImGui::MenuItem (" Open" , nullptr , &openFile.openWindowOpen );
93
+ #if defined(__APPLE__) || defined(__WIN32__) || defined(__WIN64__) || defined(__LINUX__)
94
+ ImGui::Separator ();
95
+ if (ImGui::MenuItem (" Open Avocado directory" )) {
96
+ openFileBrowser (avocado::PATH_USER.c_str ());
97
+ }
98
+ #endif
99
+ ImGui::Separator ();
88
100
if (ImGui::MenuItem (" Exit" , " Esc" )) bus.notify (Event::File::Exit{});
89
101
ImGui::EndMenu ();
90
102
}
@@ -112,7 +124,9 @@ void GUI::mainMenu(std::unique_ptr<System>& sys) {
112
124
ImGui::Separator ();
113
125
114
126
if (ImGui::MenuItem (" Quick save" , " F5" )) bus.notify (Event::System::SaveState{});
115
- if (ImGui::MenuItem (" Quick load" , " F7" )) bus.notify (Event::System::LoadState{});
127
+
128
+ bool quickLoadStateExists = fs::exists (state::getStatePath (sys.get ()));
129
+ if (ImGui::MenuItem (" Quick load" , " F7" , nullptr , quickLoadStateExists)) bus.notify (Event::System::LoadState{});
116
130
117
131
if (ImGui::BeginMenu (" Save" )) {
118
132
for (int i = 1 ; i <= 5 ; i++) {
@@ -122,8 +136,17 @@ void GUI::mainMenu(std::unique_ptr<System>& sys) {
122
136
}
123
137
124
138
if (ImGui::BeginMenu (" Load" )) {
139
+ bool anySaveExists = false ;
125
140
for (int i = 1 ; i <= 5 ; i++) {
126
- if (ImGui::MenuItem (fmt::format (" Slot {}##load" , i).c_str ())) bus.notify (Event::System::LoadState{i});
141
+ auto path = state::getStatePath (sys.get (), i);
142
+ if (fs::exists (path)) {
143
+ anySaveExists = true ;
144
+ if (ImGui::MenuItem (fmt::format (" Slot {}##load" , i).c_str ())) bus.notify (Event::System::LoadState{i});
145
+ }
146
+ }
147
+
148
+ if (!anySaveExists) {
149
+ ImGui::TextUnformatted (" No save states" );
127
150
}
128
151
ImGui::EndMenu ();
129
152
}
@@ -200,11 +223,27 @@ void GUI::mainMenu(std::unique_ptr<System>& sys) {
200
223
ImGui::EndMenu ();
201
224
}
202
225
203
- // Print info
204
- auto info = fmt::format (" fps: {:.2f}" , 60 .f );
226
+ std::string info;
227
+ if (statusMouseLocked) {
228
+ info += " | Press Alt to unlock mouse" ;
229
+ }
230
+ if (sys->state == System::State::pause) {
231
+ info += " | Paused" ;
232
+ } else {
233
+ info += fmt::format (" | {:.0f} FPS" , statusFps);
234
+ if (!statusFramelimitter) {
235
+ info += " (Unlimited)" ;
236
+ }
237
+ }
205
238
auto size = ImGui::CalcTextSize (info.c_str ());
206
- ImGui::SameLine (ImGui::GetWindowWidth () - size.x * 1 . 2f );
239
+ ImGui::SameLine (ImGui::GetWindowWidth () - size.x - ImGui::GetStyle (). FramePadding . x * 4 );
207
240
ImGui::TextUnformatted (info.c_str ());
241
+
242
+ if (ImGui::IsItemHovered ()) {
243
+ ImGui::BeginTooltip ();
244
+ ImGui::TextUnformatted (fmt::format (" Frame time: {:.2f} ms\n Tab to disable frame limiting" , (1000.0 / statusFps)).c_str ());
245
+ ImGui::EndTooltip ();
246
+ }
208
247
ImGui::EndMainMenuBar ();
209
248
}
210
249
@@ -262,6 +301,9 @@ void GUI::render(std::unique_ptr<System>& sys) {
262
301
263
302
drawControls (sys);
264
303
304
+ // Work in progress
305
+ // renderController();
306
+
265
307
ImGui::Render ();
266
308
ImGui_ImplOpenGL3_RenderDrawData (ImGui::GetDrawData ());
267
309
}
@@ -339,8 +381,10 @@ void GUI::drawControls(std::unique_ptr<System>& sys) {
339
381
340
382
symbolButton (" Save/Load" , ICON_FA_SAVE);
341
383
if (ImGui::BeginPopupContextItem (nullptr , 0 )) {
342
- if (ImGui::Selectable (" Quick load" )) bus.notify (Event::System::LoadState{});
343
- ImGui::Separator ();
384
+ if (fs::exists (state::getStatePath (sys.get ()))) {
385
+ if (ImGui::Selectable (" Quick load" )) bus.notify (Event::System::LoadState{});
386
+ ImGui::Separator ();
387
+ }
344
388
if (ImGui::Selectable (" Quick save" )) bus.notify (Event::System::SaveState{});
345
389
ImGui::EndPopup ();
346
390
}
@@ -381,4 +425,38 @@ void GUI::drawControls(std::unique_ptr<System>& sys) {
381
425
382
426
ImGui::End ();
383
427
ImGui::PopStyleVar (3 );
384
- }
428
+ }
429
+
430
+ void GUI::renderController () {
431
+ ImDrawList* drawList = ImGui::GetBackgroundDrawList ();
432
+ float size = 64 .f ;
433
+ auto button = [drawList, size](const char * button, float _x, float _y) {
434
+ auto btn = getImage (button, avocado::assetsPath (" buttons/" ));
435
+ if (!btn) return ;
436
+ // AddImage(ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min = ImVec2(0, 0), const
437
+ // ImVec2& uv_max = ImVec2(1, 1), ImU32 col = IM_COL32_WHITE);
438
+ float x = ImGui::GetIO ().DisplaySize .x * _x;
439
+ float y = ImGui::GetIO ().DisplaySize .y * lerp (0 .3f , 0 .6f , _y);
440
+ float r = size / 2 * 1.2 ;
441
+
442
+ drawList->AddCircleFilled (ImVec2 (x, y), r, ImColor (0 , 0 , 0 , 128 ));
443
+ drawList->AddImage ((ImTextureID)btn->id , ImVec2 (x - size / 2 , y - size / 2 ), ImVec2 (x + size / 2 , y + size / 2 ), ImVec2 (0 , 0 ),
444
+ ImVec2 (1 , 1 ), ImColor (0xff , 0xff , 0xff , 192 ));
445
+ };
446
+
447
+ float COL = 1 .f / 12 .f ;
448
+ float ROW = 1 .f / 3 .f ;
449
+
450
+ button (" dpad_up" , 2 * COL, 1 * ROW);
451
+ button (" dpad_left" , 1 * COL, 2 * ROW);
452
+ button (" dpad_right" , 3 * COL, 2 * ROW);
453
+ button (" dpad_down" , 2 * COL, 3 * ROW);
454
+
455
+ button (" select" , 5 * COL, 3 * ROW);
456
+ button (" start" , 7 * COL, 3 * ROW);
457
+
458
+ button (" triangle" , 1 - 2 * COL, 1 * ROW);
459
+ button (" square" , 1 - 1 * COL, 2 * ROW);
460
+ button (" circle" , 1 - 3 * COL, 2 * ROW);
461
+ button (" cross" , 1 - 2 * COL, 3 * ROW);
462
+ }
0 commit comments