window.fullscreen, window.allow_resize

This commit is contained in:
Charlie Malmqvist 2024-08-23 14:09:45 +02:00
parent ff654859a0
commit 884d28add0
5 changed files with 129 additions and 35 deletions

View file

@ -1,5 +1,12 @@
## v0.01.005
- Window
- Added bool window.fullscreen
- Added bool window.allow_resize
- Reworked window initialization
Window now starts of invisible and is made visible on first os_update().
This also gets rid of the weird window resize and reposition at startup.
## v0.01.004 - Gamepad input, text wrapping, bug fixes
- Input

View file

@ -7,7 +7,8 @@ int entry(int argc, char **argv) {
window.x = 200;
window.y = 90;
window.clear_color = hex_to_rgba(0x6495EDff);
window.allow_resize = true;
float64 last_time = os_get_elapsed_seconds();
while (!window.should_close) {
reset_temporary_storage();
@ -29,6 +30,10 @@ int entry(int argc, char **argv) {
draw_line(v2(-.75, -.75), v2(mx, my), 0.005, COLOR_WHITE);
if (is_key_just_pressed('F')) {
window.fullscreen = !window.fullscreen;
}
os_update();
gfx_update();
}

View file

@ -231,29 +231,19 @@ void d3d11_update_swapchain() {
if (d3d11_window_render_target_view) D3D11Release(d3d11_window_render_target_view);
if (d3d11_back_buffer) D3D11Release(d3d11_back_buffer);
RECT client_rect;
bool ok = GetClientRect(window._os_handle, &client_rect);
assert(ok, "GetClientRect failed with error code %lu", GetLastError());
u32 window_width = client_rect.right-client_rect.left;
u32 window_height = client_rect.bottom-client_rect.top;
hr = IDXGISwapChain1_ResizeBuffers(d3d11_swap_chain, d3d11_swap_chain_desc.BufferCount, window_width, window_height, d3d11_swap_chain_desc.Format, d3d11_swap_chain_desc.Flags);
hr = IDXGISwapChain1_ResizeBuffers(d3d11_swap_chain, d3d11_swap_chain_desc.BufferCount, window.pixel_width, window.pixel_height, d3d11_swap_chain_desc.Format, d3d11_swap_chain_desc.Flags);
d3d11_check_hr(hr);
// update swap chain description
hr = IDXGISwapChain1_GetDesc1(d3d11_swap_chain, &d3d11_swap_chain_desc);
d3d11_check_hr(hr);
log("Resized swap chain from %dx%d to %dx%d", d3d11_swap_chain_width, d3d11_swap_chain_height, window_width, window_height);
log("Resized swap chain from %dx%d to %dx%d", d3d11_swap_chain_width, d3d11_swap_chain_height, window.pixel_width, window.pixel_height);
d3d11_swap_chain_width = window_width;
d3d11_swap_chain_height = window_height;
d3d11_swap_chain_width = window.pixel_width;
d3d11_swap_chain_height = window.pixel_height;
}
hr = IDXGISwapChain1_GetBuffer(d3d11_swap_chain, 0, &IID_ID3D11Texture2D, (void**)&d3d11_back_buffer);
d3d11_check_hr(hr);
hr = ID3D11Device_CreateRenderTargetView(d3d11_device, (ID3D11Resource*)d3d11_back_buffer, 0, &d3d11_window_render_target_view);
@ -858,12 +848,7 @@ void gfx_update() {
HRESULT hr;
///
// Maybe resize swap chain
RECT client_rect;
bool ok = GetClientRect(window._os_handle, &client_rect);
assert(ok, "GetClientRect failed with error code %lu", GetLastError());
u32 window_width = client_rect.right-client_rect.left;
u32 window_height = client_rect.bottom-client_rect.top;
if (window_width != d3d11_swap_chain_width || window_height != d3d11_swap_chain_height) {
if (window.pixel_width != d3d11_swap_chain_width || window.pixel_height != d3d11_swap_chain_height) {
d3d11_update_swapchain();
}

View file

@ -113,6 +113,15 @@ SYSTEM_INFO win32_system_info;
LARGE_INTEGER win32_counter_at_start;
bool win32_do_handle_raw_input = false;
HANDLE win32_xinput = 0;
bool has_os_update_been_called_at_all = false;
// Used to save windowed state when in fullscreen mode.
DWORD win32_windowed_style = 0;
DWORD win32_windowed_style_ex = 0;
s32 win32_windowed_x = 0;
s32 win32_windowed_y = 0;
s32 win32_windowed_width = 0;
s32 win32_windowed_height = 0;
// impl input.c
const u64 MAX_NUMBER_OF_GAMEPADS = XUSER_MAX_COUNT;
@ -319,15 +328,15 @@ win32_init_window() {
RECT rect = {0, 0, window.width, window.height};
DWORD style = WS_OVERLAPPEDWINDOW;
DWORD ex_style = WS_EX_CLIENTEDGE;
ok = AdjustWindowRectEx(&rect, style, FALSE, ex_style);
DWORD style_ex = WS_EX_CLIENTEDGE;
ok = AdjustWindowRectEx(&rect, style, FALSE, style_ex);
assert(ok != 0, "AdjustWindowRectEx failed with error code %lu", GetLastError());
u32 actual_window_width = rect.right - rect.left;
u32 actual_window_height = rect.bottom - rect.top;
// Create the window
window._os_handle = CreateWindowEx(
ex_style,
style_ex,
"sigma balls",
temp_convert_to_null_terminated_string(window.title),
style,
@ -335,8 +344,14 @@ win32_init_window() {
0, 0, instance, 0);
assert(window._os_handle != 0, "Window creation failed, error: %lu", GetLastError());
window._initialized = true;
ShowWindow(window._os_handle, SW_SHOWDEFAULT);
window.allow_resize = true;
UpdateWindow(window._os_handle);
ShowWindow(window._os_handle, SW_HIDE);
style = GetWindowLong(window._os_handle, GWL_EXSTYLE);
style &= ~WS_EX_APPWINDOW; // Remove from taskbar
style |= WS_EX_TOOLWINDOW; // Make it a tool window
SetWindowLong(window._os_handle, GWL_EXSTYLE, style);
}
void
@ -482,15 +497,26 @@ BOOL win32_query_monitors_callback(HMONITOR monitor_handle, HDC dc, LPRECT rect,
GetDpiForMonitor(monitor_handle, MDT_EFFECTIVE_DPI, (UINT*)&monitor->dpi, (UINT*)&monitor->dpi_y);
if (monitor_handle == MonitorFromWindow(window._os_handle, MONITOR_DEFAULTTONEAREST)) {
window.monitor = monitor;
}
return TRUE;
}
void win32_query_monitors() {
window.monitor = 0;
if (os.monitors) growing_array_clear((void**)&os.monitors);
else growing_array_init((void**)&os.monitors, sizeof(Os_Monitor), get_heap_allocator());
EnumDisplayMonitors(0, 0, win32_query_monitors_callback, 0);
os.number_of_connected_monitors = growing_array_get_valid_count(os.monitors);
if (!window.monitor) {
window.monitor = os.primary_monitor;
}
}
void s64_to_null_terminated_string_reverse(char str[], int length)
@ -1847,26 +1873,51 @@ void set_specific_gamepad_vibration(u64 gamepad_index, float32 left, float32 rig
void os_update() {
// Only show window after first call to os_update
if (!has_os_update_been_called_at_all) {
ShowWindow(window._os_handle, SW_SHOW);
DWORD style = GetWindowLong(window._os_handle, GWL_EXSTYLE);
style &= ~WS_EX_TOOLWINDOW;
style |= WS_EX_APPWINDOW;
SetWindowLong(window._os_handle, GWL_EXSTYLE, style);
}
has_os_update_been_called_at_all = true;
win32_do_handle_raw_input = true;
#ifndef OOGABOOGA_HEADLESS
UINT dpi = GetDpiForWindow(window._os_handle);
float dpi_scale_factor = dpi / 96.0f;
local_persist Os_Window last_window;
//
// Window title
if (!strings_match(last_window.title, window.title)) {
SetWindowText(window._os_handle, temp_convert_to_null_terminated_string(window.title));
}
//
// Window sizing & position
if (window.fullscreen && last_window.fullscreen) {
window.pixel_width = window.monitor->resolution_x;
window.pixel_height = window.monitor->resolution_y;
window.x = 0;
window.y = 0;
}
BOOL ok;
DWORD style = (DWORD)GetWindowLong(window._os_handle, GWL_STYLE);
DWORD style_ex = (DWORD)GetWindowLong(window._os_handle, GWL_EXSTYLE);
int screen_height = os.primary_monitor->resolution_y;
if (last_window.scaled_width != window.scaled_width || last_window.scaled_height != window.scaled_height) {
window.width = window.scaled_width*dpi_scale_factor;
window.height = window.scaled_height*dpi_scale_factor;
}
BOOL ok;
int screen_height = GetSystemMetrics(SM_CYSCREEN);
DWORD style = (DWORD)GetWindowLong(window._os_handle, GWL_STYLE);
DWORD ex_style = (DWORD)GetWindowLong(window._os_handle, GWL_EXSTYLE);
if (last_window.x != window.x || last_window.y != window.y || last_window.width != window.width || last_window.height != window.height) {
RECT update_rect;
update_rect.left = window.x;
@ -1874,7 +1925,7 @@ void os_update() {
update_rect.top = window.y;
update_rect.bottom = window.y + window.height;
BOOL ok = AdjustWindowRectEx(&update_rect, style, FALSE, ex_style);
BOOL ok = AdjustWindowRectEx(&update_rect, style, FALSE, style_ex);
assert(ok != 0, "AdjustWindowRectEx failed with error code %lu", GetLastError());
u32 actual_width = update_rect.right - update_rect.left;
@ -1884,13 +1935,12 @@ void os_update() {
SetWindowPos(window._os_handle, 0, actual_x, actual_y, actual_width, actual_height, SWP_NOZORDER | SWP_NOACTIVATE);
}
RECT client_rect;
ok = GetClientRect(window._os_handle, &client_rect);
assert(ok, "GetClientRect failed with error code %lu", GetLastError());
RECT adjusted_rect = client_rect;
ok = AdjustWindowRectEx(&adjusted_rect, style, FALSE, ex_style);
ok = AdjustWindowRectEx(&adjusted_rect, style, FALSE, style_ex);
assert(ok != 0, "AdjustWindowRectEx failed with error code %lu", GetLastError());
RECT window_rect;
@ -1927,8 +1977,51 @@ void os_update() {
window.scaled_width = (u32)((bottom_right.x - top_left.x) * dpi_scale_factor);
window.scaled_height = (u32)((bottom_right.y - top_left.y) * dpi_scale_factor);
if (last_window.allow_resize != window.allow_resize) {
if (window.allow_resize) style |= WS_SIZEBOX;
else style &= ~(WS_SIZEBOX);
SetWindowLongW(window._os_handle, GWL_STYLE, style);
}
bool last_fullscreen = last_window.fullscreen;
last_window = window;
//
// Fullscreen
if (last_fullscreen != window.fullscreen) {
if (window.fullscreen) {
// Save windowed state
win32_windowed_style = style;
win32_windowed_style_ex = style_ex;
win32_windowed_x = window.x;
win32_windowed_y = window.y;
win32_windowed_width = window.width;
win32_windowed_height = window.height;
SetWindowLongW(window._os_handle, GWL_STYLE, style & ~(WS_CAPTION | WS_THICKFRAME));
SetWindowLongW(window._os_handle, GWL_EXSTYLE,
style_ex & ~(WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE)
);
} else {
// Restore windowed_state
style = win32_windowed_style;
style_ex = win32_windowed_style_ex;
window.x = win32_windowed_x;
window.y = win32_windowed_y;
window.width = win32_windowed_width;
window.height = win32_windowed_height;
SetWindowLongW(window._os_handle, GWL_STYLE, win32_windowed_style);
SetWindowLongW(window._os_handle, GWL_EXSTYLE, win32_windowed_style_ex);
}
}
// Reflect what the user layer did to input state before we query for OS inputs
memcpy(win32_key_states, input_frame.key_states, sizeof(input_frame.key_states));

View file

@ -75,6 +75,8 @@ typedef struct Os_Window {
s32 y;
Vector4 clear_color;
bool enable_vsync;
bool fullscreen;
bool allow_resize;
bool should_close;
@ -82,6 +84,8 @@ typedef struct Os_Window {
bool _initialized;
Window_Handle _os_handle;
Os_Monitor *monitor;
} Os_Window;
// #Global
@ -90,8 +94,8 @@ ogb_instance Os_Context os;
#if !OOGABOOGA_LINK_EXTERNAL_INSTANCE
Os_Context os;
Os_Window window;
Os_Context os = ZERO(Os_Context);
Os_Window window = ZERO(Os_Window);
#endif // NOT OOGABOOGA_LINK_EXTERNAL_INSTANCE