[Scummvm-git-logs] scummvm master -> 71efbea57e9727fb3a228bcc15379cc33b3634f1
dreammaster
noreply at scummvm.org
Mon Jun 22 08:20:52 UTC 2026
This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
68ab7092cd MADS: FOREST: Workaround for crash using invalid series_id
d2dbf7c0df MADS: FOREST: Implementing custom Forest interface
71efbea57e NEWS: Added MM engine section for Scorp's PRs that was previously missing
Commit: 68ab7092cdf3363d2b242104cda5063d5230e6ea
https://github.com/scummvm/scummvm/commit/68ab7092cdf3363d2b242104cda5063d5230e6ea
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-06-22T18:20:23+10:00
Commit Message:
MADS: FOREST: Workaround for crash using invalid series_id
Changed paths:
engines/mads/madsv2/core/matte.cpp
diff --git a/engines/mads/madsv2/core/matte.cpp b/engines/mads/madsv2/core/matte.cpp
index 06dc11664e6..fc302390d8c 100644
--- a/engines/mads/madsv2/core/matte.cpp
+++ b/engines/mads/madsv2/core/matte.cpp
@@ -889,10 +889,13 @@ void matte_frame(int special_effect, int full_screen) {
// Now, run through our depth list, and for each entry, draw the
// indicated sprite into the work buffer.
for (id = 0; id < depth_size; id++) {
-
// Get the index for the series for this depth list entry
id2 = depth_list_id[id];
+ // WORKAROUND: Invalid series_id
+ if (image_list[id2].series_id == (byte)-1)
+ continue;
+
// Draw the sprite into the work buffer at the appropriate depth
if (image_list[id2].scale >= 100) {
if (image_list[id2].scale == IMAGE_UNSCALED) {
Commit: d2dbf7c0df11ddc3123f8bec4d50ae7374961837
https://github.com/scummvm/scummvm/commit/d2dbf7c0df11ddc3123f8bec4d50ae7374961837
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-06-22T18:20:23+10:00
Commit Message:
MADS: FOREST: Implementing custom Forest interface
Changed paths:
engines/mads/madsv2/core/anim.cpp
engines/mads/madsv2/core/anim.h
engines/mads/madsv2/core/game.cpp
engines/mads/madsv2/core/game.h
engines/mads/madsv2/engine.cpp
engines/mads/madsv2/forest/extra.cpp
engines/mads/madsv2/forest/extra.h
engines/mads/madsv2/forest/global.cpp
diff --git a/engines/mads/madsv2/core/anim.cpp b/engines/mads/madsv2/core/anim.cpp
index 6463112d948..f4d7a792ea0 100644
--- a/engines/mads/madsv2/core/anim.cpp
+++ b/engines/mads/madsv2/core/anim.cpp
@@ -78,7 +78,11 @@ void Speech::load(Common::SeekableReadStream *src) {
}
void ImageInter::load(Common::SeekableReadStream *src) {
- src->readMultipleLE(flags, segment_id, series_id, sprite_id, x, y);
+ src->readMultipleLE(flags, segment_id, series_id, sprite_id);
+ src->skip(1);
+ x = src->readSint16LE();
+ y = src->readByte();
+ src->skip(1);
}
void Frame::load(Common::SeekableReadStream *src) {
diff --git a/engines/mads/madsv2/core/anim.h b/engines/mads/madsv2/core/anim.h
index 2385b8bba9a..453fccf6e40 100644
--- a/engines/mads/madsv2/core/anim.h
+++ b/engines/mads/madsv2/core/anim.h
@@ -237,10 +237,12 @@ struct ImageInter {
byte segment_id;
byte series_id;
byte sprite_id;
+ // byte padding
int16 x;
byte y;
+ // byte padding
- static constexpr int SIZE = 2 + 1 + 1 + 1 + 2 + 1;
+ static constexpr int SIZE = 2 + 1 + 1 + 1 + 1 + 2 + 1 + 1;
void load(Common::SeekableReadStream *src);
};
typedef ImageInter *ImageInterPtr;
diff --git a/engines/mads/madsv2/core/game.cpp b/engines/mads/madsv2/core/game.cpp
index 9e2118ef213..610549274bb 100644
--- a/engines/mads/madsv2/core/game.cpp
+++ b/engines/mads/madsv2/core/game.cpp
@@ -109,7 +109,6 @@ int debugger_memory_all = false; /* Not showing ALL memory */
int debugger_memory_keywait = false; /* Not waiting for memory */
void (*debugger_reset)() = NULL; /* Debugger reset routine */
void (*debugger_update)() = NULL; /* Debugger update routine */
-int int_sprite[6];
int selected_intro = false;
long correction_clock;
@@ -1286,7 +1285,8 @@ void game_control() {
}
// Game level control loop
- int_sprite[fx_int_journal] = -1;
+ if (g_engine->getGameID() == GType_Forest)
+ Forest::int_sprite[Forest::fx_int_journal] = -1;
while (game.going) {
@@ -1371,32 +1371,21 @@ void game_control() {
if (player.walker_is_loaded) {
player_dump_walker();
}
-#if 0
- if (int_sprite[fx_int_journal] != -1 && room_id != KERNEL_RESTORING_GAME) {
- matte_deallocate_series(int_sprite[fx_int_candle_on], true);
- matte_deallocate_series(int_sprite[fx_int_dooropen], true);
- matte_deallocate_series(int_sprite[fx_int_exit], true);
- matte_deallocate_series(int_sprite[fx_int_candle], true);
- matte_deallocate_series(int_sprite[fx_int_backpack], true);
- matte_deallocate_series(int_sprite[fx_int_journal], true);
- int_sprite[fx_int_journal] = -1;
+
+ if (g_engine->getGameID() == GType_Forest) {
+ if (room_id != KERNEL_RESTORING_GAME)
+ Forest::unload_interface();
+
+ g_engine->section_music(section_id);
}
- g_engine->section_music(section_id);
-#endif
pal_init(KERNEL_RESERVED_LOW_COLORS, KERNEL_RESERVED_HIGH_COLORS);
matte_init(true);
-#if 0
- if (!player.walker_is_loaded) {
- int_sprite[fx_int_journal] = kernel_load_series("*journal", false);
- int_sprite[fx_int_backpack] = kernel_load_series("*backpack", false);
- int_sprite[fx_int_candle] = kernel_load_series("*candle", false);
- int_sprite[fx_int_exit] = kernel_load_series("*door", false);
- int_sprite[fx_int_dooropen] = kernel_load_series("*dooropen", false);
- int_sprite[fx_int_candle_on] = kernel_load_series("*candleon", false);
- }
-#endif
+
+ if (!player.walker_is_loaded && g_engine->getGameID() == GType_Forest)
+ Forest::load_interface();
+
} else {
player_preserve_palette();
#if 0
@@ -1492,20 +1481,10 @@ void game_control() {
kernel_set_interface_mode(INTER_LIMITED_SENTENCES);
game_exec_function(room_init_code_pointer);
-#if 0
- // paul - oh no! magic numbers!
- stamp_sprite_to_interface(BP_X, BP_Y, 1, int_sprite[fx_int_backpack]);
- if (global[5]) { // candle_is_on
- stamp_sprite_to_interface(CANDLE_X, CANDLE_Y, 1, int_sprite[fx_int_candle_on]);
- } else {
- stamp_sprite_to_interface(CANDLE_X, CANDLE_Y, 1, int_sprite[fx_int_candle]);
- }
- stamp_sprite_to_interface(DOOR_X, DOOR_Y, 1, int_sprite[fx_int_exit]);
- if (room_id != 199) { // Taranjeet, if this is not journal room
- stamp_sprite_to_interface(JOURNAL_X, JOURNAL_Y, 1, int_sprite[fx_int_journal]);
- }
-#endif
+ if (g_engine->getGameID() == GType_Forest)
+ Forest::draw_interface();
+
scr_work.data = buffer_pointer(&scr_main, 0, viewing_at_y);
if (viewing_at_y) {
buffer_rect_fill(scr_main, 0, 0, video_x, viewing_at_y, 0);
@@ -1612,17 +1591,8 @@ emergency:
kernel_unload_all_series();
}
- if (room_id != KERNEL_RESTORING_GAME && g_engine->getGameID() == GType_Forest) {
- if (int_sprite[fx_int_journal] != -1) {
- matte_deallocate_series(int_sprite[fx_int_candle_on], true);
- matte_deallocate_series(int_sprite[fx_int_dooropen], true);
- matte_deallocate_series(int_sprite[fx_int_exit], true);
- matte_deallocate_series(int_sprite[fx_int_candle], true);
- matte_deallocate_series(int_sprite[fx_int_backpack], true);
- matte_deallocate_series(int_sprite[fx_int_journal], true);
- int_sprite[fx_int_journal] = -1;
- }
- }
+ if (room_id != KERNEL_RESTORING_GAME && g_engine->getGameID() == GType_Forest)
+ Forest::unload_interface();
pal_unlock();
@@ -3004,7 +2974,6 @@ void init_game() {
debugger_memory_keywait = false;
debugger_reset = NULL;
debugger_update = NULL;
- memset(int_sprite, 0, sizeof(int_sprite));
selected_intro = false;
correction_clock = 0;
memset(save_game_key, 0, sizeof(save_game_key));
diff --git a/engines/mads/madsv2/core/game.h b/engines/mads/madsv2/core/game.h
index eaf730a697f..2755de20a9c 100644
--- a/engines/mads/madsv2/core/game.h
+++ b/engines/mads/madsv2/core/game.h
@@ -95,18 +95,8 @@ namespace MADSV2 {
#define DEBUGGER_MAX_WATCH 12
-extern int int_sprite[6];
-
extern int selected_intro;
-#define fx_int_journal 0
-#define fx_int_backpack 1
-#define fx_int_candle 2
-#define fx_int_exit 3
-#define fx_int_dooropen 4
-#define fx_int_candle_on 5
-
-
#define EXTRA_MAX_INV_OBJECTS 18 /* 16, + background, + open backpack */
/* int inven_ss[EXTRA_MAX_INV_OBJECTS]; */
diff --git a/engines/mads/madsv2/engine.cpp b/engines/mads/madsv2/engine.cpp
index e7fe891fcb9..22b7879d63b 100644
--- a/engines/mads/madsv2/engine.cpp
+++ b/engines/mads/madsv2/engine.cpp
@@ -53,6 +53,7 @@
#include "mads/madsv2/core/timer.h"
#include "mads/madsv2/core/vocab.h"
#include "mads/madsv2/phantom/main.h"
+#include "mads/madsv2/forest/extra.h"
#include "mads/core/sound_manager.h"
namespace MADS {
@@ -114,6 +115,7 @@ void MADSV2Engine::initGlobals() {
init_sprite();
init_timer();
init_vocab();
+ Forest::init_extra();
}
void MADSV2Engine::readConfigFile() {
diff --git a/engines/mads/madsv2/forest/extra.cpp b/engines/mads/madsv2/forest/extra.cpp
index b222cf4d01d..25d8a625a6f 100644
--- a/engines/mads/madsv2/forest/extra.cpp
+++ b/engines/mads/madsv2/forest/extra.cpp
@@ -34,6 +34,12 @@ namespace MADS {
namespace MADSV2 {
namespace Forest {
+int int_sprite[6];
+
+void init_extra() {
+ Common::fill(int_sprite, int_sprite + 6, 0);
+}
+
void display_interface() {
error("TODO: display_interface");
}
@@ -63,7 +69,14 @@ void extra_spinning_object(void) {
}
void stamp_sprite_to_interface(int x, int y, int sprite, int series) {
- error("TODO: stamp_sprite_to_interface");
+ ImageInter &ii = image_inter_list[image_inter_marker++];
+
+ ii.flags = IMAGE_UPDATE;
+ ii.segment_id = 200;
+ ii.sprite_id = sprite;
+ ii.series_id = series;
+ ii.x = x;
+ ii.y = y;
}
void delete_sprite_in_interface(int series) {
@@ -82,7 +95,44 @@ void extra_blank_knothole(void) {
error("TODO: extra_blank_knothole");
}
-void do_interface_for_ouaf() {
+void load_interface() {
+ int_sprite[fx_int_journal] = kernel_load_series("*journal", false);
+ int_sprite[fx_int_backpack] = kernel_load_series("*backpack", false);
+ int_sprite[fx_int_candle] = kernel_load_series("*candle", false);
+ int_sprite[fx_int_exit] = kernel_load_series("*door", false);
+ int_sprite[fx_int_dooropen] = kernel_load_series("*dooropen", false);
+ int_sprite[fx_int_candle_on] = kernel_load_series("*candleon", false);
+}
+
+void unload_interface() {
+ if (int_sprite[fx_int_journal] != -1) {
+ matte_deallocate_series(int_sprite[fx_int_candle_on], true);
+ matte_deallocate_series(int_sprite[fx_int_dooropen], true);
+ matte_deallocate_series(int_sprite[fx_int_exit], true);
+ matte_deallocate_series(int_sprite[fx_int_candle], true);
+ matte_deallocate_series(int_sprite[fx_int_backpack], true);
+ matte_deallocate_series(int_sprite[fx_int_journal], true);
+ int_sprite[fx_int_journal] = -1;
+ }
+}
+
+void draw_interface() {
+ // Once Upon a Forest uses a custom interface
+ stamp_sprite_to_interface(BP_X, BP_Y, 1, int_sprite[fx_int_backpack]);
+ if (global[Forest::walker_converse_state]) { // candle_is_on
+ stamp_sprite_to_interface(CANDLE_X, CANDLE_Y, 1, int_sprite[fx_int_candle_on]);
+ } else {
+ stamp_sprite_to_interface(CANDLE_X, CANDLE_Y, 1, int_sprite[fx_int_candle]);
+ }
+ stamp_sprite_to_interface(DOOR_X, DOOR_Y, 1, int_sprite[fx_int_exit]);
+
+ if (room_id != 199) { // Taranjeet, if this is not journal room
+ stamp_sprite_to_interface(JOURNAL_X, JOURNAL_Y, 1, int_sprite[fx_int_journal]);
+ }
+
+}
+
+void do_interface() {
if (mouse_y > 156 &&
mouse_stop_stroke &&
player.commands_allowed &&
diff --git a/engines/mads/madsv2/forest/extra.h b/engines/mads/madsv2/forest/extra.h
index 8639da8addb..2fa56c6d0ad 100644
--- a/engines/mads/madsv2/forest/extra.h
+++ b/engines/mads/madsv2/forest/extra.h
@@ -28,6 +28,16 @@ namespace MADS {
namespace MADSV2 {
namespace Forest {
+// Interface sprites
+enum {
+ fx_int_journal = 0,
+ fx_int_backpack = 1,
+ fx_int_candle = 2,
+ fx_int_exit = 3,
+ fx_int_dooropen = 4,
+ fx_int_candle_on = 5
+};
+
#define JOURNAL_FLY 1
#define BP_FLY 2
#define CANDLE_FLY 3
@@ -45,6 +55,10 @@ namespace Forest {
#define DOOR_X 264 /* X for top left corner of DOOR */
#define DOOR_Y 2 /* Y for top left corner of DOOR */
+extern int int_sprite[6];
+
+extern void init_extra();
+
extern void fly_on_screen(int flying_object);
extern void fly_off_screen(int flying_object);
@@ -53,7 +67,10 @@ extern void display_inventory(void);
extern void solve_me_selected(void);
extern void door_selected(void);
-extern void do_interface_for_ouaf();
+extern void load_interface();
+extern void unload_interface();
+extern void draw_interface();
+extern void do_interface();
extern void extra_spinning_object(void);
extern void extra_inven_preserve_palette(void);
diff --git a/engines/mads/madsv2/forest/global.cpp b/engines/mads/madsv2/forest/global.cpp
index d5bae9788be..9c4c62e91c5 100644
--- a/engines/mads/madsv2/forest/global.cpp
+++ b/engines/mads/madsv2/forest/global.cpp
@@ -1002,10 +1002,11 @@ void global_daemon_code() {
digi_read_another_chunk();
- if (global[9]) midi_loop(); // please loop the damn music
+ if (global[9])
+ midi_loop();
if (section_id != 9) {
- do_interface_for_ouaf();
+ do_interface();
}
}
Commit: 71efbea57e9727fb3a228bcc15379cc33b3634f1
https://github.com/scummvm/scummvm/commit/71efbea57e9727fb3a228bcc15379cc33b3634f1
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-06-22T18:20:23+10:00
Commit Message:
NEWS: Added MM engine section for Scorp's PRs that was previously missing
Changed paths:
NEWS.md
diff --git a/NEWS.md b/NEWS.md
index 8e5dfbc53ab..cef4ab8ba29 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -11,6 +11,12 @@ For a more comprehensive changelog of the latest experimental code, see:
Atari port:
- Added integration with nFM library.
+ MM:
+ - Fix multiple M&M1 classic combat crashes
+ - Implement M&M1 classic PC speaker sound
+ - Fix stale view close handling causing crash.
+ - Fix M&M1 spelling mistakes
+ - Improved M&M1 Enhanced mouse support, character generation, and general in-game UI
#### 2026.3.0 "Carousels & Killer Whales" (2026-06-20)
More information about the Scummvm-git-logs
mailing list