[Scummvm-git-logs] scummvm master -> 45a535808b2db21093c092b2815caadd31f06dac
dreammaster
noreply at scummvm.org
Wed May 27 02:41:28 UTC 2026
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
621342699c MADS: DRAGONSPHERE: Workarounds for memory overruns in globe cutscenes
45a535808b MADS: DRAGONSPHERE: Fix restoring bg for closed dialogs that overlap the interface area
Commit: 621342699c85c7a38f4048c67e413c33bc34f5a0
https://github.com/scummvm/scummvm/commit/621342699c85c7a38f4048c67e413c33bc34f5a0
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-05-27T12:41:08+10:00
Commit Message:
MADS: DRAGONSPHERE: Workarounds for memory overruns in globe cutscenes
Changed paths:
engines/mads/madsv2/core/game.cpp
engines/mads/madsv2/core/player.cpp
diff --git a/engines/mads/madsv2/core/game.cpp b/engines/mads/madsv2/core/game.cpp
index a81c5827735..234305d555c 100644
--- a/engines/mads/madsv2/core/game.cpp
+++ b/engines/mads/madsv2/core/game.cpp
@@ -2199,7 +2199,10 @@ static void game_main_loop() {
cursor_id = room_spots[id].cursor_number;
} else {
id -= room_num_spots;
- cursor_id = kernel_dynamic_hot[id].cursor;
+
+ // WORKAROUND: Dragonsphere globe cutscenes
+ if (id < kernel_num_dynamic)
+ cursor_id = kernel_dynamic_hot[id].cursor;
}
if (!cursor_id) cursor_id = 1;
}
diff --git a/engines/mads/madsv2/core/player.cpp b/engines/mads/madsv2/core/player.cpp
index ea595e1702e..41aeccd3403 100644
--- a/engines/mads/madsv2/core/player.cpp
+++ b/engines/mads/madsv2/core/player.cpp
@@ -183,9 +183,9 @@ void player_new_stop_walker() {
int abs_stop;
WalkerInfoPtr walker;
- // WORKAROUND: For ROTP opera and final chandelier fight cutscene
+ // WORKAROUND: For ROTP opera and final chandelier fight cutscene, Dragonsphere globe cutscenes
id = player.series_base + player.series;
- if (!series_list[id])
+ if (id < 0 || !series_list[id])
return;
walker = series_list[id]->walker;
if (!walker)
@@ -241,9 +241,9 @@ void player_select_series() {
player.mirror = MIRROR_MASK;
}
- // WORKAROUND: For ROTP final confrontation on Chandelier
+ // WORKAROUND: For ROTP final confrontation on Chandelier, Dragonsphere globe cutscenes
id = player.series_base + player.series;
- if (!series_list[id])
+ if (id < 0 || !series_list[id])
return;
walker = series_list[id]->walker;
if (!walker)
@@ -345,9 +345,9 @@ void player_stationary_update() {
goto done;
}
- // WORKAROUND: For ROTP Opera scene and final chandelier fight
+ // WORKAROUND: For ROTP Opera scene and final chandelier fight, and Dragonsphere globe cutscenes
id = player.series_base + player.series;
- if (!series_list[id])
+ if (id < 0 || !series_list[id])
return;
walker = series_list[id]->walker;
if (!walker)
Commit: 45a535808b2db21093c092b2815caadd31f06dac
https://github.com/scummvm/scummvm/commit/45a535808b2db21093c092b2815caadd31f06dac
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-05-27T12:41:08+10:00
Commit Message:
MADS: DRAGONSPHERE: Fix restoring bg for closed dialogs that overlap the interface area
Changed paths:
engines/mads/madsv2/core/popup.cpp
engines/mads/madsv2/core/popup.h
diff --git a/engines/mads/madsv2/core/popup.cpp b/engines/mads/madsv2/core/popup.cpp
index 4879106cb87..4102ab77831 100644
--- a/engines/mads/madsv2/core/popup.cpp
+++ b/engines/mads/madsv2/core/popup.cpp
@@ -137,10 +137,12 @@ int popup_create(int horiz_pieces, int x, int y) {
box->text_width = (box->text_xs / box_param.font->max_x_size) << 1;
box->screen_buffer.data = NULL;
+ box->orig_buffer.data = NULL;
box->depth_buffer.data = NULL;
box->screen_saved = false;
- box->depth_saved = false;
+ box->orig_saved = false;
+ box->depth_saved = false;
box->active = true;
@@ -520,19 +522,13 @@ int popup_draw(int save_screen, int depth_code) {
if (save_screen) {
matte_map_work_screen();
- if (depth_code) {
- buffer_init(&box->screen_buffer, box->xs, box->ys);
- if (box->screen_buffer.data != NULL)
- buffer_rect_copy_2(scr_orig, box->screen_buffer,
- box->x + picture_map.pan_offset_x,
- box->y + picture_map.pan_offset_y,
- 0, 0, box->xs, box->ys);
- } else {
- buffer_init(&box->screen_buffer, box->xs, box->ys);
- if (box->screen_buffer.data != NULL)
- buffer_rect_copy_2(scr_main, box->screen_buffer,
- box->x, box->y, 0, 0, box->xs, box->ys);
- }
+ // Always save from scr_main â it spans both the game area and the
+ // interface strip, so dialogs that overlap the interface are handled
+ // without any buffer splitting.
+ buffer_init(&box->screen_buffer, box->xs, box->ys);
+ if (box->screen_buffer.data != NULL)
+ buffer_rect_copy_2(scr_main, box->screen_buffer,
+ box->x, box->y, 0, 0, box->xs, box->ys);
box->screen_saved = (box->screen_buffer.data != NULL);
@@ -550,14 +546,36 @@ int popup_draw(int save_screen, int depth_code) {
box->depth_x = box->depth_x >> 1;
box->depth_xs = box->depth_xs >> 1;
- buffer_init(&box->depth_buffer, box->depth_xs, box->ys);
- if (box->depth_buffer.data != NULL)
- buffer_rect_copy_2(scr_depth, box->depth_buffer,
- box->depth_x,
- box->y + picture_map.pan_offset_y,
- 0, 0, box->depth_xs, box->ys);
+ // Clip to scr_depth bounds â the interface strip has no depth data.
+ int depth_ys = MAX(0, MIN(box->ys, scr_depth.y - (box->y + picture_map.pan_offset_y)));
+
+ if (depth_ys > 0) {
+ buffer_init(&box->depth_buffer, box->depth_xs, depth_ys);
+ if (box->depth_buffer.data != NULL)
+ buffer_rect_copy_2(scr_depth, box->depth_buffer,
+ box->depth_x,
+ box->y + picture_map.pan_offset_y,
+ 0, 0, box->depth_xs, depth_ys);
+ }
box->depth_saved = (box->depth_buffer.data != NULL);
+
+ // Also save the corresponding scr_orig region so that matte_frame()'s
+ // IMAGE_REFRESH path (which blits scr_orig â scr_work â scr_main) does
+ // not re-introduce popup pixels into the game area after we close.
+ // Clip to scr_orig.y â the interface strip has no orig data.
+ int orig_ys = MAX(0, MIN(box->ys, scr_orig.y - (box->y + picture_map.pan_offset_y)));
+
+ if (orig_ys > 0) {
+ buffer_init(&box->orig_buffer, box->xs, orig_ys);
+ if (box->orig_buffer.data != NULL)
+ buffer_rect_copy_2(scr_orig, box->orig_buffer,
+ box->x + picture_map.pan_offset_x,
+ box->y + picture_map.pan_offset_y,
+ 0, 0, box->xs, orig_ys);
+ }
+
+ box->orig_saved = (box->orig_buffer.data != NULL);
}
}
@@ -751,23 +769,38 @@ void popup_destroy(void) {
int xs, ys;
if (box->active && box->screen_saved) {
+ // Always restore the screen from scr_main â it spans both the game
+ // area and the interface strip, so no buffer split is required.
+ matte_map_work_screen();
+ if (box->screen_buffer.data != NULL) {
+ buffer_rect_copy_2(box->screen_buffer, scr_main,
+ 0, 0, box->x, box->y, box->xs, box->ys);
+ buffer_free(&box->screen_buffer);
+ }
+
if (box->depth_saved) {
- if (box->screen_buffer.data != NULL) {
- buffer_rect_copy_2(box->screen_buffer, scr_orig,
- 0, 0,
- box->x + picture_map.pan_offset_x,
- box->y + picture_map.pan_offset_y,
- box->xs, box->ys);
- buffer_free(&box->screen_buffer);
- }
if (box->depth_buffer.data != NULL) {
buffer_rect_copy_2(box->depth_buffer, scr_depth,
0, 0,
box->depth_x, box->y + picture_map.pan_offset_y,
- box->depth_xs, box->ys);
+ box->depth_xs, box->depth_buffer.y);
buffer_free(&box->depth_buffer);
}
+ // Restore scr_orig before matte_refresh_work() so that the next
+ // matte_frame() IMAGE_REFRESH blit doesn't propagate popup pixels
+ // from scr_orig back into the game area of scr_main.
+ if (box->orig_saved) {
+ if (box->orig_buffer.data != NULL) {
+ buffer_rect_copy_2(box->orig_buffer, scr_orig,
+ 0, 0,
+ box->x + picture_map.pan_offset_x,
+ box->y + picture_map.pan_offset_y,
+ box->orig_buffer.x, box->orig_buffer.y);
+ buffer_free(&box->orig_buffer);
+ }
+ }
+
matte_guard_depth_0 = false;
matte_refresh_work();
@@ -787,16 +820,21 @@ void popup_destroy(void) {
mouse_show();
matte_disable_screen_update = false;
- }
+ } else {
+ matte_map_work_screen();
- } else {
- matte_map_work_screen();
- if (box->screen_buffer.data != NULL) {
- buffer_rect_copy_2(box->screen_buffer, scr_main,
- 0, 0, box->x, box->y, box->xs, box->ys);
- buffer_free(&box->screen_buffer);
- }
+ x = box->x;
+ y = box->y;
+ xs = box->xs;
+ ys = box->ys;
+
+ buffer_conform(&scr_main, &x, &y, &xs, &ys);
+ mouse_hide();
+ video_update(&scr_main, x, y, x, y, xs, ys);
+ mouse_show();
+ }
+ } else {
matte_map_work_screen();
x = box->x;
@@ -807,9 +845,7 @@ void popup_destroy(void) {
buffer_conform(&scr_main, &x, &y, &xs, &ys);
mouse_hide();
- video_update(&scr_main, x, y,
- x, y,
- xs, ys);
+ video_update(&scr_main, x, y, x, y, xs, ys);
mouse_show();
}
}
@@ -821,7 +857,8 @@ void popup_destroy(void) {
}
box->screen_saved = false;
- box->depth_saved = false;
+ box->orig_saved = false;
+ box->depth_saved = false;
box->active = false;
}
diff --git a/engines/mads/madsv2/core/popup.h b/engines/mads/madsv2/core/popup.h
index 6f9e41ab8df..2645265293c 100644
--- a/engines/mads/madsv2/core/popup.h
+++ b/engines/mads/madsv2/core/popup.h
@@ -177,10 +177,12 @@ typedef struct {
int preserve_handle;
int depth_preserve_handle;
- Buffer screen_buffer; /* Direct copy of screen area under popup */
- Buffer depth_buffer; /* Direct copy of depth area under popup */
+ Buffer screen_buffer; /* scr_main copy covering the full popup rect */
+ Buffer orig_buffer; /* scr_orig copy for the game-area portion (depth) */
+ Buffer depth_buffer; /* scr_depth copy (clipped to depth-buffer height) */
int screen_saved;
+ int orig_saved;
int depth_saved;
word fill_accum;
More information about the Scummvm-git-logs
mailing list