[Scummvm-git-logs] scummvm master -> 4e06fe50ff0b41f26a6ebbb951af128fffc72767
dreammaster
noreply at scummvm.org
Wed May 6 11:49:29 UTC 2026
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
4e06fe50ff MADS: DRAGONSPHERE: Added room 909 code
Commit: 4e06fe50ff0b41f26a6ebbb951af128fffc72767
https://github.com/scummvm/scummvm/commit/4e06fe50ff0b41f26a6ebbb951af128fffc72767
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-05-06T21:49:14+10:00
Commit Message:
MADS: DRAGONSPHERE: Added room 909 code
Changed paths:
engines/mads/madsv2/dragonsphere/rooms/room909.cpp
engines/mads/madsv2/dragonsphere/rooms/room909.h
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room909.cpp b/engines/mads/madsv2/dragonsphere/rooms/room909.cpp
index 115d623a184..afe3bebacab 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room909.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room909.cpp
@@ -19,12 +19,14 @@
*
*/
-#include "mads/madsv2/core/conv.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/matte.h"
#include "mads/madsv2/core/sound.h"
+#include "mads/madsv2/core/speech.h"
#include "mads/madsv2/core/text.h"
+#include "mads/madsv2/dragonsphere/dragonsphere.h"
#include "mads/madsv2/dragonsphere/global.h"
#include "mads/madsv2/dragonsphere/rooms/section9.h"
#include "mads/madsv2/dragonsphere/rooms/room909.h"
@@ -34,14 +36,134 @@ namespace MADSV2 {
namespace Dragonsphere {
namespace Rooms {
-//static Scratch scratch;
+static Scratch scratch;
void room_909_init() {
+ player.commands_allowed = 0;
+ player.walker_visible = 0;
+ viewing_at_y = 22;
+ kernel_init_dialog();
+ kernel_set_interface_mode(2);
+ scratch.x00 = kernel_load_series(kernel_name('x', 0), 0);
+ scratch.x02 = kernel_load_series(kernel_name('x', 1), 0);
+ scratch.x04 = kernel_load_series(kernel_name('x', 2), 0);
+
+ scratch.x1e = kernel_seq_forward(scratch.x00, false, 6, 0, 0, 0);
+ kernel_seq_depth(scratch.x1e, 12);
+ kernel_seq_range(scratch.x1e, -1, -2);
+
+ scratch.x20 = kernel_seq_forward(scratch.x02, false, 6, 0, 0, 0);
+ kernel_seq_depth(scratch.x20, 12);
+ kernel_seq_range(scratch.x20, -1, -2);
+
+ scratch.x22 = kernel_seq_forward(scratch.x04, false, 6, 0, 0, 0);
+ kernel_seq_depth(scratch.x22, 12);
+ kernel_seq_range(scratch.x22, -1, -2);
+
+ scratch.x3c = kernel_run_animation(kernel_name('w', 1), 0);
+
+ section_9_music();
+}
+
+/**
+ * Monitors the 'w' animation for frame transitions and dispatches
+ * sound/timing effects at specific frames. When a looping reset is
+ * needed (var_2 >= 0) the animation is jumped back and the frame
+ * tracker is updated so the next call does not re-fire.
+ *
+ * Called once per tick from room_909_daemon.
+ */
+static void room_909_anim() {
+ int16 var_2;
+ int cur_frame = kernel_anim[scratch.x3c].frame;
+
+ if (cur_frame == scratch.x44)
+ return;
+
+ var_2 = -1;
+ scratch.x44 = (int16)cur_frame;
+
+ // Frame dispatch (ascending subtraction chain, mirroring original assembly)
+ if (cur_frame == FRAME_LOOP_RESET) {
+ // Frame 106: reset animation back to frame 105 so it loops continuously
+ var_2 = FRAME_TIMING_TRIGGER;
+
+ } else if (cur_frame < FRAME_LOOP_RESET) {
+ int remaining = cur_frame;
+
+ remaining -= FRAME_HEARTBEAT_SOUND; // 52
+ if (remaining == 0) {
+ // Frame 52: play speech line 1 if speech system is active and enabled;
+ // otherwise play the sound-effect fallback.
+ // (word_845AE = speech_system_active, word_842A8 = speech_on,
+ // byte_106AF+9 = overlay thunk â global_speech_go)
+ if (speech_system_active && speech_on)
+ global_speech_go(1);
+ else
+ sound_play(61);
+ goto apply;
+ }
+
+ remaining -= 30; // 52+30 = 82
+ if (remaining == 0) {
+ // Frame 82: play music sting only when music is enabled
+ if (g_engine->_musicFlag)
+ sound_play(60);
+ goto apply;
+ }
+
+ remaining -= 23; // 52+30+23 = 105
+ if (remaining == 0) {
+ // Frame 105: arm the 2-second delay before showing the score screen
+ kernel_timing_trigger(120, TRIGGER_SHOW_SCORE);
+ goto apply;
+ }
+ // All other frames: no action, var_2 stays -1
+ }
+ // cur_frame > FRAME_LOOP_RESET: no action
+
+apply:
+ if (var_2 >= 0) {
+ kernel_reset_animation(scratch.x3c, var_2);
+ scratch.x44 = var_2;
+ }
}
void room_909_daemon() {
+ room_909_anim();
+
+ if (kernel.trigger != TRIGGER_SHOW_SCORE)
+ return;
+
+ // Clamp score to maximum of 250
+ int score = global[player_score];
+ if (score > 250)
+ score = 250;
+
+ // Populate text_index[] before calling text_show(99) so the score-screen
+ // text can substitute the values via [INDEX N] commands.
+ // text_index[0] = current score (word_86A44 in original DS data segment)
+ // text_index[1] = maximum score (word_86A46)
+ // text_index[2] = rank tier 1-9 (word_86A48)
+ text_index[1] = 250;
+ text_index[0] = score;
+
+ // Determine rank tier (mirrors Phantom room250 score screen but adds tier 9)
+ int tier;
+ if (score <= 25) tier = 1;
+ else if (score <= 50) tier = 2;
+ else if (score <= 75) tier = 3;
+ else if (score <= 100) tier = 4;
+ else if (score <= 150) tier = 5;
+ else if (score <= 200) tier = 6;
+ else if (score <= 249) tier = 7;
+ else if (score <= 250) tier = 8; // exactly 250
+ else tier = 9; // unreachable in normal play
+
+ text_index[2] = tier;
+ text_show(99);
}
void room_909_pre_parser() {
@@ -51,14 +173,21 @@ void room_909_parser() {
}
void room_909_synchronize(Common::Serializer &s) {
-
+ s.syncAsSint16LE(scratch.x00);
+ s.syncAsSint16LE(scratch.x02);
+ s.syncAsSint16LE(scratch.x04);
+ s.syncAsSint16LE(scratch.x1e);
+ s.syncAsSint16LE(scratch.x20);
+ s.syncAsSint16LE(scratch.x22);
+ s.syncAsSint16LE(scratch.x3c);
+ s.syncAsSint16LE(scratch.x44);
}
void room_909_preload() {
- room_init_code_pointer = room_909_init;
+ room_init_code_pointer = room_909_init;
room_pre_parser_code_pointer = room_909_pre_parser;
- room_parser_code_pointer = room_909_parser;
- room_daemon_code_pointer = room_909_daemon;
+ room_parser_code_pointer = room_909_parser;
+ room_daemon_code_pointer = room_909_daemon;
section_9_walker();
section_9_interface();
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room909.h b/engines/mads/madsv2/dragonsphere/rooms/room909.h
index 3733e8ed6a8..a1d644ed8e3 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room909.h
+++ b/engines/mads/madsv2/dragonsphere/rooms/room909.h
@@ -36,12 +36,53 @@ namespace Rooms {
#define aa local->animation
/**
- * Room local variables
+ * Room local variables (field names encode game.scratch byte offsets).
+ *
+ * Layout verified against disassembly of room_909_init / room_909_anim:
+ * x00 = game.scratch+0x00 series handle: kernel_name('x', 0)
+ * x02 = game.scratch+0x02 series handle: kernel_name('x', 1)
+ * x04 = game.scratch+0x04 series handle: kernel_name('x', 2)
+ * x1e = game.scratch+0x1E seq handle: forward sequence for series x0
+ * x20 = game.scratch+0x20 seq handle: forward sequence for series x1
+ * x22 = game.scratch+0x22 seq handle: forward sequence for series x2
+ * x3c = game.scratch+0x3C animation handle: kernel_name('w', 1)
+ * x44 = game.scratch+0x44 last observed animation frame (change detector)
*/
struct Scratch {
-
+ int16 x00; // sprite series: kernel_name('x', 0)
+ int16 x02; // sprite series: kernel_name('x', 1)
+ int16 x04; // sprite series: kernel_name('x', 2)
+ int16 _pad06[12]; // offsets 0x06..0x1C (unused in this room)
+ int16 x1e; // seq: forward play of series x0, depth 12, range [-1..-2]
+ int16 x20; // seq: forward play of series x1, depth 12, range [-1..-2]
+ int16 x22; // seq: forward play of series x2, depth 12, range [-1..-2]
+ int16 _pad24[12]; // offsets 0x24..0x3B (unused in this room)
+ int16 x3c; // animation handle: kernel_name('w', 1)
+ int16 _pad3e[3]; // offsets 0x3E..0x43 (unused in this room)
+ int16 x44; // last observed animation frame (for frame-change detection)
};
+
+/* ========================= Triggers ======================== */
+
+#define TRIGGER_SHOW_SCORE 61 // fired by kernel_timing_trigger after frame 105; daemon shows score screen
+
+
+/* ======================== Anim frames ====================== */
+
+#define FRAME_HEARTBEAT_SOUND 52 // 0x34: play speech line 1 (or sound fallback)
+#define FRAME_MUSIC_SOUND 82 // 0x52: play music sound (60) if music enabled
+#define FRAME_TIMING_TRIGGER 105 // 0x69: arm 2-second delay for TRIGGER_SHOW_SCORE
+#define FRAME_LOOP_RESET 106 // 0x6A: reset animation to FRAME_TIMING_TRIGGER
+
+
+extern void room_909_preload();
+extern void room_909_init();
+extern void room_909_daemon();
+extern void room_909_pre_parser();
+extern void room_909_parser();
+extern void room_909_synchronize(Common::Serializer &s);
+
} // namespace Rooms
} // namespace Dragonsphere
} // namespace MADSV2
More information about the Scummvm-git-logs
mailing list