[Scummvm-git-logs] scummvm master -> b11fe476ee94b44dc9408e253eeaca6ceece13c7

dreammaster noreply at scummvm.org
Tue Jun 23 11:29:39 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:
e767e3db35 MADS: FOREST: Switch digi to speech sound type
c843367bf9 MADS: FOREST: Fix GMM save/load can save currently
b11fe476ee MADS: FOREST: Implementing display_inventory


Commit: e767e3db350bf3338f6449488b571883b1cb0431
    https://github.com/scummvm/scummvm/commit/e767e3db350bf3338f6449488b571883b1cb0431
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-06-23T21:28:05+10:00

Commit Message:
MADS: FOREST: Switch digi to speech sound type

Changed paths:
    engines/mads/detection_tables.h
    engines/mads/madsv2/forest/digi.cpp


diff --git a/engines/mads/detection_tables.h b/engines/mads/detection_tables.h
index d81ce0cd201..33e67a4c352 100644
--- a/engines/mads/detection_tables.h
+++ b/engines/mads/detection_tables.h
@@ -262,7 +262,7 @@ static const MADSGameDescription gameDescriptions[] = {
 			Common::EN_ANY,
 			Common::kPlatformDOS,
 			ADGF_UNSTABLE,
-			GUIO1(GAMEOPTION_ORIGINAL_SAVELOAD)
+			GUIO2(GUIO_NOSFX, GAMEOPTION_ORIGINAL_SAVELOAD)
 		},
 		GType_Forest,
 		0
diff --git a/engines/mads/madsv2/forest/digi.cpp b/engines/mads/madsv2/forest/digi.cpp
index caba27355f2..16c5f20e0fe 100644
--- a/engines/mads/madsv2/forest/digi.cpp
+++ b/engines/mads/madsv2/forest/digi.cpp
@@ -62,7 +62,7 @@ void DigiPlayer::play(const char *name, int slot) {
 
 	Audio::AudioStream *audioStream = Audio::makeADPCMStream(src, DisposeAfterUse::YES,
 		src->size() - 0x20, Audio::kADPCMApple, 11025, 1);
-	_mixer->playStream(Audio::Mixer::kSFXSoundType, &c._soundHandle, audioStream);
+	_mixer->playStream(Audio::Mixer::kSpeechSoundType, &c._soundHandle, audioStream);
 	c._isPlaying = true;
 }
 


Commit: c843367bf9c70a7fdccf97e5d7bc684c496674bf
    https://github.com/scummvm/scummvm/commit/c843367bf9c70a7fdccf97e5d7bc684c496674bf
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-06-23T21:28:05+10:00

Commit Message:
MADS: FOREST: Fix GMM save/load can save currently

Changed paths:
    engines/mads/madsv2/forest/forest.cpp
    engines/mads/madsv2/forest/forest.h


diff --git a/engines/mads/madsv2/forest/forest.cpp b/engines/mads/madsv2/forest/forest.cpp
index 56f0f3eaf3d..4d154a7798a 100644
--- a/engines/mads/madsv2/forest/forest.cpp
+++ b/engines/mads/madsv2/forest/forest.cpp
@@ -111,6 +111,11 @@ void ForestEngine::global_section_constructor() {
 	Forest::global_section_constructor();
 }
 
+bool ForestEngine::canLoadGameStateCurrently(Common::U32String *msg) {
+	return game.going && !win_status && !kernel.activate_menu &&
+		inter_input_mode == INTER_LIMITED_SENTENCES && section_id != 9;
+}
+
 void ForestEngine::syncRoom(Common::Serializer &s) {
 	Forest::sync_room(s);
 }
diff --git a/engines/mads/madsv2/forest/forest.h b/engines/mads/madsv2/forest/forest.h
index 2d32537f87d..d73e0f2ebe6 100644
--- a/engines/mads/madsv2/forest/forest.h
+++ b/engines/mads/madsv2/forest/forest.h
@@ -40,6 +40,7 @@ public:
 	~ForestEngine() override;
 
 	Common::Error run() override;
+	bool canLoadGameStateCurrently(Common::U32String *msg) override;
 	void syncRoom(Common::Serializer &s) override;
 
 	void global_init_code() override;


Commit: b11fe476ee94b44dc9408e253eeaca6ceece13c7
    https://github.com/scummvm/scummvm/commit/b11fe476ee94b44dc9408e253eeaca6ceece13c7
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-06-23T21:28:05+10:00

Commit Message:
MADS: FOREST: Implementing display_inventory

Changed paths:
  A engines/mads/madsv2/forest/inventory.cpp
  A engines/mads/madsv2/forest/inventory.h
    engines/mads/madsv2/core/game.cpp
    engines/mads/madsv2/core/inter.cpp
    engines/mads/madsv2/forest/extra.cpp
    engines/mads/madsv2/forest/extra.h
    engines/mads/madsv2/forest/forest.cpp
    engines/mads/module.mk


diff --git a/engines/mads/madsv2/core/game.cpp b/engines/mads/madsv2/core/game.cpp
index 97819ba08b4..d981a3e0212 100644
--- a/engines/mads/madsv2/core/game.cpp
+++ b/engines/mads/madsv2/core/game.cpp
@@ -1388,9 +1388,6 @@ void game_control() {
 
 			} else {
 				player_preserve_palette();
-#if 0
-				extra_inven_preserve_palette();
-#endif
 			}
 
 			pal_activate_shadow(&kernel_shadow_main);
diff --git a/engines/mads/madsv2/core/inter.cpp b/engines/mads/madsv2/core/inter.cpp
index 38701b35398..641f5113e42 100644
--- a/engines/mads/madsv2/core/inter.cpp
+++ b/engines/mads/madsv2/core/inter.cpp
@@ -205,8 +205,6 @@ int  inter_object_id;
 char inter_object_buf[20];
 void (*inter_object_routine)() = NULL;
 
-int paul_object_showing = -1;
-
 #define OUAF_OBJECT_X    140
 #define OUAF_OBJECT_Y    5
 
@@ -218,6 +216,82 @@ void VerbBuf::synchronize(Common::Serializer &s) {
 }
 
 
+void init_inter() {
+	stroke_type = STROKE_NONE;
+	inter_auxiliary_click = 0;
+	inter_anim = NULL;
+	inter_mouse_x = 0;
+	inter_mouse_y = 0;
+	inter_mouse_type = 0;
+	inter_object_sprite = 1;
+	inter_object_series = -1;
+	inter_spinning_objects = true;
+	inter_animation_running = true;
+	inter_objects_block = NULL;
+	inter_objects_block_size = 0;
+	inter_input_mode = INTER_BUILDING_SENTENCES;
+	memset(inter_dialog_strings, 0, sizeof(inter_dialog_strings));
+	memset(inter_dialog_results, 0, sizeof(inter_dialog_results));
+	memset(inven, 0, sizeof(inven));
+	inven_num_objects = 0;
+	right_command = 0;
+	left_command = -1;
+	left_inven = -1;
+	left_action = -1;
+	right_action = -1;
+	active_inven = -1;
+	first_inven = 0;
+	scroll_base_time = 0;
+	scroll_active = false;
+	scroll_quickly = false;
+	first_inven_changed = false;
+	picked_word = 0;
+	memset(inter_sentence, 0, sizeof(inter_sentence));
+	inter_sentence_handle = -1;
+	inter_sentence_changed = false;
+	inter_look_around = 0;
+	inter_command = 0;
+	inter_main_object = 0;
+	inter_second_object = 0;
+	inter_prep = 0;
+	inter_main_syntax = 0;
+	inter_second_syntax = 0;
+	inter_verb_type = 0;
+	inter_prep_type = 0;
+	inter_command_source = 0;
+	inter_main_object_source = 0;
+	inter_second_object_source = 0;
+	memset(inter_words, 0, sizeof(inter_words));
+	inter_point_established = 0;
+	inter_point_x = 0;
+	inter_point_y = 0;
+	inter_recent_command = 0;
+	inter_recent_command_source = 0;
+	inter_sentence_ready = false;
+	inter_awaiting = AWAITING_COMMAND;
+	inter_report_hotspots = false;
+	inter_force_rescan = false;
+	inter_base_hotspots = 0;
+	inter_no_segments_active = true;
+	inter_some_segments_active = false;
+	inter_spot_class = 0;
+	inter_spot_index = 0;
+	inter_spot_id = 0;
+	inter_base_time = 0;
+	end_of_selection = false;
+	memset(spot_base, 0, sizeof(spot_base));
+	scrollbar_active = 0;
+	scrollbar_elevator = 0;
+	scrollbar_old_active = -1;
+	scrollbar_old_elevator = -1;
+	scrollbar_stroke_type = 0;
+	scrollbar_quickly = false;
+	scrollbar_base_timing = 0;
+	inter_object_id = 0;
+	memset(inter_object_buf, 0, sizeof(inter_object_buf));
+	inter_object_routine = NULL;
+}
+
 /**
  * Picks out font colors based on the current mode.
  *
@@ -731,34 +805,36 @@ void inter_set_active_inven(int new_active) {
 				xs = action_delta_x;
 				ys = (inter_delta_y * max_verbs);
 
-				if (image_inter_marker < IMAGE_INTER_LIST_SIZE) {
-					image_inter_list[image_inter_marker].flags = IMAGE_OVERPRINT;
-					image_inter_list[image_inter_marker].x = x1;
-					image_inter_list[image_inter_marker].y = (byte)y1;
-					image_inter_list[image_inter_marker].sprite_id = (byte)xs;
-					image_inter_list[image_inter_marker].series_id = (byte)ys;
-					image_inter_marker++;
-				}
+				if (g_engine->getGameID() != GType_Forest || Forest::knuthole_flag) {
+					if (image_inter_marker < IMAGE_INTER_LIST_SIZE) {
+						image_inter_list[image_inter_marker].flags = IMAGE_OVERPRINT;
+						image_inter_list[image_inter_marker].x = x1;
+						image_inter_list[image_inter_marker].y = (byte)y1;
+						image_inter_list[image_inter_marker].sprite_id = (byte)xs;
+						image_inter_list[image_inter_marker].series_id = (byte)ys;
+						image_inter_marker++;
+					}
 #ifndef disable_error_check
-				else {
-					error_report(ERROR_IMAGE_INTER_LIST_FULL, WARNING, MODULE_INTER, IMAGE_INTER_LIST_SIZE, 2);
-				}
+					else {
+						error_report(ERROR_IMAGE_INTER_LIST_FULL, WARNING, MODULE_INTER, IMAGE_INTER_LIST_SIZE, 2);
+					}
 #endif
 
-				matte_inter_frame(false, false);
+					matte_inter_frame(false, false);
 
-				inter_show_all_actions();
-				inter_update(x1, y1, xs, ys);
+					inter_show_all_actions();
+					inter_update(x1, y1, xs, ys);
+				}
 			}
 		}
 	}
 
-	if (new_active != -1) {
+	if (new_active == -1) {
+		inter_turn_off_object();
+	} else if (g_engine->getGameID() != GType_Forest || Forest::knuthole_flag) {
 		inter_spin_object(inven[new_active]);
 		mcga_setpal_range(&master_palette, 7, 1);
 		mcga_setpal_range(&master_palette, 246, 2);
-	} else {
-		inter_turn_off_object();
 	}
 }
 
@@ -857,9 +933,8 @@ void inter_take_from_player(int this_, int where_to) {
 }
 
 void inter_move_object(int object_id, int location) {
-
-	if (object_id == paul_object_showing &&
-		location == 2) goto done;
+	if (g_engine->getGameID() == GType_Forest && object_id == Forest::paul_object_showing && location == 2)
+		goto done;
 
 	if (object[object_id].location == PLAYER) {
 		inter_take_from_player(object_id, NOWHERE);
@@ -870,9 +945,9 @@ void inter_move_object(int object_id, int location) {
 		object[object_id].location = location;
 	}
 
-	// extra_blank_knothole();
 done:
-	;
+	if (g_engine->getGameID() == GType_Forest)
+		Forest::extra_blank_knothole();
 }
 
 /**
@@ -1872,7 +1947,7 @@ void inter_turn_off_object(void) {
 
 
 	if (new_room == room_id) {
-		paul_object_showing = -1;
+		Forest::paul_object_showing = true;
 	}
 
 	// will wipe out other 4 sprites
@@ -1966,7 +2041,7 @@ void inter_spin_object(int object_id) {
 
 	if (g_engine->getGameID() == GType_Forest) {
 		Forest::stamp_sprite_to_interface(OUAF_OBJECT_X, OUAF_OBJECT_Y, 1, inter_object_series);
-		paul_object_showing = object_id;
+		Forest::paul_object_showing = object_id;
 	}
 
 	if (inter_object_series < 0)
@@ -2165,82 +2240,5 @@ done:
 	return error_flag;
 }
 
-void init_inter() {
-	stroke_type = STROKE_NONE;
-	inter_auxiliary_click = 0;
-	inter_anim = NULL;
-	inter_mouse_x = 0;
-	inter_mouse_y = 0;
-	inter_mouse_type = 0;
-	inter_object_sprite = 1;
-	inter_object_series = -1;
-	inter_spinning_objects = true;
-	inter_animation_running = true;
-	inter_objects_block = NULL;
-	inter_objects_block_size = 0;
-	inter_input_mode = INTER_BUILDING_SENTENCES;
-	memset(inter_dialog_strings, 0, sizeof(inter_dialog_strings));
-	memset(inter_dialog_results, 0, sizeof(inter_dialog_results));
-	memset(inven, 0, sizeof(inven));
-	inven_num_objects = 0;
-	right_command = 0;
-	left_command = -1;
-	left_inven = -1;
-	left_action = -1;
-	right_action = -1;
-	active_inven = -1;
-	first_inven = 0;
-	scroll_base_time = 0;
-	scroll_active = false;
-	scroll_quickly = false;
-	first_inven_changed = false;
-	picked_word = 0;
-	memset(inter_sentence, 0, sizeof(inter_sentence));
-	inter_sentence_handle = -1;
-	inter_sentence_changed = false;
-	inter_look_around = 0;
-	inter_command = 0;
-	inter_main_object = 0;
-	inter_second_object = 0;
-	inter_prep = 0;
-	inter_main_syntax = 0;
-	inter_second_syntax = 0;
-	inter_verb_type = 0;
-	inter_prep_type = 0;
-	inter_command_source = 0;
-	inter_main_object_source = 0;
-	inter_second_object_source = 0;
-	memset(inter_words, 0, sizeof(inter_words));
-	inter_point_established = 0;
-	inter_point_x = 0;
-	inter_point_y = 0;
-	inter_recent_command = 0;
-	inter_recent_command_source = 0;
-	inter_sentence_ready = false;
-	inter_awaiting = AWAITING_COMMAND;
-	inter_report_hotspots = false;
-	inter_force_rescan = false;
-	inter_base_hotspots = 0;
-	inter_no_segments_active = true;
-	inter_some_segments_active = false;
-	inter_spot_class = 0;
-	inter_spot_index = 0;
-	inter_spot_id = 0;
-	inter_base_time = 0;
-	end_of_selection = false;
-	memset(spot_base, 0, sizeof(spot_base));
-	scrollbar_active = 0;
-	scrollbar_elevator = 0;
-	scrollbar_old_active = -1;
-	scrollbar_old_elevator = -1;
-	scrollbar_stroke_type = 0;
-	scrollbar_quickly = false;
-	scrollbar_base_timing = 0;
-	inter_object_id = 0;
-	memset(inter_object_buf, 0, sizeof(inter_object_buf));
-	inter_object_routine = NULL;
-	paul_object_showing = -1;
-}
-
 } // namespace MADSV2
 } // namespace MADS
diff --git a/engines/mads/madsv2/forest/extra.cpp b/engines/mads/madsv2/forest/extra.cpp
index c8b475d1123..2ef89880ac5 100644
--- a/engines/mads/madsv2/forest/extra.cpp
+++ b/engines/mads/madsv2/forest/extra.cpp
@@ -36,18 +36,19 @@ namespace MADSV2 {
 namespace Forest {
 
 int int_sprite[6];
+bool knuthole_flag;
+int paul_object_showing;
 
 void init_extra() {
 	Common::fill(int_sprite, int_sprite + 6, 0);
+	knuthole_flag = false;
+	paul_object_showing = -1;
 }
 
 void display_interface() {
 	error("TODO: display_interface");
 }
 
-void display_inventory(void) {
-	error("TODO: display_inventory");
-}
 
 void solve_me_selected(void) {
 	global[walker_converse_state] = -1;
@@ -60,10 +61,6 @@ void door_selected(void) {
 	kernel.activate_menu = GAME_MAIN_MENU;
 }
 
-void extra_spinning_object(void) {
-	error("TODO: extra_spinning_object");
-}
-
 void stamp_sprite_to_interface(int x, int y, int sprite, int series) {
 	ImageInter &ii = image_inter_list[image_inter_marker++];
 
@@ -87,10 +84,6 @@ void extra_shift_animation(int handle, int x, int y, byte scale) {
 	error("TODO: extra_shift_animation");
 }
 
-void extra_blank_knothole(void) {
-	error("TODO: extra_blank_knothole");
-}
-
 void load_interface() {
 	int_sprite[fx_int_journal] = kernel_load_series("*journal", false);
 	int_sprite[fx_int_backpack] = kernel_load_series("*backpack", false);
@@ -159,6 +152,17 @@ void do_interface() {
 	}
 }
 
+void inter_update_series(int series_id) {
+	for (int count = 0; count < (int)image_inter_marker; count++) {
+		ImageInter &ii = image_inter_list[count];
+
+		if (ii.series_id == series_id)
+			ii.flags = IMAGE_ERASE;
+		else if (ii.series_id != IMAGE_ERASE)
+			ii.flags = IMAGE_UPDATE;
+	}
+}
+
 } // namespace Forest
 } // namespace MADSV2
 } // namespace MADS
diff --git a/engines/mads/madsv2/forest/extra.h b/engines/mads/madsv2/forest/extra.h
index e36477d7a23..fc2697d18c2 100644
--- a/engines/mads/madsv2/forest/extra.h
+++ b/engines/mads/madsv2/forest/extra.h
@@ -19,8 +19,8 @@
  *
  */
 
-#ifndef MADS_CORE_EXTRA_H
-#define MADS_CORE_EXTRA_H
+#ifndef MADS_FOREST_EXTRA_H
+#define MADS_FOREST_EXTRA_H
 
 #include "mads/madsv2/core/general.h"
 
@@ -56,26 +56,31 @@ enum {
 #define DOOR_Y                 2     /* Y for top left corner of DOOR    */
 
 extern int int_sprite[6];
+extern bool knuthole_flag;
+extern int paul_object_showing;
 
 extern void init_extra();
 
+inline void extra_blank_knothole() {
+	knuthole_flag = 0;
+}
+
 extern void display_interface();
-extern void display_inventory(void);
-extern void solve_me_selected(void);
-extern void door_selected(void);
+extern void display_inventory();
+extern void solve_me_selected();
+extern void door_selected();
 
 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);
 extern void stamp_sprite_to_interface(int x, int y, int sprite, int series);
 extern void delete_sprite_in_interface(int series);
 extern void extra_change_animation(int handle, int x, int y, byte scale, byte depth);
 extern void extra_shift_animation(int handle, int x, int y, byte scale);
-extern void extra_blank_knothole(void);
+extern void extra_blank_knothole();
+extern void inter_update_series(int series_id);
 
 } // namespace Forest
 } // namespace MADSV2
diff --git a/engines/mads/madsv2/forest/forest.cpp b/engines/mads/madsv2/forest/forest.cpp
index 4d154a7798a..174a13c1e5d 100644
--- a/engines/mads/madsv2/forest/forest.cpp
+++ b/engines/mads/madsv2/forest/forest.cpp
@@ -36,7 +36,9 @@
 #include "mads/madsv2/core/sound.h"
 #include "mads/madsv2/core/text.h"
 #include "mads/madsv2/forest/forest.h"
+#include "mads/madsv2/forest/extra.h"
 #include "mads/madsv2/forest/global.h"
+#include "mads/madsv2/forest/inventory.h"
 #include "mads/madsv2/forest/main.h"
 #include "mads/madsv2/forest/rooms/section1.h"
 #include "mads/madsv2/forest/rooms/section2.h"
@@ -58,6 +60,8 @@ ForestEngine *g_engine;
 ForestEngine::ForestEngine(OSystem *syst, const MADSGameDescription *gameDesc) :
 		MADSV2Engine(syst, gameDesc) {
 	g_engine = this;
+	init_extra();
+	init_inventory();
 }
 
 ForestEngine::~ForestEngine() {
diff --git a/engines/mads/madsv2/forest/inventory.cpp b/engines/mads/madsv2/forest/inventory.cpp
new file mode 100644
index 00000000000..bbd95ddc97c
--- /dev/null
+++ b/engines/mads/madsv2/forest/inventory.cpp
@@ -0,0 +1,418 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "mads/madsv2/core/buffer.h"
+#include "mads/madsv2/core/error.h"
+#include "mads/madsv2/core/game.h"
+#include "mads/madsv2/core/global.h"
+#include "mads/madsv2/core/inter.h"
+#include "mads/madsv2/core/kernel.h"
+#include "mads/madsv2/core/matte.h"
+#include "mads/madsv2/core/mcga.h"
+#include "mads/madsv2/core/mouse.h"
+#include "mads/madsv2/core/object.h"
+#include "mads/madsv2/core/pal.h"
+#include "mads/madsv2/core/player.h"
+#include "mads/madsv2/core/screen.h"
+#include "mads/madsv2/core/sprite.h"
+#include "mads/madsv2/core/timer.h"
+#include "mads/madsv2/forest/digi.h"
+#include "mads/madsv2/forest/extra.h"
+#include "mads/madsv2/forest/global.h"
+#include "mads/madsv2/forest/inventory.h"
+#include "mads/madsv2/forest/journal.h"
+#include "mads/madsv2/forest/midi.h"
+
+namespace MADS {
+namespace MADSV2 {
+namespace Forest {
+
+char interface_name[40];
+
+void init_inventory() {
+	Common::fill(interface_name, interface_name + 40, 0);
+}
+
+static Series *object_icon(int num) {
+	Common::String name = Common::String::format("*obj%3di", num);
+	return sprite_series_load(name.c_str(), 0);
+}
+
+static int inventory_get_item(int num) {
+	if (!mouse_stop_stroke)
+		return 0;
+	if (num < 1)
+		return -1;
+
+	int var_6 = 0;
+	for (int dx = 1; dx <= num; dx++) {
+		int cx;
+		switch (dx) {
+		case 1:  case 8:  cx = 9;   break;
+		case 2:  case 9:  cx = 51;  break;
+		case 3:  case 10: cx = 93;  break;
+		case 4:  case 11: cx = 135; break;
+		case 5:  case 12: cx = 177; break;
+		case 6:  case 13: cx = 219; break;
+		case 7:  case 14: cx = 261; break;
+		default:          cx = var_6; break;
+		}
+		int bx = cx + 42;
+		int di = (dx >= 8) ? 108 : 72;
+		int ax = di + 36;
+		var_6 = cx;
+
+		if (mouse_x >= cx && mouse_x <= bx && mouse_y >= di && mouse_y <= ax)
+			return dx;
+	}
+	return -1;
+}
+
+static void kernel_load_interface(void) {
+	char temp_buf[80];
+	char *mark;
+
+	Common::strcpy_s(temp_buf, kernel.interface);
+	mark = strchr(temp_buf, '.');
+	if (mark != NULL) {
+		*mark = 0;
+	}
+	if (inter_input_mode != INTER_BUILDING_SENTENCES) {
+		Common::strcat_s(temp_buf, "A");
+	}
+	Common::strcat_s(temp_buf, ".INT");
+
+	if (strcmp(interface_name, temp_buf)) {
+		buffer_free(&scr_inter_orig);
+		pal_activate_shadow(&kernel_shadow_inter);
+		if (inter_load_background(temp_buf, &scr_inter_orig)) {
+			error_report(ERROR_KERNEL_NO_INTERFACE, SEVERE, MODULE_KERNEL, inter_input_mode, 0);
+		}
+		Common::strcpy_s(interface_name, temp_buf);
+		pal_activate_shadow(&kernel_shadow_main);
+	}
+}
+
+static void inven_set_interface_mode(int mode) {
+	inter_input_mode = 2;
+	kernel_load_interface();
+	inter_base_time = timer_read();
+	left_command = -1;
+	left_action  = -1;
+	left_inven   = -1;
+
+	if (!viewing_at_y) {
+		if (mode != 0)
+			buffer_rect_copy(scr_inter_orig, scr_inter, 138, 0, 58, 44);
+		else
+			buffer_rect_copy(scr_inter_orig, scr_inter, 0, 0, 320, 44);
+
+		if (kernel_mode == 5)
+			matte_inter_frame(0, 0);
+	}
+
+	inter_init_sentence();
+	inter_setup_hotspots();
+
+	if (!viewing_at_y)
+		inter_prepare_background();
+
+	kernel_refresh_dynamic();
+}
+
+void display_inventory() {
+	int var_10 = 17;
+	int var_12 = 72;
+	int var_2  = -1;
+	int var_22 = -1;
+	int var_6  = 0;
+	int var_E  = 0;
+	int var_20 = 0;
+	int var_4  = 0;
+	int var_1E = 0;
+	long var_1C_1A = 0;
+	int var_8  = 0;
+
+	if (kernel.trigger != 0)
+		return;
+
+	inter_turn_off_object();
+	buffer_rect_copy_2(scr_live, scr_inter_orig, 42, 55, 0, 156, 138, 138);
+	inter_update_series(int_sprite[fx_int_journal]);
+	inter_update_series(int_sprite[fx_int_backpack]);
+	inter_update_series(int_sprite[fx_int_candle]);
+	inter_update_series(int_sprite[fx_int_exit]);
+	inven_set_interface_mode(-1);
+
+	open_journal(2);
+	cursor_id = 2;
+	if (cursor_last != 2) {
+		mouse_cursor_sprite(cursor, 2);
+		cursor_last = cursor_id;
+	}
+
+	for (int on = 0; on < 16; on++) {
+		if (object[on].location == 2)
+			var_20++;
+	}
+
+	global[inventory_is_displayed] = -1;
+	mouse_hide();
+
+	// Draw inventory background
+	SeriesPtr bg_series = sprite_series_load("*backinv", 0);
+	mcga_setpal(&master_palette);
+	sprite_draw(bg_series, 1, &scr_live, 1, 53);
+	sprite_free(&bg_series, -1);
+
+	// Draw inventory item icons in a 7-per-row grid
+	int object_num = 0;
+	while (object_num < 16) {
+		if (object[object_num].location != 2) {
+			object_num++;
+			continue;
+		}
+		SeriesPtr icon_series = object_icon(object_num);
+		mcga_setpal(&master_palette);
+		var_6++;
+		if (var_6 % 8 == 0) {
+			var_12 += 40;
+			var_10 = 17;
+		} else if (var_6 != 1) {
+			var_10 += 41;
+		}
+		sprite_draw(icon_series, 1, &scr_live, var_10, var_12);
+		sprite_free(&icon_series, -1);
+		object_num++;
+	}
+
+	mouse_cursor_sprite(cursor, 1);
+	mouse_show();
+
+	// Main event loop
+	for (;;) {
+		digi_read_another_chunk();
+		if (global[g009])
+			midi_loop();
+		mouse_begin_cycle(0);
+		// TODO: delay_to_expiry(0, -1) — not yet declared
+
+		if (var_1E) {
+			long current = timer_read();
+			if (current > var_1C_1A + (int16)var_8)
+				goto exit_inventory;
+		}
+
+		if (!player.commands_allowed)
+			continue;
+
+		var_4 = inventory_get_item(var_20);
+		if (var_4 == 0)
+			continue;
+
+		if (var_4 == -1) {
+			kernel_force_refresh();
+			goto cancel_inventory;
+		}
+
+		// Find the var_4-th inventory item
+		object_num = 0;
+		var_E = 0;
+		while (object_num < 16) {
+			if (object[object_num].location == 2) {
+				var_E++;
+				if (var_E == var_4) {
+					var_2 = object_num;
+					break;
+				}
+			}
+			object_num++;
+		}
+		if (object_num >= 16) {
+			var_E = 0;
+			var_4 = 0;
+			continue;
+		}
+
+		kernel_force_refresh();
+
+		// Determine usability based on object number and room
+		if (var_2 <= 15) {
+			switch (var_2) {
+			case 0:
+				var_22 = (room_id == 521) ? 0 : -1;
+				break;
+			case 1: case 10: case 15:
+				var_22 = (room_id == 308) ? 0 : -1;
+				break;
+			case 2: case 3: case 6: case 7: case 9: case 11: case 12:
+				var_22 = (room_id == 521) ? 0 : -1;
+				break;
+			case 4: case 14:
+				var_22 = (room_id == 307 || room_id == 322 || room_id == 308 ||
+				          room_id == 401 || room_id == 512) ? 0 : -1;
+				break;
+			case 5:
+				var_22 = (room_id == 203 || room_id == 308) ? 0 : -1;
+				break;
+			case 8:
+				var_22 = (room_id == 203) ? 0 : -1;
+				break;
+			case 13:
+				var_22 = (room_id == 404) ? 0 : -1;
+				break;
+			default:
+				break;
+			}
+		}
+
+		if (object_check_quality(var_2, 0))
+			var_22 = -1;
+
+		// Room 203: special quality-gated overrides
+		if (room_id == 203 && !global[g046]) {
+			if (var_2 == 8 || var_2 == 5) {
+				if (object_check_quality(var_2, 0))
+					var_22 = -1;
+				else
+					var_22 = 0;
+			} else {
+				var_22 = 0;
+			}
+		}
+
+		// Room 402
+		if (room_id == 402) {
+			if (global[g083] >= 3)
+				var_22 = -1;
+			else
+				var_22 = 0;
+		}
+
+		// Room 308
+		if (room_id == 308) {
+			if (var_2 == 1 || var_2 == 15 || var_2 == 5) {
+				if (object_check_quality(var_2, 0))
+					var_22 = -1;
+				else
+					var_22 = 0;
+			} else {
+				var_22 = 0;
+			}
+		}
+
+		if (var_2 == -1 || var_4 == -1 || var_22 != 0) {
+			var_E = 0;
+			var_4 = 0;
+			continue;
+		}
+
+		// var_22 == 0: item may be usable here — check room-specific audio/action
+		switch (room_id) {
+		case 221:
+			digi_play_build(221, 'e', 5, 2);
+			var_22 = -1;
+			break;
+		case 203:
+			if (var_2 != 5 && var_2 != 8) {
+				digi_play_build(203, 'R', 5, 2);
+				var_22 = -1;
+			}
+			break;
+		case 308:
+			if (var_2 == 1 || var_2 == 15) {
+				var_8 = 90;
+				digi_play_build(308, 'e', 4, 1);
+				var_1C_1A = timer_read();
+				var_1E = -1;
+				player.commands_allowed = 0;
+				mouse_cursor_sprite(cursor, 2);
+				continue;
+			} else if (var_2 == 5) {
+				var_8 = 180;
+				digi_play_build(308, 'r', 2, 1);
+				var_1C_1A = timer_read();
+				var_1E = -1;
+				player.commands_allowed = 0;
+				mouse_cursor_sprite(cursor, 2);
+				continue;
+			} else {
+				digi_play_build(308, 'r', 3, 1);
+				var_22 = -1;
+			}
+			break;
+		case 402:
+			digi_play_build(203, 'R', 5, 2);
+			var_22 = -1;
+			break;
+		default:
+			break;
+		}
+
+		if (var_22 != 0) {
+			var_E = 0;
+			var_4 = 0;
+			continue;
+		}
+
+		// Item is usable — exit inventory with selection
+		mouse_cursor_sprite(cursor, 2);
+
+exit_inventory:
+		global[inventory_is_displayed] = 0;
+		var_6 = var_20;
+		close_journal(2);
+		knuthole_flag = true;
+		inter_spin_object(var_2);
+		inter_move_object(var_2, 2);
+		global[player_selected_object] = var_2;
+
+		player_verb        = -1;
+		player_main_noun   = -1;
+		player_second_noun = -1;
+		inv_enable_command = true;
+
+		game_exec_function(room_pre_parser_code_pointer);
+		game_exec_function(room_parser_code_pointer);
+		goto restore_interface;
+
+cancel_inventory:
+		mouse_cursor_sprite(cursor, 2);
+		global[inventory_is_displayed] = 0;
+		var_6 = var_20;
+		close_journal(2);
+
+restore_interface:
+		stamp_sprite_to_interface(JOURNAL_X, JOURNAL_Y, 1, int_sprite[fx_int_journal]);
+		stamp_sprite_to_interface(BP_X,      BP_Y,      1, int_sprite[fx_int_backpack]);
+		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 (inv_enable_command) {
+			mouse_cursor_sprite(cursor, 1);
+			player.commands_allowed = -1;
+		}
+		return;
+	}
+}
+
+} // namespace Forest
+} // namespace MADSV2
+} // namespace MADS
diff --git a/engines/mads/madsv2/forest/inventory.h b/engines/mads/madsv2/forest/inventory.h
new file mode 100644
index 00000000000..32c927de406
--- /dev/null
+++ b/engines/mads/madsv2/forest/inventory.h
@@ -0,0 +1,38 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef MADS_FOREST_INVENTORY_H
+#define MADS_FOREST_INVENTORY_H
+
+#include "mads/madsv2/core/general.h"
+
+namespace MADS {
+namespace MADSV2 {
+namespace Forest {
+
+extern void init_inventory();
+extern void display_inventory();
+
+} // namespace Forest
+} // namespace MADSV2
+} // namespace MADS
+
+#endif
diff --git a/engines/mads/module.mk b/engines/mads/module.mk
index cee9da707fd..0ae9a6e3841 100644
--- a/engines/mads/module.mk
+++ b/engines/mads/module.mk
@@ -264,6 +264,7 @@ MODULE_OBJS += \
 	madsv2/forest/digi.o \
 	madsv2/forest/extra.o \
 	madsv2/forest/global.o \
+	madsv2/forest/inventory.o \
 	madsv2/forest/journal.o \
 	madsv2/forest/main.o \
 	madsv2/forest/menus.o \




More information about the Scummvm-git-logs mailing list