[Scummvm-git-logs] scummvm master -> 07298a76da8e1c003c393f9de30d4a9c5778e3f7
dreammaster
noreply at scummvm.org
Thu May 21 20:45:59 UTC 2026
This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
4eacb7d50d MADS: PHANTOM: Remove unused functions from main_menu.cpp
845f7a2b45 MADS: DRAGONSPHERE: Beginnings of main menu
1892a6850c MADS: DRAGONSPHERE: Main menu buttons showing
6a2f5bd733 MADS: DRAGONSPHERE: Added global_parser_code
07298a76da MADS: DRAGONSPHERE: Other global game functions
Commit: 4eacb7d50da1ab0c072022a8b25c5ed1a3f34404
https://github.com/scummvm/scummvm/commit/4eacb7d50da1ab0c072022a8b25c5ed1a3f34404
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-05-22T06:20:41+10:00
Commit Message:
MADS: PHANTOM: Remove unused functions from main_menu.cpp
Changed paths:
engines/mads/madsv2/phantom/main_menu.cpp
diff --git a/engines/mads/madsv2/phantom/main_menu.cpp b/engines/mads/madsv2/phantom/main_menu.cpp
index 727b1d769e5..12636a1df5b 100644
--- a/engines/mads/madsv2/phantom/main_menu.cpp
+++ b/engines/mads/madsv2/phantom/main_menu.cpp
@@ -152,7 +152,7 @@ Palette special_pal; /* Palette for fadeout */
MenuItem menu_item[NUM_MENU_ITEMS+1]; /* Menu item array */
-void start_series() {
+static void start_series() {
int error_flag = true;
int count;
int handle;
@@ -180,7 +180,7 @@ done:
}
}
-void stop_series(void) {
+static void stop_series(void) {
int count;
for (count = NUM_MENU_ITEMS - 1; count >= 0; count--) {
@@ -188,7 +188,7 @@ void stop_series(void) {
}
}
-void start_hotspots(void) {
+static void start_hotspots(void) {
int count;
int x1, x2, y1, y2;
int xs, ys;
@@ -211,7 +211,7 @@ void start_hotspots(void) {
hspot_add(156, 77, 170, 83, 2, EYE_HOTSPOT + 1, mcga_mode);
}
-void process_menu(void) {
+static void process_menu(void) {
int myspot;
myspot = hspot_which(mouse_x, mouse_y - viewing_at_y, mcga_mode);
@@ -236,7 +236,7 @@ void process_menu(void) {
}
}
-void process_sprites(void) {
+static void process_sprites(void) {
int count;
int sprite;
int series;
@@ -309,7 +309,7 @@ done:
;
}
-void process_messages(int anim) {
+static void process_messages(int anim) {
int total;
int count;
int id, x, y;
@@ -464,36 +464,9 @@ void menu_control(void) {
kernel.clock = now_clock;
if (now_clock >= menu_clock) {
- switch (menu_mode) {
- case MENU_APPEARING:
- /*
- menu_state -= 1;
- if (menu_state <= 1) {
- menu_state = MENU_HIGH_SPRITE;
- do {
- menu_appear_state += 1;
- } while ((menu_appear_state < NUM_MENU_ITEMS) &&
- (!menu_item[menu_appear_state].active));
- if (menu_appear_state >= NUM_MENU_ITEMS) {
- menu_mode = MENU_ACCEPTING_COMMANDS;
- }
- }
- */
- break;
-
- case MENU_ACCEPTING_COMMANDS:
- break;
-
- case MENU_DISAPPEARING:
+ if (menu_mode == MENU_DISAPPEARING)
going = false;
- /*
- menu_state += 1;
- if (menu_state > MENU_HIGH_SPRITE + 1) {
- going = false;
- }
- */
- break;
- }
+
menu_clock = now_clock + MENU_FRAME_RATE;
}
@@ -571,72 +544,6 @@ void menu_control(void) {
stop_series();
}
-void add_parameter(char *parameter) {
- if (command_line_size < COMMAND_LINE_MAX) {
- Common::strcpy_s(command_line[command_line_size], parameter);
- command_list[command_line_size] = command_line[command_line_size];
- command_line_size++;
- }
-}
-
-void add_sound_parameter(void) {
- char temp_buf[80];
- char work_buf[80];
-
- Common::strcpy_s(temp_buf, "-c:n");
- temp_buf[3] = sound_letter;
-
- Common::strcat_s(temp_buf, ",");
- Common::sprintf_s(work_buf, "%x", config_file.sound_card_address);
- Common::strcat_s(temp_buf, work_buf);
- Common::strcat_s(temp_buf, ",");
- Common::sprintf_s(work_buf, "%x", config_file.sound_card_type);
- Common::strcat_s(temp_buf, work_buf);
-
- add_parameter(temp_buf);
-}
-
-void add_speech_parameter(void) {
- char temp_buf[80];
- char work_buf[80];
-
- if (config_file.speech_card_type > 0) {
- Common::strcpy_s(temp_buf, "-u:");
-
- Common::sprintf_s(work_buf, "%x", config_file.speech_card_address);
- Common::strcat_s(temp_buf, work_buf);
- Common::strcat_s(temp_buf, ",");
- Common::sprintf_s(work_buf, "%x", config_file.speech_card_type);
- Common::strcat_s(temp_buf, work_buf);
- Common::strcat_s(temp_buf, ",");
- env_catint(temp_buf, config_file.speech_card_irq, 2);
- Common::strcat_s(temp_buf, ",");
- env_catint(temp_buf, config_file.speech_card_drq, 2);
-
- add_parameter(temp_buf);
- }
-}
-
-void add_chain_parameter(void) {
- char temp_buf[80];
- int added_dash = false;
-
- Common::strcpy_s(temp_buf, "-a:\"mainmenu");
-
- if (env_search_mode == ENV_SEARCH_CONCAT_FILES) {
- Common::strcat_s(temp_buf, " -p");
- added_dash = true;
- }
-
- if (use_mouse_cursor_fix) {
- if (!added_dash) {
- Common::strcat_s(temp_buf, " -");
- added_dash = true;
- }
- Common::strcat_s(temp_buf, "u");
- }
-}
-
} // namespace Phantom
} // namespace MADSV2
} // namespace MADS
Commit: 845f7a2b45f994d941ad34f070e1079e2c369cc0
https://github.com/scummvm/scummvm/commit/845f7a2b45f994d941ad34f070e1079e2c369cc0
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-05-22T06:20:41+10:00
Commit Message:
MADS: DRAGONSPHERE: Beginnings of main menu
Changed paths:
A engines/mads/madsv2/dragonsphere/main.cpp
A engines/mads/madsv2/dragonsphere/main.h
A engines/mads/madsv2/dragonsphere/main_menu.cpp
A engines/mads/madsv2/dragonsphere/main_menu.h
A engines/mads/madsv2/dragonsphere/menus.cpp
A engines/mads/madsv2/dragonsphere/menus.h
A engines/mads/madsv2/dragonsphere/sound_dragonsphere.cpp
A engines/mads/madsv2/dragonsphere/sound_dragonsphere.h
engines/mads/madsv2/dragonsphere/dragonsphere.cpp
engines/mads/madsv2/dragonsphere/mads/sounds.h
engines/mads/module.mk
diff --git a/engines/mads/madsv2/dragonsphere/dragonsphere.cpp b/engines/mads/madsv2/dragonsphere/dragonsphere.cpp
index 370f905ee38..891c94915e4 100644
--- a/engines/mads/madsv2/dragonsphere/dragonsphere.cpp
+++ b/engines/mads/madsv2/dragonsphere/dragonsphere.cpp
@@ -27,6 +27,8 @@
#include "mads/madsv2/core/screen.h"
#include "mads/madsv2/dragonsphere/dragonsphere.h"
#include "mads/madsv2/dragonsphere/global.h"
+#include "mads/madsv2/dragonsphere/main.h"
+#include "mads/madsv2/dragonsphere/sound_dragonsphere.h"
namespace MADS {
namespace MADSV2 {
@@ -41,12 +43,11 @@ Common::Error DragonsphereEngine::run() {
setDebugger(new Console());
// Set up sound manager
- _soundManager = nullptr; // new DragonsphereSoundManager(_mixer, _soundFlag);
- //_soundManager->validate();
+ _soundManager = new DragonSoundManager(_mixer, _soundFlag);
+ _soundManager->validate();
// Run the game
- // TODO
- Dragonsphere::global_section_constructor(); // Test call
+ Dragonsphere::dragonsphere_main();
return Common::kNoError;
}
diff --git a/engines/mads/madsv2/dragonsphere/mads/sounds.h b/engines/mads/madsv2/dragonsphere/mads/sounds.h
index ecf9d31c787..2e7d9469e62 100644
--- a/engines/mads/madsv2/dragonsphere/mads/sounds.h
+++ b/engines/mads/madsv2/dragonsphere/mads/sounds.h
@@ -80,7 +80,10 @@ enum {
N_BigBirdCall = 69,
N_JumpThwang = 70,
N_StepOnFloatingDisk = 77,
- N_004CryOfDismay = 78
+ N_004CryOfDismay = 78,
+
+ // Section 9
+ N_AllFade = 1
};
} // namespace Dragonsphere
diff --git a/engines/mads/madsv2/dragonsphere/main.cpp b/engines/mads/madsv2/dragonsphere/main.cpp
new file mode 100644
index 00000000000..5d46d24113d
--- /dev/null
+++ b/engines/mads/madsv2/dragonsphere/main.cpp
@@ -0,0 +1,320 @@
+/* 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 "common/config-manager.h"
+#include "gui/saveload.h"
+#include "mads/madsv2/dragonsphere/main.h"
+#include "mads/madsv2/animview/animview.h"
+#include "mads/madsv2/textview/textview.h"
+#include "mads/madsv2/core/env.h"
+#include "mads/madsv2/core/error.h"
+#include "mads/madsv2/core/fileio.h"
+#include "mads/madsv2/core/game.h"
+#include "mads/madsv2/core/himem.h"
+#include "mads/madsv2/core/kernel.h"
+#include "mads/madsv2/core/magic.h"
+#include "mads/madsv2/core/matte.h"
+#include "mads/madsv2/core/mcga.h"
+#include "mads/madsv2/core/mouse.h"
+#include "mads/madsv2/core/pal.h"
+#include "mads/madsv2/core/player.h"
+#include "mads/madsv2/core/quote.h"
+#include "mads/madsv2/core/speech.h"
+#include "mads/madsv2/dragonsphere/main_menu.h"
+#include "mads/madsv2/dragonsphere/menus.h"
+#include "mads/madsv2/engine.h"
+
+namespace MADS {
+namespace MADSV2 {
+namespace Dragonsphere {
+
+constexpr bool SHOW_LINES = true;
+constexpr byte LINE_COLOR = 2;
+
+char *quotes;
+
+static void main_menu_main() {
+ auto &screen = *g_engine->getScreen();
+ Palette palette;
+
+ if (!kernel_game_startup(19, KERNEL_STARTUP_CURSOR | KERNEL_STARTUP_INTERRUPT | KERNEL_STARTUP_FONT,
+ nullptr, nullptr)) {
+ viewing_at_y = (200 - scr_work.y) >> 1;
+
+ mouse_cursor_sprite(cursor, 7);
+ mouse_show();
+ mouse_force(280, 126);
+ mouse_hide();
+
+ mouse_cursor_sprite(cursor, 1);
+ matte_init(0xFFFF);
+ kernel_seq_init();
+ kernel_message_init();
+ kernel_animation_init();
+ kernel_init_dynamic();
+
+ picture_view_x = 0;
+ picture_view_y = 0;
+
+ quotes = quote_load(0, 68, 69, 70, 71, 72, 73, 74, 75, 76,
+ 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
+ 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
+ 97, 98, 99, 0);
+
+ global_speech_load(9);
+ bool valid = !kernel_room_startup(902, 0, nullptr, true, true);
+
+ master_palette[4].r = 63;
+ master_palette[4].g = 50;
+ master_palette[4].b = 0;
+ master_palette[5].r = 30;
+ master_palette[5].g = 15;
+ master_palette[5].b = 0;
+ mcga_setpal_range(&master_palette, 4, 2);
+
+ new_background = true;
+
+ if (valid) {
+ memset(&palette, 0, sizeof(palette));
+ mcga_setpal(&palette);
+ mouse_cursor_sprite(cursor, 1);
+
+ if (SHOW_LINES && viewing_at_y != 0) {
+ screen.hLine(0, viewing_at_y - 2, 319, LINE_COLOR);
+ screen.hLine(0, scr_work.y + viewing_at_y + 1, 319, LINE_COLOR);
+ }
+
+ kernel_load_sound_driver("*#SOUND.PH9", 'N', 544, 0, 49);
+
+ menu_control();
+
+ if (selected_item >= 0) {
+ // Zero out the first 3 entries of both magic color arrays
+ for (int i = 0; i < 3; i++) {
+ magic_color_values[i] = 0;
+ magic_color_flags[i] = 0;
+ }
+
+ mcga_getpal(&palette);
+
+ magic_fade_to_grey(palette, 0, 0x10, 1, 1, 0, 0, 0);
+ }
+ }
+
+ free(quotes);
+ kernel_unload_sound_driver();
+ kernel_game_shutdown();
+ }
+
+ mcga_reset();
+}
+
+static void main_cold_data_init() {
+ debugger_reset = game_debugger_reset;
+ debugger_update = game_debugger;
+ game_menu_routine = global_game_menu;
+ game_menu_init = global_menu_system_init;
+ game_menu_exit = global_menu_system_shutdown;
+ game_emergency_save = global_emergency_save;
+
+ Common::strcpy_s(config_file_name, "config.pha");
+ Common::strcpy_s(save_game_key, "phan");
+ Common::strcpy_s(restart_game_key, "phantom");
+
+ Common::strcpy_s(player.series_name, "RAL");
+ player.walker_must_reload = true;
+ player.walker_loads_first = false;
+ player.walker_visible = true;
+ player.scaling_velocity = true;
+
+ Common::strcpy_s(kernel_cheating_password, "WIDECHEW");
+ kernel_cheating_allowed = strlen(kernel_cheating_password);
+
+ kernel.cheating = gDebugLevel == 9 ? kernel_cheating_allowed : 0;
+}
+
+static void game_main(int argc, const char **argv) {
+ int count;
+ int mads_mode;
+ const char *scan;
+
+ pack_enable_pfab_explode();
+
+ mads_mode = env_verify();
+
+ new_section = 1;
+ new_room = 101;
+ player.x = 160;
+ player.y = 78;
+
+ player.target_facing = FACING_NORTH;
+
+ game_cold_data_init();
+ main_cold_data_init();
+ g_engine->readConfigFile();
+ global_load_config_parameters();
+
+ if (argc >= 2) {
+ for (count = 1; count < argc; count++) {
+ if (strchr("-/", argv[count][0]) != NULL) {
+ for (scan = argv[count] + 1; *scan != 0; scan++) {
+ flag_parse(&scan);
+ }
+ } else if (argv[count][0] == '?') {
+ show_logo();
+
+ if (!mads_mode) env_search_mode = ENV_SEARCH_CONCAT_FILES;
+ error_dump_file("*warn2.dat");
+ goto done;
+ }
+ }
+ }
+
+ if (report_version) {
+ show_version();
+ goto done;
+ }
+
+ if (fileio_exist("global.hag")) {
+ art_hags_are_on_hd = true;
+ } else {
+ art_hags_are_on_hd = false;
+ }
+
+#if 0
+ if (config_file.cd_version_installed) {
+ strcpy(temp_buf_2, "x:\\forest.exe");
+ temp_buf_2[0] = env_cd_drive;
+ if (!fileio_exist(temp_buf_2)) {
+ problem();
+ printf("Please throw the Once Upon A Forest CD into drive %c:\n", (char)env_cd_drive);
+ printf("and type 'OUAF'. If your CD-ROM drive letter has changed, run\n");
+ printf("INSTALL to reconfigure this option.\n\n");
+ goto done;
+ }
+ }
+
+ if (!fileio_exist("config.for")) {
+ problem();
+ printf("Before you can run Once Upon A Forest, you need to run 'INSTALL' to configure\n");
+ printf("the game for you your hardware. Type 'INSTALL' and hit 'ENTER' when you have\n");
+ printf("finished reading this.\n\n");
+ goto done;
+ }
+
+ mem_you_got = mem_used + mem_avail_at_start;
+
+ if (mem_you_got < 569000) {
+ need_to_free = 569000 - mem_you_got;
+ problem();
+ printf("You need at least 588,000 bytes of conventional memory to play\n");
+ printf("Once Upon A Forest. You'll need to free up another %6ld bytes.\n\n", need_to_free);
+ /* printf("to play this game.\n\n"); */
+ goto done;
+ }
+#endif
+ himem_startup();
+
+ himem_shutdown();
+
+ if (!mads_mode && (env_search_mode == ENV_SEARCH_MADS_PATH))
+ error("false start");
+
+ game_control();
+
+done:
+ global_unload_config_parameters();
+
+ if (fileio_exist("config.for")) {
+ global_write_config_file();
+ }
+ if (chain_flag && (win_status || force_chain) && (key_abort_level < 2)) {
+ warning("TODO: chain_execute");
+ } else {
+ if (win_status) {
+ debug("(Ending: %d)", win_status);
+ }
+ }
+}
+
+void dragonsphere_main() {
+ static const char *CMD_LINE[] = { nullptr, "-p" };
+
+ pack_enable_pfab_explode();
+ if (!env_verify())
+ env_search_mode = ENV_SEARCH_CONCAT_FILES;
+
+ if (ConfMan.getBool("start_game") || ConfMan.hasKey("save_slot"))
+ selected_item = 0;
+ else if (ConfMan.getBool("start_intro"))
+ selected_item = 3;
+ else
+ selected_item = -1;
+
+ while (!g_engine->shouldQuit()) {
+ switch (selected_item) {
+ case -1:
+ main_menu_main();
+ break;
+
+ case 0:
+ game_main(2, CMD_LINE);
+ return;
+
+ case 1: {
+ // Resume savegame
+ // Get a list of saves and choose the last one
+ auto saves = g_engine->listSaves();
+ if (!saves.empty())
+ savegame_slot = saves.back().getSaveSlot();
+
+ // Start the game, which will also load the selected savegame
+ game_main(2, CMD_LINE);
+ return;
+ }
+
+ case 2:
+ // Restore savegame
+ game_restore_flag = 2;
+ game_main(2, CMD_LINE);
+ return;
+
+ case 3:
+ AnimView::animview_main("@phantom");
+ selected_item = -1;
+ break;
+
+ case 4:
+ // Exit
+ return;
+
+ default:
+ // Credits
+ TextView::textview_main("credits");
+ selected_item = -1;
+ break;
+ }
+ }
+}
+
+} // namespace Dragonspheree
+} // namespace MADSV2
+} // namespace MADS
diff --git a/engines/mads/madsv2/dragonsphere/main.h b/engines/mads/madsv2/dragonsphere/main.h
new file mode 100644
index 00000000000..b2851a42dc7
--- /dev/null
+++ b/engines/mads/madsv2/dragonsphere/main.h
@@ -0,0 +1,37 @@
+/* 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_DRAGONSPHERE_MAIN_H
+#define MADS_DRAGONSPHERE_MAIN_H
+
+#include "common/scummsys.h"
+
+namespace MADS {
+namespace MADSV2 {
+namespace Dragonsphere {
+
+extern void dragonsphere_main();
+
+} // namespace Dragonsphere
+} // namespace MADSV2
+} // namespace MADS
+
+#endif
diff --git a/engines/mads/madsv2/dragonsphere/main_menu.cpp b/engines/mads/madsv2/dragonsphere/main_menu.cpp
new file mode 100644
index 00000000000..e2e22963e34
--- /dev/null
+++ b/engines/mads/madsv2/dragonsphere/main_menu.cpp
@@ -0,0 +1,440 @@
+/* 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/engine.h"
+#include "mads/madsv2/core/general.h"
+#include "mads/madsv2/core/config.h"
+#include "mads/madsv2/core/font.h"
+#include "mads/madsv2/core/speech.h"
+#include "mads/madsv2/core/matte.h"
+#include "mads/madsv2/core/sprite.h"
+#include "mads/madsv2/core/error.h"
+#include "mads/madsv2/core/room.h"
+#include "mads/madsv2/core/fileio.h"
+#include "mads/madsv2/core/env.h"
+#include "mads/madsv2/core/buffer.h"
+#include "mads/madsv2/core/mem.h"
+#include "mads/madsv2/core/pal.h"
+#include "mads/madsv2/core/timer.h"
+#include "mads/madsv2/core/mcga.h"
+#include "mads/madsv2/core/cycle.h"
+#include "mads/madsv2/core/mouse.h"
+#include "mads/madsv2/core/screen.h"
+#include "mads/madsv2/core/video.h"
+#include "mads/madsv2/core/lib.h"
+#include "mads/madsv2/core/keys.h"
+#include "mads/madsv2/core/sound.h"
+#include "mads/madsv2/core/btype.h"
+#include "mads/madsv2/core/hspot.h"
+#include "mads/madsv2/core/magic.h"
+#include "mads/madsv2/core/ems.h"
+#include "mads/madsv2/core/xms.h"
+#include "mads/madsv2/core/imath.h"
+#include "mads/madsv2/core/kernel.h"
+#include "mads/madsv2/core/game.h"
+#include "mads/madsv2/core/pack.h"
+#include "mads/madsv2/core/quote.h"
+#include "mads/madsv2/dragonsphere/mads/sounds.h"
+#include "mads/madsv2/dragonsphere/main_menu.h"
+
+namespace MADS {
+namespace MADSV2 {
+namespace Dragonsphere {
+
+#define CONFIG_FILE_NAME "CONFIG.PHA"
+
+#define EYE_QUOTES 16
+#define EYE_HOTSPOT 32
+#define EYE_MESSAGES 2
+
+#undef MESSAGE_COLOR
+#define MESSAGE_COLOR 1284
+
+
+ConfigFile config_file;
+
+int mads_mode = false;
+
+FontPtr font = NULL;
+int font_auto_spacing = -1;
+
+bool new_background = false;
+int room_number = 0;
+
+int win_status = 0;
+
+bool force_opening = false;
+bool dont_return = false;
+bool white_bars = true;
+byte white_border = 2;
+
+char command_line[COMMAND_LINE_MAX][80];
+char *command_list[COMMAND_LINE_MAX+1];
+int command_line_size = 0;
+
+int use_mouse_cursor_fix = false;
+
+bool going;
+int menu_mode;
+int must_perform_matte;
+
+long frame_clock;
+long now_clock;
+long menu_clock;
+
+int menu_state;
+int menu_appear_state;
+
+int highest_y = -1;
+int next_x = -1;
+
+char sound_file[80] = "*#SOUND.PH9";
+char sound_letter = 'N';
+
+int sound_board_address = 0x220; /* Default sound board address */
+int sound_board_type = sound_board_roland; /* Default sound board type */
+
+int swapping = false; /* Flag when swapping in new background */
+int swap_line; /* Currently active swap line */
+long swap_clock; /* Time for next swap */
+
+int current_item;
+int current_eye = false;
+int eye_latch = false;
+int selected_item = -1;
+
+#define LEFT_EYE 0
+#define RIGHT_EYE 1
+
+extern char *quotes;
+int eye_message[2];
+int eye_pokes = 0;
+int recent_eye = 0;
+int rebel_base = 0;
+int poke_count_message = -1;
+int poke_count = 0;
+int poke_counting = false;
+
+char poke_count_buf[2][20];
+
+char bonus_buf[80] = "";
+
+Palette special_pal; /* Palette for fadeout */
+
+
+MenuItem menu_item[NUM_MENU_ITEMS+1]; /* Menu item array */
+
+static void start_series() {
+ int error_flag = true;
+ int count;
+ int handle;
+ char temp_buf[80];
+
+ for (count = 0; count < NUM_MENU_ITEMS; count++) {
+ handle = -1;
+ Common::strcpy_s(temp_buf, "*MAIN0.SS");
+ temp_buf[5] = (char)('0' + count);
+
+ handle = matte_load_series(temp_buf, 0, 0);
+ if (handle < 0) goto done;
+
+ menu_item[count].handle = handle;
+ menu_item[count].active = count != 6; // Quotes button was never implemented
+ menu_item[count].status = 0;
+ }
+
+ error_flag = false;
+
+done:
+ if (error_flag) {
+ Common::strcpy_s(error_string, temp_buf);
+ error_report(ERROR_SERIES_LOAD_FAILED, WARNING, MODULE_UNKNOWN, count, handle);
+ }
+}
+
+static void stop_series() {
+ int count;
+
+ for (count = NUM_MENU_ITEMS - 1; count >= 0; count--) {
+ matte_deallocate_series(menu_item[count].handle, true);
+ }
+}
+
+static void start_hotspots() {
+ int count;
+ int x1, x2, y1, y2;
+ int xs, ys;
+ SeriesPtr series;
+
+ numspots = 0;
+
+ for (count = 0; count < NUM_MENU_ITEMS; count++) {
+ series = series_list[menu_item[count].handle];
+ xs = series->index[0].xs;
+ ys = series->index[0].ys;
+ x1 = series->index[0].x - (xs >> 1);
+ y1 = series->index[0].y - (ys - 1);
+ x2 = x1 + xs - 1;
+ y2 = y1 + ys - 1;
+ hspot_add(x1, y1, x2, y2, 1, count, mcga_mode);
+ }
+}
+
+static void process_menu() {
+ int myspot;
+
+ myspot = hspot_which(mouse_x, mouse_y - viewing_at_y, mcga_mode);
+
+ current_eye = false;
+
+ if ((myspot > 0) && mouse_any_stroke && (menu_mode == MENU_ACCEPTING_COMMANDS)) {
+ current_item = spot[myspot].num;
+ if (current_item >= EYE_HOTSPOT) {
+ current_item = -1;
+ current_eye = true;
+ }
+ } else {
+ current_item = -1;
+ }
+
+ if (mouse_stop_stroke && (current_item >= 0) && (menu_mode == MENU_ACCEPTING_COMMANDS)) {
+ selected_item = current_item;
+ menu_mode = MENU_DISAPPEARING;
+ menu_state = 1;
+ sound_queue(N_AllFade);
+ }
+}
+
+static void process_sprites() {
+ int count;
+ int sprite;
+ int series;
+ int look, match;
+ Image image;
+
+ for (count = 0; count < (int)image_marker; count++) {
+ if ((image_list[count].segment_id < KERNEL_SEGMENT_ANIMATION) ||
+ (image_list[count].segment_id > KERNEL_SEGMENT_ANIMATION_HIGH)) {
+ if (image_list[count].flags >= IMAGE_STATIC) {
+ image_list[count].flags = IMAGE_ERASE;
+ }
+ }
+ }
+
+ if (menu_mode == MENU_APPEARING) goto done;
+
+ for (count = 0; count < NUM_MENU_ITEMS; count++) {
+ if (menu_item[count].active) {
+ image.flags = IMAGE_UPDATE;
+ image.segment_id = (byte)(count + 1);
+
+ series = count;
+ if (menu_mode == MENU_ACCEPTING_COMMANDS) {
+ if (count != current_item) {
+ sprite = 1;
+ } else {
+ sprite = 2;
+ }
+ } else {
+ sprite = 1;
+ /*
+ if (count != selected_item) {
+ sprite = 1;
+ } else {
+ sprite = 2;
+ }
+ */
+ }
+
+ image.series_id = (byte)menu_item[series].handle;
+ image.sprite_id = sprite;
+
+ image.x = series_list[series]->index[sprite - 1].x;
+ image.y = series_list[series]->index[sprite - 1].y;
+
+ image.depth = 0;
+ image.scale = 100;
+
+ match = !(sprite <= MENU_HIGH_SPRITE);
+
+ for (look = 0; !match && (look < (int)image_marker); look++) {
+ if (image_list[look].segment_id == image.segment_id) {
+ if (memcmp(&image_list[look].series_id,
+ &image.series_id, 9) == 0) {
+ image_list[look].flags = IMAGE_STATIC;
+ match = true;
+ }
+ }
+ }
+
+ if (!match) {
+ image_list[image_marker] = image;
+ image_marker++;
+ }
+ }
+ }
+
+done:
+ ;
+}
+
+void menu_control() {
+ int fx;
+ int mykey;
+ int last_frame = -1;
+ int now_frame;
+ int reset_frame;
+ int anim;
+ int initial_reset = false;
+
+ menu_mode = MENU_APPEARING;
+ menu_state = MENU_HIGH_SPRITE;
+ menu_appear_state = 0;
+ menu_clock = 999999999;
+
+ going = true;
+ must_perform_matte = false;
+
+ frame_clock = 0;
+
+ start_series();
+ start_hotspots();
+
+ anim = kernel_run_animation("*RM902A.AA", 0);
+
+ mouse_init_cycle();
+
+ while (going && !g_engine->shouldQuit()) {
+ if (keys_any()) {
+ mykey = keys_get();
+ switch (toupper(mykey)) {
+ case esc_key:
+ selected_item = 4;
+ going = false;
+ break;
+
+ case alt_x_key:
+ case alt_q_key:
+ case ctrl_x_key:
+ case ctrl_q_key:
+ going = false;
+ break;
+
+ case 'S':
+ menu_mode = MENU_APPEARING;
+ menu_state = MENU_HIGH_SPRITE;
+ menu_appear_state = 0;
+ break;
+
+ default:
+ if (menu_mode == MENU_APPEARING) {
+ menu_mode = MENU_ACCEPTING_COMMANDS;
+ kernel_reset_animation(anim, 105);
+ kernel_anim[anim].next_clock = kernel.clock;
+ }
+ break;
+ }
+ }
+
+ mouse_begin_cycle(false);
+
+ if (mouse_stroke_going) {
+ if (menu_mode == MENU_APPEARING) {
+ menu_mode = MENU_ACCEPTING_COMMANDS;
+ kernel_reset_animation(anim, 105);
+ kernel_anim[anim].next_clock = kernel.clock;
+ mouse_init_cycle();
+ }
+ }
+
+ if (menu_mode != MENU_APPEARING) {
+ mouse_show();
+ }
+
+ now_clock = timer_read();
+ kernel.clock = now_clock;
+
+ if (now_clock >= menu_clock) {
+ if (menu_mode == MENU_DISAPPEARING)
+ going = false;
+
+ menu_clock = now_clock + MENU_FRAME_RATE;
+ }
+
+ process_menu();
+ kernel_message_update_all();
+ kernel_process_all_animations();
+
+ reset_frame = -1;
+ now_frame = kernel_anim[anim].frame;
+ if (now_frame != last_frame) {
+ last_frame = now_frame;
+
+ if (now_frame < 105) {
+ if (menu_mode != MENU_APPEARING) {
+ if (!initial_reset) {
+ reset_frame = 105;
+ initial_reset = true;
+ }
+ }
+ }
+
+ if (now_frame >= 109) {
+ if (menu_mode == MENU_APPEARING)
+ menu_mode = MENU_ACCEPTING_COMMANDS;
+
+ reset_frame = 105;
+ }
+
+ if (reset_frame >= 0) {
+ kernel_reset_animation(anim, reset_frame);
+ last_frame = reset_frame;
+ }
+ }
+
+ if (now_clock >= frame_clock) {
+ process_sprites();
+
+ fx = new_background ? 1 : 0;
+ matte_frame(fx, false);
+
+ if (fx) {
+ now_clock = timer_read();
+ menu_clock = now_clock + MENU_FRAME_RATE;
+ }
+
+ must_perform_matte = false;
+ new_background = false;
+
+ frame_clock = now_clock + FRAME_RATE;
+ }
+
+ mouse_end_cycle(false, going);
+ }
+
+ kernel_abort_animation(anim);
+
+ stop_series();
+}
+
+} // namespace Dragonsphere
+} // namespace MADSV2
+} // namespace MADS
diff --git a/engines/mads/madsv2/dragonsphere/main_menu.h b/engines/mads/madsv2/dragonsphere/main_menu.h
new file mode 100644
index 00000000000..cc895fb0896
--- /dev/null
+++ b/engines/mads/madsv2/dragonsphere/main_menu.h
@@ -0,0 +1,59 @@
+/* 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_DRAGONSPHERE_MAIN_MENU_H
+#define MADS_DRAGONSPHERE_MAIN_MENU_H
+
+#include "common/str.h"
+
+namespace MADS {
+namespace MADSV2 {
+namespace Dragonsphere {
+
+#define COMMAND_LINE_MAX 10
+
+#define FRAME_RATE 1
+#define MENU_FRAME_RATE 3
+
+#define NUM_MENU_ITEMS 6
+
+#define MENU_APPEARING 0
+#define MENU_ACCEPTING_COMMANDS 1
+#define MENU_DISAPPEARING 2
+
+#define MENU_HIGH_SPRITE 15
+
+typedef struct {
+ int handle; /* Sprite series handle */
+ int active; /* Menu item is active */
+ int status; /* Current status */
+} MenuItem;
+
+extern bool new_background;
+extern int selected_item;
+
+extern void menu_control();
+
+} // namespace Dragonsphere
+} // namespace MADSV2
+} // namespace MADS
+
+#endif
diff --git a/engines/mads/madsv2/dragonsphere/menus.cpp b/engines/mads/madsv2/dragonsphere/menus.cpp
new file mode 100644
index 00000000000..9fe53d0397f
--- /dev/null
+++ b/engines/mads/madsv2/dragonsphere/menus.cpp
@@ -0,0 +1,615 @@
+/* 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/config.h"
+#include "mads/madsv2/core/echo.h"
+#include "mads/madsv2/core/game.h"
+#include "mads/madsv2/core/global.h"
+#include "mads/madsv2/core/kernel.h"
+#include "mads/madsv2/core/keys.h"
+#include "mads/madsv2/core/matte.h"
+#include "mads/madsv2/core/mem.h"
+#include "mads/madsv2/core/speech.h"
+#include "mads/madsv2/core/quote.h"
+#include "mads/madsv2/core/text.h"
+#include "mads/madsv2/dragonsphere/menus.h"
+#include "mads/madsv2/dragonsphere/global.h"
+
+namespace MADS {
+namespace MADSV2 {
+namespace Dragonsphere {
+
+#define SAVE_MENU_PIXEL_WIDTH 200
+#define MAX_SAVES_ON_SCREEN 10
+
+#define SPACE_BETWEEN -1
+
+#define MAIN_MENU_ITEM_WIDTH 140
+#define MAIN_MENU_FORCE_WIDTH 160
+
+#define DIFFICULTY_MENU_FORCE_WIDTH 140
+
+#define OPTIONS_MENU_ITEM_WIDTH 160
+#define OPTIONS_MENU_FORCE_WIDTH 170
+#define OPTIONS_MENU_OFF_CENTER 10
+
+
+#define SAVE_SUCCESSFUL 1
+#define RESTORE_SUCCESSFUL 2
+#define SAVE_FAILED 3
+#define RESTORE_FAILED 4
+
+
+int global_menu_direct_jump;
+int global_menu_force_restart;
+
+char *menu_quotes = NULL;
+
+
+static int global_save(int id, const char *save_game_name) {
+ int status;
+
+ game_save_name(id + 1);
+
+ if (g_engine->saveGameState(id + 1, save_game_name).getCode() == Common::kNoError)
+ status = SAVE_SUCCESSFUL;
+ else
+ status = SAVE_FAILED;
+
+ return status;
+}
+
+static int global_restore(int id) {
+ int status;
+
+ if (g_engine->loadGameState(id + 1).getCode() == Common::kNoError)
+ status = RESTORE_SUCCESSFUL;
+ else
+ status = RESTORE_FAILED;
+
+ WRITE_LE_UINT32(&global[walker_timing], 0);
+
+ return status;
+}
+
+void global_menu_system_init() {
+}
+
+void global_menu_system_shutdown() {
+ if (menu_quotes != NULL)
+ mem_free(menu_quotes);
+}
+
+static char *menu_quote(int id) {
+ return quote_string(menu_quotes, id);
+}
+
+void global_emergency_save() {
+ game_save_name(0);
+
+ if (scr_orig.data != NULL) mem_free(scr_orig.data);
+
+ g_engine->saveAutosaveIfEnabled();
+}
+
+static void global_alert(int status) {
+}
+
+static void global_menu_score() {
+}
+
+static void global_menu_save_restore(int save) {
+#if 0
+ int status = -1;
+ int selection;
+ char *save_game_name;
+ PopupItem *save_list;
+ PopupItem *go_button;
+ PopupItem *clear_button;
+ PopupItem *cancel_button;
+ PopupItem *result;
+
+ popup_dialog_create(game_menu_popup, GAME_DIALOG_HEAP, 20);
+
+ if (save) {
+ popup_message(menu_quote(quote_save_title), POPUP_CENTER, POPUP_FILL);
+ } else {
+ popup_message(menu_quote(quote_restore_title), POPUP_CENTER, POPUP_FILL);
+ }
+ popup_blank(4);
+
+ save_list = popup_savelist(game_save_directory, menu_quote(quote_menu_empty),
+ GAME_MAX_SAVE_SLOTS,
+ GAME_MAX_SAVE_LENGTH + 1,
+ GAME_MAX_SAVE_LENGTH,
+ SAVE_MENU_PIXEL_WIDTH,
+ MAX_SAVES_ON_SCREEN,
+ save, game.last_save);
+
+ if (save) {
+ go_button = popup_button(menu_quote(quote_menu_save), POPUP_BUTTON_LEFT);
+ clear_button = popup_button(menu_quote(quote_menu_clear), POPUP_CENTER);
+ game_menu_popup->clear_item = clear_button;
+ } else {
+ go_button = popup_button(menu_quote(quote_menu_restore), POPUP_BUTTON_LEFT);
+ }
+ cancel_button = popup_cancel_button(menu_quote(quote_menu_cancel));
+
+ result = popup_execute();
+
+ if (result == cancel_button) {
+ switch (game_menu_popup->key) {
+ case alt_x_key:
+ case ctrl_x_key:
+ case alt_q_key:
+ case ctrl_q_key:
+ game.going = false;
+ kernel.activate_menu = GAME_NO_MENU;
+ break;
+
+ case f1_key:
+ kernel.activate_menu = GAME_MAIN_MENU;
+ break;
+
+ case f2_key:
+ if (save) {
+ kernel.activate_menu = GAME_MAIN_MENU;
+ } else {
+ kernel.activate_menu = GAME_SAVE_MENU;
+ }
+ break;
+
+ case f3_key:
+ if (!save) {
+ kernel.activate_menu = GAME_MAIN_MENU;
+ } else {
+ kernel.activate_menu = GAME_RESTORE_MENU;
+ }
+ break;
+
+ case f4_key:
+ kernel.activate_menu = GAME_SCORE_MENU;
+ break;
+
+ case f5_key:
+ kernel.activate_menu = GAME_OPTIONS_MENU;
+ break;
+
+ default:
+ kernel.activate_menu = GAME_MAIN_MENU;
+ break;
+ }
+ } else {
+ kernel.activate_menu = GAME_NO_MENU;
+ }
+
+ popup_dialog_destroy();
+
+ if (result == go_button) {
+ selection = save_list->list->picked_element;
+ game.last_save = selection;
+ if (save) {
+ save_game_name = game_save_directory + ((GAME_MAX_SAVE_LENGTH + 1) * selection);
+ if (!strlen(save_game_name)) {
+ Common::strcpy_s(save_game_name, GAME_MAX_SAVE_LENGTH, menu_quote(quote_menu_unnamed));
+ }
+ status = global_save(selection, save_game_name);
+
+ } else {
+ status = global_restore(selection);
+ }
+
+ if (status > 0)
+ // Dummy name to signal save/load went ok
+ Common::strcpy_s(save_game_buf, "OK");
+ }
+
+ if (status >= 0) {
+ global_alert(status);
+ }
+#endif
+}
+
+static void global_menu_options() {
+#if 0
+ int initial_1, initial_2, initial_3;
+ int initial_4, initial_5, initial_6;
+ int former_music;
+ int former_sound;
+ PopupItem *music_item;
+ PopupItem *sound_item;
+ PopupItem *interface_item;
+ PopupItem *fade_item;
+ PopupItem *panning_item;
+ PopupItem *speech_item;
+ PopupItem *done_button;
+ PopupItem *cancel_button;
+ PopupItem *result;
+
+ global_unload_config_parameters();
+
+ popup_dialog_create(game_menu_popup, GAME_DIALOG_HEAP, 20);
+
+ popup_sprite(box_param.logo, 1, POPUP_CENTER, POPUP_FILL);
+ popup_blank(2);
+
+ former_music = config_file.music_flag;
+ former_sound = config_file.sound_flag;
+
+ initial_1 = config_file.music_flag ? 0 : 1;
+ initial_2 = config_file.sound_flag ? 0 : 1;
+ initial_6 = config_file.speech_flag ? 0 : 1;
+ initial_3 = config_file.interface_hotspots;
+ initial_4 = config_file.screen_fade;
+ initial_5 = config_file.panning_speed;
+
+ music_item = popup_menu(menu_quote(quote_options_item1),
+ POPUP_CENTER, POPUP_FILL, OPTIONS_MENU_ITEM_WIDTH,
+ OPTIONS_MENU_OFF_CENTER,
+ 2, 40, initial_1);
+ popup_menu_option(music_item, menu_quote(quote_options_item1a));
+ popup_menu_option(music_item, menu_quote(quote_options_item1b));
+
+ popup_blank(SPACE_BETWEEN);
+
+
+ sound_item = popup_menu(menu_quote(quote_options_item2),
+ POPUP_CENTER, POPUP_FILL, OPTIONS_MENU_ITEM_WIDTH,
+ OPTIONS_MENU_OFF_CENTER,
+ 2, 40, initial_2);
+ popup_menu_option(sound_item, menu_quote(quote_options_item2a));
+ popup_menu_option(sound_item, menu_quote(quote_options_item2b));
+
+ popup_blank(SPACE_BETWEEN);
+
+
+ speech_item = popup_menu(menu_quote(quote_options_item6),
+ POPUP_CENTER, POPUP_FILL, OPTIONS_MENU_ITEM_WIDTH,
+ OPTIONS_MENU_OFF_CENTER,
+ 2, 40, initial_6);
+ popup_menu_option(speech_item, menu_quote(quote_options_item6a));
+ popup_menu_option(speech_item, menu_quote(quote_options_item6b));
+
+ popup_blank(SPACE_BETWEEN);
+
+
+ interface_item = popup_menu(menu_quote(quote_options_item3),
+ POPUP_CENTER, POPUP_FILL, OPTIONS_MENU_ITEM_WIDTH,
+ OPTIONS_MENU_OFF_CENTER,
+ 2, 40, initial_3);
+ popup_menu_option(interface_item, menu_quote(quote_options_item3a));
+ popup_menu_option(interface_item, menu_quote(quote_options_item3b));
+
+ popup_blank(SPACE_BETWEEN);
+
+
+ fade_item = popup_menu(menu_quote(quote_options_item4),
+ POPUP_CENTER, POPUP_FILL, OPTIONS_MENU_ITEM_WIDTH,
+ OPTIONS_MENU_OFF_CENTER,
+ 3, 40, initial_4);
+ popup_menu_option(fade_item, menu_quote(quote_options_item4a));
+ popup_menu_option(fade_item, menu_quote(quote_options_item4b));
+ popup_menu_option(fade_item, menu_quote(quote_options_item4c));
+
+ popup_blank(SPACE_BETWEEN);
+
+
+ panning_item = popup_menu(menu_quote(quote_options_item5),
+ POPUP_CENTER, POPUP_FILL, OPTIONS_MENU_ITEM_WIDTH,
+ OPTIONS_MENU_OFF_CENTER,
+ 3, 40, initial_5);
+ popup_menu_option(panning_item, menu_quote(quote_options_item5a));
+ popup_menu_option(panning_item, menu_quote(quote_options_item5b));
+ popup_menu_option(panning_item, menu_quote(quote_options_item5c));
+
+
+
+ done_button = popup_button(menu_quote(quote_menu_done), POPUP_LEFT);
+ cancel_button = popup_cancel_button(menu_quote(quote_menu_cancel));
+
+ popup_width_force(OPTIONS_MENU_FORCE_WIDTH);
+
+ result = popup_execute();
+
+ kernel.activate_menu = GAME_MAIN_MENU;
+
+ if (result == cancel_button) {
+ switch (game_menu_popup->key) {
+ case alt_x_key:
+ case ctrl_x_key:
+ case alt_q_key:
+ case ctrl_q_key:
+ game.going = false;
+ kernel.activate_menu = GAME_NO_MENU;
+ break;
+
+ case f1_key:
+ kernel.activate_menu = GAME_MAIN_MENU;
+ break;
+
+ case f2_key:
+ kernel.activate_menu = GAME_SAVE_MENU;
+ break;
+
+ case f3_key:
+ kernel.activate_menu = GAME_RESTORE_MENU;
+ break;
+
+ case f4_key:
+ kernel.activate_menu = GAME_SCORE_MENU;
+ break;
+
+ case f5_key:
+ kernel.activate_menu = GAME_MAIN_MENU;
+ break;
+
+ default:
+ kernel.activate_menu = GAME_MAIN_MENU;
+ break;
+ }
+ }
+
+ if (result == done_button) {
+ config_file.music_flag = !music_item->list->picked_element;
+ config_file.sound_flag = !sound_item->list->picked_element;
+ config_file.speech_flag = !speech_item->list->picked_element;
+ config_file.interface_hotspots = interface_item->list->picked_element;
+ config_file.screen_fade = fade_item->list->picked_element;
+ config_file.panning_speed = panning_item->list->picked_element;
+
+ global_write_config_file();
+ global_load_config_parameters();
+
+ kernel.activate_menu = GAME_NO_MENU;
+ }
+
+ if ((former_music != config_file.music_flag) ||
+ (former_sound != config_file.sound_flag)) {
+ game_exec_function(section_music_reset_pointer);
+ }
+
+ if (!config_file.speech_flag) {
+ if (speech_system_active)
+ speech_all_off();
+ }
+
+ popup_dialog_destroy();
+#endif
+}
+
+static void global_menu_difficulty() {
+#if 0
+ PopupItem *easy_item;
+ PopupItem *result;
+
+ popup_dialog_create(game_menu_popup, GAME_DIALOG_HEAP, 20);
+
+ popup_message(menu_quote(quote_difficulty_title), POPUP_CENTER, POPUP_FILL);
+ popup_blank(6);
+
+ easy_item = popup_menu(menu_quote(quote_difficulty_item1),
+ POPUP_CENTER, POPUP_FILL, MAIN_MENU_ITEM_WIDTH, 0,
+ 0, 0, 0);
+
+ popup_blank(SPACE_BETWEEN);
+
+ (void)popup_menu(menu_quote(quote_difficulty_item2),
+ POPUP_CENTER, POPUP_FILL, MAIN_MENU_ITEM_WIDTH, 0,
+ 0, 0, 0);
+
+
+ popup_width_force(DIFFICULTY_MENU_FORCE_WIDTH);
+
+ game_menu_popup->cancel_item = NULL;
+
+ result = popup_execute();
+
+ kernel.activate_menu = GAME_NO_MENU;
+
+ if (result == easy_item) {
+ game.difficulty = EASY_MODE;
+ } else {
+ game.difficulty = HARD_MODE;
+ }
+
+ if (result == NULL) {
+ game.going = false;
+ }
+
+ switch (game_menu_popup->key) {
+ case alt_x_key:
+ case ctrl_x_key:
+ case alt_q_key:
+ case ctrl_q_key:
+ case esc_key:
+ game.going = false;
+ break;
+ }
+
+ popup_dialog_destroy();
+#endif
+}
+
+static void global_menu_main() {
+#if 0
+ PopupItem *save_item;
+ PopupItem *restore_item;
+ PopupItem *score_item;
+ PopupItem *options_item;
+ PopupItem *resume_item;
+ PopupItem *quit_item;
+ PopupItem *result;
+
+ popup_dialog_create(game_menu_popup, GAME_DIALOG_HEAP, 20);
+
+ popup_sprite(box_param.logo, 1, POPUP_CENTER, POPUP_FILL);
+ popup_blank(6);
+
+ save_item = popup_menu(menu_quote(quote_main_item1),
+ POPUP_CENTER, POPUP_FILL, MAIN_MENU_ITEM_WIDTH, 0,
+ 0, 0, 0);
+
+ popup_blank(SPACE_BETWEEN);
+
+ restore_item = popup_menu(menu_quote(quote_main_item2),
+ POPUP_CENTER, POPUP_FILL, MAIN_MENU_ITEM_WIDTH, 0,
+ 0, 0, 0);
+
+ popup_blank(SPACE_BETWEEN);
+
+ score_item = popup_menu(menu_quote(quote_main_item6),
+ POPUP_CENTER, POPUP_FILL, MAIN_MENU_ITEM_WIDTH, 0,
+ 0, 0, 0);
+
+ popup_blank(SPACE_BETWEEN);
+
+ options_item = popup_menu(menu_quote(quote_main_item3),
+ POPUP_CENTER, POPUP_FILL, MAIN_MENU_ITEM_WIDTH, 0,
+ 0, 0, 0);
+
+ popup_blank(SPACE_BETWEEN);
+
+ resume_item = popup_menu(menu_quote(quote_main_item4),
+ POPUP_CENTER, POPUP_FILL, MAIN_MENU_ITEM_WIDTH, 0,
+ 0, 0, 0);
+
+ popup_blank(SPACE_BETWEEN);
+
+ quit_item = popup_menu(menu_quote(quote_main_item5),
+ POPUP_CENTER, POPUP_FILL, MAIN_MENU_ITEM_WIDTH, 0,
+ 0, 0, 0);
+
+ popup_width_force(MAIN_MENU_FORCE_WIDTH);
+ game_menu_popup->cancel_item = resume_item;
+
+ result = popup_execute();
+
+ if (result == save_item) {
+ kernel.activate_menu = GAME_SAVE_MENU;
+ } else if (result == restore_item) {
+ kernel.activate_menu = GAME_RESTORE_MENU;
+ } else if (result == options_item) {
+ kernel.activate_menu = GAME_OPTIONS_MENU;
+ } else if (result == score_item) {
+ kernel.activate_menu = GAME_SCORE_MENU;
+ } else {
+ kernel.activate_menu = GAME_NO_MENU;
+ }
+
+ if (result == quit_item)
+ game.going = false;
+
+ switch (game_menu_popup->key) {
+ case alt_q_key:
+ case alt_x_key:
+ case ctrl_q_key:
+ game.going = false;
+ kernel.activate_menu = GAME_NO_MENU;
+ break;
+
+ case f5_key:
+ kernel.activate_menu = GAME_SAVE_MENU;
+ break;
+
+ case f7_key:
+ kernel.activate_menu = GAME_RESTORE_MENU;
+ break;
+
+ case f8_key:
+ kernel.activate_menu = GAME_SCORE_MENU;
+ break;
+
+ case f10_key:
+ kernel.activate_menu = GAME_OPTIONS_MENU;
+ break;
+
+ default:
+ break;
+ }
+#endif
+}
+
+void global_game_menu() {
+ bool loaded = false;
+
+ if (box_param.series == NULL) {
+ Common::strcpy_s(box_param.name, "*BOX");
+ if (popup_box_load())
+ goto done;
+ loaded = true;
+ }
+
+ game_menu_setup();
+ g_engine->flushKeys();
+
+ do {
+ switch (kernel.activate_menu) {
+ case GAME_MAIN_MENU:
+ global_menu_main();
+ break;
+ case GAME_SAVE_MENU:
+ if (config_file.original_save_load) {
+ global_menu_save_restore(true);
+ } else {
+ kernel.activate_menu = GAME_NO_MENU;
+ g_engine->saveGameDialog();
+ }
+ break;
+ case GAME_RESTORE_MENU:
+ if (config_file.original_save_load) {
+ global_menu_save_restore(false);
+ } else {
+ kernel.activate_menu = GAME_NO_MENU;
+ if (g_engine->loadGameDialog())
+ // Dummy name to flag that load was successful
+ Common::strcpy_s(save_game_buf, "OK");
+ }
+ break;
+ case GAME_OPTIONS_MENU:
+ global_menu_options();
+ break;
+ case GAME_DIFFICULTY_MENU:
+ global_menu_difficulty();
+ break;
+ case GAME_SCORE_MENU:
+ global_menu_score();
+ break;
+ default:
+ kernel.activate_menu = GAME_NO_MENU;
+ break;
+ }
+ } while (!g_engine->shouldQuit() && game.going && kernel.activate_menu != GAME_NO_MENU);
+
+ game_menu_shutdown();
+
+ if (loaded) {
+ sprite_free(&box_param.menu, true);
+ sprite_free(&box_param.logo, true);
+ sprite_free(&box_param.series, true);
+ }
+
+done:
+ ;
+}
+
+} // namespace Dragonsphere
+} // namespace MADSV2
+} // namespace MADS
diff --git a/engines/mads/madsv2/dragonsphere/menus.h b/engines/mads/madsv2/dragonsphere/menus.h
new file mode 100644
index 00000000000..5876ffa2af8
--- /dev/null
+++ b/engines/mads/madsv2/dragonsphere/menus.h
@@ -0,0 +1,40 @@
+/* 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_DRAGONSPHERE_MENUS_H
+#define MADS_DRAGONSPHERE_MENUS_H
+
+#include "common/scummsys.h"
+
+namespace MADS {
+namespace MADSV2 {
+namespace Dragonsphere {
+
+extern void global_menu_system_init();
+extern void global_menu_system_shutdown();
+extern void global_emergency_save();
+extern void global_game_menu();
+
+} // namespace Dragonsphere
+} // namespace MADSV2
+} // namespace MADS
+
+#endif
diff --git a/engines/mads/madsv2/dragonsphere/sound_dragonsphere.cpp b/engines/mads/madsv2/dragonsphere/sound_dragonsphere.cpp
new file mode 100644
index 00000000000..5c449b0f56e
--- /dev/null
+++ b/engines/mads/madsv2/dragonsphere/sound_dragonsphere.cpp
@@ -0,0 +1,1573 @@
+/* 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 "common/endian.h"
+#include "common/file.h"
+#include "common/md5.h"
+#include "common/textconsole.h"
+#include "mads/madsv2/dragonsphere/sound_dragonsphere.h"
+
+namespace MADS {
+namespace MADSV2 {
+namespace Dragonsphere {
+
+void DragonSoundManager::validate() {
+ Common::File f;
+ static const char *const MD5[] = {
+ "cac84f53ccf18ca56f4c03352037790f",
+ "2dcdbe18ca5225384cdb97ceb7f5642a",
+ "c6001b0dfe32cb9399ab60742b631c2e",
+ "1596b657c6171e13714eaf114bf94641",
+ "ecbb8bdf1e2e36fcacedce79761e625b",
+ "29639869e5faed1378dd2cdc1d132889",
+ nullptr,
+ nullptr,
+ "379fcc9af2142f15a3e7166eee6dd49d"
+ };
+
+ for (int i = 1; i <= 9; ++i) {
+ if (i == 7 || i == 8)
+ continue;
+ Common::Path filename(Common::String::format("asound.dr%d", i));
+ if (!f.open(filename))
+ error("Could not process - %s", filename.toString().c_str());
+ Common::String md5str = Common::computeStreamMD5AsString(f, 8192);
+ f.close();
+
+ if (md5str != MD5[i - 1])
+ error("Invalid sound file - %s", filename.toString().c_str());
+ }
+}
+
+void DragonSoundManager::loadDriver(int sectionNumber) {
+ switch (sectionNumber) {
+ case 1:
+ _driver = new ASound1(_mixer, _opl);
+ break;
+ case 2:
+ _driver = new ASound2(_mixer, _opl);
+ break;
+ case 3:
+ _driver = new ASound3(_mixer, _opl);
+ break;
+ case 4:
+ _driver = new ASound4(_mixer, _opl);
+ break;
+ case 5:
+ _driver = new ASound5(_mixer, _opl);
+ break;
+ case 9:
+ _driver = new ASound9(_mixer, _opl);
+ break;
+ default:
+ _driver = nullptr;
+ return;
+ }
+}
+
+/*-----------------------------------------------------------------------*/
+/* ASound1 (asound.dr1) *
+ *-----------------------------------------------------------------------*/
+
+const ASound1::CommandPtr ASound1::_commandList[40] = {
+ &ASound1::command0, &ASound1::command1, &ASound1::command2, &ASound1::command3,
+ &ASound1::command4, &ASound1::command5, &ASound1::command6, &ASound1::command7,
+ &ASound1::command8, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ &ASound1::command16, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ &ASound1::command24, &ASound1::command25, &ASound1::command26, &ASound1::command27,
+ nullptr, nullptr, nullptr, nullptr,
+ &ASound1::command32, &ASound1::command33, &ASound1::command34, &ASound1::command35,
+ &ASound1::command36, &ASound1::command37, &ASound1::command38, &ASound1::command39
+};
+
+ASound1::ASound1(Audio::Mixer *mixer, OPL::OPL *opl)
+ : ASound(mixer, opl, "asound.dr1", 0x21e0, 0x4d20) {
+ // Load sound samples
+ auto samplesStream = getDataStream(0x1d4);
+ for (int i = 0; i < 120; ++i)
+ _samples.push_back(AdlibSample(samplesStream));
+}
+
+int ASound1::command(int commandId, int param) {
+ if (commandId > 39 || !_commandList[commandId])
+ return 0;
+
+ return (this->*_commandList[commandId])();
+}
+
+// commands 0-8: delegate to base ASound
+int ASound1::command0() { return ASound::command0(); }
+int ASound1::command1() { return ASound::command1(); }
+int ASound1::command2() { return ASound::command2(); }
+int ASound1::command3() { return ASound::command3(); }
+int ASound1::command4() { return ASound::command4(); }
+int ASound1::command5() { return ASound::command5(); }
+int ASound1::command6() { return ASound::command6(); }
+int ASound1::command7() { return ASound::command7(); }
+int ASound1::command8() { return ASound::command8(); }
+
+int ASound1::commandMusic0() {
+ ASound::command1();
+ _channels[0]->load(loadData(0x1ECA));
+ _channels[1]->load(loadData(0x1FBF));
+ _channels[2]->load(loadData(0x2037));
+ _channels[3]->load(loadData(0x20EE));
+ _channels[4]->load(loadData(0x219B));
+ _channels[5]->load(loadData(0x21AF));
+ return 0;
+}
+
+int ASound1::commandMusic1() {
+ ASound::command1();
+ _channels[0]->load(loadData(0x3418));
+ _channels[1]->load(loadData(0x34EB));
+ _channels[2]->load(loadData(0x359B));
+ _channels[3]->load(loadData(0x3658));
+ _channels[4]->load(loadData(0x3667));
+ _channels[5]->load(loadData(0x3677));
+ return 0;
+}
+
+int ASound1::commandMusic2() {
+ ASound::command1();
+ _channels[0]->load(loadData(0x3688));
+ _channels[1]->load(loadData(0x387B));
+ _channels[2]->load(loadData(0x3A01));
+ _channels[3]->load(loadData(0x3BC6));
+ _channels[4]->load(loadData(0x3D31));
+ _channels[5]->load(loadData(0x3D41));
+ return 0;
+}
+
+int ASound1::commandMusic3() {
+ ASound::command1();
+ _channels[0]->load(loadData(0x3D52));
+ _channels[1]->load(loadData(0x3FD3));
+ _channels[2]->load(loadData(0x41FF));
+ _channels[3]->load(loadData(0x420C));
+ _channels[4]->load(loadData(0x4219));
+ _channels[5]->load(loadData(0x4229));
+ return 0;
+}
+
+// ---------------------------------------------------------------------------
+// command16 - random background music
+//
+// If channel 0 is active and already playing one of the five known music
+// pieces (identified by their starting offset in field_17), leave it alone.
+// Otherwise pick a piece at random: the original uses getRandomNumber() & 7,
+// discarding 0 and indexing a four-entry table repeated twice (entries 1-3
+// -> pieces 1-3, entries 4-7 -> same pieces again with entry 4 wrapping to
+// piece 0). We reproduce this with a modulo-4 on a non-zero value.
+// ---------------------------------------------------------------------------
+int ASound1::command16() {
+ if (_channels[0]->_activeCount) {
+ // Special offset checks
+ int f = _channels[0]->_loopStartPtr - &_soundData[0];
+
+ if (f == 0 || f == 0x1ECA || f == 0x21C4 ||
+ f == 0x3418 || f == 0x3688 || f == 0x3D52)
+ return 0;
+ }
+
+ int idx;
+ do {
+ idx = getRandomNumber() & 3;
+ } while (idx == 0);
+ _musicIndex = idx;
+
+ typedef int (ASound1::*MusicPtr)();
+ static const MusicPtr musicTable[4] = {
+ &ASound1::commandMusic0,
+ &ASound1::commandMusic1,
+ &ASound1::commandMusic2,
+ &ASound1::commandMusic3
+ };
+ return (this->*musicTable[idx])();
+}
+
+// ---------------------------------------------------------------------------
+// commands 24-27 - upper channel pool
+// ---------------------------------------------------------------------------
+
+int ASound1::command24() {
+ playSound(0x173A);
+ playSound(0x176D);
+ return 0;
+}
+
+int ASound1::command25() {
+ playSound(0x179B);
+ playSound(0x17C7);
+ return 0;
+}
+
+int ASound1::command26() {
+ playSound(0x17F5);
+ return 0;
+}
+
+int ASound1::command27() {
+ playSound(0x1801);
+ return 0;
+}
+
+// ---------------------------------------------------------------------------
+// commands 32-39
+// ---------------------------------------------------------------------------
+
+// command32 - no guard, no fade, load ch0-5
+int ASound1::command32() {
+ _channels[0]->load(loadData(0x2522));
+ _channels[1]->load(loadData(0x255D));
+ _channels[2]->load(loadData(0x2591));
+ _channels[3]->load(loadData(0x25BB));
+ _channels[4]->load(loadData(0x25E7));
+ _channels[5]->load(loadData(0x2613));
+ return 0;
+}
+
+// command33 - isSoundActive guard, command1, load ch0-5
+int ASound1::command33() {
+ byte *pData = loadData(0x266C);
+ if (!isSoundActive(pData)) {
+ ASound::command1();
+ _channels[0]->load(pData);
+ _channels[1]->load(loadData(0x2929));
+ _channels[2]->load(loadData(0x2B1D));
+ _channels[3]->load(loadData(0x2D37));
+ _channels[4]->load(loadData(0x2EC3));
+ _channels[5]->load(loadData(0x3033));
+ }
+ return 0;
+}
+
+// command34 - isSoundActive guard, stop(), load ch0-5
+int ASound1::command34() {
+ byte *pData = loadData(0x1852);
+ if (!isSoundActive(pData)) {
+ stop();
+ _channels[0]->load(pData);
+ _channels[1]->load(loadData(0x1AA9));
+ _channels[2]->load(loadData(0x1BC4));
+ _channels[3]->load(loadData(0x1CF1));
+ _channels[4]->load(loadData(0x1DF2));
+ _channels[5]->load(loadData(0x1EBE));
+ }
+ return 0;
+}
+
+// command35 - isSoundActive guard, command2 (lower-bank fade),
+// load ch0-5
+int ASound1::command35() {
+ byte *pData = loadData(0x0C36);
+ if (!isSoundActive(pData)) {
+ ASound::command2();
+ _channels[0]->load(pData);
+ _channels[1]->load(loadData(0x0D7F));
+ _channels[2]->load(loadData(0x0E48));
+ _channels[3]->load(loadData(0x0F10));
+ _channels[4]->load(loadData(0x0FB2));
+ _channels[5]->load(loadData(0x1096));
+ }
+ return 0;
+}
+
+// command36 - isSoundActive guard, command2 (lower-bank fade),
+// load ch0-5
+int ASound1::command36() {
+ byte *pData = loadData(0x1190);
+ if (!isSoundActive(pData)) {
+ ASound::command2();
+ _channels[0]->load(pData);
+ _channels[1]->load(loadData(0x12D7));
+ _channels[2]->load(loadData(0x13AA));
+ _channels[3]->load(loadData(0x1476));
+ _channels[4]->load(loadData(0x1528));
+ _channels[5]->load(loadData(0x1614));
+ }
+ return 0;
+}
+
+// command37 - isSoundActive guard, command1, four loadAny
+// calls starting from channel 0
+int ASound1::command37() {
+ byte *pData = loadData(0x3220);
+ if (!isSoundActive(pData)) {
+ ASound::command1();
+ findFreeChannel(pData);
+ findFreeChannel(loadData(0x326A));
+ findFreeChannel(loadData(0x3293));
+ findFreeChannel(loadData(0x32AC));
+ }
+ return 0;
+}
+
+// command38 - alias for commandMusic0; also the direct dispatch
+// target for command 38.
+int ASound1::command38() {
+ return commandMusic0();
+}
+
+// command39 - isSoundActive guard, command1, load ch0-5
+int ASound1::command39() {
+ byte *pData = loadData(0x423A);
+ if (!isSoundActive(pData)) {
+ ASound::command1();
+ _channels[0]->load(pData);
+ _channels[1]->load(loadData(0x43DF));
+ _channels[2]->load(loadData(0x44F7));
+ _channels[3]->load(loadData(0x45ED));
+ _channels[4]->load(loadData(0x46F9));
+ _channels[5]->load(loadData(0x48AF));
+ }
+ return 0;
+}
+
+/*-----------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------*/
+/* ASound2 (asound.dr2) *
+ *-----------------------------------------------------------------------*/
+
+const ASound2::CommandPtr ASound2::_commandList[73] = {
+ // commands 0-8 (asound_commands1)
+ &ASound2::command0, &ASound2::command1, &ASound2::command2, &ASound2::command3,
+ &ASound2::command4, &ASound2::command5, &ASound2::command6, &ASound2::command7,
+ &ASound2::command8,
+ // 9-15 absent
+ nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ // command 16 (asound_commands2)
+ &ASound2::command16,
+ // 17-23 absent
+ nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ // commands 24-27 (asound_commands3)
+ &ASound2::command24, &ASound2::command25, &ASound2::command26, &ASound2::command27,
+ // 28-31 absent
+ nullptr, nullptr, nullptr, nullptr,
+ // commands 32-35 (asound_commands4)
+ &ASound2::command32, &ASound2::command33, &ASound2::command34, &ASound2::command35,
+ // 36-63 absent
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ // commands 64-72 (asound_commands5)
+ &ASound2::command64, &ASound2::command65, &ASound2::command66, &ASound2::command67,
+ &ASound2::command68, &ASound2::command69, &ASound2::command70, &ASound2::command71,
+ &ASound2::command72
+};
+
+ASound2::ASound2(Audio::Mixer *mixer, OPL::OPL *opl)
+ : ASound(mixer, opl, "asound.dr2", 0x2040, 0x2300) {
+ // Load sound samples
+ auto samplesStream = getDataStream(0x1d4);
+ for (int i = 0; i < 120; ++i)
+ _samples.push_back(AdlibSample(samplesStream));
+}
+
+int ASound2::command(int commandId, int param) {
+ if (commandId > 72 || !_commandList[commandId])
+ return 0;
+
+ return (this->*_commandList[commandId])();
+}
+
+// commands 0-8: delegate to base ASound
+int ASound2::command0() { return ASound::command0(); }
+int ASound2::command1() { return ASound::command1(); }
+int ASound2::command2() { return ASound::command2(); }
+int ASound2::command3() { return ASound::command3(); }
+int ASound2::command4() { return ASound::command4(); }
+int ASound2::command5() { return ASound::command5(); }
+int ASound2::command6() { return ASound::command6(); }
+int ASound2::command7() { return ASound::command7(); }
+int ASound2::command8() { return ASound::command8(); }
+
+// ---------------------------------------------------------------------------
+// command16 - isSoundActive guard, command1, load ch0-5
+// ---------------------------------------------------------------------------
+int ASound2::command16() {
+ byte *pData = loadData(0x0C36);
+ if (!isSoundActive(pData)) {
+ ASound::command1();
+ _channels[0]->load(pData);
+ _channels[1]->load(loadData(0x0C8E));
+ _channels[2]->load(loadData(0x0CF4));
+ _channels[3]->load(loadData(0x0D4E));
+ _channels[4]->load(loadData(0x0DA3));
+ _channels[5]->load(loadData(0x0DB1));
+ }
+ return 0;
+}
+
+// ---------------------------------------------------------------------------
+// commands 24-27 (asound_commands3) - upper channel pool
+// ---------------------------------------------------------------------------
+
+int ASound2::command24() {
+ playSound(0x1A4A);
+ playSound(0x1A7D);
+ return 0;
+}
+
+int ASound2::command25() {
+ playSound(0x1AAB);
+ playSound(0x1AD7);
+ return 0;
+}
+
+int ASound2::command26() {
+ playSound(0x1B05);
+ return 0;
+}
+
+int ASound2::command27() {
+ playSound(0x1B11);
+ return 0;
+}
+
+// ---------------------------------------------------------------------------
+// commands 32-35 (asound_commands4)
+// ---------------------------------------------------------------------------
+
+// command32 - command1, six loadAny calls from channel 0
+int ASound2::command32() {
+ ASound::command1();
+ findFreeChannel(loadData(0x1BE4));
+ findFreeChannel(loadData(0x1CB7));
+ findFreeChannel(loadData(0x1E1E));
+ findFreeChannel(loadData(0x1EC8));
+ findFreeChannel(loadData(0x1ED8));
+ findFreeChannel(loadData(0x1EEF));
+ return 0;
+}
+
+// command33 - isSoundActive guard, command1, load ch0-7
+int ASound2::command33() {
+ byte *pData = loadData(0x1B62);
+ if (!isSoundActive(pData)) {
+ ASound::command1();
+ _channels[0]->load(pData);
+ _channels[1]->load(loadData(0x1B97));
+ _channels[2]->load(loadData(0x1BA5));
+ _channels[3]->load(loadData(0x1BB3));
+ _channels[4]->load(loadData(0x1BC1));
+ _channels[5]->load(loadData(0x1BC5));
+ _channels[6]->load(loadData(0x1BC9));
+ _channels[7]->load(loadData(0x1BD5));
+ }
+ return 0;
+}
+
+// command34 - isSoundActive guard, command1, load ch0-6
+int ASound2::command34() {
+ byte *pData = loadData(0x0DC0);
+ if (!isSoundActive(pData)) {
+ ASound::command1();
+ _channels[0]->load(pData);
+ _channels[1]->load(loadData(0x0FAF));
+ _channels[2]->load(loadData(0x1206));
+ _channels[3]->load(loadData(0x139A));
+ _channels[4]->load(loadData(0x1565));
+ _channels[5]->load(loadData(0x1833));
+ _channels[6]->load(loadData(0x18CD));
+ }
+ return 0;
+}
+
+// command35 - isSoundActive guard, command1, load ch0-6
+int ASound2::command35() {
+ byte *pData = loadData(0x1F02);
+ if (!isSoundActive(pData)) {
+ ASound::command1();
+ _channels[0]->load(pData);
+ _channels[1]->load(loadData(0x1F66));
+ _channels[2]->load(loadData(0x1F70));
+ _channels[3]->load(loadData(0x1F8D));
+ _channels[4]->load(loadData(0x1FCE));
+ _channels[5]->load(loadData(0x1FF7));
+ _channels[6]->load(loadData(0x202E));
+ }
+ return 0;
+}
+
+// ---------------------------------------------------------------------------
+// commands 64-72 (asound_commands5) - upper channel pool
+// ---------------------------------------------------------------------------
+
+int ASound2::command64() {
+ playSound(0x1928);
+ return 0;
+}
+
+int ASound2::command65() {
+ playSound(0x193C);
+ return 0;
+}
+
+int ASound2::command66() {
+ playSound(0x1946);
+ playSound(0x195C);
+ return 0;
+}
+
+int ASound2::command67() {
+ playSound(0x196D);
+ return 0;
+}
+
+// no-op
+int ASound2::command68() {
+ return 0;
+}
+
+int ASound2::command69() {
+ playSound(0x197F);
+ playSound(0x19A5);
+ playSound(0x19CB);
+ return 0;
+}
+
+int ASound2::command70() {
+ playSound(0x19E5);
+ playSound(0x19F1);
+ return 0;
+}
+
+int ASound2::command71() {
+ playSound(0x19FF);
+ return 0;
+}
+
+int ASound2::command72() {
+ playSound(0x1A0D);
+ playSound(0x1A10);
+ return 0;
+}
+
+/*-----------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------*/
+/* ASound3 (asound.dr3) *
+ *-----------------------------------------------------------------------*/
+
+const ASound3::CommandPtr ASound3::_commandList[77] = {
+ // commands 0-8 (asound_commands1)
+ &ASound3::command0, &ASound3::command1, &ASound3::command2, &ASound3::command3,
+ &ASound3::command4, &ASound3::command5, &ASound3::command6, &ASound3::command7,
+ &ASound3::command8,
+ // 9-15 absent
+ nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ // command 16 (asound_commands2)
+ &ASound3::command16,
+ // 17-23 absent
+ nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ // commands 24-27 (asound_commands3)
+ &ASound3::command24, &ASound3::command25, &ASound3::command26, &ASound3::command27,
+ // 28-31 absent
+ nullptr, nullptr, nullptr, nullptr,
+ // commands 32-37 (asound_commands4)
+ &ASound3::command32, &ASound3::command33, &ASound3::command34, &ASound3::command35,
+ &ASound3::command36, &ASound3::command37,
+ // 38-63 absent
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr,
+ // commands 64-75 (asound_commands5)
+ &ASound3::command64, &ASound3::command65, &ASound3::command66, &ASound3::command67,
+ &ASound3::command68, &ASound3::command69, &ASound3::command70, &ASound3::command71,
+ &ASound3::command72, &ASound3::command73, &ASound3::command74, &ASound3::command75,
+ // command 76 = nullsub_8
+ nullptr
+};
+
+ASound3::ASound3(Audio::Mixer *mixer, OPL::OPL *opl)
+ : ASound(mixer, opl, "asound.dr3", 0x20c0, 0x31a0) {
+ // Load sound samples
+ auto samplesStream = getDataStream(0x1d4);
+ for (int i = 0; i < 120; ++i)
+ _samples.push_back(AdlibSample(samplesStream));
+}
+
+int ASound3::command(int commandId, int param) {
+ if (commandId > 76 || !_commandList[commandId])
+ return 0;
+
+ return (this->*_commandList[commandId])();
+}
+
+// commands 0-8: delegate to base ASound
+int ASound3::command0() { return ASound::command0(); }
+int ASound3::command1() { return ASound::command1(); }
+int ASound3::command2() { return ASound::command2(); }
+int ASound3::command3() { return ASound::command3(); }
+int ASound3::command4() { return ASound::command4(); }
+int ASound3::command5() { return ASound::command5(); }
+int ASound3::command6() { return ASound::command6(); }
+int ASound3::command7() { return ASound::command7(); }
+int ASound3::command8() { return ASound::command8(); }
+
+// ---------------------------------------------------------------------------
+// sub_11CC6 - shared helper used by command34.
+// isSoundActive guard on 0xC36; if not active: command1, load ch0-7.
+// (The tiny ch6 and ch7 blocks - 4 bytes each - are very short sub-blocks
+// within the same composite sound.)
+// ---------------------------------------------------------------------------
+void ASound3::sub11CC6() {
+ byte *pData = loadData(0x0C36);
+ if (!isSoundActive(pData)) {
+ ASound::command1();
+ _channels[0]->load(pData);
+ _channels[1]->load(loadData(0x0C6B));
+ _channels[2]->load(loadData(0x0C79));
+ _channels[3]->load(loadData(0x0C87));
+ _channels[4]->load(loadData(0x0C95));
+ _channels[5]->load(loadData(0x0C99));
+ _channels[6]->load(loadData(0x0C9D));
+ _channels[7]->load(loadData(0x0CA9));
+ }
+}
+
+// ---------------------------------------------------------------------------
+// command16 - isSoundActive guard, command1, load ch0-5
+// ---------------------------------------------------------------------------
+int ASound3::command16() {
+ byte *pData = loadData(0x24F2);
+ if (!isSoundActive(pData)) {
+ ASound::command1();
+ _channels[0]->load(pData);
+ _channels[1]->load(loadData(0x259E));
+ _channels[2]->load(loadData(0x2627));
+ _channels[3]->load(loadData(0x26AE));
+ _channels[4]->load(loadData(0x2761));
+ _channels[5]->load(loadData(0x2810));
+ }
+ return 0;
+}
+
+// ---------------------------------------------------------------------------
+// commands 24-27 (asound_commands3) - upper channel pool
+// ---------------------------------------------------------------------------
+
+int ASound3::command24() {
+ playSound(0x2A7C);
+ playSound(0x2AAF);
+ return 0;
+}
+
+int ASound3::command25() {
+ playSound(0x2ADD);
+ playSound(0x2B09);
+ return 0;
+}
+
+int ASound3::command26() {
+ playSound(0x2B37);
+ return 0;
+}
+
+int ASound3::command27() {
+ playSound(0x2B43);
+ return 0;
+}
+
+// ---------------------------------------------------------------------------
+// commands 32-37 (asound_commands4)
+// ---------------------------------------------------------------------------
+
+// command32 - isSoundActive guard, command1, load ch0-7
+int ASound3::command32() {
+ byte *pData = loadData(0x2B94);
+ if (!isSoundActive(pData)) {
+ ASound::command1();
+ _channels[0]->load(pData);
+ _channels[1]->load(loadData(0x2C00));
+ _channels[2]->load(loadData(0x2C49));
+ _channels[3]->load(loadData(0x2C8C));
+ _channels[4]->load(loadData(0x2D23));
+ _channels[5]->load(loadData(0x2DCE));
+ _channels[6]->load(loadData(0x2E25));
+ _channels[7]->load(loadData(0x2E84));
+ }
+ return 0;
+}
+
+// command33 - isSoundActive guard, command1, load ch0-6
+int ASound3::command33() {
+ byte *pData = loadData(0x149E);
+ if (!isSoundActive(pData)) {
+ ASound::command1();
+ _channels[0]->load(pData);
+ _channels[1]->load(loadData(0x16AB));
+ _channels[2]->load(loadData(0x1933));
+ _channels[3]->load(loadData(0x1A2F));
+ _channels[4]->load(loadData(0x1C25));
+ _channels[5]->load(loadData(0x1ECD));
+ _channels[6]->load(loadData(0x206F));
+ }
+ return 0;
+}
+
+// command34 - calls sub11CC6 (loads ch0-7 if not active),
+// then unconditionally loads ch8 at 0x298E
+int ASound3::command34() {
+ sub11CC6();
+ _channels[8]->load(loadData(0x298E));
+ return 0;
+}
+
+// command35 - isSoundActive guard, command1, load ch0-5
+int ASound3::command35() {
+ byte *pData = loadData(0x0CB8);
+ if (!isSoundActive(pData)) {
+ ASound::command1();
+ _channels[0]->load(pData);
+ _channels[1]->load(loadData(0x0E55));
+ _channels[2]->load(loadData(0x0F63));
+ _channels[3]->load(loadData(0x1051));
+ _channels[4]->load(loadData(0x1159));
+ _channels[5]->load(loadData(0x130B));
+ }
+ return 0;
+}
+
+// command36 - isSoundActive guard, command1, load ch0-5
+int ASound3::command36() {
+ byte *pData = loadData(0x2072);
+ if (!isSoundActive(pData)) {
+ ASound::command1();
+ _channels[0]->load(pData);
+ _channels[1]->load(loadData(0x2136));
+ _channels[2]->load(loadData(0x23EA));
+ _channels[3]->load(loadData(0x243D));
+ _channels[4]->load(loadData(0x2455));
+ _channels[5]->load(loadData(0x24A3));
+ }
+ return 0;
+}
+
+// command37 - single upper-pool voice
+int ASound3::command37() {
+ playSound(0x298E);
+ return 0;
+}
+
+// ---------------------------------------------------------------------------
+// commands 64-75 (asound_commands5)
+// ---------------------------------------------------------------------------
+
+int ASound3::command64() {
+ _channels[6]->load(loadData(0x28CA));
+ _channels[8]->load(loadData(0x28FC));
+ return 0;
+}
+
+int ASound3::command65() {
+ _channels[6]->load(loadData(0x2919));
+ _channels[8]->load(loadData(0x292A));
+ return 0;
+}
+
+int ASound3::command66() {
+ _channels[6]->load(loadData(0x2937));
+ _channels[7]->load(loadData(0x2956));
+ _channels[8]->load(loadData(0x2965));
+ return 0;
+}
+
+int ASound3::command67() {
+ playSound(0x2984);
+ return 0;
+}
+
+int ASound3::command68() {
+ playSound(0x2998);
+ playSound(0x29AE);
+ playSound(0x29C2);
+ return 0;
+}
+
+int ASound3::command69() {
+ playSound(0x29D8);
+ return 0;
+}
+
+int ASound3::command70() {
+ playSound(0x2B4F);
+ return 0;
+}
+
+int ASound3::command71() {
+ playSound(0x2B5E);
+ return 0;
+}
+
+int ASound3::command72() {
+ _channels[7]->load(loadData(0x29EA));
+ _channels[8]->load(loadData(0x2A18));
+ return 0;
+}
+
+int ASound3::command73() {
+ playSound(0x2A44);
+ return 0;
+}
+
+int ASound3::command74() {
+ playSound(0x2A4E);
+ return 0;
+}
+
+int ASound3::command75() {
+ _channels[7]->load(loadData(0x29FB));
+ _channels[8]->load(loadData(0x2A29));
+ return 0;
+}
+
+/*-----------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------*/
+/* ASound4 (asound.dr4) *
+ *-----------------------------------------------------------------------*/
+
+const ASound4::CommandPtr ASound4::_commandList[71] = {
+ // commands 0-8 (asound_commands1)
+ &ASound4::command0, &ASound4::command1, &ASound4::command2, &ASound4::command3,
+ &ASound4::command4, &ASound4::command5, &ASound4::command6, &ASound4::command7,
+ &ASound4::command8,
+ // 9-15 absent
+ nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ // command 16 (asound_commands2)
+ &ASound4::command16,
+ // 17-23 absent
+ nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ // commands 24-27 (asound_commands3)
+ &ASound4::command24, &ASound4::command25, &ASound4::command26, &ASound4::command27,
+ // 28-63 absent (the 0x20-range table has max=0, unreachable)
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ // commands 64-70 (asound_commands4)
+ &ASound4::command64, &ASound4::command65, &ASound4::command66, &ASound4::command67,
+ &ASound4::command68, &ASound4::command69, &ASound4::command70
+};
+
+ASound4::ASound4(Audio::Mixer *mixer, OPL::OPL *opl)
+ : ASound(mixer, opl, "asound.dr4", 0x1f90, 0x14d0) {
+ // Load sound samples
+ auto samplesStream = getDataStream(0x1d4);
+ for (int i = 0; i < 120; ++i)
+ _samples.push_back(AdlibSample(samplesStream));
+}
+
+int ASound4::command(int commandId, int param) {
+ if (commandId > 70 || !_commandList[commandId])
+ return 0;
+
+ return (this->*_commandList[commandId])();
+}
+
+// commands 0-8: delegate to base ASound
+int ASound4::command0() { return ASound::command0(); }
+int ASound4::command1() { return ASound::command1(); }
+int ASound4::command2() { return ASound::command2(); }
+int ASound4::command3() { return ASound::command3(); }
+int ASound4::command4() { return ASound::command4(); }
+int ASound4::command5() { return ASound::command5(); }
+int ASound4::command6() { return ASound::command6(); }
+int ASound4::command7() { return ASound::command7(); }
+int ASound4::command8() { return ASound::command8(); }
+
+// ---------------------------------------------------------------------------
+// command16 - isSoundActive guard, command1, load ch0-6
+// ---------------------------------------------------------------------------
+int ASound4::command16() {
+ byte *pData = loadData(0x0C36);
+ if (!isSoundActive(pData)) {
+ ASound::command1();
+ _channels[0]->load(pData);
+ _channels[1]->load(loadData(0x0C75));
+ _channels[2]->load(loadData(0x0EF1));
+ _channels[3]->load(loadData(0x0F19));
+ _channels[4]->load(loadData(0x0F41));
+ _channels[5]->load(loadData(0x0F67));
+ _channels[6]->load(loadData(0x0F90));
+ }
+ return 0;
+}
+
+// ---------------------------------------------------------------------------
+// commands 24-27 (asound_commands3) - upper pool
+//
+// commands 24 and 25 are both wired to the same handler,
+// which loads two upper-pool sounds.
+// ---------------------------------------------------------------------------
+
+int ASound4::command24() {
+ playSound(0x0FFA);
+ playSound(0x100C);
+ return 0;
+}
+
+int ASound4::command25() {
+ return command24();
+}
+
+int ASound4::command26() {
+ playSound(0x119D);
+ return 0;
+}
+
+int ASound4::command27() {
+ playSound(0x11A9);
+ return 0;
+}
+
+// ---------------------------------------------------------------------------
+// commands 64-70 (asound_commands4, base 0x40)
+// All entries use the upper pool
+// ---------------------------------------------------------------------------
+
+int ASound4::command64() {
+ playSound(0x1017);
+ playSound(0x1031);
+ return 0;
+}
+
+int ASound4::command65() {
+ playSound(0x1042);
+ playSound(0x104B);
+ return 0;
+}
+
+int ASound4::command66() {
+ playSound(0x105F);
+ playSound(0x1068);
+ return 0;
+}
+
+int ASound4::command67() {
+ playSound(0x1078);
+ playSound(0x1081);
+ return 0;
+}
+
+int ASound4::command68() {
+ playSound(0x108F);
+ return 0;
+}
+
+int ASound4::command69() {
+ playSound(0x109B);
+ return 0;
+}
+
+int ASound4::command70() {
+ playSound(0x10A5);
+ playSound(0x10A8);
+ return 0;
+}
+
+/*-----------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------*/
+/* ASound5 (asound.dr5) *
+ *-----------------------------------------------------------------------*/
+
+const ASound5::CommandPtr ASound5::_commandList[79] = {
+ // commands 0-8 (asound_commands1)
+ &ASound5::command0, &ASound5::command1, &ASound5::command2, &ASound5::command3,
+ &ASound5::command4, &ASound5::command5, &ASound5::command6, &ASound5::command7,
+ &ASound5::command8,
+ // 9-15 absent
+ nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ // command 16 (asound_commands2)
+ &ASound5::command16,
+ // 17-23 absent
+ nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ // commands 24-27 (asound_commands3)
+ &ASound5::command24, &ASound5::command25, &ASound5::command26, &ASound5::command27,
+ // 28-31 absent
+ nullptr, nullptr, nullptr, nullptr,
+ // commands 32-39 (asound_commands4)
+ &ASound5::command32, &ASound5::command33, &ASound5::command34, &ASound5::command35,
+ &ASound5::command36, &ASound5::command37, &ASound5::command38, &ASound5::command39,
+ // 40-63 absent
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ // commands 64-78 (asound_commands5)
+ &ASound5::command64, &ASound5::command65, &ASound5::command66, &ASound5::command67,
+ &ASound5::command68, &ASound5::command69, &ASound5::command70, &ASound5::command71,
+ &ASound5::command72, &ASound5::command73, &ASound5::command74, &ASound5::command75,
+ &ASound5::command76, &ASound5::command77, &ASound5::command78
+};
+
+ASound5::ASound5(Audio::Mixer *mixer, OPL::OPL *opl)
+ : ASound(mixer, opl, "asound.dr5", 0x2140, 0x5cd0) {
+ // Load sound samples
+ auto samplesStream = getDataStream(0x1d4);
+ for (int i = 0; i < 120; ++i)
+ _samples.push_back(AdlibSample(samplesStream));
+}
+
+int ASound5::command(int commandId, int param) {
+ if (commandId > 78 || !_commandList[commandId])
+ return 0;
+
+ return (this->*_commandList[commandId])();
+}
+
+// commands 0-8: delegate to base ASound
+int ASound5::command0() { return ASound::command0(); }
+int ASound5::command1() { return ASound::command1(); }
+int ASound5::command2() { return ASound::command2(); }
+int ASound5::command3() { return ASound::command3(); }
+int ASound5::command4() { return ASound::command4(); }
+int ASound5::command5() { return ASound::command5(); }
+int ASound5::command6() { return ASound::command6(); }
+int ASound5::command7() { return ASound::command7(); }
+int ASound5::command8() { return ASound::command8(); }
+
+// ---------------------------------------------------------------------------
+// command16 - isSoundActive guard, command1, load ch0-5
+// ---------------------------------------------------------------------------
+int ASound5::command16() {
+ byte *pData = loadData(0x4142);
+ if (!isSoundActive(pData)) {
+ ASound::command1();
+ _channels[0]->load(pData);
+ _channels[1]->load(loadData(0x41BA));
+ _channels[2]->load(loadData(0x424C));
+ _channels[3]->load(loadData(0x42D1));
+ _channels[4]->load(loadData(0x4316));
+ _channels[5]->load(loadData(0x43AE));
+ }
+ return 0;
+}
+
+// ---------------------------------------------------------------------------
+// commands 24-27 (asound_commands3) - upper pool
+// ---------------------------------------------------------------------------
+
+int ASound5::command24() {
+ playSound(0x51FA);
+ playSound(0x522D);
+ return 0;
+}
+
+int ASound5::command25() {
+ playSound(0x525B);
+ playSound(0x5287);
+ return 0;
+}
+
+int ASound5::command26() {
+ playSound(0x52B5);
+ return 0;
+}
+
+// three upper-pool voices
+int ASound5::command27() {
+ playSound(0x4040);
+ playSound(0x404A);
+ playSound(0x4061);
+ return 0;
+}
+
+// ---------------------------------------------------------------------------
+// commands 32-39 (asound_commands4)
+// ---------------------------------------------------------------------------
+
+// command1, eight loadAny (lower pool, AdlibChannel_loadAny)
+int ASound5::command32() {
+ ASound::command1();
+ findFreeChannel(loadData(0x43BC));
+ findFreeChannel(loadData(0x466D));
+ findFreeChannel(loadData(0x4773));
+ findFreeChannel(loadData(0x4953));
+ findFreeChannel(loadData(0x4B4B));
+ findFreeChannel(loadData(0x4D93));
+ findFreeChannel(loadData(0x4EC7));
+ findFreeChannel(loadData(0x5071));
+ return 0;
+}
+
+// isSoundActive guard, command1, load ch0-6
+int ASound5::command33() {
+ byte *pData = loadData(0x21C6);
+ if (!isSoundActive(pData)) {
+ ASound::command1();
+ _channels[0]->load(pData);
+ _channels[1]->load(loadData(0x2427));
+ _channels[2]->load(loadData(0x26B3));
+ _channels[3]->load(loadData(0x27C3));
+ _channels[4]->load(loadData(0x29F1));
+ _channels[5]->load(loadData(0x2CB9));
+ _channels[6]->load(loadData(0x2E89));
+ }
+ return 0;
+}
+
+// isSoundActive guard, command1, load ch0-5 (non-sequential)
+// ch1 and ch3 use data from the 0x4000 region; ch0/ch2/ch4 from 0x2E9E region
+int ASound5::command34() {
+ byte *pData = loadData(0x2E9E);
+ if (!isSoundActive(pData)) {
+ ASound::command1();
+ _channels[0]->load(pData);
+ _channels[1]->load(loadData(0x4003));
+ _channels[2]->load(loadData(0x348F));
+ _channels[3]->load(loadData(0x400A));
+ _channels[4]->load(loadData(0x3A1F));
+ _channels[5]->load(loadData(0x4011));
+ }
+ return 0;
+}
+
+// isSoundActive guard, command1, load ch0-5 (non-sequential)
+// ch1/ch3/ch5 use data from the 0x2196 region interleaved with ch0/ch2/ch4
+int ASound5::command35() {
+ byte *pData = loadData(0x1D0A);
+ if (!isSoundActive(pData)) {
+ ASound::command1();
+ _channels[0]->load(pData);
+ _channels[1]->load(loadData(0x2196));
+ _channels[2]->load(loadData(0x1E4A));
+ _channels[3]->load(loadData(0x21A8));
+ _channels[4]->load(loadData(0x1F7A));
+ _channels[5]->load(loadData(0x21BA));
+ }
+ return 0;
+}
+
+// isSoundActive guard, command1, load ch0-5 (non-sequential)
+// ch4 and ch5 reuse blocks at 0x15EC and 0x18D9 that precede ch0's data
+int ASound5::command36() {
+ byte *pData = loadData(0x15F5);
+ if (!isSoundActive(pData)) {
+ ASound::command1();
+ _channels[0]->load(pData);
+ _channels[1]->load(loadData(0x18E2));
+ _channels[2]->load(loadData(0x1A28));
+ _channels[3]->load(loadData(0x1C59));
+ _channels[4]->load(loadData(0x15EC));
+ _channels[5]->load(loadData(0x18D9));
+ }
+ return 0;
+}
+
+// isSoundActive guard, command1, load ch0-8
+int ASound5::command37() {
+ byte *pData = loadData(0x1190);
+ if (!isSoundActive(pData)) {
+ ASound::command1();
+ _channels[0]->load(pData);
+ _channels[1]->load(loadData(0x131D));
+ _channels[2]->load(loadData(0x1497));
+ _channels[3]->load(loadData(0x14D3));
+ _channels[4]->load(loadData(0x1513));
+ _channels[5]->load(loadData(0x153F));
+ _channels[6]->load(loadData(0x156B));
+ _channels[7]->load(loadData(0x159D));
+ _channels[8]->load(loadData(0x15D1));
+ }
+ return 0;
+}
+
+// isSoundActive guard, command2 (lower-bank fade), load ch0-5
+int ASound5::command38() {
+ byte *pData = loadData(0x0C36);
+ if (!isSoundActive(pData)) {
+ ASound::command2();
+ _channels[0]->load(pData);
+ _channels[1]->load(loadData(0x0D7F));
+ _channels[2]->load(loadData(0x0E48));
+ _channels[3]->load(loadData(0x0F10));
+ _channels[4]->load(loadData(0x0FB2));
+ _channels[5]->load(loadData(0x1096));
+ }
+ return 0;
+}
+
+// isSoundActive guard, command3 (lower-bank fade only), load ch0-5
+int ASound5::command39() {
+ byte *pData = loadData(0x5312);
+ if (!isSoundActive(pData)) {
+ ASound::command3();
+ _channels[0]->load(pData);
+ _channels[1]->load(loadData(0x5569));
+ _channels[2]->load(loadData(0x567C));
+ _channels[3]->load(loadData(0x579D));
+ _channels[4]->load(loadData(0x5890));
+ _channels[5]->load(loadData(0x5954));
+ }
+ return 0;
+}
+
+// ---------------------------------------------------------------------------
+// commands 64-78 (asound_commands5) - upper pool unless noted
+// ---------------------------------------------------------------------------
+
+int ASound5::command64() {
+ playSound(0x4101);
+ return 0;
+}
+
+int ASound5::command65() {
+ playSound(0x401A);
+ return 0;
+}
+
+int ASound5::command66() {
+ playSound(0x402C);
+ return 0;
+}
+
+int ASound5::command67() {
+ playSound(0x4036);
+ return 0;
+}
+
+int ASound5::command68() {
+ playSound(0x407A);
+ return 0;
+}
+
+int ASound5::command69() {
+ playSound(0x408C);
+ return 0;
+}
+
+// also shared by command77 and command78
+int ASound5::command70() {
+ playSound(0x40BA);
+ return 0;
+}
+
+int ASound5::command71() {
+ playSound(0x40C8);
+ return 0;
+}
+
+int ASound5::command72() {
+ playSound(0x40D2);
+ return 0;
+}
+
+int ASound5::command73() {
+ playSound(0x40DC);
+ playSound(0x40E7);
+ return 0;
+}
+
+int ASound5::command74() {
+ playSound(0x410B);
+ return 0;
+}
+
+int ASound5::command75() {
+ playSound(0x4129);
+ playSound(0x4134);
+ return 0;
+}
+
+// same block as command70
+int ASound5::command76() {
+ return command70();
+}
+
+// same block as command70
+int ASound5::command77() {
+ return command70();
+}
+
+int ASound5::command78() {
+ playSound(0x411F);
+ return 0;
+}
+
+/*-----------------------------------------------------------------------*/
+
+const ASound9::CommandPtr ASound9::_commandList[72] = {
+ &ASound9::command0, &ASound9::command1, &ASound9::command2, &ASound9::command3,
+ &ASound9::command4, &ASound9::command5, &ASound9::command6, &ASound9::command7,
+ &ASound9::command8, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ &ASound9::command16, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ &ASound9::command24, &ASound9::command25, &ASound9::command26, &ASound9::command27,
+ nullptr, nullptr, nullptr, nullptr,
+ &ASound9::command32, &ASound9::command33, &ASound9::command34, &ASound9::command35,
+ &ASound9::command36, &ASound9::command37, &ASound9::command38, &ASound9::command39,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr,
+ &ASound9::command64, &ASound9::command65, &ASound9::command66, &ASound9::command67,
+ &ASound9::command68, &ASound9::command69, &ASound9::command70, &ASound9::command71
+};
+
+ASound9::ASound9(Audio::Mixer *mixer, OPL::OPL *opl) :
+ ASound(mixer, opl, "asound.dr9", 0x20c0, 0x3690) {
+ // Load sound samples
+ auto samplesStream = getDataStream(0x1d4);
+ for (int i = 0; i < 120; ++i)
+ _samples.push_back(AdlibSample(samplesStream));
+}
+
+int ASound9::command(int commandId, int param) {
+ if (commandId > 71 || !_commandList[commandId])
+ return 0;
+
+ return (this->*_commandList[commandId])();
+}
+
+// commands 0-8: delegate to base ASound
+int ASound9::command0() {
+ return ASound::command0();
+}
+int ASound9::command1() {
+ return ASound::command1();
+}
+int ASound9::command2() {
+ return ASound::command2();
+}
+int ASound9::command3() {
+ return ASound::command3();
+}
+int ASound9::command4() {
+ return ASound::command4();
+}
+int ASound9::command5() {
+ return ASound::command5();
+}
+int ASound9::command6() {
+ return ASound::command6();
+}
+int ASound9::command7() {
+ return ASound::command7();
+}
+int ASound9::command8() {
+ return ASound::command8();
+}
+
+int ASound9::command24() {
+ playSound(0x203E);
+ playSound(0x2071);
+ return 0;
+}
+
+int ASound9::command25() {
+ playSound(0x209F);
+ playSound(0x20CB);
+ return 0;
+}
+
+int ASound9::command26() {
+ playSound(0x20F9);
+ return 0;
+}
+
+int ASound9::command27() {
+ playSound(0x2105);
+ return 0;
+}
+
+int ASound9::command32() {
+ ASound::command1();
+ findFreeChannel(loadData(0x2B16));
+ findFreeChannel(loadData(0x2B6C));
+ findFreeChannel(loadData(0x2BB6));
+ findFreeChannel(loadData(0x2E88));
+ findFreeChannel(loadData(0x2E98));
+ findFreeChannel(loadData(0x2EA3));
+ findFreeChannel(loadData(0x2EAE));
+ findFreeChannel(loadData(0x2EB7));
+ return 0;
+}
+
+int ASound9::command33() {
+ return 0;
+}
+
+int ASound9::command34() {
+ ASound::command1();
+ _channels[0]->load(loadData(0x31D0));
+ _channels[1]->load(loadData(0x3221));
+ _channels[2]->load(loadData(0x3282));
+ _channels[3]->load(loadData(0x32CB));
+ _channels[4]->load(loadData(0x331A));
+ _channels[5]->load(loadData(0x3369));
+ _channels[6]->load(loadData(0x33B0));
+ return 0;
+}
+
+int ASound9::command35() {
+ ASound::command1();
+ _channels[0]->load(loadData(0x295E));
+ _channels[1]->load(loadData(0x299E));
+ _channels[2]->load(loadData(0x29C3));
+ _channels[3]->load(loadData(0x29E8));
+ _channels[4]->load(loadData(0x2A46));
+ _channels[5]->load(loadData(0x2AA5));
+ _channels[6]->load(loadData(0x2AE0));
+ return 0;
+}
+
+int ASound9::command36() {
+ ASound::command1();
+ _channels[0]->load(loadData(0x30AA));
+ _channels[1]->load(loadData(0x30DD));
+ _channels[2]->load(loadData(0x3109));
+ _channels[3]->load(loadData(0x313D));
+ _channels[4]->load(loadData(0x3175));
+ _channels[5]->load(loadData(0x319B));
+ return 0;
+}
+
+int ASound9::command37() {
+ ASound::command1();
+ _channels[0]->load(loadData(0x2156));
+ _channels[1]->load(loadData(0x21A6));
+ _channels[2]->load(loadData(0x228E));
+ _channels[3]->load(loadData(0x22F7));
+ _channels[4]->load(loadData(0x2351));
+ _channels[5]->load(loadData(0x25A8));
+ _channels[6]->load(loadData(0x28BF));
+ return 0;
+}
+
+int ASound9::command38() {
+ byte *pData = loadData(0x11BC);
+ if (!isSoundActive(pData)) {
+ ASound::command1();
+ _channels[0]->load(pData);
+ _channels[1]->load(loadData(0x1477));
+ _channels[2]->load(loadData(0x158D));
+ _channels[3]->load(loadData(0x1777));
+ _channels[4]->load(loadData(0x1977));
+ _channels[5]->load(loadData(0x1BC5));
+ _channels[6]->load(loadData(0x1CFF));
+ _channels[7]->load(loadData(0x1EAF));
+ }
+ return 0;
+}
+
+int ASound9::command39() {
+ byte *pData = loadData(0x0C36);
+ if (!isSoundActive(pData)) {
+ ASound::command0();
+ _channels[0]->load(pData);
+ _channels[1]->load(loadData(0x0D7D));
+ _channels[2]->load(loadData(0x0E50));
+ _channels[3]->load(loadData(0x0F1C));
+ _channels[4]->load(loadData(0x0FCE));
+ _channels[5]->load(loadData(0x10BA));
+ }
+ return 0;
+}
+
+int ASound9::command64() {
+ playSound(0x2EC6);
+ return 0;
+}
+
+int ASound9::command65() {
+ playSound(0x2EDA);
+ return 0;
+}
+
+int ASound9::command66() {
+ _channels[0]->load(loadData(0x2EE4));
+ _channels[1]->load(loadData(0x2F0E));
+ _channels[2]->load(loadData(0x2F3E));
+ _channels[3]->load(loadData(0x2F6E));
+ _channels[4]->load(loadData(0x2EE4));
+ _channels[5]->load(loadData(0x2F0E));
+ _channels[6]->load(loadData(0x2F3E));
+ _channels[7]->load(loadData(0x2F6E));
+ return 0;
+}
+
+int ASound9::command67() {
+ _channels[6]->load(loadData(0x2F9E));
+ _channels[7]->load(loadData(0x2FBD));
+ _channels[8]->load(loadData(0x2FCC));
+ return 0;
+}
+
+int ASound9::command68() {
+ playSound(0x2FEB);
+ return 0;
+}
+
+int ASound9::command69() {
+ playSound(0x2FF5);
+ playSound(0x301B);
+ playSound(0x3041);
+ return 0;
+}
+
+int ASound9::command70() {
+ playSound(0x305B);
+ playSound(0x3064);
+ return 0;
+}
+
+int ASound9::command71() {
+ playSound(0x306D);
+ playSound(0x308A);
+ return 0;
+}
+
+} // namespace Dragonsphere
+} // namespace MADSV2
+} // namespace MADS
diff --git a/engines/mads/madsv2/dragonsphere/sound_dragonsphere.h b/engines/mads/madsv2/dragonsphere/sound_dragonsphere.h
new file mode 100644
index 00000000000..e0d63abed2c
--- /dev/null
+++ b/engines/mads/madsv2/dragonsphere/sound_dragonsphere.h
@@ -0,0 +1,392 @@
+/* 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_DRAGONSPHERE_SOUND_H
+#define MADS_DRAGONSPHERE_SOUND_H
+
+#include "mads/madsv2/core/asound.h"
+
+namespace MADS {
+namespace MADSV2 {
+namespace Dragonsphere {
+
+class DragonSoundManager : public SoundManager {
+protected:
+ void loadDriver(int sectionNum) override;
+
+public:
+ DragonSoundManager(Audio::Mixer *mixer, bool &soundFlag) : SoundManager(mixer, soundFlag) {
+ }
+ ~DragonSoundManager() override {
+ }
+
+ void validate() override;
+};
+
+/**
+ * ASound1 (asound.ph1, _dataOffset = 0x21e0)
+ *
+ * Dispatch table layout:
+ * off_11C32: commands 0â8 (max=8, base=0)
+ * off_11C44: command 16 (max=0x10, base=0x10, 1 entry)
+ * off_11C46: commands 24â27 (max=0x1B, base=0x18, 4 entries)
+ * off_11C4E: commands 32â39 (max=0x27, base=0x20, 8 entries)
+ *
+ * A fifth table (unk_13C3E, commands 64â76) exists but is encoded as raw
+ * sound data bytes used as near-pointers â not reconstructible without the
+ * binary. Those commands are silently ignored.
+ *
+ * command16 (sub_11F70): random background-music selector. Checks whether
+ * channel 0 is already playing one of the five known music pieces; if not,
+ * randomly picks from four music loaders and plays it, storing the choice
+ * in _musicIndex (mirrors word_11F5E in the original).
+ */
+class ASound1 : public ASound {
+private:
+ typedef int (ASound1::*CommandPtr)();
+ static const CommandPtr _commandList[40];
+
+ // Mirrors word_11F5E: tracks which music piece was last selected.
+ int _musicIndex = 0;
+
+ // Background-music loaders (targets of the CS:0x1F60 indirect table).
+ int commandMusic0(); // sub_11D84 â starts at 0x1ECA
+ int commandMusic1(); // sub_11EE6 â starts at 0x3418
+ int commandMusic2(); // sub_11F0E â starts at 0x3688
+ int commandMusic3(); // sub_11F36 â starts at 0x3D52
+
+ int command0();
+ int command1();
+ int command2();
+ int command3();
+ int command4();
+ int command5();
+ int command6();
+ int command7();
+ int command8();
+
+ int command16();
+
+ int command24();
+ int command25();
+ int command26();
+ int command27();
+
+ int command32();
+ int command33();
+ int command34();
+ int command35();
+ int command36();
+ int command37();
+ int command38();
+ int command39();
+
+public:
+ ASound1(Audio::Mixer *mixer, OPL::OPL *opl);
+ ~ASound1() override {}
+ int command(int commandId, int param) override;
+};
+
+/**
+ * ASound2 (asound.ph2, _dataOffset = 0x2040)
+ *
+ * Dispatch table layout:
+ * asound_commands1: commands 0â8 (max=8, base=0)
+ * asound_commands2: command 16 (max=0x10, base=0x10, 1 entry)
+ * asound_commands3: commands 24â27 (max=0x1B, base=0x18, 4 entries)
+ * asound_commands4: commands 32â35 (max=0x23, base=0x20, 4 entries)
+ * asound_commands5: commands 64â72 (max=0x48, base=0x40, 9 entries)
+ */
+class ASound2 : public ASound {
+private:
+ typedef int (ASound2::*CommandPtr)();
+ static const CommandPtr _commandList[73];
+
+ int command0();
+ int command1();
+ int command2();
+ int command3();
+ int command4();
+ int command5();
+ int command6();
+ int command7();
+ int command8();
+
+ int command16();
+
+ int command24();
+ int command25();
+ int command26();
+ int command27();
+
+ int command32();
+ int command33();
+ int command34();
+ int command35();
+
+ int command64();
+ int command65();
+ int command66();
+ int command67();
+ int command68();
+ int command69();
+ int command70();
+ int command71();
+ int command72();
+
+public:
+ ASound2(Audio::Mixer *mixer, OPL::OPL *opl);
+ ~ASound2() override {}
+ int command(int commandId, int param) override;
+};
+
+/**
+ * ASound3 (asound.ph3, _dataOffset = 0x20c0)
+ *
+ * Dispatch table layout:
+ * asound_commands1: commands 0â8 (max=8, base=0)
+ * asound_commands2: command 16 (max=0x10, base=0x10, 1 entry)
+ * asound_commands3: commands 24â27 (max=0x1B, base=0x18, 4 entries)
+ * asound_commands4: commands 32â37 (max=0x25, base=0x20, 6 entries)
+ * asound_commands5: commands 64â75 (max=0x4B, base=0x40, 12 entries)
+ * (command 76 = nullsub_8, silently ignored by bounds check)
+ */
+class ASound3 : public ASound {
+private:
+ typedef int (ASound3::*CommandPtr)();
+ static const CommandPtr _commandList[77];
+
+ // Internal helper: isSoundActive guard on 0xC36, load ch0â7.
+ // Called by command34 which then adds ch8.
+ void sub11CC6();
+
+ int command0();
+ int command1();
+ int command2();
+ int command3();
+ int command4();
+ int command5();
+ int command6();
+ int command7();
+ int command8();
+
+ int command16();
+
+ int command24();
+ int command25();
+ int command26();
+ int command27();
+
+ int command32();
+ int command33();
+ int command34();
+ int command35();
+ int command36();
+ int command37();
+
+ int command64();
+ int command65();
+ int command66();
+ int command67();
+ int command68();
+ int command69();
+ int command70();
+ int command71();
+ int command72();
+ int command73();
+ int command74();
+ int command75();
+
+public:
+ ASound3(Audio::Mixer *mixer, OPL::OPL *opl);
+ ~ASound3() override {}
+ int command(int commandId, int param) override;
+};
+
+/**
+ * ASound4 (asound.ph4, _dataOffset = 0x1f90)
+ *
+ * Dispatch table layout:
+ * asound_commands1: commands 0â8 (max=8, base=0)
+ * asound_commands2: command 16 (max=0x10, base=0x10, 1 entry)
+ * asound_commands3: commands 24â27 (max=0x1B, base=0x18, 4 entries)
+ * asound_commands4: commands 64â70 (max=0x46, base=0x40, 7 entries)
+ * (Commands 32â63 are unreachable: the 0x20-range max constant = 0)
+ *
+ * commands 24 and 25 share the same handler (sub_11D0A).
+ */
+class ASound4 : public ASound {
+private:
+ typedef int (ASound4::*CommandPtr)();
+ static const CommandPtr _commandList[71];
+
+ int command0();
+ int command1();
+ int command2();
+ int command3();
+ int command4();
+ int command5();
+ int command6();
+ int command7();
+ int command8();
+
+ int command16();
+
+ int command24();
+ int command25();
+ int command26();
+ int command27();
+
+ int command64();
+ int command65();
+ int command66();
+ int command67();
+ int command68();
+ int command69();
+ int command70();
+
+public:
+ ASound4(Audio::Mixer *mixer, OPL::OPL *opl);
+ ~ASound4() override {}
+ int command(int commandId, int param) override;
+};
+
+/**
+ * ASound5 (asound.ph5, _dataOffset = 0x2140)
+ *
+ * Dispatch table layout:
+ * asound_commands1: commands 0â8 (max=8, base=0)
+ * asound_commands2: command 16 (max=0x10, base=0x10, 1 entry)
+ * asound_commands3: commands 24â27 (max=0x1B, base=0x18, 4 entries)
+ * asound_commands4: commands 32â39 (max=0x27, base=0x20, 8 entries)
+ * asound_commands5: commands 64â78 (max=0x4E, base=0x40, 15 entries)
+ * (command 79 = nullsub_8, silently ignored by bounds check)
+ *
+ * commands 36/35/34 load channels in non-sequential data order.
+ * commands 70, 77, and 78 all play the same 0x40BA sound block.
+ */
+class ASound5 : public ASound {
+private:
+ typedef int (ASound5::*CommandPtr)();
+ static const CommandPtr _commandList[79];
+
+ int command0();
+ int command1();
+ int command2();
+ int command3();
+ int command4();
+ int command5();
+ int command6();
+ int command7();
+ int command8();
+
+ int command16();
+
+ int command24();
+ int command25();
+ int command26();
+ int command27();
+
+ int command32();
+ int command33();
+ int command34();
+ int command35();
+ int command36();
+ int command37();
+ int command38();
+ int command39();
+
+ int command64();
+ int command65();
+ int command66();
+ int command67();
+ int command68();
+ int command69();
+ int command70();
+ int command71();
+ int command72();
+ int command73();
+ int command74();
+ int command75();
+ int command76();
+ int command77();
+ int command78();
+
+public:
+ ASound5(Audio::Mixer *mixer, OPL::OPL *opl);
+ ~ASound5() override {}
+ int command(int commandId, int param) override;
+};
+
+class ASound9 : public ASound {
+private:
+ typedef int (ASound9:: *CommandPtr)();
+ int command0();
+ int command1();
+ int command2();
+ int command3();
+ int command4();
+ int command5();
+ int command6();
+ int command7();
+ int command8();
+
+ int command16() {
+ return command24();
+ }
+
+ int command24();
+ int command25();
+ int command26();
+ int command27();
+
+ int command32();
+ int command33();
+ int command34();
+ int command35();
+ int command36();
+ int command37();
+ int command38();
+ int command39();
+
+ int command64();
+ int command65();
+ int command66();
+ int command67();
+ int command68();
+ int command69();
+ int command70();
+ int command71();
+
+ static const CommandPtr _commandList[72];
+
+public:
+ ASound9(Audio::Mixer *mixer, OPL::OPL *opl);
+ ~ASound9() override {
+ }
+ int command(int commandId, int param) override;
+};
+
+} // namespace Dragonsphere
+} // namespace MADSV2
+} // namespace MADS
+
+#endif
diff --git a/engines/mads/module.mk b/engines/mads/module.mk
index 65e1e8a416b..27e8f8ec714 100644
--- a/engines/mads/module.mk
+++ b/engines/mads/module.mk
@@ -183,6 +183,10 @@ MODULE_OBJS += \
madsv2/phantom/sound_phantom.o \
madsv2/dragonsphere/dragonsphere.o \
madsv2/dragonsphere/global.o \
+ madsv2/dragonsphere/main.o \
+ madsv2/dragonsphere/main_menu.o \
+ madsv2/dragonsphere/menus.o \
+ madsv2/dragonsphere/sound_dragonsphere.o \
madsv2/dragonsphere/mads/mads.o \
madsv2/dragonsphere/rooms/section1.o \
madsv2/dragonsphere/rooms/room101.o \
Commit: 1892a6850c779a15d36ec5024ed6029eff365cb2
https://github.com/scummvm/scummvm/commit/1892a6850c779a15d36ec5024ed6029eff365cb2
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-05-22T06:20:41+10:00
Commit Message:
MADS: DRAGONSPHERE: Main menu buttons showing
Changed paths:
engines/mads/madsv2/dragonsphere/main.cpp
engines/mads/madsv2/dragonsphere/main_menu.cpp
diff --git a/engines/mads/madsv2/dragonsphere/main.cpp b/engines/mads/madsv2/dragonsphere/main.cpp
index 5d46d24113d..8d6641fc972 100644
--- a/engines/mads/madsv2/dragonsphere/main.cpp
+++ b/engines/mads/madsv2/dragonsphere/main.cpp
@@ -57,6 +57,12 @@ static void main_menu_main() {
if (!kernel_game_startup(19, KERNEL_STARTUP_CURSOR | KERNEL_STARTUP_INTERRUPT | KERNEL_STARTUP_FONT,
nullptr, nullptr)) {
+ matte_init(0xFFFF);
+ bool valid = !kernel_room_startup(920, 0, nullptr, true, true);
+
+ // Setup scr_work to use the full surface of scr_main (i.e. 320x200).
+ // Because of this, viewing_at_y is actually == 0
+ scr_work.y = picture_map.viewport_y;
viewing_at_y = (200 - scr_work.y) >> 1;
mouse_cursor_sprite(cursor, 7);
@@ -65,7 +71,6 @@ static void main_menu_main() {
mouse_hide();
mouse_cursor_sprite(cursor, 1);
- matte_init(0xFFFF);
kernel_seq_init();
kernel_message_init();
kernel_animation_init();
@@ -73,23 +78,6 @@ static void main_menu_main() {
picture_view_x = 0;
picture_view_y = 0;
-
- quotes = quote_load(0, 68, 69, 70, 71, 72, 73, 74, 75, 76,
- 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
- 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
- 97, 98, 99, 0);
-
- global_speech_load(9);
- bool valid = !kernel_room_startup(902, 0, nullptr, true, true);
-
- master_palette[4].r = 63;
- master_palette[4].g = 50;
- master_palette[4].b = 0;
- master_palette[5].r = 30;
- master_palette[5].g = 15;
- master_palette[5].b = 0;
- mcga_setpal_range(&master_palette, 4, 2);
-
new_background = true;
if (valid) {
@@ -102,7 +90,7 @@ static void main_menu_main() {
screen.hLine(0, scr_work.y + viewing_at_y + 1, 319, LINE_COLOR);
}
- kernel_load_sound_driver("*#SOUND.PH9", 'N', 544, 0, 49);
+ kernel_load_sound_driver("*#SOUND.DR9", 'N', 544, 0, 49);
menu_control();
@@ -135,9 +123,9 @@ static void main_cold_data_init() {
game_menu_exit = global_menu_system_shutdown;
game_emergency_save = global_emergency_save;
- Common::strcpy_s(config_file_name, "config.pha");
- Common::strcpy_s(save_game_key, "phan");
- Common::strcpy_s(restart_game_key, "phantom");
+ Common::strcpy_s(config_file_name, "config.dra");
+ Common::strcpy_s(save_game_key, "drag");
+ Common::strcpy_s(restart_game_key, "dragon");
Common::strcpy_s(player.series_name, "RAL");
player.walker_must_reload = true;
diff --git a/engines/mads/madsv2/dragonsphere/main_menu.cpp b/engines/mads/madsv2/dragonsphere/main_menu.cpp
index e2e22963e34..7ece6326494 100644
--- a/engines/mads/madsv2/dragonsphere/main_menu.cpp
+++ b/engines/mads/madsv2/dragonsphere/main_menu.cpp
@@ -192,6 +192,7 @@ static void start_hotspots() {
ys = series->index[0].ys;
x1 = series->index[0].x - (xs >> 1);
y1 = series->index[0].y - (ys - 1);
+
x2 = x1 + xs - 1;
y2 = y1 + ys - 1;
hspot_add(x1, y1, x2, y2, 1, count, mcga_mode);
@@ -255,13 +256,6 @@ static void process_sprites() {
}
} else {
sprite = 1;
- /*
- if (count != selected_item) {
- sprite = 1;
- } else {
- sprite = 2;
- }
- */
}
image.series_id = (byte)menu_item[series].handle;
Commit: 6a2f5bd733a547ea932cd109ac65e77a013ed2fa
https://github.com/scummvm/scummvm/commit/6a2f5bd733a547ea932cd109ac65e77a013ed2fa
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-05-22T06:20:41+10:00
Commit Message:
MADS: DRAGONSPHERE: Added global_parser_code
Changed paths:
engines/mads/madsv2/core/kernel.cpp
engines/mads/madsv2/dragonsphere/dragonsphere.cpp
engines/mads/madsv2/dragonsphere/dragonsphere.h
engines/mads/madsv2/dragonsphere/mads/inventory.h
engines/mads/madsv2/dragonsphere/mads/sounds.h
engines/mads/madsv2/dragonsphere/mads/words.h
diff --git a/engines/mads/madsv2/core/kernel.cpp b/engines/mads/madsv2/core/kernel.cpp
index 71c16299c0a..3ebb60eed69 100644
--- a/engines/mads/madsv2/core/kernel.cpp
+++ b/engines/mads/madsv2/core/kernel.cpp
@@ -2552,7 +2552,7 @@ int kernel_load_sound_driver(const char *name, char sound_card_, int sound_board
// Get the section number from the end of the driver filename, and use it to initialize
// the sound system; we provide our own implementation of the drivers
int sectionNum = *(name + strlen(name) - 1) - '0';
- assert((sectionNum >= 1 && sectionNum <= 5) || sectionNum == 9);
+ assert(sectionNum >= 1 && sectionNum <= 9);
g_engine->_soundManager->init(sectionNum);
diff --git a/engines/mads/madsv2/dragonsphere/dragonsphere.cpp b/engines/mads/madsv2/dragonsphere/dragonsphere.cpp
index 891c94915e4..9924c7cf1af 100644
--- a/engines/mads/madsv2/dragonsphere/dragonsphere.cpp
+++ b/engines/mads/madsv2/dragonsphere/dragonsphere.cpp
@@ -21,14 +21,30 @@
#include "engines/util.h"
#include "mads/madsv2/console.h"
+#include "mads/madsv2/core/conv.h"
+#include "mads/madsv2/core/env.h"
#include "mads/madsv2/core/game.h"
#include "mads/madsv2/core/imath.h"
+#include "mads/madsv2/core/inter.h"
#include "mads/madsv2/core/kernel.h"
+#include "mads/madsv2/core/object.h"
#include "mads/madsv2/core/screen.h"
+#include "mads/madsv2/core/sound.h"
+#include "mads/madsv2/core/text.h"
#include "mads/madsv2/dragonsphere/dragonsphere.h"
#include "mads/madsv2/dragonsphere/global.h"
#include "mads/madsv2/dragonsphere/main.h"
#include "mads/madsv2/dragonsphere/sound_dragonsphere.h"
+#include "mads/madsv2/dragonsphere/rooms/section1.h"
+#include "mads/madsv2/dragonsphere/rooms/section2.h"
+#include "mads/madsv2/dragonsphere/rooms/section3.h"
+#include "mads/madsv2/dragonsphere/rooms/section4.h"
+#include "mads/madsv2/dragonsphere/rooms/section5.h"
+#include "mads/madsv2/dragonsphere/rooms/section6.h"
+#include "mads/madsv2/dragonsphere/rooms/section9.h"
+#include "mads/madsv2/dragonsphere/mads/inventory.h"
+#include "mads/madsv2/dragonsphere/mads/sounds.h"
+#include "mads/madsv2/dragonsphere/mads/words.h"
namespace MADS {
namespace MADSV2 {
@@ -53,15 +69,202 @@ Common::Error DragonsphereEngine::run() {
}
void DragonsphereEngine::global_init_code() {
+ int count;
+
+ for (count = 0; count < GLOBAL_LIST_SIZE; count++) {
+ global[count] = 0;
+ }
+
+ /* initialize_grid (); */
+
+ global[grid_position] = 5;
+ global[grid_position + 1] = 4;
+ global[grid_position + 2] = 9;
+ global[grid_position + 3] = 10;
+ global[grid_position + 4] = 15;
+ global[grid_position + 5] = 20;
+ global[grid_position + 6] = 19;
+ global[grid_position + 7] = 24;
+ global[grid_position + 8] = 23;
+ global[grid_position + 9] = 18;
+ global[grid_position + 10] = 13;
+ global[grid_position + 11] = 8;
+ global[grid_position + 12] = 3;
+ global[grid_position + 13] = 2;
+ global[grid_position + 14] = 1;
+ global[grid_position + 15] = 6;
+ global[grid_position + 16] = 7;
+ global[grid_position + 17] = 12;
+
+ global[grid_position + 18] = 17;
+ global[grid_position + 19] = 22;
+ global[grid_position + 20] = 21;
+ global[grid_position + 21] = 16;
+ global[grid_position + 22] = 11;
+
+ global[max_grid_value] = grid_position + 22;
+
+ global[oasis] = imath_random(1, 11);
+ switch (global[oasis]) {
+ case 1: global[oasis] = 7; break;
+ case 2: global[oasis] = 13; break;
+ case 3: global[oasis] = 19; break;
+ case 4: global[oasis] = 25; break;
+ case 5: global[oasis] = 31; break;
+ case 6: global[oasis] = 37; break;
+ case 7: global[oasis] = 45; break;
+ case 8: global[oasis] = 53; break;
+ case 9: global[oasis] = 61; break;
+ case 10: global[oasis] = 69; break;
+ case 11: global[oasis] = 77; break;
+ }
+
+ do {
+ global[fire_holes] = imath_random(1, 11);
+ switch (global[fire_holes]) {
+ case 1: global[fire_holes] = 7; break;
+ case 2: global[fire_holes] = 13; break;
+ case 3: global[fire_holes] = 19; break;
+ case 4: global[fire_holes] = 25; break;
+ case 5: global[fire_holes] = 31; break;
+ case 6: global[fire_holes] = 37; break;
+ case 7: global[fire_holes] = 45; break;
+ case 8: global[fire_holes] = 53; break;
+ case 9: global[fire_holes] = 61; break;
+ case 10: global[fire_holes] = 69; break;
+ case 11: global[fire_holes] = 77; break;
+ }
+ } while (global[fire_holes] == global[oasis]);
+
+ /* Section 1 Initialization */
+
+ global[player_score] = 0;
+ global[player_score_flags] = 0;
+
+ global[dragon_high_scene] = 0;
+ global[dragon_my_scene] = 0;
+ global[player_persona] = PLAYER_IS_KING;
+ global[king_status] = KING_CAPTIVE;
+ global[ward_status] = WARD_PRESENT;
+ global[amulet_status] = AMULET_NOT_CORRECT_TIME;
+ global[books_status] = BOOKS_NOT_PRESENT;
+ global[tapestry_status] = TAPESTRY_CLOSED;
+ global[talked_to_status] = TALKED_TO_NONE;
+ global[guard_pid_status] = GUARD_NEVER_HEALED;
+
+ global[crawled_out_of_bed_101] = false;
+ global[statue_is_on_stairway_114] = false;
+ global[dog_is_asleep] = false;
+ global[crystal_ball_dead] = false;
+ global[threw_bone] = false;
+ global[no_load_walker] = false;
+ global[wooden_door_open] = false;
+ global[king_is_in_stairwell] = false;
+ global[llanie_status] = BEFORE_FALL;
+ global[no_talk_to_guard] = false;
+ global[sorceror_defeated] = false;
+ global[waterfall_diverted] = false;
+ global[shak_status] = SHAK_NEVER_MET;
+ global[move_direction_510] = true;
+ global[move_direction_409] = true;
+ global[shak_506_angry] = false;
+ global[monster_is_dead] = false;
+ global[done_talking_lani_502] = false;
+ global[found_lani_504] = false;
+ global[said_use_sword_shak] = false;
+ global[goblet_filled_soporific] = false;
+ global[been_in_504_as_pid] = false;
+ global[seen_lani_dead_1st_time] = false;
+ global[said_poem_in_504] = false;
+ global[tried_to_heal_llanie_504] = false;
+ global[put_bundle_on_llanie_504] = false;
+ global[mud_is_in_eye_603] = false;
+ global[rope_is_alive] = true;
+ global[make_504_empty] = false;
+ global[rat_cage_is_open] = false;
+ global[flask_on_plate] = NONE;
+ global[fluid_is_dripping] = false;
+ global[hole_is_in_607] = false;
+ global[rope_is_hanging_in_607] = false;
+ global[object_is_in_freezer_605] = NEVER_USED_FREEZER;
+ global[has_taken_mud] = false;
+ global[desert_room] = 42;
+ global[object_imitated] = -1;
+ global[has_red] = false;
+ global[has_yellow] = false;
+ global[has_blue] = false;
+ global[wizard_dead] = false;
+ global[vine_will_grab] = true;
+ global[desert_counter] = 0;
+ global[floor_is_cool] = false;
+ global[rat_melted] = false;
+ global[door_is_cool] = false;
+ global[used_elevator] = false;
+ global[been_on_top_floor] = false;
+ global[torch_is_in_609] = false;
+ global[platform_clicked_606] = false;
+ global[perform_displacements] = true;
+ global[had_spirit_bundle] = false;
+ global[heal_verbs_visible] = false;
+ global[pid_talk_shamon] = false;
+ global[talked_to_soptus] = false;
+ global[pid_just_died] = false;
+ global[grapes_have_grown] = GRAPES_NOT_THERE;
+ global[grapes_are_dead] = false;
+ global[roc_is_chewing_dates] = false;
+ global[wins_in_desert] = 0;
+ global[wins_till_prize] = 3;
+ global[game_points] = 0;
+ global[dance_points] = 0;
+ global[clue_points] = 0;
+ global[prizes_owed_to_player] = 0; /* for king */
+ global[pid_has_been_healed_sop] = false;
+ global[object_flags] = 0;
+ global[save_wins_in_desert] = 0;
+ global[object_given_201] = -1;
+ global[king_got_stabbed] = false;
+ global[given_object_before] = false;
+ global[guards_are_asleep] = false;
+ global[dome_up] = false;
+ global[talked_to_wise] = false;
+ global[talked_to_shifter] = false;
+ global[talked_to_merchant] = false;
+ global[doll_given] = false;
+ global[reset_conv] = -1;
+ global[reset_conv_2] = -1;
+ global[talked_to_greta] = false;
+ global[slime_healed] = false;
+ global[dance_music_on] = false;
+ global[bubbles_up_in_301] = true;
+ global[bubble_wont_attack] = false;
+ global[can_view_crown_hole] = false;
+ global[player_is_seal] = false;
+ global[vines_have_player] = false;
+ global[end_of_game] = false;
+ global[pid_looked_at_doll] = false;
+ global[invoked_from_111] = false;
+
+ player.facing = FACING_NORTH;
+ player.turn_to_facing = FACING_NORTH;
}
void DragonsphereEngine::section_music(int section_num) {
-
+ switch (section_num) {
+ case 1: Rooms::section_1_music(); break;
+ case 2: Rooms::section_2_music(); break;
+ case 3: Rooms::section_3_music(); break;
+ case 4: Rooms::section_4_music(); break;
+ case 5: Rooms::section_5_music(); break;
+ case 6: Rooms::section_6_music(); break;
+ case 9: Rooms::section_9_music(); break;
+ }
}
void DragonsphereEngine::global_object_sprite() {
-
+ Common::strcpy_s(inter_object_buf, "*OB");
+ env_catint(inter_object_buf, inter_object_id, 3);
+ Common::strcat_s(inter_object_buf, "I");
}
void DragonsphereEngine::stop_walker_basic() {
@@ -142,22 +345,807 @@ void DragonsphereEngine::stop_walker_tricks() {
}
void DragonsphereEngine::global_section_constructor() {
-
+ Dragonsphere::global_section_constructor();
}
void DragonsphereEngine::syncRoom(Common::Serializer &s) {
-
+ Dragonsphere::sync_room(s);
}
void DragonsphereEngine::global_daemon_code() {
+ int random;
+ int count;
+ int how_many;
+
+ if (player.walker_visible && (player.commands_allowed || (conv_control.running >= 0)) && !player.walking &&
+ (player.facing == player.turn_to_facing) && global[perform_displacements]) {
+
+ if (kernel.clock >= *((long *)&global[walker_timing])) {
+
+ if (!player.stop_walker_pointer) {
+
+ random = imath_random(1, 30000);
+
+ if (global[player_persona] == PLAYER_IS_KING) {
+ if (random < 500) {
+ switch (player.facing) {
+ case FACING_SOUTHEAST:
+ case FACING_SOUTHWEST:
+ how_many = imath_random(0, 3);
+ if (how_many <= 2) {
+ for (count = 0; count < imath_random(5, 7); count++) {
+ player_add_stop_walker(how_many, 0);
+ }
+ } else {
+ player_add_stop_walker(-3, 0);
+ for (count = 0; count < imath_random(5, 7); count++) {
+ player_add_stop_walker(4, 0);
+ }
+ player_add_stop_walker(3, 0);
+ }
+ break;
+
+ case FACING_NORTHEAST:
+ case FACING_NORTHWEST:
+ how_many = imath_random(0, 1);
+ for (count = 0; count < imath_random(5, 7); count++) {
+ player_add_stop_walker(how_many, 0);
+ }
+ break;
+
+ case FACING_SOUTH:
+ how_many = imath_random(0, 3);
+ if (how_many <= 2) {
+ for (count = 0; count < imath_random(5, 7); count++) {
+ player_add_stop_walker(how_many, 0);
+ }
+
+ } else {
+ player_add_stop_walker(-3, 0);
+ for (count = 0; count < imath_random(5, 7); count++) {
+ player_add_stop_walker(4, 0);
+ }
+ player_add_stop_walker(3, 0);
+ }
+ break;
+
+ case FACING_NORTH:
+ how_many = imath_random(0, 2);
+ for (count = 0; count < imath_random(5, 7); count++) {
+ player_add_stop_walker(how_many, 0);
+ }
+ break;
+ case FACING_EAST:
+ case FACING_WEST:
+ default:
+ how_many = imath_random(0, 2);
+ if (how_many <= 1) {
+ for (count = 0; count < imath_random(5, 7); count++) {
+ player_add_stop_walker(how_many, 0);
+ }
+ } else {
+ player_add_stop_walker(-2, 0);
+ for (count = 0; count < imath_random(5, 7); count++) {
+ player_add_stop_walker(3, 0);
+ }
+ player_add_stop_walker(2, 0);
+ }
+ break;
+ }
+ }
+
+ } else { /* player is PID */
+
+ if (random < 500) {
+ switch (player.facing) {
+ case FACING_SOUTHEAST:
+ case FACING_SOUTHWEST:
+ how_many = imath_random(0, 3);
+ if (how_many <= 2) {
+ for (count = 0; count < imath_random(5, 7); count++) {
+ player_add_stop_walker(how_many, 0);
+ }
+ } else {
+ player_add_stop_walker(-3, 0);
+ for (count = 0; count < imath_random(5, 7); count++) {
+ player_add_stop_walker(4, 0);
+ }
+ player_add_stop_walker(3, 0);
+ }
+ break;
+
+ case FACING_NORTHEAST:
+ case FACING_NORTHWEST:
+ how_many = imath_random(0, 2);
+ for (count = 0; count < imath_random(5, 7); count++) {
+ player_add_stop_walker(how_many, 0);
+ }
+ break;
+
+ case FACING_SOUTH:
+ how_many = imath_random(0, 3);
+ if (how_many <= 2) {
+ for (count = 0; count < imath_random(5, 7); count++) {
+ player_add_stop_walker(how_many, 0);
+ }
+ } else {
+ player_add_stop_walker(-3, 0);
+ player_add_stop_walker(3, 0);
+ }
+ break;
+
+ case FACING_NORTH:
+ how_many = imath_random(0, 2);
+ for (count = 0; count < imath_random(5, 7); count++) {
+ player_add_stop_walker(how_many, 0);
+ }
+ break;
+
+ case FACING_EAST:
+ case FACING_WEST:
+ default:
+ how_many = imath_random(0, 2);
+ if (how_many <= 1) {
+ for (count = 0; count < imath_random(5, 7); count++) {
+ player_add_stop_walker(how_many, 0);
+ }
+ } else {
+ player_add_stop_walker(3, 0);
+ player_add_stop_walker(2, 0);
+ }
+ break;
+ }
+
+ } else if (random < 1000) {
+ WRITE_LE_UINT32(&global[walker_timing], kernel.clock);
+ }
+ }
+
+ }
+
+ WRITE_LE_UINT32(&global[walker_timing], READ_LE_UINT32(&global[walker_timing]) + 10);
+ }
+ }
}
void DragonsphereEngine::global_pre_parser_code() {
-
+ if (player_said_1(look) || player_said_1(throw)) {
+ player.need_to_walk = false;
+ }
}
void DragonsphereEngine::global_parser_code() {
+ int id;
+ int idd;
+
+ id = object_named(player_second_noun);
+ idd = object_named(player_main_noun);
+
+ if (player_said_1(revert) && idd == polystone) {
+ if (global[object_imitated] == -1 || global[object_imitated] == 9) {
+ text_show(708);
+
+ } else {
+ global[object_imitated] = 9;
+ inter_move_object(idd, NOWHERE);
+ inter_give_to_player(idd);
+ object_examine(polystone, 701, 0);
+ }
+ goto handled;
+ }
+
+ if (player_said_1(mimic)) {
+ if (player_has(id)) {
+ if (room_id == 614 && id == blue_powerstone) {
+ text_show(61422);
+ }
+
+ if ((id == 9 && idd == 9) && (global[object_imitated] == -1 || global[object_imitated] == 9)) {
+ text_show(708);
+
+ } else {
+ global[object_imitated] = id;
+
+ inter_move_object(id, NOWHERE);
+ inter_give_to_player(id);
+ if (id == 9) {
+ object_examine(polystone, 701, 0);
+ } else {
+ object_examine(polystone, 933, 0);
+ }
+ }
+
+ } else {
+ text_show(707);
+ }
+ goto handled;
+ }
+
+ if (player_said_2(polish, signet_ring)) {
+ object_examine(signet_ring, 901, 0);
+ goto handled;
+ }
+
+ if (player_said_2(invoke, red_stone) ||
+ player_said_2(invoke, yellow_stone) ||
+ player_said_2(invoke, blue_stone)) {
+ text_show(705);
+ goto handled;
+ }
+
+ if (player_said_1(pour_contents_of)) {
+ if (id == flask_full_of_acid && idd == flask_full_of_acid) {
+ text_show(23);
+ } else {
+ text_show(958);
+ }
+ goto handled;
+ }
+
+ if (player_said_1(drink) && idd == flask_full_of_acid) {
+ text_show(957);
+ goto handled;
+ }
+
+ if (player_said_2(put_magic_into, partial_bundle)) {
+ if (player_has(partly_built_bundle)) {
+ if (global[had_spirit_bundle]) {
+ inter_move_object(partly_built_bundle, NOWHERE);
+ inter_give_to_player(new_bundle);
+ object_examine(new_bundle, 977, 0);
+
+ } else {
+ text_show(998);
+ }
+ }
+ goto handled;
+ }
+
+ if (player_said_1(put_magic_into)) {
+ text_show(978);
+ goto handled;
+ }
+
+ if (player_said_2(polish, red_stone)) {
+ object_examine(red_powerstone, 935, 0);
+ goto handled;
+ }
+
+ if (player_said_2(polish, yellow_stone)) {
+ object_examine(yellow_powerstone, 703, 0);
+ goto handled;
+ }
+
+ if (player_said_2(polish, blue_stone)) {
+ object_examine(blue_powerstone, 704, 0);
+ goto handled;
+ }
+
+ if (player_said_2(give, signet_ring)) {
+ if (player_said_1(king)) {
+ text_show(902);
+ } else {
+ text_show(917);
+ }
+ goto handled;
+ }
+
+ if (player_said_2(open, music_box)) {
+ sound_play(N_MusicBoxOn);
+ object_examine(magic_music_box, 843, 0);
+ sound_play(N_MusicBoxOff);
+ goto handled;
+ }
+
+ if (player_said_2(rub, bird_figurine)) {
+ object_examine(bird_figurine, 903, 0);
+ goto handled;
+ }
+
+ if (player_said_2(talk_to, bird_figurine)) {
+ object_examine(bird_figurine, 904, 0);
+ goto handled;
+ }
+
+ if (player_said_2(rub, birdcall)) {
+ object_examine(birdcall, 906, 0);
+ goto handled;
+ }
+
+ if (player_said_2(polish, shieldstone)) {
+ object_examine(shieldstone, 907, 0);
+ goto handled;
+ }
+
+ if (player_said_2(throw, shieldstone)) {
+ text_show(908);
+ goto handled;
+ }
+
+ if (player_said_1(heal)) {
+ if (player_said_1(Llanie) ||
+ player_said_1(MacMorn) ||
+ player_said_1(shak) ||
+ player_said_1(wise_shifter) ||
+ player_said_1(Roc) ||
+ player_said_1(shifting_monster)) {
+ text_show(927);
+ goto handled;
+ }
+ }
+
+ if (player_said_1(heal)) {
+ if (player_said_1(Queen_Mother) ||
+ player_said_1(stranger) ||
+ player_said_1(Ner_Tom) ||
+ player_said_1(hermit) ||
+ player_said_1(shifter)) {
+ text_show(927);
+ goto handled;
+ }
+ }
+
+ if (player_said_1(heal)) {
+ if (player_said_1(trader) ||
+ player_said_1(lizard) ||
+ player_said_1(faerie) ||
+ player_said_1(shaman) ||
+ player_said_1(guard) ||
+ player_said_1(shapechanger) ||
+ player_said_1(Soptus_Ecliptus) ||
+ player_said_1(merchant)) {
+ text_show(927);
+ goto handled;
+ }
+ }
+
+ if (player_said_1(heal)) {
+ if (player_said_1(rat) ||
+ player_said_1(Sanwe) ||
+ player_said_1(king) ||
+ player_said_1(guard_captain) ||
+ player_said_1(beast) ||
+ player_said_1(darkness_beast)) {
+ text_show(927);
+ goto handled;
+
+ } else {
+ text_show(928);
+ goto handled;
+ }
+ }
+
+ if (player_said_1(heal_self)) {
+ text_show(929);
+ goto handled;
+ }
+
+ if (player_said_2(fill, goblet)) {
+ if (player_said_1(soporific)) {
+ if (global[goblet_filled_soporific]) {
+ object_examine(goblet, 994, 0);
+ } else {
+ object_examine(goblet, 914, 0);
+ global[goblet_filled_soporific] = true;
+ }
+ } else if (player_said_1(flask_full_of_acid)) {
+ object_examine(flask_full_of_acid, 993, 0);
+ } else {
+ object_examine(goblet, 913, 0);
+ }
+ goto handled;
+ }
+
+ if (player_said_2(drink_from, goblet)) {
+ if (global[goblet_filled_soporific]) {
+ object_examine(goblet, 916, 0);
+ } else {
+ text_show(915);
+ }
+ goto handled;
+ }
+
+ if (player_said_2(gnaw, bone)) {
+ object_examine(bone, 918, 0);
+ goto handled;
+ }
+
+ if (player_said_2(eat, fruit)) {
+ object_examine(fruit, 919, 0);
+ goto handled;
+ }
+
+ if (player_said_2(throw, fruit)) {
+ object_examine(fruit, 921, 0);
+ goto handled;
+ }
+
+ if (player_said_2(play_with, doll)) {
+ object_examine(words_doll, 922, 0);
+ goto handled;
+ }
+
+ if (player_said_2(talk_to, doll)) {
+ object_examine(words_doll, 931, 0);
+ goto handled;
+ }
+
+ if (player_said_2(open, doll)) {
+ object_examine(words_doll, 932, 0);
+ goto handled;
+ }
+
+ if (player_said_1(polystone)) {
+ if (player_said_1(push) || player_said_1(pull)) {
+ object_examine(polystone, 934, 0);
+ goto handled;
+ }
+ }
+
+ if (player_said_2(wear, key_crown)) {
+ object_examine(key_crown, 936, 0);
+ goto handled;
+ }
+
+ if (player_said_2(eat, dates)) {
+ text_show(938);
+ goto handled;
+ }
+
+ if (player_said_2(polish, statue)) {
+ object_examine(statue, 939, 0);
+ goto handled;
+ }
+
+ if (player_said_2(listen_to, flies)) {
+ sound_play(N_ListenToFlies);
+ text_show(940);
+ goto handled;
+ }
+
+ if (player_said_2(open, flies)) {
+ text_show(941);
+ goto handled;
+ }
+
+ if (player_said_2(talk_to, flies)) {
+ text_show(942);
+ goto handled;
+ }
+
+ if (player_said_2(break, soul_egg)) {
+ object_examine(soul_egg, 943, 0);
+ goto handled;
+ }
+
+ if (player_said_2(adjust, magic_belt)) {
+ object_examine(magic_belt, 944, 0);
+ goto handled;
+ }
+
+ if (player_said_2(feel, mud)) {
+ text_show(947);
+ goto handled;
+ }
+
+ if (player_said_2(taste, mud)) {
+ text_show(948);
+ goto handled;
+ }
+
+ if (player_said_2(throw, mud)) {
+ text_show(949);
+ goto handled;
+ }
+
+ if (player_said_2(feel, feathers)) {
+ text_show(950);
+ goto handled;
+ }
+
+ if (player_said_3(put, feathers, bone)) {
+ if (player_has(feathers) && player_has(bone)) {
+ inter_move_object(feathers, NOWHERE);
+ inter_move_object(bone, NOWHERE);
+ inter_give_to_player(partly_built_bundle);
+ object_examine(partly_built_bundle, 952, 0);
+ goto handled;
+ }
+ }
+
+ if (player_said_2(wave, torch)) {
+ text_show(953);
+ goto handled;
+ }
+
+ if (player_said_2(throw, torch)) {
+ text_show(954);
+ goto handled;
+ }
+
+ if (player_said_2(polish, flask)) {
+ text_show(955);
+ goto handled;
+ }
+
+ if (player_said_2(open, flask_full_of_acid)) {
+ text_show(956);
+ goto handled;
+ }
+
+ if (player_said_2(drink, flask_full_of_acid)) {
+ text_show(957);
+ goto handled;
+ }
+
+ if (player_said_2(pour, flask_full_of_acid)) {
+ text_show(958);
+ goto handled;
+ }
+
+ if (player_said_2(throw, flask_full_of_acid)) {
+ text_show(959);
+ goto handled;
+ }
+
+ if (player_said_2(tie, rope)) {
+ text_show(960);
+ goto handled;
+ }
+
+ if (player_said_2(vortex_stone, take_magic_from)) {
+ if (player_said_1(signet_ring) ||
+ player_said_1(bird_figurine) ||
+ player_said_1(birdcall) ||
+ player_said_1(shieldstone) ||
+ player_said_1(key_crown) ||
+ player_said_1(polystone) ||
+ player_said_1(red_stone) ||
+ player_said_1(blue_stone) ||
+ player_said_1(yellow_stone) ||
+ player_said_1(soul_egg) ||
+ player_said_1(magic_belt) ||
+ player_said_1(crystal_ball) ||
+ player_said_1(shifter_ring)) {
+
+ text_show(962);
+ goto handled;
+ /* then what good would it do you */
+ }
+ }
+
+ if (player_said_2(vortex_stone, take_magic_from)) {
+ if (player_said_1(signet_ring) ||
+ player_said_1(doll) ||
+ player_said_1(door_frame) ||
+ player_said_1(new_bundle) ||
+ player_said_1(tower_door) ||
+ player_said_1(vortex_stone) ||
+ player_said_1(spirit_bundle) ||
+ player_said_1(freezer) ||
+ player_said_1(music_box) ||
+ player_said_1(amulet)) {
+
+ text_show(962);
+ goto handled;
+ /* then what good would it do you */
+ }
+ }
+
+
+ if (player_said_2(vortex_stone, take_magic_from)) {
+ if ((player_said_1(cave) && room_id == 203) ||
+ (player_said_1(torch) && player.second_object_source != STROKE_INTERFACE) ||
+ (player_said_1(torch) && room_id == 607) ||
+ (player_said_1(torch) && room_id == 609) ||
+ player_said_1(teleport_door)) {
+
+ text_show(962);
+ /* then what good would it do you */
+
+ } else if (player_said_1(eye) ||
+ player_said_1(floating_disk) ||
+ player_said_1(spirit_plane) ||
+ player_said_1(waterfall) ||
+ player_said_1(darkness_beast) ||
+ player_said_1(ward) ||
+ player_said_1(teleportal) ||
+ player_said_1(tangle) ||
+ player_said_1(Roc) ||
+ player_said_1(Dragonsphere) ||
+ player_said_1(spell_shield) ||
+ player_said_1(glowing_floor) ||
+ (player_said_1(pedestal) && room_id == 116) ||
+ player_said_1(circle_of_spheres)) {
+
+ text_show(963);
+ /* too strong it fails */
+
+ } else {
+ text_show(961);
+ }
+ goto handled;
+ }
+
+ if (player_said_2(pet, dead_rat)) {
+ object_examine(dead_rat, 964, 0);
+ goto handled;
+ }
+
+ if (player_said_2(open, dead_rat)) {
+ text_show(965);
+ goto handled;
+ }
+
+ if (player_said_2(fold, map)) {
+ text_show(966);
+ goto handled;
+ }
+
+ if (player_said_2(gaze_into, crystal_ball)) {
+ object_examine(crystal_ball, 967, 0);
+ goto handled;
+ }
+
+ if (player_said_2(talk_to, crystal_ball)) {
+ object_examine(crystal_ball, 971, 0);
+ goto handled;
+ }
+
+ if (player_said_2(polish, black_sphere)) {
+ object_examine(black_sphere, 972, 0);
+ goto handled;
+ }
+
+ if (player_said_2(drink, soporific)) {
+ text_show(973);
+ goto handled;
+ }
+
+ if (player_said_1(shake)) {
+ if (idd == partly_built_bundle) {
+ text_show(976);
+
+ } else if (idd == medicine_bundle ||
+ idd == new_bundle) {
+ if (game.difficulty == HARD_MODE) {
+ text_show(974);
+
+ } else {
+ text_show(975);
+ }
+ }
+ goto handled;
+ }
+
+ if (player_said_2(lick, ratsicle)) {
+ text_show(979);
+ goto handled;
+ }
+
+ if (player_said_2(chew, tentacle_parts)) {
+ text_show(980);
+ goto handled;
+ }
+
+ if (player_said_2(put, tentacle_parts)) {
+
+ if (id == tentacle_parts) {
+ text_show(23);
+
+ } else {
+ text_show(981);
+ }
+ goto handled;
+ }
+
+ if (player_said_2(unroll, teleport_door)) {
+ text_show(982);
+ goto handled;
+ }
+
+ if (player_said_1(admire)) {
+ text_show(984);
+ goto handled;
+ }
+
+
+ if (player_said_2(make_noise, birdcall)) {
+ if (global[shak_status] == SHAK_MET) {
+ sound_play(N_BlowBirdCall);
+ text_show(50621);
+ } else if (player_has_been_in_room(509)) {
+ sound_play(N_BlowBirdCall);
+ text_show(992);
+ } else if (global[player_persona] == PLAYER_IS_KING) {
+ sound_play(N_BlowBirdCall);
+ text_show(991);
+ } else {
+ sound_play(N_BlowBirdCall);
+ text_show(992);
+ }
+ goto handled;
+ }
+
+ if (player_said_2(look, new_bundle)) {
+ object_examine(new_bundle, 890, 0);
+ goto handled;
+ }
+
+ if (player_said_1(look) && player_has(object_named(player_main_noun))) {
+ global_object_examine();
+ goto handled;
+ }
+
+ if (player_said_2(invoke, amulet)) {
+ if (global[amulet_status] == AMULET_NOT_CORRECT_TIME) {
+ object_examine(amulet, 945, 0);
+ }
+ goto handled;
+ }
+
+ if (player_said_2(thrust, sword) ||
+ player_said_2(carve_up, sword) ||
+ player_said_2(attack, sword)) {
+
+ if (player_said_1(bird_figurine) && player_has(bird_figurine)) {
+
+ inter_move_object(bird_figurine, NOWHERE);
+ inter_give_to_player(birdcall);
+ object_examine(birdcall, 912, 0);
+
+ } else {
+ text_show(911);
+ }
+ goto handled;
+ }
+
+ if (player_said_1(shift_into_bear) || player_said_1(shift_into_seal) ||
+ player_said_1(shift_into_snake)) {
+ text_show(988);
+ goto handled;
+ }
+
+ if (player_said_1(revert)) {
+ text_show(989);
+ goto handled;
+ }
+
+ if (player_said_2(invoke, signet_ring)) {
+ if (room_id == 408 || room_id == 409 || room_id == 410 || room_id == 411) {
+ text_show(702);
+ } else if (room_id == 110) {
+ text_show(996);
+ } else {
+ text_show(900);
+ global[desert_counter] = 0;
+ global[move_direction_510] = true;
+ new_room = 110;
+ }
+ goto handled;
+ }
+
+ if (player_said_2(speak_words_on, parchment)) {
+ text_show(985);
+ goto handled;
+ }
+
+ if (player_said_2(invoke_power_of, crystal_ball)) {
+ object_examine(crystal_ball, 969, 0);
+ goto handled;
+ }
+
+ goto done;
+
+handled:
+ player.command_ready = false;
+
+done:
+ ;
+}
+
+void DragonsphereEngine::global_object_examine() {
}
diff --git a/engines/mads/madsv2/dragonsphere/dragonsphere.h b/engines/mads/madsv2/dragonsphere/dragonsphere.h
index 5a9233b2a23..f5a6e873c59 100644
--- a/engines/mads/madsv2/dragonsphere/dragonsphere.h
+++ b/engines/mads/madsv2/dragonsphere/dragonsphere.h
@@ -31,6 +31,7 @@ namespace Dragonsphere {
class DragonsphereEngine : public MADSV2Engine {
private:
static void global_object_sprite();
+ static void global_object_examine();
static void stop_walker_basic();
static void stop_walker_tricks();
diff --git a/engines/mads/madsv2/dragonsphere/mads/inventory.h b/engines/mads/madsv2/dragonsphere/mads/inventory.h
index c27759a7a40..85d4fc9bf2c 100644
--- a/engines/mads/madsv2/dragonsphere/mads/inventory.h
+++ b/engines/mads/madsv2/dragonsphere/mads/inventory.h
@@ -29,38 +29,44 @@ namespace MADSV2 {
namespace Dragonsphere {
enum {
- bird_figurine = 1,
- shieldstone = 3,
- sword = 4,
- goblet = 5,
- bone = 6,
- fruit = 7,
- pid_doll = 8,
- polystone = 9,
- red_powerstone = 10,
- yellow_powerstone= 11,
- blue_powerstone = 12,
- key_crown = 13,
- dates = 14,
- statue = 15,
- bottle_of_flies = 16,
- soul_egg = 17,
- magic_belt = 18,
- amulet = 19,
- crystal_ball = 29,
- black_sphere = 30,
- soptus_soporific = 31,
- shifter_ring = 32,
- medicine_bundle = 33,
- tentacle_parts = 36,
- rare_coin = 38,
- crystal_flower = 39,
- ruby_ring = 41,
- gold_nugget = 42,
- magic_music_box = 43,
- emerald = 44,
- piece_of_paper = 45,
- new_bundle = 48
+ signet_ring = 0,
+ bird_figurine = 1,
+ birdcall = 2,
+ shieldstone = 3,
+ sword = 4,
+ goblet = 5,
+ bone = 6,
+ fruit = 7,
+ pid_doll = 8,
+ polystone = 9,
+ red_powerstone = 10,
+ yellow_powerstone = 11,
+ blue_powerstone = 12,
+ key_crown = 13,
+ dates = 14,
+ statue = 15,
+ bottle_of_flies = 16,
+ soul_egg = 17,
+ magic_belt = 18,
+ amulet = 19,
+ feathers = 21,
+ flask_full_of_acid = 24,
+ dead_rat = 27,
+ crystal_ball = 29,
+ black_sphere = 30,
+ soptus_soporific = 31,
+ shifter_ring = 32,
+ medicine_bundle = 33,
+ partly_built_bundle = 34,
+ tentacle_parts = 36,
+ rare_coin = 38,
+ crystal_flower = 39,
+ ruby_ring = 41,
+ gold_nugget = 42,
+ magic_music_box = 43,
+ emerald = 44,
+ piece_of_paper = 45,
+ new_bundle = 48
};
} // namespace Dragonsphere
diff --git a/engines/mads/madsv2/dragonsphere/mads/sounds.h b/engines/mads/madsv2/dragonsphere/mads/sounds.h
index 2e7d9469e62..02a14f9cc37 100644
--- a/engines/mads/madsv2/dragonsphere/mads/sounds.h
+++ b/engines/mads/madsv2/dragonsphere/mads/sounds.h
@@ -48,6 +48,7 @@ enum {
N_DogWhimper = 79,
N_BeastSnd = 80,
N_GrabKing = 82,
+ N_WaterBubbles = 86,
N_MagicDoorOpens = 88,
N_MagicDoorUnlocked = 89,
N_JumpDownWell = 93,
@@ -82,8 +83,12 @@ enum {
N_StepOnFloatingDisk = 77,
N_004CryOfDismay = 78,
- // Section 9
- N_AllFade = 1
+ // Section 9/General
+ N_AllFade = 1,
+ N_MusicBoxOn = 17,
+ N_MusicBoxOff = 18,
+ N_BlowBirdCall = 30,
+ N_ListenToFlies = 31
};
} // namespace Dragonsphere
diff --git a/engines/mads/madsv2/dragonsphere/mads/words.h b/engines/mads/madsv2/dragonsphere/mads/words.h
index a28974ecb45..64ebbdbe957 100644
--- a/engines/mads/madsv2/dragonsphere/mads/words.h
+++ b/engines/mads/madsv2/dragonsphere/mads/words.h
@@ -56,6 +56,7 @@ enum {
words_decoration = 41,
words_signet_ring = 46,
words_invoke = 47,
+ words_polish = 48,
words_bird_figurine = 50,
words_rub = 51,
words_birdcall = 52,
@@ -66,44 +67,71 @@ enum {
words_carve_up = 58,
words_goblet = 59,
words_fill = 60,
+ words_drink_from = 61,
words_bone = 62,
+ words_gnaw = 63,
words_fruit = 64,
+ words_eat = 65,
words_doll = 66,
+ words_play_with = 67,
words_heal = 68,
words_heal_self = 70,
+ words_polystone = 71,
+ words_mimic = 72,
words_key_crown = 76,
words_wear = 77,
words_dates = 78,
words_statue = 79,
words_bottle_of_flies = 80,
+ words_listen_to = 81,
words_soul_egg = 82,
- N_WaterBubbles = 86,
+ words_break = 83,
+ words_magic_belt = 84,
+ words_adjust = 85,
+ words_amulet = 86,
words_thrust = 87,
words_mud = 88,
+ words_feel = 89,
+ words_taste = 90,
+ words_feathers = 91,
words_torch = 93,
+ words_wave = 94,
+ words_flask = 95,
words_flask_full_of_acid = 96,
words_pour = 98,
words_pour_contents_of = 99,
+ words_drink = 100,
words_rope = 101,
words_tie = 102,
words_take_magic_from = 104,
words_dead_rat = 105,
+ words_pet = 106,
+ words_map = 107,
+ words_fold = 108,
words_crystal_ball = 109,
words_gaze_into = 110,
words_invoke_power_of = 111,
words_black_sphere = 112,
words_soptus_soporific = 113,
+ words_shifter_ring = 114,
words_shift_into_bear = 116,
words_shift_into_seal = 117,
words_shift_into_snake = 118,
words_revert = 119,
+ words_shake = 121,
words_partly_built_bundle = 122,
words_ratsicle = 123,
+ words_lick = 124,
words_tentacle_parts = 125,
+ words_chew = 126,
+ words_teleport_door = 127,
+ words_unroll = 128,
words_rare_coin = 129,
+ words_admire = 130,
words_crystal_flower = 131,
words_emerald = 136,
words_speak_words_on = 138,
+ words_vortex_stone = 139,
words_touch = 146,
words_throne_room = 147,
words_passageway_to_west = 150,
@@ -155,6 +183,7 @@ enum {
words_bucket = 225,
words_jump_down = 226,
words_door_to_darkness = 228,
+ words_pedestal = 229,
words_door_to_north = 230,
words_painting = 231,
words_document = 232,
@@ -179,6 +208,7 @@ enum {
words_scullery_maid = 266,
words_ward = 268,
words_darkness_beast = 269,
+ words_beast = 270,
words_put_magic_into = 271,
words_guard = 272,
words_crown = 273,
@@ -189,6 +219,7 @@ enum {
words_shapechanger = 282,
words_red_stone = 283,
words_yellow_stone = 284,
+ words_blue_stone = 285,
words_flies = 286,
words_flask_of_acid = 287,
words_partial_bundle = 288,
@@ -202,6 +233,7 @@ enum {
words_firepit = 303,
words_spirit_bundle = 306,
words_path_to_east = 313,
+ words_waterfall = 314,
words_ledge = 317,
words_sconce = 329,
words_rock_tumble = 321,
@@ -217,10 +249,23 @@ enum {
words_grotto = 345,
words_climb_through = 346,
words_Queen_Mother = 347,
+ words_MacMorn = 350,
+ words_Llanie = 355,
+ words_hermit = 357,
+ words_shak = 359,
words_moon = 361,
words_eye = 368,
words_sit_on = 363,
+ words_stranger = 364,
+ words_tower_door = 365,
+ words_freezer = 388,
+ words_Ner_Tom = 399,
+ words_music_box = 414,
+ words_circle_of_spheres = 423,
+ words_rat = 426,
+ words_door_frame = 431,
words_teleportal = 440,
+ words_glowing_floor = 443,
words_Soptus_Ecliptus = 448,
words_Slathan_ni_Patan = 453,
words_spirit_plane = 457,
@@ -234,6 +279,8 @@ enum {
words_bones = 480,
words_tent = 481,
words_bush = 482,
+ words_Sanwe = 483,
+ words_tangle = 484,
words_sand = 485,
words_magic_grapes = 486,
words_grape_vine = 488,
Commit: 07298a76da8e1c003c393f9de30d4a9c5778e3f7
https://github.com/scummvm/scummvm/commit/07298a76da8e1c003c393f9de30d4a9c5778e3f7
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-05-22T06:45:45+10:00
Commit Message:
MADS: DRAGONSPHERE: Other global game functions
Changed paths:
engines/mads/madsv2/dragonsphere/dragonsphere.cpp
engines/mads/madsv2/dragonsphere/dragonsphere.h
engines/mads/madsv2/dragonsphere/mads/words.h
diff --git a/engines/mads/madsv2/dragonsphere/dragonsphere.cpp b/engines/mads/madsv2/dragonsphere/dragonsphere.cpp
index 9924c7cf1af..0355372d3c8 100644
--- a/engines/mads/madsv2/dragonsphere/dragonsphere.cpp
+++ b/engines/mads/madsv2/dragonsphere/dragonsphere.cpp
@@ -28,6 +28,7 @@
#include "mads/madsv2/core/inter.h"
#include "mads/madsv2/core/kernel.h"
#include "mads/madsv2/core/object.h"
+#include "mads/madsv2/core/pal.h"
#include "mads/madsv2/core/screen.h"
#include "mads/madsv2/core/sound.h"
#include "mads/madsv2/core/text.h"
@@ -261,89 +262,6 @@ void DragonsphereEngine::section_music(int section_num) {
}
}
-void DragonsphereEngine::global_object_sprite() {
- Common::strcpy_s(inter_object_buf, "*OB");
- env_catint(inter_object_buf, inter_object_id, 3);
- Common::strcat_s(inter_object_buf, "I");
-}
-
-void DragonsphereEngine::stop_walker_basic() {
- int random;
- int count;
- int how_many;
-
- random = imath_random(1, 30000);
-
- switch (player.facing) {
- case FACING_SOUTH:
- if (random < 500) {
- how_many = imath_random(4, 10);
- for (count = 0; count < how_many; count++) {
- player_add_stop_walker((random < 250) ? 1 : 2, 0);
- }
- } else if (random < 750) {
- for (count = 0; count < 4; count++) {
- player_add_stop_walker(1, 0);
- }
-
- player_add_stop_walker(0, 0);
-
- for (count = 0; count < 4; count++) {
- player_add_stop_walker(2, 0);
- }
-
- player_add_stop_walker(0, 0);
- }
- break;
-
- case FACING_SOUTHEAST:
- case FACING_SOUTHWEST:
- case FACING_NORTHEAST:
- case FACING_NORTHWEST:
- if (random < 150) {
- player_add_stop_walker(-1, 0);
- player_add_stop_walker(1, 0);
- for (count = 0; count < 6; count++) {
- player_add_stop_walker(0, 0);
- }
- }
- break;
-
- case FACING_EAST:
- case FACING_WEST:
- if (random < 250) {
- player_add_stop_walker(-1, 0);
- how_many = imath_random(2, 6);
- for (count = 0; count < how_many; count++) {
- player_add_stop_walker(2, 0);
- }
- player_add_stop_walker(1, 0);
- player_add_stop_walker(0, 0);
- player_add_stop_walker(0, 0);
- } else if (random < 500) {
- WRITE_LE_UINT32(&global[walker_timing], kernel.clock);
- }
- break;
-
- case FACING_NORTH:
- if (random < 250) {
- player_add_stop_walker(-1, 0);
- how_many = imath_random(3, 7);
- for (count = 0; count < how_many; count++) {
- player_add_stop_walker(2, 0);
- }
- player_add_stop_walker(1, 0);
- player_add_stop_walker(0, 0);
- }
- break;
-
- }
-}
-
-void DragonsphereEngine::stop_walker_tricks() {
-
-}
-
void DragonsphereEngine::global_section_constructor() {
Dragonsphere::global_section_constructor();
}
@@ -360,10 +278,8 @@ void DragonsphereEngine::global_daemon_code() {
if (player.walker_visible && (player.commands_allowed || (conv_control.running >= 0)) && !player.walking &&
(player.facing == player.turn_to_facing) && global[perform_displacements]) {
- if (kernel.clock >= *((long *)&global[walker_timing])) {
-
+ if (kernel.clock >= READ_LE_INT32(&global[walker_timing])) {
if (!player.stop_walker_pointer) {
-
random = imath_random(1, 30000);
if (global[player_persona] == PLAYER_IS_KING) {
@@ -1146,19 +1062,235 @@ done:
}
void DragonsphereEngine::global_object_examine() {
+ int id;
+
+ id = object_named(player_main_noun);
+
+ /* exceptions here */
+
+ if (player_said_1(music_box)) {
+ sound_play(N_MusicBoxOn);
+ }
+
+ if (player_said_1(doll)) {
+ if (global[player_persona] == PLAYER_IS_KING) {
+ object_examine(pid_doll, 808, 0);
+
+ } else { /* pid */
+ if (game.difficulty == EASY_MODE) {
+ if (global[pid_looked_at_doll]) {
+ object_examine(pid_doll, 896, 0);
+ } else {
+ object_examine(pid_doll, 895, 0);
+ global[pid_looked_at_doll] = true;
+ global[heal_verbs_visible] = true;
+ inter_move_object(pid_doll, NOWHERE);
+ inter_give_to_player(pid_doll);
+ }
+ } else {
+ if (global[pid_looked_at_doll]) {
+ object_examine(pid_doll, 896, 0);
+ } else {
+ object_examine(pid_doll, 706, 0);
+ global[pid_looked_at_doll] = true;
+ global[heal_verbs_visible] = true;
+ inter_move_object(pid_doll, NOWHERE);
+ inter_give_to_player(pid_doll);
+ }
+ }
+ }
+
+ } else if (player_said_1(polystone) && global[object_imitated] == -1) {
+ object_examine(polystone, 809, 0);
+
+ } else if (player_said_1(polystone) && global[object_imitated] == 9) {
+ object_examine(polystone, 809, 0);
+
+ } else if (player_said_1(polystone) && global[object_imitated] >= 0) {
+ object_examine(polystone, 894, 0);
+
+ } else if (player_said_1(medicine_bundle)) {
+ object_examine(medicine_bundle, 890, 0);
+
+ } else {
+ object_examine(id, 800 + id, 0);
+ }
+
+ if (player_said_1(music_box)) {
+ sound_play(N_MusicBoxOff);
+ }
}
void DragonsphereEngine::global_error_code() {
+ int show_me = 0;
+ int item;
+ int random;
+ random = imath_random(1, 1000);
+
+ if (player_said_3(put, king, pedestal)) {
+ if (global[king_status] != KING_CAPTIVE) {
+ text_show(43);
+ goto done;
+ }
+ }
+
+ if (player_said_1(take)) {
+ item = object_named(player_main_noun);
+ if (player_has(item) && player.main_object_source != STROKE_INTERFACE) {
+ show_me = 25;
+ /* player already has it */
+
+ } else {
+ if (random <= 333) {
+ show_me = 1;
+ } else if (random <= 666) {
+ show_me = 2;
+ } else {
+ show_me = 3;
+ }
+ }
+ goto done;
+ }
+
+ if (player_said_1(push)) {
+ if (random < 750) {
+ show_me = 4;
+ } else {
+ show_me = 5;
+ }
+ goto done;
+ }
+
+ if (player_said_1(pull)) {
+ if (random < 750) {
+ show_me = 6;
+ } else {
+ show_me = 7;
+ }
+ goto done;
+ }
+
+ if (player_said_1(open)) {
+ if (random <= 500) {
+ show_me = 8;
+ } else if (random <= 750) {
+ show_me = 9;
+ } else {
+ show_me = 10;
+ }
+ goto done;
+ }
+
+ if (player_said_1(close)) {
+ if (random <= 500) {
+ show_me = 11;
+ } else if (random <= 750) {
+ show_me = 12;
+ } else {
+ show_me = 13;
+ }
+ goto done;
+ }
+
+ if (player_said_1(put)) {
+ item = object_named(player_main_noun);
+ if (player_has(item)) {
+ show_me = 26;
+
+ } else if (player.main_object_source == STROKE_INTERFACE &&
+ player.second_object_source == STROKE_INTERFACE) {
+ show_me = 28;
+
+ } else if (random < 500) {
+ show_me = 14;
+
+ } else {
+ show_me = 15;
+ }
+ goto done;
+ }
+
+ if (player_said_1(talk_to)) {
+ if (random <= 500) {
+ show_me = 16;
+ } else {
+ show_me = 17;
+ }
+ goto done;
+ }
+
+ if (player_said_1(give)) {
+ item = object_named(player_main_noun);
+ if (player_has(item)) {
+ show_me = 27;
+
+ } else if (player.main_object_source == STROKE_INTERFACE &&
+ player.second_object_source == STROKE_INTERFACE) {
+ show_me = 28;
+
+ } else {
+ show_me = 18;
+ }
+ goto done;
+ }
+
+ if (player_said_1(throw)) {
+ item = object_named(player_main_noun);
+ if (player_has(item)) {
+ show_me = 19;
+ } else {
+ show_me = 28;
+ }
+ goto done;
+ }
+
+ if (player_said_1(look)) {
+ item = object_named(player_main_noun);
+ if (random <= 333) {
+ show_me = 20;
+ } else if (random <= 666) {
+ show_me = 21;
+ } else {
+ show_me = 22;
+ }
+ goto done;
+ }
+
+ if (!player_said_1(walk_to) && !player_said_1(walk_across) &&
+ !player_said_1(walk_down) && !player_said_1(walk_behind) &&
+ !player_said_1(cross)) {
+ if (random < 500) {
+ show_me = 23;
+ } else {
+ show_me = 24;
+ }
+ goto done;
+ }
+
+done:
+ if (show_me) text_show(show_me);
}
void DragonsphereEngine::global_room_init() {
+ switch (global[player_persona]) {
+ case PLAYER_IS_KING:
+ pal_change_color(KERNEL_MESSAGE_COLOR_BASE, 63, 0, 0);
+ pal_change_color(KERNEL_MESSAGE_COLOR_BASE + 1, 45, 0, 0);
+ break;
+ case PLAYER_IS_PID:
+ default:
+ pal_change_color(KERNEL_MESSAGE_COLOR_BASE, 63, 50, 42);
+ pal_change_color(KERNEL_MESSAGE_COLOR_BASE + 1, 45, 30, 20);
+ break;
+ }
}
void DragonsphereEngine::global_sound_driver() {
-
+ Common::strcpy_s(kernel.sound_driver, "/");
+ env_catint(kernel.sound_driver, new_section, 1);
}
} // namespace Dragonsphere
diff --git a/engines/mads/madsv2/dragonsphere/dragonsphere.h b/engines/mads/madsv2/dragonsphere/dragonsphere.h
index f5a6e873c59..d5e3f721170 100644
--- a/engines/mads/madsv2/dragonsphere/dragonsphere.h
+++ b/engines/mads/madsv2/dragonsphere/dragonsphere.h
@@ -30,10 +30,7 @@ namespace Dragonsphere {
class DragonsphereEngine : public MADSV2Engine {
private:
- static void global_object_sprite();
static void global_object_examine();
- static void stop_walker_basic();
- static void stop_walker_tricks();
public:
DragonsphereEngine(OSystem *syst, const MADSGameDescription *gameDesc) :
diff --git a/engines/mads/madsv2/dragonsphere/mads/words.h b/engines/mads/madsv2/dragonsphere/mads/words.h
index 64ebbdbe957..4230d44e59d 100644
--- a/engines/mads/madsv2/dragonsphere/mads/words.h
+++ b/engines/mads/madsv2/dragonsphere/mads/words.h
@@ -48,6 +48,7 @@ enum {
words_wall = 20,
words_window = 24,
words_tapestry = 26,
+ words_walk_behind = 28,
words_look_at = 30,
words_fireplace = 34,
words_fireplace_screen = 35,
@@ -118,6 +119,7 @@ enum {
words_shift_into_seal = 117,
words_shift_into_snake = 118,
words_revert = 119,
+ words_medicine_bundle = 120,
words_shake = 121,
words_partly_built_bundle = 122,
words_ratsicle = 123,
More information about the Scummvm-git-logs
mailing list