From e5087f0757418c8b221cfde0364f0c3d031bdc73 Mon Sep 17 00:00:00 2001 From: kichikuou Date: Fri, 20 Mar 2026 11:30:37 +0900 Subject: [PATCH 1/5] PartsEngine: Implement PartsFunc 103 (GetPartsCGSurfaceArea) --- include/parts.h | 1 + src/hll/PartsEngine.c | 4 ++++ src/parts/parts.c | 12 ++++++++++++ 3 files changed, 17 insertions(+) diff --git a/include/parts.h b/include/parts.h index bb5ff93..06618b0 100644 --- a/include/parts.h +++ b/include/parts.h @@ -37,6 +37,7 @@ bool PE_SetPartsCG_by_string_index(int parts_no, struct string *cg_no, int sprite_deform, int state); void PE_GetPartsCGName(int parts_no, struct string **cg_name, int state); bool PE_SetPartsCGSurfaceArea(int parts_no, int x, int y, int w, int h, int state); +void PE_GetPartsCGSurfaceArea(int parts_no, int *x, int *y, int *w, int *h, int state); int PE_GetPartsCGNumber(int parts_no, int state); bool PE_SetLoopCG_by_index(int parts_no, int cg_no, int nr_frames, int frame_time, int state); bool PE_SetLoopCG(int parts_no, struct string *cg_name, int start_no, int nr_frames, diff --git a/src/hll/PartsEngine.c b/src/hll/PartsEngine.c index 8ee99b1..53e5ffa 100644 --- a/src/hll/PartsEngine.c +++ b/src/hll/PartsEngine.c @@ -127,6 +127,10 @@ static int PartsEngine_PartsFunc(int func_id, struct page **array_int, REQUIRE_INTS(1); ints[0].i = PE_get_system_controller(); return 1; + case 103: // void GetPartsCGSurfaceArea(int parts_no, int *x, int *y, int *w, int *h, int state) + REQUIRE_INTS(6); + PE_GetPartsCGSurfaceArea(ints[0].i, &ints[1].i, &ints[2].i, &ints[3].i, &ints[4].i, ints[5].i); + return 1; case 162: // bool InitPartsMovie(int parts_no, int width, int height, int bg_r, int bg_g, int bg_b, int state) REQUIRE_INTS(8); ints[7].i = PE_init_parts_movie(ints[0].i, ints[1].i, ints[2].i, ints[3].i, ints[4].i, ints[5].i, ints[6].i); diff --git a/src/parts/parts.c b/src/parts/parts.c index 0a8805d..c2b179d 100644 --- a/src/parts/parts.c +++ b/src/parts/parts.c @@ -1227,6 +1227,18 @@ bool PE_SetPartsCGSurfaceArea(int parts_no, int x, int y, int w, int h, int stat return true; } +void PE_GetPartsCGSurfaceArea(int parts_no, int *x, int *y, int *w, int *h, int state) +{ + if (!parts_state_valid(--state)) + return; + + struct parts_cg *cg = parts_get_cg(parts_get(parts_no), state); + *x = cg->common.surface_area.x; + *y = cg->common.surface_area.y; + *w = cg->common.surface_area.w; + *h = cg->common.surface_area.h; +} + int PE_GetPartsCGNumber(int parts_no, int state) { if (!parts_state_valid(--state)) { From 28c8c277c9c5a1bd82dad55b217dd9778703b231 Mon Sep 17 00:00:00 2001 From: kichikuou Date: Sun, 22 Mar 2026 14:55:29 +0900 Subject: [PATCH 2/5] PartsEngine: Implement PartsFunc 40-42 (PARTS_GetAbsolute[XYZ]) --- include/parts.h | 3 +++ src/hll/PartsEngine.c | 18 ++++++++++++++++++ src/parts/parts.c | 18 ++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/include/parts.h b/include/parts.h index 06618b0..1523ce7 100644 --- a/include/parts.h +++ b/include/parts.h @@ -129,6 +129,9 @@ int PE_get_active_controller(void); int PE_get_system_controller(void); bool PE_init_parts_movie(int parts_no, int width, int height, int bg_r, int bg_g, int bg_b, int state); int PE_get_movie_sprite(int parts_no, int state); +float PE_parts_get_absolute_x(int parts_no); +float PE_parts_get_absolute_y(int parts_no); +int PE_parts_get_absolute_z(int parts_no); // construction.c bool PE_AddCreateToPartsConstructionProcess(int parts_no, int w, int h, int state); diff --git a/src/hll/PartsEngine.c b/src/hll/PartsEngine.c index 53e5ffa..80d6b02 100644 --- a/src/hll/PartsEngine.c +++ b/src/hll/PartsEngine.c @@ -110,9 +110,13 @@ static int PartsEngine_PartsFunc(int func_id, struct page **array_int, { int nr_ints = (array_int && *array_int) ? (*array_int)->nr_vars : 0; union vm_value *ints = nr_ints ? (*array_int)->values : NULL; + int nr_floats = (array_float && *array_float) ? (*array_float)->nr_vars : 0; + union vm_value *floats = nr_floats ? (*array_float)->values : NULL; #define REQUIRE_INTS(n) \ if (nr_ints != (n)) VM_ERROR("Invalid arguments for PartsFunc %d: expected %d ints, got %d", func_id, (n), nr_ints) +#define REQUIRE_FLOATS(n) \ + if (nr_floats < (n)) VM_ERROR("Invalid arguments for PartsFunc %d: expected %d floats, got %d", func_id, (n), nr_floats) switch (func_id) { case 0: // void SetActiveLayer(int layer) @@ -127,6 +131,20 @@ static int PartsEngine_PartsFunc(int func_id, struct page **array_int, REQUIRE_INTS(1); ints[0].i = PE_get_system_controller(); return 1; + case 40: // float PARTS_GetAbsoluteX(int number) + REQUIRE_INTS(1); + REQUIRE_FLOATS(1); + floats[0].f = PE_parts_get_absolute_x(ints[0].i); + return 1; + case 41: // float PARTS_GetAbsoluteY(int number) + REQUIRE_INTS(1); + REQUIRE_FLOATS(1); + floats[0].f = PE_parts_get_absolute_y(ints[0].i); + return 1; + case 42: // int PARTS_GetAbsoluteZ(int number) + REQUIRE_INTS(2); + ints[1].i = PE_parts_get_absolute_z(ints[0].i); + return 1; case 103: // void GetPartsCGSurfaceArea(int parts_no, int *x, int *y, int *w, int *h, int state) REQUIRE_INTS(6); PE_GetPartsCGSurfaceArea(ints[0].i, &ints[1].i, &ints[2].i, &ints[3].i, &ints[4].i, ints[5].i); diff --git a/src/parts/parts.c b/src/parts/parts.c index c2b179d..2e7a67a 100644 --- a/src/parts/parts.c +++ b/src/parts/parts.c @@ -2101,6 +2101,24 @@ int PE_get_system_controller(void) return PARTS_CONTROLLER_SYSTEM_OVERLAY; } +float PE_parts_get_absolute_x(int parts_no) +{ + struct parts *parts = parts_try_get(parts_no); + return parts ? (float)parts->global.pos.x : 0.0f; +} + +float PE_parts_get_absolute_y(int parts_no) +{ + struct parts *parts = parts_try_get(parts_no); + return parts ? (float)parts->global.pos.y : 0.0f; +} + +int PE_parts_get_absolute_z(int parts_no) +{ + struct parts *parts = parts_try_get(parts_no); + return parts ? parts->global.z : 0; +} + bool PE_init_parts_movie(int parts_no, int width, int height, int bg_r, int bg_g, int bg_b, int state) { if (!parts_state_valid(--state)) From 88f199a8f276f92ca3e00147731d0488c241f951 Mon Sep 17 00:00:00 2001 From: kichikuou Date: Tue, 24 Mar 2026 11:16:13 +0900 Subject: [PATCH 3/5] PartsEngine: Implement PartsFunc 45 (PARTS_SetLockInputState) This adds lock_input_state parts flag which prevents state transition. --- include/parts.h | 1 + src/hll/PartsEngine.c | 4 ++++ src/parts/debug.c | 2 ++ src/parts/parts.c | 7 +++++++ src/parts/parts_internal.h | 1 + src/parts/save.c | 2 ++ 6 files changed, 17 insertions(+) diff --git a/include/parts.h b/include/parts.h index 1523ce7..1df91fe 100644 --- a/include/parts.h +++ b/include/parts.h @@ -132,6 +132,7 @@ int PE_get_movie_sprite(int parts_no, int state); float PE_parts_get_absolute_x(int parts_no); float PE_parts_get_absolute_y(int parts_no); int PE_parts_get_absolute_z(int parts_no); +void PE_parts_set_lock_input_state(int parts_no, bool lock); // construction.c bool PE_AddCreateToPartsConstructionProcess(int parts_no, int w, int h, int state); diff --git a/src/hll/PartsEngine.c b/src/hll/PartsEngine.c index 80d6b02..f5705ef 100644 --- a/src/hll/PartsEngine.c +++ b/src/hll/PartsEngine.c @@ -145,6 +145,10 @@ static int PartsEngine_PartsFunc(int func_id, struct page **array_int, REQUIRE_INTS(2); ints[1].i = PE_parts_get_absolute_z(ints[0].i); return 1; + case 45: // void PARTS_SetLockInputState(int number, bool lock) + REQUIRE_INTS(2); + PE_parts_set_lock_input_state(ints[0].i, !!ints[1].i); + return 1; case 103: // void GetPartsCGSurfaceArea(int parts_no, int *x, int *y, int *w, int *h, int state) REQUIRE_INTS(6); PE_GetPartsCGSurfaceArea(ints[0].i, &ints[1].i, &ints[2].i, &ints[3].i, &ints[4].i, ints[5].i); diff --git a/src/parts/debug.c b/src/parts/debug.c index 6c57460..9d76593 100644 --- a/src/parts/debug.c +++ b/src/parts/debug.c @@ -388,6 +388,8 @@ cJSON *parts_to_json(struct parts *parts, bool recursive, bool verbose) cJSON_AddNumberToObject(obj, "delegate_index", parts->delegate_index); cJSON_AddNumberToObject(obj, "sprite_deform", parts->sprite_deform); cJSON_AddBoolToObject(obj, "clickable", parts->clickable); + cJSON_AddBoolToObject(obj, "pass_cursor", parts->pass_cursor); + cJSON_AddBoolToObject(obj, "lock_input_state", parts->lock_input_state); if (parts->on_cursor_sound >= 0) cJSON_AddNumberToObject(obj, "on_cursor_sound", parts->on_cursor_sound); if (parts->on_click_sound >= 0) diff --git a/src/parts/parts.c b/src/parts/parts.c index 2e7a67a..822d188 100644 --- a/src/parts/parts.c +++ b/src/parts/parts.c @@ -884,6 +884,8 @@ bool parts_numeral_set_number(struct parts *parts, struct parts_numeral *num, in void parts_set_state(struct parts *parts, enum parts_state_type state) { + if (parts->lock_input_state) + return; while (state > PARTS_STATE_DEFAULT && parts->states[state].type == PARTS_UNINITIALIZED) state--; if (parts->state != state) { @@ -2119,6 +2121,11 @@ int PE_parts_get_absolute_z(int parts_no) return parts ? parts->global.z : 0; } +void PE_parts_set_lock_input_state(int parts_no, bool lock) +{ + parts_get(parts_no)->lock_input_state = lock; +} + bool PE_init_parts_movie(int parts_no, int width, int height, int bg_r, int bg_g, int bg_b, int state) { if (!parts_state_valid(--state)) diff --git a/src/parts/parts_internal.h b/src/parts/parts_internal.h index 9743371..0db0de5 100644 --- a/src/parts/parts_internal.h +++ b/src/parts/parts_internal.h @@ -366,6 +366,7 @@ struct parts { int sprite_deform; bool clickable; bool pass_cursor; + bool lock_input_state; int on_cursor_sound; int on_click_sound; int origin_mode; diff --git a/src/parts/save.c b/src/parts/save.c index 5907aa4..f4ea3ed 100644 --- a/src/parts/save.c +++ b/src/parts/save.c @@ -537,6 +537,7 @@ static void save_parts(struct iarray_writer *w, struct parts *parts) if (parts_multi_controller) { iarray_write(w, parts->controller_no); iarray_write(w, parts->pass_cursor); + iarray_write(w, parts->lock_input_state); } unsigned motion_count_pos = iarray_writer_pos(w); @@ -582,6 +583,7 @@ static void load_parts(struct iarray_reader *r, int version) if (parts_multi_controller) { parts->controller_no = iarray_read(r); parts->pass_cursor = iarray_read(r); + parts->lock_input_state = iarray_read(r); } int motion_count = iarray_read(r); for (int i = 0; i < motion_count; i++) { From 93c790dcc6da93510c0aec56defbe095b1c74a56 Mon Sep 17 00:00:00 2001 From: kichikuou Date: Wed, 25 Mar 2026 12:24:52 +0900 Subject: [PATCH 4/5] PartsEngine: Implement PartsFunc 159 (AddConstructProcess) This function has a large number of parameters, which are serialized fields from CASConstructionProcess. Dispatch on the command number to the appropriate PE_Add*ToPartsConstructionProcess function. --- src/hll/PartsEngine.c | 135 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) diff --git a/src/hll/PartsEngine.c b/src/hll/PartsEngine.c index f5705ef..8c399e1 100644 --- a/src/hll/PartsEngine.c +++ b/src/hll/PartsEngine.c @@ -18,6 +18,7 @@ #include "system4/ain.h" +#include "vm/heap.h" #include "vm/page.h" #include "parts.h" #include "hll.h" @@ -97,6 +98,130 @@ static void PartsEngine_AddComponentMotionPos(int parts_no, float begin_x, float begin_t, end_t, curve_name); } +static void PartsEngine_add_construction_process(union vm_value *ints, + union vm_value *floats, union vm_value *strings) +{ + int parts_no = ints[0].i; + int state = ints[1].i; + int command = ints[2].i; + int interp_type = ints[3].i; + int sx = ints[4].i; + int sy = ints[5].i; + int sw = ints[6].i; + int sh = ints[7].i; + int dx = ints[8].i; + int dy = ints[9].i; + int dw = ints[12].i; + int dh = ints[13].i; + int r = ints[14].i; + int g = ints[15].i; + int b = ints[16].i; + int a = ints[17].i; + // int r2 = ints[18].i; + // int g2 = ints[19].i; + // int b2 = ints[20].i; + int char_space = ints[21].i; + int line_space = ints[22].i; + int font_type = ints[23].i; + int font_size = ints[24].i; + int font_r = ints[25].i; + int font_g = ints[26].i; + int font_b = ints[27].i; + int edge_r = ints[28].i; + int edge_g = ints[29].i; + int edge_b = ints[30].i; + int full_size = ints[31].i; + float bold_weight = floats[0].f; + float edge_weight = floats[1].f; + struct string *text = heap_get_string(strings[0].i); + struct string *cg_name = heap_get_string(strings[1].i); + + switch (command) { + case 0: // CASConstructionProcess::SetCreate + PE_AddCreateToPartsConstructionProcess(parts_no, dw, dh, state); + break; + case 1: // CASConstructionProcess::SetCreatePixelOnly + PE_AddCreatePixelOnlyToPartsConstructionProcess(parts_no, dw, dh, state); + break; + case 2: // CASConstructionProcess::SetCreateCG + PE_AddCreateCGToProcess(parts_no, cg_name, state); + break; + case 3: // CASConstructionProcess::SetFill + PE_AddFillToPartsConstructionProcess(parts_no, + dx, dy, dw, dh, r, g, b, state); + break; + case 4: // CASConstructionProcess::SetFillAlphaColor + PE_AddFillAlphaColorToPartsConstructionProcess(parts_no, + dx, dy, dw, dh, r, g, b, a, state); + break; + case 5: // CASConstructionProcess::SetFillAMap + PE_AddFillAMapToPartsConstructionProcess(parts_no, + dx, dy, dw, dh, a, state); + break; + case 6: // CASConstructionProcess::SetFillWithAlpha + PE_AddFillWithAlphaToPartsConstructionProcess(parts_no, + dx, dy, dw, dh, r, g, b, a, state); + break; + case 7: // CASConstructionProcess::SetDrawText + PE_AddDrawTextToPartsConstructionProcess(parts_no, + dx, dy, text, font_type, font_size, + font_r, font_g, font_b, bold_weight, + edge_r, edge_g, edge_b, edge_weight, + char_space, line_space, state); + break; + case 8: // CASConstructionProcess::SetCopyText + PE_AddCopyTextToPartsConstructionProcess(parts_no, + dx, dy, text, font_type, font_size, + font_r, font_g, font_b, bold_weight, + edge_r, edge_g, edge_b, edge_weight, + char_space, line_space, state); + break; + case 9: // CASConstructionProcess::SetFillGradationHorizon + WARNING("AddConstructProcess: FillGradationHorizon unimplemented"); + break; + case 10: // CASConstructionProcess::SetDrawRect + PE_AddDrawRectToPartsConstructionProcess(parts_no, + dx, dy, dw, dh, r, g, b, state); + break; + case 11: // CASConstructionProcess::SetCutCGBlend (equal scale) + PE_AddDrawCutCGToPartsConstructionProcess(parts_no, cg_name, + dx, dy, dw, dh, sx, sy, dw, dh, + interp_type, state); + break; + case 12: // CASConstructionProcess::SetCutCGCopy (equal scale) + PE_AddCopyCutCGToPartsConstructionProcess(parts_no, cg_name, + dx, dy, dw, dh, sx, sy, dw, dh, + interp_type, state); + break; + case 13: // CASConstructionProcess::SetCutCGScaleBlend + PE_AddDrawCutCGToPartsConstructionProcess(parts_no, cg_name, + dx, dy, dw, dh, sx, sy, sw, sh, + interp_type, state); + break; + case 14: // CASConstructionProcess::SetCutCGScaleCopy + PE_AddCopyCutCGToPartsConstructionProcess(parts_no, cg_name, + dx, dy, dw, dh, sx, sy, sw, sh, + interp_type, state); + break; + case 15: // CASConstructionProcess::SetGrayFilter + PE_AddGrayFilterToPartsConstructionProcess(parts_no, + dx, dy, dw, dh, full_size, state); + break; + case 16: // CASConstructionProcess::SetAddFilter + WARNING("AddConstructProcess: AddFilter unimplemented"); + break; + case 17: // CASConstructionProcess::SetMulFilter + WARNING("AddConstructProcess: MulFilter unimplemented"); + break; + case 18: // CASConstructionProcess::SetDrawLine + WARNING("AddConstructProcess: DrawLine unimplemented"); + break; + default: + WARNING("AddConstructProcess: unknown command %d", command); + break; + } +} + // Generic dispatch function for PartsEngine operations. // func_id selects the operation; arguments and return values are passed // through three typed arrays (int/bool, float, string). @@ -112,11 +237,15 @@ static int PartsEngine_PartsFunc(int func_id, struct page **array_int, union vm_value *ints = nr_ints ? (*array_int)->values : NULL; int nr_floats = (array_float && *array_float) ? (*array_float)->nr_vars : 0; union vm_value *floats = nr_floats ? (*array_float)->values : NULL; + int nr_strings = (array_string && *array_string) ? (*array_string)->nr_vars : 0; + union vm_value *strings = nr_strings ? (*array_string)->values : NULL; #define REQUIRE_INTS(n) \ if (nr_ints != (n)) VM_ERROR("Invalid arguments for PartsFunc %d: expected %d ints, got %d", func_id, (n), nr_ints) #define REQUIRE_FLOATS(n) \ if (nr_floats < (n)) VM_ERROR("Invalid arguments for PartsFunc %d: expected %d floats, got %d", func_id, (n), nr_floats) +#define REQUIRE_STRINGS(n) \ + if (nr_strings < (n)) VM_ERROR("Invalid arguments for PartsFunc %d: expected %d strings, got %d", func_id, (n), nr_strings) switch (func_id) { case 0: // void SetActiveLayer(int layer) @@ -153,6 +282,12 @@ static int PartsEngine_PartsFunc(int func_id, struct page **array_int, REQUIRE_INTS(6); PE_GetPartsCGSurfaceArea(ints[0].i, &ints[1].i, &ints[2].i, &ints[3].i, &ints[4].i, ints[5].i); return 1; + case 159: // AddConstructProcess(ArrayInt[32], ArrayFloat[2], ArrayString[2]) + REQUIRE_INTS(32); + REQUIRE_FLOATS(2); + REQUIRE_STRINGS(2); + PartsEngine_add_construction_process(ints, floats, strings); + return 1; case 162: // bool InitPartsMovie(int parts_no, int width, int height, int bg_r, int bg_g, int bg_b, int state) REQUIRE_INTS(8); ints[7].i = PE_init_parts_movie(ints[0].i, ints[1].i, ints[2].i, ints[3].i, ints[4].i, ints[5].i, ints[6].i); From c4f89d040ad9a254c6e8e7b1a7671ad16f27d488 Mon Sep 17 00:00:00 2001 From: kichikuou Date: Thu, 26 Mar 2026 08:38:33 +0900 Subject: [PATCH 5/5] PartsEngine: Implement PartsFunc 4 (SetWantSave) This adds want_save parts flag which defaults to true. Parts with want_save set to false are excluded from save data. --- include/parts.h | 1 + src/hll/PartsEngine.c | 4 ++++ src/parts/debug.c | 1 + src/parts/parts.c | 6 ++++++ src/parts/parts_internal.h | 1 + src/parts/save.c | 2 ++ 6 files changed, 15 insertions(+) diff --git a/include/parts.h b/include/parts.h index 1df91fe..0f75fbc 100644 --- a/include/parts.h +++ b/include/parts.h @@ -127,6 +127,7 @@ bool PE_IsExist(int parts_no); void PE_set_active_controller(int controller_no); int PE_get_active_controller(void); int PE_get_system_controller(void); +void PE_parts_set_want_save(int parts_no, bool want_save); bool PE_init_parts_movie(int parts_no, int width, int height, int bg_r, int bg_g, int bg_b, int state); int PE_get_movie_sprite(int parts_no, int state); float PE_parts_get_absolute_x(int parts_no); diff --git a/src/hll/PartsEngine.c b/src/hll/PartsEngine.c index 8c399e1..6539cee 100644 --- a/src/hll/PartsEngine.c +++ b/src/hll/PartsEngine.c @@ -260,6 +260,10 @@ static int PartsEngine_PartsFunc(int func_id, struct page **array_int, REQUIRE_INTS(1); ints[0].i = PE_get_system_controller(); return 1; + case 4: // void SetWantSave(int parts_no, bool want_save) + REQUIRE_INTS(2); + PE_parts_set_want_save(ints[0].i, !!ints[1].i); + return 1; case 40: // float PARTS_GetAbsoluteX(int number) REQUIRE_INTS(1); REQUIRE_FLOATS(1); diff --git a/src/parts/debug.c b/src/parts/debug.c index 9d76593..c5a24c7 100644 --- a/src/parts/debug.c +++ b/src/parts/debug.c @@ -390,6 +390,7 @@ cJSON *parts_to_json(struct parts *parts, bool recursive, bool verbose) cJSON_AddBoolToObject(obj, "clickable", parts->clickable); cJSON_AddBoolToObject(obj, "pass_cursor", parts->pass_cursor); cJSON_AddBoolToObject(obj, "lock_input_state", parts->lock_input_state); + cJSON_AddBoolToObject(obj, "want_save", parts->want_save); if (parts->on_cursor_sound >= 0) cJSON_AddNumberToObject(obj, "on_cursor_sound", parts->on_cursor_sound); if (parts->on_click_sound >= 0) diff --git a/src/parts/parts.c b/src/parts/parts.c index 822d188..91ebbf2 100644 --- a/src/parts/parts.c +++ b/src/parts/parts.c @@ -62,6 +62,7 @@ static void parts_init(struct parts *parts) parts->local = PARTS_PARAMS_INITIALIZER; parts->global = PARTS_PARAMS_INITIALIZER; parts->delegate_index = -1; + parts->want_save = true; parts->on_cursor_sound = -1; parts->on_click_sound = -1; parts->origin_mode = 1; @@ -2103,6 +2104,11 @@ int PE_get_system_controller(void) return PARTS_CONTROLLER_SYSTEM_OVERLAY; } +void PE_parts_set_want_save(int parts_no, bool want_save) +{ + parts_get(parts_no)->want_save = want_save; +} + float PE_parts_get_absolute_x(int parts_no) { struct parts *parts = parts_try_get(parts_no); diff --git a/src/parts/parts_internal.h b/src/parts/parts_internal.h index 0db0de5..8e02750 100644 --- a/src/parts/parts_internal.h +++ b/src/parts/parts_internal.h @@ -367,6 +367,7 @@ struct parts { bool clickable; bool pass_cursor; bool lock_input_state; + bool want_save; int on_cursor_sound; int on_click_sound; int origin_mode; diff --git a/src/parts/save.c b/src/parts/save.c index f4ea3ed..991bf90 100644 --- a/src/parts/save.c +++ b/src/parts/save.c @@ -650,6 +650,8 @@ static bool parts_engine_save(struct page **buffer, bool save_hidden) PARTS_LIST_FOREACH(parts) { if (!save_hidden && !parts->global.show) continue; + if (!parts->want_save) + continue; save_parts(&w, parts); count++; }