From e0da7ca817e2ddca8fb247ca1823bca8e97b4c2b Mon Sep 17 00:00:00 2001 From: luboslenco Date: Thu, 4 Jun 2026 20:45:16 +0200 Subject: [PATCH] paint: custom layer res --- paint/sources/config.c | 36 ++++++++++--------------- paint/sources/context.c | 1 - paint/sources/enums.h | 13 ++++----- paint/sources/functions.h | 1 + paint/sources/globals.h | 2 ++ paint/sources/io/import_arm.c | 2 ++ paint/sources/main.c | 6 +++++ paint/sources/project.c | 22 ++++------------ paint/sources/slot_layer.c | 2 +- paint/sources/types.h | 1 - paint/sources/ui/box_export.c | 21 +++------------ paint/sources/ui/box_preferences.c | 20 ++------------ paint/sources/ui/tab_layers.c | 42 +++++++++++++++++------------- 13 files changed, 65 insertions(+), 104 deletions(-) diff --git a/paint/sources/config.c b/paint/sources/config.c index f96205fd..a9733940 100644 --- a/paint/sources/config.c +++ b/paint/sources/config.c @@ -283,6 +283,7 @@ void config_init() { } #endif base_res_handle->i = g_config->layer_res; + config_set_texture_res(g_config->layer_res); keymap_load(); } @@ -421,20 +422,7 @@ f32 config_get_super_sample_size(i32 i) { } i32 config_texture_res_size(i32 pos) { - return pos == TEXTURE_RES_RES128 ? 128 - : pos == TEXTURE_RES_RES256 ? 256 - : pos == TEXTURE_RES_RES512 ? 512 - : pos == TEXTURE_RES_RES1024 ? 1024 - : pos == TEXTURE_RES_RES2048 ? 2048 - : pos == TEXTURE_RES_RES4096 ? 4096 - : pos == TEXTURE_RES_RES8192 ? 8192 - : pos == TEXTURE_RES_RES16384 ? 16384 - : 0; -} - -i32 config_get_texture_res() { - i32 res = base_res_handle->i; - return config_texture_res_size(res); + return pos == TEXTURE_RES_RES2048 ? 2048 : pos == TEXTURE_RES_RES4096 ? 4096 : pos == TEXTURE_RES_RES8192 ? 8192 : pos == TEXTURE_RES_RES16384 ? 16384 : 0; } i32 config_get_layer_res() { @@ -447,24 +435,28 @@ i32 config_get_scene_atlas_res() { return config_texture_res_size(res); } +void config_set_texture_res(i32 pos) { + if (pos != TEXTURE_RES_CUSTOM) { + f32 res = (f32)config_texture_res_size(pos); + base_res_x_handle->f = res; + base_res_y_handle->f = res; + } +} + i32 config_get_texture_res_x() { - return g_context->project_aspect_ratio == 2 ? math_floor(config_get_texture_res() / 2.0) : config_get_texture_res(); + return (i32)base_res_x_handle->f; } i32 config_get_texture_res_y() { - return g_context->project_aspect_ratio == 1 ? math_floor(config_get_texture_res() / 2.0) : config_get_texture_res(); + return (i32)base_res_y_handle->f; } i32 config_get_texture_res_pos(i32 i) { - return i == 128 ? TEXTURE_RES_RES128 - : i == 256 ? TEXTURE_RES_RES256 - : i == 512 ? TEXTURE_RES_RES512 - : i == 1024 ? TEXTURE_RES_RES1024 - : i == 2048 ? TEXTURE_RES_RES2048 + return i == 2048 ? TEXTURE_RES_RES2048 : i == 4096 ? TEXTURE_RES_RES4096 : i == 8192 ? TEXTURE_RES_RES8192 : i == 16384 ? TEXTURE_RES_RES16384 - : 0; + : TEXTURE_RES_CUSTOM; } void config_load_theme(char *theme, bool tag_redraw) { diff --git a/paint/sources/context.c b/paint/sources/context.c index f0bd433b..f57f6ec4 100644 --- a/paint/sources/context.c +++ b/paint/sources/context.c @@ -47,7 +47,6 @@ context_t *context_create() { c->clone_delta_x = 0.0; c->clone_delta_y = 0.0; c->show_compass = true; - c->project_aspect_ratio = 0; // 1:1, 2:1, 1:2 c->last_paint_vec_x = -1.0; c->last_paint_vec_y = -1.0; c->prev_paint_vec_x = -1.0; diff --git a/paint/sources/enums.h b/paint/sources/enums.h index bc46b8ab..7fe35d49 100644 --- a/paint/sources/enums.h +++ b/paint/sources/enums.h @@ -249,14 +249,11 @@ typedef enum { } tab_area_t; typedef enum { - TEXTURE_RES_RES128 = 0, - TEXTURE_RES_RES256 = 1, - TEXTURE_RES_RES512 = 2, - TEXTURE_RES_RES1024 = 3, - TEXTURE_RES_RES2048 = 4, - TEXTURE_RES_RES4096 = 5, - TEXTURE_RES_RES8192 = 6, - TEXTURE_RES_RES16384 = 7, + TEXTURE_RES_RES2048 = 0, + TEXTURE_RES_RES4096 = 1, + TEXTURE_RES_RES8192 = 2, + TEXTURE_RES_RES16384 = 3, + TEXTURE_RES_CUSTOM = 4, } texture_res_t; typedef enum { diff --git a/paint/sources/functions.h b/paint/sources/functions.h index e7ec6b63..a7d9b1e9 100644 --- a/paint/sources/functions.h +++ b/paint/sources/functions.h @@ -105,6 +105,7 @@ i32 config_get_super_sample_quality(f32 f); f32 config_get_super_sample_size(i32 i); i32 config_get_layer_res(); i32 config_get_scene_atlas_res(); +void config_set_texture_res(i32 pos); i32 config_get_texture_res_x(); i32 config_get_texture_res_y(); i32 config_get_texture_res_pos(i32 i); diff --git a/paint/sources/globals.h b/paint/sources/globals.h index a405e6a9..8f1a94a5 100644 --- a/paint/sources/globals.h +++ b/paint/sources/globals.h @@ -122,6 +122,8 @@ i32 base_default_element_w = 100; i32 base_default_element_h = 28; i32 base_default_font_size = 13; ui_handle_t *base_res_handle; +ui_handle_t *base_res_x_handle; +ui_handle_t *base_res_y_handle; ui_handle_t *base_bits_handle; string_array_t *base_drop_paths; slot_material_t *base_drag_material = NULL; diff --git a/paint/sources/io/import_arm.c b/paint/sources/io/import_arm.c index 10aa2bf1..a68a4c34 100644 --- a/paint/sources/io/import_arm.c +++ b/paint/sources/io/import_arm.c @@ -300,6 +300,8 @@ void import_arm_run_project(char *path) { gc_root(g_project); layer_data_t *l0 = project->layer_datas->buffer[0]; base_res_handle->i = config_get_texture_res_pos(l0->res); + base_res_x_handle->f = (f32)l0->res; + base_res_y_handle->f = (f32)l0->res; texture_bits_t bits_pos = l0->bpp == 8 ? TEXTURE_BITS_BITS8 : l0->bpp == 16 ? TEXTURE_BITS_BITS16 : TEXTURE_BITS_BITS32; base_bits_handle->i = bits_pos; i32 bytes_per_pixel = math_floor(l0->bpp / 8.0); diff --git a/paint/sources/main.c b/paint/sources/main.c index 9d41435d..23b355cb 100644 --- a/paint/sources/main.c +++ b/paint/sources/main.c @@ -275,6 +275,12 @@ void _kickstart() { base_res_handle = ui_handle_create(); gc_root(base_res_handle); + base_res_x_handle = ui_handle_create(); + gc_root(base_res_x_handle); + + base_res_y_handle = ui_handle_create(); + gc_root(base_res_y_handle); + base_bits_handle = ui_handle_create(); gc_root(base_bits_handle); diff --git a/paint/sources/project.c b/paint/sources/project.c index 9de4b5fa..734df327 100644 --- a/paint/sources/project.c +++ b/paint/sources/project.c @@ -106,24 +106,12 @@ void project_fetch_default_meshes() { void project_new_box_draw() { project_fetch_default_meshes(); - ui_row2(); + ui_handle_t *h_project_type = ui_handle(__ID__); if (h_project_type->init) { h_project_type->i = g_context->project_type; } - g_context->project_type = ui_combo(h_project_type, project_mesh_list, tr("Template"), true, UI_ALIGN_LEFT, true); - ui_handle_t *h_project_aspect_ratio = ui_handle(__ID__); - if (h_project_aspect_ratio->init) { - h_project_aspect_ratio->i = g_context->project_aspect_ratio; - } - string_array_t *project_aspect_ratio_combo = any_array_create_from_raw( - (void *[]){ - "1:1", - "2:1", - "1:2", - }, - 3); - g_context->project_aspect_ratio = ui_combo(h_project_aspect_ratio, project_aspect_ratio_combo, tr("Aspect Ratio"), true, UI_ALIGN_LEFT, true); + g_context->project_type = ui_combo(h_project_type, project_mesh_list, tr("Template"), true, UI_ALIGN_LEFT, true); ui_end_element(); ui_row2(); if (ui_icon_button(tr("Cancel"), ICON_CLOSE, UI_ALIGN_CENTER)) { @@ -311,15 +299,15 @@ void project_new(bool reset_layers) { ui_base_hwnds->buffer[TAB_AREA_SIDEBAR1]->redraws = 2; if (reset_layers) { - bool aspect_ratio_changed = project_layers->buffer[0]->texpaint->width != config_get_texture_res_x() || - project_layers->buffer[0]->texpaint->height != config_get_texture_res_y(); + bool res_changed = project_layers->buffer[0]->texpaint->width != config_get_texture_res_x() || + project_layers->buffer[0]->texpaint->height != config_get_texture_res_y(); while (project_layers->length > 0) { slot_layer_unload(array_pop(project_layers)); } slot_layer_t *layer = slot_layer_create("", LAYER_SLOT_TYPE_LAYER, NULL); any_array_push(project_layers, layer); context_set_layer(layer); - if (aspect_ratio_changed) { + if (res_changed) { sys_notify_on_next_frame(&project_new_resize_layers, NULL); } sys_notify_on_next_frame(&project_new_reset_layers, NULL); diff --git a/paint/sources/slot_layer.c b/paint/sources/slot_layer.c index 14e9529d..def3f110 100644 --- a/paint/sources/slot_layer.c +++ b/paint/sources/slot_layer.c @@ -892,7 +892,7 @@ void layers_init() { } void layers_resize() { - if (base_res_handle->i >= math_floor(TEXTURE_RES_RES16384)) { // Save memory for >=16k + if (config_get_texture_res_x() >= 16384 || config_get_texture_res_y() >= 16384) { // Save memory for >=16k g_config->undo_steps = 1; while (history_undo_layers->length > g_config->undo_steps) { slot_layer_t *l = array_pop(history_undo_layers); diff --git a/paint/sources/types.h b/paint/sources/types.h index d40d3a67..e737708f 100644 --- a/paint/sources/types.h +++ b/paint/sources/types.h @@ -236,7 +236,6 @@ typedef struct context { f32 clone_delta_y; bool show_compass; i32 project_type; - i32 project_aspect_ratio; f32 last_paint_vec_x; f32 last_paint_vec_y; f32 prev_paint_vec_x; diff --git a/paint/sources/ui/box_export.c b/paint/sources/ui/box_export.c index 5d5c4112..3de39e5a 100644 --- a/paint/sources/ui/box_export.c +++ b/paint/sources/ui/box_export.c @@ -41,34 +41,19 @@ void box_export_tab_export_textures(char *title, bool bake_material) { ui_row2(); -#if defined(IRON_ANDROID) || defined(IRON_IOS) string_array_t *base_res_combo = any_array_create_from_raw( (void *[]){ - "128", - "256", - "512", - "1024", - "2048", - "4096", - }, - 6); -#else - string_array_t *base_res_combo = any_array_create_from_raw( - (void *[]){ - "128", - "256", - "512", - "1024", "2048", "4096", "8192", "16384", + tr("Custom"), }, - 8); -#endif + 5); ui_combo(base_res_handle, base_res_combo, tr("Resolution"), true, UI_ALIGN_LEFT, true); if (base_res_handle->changed) { + config_set_texture_res(base_res_handle->i); layers_on_resized(); } diff --git a/paint/sources/ui/box_preferences.c b/paint/sources/ui/box_preferences.c index 1cecc615..116e59b3 100644 --- a/paint/sources/ui/box_preferences.c +++ b/paint/sources/ui/box_preferences.c @@ -403,31 +403,15 @@ void box_preferences_usage_tab() { ui_handle_t *h_layer_res = ui_handle(__ID__); h_layer_res->i = g_config->layer_res; -#if defined(IRON_ANDROID) || defined(IRON_IOS) + string_array_t *res_combo = any_array_create_from_raw( (void *[]){ - "128", - "256", - "512", - "1024", - "2048", - "4096", - }, - 6); -#else - string_array_t *res_combo = any_array_create_from_raw( - (void *[]){ - "128", - "256", - "512", - "1024", "2048", "4096", "8192", "16384", }, - 8); -#endif + 4); g_config->layer_res = ui_combo(h_layer_res, res_combo, tr("Default Layer Resolution"), true, UI_ALIGN_LEFT, true); ui_handle_t *h_scene_atlas_res = ui_handle(__ID__); diff --git a/paint/sources/ui/tab_layers.c b/paint/sources/ui/tab_layers.c index 03ec0056..c2eaf3c6 100644 --- a/paint/sources/ui/tab_layers.c +++ b/paint/sources/ui/tab_layers.c @@ -723,42 +723,48 @@ void tab_layers_draw_layer_context_menu_draw() { if (!slot_layer_is_group(l)) { ui_menu_align(); -#if defined(IRON_ANDROID) || defined(IRON_IOS) string_array_t *ar = any_array_create_from_raw( (void *[]){ - "128", - "256", - "512", - "1024", - "2048", - "4096", - }, - 6); -#else - string_array_t *ar = any_array_create_from_raw( - (void *[]){ - "128", - "256", - "512", - "1024", "2048", "4096", "8192", "16384", + tr("Custom"), }, - 8); -#endif + 5); ui_handle_t *h = ui_handle(__ID__); bool changed_last = h->changed; h->i = base_res_handle->i; base_res_handle->i = ui_combo(h, ar, tr("Resolution"), true, UI_ALIGN_LEFT, true); if (h->changed) { ui_menu_keep_open = true; + config_set_texture_res(base_res_handle->i); } if (changed_last && !h->changed) { layers_on_resized(); } + if (base_res_handle->i == TEXTURE_RES_CUSTOM) { + static bool res_was_changed = false; + + ui_menu_align(); + ui_slider(base_res_x_handle, tr("Width"), 1, 16384, false, 1, true, UI_ALIGN_RIGHT, true); + ui_menu_align(); + ui_slider(base_res_y_handle, tr("Height"), 1, 16384, false, 1, true, UI_ALIGN_RIGHT, true); + + if (base_res_x_handle->changed || base_res_y_handle->changed) { + ui_menu_keep_open = true; + } + if (res_was_changed && !ui->input_down) { + res_was_changed = false; + layers_on_resized(); + } + + if (base_res_x_handle->changed || base_res_y_handle->changed) { + res_was_changed = true; + } + } + ui_menu_align(); ui_handle_t *huv = ui_handle(__ID__); huv->i = l->uv_map;