# HG changeset patch # User Mike Becker # Date 1769345389 -3600 # Node ID 4df350dac84f4f082a76aea15364adb1d83bd94e # Parent 24b0f47f619c0d521afdc758c90bb1b35304fb6b add functions for centering a window on only one axis diff -r 24b0f47f619c -r 4df350dac84f demo/snake/snake.c --- a/demo/snake/snake.c Sun Jan 25 13:18:26 2026 +0100 +++ b/demo/snake/snake.c Sun Jan 25 13:49:49 2026 +0100 @@ -137,7 +137,7 @@ // scale the backdrop to the size of the window if (!asc_active_window->resized) return; asc_ptr_cast(AscSprite, sprite, behavior->node); - asc_vec2u window_size = asc_active_window->dimensions; + asc_vec2u window_size = asc_active_window->rect.size; asc_sprite_set_size(sprite, window_size); } @@ -178,7 +178,7 @@ AscSceneNode *node = behavior->node; if (asc_test_flag(node->flags, ASC_SCENE_NODE_GRAPHICS_UPDATED) || asc_active_window->resized) { asc_scene_node_set_position2f(node, ASC_VEC2F(10, - asc_active_window->dimensions.y - ((AscText*)node)->dimension.height - 10 + asc_active_window->rect.size.height - ((AscText*)node)->dimension.height - 10 )); } } @@ -618,7 +618,7 @@ if (asc_has_error()) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", asc_get_error(), - asc_active_window->window); + asc_active_window->sdl); asc_clear_error(); asc_context_quit(); } diff -r 24b0f47f619c -r 4df350dac84f src/ascension/datatypes.h --- a/src/ascension/datatypes.h Sun Jan 25 13:18:26 2026 +0100 +++ b/src/ascension/datatypes.h Sun Jan 25 13:49:49 2026 +0100 @@ -152,6 +152,9 @@ asc_vec2u size; } asc_rect; #define ASC_RECT(x, y, w, h) (asc_rect){ASC_VEC2I(x,y), ASC_VEC2U(w,h)} +#define ASC_RECTV(p, s) (asc_rect){ASC_VEC2I((p).x, (p).y), ASC_VEC2U((s).width, (s).height)} +#define ASC_RECT_PRI "(%d,%d,%u,%u)" +#define ASC_RECT_FMT(r) (r).pos.x, (r).pos.y, (r).size.width, (r).size.height typedef union asc_vec2f { struct { float x, y; }; diff -r 24b0f47f619c -r 4df350dac84f src/ascension/window.h --- a/src/ascension/window.h Sun Jan 25 13:18:26 2026 +0100 +++ b/src/ascension/window.h Sun Jan 25 13:49:49 2026 +0100 @@ -46,15 +46,16 @@ typedef struct asc_window_s { Uint32 id; - bool resized; - bool focused; - SDL_Window *window; - asc_vec2u dimensions; + SDL_Window *sdl; + asc_rect rect; AscGLContext glctx; float ui_scale; AscScene ui; AscCamera ui_camera; AscScene scenes[ASC_MAX_SCENES]; + bool resized; + bool moved; + bool focused; } AscWindow; /** @@ -177,6 +178,20 @@ void asc_window_center(unsigned index); /** + * Centers the window horizontally on screen. + * + * @param index the window index + */ +void asc_window_hcenter(unsigned index); + +/** + * Centers the window vertically on screen. + * + * @param index the window index + */ +void asc_window_vcenter(unsigned index); + +/** * Sets the window size. * * @param index the window index diff -r 24b0f47f619c -r 4df350dac84f src/context.c --- a/src/context.c Sun Jan 25 13:18:26 2026 +0100 +++ b/src/context.c Sun Jan 25 13:49:49 2026 +0100 @@ -34,6 +34,7 @@ #include #include +#include AscContext asc_context; @@ -119,13 +120,29 @@ } } +static AscWindow * asc_window_find(Uint32 sdl_id) { + for (unsigned i = 0 ; i < ASC_MAX_WINDOWS ; i++) { + if (asc_context.windows[i].id == sdl_id) { + return asc_context.windows + i; + } + } + return NULL; +} + static void asc_event_window_resized(Uint32 id, Sint32 width, Sint32 height) { - unsigned int i = asc_window_index(id); - if (i < ASC_MAX_WINDOWS) { - asc_context.windows[i].resized = true; - asc_context.windows[i].dimensions.width = (unsigned) width; - asc_context.windows[i].dimensions.height = (unsigned) height; - } + AscWindow *window = asc_window_find(id); + assert(window != NULL); + window->resized = true; + window->rect.size.width = (unsigned) width; + window->rect.size.height = (unsigned) height; +} + +static void asc_event_window_moved(Uint32 id, Sint32 x, Sint32 y) { + AscWindow *window = asc_window_find(id); + assert(window != NULL); + window->moved = true; + window->rect.pos.x = x; + window->rect.pos.y = y; } bool asc_loop_next(void) { @@ -145,6 +162,14 @@ case SDL_EVENT_QUIT: asc_set_flag(asc_context.flags, ASC_FLAG_QUIT); break; + case SDL_EVENT_WINDOW_MOVED: { + asc_event_window_moved( + event.window.windowID, + event.window.data1, + event.window.data2 + ); + break; + } case SDL_EVENT_WINDOW_RESIZED: { asc_event_window_resized( event.window.windowID, @@ -154,13 +179,11 @@ break; } case SDL_EVENT_WINDOW_FOCUS_GAINED: { - unsigned int idx = asc_window_index(event.window.windowID); - asc_context.windows[idx].focused = true; + asc_window_find(event.window.windowID)->focused = true; break; } case SDL_EVENT_WINDOW_FOCUS_LOST: { - unsigned int idx = asc_window_index(event.window.windowID); - asc_context.windows[idx].focused = false; + asc_window_find(event.window.windowID)->focused = false; break; } case SDL_EVENT_MOUSE_MOTION: { diff -r 24b0f47f619c -r 4df350dac84f src/util.c --- a/src/util.c Sun Jan 25 13:18:26 2026 +0100 +++ b/src/util.c Sun Jan 25 13:49:49 2026 +0100 @@ -41,7 +41,7 @@ uint32_t asc_util_rand(uint32_t n) { if (n > INT32_MAX) { - // TODO: this probably uses quality of the generated numbers + // TODO: this likely reduces the quality of the generated numbers return SDL_rand_bits() % n; } else { return SDL_rand((int32_t) n); diff -r 24b0f47f619c -r 4df350dac84f src/window.c --- a/src/window.c Sun Jan 25 13:18:26 2026 +0100 +++ b/src/window.c Sun Jan 25 13:49:49 2026 +0100 @@ -47,28 +47,29 @@ SDL_WindowFlags flags = SDL_WINDOW_OPENGL; flags |= settings.fullscreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_RESIZABLE; - window->window = SDL_CreateWindow("Ascension",800, 600, flags); - if (window->window == NULL) { + window->sdl = SDL_CreateWindow("Ascension",800, 600, flags); + if (window->sdl == NULL) { asc_error("Creating Window failed: %s", SDL_GetError()); return; } - window->id = SDL_GetWindowID(window->window); + window->id = SDL_GetWindowID(window->sdl); { - Sint32 w, h; - SDL_GetWindowSize(window->window, &w, &h); - window->dimensions = ASC_VEC2U(w, h); + int x,y, w, h; + SDL_GetWindowPosition(window->sdl, &x, &y); + SDL_GetWindowSize(window->sdl, &w, &h); + window->rect = ASC_RECT(x, y, w, h); } window->resized = true; // count initial sizing as resize // default UI scale window->ui_scale = 1.0f; - if (asc_gl_context_initialize(&window->glctx, window->window, &settings)) { + if (asc_gl_context_initialize(&window->glctx, window->sdl, &settings)) { char ui_scene_name[16]; snprintf(ui_scene_name, sizeof(ui_scene_name), "Window %u UI", index); asc_camera_init(&window->ui_camera, .type = ASC_CAMERA_ORTHO, - .ortho.rect = ASC_RECT(0, 0, window->dimensions.width, window->dimensions.height), + .ortho.rect = ASC_RECTV(ASC_VEC2I_0, window->rect.size), .viewport_update_func = asc_camera_ortho_update_size); asc_scene_init(&window->ui, ui_scene_name, &window->ui_camera); asc_dprintf("Window %u initialized at index %u", window->id, index); @@ -76,8 +77,8 @@ } else { asc_error("Creating GL context failed for window %u at index %u", window->id, index); // cleanup on error - SDL_DestroyWindow(window->window); - window->window = NULL; + SDL_DestroyWindow(window->sdl); + window->sdl = NULL; window->id = 0; } } @@ -107,8 +108,8 @@ asc_gl_context_destroy(&window->glctx); // destroy window - if (window->window != NULL) { - SDL_DestroyWindow(window->window); + if (window->sdl != NULL) { + SDL_DestroyWindow(window->sdl); } // if another window was active, make the other context current again @@ -152,19 +153,19 @@ } // Clear the color buffer for the window frame - int window_width = window->dimensions.width; - int window_height = window->dimensions.height; - glViewport(0, 0, window_width, window_height); + glViewport(0, 0, + (GLsizei) window->rect.size.width, + (GLsizei) window->rect.size.height); glClear(GL_COLOR_BUFFER_BIT); // Update the viewports when the window resized if (window->resized) { for (unsigned int i = 0; i < ASC_MAX_SCENES; i++) { if (asc_scene_active(&window->scenes[i])) { - asc_window_update_viewport(window->scenes[i].camera, window->dimensions); + asc_window_update_viewport(window->scenes[i].camera, window->rect.size); } } - asc_window_update_viewport(window->ui.camera, window->dimensions); + asc_window_update_viewport(window->ui.camera, window->rect.size); } // Execute camera updates @@ -189,10 +190,11 @@ asc_scene_draw(&window->ui); // Swap Buffers - SDL_GL_SwapWindow(window->window); + SDL_GL_SwapWindow(window->sdl); // Clear Flags window->resized = false; + window->moved = false; if (index != active_index) { asc_window_activate(active_index); @@ -218,7 +220,7 @@ asc_vec2u asc_window_display_resolution(void) { const AscWindow *window = asc_active_window; - SDL_DisplayID display = SDL_GetDisplayForWindow(window->window); + SDL_DisplayID display = SDL_GetDisplayForWindow(window->sdl); const SDL_DisplayMode *dm = SDL_GetDesktopDisplayMode(display); if (dm == NULL) { asc_error("Failed to get display mode for window %u on display %d: %s", @@ -228,31 +230,46 @@ } float asc_window_ui_scale(unsigned int index) { - assert(asc_context.windows[index].window != NULL); + assert(asc_context.windows[index].sdl != NULL); return asc_context.windows[index].ui_scale; } +// TODO: error handling for all SDL_SetStuff() functions + void asc_window_set_title(unsigned index, const char *title) { - assert(asc_context.windows[index].window != NULL); - SDL_SetWindowTitle(asc_context.windows[index].window, title); + assert(asc_context.windows[index].sdl != NULL); + SDL_SetWindowTitle(asc_context.windows[index].sdl, title); } void asc_window_set_position(unsigned index, asc_vec2i pos) { - assert(asc_context.windows[index].window != NULL); - SDL_SetWindowPosition(asc_context.windows[index].window, pos.x, pos.y); + assert(asc_context.windows[index].sdl != NULL); + SDL_SetWindowPosition(asc_context.windows[index].sdl, pos.x, pos.y); } void asc_window_center(unsigned index) { // TODO: add support for multiple displays - // TODO: add support for centering just one axis - assert(asc_context.windows[index].window != NULL); - SDL_SetWindowPosition(asc_context.windows[index].window, - SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); + const AscWindow *window = asc_context.windows + index; + assert(window->sdl != NULL); + SDL_SetWindowPosition(window->sdl, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); +} + +void asc_window_hcenter(unsigned index) { + // TODO: add support for multiple displays + const AscWindow *window = asc_context.windows + index; + assert(window->sdl != NULL); + SDL_SetWindowPosition(window->sdl, SDL_WINDOWPOS_CENTERED, window->rect.pos.y); +} + +void asc_window_vcenter(unsigned index) { + // TODO: add support for multiple displays + const AscWindow *window = asc_context.windows + index; + assert(window->sdl != NULL); + SDL_SetWindowPosition(window->sdl, window->rect.pos.x, SDL_WINDOWPOS_CENTERED); } void asc_window_set_size(unsigned index, asc_vec2u size) { - assert(asc_context.windows[index].window != NULL); - asc_context.windows[index].dimensions = size; + const AscWindow *window = asc_context.windows + index; + assert(window->sdl != NULL); // TODO: check what needs to be changed when SDL_WINDOW_ALLOW_HIGHDPI is supported by the engine - SDL_SetWindowSize(asc_context.windows[index].window, (int)size.width, (int)size.height); + SDL_SetWindowSize(window->sdl, (int)size.width, (int)size.height); }