From 5dc79304dfe047b935e5aeefde3b73ad4d4a83f8 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Tue, 12 Dec 2023 12:03:28 +0100 Subject: [PATCH 01/16] reverted order of processing game modes for global animations clicks The assumptions that led to the change that is reverted here were simply wrong: When drawing global animations in a certain order, checking for mouse clicks must be done in reverse order, to ensure that the click is processed for the topmost global animation. This includes processing game modes in reverse order (which are handled in normal order when drawing global animations). Processing clicks for a global animation based custom mouse pointer should be handled separately anyway, to process it independently from the game mode it was defined for. This reverts commit e3411dc9. --- src/anim.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/anim.c b/src/anim.c index 08abd668..dcd66e33 100644 --- a/src/anim.c +++ b/src/anim.c @@ -2120,7 +2120,8 @@ static boolean InitGlobalAnim_Clicked(int mx, int my, int clicked_event) int mode_nr; int i; - for (mode_nr = 0; mode_nr < NUM_GAME_MODES; mode_nr++) + // check game modes in reverse draw order (to stop when clicked) + for (mode_nr = NUM_GAME_MODES - 1; mode_nr >= 0; mode_nr--) { struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[mode_nr]; int anim_nr; -- 2.34.1 From 263c1f057f081555ae53ad16d9b65ea026180441 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Tue, 12 Dec 2023 12:20:53 +0100 Subject: [PATCH 02/16] fixed bug caused by support for only eight global animations in the past --- src/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/init.c b/src/init.c index f9e46b4f..af11e4c7 100644 --- a/src/init.c +++ b/src/init.c @@ -1649,7 +1649,7 @@ static void set_graphic_parameters_ext(int graphic, int *parameter, g->draw_yoffset = parameter[GFX_ARG_DRAW_YOFFSET]; // use a different default value for global animations and toons - if ((graphic >= IMG_GFX_GLOBAL_ANIM_1 && graphic <= IMG_GFX_GLOBAL_ANIM_8) || + if ((graphic >= IMG_GFX_GLOBAL_ANIM_1 && graphic <= IMG_GFX_GLOBAL_ANIM_32) || (graphic >= IMG_TOON_1 && graphic <= IMG_TOON_20)) g->draw_masked = TRUE; -- 2.34.1 From d1a0dcb34b3d1c33e8cc283fe4dee238c94b84f8 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Tue, 12 Dec 2023 14:12:40 +0100 Subject: [PATCH 03/16] removed explicitly setting draw order for pointer-style animations As pointer-style animations are handled specially anyway (always drawn on top of all other global animations), setting the draw order is not required anymore. --- src/anim.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/anim.c b/src/anim.c index dcd66e33..a23d6e58 100644 --- a/src/anim.c +++ b/src/anim.c @@ -602,19 +602,10 @@ static void InitGlobalAnimControls(void) anim->has_base = TRUE; } - // apply special settings for pointer-style animations - if (part->control_info.class == get_hash_from_key("pointer")) - { - // force animation to be on top (must set anim and part control) - if (anim->control_info.draw_order == 0) - anim->control_info.draw_order = 1000000; - if (part->control_info.draw_order == 0) - part->control_info.draw_order = 1000000; - - // force animation to pass-through clicks (must set part control) - if (part->control_info.style == STYLE_DEFAULT) - part->control_info.style |= STYLE_PASSTHROUGH; - } + // force pointer-style animations to pass-through clicks + if (part->control_info.class == get_hash_from_key("pointer") && + part->control_info.style == STYLE_DEFAULT) + part->control_info.style |= STYLE_PASSTHROUGH; } if (anim->num_parts > 0 || anim->has_base) -- 2.34.1 From 895d5cb33db251c933445778400bb3e50b76d4ab Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Tue, 12 Dec 2023 14:21:04 +0100 Subject: [PATCH 04/16] fixed setting (and maybe inheriting) draw order for global animations --- src/anim.c | 8 ++++++++ src/init.c | 21 +++++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/anim.c b/src/anim.c index a23d6e58..0cb2023d 100644 --- a/src/anim.c +++ b/src/anim.c @@ -535,6 +535,10 @@ static void InitGlobalAnimControls(void) anim->state = ANIM_STATE_INACTIVE; + // if draw order is undefined, set to default value "0" + if (anim->control_info.draw_order == ARG_UNDEFINED_VALUE) + anim->control_info.draw_order = 0; + part_nr = 0; for (p = 0; p < NUM_GLOBAL_ANIM_PARTS_ALL; p++) @@ -606,6 +610,10 @@ static void InitGlobalAnimControls(void) if (part->control_info.class == get_hash_from_key("pointer") && part->control_info.style == STYLE_DEFAULT) part->control_info.style |= STYLE_PASSTHROUGH; + + // if draw order is undefined, inherit it from main animation + if (part->control_info.draw_order == ARG_UNDEFINED_VALUE) + part->control_info.draw_order = anim->control_info.draw_order; } if (anim->num_parts > 0 || anim->has_base) diff --git a/src/init.c b/src/init.c index af11e4c7..45945dcd 100644 --- a/src/init.c +++ b/src/init.c @@ -722,14 +722,23 @@ static void InitGlobalAnimGraphicInfo(void) struct GraphicInfo *g = &graphic_info[graphic]; struct FileInfo *image = getImageListEntryFromImageID(graphic); char **parameter_raw = image->parameter; - int p = GFX_ARG_DRAW_MASKED; - int draw_masked = get_graphic_parameter_value(parameter_raw[p], - image_config_suffix[p].token, - image_config_suffix[p].type); + int p1 = GFX_ARG_DRAW_MASKED; + int p2 = GFX_ARG_DRAW_ORDER; + int draw_masked = get_graphic_parameter_value(parameter_raw[p1], + image_config_suffix[p1].token, + image_config_suffix[p1].type); + int draw_order = get_graphic_parameter_value(parameter_raw[p2], + image_config_suffix[p2].token, + image_config_suffix[p2].type); // if ".draw_masked" parameter is undefined, use default value "TRUE" if (draw_masked == ARG_UNDEFINED_VALUE) g->draw_masked = TRUE; + + // if ".draw_order" parameter is undefined, set back to "undefined" + // (used to be able to inherit draw order from main animation later) + if (draw_order == ARG_UNDEFINED_VALUE) + g->draw_order = ARG_UNDEFINED_VALUE; } #if 0 @@ -1657,6 +1666,10 @@ static void set_graphic_parameters_ext(int graphic, int *parameter, if (parameter[GFX_ARG_DRAW_MASKED] != ARG_UNDEFINED_VALUE) g->draw_masked = parameter[GFX_ARG_DRAW_MASKED]; + // use a different default value for global animations (corrected later) + if (graphic >= IMG_GLOBAL_ANIM_1 && graphic <= IMG_GLOBAL_ANIM_32) + g->draw_order = ARG_UNDEFINED_VALUE; + // used for toon animations and global animations if (parameter[GFX_ARG_DRAW_ORDER] != ARG_UNDEFINED_VALUE) g->draw_order = parameter[GFX_ARG_DRAW_ORDER]; -- 2.34.1 From 70df2b1709f05156b8bf6b142cc2a2e23205130b Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Tue, 12 Dec 2023 15:01:10 +0100 Subject: [PATCH 05/16] fixed correctly using defined draw order of global animations Before this change, there was only limited support for the attribute ".draw_order" for global animations, which did not work correctly if the global animations had different game modes defined (like ".MAIN"), as global animations were drawn in numerical game mode order, so draw order was ignored between game modes and also between main animations. With this change, global animations will really be drawn with their defined draw order. --- src/anim.c | 312 +++++++++++++++++++++-------------------------------- 1 file changed, 123 insertions(+), 189 deletions(-) diff --git a/src/anim.c b/src/anim.c index 0cb2023d..e836ff6a 100644 --- a/src/anim.c +++ b/src/anim.c @@ -34,6 +34,10 @@ #define NUM_GLOBAL_ANIM_PARTS_AND_TOONS MAX(NUM_GLOBAL_ANIM_PARTS_ALL, \ NUM_GLOBAL_TOON_PARTS) +#define MAX_GLOBAL_ANIM_LIST (NUM_GAME_MODES * \ + NUM_GLOBAL_ANIMS_AND_TOONS * \ + NUM_GLOBAL_ANIM_PARTS_AND_TOONS) + #define ANIM_CLASS_BIT_TITLE_INITIAL 0 #define ANIM_CLASS_BIT_TITLE 1 #define ANIM_CLASS_BIT_MAIN 2 @@ -250,6 +254,8 @@ static void ResetGlobalAnim_Clickable(void); static void ResetGlobalAnim_Clicked(void); static struct GlobalAnimControlInfo global_anim_ctrl[NUM_GAME_MODES]; +static struct GlobalAnimPartControlInfo *global_anim_list[MAX_GLOBAL_ANIM_LIST]; +static int num_global_anim_list = 0; static unsigned int anim_sync_frame = 0; @@ -355,27 +361,17 @@ static int getGlobalAnimationPart(struct GlobalAnimMainControlInfo *anim) static int compareGlobalAnimPartControlInfo(const void *obj1, const void *obj2) { const struct GlobalAnimPartControlInfo *o1 = - (struct GlobalAnimPartControlInfo *)obj1; + *(struct GlobalAnimPartControlInfo **)obj1; const struct GlobalAnimPartControlInfo *o2 = - (struct GlobalAnimPartControlInfo *)obj2; - int compare_result; - - // do not sort animations parts by draw order (as it would be confusing) - compare_result = o1->nr - o2->nr; - - return compare_result; -} - -static int compareGlobalAnimMainControlInfo(const void *obj1, const void *obj2) -{ - const struct GlobalAnimMainControlInfo *o1 = - (struct GlobalAnimMainControlInfo *)obj1; - const struct GlobalAnimMainControlInfo *o2 = - (struct GlobalAnimMainControlInfo *)obj2; + *(struct GlobalAnimPartControlInfo **)obj2; int compare_result; if (o1->control_info.draw_order != o2->control_info.draw_order) compare_result = o1->control_info.draw_order - o2->control_info.draw_order; + else if (o1->mode_nr != o2->mode_nr) + compare_result = o1->mode_nr - o2->mode_nr; + else if (o1->anim_nr != o2->anim_nr) + compare_result = o1->anim_nr - o2->anim_nr; else compare_result = o1->nr - o2->nr; @@ -626,26 +622,18 @@ static void InitGlobalAnimControls(void) InitToonControls(); - // sort all animations according to draw_order and animation number + // create list of all animation parts + num_global_anim_list = 0; for (m = 0; m < NUM_GAME_MODES; m++) - { - struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[m]; - - // sort all main animations for this game mode - qsort(ctrl->anim, ctrl->num_anims, - sizeof(struct GlobalAnimMainControlInfo), - compareGlobalAnimMainControlInfo); - - for (a = 0; a < ctrl->num_anims; a++) - { - struct GlobalAnimMainControlInfo *anim = &ctrl->anim[a]; + for (a = 0; a < global_anim_ctrl[m].num_anims; a++) + for (p = 0; p < global_anim_ctrl[m].anim[a].num_parts_all; p++) + global_anim_list[num_global_anim_list++] = + &global_anim_ctrl[m].anim[a].part[p]; - // sort all animation parts for this main animation - qsort(anim->part, anim->num_parts, - sizeof(struct GlobalAnimPartControlInfo), - compareGlobalAnimPartControlInfo); - } - } + // sort list of all animation parts according to draw_order and number + qsort(global_anim_list, num_global_anim_list, + sizeof(struct GlobalAnimPartControlInfo *), + compareGlobalAnimPartControlInfo); for (i = 0; i < NUM_GAME_MODES; i++) game_mode_anim_classes[i] = ANIM_CLASS_NONE; @@ -798,6 +786,7 @@ static void DrawGlobalAnimationsExt(int drawing_target, int drawing_stage) { int game_mode_anim_action[NUM_GAME_MODES]; int mode_nr; + int i; if (!setup.toons) return; @@ -897,89 +886,61 @@ static void DrawGlobalAnimationsExt(int drawing_target, int drawing_stage) if (global.anim_status == GAME_MODE_LOADING) return; - for (mode_nr = 0; mode_nr < NUM_GAME_MODES; mode_nr++) + for (i = 0; i < num_global_anim_list; i++) { - struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[mode_nr]; - int anim_nr; + struct GlobalAnimPartControlInfo *part = global_anim_list[i]; + struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[part->mode_nr]; + struct GlobalAnimMainControlInfo *anim = &ctrl->anim[part->anim_nr]; + struct GraphicInfo *g = &part->graphic_info; + Bitmap *src_bitmap; + int src_x, src_y; + int sync_frame; + int frame; + int last_anim_random_frame = gfx.anim_random_frame; // when preparing source fading buffer, only draw animations to be stopped if (drawing_target == DRAW_TO_FADE_SOURCE && - game_mode_anim_action[mode_nr] != ANIM_STOP) + game_mode_anim_action[part->mode_nr] != ANIM_STOP) continue; // when preparing target fading buffer, only draw animations to be started if (drawing_target == DRAW_TO_FADE_TARGET && - game_mode_anim_action[mode_nr] != ANIM_START) + game_mode_anim_action[part->mode_nr] != ANIM_START) continue; -#if 0 - if (mode_nr != GFX_SPECIAL_ARG_DEFAULT && - mode_nr != game_status) + if (!(anim->state & ANIM_STATE_RUNNING)) continue; -#endif - - for (anim_nr = 0; anim_nr < ctrl->num_anims; anim_nr++) - { - struct GlobalAnimMainControlInfo *anim = &ctrl->anim[anim_nr]; - struct GraphicInfo *c = &anim->control_info; - int part_first, part_last; - int part_nr; - if (!(anim->state & ANIM_STATE_RUNNING)) - continue; - - part_first = part_last = anim->active_part_nr; - - if (c->anim_mode & ANIM_ALL || anim->num_parts == 0) - { - int num_parts = anim->num_parts + (anim->has_base ? 1 : 0); - - part_first = 0; - part_last = num_parts - 1; - } - - for (part_nr = part_first; part_nr <= part_last; part_nr++) - { - struct GlobalAnimPartControlInfo *part = &anim->part[part_nr]; - struct GraphicInfo *g = &part->graphic_info; - Bitmap *src_bitmap; - int src_x, src_y; - int sync_frame; - int frame; - int last_anim_random_frame = gfx.anim_random_frame; - - if (!(part->state & ANIM_STATE_RUNNING)) - continue; + if (!(part->state & ANIM_STATE_RUNNING)) + continue; - if (part->drawing_stage != drawing_stage) - continue; + if (part->drawing_stage != drawing_stage) + continue; - // if game is paused, also pause playfield and door animations - if (isPausedOnPlayfieldOrDoor(part)) - part->initial_anim_sync_frame++; + // if game is paused, also pause playfield and door animations + if (isPausedOnPlayfieldOrDoor(part)) + part->initial_anim_sync_frame++; - sync_frame = anim_sync_frame - part->initial_anim_sync_frame; + sync_frame = anim_sync_frame - part->initial_anim_sync_frame; - // re-initialize random animation frame after animation delay - if (g->anim_mode == ANIM_RANDOM && - sync_frame % g->anim_delay == 0 && - sync_frame > 0) - part->anim_random_frame = GetSimpleRandom(g->anim_frames); + // re-initialize random animation frame after animation delay + if (g->anim_mode == ANIM_RANDOM && + sync_frame % g->anim_delay == 0 && + sync_frame > 0) + part->anim_random_frame = GetSimpleRandom(g->anim_frames); - gfx.anim_random_frame = part->anim_random_frame; + gfx.anim_random_frame = part->anim_random_frame; - frame = getAnimationFrame(g->anim_frames, g->anim_delay, - g->anim_mode, g->anim_start_frame, - sync_frame); + frame = getAnimationFrame(g->anim_frames, g->anim_delay, + g->anim_mode, g->anim_start_frame, + sync_frame); - gfx.anim_random_frame = last_anim_random_frame; + gfx.anim_random_frame = last_anim_random_frame; - getGlobalAnimGraphicSource(part->graphic, frame, &src_bitmap, - &src_x, &src_y); + getGlobalAnimGraphicSource(part->graphic, frame, &src_bitmap, + &src_x, &src_y); - BlitGlobalAnimation(part, src_bitmap, src_x, src_y, drawing_target); - } - } + BlitGlobalAnimation(part, src_bitmap, src_x, src_y, drawing_target); } if (drawing_target == DRAW_TO_FADE_TARGET) @@ -2080,29 +2041,17 @@ static boolean DoGlobalAnim_EventAction(struct GlobalAnimPartControlInfo *part) static void InitGlobalAnim_Clickable(void) { - int mode_nr; + int i; - for (mode_nr = 0; mode_nr < NUM_GAME_MODES; mode_nr++) + for (i = 0; i < num_global_anim_list; i++) { - struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[mode_nr]; - int anim_nr; + struct GlobalAnimPartControlInfo *part = global_anim_list[i]; - for (anim_nr = 0; anim_nr < ctrl->num_anims; anim_nr++) - { - struct GlobalAnimMainControlInfo *anim = &ctrl->anim[anim_nr]; - int part_nr; + if (part->triggered) + part->clicked = TRUE; - for (part_nr = 0; part_nr < anim->num_parts_all; part_nr++) - { - struct GlobalAnimPartControlInfo *part = &anim->part[part_nr]; - - if (part->triggered) - part->clicked = TRUE; - - part->triggered = FALSE; - part->clickable = FALSE; - } - } + part->triggered = FALSE; + part->clickable = FALSE; } } @@ -2116,108 +2065,93 @@ static boolean InitGlobalAnim_Clicked(int mx, int my, int clicked_event) boolean anything_clicked = FALSE; boolean any_part_clicked = FALSE; boolean any_event_action = FALSE; - int mode_nr; int i; - // check game modes in reverse draw order (to stop when clicked) - for (mode_nr = NUM_GAME_MODES - 1; mode_nr >= 0; mode_nr--) + // check animation parts in reverse draw order (to stop when clicked) + for (i = num_global_anim_list - 1; i >= 0; i--) { - struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[mode_nr]; - int anim_nr; - - // check animations in reverse draw order (to stop when clicked) - for (anim_nr = ctrl->num_anims - 1; anim_nr >= 0; anim_nr--) - { - struct GlobalAnimMainControlInfo *anim = &ctrl->anim[anim_nr]; - int part_nr; + struct GlobalAnimPartControlInfo *part = global_anim_list[i]; - // check animation parts in reverse draw order (to stop when clicked) - for (part_nr = anim->num_parts_all - 1; part_nr >= 0; part_nr--) - { - struct GlobalAnimPartControlInfo *part = &anim->part[part_nr]; - - // if request dialog is active, only handle pointer-style animations - if (game.request_active && - part->control_info.class != get_hash_from_key("pointer")) - continue; + // if request dialog is active, only handle pointer-style animations + if (game.request_active && + part->control_info.class != get_hash_from_key("pointer")) + continue; - if (clicked_event == ANIM_CLICKED_RESET) - { - part->clicked = FALSE; + if (clicked_event == ANIM_CLICKED_RESET) + { + part->clicked = FALSE; - continue; - } + continue; + } - if (!part->clickable) - continue; + if (!part->clickable) + continue; - if (!(part->state & ANIM_STATE_RUNNING)) - continue; + if (!(part->state & ANIM_STATE_RUNNING)) + continue; - // always handle "any" click events (clicking anywhere on screen) ... - if (clicked_event == ANIM_CLICKED_PRESSED && - isClickablePart(part, ANIM_EVENT_ANY)) - { + // always handle "any" click events (clicking anywhere on screen) ... + if (clicked_event == ANIM_CLICKED_PRESSED && + isClickablePart(part, ANIM_EVENT_ANY)) + { #if DEBUG_ANIM_EVENTS - Debug("anim:InitGlobalAnim_Clicked", "%d.%d TRIGGERED BY ANY", - part->old_anim_nr + 1, part->old_nr + 1); + Debug("anim:InitGlobalAnim_Clicked", "%d.%d TRIGGERED BY ANY", + part->old_anim_nr + 1, part->old_nr + 1); #endif - anything_clicked = part->clicked = TRUE; - click_consumed |= clickConsumed(part); - } + anything_clicked = part->clicked = TRUE; + click_consumed |= clickConsumed(part); + } - // always handle "unclick:any" events (releasing anywhere on screen) ... - if (clicked_event == ANIM_CLICKED_RELEASED && - isClickablePart(part, ANIM_EVENT_UNCLICK_ANY)) - { + // always handle "unclick:any" events (releasing anywhere on screen) ... + if (clicked_event == ANIM_CLICKED_RELEASED && + isClickablePart(part, ANIM_EVENT_UNCLICK_ANY)) + { #if DEBUG_ANIM_EVENTS - Debug("anim:InitGlobalAnim_Clicked", "%d.%d TRIGGERED BY UNCLICK:ANY", - part->old_anim_nr + 1, part->old_nr + 1); + Debug("anim:InitGlobalAnim_Clicked", "%d.%d TRIGGERED BY UNCLICK:ANY", + part->old_anim_nr + 1, part->old_nr + 1); #endif - anything_clicked = part->clicked = TRUE; - click_consumed |= clickConsumed(part); - } + anything_clicked = part->clicked = TRUE; + click_consumed |= clickConsumed(part); + } - // ... but only handle the first (topmost) clickable animation - if (any_part_clicked) - continue; + // ... but only handle the first (topmost) clickable animation + if (any_part_clicked) + continue; - if (clicked_event == ANIM_CLICKED_PRESSED && - isClickedPart(part, mx, my, TRUE)) - { + if (clicked_event == ANIM_CLICKED_PRESSED && + isClickedPart(part, mx, my, TRUE)) + { #if 0 - Debug("anim:InitGlobalAnim_Clicked", "%d.%d CLICKED [%d]", - anim_nr, part_nr, part->control_info.anim_event_action); + Debug("anim:InitGlobalAnim_Clicked", "%d.%d CLICKED [%d]", + anim_nr, part_nr, part->control_info.anim_event_action); #endif - // after executing event action, ignore any further actions - if (!any_event_action && DoGlobalAnim_EventAction(part)) - any_event_action = TRUE; + // after executing event action, ignore any further actions + if (!any_event_action && DoGlobalAnim_EventAction(part)) + any_event_action = TRUE; - // determine if mouse clicks should be blocked from other animations - any_part_clicked |= clickConsumed(part); + // determine if mouse clicks should be blocked from other animations + any_part_clicked |= clickConsumed(part); - if (isClickablePart(part, ANIM_EVENT_SELF)) - { + if (isClickablePart(part, ANIM_EVENT_SELF)) + { #if DEBUG_ANIM_EVENTS - Debug("anim:InitGlobalAnim_Clicked", "%d.%d TRIGGERED BY SELF", - part->old_anim_nr + 1, part->old_nr + 1); + Debug("anim:InitGlobalAnim_Clicked", "%d.%d TRIGGERED BY SELF", + part->old_anim_nr + 1, part->old_nr + 1); #endif - anything_clicked = part->clicked = TRUE; - click_consumed |= clickConsumed(part); - } + anything_clicked = part->clicked = TRUE; + click_consumed |= clickConsumed(part); + } - // determine if mouse clicks should be blocked by this animation - click_consumed |= clickBlocked(part); + // determine if mouse clicks should be blocked by this animation + click_consumed |= clickBlocked(part); - // check if this click is defined to trigger other animations - InitGlobalAnim_Triggered(part, &click_consumed, &any_event_action, - ANIM_EVENT_CLICK, "CLICK"); - } - } + // check if this click is defined to trigger other animations + InitGlobalAnim_Triggered(part, &click_consumed, &any_event_action, + ANIM_EVENT_CLICK, "CLICK"); } } -- 2.34.1 From 5d1f7afe4cac805e10a8f4e61c67497c55e22453 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Wed, 13 Dec 2023 17:06:03 +0100 Subject: [PATCH 06/16] reverted setting (and maybe inheriting) draw order for global animations Although this feature seems to be quite useful (setting draw order for main animations once, and let animation parts inherit the draw order from the main animation if it is not defined for the animation part), it would have to be implemented for all other attributes, too (like X and Y position of the main animation and animation parts, for example), so it seems to be better to not make an exception for this specific attribute. This reverts commit 895d5cb3. --- src/anim.c | 8 -------- src/init.c | 21 ++++----------------- 2 files changed, 4 insertions(+), 25 deletions(-) diff --git a/src/anim.c b/src/anim.c index e836ff6a..cdc0fd05 100644 --- a/src/anim.c +++ b/src/anim.c @@ -531,10 +531,6 @@ static void InitGlobalAnimControls(void) anim->state = ANIM_STATE_INACTIVE; - // if draw order is undefined, set to default value "0" - if (anim->control_info.draw_order == ARG_UNDEFINED_VALUE) - anim->control_info.draw_order = 0; - part_nr = 0; for (p = 0; p < NUM_GLOBAL_ANIM_PARTS_ALL; p++) @@ -606,10 +602,6 @@ static void InitGlobalAnimControls(void) if (part->control_info.class == get_hash_from_key("pointer") && part->control_info.style == STYLE_DEFAULT) part->control_info.style |= STYLE_PASSTHROUGH; - - // if draw order is undefined, inherit it from main animation - if (part->control_info.draw_order == ARG_UNDEFINED_VALUE) - part->control_info.draw_order = anim->control_info.draw_order; } if (anim->num_parts > 0 || anim->has_base) diff --git a/src/init.c b/src/init.c index 45945dcd..af11e4c7 100644 --- a/src/init.c +++ b/src/init.c @@ -722,23 +722,14 @@ static void InitGlobalAnimGraphicInfo(void) struct GraphicInfo *g = &graphic_info[graphic]; struct FileInfo *image = getImageListEntryFromImageID(graphic); char **parameter_raw = image->parameter; - int p1 = GFX_ARG_DRAW_MASKED; - int p2 = GFX_ARG_DRAW_ORDER; - int draw_masked = get_graphic_parameter_value(parameter_raw[p1], - image_config_suffix[p1].token, - image_config_suffix[p1].type); - int draw_order = get_graphic_parameter_value(parameter_raw[p2], - image_config_suffix[p2].token, - image_config_suffix[p2].type); + int p = GFX_ARG_DRAW_MASKED; + int draw_masked = get_graphic_parameter_value(parameter_raw[p], + image_config_suffix[p].token, + image_config_suffix[p].type); // if ".draw_masked" parameter is undefined, use default value "TRUE" if (draw_masked == ARG_UNDEFINED_VALUE) g->draw_masked = TRUE; - - // if ".draw_order" parameter is undefined, set back to "undefined" - // (used to be able to inherit draw order from main animation later) - if (draw_order == ARG_UNDEFINED_VALUE) - g->draw_order = ARG_UNDEFINED_VALUE; } #if 0 @@ -1666,10 +1657,6 @@ static void set_graphic_parameters_ext(int graphic, int *parameter, if (parameter[GFX_ARG_DRAW_MASKED] != ARG_UNDEFINED_VALUE) g->draw_masked = parameter[GFX_ARG_DRAW_MASKED]; - // use a different default value for global animations (corrected later) - if (graphic >= IMG_GLOBAL_ANIM_1 && graphic <= IMG_GLOBAL_ANIM_32) - g->draw_order = ARG_UNDEFINED_VALUE; - // used for toon animations and global animations if (parameter[GFX_ARG_DRAW_ORDER] != ARG_UNDEFINED_VALUE) g->draw_order = parameter[GFX_ARG_DRAW_ORDER]; -- 2.34.1 From b08a9452f891ea0132aca72b79abead3f7784d1c Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Wed, 13 Dec 2023 17:15:08 +0100 Subject: [PATCH 07/16] fixed always drawing pointer-style global animations above everything else --- src/libgame/sdl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libgame/sdl.c b/src/libgame/sdl.c index 096eeb70..0b3ec7f6 100644 --- a/src/libgame/sdl.c +++ b/src/libgame/sdl.c @@ -70,13 +70,13 @@ static void FinalizeScreen(int draw_target) if (gfx.draw_envelope_request_function != NULL) gfx.draw_envelope_request_function(draw_target); - // copy global animations to render target buffer, if defined (mouse pointer) - if (gfx.draw_global_anim_function != NULL) - gfx.draw_global_anim_function(draw_target, DRAW_GLOBAL_ANIM_STAGE_3); - // copy tile selection cursor to render target buffer, if defined (part 2) if (gfx.draw_tile_cursor_function != NULL) gfx.draw_tile_cursor_function(draw_target, FALSE); + + // copy global animations to render target buffer, if defined (mouse pointer) + if (gfx.draw_global_anim_function != NULL) + gfx.draw_global_anim_function(draw_target, DRAW_GLOBAL_ANIM_STAGE_3); } static void UpdateScreenExt(SDL_Rect *rect, boolean with_frame_delay) -- 2.34.1 From 957bd13ee6bd1ab827435f4859d8e53f126891ef Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Wed, 13 Dec 2023 17:56:35 +0100 Subject: [PATCH 08/16] changed setup option to disable global animations to only affect toons All global animations can still be disabled in the setup config file, but this should probably only be used for testing purposes, as global animations are an integral part of certain custom level sets now. --- src/anim.c | 7 ++++++- src/files.c | 5 +++++ src/init.c | 6 +++--- src/libgame/system.h | 1 + src/screens.c | 2 +- 5 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/anim.c b/src/anim.c index cdc0fd05..b651ac6f 100644 --- a/src/anim.c +++ b/src/anim.c @@ -780,7 +780,7 @@ static void DrawGlobalAnimationsExt(int drawing_target, int drawing_stage) int mode_nr; int i; - if (!setup.toons) + if (!setup.global_animations) return; if (drawing_stage == DRAW_GLOBAL_ANIM_STAGE_1 && @@ -890,6 +890,11 @@ static void DrawGlobalAnimationsExt(int drawing_target, int drawing_stage) int frame; int last_anim_random_frame = gfx.anim_random_frame; + if (!setup.toons && + part->graphic >= IMG_TOON_1 && + part->graphic <= IMG_TOON_20) + continue; + // when preparing source fading buffer, only draw animations to be stopped if (drawing_target == DRAW_TO_FADE_SOURCE && game_mode_anim_action[part->mode_nr] != ANIM_STOP) diff --git a/src/files.c b/src/files.c index c4881f64..671a8515 100644 --- a/src/files.c +++ b/src/files.c @@ -9490,6 +9490,10 @@ static struct TokenInfo global_setup_tokens[] = TYPE_SWITCH, &setup.toons, "toons" }, + { + TYPE_SWITCH, + &setup.global_animations, "global_animations" + }, { TYPE_SWITCH, &setup.scroll_delay, "scroll_delay" @@ -10409,6 +10413,7 @@ static void setSetupInfoToDefaults(struct SetupInfo *si) si->sound_music = TRUE; si->sound_simple = TRUE; si->toons = TRUE; + si->global_animations = TRUE; si->scroll_delay = TRUE; si->forced_scroll_delay = FALSE; si->scroll_delay_value = STD_SCROLL_DELAY; diff --git a/src/init.c b/src/init.c index af11e4c7..62a5d0ff 100644 --- a/src/init.c +++ b/src/init.c @@ -6477,8 +6477,8 @@ void DisplayExitMessage(char *format, va_list ap) BackToFront(); - // deactivate toons on error message screen - setup.toons = FALSE; + // deactivate toons and global animations on error message screen + setup.global_animations = FALSE; WaitForEventToContinue(); } @@ -6671,7 +6671,7 @@ static boolean WaitForApiThreads(void) return TRUE; // deactivate global animations (not accessible in game state "loading") - setup.toons = FALSE; + setup.global_animations = FALSE; // set game state to "loading" to be able to show busy animation SetGameStatus(GAME_MODE_LOADING); diff --git a/src/libgame/system.h b/src/libgame/system.h index bcfee01e..73d50ddc 100644 --- a/src/libgame/system.h +++ b/src/libgame/system.h @@ -1518,6 +1518,7 @@ struct SetupInfo boolean sound_music; boolean sound_simple; boolean toons; + boolean global_animations; boolean scroll_delay; boolean forced_scroll_delay; int scroll_delay_value; diff --git a/src/screens.c b/src/screens.c index c919220e..fc344373 100644 --- a/src/screens.c +++ b/src/screens.c @@ -7548,7 +7548,7 @@ static struct TokenInfo setup_info_graphics[] = { TYPE_SWITCH, &setup.quick_switch, "Quick Player Focus Switch:" }, { TYPE_SWITCH, &setup.quick_doors, "Quick Menu Doors:" }, { TYPE_SWITCH, &setup.show_titlescreen,"Show Title Screens:" }, - { TYPE_SWITCH, &setup.toons, "Show Menu Animations:" }, + { TYPE_SWITCH, &setup.toons, "Show Toons:" }, { TYPE_SWITCH, &setup.small_game_graphics, "Small Game Graphics:" }, { TYPE_YES_NO_AUTO, &setup.debug.xsn_mode, debug_xsn_mode }, { TYPE_EMPTY, NULL, "" }, -- 2.34.1 From e29c8fb313787ad2a768de58c5852d3ba29d43d5 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Mon, 18 Dec 2023 11:41:35 +0100 Subject: [PATCH 09/16] fixed bug with closing doors when exiting from level editor --- src/editor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/editor.c b/src/editor.c index 177336f7..671ac61d 100644 --- a/src/editor.c +++ b/src/editor.c @@ -15283,7 +15283,7 @@ void RequestExitLevelEditor(boolean ask_if_level_has_changed, vp_door_2->height == VYSIZE) CloseDoor(DOOR_CLOSE_ALL | DOOR_NO_DELAY); else - SetDoorState(DOOR_CLOSE_2); + SetDoorState(DOOR_CLOSE_ALL); BackToFront(); -- 2.34.1 From e498c78309eb6b3b2cc1820833120862569858b7 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Mon, 18 Dec 2023 12:35:17 +0100 Subject: [PATCH 10/16] added "const" to some string function parameters --- src/libgame/misc.c | 49 +++++++++++++++++++++++++--------------------- src/libgame/misc.h | 41 +++++++++++++++++++------------------- 2 files changed, 48 insertions(+), 42 deletions(-) diff --git a/src/libgame/misc.c b/src/libgame/misc.c index 02358aa2..536d90b5 100644 --- a/src/libgame/misc.c +++ b/src/libgame/misc.c @@ -1088,7 +1088,9 @@ char *getBasePath(char *filename) // various string functions // ---------------------------------------------------------------------------- -char *getStringCat2WithSeparator(char *s1, char *s2, char *sep) +char *getStringCat2WithSeparator(const char *s1, + const char *s2, + const char *sep) { if (s1 == NULL || s2 == NULL || sep == NULL) return NULL; @@ -1101,7 +1103,10 @@ char *getStringCat2WithSeparator(char *s1, char *s2, char *sep) return complete_string; } -char *getStringCat3WithSeparator(char *s1, char *s2, char *s3, char *sep) +char *getStringCat3WithSeparator(const char *s1, + const char *s2, + const char *s3, + const char *sep) { if (s1 == NULL || s2 == NULL || s3 == NULL || sep == NULL) return NULL; @@ -1115,17 +1120,17 @@ char *getStringCat3WithSeparator(char *s1, char *s2, char *s3, char *sep) return complete_string; } -char *getStringCat2(char *s1, char *s2) +char *getStringCat2(const char *s1, const char *s2) { return getStringCat2WithSeparator(s1, s2, ""); } -char *getStringCat3(char *s1, char *s2, char *s3) +char *getStringCat3(const char *s1, const char *s2, const char *s3) { return getStringCat3WithSeparator(s1, s2, s3, ""); } -char *getPath2(char *path1, char *path2) +char *getPath2(const char *path1, const char *path2) { #if defined(PLATFORM_ANDROID) // workaround for reading from assets directory -- skip "." subdirs in path @@ -1138,7 +1143,7 @@ char *getPath2(char *path1, char *path2) return getStringCat2WithSeparator(path1, path2, STRING_PATH_SEPARATOR); } -char *getPath3(char *path1, char *path2, char *path3) +char *getPath3(const char *path1, const char *path2, const char *path3) { #if defined(PLATFORM_ANDROID) // workaround for reading from assets directory -- skip "." subdirs in path @@ -1166,12 +1171,12 @@ static char *getPngOrPcxIfNotExists(char *filename) return filename; } -char *getImg2(char *path1, char *path2) +char *getImg2(const char *path1, const char *path2) { return getPngOrPcxIfNotExists(getPath2(path1, path2)); } -char *getImg3(char *path1, char *path2, char *path3) +char *getImg3(const char *path1, const char *path2, const char *path3) { return getPngOrPcxIfNotExists(getPath3(path1, path2, path3)); } @@ -1227,14 +1232,14 @@ char *getStringToLower(const char *s) return s_copy; } -void setString(char **old_value, char *new_value) +void setString(char **old_value, const char *new_value) { checked_free(*old_value); *old_value = getStringCopy(new_value); } -boolean strEqual(char *s1, char *s2) +boolean strEqual(const char *s1, const char *s2) { return (s1 == NULL && s2 == NULL ? TRUE : s1 == NULL && s2 != NULL ? FALSE : @@ -1242,7 +1247,7 @@ boolean strEqual(char *s1, char *s2) strcmp(s1, s2) == 0); } -boolean strEqualN(char *s1, char *s2, int n) +boolean strEqualN(const char *s1, const char *s2, int n) { return (s1 == NULL && s2 == NULL ? TRUE : s1 == NULL && s2 != NULL ? FALSE : @@ -1250,7 +1255,7 @@ boolean strEqualN(char *s1, char *s2, int n) strncmp(s1, s2, n) == 0); } -boolean strEqualCase(char *s1, char *s2) +boolean strEqualCase(const char *s1, const char *s2) { return (s1 == NULL && s2 == NULL ? TRUE : s1 == NULL && s2 != NULL ? FALSE : @@ -1258,7 +1263,7 @@ boolean strEqualCase(char *s1, char *s2) strcasecmp(s1, s2) == 0); } -boolean strEqualCaseN(char *s1, char *s2, int n) +boolean strEqualCaseN(const char *s1, const char *s2, int n) { return (s1 == NULL && s2 == NULL ? TRUE : s1 == NULL && s2 != NULL ? FALSE : @@ -1266,7 +1271,7 @@ boolean strEqualCaseN(char *s1, char *s2, int n) strncasecmp(s1, s2, n) == 0); } -boolean strPrefix(char *s, char *prefix) +boolean strPrefix(const char *s, const char *prefix) { return (s == NULL && prefix == NULL ? TRUE : s == NULL && prefix != NULL ? FALSE : @@ -1274,7 +1279,7 @@ boolean strPrefix(char *s, char *prefix) strncmp(s, prefix, strlen(prefix)) == 0); } -boolean strSuffix(char *s, char *suffix) +boolean strSuffix(const char *s, const char *suffix) { return (s == NULL && suffix == NULL ? TRUE : s == NULL && suffix != NULL ? FALSE : @@ -1283,7 +1288,7 @@ boolean strSuffix(char *s, char *suffix) strcmp(&s[strlen(s) - strlen(suffix)], suffix) == 0); } -boolean strPrefixLower(char *s, char *prefix) +boolean strPrefixLower(const char *s, const char *prefix) { char *s_lower = getStringToLower(s); boolean match = strPrefix(s_lower, prefix); @@ -1293,7 +1298,7 @@ boolean strPrefixLower(char *s, char *prefix) return match; } -boolean strSuffixLower(char *s, char *suffix) +boolean strSuffixLower(const char *s, const char *suffix) { char *s_lower = getStringToLower(s); boolean match = strSuffix(s_lower, suffix); @@ -1303,7 +1308,7 @@ boolean strSuffixLower(char *s, char *suffix) return match; } -boolean isURL(char *s) +boolean isURL(const char *s) { while (*s && *s >= 'a' && *s <= 'z') s++; @@ -3072,7 +3077,7 @@ void freeDirectoryEntry(DirectoryEntry *dir_entry) // functions for checking files and filenames // ---------------------------------------------------------------------------- -boolean directoryExists(char *dir_name) +boolean directoryExists(const char *dir_name) { if (dir_name == NULL) return FALSE; @@ -3100,7 +3105,7 @@ boolean directoryExists(char *dir_name) return success; } -boolean fileExists(char *filename) +boolean fileExists(const char *filename) { if (filename == NULL) return FALSE; @@ -3124,7 +3129,7 @@ boolean fileExists(char *filename) } #if 0 -static boolean fileHasPrefix(char *basename, char *prefix) +static boolean fileHasPrefix(const char *basename, const char *prefix) { static char *basename_lower = NULL; int basename_length, prefix_length; @@ -3147,7 +3152,7 @@ static boolean fileHasPrefix(char *basename, char *prefix) } #endif -static boolean fileHasSuffix(char *basename, char *suffix) +static boolean fileHasSuffix(const char *basename, const char *suffix) { static char *basename_lower = NULL; int basename_length, suffix_length; diff --git a/src/libgame/misc.h b/src/libgame/misc.h index 7097e968..2893ba0f 100644 --- a/src/libgame/misc.h +++ b/src/libgame/misc.h @@ -168,28 +168,28 @@ char *getBaseName(char *); char *getBaseNamePtr(char *); char *getBaseNameNoSuffix(char *); -char *getStringCat2WithSeparator(char *, char *, char *); -char *getStringCat3WithSeparator(char *, char *, char *, char *); -char *getStringCat2(char *, char *); -char *getStringCat3(char *, char *, char *); -char *getPath2(char *, char *); -char *getPath3(char *, char *, char*); -char *getImg2(char *, char *); -char *getImg3(char *, char *, char*); +char *getStringCat2WithSeparator(const char *, const char *, const char *); +char *getStringCat3WithSeparator(const char *, const char *, const char *, const char *); +char *getStringCat2(const char *, const char *); +char *getStringCat3(const char *, const char *, const char *); +char *getPath2(const char *, const char *); +char *getPath3(const char *, const char *, const char *); +char *getImg2(const char *, const char *); +char *getImg3(const char *, const char *, const char *); char *getStringCopy(const char *); char *getStringCopyN(const char *, int); char *getStringCopyNStatic(const char *, int); char *getStringToLower(const char *); -void setString(char **, char *); -boolean strEqual(char *, char *); -boolean strEqualN(char *, char *, int); -boolean strEqualCase(char *, char *); -boolean strEqualCaseN(char *, char *, int); -boolean strPrefix(char *, char *); -boolean strSuffix(char *, char *); -boolean strPrefixLower(char *, char *); -boolean strSuffixLower(char *, char *); -boolean isURL(char *); +void setString(char **, const char *); +boolean strEqual(const char *, const char *); +boolean strEqualN(const char *, const char *, int); +boolean strEqualCase(const char *, const char *); +boolean strEqualCaseN(const char *, const char *, int); +boolean strPrefix(const char *, const char *); +boolean strSuffix(const char *, const char *); +boolean strPrefixLower(const char *, const char *); +boolean strSuffixLower(const char *, const char *); +boolean isURL(const char *); void GetOptions(int, char **, void (*print_usage_function)(void), @@ -279,8 +279,9 @@ int closeDirectory(Directory *); DirectoryEntry *readDirectory(Directory *); void freeDirectoryEntry(DirectoryEntry *); -boolean directoryExists(char *); -boolean fileExists(char *); +boolean directoryExists(const char *); +boolean fileExists(const char *); + boolean FileIsGraphic(char *); boolean FileIsSound(char *); boolean FileIsMusic(char *); -- 2.34.1 From ffbf029c35d1abc2975fe61dc2cd7230d7e2f04b Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Fri, 29 Dec 2023 10:41:29 +0100 Subject: [PATCH 11/16] version number set to 4.3.8.2 --- src/main.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.h b/src/main.h index 609216f9..a58ab7bb 100644 --- a/src/main.h +++ b/src/main.h @@ -2664,7 +2664,7 @@ enum #define PROGRAM_VERSION_SUPER 4 #define PROGRAM_VERSION_MAJOR 3 #define PROGRAM_VERSION_MINOR 8 -#define PROGRAM_VERSION_PATCH 1 +#define PROGRAM_VERSION_PATCH 2 #define PROGRAM_VERSION_EXTRA "" #define PROGRAM_TITLE_STRING "Rocks'n'Diamonds" -- 2.34.1 From d3169996a584ab249a078dd71a62111f60c7683c Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Thu, 4 Jan 2024 14:36:48 +0100 Subject: [PATCH 12/16] re-added explicitly setting draw order for pointer-style animations Even though pointer-style animations are handled specially when being drawn (on top of all other global animations), they are not handled specially when being checked for clicks. Therefore, forcing a high draw order for pointer-style animations is still required (as the draw order is not only used for drawing, but also for the order of checking animations for mouse clicks). This reverts commit d1a0dcb3. --- src/anim.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/anim.c b/src/anim.c index b651ac6f..1389dc4e 100644 --- a/src/anim.c +++ b/src/anim.c @@ -598,10 +598,15 @@ static void InitGlobalAnimControls(void) anim->has_base = TRUE; } - // force pointer-style animations to pass-through clicks - if (part->control_info.class == get_hash_from_key("pointer") && - part->control_info.style == STYLE_DEFAULT) + // apply special settings to pointer-style animations + if (part->control_info.class == get_hash_from_key("pointer")) + { + // force pointer-style animations to be checked for clicks first + part->control_info.draw_order = 1000000; + + // force pointer-style animations to pass-through clicks part->control_info.style |= STYLE_PASSTHROUGH; + } } if (anim->num_parts > 0 || anim->has_base) -- 2.34.1 From 89477bc94ecdbe2bc6508fd9c85ccc852db54e69 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Sun, 7 Jan 2024 23:29:00 +0100 Subject: [PATCH 13/16] fixed truncating internal game element descriptions in level editor --- src/files.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/files.c b/src/files.c index 671a8515..097deead 100644 --- a/src/files.c +++ b/src/files.c @@ -1903,8 +1903,7 @@ static void setLevelInfoToDefaults_Elements(struct LevelInfo *level) setElementChangeInfoToDefaults(ei->change); if (IS_CUSTOM_ELEMENT(element) || - IS_GROUP_ELEMENT(element) || - IS_INTERNAL_ELEMENT(element)) + IS_GROUP_ELEMENT(element)) { setElementDescriptionToDefault(ei); -- 2.34.1 From 1ffbb41cf197bfa499c80381981716a797683b59 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Mon, 8 Jan 2024 00:16:39 +0100 Subject: [PATCH 14/16] updated title text and border graphic to show current year --- graphics/gfx_classic/RocksScreen.png | Bin 5387 -> 5405 bytes src/main.h | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/graphics/gfx_classic/RocksScreen.png b/graphics/gfx_classic/RocksScreen.png index ae1972bae2986024ba8de1c2e8f430f7109d5140..2a25840d9f3916bc99ce210c3ffc1b16f4bfedd1 100644 GIT binary patch literal 5405 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 literal 5387 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 EZ?wm2{r~^~ diff --git a/src/main.h b/src/main.h index a58ab7bb..6f5b29c7 100644 --- a/src/main.h +++ b/src/main.h @@ -2671,7 +2671,7 @@ enum #define PROGRAM_AUTHOR_STRING "Holger Schemel" #define PROGRAM_EMAIL_STRING "info@artsoft.org" #define PROGRAM_WEBSITE_STRING "https://www.artsoft.org/" -#define PROGRAM_COPYRIGHT_STRING "1995-2023 by Holger Schemel" +#define PROGRAM_COPYRIGHT_STRING "1995-2024 by Holger Schemel" #define PROGRAM_COMPANY_STRING "A Game by Artsoft Entertainment" #define PROGRAM_ICON_FILENAME "icons/icon.png" -- 2.34.1 From 012b5a6611e656aa0922c88f8f52661ba020f8d1 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Sun, 18 Feb 2024 14:29:23 +0100 Subject: [PATCH 15/16] fixed drawing pause button on closed door when restarting paused game --- src/game.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/game.c b/src/game.c index d1bf2d7d..872b4e9b 100644 --- a/src/game.c +++ b/src/game.c @@ -16473,6 +16473,10 @@ void ModifyPauseButtons(void) }; int i; + // do not redraw pause button on closed door (may happen when restarting game) + if (!(GetDoorState() & DOOR_OPEN_1)) + return; + for (i = 0; ids[i] > -1; i++) ModifyGadget(game_gadget[ids[i]], GDI_CHECKED, tape.pausing, GDI_END); } -- 2.34.1 From de2230033229c30b5b4d344d57f9b61d7be941d3 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Sun, 18 Feb 2024 14:34:28 +0100 Subject: [PATCH 16/16] added optional button to restart game (door, panel and touch variants) --- graphics/gfx_classic/RocksDoor2.png | Bin 1402 -> 2252 bytes graphics/gfx_classic/RocksTouch.png | Bin 2926 -> 4216 bytes src/conf_gfx.c | 21 +++++++++++ src/game.c | 56 +++++++++++++++++++++------- src/game.h | 5 +++ 5 files changed, 68 insertions(+), 14 deletions(-) diff --git a/graphics/gfx_classic/RocksDoor2.png b/graphics/gfx_classic/RocksDoor2.png index 73efd72d531f0335a909cce09790a0d894ebf171..7d150be02f4870e85a87db166bd812208a54bd16 100644 GIT binary patch literal 2252 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 RFev~4002ovPDHLkV1jAiflB}Y diff --git a/graphics/gfx_classic/RocksTouch.png b/graphics/gfx_classic/RocksTouch.png index 4cb63e9c68d4929844f6eab27cd17e4be683e0c0..919207ce5eaf21550ea24974081405c46842d1b5 100644 GIT binary patch literal 4216 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 D^MVsr diff --git a/src/conf_gfx.c b/src/conf_gfx.c index 7b9d243e..62bdab0e 100644 --- a/src/conf_gfx.c +++ b/src/conf_gfx.c @@ -6420,6 +6420,13 @@ struct ConfigInfo image_config[] = { "gfx.game.button.load.height", "30" }, { "gfx.game.button.load.pressed_xoffset", "-100" }, + { "gfx.game.button.restart", "RocksDoor2.png" }, + { "gfx.game.button.restart.x", "200" }, + { "gfx.game.button.restart.y", "50" }, + { "gfx.game.button.restart.width", "30" }, + { "gfx.game.button.restart.height", "30" }, + { "gfx.game.button.restart.pressed_xoffset", "30" }, + { "gfx.game.button.sound_music", "RocksDoor.png" }, { "gfx.game.button.sound_music.x", "305" }, { "gfx.game.button.sound_music.y", "245" }, @@ -6445,6 +6452,7 @@ struct ConfigInfo image_config[] = { "gfx.game.button.panel_stop", UNDEFINED_FILENAME }, { "gfx.game.button.panel_pause", UNDEFINED_FILENAME }, { "gfx.game.button.panel_play", UNDEFINED_FILENAME }, + { "gfx.game.button.panel_restart", UNDEFINED_FILENAME }, { "gfx.game.button.panel_sound_music", UNDEFINED_FILENAME }, { "gfx.game.button.panel_sound_loops", UNDEFINED_FILENAME }, @@ -6464,6 +6472,13 @@ struct ConfigInfo image_config[] = { "gfx.game.button.touch_pause.pressed_xoffset", "-200" }, { "gfx.game.button.touch_pause.active_yoffset", "60" }, + { "gfx.game.button.touch_restart", "RocksTouch.png" }, + { "gfx.game.button.touch_restart.x", "210" }, + { "gfx.game.button.touch_restart.y", "240" }, + { "gfx.game.button.touch_restart.width", "60" }, + { "gfx.game.button.touch_restart.height", "60" }, + { "gfx.game.button.touch_restart.pressed_xoffset", "-200" }, + { "gfx.tape.button.eject", "RocksDoor.png" }, { "gfx.tape.button.eject.x", "305" }, { "gfx.tape.button.eject.y", "357" }, @@ -9733,6 +9748,8 @@ struct ConfigInfo image_config[] = { "game.button.pause2.y", "-1" }, { "game.button.load.x", "-1" }, { "game.button.load.y", "-1" }, + { "game.button.restart.x", "-1" }, + { "game.button.restart.y", "-1" }, { "game.button.sound_music.x", "5" }, { "game.button.sound_music.y", "245" }, { "game.button.sound_loops.x", "35" }, @@ -9746,6 +9763,8 @@ struct ConfigInfo image_config[] = { "game.button.panel_pause.y", "-1" }, { "game.button.panel_play.x", "-1" }, { "game.button.panel_play.y", "-1" }, + { "game.button.panel_restart.x", "-1" }, + { "game.button.panel_restart.y", "-1" }, { "game.button.panel_sound_music.x", "-1" }, { "game.button.panel_sound_music.y", "-1" }, { "game.button.panel_sound_loops.x", "-1" }, @@ -9757,6 +9776,8 @@ struct ConfigInfo image_config[] = { "game.button.touch_stop.y", "0" }, { "game.button.touch_pause.x", "-60" }, { "game.button.touch_pause.y", "0" }, + { "game.button.touch_restart.x", "-1" }, + { "game.button.touch_restart.y", "-1" }, { "tape.button.eject.x", "5" }, { "tape.button.eject.y", "77" }, diff --git a/src/game.c b/src/game.c index 872b4e9b..fd943b99 100644 --- a/src/game.c +++ b/src/game.c @@ -1017,19 +1017,22 @@ static struct GamePanelControlInfo game_panel_controls[] = #define GAME_CTRL_ID_SAVE 5 #define GAME_CTRL_ID_PAUSE2 6 #define GAME_CTRL_ID_LOAD 7 -#define GAME_CTRL_ID_PANEL_STOP 8 -#define GAME_CTRL_ID_PANEL_PAUSE 9 -#define GAME_CTRL_ID_PANEL_PLAY 10 -#define GAME_CTRL_ID_TOUCH_STOP 11 -#define GAME_CTRL_ID_TOUCH_PAUSE 12 -#define SOUND_CTRL_ID_MUSIC 13 -#define SOUND_CTRL_ID_LOOPS 14 -#define SOUND_CTRL_ID_SIMPLE 15 -#define SOUND_CTRL_ID_PANEL_MUSIC 16 -#define SOUND_CTRL_ID_PANEL_LOOPS 17 -#define SOUND_CTRL_ID_PANEL_SIMPLE 18 - -#define NUM_GAME_BUTTONS 19 +#define GAME_CTRL_ID_RESTART 8 +#define GAME_CTRL_ID_PANEL_STOP 9 +#define GAME_CTRL_ID_PANEL_PAUSE 10 +#define GAME_CTRL_ID_PANEL_PLAY 11 +#define GAME_CTRL_ID_PANEL_RESTART 12 +#define GAME_CTRL_ID_TOUCH_STOP 13 +#define GAME_CTRL_ID_TOUCH_PAUSE 14 +#define GAME_CTRL_ID_TOUCH_RESTART 15 +#define SOUND_CTRL_ID_MUSIC 16 +#define SOUND_CTRL_ID_LOOPS 17 +#define SOUND_CTRL_ID_SIMPLE 18 +#define SOUND_CTRL_ID_PANEL_MUSIC 19 +#define SOUND_CTRL_ID_PANEL_LOOPS 20 +#define SOUND_CTRL_ID_PANEL_SIMPLE 21 + +#define NUM_GAME_BUTTONS 22 // forward declaration for internal use @@ -16246,6 +16249,11 @@ static struct GAME_CTRL_ID_LOAD, NULL, TRUE, FALSE, "load game" }, + { + IMG_GFX_GAME_BUTTON_RESTART, &game.button.restart, + GAME_CTRL_ID_RESTART, NULL, + TRUE, FALSE, "restart game" + }, { IMG_GFX_GAME_BUTTON_PANEL_STOP, &game.button.panel_stop, GAME_CTRL_ID_PANEL_STOP, NULL, @@ -16261,6 +16269,11 @@ static struct GAME_CTRL_ID_PANEL_PLAY, NULL, FALSE, FALSE, "play game" }, + { + IMG_GFX_GAME_BUTTON_PANEL_RESTART, &game.button.panel_restart, + GAME_CTRL_ID_PANEL_RESTART, NULL, + FALSE, FALSE, "restart game" + }, { IMG_GFX_GAME_BUTTON_TOUCH_STOP, &game.button.touch_stop, GAME_CTRL_ID_TOUCH_STOP, NULL, @@ -16271,6 +16284,11 @@ static struct GAME_CTRL_ID_TOUCH_PAUSE, NULL, FALSE, TRUE, "pause game" }, + { + IMG_GFX_GAME_BUTTON_TOUCH_RESTART, &game.button.touch_restart, + GAME_CTRL_ID_TOUCH_RESTART, NULL, + FALSE, TRUE, "restart game" + }, { IMG_GFX_GAME_BUTTON_SOUND_MUSIC, &game.button.sound_music, SOUND_CTRL_ID_MUSIC, &setup.sound_music, @@ -16350,7 +16368,10 @@ void CreateGameButtons(void) id == GAME_CTRL_ID_PLAY || id == GAME_CTRL_ID_PANEL_PLAY || id == GAME_CTRL_ID_SAVE || - id == GAME_CTRL_ID_LOAD) + id == GAME_CTRL_ID_LOAD || + id == GAME_CTRL_ID_RESTART || + id == GAME_CTRL_ID_PANEL_RESTART || + id == GAME_CTRL_ID_TOUCH_RESTART) { button_type = GD_TYPE_NORMAL_BUTTON; checked = FALSE; @@ -16698,6 +16719,13 @@ static void HandleGameButtonsExt(int id, int button) TapeQuickLoad(); break; + case GAME_CTRL_ID_RESTART: + case GAME_CTRL_ID_PANEL_RESTART: + case GAME_CTRL_ID_TOUCH_RESTART: + TapeRestartGame(); + + break; + case SOUND_CTRL_ID_MUSIC: case SOUND_CTRL_ID_PANEL_MUSIC: if (setup.sound_music) diff --git a/src/game.h b/src/game.h index c555578b..3752ba00 100644 --- a/src/game.h +++ b/src/game.h @@ -123,6 +123,8 @@ struct GameButtonInfo struct XY pause2; struct XY load; + struct XY restart; + struct XY sound_music; struct XY sound_loops; struct XY sound_simple; @@ -131,12 +133,15 @@ struct GameButtonInfo struct XY panel_pause; struct XY panel_play; + struct XY panel_restart; + struct XY panel_sound_music; struct XY panel_sound_loops; struct XY panel_sound_simple; struct XY touch_stop; struct XY touch_pause; + struct XY touch_restart; }; struct GameSnapshotInfo -- 2.34.1