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

dreammaster noreply at scummvm.org
Wed May 20 12:43:41 UTC 2026


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

Summary:
a5f4d0d548 MADS: DRAGONSPHERE: Added rooms 401 to 406


Commit: a5f4d0d5484fac9d8ba6c3194b98d8611a84f094
    https://github.com/scummvm/scummvm/commit/a5f4d0d5484fac9d8ba6c3194b98d8611a84f094
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-05-20T22:42:43+10:00

Commit Message:
MADS: DRAGONSPHERE: Added rooms 401 to 406

Changed paths:
    engines/mads/madsv2/dragonsphere/mads/conv.h
    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/room401.cpp
    engines/mads/madsv2/dragonsphere/rooms/room402.cpp
    engines/mads/madsv2/dragonsphere/rooms/room403.cpp
    engines/mads/madsv2/dragonsphere/rooms/room404.cpp
    engines/mads/madsv2/dragonsphere/rooms/room405.cpp
    engines/mads/madsv2/dragonsphere/rooms/room406.cpp


diff --git a/engines/mads/madsv2/dragonsphere/mads/conv.h b/engines/mads/madsv2/dragonsphere/mads/conv.h
index 3d28fb9da10..a22195d1d6e 100644
--- a/engines/mads/madsv2/dragonsphere/mads/conv.h
+++ b/engines/mads/madsv2/dragonsphere/mads/conv.h
@@ -154,6 +154,85 @@ enum {
 	conv035_exit_b_b    =  3
 };
 
+enum {
+	conv038_third_yes        =  2,
+	conv038_third_idont      =  4,
+	conv038_third_blab       =  5,
+	conv038_knowledge_yes    = 12,
+	conv038_knowledge_no     = 13,
+	conv038_knowledge_idont  = 14,
+	conv038_fourth_nound     = 21
+};
+
+enum {
+	conv039_greeting_only    =  0,
+	conv039_choices_b_b      =  2,
+	conv039_gift_b_b         = 19,
+	conv039_pre_addon_b_b    = 30,
+	conv039_exit_b_b         = 36,
+	conv039_exit_d_d         = 38
+};
+
+enum {
+	conv040_enter_b_b        =  4,
+	conv040_repeater         =  7,
+	conv040_leave_b_b        =  8
+};
+
+enum {
+	conv041_indance          = 17,
+	conv041_postdanc         = 21,
+	conv041_postgame         = 24,
+
+	conv041_danceyn_no       = 15,
+	conv041_to_game_b_b      = 17,
+	conv041_to_game_d_d      = 19,
+	conv041_dance_b_b        = 24,
+	conv041_postdance_b_b    = 35,
+	conv041_postdanc_only    = 36,
+	conv041_leaving          = 41,
+	conv041_give_stuff_a_a   = 42,
+	conv041_give_stuff_b_b   = 43,
+	conv041_give_stuff_f_f   = 45,
+	conv041_give_stuff_c_c   = 46,
+	conv041_give_stuff_d_d   = 47,
+	conv041_exit_b_b         = 64,
+	conv041_exit_d_d         = 66,
+	conv041_exit_f_f         = 68
+};
+
+enum {
+	conv043_greeting         =  0,
+	conv043_restart          =  4,
+	conv043_homenow          = 14,
+	conv043_rise_b_b         = 17,
+	conv043_rise_d_d         = 19,
+	conv043_exit_b_b         = 21,
+	conv043_exit_d_d         = 23
+};
+
+enum {
+	conv044_repeater         =  0,
+	conv044_greet            =  2,
+	conv044_leave_b_b        =  7,
+	conv044_enter_b_b        =  9
+};
+
+enum {
+	conv045_egaming_only     =  4,
+	conv045_hgaming_only     =  5,
+	conv045_to_game_b_b      =  9,
+	conv045_giver            = 11,
+	conv045_exit_b_b         = 11,
+	conv045_give_stuff_a_a   = 14,
+	conv045_give_stuff_b_b   = 15,
+	conv045_moredrink_b_b    = 20,
+	conv045_passout_b_b      = 23,
+	conv045_passout_e_e      = 26,
+	conv045_revive           = 28,
+	conv045_timer_b_b        = 29
+};
+
 enum {
 	conv047_protect          =  0,
 	conv047_kingsay_escort   =  3,
diff --git a/engines/mads/madsv2/dragonsphere/mads/inventory.h b/engines/mads/madsv2/dragonsphere/mads/inventory.h
index 5c10d42687c..14dbe8223a2 100644
--- a/engines/mads/madsv2/dragonsphere/mads/inventory.h
+++ b/engines/mads/madsv2/dragonsphere/mads/inventory.h
@@ -38,7 +38,10 @@ enum {
 	pid_doll         =  8,
 	polystone        =  9,
 	red_powerstone   = 10,
+	yellow_powerstone= 11,
+	blue_powerstone  = 12,
 	key_crown        = 13,
+	dates            = 14,
 	statue           = 15,
 	bottle_of_flies  = 16,
 	soul_egg         = 17,
@@ -47,6 +50,7 @@ enum {
 	crystal_ball     = 29,
 	soptus_soporific = 31,
 	shifter_ring     = 32,
+	medicine_bundle  = 33,
 	tentacle_parts   = 36,
 	rare_coin        = 38,
 	crystal_flower   = 39,
@@ -54,7 +58,8 @@ enum {
 	gold_nugget      = 42,
 	magic_music_box  = 43,
 	emerald          = 44,
-	piece_of_paper   = 45
+	piece_of_paper   = 45,
+	new_bundle       = 48
 };
 
 } // namespace Dragonsphere
diff --git a/engines/mads/madsv2/dragonsphere/mads/sounds.h b/engines/mads/madsv2/dragonsphere/mads/sounds.h
index cb355a2ebe3..2ffc628a86f 100644
--- a/engines/mads/madsv2/dragonsphere/mads/sounds.h
+++ b/engines/mads/madsv2/dragonsphere/mads/sounds.h
@@ -67,7 +67,13 @@ enum {
 	N_ToadEatsPlayer     =  70,
 	N_RalphIsRed         =  71,
 	N_EveryoneScatter    =  72,
-	N_CrystalPing        =  73
+	N_CrystalPing        =  73,
+
+	// Section 4
+	N_WindWhistles       =  29,
+	N_Bk404Music         =  33,
+	N_Bk406Music         =  35,
+	N_BellyDanceMusic    =  36
 };
 
 } // namespace Dragonsphere
diff --git a/engines/mads/madsv2/dragonsphere/mads/words.h b/engines/mads/madsv2/dragonsphere/mads/words.h
index 62404d3ae58..dd739c35f71 100644
--- a/engines/mads/madsv2/dragonsphere/mads/words.h
+++ b/engines/mads/madsv2/dragonsphere/mads/words.h
@@ -63,6 +63,7 @@ enum {
 	words_attack               =  57,
 	words_carve_up             =  58,
 	words_goblet               =  59,
+	words_fill                 =  60,
 	words_bone                 =  62,
 	words_fruit                =  64,
 	words_doll                 =  66,
@@ -90,6 +91,7 @@ enum {
 	words_shift_into_seal      = 117,
 	words_shift_into_snake     = 118,
 	words_revert               = 119,
+	words_partly_built_bundle  = 122,
 	words_ratsicle             = 123,
 	words_tentacle_parts       = 125,
 	words_rare_coin            = 129,
@@ -180,6 +182,7 @@ enum {
 	words_shapechanger         = 282,
 	words_flies                = 286,
 	words_flask_of_acid        = 287,
+	words_partial_bundle       = 288,
 	words_soporific            = 289,
 	words_parchment            = 290,
 	words_king                 = 291,
@@ -187,6 +190,8 @@ enum {
 	words_climb_up             = 296,
 	words_boulders             = 320,
 	words_path_to_west         = 299,
+	words_firepit              = 303,
+	words_spirit_bundle        = 306,
 	words_path_to_east         = 313,
 	words_sconce               = 329,
 	words_rock_tumble          = 321,
@@ -201,18 +206,37 @@ enum {
 	words_grotto               = 345,
 	words_climb_through        = 346,
 	words_Queen_Mother         = 347,
+	words_moon                 = 361,
 	words_eye                  = 368,
 	words_sit_on               = 363,
 	words_teleportal           = 440,
 	words_Soptus_Ecliptus      = 448,
 	words_Slathan_ni_Patan     = 453,
+	words_desert_to_west       = 473,
+	words_cross                = 474,
+	words_desert_to_east       = 475,
+	words_desert_to_south      = 476,
+	words_desert_to_north      = 477,
+	words_desert               = 478,
+	words_bones                = 480,
+	words_tent                 = 481,
 	words_bush                 = 482,
+	words_sand                 = 485,
+	words_desert_sky           = 496,
 	words_pool                 = 497,
+	words_palm_tree            = 498,
+	words_oasis                = 499,
+	words_lean_to              = 500,
+	words_trader               = 501,
+	words_sign                 = 502,
+	words_shaman               = 508,
 	words_guardhouse           = 509,
 	words_bone_tree            = 510,
 	words_ear_rock             = 511,
 	words_mouth_rock           = 512,
 	words_nose_rock            = 513,
+	words_new_bundle           = 514,
+	words_lizard               = 515,
 	words_path                 = 522,
 	words_guards               = 523,
 	words_eye_rock             = 533,
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room401.cpp b/engines/mads/madsv2/dragonsphere/rooms/room401.cpp
index ecc76bc5260..c875453c11d 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room401.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room401.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
@@ -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/object.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"
@@ -39,6 +42,16 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[23];
+	int16 sequence[23];
+	int16 animation[4];
+	int16 sop_frame;
+	int16 sop_action;
+	int16 sop_talk_count;
+	int16 anim_0_running;
+	int16 prevent;
+	int16 moving;
+	int16 cut_scene;
 };
 
 #define local (&scratch)
@@ -46,26 +59,1298 @@ struct Scratch {
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
+static Scratch scratch;
 
-void room_401_init() {
+#define fx_red_blue_tent        0
+#define fx_bones                1
+#define fx_stone_marker         2
+#define fx_red_rocks            3
+#define fx_distant_dune         4
+#define fx_medium_dune          5
+#define fx_small_dune           6
+#define fx_dune_rocks           7
+#define fx_large_dune           8
+#define fx_bush                 9
+#define fx_large_dune_cactus    10
+#define fx_large_round_dune     11
+#define fx_grassy_dune          12
+#define fx_medium_dunes         13
+#define fx_large_tent           14
+#define fx_small_tent           15
+#define fx_tumbleweed           16
+#define fx_00                   17
+#define fx_take                 18
+#define fx_disp_6               19
+#define fx_disp_9               20
+#define fx_disp_3               21
+#define fx_fire                 22
 
+#define ROOM_401_ME_TALK        60
+#define ROOM_401_YOU_TALK       62
+#define ROOM_401_HANDS_UP       64
+#define ROOM_401_LAUGH          66
+#define ROOM_401_DEATH          69
+#define ROOM_401_LIFE           72
+#define ROOM_401_TEXT           78
+#define MUSIC                   100
+
+#define CONV_38_SOPTUS          38
+
+#define BONES_X                 236
+#define BONES_Y                 143
+#define TENT_X                  64
+#define TENT_Y                  151
+#define MARKER_X                193
+#define MARKER_Y                139
+#define FIREPIT_X               193
+#define FIREPIT_Y               139
+#define LEAVE_SOUTH_X           79
+#define LEAVE_SOUTH_Y           150
+
+#define RED_ROCKS_X             45
+#define RED_ROCKS_Y             155
+#define BUSH_X                  289
+#define BUSH_Y                  155
+#define MEDIUM_DUNE_X           270
+#define MEDIUM_DUNE_Y           155
+#define DUNE_ROCKS_X            227
+#define DUNE_ROCKS_Y            155
+#define LARGE_DUNE_CACTUS_X     279
+#define LARGE_DUNE_CACTUS_Y     155
+#define LARGE_ROUND_DUNE_X      300
+#define LARGE_ROUND_DUNE_Y      155
+#define MEDIUM_DUNES_X          270
+#define MEDIUM_DUNES_Y          155
+
+#define GRASSY_DUNE_X           29
+#define GRASSY_DUNE_Y           131
+#define LARGE_DUNE_X            32
+#define LARGE_DUNE_Y            126
+#define SMALL_DUNE_X            230
+#define SMALL_DUNE_Y            133
+#define DISTANT_DUNE_X          280
+#define DISTANT_DUNE_Y          128
+
+#define LARGE_TENT_X            70
+#define LARGE_TENT_Y            130
+#define SMALL_TENT_X            217
+#define SMALL_TENT_Y            127
+#define TUMBLEWEED_X            108
+#define TUMBLEWEED_Y            149
+
+#define FROM_NORTH_X            163
+#define FROM_NORTH_Y            131
+#define FROM_SOUTH_X            161
+#define FROM_SOUTH_Y            143
+#define FROM_EAST_X_1           330
+#define FROM_EAST_Y_1           143
+#define FROM_EAST_X_2           302
+#define FROM_EAST_Y_2           143
+#define FROM_WEST_X_1           -15
+#define FROM_WEST_Y_1           143
+#define FROM_WEST_X_2           15
+#define FROM_WEST_Y_2           143
+
+#define BIG_DESERT_X            140
+#define BIG_DESERT_Y            136
+#define DESERT_1_X              22
+#define DESERT_1_Y              146
+#define DESERT_2_X              36
+#define DESERT_2_Y              146
+#define DESERT_3_X              52
+#define DESERT_3_Y              146
+#define DESERT_4_X              60
+#define DESERT_4_Y              146
+#define DESERT_5_X              74
+#define DESERT_5_Y              146
+#define DESERT_6_X              87
+#define DESERT_6_Y              146
+#define DESERT_SOUTH_1_X        38
+#define DESERT_SOUTH_1_Y        153
+#define DESERT_SOUTH_2_X        78
+#define DESERT_SOUTH_2_Y        153
+#define DESERT_SOUTH_3_X        109
+#define DESERT_SOUTH_3_Y        151
+
+#define SHUT_UP                 0
+#define TALK                    1
+#define HANDS_UP                2
+#define POINT_N                 3
+#define POINT_S                 4
+#define POINT_E                 5
+#define POINT_W                 6
+#define LAUGH                   7
+#define NOD                     8
+
+#define DESERTT_1_X             107
+#define DESERTT_1_Y             137
+#define DESERTT_2_X             121
+#define DESERTT_2_Y             137
+
+#define PID_BONES_X             225
+#define PID_BONES_Y             143
+
+
+static void send_variables() {
+	int count;
+	int xx;
+	int it = 0;
+
+	for (xx = 0; xx < 2; xx++) {
+		if (xx == 0)
+			it = global[oasis];
+		if (xx == 1)
+			it = global[fire_holes];
+
+		switch (it) {
+		case 7:
+			for (count = 0; count < 5; count++) {
+				conv_export_value(1);
+			}
+			break;
+
+		case 13:
+			for (count = 0; count < 2; count++) {
+				conv_export_value(1);
+			}
+			conv_export_value(4);
+			for (count = 0; count < 2; count++) {
+				conv_export_value(1);
+			}
+			break;
+
+		case 19:
+			conv_export_value(1);
+			conv_export_value(4);
+			for (count = 0; count < 2; count++) {
+				conv_export_value(1);
+			}
+			conv_export_value(4);
+			break;
+
+		case 25:
+			conv_export_value(1);
+			conv_export_value(4);
+			conv_export_value(1);
+			for (count = 0; count < 2; count++) {
+				conv_export_value(4);
+			}
+			break;
+
+		case 31:
+			for (count = 0; count < 2; count++) {
+				conv_export_value(4);
+			}
+			conv_export_value(1);
+			for (count = 0; count < 4; count++) {
+				conv_export_value(4);
+			}
+			break;
+
+		case 37:
+			for (count = 0; count < 5; count++) {
+				conv_export_value(4);
+			}
+			break;
+
+		case 45:
+			conv_export_value(4);
+			conv_export_value(2);
+			for (count = 0; count < 3; count++) {
+				conv_export_value(4);
+			}
+			break;
+
+		case 53:
+			conv_export_value(4);
+			conv_export_value(2);
+			conv_export_value(4);
+			conv_export_value(2);
+			conv_export_value(4);
+			break;
+
+		case 61:
+			conv_export_value(2);
+			for (count = 0; count < 2; count++) {
+				conv_export_value(4);
+			}
+			for (count = 0; count < 2; count++) {
+				conv_export_value(2);
+			}
+			break;
+
+		case 69:
+			for (count = 0; count < 3; count++) {
+				conv_export_value(2);
+			}
+			conv_export_value(4);
+			conv_export_value(2);
+			break;
+
+		case 77:
+			for (count = 0; count < 5; count++) {
+				conv_export_value(2);
+			}
+			break;
+		}
+	}
 }
 
-void room_401_daemon() {
+static void handle_animation_sop() {
+	int sop_reset_frame;
+
+	if (kernel_anim[aa[0]].frame != local->sop_frame) {
+		local->sop_frame = kernel_anim[aa[0]].frame;
+		sop_reset_frame = -1;
+
+		switch (local->sop_frame) {
+		case 1:
+		case 2:
+		case 3:
+		case 4:
+		case 9:
+		case 68:
+		case 63:
+			switch (local->sop_action) {
+			case SHUT_UP:
+				if (local->sop_frame >= 5) {
+					local->sop_frame = 1;
+				}
+
+				++local->sop_talk_count;
+				if (local->sop_talk_count > imath_random(15, 25)) {
+					if (local->sop_frame == 1) {
+						sop_reset_frame = imath_random(0, 1);
+					} else if (local->sop_frame == 2) {
+						sop_reset_frame = imath_random(0, 2);
+					} else if (local->sop_frame == 3) {
+						sop_reset_frame = imath_random(1, 3);
+					} else if (local->sop_frame == 4) {
+						sop_reset_frame = imath_random(2, 3);
+					}
+					local->sop_talk_count = 0;
+
+				} else {
+					sop_reset_frame = local->sop_frame - 1;
+				}
+				break;
+
+			case HANDS_UP:
+				sop_reset_frame   = 4;
+				local->sop_action = TALK;
+				break;
+
+			case POINT_E:
+				sop_reset_frame   = 63;
+				local->sop_action = TALK;
+				break;
+
+			case POINT_N:
+				sop_reset_frame   = 56;
+				local->sop_action = TALK;
+				break;
+
+			default:
+				sop_reset_frame = 30;
+				break;
+			}
+			break;
+
+		case 25:
+		case 30:
+		case 31:
+		case 32:
+		case 45:
+		case 26:
+		case 29:
+		case 56:
+		case 69:
+			switch (local->sop_action) {
+			case TALK:
+				if (local->sop_talk_count == 0) {
+					if (imath_random(1, 2) == 1) {
+						sop_reset_frame = 32;
+					} else {
+						sop_reset_frame = 30;
+						++local->sop_talk_count;
+					}
+
+				} else {
+					sop_reset_frame = imath_random(29, 31);
+					++local->sop_talk_count;
+					if (local->sop_talk_count > 17) {
+						local->sop_action     = SHUT_UP;
+						local->sop_talk_count = 0;
+						sop_reset_frame       = 30;
+					}
+				}
+				break;
+
+			case SHUT_UP:
+				++local->sop_talk_count;
+				if (local->sop_talk_count > imath_random(15, 25)) {
+					sop_reset_frame = imath_random(0, 1);
+					if (sop_reset_frame == 1) {
+						sop_reset_frame = 30;
+					}
 
+				} else {
+					sop_reset_frame = 30;
+				}
+				break;
+
+			case POINT_S:
+				sop_reset_frame   = 38;
+				local->sop_action = TALK;
+				break;
+
+			case POINT_W:
+				sop_reset_frame   = 45;
+				local->sop_action = TALK;
+				break;
+
+			case LAUGH:
+				sop_reset_frame   = 10;
+				local->sop_action = SHUT_UP;
+				break;
+
+			case NOD:
+				sop_reset_frame = 26;
+				break;
+
+			case HANDS_UP:
+			case POINT_E:
+			case POINT_N:
+				sop_reset_frame = 0;
+				break;
+			}
+			break;
+
+		case 33:
+		case 34:
+		case 35:
+		case 36:
+			switch (local->sop_action) {
+			case TALK:
+				sop_reset_frame = imath_random(33, 35);
+				++local->sop_talk_count;
+				if (local->sop_talk_count > 17) {
+					local->sop_action     = SHUT_UP;
+					local->sop_talk_count = 0;
+					sop_reset_frame       = 68;
+				}
+				break;
+
+			default:
+				sop_reset_frame = 68;
+				break;
+			}
+			break;
+		}
+
+		if (sop_reset_frame >= 0) {
+			kernel_reset_animation(aa[0], sop_reset_frame);
+			local->sop_frame = sop_reset_frame;
+		}
+	}
 }
 
-void room_401_pre_parser() {
+static void process_conv_sop() {
+	int you_trig_flag  = false;
+	int me_trig_flag   = false;
+
+	switch (player_verb) {
+	case conv038_third_idont:
+	case conv038_knowledge_no:
+	case conv038_knowledge_idont:
+	case conv038_fourth_nound:
+		if (!kernel.trigger) {
+			conv_you_trigger(ROOM_401_HANDS_UP);
+		}
+		you_trig_flag = true;
+		me_trig_flag  = true;
+		break;
+
+	case conv038_knowledge_yes:
+		if (!kernel.trigger) {
+			conv_you_trigger(ROOM_401_LIFE);
+		}
+		you_trig_flag = true;
+		me_trig_flag  = true;
+		break;
+
+	case conv038_third_yes:
+		if (!kernel.trigger) {
+			conv_you_trigger(ROOM_401_DEATH);
+		}
+		you_trig_flag = true;
+		me_trig_flag  = true;
+		break;
 
+	case conv038_third_blab:
+		if (!kernel.trigger) {
+			conv_you_trigger(ROOM_401_LAUGH);
+		}
+		you_trig_flag = true;
+		me_trig_flag  = true;
+		break;
+	}
+
+	if (kernel.trigger == ROOM_401_DEATH) {
+		if (global[fire_holes] < 37) {
+			local->sop_action = POINT_N;
+		} else if (global[fire_holes] > 37) {
+			local->sop_action = POINT_S;
+		} else {
+			local->sop_action = POINT_W;
+		}
+	}
+
+	if (kernel.trigger == ROOM_401_LIFE) {
+		if (global[oasis] < 37) {
+			local->sop_action = POINT_N;
+		} else if (global[oasis] > 37) {
+			local->sop_action = POINT_S;
+		} else {
+			local->sop_action = POINT_W;
+		}
+	}
+
+	if (kernel.trigger == ROOM_401_HANDS_UP) {
+		local->sop_action = HANDS_UP;
+	}
+
+	if (kernel.trigger == ROOM_401_LAUGH) {
+		local->sop_action = LAUGH;
+	}
+
+	if (kernel.trigger == ROOM_401_ME_TALK) {
+		local->sop_action = SHUT_UP;
+	}
+
+	if (kernel.trigger == ROOM_401_YOU_TALK) {
+		local->sop_action = TALK;
+	}
+
+	if (!you_trig_flag) {
+		conv_you_trigger(ROOM_401_YOU_TALK);
+	}
+
+	if (!me_trig_flag) {
+		conv_me_trigger(ROOM_401_ME_TALK);
+	}
+
+	local->sop_talk_count = 0;
 }
 
-void room_401_parser() {
+static void room_401_init() {
+	int count;
+	int count2 = global[fire_holes] - 1;
+	int skip   = 0;
+
+	int front_right = false;
+	int front_left  = false;
+	int back_left   = false;
+	int back_right  = false;
+
+
+	if (global[player_persona] == PLAYER_IS_PID) {
+		global[perform_displacements] = true;
+	}
+
+	if (global[desert_room] == 42 && global[player_persona] == PLAYER_IS_KING) {
+		conv_get(CONV_38_SOPTUS);
+	}
+
+	local->cut_scene         = false;
+	local->prevent           = false;
+	ss[fx_bush]              = -1;
+	ss[fx_red_rocks]         = -1;
+	ss[fx_medium_dune]       = -1;
+	ss[fx_large_dune_cactus] = -1;
+	ss[fx_medium_dunes]      = -1;
+	ss[fx_00]                = -1;
+
+	local->moving  = false;
+	ss[fx_disp_3]  = kernel_load_series("*KG4DIS3", false);
+	ss[fx_disp_6]  = kernel_load_series("*KG4DIS6", false);
+	ss[fx_disp_9]  = kernel_load_series("*KG4DIS9", false);
+
+	if (global[desert_room] != 42) {
+		kernel_flip_hotspot(words_tent, false);
+		kernel_flip_hotspot(words_sign, false);
+		kernel_flip_hotspot(words_bones, false);
+		kernel_flip_hotspot(words_trader, false);
+		kernel_flip_hotspot(words_firepit, false);
+		kernel_flip_hotspot(words_lean_to, false);
+
+	} else if (global[player_persona] == PLAYER_IS_PID || player_has_been_in_room(405)) {
+		kernel_flip_hotspot(words_trader, false);
+
+	} else if (global[player_persona] == PLAYER_IS_KING) {
+		kernel_flip_hotspot_loc(words_desert, false, DESERTT_1_X, DESERTT_1_Y);
+		kernel_flip_hotspot_loc(words_desert, true,  DESERTT_2_X, DESERTT_2_Y);
+	}
+
+	if (global[player_persona] == PLAYER_IS_KING) {
+		ss[fx_take] = kernel_load_series("*KGRL_6", false);
+	} else {
+		ss[fx_take] = kernel_load_series("*PDRL_9", false);
+	}
+
+	if (global[desert_room] == 42) {
+		global[desert_counter] = 0;
+
+		kernel_room_scale(155, 80, 129, 60);
+		ss[fx_red_blue_tent]  = kernel_load_series("*DUNE04", false);
+		seq[fx_red_blue_tent] = kernel_seq_stamp(ss[fx_red_blue_tent], false, KERNEL_FIRST);
+		kernel_seq_depth(seq[fx_red_blue_tent], 3);
+		kernel_seq_loc(seq[fx_red_blue_tent], TENT_X, TENT_Y);
+
+		ss[fx_bones]  = kernel_load_series("*DUNE05", false);
+		seq[fx_bones] = kernel_seq_stamp(ss[fx_bones], false, KERNEL_FIRST);
+		kernel_seq_depth(seq[fx_bones], 5);
+		kernel_seq_loc(seq[fx_bones], BONES_X, BONES_Y);
+
+		ss[fx_stone_marker]  = kernel_load_series("*DUNE06", false);
+		seq[fx_stone_marker] = kernel_seq_stamp(ss[fx_stone_marker], false, KERNEL_FIRST);
+		kernel_seq_depth(seq[fx_stone_marker], 6);
+		kernel_seq_loc(seq[fx_stone_marker], MARKER_X, MARKER_Y);
+
+		ss[fx_fire]  = kernel_load_series(kernel_name('h', 0), false);
+		seq[fx_fire] = kernel_seq_stamp(ss[fx_fire], false, KERNEL_FIRST);
+		kernel_seq_depth(seq[fx_fire], 14);
+
+		kernel_flip_hotspot_loc(words_desert_to_south, false, DESERT_SOUTH_1_X, DESERT_SOUTH_1_Y);
+		kernel_flip_hotspot_loc(words_desert_to_south, false, DESERT_SOUTH_2_X, DESERT_SOUTH_2_Y);
+		kernel_flip_hotspot_loc(words_desert_to_south, false, DESERT_SOUTH_3_X, DESERT_SOUTH_3_Y);
+
+	} else {
+		kernel_flip_hotspot_loc(words_desert, false, DESERT_1_X, DESERT_1_Y);
+		kernel_flip_hotspot_loc(words_desert, false, DESERT_2_X, DESERT_2_Y);
+		kernel_flip_hotspot_loc(words_desert, false, DESERT_3_X, DESERT_3_Y);
+		kernel_flip_hotspot_loc(words_desert, false, DESERT_4_X, DESERT_4_Y);
+		kernel_flip_hotspot_loc(words_desert, false, DESERT_5_X, DESERT_5_Y);
+		kernel_flip_hotspot_loc(words_desert, false, DESERT_6_X, DESERT_6_Y);
+		kernel_flip_hotspot_loc(words_desert, true,  BIG_DESERT_X, BIG_DESERT_Y);
+
+		for (count = 0; count < 77; count++) {
+			++skip; if (skip == 7) skip = 1;
+			++count2; if (count2 == 78) count2 = 1;
+
+			if (count2 == global[desert_room]) {
+				switch (skip) {
+				case 1:
+					ss[fx_medium_dune]  = kernel_load_series("*DUNE07", false);
+					seq[fx_medium_dune] = kernel_seq_stamp(ss[fx_medium_dune], false, KERNEL_FIRST);
+					kernel_seq_depth(seq[fx_medium_dune], 1);
+					kernel_seq_loc(seq[fx_medium_dune], MEDIUM_DUNE_X, MEDIUM_DUNE_Y);
+					break;
+
+				case 2:
+					ss[fx_dune_rocks]  = kernel_load_series("*DUNE09", false);
+					seq[fx_dune_rocks] = kernel_seq_stamp(ss[fx_dune_rocks], false, KERNEL_FIRST);
+					kernel_seq_depth(seq[fx_dune_rocks], 1);
+					kernel_seq_loc(seq[fx_dune_rocks], DUNE_ROCKS_X, DUNE_ROCKS_Y);
+					break;
+
+				case 3:
+					ss[fx_bush]  = kernel_load_series("*DUNE11", false);
+					seq[fx_bush] = kernel_seq_stamp(ss[fx_bush], false, KERNEL_FIRST);
+					kernel_seq_depth(seq[fx_bush], 1);
+					kernel_seq_loc(seq[fx_bush], BUSH_X, BUSH_Y);
+					break;
+
+				case 4:
+					ss[fx_large_dune_cactus]  = kernel_load_series("*DUNE12", false);
+					seq[fx_large_dune_cactus] = kernel_seq_stamp(ss[fx_large_dune_cactus], false, KERNEL_FIRST);
+					kernel_seq_depth(seq[fx_large_dune_cactus], 1);
+					kernel_seq_loc(seq[fx_large_dune_cactus], LARGE_DUNE_CACTUS_X, LARGE_DUNE_CACTUS_Y);
+					break;
+
+				case 5:
+					ss[fx_large_round_dune]  = kernel_load_series("*DUNE13", false);
+					seq[fx_large_round_dune] = kernel_seq_stamp(ss[fx_large_round_dune], false, KERNEL_FIRST);
+					kernel_seq_depth(seq[fx_large_round_dune], 1);
+					kernel_seq_loc(seq[fx_large_round_dune], LARGE_ROUND_DUNE_X, LARGE_ROUND_DUNE_Y);
+					break;
+
+				case 6:
+					ss[fx_medium_dunes]  = kernel_load_series("*DUNE15", false);
+					seq[fx_medium_dunes] = kernel_seq_stamp(ss[fx_medium_dunes], false, KERNEL_FIRST);
+					kernel_seq_depth(seq[fx_medium_dunes], 1);
+					kernel_seq_loc(seq[fx_medium_dunes], MEDIUM_DUNES_X, MEDIUM_DUNES_Y);
+					break;
+				}
+
+				if (skip <= 6) front_right = true;
+			}
+		}
+
+		/* put down LEFT foreground sprites */
+
+		count2 = 29;
+		skip   = 0;
+
+		for (count = 0; count < 77; count++) {
+			++skip; if (skip == 9) skip = 1;
+			++count2; if (count2 == 78) count2 = 1;
+
+			if (count2 == global[desert_room]) {
+				switch (skip) {
+				case 1:
+					if (ss[fx_red_rocks] == -1) {
+						ss[fx_red_rocks]  = kernel_load_series("*DUNE01", false);
+						seq[fx_red_rocks] = kernel_seq_stamp(ss[fx_red_rocks], false, KERNEL_FIRST);
+						kernel_seq_depth(seq[fx_red_rocks], 1);
+						kernel_seq_loc(seq[fx_red_rocks], RED_ROCKS_X, RED_ROCKS_Y);
+					}
+					break;
+
+				case 2:
+					if (ss[fx_bush] == -1) {
+						ss[fx_bush]  = kernel_load_series("*DUNE11", false);
+						seq[fx_bush] = kernel_seq_stamp(ss[fx_bush], false, KERNEL_FIRST);
+						kernel_seq_depth(seq[fx_bush], 1);
+						kernel_seq_loc(seq[fx_bush], 0, BUSH_Y);
+					}
+					break;
+
+				case 3:
+					if (ss[fx_medium_dune] == -1) {
+						ss[fx_medium_dune]  = kernel_load_series("*DUNE07", false);
+						seq[fx_medium_dune] = kernel_seq_stamp(ss[fx_medium_dune], false, KERNEL_FIRST);
+						kernel_seq_depth(seq[fx_medium_dune], 1);
+						kernel_seq_loc(seq[fx_medium_dune], 0, MEDIUM_DUNE_Y);
+					}
+					break;
+
+				case 4:
+					if (ss[fx_large_dune_cactus] == -1) {
+						ss[fx_large_dune_cactus]  = kernel_load_series("*DUNE12", false);
+						seq[fx_large_dune_cactus] = kernel_seq_stamp(ss[fx_large_dune_cactus], false, KERNEL_FIRST);
+						kernel_seq_depth(seq[fx_large_dune_cactus], 1);
+						kernel_seq_loc(seq[fx_large_dune_cactus], 0, LARGE_DUNE_CACTUS_Y);
+					}
+					break;
+
+				case 5:
+					if (ss[fx_medium_dunes] == -1) {
+						ss[fx_medium_dunes]  = kernel_load_series("*DUNE15", false);
+						seq[fx_medium_dunes] = kernel_seq_stamp(ss[fx_medium_dunes], false, KERNEL_FIRST);
+						kernel_seq_depth(seq[fx_medium_dunes], 1);
+						kernel_seq_loc(seq[fx_medium_dunes], 0, MEDIUM_DUNES_Y);
+					}
+					break;
+
+				case 6:
+					if (ss[fx_00] == -1) {
+						ss[fx_00]  = kernel_load_series("*DUNE00", false);
+						seq[fx_00] = kernel_seq_stamp(ss[fx_00], false, KERNEL_FIRST);
+						kernel_seq_depth(seq[fx_00], 1);
+						kernel_seq_loc(seq[fx_00], 0, MEDIUM_DUNES_Y);
+					}
+					break;
+				}
+
+				if (skip <= 6) front_left = true;
+			}
+		}
+
+		/* put down LEFT background sprites */
+
+		count2 = global[oasis] - 1;
+		skip   = 0;
 
+		for (count = 0; count < 77; count++) {
+			++skip; if (skip == 5) skip = 1;
+			++count2; if (count2 == 78) count2 = 1;
+
+			if (count2 == global[desert_room]) {
+
+				switch (skip) {
+				case 1:
+					ss[fx_large_dune]  = kernel_load_series("*DUNE10", false);
+					seq[fx_large_dune] = kernel_seq_stamp(ss[fx_large_dune], false, KERNEL_FIRST);
+					kernel_seq_depth(seq[fx_large_dune], 14);
+					kernel_seq_loc(seq[fx_large_dune], LARGE_DUNE_X, LARGE_DUNE_Y);
+					break;
+
+				case 2:
+					ss[fx_grassy_dune]  = kernel_load_series("*DUNE14", false);
+					seq[fx_grassy_dune] = kernel_seq_stamp(ss[fx_grassy_dune], false, KERNEL_FIRST);
+					kernel_seq_depth(seq[fx_grassy_dune], 14);
+					kernel_seq_loc(seq[fx_grassy_dune], GRASSY_DUNE_X, GRASSY_DUNE_Y);
+					break;
+				}
+
+				if (skip <= 2) back_left  = true;
+			}
+		}
+
+		/* put down RIGHT background sprites */
+
+		count2 = global[oasis] - 1;
+		skip   = 0;
+
+		for (count = 0; count < 77; count++) {
+
+			++skip; if (skip == 4) skip = 1;
+			++count2; if (count2 == 78) count2 = 1;
+
+			if (count2 == global[desert_room]) {
+				switch (skip) {
+				case 1:
+					if (front_right && !back_left) {
+						ss[fx_distant_dune]  = kernel_load_series("*DUNE02", false);
+						seq[fx_distant_dune] = kernel_seq_stamp(ss[fx_distant_dune], false, KERNEL_FIRST);
+						kernel_seq_depth(seq[fx_distant_dune], 14);
+						kernel_seq_loc(seq[fx_distant_dune], 40, DISTANT_DUNE_Y);
+
+					} else if (front_left && !back_right) {
+						ss[fx_distant_dune]  = kernel_load_series("*DUNE02", false);
+						seq[fx_distant_dune] = kernel_seq_stamp(ss[fx_distant_dune], false, KERNEL_FIRST);
+						kernel_seq_depth(seq[fx_distant_dune], 14);
+						kernel_seq_loc(seq[fx_distant_dune], DISTANT_DUNE_X, DISTANT_DUNE_Y);
+					}
+					break;
+				}
+
+				if (skip == 1) back_right = true;
+			}
+		}
+	}
+
+	if (previous_room != KERNEL_RESTORING_GAME) {
+		if (previous_room == 404) {
+			global[desert_counter] = 0;
+			player.x               = FROM_EAST_X_2;
+			player.y               = FROM_EAST_Y_2;
+			player.facing          = FACING_WEST;
+
+		} else {
+			switch (global[from_direction]) {
+			case FROM_NORTH:
+				player.x = FROM_NORTH_X;
+				player.y = FROM_NORTH_Y;
+				player.facing = FACING_SOUTH;
+				break;
+
+			case FROM_SOUTH:
+				player.x = FROM_SOUTH_X;
+				player.y = FROM_SOUTH_Y;
+				player.facing = FACING_NORTH;
+				break;
+
+			case FROM_EAST:
+				player_first_walk(FROM_EAST_X_1, FROM_EAST_Y_1, FACING_WEST,
+					FROM_EAST_X_2, FROM_EAST_Y_2, FACING_WEST, true);
+				break;
+
+			case FROM_WEST:
+				player_first_walk(FROM_WEST_X_1, FROM_WEST_Y_1, FACING_EAST,
+					FROM_WEST_X_2, FROM_WEST_Y_2, FACING_EAST, true);
+				break;
+			}
+		}
+	}
+
+	if (global[desert_room] == 42 && global[player_persona] == PLAYER_IS_KING &&
+	    !player_has_been_in_room(405)) {
+		aa[0]                 = kernel_run_animation(kernel_name('s', 1), 0);
+		local->anim_0_running = true;
+		local->sop_action     = SHUT_UP;
+
+		if (conv_restore_running == CONV_38_SOPTUS) {
+			conv_run(CONV_38_SOPTUS);
+			send_variables();
+		}
+	}
+
+	section_4_music();
 }
 
-void room_401_synchronize(Common::Serializer &s) {
+static void room_401_daemon() {
+	int temp;
+
+	if (local->anim_0_running) {
+		handle_animation_sop();
+	}
+
+	if (player.walker_visible && (player.commands_allowed || (conv_control.running >= 0)) && !player.walking &&
+	   (player.facing == player.turn_to_facing) && !local->moving && global[player_persona] == PLAYER_IS_KING) {
+
+		switch (player.facing) {
+		case FACING_EAST:
+		case FACING_WEST:
+			if (imath_random(1, 500) == 1) {
+				if (imath_random(1, 2) == 1) {
+					player.walker_visible = false;
+					local->moving         = true;
+					if (player.facing == FACING_EAST) {
+						seq[fx_disp_6] = kernel_seq_forward(ss[fx_disp_6], false, 6, 0, 0, 1);
+					} else {
+						seq[fx_disp_6] = kernel_seq_forward(ss[fx_disp_6], true, 6, 0, 0, 1);
+					}
+					kernel_seq_player(seq[fx_disp_6], true);
+					kernel_seq_range(seq[fx_disp_6], 8, KERNEL_LAST);
+					kernel_seq_trigger(seq[fx_disp_6], KERNEL_TRIGGER_EXPIRE, 0, 1);
 
+				} else {
+					player.walker_visible = false;
+					local->moving         = true;
+					if (player.facing == FACING_EAST) {
+						seq[fx_disp_6] = kernel_seq_forward(ss[fx_disp_6], false, 6, 0, 0, 1);
+					} else {
+						seq[fx_disp_6] = kernel_seq_forward(ss[fx_disp_6], true, 6, 0, 0, 1);
+					}
+					kernel_seq_player(seq[fx_disp_6], true);
+					kernel_seq_range(seq[fx_disp_6], 1, 7);
+					kernel_seq_trigger(seq[fx_disp_6], KERNEL_TRIGGER_EXPIRE, 0, 2);
+				}
+			}
+			break;
+
+		case FACING_SOUTHEAST:
+		case FACING_SOUTHWEST:
+			if (imath_random(1, 500) == 1) {
+				if (imath_random(1, 2) == 1) {
+					player.walker_visible = false;
+					local->moving         = true;
+					if (player.facing == FACING_SOUTHEAST) {
+						seq[fx_disp_3] = kernel_seq_forward(ss[fx_disp_3], false, 6, 0, 0, 1);
+					} else {
+						seq[fx_disp_3] = kernel_seq_forward(ss[fx_disp_3], true, 6, 0, 0, 1);
+					}
+					kernel_seq_player(seq[fx_disp_3], true);
+					kernel_seq_range(seq[fx_disp_3], 1, 17);
+					kernel_seq_trigger(seq[fx_disp_3], KERNEL_TRIGGER_EXPIRE, 0, 1);
+
+				} else {
+					player.walker_visible = false;
+					local->moving         = true;
+					if (player.facing == FACING_SOUTHEAST) {
+						seq[fx_disp_3] = kernel_seq_forward(ss[fx_disp_3], false, 6, 0, 0, 1);
+					} else {
+						seq[fx_disp_3] = kernel_seq_forward(ss[fx_disp_3], true, 6, 0, 0, 1);
+					}
+					kernel_seq_player(seq[fx_disp_3], true);
+					kernel_seq_range(seq[fx_disp_3], 18, KERNEL_LAST);
+					kernel_seq_trigger(seq[fx_disp_3], KERNEL_TRIGGER_EXPIRE, 0, 4);
+				}
+			}
+			break;
+
+
+		case FACING_NORTHWEST:
+		case FACING_NORTHEAST:
+			if (imath_random(1, 500) == 1) {
+				player.walker_visible = false;
+				local->moving         = true;
+				if (player.facing == FACING_NORTHEAST) {
+					seq[fx_disp_9] = kernel_seq_forward(ss[fx_disp_9], false, 6, 0, 0, 1);
+				} else {
+					seq[fx_disp_9] = kernel_seq_forward(ss[fx_disp_9], true, 6, 0, 0, 1);
+				}
+				kernel_seq_player(seq[fx_disp_9], true);
+				kernel_seq_range(seq[fx_disp_9], 1, KERNEL_LAST);
+				kernel_seq_trigger(seq[fx_disp_9], KERNEL_TRIGGER_EXPIRE, 0, 1);
+			}
+			break;
+		}
+	}
+
+	if (local->moving) {
+		switch (kernel.trigger) {
+		case 1:
+			player.walker_visible = true;
+			local->moving = false;
+			if (player.facing == FACING_WEST || player.facing == FACING_EAST) {
+				kernel_synch(KERNEL_PLAYER, 0, KERNEL_SERIES, seq[fx_disp_6]);
+
+			} else if (player.facing == FACING_NORTHWEST || player.facing == FACING_NORTHEAST) {
+				kernel_synch(KERNEL_PLAYER, 0, KERNEL_SERIES, seq[fx_disp_9]);
+
+			} else if (player.facing == FACING_SOUTHWEST || player.facing == FACING_SOUTHEAST) {
+				kernel_synch(KERNEL_PLAYER, 0, KERNEL_SERIES, seq[fx_disp_3]);
+			}
+			break;
+
+		case 2:
+			temp = seq[fx_disp_6];
+			if (player.facing == FACING_EAST) {
+				seq[fx_disp_6] = kernel_seq_stamp(ss[fx_disp_6], false, 7);
+			} else {
+				seq[fx_disp_6] = kernel_seq_stamp(ss[fx_disp_6], true, 7);
+			}
+			kernel_seq_player(seq[fx_disp_6], false);
+			kernel_timing_trigger(imath_random(30, 150), 3);
+			kernel_synch(KERNEL_SERIES, seq[fx_disp_6], KERNEL_SERIES, temp);
+			break;
+
+		case 3:
+			kernel_seq_delete(seq[fx_disp_6]);
+			if (player.facing == FACING_EAST) {
+				seq[fx_disp_6] = kernel_seq_backward(ss[fx_disp_6], false, 6, 0, 0, 1);
+			} else {
+				seq[fx_disp_6] = kernel_seq_backward(ss[fx_disp_6], true, 6, 0, 0, 1);
+			}
+			kernel_seq_player(seq[fx_disp_6], false);
+			kernel_seq_range(seq[fx_disp_6], 1, 7);
+			kernel_seq_trigger(seq[fx_disp_6], KERNEL_TRIGGER_EXPIRE, 0, 1);
+			break;
+
+		case 4:
+			temp = seq[fx_disp_3];
+			if (player.facing == FACING_SOUTHEAST) {
+				seq[fx_disp_3] = kernel_seq_stamp(ss[fx_disp_3], false, KERNEL_LAST);
+			} else {
+				seq[fx_disp_3] = kernel_seq_stamp(ss[fx_disp_3], true, KERNEL_LAST);
+			}
+			kernel_seq_player(seq[fx_disp_3], false);
+			kernel_timing_trigger(imath_random(30, 150), 5);
+			kernel_synch(KERNEL_SERIES, seq[fx_disp_3], KERNEL_SERIES, temp);
+			break;
+
+		case 5:
+			kernel_seq_delete(seq[fx_disp_3]);
+			if (player.facing == FACING_SOUTHEAST) {
+				seq[fx_disp_3] = kernel_seq_backward(ss[fx_disp_3], false, 6, 0, 0, 1);
+			} else {
+				seq[fx_disp_3] = kernel_seq_backward(ss[fx_disp_3], true, 6, 0, 0, 1);
+			}
+			kernel_seq_player(seq[fx_disp_3], false);
+			kernel_seq_range(seq[fx_disp_3], 18, KERNEL_LAST);
+			kernel_seq_trigger(seq[fx_disp_3], KERNEL_TRIGGER_EXPIRE, 0, 1);
+			break;
+		}
+	}
+
+	if (kernel.trigger == ROOM_401_TEXT) {
+		text_show(40103);
+	}
+
+	if (kernel.trigger == MUSIC) {
+		sound_play(N_WindWhistles);
+		sound_play(N_BackgroundMus);
+	}
+
+	if (local->cut_scene && !player.walking) {
+		local->cut_scene = false;
+		global[dragon_my_scene]--;
+	}
+}
+
+static void room_401_pre_parser() {
+	if (local->moving) {
+		switch (player.facing) {
+		case FACING_EAST:
+		case FACING_WEST:
+			kernel_seq_delete(seq[fx_disp_6]);
+			player.walker_visible = true;
+			break;
+
+		case FACING_NORTHEAST:
+		case FACING_NORTHWEST:
+			kernel_seq_delete(seq[fx_disp_9]);
+			player.walker_visible = true;
+			break;
+
+		case FACING_SOUTHEAST:
+		case FACING_SOUTHWEST:
+			kernel_seq_delete(seq[fx_disp_3]);
+			player.walker_visible = true;
+			break;
+		}
+		kernel_synch(KERNEL_PLAYER, 0, KERNEL_NOW, 0);
+		local->moving = false;
+	}
+
+	if (global[desert_room] == 42) {
+		if (player_said_2(cross, desert_to_south) && inter_point_x < 98) {
+			player_walk(LEAVE_SOUTH_X, LEAVE_SOUTH_Y, FACING_SOUTH);
+		}
+	}
+
+	if (player_said_1(cross)) {
+		if (!player_said_1(desert_to_east) && local->cut_scene) {
+			local->cut_scene = false;
+			global[dragon_my_scene]--;
+		}
+
+		if (player_has_been_in_room(405) && player_said_1(desert_to_west)) {
+			global[from_direction]       = FROM_EAST;
+			player.walk_off_edge_to_room = 405;
+
+		} else if (player_has_been_in_room(405) && player_said_1(desert_to_east)) {
+			global[pre_room] = 401;
+			if (global[dragon_my_scene] < global[dragon_high_scene]) {
+				if (!local->cut_scene) {
+					global[dragon_my_scene]++;
+				}
+				player.walk_off_edge_to_room = 111;
+				local->cut_scene             = true;
+			} else {
+				if (!local->cut_scene) {
+					player.walk_off_edge_to_room = 120;
+				}
+			}
+
+		} else if (player_said_1(desert_to_east) && global[desert_room] % 7 == 0) {
+			global[pre_room] = 401;
+			if (global[dragon_my_scene] < global[dragon_high_scene]) {
+				if (!local->cut_scene) {
+					global[dragon_my_scene]++;
+				}
+				player.walk_off_edge_to_room = 111;
+				local->cut_scene             = true;
+
+			} else if (local->cut_scene) {
+				player.walk_off_edge_to_room = 111;
+
+			} else {
+				player.walk_off_edge_to_room = 120;
+			}
+
+		} else if (player_said_1(desert_to_east) || player_said_1(desert_to_west)) {
+			player.walk_off_edge_to_room = 400;
+		}
+	}
+
+	if (player_said_2(take, bones) && global[player_persona] == PLAYER_IS_PID) {
+		player_walk(PID_BONES_X, PID_BONES_Y, FACING_NORTHEAST);
+	}
+}
+
+static void room_401_parser() {
+	int count;
+	int count2 = global[oasis] - 1;
+	int roomNum = 400;
+
+	if (conv_control.running == CONV_38_SOPTUS) {
+		process_conv_sop();
+		goto handled;
+	}
+
+	if (player_said_2(talk_to, trader)) {
+		conv_run(CONV_38_SOPTUS);
+		send_variables();
+		goto handled;
+	}
+
+	if (player_said_2(take, bones)) {
+		switch (kernel.trigger) {
+		case 0:
+			if (!player_has(bone)) {
+				player.commands_allowed = false;
+				player.walker_visible   = false;
+				seq[fx_take] = kernel_seq_pingpong(ss[fx_take], false, 6, 0, 0, 2);
+				kernel_seq_trigger(seq[fx_take], KERNEL_TRIGGER_EXPIRE, 0, 2);
+				kernel_seq_depth(seq[fx_take], 3);
+				kernel_seq_range(seq[fx_take], KERNEL_FIRST, KERNEL_LAST);
+				kernel_seq_player(seq[fx_take], true);
+				if (global[player_persona] == PLAYER_IS_KING) {
+					kernel_seq_trigger(seq[fx_take], KERNEL_TRIGGER_SPRITE, 5, 1);
+				} else {
+					kernel_seq_trigger(seq[fx_take], KERNEL_TRIGGER_SPRITE, 4, 1);
+				}
+				goto handled;
+			}
+			break;
+
+		case 1:
+			if (local->prevent) {
+				if (!(global[player_score_flags] & SCORE_TAKE_BONE)) {
+					global[player_score_flags] = global[player_score_flags] | SCORE_TAKE_BONE;
+					global[player_score] += 1;
+				}
+				sound_play(N_TakeObjectSnd);
+				inter_give_to_player(bone);
+				object_examine(bone, 40111, 0);
+			}
+			local->prevent = true;
+			goto handled;
+			break;
+
+		case 2:
+			player.walker_visible   = true;
+			player.commands_allowed = true;
+			local->prevent          = false;
+			kernel_synch(KERNEL_PLAYER, 0, KERNEL_SERIES, seq[fx_take]);
+			goto handled;
+			break;
+		}
+	}
+
+	if (player_said_2(take, bones) && player_has(bone)) {
+		text_show(40112);
+		goto handled;
+	}
+
+	if (player_said_1(cross)) {
+		if (player_said_1(desert_to_north) || player_said_1(desert_to_south)) {
+			if (player_said_1(desert_to_north)) {
+				global[desert_room] = global[desert_room] - 7;
+				global[from_direction] = FROM_SOUTH;
+
+			} else if (player_said_1(desert_to_south)) {
+				global[desert_room] += 7;
+				global[from_direction] = FROM_NORTH;
+			}
+
+			for (count = 0; count < 77; count++) {
+				++roomNum;
+				if (roomNum == 404)
+					roomNum = 401;
+				++count2;
+				if (count2 == 78)
+					count2 = 1;
+
+				if (count2 == global[desert_room]) {
+					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;
+				}
+			}
+
+over:
+
+			++global[desert_counter];
+			if (player_has_been_in_room(405)) {
+				global[from_direction] = FROM_EAST;
+				new_room               = 405;
+
+			} else if (global[desert_counter] == 6 && !player_has_been_in_room(405)) {
+				new_room = 404;
+
+			} else if (room_id == roomNum) {
+				kernel.force_restart = true;
+
+			} else {
+				new_room = roomNum;
+			}
+			goto handled;
+		}
+	}
+
+	if (player.look_around) {
+		if (global[desert_room] == 42) {
+			text_show(40101);
+		} else {
+			text_show(40201);
+		}
+		goto handled;
+	}
+
+	if (player_said_1(look) || player_said_1(look_at)) {
+		if (player_said_1(desert_to_north) ||
+		    player_said_1(desert_to_south) ||
+		    player_said_1(desert_to_east)  ||
+		    player_said_1(desert_to_west)) {
+			text_show(40102);
+			goto handled;
+		}
+
+		if (player_said_1(sky)) {
+			text_show(40103);
+			goto handled;
+		}
+
+		if (player_said_1(lean_to)) {
+			text_show(40105);
+			goto handled;
+		}
+
+		if (player_said_1(trader)) {
+			text_show(40106);
+			goto handled;
+		}
+
+		if (player_said_1(bones)) {
+			text_show(40107);
+			goto handled;
+		}
+
+		if (player_said_1(sign)) {
+			text_show(40108);
+			goto handled;
+		}
+
+		if (player_said_1(firepit)) {
+			text_show(40118);
+			goto handled;
+		}
+	}
+
+	if (player_said_2(take, desert)) {
+		text_show(40104);
+		goto handled;
+	}
+
+	if (player_said_2(take, lean_to)) {
+		text_show(40109);
+		goto handled;
+	}
+
+	if (player_said_2(take, trader)) {
+		text_show(40110);
+		goto handled;
+	}
+
+	if (player_said_2(take, sign)) {
+		text_show(40113);
+		goto handled;
+	}
+
+	if (player_said_2(open, lean_to) ||
+	    player_said_2(close, lean_to)) {
+		text_show(40114);
+		goto handled;
+	}
+
+	if (player_said_2(push, lean_to) ||
+	    player_said_2(pull, lean_to)) {
+		text_show(40115);
+		goto handled;
+	}
+
+	if (player_said_2(pull, sign)) {
+		text_show(40116);
+		goto handled;
+	}
+
+	if (player_said_2(give, trader)) {
+		text_show(40117);
+		goto handled;
+	}
+
+	if (player_said_2(put, firepit) ||
+	    player_said_2(throw, firepit)) {
+		text_show(40119);
+		goto handled;
+	}
+
+	goto done;
+
+handled:
+	player.command_ready = false;
+
+done:
+	;
+}
+
+void room_401_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.sop_frame);
+	s.syncAsSint16LE(scratch.sop_action);
+	s.syncAsSint16LE(scratch.sop_talk_count);
+	s.syncAsSint16LE(scratch.anim_0_running);
+	s.syncAsSint16LE(scratch.prevent);
+	s.syncAsSint16LE(scratch.moving);
+	s.syncAsSint16LE(scratch.cut_scene);
 }
 
 void room_401_preload() {
@@ -74,6 +1359,10 @@ void room_401_preload() {
 	room_parser_code_pointer = room_401_parser;
 	room_daemon_code_pointer = room_401_daemon;
 
+	if (global[desert_room] == 42) {
+		kernel_initial_variant = 1;
+	}
+
 	section_4_walker();
 	section_4_interface();
 }
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room402.cpp b/engines/mads/madsv2/dragonsphere/rooms/room402.cpp
index 5dd66d1e9ce..c43cec4ee89 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room402.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room402.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
@@ -22,10 +22,11 @@
 #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 +40,10 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[20];
+	int16 sequence[20];
+	int16 animation[4];
+	int16 moving;
 };
 
 #define local (&scratch)
@@ -46,26 +51,629 @@ struct Scratch {
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
+static Scratch scratch;
 
-void room_402_init() {
+#define fx_red_rocks            1
+#define fx_distant_dune         2
+#define fx_medium_dune          3
+#define fx_small_dune           4
+#define fx_dune_rocks           5
+#define fx_large_dune           6
+#define fx_bush                 7
+#define fx_large_dune_cactus    8
+#define fx_large_round_dune     9
+#define fx_grassy_dune          10
+#define fx_medium_dunes         11
+#define fx_large_tent           12
+#define fx_small_tent           13
+#define fx_tumbleweed           14
+#define fx_00                   15
+#define fx_disp_6               16
+#define fx_disp_9               17
+#define fx_disp_3               18
 
+#define RED_ROCKS_X             45
+#define RED_ROCKS_Y             155
+#define BUSH_X                  289
+#define BUSH_Y                  155
+#define MEDIUM_DUNE_X           270
+#define MEDIUM_DUNE_Y           155
+#define DUNE_ROCKS_X            227
+#define DUNE_ROCKS_Y            155
+#define LARGE_DUNE_CACTUS_X     279
+#define LARGE_DUNE_CACTUS_Y     155
+#define LARGE_ROUND_DUNE_X      300
+#define LARGE_ROUND_DUNE_Y      155
+#define MEDIUM_DUNES_X          270
+#define MEDIUM_DUNES_Y          155
+
+#define GRASSY_DUNE_X           29
+#define GRASSY_DUNE_Y           131
+#define LARGE_DUNE_X            32
+#define LARGE_DUNE_Y            126
+#define SMALL_DUNE_X            230
+#define SMALL_DUNE_Y            133
+#define DISTANT_DUNE_X          280
+#define DISTANT_DUNE_Y          128
+
+#define LARGE_TENT_X            70
+#define LARGE_TENT_Y            130
+#define SMALL_TENT_X            217
+#define SMALL_TENT_Y            127
+#define TUMBLEWEED_X            108
+#define TUMBLEWEED_Y            149
+
+#define FROM_NORTH_X            169
+#define FROM_NORTH_Y            130
+#define FROM_SOUTH_X            161
+#define FROM_SOUTH_Y            143
+#define FROM_EAST_X_1           330
+#define FROM_EAST_Y_1           143
+#define FROM_EAST_X_2           302
+#define FROM_EAST_Y_2           143
+#define FROM_WEST_X_1           -15
+#define FROM_WEST_Y_1           143
+#define FROM_WEST_X_2           15
+#define FROM_WEST_Y_2           143
+
+
+static void room_402_init() {
+	int id;
+	int count;
+	int count2 = global[fire_holes] - 1;
+	int skip   = 0;
+
+	int front_right = false;
+	int front_left  = false;
+	int back_left   = false;
+	int back_right  = false;
+
+	if (global[player_persona] == PLAYER_IS_PID) {
+		global[perform_displacements] = true;
+	}
+
+	ss[fx_bush]              = -1;
+	ss[fx_red_rocks]         = -1;
+	ss[fx_medium_dune]       = -1;
+	ss[fx_large_dune_cactus] = -1;
+	ss[fx_medium_dunes]      = -1;
+	ss[fx_00]                = -1;
+
+	local->moving  = false;
+	ss[fx_disp_3]  = kernel_load_series("*KG4DIS3", false);
+	ss[fx_disp_6]  = kernel_load_series("*KG4DIS6", false);
+	ss[fx_disp_9]  = kernel_load_series("*KG4DIS9", false);
+
+	/* put down RIGHT foreground sprites */
+
+	for (count = 0; count < 77; count++) {
+		++skip;
+		if (skip == 7)
+			skip = 1;
+		++count2;
+		if (count2 == 78)
+			count2 = 1;
+
+		if (count2 == global[desert_room]) {
+			switch (skip) {
+			case 1:
+				ss[fx_medium_dune]  = kernel_load_series("*DUNE07", false);
+				seq[fx_medium_dune] = kernel_seq_stamp(ss[fx_medium_dune], false, KERNEL_FIRST);
+				kernel_seq_depth(seq[fx_medium_dune], 1);
+				kernel_seq_loc(seq[fx_medium_dune], MEDIUM_DUNE_X, MEDIUM_DUNE_Y);
+				break;
+
+			case 2:
+				ss[fx_dune_rocks]  = kernel_load_series("*DUNE09", false);
+				seq[fx_dune_rocks] = kernel_seq_stamp(ss[fx_dune_rocks], false, KERNEL_FIRST);
+				kernel_seq_depth(seq[fx_dune_rocks], 1);
+				kernel_seq_loc(seq[fx_dune_rocks], DUNE_ROCKS_X, DUNE_ROCKS_Y);
+				break;
+
+			case 3:
+				ss[fx_bush]  = kernel_load_series("*DUNE11", false);
+				seq[fx_bush] = kernel_seq_stamp(ss[fx_bush], false, KERNEL_FIRST);
+				kernel_seq_depth(seq[fx_bush], 1);
+				kernel_seq_loc(seq[fx_bush], BUSH_X, BUSH_Y);
+				break;
+
+			case 4:
+				ss[fx_large_dune_cactus]  = kernel_load_series("*DUNE12", false);
+				seq[fx_large_dune_cactus] = kernel_seq_stamp(ss[fx_large_dune_cactus], false, KERNEL_FIRST);
+				kernel_seq_depth(seq[fx_large_dune_cactus], 1);
+				kernel_seq_loc(seq[fx_large_dune_cactus], LARGE_DUNE_CACTUS_X, LARGE_DUNE_CACTUS_Y);
+				break;
+
+			case 5:
+				ss[fx_large_round_dune]  = kernel_load_series("*DUNE13", false);
+				seq[fx_large_round_dune] = kernel_seq_stamp(ss[fx_large_round_dune], false, KERNEL_FIRST);
+				kernel_seq_depth(seq[fx_large_round_dune], 1);
+				kernel_seq_loc(seq[fx_large_round_dune], LARGE_ROUND_DUNE_X, LARGE_ROUND_DUNE_Y);
+				break;
+
+			case 6:
+				ss[fx_medium_dunes]  = kernel_load_series("*DUNE15", false);
+				seq[fx_medium_dunes] = kernel_seq_stamp(ss[fx_medium_dunes], false, KERNEL_FIRST);
+				kernel_seq_depth(seq[fx_medium_dunes], 1);
+				kernel_seq_loc(seq[fx_medium_dunes], MEDIUM_DUNES_X, MEDIUM_DUNES_Y);
+				break;
+			}
+
+			if (skip <= 6)
+				front_right = true;
+		}
+	}
+
+	/* put down LEFT foreground sprites */
+
+	count2 = 29;
+	skip   = 0;
+
+	for (count = 0; count < 77; count++) {
+		++skip;
+		if (skip == 9)
+			skip = 1;
+		++count2;
+		if (count2 == 78)
+			count2 = 1;
+
+		if (count2 == global[desert_room]) {
+			switch (skip) {
+			case 1:
+				if (ss[fx_red_rocks] == -1) {
+					ss[fx_red_rocks]  = kernel_load_series("*DUNE01", false);
+					seq[fx_red_rocks] = kernel_seq_stamp(ss[fx_red_rocks], false, KERNEL_FIRST);
+					kernel_seq_depth(seq[fx_red_rocks], 1);
+					kernel_seq_loc(seq[fx_red_rocks], RED_ROCKS_X, RED_ROCKS_Y);
+				}
+				break;
+
+			case 2:
+				if (ss[fx_bush] == -1) {
+					ss[fx_bush]  = kernel_load_series("*DUNE11", false);
+					seq[fx_bush] = kernel_seq_stamp(ss[fx_bush], false, KERNEL_FIRST);
+					kernel_seq_depth(seq[fx_bush], 1);
+					kernel_seq_loc(seq[fx_bush], 0, BUSH_Y);
+				}
+				break;
+
+			case 3:
+				if (ss[fx_medium_dune] == -1) {
+					ss[fx_medium_dune]  = kernel_load_series("*DUNE07", false);
+					seq[fx_medium_dune] = kernel_seq_stamp(ss[fx_medium_dune], false, KERNEL_FIRST);
+					kernel_seq_depth(seq[fx_medium_dune], 1);
+					kernel_seq_loc(seq[fx_medium_dune], 0, MEDIUM_DUNE_Y);
+				}
+				break;
+
+			case 4:
+				if (ss[fx_large_dune_cactus] == -1) {
+					ss[fx_large_dune_cactus]  = kernel_load_series("*DUNE12", false);
+					seq[fx_large_dune_cactus] = kernel_seq_stamp(ss[fx_large_dune_cactus], false, KERNEL_FIRST);
+					kernel_seq_depth(seq[fx_large_dune_cactus], 1);
+					kernel_seq_loc(seq[fx_large_dune_cactus], 0, LARGE_DUNE_CACTUS_Y);
+				}
+				break;
+
+			case 5:
+				if (ss[fx_medium_dunes] == -1) {
+					ss[fx_medium_dunes]  = kernel_load_series("*DUNE15", false);
+					seq[fx_medium_dunes] = kernel_seq_stamp(ss[fx_medium_dunes], false, KERNEL_FIRST);
+					kernel_seq_depth(seq[fx_medium_dunes], 1);
+					kernel_seq_loc(seq[fx_medium_dunes], 0, MEDIUM_DUNES_Y);
+				}
+				break;
+
+			case 6:
+				if (ss[fx_00] == -1) {
+					ss[fx_00]  = kernel_load_series("*DUNE00", false);
+					seq[fx_00] = kernel_seq_stamp(ss[fx_00], false, KERNEL_FIRST);
+					kernel_seq_depth(seq[fx_00], 1);
+					kernel_seq_loc(seq[fx_00], 0, MEDIUM_DUNES_Y);
+				}
+				break;
+			}
+
+			if (skip <= 6)
+				front_left = true;
+		}
+	}
+
+	/* put down LEFT background sprites */
+
+	count2 = global[oasis] - 1;
+	skip   = 0;
+
+	for (count = 0; count < 77; count++) {
+		++skip; if (skip == 5) skip = 1;
+		++count2; if (count2 == 78) count2 = 1;
+
+		if (count2 == global[desert_room]) {
+			switch (skip) {
+			case 1:
+				ss[fx_large_dune]  = kernel_load_series("*DUNE10", false);
+				seq[fx_large_dune] = kernel_seq_stamp(ss[fx_large_dune], false, KERNEL_FIRST);
+				kernel_seq_depth(seq[fx_large_dune], 14);
+				kernel_seq_loc(seq[fx_large_dune], LARGE_DUNE_X, LARGE_DUNE_Y);
+				break;
+
+			case 2:
+				ss[fx_grassy_dune]  = kernel_load_series("*DUNE14", false);
+				seq[fx_grassy_dune] = kernel_seq_stamp(ss[fx_grassy_dune], false, KERNEL_FIRST);
+				kernel_seq_depth(seq[fx_grassy_dune], 14);
+				kernel_seq_loc(seq[fx_grassy_dune], GRASSY_DUNE_X, GRASSY_DUNE_Y);
+				break;
+			}
+
+			if (skip <= 2)
+				back_left = true;
+		}
+	}
+
+	/* put down RIGHT background sprites */
+
+	count2 = global[oasis] - 1;
+	skip   = 0;
+
+	for (count = 0; count < 77; count++) {
+		++skip;
+		if (skip == 4)
+			skip = 1;
+		++count2;
+		if (count2 == 78)
+			count2 = 1;
+
+		if (count2 == global[desert_room]) {
+
+			switch (skip) {
+			case 1:
+				if (front_right && !back_left) {
+					ss[fx_distant_dune]  = kernel_load_series("*DUNE02", false);
+					seq[fx_distant_dune] = kernel_seq_stamp(ss[fx_distant_dune], false, KERNEL_FIRST);
+					kernel_seq_depth(seq[fx_distant_dune], 14);
+					kernel_seq_loc(seq[fx_distant_dune], 40, DISTANT_DUNE_Y);
+
+				} else if (front_left && !back_right) {
+					ss[fx_distant_dune]  = kernel_load_series("*DUNE02", false);
+					seq[fx_distant_dune] = kernel_seq_stamp(ss[fx_distant_dune], false, KERNEL_FIRST);
+					kernel_seq_depth(seq[fx_distant_dune], 14);
+					kernel_seq_loc(seq[fx_distant_dune], DISTANT_DUNE_X, DISTANT_DUNE_Y);
+				}
+				break;
+			}
+
+			if (skip == 1)
+				back_right = true;
+		}
+	}
+
+	if (!player.been_here_before) {
+		aa[0] = kernel_run_animation(kernel_name('l', 1), 0);
+		id    = kernel_add_dynamic(words_lizard, words_look_at, SYNTAX_SINGULAR, KERNEL_NONE,
+		                           0, 0, 0, 0);
+		kernel_dynamic_hot[id].prep = PREP_ON;
+
+		kernel_dynamic_anim(id, aa[0], 0);
+		kernel_dynamic_anim(id, aa[0], 1);
+	}
+
+
+	if (previous_room != KERNEL_RESTORING_GAME) {
+		switch (global[from_direction]) {
+		case FROM_NORTH:
+			player.x      = FROM_NORTH_X;
+			player.y      = FROM_NORTH_Y;
+			player.facing = FACING_SOUTH;
+			break;
+
+		case FROM_SOUTH:
+			player.x      = FROM_SOUTH_X;
+			player.y      = FROM_SOUTH_Y;
+			player.facing = FACING_NORTH;
+			break;
+
+		case FROM_EAST:
+			player_first_walk(FROM_EAST_X_1, FROM_EAST_Y_1, FACING_WEST,
+			                  FROM_EAST_X_2, FROM_EAST_Y_2, FACING_WEST, true);
+			break;
+
+		case FROM_WEST:
+			player_first_walk(FROM_WEST_X_1, FROM_WEST_Y_1, FACING_EAST,
+			                  FROM_WEST_X_2, FROM_WEST_Y_2, FACING_EAST, true);
+			break;
+		}
+	}
+
+	section_4_music();
 }
 
-void room_402_daemon() {
+static void room_402_daemon() {
+	int temp;
+
+	if (player.walker_visible && (player.commands_allowed || (conv_control.running >= 0)) && !player.walking &&
+	   (player.facing == player.turn_to_facing) && !local->moving && global[player_persona] == PLAYER_IS_KING) {
+
+		switch (player.facing) {
+		case FACING_EAST:
+		case FACING_WEST:
+			if (imath_random(1, 500) == 1) {
+				if (imath_random(1, 2) == 1) {
+					player.walker_visible = false;
+					local->moving         = true;
+					if (player.facing == FACING_EAST) {
+						seq[fx_disp_6] = kernel_seq_forward(ss[fx_disp_6], false, 6, 0, 0, 1);
+					} else {
+						seq[fx_disp_6] = kernel_seq_forward(ss[fx_disp_6], true, 6, 0, 0, 1);
+					}
+					kernel_seq_player(seq[fx_disp_6], true);
+					kernel_seq_range(seq[fx_disp_6], 8, KERNEL_LAST);
+					kernel_seq_trigger(seq[fx_disp_6], KERNEL_TRIGGER_EXPIRE, 0, 1);
+
+				} else {
+					player.walker_visible = false;
+					local->moving         = true;
+					if (player.facing == FACING_EAST) {
+						seq[fx_disp_6] = kernel_seq_forward(ss[fx_disp_6], false, 6, 0, 0, 1);
+					} else {
+						seq[fx_disp_6] = kernel_seq_forward(ss[fx_disp_6], true, 6, 0, 0, 1);
+					}
+					kernel_seq_player(seq[fx_disp_6], true);
+					kernel_seq_range(seq[fx_disp_6], 1, 7);
+					kernel_seq_trigger(seq[fx_disp_6], KERNEL_TRIGGER_EXPIRE, 0, 2);
+				}
+			}
+			break;
+
+		case FACING_SOUTHEAST:
+		case FACING_SOUTHWEST:
+			if (imath_random(1, 500) == 1) {
+				if (imath_random(1, 2) == 1) {
+					player.walker_visible = false;
+					local->moving         = true;
+					if (player.facing == FACING_SOUTHEAST) {
+						seq[fx_disp_3] = kernel_seq_forward(ss[fx_disp_3], false, 6, 0, 0, 1);
+					} else {
+						seq[fx_disp_3] = kernel_seq_forward(ss[fx_disp_3], true, 6, 0, 0, 1);
+					}
+					kernel_seq_player(seq[fx_disp_3], true);
+					kernel_seq_range(seq[fx_disp_3], 1, 17);
+					kernel_seq_trigger(seq[fx_disp_3], KERNEL_TRIGGER_EXPIRE, 0, 1);
 
+				} else {
+					player.walker_visible = false;
+					local->moving         = true;
+					if (player.facing == FACING_SOUTHEAST) {
+						seq[fx_disp_3] = kernel_seq_forward(ss[fx_disp_3], false, 6, 0, 0, 1);
+					} else {
+						seq[fx_disp_3] = kernel_seq_forward(ss[fx_disp_3], true, 6, 0, 0, 1);
+					}
+					kernel_seq_player(seq[fx_disp_3], true);
+					kernel_seq_range(seq[fx_disp_3], 18, KERNEL_LAST);
+					kernel_seq_trigger(seq[fx_disp_3], KERNEL_TRIGGER_EXPIRE, 0, 4);
+				}
+			}
+			break;
+
+
+		case FACING_NORTHWEST:
+		case FACING_NORTHEAST:
+			if (imath_random(1, 500) == 1) {
+				player.walker_visible = false;
+				local->moving         = true;
+				if (player.facing == FACING_NORTHEAST) {
+					seq[fx_disp_9] = kernel_seq_forward(ss[fx_disp_9], false, 6, 0, 0, 1);
+				} else {
+					seq[fx_disp_9] = kernel_seq_forward(ss[fx_disp_9], true, 6, 0, 0, 1);
+				}
+				kernel_seq_player(seq[fx_disp_9], true);
+				kernel_seq_range(seq[fx_disp_9], 1, KERNEL_LAST);
+				kernel_seq_trigger(seq[fx_disp_9], KERNEL_TRIGGER_EXPIRE, 0, 1);
+			}
+			break;
+		}
+	}
+
+	if (local->moving) switch (kernel.trigger) {
+	case 1:
+		player.walker_visible = true;
+		local->moving         = false;
+		if (player.facing == FACING_WEST || player.facing == FACING_EAST) {
+			kernel_synch(KERNEL_PLAYER, 0, KERNEL_SERIES, seq[fx_disp_6]);
+
+		} else if (player.facing == FACING_NORTHWEST || player.facing == FACING_NORTHEAST) {
+			kernel_synch(KERNEL_PLAYER, 0, KERNEL_SERIES, seq[fx_disp_9]);
+
+		} else if (player.facing == FACING_SOUTHWEST || player.facing == FACING_SOUTHEAST) {
+			kernel_synch(KERNEL_PLAYER, 0, KERNEL_SERIES, seq[fx_disp_3]);
+		}
+		break;
+
+	case 2:
+		temp = seq[fx_disp_6];
+		if (player.facing == FACING_EAST) {
+			seq[fx_disp_6] = kernel_seq_stamp(ss[fx_disp_6], false, 7);
+		} else {
+			seq[fx_disp_6] = kernel_seq_stamp(ss[fx_disp_6], true, 7);
+		}
+		kernel_seq_player(seq[fx_disp_6], false);
+		kernel_timing_trigger(imath_random(30, 150), 3);
+		kernel_synch(KERNEL_SERIES, seq[fx_disp_6], KERNEL_SERIES, temp);
+		break;
+
+	case 3:
+		kernel_seq_delete(seq[fx_disp_6]);
+		if (player.facing == FACING_EAST) {
+			seq[fx_disp_6] = kernel_seq_backward(ss[fx_disp_6], false, 6, 0, 0, 1);
+		} else {
+			seq[fx_disp_6] = kernel_seq_backward(ss[fx_disp_6], true, 6, 0, 0, 1);
+		}
+		kernel_seq_player(seq[fx_disp_6], false);
+		kernel_seq_range(seq[fx_disp_6], 1, 7);
+		kernel_seq_trigger(seq[fx_disp_6], KERNEL_TRIGGER_EXPIRE, 0, 1);
+		break;
+
+	case 4:
+		temp = seq[fx_disp_3];
+		if (player.facing == FACING_SOUTHEAST) {
+			seq[fx_disp_3] = kernel_seq_stamp(ss[fx_disp_3], false, KERNEL_LAST);
+		} else {
+			seq[fx_disp_3] = kernel_seq_stamp(ss[fx_disp_3], true, KERNEL_LAST);
+		}
+		kernel_seq_player(seq[fx_disp_3], false);
+		kernel_timing_trigger(imath_random(30, 150), 5);
+		kernel_synch(KERNEL_SERIES, seq[fx_disp_3], KERNEL_SERIES, temp);
+		break;
+
+	case 5:
+		kernel_seq_delete(seq[fx_disp_3]);
+		if (player.facing == FACING_SOUTHEAST) {
+			seq[fx_disp_3] = kernel_seq_backward(ss[fx_disp_3], false, 6, 0, 0, 1);
+		} else {
+			seq[fx_disp_3] = kernel_seq_backward(ss[fx_disp_3], true, 6, 0, 0, 1);
+		}
+		kernel_seq_player(seq[fx_disp_3], false);
+		kernel_seq_range(seq[fx_disp_3], 18, KERNEL_LAST);
+		kernel_seq_trigger(seq[fx_disp_3], KERNEL_TRIGGER_EXPIRE, 0, 1);
+		break;
+	}
 }
 
-void room_402_pre_parser() {
+static void room_402_pre_parser() {
+	if (local->moving) {
+		switch (player.facing) {
+		case FACING_EAST:
+		case FACING_WEST:
+			kernel_seq_delete(seq[fx_disp_6]);
+			player.walker_visible = true;
+			break;
+
+		case FACING_NORTHEAST:
+		case FACING_NORTHWEST:
+			kernel_seq_delete(seq[fx_disp_9]);
+			player.walker_visible = true;
+			break;
 
+		case FACING_SOUTHEAST:
+		case FACING_SOUTHWEST:
+			kernel_seq_delete(seq[fx_disp_3]);
+			player.walker_visible = true;
+			break;
+		}
+		kernel_synch(KERNEL_PLAYER, 0, KERNEL_NOW, 0);
+		local->moving = false;
+	}
+
+	if (player_said_1(cross)) {
+		if (player_has_been_in_room(405) && player_said_1(desert_to_west)) {
+			global[from_direction]       = FROM_EAST;
+			player.walk_off_edge_to_room = 405;
+
+		} else if (player_has_been_in_room(405) && player_said_1(desert_to_east)) {
+			global[pre_room]             = 401;
+			player.walk_off_edge_to_room = 120;
+
+		} else if (player_said_1(desert_to_east) && global[desert_room] % 7 == 0) {
+			global[pre_room]             = 401;
+			player.walk_off_edge_to_room = 120;
+
+		} else if (player_said_1(desert_to_east) || player_said_1(desert_to_west)) {
+			player.walk_off_edge_to_room = 400;
+		}
+	}
 }
 
-void room_402_parser() {
+static void room_402_parser() {
+	int count;
+	int count2 = global[oasis] - 1;
+	int room = 400;
+
+	if (player_said_1(cross)) {
+		if (player_said_1(desert_to_north) || player_said_1(desert_to_south)) {
+			if (player_said_1(desert_to_north)) {
+				global[desert_room] = global[desert_room] - 7;
+				global[from_direction] = FROM_SOUTH;
+
+			} else if (player_said_1(desert_to_south)) {
+				global[desert_room] += 7;
+				global[from_direction] = FROM_NORTH;
+			}
+
+			for (count = 0; count < 77; count++) {
+				++room; if (room == 404) room = 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;
+					goto over;
+				}
+			}
+
+over:
+
+			++global[desert_counter];
+			if (player_has_been_in_room(405)) {
+				global[from_direction] = FROM_EAST;
+				new_room               = 405;
+
+			} else if (global[desert_counter] == 6 && !player_has_been_in_room(405)) {
+				new_room = 404;
 
+			} else if (room_id == room) {
+				kernel.force_restart = true;
+
+			} else {
+				new_room = room;
+			}
+			goto handled;
+		}
+	}
+
+	if (player.look_around) {
+		text_show(40201);
+		goto handled;
+	}
+
+	if (player_said_1(look) || player_said_1(look_at)) {
+		if (player_said_1(desert_to_north) ||
+		    player_said_1(desert_to_south) ||
+		    player_said_1(desert_to_east)  ||
+		    player_said_1(desert_to_west)) {
+			text_show(40202);
+			goto handled;
+		}
+
+		if (player_said_1(sky)) {
+			text_show(40203);
+			goto handled;
+		}
+
+		if (player_said_1(lizard)) {
+			text_show(40205);
+			goto handled;
+		}
+	}
+
+	if (player_said_2(take, desert)) {
+		text_show(40204);
+		goto handled;
+	}
+
+	goto done;
+
+handled:
+	player.command_ready = false;
+
+done:
+	;
 }
 
 void room_402_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.moving);
 }
 
 void room_402_preload() {
@@ -76,6 +684,8 @@ void room_402_preload() {
 
 	section_4_walker();
 	section_4_interface();
+
+	vocab_make_active(words_lizard);
 }
 
 } // namespace Rooms
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room403.cpp b/engines/mads/madsv2/dragonsphere/rooms/room403.cpp
index 025f109c337..0245ac99865 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room403.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room403.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
@@ -39,6 +39,10 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[19];
+	int16 sequence[19];
+	int16 animation[4];
+	int16 moving;
 };
 
 #define local (&scratch)
@@ -46,33 +50,602 @@ struct Scratch {
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
+#define fx_red_rocks            1
+#define fx_distant_dune         2
+#define fx_medium_dune          3
+#define fx_small_dune           4
+#define fx_dune_rocks           5
+#define fx_large_dune           6
+#define fx_bush                 7
+#define fx_large_dune_cactus    8
+#define fx_large_round_dune     9
+#define fx_grassy_dune          10
+#define fx_medium_dunes         11
+#define fx_large_tent           12
+#define fx_small_tent           13
+#define fx_tumbleweed           14
+#define fx_00                   15
+#define fx_disp_6               16
+#define fx_disp_9               17
+#define fx_disp_3               18
+
+#define RED_ROCKS_X             45
+#define RED_ROCKS_Y             155
+#define BUSH_X                  289
+#define BUSH_Y                  155
+#define MEDIUM_DUNE_X           270
+#define MEDIUM_DUNE_Y           155
+#define DUNE_ROCKS_X            227
+#define DUNE_ROCKS_Y            155
+#define LARGE_DUNE_CACTUS_X     279
+#define LARGE_DUNE_CACTUS_Y     155
+#define LARGE_ROUND_DUNE_X      300
+#define LARGE_ROUND_DUNE_Y      155
+#define MEDIUM_DUNES_X          270
+#define MEDIUM_DUNES_Y          155
+#define GRASSY_DUNE_X           29
+#define GRASSY_DUNE_Y           131
+#define LARGE_DUNE_X            32
+#define LARGE_DUNE_Y            128
+#define SMALL_DUNE_X            230
+#define SMALL_DUNE_Y            133
+#define DISTANT_DUNE_X          280
+#define DISTANT_DUNE_Y          128
+#define LARGE_TENT_X            70
+#define LARGE_TENT_Y            130
+#define SMALL_TENT_X            217
+#define SMALL_TENT_Y            127
+#define TUMBLEWEED_X            108
+#define TUMBLEWEED_Y            149
+#define FROM_NORTH_X            170
+#define FROM_NORTH_Y            134
+#define FROM_SOUTH_X            161
+#define FROM_SOUTH_Y            143
+#define FROM_EAST_X_1           330
+#define FROM_EAST_Y_1           143
+#define FROM_EAST_X_2           302
+#define FROM_EAST_Y_2           143
+#define FROM_WEST_X_1           -15
+#define FROM_WEST_Y_1           143
+#define FROM_WEST_X_2           15
+#define FROM_WEST_Y_2           143
+
+static Scratch scratch;
+
 
 void room_403_init() {
+	int count;
+	int count2 = global[fire_holes] - 1;
+	int skip = 0;
+
+	int front_right = false;
+	int front_left = false;
+	int back_left = false;
+	int back_right = false;
+
+	if (global[player_persona] == PLAYER_IS_PID) {
+		global[perform_displacements] = true;
+	}
+
+	ss[fx_bush] = -1;
+	ss[fx_red_rocks] = -1;
+	ss[fx_medium_dune] = -1;
+	ss[fx_large_dune_cactus] = -1;
+	ss[fx_medium_dunes] = -1;
+	ss[fx_00] = -1;
+
+	local->moving = false;
+	ss[fx_disp_3] = kernel_load_series("*KG4DIS3", false);
+	ss[fx_disp_6] = kernel_load_series("*KG4DIS6", false);
+	ss[fx_disp_9] = kernel_load_series("*KG4DIS9", false);
+
+	/* put down RIGHT foreground sprites */
+
+	for (count = 0; count < 77; count++) {
+		++skip;
+		if (skip == 7)
+			skip = 1;
+		++count2;
+		if (count2 == 78)
+			count2 = 1;
+
+		if (count2 == global[desert_room]) {
+			switch (skip) {
+			case 1:
+				ss[fx_medium_dune] = kernel_load_series("*DUNE07", false);
+				seq[fx_medium_dune] = kernel_seq_stamp(ss[fx_medium_dune], false, KERNEL_FIRST);
+				kernel_seq_depth(seq[fx_medium_dune], 1);
+				kernel_seq_loc(seq[fx_medium_dune], MEDIUM_DUNE_X, MEDIUM_DUNE_Y);
+				break;
+
+			case 2:
+				ss[fx_dune_rocks] = kernel_load_series("*DUNE09", false);
+				seq[fx_dune_rocks] = kernel_seq_stamp(ss[fx_dune_rocks], false, KERNEL_FIRST);
+				kernel_seq_depth(seq[fx_dune_rocks], 1);
+				kernel_seq_loc(seq[fx_dune_rocks], DUNE_ROCKS_X, DUNE_ROCKS_Y);
+				break;
+
+			case 3:
+				ss[fx_bush] = kernel_load_series("*DUNE11", false);
+				seq[fx_bush] = kernel_seq_stamp(ss[fx_bush], false, KERNEL_FIRST);
+				kernel_seq_depth(seq[fx_bush], 1);
+				kernel_seq_loc(seq[fx_bush], BUSH_X, BUSH_Y);
+				break;
+
+			case 4:
+				ss[fx_large_dune_cactus] = kernel_load_series("*DUNE12", false);
+				seq[fx_large_dune_cactus] = kernel_seq_stamp(ss[fx_large_dune_cactus], false, KERNEL_FIRST);
+				kernel_seq_depth(seq[fx_large_dune_cactus], 1);
+				kernel_seq_loc(seq[fx_large_dune_cactus], LARGE_DUNE_CACTUS_X, LARGE_DUNE_CACTUS_Y);
+				break;
+
+			case 5:
+				ss[fx_large_round_dune] = kernel_load_series("*DUNE13", false);
+				seq[fx_large_round_dune] = kernel_seq_stamp(ss[fx_large_round_dune], false, KERNEL_FIRST);
+				kernel_seq_depth(seq[fx_large_round_dune], 1);
+				kernel_seq_loc(seq[fx_large_round_dune], LARGE_ROUND_DUNE_X, LARGE_ROUND_DUNE_Y);
+				break;
+
+			case 6:
+				ss[fx_medium_dunes] = kernel_load_series("*DUNE15", false);
+				seq[fx_medium_dunes] = kernel_seq_stamp(ss[fx_medium_dunes], false, KERNEL_FIRST);
+				kernel_seq_depth(seq[fx_medium_dunes], 1);
+				kernel_seq_loc(seq[fx_medium_dunes], MEDIUM_DUNES_X, MEDIUM_DUNES_Y);
+				break;
+			}
+
+			if (skip <= 6) front_right = true;
+		}
+	}
+
+	/* put down LEFT foreground sprites */
+
+	count2 = 29;
+	skip = 0;
+
+	for (count = 0; count < 77; count++) {
+		++skip;
+		if (skip == 9)
+			skip = 1;
+		++count2;
+		if (count2 == 78)
+			count2 = 1;
+
+		if (count2 == global[desert_room]) {
+			switch (skip) {
+			case 1:
+				if (ss[fx_red_rocks] == -1) {
+					ss[fx_red_rocks] = kernel_load_series("*DUNE01", false);
+					seq[fx_red_rocks] = kernel_seq_stamp(ss[fx_red_rocks], false, KERNEL_FIRST);
+					kernel_seq_depth(seq[fx_red_rocks], 1);
+					kernel_seq_loc(seq[fx_red_rocks], RED_ROCKS_X, RED_ROCKS_Y);
+				}
+				break;
+
+			case 2:
+				if (ss[fx_bush] == -1) {
+					ss[fx_bush] = kernel_load_series("*DUNE11", false);
+					seq[fx_bush] = kernel_seq_stamp(ss[fx_bush], false, KERNEL_FIRST);
+					kernel_seq_depth(seq[fx_bush], 1);
+					kernel_seq_loc(seq[fx_bush], 0, BUSH_Y);
+				}
+				break;
+
+			case 3:
+				if (ss[fx_medium_dune] == -1) {
+					ss[fx_medium_dune] = kernel_load_series("*DUNE07", false);
+					seq[fx_medium_dune] = kernel_seq_stamp(ss[fx_medium_dune], false, KERNEL_FIRST);
+					kernel_seq_depth(seq[fx_medium_dune], 1);
+					kernel_seq_loc(seq[fx_medium_dune], 0, MEDIUM_DUNE_Y);
+				}
+				break;
+
+			case 4:
+				if (ss[fx_large_dune_cactus] == -1) {
+					ss[fx_large_dune_cactus] = kernel_load_series("*DUNE12", false);
+					seq[fx_large_dune_cactus] = kernel_seq_stamp(ss[fx_large_dune_cactus], false, KERNEL_FIRST);
+					kernel_seq_depth(seq[fx_large_dune_cactus], 1);
+					kernel_seq_loc(seq[fx_large_dune_cactus], 0, LARGE_DUNE_CACTUS_Y);
+				}
+				break;
+
+			case 5:
+				if (ss[fx_medium_dunes] == -1) {
+					ss[fx_medium_dunes] = kernel_load_series("*DUNE15", false);
+					seq[fx_medium_dunes] = kernel_seq_stamp(ss[fx_medium_dunes], false, KERNEL_FIRST);
+					kernel_seq_depth(seq[fx_medium_dunes], 1);
+					kernel_seq_loc(seq[fx_medium_dunes], 0, MEDIUM_DUNES_Y);
+				}
+				break;
+
+			case 6:
+				if (ss[fx_00] == -1) {
+					ss[fx_00] = kernel_load_series("*DUNE00", false);
+					seq[fx_00] = kernel_seq_stamp(ss[fx_00], false, KERNEL_FIRST);
+					kernel_seq_depth(seq[fx_00], 1);
+					kernel_seq_loc(seq[fx_00], 0, MEDIUM_DUNES_Y);
+				}
+				break;
+			}
+
+			if (skip <= 6) front_left = true;
+		}
+	}
+
+	/* put down LEFT background sprites */
+
+	count2 = global[oasis] - 1;
+	skip = 0;
+
+	for (count = 0; count < 77; count++) {
+		++skip;
+		if (skip == 5)
+			skip = 1;
+		++count2;
+		if (count2 == 78)
+			count2 = 1;
+
+		if (count2 == global[desert_room]) {
+			switch (skip) {
+			case 1:
+				ss[fx_large_dune] = kernel_load_series("*DUNE10", false);
+				seq[fx_large_dune] = kernel_seq_stamp(ss[fx_large_dune], false, KERNEL_FIRST);
+				kernel_seq_depth(seq[fx_large_dune], 14);
+				kernel_seq_loc(seq[fx_large_dune], LARGE_DUNE_X, LARGE_DUNE_Y);
+				break;
+
+			case 2:
+				ss[fx_grassy_dune] = kernel_load_series("*DUNE14", false);
+				seq[fx_grassy_dune] = kernel_seq_stamp(ss[fx_grassy_dune], false, KERNEL_FIRST);
+				kernel_seq_depth(seq[fx_grassy_dune], 14);
+				kernel_seq_loc(seq[fx_grassy_dune], GRASSY_DUNE_X, GRASSY_DUNE_Y);
+				break;
+			}
 
+			if (skip <= 2) back_left = true;
+		}
+	}
+
+	/* put down RIGHT background sprites */
+
+	count2 = global[oasis] - 1;
+	skip = 0;
+
+	for (count = 0; count < 77; count++) {
+		++skip;
+		if (skip == 4)
+			skip = 1;
+		++count2;
+		if (count2 == 78)
+			count2 = 1;
+
+		if (count2 == global[desert_room]) {
+			switch (skip) {
+			case 1:
+				if (front_right && !back_left) {
+					ss[fx_distant_dune] = kernel_load_series("*DUNE02", false);
+					seq[fx_distant_dune] = kernel_seq_stamp(ss[fx_distant_dune], false, KERNEL_FIRST);
+					kernel_seq_depth(seq[fx_distant_dune], 14);
+					kernel_seq_loc(seq[fx_distant_dune], 40, DISTANT_DUNE_Y);
+				} else if (front_left && !back_right) {
+					ss[fx_distant_dune] = kernel_load_series("*DUNE02", false);
+					seq[fx_distant_dune] = kernel_seq_stamp(ss[fx_distant_dune], false, KERNEL_FIRST);
+					kernel_seq_depth(seq[fx_distant_dune], 14);
+					kernel_seq_loc(seq[fx_distant_dune], DISTANT_DUNE_X, DISTANT_DUNE_Y);
+				}
+				break;
+			}
+
+			if (skip == 1)
+				back_right = true;
+		}
+	}
+
+	if (previous_room != KERNEL_RESTORING_GAME) {
+		switch (global[from_direction]) {
+		case FROM_NORTH:
+			player.x = FROM_NORTH_X;
+			player.y = FROM_NORTH_Y;
+			player.facing = FACING_SOUTH;
+			break;
+
+		case FROM_SOUTH:
+			player.x = FROM_SOUTH_X;
+			player.y = FROM_SOUTH_Y;
+			player.facing = FACING_NORTH;
+			break;
+
+		case FROM_EAST:
+			player_first_walk(FROM_EAST_X_1, FROM_EAST_Y_1, FACING_WEST,
+				FROM_EAST_X_2, FROM_EAST_Y_2, FACING_WEST, true);
+			break;
+
+		case FROM_WEST:
+			player_first_walk(FROM_WEST_X_1, FROM_WEST_Y_1, FACING_EAST,
+				FROM_WEST_X_2, FROM_WEST_Y_2, FACING_EAST, true);
+			break;
+		}
+	}
+
+	section_4_music();
 }
 
-void room_403_daemon() {
+static void room_403_daemon() {
+	int temp;
+
+	if (player.walker_visible && (player.commands_allowed || (conv_control.running >= 0)) && !player.walking &&
+	   (player.facing == player.turn_to_facing) && !local->moving && global[player_persona] == PLAYER_IS_KING) {
+
+		switch (player.facing) {
+		case FACING_EAST:
+		case FACING_WEST:
+			if (imath_random(1, 500) == 1) {
+				if (imath_random(1, 2) == 1) {
+					player.walker_visible = false;
+					local->moving         = true;
+					if (player.facing == FACING_EAST) {
+						seq[fx_disp_6] = kernel_seq_forward(ss[fx_disp_6], false, 6, 0, 0, 1);
+					} else {
+						seq[fx_disp_6] = kernel_seq_forward(ss[fx_disp_6], true, 6, 0, 0, 1);
+					}
+					kernel_seq_player(seq[fx_disp_6], true);
+					kernel_seq_range(seq[fx_disp_6], 8, KERNEL_LAST);
+					kernel_seq_trigger(seq[fx_disp_6], KERNEL_TRIGGER_EXPIRE, 0, 1);
+				} else {
+					player.walker_visible = false;
+					local->moving         = true;
+					if (player.facing == FACING_EAST) {
+						seq[fx_disp_6] = kernel_seq_forward(ss[fx_disp_6], false, 6, 0, 0, 1);
+					} else {
+						seq[fx_disp_6] = kernel_seq_forward(ss[fx_disp_6], true, 6, 0, 0, 1);
+					}
+					kernel_seq_player(seq[fx_disp_6], true);
+					kernel_seq_range(seq[fx_disp_6], 1, 7);
+					kernel_seq_trigger(seq[fx_disp_6], KERNEL_TRIGGER_EXPIRE, 0, 2);
+				}
+			}
+			break;
+
+		case FACING_SOUTHEAST:
+		case FACING_SOUTHWEST:
+			if (imath_random(1, 500) == 1) {
+				if (imath_random(1, 2) == 1) {
+					player.walker_visible = false;
+					local->moving         = true;
+					if (player.facing == FACING_SOUTHEAST) {
+						seq[fx_disp_3] = kernel_seq_forward(ss[fx_disp_3], false, 6, 0, 0, 1);
+					} else {
+						seq[fx_disp_3] = kernel_seq_forward(ss[fx_disp_3], true, 6, 0, 0, 1);
+					}
+					kernel_seq_player(seq[fx_disp_3], true);
+					kernel_seq_range(seq[fx_disp_3], 1, 17);
+					kernel_seq_trigger(seq[fx_disp_3], KERNEL_TRIGGER_EXPIRE, 0, 1);
+				} else {
+					player.walker_visible = false;
+					local->moving         = true;
+					if (player.facing == FACING_SOUTHEAST) {
+						seq[fx_disp_3] = kernel_seq_forward(ss[fx_disp_3], false, 6, 0, 0, 1);
+					} else {
+						seq[fx_disp_3] = kernel_seq_forward(ss[fx_disp_3], true, 6, 0, 0, 1);
+					}
+					kernel_seq_player(seq[fx_disp_3], true);
+					kernel_seq_range(seq[fx_disp_3], 18, KERNEL_LAST);
+					kernel_seq_trigger(seq[fx_disp_3], KERNEL_TRIGGER_EXPIRE, 0, 4);
+				}
+			}
+			break;
+
+		case FACING_NORTHWEST:
+		case FACING_NORTHEAST:
+			if (imath_random(1, 500) == 1) {
+				player.walker_visible = false;
+				local->moving         = true;
+				if (player.facing == FACING_NORTHEAST) {
+					seq[fx_disp_9] = kernel_seq_forward(ss[fx_disp_9], false, 6, 0, 0, 1);
+				} else {
+					seq[fx_disp_9] = kernel_seq_forward(ss[fx_disp_9], true, 6, 0, 0, 1);
+				}
+				kernel_seq_player(seq[fx_disp_9], true);
+				kernel_seq_range(seq[fx_disp_9], 1, KERNEL_LAST);
+				kernel_seq_trigger(seq[fx_disp_9], KERNEL_TRIGGER_EXPIRE, 0, 1);
+			}
+			break;
+		}
+	}
+
+	if (local->moving) switch (kernel.trigger) {
+	case 1:
+		player.walker_visible = true;
+		local->moving         = false;
+		if (player.facing == FACING_WEST || player.facing == FACING_EAST) {
+			kernel_synch(KERNEL_PLAYER, 0, KERNEL_SERIES, seq[fx_disp_6]);
+		} else if (player.facing == FACING_NORTHWEST || player.facing == FACING_NORTHEAST) {
+			kernel_synch(KERNEL_PLAYER, 0, KERNEL_SERIES, seq[fx_disp_9]);
+		} else if (player.facing == FACING_SOUTHWEST || player.facing == FACING_SOUTHEAST) {
+			kernel_synch(KERNEL_PLAYER, 0, KERNEL_SERIES, seq[fx_disp_3]);
+		}
+		break;
 
+	case 2:
+		temp = seq[fx_disp_6];
+		if (player.facing == FACING_EAST) {
+			seq[fx_disp_6] = kernel_seq_stamp(ss[fx_disp_6], false, 7);
+		} else {
+			seq[fx_disp_6] = kernel_seq_stamp(ss[fx_disp_6], true, 7);
+		}
+		kernel_seq_player(seq[fx_disp_6], false);
+		kernel_timing_trigger(imath_random(30, 150), 3);
+		kernel_synch(KERNEL_SERIES, seq[fx_disp_6], KERNEL_SERIES, temp);
+		break;
+
+	case 3:
+		kernel_seq_delete(seq[fx_disp_6]);
+		if (player.facing == FACING_EAST) {
+			seq[fx_disp_6] = kernel_seq_backward(ss[fx_disp_6], false, 6, 0, 0, 1);
+		} else {
+			seq[fx_disp_6] = kernel_seq_backward(ss[fx_disp_6], true, 6, 0, 0, 1);
+		}
+		kernel_seq_player(seq[fx_disp_6], false);
+		kernel_seq_range(seq[fx_disp_6], 1, 7);
+		kernel_seq_trigger(seq[fx_disp_6], KERNEL_TRIGGER_EXPIRE, 0, 1);
+		break;
+
+	case 4:
+		temp = seq[fx_disp_3];
+		if (player.facing == FACING_SOUTHEAST) {
+			seq[fx_disp_3] = kernel_seq_stamp(ss[fx_disp_3], false, KERNEL_LAST);
+		} else {
+			seq[fx_disp_3] = kernel_seq_stamp(ss[fx_disp_3], true, KERNEL_LAST);
+		}
+		kernel_seq_player(seq[fx_disp_3], false);
+		kernel_timing_trigger(imath_random(30, 150), 5);
+		kernel_synch(KERNEL_SERIES, seq[fx_disp_3], KERNEL_SERIES, temp);
+		break;
+
+	case 5:
+		kernel_seq_delete(seq[fx_disp_3]);
+		if (player.facing == FACING_SOUTHEAST) {
+			seq[fx_disp_3] = kernel_seq_backward(ss[fx_disp_3], false, 6, 0, 0, 1);
+		} else {
+			seq[fx_disp_3] = kernel_seq_backward(ss[fx_disp_3], true, 6, 0, 0, 1);
+		}
+		kernel_seq_player(seq[fx_disp_3], false);
+		kernel_seq_range(seq[fx_disp_3], 18, KERNEL_LAST);
+		kernel_seq_trigger(seq[fx_disp_3], KERNEL_TRIGGER_EXPIRE, 0, 1);
+		break;
+	}
 }
 
-void room_403_pre_parser() {
+static void room_403_pre_parser() {
+	if (local->moving) {
+		switch (player.facing) {
+		case FACING_EAST:
+		case FACING_WEST:
+			kernel_seq_delete(seq[fx_disp_6]);
+			player.walker_visible = true;
+			break;
+
+		case FACING_NORTHEAST:
+		case FACING_NORTHWEST:
+			kernel_seq_delete(seq[fx_disp_9]);
+			player.walker_visible = true;
+			break;
 
+		case FACING_SOUTHEAST:
+		case FACING_SOUTHWEST:
+			kernel_seq_delete(seq[fx_disp_3]);
+			player.walker_visible = true;
+			break;
+		}
+		kernel_synch(KERNEL_PLAYER, 0, KERNEL_NOW, 0);
+		local->moving = false;
+	}
+
+	if (player_said_1(cross)) {
+		if (player_has_been_in_room(405) && player_said_1(desert_to_west)) {
+			global[from_direction]       = FROM_EAST;
+			player.walk_off_edge_to_room = 405;
+		} else if (player_has_been_in_room(405) && player_said_1(desert_to_east)) {
+			global[pre_room]             = 401;
+			player.walk_off_edge_to_room = 120;
+		} else if (player_said_1(desert_to_east) && global[desert_room] % 7 == 0) {
+			global[pre_room]             = 401;
+			player.walk_off_edge_to_room = 120;
+		} else if (player_said_1(desert_to_east) || player_said_1(desert_to_west)) {
+			player.walk_off_edge_to_room = 400;
+		}
+	}
 }
 
 void room_403_parser() {
+	int count;
+	int count2 = global[oasis] - 1;
+	int room = 400;
+
+	if (player_said_1(cross)) {
+		if (player_said_1(desert_to_north) || player_said_1(desert_to_south)) {
+			if (player_said_1(desert_to_north)) {
+				global[desert_room] = global[desert_room] - 7;
+				global[from_direction] = FROM_SOUTH;
+			} else if (player_said_1(desert_to_south)) {
+				global[desert_room] += 7;
+				global[from_direction] = FROM_NORTH;
+			}
+
+			for (count = 0; count < 77; count++) {
+				++ room; if (room == 404) room = 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;
+					goto over;
+				}
+			}
+
+over:
+			++ global[desert_counter];
+			if (player_has_been_in_room(405)) {
+				global[from_direction] = FROM_EAST;
+				new_room               = 405;
+			} else if (global[desert_counter] == 6 && !player_has_been_in_room(405)) {
+				new_room = 404;
+			} else if (room_id == room) {
+				kernel.force_restart = true;
+			} else {
+				new_room = room;
+			}
+			goto handled;
+		}
+	}
+
+	if (player.look_around) {
+		text_show(40201);
+		goto handled;
+	}
+
+	if (player_said_1(look) || player_said_1(look_at)) {
+		if (player_said_1(desert_to_north) ||
+		    player_said_1(desert_to_south) ||
+		    player_said_1(desert_to_east)  ||
+		    player_said_1(desert_to_west)) {
+			text_show(40202);
+			goto handled;
+		}
+
+		if (player_said_1(sky)) {
+			text_show(40203);
+			goto handled;
+		}
+	}
+
+	if (player_said_2(take, desert)) {
+		text_show(40204);
+		goto handled;
+	}
+
+	goto done;
+
+handled:
+	player.command_ready = false;
 
+done:
+	;
 }
 
 void room_403_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.moving);
 }
 
 void room_403_preload() {
-	room_init_code_pointer = room_403_init;
+	room_init_code_pointer       = room_403_init;
 	room_pre_parser_code_pointer = room_403_pre_parser;
-	room_parser_code_pointer = room_403_parser;
-	room_daemon_code_pointer = room_403_daemon;
+	room_parser_code_pointer     = room_403_parser;
+	room_daemon_code_pointer     = room_403_daemon;
 
 	section_4_walker();
 	section_4_interface();
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room404.cpp b/engines/mads/madsv2/dragonsphere/rooms/room404.cpp
index a755aaf786b..dfa45244a9d 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room404.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room404.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,10 +19,12 @@
  *
  */
 
+#include "mads/madsv2/core/camera.h"
 #include "mads/madsv2/core/conv.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/sound.h"
 #include "mads/madsv2/core/text.h"
 #include "mads/madsv2/dragonsphere/mads/conv.h"
@@ -39,6 +41,22 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[15];
+	int16 sequence[15];
+	int16 animation[4];
+	int16 dune_1_base;
+	int16 dyn_dune_1;
+	int16 dune_2_base;
+	int16 dyn_dune_2;
+	int16 mount_left_base;
+	int16 dyn_mount_left;
+	int16 mount_right_base;
+	int16 dyn_mount_right;
+	int16 king_frame;
+	int16 anim_0_running;
+	int16 death_frame;
+	int16 anim_1_running;
+	int16 num;
 };
 
 #define local (&scratch)
@@ -46,33 +64,357 @@ struct Scratch {
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
+#define fx_dune_1               0
+#define fx_dune_2               1
+#define fx_lean_to              2
+#define fx_mount_left           3
+#define fx_mount_right          4
+#define fx_cloud_left           5
+#define fx_cloud_right          6
 
-void room_404_init() {
+#define MUSIC                   60
 
+#define camera_ratio_1          1
+#define camera_ratio_2          2
+
+#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_1_position() {
+	int center;
+	int difference;
+	int direction;
+	int distance;
+	int displace;
+	int x;
+	int y;
+	int xs;
+
+	center = picture_view_x + (video_x >> 1);
+
+	if (seq[fx_dune_1] >= 0) {
+		kernel_seq_delete(seq[fx_dune_1]);
+	}
+
+	difference = center - local->dune_1_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_1_base + displace - 1;
+	y          = series_list[ss[fx_dune_1]]->index[0].ys + 114;
+	xs         = series_list[ss[fx_dune_1]]->index[0].xs;
+
+	if (((x - ((xs >> 1) + 1)) >= (picture_view_x + video_x)) ||
+	    ((x + ((xs >> 1) + 1)) < picture_view_x)) {
+		seq[fx_dune_1] = -1;
+	} else {
+		seq[fx_dune_1] = kernel_seq_stamp(ss[fx_dune_1], false, 1);
+		kernel_seq_loc(seq[fx_dune_1], x, y);
+		kernel_seq_depth(seq[fx_dune_1], 1);
+	}
+}
+
+static void set_dune_2_position() {
+	int center;
+	int difference;
+	int direction;
+	int distance;
+	int displace;
+	int x;
+	int y;
+	int xs;
+
+	center = picture_view_x + (video_x >> 1);
+
+	if (seq[fx_dune_2] >= 0) {
+		kernel_seq_delete(seq[fx_dune_2]);
+	}
+
+	difference = center - local->dune_2_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_2_base + displace - 1;
+	y          = series_list[ss[fx_dune_2]]->index[0].ys + 126;
+	xs         = series_list[ss[fx_dune_2]]->index[0].xs;
+
+	if (((x - ((xs >> 1) + 1)) >= (picture_view_x + video_x)) ||
+	    ((x + ((xs >> 1) + 1)) < picture_view_x)) {
+		seq[fx_dune_2] = -1;
+	} else {
+		seq[fx_dune_2] = kernel_seq_stamp(ss[fx_dune_2], false, 1);
+		kernel_seq_loc(seq[fx_dune_2], x, y);
+		kernel_seq_depth(seq[fx_dune_2], 1);
+	}
 }
 
-void room_404_daemon() {
+static void set_404_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_404_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_404_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, 80);
+	kernel_seq_depth(seq[fx_cloud_left], 15);
 }
 
-void room_404_pre_parser() {
+static void set_404_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, 82);
+	kernel_seq_depth(seq[fx_cloud_right], 3);
 }
 
-void room_404_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 132:
+			king_reset_frame = 463;
+			break;
+
+		case 475:
+			king_reset_frame = 132;
+			break;
 
+		case 245:
+			camera_pan_to(&camera_x, 0);
+			break;
+
+		case 463:
+			if (global[talked_to_soptus]) {
+				text_show(40401);
+			} else {
+				text_show(40402);
+			}
+			text_show(40403);
+			camera_x.pan_mode      = CAMERA_PLAYER;
+			global[from_direction] = FROM_EAST;
+			global[no_load_walker] = false;
+			new_room               = 401;
+			break;
+		}
+
+		if (king_reset_frame >= 0) {
+			kernel_reset_animation(aa[0], king_reset_frame);
+			local->king_frame = king_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_death() {
+	int death_reset_frame;
+
+	if (kernel_anim[aa[1]].frame != local->death_frame) {
+		local->death_frame = kernel_anim[aa[1]].frame;
+		death_reset_frame = -1;
+
+		switch (local->death_frame) {
+		case 149:
+			++ local->num;
+			if (local->num < 4) {
+				death_reset_frame = 147;
+			}
+			break;
+		}
+
+		if (death_reset_frame >= 0) {
+			kernel_reset_animation(aa[1], death_reset_frame);
+			local->death_frame = death_reset_frame;
+		}
+	}
+}
+
+static void room_404_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;
+	local->anim_1_running = false;
+	local->num = 0;
+
+	ss[fx_mount_left] = kernel_load_series(kernel_name('x', 6), false);
+	ss[fx_mount_right] = kernel_load_series(kernel_name('x', 7), 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 (global[desert_counter] == 6) {
+		aa[1] = kernel_run_animation(kernel_name('d', 1), 1);
+		local->anim_1_running = true;
+		kernel_reset_animation(aa[25], 30);
+
+	} else if (previous_room == 120 || previous_room != KERNEL_RESTORING_GAME) {
+		ss[fx_dune_1] = kernel_load_series(kernel_name('x', 0), false);
+		ss[fx_dune_2] = kernel_load_series(kernel_name('x', 3), false);
+		ss[fx_lean_to] = kernel_load_series(kernel_name('x', 1), false);
+
+		aa[0] = kernel_run_animation(kernel_name('w', 1), 0);
+		local->anim_0_running = true;
+		kernel_reset_animation(aa[0], 30);
+
+		seq[fx_lean_to] = kernel_seq_stamp(ss[fx_lean_to], false, KERNEL_FIRST);
+		kernel_seq_depth(seq[fx_lean_to], 4);
+
+		seq[fx_dune_1] = -1;
+		local->dyn_dune_1 = -1;
+		local->dune_1_base = 84;
+
+		seq[fx_dune_2] = -1;
+		local->dyn_dune_2 = -1;
+		local->dune_2_base = 500;
+
+		set_dune_1_position();
+		set_dune_2_position();
+	}
+
+	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, 80);
+	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, 82);
+	kernel_seq_depth(seq[fx_cloud_right], 3);
+
+	viewing_at_y = ((video_y - display_y) >> 1);
+
+	if (previous_room == 120) {
+		kernel_timing_trigger(10, MUSIC);
+	}
+
+	section_4_music();
+}
+
+static void room_404_daemon() {
+	if (local->anim_0_running) {
+		handle_animation_king();
+	}
+
+	if (local->anim_1_running) {
+		handle_animation_death();
+	}
+
+	if (camera_x.pan_this_frame) {
+		set_404_mount_left_position();
+		set_404_mount_right_position();
+		set_404_cloud_left_position();
+		set_404_cloud_right_position();
+		set_dune_1_position();
+		set_dune_2_position();
+	}
+
+	if (kernel.trigger == 1) {
+		text_show(40404);
+		global[desert_room]    = 42;
+		new_room               = 401;
+		global[no_load_walker] = false;
+	}
+
+	if (kernel.trigger == MUSIC) {
+		sound_play(N_Bk404Music);
+	}
+}
+
+static void room_404_pre_parser() {
+}
+
+static void room_404_parser() {
 }
 
 void room_404_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_1_base);
+	s.syncAsSint16LE(scratch.dyn_dune_1);
+	s.syncAsSint16LE(scratch.dune_2_base);
+	s.syncAsSint16LE(scratch.dyn_dune_2);
+	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);
+	s.syncAsSint16LE(scratch.death_frame);
+	s.syncAsSint16LE(scratch.anim_1_running);
+	s.syncAsSint16LE(scratch.num);
 }
 
 void room_404_preload() {
-	room_init_code_pointer = room_404_init;
+	room_init_code_pointer       = room_404_init;
 	room_pre_parser_code_pointer = room_404_pre_parser;
-	room_parser_code_pointer = room_404_parser;
-	room_daemon_code_pointer = room_404_daemon;
+	room_parser_code_pointer     = room_404_parser;
+	room_daemon_code_pointer     = room_404_daemon;
+
+	global[no_load_walker] = true;
 
 	section_4_walker();
 	section_4_interface();
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room405.cpp b/engines/mads/madsv2/dragonsphere/rooms/room405.cpp
index 8cfaf433578..0b7dea81c39 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room405.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room405.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
@@ -22,7 +22,9 @@
 #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/object.h"
 #include "mads/madsv2/core/sound.h"
 #include "mads/madsv2/core/text.h"
 #include "mads/madsv2/dragonsphere/mads/conv.h"
@@ -39,6 +41,37 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[15];
+	int16 sequence[15];
+	int16 animation[7];
+	int16 guard_frame;
+	int16 guard_action;
+	int16 guard_talk_count;
+	int16 anim_0_running;
+	int16 king_tent_frame;
+	int16 king_tent_action;
+	int16 king_tent_talk_count;
+	int16 anim_1_running;
+	int16 pid_tent_frame;
+	int16 pid_tent_action;
+	int16 pid_tent_talk_count;
+	int16 anim_2_running;
+	int16 shaman_2_frame;
+	int16 shaman_2_action;
+	int16 shaman_2_talk_count;
+	int16 anim_3_running;
+	int16 shaman_1_frame;
+	int16 shaman_1_action;
+	int16 shaman_1_talk_count;
+	int16 anim_4_running;
+	int16 king_sit_frame;
+	int16 king_sit_action;
+	int16 king_sit_talk_count;
+	int16 anim_5_running;
+	int16 pid_sit_frame;
+	int16 pid_sit_action;
+	int16 pid_sit_talk_count;
+	int16 anim_6_running;
 };
 
 #define local (&scratch)
@@ -46,38 +79,1353 @@ struct Scratch {
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
+#define fx_test                 0
+#define fx_test_2               1
+
+#define ROOM_405_DOOR_CLOSES    60
+#define ROOM_405_ME_TALK        65
+#define ROOM_405_YOU_TALK       67
+#define ROOM_405_GESTURE        75
+
+#define FROM_EAST_X_1           330
+#define FROM_EAST_Y_1           143
+#define FROM_EAST_X_2           302
+#define FROM_EAST_Y_2           143
+
+#define CONV_40_KING_GUARD      40
+#define CONV_44_PID_GUARD       44
+#define CONV_39_KING_SHAMAN     39
+#define CONV_43_PID_SHAMAN      43
+
+#define SHUT_UP                 0
+#define OPEN_TENT               1
+#define ARM_OUT                 2
+#define TALK                    3
+#define ENTER_TENT              4
+#define LEAVE                   5
+#define GESTURE_TO_SIT          6
+#define GIVE_WARNING            7
+#define TAKE                    8
+#define SIT                     9
+#define FLOAT                   10
+#define RISE                    11
+
+#define GUARD_X                 8
+#define GUARD_Y                 119
+#define PLAYER_X_FROM_406       17
+#define PLAYER_Y_FROM_406       124
+#define SHAMAN_X                96
+#define SHAMAN_Y                137
+
+static Scratch scratch;
+
+
+static void handle_animation_guard() {
+	int guard_reset_frame;
+
+	if (kernel_anim[aa[0]].frame != local->guard_frame) {
+		local->guard_frame = kernel_anim[aa[0]].frame;
+		guard_reset_frame = -1;
+
+		switch (local->guard_frame) {
+
+		case 31:
+			local->king_tent_action = ENTER_TENT;
+			local->pid_tent_action  = ENTER_TENT;
+			if (local->guard_action == OPEN_TENT) {
+				guard_reset_frame = 30;
+			}
+			break;
+
+		case 38:
+			new_room = 406;
+			break;
+
+		case 1:
+		case 2:
+		case 3:
+		case 4:
+		case 5:
+		case 18:
+		case 39:
+		case 40:
+		case 41:
+		case 42:
+			switch (local->guard_action) {
+			case TALK:
+				guard_reset_frame = imath_random(38, 41);
+				++ local->guard_talk_count;
+				if (local->guard_talk_count > 17) {
+					local->guard_action     = SHUT_UP;
+					local->guard_talk_count = 0;
+					guard_reset_frame       = 0;
+				}
+				break;
+
+			case SHUT_UP:
+				if (local->guard_frame >= 6) {
+					local->guard_frame = 1;
+				}
+
+				++ local->guard_talk_count;
+				if (local->guard_talk_count > imath_random(20, 30)) {
+					if (local->guard_frame == 1) {
+						guard_reset_frame = imath_random(0, 1);
+					} else if (local->guard_frame == 2) {
+						guard_reset_frame = imath_random(0, 2);
+					} else if (local->guard_frame == 3) {
+						guard_reset_frame = imath_random(1, 3);
+					} else if (local->guard_frame == 4) {
+						guard_reset_frame = imath_random(2, 4);
+					} else if (local->guard_frame == 5) {
+						guard_reset_frame = imath_random(3, 4);
+					}
+					local->guard_talk_count = 0;
+				} else {
+					guard_reset_frame = local->guard_frame - 1;
+				}
+				break;
+
+			case OPEN_TENT:
+				guard_reset_frame = 18;
+				break;
+
+			case ARM_OUT:
+				guard_reset_frame   = 7;
+				local->guard_action = SHUT_UP;
+				break;
+			}
+		}
+
+		if (guard_reset_frame >= 0) {
+			kernel_reset_animation(aa[0], guard_reset_frame);
+			local->guard_frame = guard_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_king_tent() {
+	int king_tent_reset_frame;
+
+	if (kernel_anim[aa[1]].frame != local->king_tent_frame) {
+		local->king_tent_frame = kernel_anim[aa[1]].frame;
+		king_tent_reset_frame = -1;
+
+		switch (local->king_tent_frame) {
+		case 33:
+			local->guard_action = SHUT_UP;
+			break;
+
+		case 1:
+		case 13:
+			switch (local->king_tent_action) {
+			case SHUT_UP:
+				king_tent_reset_frame = 0;
+				break;
+
+			case TALK:
+				king_tent_reset_frame   = 1;
+				local->king_tent_action = SHUT_UP;
+				break;
+
+			case ENTER_TENT:
+				king_tent_reset_frame = 19;
+				break;
+
+			case LEAVE:
+				local->anim_1_running   = false;
+				king_tent_reset_frame   = -1;
+				player.walker_visible   = true;
+				player.commands_allowed = true;
+				king_tent_reset_frame   = 19;
+				kernel_abort_animation(aa[1]);
+				kernel_synch(KERNEL_PLAYER, 0, KERNEL_NOW, 0);
+				break;
+			}
+			break;
+		}
+
+		if (king_tent_reset_frame >= 0) {
+			kernel_reset_animation(aa[1], king_tent_reset_frame);
+			local->king_tent_frame = king_tent_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_pid_tent() {
+	int pid_tent_reset_frame;
+
+	if (kernel_anim[aa[2]].frame != local->pid_tent_frame) {
+		local->pid_tent_frame = kernel_anim[aa[2]].frame;
+		pid_tent_reset_frame = -1;
+
+		switch (local->pid_tent_frame) {
+
+		case 14:
+			local->guard_action = SHUT_UP;
+			break;
+
+		case 1:
+			switch (local->pid_tent_action) {
+			case SHUT_UP:
+				pid_tent_reset_frame = 0;
+				break;
+
+			case ENTER_TENT:
+				pid_tent_reset_frame = 1;
+				break;
+
+			case LEAVE:
+				local->anim_2_running   = false;
+				pid_tent_reset_frame    = -1;
+				player.walker_visible   = true;
+				player.commands_allowed = true;
+				pid_tent_reset_frame    = 19;
+				kernel_abort_animation(aa[2]);
+				kernel_synch(KERNEL_PLAYER, 0, KERNEL_NOW, 0);
+				break;
+			}
+			break;
+		}
+
+		if (pid_tent_reset_frame >= 0) {
+			kernel_reset_animation(aa[2], pid_tent_reset_frame);
+			local->pid_tent_frame = pid_tent_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_shaman_2() {
+	int shaman_2_reset_frame;
+
+	if (kernel_anim[aa[3]].frame != local->shaman_2_frame) {
+		local->shaman_2_frame = kernel_anim[aa[3]].frame;
+		shaman_2_reset_frame = -1;
+
+		switch (local->shaman_2_frame) {
+		case 53:
+			new_room = 408;
+			break;
+
+		case 85:
+			local->pid_sit_frame    = SHUT_UP;
+			shaman_2_reset_frame    = 2;
+			kernel_reset_animation(aa[6], 16);
+			kernel_synch(KERNEL_ANIM, aa[6], KERNEL_ANIM, aa[3]);
+
+			conv_run(CONV_43_PID_SHAMAN);
+
+			if (player_has(new_bundle) && !player_has(medicine_bundle)) {
+				conv_export_value(1);
+			} else if (!player_has(new_bundle) && player_has(medicine_bundle)) {
+				conv_export_value(1);
+			} else {
+				conv_export_value(0);
+			}
+
+			if (player_has(new_bundle) && player_has(medicine_bundle)) {
+				conv_export_value(1);
+			} else {
+				conv_export_value(0);
+			}
+
+			conv_export_value(player_has(soul_egg));
+			conv_export_value(game.difficulty);
+			break;
+
+		case 1:
+		case 2:
+		case 3:
+		case 4:
+		case 11:
+			switch (local->shaman_2_action) {
+			case SHUT_UP:
+				if (local->shaman_2_frame >= 5) {
+					local->shaman_2_frame = 1;
+				}
+
+				++ local->shaman_2_talk_count;
+				if (local->shaman_2_talk_count > imath_random(15, 20)) {
+					if (local->shaman_2_frame == 1) {
+						shaman_2_reset_frame = imath_random(0, 1);
+					} else if (local->shaman_2_frame == 2) {
+						shaman_2_reset_frame = imath_random(0, 2);
+					} else if (local->shaman_2_frame == 3) {
+						shaman_2_reset_frame = imath_random(1, 3);
+					} else if (local->shaman_2_frame == 4) {
+						shaman_2_reset_frame = imath_random(2, 3);
+					}
+					local->shaman_2_talk_count = 0;
+				} else {
+					shaman_2_reset_frame = local->shaman_2_frame - 1;
+				}
+				break;
+
+			case GESTURE_TO_SIT:
+				shaman_2_reset_frame   = 10;
+				local->shaman_2_action = SHUT_UP;
+				break;
+
+			case RISE:
+				shaman_2_reset_frame = 11;
+				kernel_abort_animation(aa[6]);
+				local->anim_6_running = false;
+				kernel_synch(KERNEL_ANIM, aa[3], KERNEL_NOW, 0);
+				break;
+			}
+			break;
+		}
+
+		if (shaman_2_reset_frame >= 0) {
+			kernel_reset_animation(aa[3], shaman_2_reset_frame);
+			local->shaman_2_frame = shaman_2_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_shaman_1() {
+	int shaman_1_reset_frame;
+
+	if (kernel_anim[aa[4]].frame != local->shaman_1_frame) {
+		local->shaman_1_frame = kernel_anim[aa[4]].frame;
+		shaman_1_reset_frame = -1;
+
+		switch (local->shaman_1_frame) {
+		case 77:
+			shaman_1_reset_frame = 76;
+			break;
+
+		case 42:
+			local->king_sit_action = TAKE;
+			break;
+
+		case 43:
+			if (global[player_persona] == PLAYER_IS_PID) {
+				if (player_has(medicine_bundle)) {
+					inter_move_object(medicine_bundle, NOWHERE);
+					global[player_score] += 3;
+				} else {
+					inter_move_object(new_bundle, NOWHERE);
+					global[player_score] += 3;
+				}
+				local->pid_sit_action = SHUT_UP;
+			} else if (local->shaman_1_action == TAKE) {
+				shaman_1_reset_frame = 42;
+			}
+			break;
+
+		case 46:
+			if (global[player_persona] == PLAYER_IS_PID) {
+				local->shaman_1_action = RISE;
+				local->shaman_2_action = RISE;
+			}
+			break;
+
+		case 1:
+		case 2:
+		case 3:
+		case 4:
+		case 5:
+		case 6:
+		case 7:
+		case 17:
+		case 28:
+		case 49:
+		case 47:
+		case 104:
+			switch (local->shaman_1_action) {
+			case SHUT_UP:
+				if (local->shaman_1_frame >= 8) {
+					local->shaman_1_frame = 1;
+				}
+
+				++ local->shaman_1_talk_count;
+				if (local->shaman_1_talk_count > imath_random(12, 18)) {
+					if (local->shaman_1_frame == 1) {
+						shaman_1_reset_frame = imath_random(0, 1);
+					} else if (local->shaman_1_frame == 2) {
+						shaman_1_reset_frame = imath_random(0, 2);
+					} else if (local->shaman_1_frame == 3) {
+						shaman_1_reset_frame = imath_random(1, 3);
+					} else if (local->shaman_1_frame == 4) {
+						shaman_1_reset_frame = imath_random(2, 4);
+					} else if (local->shaman_1_frame == 5) {
+						shaman_1_reset_frame = imath_random(3, 5);
+					} else if (local->shaman_1_frame == 6) {
+						shaman_1_reset_frame = imath_random(5, 6);
+					} else if (local->shaman_1_frame == 7) {
+						shaman_1_reset_frame = imath_random(5, 6);
+					}
+					local->shaman_1_talk_count = 0;
+				} else {
+					shaman_1_reset_frame = local->shaman_1_frame - 1;
+				}
+				break;
+
+			case TALK:
+				shaman_1_reset_frame = 28;
+				break;
+
+			case GESTURE_TO_SIT:
+				shaman_1_reset_frame   = 7;
+				local->shaman_1_action = SHUT_UP;
+				break;
+
+			case GIVE_WARNING:
+				shaman_1_reset_frame   = 17;
+				local->shaman_1_action = SHUT_UP;
+				break;
+
+			case RISE:
+				shaman_1_reset_frame = 49;
+				break;
+
+			case TAKE:
+				shaman_1_reset_frame = 40;
+				break;
+			}
+			break;
+
+		case 30:
+		case 31:
+		case 32:
+		case 33:
+		case 34:
+		case 35:
+			switch (local->shaman_1_action) {
+			case TALK:
+				shaman_1_reset_frame = imath_random(29, 34);
+				++ local->shaman_1_talk_count;
+				if (local->shaman_1_talk_count > 18) {
+					local->shaman_1_action     = SHUT_UP;
+					local->shaman_1_talk_count = 0;
+					shaman_1_reset_frame       = 47;
+				}
+				break;
+
+			default:
+				shaman_1_reset_frame = 47;
+				break;
+			}
+			break;
+		}
+
+		if (shaman_1_reset_frame >= 0) {
+			kernel_reset_animation(aa[4], shaman_1_reset_frame);
+			local->shaman_1_frame = shaman_1_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_king_sit() {
+	int king_sit_reset_frame;
+
+	if (kernel_anim[aa[5]].frame != local->king_sit_frame) {
+		local->king_sit_frame = kernel_anim[aa[5]].frame;
+		king_sit_reset_frame = -1;
+
+		switch (local->king_sit_frame) {
+		case 23:
+			++ global[player_score];
+			++ global[dragon_high_scene];
+			sound_play(N_TakeObjectSnd);
+			inter_give_to_player(yellow_powerstone);
+			object_examine(yellow_powerstone, 40528, 0);
+			local->shaman_1_action = SHUT_UP;
+			local->king_sit_action = SHUT_UP;
+			break;
+
+		case 48:
+			if (local->king_sit_action == TALK) {
+				king_sit_reset_frame = 47;
+			} else {
+				king_sit_reset_frame = 0;
+			}
+			break;
+
+		case 14:
+		case 26:
+			conv_release();
+			break;
+
+		case 15:
+		case 33:
+		case 27:
+			switch (local->king_sit_action) {
+
+			case SHUT_UP:
+				king_sit_reset_frame = 14;
+				break;
+
+			case TALK:
+				king_sit_reset_frame = 27;
+				break;
+
+			case TAKE:
+				king_sit_reset_frame = 19;
+				break;
+
+			case LEAVE:
+				king_sit_reset_frame   = 33;
+				local->king_sit_action = SHUT_UP;
+				break;
+			}
+			break;
+
+		case 28:
+		case 29:
+		case 30:
+			switch (local->king_sit_action) {
+			case TALK:
+				king_sit_reset_frame = imath_random(28, 29);
+				++ local->king_sit_talk_count;
+				if (local->king_sit_talk_count > 8) {
+					local->king_sit_action     = SHUT_UP;
+					local->king_sit_talk_count = 0;
+					king_sit_reset_frame       = 30;
+				}
+				break;
+
+			default:
+				king_sit_reset_frame = 30;
+				break;
+			}
+			break;
+
+		case 47:
+			player.walker_visible   = true;
+			player.commands_allowed = true;
+			local->anim_5_running   = false;
+			kernel_abort_animation(aa[5]);
+			kernel_synch(KERNEL_PLAYER, 0, KERNEL_NOW, 0);
+			break;
+		}
+
+		if (king_sit_reset_frame >= 0) {
+			kernel_reset_animation(aa[5], king_sit_reset_frame);
+			local->king_sit_frame = king_sit_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_pid_sit() {
+	int pid_sit_reset_frame;
+
+	if (kernel_anim[aa[6]].frame != local->pid_sit_frame) {
+		local->pid_sit_frame = kernel_anim[aa[6]].frame;
+		pid_sit_reset_frame = -1;
+
+		switch (local->pid_sit_frame) {
+		case 37:
+			if (global[player_persona] == PLAYER_IS_PID) {
+				local->shaman_1_action = TAKE;
+			}
+			break;
+
+		case 38:
+			if (global[player_persona] == PLAYER_IS_KING) {
+				local->shaman_1_action = TAKE;
+			} else if (local->pid_sit_action == TAKE) {
+				pid_sit_reset_frame = 37;
+			}
+			break;
+
+		case 62:
+			pid_sit_reset_frame = 61;
+			break;
+
+		case 61:
+			if (local->pid_sit_action == TALK) {
+				pid_sit_reset_frame = 60;
+			} else {
+				pid_sit_reset_frame = 0;
+			}
+			break;
+
+		case 41:
+			conv_release();
+			break;
+
+		case 17:
+		case 27:
+		case 42:
+			switch (local->pid_sit_action) {
+
+			case SHUT_UP:
+				pid_sit_reset_frame = 16;
+				break;
+
+			case TALK:
+				pid_sit_reset_frame   = 17;
+				local->pid_sit_action = SHUT_UP;
+				break;
+
+			case TAKE:
+				pid_sit_reset_frame = 27;
+				break;
+
+			case LEAVE:
+				pid_sit_reset_frame   = 42;
+				local->pid_sit_action = SHUT_UP;
+				break;
+			}
+			break;
+
+		case 60:
+			player.walker_visible   = true;
+			player.commands_allowed = true;
+			local->anim_6_running   = false;
+			kernel_abort_animation(aa[6]);
+			kernel_synch(KERNEL_PLAYER, 0, KERNEL_NOW, 0);
+			break;
+		}
+
+		if (pid_sit_reset_frame >= 0) {
+			kernel_reset_animation(aa[6], pid_sit_reset_frame);
+			local->pid_sit_frame = pid_sit_reset_frame;
+		}
+	}
+}
 
 void room_405_init() {
+	global[perform_displacements] = true;
+
+	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;
+		local->anim_5_running = false;
+		local->anim_6_running = false;
+	}
+
+	if (global[pid_just_died] && previous_room == 406) {
+		if (!(global[object_flags] & 1)) {
+			inter_move_object(dates, 406);
+			--global[player_score];
+		}
+
+		if (!(global[object_flags] & 2)) {
+			inter_move_object(statue, 406);
+			--global[player_score];
+		}
+
+		if (!(global[object_flags] & 4)) {
+			inter_move_object(ruby_ring, 406);
+			global[player_score] += -5;
+		}
+
+		if (!(global[object_flags] & 8)) {
+			inter_move_object(bottle_of_flies, 406);
+			--global[player_score];
+		}
+
+		if (!(global[object_flags] & 16)) {
+			inter_move_object(soptus_soporific, 406);
+			--global[player_score];
+		}
+
+		global[object_flags] = 0;
+		global[pid_just_died] = false;
+		global[prizes_owed_to_player] = 0;
+		global[wins_in_desert] = global[save_wins_in_desert];
+		conv_reset(CONV_44_PID_GUARD);
+	}
+
+	if (global[player_persona] == PLAYER_IS_KING) {
+		conv_get(CONV_40_KING_GUARD);
+		conv_get(CONV_39_KING_SHAMAN);
+	} else {
+		conv_get(CONV_44_PID_GUARD);
+		conv_get(CONV_43_PID_SHAMAN);
+	}
+
+	/* guard */
+	aa[0] = kernel_run_animation(kernel_name('u', 1), 0);
+	local->anim_0_running = true;
+	local->guard_action = SHUT_UP;
+
+	/* shaman on left */
+	aa[4] = kernel_run_animation(kernel_name('s', 1), 0);
+	local->anim_4_running = true;
+	local->shaman_1_action = SHUT_UP;
+
+	/* shaman on right */
+	aa[3] = kernel_run_animation(kernel_name('s', 2), 0);
+	local->anim_3_running = true;
+	local->shaman_2_action = SHUT_UP;
 
+	if (conv_restore_running == CONV_40_KING_GUARD ||
+		conv_restore_running == CONV_44_PID_GUARD) {
+		player.walker_visible = false;
+		player.commands_allowed = false;
+		player.x = GUARD_X;
+		player.y = GUARD_Y;
+		player.facing = FACING_NORTHEAST;
+
+		if (global[player_persona] == PLAYER_IS_KING) {
+			aa[1] = kernel_run_animation(kernel_name('k', 1), 0);
+			local->anim_1_running = true;
+			local->king_tent_action = SHUT_UP;
+			conv_run(CONV_40_KING_GUARD);
+			conv_export_pointer(&global[game_points]);
+			conv_export_pointer(&global[dance_points]);
+			conv_export_pointer(&global[clue_points]);
+			conv_export_value(global[pid_talk_shamon]);
+		} else {
+			aa[2] = kernel_run_animation(kernel_name('p', 1), 0);
+			local->anim_2_running = true;
+			local->pid_tent_action = SHUT_UP;
+			conv_run(CONV_44_PID_GUARD);
+			conv_export_value(global[pid_talk_shamon]);
+		}
+
+	} else if (conv_restore_running == CONV_39_KING_SHAMAN ||
+		conv_restore_running == CONV_43_PID_SHAMAN) {
+		player.commands_allowed = false;
+		player.walker_visible = false;
+
+		if (global[player_persona] == PLAYER_IS_KING) {
+			player.x = SHAMAN_X;
+			player.y = SHAMAN_Y;
+		} else {
+			player.x = SHAMAN_X + 2;
+			player.y = SHAMAN_Y + 2;
+		}
+
+		player.facing = FACING_NORTHWEST;
+
+		if (global[player_persona] == PLAYER_IS_KING) {
+			aa[5] = kernel_run_animation(kernel_name('k', 2), 0);
+			local->anim_5_running = true;
+			local->king_sit_action = SHUT_UP;
+			kernel_reset_animation(aa[5], 15);
+
+			conv_run(CONV_39_KING_SHAMAN);
+			conv_export_value(global[talked_to_soptus]);
+			if (player_has(red_powerstone) || player_has(blue_powerstone)) {
+				conv_export_value(1);
+			} else {
+				conv_export_value(0);
+			}
+		} else {
+			aa[6] = kernel_run_animation(kernel_name('p', 2), 0);
+			local->anim_6_running = true;
+			local->pid_sit_action = SHUT_UP;
+			kernel_reset_animation(aa[6], 17);
+
+			player.commands_allowed = false;
+			conv_run(CONV_43_PID_SHAMAN);
+
+			conv_export_value(player_has(medicine_bundle));
+			conv_export_value(player_has(new_bundle));
+			conv_export_value(player_has(soul_egg));
+			conv_export_value(game.difficulty);
+		}
+
+	} else if (previous_room == 408) {
+
+		if (global[player_persona] == PLAYER_IS_KING) {
+			player.x = SHAMAN_X;
+			player.y = SHAMAN_Y;
+		} else {
+			player.x = SHAMAN_X + 2;
+			player.y = SHAMAN_Y + 2;
+		}
+
+		player.facing = FACING_NORTHWEST;
+		player.commands_allowed = false;
+		player.walker_visible = false;
+
+		kernel_reset_animation(aa[4], 78);
+		kernel_reset_animation(aa[3], 54);
+
+		aa[6] = kernel_run_animation(kernel_name('p', 2), 0);
+		local->anim_6_running = true;
+		kernel_reset_animation(aa[6], 62);
+
+	} else if (previous_room == 406) {
+		player.x = PLAYER_X_FROM_406;
+		player.y = PLAYER_Y_FROM_406;
+		player.facing = FACING_SOUTHEAST;
+
+	} else if (previous_room != KERNEL_RESTORING_GAME) {
+		player_first_walk(FROM_EAST_X_1, FROM_EAST_Y_1, FACING_WEST,
+			FROM_EAST_X_2, FROM_EAST_Y_2, FACING_WEST, true);
+	}
+
+	section_4_music();
+}
+
+static void room_405_daemon() {
+	if (local->anim_0_running) {
+		handle_animation_guard();
+	}
+
+	if (local->anim_1_running) {
+		handle_animation_king_tent();
+	}
+
+	if (local->anim_2_running) {
+		handle_animation_pid_tent();
+	}
+
+	if (local->anim_3_running) {
+		handle_animation_shaman_2();
+	}
+
+	if (local->anim_4_running) {
+		handle_animation_shaman_1();
+	}
+
+	if (local->anim_5_running) {
+		handle_animation_king_sit();
+	}
+
+	if (local->anim_6_running) {
+		handle_animation_pid_sit();
+	}
+}
+
+static void process_conv_king_shaman() {
+	int you_trig_flag  = false;
+	int me_trig_flag   = false;
+
+	if (player_verb == conv039_greeting_only) {
+		if (!kernel.trigger) {
+			conv_you_trigger(ROOM_405_GESTURE);
+		}
+		me_trig_flag  = true;
+		you_trig_flag = true;
+	}
+
+	if (player_verb == conv039_choices_b_b) {
+		local->king_sit_action = SHUT_UP;
+		you_trig_flag          = true;
+		me_trig_flag           = true;
+		conv_hold();
+	}
+
+	if (player_verb == conv039_gift_b_b) {
+		local->shaman_1_action = TAKE;
+		you_trig_flag          = true;
+		me_trig_flag           = true;
+		conv_hold();
+	}
+
+	if (player_verb == conv039_exit_b_b || player_verb == conv039_exit_d_d) {
+		local->king_sit_action = LEAVE;
+		you_trig_flag          = true;
+		me_trig_flag           = true;
+	}
+
+	if (player_verb == conv039_pre_addon_b_b) {
+		local->king_sit_action = SHUT_UP;
+		you_trig_flag          = true;
+		me_trig_flag           = true;
+		conv_hold();
+	}
+
+	if (kernel.trigger == ROOM_405_GESTURE) {
+		local->shaman_1_action = GESTURE_TO_SIT;
+		local->shaman_2_action = GESTURE_TO_SIT;
+	}
+
+	if (kernel.trigger == ROOM_405_YOU_TALK) {
+		local->shaman_1_action = TALK;
+		if (local->king_sit_action != LEAVE) {
+			local->king_sit_action = SHUT_UP;
+		}
+	}
+
+	if (kernel.trigger == ROOM_405_ME_TALK) {
+		local->shaman_1_action = SHUT_UP;
+		if (local->king_sit_action != LEAVE) {
+			local->king_sit_action = TALK;
+		}
+	}
+
+	if (!you_trig_flag) {
+		conv_you_trigger(ROOM_405_YOU_TALK);
+	}
+
+	if (!me_trig_flag) {
+		conv_me_trigger(ROOM_405_ME_TALK);
+	}
+
+	local->shaman_1_talk_count = 0;
+	local->king_sit_talk_count = 0;
+}
+
+static void process_conv_pid_shaman() {
+	int you_trig_flag  = false;
+	int me_trig_flag   = false;
+
+	if (player_verb == conv043_rise_b_b) {
+		*conv_my_next_start = conv043_homenow;
+		conv_abort();
+		local->shaman_1_action = RISE;
+		local->shaman_2_action = RISE;
+		me_trig_flag           = true;
+		you_trig_flag          = true;
+	}
+
+	if (player_verb == conv043_rise_d_d) {
+		*conv_my_next_start = conv043_homenow;
+		conv_abort();
+		local->pid_sit_action = TAKE;
+		me_trig_flag          = true;
+		you_trig_flag         = true;
+	}
+
+	if (player_verb == conv043_exit_b_b) {
+		*conv_my_next_start = conv043_greeting;
+		conv_abort();
+		local->pid_sit_action = LEAVE;
+		you_trig_flag         = true;
+		me_trig_flag          = true;
+	}
+
+	if (player_verb == conv043_exit_d_d) {
+		*conv_my_next_start = conv043_restart;
+		conv_abort();
+		local->pid_sit_action = LEAVE;
+		you_trig_flag         = true;
+		me_trig_flag          = true;
+	}
+
+	if (kernel.trigger == ROOM_405_YOU_TALK) {
+		if (local->shaman_1_action != RISE) {
+			local->shaman_1_action = TALK;
+		}
+
+		if (local->pid_sit_action != LEAVE &&
+		    local->pid_sit_action != TAKE) {
+			local->pid_sit_action = SHUT_UP;
+		}
+	}
+
+	if (kernel.trigger == ROOM_405_ME_TALK) {
+		if (local->shaman_1_action != RISE) {
+			local->shaman_1_action = SHUT_UP;
+		}
+
+		if (local->pid_sit_action != LEAVE &&
+		    local->pid_sit_action != TAKE) {
+			local->pid_sit_action = TALK;
+		}
+	}
+
+	if (!you_trig_flag) {
+		conv_you_trigger(ROOM_405_YOU_TALK);
+	}
+
+	if (!me_trig_flag) {
+		conv_me_trigger(ROOM_405_ME_TALK);
+	}
+
+	local->shaman_1_talk_count = 0;
+	local->pid_sit_talk_count  = 0;
+}
+
+static void process_conv_king_guard() {
+	int you_trig_flag  = false;
+	int me_trig_flag   = false;
+
+	switch (player_verb) {
+	case conv040_leave_b_b:
+		*conv_my_next_start     = conv040_repeater;
+		local->king_tent_action = LEAVE;
+		you_trig_flag           = true;
+		me_trig_flag            = true;
+		conv_abort();
+		break;
+
+	case conv040_enter_b_b:
+		*conv_my_next_start = conv040_repeater;
+		local->guard_action = OPEN_TENT;
+		you_trig_flag       = true;
+		me_trig_flag        = true;
+		conv_abort();
+		break;
+	}
+
+	if (kernel.trigger == ROOM_405_YOU_TALK) {
+		local->guard_action     = TALK;
+		local->king_tent_action = SHUT_UP;
+	}
+
+	if (kernel.trigger == ROOM_405_ME_TALK) {
+		local->guard_action     = SHUT_UP;
+		local->king_tent_action = TALK;
+	}
+
+	if (!you_trig_flag) {
+		conv_you_trigger(ROOM_405_YOU_TALK);
+	}
+
+	if (!me_trig_flag) {
+		conv_me_trigger(ROOM_405_ME_TALK);
+	}
+
+	local->guard_talk_count     = 0;
+	local->king_tent_talk_count = 0;
 }
 
-void room_405_daemon() {
+static void process_conv_pid_guard() {
+	int you_trig_flag  = false;
+	int me_trig_flag   = false;
+
+	switch (player_verb) {
+	case conv044_leave_b_b:
+		*conv_my_next_start = conv044_greet;
+		conv_abort();
+		local->pid_tent_action = LEAVE;
+		you_trig_flag = true;
+		me_trig_flag  = true;
+		break;
+
+	case conv044_enter_b_b:
+		*conv_my_next_start = conv044_repeater;
+		conv_abort();
+		local->guard_action = OPEN_TENT;
+		you_trig_flag = true;
+		me_trig_flag  = true;
+		break;
+	}
 
+	if (kernel.trigger == ROOM_405_YOU_TALK) {
+		local->guard_action = TALK;
+	}
+
+	if (kernel.trigger == ROOM_405_ME_TALK) {
+		local->guard_action = SHUT_UP;
+	}
+
+	if (!you_trig_flag) {
+		conv_you_trigger(ROOM_405_YOU_TALK);
+	}
+
+	if (!me_trig_flag) {
+		conv_me_trigger(ROOM_405_ME_TALK);
+	}
+
+	local->guard_talk_count = 0;
 }
 
-void room_405_pre_parser() {
+static void room_405_pre_parser() {
+	if (player_said_1(cross)) {
+		global[from_direction]       = FROM_WEST;
+		global[desert_room]          = 42;
+		player.walk_off_edge_to_room = 401;
+	}
 
+	if (player_said_2(talk_to, shaman) ||
+	    player_said_3(give, spirit_bundle, shaman) ||
+	    player_said_3(give, new_bundle, shaman)) {
+		if (global[player_persona] == PLAYER_IS_PID) {
+			player_walk(SHAMAN_X + 2, SHAMAN_Y + 2, FACING_NORTHWEST);
+		}
+	}
 }
 
-void room_405_parser() {
+static void room_405_parser() {
+	if (conv_control.running == CONV_40_KING_GUARD) {
+		process_conv_king_guard();
+		goto handled;
+	}
+
+	if (conv_control.running == CONV_44_PID_GUARD) {
+		process_conv_pid_guard();
+		goto handled;
+	}
+
+	if (conv_control.running == CONV_39_KING_SHAMAN) {
+		process_conv_king_shaman();
+		goto handled;
+	}
+
+	if (conv_control.running == CONV_43_PID_SHAMAN) {
+		process_conv_pid_shaman();
+		goto handled;
+	}
+
+	if (player_said_2(talk_to, shaman) ||
+	    player_said_3(give, spirit_bundle, shaman) ||
+	    player_said_3(give, new_bundle, shaman)) {
+
+		global[pid_talk_shamon] = true;
+
+		if (global[player_persona] == PLAYER_IS_KING) {
+			local->king_sit_frame   = -1;
+			aa[5]                   = kernel_run_animation(kernel_name('k', 2), 0);
+			local->anim_5_running   = true;
+			local->king_sit_action  = TALK;
+			player.walker_visible   = false;
+			player.commands_allowed = false;
+			kernel_reset_animation(aa[5], 48);
+			kernel_synch(KERNEL_ANIM, aa[5], KERNEL_PLAYER, 0);
+
+			conv_run(CONV_39_KING_SHAMAN);
+			conv_export_value(global[talked_to_soptus]);
+			if (player_has(red_powerstone) || player_has(blue_powerstone)) {
+				conv_export_value(1);
+			} else {
+				conv_export_value(0);
+			}
+		} else {
+			aa[6]                   = kernel_run_animation(kernel_name('p', 2), 0);
+			local->anim_6_running   = true;
+			local->pid_sit_action   = SHUT_UP;
+			player.walker_visible   = false;
+			player.commands_allowed = false;
+			kernel_synch(KERNEL_ANIM, aa[6], KERNEL_PLAYER, 0);
+
+			conv_run(CONV_43_PID_SHAMAN);
+
+			conv_export_value(player_has(medicine_bundle));
+			conv_export_value(player_has(new_bundle));
+			conv_export_value(player_has(soul_egg));
+			conv_export_value(game.difficulty);
+		}
+		goto handled;
+	}
+
+	if (player_said_2(walk_into, tent) ||
+	    player_said_2(talk_to, guard)) {
+		player.walker_visible   = false;
+		player.commands_allowed = false;
+
+		if (global[player_persona] == PLAYER_IS_KING) {
+			aa[1]                   = kernel_run_animation(kernel_name('k', 1), 0);
+			local->anim_1_running   = true;
+			local->king_tent_action = SHUT_UP;
+			kernel_synch(KERNEL_ANIM, aa[1], KERNEL_PLAYER, 0);
+
+			conv_run(CONV_40_KING_GUARD);
+			conv_export_pointer(&global[game_points]);
+			conv_export_pointer(&global[dance_points]);
+			conv_export_pointer(&global[clue_points]);
+			conv_export_value(global[pid_talk_shamon]);
+		} else {
+			aa[2]                   = kernel_run_animation(kernel_name('p', 1), 0);
+			local->anim_2_running   = true;
+			local->pid_tent_action  = SHUT_UP;
+			kernel_synch(KERNEL_ANIM, aa[2], KERNEL_PLAYER, 0);
+			conv_run(CONV_44_PID_GUARD);
+			conv_export_value(global[pid_talk_shamon]);
+		}
+		local->guard_action = ARM_OUT;
+		goto handled;
+	}
+
+	if (player_said_1(cross)) {
+		text_show(40517);
+		global[from_direction] = FROM_WEST;
+		global[desert_room]    = 42;
+		new_room               = 401;
+		goto handled;
+	}
+
+	if (player.look_around) {
+		text_show(40501);
+		goto handled;
+	}
+
+	if (player_said_1(look) || player_said_1(look_at)) {
+
+		if (player_said_1(tent)) {
+			text_show(40502);
+			goto handled;
+		}
 
+		if (player_said_1(palm_tree)) {
+			text_show(40505);
+			goto handled;
+		}
+
+		if (player_said_1(oasis)) {
+			text_show(40507);
+			goto handled;
+		}
+
+		if (player_said_1(sand)) {
+			text_show(40508);
+			goto handled;
+		}
+
+		if (player_said_1(moon)) {
+			text_show(40511);
+			goto handled;
+		}
+
+		if (player_said_1(pool)) {
+			text_show(40513);
+			goto handled;
+		}
+
+		if (player_said_1(desert_to_east)) {
+			text_show(40516);
+			goto handled;
+		}
+
+		if (player_said_1(desert_sky)) {
+			text_show(40518);
+			goto handled;
+		}
+
+		if (player_said_1(guard)) {
+			text_show(40523);
+			goto handled;
+		}
+
+		if (player_said_1(shaman)) {
+			if (global[player_persona] == PLAYER_IS_PID) {
+				text_show(40527);
+			} else if (global[talked_to_soptus]) {
+				text_show(40519);
+			} else {
+				text_show(40520);
+			}
+			goto handled;
+		}
+	}
+
+	if (player_said_2(open, tent)) {
+		text_show(40503);
+		goto handled;
+	}
+
+	if (player_said_2(take, pool) || player_said_3(fill, goblet, pool)) {
+		text_show(40514);
+		goto handled;
+	}
+
+	if (player_said_2(push, tent) || player_said_2(pull, tent)) {
+		text_show(40504);
+		goto handled;
+	}
+
+	if (player_said_2(push, palm_tree) || player_said_2(pull, palm_tree)) {
+		text_show(40506);
+		goto handled;
+	}
+
+	if (player_said_2(take, moon) || player_said_2(pull, moon)) {
+		text_show(40512);
+		goto handled;
+	}
+
+	if (player_said_2(push, guard) || player_said_2(throw, guard)) {
+		text_show(40524);
+		goto handled;
+	}
+
+	if (player_said_2(sword, attack) ||
+	    player_said_2(sword, carve_up) ||
+	    player_said_2(sword, thrust)) {
+		if (player_said_1(guard)) {
+			text_show(40525);
+			goto handled;
+		}
+	}
+
+	if (player_said_3(give, partial_bundle, shaman)) {
+		text_show(40526);
+		goto handled;
+	}
+
+	if (player_said_2(take, sand)) {
+		text_show(40509);
+		goto handled;
+	}
+
+	if (player_said_2(throw, sand)) {
+		text_show(40510);
+		goto handled;
+	}
+
+	if (player_said_2(push, shaman)) {
+		text_show(40521);
+		goto handled;
+	}
+
+	if (player_said_2(give, shaman)) {
+		if (player_said_1(partly_built_bundle)) {
+			text_show(40526);
+			goto handled;
+		} else if (player_has(object_named(player_main_noun))) {
+			text_show(40522);
+			goto handled;
+		}
+	}
+
+	if (player_said_2(put, pool) ||
+	    player_said_2(throw, pool) ||
+	    player_said_2(pour_contents_of, pool)) {
+		text_show(40515);
+		goto handled;
+	}
+
+	goto done;
+
+handled:
+	player.command_ready = false;
+
+done:
+	;
 }
 
 void room_405_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.guard_frame);
+	s.syncAsSint16LE(scratch.guard_action);
+	s.syncAsSint16LE(scratch.guard_talk_count);
+	s.syncAsSint16LE(scratch.anim_0_running);
+	s.syncAsSint16LE(scratch.king_tent_frame);
+	s.syncAsSint16LE(scratch.king_tent_action);
+	s.syncAsSint16LE(scratch.king_tent_talk_count);
+	s.syncAsSint16LE(scratch.anim_1_running);
+	s.syncAsSint16LE(scratch.pid_tent_frame);
+	s.syncAsSint16LE(scratch.pid_tent_action);
+	s.syncAsSint16LE(scratch.pid_tent_talk_count);
+	s.syncAsSint16LE(scratch.anim_2_running);
+	s.syncAsSint16LE(scratch.shaman_2_frame);
+	s.syncAsSint16LE(scratch.shaman_2_action);
+	s.syncAsSint16LE(scratch.shaman_2_talk_count);
+	s.syncAsSint16LE(scratch.anim_3_running);
+	s.syncAsSint16LE(scratch.shaman_1_frame);
+	s.syncAsSint16LE(scratch.shaman_1_action);
+	s.syncAsSint16LE(scratch.shaman_1_talk_count);
+	s.syncAsSint16LE(scratch.anim_4_running);
+	s.syncAsSint16LE(scratch.king_sit_frame);
+	s.syncAsSint16LE(scratch.king_sit_action);
+	s.syncAsSint16LE(scratch.king_sit_talk_count);
+	s.syncAsSint16LE(scratch.anim_5_running);
+	s.syncAsSint16LE(scratch.pid_sit_frame);
+	s.syncAsSint16LE(scratch.pid_sit_action);
+	s.syncAsSint16LE(scratch.pid_sit_talk_count);
+	s.syncAsSint16LE(scratch.anim_6_running);
 }
 
 void room_405_preload() {
-	room_init_code_pointer = room_405_init;
+	room_init_code_pointer       = room_405_init;
 	room_pre_parser_code_pointer = room_405_pre_parser;
-	room_parser_code_pointer = room_405_parser;
-	room_daemon_code_pointer = room_405_daemon;
+	room_parser_code_pointer     = room_405_parser;
+	room_daemon_code_pointer     = room_405_daemon;
+
+	global[no_load_walker] = false;
 
 	section_4_walker();
 	section_4_interface();
 }
 
+void room_405_error() {
+}
+
 } // namespace Rooms
 } // namespace Dragonsphere
 } // namespace MADSV2
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room406.cpp b/engines/mads/madsv2/dragonsphere/rooms/room406.cpp
index a869ea7db90..ca62d226928 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room406.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room406.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,11 +19,16 @@
  *
  */
 
+#include "mads/madsv2/core/camera.h"
 #include "mads/madsv2/core/conv.h"
 #include "mads/madsv2/core/game.h"
 #include "mads/madsv2/core/imath.h"
+#include "mads/madsv2/core/inter.h"
 #include "mads/madsv2/core/kernel.h"
+#include "mads/madsv2/core/matte.h"
+#include "mads/madsv2/core/object.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"
@@ -39,6 +44,54 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[15];
+	int16 sequence[15];
+	int16 animation[7];
+	int16 king_frame;
+	int16 king_action;
+	int16 king_talk_count;
+	int16 anim_0_running;
+	int16 pid_frame;
+	int16 pid_action;
+	int16 pid_talk_count;
+	int16 anim_1_running;
+	int16 cal_frame;
+	int16 cal_action;
+	int16 cal_talk_count;
+	int16 anim_2_running;
+	int16 king_walk_frame;
+	int16 king_walk_action;
+	int16 king_walk_talk_count;
+	int16 anim_3_running;
+	int16 pid_walk_frame;
+	int16 pid_walk_action;
+	int16 pid_walk_talk_count;
+	int16 anim_4_running;
+	int16 belly_before_frame;
+	int16 belly_before_talk_count;
+	int16 anim_5_running;
+	int16 belly_after_frame;
+	int16 anim_6_running;
+	int16 half_bottle_base;
+	int16 dyn_half_bottle;
+	int16 two_bottles_base;
+	int16 dyn_two_bottles;
+	int16 thing_1_base;
+	int16 dyn_thing_1;
+	int16 thing_2_base;
+	int16 dyn_thing_2;
+	int16 thing_3_base;
+	int16 dyn_thing_3;
+	int16 pole_base;
+	int16 dyn_pole;
+	int16 mount_x;
+	int16 mount_2_x;
+	int16 num_of_stuff;
+	int16 won_sop;
+	int16 clock;
+	int16 death_timer;
+	int16 activate_timer;
+	int16 panning;
 };
 
 #define local (&scratch)
@@ -46,38 +99,1471 @@ struct Scratch {
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
+#define fx_half_bottle          0
+#define fx_two_bottles          1
+#define fx_thing_1              2
+#define fx_thing_2              3
+#define fx_thing_3              4
+#define fx_pole                 5
+#define fx_mount                6
+#define fx_mount_2              7
+#define fx_smoke                8
+#define fx_cup                  9
 
-void room_406_init() {
+#define ROOM_406_ME_TALK        60
+#define ROOM_406_YOU_TALK       62
+#define ROOM_406_CUP            65
 
+#define FREEZE                  0
+#define CLAP                    1
+#define BELT                    2
+#define GIVE                    3
+#define LOOK_GIRL               4
+#define TALK                    5
+#define GET_UP                  6
+#define DIE                     7
+#define GET_DOLL                8
+#define TAKE_DRINK              9
+#define PLEASE_SIT              10
+#define DRINK                   11
+#define POST_DRINK              12
+#define LOOK_GIRL_2             13
+
+#define camera_ratio_1          1
+#define camera_ratio_2          2
+
+#define CONV_41_KING            41
+#define CONV_45_PID             45
+
+#define LENGTH_OF_LIFE          850
+
+#define PANNING_TO_DANCE        1
+#define PANNING_AWAY_FROM_DANCE 2
+
+static Scratch scratch;
+
+
+static void set_406_mount_position() {
+	int difference;
+	int x;
+
+	difference = ((picture_view_x) * 4) / 7;
+	x = local->mount_x + difference;
+	x += 1;
+
+	kernel_seq_delete(seq[fx_mount]);
+	seq[fx_mount] = kernel_seq_stamp(ss[fx_mount], false, 1);
+	kernel_seq_loc(seq[fx_mount], x, 90);
+	kernel_seq_depth(seq[fx_mount], 12);
+}
+
+static void set_406_mount_2_position() {
+	int difference;
+	int x;
+
+	difference = ((picture_view_x) * 4) / 7;
+	x = local->mount_2_x + difference;
+	x += 1;
+
+	kernel_seq_delete(seq[fx_mount_2]);
+	seq[fx_mount_2] = kernel_seq_stamp(ss[fx_mount], true, 1);
+	kernel_seq_loc(seq[fx_mount_2], x, 91);
+	kernel_seq_depth(seq[fx_mount_2], 12);
+}
+
+static void set_half_bottle_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_half_bottle] >= 0) {
+		kernel_seq_delete(seq[fx_half_bottle]);
+	}
+
+	difference = center - local->half_bottle_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->half_bottle_base + displace - 1;
+	xs         = series_list[ss[fx_half_bottle]]->index[0].xs;
+
+	if (((x - ((xs >> 1) + 1)) >= (picture_view_x + video_x)) ||
+	    ((x + ((xs >> 1) + 1)) < picture_view_x)) {
+		seq[fx_half_bottle] = -1;
+	} else {
+		seq[fx_half_bottle] = kernel_seq_stamp(ss[fx_half_bottle], false, 1);
+		kernel_seq_loc(seq[fx_half_bottle], x, 155);
+		kernel_seq_depth(seq[fx_half_bottle], 1);
+	}
+}
+
+static void set_two_bottles_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_two_bottles] >= 0) {
+		kernel_seq_delete(seq[fx_two_bottles]);
+	}
+
+	difference = center - local->two_bottles_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->two_bottles_base + displace - 1;
+	xs         = series_list[ss[fx_two_bottles]]->index[0].xs;
+
+	if (((x - ((xs >> 1) + 1)) >= (picture_view_x + video_x)) ||
+	    ((x + ((xs >> 1) + 1)) < picture_view_x)) {
+		seq[fx_two_bottles] = -1;
+	} else {
+		seq[fx_two_bottles] = kernel_seq_stamp(ss[fx_two_bottles], false, 1);
+		kernel_seq_loc(seq[fx_two_bottles], x, 155);
+		kernel_seq_depth(seq[fx_two_bottles], 1);
+	}
+}
+
+static void set_thing_1_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_thing_1] >= 0) {
+		kernel_seq_delete(seq[fx_thing_1]);
+	}
+
+	difference = center - local->thing_1_base;
+	direction  = neg(sgn(difference));
+	distance   = abs(difference);
+
+	displace   = (int)(((long)distance * camera_ratio_1) / 6);
+	displace   = sgn_in(displace, direction);
+
+	x          = local->thing_1_base + displace - 1;
+	xs         = series_list[ss[fx_thing_1]]->index[0].xs;
+
+	if (((x - ((xs >> 1) + 1)) >= (picture_view_x + video_x)) ||
+	    ((x + ((xs >> 1) + 1)) < picture_view_x)) {
+		seq[fx_thing_1] = -1;
+	} else {
+		seq[fx_thing_1] = kernel_seq_stamp(ss[fx_thing_1], false, 1);
+		kernel_seq_loc(seq[fx_thing_1], x, 45);
+		kernel_seq_depth(seq[fx_thing_1], 1);
+	}
+}
+
+static void set_thing_2_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_thing_2] >= 0) {
+		kernel_seq_delete(seq[fx_thing_2]);
+	}
+
+	difference = center - local->thing_2_base;
+	direction  = neg(sgn(difference));
+	distance   = abs(difference);
+
+	displace   = (int)(((long)distance * camera_ratio_1) / 3);
+	displace   = sgn_in(displace, direction);
+
+	x          = local->thing_2_base + displace - 1;
+	xs         = series_list[ss[fx_thing_2]]->index[0].xs;
+
+	if (((x - ((xs >> 1) + 1)) >= (picture_view_x + video_x)) ||
+	    ((x + ((xs >> 1) + 1)) < picture_view_x)) {
+		seq[fx_thing_2] = -1;
+	} else {
+		seq[fx_thing_2] = kernel_seq_stamp(ss[fx_thing_2], false, 1);
+		kernel_seq_loc(seq[fx_thing_2], x, 61);
+		kernel_seq_depth(seq[fx_thing_2], 1);
+	}
+}
+
+static void set_thing_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_thing_3] >= 0) {
+		kernel_seq_delete(seq[fx_thing_3]);
+	}
+
+	difference = center - local->thing_3_base;
+	direction  = neg(sgn(difference));
+	distance   = abs(difference);
+
+	displace   = (int)(((long)distance * camera_ratio_1) / 4);
+	displace   = sgn_in(displace, direction);
+
+	x          = local->thing_3_base + displace - 1;
+	xs         = series_list[ss[fx_thing_3]]->index[0].xs;
+
+	if (((x - ((xs >> 1) + 1)) >= (picture_view_x + video_x)) ||
+	    ((x + ((xs >> 1) + 1)) < picture_view_x)) {
+		seq[fx_thing_3] = -1;
+	} else {
+		seq[fx_thing_3] = kernel_seq_stamp(ss[fx_thing_3], false, 1);
+		kernel_seq_loc(seq[fx_thing_3], x, 86);
+		kernel_seq_depth(seq[fx_thing_3], 1);
+	}
+}
+
+static void set_pole_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_pole] >= 0) {
+		kernel_seq_delete(seq[fx_pole]);
+	}
+
+	difference = center - local->pole_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->pole_base + displace - 1;
+	xs         = series_list[ss[fx_pole]]->index[0].xs;
+
+	if (((x - ((xs >> 1) + 1)) >= (picture_view_x + video_x)) ||
+	    ((x + ((xs >> 1) + 1)) < picture_view_x)) {
+		seq[fx_pole] = -1;
+	} else {
+		seq[fx_pole] = kernel_seq_stamp(ss[fx_pole], false, 1);
+		kernel_seq_loc(seq[fx_pole], x, 155);
+		kernel_seq_depth(seq[fx_pole], 1);
+	}
+}
+
+static void handle_animation_king() {
+	int king_reset_frame;
+	int count;
+
+	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 19:
+		case 53:
+			conv_run(CONV_41_KING);
+			conv_export_pointer(&global[dance_points]);
+			conv_export_pointer(&global[game_points]);
+			conv_export_pointer(&global[clue_points]);
+			conv_export_value(global[talked_to_soptus]);
+			conv_export_value(global[pid_talk_shamon]);
+			conv_export_value(local->num_of_stuff);
+			conv_export_value(global[prizes_owed_to_player]);
+			break;
+
+		case 47:
+			for (count = 1; count <= global[prizes_owed_to_player]; count ++) {
+				if (object_is_here(dates)) {
+					sound_play(N_TakeObjectSnd);
+					inter_give_to_player(dates);
+					object_examine(dates, 814, 0);
+					++ global[dragon_high_scene];
+					++ global[player_score];
+				} else if (object_is_here(statue)) {
+					sound_play(N_TakeObjectSnd);
+					inter_give_to_player(statue);
+					object_examine(statue, 815, 0);
+					++ global[player_score];
+				} else if (object_is_here(ruby_ring)) {
+					sound_play(N_TakeObjectSnd);
+					inter_give_to_player(ruby_ring);
+					object_examine(ruby_ring, 841, 0);
+					global[player_score] += 5;
+				}
+			}
+			local->cal_action             = FREEZE;
+			global[prizes_owed_to_player] = 0;
+			break;
+
+		case 56:
+			if (local->king_action == LOOK_GIRL) {
+				global[dance_music_on] = true;
+				camera_pan_to(&camera_x, 160);
+				local->panning = PANNING_TO_DANCE;
+				if (local->belly_before_talk_count != 0) {
+					kernel_abort_animation(aa[5]);
+					aa[6]                 = kernel_run_animation(kernel_name('d', 2), 0);
+					local->anim_5_running = false;
+					local->anim_6_running = true;
+				}
+			}
+			break;
+
+		case 57:
+			if (local->king_action == LOOK_GIRL ||
+			    local->king_action == LOOK_GIRL_2) {
+				king_reset_frame = 56;
+			}
+			break;
+
+		case 43:
+			kernel_abort_animation(aa[0]);
+			local->anim_0_running = false;
+			local->anim_3_running = true;
+			aa[3]                 = kernel_run_animation(kernel_name('k', 2), 0);
+			kernel_synch(KERNEL_ANIM, aa[3], KERNEL_NOW, 0);
+			kernel_reset_animation(aa[3], 75);
+			break;
+
+		case 20:
+		case 71:
+		case 66:
+		case 55:
+		case 54:
+			switch (local->king_action) {
+			case FREEZE:
+				king_reset_frame = 54;
+				break;
+
+			case LOOK_GIRL:
+			case LOOK_GIRL_2:
+				king_reset_frame   = 55;
+				break;
+
+			case GIVE:
+				king_reset_frame   = 43;
+				local->king_action = FREEZE;
+				break;
+
+			case TALK:
+				king_reset_frame   = 66;
+				local->king_action = FREEZE;
+				break;
+
+			case GET_UP:
+				king_reset_frame   = 21;
+				local->king_action = FREEZE;
+				break;
+			}
+			break;
+		}
+
+		if (king_reset_frame >= 0) {
+			kernel_reset_animation(aa[0], king_reset_frame);
+			local->king_frame = king_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_pid() {
+	int pid_reset_frame;
+	int count;
+
+	if (kernel_anim[aa[1]].frame != local->pid_frame) {
+		local->pid_frame = kernel_anim[aa[1]].frame;
+		pid_reset_frame = -1;
+
+		switch (local->pid_frame) {
+		case 21:
+		case 47:
+			conv_run(CONV_45_PID);
+			conv_export_pointer(&global[pid_has_been_healed_sop]);
+			conv_export_value(local->won_sop);
+			conv_export_value(global[prizes_owed_to_player]);
+			break;
+
+		case 61:
+		case 78:
+			conv_release();
+			break;
+
+		case 39:
+			for (count = 1; count <= global[prizes_owed_to_player]; count ++) {
+				if (object_is_here(dates)) {
+					sound_play(N_TakeObjectSnd);
+					inter_give_to_player(dates);
+					object_examine(dates, 814, 0);
+					++ global[player_score];
+				} else if (object_is_here(statue)) {
+					sound_play(N_TakeObjectSnd);
+					inter_give_to_player(statue);
+					object_examine(statue, 815, 0);
+					++ global[player_score];
+				} else if (object_is_here(ruby_ring)) {
+					sound_play(N_TakeObjectSnd);
+					inter_give_to_player(ruby_ring);
+					object_examine(ruby_ring, 841, 0);
+					global[player_score] += 5;
+				} else if (object_is_here(bottle_of_flies)) {
+					sound_play(N_TakeObjectSnd);
+					inter_give_to_player(bottle_of_flies);
+					object_examine(bottle_of_flies, 816, 0);
+					++ global[player_score];
+				} else if (object_is_here(soptus_soporific)) {
+					sound_play(N_TakeObjectSnd);
+					inter_give_to_player(soptus_soporific);
+					object_examine(soptus_soporific, 831, 0);
+					++ global[player_score];
+				}
+			}
+			local->cal_action             = FREEZE;
+			global[prizes_owed_to_player] = 0;
+			break;
+
+		case 56:
+			conv_release();
+			break;
+
+		case 57:
+			if (local->pid_action == TAKE_DRINK) {
+				pid_reset_frame = 56;
+			}
+			break;
+
+		case 127:
+			kernel_abort_animation(aa[1]);
+			local->anim_1_running = false;
+			local->anim_4_running = true;
+			aa[4]                 = kernel_run_animation(kernel_name('p', 2), 0);
+			kernel_synch(KERNEL_ANIM, aa[4], KERNEL_NOW, 0);
+			kernel_reset_animation(aa[4], 77);
+			break;
+
+		case 54:
+			local->cal_action = FREEZE;
+			break;
+
+		case 62:
+			if (local->pid_action == DRINK) {
+				pid_reset_frame = 61;
+			}
+			break;
+
+		case 70:
+			seq[fx_cup] = kernel_seq_forward(ss[fx_cup], false, 6, 0, 0, 1);
+			kernel_seq_depth(seq[fx_cup], 1);
+			kernel_seq_range(seq[fx_cup], KERNEL_FIRST, KERNEL_LAST);
+			kernel_seq_trigger(seq[fx_cup], KERNEL_TRIGGER_EXPIRE, 0, ROOM_406_CUP);
+			kernel_synch(KERNEL_SERIES, seq[fx_cup], KERNEL_ANIM, aa[1]);
+			break;
+
+		case 79:
+			switch (local->pid_action) {
+			case GET_DOLL:
+				pid_reset_frame = 79;
+				break;
+
+			case DIE:
+				pid_reset_frame = 90;
+				break;
+
+			case POST_DRINK:
+			default:
+				pid_reset_frame = 78;
+				break;
+			}
+			break;
+
+		case 94:
+			global_speech_go(6);
+			break;
+
+		case 104:
+			sound_play(N_PlayerDies);
+			text_show(40615);
+			conv_reset(CONV_45_PID);
+			global[pid_just_died] = true;
+			new_room              = 405;
+			break;
+
+		case 89:
+			conv_run(CONV_45_PID);
+			conv_export_pointer(&global[pid_has_been_healed_sop]);
+			conv_export_value(1);
+			conv_export_value(global[prizes_owed_to_player]);
+			break;
+
+		case 85:
+			pid_reset_frame = 127;
+			break;
+
+		case 140:
+			text_show(40614);
+			pid_reset_frame = 85;
+			break;
+
+		case 22:
+		case 32:
+		case 23:
+		case 48:
+		case 90:
+			switch (local->pid_action) {
+			case FREEZE:
+				pid_reset_frame = 22;
+				break;
+
+			case TAKE_DRINK:
+				pid_reset_frame = 48;
+				break;
+
+			case GET_DOLL:
+				pid_reset_frame   = 79;
+				local->pid_action = FREEZE;
+				break;
+
+			case GIVE:
+				pid_reset_frame   = 32;
+				local->pid_action = FREEZE;
+				break;
+
+			case TALK:
+				pid_reset_frame   = 23;
+				local->pid_action = FREEZE;
+				break;
+
+			case DIE:
+				pid_reset_frame   = 90;
+				local->pid_action = FREEZE;
+				break;
+
+			case GET_UP:
+				pid_reset_frame   = 104;
+				local->pid_action = FREEZE;
+				break;
+			}
+			break;
+		}
+
+		if (pid_reset_frame >= 0) {
+			kernel_reset_animation(aa[1], pid_reset_frame);
+			local->pid_frame = pid_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_cal() {
+	int cal_reset_frame;
+
+	if (kernel_anim[aa[2]].frame != local->cal_frame) {
+		local->cal_frame = kernel_anim[aa[2]].frame;
+		cal_reset_frame = -1;
+
+		switch (local->cal_frame) {
+		case 1:
+		case 2:
+		case 3:
+			if (local->cal_action == TALK) {
+				cal_reset_frame = imath_random(0, 2);
+				++ local->cal_talk_count;
+				if (local->cal_talk_count > 24) {
+					local->cal_action     = FREEZE;
+					local->cal_talk_count = 0;
+					cal_reset_frame       = 90;
+				}
+			} else {
+				cal_reset_frame = 90;
+			}
+			break;
+
+		case 34:
+			local->king_action = GIVE;
+			local->pid_action  = GIVE;
+			break;
+
+		case 35:
+			if (local->cal_action == GIVE) {
+				cal_reset_frame = 34;
+			}
+			break;
+
+		case 64:
+			local->pid_action = TAKE_DRINK;
+			break;
+
+		case 65:
+			if (local->cal_action == TAKE_DRINK) {
+				cal_reset_frame = 64;
+			}
+			break;
+
+		case 87:
+			global[dance_music_on] = true;
+			camera_pan_to(&camera_x, 160);
+			local->panning = PANNING_TO_DANCE;
+			if (local->belly_before_talk_count != 0) {
+				kernel_abort_animation(aa[5]);
+				aa[6]                 = kernel_run_animation(kernel_name('d', 2), 0);
+				local->anim_5_running = false;
+				local->anim_6_running = true;
+			}
+			break;
+
+		case 88:
+			if (local->cal_action == CLAP) {
+				cal_reset_frame = 87;
+			}
+			break;
+
+		case 94:
+			if (local->cal_action == LOOK_GIRL) {
+				cal_reset_frame = 93;
+			} else {
+				cal_reset_frame = 98;
+			}
+			break;
+
+		case 14:
+		case 24:
+		case 40:
+		case 70:
+		case 90:
+		case 91:
+		case 97:
+		case 115:
+			switch (local->cal_action) {
+			case TALK:
+				cal_reset_frame = imath_random(14, 15);
+				if (cal_reset_frame == 14) {
+					local->cal_action = FREEZE;
+				} else {
+					cal_reset_frame = 0;
+				}
+				break;
+
+			case FREEZE:
+				cal_reset_frame = 90;
+				break;
+
+			case CLAP:
+				cal_reset_frame = 70;
+				break;
+
+			case TAKE_DRINK:
+				cal_reset_frame = 40;
+				break;
+
+			case GIVE:
+				cal_reset_frame = 24;
+				break;
+
+			case LOOK_GIRL:
+				cal_reset_frame = 91;
+				break;
+
+			case PLEASE_SIT:
+				cal_reset_frame   = 3;
+				local->cal_action = FREEZE;
+				break;
+			}
+			break;
+		}
+
+		if (cal_reset_frame >= 0) {
+			kernel_reset_animation(aa[2], cal_reset_frame);
+			local->cal_frame = cal_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_king_walk() {
+	int king_walk_reset_frame;
+
+	if (kernel_anim[aa[3]].frame != local->king_walk_frame) {
+		local->king_walk_frame = kernel_anim[aa[3]].frame;
+		king_walk_reset_frame = -1;
+
+		switch (local->king_walk_frame) {
+		case 60:
+			local->cal_action = PLEASE_SIT;
+			break;
+
+		case 74:
+			kernel_abort_animation(aa[3]);
+			local->anim_3_running = false;
+			aa[0]                 = kernel_run_animation(kernel_name('k', 1), 0);
+			local->king_action    = FREEZE;
+			local->anim_0_running = true;
+			kernel_synch(KERNEL_ANIM, aa[0], KERNEL_NOW, 0);
+			break;
+
+		case 146:
+			camera_x.pan_mode = CAMERA_PLAYER;
+			new_room          = 405;
+			break;
+		}
+
+		if (king_walk_reset_frame >= 0) {
+			kernel_reset_animation(aa[3], king_walk_reset_frame);
+			local->king_walk_frame = king_walk_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_pid_walk() {
+	int pid_walk_reset_frame;
+
+	if (kernel_anim[aa[4]].frame != local->pid_walk_frame) {
+		local->pid_walk_frame = kernel_anim[aa[4]].frame;
+		pid_walk_reset_frame = -1;
+
+		switch (local->pid_walk_frame) {
+		case 60:
+			local->cal_action = PLEASE_SIT;
+			break;
+
+		case 75:
+			kernel_abort_animation(aa[4]);
+			local->anim_4_running = false;
+			aa[1]                 = kernel_run_animation(kernel_name('p', 1), 0);
+			local->pid_action     = FREEZE;
+			local->anim_1_running = true;
+			kernel_synch(KERNEL_ANIM, aa[1], KERNEL_NOW, 0);
+			break;
+
+		case 143:
+			camera_x.pan_mode = CAMERA_PLAYER;
+			new_room          = 405;
+			break;
+		}
+
+		if (pid_walk_reset_frame >= 0) {
+			kernel_reset_animation(aa[4], pid_walk_reset_frame);
+			local->pid_walk_frame = pid_walk_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_belly_before() {
+	int belly_before_reset_frame;
+
+	if (kernel_anim[aa[5]].frame != local->belly_before_frame) {
+		local->belly_before_frame = kernel_anim[aa[5]].frame;
+		belly_before_reset_frame = -1;
+
+		switch (local->belly_before_frame) {
+		case 37:
+		case 73:
+			if (local->panning == PANNING_TO_DANCE && !camera_x.panning) {
+				++ local->belly_before_talk_count;
+				if (local->belly_before_talk_count >= 3) {
+					camera_pan_to(&camera_x, 0);
+					local->panning = PANNING_AWAY_FROM_DANCE;
+				}
+			}
+
+			if (imath_random(1, 2) == 1) {
+				belly_before_reset_frame = 0;
+			} else {
+				belly_before_reset_frame = 38;
+			}
+			break;
+		}
+
+		if (belly_before_reset_frame >= 0) {
+			kernel_reset_animation(aa[5], belly_before_reset_frame);
+			local->belly_before_frame = belly_before_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_belly_after() {
+	int belly_after_reset_frame;
+
+	if (kernel_anim[aa[6]].frame != local->belly_after_frame) {
+		local->belly_after_frame = kernel_anim[aa[6]].frame;
+		belly_after_reset_frame = -1;
+
+		switch (local->belly_after_frame) {
+		case 92:
+			camera_pan_to(&camera_x, 0);
+			local->panning = PANNING_AWAY_FROM_DANCE;
+			break;
+
+		case 100:
+			belly_after_reset_frame = 99;
+			break;
+
+		case 24:
+			if (local->panning == PANNING_TO_DANCE && camera_x.panning) {
+				belly_after_reset_frame = 0;
+			}
+			break;
+		}
+
+		if (belly_after_reset_frame >= 0) {
+			kernel_reset_animation(aa[6], belly_after_reset_frame);
+			local->belly_after_frame = belly_after_reset_frame;
+		}
+	}
+}
+
+static void room_406_init() {
+	int count;
+	int o1 = false;
+	int o2 = false;
+	int o3 = false;
+	int o4 = false;
+	int o5 = false;
+
+	global[no_load_walker] = false;
+
+	global[perform_displacements] = true;
+	camera_x.pan_mode = CAMERA_MANUAL;
+	local->death_timer = 0;
+	local->clock = 0;
+	local->panning = false;
+	local->belly_before_talk_count = 0;
+
+	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;
+		local->anim_5_running = false;
+		local->anim_6_running = false;
+		local->won_sop = false;
+		local->activate_timer = false;
+	}
+
+	if (previous_room == 405 && global[player_persona] == PLAYER_IS_PID) {
+		if (player_has(dates)) {
+			global[object_flags] = global[object_flags] | 1;
+		}
+
+		if (player_has(statue)) {
+			global[object_flags] = global[object_flags] | 2;
+		}
+
+		if (player_has(ruby_ring)) {
+			global[object_flags] = global[object_flags] | 4;
+		}
+
+		if (player_has(bottle_of_flies)) {
+			global[object_flags] = global[object_flags] | 8;
+		}
+
+		if (player_has(soptus_soporific)) {
+			global[object_flags] = global[object_flags] | 16;
+		}
+
+		global[save_wins_in_desert] = global[wins_in_desert];
+	}
+
+	ss[fx_cup] = kernel_load_series(kernel_name('x', 0), false);
+
+	if (local->activate_timer) {
+		seq[fx_cup] = kernel_seq_stamp(ss[fx_cup], false, KERNEL_LAST);
+		kernel_seq_depth(seq[fx_cup], 1);
+	} else {
+		kernel_set_interface_mode(INTER_LIMITED_SENTENCES);
+		player.commands_allowed = false;
+	}
+
+	if (global[player_persona] == PLAYER_IS_KING) {
+		conv_get(CONV_41_KING);
+	} else {
+		conv_get(CONV_45_PID);
+	}
+
+	local->num_of_stuff = 0;
+
+	if (global[player_persona] == PLAYER_IS_KING) {
+		if (object_is_here(dates))     ++local->num_of_stuff;
+		if (object_is_here(statue))    ++local->num_of_stuff;
+		if (object_is_here(ruby_ring)) ++local->num_of_stuff;
+	} else {
+		if (object_is_here(bottle_of_flies))   ++local->num_of_stuff;
+		if (object_is_here(soptus_soporific))  ++local->num_of_stuff;
+	}
+
+	if (global[player_persona] == PLAYER_IS_KING) {
+		kernel_load_series(kernel_name('a', 0), false);
+	} else {
+		kernel_load_series(kernel_name('b', 0), false);
+	}
+
+	ss[fx_smoke] = kernel_load_series(kernel_name('x', 1), false);
+	ss[fx_thing_1] = kernel_load_series(kernel_name('p', 2), false);
+	ss[fx_thing_2] = kernel_load_series(kernel_name('p', 4), false);
+	ss[fx_half_bottle] = kernel_load_series(kernel_name('p', 0), false);
+	ss[fx_thing_3] = kernel_load_series(kernel_name('p', 6), false);
+	ss[fx_pole] = kernel_load_series(kernel_name('p', 5), false);
+	ss[fx_two_bottles] = kernel_load_series(kernel_name('p', 1), false);
+	ss[fx_mount] = kernel_load_series(kernel_name('p', 7), false);
+
+	seq[fx_half_bottle] = -1;
+	local->dyn_half_bottle = -1;
+	local->half_bottle_base = 61;
+
+	seq[fx_two_bottles] = -1;
+	local->dyn_two_bottles = -1;
+	local->two_bottles_base = 75;
+
+	seq[fx_thing_1] = -1;
+	local->dyn_thing_1 = -1;
+	local->thing_1_base = 228;
+
+	seq[fx_thing_2] = -1;
+	local->dyn_thing_2 = -1;
+	local->thing_2_base = 273;
+
+	seq[fx_thing_3] = -1;
+	local->dyn_thing_3 = -1;
+	local->thing_3_base = 300;
+
+	seq[fx_pole] = -1;
+	local->dyn_pole = -1;
+	local->pole_base = 284;
+
+	seq[fx_smoke] = kernel_seq_forward(ss[fx_smoke], false, 8, 0, 0, 0);
+	kernel_seq_depth(seq[fx_smoke], 3);
+	kernel_seq_range(seq[fx_smoke], KERNEL_FIRST, KERNEL_LAST);
+
+	set_half_bottle_position();
+	set_two_bottles_position();
+	set_thing_1_position();
+	set_thing_2_position();
+	set_thing_3_position();
+	set_pole_position();
+
+	local->mount_x = 54;
+	seq[fx_mount] = kernel_seq_stamp(ss[fx_mount], false, 1);
+	kernel_seq_loc(seq[fx_mount], local->mount_x, 90);
+	kernel_seq_depth(seq[fx_mount], 12);
+
+	local->mount_2_x = 280;
+	seq[fx_mount_2] = kernel_seq_stamp(ss[fx_mount], true, 1);
+	kernel_seq_loc(seq[fx_mount_2], local->mount_2_x, 91);
+	kernel_seq_depth(seq[fx_mount_2], 12);
+
+	/* cal */
+	aa[2] = kernel_run_animation(kernel_name('c', 1), 0);
+	local->anim_2_running = true;
+	local->cal_action = FREEZE;
+	kernel_reset_animation(aa[2], 90);
+
+	if (global[player_persona] == PLAYER_IS_KING) {
+		/* dancer */
+		aa[5] = kernel_run_animation(kernel_name('d', 1), 0);
+		local->anim_5_running = true;
+	}
+
+	if (global[player_persona] == PLAYER_IS_KING) {
+		if (local->anim_0_running || previous_room == 407 || previous_room == KERNEL_RESTORING_GAME) {
+			aa[0] = kernel_run_animation(kernel_name('k', 1), 0);
+			local->king_action = FREEZE;
+			local->anim_0_running = true;
+			kernel_reset_animation(aa[0], 54);
+		} else {
+			aa[3] = kernel_run_animation(kernel_name('k', 2), 0);
+			local->anim_3_running = true;
+		}
+	} else {
+		if (local->anim_1_running || previous_room == 407 || previous_room == KERNEL_RESTORING_GAME) {
+			aa[1] = kernel_run_animation(kernel_name('p', 1), 0);
+			local->pid_action = FREEZE;
+			local->anim_1_running = true;
+			if (local->activate_timer) {
+				kernel_reset_animation(aa[1], 79);
+			} else {
+				kernel_reset_animation(aa[1], 23);
+			}
+		} else {
+			aa[4] = kernel_run_animation(kernel_name('p', 2), 0);
+			local->anim_4_running = true;
+		}
+	}
+
+	if (global[player_persona] == PLAYER_IS_KING) {
+		if (conv_restore_running == CONV_41_KING || previous_room == 407) {
+			conv_run(CONV_41_KING);
+			conv_export_pointer(&global[dance_points]);
+			conv_export_pointer(&global[game_points]);
+			conv_export_pointer(&global[clue_points]);
+			conv_export_value(global[talked_to_soptus]);
+			conv_export_value(global[pid_talk_shamon]);
+			conv_export_value(local->num_of_stuff);
+			conv_export_value(global[prizes_owed_to_player]);
+		}
+	} else {
+		for (count = 1; count <= global[prizes_owed_to_player]; count++) {
+			if (object_is_here(dates) && !o1) {
+				o1 = true;
+			} else if (object_is_here(statue) && !o2) {
+				o2 = true;
+			} else if (object_is_here(ruby_ring) && !o3) {
+				o3 = true;
+			} else if (object_is_here(bottle_of_flies) && !o4) {
+				o4 = true;
+			} else if (object_is_here(soptus_soporific) && !o5) {
+				o5 = true;
+				local->won_sop = true;
+			}
+		}
+
+		if (conv_restore_running == CONV_45_PID || previous_room == 407) {
+			conv_run(CONV_45_PID);
+			conv_export_pointer(&global[pid_has_been_healed_sop]);
+			conv_export_value(local->won_sop);
+			conv_export_value(global[prizes_owed_to_player]);
+		}
+	}
+
+	section_4_music();
 }
 
 void room_406_daemon() {
+	int dif;
+	int temp;
+
+	if (local->anim_0_running) {
+		handle_animation_king();
+	}
+
+	if (local->anim_1_running) {
+		handle_animation_pid();
+	}
+
+	if (local->anim_2_running) {
+		handle_animation_cal();
+	}
+
+	if (local->anim_3_running) {
+		handle_animation_king_walk();
+	}
+
+	if (local->anim_4_running) {
+		handle_animation_pid_walk();
+	}
+
+	if (local->anim_5_running) {
+		handle_animation_belly_before();
+	}
+
+	if (local->anim_6_running) {
+		handle_animation_belly_after();
+	}
+
+	if (local->activate_timer) {
+		if (local->death_timer == 0) {
+			kernel_set_interface_mode(INTER_BUILDING_SENTENCES);
+		}
+
+		dif = kernel.clock - local->clock;
+		if ((dif >= 0) && (dif <= 4)) {
+			local->death_timer += dif;
+		} else {
+			local->death_timer += 1;
+		}
+		local->clock = kernel.clock;
+
+		if (local->death_timer >= LENGTH_OF_LIFE) {
+			kernel_set_interface_mode(INTER_LIMITED_SENTENCES);
+			local->pid_action       = DIE;
+			local->activate_timer   = false;
+			player.commands_allowed = false;
+		}
+	}
+
+	if (kernel.trigger == ROOM_406_CUP) {
+		temp = seq[fx_cup];
+		seq[fx_cup] = kernel_seq_stamp(ss[fx_cup], false, KERNEL_LAST);
+		kernel_seq_depth(seq[fx_cup], 1);
+		kernel_synch(KERNEL_SERIES, seq[fx_cup], KERNEL_SERIES, temp);
+	}
+
+	if (camera_x.pan_this_frame) {
+		set_half_bottle_position();
+		set_two_bottles_position();
+		set_thing_1_position();
+		set_thing_2_position();
+		set_thing_3_position();
+		set_pole_position();
+		set_406_mount_position();
+		set_406_mount_2_position();
+	}
 
+	if (local->panning == PANNING_AWAY_FROM_DANCE && !camera_x.panning) {
+		conv_run(CONV_41_KING);
+		conv_export_pointer(&global[dance_points]);
+		conv_export_pointer(&global[game_points]);
+		conv_export_pointer(&global[clue_points]);
+		conv_export_value(global[talked_to_soptus]);
+		conv_export_value(global[pid_talk_shamon]);
+		conv_export_value(local->num_of_stuff);
+		conv_export_value(global[prizes_owed_to_player]);
+		local->panning     = false;
+		local->king_action = FREEZE;
+		local->cal_action  = FREEZE;
+	}
 }
 
-void room_406_pre_parser() {
+static void process_conv_king_cal() {
+	int you_trig_flag  = false;
+	int me_trig_flag   = false;
+
+	if (player_verb == conv041_to_game_b_b) {
+		*conv_my_next_start = conv041_postgame;
+		conv_abort();
+		you_trig_flag = true;
+		me_trig_flag  = true;
+		new_room = 407;
+	}
+
+	if (player_verb == conv041_to_game_d_d) {
+		*conv_my_next_start = conv041_leaving;
+		conv_abort();
+		you_trig_flag = true;
+		me_trig_flag  = true;
+		new_room = 407;
+	}
+
+	if (player_verb == conv041_dance_b_b) {
+		sound_play(N_BellyDanceMusic);
+		*conv_my_next_start = conv041_indance;
+		conv_abort();
+		local->king_action = LOOK_GIRL_2;
+		local->cal_action  = CLAP;
+		you_trig_flag = true;
+		me_trig_flag  = true;
+	}
+
+	if (player_verb == conv041_postdance_b_b) {
+		*conv_my_next_start = conv041_postdanc;
+		conv_abort();
+		local->king_action = LOOK_GIRL;
+		local->cal_action  = LOOK_GIRL;
+		you_trig_flag = true;
+		me_trig_flag  = true;
+	}
+
+	if (player_verb == conv041_danceyn_no) {
+		if (!kernel.trigger) {
+			global[wins_till_prize] = 3;
+		}
+	}
+
+	if (player_verb == conv041_postdanc_only) {
+		if (!kernel.trigger) {
+			sound_play(N_Bk406Music);
+			global[dance_music_on] = false;
+			if (global[game_points] > 6) {
+				global[wins_till_prize] = 1;
+			} else {
+				global[wins_till_prize] = 2;
+			}
+		}
+	}
+
+	if (player_verb == conv041_exit_b_b ||
+	    player_verb == conv041_exit_d_d ||
+	    player_verb == conv041_exit_f_f ||
+	    player_verb == conv041_give_stuff_f_f) {
+		local->king_action = GET_UP;
+		you_trig_flag      = true;
+		me_trig_flag       = true;
+	}
 
+	if (player_verb == conv041_give_stuff_a_a ||
+	    player_verb == conv041_give_stuff_c_c) {
+		you_trig_flag = true;
+		me_trig_flag  = true;
+	}
+
+	if (player_verb == conv041_give_stuff_b_b ||
+	    player_verb == conv041_give_stuff_d_d) {
+		local->cal_action = GIVE;
+		you_trig_flag     = true;
+		me_trig_flag      = true;
+	}
+
+	if (kernel.trigger == ROOM_406_YOU_TALK) {
+		if (local->king_action != GIVE) {
+			local->cal_action  = TALK;
+		}
+		if (local->king_action != GET_UP) {
+			local->king_action = FREEZE;
+		}
+	}
+
+	if (kernel.trigger == ROOM_406_ME_TALK) {
+		if (local->cal_action != GIVE) {
+			local->cal_action  = FREEZE;
+		}
+		if (local->king_action != GET_UP) {
+			local->king_action = TALK;
+		}
+	}
+
+	if (!you_trig_flag) {
+		conv_you_trigger(ROOM_406_YOU_TALK);
+	}
+
+	if (!me_trig_flag) {
+		conv_me_trigger(ROOM_406_ME_TALK);
+	}
+
+	local->cal_talk_count  = 0;
+	local->king_talk_count = 0;
+}
+
+static void process_conv_pid_cal() {
+	int you_trig_flag  = false;
+	int me_trig_flag   = false;
+
+	if (player_verb == conv045_to_game_b_b) {
+		*conv_my_next_start = conv045_giver;
+		conv_abort();
+		you_trig_flag = true;
+		me_trig_flag  = true;
+		new_room = 407;
+	}
+
+	if (player_verb == conv045_egaming_only) {
+		global[wins_till_prize] = 1;
+	}
+
+	if (player_verb == conv045_hgaming_only) {
+		global[wins_till_prize] = 2;
+	}
+
+	if (player_verb == conv045_exit_b_b) {
+		local->pid_action = GET_UP;
+		you_trig_flag      = true;
+		me_trig_flag       = true;
+	}
+
+	if (player_verb == conv045_give_stuff_a_a) {
+		you_trig_flag = true;
+		me_trig_flag  = true;
+	}
+
+	if (player_verb == conv045_moredrink_b_b) {
+		if (!kernel.trigger) {
+			conv_hold();
+			local->cal_action = TAKE_DRINK;
+		}
+		you_trig_flag     = true;
+		me_trig_flag      = true;
+	}
+
+	if (player_verb == conv045_passout_b_b) {
+		local->pid_action = DRINK;
+		you_trig_flag     = true;
+		me_trig_flag      = true;
+	}
+
+	if (player_verb == conv045_passout_e_e) {
+		conv_hold();
+		local->pid_action = POST_DRINK;
+		you_trig_flag     = true;
+		me_trig_flag      = true;
+	}
+
+	if (player_verb == conv045_give_stuff_b_b) {
+		local->cal_action = GIVE;
+		you_trig_flag     = true;
+		me_trig_flag      = true;
+	}
+
+	if (player_verb == conv045_timer_b_b) {
+		*conv_my_next_start = conv045_revive;
+		conv_abort();
+		kernel_set_interface_mode(INTER_BUILDING_SENTENCES);
+		you_trig_flag           = true;
+		me_trig_flag            = true;
+		player.commands_allowed = true;
+		local->activate_timer   = true;
+	}
+
+	if (kernel.trigger == ROOM_406_YOU_TALK) {
+		if (local->cal_action != GIVE) {
+			local->cal_action  = TALK;
+		}
+
+		if (local->pid_action != GET_UP &&
+		    local->pid_action != TAKE_DRINK &&
+		    local->pid_action != DRINK &&
+		    local->pid_action != POST_DRINK) {
+			local->pid_action = FREEZE;
+		}
+	}
+
+	if (kernel.trigger == ROOM_406_ME_TALK) {
+		if (local->cal_action != GIVE) {
+			local->cal_action  = FREEZE;
+		}
+
+		if (local->pid_action != GET_UP &&
+		    local->pid_action != TAKE_DRINK &&
+		    local->pid_action != DRINK &&
+		    local->pid_action != POST_DRINK) {
+			local->pid_action = TALK;
+		}
+	}
+
+	if (!you_trig_flag) {
+		conv_you_trigger(ROOM_406_YOU_TALK);
+	}
+
+	if (!me_trig_flag) {
+		conv_me_trigger(ROOM_406_ME_TALK);
+	}
+
+	local->cal_talk_count  = 0;
+	local->pid_talk_count = 0;
+}
+
+void room_406_pre_parser() {
 }
 
 void room_406_parser() {
+	if (conv_control.running == CONV_41_KING) {
+		process_conv_king_cal();
+		goto handled;
+	}
+
+	if (conv_control.running == CONV_45_PID) {
+		process_conv_pid_cal();
+		goto handled;
+	}
 
+	if (player_said_1(heal_self)) {
+		kernel_set_interface_mode(INTER_LIMITED_SENTENCES);
+		local->pid_action       = GET_DOLL;
+		local->activate_timer   = false;
+		player.commands_allowed = false;
+		global[player_score]   += 3;
+		goto handled;
+	}
+
+	if (player_said_1(look) || player_said_1(look_at)) {
+		if (!player_has(object_named(player_main_noun))) {
+			text_show(40612);
+			goto handled;
+		}
+	} else {
+		text_show(40613);
+		goto handled;
+	}
+
+	goto done;
+
+handled:
+	player.command_ready = false;
+
+done:
+	;
 }
 
 void room_406_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.king_frame);
+	s.syncAsSint16LE(scratch.king_action);
+	s.syncAsSint16LE(scratch.king_talk_count);
+	s.syncAsSint16LE(scratch.anim_0_running);
+	s.syncAsSint16LE(scratch.pid_frame);
+	s.syncAsSint16LE(scratch.pid_action);
+	s.syncAsSint16LE(scratch.pid_talk_count);
+	s.syncAsSint16LE(scratch.anim_1_running);
+	s.syncAsSint16LE(scratch.cal_frame);
+	s.syncAsSint16LE(scratch.cal_action);
+	s.syncAsSint16LE(scratch.cal_talk_count);
+	s.syncAsSint16LE(scratch.anim_2_running);
+	s.syncAsSint16LE(scratch.king_walk_frame);
+	s.syncAsSint16LE(scratch.king_walk_action);
+	s.syncAsSint16LE(scratch.king_walk_talk_count);
+	s.syncAsSint16LE(scratch.anim_3_running);
+	s.syncAsSint16LE(scratch.pid_walk_frame);
+	s.syncAsSint16LE(scratch.pid_walk_action);
+	s.syncAsSint16LE(scratch.pid_walk_talk_count);
+	s.syncAsSint16LE(scratch.anim_4_running);
+	s.syncAsSint16LE(scratch.belly_before_frame);
+	s.syncAsSint16LE(scratch.belly_before_talk_count);
+	s.syncAsSint16LE(scratch.anim_5_running);
+	s.syncAsSint16LE(scratch.belly_after_frame);
+	s.syncAsSint16LE(scratch.anim_6_running);
+	s.syncAsSint16LE(scratch.half_bottle_base);
+	s.syncAsSint16LE(scratch.dyn_half_bottle);
+	s.syncAsSint16LE(scratch.two_bottles_base);
+	s.syncAsSint16LE(scratch.dyn_two_bottles);
+	s.syncAsSint16LE(scratch.thing_1_base);
+	s.syncAsSint16LE(scratch.dyn_thing_1);
+	s.syncAsSint16LE(scratch.thing_2_base);
+	s.syncAsSint16LE(scratch.dyn_thing_2);
+	s.syncAsSint16LE(scratch.thing_3_base);
+	s.syncAsSint16LE(scratch.dyn_thing_3);
+	s.syncAsSint16LE(scratch.pole_base);
+	s.syncAsSint16LE(scratch.dyn_pole);
+	s.syncAsSint16LE(scratch.mount_x);
+	s.syncAsSint16LE(scratch.mount_2_x);
+	s.syncAsSint16LE(scratch.num_of_stuff);
+	s.syncAsSint16LE(scratch.won_sop);
+	s.syncAsSint16LE(scratch.clock);
+	s.syncAsSint16LE(scratch.death_timer);
+	s.syncAsSint16LE(scratch.activate_timer);
+	s.syncAsSint16LE(scratch.panning);
 }
 
 void room_406_preload() {
-	room_init_code_pointer = room_406_init;
+	room_init_code_pointer       = room_406_init;
 	room_pre_parser_code_pointer = room_406_pre_parser;
-	room_parser_code_pointer = room_406_parser;
-	room_daemon_code_pointer = room_406_daemon;
+	room_parser_code_pointer     = room_406_parser;
+	room_daemon_code_pointer     = room_406_daemon;
+
+	global[no_load_walker] = true;
 
 	section_4_walker();
 	section_4_interface();
 }
 
+void room_406_error() {
+}
+
 } // namespace Rooms
 } // namespace Dragonsphere
 } // namespace MADSV2




More information about the Scummvm-git-logs mailing list