Skip to content

Commit

Permalink
Window position and size is now correctly saved. (HarbourMasters#288)
Browse files Browse the repository at this point in the history
* Window now saves it's position.

* Windows now save their position and size.

* Runs clang-format
  • Loading branch information
Kenix3 authored May 24, 2023
1 parent 07a7592 commit ce43d0b
Show file tree
Hide file tree
Showing 13 changed files with 139 additions and 77 deletions.
10 changes: 8 additions & 2 deletions src/Context.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "Context.h"
#include "controller/KeyboardScancodes.h"
#include <iostream>
#include <spdlog/async.h>
#include <spdlog/sinks/rotating_file_sink.h>
Expand All @@ -23,12 +24,14 @@ Context::~Context() {
SPDLOG_TRACE("destruct context");
// Explicitly destructing everything so that logging is done last.
mAudio = nullptr;
GetWindow()->SaveWindowSizeToConfig(GetConfig());
mWindow = nullptr;
mConsole = nullptr;
mCrashHandler = nullptr;
mControlDeck = nullptr;
mResourceManager = nullptr;
mConsoleVariables = nullptr;
GetConfig()->Save();
mConfig = nullptr;
spdlog::shutdown();
}
Expand Down Expand Up @@ -58,6 +61,8 @@ void Context::CreateDefaultSettings() {
if (GetConfig()->IsNewInstance()) {
GetConfig()->SetInt("Window.Width", 640);
GetConfig()->SetInt("Window.Height", 480);
GetConfig()->SetInt("Window.PositionX", 100);
GetConfig()->SetInt("Window.PositionY", 100);

GetConfig()->SetString("Window.GfxBackend", "");
GetConfig()->SetString("Window.GfxApi", "");
Expand All @@ -71,8 +76,9 @@ void Context::CreateDefaultSettings() {
GetConfig()->SetString("Game.Main Archive", "");
GetConfig()->SetString("Game.Patches Archive", "");

GetConfig()->SetInt("Shortcuts.Fullscreen", 0x044);
GetConfig()->SetInt("Shortcuts.Console", 0x029);
GetConfig()->SetInt("Shortcuts.Fullscreen", KbScancode::LUS_KB_F9);
GetConfig()->SetInt("Shortcuts.Console", KbScancode::LUS_KB_OEM_3);

GetConfig()->Save();
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/controller/KeyboardScancodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ typedef enum KbScancode {
LUS_KB_F7 = 65,
LUS_KB_F8 = 66,
LUS_KB_F9 = 67,
LUS_KB_F10 = 68,
LUS_KB_F10 = 68, // Generally inadvised to use this as it's a windows system key.
LUS_KB_PAUSE = 69,
LUS_KB_SCROLL = 70,
LUS_KB_NUMPAD7 = 71,
Expand Down
58 changes: 33 additions & 25 deletions src/graphic/Fast3D/gfx_dxgi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ static struct {
HWND h_wnd;
bool in_paint;
bool recursive_paint_detected;
uint32_t current_width, current_height;

// These four only apply in windowed mode.
uint32_t current_width, current_height; // Width and height of client areas
int32_t posX, posY; // Screen coordinates

std::string game_name;
bool is_running = true;

Expand All @@ -52,7 +56,6 @@ static struct {

bool process_dpi_awareness_done;

RECT last_window_rect;
bool is_full_screen, last_maximized_state;

bool dxgi1_4;
Expand Down Expand Up @@ -170,16 +173,22 @@ static void toggle_borderless_window_full_screen(bool enable, bool call_callback
}

if (!enable) {
RECT r = dxgi.last_window_rect;

// Set in window mode with the last saved position and size
SetWindowLongPtr(dxgi.h_wnd, GWL_STYLE, WS_VISIBLE | WS_OVERLAPPEDWINDOW);

if (dxgi.last_maximized_state) {
SetWindowPos(dxgi.h_wnd, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE);
ShowWindow(dxgi.h_wnd, SW_MAXIMIZE);
} else {
SetWindowPos(dxgi.h_wnd, NULL, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_FRAMECHANGED);
auto conf = LUS::Context::GetInstance()->GetConfig();
dxgi.current_width = conf->GetInt("Window.Width", 640);
dxgi.current_height = conf->GetInt("Window.Height", 480);
dxgi.posX = conf->GetInt("Window.PositionX", 100);
dxgi.posY = conf->GetInt("Window.PositionY", 100);
RECT wr = { dxgi.posX, dxgi.posY, dxgi.posX + static_cast<int32_t>(dxgi.current_width),
dxgi.posY + static_cast<int32_t>(dxgi.current_height) };
AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
SetWindowPos(dxgi.h_wnd, NULL, wr.left, wr.top, wr.right - wr.left, wr.bottom - wr.top, SWP_FRAMECHANGED);
ShowWindow(dxgi.h_wnd, SW_RESTORE);
}

Expand All @@ -191,9 +200,6 @@ static void toggle_borderless_window_full_screen(bool enable, bool call_callback
GetWindowPlacement(dxgi.h_wnd, &window_placement);
dxgi.last_maximized_state = window_placement.showCmd == SW_SHOWMAXIMIZED;

// Save window position and size if the window is not maximized
GetWindowRect(dxgi.h_wnd, &dxgi.last_window_rect);

// Get in which monitor the window is
HMONITOR h_monitor = MonitorFromWindow(dxgi.h_wnd, MONITOR_DEFAULTTONEAREST);

Expand All @@ -205,8 +211,10 @@ static void toggle_borderless_window_full_screen(bool enable, bool call_callback

// Set borderless full screen to that monitor
SetWindowLongPtr(dxgi.h_wnd, GWL_STYLE, WS_VISIBLE | WS_POPUP);
// OTRTODO: This should be setting the resolution from config.
dxgi.current_width = r.right - r.left;
dxgi.current_height = r.bottom - r.top;
SetWindowPos(dxgi.h_wnd, HWND_TOP, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_FRAMECHANGED);

dxgi.is_full_screen = true;
}

Expand Down Expand Up @@ -235,8 +243,12 @@ static LRESULT CALLBACK gfx_dxgi_wnd_proc(HWND h_wnd, UINT message, WPARAM w_par
LUS::Context::GetInstance()->GetWindow()->GetGui()->Update(event_impl);
switch (message) {
case WM_SIZE:
dxgi.current_width = (uint32_t)(l_param & 0xffff);
dxgi.current_height = (uint32_t)(l_param >> 16);
dxgi.current_width = LOWORD(l_param);
dxgi.current_height = HIWORD(l_param);
break;
case WM_MOVE:
dxgi.posX = LOWORD(l_param);
dxgi.posY = HIWORD(l_param);
break;
case WM_DESTROY:
PostQuitMessage(0);
Expand Down Expand Up @@ -275,21 +287,14 @@ static LRESULT CALLBACK gfx_dxgi_wnd_proc(HWND h_wnd, UINT message, WPARAM w_par
CVarSetInteger("gNewFileDropped", 1);
CVarSave();
break;
case WM_SYSKEYDOWN:
if ((w_param == VK_RETURN) && ((l_param & 1 << 30) == 0)) {
toggle_borderless_window_full_screen(!dxgi.is_full_screen, true);
break;
} else {
return DefWindowProcW(h_wnd, message, w_param, l_param);
}
default:
return DefWindowProcW(h_wnd, message, w_param, l_param);
}
return 0;
}

void gfx_dxgi_init(const char* game_name, const char* gfx_api_name, bool start_in_fullscreen, uint32_t width,
uint32_t height) {
uint32_t height, int32_t posX, int32_t posY) {
LARGE_INTEGER qpc_init, qpc_freq;
QueryPerformanceCounter(&qpc_init);
QueryPerformanceFrequency(&qpc_freq);
Expand Down Expand Up @@ -331,9 +336,12 @@ void gfx_dxgi_init(const char* game_name, const char* gfx_api_name, bool start_i
// We need to be dpi aware when calculating the size
RECT wr = { 0, 0, width, height };
AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);

dxgi.h_wnd = CreateWindowW(WINCLASS_NAME, w_title, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, wr.right - wr.left,
wr.bottom - wr.top, nullptr, nullptr, nullptr, nullptr);
dxgi.current_width = wr.right - wr.left;
dxgi.current_height = wr.bottom - wr.top;
dxgi.posX = posX;
dxgi.posY = posY;
dxgi.h_wnd = CreateWindowW(WINCLASS_NAME, w_title, WS_OVERLAPPEDWINDOW, dxgi.posX + wr.left, dxgi.posY + wr.top,
dxgi.current_width, dxgi.current_height, nullptr, nullptr, nullptr, nullptr);
});

load_dxgi_library();
Expand Down Expand Up @@ -398,9 +406,11 @@ static void gfx_dxgi_main_loop(void (*run_one_game_iter)(void)) {
}
}

static void gfx_dxgi_get_dimensions(uint32_t* width, uint32_t* height) {
static void gfx_dxgi_get_dimensions(uint32_t* width, uint32_t* height, int32_t* posX, int32_t* posY) {
*width = dxgi.current_width;
*height = dxgi.current_height;
*posX = dxgi.posX;
*posY = dxgi.posY;
}

static void gfx_dxgi_handle_events(void) {
Expand Down Expand Up @@ -726,8 +736,6 @@ void gfx_dxgi_create_swap_chain(IUnknown* device, std::function<void()>&& before
apply_maximum_frame_latency(true);

ThrowIfFailed(dxgi.swap_chain->GetDesc1(&swap_chain_desc));
dxgi.current_width = swap_chain_desc.Width;
dxgi.current_height = swap_chain_desc.Height;

dxgi.swap_chain_device = device;
dxgi.before_destroy_swap_chain_fn = std::move(before_destroy_fn);
Expand Down
13 changes: 6 additions & 7 deletions src/graphic/Fast3D/gfx_glx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ static bool gfx_glx_check_extension(const char* extensions, const char* extensio
}

static void gfx_glx_init(const char* game_name, const char* gfx_api_name, bool start_in_fullscreen, u_int32_t width,
uint32_t height) {
uint32_t height, int32_t posX, int32_t posY) {
// On NVIDIA proprietary driver, make the driver queue up to two frames on glXSwapBuffers,
// which means that glXSwapBuffers should be non-blocking,
// if we are sure to wait at least one vsync interval between calls.
Expand All @@ -232,8 +232,8 @@ static void gfx_glx_init(const char* game_name, const char* gfx_api_name, bool s
XSetWindowAttributes swa;
swa.colormap = cmap;
swa.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | FocusChangeMask;
glx.win = XCreateWindow(glx.dpy, glx.root, 0, 0, DESIRED_SCREEN_WIDTH, DESIRED_SCREEN_HEIGHT, 0, vi->depth,
InputOutput, vi->visual, CWColormap | CWEventMask, &swa);
glx.win = XCreateWindow(glx.dpy, glx.root, posX, posY, width, height, 0, vi->depth, InputOutput, vi->visual,
CWColormap | CWEventMask, &swa);

glx.atom_wm_state = XInternAtom(glx.dpy, "_NET_WM_STATE", False);
glx.atom_wm_state_fullscreen = XInternAtom(glx.dpy, "_NET_WM_STATE_FULLSCREEN", False);
Expand Down Expand Up @@ -327,11 +327,13 @@ static void gfx_glx_main_loop(void (*run_one_game_iter)(void)) {
}
}

static void gfx_glx_get_dimensions(uint32_t* width, uint32_t* height) {
static void gfx_glx_get_dimensions(uint32_t* width, uint32_t* height, int32_t* posX, int32_t* posY) {
XWindowAttributes attributes;
XGetWindowAttributes(glx.dpy, glx.win, &attributes);
*width = attributes.width;
*height = attributes.height;
*posX = attributes.x;
*posY = attributes.y;
}

static void gfx_glx_handle_events(void) {
Expand All @@ -348,9 +350,6 @@ static void gfx_glx_handle_events(void) {
int scancode = glx.keymap[xev.xkey.keycode];
if (scancode != 0) {
if (xev.type == KeyPress) {
if (scancode == 0x44) { // F10
gfx_glx_set_fullscreen_state(!glx.is_fullscreen, true);
}
if (glx.on_key_down != NULL) {
glx.on_key_down(scancode);
}
Expand Down
13 changes: 8 additions & 5 deletions src/graphic/Fast3D/gfx_pc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ static struct RenderingState {
} rendering_state;

struct GfxDimensions gfx_current_window_dimensions;
int32_t gfx_current_window_position_x;
int32_t gfx_current_window_position_y;
struct GfxDimensions gfx_current_dimensions;
static struct GfxDimensions gfx_prev_dimensions;
struct XYWidthHeight gfx_current_game_window_viewport;
Expand Down Expand Up @@ -3027,15 +3029,15 @@ static void gfx_sp_reset() {
rsp.lights_changed = true;
}

void gfx_get_dimensions(uint32_t* width, uint32_t* height) {
gfx_wapi->get_dimensions(width, height);
void gfx_get_dimensions(uint32_t* width, uint32_t* height, int32_t* posX, int32_t* posY) {
gfx_wapi->get_dimensions(width, height, posX, posY);
}

void gfx_init(struct GfxWindowManagerAPI* wapi, struct GfxRenderingAPI* rapi, const char* game_name,
bool start_in_fullscreen, uint32_t width, uint32_t height) {
bool start_in_fullscreen, uint32_t width, uint32_t height, uint32_t posX, uint32_t posY) {
gfx_wapi = wapi;
gfx_rapi = rapi;
gfx_wapi->init(game_name, rapi->get_name(), start_in_fullscreen, width, height);
gfx_wapi->init(game_name, rapi->get_name(), start_in_fullscreen, width, height, posX, posY);
gfx_rapi->init();
gfx_rapi->update_framebuffer_parameters(0, width, height, 1, false, true, true, true);
#ifdef __APPLE__
Expand Down Expand Up @@ -3078,7 +3080,8 @@ struct GfxRenderingAPI* gfx_get_current_rendering_api(void) {

void gfx_start_frame(void) {
gfx_wapi->handle_events();
gfx_wapi->get_dimensions(&gfx_current_window_dimensions.width, &gfx_current_window_dimensions.height);
gfx_wapi->get_dimensions(&gfx_current_window_dimensions.width, &gfx_current_window_dimensions.height,
&gfx_current_window_position_x, &gfx_current_window_position_y);
LUS::Context::GetInstance()->GetWindow()->GetGui()->DrawMenu();
has_drawn_imgui_menu = true;
if (gfx_current_dimensions.height == 0) {
Expand Down
3 changes: 2 additions & 1 deletion src/graphic/Fast3D/gfx_pc.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ extern uint32_t gfx_msaa_level;
}

void gfx_init(struct GfxWindowManagerAPI* wapi, struct GfxRenderingAPI* rapi, const char* game_name,
bool start_in_fullscreen, uint32_t width = SCREEN_WIDTH, uint32_t height = SCREEN_HEIGHT);
bool start_in_fullscreen, uint32_t width = SCREEN_WIDTH, uint32_t height = SCREEN_HEIGHT,
uint32_t posX = 100, uint32_t posY = 100);
void gfx_destroy(void);
struct GfxRenderingAPI* gfx_get_current_rendering_api(void);
void gfx_start_frame(void);
Expand Down
23 changes: 16 additions & 7 deletions src/graphic/Fast3D/gfx_sdl2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ static SDL_GLContext ctx;
static SDL_Renderer* renderer;
static int sdl_to_lus_table[512];
static bool vsync_enabled = false;
// OTRTODO: These are redundant. Info can be queried from SDL.
static int window_width = DESIRED_SCREEN_WIDTH;
static int window_height = DESIRED_SCREEN_HEIGHT;
static bool fullscreen_state;
Expand Down Expand Up @@ -225,14 +226,19 @@ static void set_fullscreen(bool on, bool call_callback) {
fullscreen_state = on;

if (on) {
// OTRTODO: Get mode from config.
SDL_DisplayMode mode;
SDL_GetDesktopDisplayMode(0, &mode);
window_width = mode.w;
window_height = mode.h;
SDL_ShowCursor(false);
} else {
window_width = DESIRED_SCREEN_WIDTH;
window_height = DESIRED_SCREEN_HEIGHT;
auto conf = LUS::Context::GetInstance()->GetConfig();
window_width = conf->GetInt("Window.Width", 640);
window_height = conf->GetInt("Window.Height", 480);
int32_t posX = conf->GetInt("Window.PositionX", 100);
int32_t posY = conf->GetInt("Window.PositionY", 100);
SDL_SetWindowPosition(wnd, posX, posY);
}
SDL_SetWindowSize(wnd, window_width, window_height);
SDL_SetWindowFullscreen(
Expand Down Expand Up @@ -264,7 +270,10 @@ static int target_fps = 60;
#define FRAME_INTERVAL_US_DENOMINATOR (target_fps)

static void gfx_sdl_init(const char* game_name, const char* gfx_api_name, bool start_in_fullscreen, uint32_t width,
uint32_t height) {
uint32_t height, int32_t posX, int32_t posY) {
window_width = width;
window_height = height;

SDL_Init(SDL_INIT_VIDEO);

SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
Expand Down Expand Up @@ -315,7 +324,7 @@ static void gfx_sdl_init(const char* game_name, const char* gfx_api_name, bool s
flags = flags | SDL_WINDOW_METAL;
}

wnd = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, flags);
wnd = SDL_CreateWindow(title, posX, posY, window_width, window_height, flags);
LUS::GuiWindowInitData window_impl;

if (use_opengl) {
Expand Down Expand Up @@ -413,9 +422,9 @@ static void gfx_sdl_main_loop(void (*run_one_game_iter)(void)) {
SDL_Quit();
}

static void gfx_sdl_get_dimensions(uint32_t* width, uint32_t* height) {
*width = window_width;
*height = window_height;
static void gfx_sdl_get_dimensions(uint32_t* width, uint32_t* height, int32_t* posX, int32_t* posY) {
SDL_GL_GetDrawableSize(wnd, static_cast<int*>((void*)width), static_cast<int*>((void*)height));
SDL_GetWindowPosition(wnd, static_cast<int*>(posX), static_cast<int*>(posY));
}

static int translate_scancode(int scancode) {
Expand Down
6 changes: 4 additions & 2 deletions src/graphic/Fast3D/gfx_wiiu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ static uint32_t gfx_wiiu_proc_callback_released(void* context) {
}

static void gfx_wiiu_init(const char* game_name, const char* gfx_api_name, bool start_in_fullscreen, uint32_t width,
uint32_t height) {
uint32_t height, int32_t posX, int32_t posY) {
WHBProcInit();

uint32_t mem1_addr, mem1_size;
Expand Down Expand Up @@ -365,9 +365,11 @@ static void gfx_wiiu_main_loop(void (*run_one_game_iter)(void)) {
WHBProcShutdown();
}

static void gfx_wiiu_get_dimensions(uint32_t* width, uint32_t* height) {
static void gfx_wiiu_get_dimensions(uint32_t* width, uint32_t* height, int32_t* posX, int32_t* posY) {
*width = WIIU_DEFAULT_FB_WIDTH;
*height = WIIU_DEFAULT_FB_HEIGHT;
*posX = 0;
*posY = 0;
}

static void gfx_wiiu_handle_events(void) {
Expand Down
4 changes: 2 additions & 2 deletions src/graphic/Fast3D/gfx_window_manager_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

struct GfxWindowManagerAPI {
void (*init)(const char* game_name, const char* gfx_api_name, bool start_in_fullscreen, uint32_t width,
uint32_t height);
uint32_t height, int32_t posX, int32_t posY);
void (*close)(void);
void (*set_keyboard_callbacks)(bool (*on_key_down)(int scancode), bool (*on_key_up)(int scancode),
void (*on_all_keys_up)(void));
Expand All @@ -15,7 +15,7 @@ struct GfxWindowManagerAPI {
void (*get_active_window_refresh_rate)(uint32_t* refresh_rate);
void (*set_cursor_visibility)(bool visible);
void (*main_loop)(void (*run_one_game_iter)(void));
void (*get_dimensions)(uint32_t* width, uint32_t* height);
void (*get_dimensions)(uint32_t* width, uint32_t* height, int32_t* posX, int32_t* posY);
void (*handle_events)(void);
bool (*start_frame)(void);
void (*swap_buffers_begin)(void);
Expand Down
Loading

0 comments on commit ce43d0b

Please sign in to comment.