[Scummvm-git-logs] scummvm master -> 192bf3dad1325fd79e0a6b0a1db28beb5184eb97

dreammaster noreply at scummvm.org
Thu May 21 09:36:29 UTC 2026


This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .

Summary:
cdce5c4c5f MADS: DRAGONSPHERE: Added room 407
7b97ae1076 MADS: DRAGONSPHERE: Added room 408
192bf3dad1 MADS: DRAGONSPHERE: Added rooms 409 to 454


Commit: cdce5c4c5f6cc8761360dc71f292bae5c3302b28
    https://github.com/scummvm/scummvm/commit/cdce5c4c5f6cc8761360dc71f292bae5c3302b28
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-05-21T19:34:50+10:00

Commit Message:
MADS: DRAGONSPHERE: Added room 407

Changed paths:
    engines/mads/madsv2/dragonsphere/mads/conv.h
    engines/mads/madsv2/dragonsphere/mads/sounds.h
    engines/mads/madsv2/dragonsphere/mads/words.h
    engines/mads/madsv2/dragonsphere/rooms/room402.cpp
    engines/mads/madsv2/dragonsphere/rooms/room407.cpp


diff --git a/engines/mads/madsv2/dragonsphere/mads/conv.h b/engines/mads/madsv2/dragonsphere/mads/conv.h
index a22195d1d6e..e5fd88bb63d 100644
--- a/engines/mads/madsv2/dragonsphere/mads/conv.h
+++ b/engines/mads/madsv2/dragonsphere/mads/conv.h
@@ -270,6 +270,14 @@ enum {
 	conv049_polyquiz_b_b     = 33
 };
 
+enum {
+	conv050_exit_b_b         =  8,
+	conv050_branch           =  9,
+	conv050_answers_yes      = 16,
+	conv050_answers_rulesask = 18,
+	conv050_exit_d_d         = 20
+};
+
 enum {
 	conv051_nopass           = 0,
 	conv051_exit_b_b         = 3
diff --git a/engines/mads/madsv2/dragonsphere/mads/sounds.h b/engines/mads/madsv2/dragonsphere/mads/sounds.h
index 2ffc628a86f..b845dc3a9fc 100644
--- a/engines/mads/madsv2/dragonsphere/mads/sounds.h
+++ b/engines/mads/madsv2/dragonsphere/mads/sounds.h
@@ -73,7 +73,8 @@ enum {
 	N_WindWhistles       =  29,
 	N_Bk404Music         =  33,
 	N_Bk406Music         =  35,
-	N_BellyDanceMusic    =  36
+	N_BellyDanceMusic    =  36,
+	N_GamePieceSnd       =  66
 };
 
 } // namespace Dragonsphere
diff --git a/engines/mads/madsv2/dragonsphere/mads/words.h b/engines/mads/madsv2/dragonsphere/mads/words.h
index dd739c35f71..e2ae68dc276 100644
--- a/engines/mads/madsv2/dragonsphere/mads/words.h
+++ b/engines/mads/madsv2/dragonsphere/mads/words.h
@@ -180,6 +180,8 @@ enum {
 	words_guard_captain        = 280,
 	words_merchant             = 281,
 	words_shapechanger         = 282,
+	words_red_stone            = 283,
+	words_yellow_stone         = 284,
 	words_flies                = 286,
 	words_flask_of_acid        = 287,
 	words_partial_bundle       = 288,
@@ -237,6 +239,9 @@ enum {
 	words_nose_rock            = 513,
 	words_new_bundle           = 514,
 	words_lizard               = 515,
+	words_select               = 518,
+	words_purple_stone         = 520,
+	words_green_stone          = 521,
 	words_path                 = 522,
 	words_guards               = 523,
 	words_eye_rock             = 533,
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room402.cpp b/engines/mads/madsv2/dragonsphere/rooms/room402.cpp
index c43cec4ee89..d493ef96746 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room402.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room402.cpp
@@ -585,7 +585,7 @@ static void room_402_pre_parser() {
 static void room_402_parser() {
 	int count;
 	int count2 = global[oasis] - 1;
-	int room = 400;
+	int roomNum = 400;
 
 	if (player_said_1(cross)) {
 		if (player_said_1(desert_to_north) || player_said_1(desert_to_south)) {
@@ -599,13 +599,13 @@ static void room_402_parser() {
 			}
 
 			for (count = 0; count < 77; count++) {
-				++room; if (room == 404) room = 401;
+				++roomNum; if (roomNum == 404) roomNum = 401;
 				++count2; if (count2 == 78) count2 = 1;
 
 				if (count2 == global[desert_room]) {
-					if (global[desert_room] == 42)                 room = 401;
-					if (global[desert_room] == global[oasis])      room = 454;
-					if (global[desert_room] == global[fire_holes]) room = 412;
+					if (global[desert_room] == 42)                 roomNum = 401;
+					if (global[desert_room] == global[oasis])      roomNum = 454;
+					if (global[desert_room] == global[fire_holes]) roomNum = 412;
 					goto over;
 				}
 			}
@@ -620,11 +620,11 @@ over:
 			} else if (global[desert_counter] == 6 && !player_has_been_in_room(405)) {
 				new_room = 404;
 
-			} else if (room_id == room) {
+			} else if (room_id == roomNum) {
 				kernel.force_restart = true;
 
 			} else {
-				new_room = room;
+				new_room = roomNum;
 			}
 			goto handled;
 		}
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room407.cpp b/engines/mads/madsv2/dragonsphere/rooms/room407.cpp
index 0301552736d..b32e42b4e57 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room407.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room407.cpp
@@ -22,7 +22,10 @@
 #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/mouse.h"
+#include "mads/madsv2/core/object.h"
 #include "mads/madsv2/core/sound.h"
 #include "mads/madsv2/core/text.h"
 #include "mads/madsv2/dragonsphere/mads/conv.h"
@@ -39,6 +42,37 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[15];       /* Sprite series handles */
+	int16 sequence[15];     /* Sequence handles      */
+	int16 animation[5];     /* Animation handles     */
+
+	char his_score[3];
+	char my_score[3];
+
+	int8 his_score_int;
+	int8 my_score_int;
+
+	int16 his_score_id;
+	int16 my_score_id;
+
+	int16 highlighting;
+	int16 prevent;
+	int16 final_choice;
+
+	int16 number_of_spins;
+	int16 last_spin;
+	int16 dealt;
+
+	int16 num_of_red;
+	int16 num_of_yellow;
+	int16 num_of_green;
+	int16 num_of_purple;
+
+	int16 whos_turn;
+	int16 var_to_conv;
+
+	byte stuff_to_give[5];
+	int16 will_give;
 };
 
 #define local (&scratch)
@@ -46,26 +80,800 @@ struct Scratch {
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
 
-void room_407_init() {
+/* ========================= Sprite Series =================== */
+
+#define fx_half_bottle          0       /* rm407p0  */
+#define fx_red_abs              1       /* rm411x0  */
+#define fx_yellow_abs           2       /* rm411x1  */
+#define fx_green_abs            3       /* rm411x2  */
+#define fx_purple_abs           4       /* rm411x3  */
+
+#define fx_red_sel              5       /* rm411g0  */
+#define fx_yellow_sel           6       /* rm411g1  */
+#define fx_green_sel            7       /* rm411g2  */
+#define fx_purple_sel           8       /* rm411g3  */
+
+#define fx_face                 9       /* facepid  */
+#define fx_face2                10      /* facepid  */
+
+
+/* ========================= Triggers ======================== */
+
+#define ROOM_407_RUN_CONV       60
+#define ROOM_407_SPIN           70
+#define ROOM_407_ME_TALK        75
+#define ROOM_407_YOU_TALK       77
+#define ROOM_407_CAL_PICK       79
+
+/* ========================== Other ========================== */
+
+#define CONV_50_GAME            50
+
+#define HIS_TURN                0
+#define MY_TURN                 1
+
+#define NOT_THERE               0
+#define CAN_GIVE                1
+#define HOSIED                  2
+
+static Scratch scratch;
 
+
+static void update_scores() {
+	Common::strcpy_s(local->his_score, "\0");
+
+	kernel_message_purge();
+
+	switch (local->his_score_int) {
+	case 0: Common::strcpy_s(local->his_score, "0\0"); break;
+	case 1: Common::strcpy_s(local->his_score, "1\0"); break;
+	case 2: Common::strcpy_s(local->his_score, "2\0"); break;
+	case 3: Common::strcpy_s(local->his_score, "3\0"); break;
+	case 4: Common::strcpy_s(local->his_score, "4\0"); break;
+	case 5: Common::strcpy_s(local->his_score, "5\0"); break;
+	case 6: Common::strcpy_s(local->his_score, "6\0"); break;
+	case 7: Common::strcpy_s(local->his_score, "7\0"); break;
+	case 8: Common::strcpy_s(local->his_score, "8\0"); break;
+	case 9: Common::strcpy_s(local->his_score, "9\0"); break;
+	case 10: Common::strcpy_s(local->his_score, "10\0"); break;
+	case 11: Common::strcpy_s(local->his_score, "11\0"); break;
+	case 12: Common::strcpy_s(local->his_score, "12\0"); break;
+	case 13: Common::strcpy_s(local->his_score, "13\0"); break;
+	case 14: Common::strcpy_s(local->his_score, "14\0"); break;
+	case 15: Common::strcpy_s(local->his_score, "15\0"); break;
+	case 16: Common::strcpy_s(local->his_score, "16\0"); break;
+	case 17: Common::strcpy_s(local->his_score, "17\0"); break;
+	case 18: Common::strcpy_s(local->his_score, "18\0"); break;
+	case 19: Common::strcpy_s(local->his_score, "19\0"); break;
+	case 20: Common::strcpy_s(local->his_score, "20\0"); break;
+	case 21: Common::strcpy_s(local->his_score, "21\0"); break;
+	case 22: Common::strcpy_s(local->his_score, "22\0"); break;
+	case 23: Common::strcpy_s(local->his_score, "23\0"); break;
+	case 24: Common::strcpy_s(local->his_score, "24\0"); break;
+	case 25: Common::strcpy_s(local->his_score, "25\0"); break;
+	case 26: Common::strcpy_s(local->his_score, "26\0"); break;
+	case 27: Common::strcpy_s(local->his_score, "27\0"); break;
+	}
+
+	switch (local->my_score_int) {
+	case 0: Common::strcpy_s(local->my_score, "0\0"); break;
+	case 1: Common::strcpy_s(local->my_score, "1\0"); break;
+	case 2: Common::strcpy_s(local->my_score, "2\0"); break;
+	case 3: Common::strcpy_s(local->my_score, "3\0"); break;
+	case 4: Common::strcpy_s(local->my_score, "4\0"); break;
+	case 5: Common::strcpy_s(local->my_score, "5\0"); break;
+	case 6: Common::strcpy_s(local->my_score, "6\0"); break;
+	case 7: Common::strcpy_s(local->my_score, "7\0"); break;
+	case 8: Common::strcpy_s(local->my_score, "8\0"); break;
+	case 9: Common::strcpy_s(local->my_score, "9\0"); break;
+	case 10: Common::strcpy_s(local->my_score, "10\0"); break;
+	case 11: Common::strcpy_s(local->my_score, "11\0"); break;
+	case 12: Common::strcpy_s(local->my_score, "12\0"); break;
+	case 13: Common::strcpy_s(local->my_score, "13\0"); break;
+	case 14: Common::strcpy_s(local->my_score, "14\0"); break;
+	case 15: Common::strcpy_s(local->my_score, "15\0"); break;
+	case 16: Common::strcpy_s(local->my_score, "16\0"); break;
+	case 17: Common::strcpy_s(local->my_score, "17\0"); break;
+	case 18: Common::strcpy_s(local->my_score, "18\0"); break;
+	case 19: Common::strcpy_s(local->my_score, "19\0"); break;
+	case 20: Common::strcpy_s(local->my_score, "20\0"); break;
+	case 21: Common::strcpy_s(local->my_score, "21\0"); break;
+	case 22: Common::strcpy_s(local->my_score, "22\0"); break;
+	case 23: Common::strcpy_s(local->my_score, "23\0"); break;
+	case 24: Common::strcpy_s(local->my_score, "24\0"); break;
+	case 25: Common::strcpy_s(local->my_score, "25\0"); break;
+	case 26: Common::strcpy_s(local->my_score, "26\0"); break;
+	case 27: Common::strcpy_s(local->my_score, "27\0"); break;
+	}
+
+	local->his_score_id = kernel_message_add(local->his_score,
+		59, 51, MESSAGE_COLOR, 999999, 0, KERNEL_MESSAGE_CENTER);
+
+	local->my_score_id = kernel_message_add(local->my_score,
+		260, 85, MESSAGE_COLOR, 999999, 0, KERNEL_MESSAGE_CENTER);
 }
 
-void room_407_daemon() {
+static void room_407_init() {
+	kernel_init_dialog();
+	kernel_set_interface_mode(INTER_LIMITED_SENTENCES);
+
+	if (previous_room != KERNEL_RESTORING_GAME) {
+		if (object[dates].location == 406)            local->stuff_to_give[0] = CAN_GIVE; else local->stuff_to_give[0] = NOT_THERE;
+		if (object[statue].location == 406)           local->stuff_to_give[1] = CAN_GIVE; else local->stuff_to_give[1] = NOT_THERE;
+		if (object[ruby_ring].location == 406)        local->stuff_to_give[2] = CAN_GIVE; else local->stuff_to_give[2] = NOT_THERE;
+		if (object[bottle_of_flies].location == 406)  local->stuff_to_give[3] = CAN_GIVE; else local->stuff_to_give[3] = NOT_THERE;
+		if (object[soptus_soporific].location == 406) local->stuff_to_give[4] = CAN_GIVE; else local->stuff_to_give[4] = NOT_THERE;
+
+		local->var_to_conv = 0;
+		local->his_score_int = 0;
+		local->my_score_int = 0;
+		local->number_of_spins = 0;
+		local->whos_turn = MY_TURN;
+		local->num_of_red = 12;
+		local->num_of_yellow = 12;
+		local->num_of_green = 12;
+		local->num_of_purple = 12;
+		local->highlighting = -1;
+		local->final_choice = -1;
+		local->last_spin = -1;
+		local->his_score_int = 0;
+		local->my_score_int = 0;
+		local->will_give = true;
+	}
+
+	if (global[player_persona] == PLAYER_IS_PID) {
+		ss[fx_face] = kernel_load_series("*FACEPID", false);
+		seq[fx_face] = kernel_seq_stamp(ss[fx_face], false, KERNEL_FIRST);
+		kernel_seq_depth(seq[fx_face], 1);
+		kernel_seq_loc(seq[fx_face], 260, 79);
+
+	} else {
+		ss[fx_face] = kernel_load_series("*FACEKING", false);
+		seq[fx_face] = kernel_seq_stamp(ss[fx_face], false, KERNEL_FIRST);
+		kernel_seq_depth(seq[fx_face], 1);
+		kernel_seq_loc(seq[fx_face], 260, 79);
+	}
+
+	ss[fx_face2] = kernel_load_series("*FACECAL", false);
+	seq[fx_face2] = kernel_seq_stamp(ss[fx_face2], false, KERNEL_FIRST);
+	kernel_seq_depth(seq[fx_face2], 1);
+	kernel_seq_loc(seq[fx_face2], 59, 45);
+
+	player.walker_visible = false;
+
+	local->prevent = false;
+
+	conv_get(CONV_50_GAME);
+
+	ss[fx_red_abs] = kernel_load_series(kernel_name('x', 0), false);
+	ss[fx_yellow_abs] = kernel_load_series(kernel_name('x', 1), false);
+	ss[fx_green_abs] = kernel_load_series(kernel_name('x', 2), false);
+	ss[fx_purple_abs] = kernel_load_series(kernel_name('x', 3), false);
+	ss[fx_red_sel] = kernel_load_series(kernel_name('g', 0), false);
+	ss[fx_yellow_sel] = kernel_load_series(kernel_name('g', 1), false);
+	ss[fx_green_sel] = kernel_load_series(kernel_name('g', 2), false);
+	ss[fx_purple_sel] = kernel_load_series(kernel_name('g', 3), false);
+
+
+	update_scores();
+
+	if (previous_room == KERNEL_RESTORING_GAME) {
+		switch (local->last_spin) {
+		case 1:
+			seq[fx_red_abs] = kernel_seq_stamp(ss[fx_red_abs], false, KERNEL_FIRST);
+			kernel_seq_depth(seq[fx_red_abs], 1);
+			kernel_seq_loc(seq[fx_red_abs], 159, 134);
+			break;
+
+		case 2:
+			seq[fx_yellow_abs] = kernel_seq_stamp(ss[fx_yellow_abs], false, KERNEL_FIRST);
+			kernel_seq_depth(seq[fx_yellow_abs], 1);
+			kernel_seq_loc(seq[fx_yellow_abs], 159, 134);
+			break;
 
+		case 3:
+			seq[fx_green_abs] = kernel_seq_stamp(ss[fx_green_abs], false, KERNEL_FIRST);
+			kernel_seq_depth(seq[fx_green_abs], 1);
+			kernel_seq_loc(seq[fx_green_abs], 159, 134);
+			break;
+
+		case 4:
+			seq[fx_purple_abs] = kernel_seq_stamp(ss[fx_purple_abs], false, KERNEL_FIRST);
+			kernel_seq_depth(seq[fx_purple_abs], 1);
+			kernel_seq_loc(seq[fx_purple_abs], 159, 134);
+			break;
+		}
+
+		switch (local->final_choice) {
+		case words_red_stone:
+			seq[fx_red_sel] = kernel_seq_stamp(ss[fx_red_sel], false, KERNEL_LAST);
+			kernel_seq_depth(seq[fx_red_sel], 1);
+			local->highlighting = words_red_stone;
+			break;
+
+		case words_yellow_stone:
+			seq[fx_yellow_sel] = kernel_seq_stamp(ss[fx_yellow_sel], false, KERNEL_LAST);
+			kernel_seq_depth(seq[fx_yellow_sel], 1);
+			local->highlighting = words_yellow_stone;
+			break;
+
+		case words_green_stone:
+			seq[fx_green_sel] = kernel_seq_stamp(ss[fx_green_sel], false, KERNEL_LAST);
+			kernel_seq_depth(seq[fx_green_sel], 1);
+			local->highlighting = words_green_stone;
+			break;
+
+		case words_purple_stone:
+			seq[fx_purple_sel] = kernel_seq_stamp(ss[fx_purple_sel], false, KERNEL_LAST);
+			kernel_seq_depth(seq[fx_purple_sel], 1);
+			local->highlighting = words_purple_stone;
+			break;
+		}
+	}
+
+	if (previous_room != KERNEL_RESTORING_GAME ||
+		conv_restore_running == CONV_50_GAME) {
+		conv_run(CONV_50_GAME);
+		conv_export_pointer(&global[wins_in_desert]);
+		conv_export_value(global[wins_till_prize]);
+		conv_export_value(local->will_give);
+		conv_export_value(local->var_to_conv);
+	}
+
+
+	section_4_music();
 }
 
-void room_407_pre_parser() {
+static void do_a_round() {
+	int new_spin;
+	int sum;
+
+	++local->number_of_spins;
+
+	if (local->number_of_spins > 1) switch (local->last_spin) {
+	case 1: kernel_seq_delete(seq[fx_red_abs]);    break;
+	case 2: kernel_seq_delete(seq[fx_yellow_abs]); break;
+	case 3: kernel_seq_delete(seq[fx_green_abs]);  break;
+	case 4: kernel_seq_delete(seq[fx_purple_abs]); break;
+	}
+
+	do
+		new_spin = imath_random(1, 4);
+	while (local->last_spin == new_spin);
+
+	local->last_spin = new_spin;
+
+	if (local->number_of_spins == 10) {
+		sum = local->num_of_red + local->num_of_yellow + local->num_of_green + local->num_of_purple;
+		local->last_spin = imath_random(1, sum);
+
+
+		if (local->last_spin <= (0 + local->num_of_red)) {
+			local->last_spin = 1;
+			--local->num_of_red;
+
+		} else if (local->last_spin <= (local->num_of_red + local->num_of_yellow)) {
+			local->last_spin = 2;
+			--local->num_of_yellow;
+
+		} else if (local->last_spin <= (local->num_of_red + local->num_of_yellow + local->num_of_green)) {
+			local->last_spin = 3;
+			--local->num_of_green;
+
+		} else {
+			local->last_spin = 4;
+			--local->num_of_purple;
+		}
+
+		kernel_timing_trigger(6, ROOM_407_RUN_CONV);
 
+	} else {
+		kernel_timing_trigger(6, ROOM_407_SPIN);
+	}
+
+	sound_play(N_GamePieceSnd);
+
+	switch (local->last_spin) {
+	case 1:
+		seq[fx_red_abs] = kernel_seq_stamp(ss[fx_red_abs], false, KERNEL_FIRST);
+		kernel_seq_depth(seq[fx_red_abs], 1);
+		kernel_seq_loc(seq[fx_red_abs], 159, 134);
+		break;
+
+	case 2:
+		seq[fx_yellow_abs] = kernel_seq_stamp(ss[fx_yellow_abs], false, KERNEL_FIRST);
+		kernel_seq_depth(seq[fx_yellow_abs], 1);
+		kernel_seq_loc(seq[fx_yellow_abs], 159, 134);
+		break;
+
+	case 3:
+		seq[fx_green_abs] = kernel_seq_stamp(ss[fx_green_abs], false, KERNEL_FIRST);
+		kernel_seq_depth(seq[fx_green_abs], 1);
+		kernel_seq_loc(seq[fx_green_abs], 159, 134);
+		break;
+
+	case 4:
+		seq[fx_purple_abs] = kernel_seq_stamp(ss[fx_purple_abs], false, KERNEL_FIRST);
+		kernel_seq_depth(seq[fx_purple_abs], 1);
+		kernel_seq_loc(seq[fx_purple_abs], 159, 134);
+		break;
+	}
 }
 
-void room_407_parser() {
+static void after_round_me() {
+	switch (local->final_choice) {
+
+	case words_red_stone:
+		switch (local->last_spin) {
+		case 4:
+			local->whos_turn = HIS_TURN;
+			local->var_to_conv = 3;
+			break;
+
+		default:
+			++local->my_score_int;
+			local->var_to_conv = 2;
+			break;
+		}
+		break;
+
+	case words_yellow_stone:
+		switch (local->last_spin) {
+		case 2:
+		case 3:
+			local->my_score_int += 2;
+			local->var_to_conv = 2;
+			break;
+
+		default:
+			local->whos_turn = HIS_TURN;
+			local->var_to_conv = 3;
+			break;
+		}
+		break;
+
+	case words_green_stone:
+		switch (local->last_spin) {
+		case 3:
+			local->my_score_int += 5;
+			local->var_to_conv = 2;
+			break;
 
+		default:
+			local->whos_turn = HIS_TURN;
+			local->var_to_conv = 3;
+			break;
+		}
+		break;
+
+	case words_purple_stone:
+		switch (local->last_spin) {
+		case 4:
+			local->my_score_int += 12;
+			local->var_to_conv = 2;
+			break;
+
+		default:
+			local->his_score_int += 2;
+			if (local->his_score_int > 15) local->his_score_int = 15;
+			local->whos_turn = HIS_TURN;
+			local->var_to_conv = 3;
+			break;
+		}
+		break;
+	}
+}
+
+static void after_round_him() {
+	switch (local->final_choice) {
+
+	case words_red_stone:
+		switch (local->last_spin) {
+		case 4:
+			local->whos_turn = MY_TURN;
+			local->var_to_conv = 5;
+			break;
+
+		default:
+			++local->his_score_int;
+			local->var_to_conv = 4;
+			break;
+		}
+		break;
+
+	case words_yellow_stone:
+		switch (local->last_spin) {
+		case 2:
+		case 3:
+			local->his_score_int += 2;
+			local->var_to_conv = 4;
+			break;
+
+		default:
+			local->whos_turn = MY_TURN;
+			local->var_to_conv = 5;
+			break;
+		}
+		break;
+
+	case words_green_stone:
+		switch (local->last_spin) {
+		case 3:
+			local->his_score_int += 5;
+			local->var_to_conv = 4;
+			break;
+
+		default:
+			local->whos_turn = MY_TURN;
+			local->var_to_conv = 5;
+			break;
+		}
+		break;
+
+	case words_purple_stone:
+		switch (local->last_spin) {
+		case 4:
+			local->his_score_int += 12;
+			local->var_to_conv = 4;
+			break;
+
+		default:
+			local->my_score_int += 2;
+			if (local->my_score_int > 15) local->my_score_int = 15;
+			local->whos_turn = MY_TURN;
+			local->var_to_conv = 5;
+			break;
+		}
+		break;
+	}
+}
+
+static void room_407_daemon() {
+	int count;
+	int currently_on = -1;
+	int button_down = false;
+
+	if (((mouse_status & 1) || (mouse_status & 2)) &&
+		conv_control.running != CONV_50_GAME && player.commands_allowed) {
+		button_down = true;
+	}
+
+	for (count = 0; count < room_num_spots; count++) {
+		if (room_spots[count].active) {
+			if (mouse_x >= room_spots[count].ul_x &&
+				mouse_x <= room_spots[count].lr_x &&
+				mouse_y >= room_spots[count].ul_y &&
+				mouse_y <= room_spots[count].lr_y) {
+
+				switch (room_spots[count].vocab) {
+				case words_red_stone:
+					currently_on = words_red_stone;
+					break;
+
+				case words_yellow_stone:
+					currently_on = words_yellow_stone;
+					break;
+
+				case words_green_stone:
+					currently_on = words_green_stone;
+					break;
+
+				case words_purple_stone:
+					currently_on = words_purple_stone;
+					break;
+				}
+			}
+		}
+	}
+
+	if (button_down && local->highlighting == -1) {
+		if (currently_on == words_red_stone) {
+			seq[fx_red_sel] = kernel_seq_stamp(ss[fx_red_sel], false, KERNEL_LAST);
+			kernel_seq_depth(seq[fx_red_sel], 1);
+			local->highlighting = words_red_stone;
+
+		} else if (currently_on == words_yellow_stone) {
+			seq[fx_yellow_sel] = kernel_seq_stamp(ss[fx_yellow_sel], false, KERNEL_LAST);
+			kernel_seq_depth(seq[fx_yellow_sel], 1);
+			local->highlighting = words_yellow_stone;
+
+		} else if (currently_on == words_green_stone) {
+			seq[fx_green_sel] = kernel_seq_stamp(ss[fx_green_sel], false, KERNEL_LAST);
+			kernel_seq_depth(seq[fx_green_sel], 1);
+			local->highlighting = words_green_stone;
+
+		} else if (currently_on == words_purple_stone) {
+			seq[fx_purple_sel] = kernel_seq_stamp(ss[fx_purple_sel], false, KERNEL_LAST);
+			kernel_seq_depth(seq[fx_purple_sel], 1);
+			local->highlighting = words_purple_stone;
+		}
+	}
+
+	if ((local->highlighting != -1 && (currently_on != local->highlighting)) ||
+		(!button_down && local->highlighting != -1)) {
+
+		if (!button_down && local->highlighting != -1) {
+			local->final_choice = local->highlighting;
+			player.commands_allowed = false;
+		}
+
+		if (local->final_choice == -1) switch (local->highlighting) {
+		case words_red_stone:
+			kernel_seq_delete(seq[fx_red_sel]);
+			break;
+
+		case words_yellow_stone:
+			kernel_seq_delete(seq[fx_yellow_sel]);
+			break;
+
+		case words_green_stone:
+			kernel_seq_delete(seq[fx_green_sel]);
+			break;
+
+		case words_purple_stone:
+			kernel_seq_delete(seq[fx_purple_sel]);
+			break;
+		}
+		local->highlighting = -1;
+	}
+
+
+	if ((local->final_choice != -1 && local->number_of_spins == 0) ||
+		kernel.trigger == ROOM_407_SPIN) {
+		do_a_round();
+	}
+
+	if (kernel.trigger == ROOM_407_RUN_CONV) {
+		if (local->whos_turn == HIS_TURN) {
+			after_round_him();
+		} else {
+			after_round_me();
+		}
+
+		if (local->whos_turn == MY_TURN) {
+			player.commands_allowed = true;
+		} else {
+			player.commands_allowed = false;
+		}
+
+		if (local->his_score_int >= 16) {
+			local->var_to_conv = 7;
+			player.commands_allowed = true;
+		}
+
+		if (local->my_score_int >= 16) {
+			local->var_to_conv = 6;
+			++global[wins_in_desert];
+		}
+
+		update_scores();
+
+
+		if (global[wins_in_desert] == global[wins_till_prize]) {
+
+			if (global[player_persona] == PLAYER_IS_KING) {
+				if (local->stuff_to_give[0] == CAN_GIVE) {
+					++global[prizes_owed_to_player];
+
+				} else if (local->stuff_to_give[1] == CAN_GIVE) {
+					++global[prizes_owed_to_player];
+
+				} else if (local->stuff_to_give[2] == CAN_GIVE) {
+					++global[prizes_owed_to_player];
+				}
+
+			} else {
+				if (local->stuff_to_give[0] == CAN_GIVE) {
+					++global[prizes_owed_to_player];
+
+				} else if (local->stuff_to_give[1] == CAN_GIVE) {
+					++global[prizes_owed_to_player];
+
+				} else if (local->stuff_to_give[2] == CAN_GIVE) {
+					++global[prizes_owed_to_player];
+
+				} else if (local->stuff_to_give[3] == CAN_GIVE) {
+					++global[prizes_owed_to_player];
+
+				} else if (local->stuff_to_give[4] == CAN_GIVE) {
+					++global[prizes_owed_to_player];
+				}
+			}
+
+			if (global[player_persona] == PLAYER_IS_KING) {
+				if (local->stuff_to_give[0] != CAN_GIVE &&
+					local->stuff_to_give[1] != CAN_GIVE &&
+					local->stuff_to_give[2] != CAN_GIVE) {
+					local->will_give = false;
+				}
+
+				if (local->stuff_to_give[0] == CAN_GIVE) {
+					local->stuff_to_give[0] = HOSIED;
+
+				} else if (local->stuff_to_give[1] == CAN_GIVE) {
+					local->stuff_to_give[1] = HOSIED;
+
+				} else if (local->stuff_to_give[2] == CAN_GIVE) {
+					local->stuff_to_give[2] = HOSIED;
+				}
+
+			} else {
+				if (local->stuff_to_give[0] != CAN_GIVE &&
+					local->stuff_to_give[1] != CAN_GIVE &&
+					local->stuff_to_give[2] != CAN_GIVE &&
+					local->stuff_to_give[3] != CAN_GIVE &&
+					local->stuff_to_give[4] != CAN_GIVE) {
+					local->will_give = false;
+				}
+
+				if (local->stuff_to_give[0] == CAN_GIVE) {
+					local->stuff_to_give[0] = HOSIED;
+
+				} else if (local->stuff_to_give[1] == CAN_GIVE) {
+					local->stuff_to_give[1] = HOSIED;
+
+				} else if (local->stuff_to_give[2] == CAN_GIVE) {
+					local->stuff_to_give[2] = HOSIED;
+
+				} else if (local->stuff_to_give[3] == CAN_GIVE) {
+					local->stuff_to_give[3] = HOSIED;
+
+				} else if (local->stuff_to_give[4] == CAN_GIVE) {
+					local->stuff_to_give[4] = HOSIED;
+				}
+			}
+		}
+
+		conv_run(CONV_50_GAME);
+		conv_export_pointer(&global[wins_in_desert]);
+		conv_export_value(global[wins_till_prize]);
+		conv_export_value(local->will_give);
+		conv_export_value(local->var_to_conv);
+	}
+}
+
+static void process_conv_game() {
+	if (player_verb == conv050_answers_yes ||
+		player_verb == conv050_answers_rulesask) {
+		local->his_score_int = 0;
+		local->my_score_int = 0;
+		local->num_of_red = 12;
+		local->num_of_yellow = 12;
+		local->num_of_green = 12;
+		local->num_of_purple = 12;
+		local->whos_turn = MY_TURN;
+	}
+
+	if (player_verb == conv050_exit_b_b) {
+		*conv_my_next_start = conv050_branch;
+		conv_abort();
+		update_scores();
+
+		switch (local->final_choice) {
+		case words_red_stone:    kernel_seq_delete(seq[fx_red_sel]);    break;
+		case words_yellow_stone: kernel_seq_delete(seq[fx_yellow_sel]); break;
+		case words_green_stone:  kernel_seq_delete(seq[fx_green_sel]);  break;
+		case words_purple_stone: kernel_seq_delete(seq[fx_purple_sel]); break;
+		}
+
+		switch (local->last_spin) {
+		case 1: kernel_seq_delete(seq[fx_red_abs]);    break;
+		case 2: kernel_seq_delete(seq[fx_yellow_abs]); break;
+		case 3: kernel_seq_delete(seq[fx_green_abs]);  break;
+		case 4: kernel_seq_delete(seq[fx_purple_abs]); break;
+		}
+
+		if (local->whos_turn == MY_TURN) {
+			local->final_choice = -1;
+			local->highlighting = -1;
+			local->last_spin = -1;
+			local->number_of_spins = 0;
+
+		} else {
+			kernel_timing_trigger(ONE_SECOND, ROOM_407_CAL_PICK);
+		}
+	}
+
+	if (player_verb == conv050_exit_d_d) {
+		*conv_my_next_start = conv050_branch;
+		conv_abort();
+		new_room = 406;
+	}
+}
+
+static void room_407_pre_parser() {
+	player.need_to_walk = false;
+
+	if (player_said_1(select)) {
+		player_cancel_command();
+	}
+}
+
+static void room_407_parser() {
+	if (conv_control.running == CONV_50_GAME) {
+		process_conv_game();
+		goto handled;
+	}
+
+	if (kernel.trigger == ROOM_407_CAL_PICK) {
+		local->highlighting = imath_random(1, 4);
+
+		kernel_timing_trigger(ONE_SECOND, ROOM_407_CAL_PICK + 1);
+
+		switch (local->highlighting) {
+		case 1:
+			seq[fx_red_sel] = kernel_seq_stamp(ss[fx_red_sel], false, KERNEL_LAST);
+			kernel_seq_depth(seq[fx_red_sel], 1);
+			local->highlighting = words_red_stone;
+			local->final_choice = words_red_stone;
+			break;
+
+		case 2:
+			seq[fx_yellow_sel] = kernel_seq_stamp(ss[fx_yellow_sel], false, KERNEL_LAST);
+			kernel_seq_depth(seq[fx_yellow_sel], 1);
+			local->highlighting = words_yellow_stone;
+			local->final_choice = words_yellow_stone;
+			break;
+
+		case 3:
+			seq[fx_green_sel] = kernel_seq_stamp(ss[fx_green_sel], false, KERNEL_LAST);
+			kernel_seq_depth(seq[fx_green_sel], 1);
+			local->highlighting = words_green_stone;
+			local->final_choice = words_green_stone;
+			break;
+
+		case 4:
+			seq[fx_purple_sel] = kernel_seq_stamp(ss[fx_purple_sel], false, KERNEL_LAST);
+			kernel_seq_depth(seq[fx_purple_sel], 1);
+			local->highlighting = words_purple_stone;
+			local->final_choice = words_purple_stone;
+			break;
+		}
+		goto handled;
+	}
+
+
+	if (kernel.trigger == ROOM_407_CAL_PICK + 1) {
+		local->number_of_spins = 0;
+		local->last_spin = 0;
+		goto handled;
+	} /* this will start spin in daemon */
+
+
+	goto done;
+
+handled:
+	player.command_ready = false;
+
+done:
+	;
 }
 
 void room_407_synchronize(Common::Serializer &s) {
-	
+	for (int16 &v : scratch.sprite)    s.syncAsSint16LE(v);
+	for (int16 &v : scratch.sequence)  s.syncAsSint16LE(v);
+	for (int16 &v : scratch.animation) s.syncAsSint16LE(v);
+	s.syncBytes((byte *)scratch.his_score, sizeof(scratch.his_score));
+	s.syncBytes((byte *)scratch.my_score,  sizeof(scratch.my_score));
+	s.syncAsByte(scratch.his_score_int);
+	s.syncAsByte(scratch.my_score_int);
+	s.syncAsSint16LE(scratch.his_score_id);
+	s.syncAsSint16LE(scratch.my_score_id);
+	s.syncAsSint16LE(scratch.highlighting);
+	s.syncAsSint16LE(scratch.prevent);
+	s.syncAsSint16LE(scratch.final_choice);
+	s.syncAsSint16LE(scratch.number_of_spins);
+	s.syncAsSint16LE(scratch.last_spin);
+	s.syncAsSint16LE(scratch.dealt);
+	s.syncAsSint16LE(scratch.num_of_red);
+	s.syncAsSint16LE(scratch.num_of_yellow);
+	s.syncAsSint16LE(scratch.num_of_green);
+	s.syncAsSint16LE(scratch.num_of_purple);
+	s.syncAsSint16LE(scratch.whos_turn);
+	s.syncAsSint16LE(scratch.var_to_conv);
+	for (byte &v : scratch.stuff_to_give) s.syncAsByte(v);
+	s.syncAsSint16LE(scratch.will_give);
 }
 
 void room_407_preload() {
@@ -74,6 +882,8 @@ void room_407_preload() {
 	room_parser_code_pointer = room_407_parser;
 	room_daemon_code_pointer = room_407_daemon;
 
+	global[no_load_walker] = true;
+
 	section_4_walker();
 	section_4_interface();
 }


Commit: 7b97ae10769be17188d7536dc45f10b7bdb7e56c
    https://github.com/scummvm/scummvm/commit/7b97ae10769be17188d7536dc45f10b7bdb7e56c
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-05-21T19:34:51+10:00

Commit Message:
MADS: DRAGONSPHERE: Added room 408

Changed paths:
    engines/mads/madsv2/dragonsphere/mads/conv.h
    engines/mads/madsv2/dragonsphere/mads/words.h
    engines/mads/madsv2/dragonsphere/rooms/room403.cpp
    engines/mads/madsv2/dragonsphere/rooms/room408.cpp


diff --git a/engines/mads/madsv2/dragonsphere/mads/conv.h b/engines/mads/madsv2/dragonsphere/mads/conv.h
index e5fd88bb63d..9803a46f8af 100644
--- a/engines/mads/madsv2/dragonsphere/mads/conv.h
+++ b/engines/mads/madsv2/dragonsphere/mads/conv.h
@@ -233,6 +233,13 @@ enum {
 	conv045_timer_b_b        = 29
 };
 
+enum {
+	conv046_advicelp         =  1,
+	conv046_advicelp_bynow   =  2,
+	conv046_advicelp_seeya   =  4,
+	conv046_exit_b_b         =  6
+};
+
 enum {
 	conv047_protect          =  0,
 	conv047_kingsay_escort   =  3,
diff --git a/engines/mads/madsv2/dragonsphere/mads/words.h b/engines/mads/madsv2/dragonsphere/mads/words.h
index e2ae68dc276..feb4ba85eab 100644
--- a/engines/mads/madsv2/dragonsphere/mads/words.h
+++ b/engines/mads/madsv2/dragonsphere/mads/words.h
@@ -195,6 +195,7 @@ enum {
 	words_firepit              = 303,
 	words_spirit_bundle        = 306,
 	words_path_to_east         = 313,
+	words_ledge                = 317,
 	words_sconce               = 329,
 	words_rock_tumble          = 321,
 	words_stairway             = 331,
@@ -214,6 +215,8 @@ enum {
 	words_teleportal           = 440,
 	words_Soptus_Ecliptus      = 448,
 	words_Slathan_ni_Patan     = 453,
+	words_spirit_plane         = 457,
+	words_spirit_tree          = 458,
 	words_desert_to_west       = 473,
 	words_cross                = 474,
 	words_desert_to_east       = 475,
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room403.cpp b/engines/mads/madsv2/dragonsphere/rooms/room403.cpp
index 0245ac99865..b0a781dcfb9 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room403.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room403.cpp
@@ -113,7 +113,7 @@ struct Scratch {
 static Scratch scratch;
 
 
-void room_403_init() {
+static void room_403_init() {
 	int count;
 	int count2 = global[fire_holes] - 1;
 	int skip = 0;
@@ -557,10 +557,10 @@ static void room_403_pre_parser() {
 	}
 }
 
-void room_403_parser() {
+static void room_403_parser() {
 	int count;
 	int count2 = global[oasis] - 1;
-	int room = 400;
+	int roomNum = 400;
 
 	if (player_said_1(cross)) {
 		if (player_said_1(desert_to_north) || player_said_1(desert_to_south)) {
@@ -573,13 +573,13 @@ void room_403_parser() {
 			}
 
 			for (count = 0; count < 77; count++) {
-				++ room; if (room == 404) room = 401;
+				++ roomNum; if (roomNum == 404) roomNum = 401;
 				++ count2; if (count2 == 78) count2 = 1;
 
 				if (count2 == global[desert_room]) {
-					if (global[desert_room] == 42)                 room = 401;
-					if (global[desert_room] == global[oasis])      room = 454;
-					if (global[desert_room] == global[fire_holes]) room = 412;
+					if (global[desert_room] == 42)                 roomNum = 401;
+					if (global[desert_room] == global[oasis])      roomNum = 454;
+					if (global[desert_room] == global[fire_holes]) roomNum = 412;
 					goto over;
 				}
 			}
@@ -591,10 +591,10 @@ over:
 				new_room               = 405;
 			} else if (global[desert_counter] == 6 && !player_has_been_in_room(405)) {
 				new_room = 404;
-			} else if (room_id == room) {
+			} else if (room_id == roomNum) {
 				kernel.force_restart = true;
 			} else {
-				new_room = room;
+				new_room = roomNum;
 			}
 			goto handled;
 		}
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room408.cpp b/engines/mads/madsv2/dragonsphere/rooms/room408.cpp
index 4a1c17f72e0..56cf4f2fe1d 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room408.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room408.cpp
@@ -39,6 +39,27 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[15];       /* Sprite series handles */
+	int16 sequence[15];     /* Sequence handles      */
+	int16 animation[4];     /* Animation handles     */
+
+	int16 shaman_1_frame;       /* animation frame being held for shaman_1 stuff */
+	int16 shaman_1_action;      /* Type of action to run for shaman_1 animation */
+	int16 shaman_1_talk_count;  /* counter for shaman_1 talking */
+	int16 anim_0_running;
+
+	int16 shaman_2_frame;       /* animation frame being held for shaman_2 stuff */
+	int16 shaman_2_action;      /* Type of action to run for shaman_2 animation */
+	int16 shaman_2_talk_count;  /* counter for shaman_2 talking */
+	int16 anim_1_running;
+
+	int16 face_1_on;
+	int16 face_2_on;
+	int16 face_3_on;
+	int16 face_4_on;
+	int16 face_5_on;
+	int16 face_6_on;
+	int16 face_7_on;
 };
 
 #define local (&scratch)
@@ -46,26 +67,498 @@ struct Scratch {
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
 
-void room_408_init() {
 
+/* ========================= Sprite Series =================== */
+
+#define fx_pid                  0       /* rm408b0 */
+#define fx_face_1               1       /* rm408z0 */
+#define fx_face_2               2       /* rm408z1 */
+#define fx_face_3               3       /* rm408z2 */
+#define fx_face_4               4       /* rm408z3 */
+#define fx_face_5               5       /* rm408z4 */
+#define fx_face_6               6       /* rm408z5 */
+#define fx_face_7               7       /* rm408z6 */
+
+
+/* ======================== Triggers ========================= */
+
+#define ROOM_408_ME_TALK        60
+#define ROOM_408_YOU_TALK       62
+
+/* ========================= Other Macros ==================== */
+
+#define PLAYER_X_FROM_405       213
+#define PLAYER_Y_FROM_405       115
+
+#define PLAYER_X_FROM_409       330
+#define PLAYER_Y_FROM_409       115
+#define WALK_TO_X_FROM_409      310
+#define WALK_TO_Y_FROM_409      115
+
+#define SHUT_UP                 0
+#define TALK                    1
+#define LEAVE                   2
+
+#define CONV_46_PID             46
+
+static Scratch scratch;
+
+
+static void room_408_init() {
+	global[perform_displacements] = true;
+
+	global[move_direction_409] = true;
+
+	local->face_1_on = false;
+	local->face_2_on = false;
+	local->face_3_on = false;
+	local->face_4_on = false;
+	local->face_5_on = false;
+	local->face_6_on = false;
+	local->face_7_on = false;
+
+	conv_get(CONV_46_PID);
+
+	ss[fx_pid] = kernel_load_series(kernel_name('b', 0), false);
+	ss[fx_face_1] = kernel_load_series(kernel_name('z', 0), false);
+	ss[fx_face_2] = kernel_load_series(kernel_name('z', 1), false);
+	ss[fx_face_3] = kernel_load_series(kernel_name('z', 2), false);
+	ss[fx_face_4] = kernel_load_series(kernel_name('z', 3), false);
+	ss[fx_face_5] = kernel_load_series(kernel_name('z', 4), false);
+	ss[fx_face_6] = kernel_load_series(kernel_name('z', 5), false);
+	ss[fx_face_7] = kernel_load_series(kernel_name('z', 6), false);
+
+	aa[0] = kernel_run_animation(kernel_name('s', 1), 0);
+	local->anim_0_running = true;
+	local->shaman_1_action = SHUT_UP;
+
+	aa[1] = kernel_run_animation(kernel_name('s', 2), 0);
+	local->anim_1_running = true;
+	local->shaman_2_action = SHUT_UP;
+
+	if (conv_restore_running == CONV_46_PID) {
+		player.x = PLAYER_X_FROM_405;
+		player.y = PLAYER_Y_FROM_405;
+		player.facing = FACING_NORTHWEST;
+
+		kernel_reset_animation(aa[0], 41);
+		kernel_reset_animation(aa[1], 8);
+
+		conv_run(CONV_46_PID);
+		conv_export_value(player_has(soul_egg));
+
+	} else if (previous_room == 405) {
+
+		player.x = PLAYER_X_FROM_405;
+		player.y = PLAYER_Y_FROM_405;
+		player.facing = FACING_NORTHWEST;
+		player.commands_allowed = false;
+		player.walker_visible = false;
+
+		seq[fx_pid] = kernel_seq_forward(ss[fx_pid], false, 7, 0, 0, 1);
+		kernel_seq_depth(seq[fx_pid], 2);
+		kernel_seq_range(seq[fx_pid], KERNEL_FIRST, KERNEL_LAST);
+		kernel_seq_trigger(seq[fx_pid], KERNEL_TRIGGER_EXPIRE, 0, 1);
+
+		global[perform_displacements] = false;
+
+	} else if (previous_room == 409 || previous_room != KERNEL_RESTORING_GAME) {
+
+		kernel_reset_animation(aa[0], 41);
+		kernel_reset_animation(aa[1], 8);
+
+		player_first_walk(PLAYER_X_FROM_409, PLAYER_Y_FROM_409, FACING_WEST,
+			WALK_TO_X_FROM_409, WALK_TO_Y_FROM_409, FACING_WEST, true);
+
+	} else if (previous_room == KERNEL_RESTORING_GAME) {
+		kernel_reset_animation(aa[0], 41);
+		kernel_reset_animation(aa[1], 8);
+	}
+
+	if (previous_room == 411) {
+		text_show(41150);
+	}
+
+	section_4_music();
 }
 
-void room_408_daemon() {
+static void handle_animation_shaman_1() {
+	int shaman_1_reset_frame;
+	int it;
+
+	if (kernel_anim[aa[0]].frame != local->shaman_1_frame) {
+		local->shaman_1_frame = kernel_anim[aa[0]].frame;
+		shaman_1_reset_frame = -1;
+
+		switch (local->shaman_1_frame) {
 
+		case 40: /* end of invisible */
+			shaman_1_reset_frame = 39;
+			break;
+
+		case 7:  /* end of talk */
+		case 8:  /* end of talk */
+		case 9:  /* end of talk */
+			if (local->shaman_1_action == TALK) {
+				shaman_1_reset_frame = imath_random(6, 8);
+				++local->shaman_1_talk_count;
+				if (local->shaman_1_talk_count > 24) {
+					local->shaman_1_action = SHUT_UP;
+					local->shaman_1_talk_count = 0;
+					shaman_1_reset_frame = 40; /* make shaman_1 shut up */
+				}
+
+			} else {
+				shaman_1_reset_frame = 40; /* make shaman_1 shut up */
+			}
+			break;
+
+		case 6:  /* end of fade in     */
+		case 20: /* end of talk        */
+		case 33: /* end of talk        */
+		case 41: /* end of freeze      */
+			switch (local->shaman_1_action) {
+			case SHUT_UP:
+				shaman_1_reset_frame = 40;
+				break;
+
+			case TALK:
+				it = imath_random(1, 3);
+				if (it == 1) {
+					shaman_1_reset_frame = 9;
+					local->shaman_1_action = SHUT_UP;
+				} else if (it == 2) {
+					shaman_1_reset_frame = 20;
+					local->shaman_1_action = SHUT_UP;
+				} else {
+					shaman_1_reset_frame = 6;
+				}
+				break;
+
+			case LEAVE:
+				shaman_1_reset_frame = 33;
+				break;
+			}
+			break;
+		}
+
+		if (shaman_1_reset_frame >= 0) {
+			kernel_reset_animation(aa[0], shaman_1_reset_frame);
+			local->shaman_1_frame = shaman_1_reset_frame;
+		}
+	}
 }
 
-void room_408_pre_parser() {
+static void handle_animation_shaman_2() {
+	int shaman_2_reset_frame;
+
+	if (kernel_anim[aa[1]].frame != local->shaman_2_frame) {
+		local->shaman_2_frame = kernel_anim[aa[1]].frame;
+		shaman_2_reset_frame = -1;
+
+		switch (local->shaman_2_frame) {
+		case 18:
+			shaman_2_reset_frame = 17;
+			break;
+
+		case 7:  /* end of look around   */
+		case 8:  /* end of look around   */
+		case 9:  /* end of look around   */
+		case 10: /* end of look around   */
+			switch (local->shaman_2_action) {
+			case SHUT_UP:
+				if (local->shaman_2_frame >= 11) {
+					local->shaman_2_frame = 7;
+				}
+
+				++local->shaman_2_talk_count;
+				if (local->shaman_2_talk_count > imath_random(6, 9)) {
+					if (local->shaman_2_frame == 7) {
+						shaman_2_reset_frame = imath_random(6, 7);
+					} else if (local->shaman_2_frame == 8) {
+						shaman_2_reset_frame = imath_random(6, 8);
+					} else if (local->shaman_2_frame == 9) {
+						shaman_2_reset_frame = imath_random(7, 9);
+					} else if (local->shaman_2_frame == 10) {
+						shaman_2_reset_frame = imath_random(8, 9);
+					}
+					local->shaman_2_talk_count = 0;
+
+				} else {
+					shaman_2_reset_frame = local->shaman_2_frame - 1;
+				}
+				break;
 
+			case LEAVE:
+				shaman_2_reset_frame = 10;
+				break;
+			}
+			break;
+		}
+
+		if (shaman_2_reset_frame >= 0) {
+			kernel_reset_animation(aa[1], shaman_2_reset_frame);
+			local->shaman_2_frame = shaman_2_reset_frame;
+		}
+	}
+}
+
+static void room_408_daemon() {
+	if (local->anim_0_running) {
+		handle_animation_shaman_1();
+	}
+
+	if (local->anim_1_running) {
+		handle_animation_shaman_2();
+	}
+
+	if (kernel.trigger == 1) {
+		player.walker_visible = true;
+		player.commands_allowed = true;
+		kernel_synch(KERNEL_PLAYER, 0, KERNEL_SERIES, seq[fx_pid]);
+		conv_run(CONV_46_PID);
+		conv_export_value(player_has(soul_egg));
+	}
+
+	if (!local->face_1_on && imath_random(1, 600) == 1) {
+		seq[fx_face_1] = kernel_seq_forward(ss[fx_face_1], false, 9, 0, 0, 1);
+		kernel_seq_depth(seq[fx_face_1], 1);
+		kernel_seq_range(seq[fx_face_1], KERNEL_FIRST, KERNEL_LAST);
+		kernel_seq_trigger(seq[fx_face_1], KERNEL_TRIGGER_EXPIRE, 0, 10);
+		local->face_1_on = true;
+	}
+
+	if (!local->face_2_on && imath_random(1, 600) == 1) {
+		seq[fx_face_2] = kernel_seq_forward(ss[fx_face_2], false, 9, 0, 0, 1);
+		kernel_seq_depth(seq[fx_face_2], 1);
+		kernel_seq_range(seq[fx_face_2], KERNEL_FIRST, KERNEL_LAST);
+		kernel_seq_trigger(seq[fx_face_2], KERNEL_TRIGGER_EXPIRE, 0, 11);
+		local->face_2_on = true;
+	}
+
+	if (!local->face_3_on && imath_random(1, 600) == 1) {
+		seq[fx_face_3] = kernel_seq_forward(ss[fx_face_3], false, 9, 0, 0, 1);
+		kernel_seq_depth(seq[fx_face_3], 1);
+		kernel_seq_range(seq[fx_face_3], KERNEL_FIRST, KERNEL_LAST);
+		kernel_seq_trigger(seq[fx_face_3], KERNEL_TRIGGER_EXPIRE, 0, 12);
+		local->face_3_on = true;
+	}
+
+	if (!local->face_4_on && imath_random(1, 600) == 1) {
+		seq[fx_face_4] = kernel_seq_forward(ss[fx_face_4], false, 9, 0, 0, 1);
+		kernel_seq_depth(seq[fx_face_4], 1);
+		kernel_seq_range(seq[fx_face_4], KERNEL_FIRST, KERNEL_LAST);
+		kernel_seq_trigger(seq[fx_face_4], KERNEL_TRIGGER_EXPIRE, 0, 13);
+		local->face_4_on = true;
+	}
+
+	if (!local->face_5_on && imath_random(1, 600) == 1) {
+		seq[fx_face_5] = kernel_seq_forward(ss[fx_face_5], false, 9, 0, 0, 1);
+		kernel_seq_depth(seq[fx_face_5], 1);
+		kernel_seq_range(seq[fx_face_5], KERNEL_FIRST, KERNEL_LAST);
+		kernel_seq_trigger(seq[fx_face_5], KERNEL_TRIGGER_EXPIRE, 0, 14);
+		local->face_5_on = true;
+	}
+
+	if (!local->face_6_on && imath_random(1, 600) == 1) {
+		seq[fx_face_6] = kernel_seq_forward(ss[fx_face_6], false, 9, 0, 0, 1);
+		kernel_seq_depth(seq[fx_face_6], 1);
+		kernel_seq_range(seq[fx_face_6], KERNEL_FIRST, KERNEL_LAST);
+		kernel_seq_trigger(seq[fx_face_6], KERNEL_TRIGGER_EXPIRE, 0, 15);
+		local->face_6_on = true;
+	}
+
+	if (!local->face_7_on && imath_random(1, 600) == 1) {
+		seq[fx_face_7] = kernel_seq_forward(ss[fx_face_7], false, 9, 0, 0, 1);
+		kernel_seq_depth(seq[fx_face_7], 1);
+		kernel_seq_range(seq[fx_face_7], KERNEL_FIRST, KERNEL_LAST);
+		kernel_seq_trigger(seq[fx_face_7], KERNEL_TRIGGER_EXPIRE, 0, 16);
+		local->face_7_on = true;
+	}
+
+	switch (kernel.trigger) {
+	case 10:
+		local->face_1_on = false;
+		break;
+
+	case 11:
+		local->face_2_on = false;
+		break;
+
+	case 12:
+		local->face_3_on = false;
+		break;
+
+	case 13:
+		local->face_4_on = false;
+		break;
+
+	case 14:
+		local->face_5_on = false;
+		break;
+
+	case 15:
+		local->face_6_on = false;
+		break;
+
+	case 16:
+		local->face_7_on = false;
+		break;
+	}
+}
+
+static void process_conv_pid() {
+	int you_trig_flag = false;
+	int me_trig_flag = false;
+
+	if (player_verb == conv046_exit_b_b) {
+		*conv_my_next_start = conv046_advicelp;
+		conv_abort();
+		if (!kernel.trigger) {
+			local->shaman_1_action = LEAVE;
+			local->shaman_2_action = LEAVE;
+
+			player.walker_visible = false;
+			player.commands_allowed = false;
+
+			seq[fx_pid] = kernel_seq_backward(ss[fx_pid], false, 7, 0, 0, 1);
+			kernel_seq_depth(seq[fx_pid], 1);
+			kernel_seq_range(seq[fx_pid], KERNEL_FIRST, KERNEL_LAST);
+			kernel_seq_trigger(seq[fx_pid], KERNEL_TRIGGER_EXPIRE, 0, 2);
+			kernel_synch(KERNEL_SERIES, seq[fx_pid], KERNEL_PLAYER, 0);
+		}
+	}
+
+	if (player_verb == conv046_advicelp_bynow ||
+		player_verb == conv046_advicelp_seeya) {
+		global[perform_displacements] = true;
+	}
+
+	if (kernel.trigger == ROOM_408_YOU_TALK) {
+		local->shaman_1_action = TALK;
+	}
+
+	if (kernel.trigger == ROOM_408_ME_TALK) {
+		local->shaman_1_action = SHUT_UP;
+	}
+
+	if (!you_trig_flag) {
+		conv_you_trigger(ROOM_408_YOU_TALK);
+	} /* if you_trig_flag == true, then a you trigger is called from above, not here. */
+
+	if (!me_trig_flag) {
+		conv_me_trigger(ROOM_408_ME_TALK);
+	} /* if me_trig_flag == true, then a me trigger is called from above, not here. */
+
+	local->shaman_1_talk_count = 0;
+}
+
+static void room_408_pre_parser() {
+	if (player_said_2(walk_down, path_to_east)) {
+		player.walk_off_edge_to_room = 409;
+	}
 }
 
-void room_408_parser() {
+static void room_408_parser() {
+	if (kernel.trigger == 2) {
+		global[perform_displacements] = true;
+		kernel_timing_trigger(TWO_SECONDS, 3);
+		goto handled;
+	}
+
+	if (kernel.trigger == 3) {
+		new_room = 405;
+		goto handled;
+	}
+
+	if (conv_control.running == CONV_46_PID) {
+		process_conv_pid();
+		goto handled;
+	}
+
+	if (player_said_2(talk_to, shaman)) {
+		conv_run(CONV_46_PID);
+		conv_export_value(player_has(soul_egg));
+		global[perform_displacements] = false;
+		goto handled;
+	}
 
+	if (player.look_around) {
+		text_show(40801);
+		goto handled;
+	}
+
+	if (player_said_1(look) || player_said_1(look_at)) {
+		if (player_said_1(spirit_tree)) {
+			text_show(40802);
+			goto handled;
+		}
+
+		if (player_said_1(path_to_east)) {
+			text_show(40803);
+			goto handled;
+		}
+
+		if (player_said_1(ledge)) {
+			text_show(40804);
+			goto handled;
+		}
+
+		if (player_said_1(spirit_plane)) {
+			text_show(40805);
+			goto handled;
+		}
+
+		if (player_said_1(shaman)) {
+			text_show(40806);
+			goto handled;
+		}
+	}
+
+	if (player_said_1(spirit_tree)) {
+		if (player_said_1(push) ||
+			player_said_1(pull) ||
+			player_said_1(open) ||
+			player_said_1(close)) {
+			text_show(40807);
+			goto handled;
+		}
+	}
+
+	if (player_said_2(talk_to, spirit_tree)) {
+		text_show(40808);
+		goto handled;
+	}
+
+	goto done;
+
+handled:
+	player.command_ready = false;
+
+done:
+	;
 }
 
 void room_408_synchronize(Common::Serializer &s) {
-	
+	for (int16 &v : scratch.sprite)    s.syncAsSint16LE(v);
+	for (int16 &v : scratch.sequence)  s.syncAsSint16LE(v);
+	for (int16 &v : scratch.animation) s.syncAsSint16LE(v);
+	s.syncAsSint16LE(scratch.shaman_1_frame);
+	s.syncAsSint16LE(scratch.shaman_1_action);
+	s.syncAsSint16LE(scratch.shaman_1_talk_count);
+	s.syncAsSint16LE(scratch.anim_0_running);
+	s.syncAsSint16LE(scratch.shaman_2_frame);
+	s.syncAsSint16LE(scratch.shaman_2_action);
+	s.syncAsSint16LE(scratch.shaman_2_talk_count);
+	s.syncAsSint16LE(scratch.anim_1_running);
+	s.syncAsSint16LE(scratch.face_1_on);
+	s.syncAsSint16LE(scratch.face_2_on);
+	s.syncAsSint16LE(scratch.face_3_on);
+	s.syncAsSint16LE(scratch.face_4_on);
+	s.syncAsSint16LE(scratch.face_5_on);
+	s.syncAsSint16LE(scratch.face_6_on);
+	s.syncAsSint16LE(scratch.face_7_on);
 }
 
 void room_408_preload() {
@@ -74,6 +567,10 @@ void room_408_preload() {
 	room_parser_code_pointer = room_408_parser;
 	room_daemon_code_pointer = room_408_daemon;
 
+	if (kernel.teleported_in) {
+		global[player_persona] = PLAYER_IS_PID;
+	}
+
 	section_4_walker();
 	section_4_interface();
 }


Commit: 192bf3dad1325fd79e0a6b0a1db28beb5184eb97
    https://github.com/scummvm/scummvm/commit/192bf3dad1325fd79e0a6b0a1db28beb5184eb97
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-05-21T19:34:51+10:00

Commit Message:
MADS: DRAGONSPHERE: Added rooms 409 to 454

Changed paths:
    engines/mads/madsv2/dragonsphere/mads/inventory.h
    engines/mads/madsv2/dragonsphere/mads/sounds.h
    engines/mads/madsv2/dragonsphere/mads/words.h
    engines/mads/madsv2/dragonsphere/rooms/room409.cpp
    engines/mads/madsv2/dragonsphere/rooms/room410.cpp
    engines/mads/madsv2/dragonsphere/rooms/room411.cpp
    engines/mads/madsv2/dragonsphere/rooms/room412.cpp
    engines/mads/madsv2/dragonsphere/rooms/room454.cpp


diff --git a/engines/mads/madsv2/dragonsphere/mads/inventory.h b/engines/mads/madsv2/dragonsphere/mads/inventory.h
index 14dbe8223a2..c27759a7a40 100644
--- a/engines/mads/madsv2/dragonsphere/mads/inventory.h
+++ b/engines/mads/madsv2/dragonsphere/mads/inventory.h
@@ -48,6 +48,7 @@ enum {
 	magic_belt       = 18,
 	amulet           = 19,
 	crystal_ball     = 29,
+	black_sphere     = 30,
 	soptus_soporific = 31,
 	shifter_ring     = 32,
 	medicine_bundle  = 33,
diff --git a/engines/mads/madsv2/dragonsphere/mads/sounds.h b/engines/mads/madsv2/dragonsphere/mads/sounds.h
index b845dc3a9fc..ecf9d31c787 100644
--- a/engines/mads/madsv2/dragonsphere/mads/sounds.h
+++ b/engines/mads/madsv2/dragonsphere/mads/sounds.h
@@ -74,7 +74,13 @@ enum {
 	N_Bk404Music         =  33,
 	N_Bk406Music         =  35,
 	N_BellyDanceMusic    =  36,
-	N_GamePieceSnd       =  66
+	N_GamePieceSnd       =  66,
+	N_FlameBurst         =  67,
+	N_SnakeHiss          =  68,
+	N_BigBirdCall        =  69,
+	N_JumpThwang         =  70,
+	N_StepOnFloatingDisk =  77,
+	N_004CryOfDismay     =  78
 };
 
 } // namespace Dragonsphere
diff --git a/engines/mads/madsv2/dragonsphere/mads/words.h b/engines/mads/madsv2/dragonsphere/mads/words.h
index feb4ba85eab..a28974ecb45 100644
--- a/engines/mads/madsv2/dragonsphere/mads/words.h
+++ b/engines/mads/madsv2/dragonsphere/mads/words.h
@@ -56,6 +56,8 @@ enum {
 	words_decoration           =  41,
 	words_signet_ring          =  46,
 	words_invoke               =  47,
+	words_bird_figurine        =  50,
+	words_rub                  =  51,
 	words_birdcall             =  52,
 	words_make_noise           =  54,
 	words_shieldstone          =  55,
@@ -74,10 +76,13 @@ enum {
 	words_dates                =  78,
 	words_statue               =  79,
 	words_bottle_of_flies      =  80,
+	words_soul_egg             =  82,
 	N_WaterBubbles             =  86,
 	words_thrust               =  87,
 	words_mud                  =  88,
 	words_torch                =  93,
+	words_flask_full_of_acid   =  96,
+	words_pour                 =  98,
 	words_pour_contents_of     =  99,
 	words_rope                 = 101,
 	words_tie                  = 102,
@@ -86,6 +91,7 @@ enum {
 	words_crystal_ball         = 109,
 	words_gaze_into            = 110,
 	words_invoke_power_of      = 111,
+	words_black_sphere         = 112,
 	words_soptus_soporific     = 113,
 	words_shift_into_bear      = 116,
 	words_shift_into_seal      = 117,
@@ -173,6 +179,7 @@ enum {
 	words_scullery_maid        = 266,
 	words_ward                 = 268,
 	words_darkness_beast       = 269,
+	words_put_magic_into       = 271,
 	words_guard                = 272,
 	words_crown                = 273,
 	words_doorway              = 277,
@@ -198,6 +205,7 @@ enum {
 	words_ledge                = 317,
 	words_sconce               = 329,
 	words_rock_tumble          = 321,
+	words_jump_to              = 324,
 	words_stairway             = 331,
 	words_mechanism            = 332,
 	words_spearheads           = 333,
@@ -227,6 +235,10 @@ enum {
 	words_tent                 = 481,
 	words_bush                 = 482,
 	words_sand                 = 485,
+	words_magic_grapes         = 486,
+	words_grape_vine           = 488,
+	words_east_end_of_island   = 491,
+	words_secret_message       = 493,
 	words_desert_sky           = 496,
 	words_pool                 = 497,
 	words_palm_tree            = 498,
@@ -234,6 +246,9 @@ enum {
 	words_lean_to              = 500,
 	words_trader               = 501,
 	words_sign                 = 502,
+	words_floating_disk        = 504,
+	words_gnarled_root         = 505,
+	words_snake_pit            = 506,
 	words_shaman               = 508,
 	words_guardhouse           = 509,
 	words_bone_tree            = 510,
@@ -242,6 +257,8 @@ enum {
 	words_nose_rock            = 513,
 	words_new_bundle           = 514,
 	words_lizard               = 515,
+	words_Roc                  = 516,
+	words_Roc_s_nest           = 517,
 	words_select               = 518,
 	words_purple_stone         = 520,
 	words_green_stone          = 521,
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room409.cpp b/engines/mads/madsv2/dragonsphere/rooms/room409.cpp
index dca0fbd6439..c128a920863 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room409.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room409.cpp
@@ -1,4 +1,4 @@
-/* ScummVM - Graphic Adventure Engine
+/* 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
@@ -19,13 +19,12 @@
  *
  */
 
-#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/sound.h"
 #include "mads/madsv2/core/text.h"
-#include "mads/madsv2/dragonsphere/mads/conv.h"
 #include "mads/madsv2/dragonsphere/mads/inventory.h"
 #include "mads/madsv2/dragonsphere/mads/sounds.h"
 #include "mads/madsv2/dragonsphere/mads/words.h"
@@ -39,6 +38,24 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[15];
+	int16 sequence[15];
+	int16 animation[4];
+	int16 facing;
+	int16 new_x;
+	int16 new_y;
+	int16 old_x;
+	int16 old_y;
+	int16 old_facing;
+	int16 on_shore;
+	int16 standing_on;
+	int16 pid_frame;
+	int16 pid_action;
+	int16 anim_0_running;
+	int16 pid_1_frame;
+	int16 anim_1_running;
+	int16 move_counter;
+	int16 fire;
 };
 
 #define local (&scratch)
@@ -46,33 +63,1261 @@ struct Scratch {
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
+#define fx_n                    0
+#define fx_ew                   1
+#define fx_s                    2
+#define fx_death_n              3
+#define fx_death_ew             4
+#define fx_death_s              5
+#define fx_fire                 6
 
-void room_409_init() {
+#define ROOM_409_DONE_ENTER_FROM_509 60
+#define ROOM_409_JUMP                65
+#define ROOM_409_END_OF_JUMP         67
+#define ROOM_409_TURN                70
+#define ROOM_409_END_OF_TURN         75
+#define ROOM_409_WHOA_SOUTH          80
+#define ROOM_409_WHOA_NORTH          85
+#define ROOM_409_WAIT_FOR_END_SLIDE  90
+#define ROOM_409_SOUND               120
+#define ROOM_409_END_DEATH           125
 
+#define BASE_X                  78
+#define BASE_Y                  18
+
+#define ENTER_408_X_BOTTOM      43
+#define ENTER_408_Y_BOTTOM      47
+
+#define ENTER_410_X_BOTTOM      253
+#define ENTER_410_Y_BOTTOM      105
+
+#define NEITHER                 0
+#define TOP_LEFT                1
+#define BOTTOM_LEFT             2
+#define TOP_RIGHT               3
+#define BOTTOM_RIGHT            4
+
+#define PID_SLIDE               0
+#define PID_LEAVE               1
+#define PID_FREEZE              2
+#define PID_SLIDE_JUMP          3
+
+#define FIRE                    60
+
+static Scratch scratch;
+
+
+static void which_pillar_409(int *it, int *new_x, int *new_y, int *adjoining) {
+	int offset;
+
+	if (inter_point_x < 99) {
+		offset = 0;
+	} else if (inter_point_x < 130) {
+		offset = 1;
+	} else if (inter_point_x < 168) {
+		offset = 2;
+	} else if (inter_point_x < 201) {
+		offset = 3;
+	} else {
+		offset = 4;
+	}
+
+	if (inter_point_y < 31) {
+		*it    = 1 + offset;
+		*new_y = BASE_Y;
+	} else if (inter_point_y < 61) {
+		*it    = 6 + offset;
+		*new_y = BASE_Y + 29;
+	} else if (inter_point_y < 91) {
+		*it    = 11 + offset;
+		*new_y = BASE_Y + 58;
+	} else if (inter_point_y < 121) {
+		*it    = 16 + offset;
+		*new_y = BASE_Y + 87;
+	} else {
+		*it    = 21 + offset;
+		*new_y = BASE_Y + 116;
+	}
+
+	*new_x = BASE_X + (35 * offset);
+
+	if (((*adjoining >= 7) && (*adjoining <= 9)) ||
+	    ((*adjoining >= 12) && (*adjoining <= 14)) ||
+	    ((*adjoining >= 17) && (*adjoining <= 19))) {
+		if ((*it == *adjoining + 1) || (*it == *adjoining - 1) ||
+		    (*it == *adjoining + 5) || (*it == *adjoining - 5)) {
+			*adjoining = true;
+		} else {
+			*adjoining = false;
+		}
+
+	} else if ((*adjoining >= 2) && (*adjoining <= 4)) {
+		if ((*it == *adjoining + 5) || (*it == *adjoining + 1) || (*it == *adjoining - 1)) {
+			*adjoining = true;
+		} else {
+			*adjoining = false;
+		}
+
+	} else if ((*adjoining >= 22) && (*adjoining <= 24)) {
+		if ((*it == *adjoining - 5) || (*it == *adjoining + 1) || (*it == *adjoining - 1)) {
+			*adjoining = true;
+		} else {
+			*adjoining = false;
+		}
+
+	} else if ((*adjoining == 6) || (*adjoining == 11) || (*adjoining == 16)) {
+		if ((*it == *adjoining - 5) || (*it == *adjoining + 5) || (*it == *adjoining + 1)) {
+			*adjoining = true;
+		} else {
+			*adjoining = false;
+		}
+
+	} else if ((*adjoining == 10) || (*adjoining == 15) || (*adjoining == 20)) {
+		if ((*it == *adjoining - 5) || (*it == *adjoining + 5) || (*it == *adjoining - 1)) {
+			*adjoining = true;
+		} else {
+			*adjoining = false;
+		}
+
+	} else if (*adjoining == 1) {
+		if ((*it == 2) || (*it == 6)) {
+			*adjoining = true;
+		} else {
+			*adjoining = false;
+		}
+
+	} else if (*adjoining == 5) {
+		if ((*it == 4) || (*it == 10)) {
+			*adjoining = true;
+		} else {
+			*adjoining = false;
+		}
+
+	} else if (*adjoining == 21) {
+		if ((*it == 22) || (*it == 16)) {
+			*adjoining = true;
+		} else {
+			*adjoining = false;
+		}
+	}
 }
 
-void room_409_daemon() {
+static void handle_animation_pid() {
+	int pid_reset_frame;
+	int no_commands = false;
+
+	if (kernel_anim[aa[0]].frame != local->pid_frame) {
+		local->pid_frame = kernel_anim[aa[0]].frame;
+		pid_reset_frame = -1;
+
+		if (local->pid_action == PID_SLIDE_JUMP) {
+			no_commands = true;
+		}
+
+		switch (local->pid_frame) {
+		case 176:
+		case 220:
+			global[no_load_walker] = false;
+			new_room               = 408;
+			break;
+
+		case 101:
+		case 133:
+		case 70:
+		case 35:
+			if (local->pid_frame == 101 || local->pid_frame == 133) {
+				local->pid_action = PID_FREEZE;
+			}
+
+			switch (local->pid_action) {
+			case PID_FREEZE:
+				if (!no_commands) {
+					player.commands_allowed = true;
+				}
+				if (local->on_shore == TOP_LEFT) {
+					pid_reset_frame = 34;
+				} else {
+					pid_reset_frame = 69;
+				}
+				break;
+
+			case PID_SLIDE:
+			case PID_SLIDE_JUMP:
+				player.commands_allowed = false;
+				if (local->on_shore == TOP_LEFT) {
+					pid_reset_frame = 70;
+					local->on_shore = BOTTOM_LEFT;
+					if (local->pid_action == PID_SLIDE) {
+						local->new_y = ENTER_408_Y_BOTTOM;
+					}
+				} else {
+					pid_reset_frame = 101;
+					local->on_shore = TOP_LEFT;
+					if (local->pid_action == PID_SLIDE) {
+						local->new_y = ENTER_408_Y_BOTTOM - 29;
+					}
+				}
+				break;
+
+			case PID_LEAVE:
+				player.commands_allowed = false;
+				if (local->on_shore == TOP_LEFT) {
+					pid_reset_frame = 133;
+				} else {
+					pid_reset_frame = 176;
+				}
+				break;
+			}
+			break;
+		}
+
+		if (pid_reset_frame >= 0) {
+			kernel_reset_animation(aa[0], pid_reset_frame);
+			local->pid_frame = pid_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_pid_1() {
+	int pid_1_reset_frame;
+	int no_commands = false;
+
+	if (kernel_anim[aa[1]].frame != local->pid_1_frame) {
+		local->pid_1_frame = kernel_anim[aa[1]].frame;
+		pid_1_reset_frame = -1;
+
+		if (local->pid_action == PID_SLIDE_JUMP) {
+			no_commands = true;
+		}
+
+		switch (local->pid_1_frame) {
+		case 205:
+		case 259:
+			global[no_load_walker] = false;
+			new_room               = 410;
+			break;
+
+		case 152:
+		case 123:
+		case 48:
+		case 95:
+			if (local->pid_1_frame == 123 || local->pid_1_frame == 152) {
+				local->pid_action = PID_FREEZE;
+			}
+
+			switch (local->pid_action) {
+			case PID_FREEZE:
+				if (!no_commands) {
+					player.commands_allowed = true;
+				}
+				if (local->on_shore == TOP_RIGHT) {
+					pid_1_reset_frame = 47;
+				} else {
+					pid_1_reset_frame = 94;
+				}
+				break;
 
+			case PID_SLIDE:
+			case PID_SLIDE_JUMP:
+				player.commands_allowed = false;
+				if (local->on_shore == TOP_RIGHT) {
+					pid_1_reset_frame = 123;
+					local->on_shore   = BOTTOM_RIGHT;
+					if (local->pid_action == PID_SLIDE) {
+						local->new_y = ENTER_410_Y_BOTTOM;
+					}
+				} else {
+					pid_1_reset_frame = 95;
+					local->on_shore   = TOP_RIGHT;
+					if (local->pid_action == PID_SLIDE) {
+						local->new_y = ENTER_410_Y_BOTTOM - 29;
+					}
+				}
+				break;
+
+			case PID_LEAVE:
+				player.commands_allowed = false;
+				if (local->on_shore == TOP_RIGHT) {
+					pid_1_reset_frame = 205;
+				} else {
+					pid_1_reset_frame = 152;
+				}
+				break;
+			}
+			break;
+		}
+
+		if (pid_1_reset_frame >= 0) {
+			kernel_reset_animation(aa[1], pid_1_reset_frame);
+			local->pid_1_frame = pid_1_reset_frame;
+		}
+	}
 }
 
-void room_409_pre_parser() {
+static void room_409_init() {
+	global[perform_displacements] = true;
+
+	local->fire = 0;
+
+	global[grid_position] = 1;
+	global[grid_position + 1] = 2;
+	global[grid_position + 2] = 7;
+	global[grid_position + 3] = 6;
+	global[grid_position + 4] = 11;
+	global[grid_position + 5] = 16;
+	global[grid_position + 6] = 17;
+	global[grid_position + 7] = 22;
+	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] = 4;
+	global[grid_position + 14] = 5;
+	global[grid_position + 15] = 10;
+	global[grid_position + 16] = 9;
+	global[grid_position + 17] = 14;
+	global[grid_position + 18] = 19;
+	global[grid_position + 19] = 24;
+	global[grid_position + 20] = 25;
+	global[grid_position + 21] = 20;
+	global[grid_position + 22] = 15;
+
+	if (kernel.teleported_in) {
+		global[player_persona] = PLAYER_IS_PID;
+	}
+
+	if (previous_room != KERNEL_RESTORING_GAME) {
+		local->anim_0_running = false;
+		local->anim_1_running = false;
+		local->standing_on = 0;
+		local->move_counter = 0;
+	}
+
+	ss[fx_n] = kernel_load_series("*RM510B0", false);
+	ss[fx_s] = kernel_load_series("*RM510B3", false);
+	ss[fx_ew] = kernel_load_series("*RM510B1", false);
+	ss[fx_death_n] = kernel_load_series(kernel_name('b', 3), false);
+	ss[fx_death_ew] = kernel_load_series(kernel_name('b', 4), false);
+	ss[fx_death_s] = kernel_load_series(kernel_name('b', 5), false);
+	ss[fx_fire] = kernel_load_series(kernel_name('x', 0), false);
+
+	player.walker_visible = false;
+
+	if (previous_room == KERNEL_RESTORING_GAME) {
+		if (local->standing_on) {
+			switch (local->facing) {
+			case FACING_NORTH:
+				seq[fx_n] = kernel_seq_stamp(ss[fx_n], false, 13);
+				kernel_seq_loc(seq[fx_n], local->new_x - 1, local->new_y + 11);
+				kernel_seq_depth(seq[fx_n], 1);
+				break;
 
+			case FACING_SOUTH:
+				seq[fx_s] = kernel_seq_stamp(ss[fx_s], true, 12);
+				kernel_seq_loc(seq[fx_s], local->new_x + 3, local->new_y + 36);
+				kernel_seq_depth(seq[fx_s], 1);
+				break;
+
+			case FACING_EAST:
+				seq[fx_ew] = kernel_seq_stamp(ss[fx_ew], true, 13);
+				kernel_seq_loc(seq[fx_ew], local->new_x + 2, local->new_y + 19);
+				kernel_seq_depth(seq[fx_ew], 1);
+				break;
+
+			case FACING_WEST:
+				seq[fx_ew] = kernel_seq_stamp(ss[fx_ew], false, 13);
+				kernel_seq_loc(seq[fx_ew], local->new_x + 2, local->new_y + 19);
+				kernel_seq_depth(seq[fx_ew], 1);
+				break;
+			}
+		} else {
+			if (local->on_shore == TOP_LEFT) {
+				aa[0] = kernel_run_animation(kernel_name('l', -1), 0);
+				kernel_reset_animation(aa[0], 35);
+			} else if (local->on_shore == BOTTOM_LEFT) {
+				aa[0] = kernel_run_animation(kernel_name('l', -1), 0);
+				kernel_reset_animation(aa[0], 70);
+			} else if (local->on_shore == TOP_RIGHT) {
+				aa[1] = kernel_run_animation(kernel_name('r', -1), 0);
+				kernel_reset_animation(aa[0], 95);
+			} else if (local->on_shore == BOTTOM_RIGHT) {
+				aa[1] = kernel_run_animation(kernel_name('r', -1), 0);
+				kernel_reset_animation(aa[0], 48);
+			}
+		}
+
+	} else if (previous_room == 409) {
+		if (global[move_direction_409]) {
+			aa[0] = kernel_run_animation(kernel_name('l', -1), 0);
+			kernel_reset_animation(aa[0], 70);
+			local->anim_0_running = true;
+			local->on_shore = BOTTOM_LEFT;
+			local->pid_action = PID_FREEZE;
+			local->facing = FACING_EAST;
+			local->new_x = ENTER_408_X_BOTTOM;
+			local->new_y = ENTER_408_Y_BOTTOM;
+		} else {
+			aa[1] = kernel_run_animation(kernel_name('r', -1), 0);
+			kernel_reset_animation(aa[0], 48);
+			local->anim_1_running = true;
+			local->on_shore = BOTTOM_RIGHT;
+			local->pid_action = PID_FREEZE;
+			local->facing = FACING_WEST;
+			local->new_x = ENTER_410_X_BOTTOM;
+			local->new_y = ENTER_410_Y_BOTTOM;
+		}
+
+	} else if (previous_room == 410) {
+		aa[1] = kernel_run_animation(kernel_name('r', -1), 0);
+		kernel_reset_animation(aa[1], 49);
+		player.commands_allowed = false;
+		local->anim_1_running = true;
+		local->pid_action = PID_FREEZE;
+		local->on_shore = BOTTOM_RIGHT;
+		local->facing = FACING_WEST;
+		local->new_x = ENTER_410_X_BOTTOM;
+		local->new_y = ENTER_410_Y_BOTTOM;
+
+	} else if (previous_room == 408 || previous_room != KERNEL_RESTORING_GAME) {
+		aa[0] = kernel_run_animation(kernel_name('l', -1), 0);
+		kernel_reset_animation(aa[0], 36);
+		player.commands_allowed = false;
+		local->anim_0_running = true;
+		local->pid_action = PID_FREEZE;
+		local->on_shore = BOTTOM_LEFT;
+		local->facing = FACING_EAST;
+		local->new_x = ENTER_408_X_BOTTOM;
+		local->new_y = ENTER_408_Y_BOTTOM;
+	}
+
+	section_4_music();
 }
 
-void room_409_parser() {
+static void room_409_daemon() {
+	int x, y;
+
+	if (local->anim_0_running) {
+		handle_animation_pid();
+	}
+
+	if (local->anim_1_running) {
+		handle_animation_pid_1();
+	}
 
+	if (kernel.trigger == ROOM_409_SOUND) {
+		sound_play(N_JumpThwang);
+	}
+
+	if (imath_random(1, 100) == 1 && local->fire == 0) {
+		local->fire = imath_random(1, 25);
+		while (local->standing_on == local->fire) {
+			local->fire = imath_random(1, 25);
+		}
+		seq[fx_fire] = kernel_seq_forward(ss[fx_fire], false, 7, 0, 0, 1);
+		kernel_seq_depth(seq[fx_fire], 1);
+		kernel_seq_range(seq[fx_fire], KERNEL_FIRST, KERNEL_LAST);
+		kernel_seq_trigger(seq[fx_fire], KERNEL_TRIGGER_EXPIRE, 0, FIRE);
+
+		if (local->fire <= 5)       y = BASE_Y + 10;
+		else if (local->fire <= 10) y = BASE_Y + 39;
+		else if (local->fire <= 15) y = BASE_Y + 68;
+		else if (local->fire <= 20) y = BASE_Y + 97;
+		else                        y = BASE_Y + 126;
+
+		switch (local->fire) {
+		case 1: case 6:  case 11: case 16: case 21: x = BASE_X + 1;   break;
+		case 2: case 7:  case 12: case 17: case 22: x = BASE_X + 36;  break;
+		case 3: case 8:  case 13: case 18: case 23: x = BASE_X + 71;  break;
+		case 4: case 9:  case 14: case 19: case 24: x = BASE_X + 106; break;
+		default:                                     x = BASE_X + 141; break;
+		}
+		kernel_seq_loc(seq[fx_fire], x, y);
+	}
+
+	if (kernel.trigger == FIRE) {
+		local->fire = 0;
+	}
+}
+
+static void room_409_pre_parser() {
+	player.need_to_walk = false;
+}
+
+static void room_409_parser() {
+	int temp;
+	int selected;
+	int new_x;
+	int new_y;
+	int adjoining;
+
+	if (kernel.trigger == ROOM_409_SOUND) {
+		sound_play(N_StepOnFloatingDisk);
+		player.command_ready = false;
+		return;
+	}
+
+	if (kernel.trigger == ROOM_409_END_DEATH) {
+		sound_play(N_PlayerDies);
+		if (game.difficulty == EASY_MODE) {
+			text_show(40914);
+		} else {
+			text_show(45);
+		}
+		kernel.force_restart = true;
+		player.command_ready = false;
+		return;
+	}
+
+	switch (kernel.trigger) {
+	case ROOM_409_JUMP:
+		if (local->on_shore) {
+			if (local->anim_0_running) {
+				kernel_abort_animation(aa[0]);
+				local->anim_0_running = false;
+			} else {
+				kernel_abort_animation(aa[1]);
+				local->anim_1_running = false;
+			}
+			player.commands_allowed = false;
+
+		} else {
+			switch (local->facing) {
+			case FACING_NORTH:
+				kernel_seq_delete(seq[fx_n]);
+				break;
+
+			case FACING_SOUTH:
+				kernel_seq_delete(seq[fx_s]);
+				break;
+
+			case FACING_EAST:
+			case FACING_WEST:
+				kernel_seq_delete(seq[fx_ew]);
+				break;
+			}
+		}
+
+		switch (local->facing) {
+		case FACING_NORTH:
+			seq[fx_n] = kernel_seq_forward(ss[fx_n], false, 5, 0, 0, 1);
+			kernel_seq_depth(seq[fx_n], 1);
+			kernel_seq_range(seq[fx_n], 15, 34);
+			kernel_seq_trigger(seq[fx_n], KERNEL_TRIGGER_EXPIRE, 0, ROOM_409_END_OF_JUMP);
+			kernel_seq_trigger(seq[fx_n], KERNEL_TRIGGER_SPRITE, 30, ROOM_409_SOUND);
+			kernel_seq_loc(seq[fx_n], local->new_x, local->new_y + 40);
+			break;
+
+		case FACING_SOUTH:
+			seq[fx_s] = kernel_seq_forward(ss[fx_s], false, 5, 0, 0, 1);
+			kernel_seq_depth(seq[fx_s], 1);
+			kernel_seq_range(seq[fx_s], 15, 33);
+			kernel_seq_trigger(seq[fx_s], KERNEL_TRIGGER_EXPIRE, 0, ROOM_409_END_OF_JUMP);
+			kernel_seq_trigger(seq[fx_s], KERNEL_TRIGGER_SPRITE, 29, ROOM_409_SOUND);
+			kernel_seq_loc(seq[fx_s], local->new_x, local->new_y + 7);
+			break;
+
+		case FACING_EAST:
+			seq[fx_ew] = kernel_seq_forward(ss[fx_ew], true, 5, 0, 0, 1);
+			kernel_seq_depth(seq[fx_ew], 1);
+			kernel_seq_range(seq[fx_ew], 16, 34);
+			kernel_seq_trigger(seq[fx_ew], KERNEL_TRIGGER_EXPIRE, 0, ROOM_409_END_OF_JUMP);
+			kernel_seq_trigger(seq[fx_ew], KERNEL_TRIGGER_SPRITE, 30, ROOM_409_SOUND);
+			if (local->on_shore == TOP_LEFT) {
+				kernel_seq_loc(seq[fx_ew], ENTER_408_X_BOTTOM, ENTER_408_Y_BOTTOM - 11);
+				kernel_synch(KERNEL_SERIES, seq[fx_ew], KERNEL_NOW, 0);
+				local->on_shore = NEITHER;
+			} else if (local->on_shore == BOTTOM_LEFT) {
+				kernel_seq_loc(seq[fx_ew], ENTER_408_X_BOTTOM + 2, ENTER_408_Y_BOTTOM + 17);
+				kernel_synch(KERNEL_SERIES, seq[fx_ew], KERNEL_NOW, 0);
+				local->on_shore = NEITHER;
+			} else if (local->on_shore == NEITHER) {
+				kernel_seq_loc(seq[fx_ew], local->old_x + 2, local->new_y + 19);
+			}
+			break;
+
+		case FACING_WEST:
+			seq[fx_ew] = kernel_seq_forward(ss[fx_ew], false, 5, 0, 0, 1);
+			kernel_seq_depth(seq[fx_ew], 1);
+			kernel_seq_range(seq[fx_ew], 16, 34);
+			kernel_seq_trigger(seq[fx_ew], KERNEL_TRIGGER_EXPIRE, 0, ROOM_409_END_OF_JUMP);
+			kernel_seq_trigger(seq[fx_ew], KERNEL_TRIGGER_SPRITE, 30, ROOM_409_SOUND);
+			if (local->on_shore == TOP_RIGHT) {
+				kernel_seq_loc(seq[fx_ew], ENTER_410_X_BOTTOM, ENTER_410_Y_BOTTOM - 11);
+				kernel_synch(KERNEL_SERIES, seq[fx_ew], KERNEL_NOW, 0);
+				local->on_shore = NEITHER;
+			} else if (local->on_shore == BOTTOM_RIGHT) {
+				kernel_seq_loc(seq[fx_ew], ENTER_410_X_BOTTOM + 2, ENTER_410_Y_BOTTOM + 17);
+				kernel_synch(KERNEL_SERIES, seq[fx_ew], KERNEL_NOW, 0);
+				local->on_shore = NEITHER;
+			} else if (local->on_shore == NEITHER) {
+				kernel_seq_loc(seq[fx_ew], local->old_x + 2, local->new_y + 19);
+			}
+			break;
+		}
+		player.command_ready = false;
+		return;
+
+	case ROOM_409_END_OF_JUMP:
+
+		seq[fx_death_n]  = -1;
+		seq[fx_death_s]  = -1;
+		seq[fx_death_ew] = -1;
+
+		if (local->standing_on < 400) {
+
+			if ((global[move_direction_409] && global[grid_position + local->move_counter] != local->standing_on) ||
+			    (!global[move_direction_409] && global[global[max_grid_value] - local->move_counter] != local->standing_on)) {
+
+				sound_play(N_FlameBurst);
+				switch (local->facing) {
+				case FACING_NORTH:
+					seq[fx_death_n] = kernel_seq_forward(ss[fx_death_n], false, 6, 0, 0, 1);
+					kernel_seq_depth(seq[fx_death_n], 1);
+					kernel_seq_range(seq[fx_death_n], KERNEL_FIRST, KERNEL_LAST);
+					kernel_seq_trigger(seq[fx_death_n], KERNEL_TRIGGER_EXPIRE, 0, ROOM_409_END_DEATH);
+					kernel_seq_loc(seq[fx_death_n], local->new_x - 1, local->new_y + 17);
+					break;
+
+				case FACING_SOUTH:
+					seq[fx_death_s] = kernel_seq_forward(ss[fx_death_s], false, 6, 0, 0, 1);
+					kernel_seq_depth(seq[fx_death_s], 1);
+					kernel_seq_range(seq[fx_death_s], KERNEL_FIRST, KERNEL_LAST);
+					kernel_seq_trigger(seq[fx_death_s], KERNEL_TRIGGER_EXPIRE, 0, ROOM_409_END_DEATH);
+					kernel_seq_loc(seq[fx_death_s], local->new_x + 3, local->new_y + 29);
+					break;
+
+				case FACING_EAST:
+				case FACING_WEST:
+					if (local->facing == FACING_EAST) {
+						seq[fx_death_ew] = kernel_seq_forward(ss[fx_death_ew], false, 6, 0, 0, 1);
+						kernel_seq_loc(seq[fx_death_ew], local->new_x + 7, local->new_y + 29);
+					} else {
+						seq[fx_death_ew] = kernel_seq_forward(ss[fx_death_ew], true, 6, 0, 0, 1);
+						kernel_seq_loc(seq[fx_death_ew], local->new_x - 3, local->new_y + 30);
+					}
+					kernel_seq_depth(seq[fx_death_ew], 1);
+					kernel_seq_range(seq[fx_death_ew], KERNEL_FIRST, KERNEL_LAST);
+					kernel_seq_trigger(seq[fx_death_ew], KERNEL_TRIGGER_EXPIRE, 0, ROOM_409_END_DEATH);
+					break;
+				}
+			}
+		}
+
+		++local->move_counter;
+
+		if (seq[fx_death_n] == -1 && seq[fx_death_s] == -1 && seq[fx_death_ew] == -1) {
+
+			switch (local->facing) {
+
+			case FACING_NORTH:
+				temp      = seq[fx_n];
+				seq[fx_n] = kernel_seq_stamp(ss[fx_n], false, 13);
+				kernel_seq_loc(seq[fx_n], local->new_x - 1, local->new_y + 11);
+				kernel_seq_depth(seq[fx_n], 2);
+				kernel_synch(KERNEL_SERIES, seq[fx_n], KERNEL_SERIES, temp);
+				local->facing   = FACING_NORTH;
+				local->on_shore = NEITHER;
+				if (imath_random(1, 7) == 1) {
+					kernel_timing_trigger(1, ROOM_409_WHOA_NORTH);
+				} else {
+					player.commands_allowed = true;
+				}
+				break;
+
+			case FACING_SOUTH:
+				temp      = seq[fx_s];
+				seq[fx_s] = kernel_seq_stamp(ss[fx_s], true, 12);
+				kernel_seq_loc(seq[fx_s], local->new_x + 3, local->new_y + 36);
+				kernel_seq_depth(seq[fx_s], 2);
+				kernel_synch(KERNEL_SERIES, seq[fx_s], KERNEL_SERIES, temp);
+				local->facing   = FACING_SOUTH;
+				local->on_shore = NEITHER;
+				if (imath_random(1, 7) == 1) {
+					kernel_timing_trigger(1, ROOM_409_WHOA_SOUTH);
+				} else {
+					player.commands_allowed = true;
+				}
+				break;
+
+			case FACING_EAST:
+				temp       = seq[fx_ew];
+				if (local->standing_on == 410) {
+					aa[1] = kernel_run_animation(kernel_name('r', -1), 0);
+					kernel_synch(KERNEL_ANIM, aa[1], KERNEL_SERIES, temp);
+					if (local->new_y == ENTER_410_Y_BOTTOM) {
+						kernel_reset_animation(aa[1], 161);
+					} else {
+						kernel_reset_animation(aa[1], 214);
+					}
+					local->anim_1_running = true;
+				} else {
+					seq[fx_ew] = kernel_seq_stamp(ss[fx_ew], true, 13);
+					kernel_seq_loc(seq[fx_ew], local->new_x + 2, local->new_y + 19);
+					kernel_seq_depth(seq[fx_ew], 2);
+					kernel_synch(KERNEL_SERIES, seq[fx_ew], KERNEL_SERIES, temp);
+					player.commands_allowed = true;
+					local->facing           = FACING_EAST;
+					local->on_shore         = NEITHER;
+				}
+				if (!(global[player_score_flags] & SCORE_CROSS_SKY)) {
+					global[player_score_flags] = global[player_score_flags] | SCORE_CROSS_SKY;
+					global[player_score] += 2;
+				}
+				break;
+
+			case FACING_WEST:
+				temp       = seq[fx_ew];
+				if (local->standing_on == 408) {
+					aa[0] = kernel_run_animation(kernel_name('l', -1), 0);
+					kernel_synch(KERNEL_ANIM, aa[0], KERNEL_SERIES, temp);
+					if (local->new_y == ENTER_408_Y_BOTTOM) {
+						kernel_reset_animation(aa[0], 183);
+					} else {
+						kernel_reset_animation(aa[0], 141);
+					}
+					local->anim_0_running = true;
+				} else {
+					seq[fx_ew] = kernel_seq_stamp(ss[fx_ew], false, 13);
+					kernel_seq_loc(seq[fx_ew], local->new_x + 2, local->new_y + 19);
+					kernel_seq_depth(seq[fx_ew], 2);
+					kernel_synch(KERNEL_SERIES, seq[fx_ew], KERNEL_SERIES, temp);
+					player.commands_allowed = true;
+					local->facing           = FACING_WEST;
+					local->on_shore         = NEITHER;
+				}
+				break;
+			}
+		}
+		player.command_ready = false;
+		return;
+
+	case ROOM_409_TURN:
+		switch (local->old_facing) {
+
+		case FACING_NORTH:
+			kernel_seq_delete(seq[fx_n]);
+			switch (local->facing) {
+			case FACING_EAST:
+				seq[fx_n] = kernel_seq_forward(ss[fx_n], true, 7, 0, 0, 1);
+				kernel_seq_range(seq[fx_n], 36, 39);
+				kernel_seq_loc(seq[fx_n], local->old_x + 2, local->old_y + 11);
+				break;
+			case FACING_WEST:
+				seq[fx_n] = kernel_seq_forward(ss[fx_n], false, 7, 0, 0, 1);
+				kernel_seq_range(seq[fx_n], 36, 39);
+				kernel_seq_loc(seq[fx_n], local->old_x - 1, local->old_y + 11);
+				break;
+			case FACING_SOUTH:
+				seq[fx_n] = kernel_seq_forward(ss[fx_n], false, 7, 0, 0, 1);
+				kernel_seq_range(seq[fx_n], 36, 43);
+				kernel_seq_loc(seq[fx_n], local->old_x - 1, local->old_y + 11);
+				break;
+			}
+			kernel_seq_depth(seq[fx_n], 1);
+			kernel_seq_trigger(seq[fx_n], KERNEL_TRIGGER_EXPIRE, 0, ROOM_409_END_OF_TURN);
+			break;
+
+		case FACING_SOUTH:
+			kernel_seq_delete(seq[fx_s]);
+			switch (local->facing) {
+			case FACING_EAST:
+				seq[fx_n] = kernel_seq_backward(ss[fx_n], true, 7, 0, 0, 1);
+				kernel_seq_range(seq[fx_n], 40, 43);
+				kernel_seq_loc(seq[fx_n], local->old_x + 2, local->old_y + 11);
+				break;
+			case FACING_WEST:
+				seq[fx_n] = kernel_seq_backward(ss[fx_n], false, 7, 0, 0, 1);
+				kernel_seq_range(seq[fx_n], 40, 43);
+				kernel_seq_loc(seq[fx_n], local->old_x - 1, local->old_y + 11);
+				break;
+			case FACING_NORTH:
+				seq[fx_n] = kernel_seq_backward(ss[fx_n], false, 7, 0, 0, 1);
+				kernel_seq_range(seq[fx_n], 36, 43);
+				kernel_seq_loc(seq[fx_n], local->old_x - 1, local->old_y + 11);
+				break;
+			}
+			kernel_seq_depth(seq[fx_n], 1);
+			kernel_seq_trigger(seq[fx_n], KERNEL_TRIGGER_EXPIRE, 0, ROOM_409_END_OF_TURN);
+			break;
+
+		case FACING_WEST:
+			kernel_seq_delete(seq[fx_ew]);
+			switch (local->facing) {
+			case FACING_EAST:
+				seq[fx_n] = kernel_seq_backward(ss[fx_n], false, 7, 0, 0, 1);
+				kernel_seq_range(seq[fx_n], 36, 39);
+				kernel_seq_trigger(seq[fx_n], KERNEL_TRIGGER_EXPIRE, 0, ROOM_409_TURN + 2);
+				kernel_seq_loc(seq[fx_n], local->old_x + 2, local->old_y + 11);
+				break;
+			case FACING_NORTH:
+				seq[fx_n] = kernel_seq_backward(ss[fx_n], false, 7, 0, 0, 1);
+				kernel_seq_range(seq[fx_n], 36, 39);
+				kernel_seq_trigger(seq[fx_n], KERNEL_TRIGGER_EXPIRE, 0, ROOM_409_END_OF_TURN);
+				kernel_seq_loc(seq[fx_n], local->old_x + 1, local->old_y + 11);
+				break;
+			case FACING_SOUTH:
+				seq[fx_n] = kernel_seq_forward(ss[fx_n], false, 7, 0, 0, 1);
+				kernel_seq_range(seq[fx_n], 40, 43);
+				kernel_seq_trigger(seq[fx_n], KERNEL_TRIGGER_EXPIRE, 0, ROOM_409_END_OF_TURN);
+				kernel_seq_loc(seq[fx_n], local->old_x - 1, local->old_y + 11);
+				break;
+			}
+			kernel_seq_depth(seq[fx_n], 1);
+			break;
+
+		case FACING_EAST:
+			kernel_seq_delete(seq[fx_ew]);
+			switch (local->facing) {
+			case FACING_NORTH:
+				seq[fx_n] = kernel_seq_backward(ss[fx_n], true, 7, 0, 0, 1);
+				kernel_seq_range(seq[fx_n], 36, 39);
+				kernel_seq_trigger(seq[fx_n], KERNEL_TRIGGER_EXPIRE, 0, ROOM_409_END_OF_TURN);
+				kernel_seq_loc(seq[fx_n], local->old_x + 2, local->old_y + 11);
+				break;
+			case FACING_WEST:
+				seq[fx_n] = kernel_seq_backward(ss[fx_n], true, 7, 0, 0, 1);
+				kernel_seq_range(seq[fx_n], 36, 39);
+				kernel_seq_trigger(seq[fx_n], KERNEL_TRIGGER_EXPIRE, 0, ROOM_409_TURN + 1);
+				kernel_seq_loc(seq[fx_n], local->old_x + 2, local->old_y + 11);
+				break;
+			case FACING_SOUTH:
+				seq[fx_n] = kernel_seq_forward(ss[fx_n], true, 7, 0, 0, 1);
+				kernel_seq_range(seq[fx_n], 40, 43);
+				kernel_seq_trigger(seq[fx_n], KERNEL_TRIGGER_EXPIRE, 0, ROOM_409_END_OF_TURN);
+				kernel_seq_loc(seq[fx_n], local->old_x + 2, local->old_y + 11);
+				break;
+			}
+			kernel_seq_depth(seq[fx_n], 1);
+			break;
+		}
+		player.command_ready = false;
+		return;
+
+	case ROOM_409_TURN + 1:
+		seq[fx_n] = kernel_seq_forward(ss[fx_n], false, 7, 0, 0, 1);
+		kernel_seq_range(seq[fx_n], 36, 39);
+		kernel_seq_depth(seq[fx_n], 1);
+		kernel_seq_loc(seq[fx_n], local->old_x + 2, local->old_y + 11);
+		kernel_seq_trigger(seq[fx_n], KERNEL_TRIGGER_EXPIRE, 0, ROOM_409_END_OF_TURN);
+		player.command_ready = false;
+		return;
+
+	case ROOM_409_TURN + 2:
+		seq[fx_n] = kernel_seq_forward(ss[fx_n], true, 7, 0, 0, 1);
+		kernel_seq_range(seq[fx_n], 36, 39);
+		kernel_seq_depth(seq[fx_n], 1);
+		kernel_seq_loc(seq[fx_n], local->old_x + 2, local->old_y + 11);
+		kernel_seq_trigger(seq[fx_n], KERNEL_TRIGGER_EXPIRE, 0, ROOM_409_END_OF_TURN);
+		player.command_ready = false;
+		return;
+
+	case ROOM_409_END_OF_TURN:
+		switch (local->facing) {
+		case FACING_NORTH:
+			temp      = seq[fx_n];
+			seq[fx_n] = kernel_seq_stamp(ss[fx_n], false, 13);
+			kernel_seq_loc(seq[fx_n], local->old_x - 1, local->old_y + 11);
+			kernel_seq_depth(seq[fx_n], 1);
+			kernel_synch(KERNEL_SERIES, seq[fx_n], KERNEL_SERIES, temp);
+			break;
+		case FACING_SOUTH:
+			temp      = seq[fx_n];
+			seq[fx_s] = kernel_seq_stamp(ss[fx_s], true, 12);
+			kernel_seq_loc(seq[fx_s], local->old_x + 3, local->old_y + 36);
+			kernel_seq_depth(seq[fx_s], 1);
+			kernel_synch(KERNEL_SERIES, seq[fx_s], KERNEL_SERIES, temp);
+			break;
+		case FACING_EAST:
+			temp       = seq[fx_n];
+			seq[fx_ew] = kernel_seq_stamp(ss[fx_ew], true, 13);
+			kernel_seq_loc(seq[fx_ew], local->old_x + 2, local->old_y + 19);
+			kernel_seq_depth(seq[fx_ew], 1);
+			kernel_synch(KERNEL_SERIES, seq[fx_ew], KERNEL_SERIES, temp);
+			break;
+		case FACING_WEST:
+			temp       = seq[fx_n];
+			seq[fx_ew] = kernel_seq_stamp(ss[fx_ew], false, 13);
+			kernel_seq_loc(seq[fx_ew], local->old_x + 2, local->old_y + 19);
+			kernel_seq_depth(seq[fx_ew], 1);
+			kernel_synch(KERNEL_SERIES, seq[fx_ew], KERNEL_SERIES, temp);
+			break;
+		}
+		kernel_timing_trigger(4, ROOM_409_JUMP);
+		player.command_ready = false;
+		return;
+
+	case ROOM_409_WHOA_SOUTH:
+		sound_play(N_004CryOfDismay);
+		kernel_seq_delete(seq[fx_s]);
+		seq[fx_s] = kernel_seq_forward(ss[fx_s], false, 6, 0, 0, 1);
+		kernel_seq_depth(seq[fx_s], 1);
+		kernel_seq_range(seq[fx_s], 35, 54);
+		kernel_seq_loc(seq[fx_s], local->new_x + 1, local->new_y + 37);
+		kernel_seq_trigger(seq[fx_s], KERNEL_TRIGGER_EXPIRE, 0, ROOM_409_WHOA_SOUTH + 1);
+		player.command_ready = false;
+		return;
+
+	case ROOM_409_WHOA_SOUTH + 1:
+		temp      = seq[fx_s];
+		seq[fx_s] = kernel_seq_stamp(ss[fx_s], true, 12);
+		kernel_seq_loc(seq[fx_s], local->new_x + 3, local->new_y + 36);
+		kernel_seq_depth(seq[fx_s], 1);
+		kernel_synch(KERNEL_SERIES, seq[fx_s], KERNEL_SERIES, temp);
+		player.commands_allowed = true;
+		player.command_ready = false;
+		return;
+
+	case ROOM_409_WHOA_NORTH:
+		sound_play(N_004CryOfDismay);
+		kernel_seq_delete(seq[fx_n]);
+		seq[fx_n] = kernel_seq_forward(ss[fx_n], false, 6, 0, 0, 1);
+		kernel_seq_depth(seq[fx_n], 1);
+		kernel_seq_range(seq[fx_n], 44, 63);
+		kernel_seq_loc(seq[fx_n], local->new_x - 1, local->new_y + 11);
+		kernel_seq_trigger(seq[fx_n], KERNEL_TRIGGER_EXPIRE, 0, ROOM_409_WHOA_NORTH + 1);
+		player.command_ready = false;
+		return;
+
+	case ROOM_409_WHOA_NORTH + 1:
+		temp      = seq[fx_n];
+		seq[fx_n] = kernel_seq_stamp(ss[fx_n], false, 13);
+		kernel_seq_loc(seq[fx_n], local->new_x - 1, local->new_y + 11);
+		kernel_seq_depth(seq[fx_n], 1);
+		kernel_synch(KERNEL_SERIES, seq[fx_n], KERNEL_SERIES, temp);
+		player.commands_allowed = true;
+		player.command_ready = false;
+		return;
+	}
+
+	if (kernel.trigger == ROOM_409_WAIT_FOR_END_SLIDE) {
+		if (local->pid_action != PID_FREEZE) {
+			kernel_timing_trigger(1, ROOM_409_WAIT_FOR_END_SLIDE);
+		} else {
+			kernel_timing_trigger(1, ROOM_409_JUMP);
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(jump_to, ledge) ||
+	    player_said_2(walk_down, path_to_west) ||
+	    player_said_2(walk_to, east_end_of_island) ||
+	    player_said_2(walk_across, ledge)) {
+
+		local->old_facing = local->facing;
+
+		if (!local->standing_on) {
+			if (local->on_shore == TOP_LEFT || local->on_shore == BOTTOM_LEFT) {
+				if (inter_point_x < 62) {
+					if (player_said_1(walk_down)) {
+						local->pid_action = PID_LEAVE;
+					} else if (local->on_shore) {
+						local->pid_action = PID_SLIDE;
+					}
+					player.command_ready = false;
+					return;
+				} else {
+					text_show(40911);
+					player.command_ready = false;
+					return;
+				}
+
+			} else if (local->on_shore == TOP_RIGHT || local->on_shore == BOTTOM_RIGHT) {
+				if (inter_point_x > 235) {
+					if (player_said_1(walk_to)) {
+						local->pid_action = PID_LEAVE;
+					} else if (local->on_shore) {
+						local->pid_action = PID_SLIDE;
+					}
+					player.command_ready = false;
+					return;
+				} else {
+					text_show(40911);
+					player.command_ready = false;
+					return;
+				}
+			}
+
+		} else if (local->standing_on == 1) {
+			if (inter_point_x > 100) {
+				text_show(40911);
+				player.command_ready = false;
+				return;
+			} else {
+				local->old_x  = local->new_x;
+				local->old_y  = local->new_y;
+				local->new_x  = ENTER_408_X_BOTTOM - 3;
+				local->new_y  = ENTER_408_Y_BOTTOM - 29;
+				local->facing = FACING_WEST;
+			}
+
+		} else if (local->standing_on == 6) {
+			if (inter_point_x > 100) {
+				text_show(40911);
+				player.command_ready = false;
+				return;
+			} else {
+				local->old_x  = local->new_x;
+				local->old_y  = local->new_y;
+				local->new_x  = ENTER_408_X_BOTTOM - 2;
+				local->new_y  = ENTER_408_Y_BOTTOM;
+				local->facing = FACING_WEST;
+			}
+
+		} else if (local->standing_on == 15) {
+			if (inter_point_x < 100) {
+				text_show(40911);
+				player.command_ready = false;
+				return;
+			} else {
+				local->old_x  = local->new_x;
+				local->old_y  = local->new_y;
+				local->new_x  = ENTER_410_X_BOTTOM - 3;
+				local->new_y  = ENTER_410_Y_BOTTOM - 29;
+				local->facing = FACING_EAST;
+			}
+
+		} else if (local->standing_on == 20) {
+			if (inter_point_x < 100) {
+				text_show(40911);
+				player.command_ready = false;
+				return;
+			} else {
+				local->old_x  = local->new_x;
+				local->old_y  = local->new_y;
+				local->new_x  = ENTER_410_X_BOTTOM - 3;
+				local->new_y  = ENTER_410_Y_BOTTOM;
+				local->facing = FACING_EAST;
+			}
+
+		} else {
+			text_show(40911);
+			player.command_ready = false;
+			return;
+		}
+
+		if (local->standing_on == 15 || local->standing_on == 20) {
+			local->standing_on = 410;
+		} else if (local->standing_on == 1 || local->standing_on == 6) {
+			local->standing_on = 408;
+		}
+
+		player.commands_allowed = false;
+
+		if (local->old_facing == local->facing) {
+			kernel_timing_trigger(1, ROOM_409_JUMP);
+		} else {
+			kernel_timing_trigger(1, ROOM_409_TURN);
+		}
+
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(jump_to, floating_disk)) {
+
+		local->old_x = local->new_x;
+		local->old_y = local->new_y;
+
+		adjoining = local->standing_on;
+		which_pillar_409(&selected, &new_x, &new_y, &adjoining);
+
+		if (local->on_shore == TOP_LEFT) {
+			if (selected == 6) {
+				local->pid_action = PID_SLIDE_JUMP;
+				kernel_timing_trigger(1, ROOM_409_WAIT_FOR_END_SLIDE);
+				local->standing_on      = selected;
+				player.commands_allowed = false;
+				local->new_x = new_x;
+				local->new_y = new_y;
+				player.command_ready = false;
+				return;
+			} else if (selected != 1) {
+				text_show(40912);
+				player.command_ready = false;
+				return;
+			}
+
+		} else if (local->on_shore == BOTTOM_LEFT) {
+			if (selected == 1) {
+				local->pid_action = PID_SLIDE_JUMP;
+				kernel_timing_trigger(1, ROOM_409_WAIT_FOR_END_SLIDE);
+				local->standing_on      = selected;
+				player.commands_allowed = false;
+				local->new_x = new_x;
+				local->new_y = new_y;
+				player.command_ready = false;
+				return;
+			} else if (selected != 6) {
+				text_show(40912);
+				player.command_ready = false;
+				return;
+			}
+
+		} else if (local->on_shore == TOP_RIGHT) {
+			if (selected == 20) {
+				local->pid_action = PID_SLIDE_JUMP;
+				kernel_timing_trigger(1, ROOM_409_WAIT_FOR_END_SLIDE);
+				local->standing_on      = selected;
+				player.commands_allowed = false;
+				local->new_x = new_x;
+				local->new_y = new_y;
+				player.command_ready = false;
+				return;
+			} else if (selected != 15) {
+				text_show(40912);
+				player.command_ready = false;
+				return;
+			}
+
+		} else if (local->on_shore == BOTTOM_RIGHT) {
+			if (selected == 15) {
+				local->pid_action = PID_SLIDE_JUMP;
+				kernel_timing_trigger(1, ROOM_409_WAIT_FOR_END_SLIDE);
+				local->standing_on      = selected;
+				player.commands_allowed = false;
+				local->new_x = new_x;
+				local->new_y = new_y;
+				player.command_ready = false;
+				return;
+			} else if (selected != 20) {
+				text_show(40912);
+				player.command_ready = false;
+				return;
+			}
+		}
+
+		if (selected == local->standing_on) {
+			text_show(40913);
+			player.command_ready = false;
+			return;
+
+		} else if (adjoining || local->on_shore) {
+
+			local->new_x = new_x;
+			local->new_y = new_y;
+
+			local->old_facing = local->facing;
+
+			if (!local->on_shore) {
+				if (selected == local->standing_on + 1) {
+					local->facing = FACING_EAST;
+				} else if (selected == local->standing_on - 1) {
+					local->facing = FACING_WEST;
+				} else if (selected == local->standing_on + 5) {
+					local->facing = FACING_SOUTH;
+				} else if (selected == local->standing_on - 5) {
+					local->facing = FACING_NORTH;
+				}
+			}
+
+			local->standing_on      = selected;
+			player.commands_allowed = false;
+
+			if ((local->old_facing == local->facing) || local->on_shore) {
+				kernel_timing_trigger(1, ROOM_409_JUMP);
+			} else {
+				kernel_timing_trigger(1, ROOM_409_TURN);
+			}
+
+		} else {
+			text_show(40912);
+		}
+
+		player.command_ready = false;
+		return;
+	}
+
+	if (player.look_around) {
+		if (game.difficulty == HARD_MODE) {
+			text_show(40901);
+		} else {
+			text_show(40902);
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_1(look) || player_said_1(look_at)) {
+		if (player_said_1(ledge)) {
+			text_show(40904);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(floating_disk)) {
+			text_show(40905);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(path_to_west)) {
+			text_show(40907);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(east_end_of_island)) {
+			text_show(40908);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(spirit_plane)) {
+			text_show(40909);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_1(take) || player_said_1(push) || player_said_1(pull)) {
+		if (player_said_1(floating_disk)) {
+			text_show(40906);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_1(secret_message)) {
+		text_show(40903);
+		player.command_ready = false;
+		return;
+	}
 }
 
 void room_409_synchronize(Common::Serializer &s) {
-	
+	for (int16 &v : scratch.sprite)    s.syncAsSint16LE(v);
+	for (int16 &v : scratch.sequence)  s.syncAsSint16LE(v);
+	for (int16 &v : scratch.animation) s.syncAsSint16LE(v);
+	s.syncAsSint16LE(scratch.facing);
+	s.syncAsSint16LE(scratch.new_x);
+	s.syncAsSint16LE(scratch.new_y);
+	s.syncAsSint16LE(scratch.old_x);
+	s.syncAsSint16LE(scratch.old_y);
+	s.syncAsSint16LE(scratch.old_facing);
+	s.syncAsSint16LE(scratch.on_shore);
+	s.syncAsSint16LE(scratch.standing_on);
+	s.syncAsSint16LE(scratch.pid_frame);
+	s.syncAsSint16LE(scratch.pid_action);
+	s.syncAsSint16LE(scratch.anim_0_running);
+	s.syncAsSint16LE(scratch.pid_1_frame);
+	s.syncAsSint16LE(scratch.anim_1_running);
+	s.syncAsSint16LE(scratch.move_counter);
+	s.syncAsSint16LE(scratch.fire);
 }
 
 void room_409_preload() {
-	room_init_code_pointer = room_409_init;
+	room_init_code_pointer       = room_409_init;
 	room_pre_parser_code_pointer = room_409_pre_parser;
-	room_parser_code_pointer = room_409_parser;
-	room_daemon_code_pointer = room_409_daemon;
+	room_parser_code_pointer     = room_409_parser;
+	room_daemon_code_pointer     = room_409_daemon;
+
+	global[no_load_walker] = true;
+
+	if (kernel.teleported_in) {
+		global[player_persona] = PLAYER_IS_PID;
+	}
 
 	section_4_walker();
 	section_4_interface();
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room410.cpp b/engines/mads/madsv2/dragonsphere/rooms/room410.cpp
index fcbbffab933..09773800ec8 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room410.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room410.cpp
@@ -1,4 +1,4 @@
-/* ScummVM - Graphic Adventure Engine
+/* 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
@@ -19,13 +19,13 @@
  *
  */
 
-#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/player.h"
 #include "mads/madsv2/core/sound.h"
 #include "mads/madsv2/core/text.h"
-#include "mads/madsv2/dragonsphere/mads/conv.h"
 #include "mads/madsv2/dragonsphere/mads/inventory.h"
 #include "mads/madsv2/dragonsphere/mads/sounds.h"
 #include "mads/madsv2/dragonsphere/mads/words.h"
@@ -39,6 +39,26 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[17];
+	int16 sequence[17];
+	int16 animation[4];
+
+	int16 snake_1_on;
+	int16 snake_2_on;
+	int16 snake_3_on;
+	int16 snake_4_on;
+	int16 snake_5_on;
+	int16 snake_6_on;
+	int16 snake_7_on;
+	int16 snake_8_on;
+	int16 snake_9_on;
+	int16 snake_10_on;
+	int16 snake_11_on;
+
+	int16 face_1_on;
+	int16 face_2_on;
+	int16 face_3_on;
+	int16 face_4_on;
 };
 
 #define local (&scratch)
@@ -46,33 +66,579 @@ struct Scratch {
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
+#define fx_snake_1              0
+#define fx_snake_2              1
+#define fx_snake_3              2
+#define fx_snake_4              3
+#define fx_snake_5              4
+#define fx_snake_6              5
+#define fx_snake_7              6
+#define fx_snake_8              7
+#define fx_shift                8
+#define fx_face_1               9
+#define fx_face_2               10
+#define fx_face_3               11
+#define fx_face_4               12
+#define fx_snake_9              13
+#define fx_snake_10             14
+#define fx_snake_11             15
+#define fx_death                16
+
+#define ROOM_410_DOOR_CLOSES    60
+#define ROOM_410_FACE_OFF       70
+#define ROOM_410_DIE            90
+
+#define SNAKE_X                 109
+#define SNAKE_Y                 145
+
+#define DEATH_X                 128
+#define DEATH_Y                 131
+
+#define AFTER_SNAKE_X           200
+#define AFTER_SNAKE_Y           89
+
+#define WALK_TO_X               329
+#define WALK_TO_Y               85
+
+#define PLAYER_X_FROM_409       137
+#define PLAYER_Y_FROM_409       149
+
+static Scratch scratch;
 
-void room_410_init() {
 
+static void room_410_init() {
+	local->snake_1_on = false;
+	local->snake_2_on = false;
+	local->snake_3_on = false;
+	local->snake_4_on = false;
+	local->snake_5_on = false;
+	local->snake_6_on = false;
+	local->snake_7_on = false;
+	local->snake_8_on = false;
+	local->snake_9_on = false;
+	local->snake_10_on = false;
+	local->snake_11_on = false;
+	local->face_1_on = false;
+	local->face_2_on = false;
+	local->face_3_on = false;
+	local->face_4_on = false;
+	kernel.disable_fastwalk = true;
+
+	ss[fx_snake_1] = kernel_load_series(kernel_name('y', 1), false);
+	ss[fx_snake_2] = kernel_load_series(kernel_name('y', 2), false);
+	ss[fx_snake_3] = kernel_load_series(kernel_name('y', 3), false);
+	ss[fx_snake_4] = kernel_load_series(kernel_name('y', 4), false);
+	ss[fx_snake_5] = kernel_load_series(kernel_name('y', 6), false);
+	ss[fx_snake_6] = kernel_load_series(kernel_name('y', 0), false);
+	ss[fx_snake_7] = kernel_load_series(kernel_name('y', 5), false);
+	ss[fx_snake_8] = kernel_load_series(kernel_name('y', 7), false);
+	ss[fx_snake_9] = kernel_load_series(kernel_name('x', 0), false);
+	ss[fx_snake_10] = kernel_load_series(kernel_name('x', 1), false);
+	ss[fx_snake_11] = kernel_load_series(kernel_name('x', 2), false);
+	ss[fx_shift] = kernel_load_series(kernel_name('b', 0), false);
+	ss[fx_face_1] = kernel_load_series(kernel_name('z', 0), false);
+	ss[fx_face_2] = kernel_load_series(kernel_name('z', 2), false);
+	ss[fx_face_3] = kernel_load_series(kernel_name('z', 3), false);
+	ss[fx_face_4] = kernel_load_series(kernel_name('z', 4), false);
+	ss[fx_death] = kernel_load_series(kernel_name('b', 1), false);
+
+	seq[fx_snake_8] = kernel_seq_pingpong(ss[fx_snake_8], false, 25, 0, 0, 0);
+	kernel_seq_depth(seq[fx_snake_8], 10);
+	kernel_seq_range(seq[fx_snake_8], KERNEL_FIRST, KERNEL_LAST);
+
+	seq[fx_snake_1] = kernel_seq_stamp(ss[fx_snake_1], false, 1);
+	kernel_seq_depth(seq[fx_snake_1], 1);
+
+	seq[fx_snake_7] = kernel_seq_stamp(ss[fx_snake_7], false, 20);
+	kernel_seq_depth(seq[fx_snake_7], 1);
+
+	global[perform_displacements] = true;
+	global[move_direction_409] = false;
+
+	if (previous_room == 409 || previous_room != KERNEL_RESTORING_GAME) {
+		player.x = PLAYER_X_FROM_409;
+		player.y = PLAYER_Y_FROM_409;
+		player.facing = FACING_NORTHEAST;
+	}
+
+	section_4_music();
 }
 
-void room_410_daemon() {
+static void room_410_daemon() {
+	int temp;
+
+	if (!local->snake_2_on && imath_random(1, 300) == 1) {
+		seq[fx_snake_2] = kernel_seq_forward(ss[fx_snake_2], false, 9, 0, 0, 1);
+		kernel_seq_depth(seq[fx_snake_2], 3);
+		kernel_seq_range(seq[fx_snake_2], KERNEL_FIRST, KERNEL_LAST);
+		kernel_seq_trigger(seq[fx_snake_2], KERNEL_TRIGGER_EXPIRE, 0, 2);
+		local->snake_2_on = true;
+	}
+
+	if (!local->snake_3_on && imath_random(1, 300) == 1) {
+		seq[fx_snake_3] = kernel_seq_forward(ss[fx_snake_3], false, 7, 0, 0, 1);
+		kernel_seq_depth(seq[fx_snake_3], 3);
+		kernel_seq_range(seq[fx_snake_3], KERNEL_FIRST, KERNEL_LAST);
+		kernel_seq_trigger(seq[fx_snake_3], KERNEL_TRIGGER_EXPIRE, 0, 3);
+		local->snake_3_on = true;
+	}
+
+	if (!local->snake_4_on && imath_random(1, 300) == 1) {
+		seq[fx_snake_4] = kernel_seq_forward(ss[fx_snake_4], false, 7, 0, 0, 1);
+		kernel_seq_depth(seq[fx_snake_4], 3);
+		kernel_seq_range(seq[fx_snake_4], KERNEL_FIRST, KERNEL_LAST);
+		kernel_seq_trigger(seq[fx_snake_4], KERNEL_TRIGGER_EXPIRE, 0, 4);
+		local->snake_4_on = true;
+	}
+
+	if (!local->snake_5_on && imath_random(1, 300) == 1) {
+		seq[fx_snake_5] = kernel_seq_forward(ss[fx_snake_5], false, 7, 0, 0, 1);
+		kernel_seq_depth(seq[fx_snake_5], 3);
+		kernel_seq_range(seq[fx_snake_5], KERNEL_FIRST, KERNEL_LAST);
+		kernel_seq_trigger(seq[fx_snake_5], KERNEL_TRIGGER_EXPIRE, 0, 5);
+		local->snake_5_on = true;
+	}
+
+	if (!local->snake_9_on && imath_random(1, 300) == 1) {
+		seq[fx_snake_9] = kernel_seq_forward(ss[fx_snake_9], false, 9, 0, 0, 1);
+		kernel_seq_depth(seq[fx_snake_9], 3);
+		kernel_seq_range(seq[fx_snake_9], KERNEL_FIRST, KERNEL_LAST);
+		kernel_seq_loc(seq[fx_snake_9], imath_random(161, 207), imath_random(109, 120));
+		kernel_seq_trigger(seq[fx_snake_9], KERNEL_TRIGGER_EXPIRE, 0, 6);
+		local->snake_9_on = true;
+	}
+
+	if (!local->snake_10_on && imath_random(1, 300) == 1) {
+		seq[fx_snake_10] = kernel_seq_forward(ss[fx_snake_10], false, 9, 0, 0, 1);
+		kernel_seq_depth(seq[fx_snake_10], 3);
+		kernel_seq_range(seq[fx_snake_10], KERNEL_FIRST, KERNEL_LAST);
+		kernel_seq_loc(seq[fx_snake_10], imath_random(161, 207), imath_random(109, 120));
+		kernel_seq_trigger(seq[fx_snake_10], KERNEL_TRIGGER_EXPIRE, 0, 7);
+		local->snake_10_on = true;
+	}
+
+	if (!local->snake_11_on && imath_random(1, 300) == 1) {
+		seq[fx_snake_11] = kernel_seq_forward(ss[fx_snake_11], false, 9, 0, 0, 1);
+		kernel_seq_depth(seq[fx_snake_11], 3);
+		kernel_seq_range(seq[fx_snake_11], KERNEL_FIRST, KERNEL_LAST);
+		kernel_seq_loc(seq[fx_snake_11], imath_random(161, 207), imath_random(109, 120));
+		kernel_seq_trigger(seq[fx_snake_11], KERNEL_TRIGGER_EXPIRE, 0, 8);
+		local->snake_11_on = true;
+	}
+
+	switch (kernel.trigger) {
+	case 1: local->snake_5_on  = false; break;
+	case 2: local->snake_2_on  = false; break;
+	case 3: local->snake_3_on  = false; break;
+	case 4: local->snake_5_on  = false; break;
+	case 5: local->snake_5_on  = false; break;
+	case 6: local->snake_9_on  = false; break;
+	case 7: local->snake_10_on = false; break;
+	case 8: local->snake_11_on = false; break;
+	}
+
+	switch (kernel.trigger) {
+	case 0:
+		if (!local->snake_1_on && imath_random(1, 300) == 1) {
+			kernel_seq_delete(seq[fx_snake_1]);
+			seq[fx_snake_1] = kernel_seq_forward(ss[fx_snake_1], false, 8, 0, 0, 1);
+			kernel_seq_depth(seq[fx_snake_1], 3);
+			kernel_seq_range(seq[fx_snake_1], KERNEL_FIRST, KERNEL_LAST);
+			kernel_seq_trigger(seq[fx_snake_1], KERNEL_TRIGGER_EXPIRE, 0, 25);
+			local->snake_1_on = true;
+		}
+		break;
+
+	case 25:
+		temp = seq[fx_snake_1];
+		seq[fx_snake_1] = kernel_seq_stamp(ss[fx_snake_1], false, 1);
+		kernel_seq_depth(seq[fx_snake_1], 3);
+		kernel_synch(KERNEL_SERIES, seq[fx_snake_1], KERNEL_SERIES, temp);
+		local->snake_1_on = false;
+		break;
+	}
+
+	switch (kernel.trigger) {
+	case 0:
+		if (!local->snake_6_on && imath_random(1, 300) == 1) {
+			seq[fx_snake_6] = kernel_seq_forward(ss[fx_snake_6], false, 8, 0, 0, 1);
+			kernel_seq_depth(seq[fx_snake_6], 3);
+			kernel_seq_range(seq[fx_snake_6], KERNEL_FIRST, 7);
+			kernel_seq_trigger(seq[fx_snake_6], KERNEL_TRIGGER_EXPIRE, 0, 10);
+			local->snake_6_on = true;
+		}
+		break;
+
+	case 10:
+		temp = seq[fx_snake_6];
+		seq[fx_snake_6] = kernel_seq_stamp(ss[fx_snake_6], false, 7);
+		kernel_seq_depth(seq[fx_snake_6], 3);
+		kernel_synch(KERNEL_SERIES, seq[fx_snake_6], KERNEL_SERIES, temp);
+		kernel_timing_trigger(imath_random(100, 200), 11);
+		break;
+
+	case 11:
+		kernel_seq_delete(seq[fx_snake_6]);
+		seq[fx_snake_6] = kernel_seq_forward(ss[fx_snake_6], false, 8, 0, 0, 1);
+		kernel_seq_depth(seq[fx_snake_6], 3);
+		kernel_seq_range(seq[fx_snake_6], 8, 11);
+		kernel_seq_trigger(seq[fx_snake_6], KERNEL_TRIGGER_EXPIRE, 0, 12);
+		local->snake_6_on = true;
+		break;
+
+	case 12:
+		local->snake_6_on = false;
+		break;
+	}
+
+	switch (kernel.trigger) {
+	case 0:
+		if (!local->snake_7_on && imath_random(1, 300) == 1) {
+			kernel_seq_delete(seq[fx_snake_7]);
+			seq[fx_snake_7] = kernel_seq_backward(ss[fx_snake_7], false, 8, 0, 0, 1);
+			kernel_seq_depth(seq[fx_snake_7], 3);
+			kernel_seq_range(seq[fx_snake_7], KERNEL_FIRST, 7);
+			kernel_seq_trigger(seq[fx_snake_7], KERNEL_TRIGGER_EXPIRE, 0, 19);
+			local->snake_7_on = true;
+		}
+		break;
+
+	case 15:
+		seq[fx_snake_7] = kernel_seq_forward(ss[fx_snake_7], false, 8, 0, 0, 1);
+		kernel_seq_depth(seq[fx_snake_7], 3);
+		kernel_seq_range(seq[fx_snake_7], 7, 20);
+		kernel_seq_trigger(seq[fx_snake_7], KERNEL_TRIGGER_EXPIRE, 0, 16);
+		break;
+
+	case 16:
+		temp = seq[fx_snake_7];
+		seq[fx_snake_7] = kernel_seq_stamp(ss[fx_snake_7], false, 20);
+		kernel_seq_depth(seq[fx_snake_7], 3);
+		kernel_synch(KERNEL_SERIES, seq[fx_snake_7], KERNEL_SERIES, temp);
+		kernel_timing_trigger(imath_random(60, 200), 17);
+		break;
 
+	case 17:
+		kernel_seq_delete(seq[fx_snake_7]);
+		seq[fx_snake_7] = kernel_seq_forward(ss[fx_snake_7], false, 8, 0, 0, 1);
+		kernel_seq_depth(seq[fx_snake_7], 3);
+		kernel_seq_range(seq[fx_snake_7], 7, 20);
+		kernel_seq_trigger(seq[fx_snake_7], KERNEL_TRIGGER_EXPIRE, 0, 18);
+		break;
+
+	case 18:
+		temp = seq[fx_snake_7];
+		seq[fx_snake_7] = kernel_seq_stamp(ss[fx_snake_7], false, 20);
+		kernel_seq_depth(seq[fx_snake_7], 3);
+		kernel_synch(KERNEL_SERIES, seq[fx_snake_7], KERNEL_SERIES, temp);
+		local->snake_7_on = false;
+		break;
+
+	case 19:
+		temp = seq[fx_snake_7];
+		seq[fx_snake_7] = kernel_seq_forward(ss[fx_snake_7], false, 8, 0, 0, 1);
+		kernel_seq_depth(seq[fx_snake_7], 3);
+		kernel_seq_range(seq[fx_snake_7], KERNEL_FIRST, 7);
+		kernel_seq_trigger(seq[fx_snake_7], KERNEL_TRIGGER_EXPIRE, 0, 15);
+		kernel_synch(KERNEL_SERIES, seq[fx_snake_7], KERNEL_SERIES, temp);
+		break;
+	}
+
+	if (!local->face_1_on && imath_random(1, 600) == 1) {
+		seq[fx_face_1] = kernel_seq_forward(ss[fx_face_1], false, 9, 0, 0, 1);
+		kernel_seq_depth(seq[fx_face_1], 10);
+		kernel_seq_range(seq[fx_face_1], KERNEL_FIRST, KERNEL_LAST);
+		kernel_seq_trigger(seq[fx_face_1], KERNEL_TRIGGER_EXPIRE, 0, ROOM_410_FACE_OFF);
+		local->face_1_on = true;
+	}
+
+	if (!local->face_2_on && imath_random(1, 600) == 1) {
+		seq[fx_face_2] = kernel_seq_forward(ss[fx_face_2], false, 9, 0, 0, 1);
+		kernel_seq_depth(seq[fx_face_2], 10);
+		kernel_seq_range(seq[fx_face_2], KERNEL_FIRST, KERNEL_LAST);
+		kernel_seq_trigger(seq[fx_face_2], KERNEL_TRIGGER_EXPIRE, 0, ROOM_410_FACE_OFF + 1);
+		local->face_2_on = true;
+	}
+
+	if (!local->face_3_on && imath_random(1, 600) == 1) {
+		seq[fx_face_3] = kernel_seq_forward(ss[fx_face_3], false, 9, 0, 0, 1);
+		kernel_seq_depth(seq[fx_face_3], 10);
+		kernel_seq_range(seq[fx_face_3], KERNEL_FIRST, KERNEL_LAST);
+		kernel_seq_trigger(seq[fx_face_3], KERNEL_TRIGGER_EXPIRE, 0, ROOM_410_FACE_OFF + 2);
+		local->face_3_on = true;
+	}
+
+	if (!local->face_4_on && imath_random(1, 600) == 1) {
+		seq[fx_face_4] = kernel_seq_forward(ss[fx_face_4], false, 9, 0, 0, 1);
+		kernel_seq_depth(seq[fx_face_4], 10);
+		kernel_seq_range(seq[fx_face_4], KERNEL_FIRST, KERNEL_LAST);
+		kernel_seq_trigger(seq[fx_face_4], KERNEL_TRIGGER_EXPIRE, 0, ROOM_410_FACE_OFF + 3);
+		local->face_4_on = true;
+	}
+
+	switch (kernel.trigger) {
+	case ROOM_410_FACE_OFF:     local->face_1_on = false; break;
+	case ROOM_410_FACE_OFF + 1: local->face_2_on = false; break;
+	case ROOM_410_FACE_OFF + 2: local->face_3_on = false; break;
+	case ROOM_410_FACE_OFF + 3: local->face_4_on = false; break;
+	}
 }
 
-void room_410_pre_parser() {
+static void room_410_pre_parser() {
+	if (inter_point_x < 271 && inter_point_y > 112) {
+	} else {
+		if (player_said_1(walk_across) || player_said_1(walk_through)) {
+			player_walk(DEATH_X, DEATH_Y, FACING_NORTHEAST);
+		} else if (!player_said_1(walk_to)) {
+			player.need_to_walk = false;
+		}
+	}
+
+	if (player_said_1(walk_through)) {
+		player_walk(DEATH_X, DEATH_Y, FACING_NORTHEAST);
+	}
 
+	if (player_said_1(shift_into_snake) ||
+	    player_said_2(invoke_power_of, crystal_ball)) {
+		player_walk(SNAKE_X, SNAKE_Y, FACING_NORTHEAST);
+	}
+
+	if (player_said_2(walk_down, path_to_east)) {
+		player_walk(DEATH_X, DEATH_Y, FACING_NORTHEAST);
+	}
 }
 
-void room_410_parser() {
+static void room_410_parser() {
+	if (player_said_2(walk_down, path_to_south)) {
+		text_show(41005);
+		new_room = 408;
+		player.command_ready = false;
+		return;
+	}
+
+	if (kernel.trigger == ROOM_410_DIE) {
+		sound_play(N_PlayerDies);
+		player.command_ready = false;
+		return;
+	}
+
+	if (((inter_point_x > 271 || inter_point_y < 112) && player_said_1(walk_across)) ||
+	    player_said_2(walk_down, path_to_east) || player_said_1(walk_through)) {
+		switch (kernel.trigger) {
+		case 0:
+			text_show(41004);
+			player.walker_visible   = false;
+			player.commands_allowed = false;
+			seq[fx_death] = kernel_seq_forward(ss[fx_death], false, 7, 0, 0, 1);
+			kernel_seq_depth(seq[fx_death], 1);
+			kernel_seq_range(seq[fx_death], KERNEL_FIRST, KERNEL_LAST);
+			kernel_seq_trigger(seq[fx_death], KERNEL_TRIGGER_SPRITE, 31, ROOM_410_DIE);
+			kernel_seq_trigger(seq[fx_death], KERNEL_TRIGGER_EXPIRE, 0, 1);
+			kernel_synch(KERNEL_SERIES, seq[fx_death], KERNEL_PLAYER, 0);
+			break;
+
+		case 1:
+			if (game.difficulty == EASY_MODE) {
+				text_show(41027);
+			} else {
+				text_show(45);
+			}
+			kernel.force_restart = true;
+			break;
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_1(shift_into_snake) ||
+	    player_said_2(invoke_power_of, crystal_ball)) {
+		switch (kernel.trigger) {
+		case 0:
+			sound_play(N_InvokeCrystalBall);
+			player.walker_visible   = false;
+			player.commands_allowed = false;
+			seq[fx_shift] = kernel_seq_forward(ss[fx_shift], false, 6, 0, 0, 1);
+			kernel_seq_depth(seq[fx_shift], 1);
+			kernel_seq_range(seq[fx_shift], KERNEL_FIRST, KERNEL_LAST);
+			kernel_seq_trigger(seq[fx_shift], KERNEL_TRIGGER_EXPIRE, 0, 1);
+			kernel_seq_trigger(seq[fx_shift], KERNEL_TRIGGER_SPRITE, 53, 3);
+			kernel_synch(KERNEL_SERIES, seq[fx_shift], KERNEL_PLAYER, 0);
+			player_demand_location(AFTER_SNAKE_X, AFTER_SNAKE_Y);
+			player_demand_facing(FACING_NORTHEAST);
+			sound_play(N_SnakeHiss);
+			break;
+
+		case 1:
+			global[player_score] += 3;
+			if (player_said_1(crystal_ball)) {
+				text_show(41023);
+				text_show(970);
+				inter_move_object(crystal_ball, NOWHERE);
+				global[crystal_ball_dead] = true;
+			} else {
+				text_show(41024);
+			}
+			player.walker_visible = true;
+			kernel_synch(KERNEL_PLAYER, 0, KERNEL_SERIES, seq[fx_shift]);
+			player_walk(WALK_TO_X, WALK_TO_Y, FACING_EAST);
+			player_walk_trigger(2);
+			break;
+
+		case 2:
+			new_room = 411;
+			break;
+
+		case 3:
+			sound_play(N_SnakeHiss);
+			break;
+		}
+		player.command_ready = false;
+		return;
+	}
 
+	if (player.look_around) {
+		text_show(41001);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_1(look) || player_said_1(look_at)) {
+
+		if (player_said_1(spirit_tree)) {
+			text_show(41003);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(snake_pit)) {
+			text_show(41008);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(ledge)) {
+			text_show(41011);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(path_to_east)) {
+			text_show(41016);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(path_to_south)) {
+			text_show(41017);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(spirit_plane)) {
+			text_show(41018);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(gnarled_root)) {
+			if (inter_point_x > 86 && inter_point_y > 95) {
+				text_show(41014);
+			} else {
+				text_show(41013);
+			}
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_2(talk_to, spirit_tree)) {
+		text_show(41007);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_1(spirit_tree)) {
+		text_show(41028);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(close, snake_pit)) {
+		text_show(41009);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_1(snake_pit)) {
+		if (player_said_1(put) || player_said_1(throw)) {
+			text_show(41010);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_2(sword, attack) ||
+	    player_said_2(sword, carve_up) ||
+	    player_said_2(sword, thrust) ||
+	    player_said_2(pour_contents_of, floor)) {
+		if (player_said_1(ledge)) {
+			text_show(41012);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_2(sword, attack) ||
+	    player_said_2(sword, carve_up) ||
+	    player_said_2(sword, thrust) ||
+	    player_said_1(take) ||
+	    player_said_1(push) ||
+	    player_said_1(pull) ||
+	    player_said_2(pour_contents_of, floor)) {
+		if (player_said_1(gnarled_root)) {
+			text_show(41015);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_2(gaze_into, crystal_ball)) {
+		text_show(41022);
+		player.command_ready = false;
+		return;
+	}
 }
 
 void room_410_synchronize(Common::Serializer &s) {
-	
+	for (int16 &v : scratch.sprite)    s.syncAsSint16LE(v);
+	for (int16 &v : scratch.sequence)  s.syncAsSint16LE(v);
+	for (int16 &v : scratch.animation) s.syncAsSint16LE(v);
+	s.syncAsSint16LE(scratch.snake_1_on);
+	s.syncAsSint16LE(scratch.snake_2_on);
+	s.syncAsSint16LE(scratch.snake_3_on);
+	s.syncAsSint16LE(scratch.snake_4_on);
+	s.syncAsSint16LE(scratch.snake_5_on);
+	s.syncAsSint16LE(scratch.snake_6_on);
+	s.syncAsSint16LE(scratch.snake_7_on);
+	s.syncAsSint16LE(scratch.snake_8_on);
+	s.syncAsSint16LE(scratch.snake_9_on);
+	s.syncAsSint16LE(scratch.snake_10_on);
+	s.syncAsSint16LE(scratch.snake_11_on);
+	s.syncAsSint16LE(scratch.face_1_on);
+	s.syncAsSint16LE(scratch.face_2_on);
+	s.syncAsSint16LE(scratch.face_3_on);
+	s.syncAsSint16LE(scratch.face_4_on);
 }
 
 void room_410_preload() {
-	room_init_code_pointer = room_410_init;
+	room_init_code_pointer       = room_410_init;
 	room_pre_parser_code_pointer = room_410_pre_parser;
-	room_parser_code_pointer = room_410_parser;
-	room_daemon_code_pointer = room_410_daemon;
+	room_parser_code_pointer     = room_410_parser;
+	room_daemon_code_pointer     = room_410_daemon;
+
+	if (kernel.teleported_in) {
+		global[player_persona] = PLAYER_IS_PID;
+	}
 
 	section_4_walker();
 	section_4_interface();
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room411.cpp b/engines/mads/madsv2/dragonsphere/rooms/room411.cpp
index 6546a0f6d8e..c293064ed25 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room411.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room411.cpp
@@ -1,4 +1,4 @@
-/* ScummVM - Graphic Adventure Engine
+/* 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
@@ -19,13 +19,16 @@
  *
  */
 
-#include "mads/madsv2/core/conv.h"
 #include "mads/madsv2/core/game.h"
+#include "mads/madsv2/core/hspot.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/player.h"
 #include "mads/madsv2/core/sound.h"
+#include "mads/madsv2/core/speech.h"
 #include "mads/madsv2/core/text.h"
-#include "mads/madsv2/dragonsphere/mads/conv.h"
 #include "mads/madsv2/dragonsphere/mads/inventory.h"
 #include "mads/madsv2/dragonsphere/mads/sounds.h"
 #include "mads/madsv2/dragonsphere/mads/words.h"
@@ -39,6 +42,28 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[15];
+	int16 sequence[15];
+	int16 animation[5];
+	int16 bird_1_frame;
+	int16 bird_1_action;
+	int16 bird_1_talk_count;
+	int16 anim_0_running;
+	int16 bird_2_frame;
+	int16 bird_2_action;
+	int16 bird_2_talk_count;
+	int16 anim_1_running;
+	int16 bird_3_frame;
+	int16 bird_3_action;
+	int16 bird_3_talk_count;
+	int16 anim_2_running;
+	int16 bird_death_frame;
+	int16 bird_death_action;
+	int16 bird_death_talk_count;
+	int16 anim_3_running;
+	int16 zap_frame;
+	int16 anim_4_running;
+	int16 prevent;
 };
 
 #define local (&scratch)
@@ -46,33 +71,970 @@ struct Scratch {
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
+#define fx_egg          0
+#define fx_grapes       1
+#define fx_throw        2
+#define fx_take         3
+#define fx_fall         4
 
-void room_411_init() {
+#define ROOM_411_COMMANDS_ALLOWED  40
+#define ROOM_411_DONE_TAKING       50
+#define ROOM_411_KILL_PID          60
+#define ROOM_411_FALL              65
 
+#define PLAYER_X_FROM_410   -13
+#define PLAYER_Y_FROM_410   112
+#define WALK_TO_X_FROM_410   13
+#define WALK_TO_Y_FROM_410  112
+
+#define FREEZE          0
+#define KILL            1
+#define EAT             2
+#define THROW           3
+#define WAIT_FOR_KILL   4
+
+#define BIRD_X          122
+#define BIRD_Y           95
+
+static Scratch scratch;
+
+
+static void handle_animation_bird_1() {
+	int bird_1_reset_frame;
+
+	if (kernel_anim[aa[0]].frame != local->bird_1_frame) {
+		local->bird_1_frame = kernel_anim[aa[0]].frame;
+		bird_1_reset_frame = -1;
+
+		switch (local->bird_1_frame) {
+
+		case 6:
+			kernel_seq_delete(seq[fx_grapes]);
+			kernel_flip_hotspot(words_magic_grapes, false);
+			global[grapes_have_grown] = GRAPES_NOT_THERE;
+			break;
+
+		case 20:
+		case 21:
+		case 22:
+		case 23:
+			switch (local->bird_1_action) {
+			case WAIT_FOR_KILL:
+				if (local->bird_1_frame == 23) {
+					bird_1_reset_frame = 21;
+				} else if (local->bird_1_frame == 22) {
+					bird_1_reset_frame = 20;
+				} else {
+					text_show(41145);
+					kernel_abort_animation(aa[0]);
+					local->anim_0_running = false;
+					local->anim_3_running = true;
+					aa[3] = kernel_run_animation(kernel_name('d', 1), 0);
+					kernel_synch(KERNEL_ANIM, aa[3], KERNEL_NOW, 0);
+				}
+				break;
+
+			case FREEZE:
+			case THROW:
+				if (imath_random(1, 12) == 1 && local->bird_1_frame == 21 && global[grapes_have_grown] == GRAPES_GROWN) {
+					bird_1_reset_frame = 0;
+				} else {
+					++local->bird_1_talk_count;
+					if (local->bird_1_talk_count > imath_random(10, 15)) {
+						if (local->bird_1_frame == 21) {
+							bird_1_reset_frame = imath_random(20, 21);
+						} else if (local->bird_1_frame == 22) {
+							bird_1_reset_frame = imath_random(20, 22);
+						} else if (local->bird_1_frame == 23) {
+							bird_1_reset_frame = imath_random(21, 22);
+						}
+						local->bird_1_talk_count = 0;
+					} else {
+						bird_1_reset_frame = local->bird_1_frame - 1;
+					}
+
+					if (local->bird_1_action == THROW ||
+					    local->bird_1_action == WAIT_FOR_KILL) {
+						bird_1_reset_frame = 20;
+					}
+				}
+				break;
+			}
+			break;
+		}
+
+		if (bird_1_reset_frame >= 0) {
+			kernel_reset_animation(aa[0], bird_1_reset_frame);
+			local->bird_1_frame = bird_1_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_bird_2() {
+	int bird_2_reset_frame;
+
+	if (kernel_anim[aa[1]].frame != local->bird_2_frame) {
+		local->bird_2_frame = kernel_anim[aa[1]].frame;
+		bird_2_reset_frame = -1;
+
+		switch (local->bird_2_frame) {
+		case 5:
+			inter_move_object(fruit, NOWHERE);
+			break;
+
+		case 8:
+			player.walker_visible   = true;
+			player.commands_allowed = true;
+			kernel_synch(KERNEL_PLAYER, 0, KERNEL_ANIM, aa[1]);
+			break;
+
+		case 36:
+			kernel_abort_animation(aa[1]);
+			aa[0] = kernel_run_animation(kernel_name('b', 1), 0);
+			kernel_reset_animation(aa[0], 21);
+			player.commands_allowed = true;
+			local->anim_1_running   = false;
+			local->anim_0_running   = true;
+			local->bird_1_action    = FREEZE;
+			kernel_synch(KERNEL_ANIM, aa[0], KERNEL_NOW, 0);
+			break;
+		}
+
+		if (bird_2_reset_frame >= 0) {
+			kernel_reset_animation(aa[1], bird_2_reset_frame);
+			local->bird_2_frame = bird_2_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_bird_3() {
+	int bird_3_reset_frame;
+
+	if (kernel_anim[aa[2]].frame != local->bird_3_frame) {
+		local->bird_3_frame = kernel_anim[aa[2]].frame;
+		bird_3_reset_frame = -1;
+
+		switch (local->bird_3_frame) {
+		case 5:
+			inter_move_object(dates, NOWHERE);
+			break;
+
+		case 8:
+			player.walker_visible = true;
+			kernel_synch(KERNEL_PLAYER, 0, KERNEL_ANIM, aa[2]);
+			break;
+
+		case 42:
+			bird_3_reset_frame = 23;
+			break;
+
+		case 18:
+			sound_play(N_BigBirdCall);
+			break;
+
+		case 24:
+		case 33:
+			if (local->bird_3_action == KILL) {
+				bird_3_reset_frame = 33;
+			} else {
+				player.commands_allowed = true;
+				if (imath_random(1, 3) == 1) {
+					bird_3_reset_frame = 24;
+				} else {
+					bird_3_reset_frame = 18;
+				}
+			}
+			break;
+
+		case 37:
+			kernel_abort_animation(aa[2]);
+			text_show(41145);
+			local->anim_2_running = false;
+			local->anim_3_running = true;
+			aa[3] = kernel_run_animation(kernel_name('d', 1), 0);
+			kernel_synch(KERNEL_ANIM, aa[3], KERNEL_NOW, 0);
+			break;
+		}
+
+		if (bird_3_reset_frame >= 0) {
+			kernel_reset_animation(aa[2], bird_3_reset_frame);
+			local->bird_3_frame = bird_3_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_bird_death() {
+	int bird_death_reset_frame;
+
+	if (kernel_anim[aa[3]].frame != local->bird_death_frame) {
+		local->bird_death_frame = kernel_anim[aa[3]].frame;
+		bird_death_reset_frame = -1;
+
+		switch (local->bird_death_frame) {
+		case 27:
+			seq[fx_fall] = kernel_seq_forward(ss[fx_fall], false, 4, 0, 0, 1);
+			kernel_seq_depth(seq[fx_fall], 1);
+			kernel_seq_range(seq[fx_fall], 6, KERNEL_LAST);
+			kernel_seq_trigger(seq[fx_fall], KERNEL_TRIGGER_EXPIRE, 0, ROOM_411_FALL);
+			kernel_synch(KERNEL_SERIES, seq[fx_fall], KERNEL_ANIM, aa[3]);
+			break;
+
+		case 1:
+			player.walker_visible = false;
+			kernel_synch(KERNEL_PLAYER, 0, KERNEL_ANIM, aa[3]);
+			break;
+
+		case 9:
+			global_speech_go(7);
+			break;
+
+		case 48:
+			if (game.difficulty == EASY_MODE) {
+				text_show(41165);
+			} else {
+				text_show(45);
+			}
+			global[pid_just_died] = true;
+			--global[player_score];
+			kernel.force_restart  = true;
+			break;
+		}
+
+		if (bird_death_reset_frame >= 0) {
+			kernel_reset_animation(aa[3], bird_death_reset_frame);
+			local->bird_death_frame = bird_death_reset_frame;
+		}
+	}
 }
 
-void room_411_daemon() {
+static void handle_animation_zap() {
+	int zap_reset_frame;
+
+	if (kernel_anim[aa[4]].frame != local->zap_frame) {
+		local->zap_frame = kernel_anim[aa[4]].frame;
+		zap_reset_frame = -1;
+
+		switch (local->zap_frame) {
+		case 30:
+			player.walker_visible = true;
+			kernel_synch(KERNEL_PLAYER, 0, KERNEL_ANIM, aa[4]);
+			break;
 
+		case 42:
+			local->anim_4_running   = false;
+			player.commands_allowed = true;
+			if (global[grapes_have_grown] == GRAPES_GROWN) {
+				text_show(41152);
+				global[grapes_are_dead] = true;
+			} else {
+				text_show(41109);
+				global[grapes_are_dead] = true;
+			}
+			break;
+		}
+
+		if (zap_reset_frame >= 0) {
+			kernel_reset_animation(aa[4], zap_reset_frame);
+			local->zap_frame = zap_reset_frame;
+		}
+	}
 }
 
-void room_411_pre_parser() {
+static void room_411_init() {
+	global[perform_displacements] = true;
+
+	if (global[pid_just_died]) {
+		inter_move_object(soul_egg, 411);
+		global[pid_just_died] = false;
+		local->bird_3_action  = FREEZE;
+	}
+
+	global[grapes_have_grown] = GRAPES_NOT_THERE;
+	local->prevent            = false;
+
+	ss[fx_fall]   = kernel_load_series(kernel_name('a', 0), false);
+	ss[fx_grapes] = kernel_load_series(kernel_name('p', 1), false);
+	ss[fx_take]   = kernel_load_series(kernel_name('a', 1), false);
+	kernel_load_series(kernel_name('y', 2), false);
+
+	kernel_flip_hotspot(words_magic_grapes, false);
+
+	if (previous_room != KERNEL_RESTORING_GAME) {
+		local->anim_0_running = false;
+		local->anim_1_running = false;
+		local->anim_2_running = false;
+		local->anim_3_running = false;
+		local->anim_4_running = false;
+	}
+
+	ss[fx_egg] = kernel_load_series(kernel_name('p', 0), false);
+
+	if (object_is_here(soul_egg)) {
+		seq[fx_egg] = kernel_seq_stamp(ss[fx_egg], false, KERNEL_FIRST);
+		kernel_seq_depth(seq[fx_egg], 2);
+	} else {
+		kernel_flip_hotspot(words_soul_egg, false);
+	}
 
+	if (object_is_here(black_sphere)) {
+		seq[fx_egg] = kernel_seq_stamp(ss[fx_egg], false, KERNEL_FIRST);
+		kernel_seq_depth(seq[fx_egg], 2);
+	} else {
+		kernel_flip_hotspot(words_black_sphere, false);
+	}
+
+	if (local->anim_2_running || global[roc_is_chewing_dates]) {
+		local->bird_1_action  = FREEZE;
+		local->anim_2_running = true;
+		aa[2] = kernel_run_animation(kernel_name('t', 2), 0);
+		kernel_synch(KERNEL_ANIM, aa[2], KERNEL_NOW, 0);
+		kernel_reset_animation(aa[2], 24);
+	} else {
+		aa[0]                 = kernel_run_animation(kernel_name('b', 1), 0);
+		local->anim_0_running = true;
+		local->bird_1_action  = FREEZE;
+		kernel_reset_animation(aa[0], 21);
+	}
+
+	if (previous_room == 410 || previous_room != KERNEL_RESTORING_GAME) {
+		player_first_walk(PLAYER_X_FROM_410, PLAYER_Y_FROM_410, FACING_EAST,
+		                  WALK_TO_X_FROM_410, WALK_TO_Y_FROM_410, FACING_EAST, true);
+	}
+
+	section_4_music();
 }
 
-void room_411_parser() {
+static void room_411_daemon() {
+	int temp;
+
+	if (local->anim_0_running) {
+		handle_animation_bird_1();
+	}
+
+	if (local->anim_1_running) {
+		handle_animation_bird_2();
+	}
+
+	if (local->anim_2_running) {
+		handle_animation_bird_3();
+	}
+
+	if (local->anim_3_running) {
+		handle_animation_bird_death();
+	}
+
+	if (local->anim_4_running) {
+		handle_animation_zap();
+	}
 
+	if (kernel.trigger == ROOM_411_FALL) {
+		temp = seq[fx_fall];
+		seq[fx_fall] = kernel_seq_stamp(ss[fx_fall], false, KERNEL_LAST);
+		kernel_seq_depth(seq[fx_fall], 1);
+		kernel_synch(KERNEL_SERIES, seq[fx_fall], KERNEL_SERIES, temp);
+	}
+
+	if (!global[grapes_have_grown] && imath_random(1, 100) == 1 && !global[grapes_are_dead]) {
+		kernel_flip_hotspot(words_magic_grapes, true);
+		global[grapes_have_grown] = GRAPES_GROWING;
+		seq[fx_grapes] = kernel_seq_forward(ss[fx_grapes], false, 7, 0, 0, 1);
+		kernel_seq_depth(seq[fx_grapes], 2);
+		kernel_seq_range(seq[fx_grapes], KERNEL_FIRST, KERNEL_LAST);
+		kernel_seq_trigger(seq[fx_grapes], KERNEL_TRIGGER_EXPIRE, 0, 1);
+	}
+
+	if (kernel.trigger == 1) {
+		temp = seq[fx_grapes];
+		seq[fx_grapes] = kernel_seq_stamp(ss[fx_grapes], false, KERNEL_LAST);
+		kernel_seq_depth(seq[fx_grapes], 2);
+		global[grapes_have_grown] = GRAPES_GROWN;
+		kernel_synch(KERNEL_SERIES, seq[fx_grapes], KERNEL_SERIES, temp);
+	}
+}
+
+static void room_411_pre_parser() {
+	if (player_said_2(walk_down, path_to_west)) {
+		player.walk_off_edge_to_room = 408;
+	}
+
+	if (player_said_1(Roc_s_nest)) {
+		if (player.x == BIRD_X && player.y == BIRD_Y) {
+			player.need_to_walk = false;
+		} else if (player.need_to_walk) {
+			player_walk(BIRD_X, BIRD_Y, FACING_NORTHEAST);
+		}
+	}
+
+	if (player_said_2(take_magic_from, magic_grapes) ||
+	    player_said_2(take_magic_from, grape_vine)) {
+		player_walk(BIRD_X, BIRD_Y, FACING_NORTHEAST);
+	}
+
+	if (player_said_3(throw, Roc, fruit) ||
+	    player_said_3(throw, Roc, dates) ||
+	    player_said_3(give, Roc, dates) ||
+	    player_said_3(give, Roc, fruit) ||
+	    player_said_3(put, black_sphere, Roc_s_nest) ||
+	    player_said_3(throw, black_sphere, Roc_s_nest)) {
+
+		if (player.x == BIRD_X && player.y == BIRD_Y) {
+			player.need_to_walk = false;
+		} else {
+			player_walk(BIRD_X, BIRD_Y, FACING_NORTHEAST);
+		}
+	}
+
+	if (global[roc_is_chewing_dates]) {
+		if (player.need_to_walk && player_has(soul_egg) && !object_is_here(black_sphere)) {
+			local->bird_3_action    = KILL;
+			player.commands_allowed = false;
+			player_cancel_command();
+		}
+	}
+}
+
+static void room_411_parser() {
+	if (player_said_2(take_magic_from, magic_grapes) ||
+	    player_said_2(take_magic_from, grape_vine)) {
+
+		if (global[grapes_are_dead]) {
+			text_show(41162);
+		} else if (global[roc_is_chewing_dates]) {
+			text_show(41167);
+		} else {
+			player.commands_allowed = false;
+			player.walker_visible   = false;
+			local->anim_4_running   = true;
+			aa[4]                   = kernel_run_animation(kernel_name('x', 1), 0);
+			global[player_score]   += 3;
+			kernel_synch(KERNEL_ANIM, aa[4], KERNEL_NOW, 0);
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(take, soul_egg)) {
+		switch (kernel.trigger) {
+		case 0:
+			if (!player_has(soul_egg)) {
+				player.commands_allowed = false;
+				player.walker_visible   = false;
+				seq[fx_take] = kernel_seq_pingpong(ss[fx_take], false, 7, 0, 0, 2);
+				kernel_seq_trigger(seq[fx_take], KERNEL_TRIGGER_SPRITE, 12, 1);
+				kernel_seq_trigger(seq[fx_take], KERNEL_TRIGGER_EXPIRE, 0, 2);
+				kernel_seq_depth(seq[fx_take], 1);
+				kernel_seq_range(seq[fx_take], KERNEL_FIRST, KERNEL_LAST);
+				kernel_synch(KERNEL_SERIES, seq[fx_take], KERNEL_PLAYER, 0);
+				player.command_ready = false;
+				return;
+			}
+			break;
+
+		case 1:
+			if (local->prevent) {
+				kernel_seq_delete(seq[fx_egg]);
+				kernel_flip_hotspot(words_soul_egg, false);
+				++global[player_score];
+				sound_play(N_TakeObjectSnd);
+				inter_give_to_player(soul_egg);
+				if (local->anim_2_running) {
+					object_examine(soul_egg, 41151, 0);
+				} else {
+					object_examine(soul_egg, 41161, 0);
+				}
+			}
+			local->prevent = true;
+			player.command_ready = false;
+			return;
+
+		case 2:
+			player.walker_visible = true;
+			local->prevent        = false;
+			kernel_synch(KERNEL_PLAYER, 0, KERNEL_SERIES, seq[fx_take]);
+
+			if (!local->anim_2_running) {
+				local->bird_1_action = WAIT_FOR_KILL;
+			} else {
+				player.commands_allowed = true;
+			}
+
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_3(put, black_sphere, Roc_s_nest) ||
+	    player_said_3(throw, black_sphere, Roc_s_nest)) {
+
+		if (!player_has(soul_egg)) {
+			text_show(41138);
+			player.command_ready = false;
+			return;
+		} else switch (kernel.trigger) {
+		case 0:
+			if (player_has(black_sphere)) {
+				player.commands_allowed = false;
+				player.walker_visible   = false;
+				seq[fx_take] = kernel_seq_pingpong(ss[fx_take], false, 7, 0, 0, 2);
+				kernel_seq_trigger(seq[fx_take], KERNEL_TRIGGER_SPRITE, 12, 1);
+				kernel_seq_trigger(seq[fx_take], KERNEL_TRIGGER_EXPIRE, 0, 2);
+				kernel_seq_depth(seq[fx_take], 1);
+				kernel_seq_range(seq[fx_take], KERNEL_FIRST, KERNEL_LAST);
+				kernel_synch(KERNEL_SERIES, seq[fx_take], KERNEL_PLAYER, 0);
+				player.command_ready = false;
+				return;
+			}
+			break;
+
+		case 1:
+			if (local->prevent) {
+				ss[fx_egg]  = kernel_load_series(kernel_name('p', 0), false);
+				seq[fx_egg] = kernel_seq_stamp(ss[fx_egg], false, KERNEL_FIRST);
+				kernel_seq_depth(seq[fx_egg], 2);
+				kernel_flip_hotspot(words_black_sphere, true);
+
+				global[player_score] += 3;
+				inter_move_object(black_sphere, 411);
+			}
+			local->prevent = true;
+			player.command_ready = false;
+			return;
+
+		case 2:
+			text_show(41147);
+			player.walker_visible   = true;
+			player.commands_allowed = true;
+			local->prevent          = false;
+			kernel_synch(KERNEL_PLAYER, 0, KERNEL_SERIES, seq[fx_take]);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_3(throw, Roc, fruit) ||
+	    player_said_3(give, Roc, fruit)) {
+
+		if (global[roc_is_chewing_dates]) {
+			text_show(41160);
+		} else if (!global[grapes_are_dead]) {
+			text_show(41135);
+		} else {
+			local->bird_1_action    = THROW;
+			player.commands_allowed = false;
+
+			if (local->bird_1_frame != 20) {
+				kernel_timing_trigger(1, 2);
+			} else {
+				kernel_abort_animation(aa[0]);
+				local->bird_1_action  = FREEZE;
+				player.walker_visible = false;
+				local->anim_1_running = true;
+				local->anim_0_running = false;
+				aa[1] = kernel_run_animation(kernel_name('t', 1), 0);
+				kernel_synch(KERNEL_ANIM, aa[1], KERNEL_NOW, 0);
+			}
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_3(throw, Roc, dates) ||
+	    player_said_3(give, Roc, dates)) {
+
+		if (global[roc_is_chewing_dates]) {
+			text_show(41160);
+		} else if (!global[grapes_are_dead]) {
+			text_show(41135);
+		} else {
+			local->bird_1_action    = THROW;
+			player.commands_allowed = false;
+
+			if (local->bird_1_frame != 20) {
+				kernel_timing_trigger(1, 2);
+			} else {
+				global[roc_is_chewing_dates] = true;
+				global[player_score] += 3;
+				kernel_abort_animation(aa[0]);
+				local->bird_1_action  = FREEZE;
+				local->bird_3_action  = FREEZE;
+				player.walker_visible = false;
+				local->anim_2_running = true;
+				local->anim_0_running = false;
+				aa[2] = kernel_run_animation(kernel_name('t', 2), 0);
+				kernel_synch(KERNEL_ANIM, aa[2], KERNEL_NOW, 0);
+			}
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(invoke_power_of, crystal_ball)) {
+		if (!global[roc_is_chewing_dates]) switch (kernel.trigger) {
+		case 0:
+			sound_play(N_InvokeCrystalBall);
+			text_show(970);
+			player.commands_allowed = false;
+			kernel_timing_trigger(FOUR_SECONDS, 1);
+			global[player_score] += 3;
+			kernel_abort_animation(aa[0]);
+			local->bird_1_action  = FREEZE;
+			local->bird_3_action  = FREEZE;
+			local->anim_2_running = true;
+			local->anim_0_running = false;
+			aa[2] = kernel_run_animation(kernel_name('t', 2), 0);
+			kernel_reset_animation(aa[2], 38);
+			kernel_synch(KERNEL_ANIM, aa[2], KERNEL_NOW, 0);
+			player.command_ready = false;
+			return;
+
+		case 1:
+			global[roc_is_chewing_dates] = true;
+			global[crystal_ball_dead]    = true;
+			player.commands_allowed      = true;
+			inter_move_object(crystal_ball, NOWHERE);
+			text_show(41149);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player.look_around) {
+		if (object_is_here(soul_egg)) {
+			text_show(41101);
+		} else if (object_is_here(black_sphere)) {
+			text_show(41102);
+		} else {
+			text_show(41121);
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_1(look) || player_said_1(look_at)) {
+
+		if (player_said_1(spirit_tree)) {
+			text_show(41103);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(grape_vine)) {
+			text_show(41105);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(black_sphere) && object_is_here(black_sphere)) {
+			text_show(41155);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(magic_grapes)) {
+			if (global[grapes_are_dead]) {
+				text_show(41158);
+			} else if (game.difficulty == HARD_MODE) {
+				text_show(41110);
+			} else {
+				text_show(41111);
+			}
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(sand)) {
+			text_show(41118);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(path_to_west)) {
+			text_show(41119);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(Roc_s_nest)) {
+			if (object_is_here(soul_egg)) {
+				text_show(41120);
+			} else if (object_is_here(black_sphere)) {
+				text_show(41102);
+			} else {
+				text_show(41121);
+			}
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(spirit_plane)) {
+			text_show(41125);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(Roc)) {
+			if (local->anim_2_running) {
+				if (player_has(dates)) {
+					text_show(41157);
+				} else if (player_has(soul_egg)) {
+					text_show(41159);
+				} else {
+					text_show(41128);
+				}
+			} else if (global[grapes_are_dead]) {
+				text_show(41127);
+			} else {
+				text_show(41126);
+			}
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(soul_egg) && object_is_here(soul_egg)) {
+			text_show(41144);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_2(talk_to, spirit_tree)) {
+		text_show(41104);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(sword, attack) ||
+	    player_said_2(sword, carve_up) ||
+	    player_said_2(sword, thrust) ||
+	    player_said_2(pour, flask_full_of_acid)) {
+
+		if (player_said_1(grape_vine) ||
+		    player_said_1(spirit_tree)) {
+			text_show(61407);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_2(sword, attack) ||
+	    player_said_2(sword, carve_up) ||
+	    player_said_2(sword, thrust) ||
+	    player_said_1(pull) ||
+	    player_said_2(pour, flask_full_of_acid)) {
+
+		if (player_said_1(Roc_s_nest)) {
+			text_show(41122);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_2(heal, spirit_tree)) {
+		text_show(41108);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(open, Roc_s_nest)) {
+		if (object_is_here(soul_egg)) {
+			text_show(41123);
+		} else {
+			text_show(41124);
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(take, magic_grapes) ||
+	    player_said_2(pull, magic_grapes) ||
+	    player_said_2(heal, magic_grapes)) {
+		text_show(41112);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_1(take_magic_from) || player_said_1(put_magic_into)) {
+		if (player_said_1(spirit_tree) ||
+		    player_said_1(grape_vine)) {
+			text_show(41108);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_2(take, grape_vine) || player_said_2(pull, grape_vine)) {
+		if (global[grapes_are_dead]) {
+			text_show(41117);
+		} else {
+			text_show(41106);
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(throw, magic_grapes)) {
+		if (player_said_1(mud)) {
+			text_show(41115);
+		} else if (player_said_1(soporific)) {
+			text_show(41116);
+		} else {
+			text_show(41113);
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(sword, attack) ||
+	    player_said_2(sword, carve_up) ||
+	    player_said_2(sword, thrust)) {
+
+		if (player_said_1(magic_grapes)) {
+			text_show(41114);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_2(sword, attack) ||
+	    player_said_2(sword, carve_up) ||
+	    player_said_2(sword, thrust) ||
+	    player_said_1(push) ||
+	    player_said_1(pull)) {
+
+		if (player_said_1(Roc)) {
+			text_show(41129);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_2(talk_to, Roc)) {
+		text_show(41130);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(throw, Roc) ||
+	    player_said_2(give, Roc)) {
+
+		if (player_said_1(bone) || player_said_1(tentacle_parts)) {
+			text_show(41132);
+		} else if (player_said_1(soporific)) {
+			text_show(41141);
+		} else if (player_said_1(dead_rat) || player_said_1(ratsicle)) {
+			if (global[grapes_are_dead]) {
+				text_show(41154);
+			} else {
+				text_show(41135);
+			}
+		} else if (player_said_1(bird_figurine)) {
+			if (object_is_here(soul_egg)) {
+				text_show(41139);
+			} else {
+				text_show(41140);
+			}
+		} else {
+			if (object_is_here(soul_egg)) {
+				text_show(41139);
+			} else {
+				text_show(41140);
+			}
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(make_noise, birdcall) ||
+	    player_said_2(rub, bird_figurine) ||
+	    player_said_2(rub, birdcall)) {
+		text_show(41136);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(open, flies)) {
+		if (global[grapes_are_dead]) {
+			text_show(41137);
+		} else {
+			text_show(41135);
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_1(shift_into_bear) || player_said_1(shift_into_seal) ||
+	    player_said_1(shift_into_snake)) {
+		text_show(41142);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(speak_words_on, parchment)) {
+		text_show(41143);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(gaze_into, crystal_ball)) {
+		if (!global[roc_is_chewing_dates]) {
+			text_show(41148);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_2(put_magic_into, magic_grapes) ||
+	    player_said_2(put_magic_into, grape_vine)) {
+		if (global[grapes_are_dead]) {
+			text_show(41163);
+		} else {
+			text_show(41164);
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(take, black_sphere) && !player_has(black_sphere)) {
+		text_show(41166);
+		player.command_ready = false;
+		return;
+	}
 }
 
 void room_411_synchronize(Common::Serializer &s) {
-	
+	for (int16 &v : scratch.sprite)    s.syncAsSint16LE(v);
+	for (int16 &v : scratch.sequence)  s.syncAsSint16LE(v);
+	for (int16 &v : scratch.animation) s.syncAsSint16LE(v);
+	s.syncAsSint16LE(scratch.bird_1_frame);
+	s.syncAsSint16LE(scratch.bird_1_action);
+	s.syncAsSint16LE(scratch.bird_1_talk_count);
+	s.syncAsSint16LE(scratch.anim_0_running);
+	s.syncAsSint16LE(scratch.bird_2_frame);
+	s.syncAsSint16LE(scratch.bird_2_action);
+	s.syncAsSint16LE(scratch.bird_2_talk_count);
+	s.syncAsSint16LE(scratch.anim_1_running);
+	s.syncAsSint16LE(scratch.bird_3_frame);
+	s.syncAsSint16LE(scratch.bird_3_action);
+	s.syncAsSint16LE(scratch.bird_3_talk_count);
+	s.syncAsSint16LE(scratch.anim_2_running);
+	s.syncAsSint16LE(scratch.bird_death_frame);
+	s.syncAsSint16LE(scratch.bird_death_action);
+	s.syncAsSint16LE(scratch.bird_death_talk_count);
+	s.syncAsSint16LE(scratch.anim_3_running);
+	s.syncAsSint16LE(scratch.zap_frame);
+	s.syncAsSint16LE(scratch.anim_4_running);
+	s.syncAsSint16LE(scratch.prevent);
 }
 
 void room_411_preload() {
-	room_init_code_pointer = room_411_init;
+	room_init_code_pointer       = room_411_init;
 	room_pre_parser_code_pointer = room_411_pre_parser;
-	room_parser_code_pointer = room_411_parser;
-	room_daemon_code_pointer = room_411_daemon;
+	room_parser_code_pointer     = room_411_parser;
+	room_daemon_code_pointer     = room_411_daemon;
+
+	if (kernel.teleported_in) {
+		global[player_persona] = PLAYER_IS_PID;
+	}
 
 	section_4_walker();
 	section_4_interface();
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room412.cpp b/engines/mads/madsv2/dragonsphere/rooms/room412.cpp
index b2a4b6f2ba2..d596cbcaf85 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room412.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room412.cpp
@@ -1,4 +1,4 @@
-/* ScummVM - Graphic Adventure Engine
+/* 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
@@ -19,16 +19,12 @@
  *
  */
 
-#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/sound.h"
+#include "mads/madsv2/core/matte.h"
+#include "mads/madsv2/core/player.h"
 #include "mads/madsv2/core/text.h"
-#include "mads/madsv2/dragonsphere/mads/conv.h"
-#include "mads/madsv2/dragonsphere/mads/inventory.h"
-#include "mads/madsv2/dragonsphere/mads/sounds.h"
-#include "mads/madsv2/dragonsphere/mads/words.h"
 #include "mads/madsv2/dragonsphere/global.h"
 #include "mads/madsv2/dragonsphere/rooms/section4.h"
 #include "mads/madsv2/dragonsphere/rooms/room412.h"
@@ -39,6 +35,9 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[15];
+	int16 sequence[15];
+	int16 animation[4];
 };
 
 #define local (&scratch)
@@ -46,33 +45,54 @@ struct Scratch {
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
+#define fx_test         0
+#define fx_test_2       1
 
-void room_412_init() {
+static Scratch scratch;
 
-}
 
-void room_412_daemon() {
+static void room_412_init() {
+	global[perform_displacements] = true;
 
-}
+	viewing_at_y = ((video_y - display_y) >> 1);
+	kernel_init_dialog();
+	kernel_set_interface_mode(INTER_LIMITED_SENTENCES);
 
-void room_412_pre_parser() {
+	player.commands_allowed = false;
+	player.walker_visible   = false;
+	aa[0] = kernel_run_animation(kernel_name('w', 1), 1);
+}
 
+static void room_412_daemon() {
+	if (kernel.trigger == 1) {
+		text_show(41201);
+		global[from_direction] = FROM_EAST;
+		global[desert_room]    = 42;
+		global[desert_counter] = 0;
+		new_room               = 401;
+		global[no_load_walker] = false;
+	}
 }
 
-void room_412_parser() {
+static void room_412_pre_parser() {
+}
 
+static void room_412_parser() {
 }
 
 void room_412_synchronize(Common::Serializer &s) {
-	
+	for (int16 &v : scratch.sprite)    s.syncAsSint16LE(v);
+	for (int16 &v : scratch.sequence)  s.syncAsSint16LE(v);
+	for (int16 &v : scratch.animation) s.syncAsSint16LE(v);
 }
 
 void room_412_preload() {
-	room_init_code_pointer = room_412_init;
+	room_init_code_pointer       = room_412_init;
 	room_pre_parser_code_pointer = room_412_pre_parser;
-	room_parser_code_pointer = room_412_parser;
-	room_daemon_code_pointer = room_412_daemon;
+	room_parser_code_pointer     = room_412_parser;
+	room_daemon_code_pointer     = room_412_daemon;
+
+	global[no_load_walker] = true;
 
 	section_4_walker();
 	section_4_interface();
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room454.cpp b/engines/mads/madsv2/dragonsphere/rooms/room454.cpp
index ff9b9024563..bc021d9e50b 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room454.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room454.cpp
@@ -1,4 +1,4 @@
-/* ScummVM - Graphic Adventure Engine
+/* 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
@@ -19,16 +19,13 @@
  *
  */
 
-#include "mads/madsv2/core/conv.h"
+#include "mads/madsv2/core/camera.h"
 #include "mads/madsv2/core/game.h"
-#include "mads/madsv2/core/imath.h"
 #include "mads/madsv2/core/kernel.h"
+#include "mads/madsv2/core/matte.h"
+#include "mads/madsv2/core/player.h"
 #include "mads/madsv2/core/sound.h"
 #include "mads/madsv2/core/text.h"
-#include "mads/madsv2/dragonsphere/mads/conv.h"
-#include "mads/madsv2/dragonsphere/mads/inventory.h"
-#include "mads/madsv2/dragonsphere/mads/sounds.h"
-#include "mads/madsv2/dragonsphere/mads/words.h"
 #include "mads/madsv2/dragonsphere/global.h"
 #include "mads/madsv2/dragonsphere/rooms/section4.h"
 #include "mads/madsv2/dragonsphere/rooms/room454.h"
@@ -39,6 +36,19 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[15];
+	int16 sequence[15];
+	int16 animation[4];
+	int16 dune_3_base;
+	int16 dyn_dune_3;
+	int16 dune_4_base;
+	int16 dyn_dune_4;
+	int16 mount_left_base;
+	int16 dyn_mount_left;
+	int16 mount_right_base;
+	int16 dyn_mount_right;
+	int16 king_frame;
+	int16 anim_0_running;
 };
 
 #define local (&scratch)
@@ -46,33 +56,288 @@ struct Scratch {
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
+#define fx_dune_3       0
+#define fx_dune_4       1
+#define fx_oasis        2
+#define fx_mount_left   3
+#define fx_mount_right  4
+#define fx_cloud_left   5
+#define fx_cloud_right  6
 
-void room_454_init() {
+#define camera_ratio_1  1
+#define camera_ratio_2  2
 
+#define WALK_1_X        645
+#define WALK_1_Y        130
+#define WALK_2_X        202
+#define WALK_2_Y        130
+#define WALK_3_X        121
+#define WALK_3_Y        112
+#define WALK_4_X          1
+#define WALK_4_Y        104
+
+static Scratch scratch;
+
+
+static void set_dune_3_position() {
+	int center;
+	int difference;
+	int direction;
+	int distance;
+	int displace;
+	int x;
+	int xs;
+
+	center = picture_view_x + (video_x >> 1);
+
+	if (seq[fx_dune_3] >= 0) {
+		kernel_seq_delete(seq[fx_dune_3]);
+	}
+
+	difference = center - local->dune_3_base;
+	direction  = neg(sgn(difference));
+	distance   = abs(difference);
+
+	displace   = (int)(((long)distance * camera_ratio_1) / camera_ratio_2);
+	displace   = sgn_in(displace, direction);
+
+	x          = local->dune_3_base + displace - 1;
+	xs         = series_list[ss[fx_dune_3]]->index[0].xs;
+
+	if (((x - ((xs >> 1) + 1)) >= (picture_view_x + video_x)) ||
+	    ((x + ((xs >> 1) + 1)) < picture_view_x)) {
+		seq[fx_dune_3] = -1;
+	} else {
+		seq[fx_dune_3] = kernel_seq_stamp(ss[fx_dune_3], false, 1);
+		kernel_seq_loc(seq[fx_dune_3], x, 155);
+		kernel_seq_depth(seq[fx_dune_3], 1);
+	}
+}
+
+static void set_dune_4_position() {
+	int center;
+	int difference;
+	int direction;
+	int distance;
+	int displace;
+	int x;
+	int xs;
+
+	center = picture_view_x + (video_x >> 1);
+
+	if (seq[fx_dune_4] >= 0) {
+		kernel_seq_delete(seq[fx_dune_4]);
+	}
+
+	difference = center - local->dune_4_base;
+	direction  = neg(sgn(difference));
+	distance   = abs(difference);
+
+	displace   = (int)(((long)distance * camera_ratio_1) / camera_ratio_2);
+	displace   = sgn_in(displace, direction);
+
+	x          = local->dune_4_base + displace - 1;
+	xs         = series_list[ss[fx_dune_4]]->index[0].xs;
+
+	if (((x - ((xs >> 1) + 1)) >= (picture_view_x + video_x)) ||
+	    ((x + ((xs >> 1) + 1)) < picture_view_x)) {
+		seq[fx_dune_4] = -1;
+	} else {
+		seq[fx_dune_4] = kernel_seq_stamp(ss[fx_dune_4], false, 1);
+		kernel_seq_loc(seq[fx_dune_4], x, 155);
+		kernel_seq_depth(seq[fx_dune_4], 1);
+	}
+}
+
+static void set_454_mount_left_position() {
+	int difference;
+	int x;
+
+	difference = ((280 - picture_view_x) * 4) / 5;
+	x = series_list[ss[fx_mount_left]]->index[0].x - difference;
+	x += 1;
+
+	kernel_seq_delete(seq[fx_mount_left]);
+	seq[fx_mount_left] = kernel_seq_stamp(ss[fx_mount_left], false, 1);
+	kernel_seq_loc(seq[fx_mount_left], x, 85);
+	kernel_seq_depth(seq[fx_mount_left], 12);
+}
+
+static void set_454_mount_right_position() {
+	int difference;
+	int x;
+
+	difference = ((280 - picture_view_x) * 4) / 5;
+	x = series_list[ss[fx_mount_right]]->index[0].x - difference;
+	x += 320;
+
+	kernel_seq_delete(seq[fx_mount_right]);
+	seq[fx_mount_right] = kernel_seq_stamp(ss[fx_mount_right], false, 1);
+	kernel_seq_loc(seq[fx_mount_right], x, 85);
+	kernel_seq_depth(seq[fx_mount_right], 12);
+}
+
+static void set_454_cloud_left_position() {
+	int difference;
+	int x;
+
+	difference = ((280 - picture_view_x) * 10) / 11;
+	x = series_list[ss[fx_cloud_left]]->index[0].x - difference;
+	x += -38;
+
+	kernel_seq_delete(seq[fx_cloud_left]);
+	seq[fx_cloud_left] = kernel_seq_stamp(ss[fx_cloud_left], false, 1);
+	kernel_seq_loc(seq[fx_cloud_left], x, 70);
+	kernel_seq_depth(seq[fx_cloud_left], 15);
 }
 
-void room_454_daemon() {
+static void set_454_cloud_right_position() {
+	int difference;
+	int x;
 
+	difference = ((280 - picture_view_x) * 10) / 11;
+	x = series_list[ss[fx_cloud_right]]->index[0].x - difference;
+	x += 280;
+
+	kernel_seq_delete(seq[fx_cloud_right]);
+	seq[fx_cloud_right] = kernel_seq_stamp(ss[fx_cloud_right], false, 1);
+	kernel_seq_loc(seq[fx_cloud_right], x, 75);
+	kernel_seq_depth(seq[fx_cloud_right], 3);
 }
 
-void room_454_pre_parser() {
+static void handle_animation_king() {
+	int king_reset_frame;
+
+	if (kernel_anim[aa[0]].frame != local->king_frame) {
+		local->king_frame = kernel_anim[aa[0]].frame;
+		king_reset_frame = -1;
+
+		switch (local->king_frame) {
+
+		case 210:
+			camera_pan_to(&camera_x, 0);
+			break;
 
+		case 498:
+			camera_x.pan_mode      = CAMERA_PLAYER;
+			global[from_direction] = FROM_EAST;
+			global[no_load_walker] = false;
+			new_room               = 405;
+			break;
+		}
+
+		if (king_reset_frame >= 0) {
+			kernel_reset_animation(aa[0], king_reset_frame);
+			local->king_frame = king_reset_frame;
+		}
+	}
 }
 
-void room_454_parser() {
+static void room_454_init() {
+	global[perform_displacements] = true;
+
+	player.commands_allowed = false;
+	player.walker_visible   = false;
+
+	camera_x.pan_mode = CAMERA_MANUAL;
+	camera_jump_to(280, 0);
+
+	local->anim_0_running = false;
+
+	ss[fx_mount_left]  = kernel_load_series(kernel_name('x', 0), false);
+	ss[fx_mount_right] = kernel_load_series(kernel_name('x', 1), false);
+
+	ss[fx_cloud_left]  = kernel_load_series(kernel_name('c', 0), false);
+	ss[fx_cloud_right] = kernel_load_series(kernel_name('c', 1), false);
+
+	if (previous_room != KERNEL_RESTORING_GAME) {
+		ss[fx_dune_3] = kernel_load_series(kernel_name('x', 3), false);
+		ss[fx_dune_4] = kernel_load_series(kernel_name('x', 2), false);
+		ss[fx_oasis]  = kernel_load_series(kernel_name('x', 4), false);
+
+		seq[fx_oasis] = kernel_seq_stamp(ss[fx_oasis], false, 1);
+		kernel_seq_depth(seq[fx_oasis], 8);
+
+		seq[fx_dune_3]     = -1;
+		local->dyn_dune_3  = -1;
+		local->dune_3_base = 110;
+
+		seq[fx_dune_4]     = -1;
+		local->dyn_dune_4  = -1;
+		local->dune_4_base = 505;
+
+		set_dune_3_position();
+		set_dune_4_position();
+
+		aa[0]                 = kernel_run_animation(kernel_name('k', 1), 0);
+		kernel_reset_animation(aa[0], 21);
+		local->anim_0_running = true;
+	}
+
+	seq[fx_mount_left] = kernel_seq_stamp(ss[fx_mount_left], false, 1);
+	kernel_seq_loc(seq[fx_mount_left], 270, 85);
+	kernel_seq_depth(seq[fx_mount_left], 12);
+
+	seq[fx_mount_right] = kernel_seq_stamp(ss[fx_mount_right], false, 1);
+	kernel_seq_loc(seq[fx_mount_right], 480, 85);
+	kernel_seq_depth(seq[fx_mount_right], 12);
+
+	seq[fx_cloud_left] = kernel_seq_stamp(ss[fx_cloud_left], false, 1);
+	kernel_seq_loc(seq[fx_cloud_left], 258, 70);
+	kernel_seq_depth(seq[fx_cloud_left], 15);
+
+	seq[fx_cloud_right] = kernel_seq_stamp(ss[fx_cloud_right], false, 1);
+	kernel_seq_loc(seq[fx_cloud_right], 441, 75);
+	kernel_seq_depth(seq[fx_cloud_right], 3);
+
+	viewing_at_y = ((video_y - display_y) >> 1);
+
+	section_4_music();
+}
+
+static void room_454_daemon() {
+	if (local->anim_0_running) {
+		handle_animation_king();
+	}
+
+	if (camera_x.pan_this_frame) {
+		set_454_mount_left_position();
+		set_454_mount_right_position();
+		set_454_cloud_left_position();
+		set_454_cloud_right_position();
+
+		set_dune_3_position();
+		set_dune_4_position();
+	}
+}
+
+static void room_454_pre_parser() {
+}
 
+static void room_454_parser() {
 }
 
 void room_454_synchronize(Common::Serializer &s) {
-	
+	for (int16 &v : scratch.sprite)    s.syncAsSint16LE(v);
+	for (int16 &v : scratch.sequence)  s.syncAsSint16LE(v);
+	for (int16 &v : scratch.animation) s.syncAsSint16LE(v);
+	s.syncAsSint16LE(scratch.dune_3_base);
+	s.syncAsSint16LE(scratch.dyn_dune_3);
+	s.syncAsSint16LE(scratch.dune_4_base);
+	s.syncAsSint16LE(scratch.dyn_dune_4);
+	s.syncAsSint16LE(scratch.mount_left_base);
+	s.syncAsSint16LE(scratch.dyn_mount_left);
+	s.syncAsSint16LE(scratch.mount_right_base);
+	s.syncAsSint16LE(scratch.dyn_mount_right);
+	s.syncAsSint16LE(scratch.king_frame);
+	s.syncAsSint16LE(scratch.anim_0_running);
 }
 
 void room_454_preload() {
-	room_init_code_pointer = room_454_init;
+	room_init_code_pointer       = room_454_init;
 	room_pre_parser_code_pointer = room_454_pre_parser;
-	room_parser_code_pointer = room_454_parser;
-	room_daemon_code_pointer = room_454_daemon;
+	room_parser_code_pointer     = room_454_parser;
+	room_daemon_code_pointer     = room_454_daemon;
 
 	section_4_walker();
 	section_4_interface();




More information about the Scummvm-git-logs mailing list