ui: Refactor

This commit is contained in:
Matt Borgerson 2020-04-25 21:37:22 -07:00
parent b4f2267101
commit c02c245e0f
5 changed files with 148 additions and 155 deletions

View File

@ -26,7 +26,6 @@ endif
# Override with xemu UI # Override with xemu UI
sdl.mo-objs := \ sdl.mo-objs := \
imgui/imgui.o \ imgui/imgui.o \
imgui/imgui_demo.o \
imgui/imgui_draw.o \ imgui/imgui_draw.o \
imgui/imgui_widgets.o \ imgui/imgui_widgets.o \
imgui/examples/imgui_impl_opengl3.o \ imgui/examples/imgui_impl_opengl3.o \

View File

@ -20,6 +20,7 @@
#include <SDL.h> #include <SDL.h>
#include <epoxy/gl.h> #include <epoxy/gl.h>
#include <stdio.h> #include <stdio.h>
#include <deque>
#include "xemu-hud.h" #include "xemu-hud.h"
#include "xemu-input.h" #include "xemu-input.h"
@ -55,22 +56,21 @@ extern "C" {
#undef atomic_fetch_sub #undef atomic_fetch_sub
} }
#include <deque>
using namespace std;
ImFont *g_fixed_width_font; ImFont *g_fixed_width_font;
float g_main_menu_height; float g_main_menu_height;
float g_ui_scale = 1.0; float g_ui_scale = 1.0;
bool g_trigger_style_update = true; bool g_trigger_style_update = true;
struct NotificationManager { class NotificationManager
std::deque<const char *> notification_queue; {
private:
const int kNotificationDuration = 4000; const int kNotificationDuration = 4000;
std::deque<const char *> notification_queue;
bool active; bool active;
uint32_t notification_end_ts; uint32_t notification_end_ts;
const char *msg; const char *msg;
public:
NotificationManager() NotificationManager()
{ {
active = false; active = false;
@ -112,6 +112,7 @@ struct NotificationManager {
} }
} }
private:
void DrawNotification(float t, const char *msg) void DrawNotification(float t, const char *msg)
{ {
const float DISTANCE = 10.0f; const float DISTANCE = 10.0f;
@ -181,10 +182,12 @@ static void HelpMarker(const char* desc)
} }
} }
struct MonitorWindow class MonitorWindow
{ {
public:
bool is_open; bool is_open;
private:
char InputBuf[256]; char InputBuf[256];
ImVector<char*> Items; ImVector<char*> Items;
ImVector<const char*> Commands; ImVector<const char*> Commands;
@ -194,6 +197,7 @@ struct MonitorWindow
bool AutoScroll; bool AutoScroll;
bool ScrollToBottom; bool ScrollToBottom;
public:
MonitorWindow() MonitorWindow()
{ {
is_open = false; is_open = false;
@ -208,7 +212,6 @@ struct MonitorWindow
// Portable helpers // Portable helpers
static int Stricmp(const char* str1, const char* str2) { int d; while ((d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; } return d; } static int Stricmp(const char* str1, const char* str2) { int d; while ((d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; } return d; }
static int Strnicmp(const char* str1, const char* str2, int n) { int d = 0; while (n > 0 && (d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; n--; } return d; }
static char* Strdup(const char *str) { size_t len = strlen(str) + 1; void* buf = malloc(len); IM_ASSERT(buf); return (char*)memcpy(buf, (const void*)str, len); } static char* Strdup(const char *str) { size_t len = strlen(str) + 1; void* buf = malloc(len); IM_ASSERT(buf); return (char*)memcpy(buf, (const void*)str, len); }
static void Strtrim(char* str) { char* str_end = str + strlen(str); while (str_end > str && str_end[-1] == ' ') str_end--; *str_end = 0; } static void Strtrim(char* str) { char* str_end = str + strlen(str); while (str_end > str && str_end[-1] == ' ') str_end--; *str_end = 0; }
@ -262,6 +265,7 @@ struct MonitorWindow
ImGui::End(); ImGui::End();
} }
private:
void ExecCommand(const char* command_line) void ExecCommand(const char* command_line)
{ {
xemu_run_monitor_command(command_line); xemu_run_monitor_command(command_line);
@ -322,8 +326,9 @@ struct MonitorWindow
} }
}; };
struct InputWindow class InputWindow
{ {
public:
bool is_open; bool is_open;
InputWindow() InputWindow()
@ -369,8 +374,8 @@ struct InputWindow
// circular numbers above them. These buttons can be activated to // circular numbers above them. These buttons can be activated to
// configure the associated port, like a tabbed interface. // configure the associated port, like a tabbed interface.
// //
ImVec4 color_active = ImVec4(0.5058, 0.8627, 0.5411, 0.1294); ImVec4 color_active(0.50, 0.86, 0.54, 0.12);
ImVec4 color_inactive = ImVec4(0, 0, 0, 0); ImVec4 color_inactive(0, 0, 0, 0);
// Begin a 4-column layout to render the ports // Begin a 4-column layout to render the ports
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,12)); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,12));
@ -529,10 +534,12 @@ struct InputWindow
#define MAX_STRING_LEN 2048 // FIXME: Completely arbitrary and only used here #define MAX_STRING_LEN 2048 // FIXME: Completely arbitrary and only used here
// to give a buffer to ImGui for each field // to give a buffer to ImGui for each field
struct SettingsWindow class SettingsWindow
{ {
public:
bool is_open; bool is_open;
private:
bool dirty; bool dirty;
bool pending_restart; bool pending_restart;
@ -544,9 +551,13 @@ struct SettingsWindow
int memory_idx; int memory_idx;
bool short_animation; bool short_animation;
public:
SettingsWindow() SettingsWindow()
{ {
is_open = false; is_open = false;
dirty = false;
pending_restart = false;
flash_path[0] = '\0'; flash_path[0] = '\0';
bootrom_path[0] = '\0'; bootrom_path[0] = '\0';
hdd_path[0] = '\0'; hdd_path[0] = '\0';
@ -554,15 +565,13 @@ struct SettingsWindow
eeprom_path[0] = '\0'; eeprom_path[0] = '\0';
memory_idx = 0; memory_idx = 0;
short_animation = false; short_animation = false;
pending_restart = false;
dirty = false;
} }
~SettingsWindow() ~SettingsWindow()
{ {
} }
void Load(void) void Load()
{ {
const char *tmp; const char *tmp;
int tmp_int; int tmp_int;
@ -570,27 +579,27 @@ struct SettingsWindow
xemu_settings_get_string(XEMU_SETTINGS_SYSTEM_FLASH_PATH, &tmp); xemu_settings_get_string(XEMU_SETTINGS_SYSTEM_FLASH_PATH, &tmp);
len = strlen(tmp); len = strlen(tmp);
assert(len < (MAX_STRING_LEN-1)); assert(len < MAX_STRING_LEN);
strncpy(flash_path, tmp, sizeof(flash_path)); strncpy(flash_path, tmp, sizeof(flash_path));
xemu_settings_get_string(XEMU_SETTINGS_SYSTEM_BOOTROM_PATH, &tmp); xemu_settings_get_string(XEMU_SETTINGS_SYSTEM_BOOTROM_PATH, &tmp);
len = strlen(tmp); len = strlen(tmp);
assert(len < (MAX_STRING_LEN-1)); assert(len < MAX_STRING_LEN);
strncpy(bootrom_path, tmp, sizeof(bootrom_path)); strncpy(bootrom_path, tmp, sizeof(bootrom_path));
xemu_settings_get_string(XEMU_SETTINGS_SYSTEM_HDD_PATH, &tmp); xemu_settings_get_string(XEMU_SETTINGS_SYSTEM_HDD_PATH, &tmp);
len = strlen(tmp); len = strlen(tmp);
assert(len < (MAX_STRING_LEN-1)); assert(len < MAX_STRING_LEN);
strncpy(hdd_path, tmp, sizeof(hdd_path)); strncpy(hdd_path, tmp, sizeof(hdd_path));
xemu_settings_get_string(XEMU_SETTINGS_SYSTEM_DVD_PATH, &tmp); xemu_settings_get_string(XEMU_SETTINGS_SYSTEM_DVD_PATH, &tmp);
len = strlen(tmp); len = strlen(tmp);
assert(len < (MAX_STRING_LEN-1)); assert(len < MAX_STRING_LEN);
strncpy(dvd_path, tmp, sizeof(dvd_path)); strncpy(dvd_path, tmp, sizeof(dvd_path));
xemu_settings_get_string(XEMU_SETTINGS_SYSTEM_EEPROM_PATH, &tmp); xemu_settings_get_string(XEMU_SETTINGS_SYSTEM_EEPROM_PATH, &tmp);
len = strlen(tmp); len = strlen(tmp);
assert(len < (MAX_STRING_LEN-1)); assert(len < MAX_STRING_LEN);
strncpy(eeprom_path, tmp, sizeof(eeprom_path)); strncpy(eeprom_path, tmp, sizeof(eeprom_path));
xemu_settings_get_int(XEMU_SETTINGS_SYSTEM_MEMORY, &tmp_int); xemu_settings_get_int(XEMU_SETTINGS_SYSTEM_MEMORY, &tmp_int);
@ -602,7 +611,7 @@ struct SettingsWindow
dirty = false; dirty = false;
} }
void Save(void) void Save()
{ {
xemu_settings_set_string(XEMU_SETTINGS_SYSTEM_FLASH_PATH, flash_path); xemu_settings_set_string(XEMU_SETTINGS_SYSTEM_FLASH_PATH, flash_path);
xemu_settings_set_string(XEMU_SETTINGS_SYSTEM_BOOTROM_PATH, bootrom_path); xemu_settings_set_string(XEMU_SETTINGS_SYSTEM_BOOTROM_PATH, bootrom_path);
@ -659,31 +668,31 @@ struct SettingsWindow
ImGui::NextColumn(); ImGui::NextColumn();
float picker_width = ImGui::GetColumnWidth()-120*g_ui_scale; float picker_width = ImGui::GetColumnWidth()-120*g_ui_scale;
ImGui::SetNextItemWidth(picker_width); ImGui::SetNextItemWidth(picker_width);
FilePicker("###Flash", flash_path, MAX_STRING_LEN, rom_file_filters); FilePicker("###Flash", flash_path, sizeof(flash_path), rom_file_filters);
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::Text("BootROM File"); ImGui::Text("BootROM File");
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::SetNextItemWidth(picker_width); ImGui::SetNextItemWidth(picker_width);
FilePicker("###BootROM", bootrom_path, MAX_STRING_LEN, rom_file_filters); FilePicker("###BootROM", bootrom_path, sizeof(bootrom_path), rom_file_filters);
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::Text("Hard Disk Image File"); ImGui::Text("Hard Disk Image File");
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::SetNextItemWidth(picker_width); ImGui::SetNextItemWidth(picker_width);
FilePicker("###HDD", hdd_path, MAX_STRING_LEN, qcow_file_filters); FilePicker("###HDD", hdd_path, sizeof(hdd_path), qcow_file_filters);
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::Text("DVD Image File"); ImGui::Text("DVD Image File");
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::SetNextItemWidth(picker_width); ImGui::SetNextItemWidth(picker_width);
FilePicker("###DVD", dvd_path, MAX_STRING_LEN, iso_file_filters); FilePicker("###DVD", dvd_path, sizeof(dvd_path), iso_file_filters);
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::Text("EEPROM File"); ImGui::Text("EEPROM File");
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::SetNextItemWidth(picker_width); ImGui::SetNextItemWidth(picker_width);
FilePicker("###EEPROM", eeprom_path, MAX_STRING_LEN, rom_file_filters); FilePicker("###EEPROM", eeprom_path, sizeof(eeprom_path), rom_file_filters);
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::Text("System Memory"); ImGui::Text("System Memory");
@ -726,11 +735,15 @@ struct SettingsWindow
} }
}; };
struct AboutWindow class AboutWindow
{ {
public:
bool is_open; bool is_open;
private:
char build_info_text[256]; char build_info_text[256];
public:
AboutWindow() AboutWindow()
{ {
snprintf(build_info_text, sizeof(build_info_text), snprintf(build_info_text, sizeof(build_info_text),
@ -786,109 +799,27 @@ struct AboutWindow
ImGui::SetCursorPosX(10*g_ui_scale); ImGui::SetCursorPosX(10*g_ui_scale);
ImGui::Dummy(ImVec2(0,20*g_ui_scale)); ImGui::Dummy(ImVec2(0,20*g_ui_scale));
const char *msg = "Visit https://xemu.app for more information"; const char *msg = "Visit https://xemu.app for more information";
float button_width = ImGui::GetStyle().FramePadding.x*2 + ImGui::CalcTextSize(msg).x; ImGui::SetCursorPosX((ImGui::GetWindowWidth()-ImGui::CalcTextSize(msg).x)/2);
ImGui::SetCursorPosX((ImGui::GetWindowWidth()-button_width)/2); ImGui::Text("%s", msg);
// ImGui::Text("%s", msg); if (ImGui::IsItemClicked()) {
if (ImGui::Button(msg, ImVec2(button_width, 0))) {
xemu_open_web_browser("https://xemu.app"); xemu_open_web_browser("https://xemu.app");
} }
ImGui::Dummy(ImVec2(0,40*g_ui_scale)); ImGui::Dummy(ImVec2(0,40*g_ui_scale));
ImGui::PushFont(g_fixed_width_font); ImGui::PushFont(g_fixed_width_font);
ImGui::InputTextMultiline("##build_info", build_info_text, IM_ARRAYSIZE(build_info_text), ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 6), ImGuiInputTextFlags_ReadOnly); ImGui::InputTextMultiline("##build_info", build_info_text, sizeof(build_info_text), ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 6), ImGuiInputTextFlags_ReadOnly);
ImGui::PopFont(); ImGui::PopFont();
if (ImGui::BeginPopupContextItem("##build_info_context", 1))
{
if (ImGui::MenuItem("Copy to Clipboard")) {
SDL_SetClipboardText(build_info_text);
}
ImGui::EndPopup();
}
ImGui::End(); ImGui::End();
} }
}; };
struct FirstBootWindow class NetworkWindow
{
bool is_open;
FirstBootWindow()
{
is_open = false;
}
~FirstBootWindow()
{
}
void Draw()
{
if (!is_open) return;
ImVec2 size(400*g_ui_scale, 300*g_ui_scale);
ImGuiIO& io = ImGui::GetIO();
ImVec2 window_pos = ImVec2((io.DisplaySize.x - size.x)/2, (io.DisplaySize.y - size.y)/2);
ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always);
ImGui::SetNextWindowSize(size, ImGuiCond_Appearing);
if (!ImGui::Begin("First Boot", &is_open, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoDecoration)) {
ImGui::End();
return;
}
static uint32_t time_start = 0;
if (ImGui::IsWindowAppearing()) {
time_start = SDL_GetTicks();
}
uint32_t now = SDL_GetTicks() - time_start;
ImGui::SetCursorPosY(ImGui::GetCursorPosY()-50*g_ui_scale);
ImGui::SetCursorPosX((ImGui::GetWindowWidth()-256*g_ui_scale)/2);
ImTextureID id = (ImTextureID)(intptr_t)render_to_fbo(logo_fbo);
float t_w = 256.0;
float t_h = 256.0;
float x_off = 0;
ImGui::Image(id,
ImVec2((t_w-x_off)*g_ui_scale, t_h*g_ui_scale),
ImVec2(x_off/t_w, t_h/t_h),
ImVec2(t_w/t_w, 0));
render_logo(now, 0x42e335ff, 0x42e335ff, 0x00000000);
render_to_default_fb();
ImGui::SetCursorPosX(10*g_ui_scale);
ImGui::SetCursorPosY(ImGui::GetCursorPosY()-75*g_ui_scale);
const char *msg = "To get started, please configure machine settings.";
ImGui::SetCursorPosX((ImGui::GetWindowWidth()-ImGui::CalcTextSize(msg).x)/2);
ImGui::Text("%s", msg);
ImGui::Dummy(ImVec2(0,20*g_ui_scale));
ImGui::SetCursorPosX((ImGui::GetWindowWidth()-120*g_ui_scale)/2);
if (ImGui::Button("Settings", ImVec2(120*g_ui_scale, 0))) {
// settings_window.is_open = true; // FIXME
}
ImGui::Dummy(ImVec2(0,20*g_ui_scale));
ImGui::SetCursorPosX(10*g_ui_scale);
msg = "Visit https://xemu.app for more information";
ImGui::SetCursorPosY(ImGui::GetWindowHeight()-ImGui::CalcTextSize(msg).y-10*g_ui_scale);
ImGui::SetCursorPosX((ImGui::GetWindowWidth()-ImGui::CalcTextSize(msg).x)/2);
ImGui::Text("%s", msg);
ImGui::End();
}
};
struct NetworkWindow
{ {
public:
bool is_open; bool is_open;
char remote_addr[64]; char remote_addr[64];
char local_addr[64]; char local_addr[64];
@ -922,8 +853,6 @@ struct NetworkWindow
strncpy(local_addr, tmp, sizeof(local_addr)-1); strncpy(local_addr, tmp, sizeof(local_addr)-1);
} }
bool is_enabled = xemu_net_is_enabled();
ImGui::TextWrapped( ImGui::TextWrapped(
"xemu socket networking works by sending and receiving packets over " "xemu socket networking works by sending and receiving packets over "
"UDP which encapsulate the network traffic that the machine would " "UDP which encapsulate the network traffic that the machine would "
@ -938,6 +867,7 @@ struct NetworkWindow
ImGui::SetColumnWidth(0, ImGui::GetWindowWidth()*0.33); ImGui::SetColumnWidth(0, ImGui::GetWindowWidth()*0.33);
ImGuiInputTextFlags flg = 0; ImGuiInputTextFlags flg = 0;
bool is_enabled = xemu_net_is_enabled();
if (is_enabled) { if (is_enabled) {
flg |= ImGuiInputTextFlags_ReadOnly; flg |= ImGuiInputTextFlags_ReadOnly;
} }
@ -987,27 +917,6 @@ struct NetworkWindow
} }
}; };
#ifdef WIN32
// https://stackoverflow.com/a/2513561
#include <windows.h>
unsigned long long getTotalSystemMemory()
{
MEMORYSTATUSEX status;
status.dwLength = sizeof(status);
GlobalMemoryStatusEx(&status);
return status.ullTotalPhys / (1024 * 1024);
}
#else
#include <unistd.h>
unsigned long long getTotalSystemMemory()
{
long pages = sysconf(_SC_PHYS_PAGES);
long page_size = sysconf(_SC_PAGE_SIZE);
return pages * page_size / (1024 * 1024);
}
#endif
#ifdef CONFIG_CPUID_H #ifdef CONFIG_CPUID_H
#include <cpuid.h> #include <cpuid.h>
#endif #endif
@ -1028,8 +937,9 @@ const char *get_cpu_info(void)
return cpu_info; return cpu_info;
} }
struct CompatibilityReporter class CompatibilityReporter
{ {
public:
bool is_open; bool is_open;
CompatibilityReporter() CompatibilityReporter()
@ -1089,7 +999,6 @@ struct CompatibilityReporter
"OS: %s\n" "OS: %s\n"
"CPU: %s\n" "CPU: %s\n"
"GPU: %s\n" "GPU: %s\n"
"Memory: %lld M\n"
"XBE: %s", "XBE: %s",
xemu_version, xemu_version,
xemu_branch, xemu_branch,
@ -1097,7 +1006,6 @@ struct CompatibilityReporter
xemu_get_os_info(), xemu_get_os_info(),
get_cpu_info(), get_cpu_info(),
gpu_info, gpu_info,
getTotalSystemMemory(),
xbe_info xbe_info
); );
@ -1152,7 +1060,7 @@ struct CompatibilityReporter
ImGui::Text("Additional Information"); ImGui::Text("Additional Information");
ImGui::PushFont(g_fixed_width_font); ImGui::PushFont(g_fixed_width_font);
ImGui::InputTextMultiline("##build_info", report_info, IM_ARRAYSIZE(report_info), ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 7), ImGuiInputTextFlags_ReadOnly); ImGui::InputTextMultiline("##build_info", report_info, sizeof(report_info), ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 7), ImGuiInputTextFlags_ReadOnly);
ImGui::PopFont(); ImGui::PopFont();
ImGui::Columns(1); ImGui::Columns(1);
@ -1171,13 +1079,96 @@ struct CompatibilityReporter
static MonitorWindow monitor_window; static MonitorWindow monitor_window;
static InputWindow input_window; static InputWindow input_window;
static NetworkWindow network_window; static NetworkWindow network_window;
static FirstBootWindow first_boot_window;
static AboutWindow about_window; static AboutWindow about_window;
static SettingsWindow settings_window; static SettingsWindow settings_window;
static CompatibilityReporter compatibility_reporter_window; static CompatibilityReporter compatibility_reporter_window;
static NotificationManager notification_manager; static NotificationManager notification_manager;
static std::deque<const char *> g_errors; static std::deque<const char *> g_errors;
class FirstBootWindow
{
public:
bool is_open;
FirstBootWindow()
{
is_open = false;
}
~FirstBootWindow()
{
}
void Draw()
{
if (!is_open) return;
ImVec2 size(400*g_ui_scale, 300*g_ui_scale);
ImGuiIO& io = ImGui::GetIO();
ImVec2 window_pos = ImVec2((io.DisplaySize.x - size.x)/2, (io.DisplaySize.y - size.y)/2);
ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always);
ImGui::SetNextWindowSize(size, ImGuiCond_Appearing);
if (!ImGui::Begin("First Boot", &is_open, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoDecoration)) {
ImGui::End();
return;
}
static uint32_t time_start = 0;
if (ImGui::IsWindowAppearing()) {
time_start = SDL_GetTicks();
}
uint32_t now = SDL_GetTicks() - time_start;
ImGui::SetCursorPosY(ImGui::GetCursorPosY()-50*g_ui_scale);
ImGui::SetCursorPosX((ImGui::GetWindowWidth()-256*g_ui_scale)/2);
ImTextureID id = (ImTextureID)(intptr_t)render_to_fbo(logo_fbo);
float t_w = 256.0;
float t_h = 256.0;
float x_off = 0;
ImGui::Image(id,
ImVec2((t_w-x_off)*g_ui_scale, t_h*g_ui_scale),
ImVec2(x_off/t_w, t_h/t_h),
ImVec2(t_w/t_w, 0));
if (ImGui::IsItemClicked()) {
time_start = SDL_GetTicks();
}
render_logo(now, 0x42e335ff, 0x42e335ff, 0x00000000);
render_to_default_fb();
ImGui::SetCursorPosY(ImGui::GetCursorPosY()-100*g_ui_scale);
ImGui::SetCursorPosX((ImGui::GetWindowWidth()-ImGui::CalcTextSize(xemu_version).x)/2);
ImGui::Text("%s", xemu_version);
ImGui::SetCursorPosX(10*g_ui_scale);
ImGui::Dummy(ImVec2(0,20*g_ui_scale));
const char *msg = "To get started, please configure machine settings.";
ImGui::SetCursorPosX((ImGui::GetWindowWidth()-ImGui::CalcTextSize(msg).x)/2);
ImGui::Text("%s", msg);
ImGui::Dummy(ImVec2(0,20*g_ui_scale));
ImGui::SetCursorPosX((ImGui::GetWindowWidth()-120*g_ui_scale)/2);
if (ImGui::Button("Settings", ImVec2(120*g_ui_scale, 0))) {
settings_window.is_open = true; // FIXME
}
ImGui::Dummy(ImVec2(0,20*g_ui_scale));
msg = "Visit https://xemu.app for more information";
ImGui::SetCursorPosX((ImGui::GetWindowWidth()-ImGui::CalcTextSize(msg).x)/2);
ImGui::Text("%s", msg);
if (ImGui::IsItemClicked()) {
xemu_open_web_browser("https://xemu.app");
}
ImGui::End();
}
};
static void ShowMainMenu() static void ShowMainMenu()
{ {
bool running = runstate_is_running(); bool running = runstate_is_running();
@ -1293,7 +1284,7 @@ static void InitializeStyle()
ImVec4* colors = ImGui::GetStyle().Colors; ImVec4* colors = ImGui::GetStyle().Colors;
colors[ImGuiCol_Text] = ImVec4(0.86f, 0.93f, 0.89f, 0.78f); colors[ImGuiCol_Text] = ImVec4(0.86f, 0.93f, 0.89f, 0.78f);
colors[ImGuiCol_TextDisabled] = ImVec4(0.86f, 0.93f, 0.89f, 0.28f); colors[ImGuiCol_TextDisabled] = ImVec4(0.86f, 0.93f, 0.89f, 0.28f);
colors[ImGuiCol_WindowBg] = ImVec4(0.06f, 0.06f, 0.06f, 250.0/255.0); colors[ImGuiCol_WindowBg] = ImVec4(0.06f, 0.06f, 0.06f, 0.98f);
colors[ImGuiCol_ChildBg] = ImVec4(0.16f, 0.16f, 0.16f, 0.58f); colors[ImGuiCol_ChildBg] = ImVec4(0.16f, 0.16f, 0.16f, 0.58f);
colors[ImGuiCol_PopupBg] = ImVec4(0.16f, 0.16f, 0.16f, 0.90f); colors[ImGuiCol_PopupBg] = ImVec4(0.16f, 0.16f, 0.16f, 0.90f);
colors[ImGuiCol_Border] = ImVec4(0.11f, 0.11f, 0.11f, 0.60f); colors[ImGuiCol_Border] = ImVec4(0.11f, 0.11f, 0.11f, 0.60f);
@ -1342,6 +1333,7 @@ static void InitializeStyle()
} }
/* External interface, called from ui/xemu.c which handles SDL main loop */ /* External interface, called from ui/xemu.c which handles SDL main loop */
static FirstBootWindow first_boot_window;
static SDL_Window *g_sdl_window; static SDL_Window *g_sdl_window;
void xemu_hud_init(SDL_Window* window, void* sdl_gl_context) void xemu_hud_init(SDL_Window* window, void* sdl_gl_context)
@ -1360,8 +1352,7 @@ void xemu_hud_init(SDL_Window* window, void* sdl_gl_context)
// Setup Platform/Renderer bindings // Setup Platform/Renderer bindings
ImGui_ImplSDL2_InitForOpenGL(window, sdl_gl_context); ImGui_ImplSDL2_InitForOpenGL(window, sdl_gl_context);
const char *glsl_version = "#version 150"; ImGui_ImplOpenGL3_Init("#version 150");
ImGui_ImplOpenGL3_Init(glsl_version);
first_boot_window.is_open = xemu_settings_did_fail_to_load(); first_boot_window.is_open = xemu_settings_did_fail_to_load();

View File

@ -102,9 +102,9 @@ void xemu_run_monitor_command(const char *cmd)
int len = strlen(cmd)+1; int len = strlen(cmd)+1;
/* FIXME: qemu_chr_be_write needs to be fixed to declare inbuf as const. It /* FIXME: qemu_chr_be_write needs to be fixed to declare inbuf as const. It
* does not modify the data. Accept the warning for now as a reminder. * does not modify the data. Cast for now.
*/ */
qemu_chr_be_write(mon_chr, cmd, len); qemu_chr_be_write(mon_chr, (unsigned char*)cmd, len);
} }
static const TypeInfo char_xemu_type_info = { static const TypeInfo char_xemu_type_info = {

View File

@ -69,6 +69,10 @@ const char *xemu_get_os_info(void)
void xemu_open_web_browser(const char *url) void xemu_open_web_browser(const char *url)
{ {
char *cmd = g_strdup_printf("xdg-open %s", url); char *cmd = g_strdup_printf("xdg-open %s", url);
system(cmd); int status = system(cmd);
if (status < 0) {
fprintf(stderr, "Failed to run: %s\n", cmd);
}
free(cmd); free(cmd);
} }

View File

@ -1420,9 +1420,8 @@ static void post_swap(void)
} }
} }
// #undef main int main(int argc, char **argv)
{
int main(int argc, char **argv) {
QemuThread thread; QemuThread thread;
DPRINTF("Entered main()\n"); DPRINTF("Entered main()\n");