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

dreammaster noreply at scummvm.org
Sat May 23 03:20:46 UTC 2026


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

Summary:
fccba958a4 MADS: DRAGONSPHERE: Beginnings of sound drivers
bb32ee0b43 MADS: DRAGONSPHERE: All of the section 5 rooms


Commit: fccba958a477a93418d3e12447f119d7e476787a
    https://github.com/scummvm/scummvm/commit/fccba958a477a93418d3e12447f119d7e476787a
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-05-23T13:20:37+10:00

Commit Message:
MADS: DRAGONSPHERE: Beginnings of sound drivers

For now I've copied over the Dragonsphere sound drivers,
and adjusted their constructors to have the correct data
segment offsets and sizes, filenames, and samples loading.

Changed paths:
    engines/mads/madsv2/dragonsphere/sound_dragonsphere.cpp
    engines/mads/madsv2/dragonsphere/sound_dragonsphere.h


diff --git a/engines/mads/madsv2/dragonsphere/sound_dragonsphere.cpp b/engines/mads/madsv2/dragonsphere/sound_dragonsphere.cpp
index 5c449b0f56e..d4ddedd0b02 100644
--- a/engines/mads/madsv2/dragonsphere/sound_dragonsphere.cpp
+++ b/engines/mads/madsv2/dragonsphere/sound_dragonsphere.cpp
@@ -74,6 +74,8 @@ void DragonSoundManager::loadDriver(int sectionNumber) {
 	case 5:
 		_driver = new ASound5(_mixer, _opl);
 		break;
+	case 6:
+		// TODO
 	case 9:
 		_driver = new ASound9(_mixer, _opl);
 		break;
@@ -101,10 +103,10 @@ const ASound1::CommandPtr ASound1::_commandList[40] = {
 };
 
 ASound1::ASound1(Audio::Mixer *mixer, OPL::OPL *opl)
-		: ASound(mixer, opl, "asound.dr1", 0x21e0, 0x4d20) {
+		: ASound(mixer, opl, "asound.dr1", 0x2520, 0x49e0) {
 	// Load sound samples
-	auto samplesStream = getDataStream(0x1d4);
-	for (int i = 0; i < 120; ++i)
+	auto samplesStream = getDataStream(0x1dc);
+	for (int i = 0; i < 182; ++i)
 		_samples.push_back(AdlibSample(samplesStream));
 }
 
@@ -384,10 +386,10 @@ const ASound2::CommandPtr ASound2::_commandList[73] = {
 };
 
 ASound2::ASound2(Audio::Mixer *mixer, OPL::OPL *opl)
-		: ASound(mixer, opl, "asound.dr2", 0x2040, 0x2300) {
+		: ASound(mixer, opl, "asound.dr2", 0x1fa0, 0x2950) {
 	// Load sound samples
-	auto samplesStream = getDataStream(0x1d4);
-	for (int i = 0; i < 120; ++i)
+	auto samplesStream = getDataStream(0x1dc);
+	for (int i = 0; i < 182; ++i)
 		_samples.push_back(AdlibSample(samplesStream));
 }
 
@@ -614,10 +616,10 @@ const ASound3::CommandPtr ASound3::_commandList[77] = {
 };
 
 ASound3::ASound3(Audio::Mixer *mixer, OPL::OPL *opl)
-		: ASound(mixer, opl, "asound.dr3", 0x20c0, 0x31a0) {
+		: ASound(mixer, opl, "asound.dr3", 0x1f30, 0x2750) {
 	// Load sound samples
-	auto samplesStream = getDataStream(0x1d4);
-	for (int i = 0; i < 120; ++i)
+	auto samplesStream = getDataStream(0x1dc);
+	for (int i = 0; i < 182; ++i)
 		_samples.push_back(AdlibSample(samplesStream));
 }
 
@@ -893,10 +895,10 @@ const ASound4::CommandPtr ASound4::_commandList[71] = {
 };
 
 ASound4::ASound4(Audio::Mixer *mixer, OPL::OPL *opl)
-		: ASound(mixer, opl, "asound.dr4", 0x1f90, 0x14d0) {
+		: ASound(mixer, opl, "asound.dr4", 0x2120, 0x31d0) {
 	// Load sound samples
-	auto samplesStream = getDataStream(0x1d4);
-	for (int i = 0; i < 120; ++i)
+	auto samplesStream = getDataStream(0x1dc);
+	for (int i = 0; i < 182; ++i)
 		_samples.push_back(AdlibSample(samplesStream));
 }
 
@@ -1049,10 +1051,10 @@ const ASound5::CommandPtr ASound5::_commandList[79] = {
 };
 
 ASound5::ASound5(Audio::Mixer *mixer, OPL::OPL *opl)
-		: ASound(mixer, opl, "asound.dr5", 0x2140, 0x5cd0) {
+		: ASound(mixer, opl, "asound.dr5", 0x20d0, 0x2ee0) {
 	// Load sound samples
-	auto samplesStream = getDataStream(0x1d4);
-	for (int i = 0; i < 120; ++i)
+	auto samplesStream = getDataStream(0x1dc);
+	for (int i = 0; i < 182; ++i)
 		_samples.push_back(AdlibSample(samplesStream));
 }
 
@@ -1334,6 +1336,63 @@ int ASound5::command78() {
 
 /*-----------------------------------------------------------------------*/
 
+/*-----------------------------------------------------------------------*/
+/* ASound5  (asound.dr6)                                                  *
+ *-----------------------------------------------------------------------*/
+
+const ASound6::CommandPtr ASound6::_commandList[98] = {
+	// commands 0-8  (asound_commands1)
+	&ASound6::command0,  &ASound6::command1,  &ASound6::command2,  &ASound6::command3,
+	&ASound6::command4,  &ASound6::command5,  &ASound6::command6,  &ASound6::command7,
+	&ASound6::command8
+};
+
+ASound6::ASound6(Audio::Mixer *mixer, OPL::OPL *opl)
+	: ASound(mixer, opl, "asound.dr6", 0x2370, 0x3870) {
+	// Load sound samples
+	auto samplesStream = getDataStream(0x1dc);
+	for (int i = 0; i < 182; ++i)
+		_samples.push_back(AdlibSample(samplesStream));
+}
+
+int ASound6::command(int commandId, int param) {
+	if (commandId > 71 || !_commandList[commandId])
+		return 0;
+
+	return (this->*_commandList[commandId])();
+}
+
+// commands 0-8: delegate to base ASound
+int ASound6::command0() {
+	return ASound::command0();
+}
+int ASound6::command1() {
+	return ASound::command1();
+}
+int ASound6::command2() {
+	return ASound::command2();
+}
+int ASound6::command3() {
+	return ASound::command3();
+}
+int ASound6::command4() {
+	return ASound::command4();
+}
+int ASound6::command5() {
+	return ASound::command5();
+}
+int ASound6::command6() {
+	return ASound::command6();
+}
+int ASound6::command7() {
+	return ASound::command7();
+}
+int ASound6::command8() {
+	return ASound::command8();
+}
+
+/*-----------------------------------------------------------------------*/
+
 const ASound9::CommandPtr ASound9::_commandList[72] = {
 	&ASound9::command0,  &ASound9::command1,  &ASound9::command2,  &ASound9::command3,
 	&ASound9::command4,  &ASound9::command5,  &ASound9::command6,  &ASound9::command7,
@@ -1356,10 +1415,10 @@ const ASound9::CommandPtr ASound9::_commandList[72] = {
 };
 
 ASound9::ASound9(Audio::Mixer *mixer, OPL::OPL *opl) :
-		ASound(mixer, opl, "asound.dr9", 0x20c0, 0x3690) {
+		ASound(mixer, opl, "asound.dr9", 0x23a0, 0x6a10) {
 	// Load sound samples
-	auto samplesStream = getDataStream(0x1d4);
-	for (int i = 0; i < 120; ++i)
+	auto samplesStream = getDataStream(0x1dc);
+	for (int i = 0; i < 182; ++i)
 		_samples.push_back(AdlibSample(samplesStream));
 }
 
diff --git a/engines/mads/madsv2/dragonsphere/sound_dragonsphere.h b/engines/mads/madsv2/dragonsphere/sound_dragonsphere.h
index e0d63abed2c..2955781d638 100644
--- a/engines/mads/madsv2/dragonsphere/sound_dragonsphere.h
+++ b/engines/mads/madsv2/dragonsphere/sound_dragonsphere.h
@@ -336,6 +336,29 @@ public:
 	int command(int commandId, int param) override;
 };
 
+
+class ASound6 : public ASound {
+private:
+	typedef int (ASound6:: *CommandPtr)();
+	int command0();
+	int command1();
+	int command2();
+	int command3();
+	int command4();
+	int command5();
+	int command6();
+	int command7();
+	int command8();
+
+	static const CommandPtr _commandList[98];
+
+public:
+	ASound6(Audio::Mixer *mixer, OPL::OPL *opl);
+	~ASound6() override {
+	}
+	int command(int commandId, int param) override;
+};
+
 class ASound9 : public ASound {
 private:
 	typedef int (ASound9:: *CommandPtr)();


Commit: bb32ee0b43640e1df5d3e47401a7aa8a98ce1a8c
    https://github.com/scummvm/scummvm/commit/bb32ee0b43640e1df5d3e47401a7aa8a98ce1a8c
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2026-05-23T13:20:37+10:00

Commit Message:
MADS: DRAGONSPHERE: All of the section 5 rooms

Changed paths:
  A engines/mads/madsv2/dragonsphere/mads/quotes.h
    engines/mads/madsv2/core/conv.cpp
    engines/mads/madsv2/core/conv.h
    engines/mads/madsv2/core/sound.cpp
    engines/mads/madsv2/core/sound.h
    engines/mads/madsv2/dragonsphere/mads/conv.h
    engines/mads/madsv2/dragonsphere/mads/inventory.h
    engines/mads/madsv2/dragonsphere/mads/mads.cpp
    engines/mads/madsv2/dragonsphere/mads/sounds.h
    engines/mads/madsv2/dragonsphere/mads/words.h
    engines/mads/madsv2/dragonsphere/rooms/room501.cpp
    engines/mads/madsv2/dragonsphere/rooms/room502.cpp
    engines/mads/madsv2/dragonsphere/rooms/room503.cpp
    engines/mads/madsv2/dragonsphere/rooms/room504.cpp
    engines/mads/madsv2/dragonsphere/rooms/room505.cpp
    engines/mads/madsv2/dragonsphere/rooms/room506.cpp
    engines/mads/madsv2/dragonsphere/rooms/room507.cpp
    engines/mads/madsv2/dragonsphere/rooms/room508.cpp
    engines/mads/madsv2/dragonsphere/rooms/room509.cpp
    engines/mads/madsv2/dragonsphere/rooms/room510.cpp
    engines/mads/madsv2/dragonsphere/rooms/room511.cpp
    engines/mads/madsv2/dragonsphere/rooms/room512.cpp
    engines/mads/madsv2/dragonsphere/rooms/room557.cpp


diff --git a/engines/mads/madsv2/core/conv.cpp b/engines/mads/madsv2/core/conv.cpp
index 283795c105d..f0fb7ec96c0 100644
--- a/engines/mads/madsv2/core/conv.cpp
+++ b/engines/mads/madsv2/core/conv.cpp
@@ -57,6 +57,7 @@ Box conv_box;
 int16 *conv_my_next_start;
 int conv_error_code;
 int conv_dlg_script_ptr, conv_dlg_script_end;
+bool conv_show_boxes;
 
 struct MemoryWriteStreamDynamic : public Common::MemoryWriteStreamDynamic {
 public:
@@ -1218,6 +1219,8 @@ void conv_run(int convId) {
 	char name[80];
 	int idx;
 
+	conv_show_boxes = true;
+
 	// Validate convId is loaded (non-fatal: report error but continue, matching original)
 	if (conv_indexes[convId] < 2)
 		error_report(ERROR_CONV_RUN, ERROR, MODULE_CONV, convId, 0);
diff --git a/engines/mads/madsv2/core/conv.h b/engines/mads/madsv2/core/conv.h
index a47cf588b08..25ea6f4f664 100644
--- a/engines/mads/madsv2/core/conv.h
+++ b/engines/mads/madsv2/core/conv.h
@@ -207,6 +207,7 @@ extern int16 *conv_vars0ValPtr;
 extern int conv_restore_running;
 extern ConvControl conv_control;
 extern int16 *conv_my_next_start;
+extern bool conv_show_boxes;
 
 extern void conv_system_init();
 extern void conv_system_cleanup();
diff --git a/engines/mads/madsv2/core/sound.cpp b/engines/mads/madsv2/core/sound.cpp
index 446352096ed..2eb92631ba4 100644
--- a/engines/mads/madsv2/core/sound.cpp
+++ b/engines/mads/madsv2/core/sound.cpp
@@ -30,7 +30,7 @@ int sound_play(int soundNum) {
 	return sound_queue(soundNum);
 }
 
-int sound_queue(int soundNum) {
+int sound_queue(int soundNum, int /*distance*/) {
 	return g_engine->_soundManager->command(soundNum);
 }
 
diff --git a/engines/mads/madsv2/core/sound.h b/engines/mads/madsv2/core/sound.h
index 231a6cacf04..831c852b4cb 100644
--- a/engines/mads/madsv2/core/sound.h
+++ b/engines/mads/madsv2/core/sound.h
@@ -31,7 +31,7 @@ constexpr int sound_board_roland = 1;
 constexpr bool global_prefer_roland = false;
 
 extern int sound_play(int soundNum);
-extern int sound_queue(int soundNum);
+extern int sound_queue(int soundNum, int distance = 0);
 extern void sound_queue_hold();
 extern void sound_queue_flush();
 
diff --git a/engines/mads/madsv2/dragonsphere/mads/conv.h b/engines/mads/madsv2/dragonsphere/mads/conv.h
index 9803a46f8af..b5c5b86a378 100644
--- a/engines/mads/madsv2/dragonsphere/mads/conv.h
+++ b/engines/mads/madsv2/dragonsphere/mads/conv.h
@@ -110,6 +110,17 @@ enum {
 	conv014_banter_only      = 8
 };
 
+enum {
+	conv015_seeher_show      =  0,
+	conv015_seeher_who       =  1,
+	conv015_seeher_comeout   =  2,
+	conv015_answer_go        =  6,
+	conv015_react_gohome     =  9,
+	conv015_gift3_b_b        = 19,
+	conv015_kiss_b_b         = 27,
+	conv015_exit_b_b         = 32
+};
+
 enum {
 	conv017_exit_b_b    = 4,
 	conv016_exit_b_b    = 5,
@@ -139,6 +150,48 @@ enum {
 	conv023_exit_b_b    = 6
 };
 
+enum {
+	conv026_last_one     = 10,
+	conv026_exit_b_b     = 17
+};
+
+enum {
+	conv027_hello_only       =  0,
+	conv027_seven_only       =  2,
+	conv027_stopper_monk     =  4,
+	conv027_explain_one      =  6,
+	conv027_next_one         =  7,
+	conv027_last_one         =  8,
+	conv027_quickie_b_b      = 12,
+	conv027_quickie_only     = 13,
+	conv027_hem_only         = 14,
+	conv027_one_only         = 15,
+	conv027_two_only         = 16,
+	conv027_four_only        = 19,
+	conv027_inter2_only      = 21,
+	conv027_amulet_only      = 22,
+	conv027_inter2_b_b       = 24,
+	conv027_six_only         = 25,
+	conv027_amulet_b_b       = 27,
+	conv027_eight_only       = 28,
+	conv027_kiss_b_b         = 30,
+	conv027_nogood_hidewhat  = 31,
+	conv027_exit_b_b         = 34,
+	conv027_restart          = 35,
+	conv027_restart_only     = 35,
+	conv027_ten_only         = 36
+};
+
+enum {
+	conv028_didnot_innocent = 9,
+	conv028_exit_b_b        = 26
+};
+
+enum {
+	conv033_six_only     =  4,
+	conv033_exit_b_b     =  7
+};
+
 enum {
 	conv034_five_b_b    =  4,
 	conv034_seven_only  =  7,
@@ -154,6 +207,11 @@ enum {
 	conv035_exit_b_b    =  3
 };
 
+enum {
+	conv037_next_b_b         =  2,
+	conv037_exit_b_b         =  5
+};
+
 enum {
 	conv038_third_yes        =  2,
 	conv038_third_idont      =  4,
@@ -201,6 +259,121 @@ enum {
 	conv041_exit_f_f         = 68
 };
 
+enum {
+	conv042_pre_poem         =  0,
+	conv042_one_first        =  1,
+	conv042_one_second       =  2,
+	conv042_one_third        =  3,
+	conv042_one_restart      =  4,
+	conv042_one_abort        =  5,
+
+	conv042_two_first        =  6,
+	conv042_two_second       =  7,
+	conv042_two_third        =  8,
+	conv042_two_restart      =  9,
+	conv042_two_abort        = 10,
+
+	conv042_three_first      = 11,
+	conv042_three_second     = 12,
+	conv042_three_third      = 13,
+	conv042_three_restart    = 14,
+	conv042_three_abort      = 15,
+
+	conv042_four_first       = 16,
+	conv042_four_second      = 17,
+	conv042_four_third       = 18,
+	conv042_four_restart     = 19,
+	conv042_four_abort       = 20,
+
+	conv042_five_first       = 21,
+	conv042_five_second      = 22,
+	conv042_five_third       = 23,
+	conv042_five_restart     = 24,
+	conv042_five_abort       = 25,
+
+	conv042_six_first        = 26,
+	conv042_six_second       = 27,
+	conv042_six_third        = 28,
+	conv042_six_restart      = 29,
+	conv042_six_abort        = 30,
+
+	conv042_seven_first      = 31,
+	conv042_seven_second     = 32,
+	conv042_seven_third      = 33,
+	conv042_seven_restart    = 34,
+	conv042_seven_abort      = 35,
+
+	conv042_eight_first      = 36,
+	conv042_eight_second     = 37,
+	conv042_eight_third      = 38,
+	conv042_eight_restart    = 39,
+	conv042_eight_abort      = 40,
+
+	conv042_nine_first       = 41,
+	conv042_nine_second      = 42,
+	conv042_nine_third       = 43,
+	conv042_nine_restart     = 44,
+	conv042_nine_abort       = 45,
+
+	conv042_ten_first        = 46,
+	conv042_ten_second       = 47,
+	conv042_ten_third        = 48,
+	conv042_ten_restart      = 49,
+	conv042_ten_abort        = 50,
+
+	conv042_eleven_first     = 51,
+	conv042_eleven_second    = 52,
+	conv042_eleven_third     = 53,
+	conv042_eleven_restart   = 54,
+	conv042_eleven_abort     = 55,
+
+	conv042_twelve_first     = 56,
+	conv042_twelve_second    = 57,
+	conv042_twelve_third     = 58,
+	conv042_twelve_restart   = 59,
+	conv042_twelve_abort     = 60,
+
+	conv042_thirteen_first   = 61,
+	conv042_thirteen_second  = 62,
+	conv042_thirteen_third   = 63,
+	conv042_thirteen_restart = 64,
+	conv042_thirteen_abort   = 65,
+
+	conv042_fourteen_first   = 66,
+	conv042_fourteen_second  = 67,
+	conv042_fourteen_third   = 68,
+	conv042_fourteen_restart = 69,
+	conv042_fourteen_abort   = 70,
+
+	conv042_easy_14_first    = 71,
+	conv042_easy_14_second   = 72,
+	conv042_easy_14_third    = 73,
+	conv042_easy_14_restart  = 74,
+	conv042_easy_14_abort    = 75,
+
+	conv042_fifteen_first    = 76,
+	conv042_fifteen_second   = 77,
+	conv042_fifteen_third    = 78,
+	conv042_fifteen_restart  = 79,
+	conv042_fifteen_abort    = 80,
+
+	conv042_sixteen_first    = 81,
+	conv042_sixteen_second   = 82,
+	conv042_sixteen_third    = 83,
+	conv042_sixteen_restart  = 84,
+	conv042_sixteen_abort    = 85,
+
+	conv042_seventeen_first  = 86,
+	conv042_seventeen_second = 87,
+	conv042_seventeen_third  = 88,
+	conv042_seventeen_restart= 89,
+	conv042_seventeen_abort  = 90,
+
+	conv042_exit_b_b         = 93,
+	conv042_later_b_b        = 94,
+	conv042_whoops_b_b       = 96,
+};
+
 enum {
 	conv043_greeting         =  0,
 	conv043_restart          =  4,
diff --git a/engines/mads/madsv2/dragonsphere/mads/inventory.h b/engines/mads/madsv2/dragonsphere/mads/inventory.h
index 85d4fc9bf2c..167e5720cdc 100644
--- a/engines/mads/madsv2/dragonsphere/mads/inventory.h
+++ b/engines/mads/madsv2/dragonsphere/mads/inventory.h
@@ -49,6 +49,7 @@ enum {
 	soul_egg            = 17,
 	magic_belt          = 18,
 	amulet              = 19,
+	mud                 = 20,
 	feathers            = 21,
 	flask_full_of_acid  = 24,
 	dead_rat            = 27,
diff --git a/engines/mads/madsv2/dragonsphere/mads/mads.cpp b/engines/mads/madsv2/dragonsphere/mads/mads.cpp
index 88af2528d5e..538ff0af453 100644
--- a/engines/mads/madsv2/dragonsphere/mads/mads.cpp
+++ b/engines/mads/madsv2/dragonsphere/mads/mads.cpp
@@ -21,5 +21,6 @@
 
 #include "mads/madsv2/dragonsphere/mads/conv.h"
 #include "mads/madsv2/dragonsphere/mads/inventory.h"
+#include "mads/madsv2/dragonsphere/mads/quotes.h"
 #include "mads/madsv2/dragonsphere/mads/sounds.h"
 #include "mads/madsv2/dragonsphere/mads/words.h"
diff --git a/engines/mads/madsv2/dragonsphere/mads/quotes.h b/engines/mads/madsv2/dragonsphere/mads/quotes.h
new file mode 100644
index 00000000000..533e6cd4d4b
--- /dev/null
+++ b/engines/mads/madsv2/dragonsphere/mads/quotes.h
@@ -0,0 +1,92 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef MADS_DRAGONSPHERE_MADS_QUOTES_H
+#define MADS_DRAGONSPHERE_MADS_QUOTES_H
+
+#include "common/scummsys.h"
+
+namespace MADS {
+namespace MADSV2 {
+namespace Dragonsphere {
+
+enum {
+	quote_poem_one_how        =  74,
+	quote_poem_one_thou       =  75,
+	quote_poem_one_soft       =  76,
+	quote_poem_two_art 		  =  77,
+	quote_poem_two_do 		  =  78,
+	quote_poem_two_what 	  =  79,
+	quote_poem_three_light 	  =  80,
+	quote_poem_three_i 		  =  81,
+	quote_poem_three_a 		  =  82,
+	quote_poem_four_through   =  83,
+	quote_poem_four_rose 	  =  84,
+	quote_poem_four_love 	  =  85,
+	quote_poem_five_but 	  =  86,
+	quote_poem_five_yonder 	  =  87,
+	quote_poem_five_thee 	  =  88,
+	quote_poem_six_let 		  =  89,
+	quote_poem_six_no 		  =  90,
+	quote_poem_six_window 	  =  91,
+	quote_poem_seven_breaks   =  92,
+	quote_poem_seven_for 	  =  93,
+	quote_poem_seven_me 	  =  94,
+	quote_poem_eight_no 	  =  95,
+	quote_poem_eight_count 	  =  96,
+	quote_poem_eight_tis 	  =  97,
+	quote_poem_nine_rose 	  =  98,
+	quote_poem_nine_the 	  =  99,
+	quote_poem_nine_bird 	  = 100,
+	quote_poem_ten_ways 	  = 101,
+	quote_poem_ten_and 		  = 102,
+	quote_poem_ten_as 		  = 103,
+	quote_poem_eleven_and 	  = 104,
+	quote_poem_eleven_fair 	  = 105,
+	quote_poem_eleven_one 	  = 106,
+	quote_poem_twelve_did 	  = 107,
+	quote_poem_twelve_bird 	  = 108,
+	quote_poem_twelve_two 	  = 109,
+	quote_poem_thirteen_ever  = 110,
+	quote_poem_thirteen_three = 111,
+	quote_poem_thirteen_bird  = 112,
+	quote_poem_fourteen_are   = 113,
+	quote_poem_fourteen_is 	  = 114,
+	quote_poem_fourteen_grow  = 115,
+	quote_poem_easy_14_are 	  = 116,
+	quote_poem_easy_14_is 	  = 117,
+	quote_poem_easy_14_grow   = 118,
+	quote_poem_fifteen_enough =	119,
+	quote_poem_fifteen_in     =	120,
+	quote_poem_fifteen_the    =	121,
+	quote_poem_sixteen_for    = 122,
+	quote_poem_sixteen_any    = 123,
+	quote_poem_sixteen_sun    = 124,
+	quote_poem_seventeen_thee = 125,
+	quote_poem_seventeen_land = 126,
+	quote_poem_seventeen_oh   = 127
+};
+
+} // namespace Dragonsphere
+} // namespace MADSV2
+} // namespace MADS
+
+#endif
diff --git a/engines/mads/madsv2/dragonsphere/mads/sounds.h b/engines/mads/madsv2/dragonsphere/mads/sounds.h
index c230edac872..a6a9d2c6e6e 100644
--- a/engines/mads/madsv2/dragonsphere/mads/sounds.h
+++ b/engines/mads/madsv2/dragonsphere/mads/sounds.h
@@ -106,6 +106,14 @@ enum {
 	N_ShakMus            =  32,
 	N_Battle             =  33,
 	N_Hermit             =  34,
+	N_KissMusic          =  35,
+	N_TheKiss            =  36,
+	N_TenseMusic         =  38,
+	N_005Waterfall       =  42,
+	N_FarEchos           =  67,
+	N_RockClatter        =  68,
+	N_CryOfDismay        =  72,
+	N_005FlyingInsect    =  78,
 
 	// Section 6
 	N_Bk603Music         =  32,
diff --git a/engines/mads/madsv2/dragonsphere/mads/words.h b/engines/mads/madsv2/dragonsphere/mads/words.h
index 4230d44e59d..1999084579b 100644
--- a/engines/mads/madsv2/dragonsphere/mads/words.h
+++ b/engines/mads/madsv2/dragonsphere/mads/words.h
@@ -131,6 +131,7 @@ enum {
 	words_rare_coin            = 129,
 	words_admire               = 130,
 	words_crystal_flower       = 131,
+	words_gold_nugget          = 134,
 	words_emerald              = 136,
 	words_speak_words_on       = 138,
 	words_vortex_stone         = 139,
@@ -139,15 +140,17 @@ enum {
 	words_passageway_to_west   = 150,
 	words_passageway_to_east   = 151,
 	words_cave_floor           = 152,
+	words_look_into            = 155,
 	words_castle               = 156,
 	words_ground               = 158,
 	words_door                 = 166,
 	words_wall_switch          = 167,
 	words_stairs               = 168,
 	words_cave                 = 149,
-	words_rock                 = 172,
+	words_abyss                = 154,
 	words_walk_down            = 169,
 	words_edge_of_abyss        = 170,
+	words_rock                 = 172,
 	words_cave_ceiling         = 173,
 	words_cave_wall            = 174,
 	words_brazier              = 175,
@@ -228,17 +231,33 @@ enum {
 	words_soporific            = 289,
 	words_parchment            = 290,
 	words_king                 = 291,
+	words_mountainside         = 293,
 	words_path_to_south        = 294,
+	words_rough_stone          = 295,
 	words_climb_up             = 296,
+	words_large_rock           = 297,
+	words_small_rock           = 298,
+	words_puddle               = 315,
 	words_boulders             = 320,
 	words_path_to_west         = 299,
+	words_cave_entrance        = 300,
+	words_pallet               = 301,
+	words_blanket              = 302,
 	words_firepit              = 303,
+	words_flat_stone           = 304,
 	words_spirit_bundle        = 306,
+	words_follow               = 308,
+	words_nest                 = 310,
 	words_path_to_east         = 313,
 	words_waterfall            = 314,
+	words_edge_of_cliff        = 316,
 	words_ledge                = 317,
+	words_climb_down           = 318,
+	words_landing              = 319,
 	words_sconce               = 329,
 	words_rock_tumble          = 321,
+	words_rock_tree            = 322,
+	words_pillar               = 323,
 	words_jump_to              = 324,
 	words_stairway             = 331,
 	words_mechanism            = 332,
@@ -262,6 +281,7 @@ enum {
 	words_tower_door           = 365,
 	words_freezer              = 388,
 	words_Ner_Tom              = 399,
+	words_belt                 = 400,
 	words_music_box            = 414,
 	words_circle_of_spheres    = 423,
 	words_rat                  = 426,
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room501.cpp b/engines/mads/madsv2/dragonsphere/rooms/room501.cpp
index 677b333538f..0093c71a35f 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room501.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room501.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/matte.h"
 #include "mads/madsv2/core/sound.h"
 #include "mads/madsv2/core/text.h"
 #include "mads/madsv2/dragonsphere/mads/conv.h"
@@ -39,37 +41,95 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[15];
+	int16 sequence[15];
+	int16 animation[4];
 };
 
+static Scratch scratch;
+
 #define local (&scratch)
 #define ss    local->sprite
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
+#define ROOM_501_BYE         60
+#define MUSIC                70
 
-void room_501_init() {
+#define PLAYER_X_FROM_120    325
+#define PLAYER_Y_FROM_120    143
+#define WALK_TO_X_FROM_120   284
+#define WALK_TO_Y_FROM_120   134
+#define PLAYER_X_FROM_502    158
+#define PLAYER_Y_FROM_502    102
 
-}
 
-void room_501_daemon() {
+static void room_501_init() {
+	viewing_at_y = ((video_y - display_y) >> 1);
+	kernel_init_dialog();
+	kernel_set_interface_mode(INTER_LIMITED_SENTENCES);
 
-}
+	if (previous_room == 502) {
+		player_first_walk(PLAYER_X_FROM_502, PLAYER_Y_FROM_502, FACING_SOUTHEAST,
+		                  PLAYER_X_FROM_120, PLAYER_Y_FROM_120, FACING_WEST, false);
+		player_walk_trigger(ROOM_501_BYE + 2);
 
-void room_501_pre_parser() {
+	} else if ((previous_room == 120) || (previous_room != KERNEL_RESTORING_GAME)) {
+		player_first_walk(PLAYER_X_FROM_120, PLAYER_Y_FROM_120, FACING_WEST,
+		                  PLAYER_X_FROM_502, PLAYER_Y_FROM_502, FACING_NORTHWEST, false);
+		player_walk_trigger(ROOM_501_BYE);
+	}
 
+	section_5_music();
 }
 
-void room_501_parser() {
+static void room_501_daemon() {
+	if (kernel.trigger == ROOM_501_BYE) {
+		if (global[player_persona] == PLAYER_IS_KING) {
+			player.walker_visible = false;
+			aa[0] = kernel_run_animation(kernel_name('x', 1), ROOM_501_BYE + 1);
+			kernel_synch(KERNEL_ANIM, aa[0], KERNEL_PLAYER, 0);
+
+		} else {
+			new_room = 502;
+		}
+	}
+
+	if (kernel.trigger == ROOM_501_BYE + 1) {
+		new_room = 502;
+	}
+
+	if (kernel.trigger == ROOM_501_BYE + 2) {
+		global[pre_room] = 501;
+		if (global[dragon_my_scene] < global[dragon_high_scene]) {
+			global[dragon_my_scene]++;
+			new_room = 111;
+		} else {
+			new_room = 120;
+		}
+	}
+}
 
+static void room_501_pre_parser() {
 }
 
-void room_501_synchronize(Common::Serializer &s) {
+static void room_501_parser() {
+}
 
+void room_501_synchronize(Common::Serializer &s) {
+	for (int16 &v : scratch.sprite)    s.syncAsSint16LE(v);
+	for (int16 &v : scratch.sequence)  s.syncAsSint16LE(v);
+	for (int16 &v : scratch.animation) s.syncAsSint16LE(v);
 }
 
 void room_501_preload() {
+	room_init_code_pointer       = room_501_init;
+	room_pre_parser_code_pointer = room_501_pre_parser;
+	room_parser_code_pointer     = room_501_parser;
+	room_daemon_code_pointer     = room_501_daemon;
 
+	section_5_walker();
+	section_5_interface();
 }
 
 } // namespace Rooms
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room502.cpp b/engines/mads/madsv2/dragonsphere/rooms/room502.cpp
index 1a4245547fe..a683fc408f4 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room502.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room502.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/matte.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,43 +42,806 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[15];
+	int16 sequence[15];
+	int16 animation[4];
+	int16 lani_frame;
+	int16 lani_action;
+	int16 lani_talk_count;
+	int16 anim_0_running;
+	int16 anim_1_running;
+	int16 lani_location;
+	int16 prevent;
 };
 
+static Scratch scratch;
+
 #define local (&scratch)
 #define ss    local->sprite
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
+#define fx_up             0
+#define fx_down           1
+#define fx_give           2
+
+#define ROOM_502_DONE_DOWN    60
+#define ROOM_502_YOU_TALK     65
+#define ROOM_502_ME_TALK      67
+#define ROOM_502_COME_OUT     69
+#define ROOM_502_FOOT         71
+#define ROOM_502_DONE_GIVING  73
+#define ROOM_502_TALK         75
+
+#define PLAYER_X_FROM_503    -20
+#define PLAYER_Y_FROM_503    148
+#define WALK_TO_X_FROM_503    13
+#define WALK_TO_Y_FROM_503   148
+#define PLAYER_X_FROM_501    207
+#define PLAYER_Y_FROM_501    152
+#define PLAYER_X_FROM_506    248
+#define PLAYER_Y_FROM_506    109
+#define WALK_TO_X_FROM_506   227
+#define WALK_TO_Y_FROM_506   116
+
+#define CONV_15_LANI          15
+
+#define LANI_BOW              0
+#define LANI_SHUT_UP          1
+#define LANI_STAMP_FOOT       2
+#define LANI_TALK             3
+#define LANI_LEAN             4
+#define LANI_KISS             5
+#define LANI_GIVE             6
+
+#define WALK_TO_LANI_X       130
+#define WALK_TO_LANI_Y       120
+
+#define BEHIND_ROCK           0
+#define OUT_IN_OPEN           1
+#define AGAINST_ROCK          2
+
+
+static void handle_animation_lani_1() {
+	int lani_reset_frame;
+
+	if (kernel_anim[aa[1]].frame != local->lani_frame) {
+		local->lani_frame = kernel_anim[aa[1]].frame;
+		lani_reset_frame  = -1;
+
+		switch (local->lani_frame) {
+		case 1:
+		case 2:
+		case 3:
+			switch (local->lani_action) {
+			case LANI_TALK:
+				lani_reset_frame = imath_random(0, 2);
+				++local->lani_talk_count;
+				if (local->lani_talk_count > 17) {
+					local->lani_action     = LANI_SHUT_UP;
+					local->lani_talk_count = 0;
+					lani_reset_frame       = 0;
+				}
+				break;
+
+			default:
+				lani_reset_frame = 0;
+				break;
+			}
+			break;
+		}
+
+		if (lani_reset_frame >= 0) {
+			kernel_reset_animation(aa[1], lani_reset_frame);
+			local->lani_frame = lani_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_lani_0() {
+	int lani_reset_frame;
+	int random;
+	int id;
+
+	if (kernel_anim[aa[0]].frame != local->lani_frame) {
+		local->lani_frame = kernel_anim[aa[0]].frame;
+		lani_reset_frame  = -1;
+
+		switch (local->lani_frame) {
+		case 1:
+		case 2:
+		case 3:
+			if (local->lani_action != LANI_BOW) {
+				++local->lani_talk_count;
+				if (local->lani_talk_count > imath_random(15, 25)) {
+					lani_reset_frame = imath_random(0, 2);
+					local->lani_talk_count = 0;
+				} else {
+					lani_reset_frame = local->lani_frame - 1;
+				}
+			} else {
+				lani_reset_frame     = 3;
+				local->lani_location = OUT_IN_OPEN;
+			}
+			break;
+
+		case 21:
+		case 122:
+			conv_release();
+			break;
+
+		case 49:
+			lani_reset_frame = 153;
+			break;
+
+		case 22:
+		case 123:
+		case 43:
+		case 30:
+		case 53:
+		case 75:
+		case 99:
+		case 87:
+			if (local->lani_frame == 99) {
+				sound_play(N_TakeObjectSnd);
+				inter_give_to_player(amulet);
+				object_examine(amulet, 819, 0);
+				global[player_score] += 2;
+			}
+
+			switch (local->lani_action) {
+			case LANI_SHUT_UP:
+				++local->lani_talk_count;
+				if (local->lani_talk_count > imath_random(20, 30)) {
+					random = imath_random(1, 3);
+					switch (random) {
+					case 1: lani_reset_frame = 21;  break;
+					case 2: lani_reset_frame = 53;  break;
+					case 3: lani_reset_frame = 30;  break;
+					}
+					local->lani_talk_count = 0;
+				} else {
+					lani_reset_frame = 21;
+				}
+				break;
+
+			case LANI_STAMP_FOOT:
+				lani_reset_frame = 53;
+				break;
+
+			case LANI_BOW:
+				lani_reset_frame = 22;
+				local->lani_action = LANI_SHUT_UP;
+				break;
+
+			case LANI_TALK:
+				random = imath_random(1, 2);
+				if (random == 1) {
+					lani_reset_frame = 75;
+				} else {
+					lani_reset_frame = 45;
+				}
+				break;
+
+			case LANI_LEAN:
+				lani_reset_frame = 123;
+				break;
+
+			case LANI_KISS:
+				lani_reset_frame = 104;
+				break;
+
+			case LANI_GIVE:
+				lani_reset_frame = 87;
+				break;
+			}
+			break;
+
+		case 81:
+		case 82:
+		case 83:
+		case 84:
+			switch (local->lani_action) {
+			case LANI_TALK:
+				lani_reset_frame = imath_random(81, 83);
+				++local->lani_talk_count;
+				if (local->lani_talk_count > 17) {
+					local->lani_action     = LANI_SHUT_UP;
+					local->lani_talk_count = 0;
+					lani_reset_frame       = 84;
+				}
+				break;
+
+			default:
+				lani_reset_frame = 84;
+				break;
+			}
+			break;
+
+		case 97:
+			player.walker_visible = false;
+			seq[fx_give]          = kernel_seq_pingpong(ss[fx_give], true, 10, 0, 0, 2);
+			kernel_seq_depth(seq[fx_give], 1);
+			kernel_seq_player(seq[fx_give], true);
+			kernel_seq_range(seq[fx_give], KERNEL_FIRST, KERNEL_LAST);
+			kernel_seq_trigger(seq[fx_give], KERNEL_TRIGGER_EXPIRE, 0, ROOM_502_DONE_GIVING);
+			break;
+
+		case 98:
+			switch (local->lani_action) {
+			case LANI_GIVE:
+				lani_reset_frame = 97;
+				break;
+
+			default:
+				lani_reset_frame = 98;
+				break;
+			}
+			break;
+
+		case 134:
+			kernel_abort_animation(aa[0]);
+			aa[1] = kernel_run_animation(kernel_name('l', 2), 0);
+			kernel_synch(KERNEL_ANIM, aa[1], KERNEL_NOW, 0);
+			id = kernel_add_dynamic(words_Llanie, words_walk_to, SYNTAX_SINGULAR_FEM, KERNEL_NONE,
+			                        0, 0, 0, 0);
+			kernel_dynamic_hot[id].prep = PREP_ON;
+			kernel_dynamic_walk(id, WALK_TO_LANI_X, WALK_TO_LANI_Y, FACING_NORTHWEST);
+			kernel_dynamic_anim(id, aa[1], 0);
+
+			local->anim_0_running         = false;
+			local->anim_1_running         = true;
+			lani_reset_frame              = -1;
+			player.commands_allowed       = true;
+			local->lani_location          = AGAINST_ROCK;
+			global[done_talking_lani_502] = true;
+			local->lani_action            = LANI_SHUT_UP;
+			kernel_flip_hotspot(words_stranger, false);
+			break;
+
+		case 135:
+		case 136:
+		case 137:
+			switch (local->lani_action) {
+			case LANI_TALK:
+				lani_reset_frame = imath_random(134, 136);
+				++local->lani_talk_count;
+				if (local->lani_talk_count > 17) {
+					local->lani_action     = LANI_SHUT_UP;
+					local->lani_talk_count = 0;
+					lani_reset_frame       = 134;
+				}
+				break;
+
+			default:
+				lani_reset_frame = 134;
+				break;
+			}
+			break;
+
+		case 59:
+		case 70:
+		case 104:
+			switch (local->lani_action) {
+			case LANI_STAMP_FOOT:
+				lani_reset_frame   = 59;
+				local->lani_action = LANI_SHUT_UP;
+				break;
+
+			case LANI_SHUT_UP:
+				++local->lani_talk_count;
+				if (local->lani_talk_count > 17) {
+					random = imath_random(1, 3);
+					switch (random) {
+					case 1: lani_reset_frame = 58;  break;
+					case 2: lani_reset_frame = 70;  break;
+					case 3: lani_reset_frame = 99;  break;
+					}
+					local->lani_talk_count = 0;
+				} else {
+					lani_reset_frame = 58;
+				}
+				break;
+
+			default:
+				lani_reset_frame = 70;
+				break;
+			}
+			break;
+
+		case 102:
+			switch (local->lani_action) {
+			case LANI_SHUT_UP:
+				lani_reset_frame = 101;
+				++local->lani_talk_count;
+				if (local->lani_talk_count > 17) {
+					lani_reset_frame       = imath_random(101, 102);
+					local->lani_talk_count = 0;
+				} else {
+					lani_reset_frame = 101;
+				}
+				break;
+
+			default:
+				lani_reset_frame = 102;
+				break;
+			}
+			break;
+
+		case 154:
+		case 155:
+		case 156:
+			switch (local->lani_action) {
+			case LANI_TALK:
+				lani_reset_frame = imath_random(153, 155);
+				++local->lani_talk_count;
+				if (local->lani_talk_count > 10) {
+					local->lani_action     = LANI_SHUT_UP;
+					local->lani_talk_count = 0;
+					lani_reset_frame       = 49;
+				}
+				break;
+
+			default:
+				lani_reset_frame = 49;
+				break;
+			}
+			break;
+		}
+
+		if (lani_reset_frame >= 0) {
+			kernel_reset_animation(aa[0], lani_reset_frame);
+			local->lani_frame = lani_reset_frame;
+		}
+	}
+}
+
+static void room_502_init() {
+	// TODO: id used in kernel_dynamic_anim before being set in original.
+	// Perhaps a previously undiscovered logic bug?
+	int id = 0;
+
+	kernel.disable_fastwalk = true;
+
+	if (previous_room != KERNEL_RESTORING_GAME) {
+		local->anim_0_running = false;
+		local->anim_1_running = false;
+		local->prevent        = false;
+		local->lani_location  = -1;
+	}
+
+	if (previous_room == KERNEL_RESTORING_GAME) {
+		if (local->anim_1_running) {
+			conv_get(CONV_15_LANI);
+			aa[1]                 = kernel_run_animation(kernel_name('l', 2), 0);
+			local->anim_1_running = true;
+			kernel_dynamic_anim(id, aa[1], 3);
+			kernel_flip_hotspot(words_stranger, false);
+			id = kernel_add_dynamic(words_Llanie, words_walk_to, SYNTAX_SINGULAR_FEM, KERNEL_NONE,
+			                        0, 0, 0, 0);
+			kernel_dynamic_hot[id].prep = PREP_ON;
+			kernel_dynamic_walk(id, WALK_TO_LANI_X, WALK_TO_LANI_Y, FACING_NORTHWEST);
+			kernel_dynamic_anim(id, aa[1], 0);
+		}
+	}
 
-void room_502_init() {
+	if (!global[done_talking_lani_502]) {
+		ss[fx_give] = kernel_load_series("*KGRD_9", false);
+		conv_get(CONV_15_LANI);
 
+		id = kernel_add_dynamic(words_Llanie, words_walk_to, SYNTAX_SINGULAR_FEM, KERNEL_NONE,
+		                        0, 0, 0, 0);
+		kernel_dynamic_hot[id].prep = PREP_ON;
+		kernel_dynamic_walk(id, WALK_TO_LANI_X, WALK_TO_LANI_Y, FACING_NORTHWEST);
+
+		if (local->lani_location == AGAINST_ROCK) {
+			aa[1]                 = kernel_run_animation(kernel_name('l', 2), 0);
+			local->anim_1_running = true;
+			kernel_dynamic_anim(id, aa[1], 0);
+		} else {
+			aa[0]                 = kernel_run_animation(kernel_name('l', 1), 0);
+			local->anim_0_running = true;
+			kernel_dynamic_anim(id, aa[0], 3);
+		}
+
+		local->lani_action = LANI_SHUT_UP;
+
+		if (previous_room == KERNEL_RESTORING_GAME) {
+			if (local->lani_location == OUT_IN_OPEN) {
+				kernel_reset_animation(aa[0], 22);
+				kernel_flip_hotspot(words_stranger, false);
+			} else if (local->lani_location == AGAINST_ROCK) {
+				kernel_flip_hotspot(words_stranger, false);
+			}
+
+			if (conv_restore_running == CONV_15_LANI) {
+				player.commands_allowed = false;
+				conv_run(CONV_15_LANI);
+			}
+		} else {
+			local->lani_location = BEHIND_ROCK;
+		}
+	} else {
+		kernel_flip_hotspot(words_stranger, false);
+	}
+
+	if (previous_room == 503) {
+		player_first_walk(PLAYER_X_FROM_503, PLAYER_Y_FROM_503, FACING_EAST,
+		                  WALK_TO_X_FROM_503, WALK_TO_Y_FROM_503, FACING_EAST, true);
+
+	} else if (previous_room == 506) {
+		player.commands_allowed = false;
+		player.walker_visible   = false;
+		player.x                = PLAYER_X_FROM_506;
+		player.y                = PLAYER_Y_FROM_506;
+		player.facing           = FACING_NORTH;
+
+		if (global[player_persona] == PLAYER_IS_KING) {
+			aa[0] = kernel_run_animation(kernel_name('k', 2), ROOM_502_DONE_DOWN);
+			kernel_reset_animation(aa[0], 1);
+		} else {
+			ss[fx_down]  = kernel_load_series(kernel_name('b', 0), false);
+			seq[fx_down] = kernel_seq_backward(ss[fx_down], false, 6, 0, 0, 1);
+			kernel_seq_depth(seq[fx_down], 1);
+			kernel_seq_range(seq[fx_down], KERNEL_FIRST, KERNEL_LAST);
+			kernel_seq_trigger(seq[fx_down], KERNEL_TRIGGER_EXPIRE, 0, ROOM_502_DONE_DOWN + 1);
+		}
+	} else if (previous_room != KERNEL_RESTORING_GAME) {
+		player.x      = PLAYER_X_FROM_501;
+		player.y      = PLAYER_Y_FROM_501;
+		player.facing = FACING_NORTH;
+	}
+
+	section_5_music();
 }
 
-void room_502_daemon() {
+static void room_502_daemon() {
+	if (local->anim_0_running) {
+		handle_animation_lani_0();
+	}
+
+	if (local->anim_1_running) {
+		handle_animation_lani_1();
+	}
+
+	if (local->anim_0_running && !local->prevent) {
+		if (player.x < 60) {
+			text_show(50219);
+			player_walk(WALK_TO_LANI_X, WALK_TO_LANI_Y, FACING_NORTHWEST);
+			player_walk_trigger(ROOM_502_TALK);
+			player.commands_allowed = false;
+			local->prevent          = true;
+		}
+	}
+
+	if (kernel.trigger == ROOM_502_TALK) {
+		kernel_timing_trigger(1, ROOM_502_TALK + 1);
+	}
+
+	if (kernel.trigger == ROOM_502_TALK + 1) {
+		conv_run(CONV_15_LANI);
+	}
+
+	if (kernel.trigger == ROOM_502_DONE_DOWN) {
+		player.walker_visible   = true;
+		player.commands_allowed = true;
+		player_walk(WALK_TO_X_FROM_506, WALK_TO_Y_FROM_506, FACING_SOUTH);
+		kernel_synch(KERNEL_PLAYER, 0, KERNEL_ANIM, aa[0]);
+	}
 
+	if (kernel.trigger == ROOM_502_DONE_DOWN + 1) {
+		player.walker_visible   = true;
+		player.commands_allowed = true;
+		player_walk(WALK_TO_X_FROM_506, WALK_TO_Y_FROM_506, FACING_SOUTH);
+		kernel_synch(KERNEL_PLAYER, 0, KERNEL_SERIES, seq[fx_down]);
+	}
+
+	if (kernel.trigger == ROOM_502_DONE_GIVING) {
+		local->lani_action    = LANI_SHUT_UP;
+		player.walker_visible = true;
+		conv_release();
+		kernel_synch(KERNEL_PLAYER, 0, KERNEL_SERIES, seq[fx_give]);
+	}
 }
 
-void room_502_pre_parser() {
+static void process_conv_lani() {
+	int you_trig_flag = false;
+	int me_trig_flag  = false;
+
+	switch (player_verb) {
+	case conv015_seeher_show:
+	case conv015_seeher_who:
+	case conv015_seeher_comeout:
+		you_trig_flag = true;
+		me_trig_flag  = true;
+		if (!kernel.trigger) {
+			conv_you_trigger(ROOM_502_COME_OUT);
+		}
+		break;
+
+	case conv015_exit_b_b:
+		if (local->lani_location != AGAINST_ROCK) {
+			you_trig_flag = true;
+			me_trig_flag  = true;
+			local->lani_action = LANI_LEAN;
+		}
+		break;
+
+	case conv015_gift3_b_b:
+		you_trig_flag      = true;
+		me_trig_flag       = true;
+		local->lani_action = LANI_GIVE;
+		conv_hold();
+		break;
+
+	case conv015_kiss_b_b:
+		you_trig_flag      = true;
+		me_trig_flag       = true;
+		local->lani_action = LANI_KISS;
+		sound_play(N_TheKiss);
+		conv_hold();
+		break;
+
+	case conv015_react_gohome:
+	case conv015_answer_go:
+		you_trig_flag = true;
+		me_trig_flag  = true;
+		if (!kernel.trigger) {
+			conv_you_trigger(ROOM_502_FOOT);
+		}
+		break;
+	}
+
+	if (kernel.trigger == ROOM_502_COME_OUT) {
+		local->lani_action = LANI_BOW;
+		conv_hold();
+	}
+
+	if (kernel.trigger == ROOM_502_FOOT) {
+		local->lani_action = LANI_STAMP_FOOT;
+	}
+
+	if (kernel.trigger == ROOM_502_YOU_TALK) {
+		if (local->lani_action != LANI_BOW       &&
+		    local->lani_action != LANI_STAMP_FOOT &&
+		    local->lani_action != LANI_LEAN       &&
+		    local->lani_action != LANI_KISS       &&
+		    local->lani_action != LANI_GIVE) {
+			local->lani_action = LANI_TALK;
+		}
+	}
+
+	if (kernel.trigger == ROOM_502_ME_TALK) {
+		if (local->lani_action != LANI_BOW       &&
+		    local->lani_action != LANI_STAMP_FOOT &&
+		    local->lani_action != LANI_LEAN       &&
+		    local->lani_action != LANI_KISS       &&
+		    local->lani_action != LANI_GIVE) {
+			local->lani_action = LANI_SHUT_UP;
+		}
+	}
+
+	if (!you_trig_flag) {
+		conv_you_trigger(ROOM_502_YOU_TALK);
+	}
+
+	if (!me_trig_flag) {
+		conv_me_trigger(ROOM_502_ME_TALK);
+	}
 
+	local->lani_talk_count = 0;
 }
 
-void room_502_parser() {
+static void room_502_pre_parser() {
+	if (player_said_2(walk_down, path_to_west)) {
+		player.walk_off_edge_to_room = 503;
+	}
+}
+
+static void room_502_parser() {
+	if (conv_control.running == CONV_15_LANI) {
+		process_conv_lani();
+		player.command_ready = false;
+		return;
+	}
+
+	if (kernel.trigger == ROOM_502_TALK) {
+		kernel_timing_trigger(1, ROOM_502_TALK + 1);
+		player.command_ready = false;
+		return;
+	}
+
+	if (kernel.trigger == ROOM_502_TALK + 1) {
+		conv_run(CONV_15_LANI);
+		local->prevent = true;
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(walk_down, path_to_west)) {
+		if (local->anim_0_running) {
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_2(walk_down, path_to_south)) {
+		new_room = 501;
+		player.command_ready = false;
+		return;
+	}
+
+	if (player.look_around) {
+		if (global[sorceror_defeated]) {
+			text_show(50214);
+
+		} else if (game.difficulty == EASY_MODE) {
+			text_show(50201);
+			if (global[llanie_status] == BEFORE_FALL) {
+				text_show(50202);
+			}
+
+		} else {
+			text_show(50201);
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(climb_up, rough_stone)) {
+		switch (kernel.trigger) {
+		case 0:
+			if (!global[done_talking_lani_502]) {
+				text_show(50219);
+				player_walk(WALK_TO_LANI_X, WALK_TO_LANI_Y, FACING_NORTHWEST);
+				player_walk_trigger(ROOM_502_TALK);
+				player.commands_allowed = false;
+
+			} else {
+				player.commands_allowed = false;
+				player.walker_visible   = false;
+				if (global[player_persona] == PLAYER_IS_KING) {
+					aa[0] = kernel_run_animation(kernel_name('k', 1), 1);
+					kernel_synch(KERNEL_ANIM, aa[0], KERNEL_PLAYER, 0);
+				} else {
+					aa[3] = kernel_run_animation(kernel_name('p', 2), 1);
+					kernel_synch(KERNEL_ANIM, aa[3], KERNEL_PLAYER, 0);
+				}
+			}
+			break;
+
+		case 1:
+			new_room = 506;
+			break;
+		}
+		player.command_ready = false;
+		return;
+	}
 
+	if (player_said_1(look) || player_said_1(look_at)) {
+		if (player_said_1(path_to_south)) {
+			text_show(50203);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(path_to_west)) {
+			if (!global[found_lani_504] && global[monster_is_dead]) {
+				text_show(50213);
+			} else if (global[sorceror_defeated]) {
+				text_show(50215);
+			} else {
+				text_show(50204);
+			}
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(rough_stone)) {
+			text_show(50205);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(large_rock)) {
+			if (local->anim_0_running || local->anim_1_running) {
+				if (local->lani_location == AGAINST_ROCK) {
+					text_show(50212);
+				} else if (game.difficulty == EASY_MODE) {
+					text_show(50207);
+				} else {
+					text_show(50206);
+				}
+			} else {
+				if (!global[monster_is_dead]) {
+					text_show(50220);
+				} else {
+					text_show(50206);
+				}
+			}
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(small_rock)) {
+			text_show(50208);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(mountainside)) {
+			text_show(50210);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(Llanie)) {
+			text_show(50211);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(stranger)) {
+			text_show(50219);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_2(take, small_rock)) {
+		text_show(50209);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_3(give, amulet, Llanie)) {
+		text_show(50217);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_3(put, tentacle_parts, mountainside)) {
+		text_show(50218);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_1(talk_to)) {
+		if (player_said_1(Llanie) || player_said_1(stranger)) {
+			if (local->lani_location != AGAINST_ROCK) {
+				player.commands_allowed = false;
+			}
+			conv_run(CONV_15_LANI);
+			local->prevent = true;
+			player.command_ready = false;
+			return;
+		}
+	}
 }
 
 void room_502_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(local->lani_frame);
+	s.syncAsSint16LE(local->lani_action);
+	s.syncAsSint16LE(local->lani_talk_count);
+	s.syncAsSint16LE(local->anim_0_running);
+	s.syncAsSint16LE(local->anim_1_running);
+	s.syncAsSint16LE(local->lani_location);
+	s.syncAsSint16LE(local->prevent);
 }
 
 void room_502_preload() {
-	room_init_code_pointer = room_502_init;
+	room_init_code_pointer       = room_502_init;
 	room_pre_parser_code_pointer = room_502_pre_parser;
-	room_parser_code_pointer = room_502_parser;
-	room_daemon_code_pointer = room_502_daemon;
+	room_parser_code_pointer     = room_502_parser;
+	room_daemon_code_pointer     = room_502_daemon;
 
 	section_5_walker();
 	section_5_interface();
+
+	vocab_make_active(words_Llanie);
 }
 
 } // namespace Rooms
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room503.cpp b/engines/mads/madsv2/dragonsphere/rooms/room503.cpp
index 215f9f0fc93..06be0081078 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room503.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room503.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,15 @@
  *
  */
 
+#include "mads/madsv2/core/camera.h"
+#include "mads/madsv2/core/config.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/text.h"
 #include "mads/madsv2/dragonsphere/mads/conv.h"
@@ -39,43 +44,490 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[15];
+	int16 sequence[15];
+	int16 animation[4];
+	int16 water_frame;
+	int16 anim_0_running;
+	int16 rock_base;
+	int16 dyn_rock;
+	int16 branch_base;
+	int16 dyn_branch;
+	int16 prevent;
+	int32 update_clock;
 };
 
+static Scratch scratch;
+
 #define local (&scratch)
 #define ss    local->sprite
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
+#define fx_body          0
+#define fx_flies         1
+#define fx_gold          2
+#define fx_take_gold     3
+#define fx_bottom        4
+#define fx_rock          5
+#define fx_branch        6
+
+#define ROOM_503_DOOR_CLOSES  60
+
+#define PLAYER_X_FROM_505    -15
+#define PLAYER_Y_FROM_505    119
+#define WALK_TO_X_FROM_505    15
+#define WALK_TO_Y_FROM_505   119
+#define PLAYER_X_FROM_504    318
+#define PLAYER_Y_FROM_504    112
+#define WALK_TO_X_FROM_504   337
+#define WALK_TO_Y_FROM_504   123
+#define PLAYER_X_FROM_502    645
+#define PLAYER_Y_FROM_502    115
+#define WALK_TO_X_FROM_502   624
+#define WALK_TO_Y_FROM_502   115
+
+#define camera_ratio_1    1
+#define camera_ratio_2    3
+
+#define GOLD_X            195
+#define GOLD_Y            139
+
+
+static void set_rock_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_rock] >= 0) {
+		kernel_seq_delete(seq[fx_rock]);
+	}
 
-void room_503_init() {
+	difference = center - local->rock_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->rock_base + displace - 1;
+	y          = series_list[ss[fx_rock]]->index[0].ys + 126;
+	xs         = series_list[ss[fx_rock]]->index[0].xs;
+
+	if (((x - ((xs >> 1) + 1)) >= (picture_view_x + video_x)) ||
+	    ((x + ((xs >> 1) + 1)) < picture_view_x)) {
+		seq[fx_rock] = -1;
+	} else {
+		seq[fx_rock] = kernel_seq_stamp(ss[fx_rock], false, 1);
+		kernel_seq_loc(seq[fx_rock], x, y);
+		kernel_seq_depth(seq[fx_rock], 1);
+	}
 }
 
-void room_503_daemon() {
+static void set_branch_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_branch] >= 0) {
+		kernel_seq_delete(seq[fx_branch]);
+	}
+
+	difference = center - local->branch_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->branch_base + displace - 1;
+	y          = series_list[ss[fx_branch]]->index[0].ys + 118;
+	xs         = series_list[ss[fx_branch]]->index[0].xs;
+
+	if (((x - ((xs >> 1) + 1)) >= (picture_view_x + video_x)) ||
+	    ((x + ((xs >> 1) + 1)) < picture_view_x)) {
+		seq[fx_branch] = -1;
+	} else {
+		seq[fx_branch] = kernel_seq_stamp(ss[fx_branch], false, 1);
+		kernel_seq_loc(seq[fx_branch], x, y);
+		kernel_seq_depth(seq[fx_branch], 1);
+	}
 }
 
-void room_503_pre_parser() {
+static void handle_animation_water() {
+	int water_reset_frame;
+
+	if (kernel_anim[aa[0]].frame != local->water_frame) {
+		local->water_frame = kernel_anim[aa[0]].frame;
+		water_reset_frame  = -1;
+
+		if (local->water_frame == 26) {
+			water_reset_frame = 0;
+		}
 
+		if (water_reset_frame >= 0) {
+			kernel_reset_animation(aa[0], water_reset_frame);
+			local->water_frame = water_reset_frame;
+		}
+	}
 }
 
-void room_503_parser() {
+static void room_503_init() {
+	kernel.disable_fastwalk = true;
+	local->prevent = false;
 
+	ss[fx_rock] = kernel_load_series(kernel_name('r', 0), false);
+	ss[fx_branch] = kernel_load_series(kernel_name('r', 1), false);
+
+	if (global[monster_is_dead]) {
+		ss[fx_flies] = kernel_load_series(kernel_name('x', 1), false);
+		ss[fx_body] = kernel_load_series(kernel_name('x', 0), false);
+		seq[fx_body] = kernel_seq_stamp(ss[fx_body], false, KERNEL_FIRST);
+		kernel_seq_depth(seq[fx_body], 14);
+		seq[fx_flies] = kernel_seq_forward(ss[fx_flies], false, 4, 0, 0, 0);
+		kernel_seq_depth(seq[fx_flies], 1);
+		kernel_seq_range(seq[fx_flies], KERNEL_FIRST, KERNEL_LAST);
+
+	} else {
+		kernel_flip_hotspot(words_beast, false);
+	}
+
+	if (object_is_here(gold_nugget)) {
+		if (global[player_persona] == PLAYER_IS_KING) {
+			ss[fx_take_gold] = kernel_load_series("*KGRD_7", false);
+		} else {
+			ss[fx_take_gold] = kernel_load_series("*PDRL_9", false);
+		}
+		ss[fx_gold] = kernel_load_series(kernel_name('p', 0), false);
+		seq[fx_gold] = kernel_seq_stamp(ss[fx_gold], false, KERNEL_FIRST);
+		kernel_seq_depth(seq[fx_gold], 14);
+
+	} else {
+		kernel_flip_hotspot(words_gold_nugget, false);
+	}
+
+	if (!global[waterfall_diverted]) {
+		ss[fx_bottom] = kernel_load_series(kernel_name('x', 2), false);
+		seq[fx_bottom] = kernel_seq_forward(ss[fx_bottom], false, 6, 0, 0, 0);
+		kernel_seq_depth(seq[fx_bottom], 3);
+		kernel_seq_range(seq[fx_bottom], KERNEL_FIRST, KERNEL_LAST);
+
+		aa[0] = kernel_run_animation(kernel_name('w', 1), 0);
+		local->anim_0_running = true;
+
+	} else {
+		local->anim_0_running = false;
+	}
+
+	if (previous_room == 505) {
+		player_first_walk(PLAYER_X_FROM_505, PLAYER_Y_FROM_505, FACING_EAST,
+			WALK_TO_X_FROM_505, WALK_TO_Y_FROM_505, FACING_EAST, true);
+
+	} else if (previous_room == 504) {
+		player_first_walk(PLAYER_X_FROM_504, PLAYER_Y_FROM_504, FACING_SOUTHEAST,
+			WALK_TO_X_FROM_504, WALK_TO_Y_FROM_504, FACING_SOUTHEAST, true);
+		camera_jump_to(160, 0);
+
+	} else if ((previous_room == 502) || (previous_room != KERNEL_RESTORING_GAME)) {
+		player_first_walk(PLAYER_X_FROM_502, PLAYER_Y_FROM_502, FACING_WEST,
+			WALK_TO_X_FROM_502, WALK_TO_Y_FROM_502, FACING_WEST, true);
+		camera_jump_to(320, 0);
+	}
+
+	seq[fx_rock] = -1;
+	local->dyn_rock = -1;
+	local->rock_base = 75;
+
+	seq[fx_branch] = -1;
+	local->dyn_branch = -1;
+	local->branch_base = 558;
+
+	set_rock_position();
+	set_branch_position();
+
+	local->update_clock = kernel.clock;
+
+	section_5_music();
+}
+
+static void room_503_daemon() {
+	int dist;
+
+	if (local->anim_0_running) {
+		handle_animation_water();
+	}
+
+	if (camera_x.pan_this_frame) {
+		set_rock_position();
+		set_branch_position();
+	}
+
+	if (kernel.clock >= local->update_clock) {
+		dist = 127 - ((imath_hypot(player.x - 287, player.y - 146) * 127) / 378);
+		if (!sound_off) {
+			if (player.x < 33 || player.x > 534) {
+				sound_queue(N_005Waterfall, 42);
+			} else {
+				sound_queue(N_005Waterfall, dist);
+			}
+		}
+		local->update_clock = kernel.clock + player.frame_delay;
+	}
+
+	if (player.x > 432 && player.x < 550 && global[monster_is_dead]) {
+		sound_play(N_005FlyingInsect);
+	}
+}
+
+static void room_503_pre_parser() {
+	if (player_said_2(walk_down, path_to_west)) {
+		player.walk_off_edge_to_room = 505;
+	}
+
+	if (player_said_2(walk_down, path_to_east)) {
+		player.walk_off_edge_to_room = 502;
+	}
+
+	if (player_said_2(take, gold_nugget) && !player_has(gold_nugget) &&
+	    global[player_persona] == PLAYER_IS_PID) {
+		player_walk(GOLD_X, GOLD_Y, FACING_NORTHWEST);
+	}
+
+	if (player_said_1(cave) && player.need_to_walk) {
+		if (!player_said_1(walk_into)) {
+			player.need_to_walk = false;
+		}
+	}
+}
+
+static void room_503_parser() {
+	if (player_said_2(walk_into, cave)) {
+		new_room = 504;
+		player.command_ready = false;
+		return;
+	}
+
+	if (player.look_around) {
+		text_show(50301);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(take, gold_nugget) ||
+	    player_said_2(pull, gold_nugget)) {
+
+		switch (kernel.trigger) {
+		case 0:
+			if (!player_has(gold_nugget)) {
+				player.commands_allowed = false;
+				player.walker_visible   = false;
+				if (global[player_persona] == PLAYER_IS_KING) {
+					seq[fx_take_gold] = kernel_seq_forward(ss[fx_take_gold], false, 7, 0, 0, 1);
+					kernel_seq_trigger(seq[fx_take_gold], KERNEL_TRIGGER_EXPIRE, 0, 1);
+				} else {
+					seq[fx_take_gold] = kernel_seq_pingpong(ss[fx_take_gold], true, 7, 0, 0, 2);
+					kernel_seq_trigger(seq[fx_take_gold], KERNEL_TRIGGER_SPRITE, 4, 2);
+					kernel_seq_trigger(seq[fx_take_gold], KERNEL_TRIGGER_EXPIRE, 0, 3);
+				}
+				kernel_seq_depth(seq[fx_take_gold], 1);
+				kernel_seq_range(seq[fx_take_gold], KERNEL_FIRST, KERNEL_LAST);
+				kernel_seq_player(seq[fx_take_gold], true);
+				player.command_ready = false;
+				return;
+			}
+			break;
+
+		case 1:
+			kernel_seq_delete(seq[fx_gold]);
+			kernel_flip_hotspot(words_gold_nugget, false);
+			player.walker_visible   = true;
+			player.commands_allowed = true;
+			global[player_score]   += 5;
+			kernel_synch(KERNEL_PLAYER, 0, KERNEL_SERIES, seq[fx_take_gold]);
+			sound_play(N_TakeObjectSnd);
+			inter_give_to_player(gold_nugget);
+			object_examine(gold_nugget, 50319, 0);
+			player.command_ready = false;
+			return;
+
+		case 2:
+			if (local->prevent) {
+				kernel_seq_delete(seq[fx_gold]);
+				kernel_flip_hotspot(words_gold_nugget, false);
+				global[player_score]   += 5;
+				sound_play(N_TakeObjectSnd);
+				inter_give_to_player(gold_nugget);
+				object_examine(gold_nugget, 50319, 0);
+			}
+			local->prevent = true;
+			player.command_ready = false;
+			return;
+
+		case 3:
+			player.walker_visible   = true;
+			player.commands_allowed = true;
+			kernel_synch(KERNEL_PLAYER, 0, KERNEL_SERIES, seq[fx_take_gold]);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_1(look) || player_said_1(look_at)) {
+
+		if (player_said_1(cave)) {
+			if (!player_has_been_in_room(504)) {
+				if (global[waterfall_diverted]) {
+					text_show(50309);
+				} else {
+					text_show(50308);
+				}
+			} else {
+				text_show(50310);
+			}
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(path_to_west)) {
+			text_show(50313);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(path_to_east)) {
+			text_show(50314);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(mountainside)) {
+			text_show(50315);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(waterfall)) {
+			text_show(50316);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(ground)) {
+			text_show(50317);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(gold_nugget) && object_is_here(gold_nugget)) {
+			text_show(50318);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(puddle)) {
+			text_show(50303);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(beast)) {
+			if (global[found_lani_504]) {
+				text_show(50321);
+			} else {
+				text_show(50320);
+			}
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_3(fill, goblet, waterfall) ||
+	    player_said_3(fill, goblet, puddle)) {
+		text_show(50305);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(put, waterfall) ||
+	    player_said_2(put, puddle)) {
+		if (player_said_1(torch)) {
+			text_show(50306);
+			player.command_ready = false;
+			return;
+		} else if (player_has(object_named(player_main_noun))) {
+			text_show(50307);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_1(cave)) {
+		if (player_said_1(open) || player_said_1(close)) {
+			text_show(50311);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_2(throw, cave)) {
+		text_show(50312);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(heal, beast)) {
+		text_show(50322);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(talk_to, beast)) {
+		text_show(50323);
+		player.command_ready = false;
+		return;
+	}
 }
 
 void room_503_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(local->water_frame);
+	s.syncAsSint16LE(local->anim_0_running);
+	s.syncAsSint16LE(local->rock_base);
+	s.syncAsSint16LE(local->dyn_rock);
+	s.syncAsSint16LE(local->branch_base);
+	s.syncAsSint16LE(local->dyn_branch);
+	s.syncAsSint16LE(local->prevent);
+	s.syncAsSint32LE(local->update_clock);
 }
 
 void room_503_preload() {
-	room_init_code_pointer = room_503_init;
+	room_init_code_pointer       = room_503_init;
 	room_pre_parser_code_pointer = room_503_pre_parser;
-	room_parser_code_pointer = room_503_parser;
-	room_daemon_code_pointer = room_503_daemon;
+	room_parser_code_pointer     = room_503_parser;
+	room_daemon_code_pointer     = room_503_daemon;
 
 	section_5_walker();
 	section_5_interface();
+
+	if (global[monster_is_dead]) {
+		kernel_initial_variant = 1;
+	}
 }
 
 } // namespace Rooms
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room504.cpp b/engines/mads/madsv2/dragonsphere/rooms/room504.cpp
index 196be4a0466..a174bb1c9bd 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room504.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room504.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,11 +22,16 @@
 #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/quote.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/quotes.h"
 #include "mads/madsv2/dragonsphere/mads/sounds.h"
 #include "mads/madsv2/dragonsphere/mads/words.h"
 #include "mads/madsv2/dragonsphere/global.h"
@@ -39,43 +44,1921 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[15];
+	int16 sequence[15];
+	int16 animation[5];
+
+	int16 lani_pid_frame;
+	int16 lani_pid_action;
+	int16 lani_pid_talk_count;
+	int16 anim_0_running;
+
+	int16 poking_frame;
+	int16 poking_action;
+	int16 poking_talk_count;
+	int16 anim_1_running;
+
+	int16 heal_frame;
+	int16 heal_action;
+	int16 heal_talk_count;
+	int16 anim_2_running;
+
+	int16 reveal_frame;
+	int16 reveal_action;
+	int16 reveal_talk_count;
+	int16 anim_3_running;
+
+	int16 tom_talk_frame;
+	int16 tom_talk_action;
+	int16 tom_talk_talk_count;
+	int16 anim_4_running;
+
+	int16 ready_to_heal;
+	int16 prevent;
+	int16 dynamic_hs;
+	int16 pid_is_kneeling;
+	int16 purpose_for_healing;
+	int16 got_it;
+
+	char  line_1[70];
+	char  line_2[70];
+	char  line_3[70];
+	int16 working_on_line;
+	int16 quote_id;
+
+	int16 shit;
 };
 
+static Scratch scratch;
+
 #define local (&scratch)
 #define ss    local->sprite
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
+#define fx_fire           0
+#define fx_look_at_heal   1
+#define fx_lani           2
+
+#define ROOM_504_DOOR_CLOSES    60
+#define ROOM_504_YOU_TALK       65
+#define ROOM_504_ME_TALK        67
+#define ROOM_504_DONE_HEALING   73
+#define ROOM_504_TALK_TO_HERMIT 77
+#define ROOM_504_RUN_POEM_CONV  90
+#define ROOM_504_END_POEM       92
+
+#define NOTHING           0
+#define BUNDLE            1
+#define HEAL              2
+#define HEAL_CRYSTAL      3
+#define POEM              4
+#define NEW               5
+
+#define PLAYER_X_FROM_503  114
+#define PLAYER_Y_FROM_503  147
+
+#define LANI_X             184
+#define LANI_Y             147
+
+#define CONV_24_KING            24
+#define CONV_25_KING_AFTER_FALL 25
+#define CONV_26_PID_PRE_HEAL    26
+#define CONV_27_PID_HEAL        27
+#define CONV_42_POEM            42
+
+#define LANI_DEAD          0
+#define PID_KNEEL          1
+#define PID_LOOK_TOM       2
+#define PID_TALK_TO_LANI   3
+#define LANI_TALK          4
+#define BOTH_SHUT_UP       5
+#define LANI_KISS          6
+#define PID_HEAL           7
+#define GIVE               8
+#define PID_GET_UP         9
+#define LANI_SIT_UP        10
+#define LANI_LAY_DOWN      11
+#define PID_POEM           12
+
+#define TOM_SHUT_UP        0
+#define TOM_TALK           1
+#define TOM_LOOK_AT_HEAL   2
+#define TOM_REVEAL         3
+#define TOM_HIDE           4
+
+#define WALK_TO_HERMIT_X   143
+#define WALK_TO_HERMIT_Y   134
+
+
+static void handle_animation_lani_pid() {
+	int lani_pid_reset_frame;
+	int id;
+
+	if (kernel_anim[aa[0]].frame != local->lani_pid_frame) {
+		local->lani_pid_frame = kernel_anim[aa[0]].frame;
+		lani_pid_reset_frame  = -1;
+
+		switch (local->lani_pid_frame) {
+		case 99:
+			if (!player_has(piece_of_paper)) {
+				sound_play(N_TakeObjectSnd);
+				inter_give_to_player(piece_of_paper);
+				object_examine(piece_of_paper, 845, 0);
+				global[player_score] += 1;
+				local->shit = true;
+
+			} else if (!player_has(amulet)) {
+				sound_play(N_TakeObjectSnd);
+				inter_give_to_player(amulet);
+				object_examine(amulet, 819, 0);
+				global[player_score] += 2;
+			}
+			break;
+
+		case 100:
+			if (local->shit) {
+				local->shit = false;
+				sound_play(N_KissMusic);
+			}
+			break;
+
+		case 165:
+			lani_pid_reset_frame = 164;
+			break;
+
+		case 114:
+		case 122:
+			if (local->lani_pid_frame == 122) {
+				if (global[llanie_status] == IS_SAVED) {
+					*conv_my_next_start = conv027_restart;
+				}
+				conv_abort();
+				kernel_set_interface_mode(INTER_BUILDING_SENTENCES);
+				player.walker_visible  = true;
+				local->pid_is_kneeling = false;
+				local->lani_pid_action = LANI_DEAD;
+				local->tom_talk_action = TOM_HIDE;
+				player.ready_to_walk   = true;
+				kernel_synch(KERNEL_PLAYER, 0, KERNEL_ANIM, aa[0]);
+			}
+
+			switch (local->lani_pid_action) {
+			case LANI_DEAD:
+				lani_pid_reset_frame = 113;
+				break;
+
+			case PID_HEAL:
+			case PID_KNEEL:
+			case BOTH_SHUT_UP:
+				local->pid_is_kneeling = true;
+				player.walker_visible  = false;
+				lani_pid_reset_frame   = 20;
+				kernel_synch(KERNEL_PLAYER, 0, KERNEL_ANIM, aa[0]);
+				break;
+			}
+			break;
+
+		case 32:
+			lani_pid_reset_frame = imath_random(31, 32);
+			++local->lani_pid_talk_count;
+			if (local->lani_pid_talk_count > 15) {
+				local->lani_pid_talk_count = 0;
+				lani_pid_reset_frame       = 34;
+			}
+			break;
+
+		case 33:
+			lani_pid_reset_frame = imath_random(31, 33);
+			++local->lani_pid_talk_count;
+			if (local->lani_pid_talk_count > 15) {
+				local->lani_pid_talk_count = 0;
+				lani_pid_reset_frame       = 34;
+			}
+			break;
+
+		case 34:
+			lani_pid_reset_frame = imath_random(32, 33);
+			++local->lani_pid_talk_count;
+			if (local->lani_pid_talk_count > 15) {
+				local->lani_pid_talk_count = 0;
+				lani_pid_reset_frame       = 34;
+			}
+			break;
+
+		case 159:
+		case 39:
+		case 28:
+		case 31:
+		case 107:
+		case 108:
+		case 109:
+		case 110:
+		case 113:
+			if (local->purpose_for_healing != POEM) {
+				if (local->lani_pid_frame == 39) {
+					if ((!global[said_poem_in_504] || !global[put_bundle_on_llanie_504]) ||
+					    (local->purpose_for_healing < HEAL || local->purpose_for_healing == NEW)) {
+
+						kernel_seq_delete(seq[fx_look_at_heal]);
+
+						aa[1] = kernel_run_animation(kernel_name('t', 1), 0);
+						kernel_reset_animation(aa[1], 5);
+
+						local->poking_action     = TOM_SHUT_UP;
+						local->anim_1_running    = true;
+						local->prevent           = false;
+						local->lani_pid_action   = BOTH_SHUT_UP;
+						player.commands_allowed  = true;
+
+						id = kernel_add_dynamic(words_hermit, words_walk_to, SYNTAX_MASC_NOT_PROPER, KERNEL_NONE,
+						                        0, 0, 0, 0);
+						kernel_dynamic_hot[id].prep = PREP_ON;
+						kernel_dynamic_walk(id, WALK_TO_HERMIT_X, WALK_TO_HERMIT_Y, FACING_NORTHWEST);
+						kernel_dynamic_anim(id, aa[1], 0);
+
+						if ((local->purpose_for_healing == NOTHING) && (!global[tried_to_heal_llanie_504])) {
+							global[tried_to_heal_llanie_504] = true;
+							local->lani_pid_action           = PID_LOOK_TOM;
+							conv_run(CONV_26_PID_PRE_HEAL);
+							conv_export_value(global[put_bundle_on_llanie_504]);
+							conv_export_value(global[said_poem_in_504]);
+							conv_export_value(global[tried_to_heal_llanie_504]);
+							conv_export_value(player_has(shifter_ring));
+						}
+
+					} else if (global[llanie_status] != IS_SAVED) {
+
+						global[tried_to_heal_llanie_504] = true;
+						global[llanie_status]            = IS_SAVED;
+						local->lani_pid_action           = LANI_TALK;
+						local->poking_action             = TOM_SHUT_UP;
+						local->anim_1_running            = true;
+						local->prevent                   = false;
+						global[player_score]            += 5;
+
+						kernel_seq_delete(seq[fx_look_at_heal]);
+
+						aa[1] = kernel_run_animation(kernel_name('t', 1), 0);
+						kernel_reset_animation(aa[1], 5);
+
+						kernel_init_dialog();
+						kernel_set_interface_mode(INTER_LIMITED_SENTENCES);
+						conv_run(CONV_27_PID_HEAL);
+						conv_export_value(player_has(amulet));
+					}
+				}
+			}
+
+			switch (local->lani_pid_action) {
+			case PID_TALK_TO_LANI:
+				lani_pid_reset_frame   = 31;
+				local->lani_pid_action = BOTH_SHUT_UP;
+				break;
+
+			case LANI_TALK:
+				lani_pid_reset_frame = imath_random(107, 109);
+				++local->lani_pid_talk_count;
+				if (local->lani_pid_talk_count > 15) {
+					local->lani_pid_action     = BOTH_SHUT_UP;
+					local->lani_pid_talk_count = 0;
+					lani_pid_reset_frame       = 110;
+				}
+				break;
+
+			case PID_LOOK_TOM:
+				lani_pid_reset_frame = 28;
+				break;
+
+			case LANI_SIT_UP:
+				lani_pid_reset_frame = 70;
+				break;
+
+			case PID_HEAL:
+				if (player_said_2(talk_to, Llanie)) {
+					local->lani_pid_talk_count = 0;
+					lani_pid_reset_frame       = 31;
+					local->lani_pid_action     = BOTH_SHUT_UP;
+
+				} else {
+					aa[2]                  = kernel_run_animation(kernel_name('h', 1), ROOM_504_DONE_HEALING);
+					local->anim_2_running  = true;
+					lani_pid_reset_frame   = 113;
+					local->lani_pid_action = LANI_DEAD;
+				}
+				break;
+
+			case PID_GET_UP:
+				lani_pid_reset_frame = 115;
+				break;
+
+			case PID_POEM:
+				local->lani_pid_talk_count = 0;
+				lani_pid_reset_frame       = 31;
+				local->lani_pid_action     = BOTH_SHUT_UP;
+				break;
+
+			default:
+				if (local->lani_pid_action == BOTH_SHUT_UP) {
+					if (player_said_2(talk_to, Llanie) && !global[said_poem_in_504]) {
+						text_show(50425);
+						kernel_init_dialog();
+						kernel_set_interface_mode(INTER_LIMITED_SENTENCES);
+						player.commands_allowed = false;
+						conv_run(CONV_42_POEM);
+						conv_export_value(0);
+						conv_export_value(game.difficulty);
+						conv_show_boxes = false;
+					}
+				}
+				lani_pid_reset_frame = 27;
+				break;
+			}
+			break;
+
+		case 30:
+			if (local->lani_pid_action == PID_LOOK_TOM) {
+				lani_pid_reset_frame = 29;
+			} else {
+				lani_pid_reset_frame = 30;
+			}
+			break;
+
+		case 93:
+		case 103:
+			conv_release();
+			break;
+
+		case 72:
+		case 73:
+		case 74:
+		case 75:
+		case 76:
+		case 77:
+		case 94:
+		case 167:
+		case 104:
+		case 160:
+		case 161:
+		case 162:
+			if (local->lani_pid_frame == 72) {
+				local->lani_pid_action = PID_LOOK_TOM;
+			}
+
+			switch (local->lani_pid_action) {
+			case LANI_TALK:
+				lani_pid_reset_frame = imath_random(72, 76);
+				++local->lani_pid_talk_count;
+				if (local->lani_pid_talk_count > 15) {
+					local->lani_pid_action     = BOTH_SHUT_UP;
+					local->lani_pid_talk_count = 0;
+					lani_pid_reset_frame       = 103;
+				}
+				break;
+
+			case LANI_KISS:
+				lani_pid_reset_frame   = 78;
+				local->lani_pid_action = BOTH_SHUT_UP;
+				break;
+
+			case LANI_LAY_DOWN:
+				lani_pid_reset_frame   = 104;
+				local->lani_pid_action = BOTH_SHUT_UP;
+				break;
+
+			case PID_LOOK_TOM:
+				lani_pid_reset_frame = 166;
+				break;
+
+			case GIVE:
+				lani_pid_reset_frame   = 94;
+				local->lani_pid_action = BOTH_SHUT_UP;
+				break;
+
+			case PID_TALK_TO_LANI:
+				lani_pid_reset_frame = imath_random(159, 161);
+				++local->lani_pid_talk_count;
+				if (local->lani_pid_talk_count > 15) {
+					local->lani_pid_action     = BOTH_SHUT_UP;
+					local->lani_pid_talk_count = 0;
+					lani_pid_reset_frame       = 103;
+				}
+				break;
+
+			case PID_GET_UP:
+				lani_pid_reset_frame = 104;
+				break;
+
+			default:
+				lani_pid_reset_frame = 103;
+				break;
+			}
+			break;
+		}
+
+		if (lani_pid_reset_frame >= 0) {
+			kernel_reset_animation(aa[0], lani_pid_reset_frame);
+			local->lani_pid_frame = lani_pid_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_tom_poking() {
+	int poking_reset_frame;
+	int random;
+
+	if (kernel_anim[aa[1]].frame != local->poking_frame) {
+		local->poking_frame = kernel_anim[aa[1]].frame;
+		poking_reset_frame  = -1;
+
+		switch (local->poking_frame) {
+		case 1:
+		case 44:
+			switch (local->poking_action) {
+			case TOM_SHUT_UP:
+				++local->poking_talk_count;
+				if (local->poking_talk_count > imath_random(20, 30)) {
+					local->poking_talk_count = 0;
+					poking_reset_frame       = imath_random(0, 1);
+				} else {
+					poking_reset_frame = 0;
+				}
+				break;
+
+			default:
+				poking_reset_frame = 1;
+				break;
+			}
+			break;
+
+		case 3:
+		case 42:
+		case 53:
+		case 23:
+			switch (local->poking_action) {
+			case TOM_SHUT_UP:
+				++local->poking_talk_count;
+				if (local->poking_talk_count > imath_random(12, 20)) {
+					random = imath_random(1, 5);
+					switch (random) {
+					case 1: poking_reset_frame = 42;  break;
+					case 2: poking_reset_frame = 2;   break;
+					case 3: poking_reset_frame = 19;  break;
+					case 4: poking_reset_frame = 23;  break;
+					case 5: poking_reset_frame = 3;   break;
+					}
+					local->poking_talk_count = 0;
+
+					if (local->prevent) {
+						poking_reset_frame = 3;
+					}
+
+					if (local->pid_is_kneeling) {
+						if (poking_reset_frame == 23) {
+							poking_reset_frame = 3;
+						}
+					}
+
+				} else {
+					poking_reset_frame = 2;
+				}
+				break;
+
+			case TOM_REVEAL:
+				*conv_my_next_start = conv027_quickie_only;
+				conv_abort();
+
+				kernel_abort_animation(aa[1]);
+				aa[3] = kernel_run_animation(kernel_name('t', 2), 0);
+				kernel_synch(KERNEL_ANIM, aa[3], KERNEL_NOW, 0);
+
+				local->tom_talk_action = TOM_TALK;
+				local->anim_3_running  = true;
+				local->anim_1_running  = false;
+				poking_reset_frame     = -1;
+				break;
+
+			default:
+				poking_reset_frame = 3;
+				break;
+			}
+			break;
+
+		case 5:
+		case 6:
+		case 7:
+		case 19:
+			switch (local->poking_action) {
+			case TOM_SHUT_UP:
+				++local->poking_talk_count;
+				if (local->poking_talk_count > imath_random(15, 30)) {
+					local->poking_talk_count = 0;
+					random = imath_random(1, 2);
+					if (random == 1) {
+						poking_reset_frame = 4;
+					} else {
+						poking_reset_frame = 39;
+					}
+				} else {
+					poking_reset_frame = 4;
+				}
+				break;
+
+			case TOM_REVEAL:
+				poking_reset_frame = 39;
+				break;
+
+			case TOM_TALK:
+				poking_reset_frame = imath_random(4, 6);
+				++local->poking_talk_count;
+				if (local->poking_talk_count > 17) {
+					local->poking_action     = TOM_SHUT_UP;
+					local->poking_talk_count = 0;
+					poking_reset_frame       = 39;
+				}
+				break;
+
+			case TOM_LOOK_AT_HEAL:
+				if (!local->ready_to_heal) {
+					poking_reset_frame = 4;
+
+				} else {
+
+					kernel_abort_animation(aa[1]);
+					local->anim_1_running  = false;
+					poking_reset_frame     = -1;
+					local->ready_to_heal   = false;
+					player.walker_visible  = false;
+					local->lani_pid_action = PID_HEAL;
+
+					seq[fx_look_at_heal] = kernel_seq_stamp(ss[fx_look_at_heal], false, KERNEL_FIRST);
+					kernel_seq_depth(seq[fx_look_at_heal], 14);
+					kernel_synch(KERNEL_SERIES, seq[fx_look_at_heal], KERNEL_NOW, 0);
+
+					if (local->pid_is_kneeling) {
+						kernel_reset_animation(aa[0], 27);
+					} else {
+						kernel_reset_animation(aa[0], 20);
+					}
+					local->pid_is_kneeling = true;
+					kernel_synch(KERNEL_ANIM, aa[0], KERNEL_PLAYER, 0);
+				}
+				break;
+			}
+			break;
+
+		case 12:
+		case 13:
+		case 14:
+			switch (local->poking_action) {
+			case TOM_TALK:
+				poking_reset_frame = imath_random(11, 13);
+				++local->poking_talk_count;
+				if (local->poking_talk_count > 17) {
+					local->poking_action     = TOM_SHUT_UP;
+					local->poking_talk_count = 0;
+					poking_reset_frame       = 14;
+				}
+				break;
+
+			default:
+				poking_reset_frame = 14;
+				break;
+			}
+			break;
+
+		case 21:
+			switch (local->poking_action) {
+			case TOM_SHUT_UP:
+				++local->poking_talk_count;
+				if (local->poking_talk_count > imath_random(5, 9)) {
+					local->poking_talk_count = 0;
+					poking_reset_frame       = imath_random(20, 21);
+				} else {
+					poking_reset_frame = 20;
+				}
+				break;
+
+			default:
+				poking_reset_frame = 21;
+				break;
+			}
+			break;
+
+		case 37:
+			switch (local->poking_action) {
+			case TOM_SHUT_UP:
+				++local->poking_talk_count;
+				if (local->poking_talk_count > imath_random(10, 14)) {
+					random = imath_random(1, 5);
+					switch (random) {
+					case 1:
+						poking_reset_frame       = 36;
+						local->poking_talk_count = 0;
+						break;
+					case 2:
+						poking_reset_frame       = 44;
+						local->poking_talk_count = 0;
+						break;
+					default:
+						poking_reset_frame       = 31;
+						local->poking_talk_count = 40;
+						break;
+					}
+				} else {
+					poking_reset_frame = 36;
+				}
+				break;
+
+			default:
+				poking_reset_frame = 44;
+				break;
+			}
+			break;
+		}
+
+		if (poking_reset_frame >= 0) {
+			kernel_reset_animation(aa[1], poking_reset_frame);
+			local->poking_frame = poking_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_reveal() {
+	int reveal_reset_frame;
+	int id;
+
+	if (kernel_anim[aa[3]].frame != local->reveal_frame) {
+		local->reveal_frame = kernel_anim[aa[3]].frame;
+		reveal_reset_frame  = -1;
+
+		switch (local->reveal_frame) {
+		case 7:
+			local->lani_pid_action = LANI_SIT_UP;
+			break;
+
+		case 24:
+			kernel_abort_animation(aa[3]);
+			aa[4] = kernel_run_animation(kernel_name('t', 3), 0);
+			kernel_reset_animation(aa[4], 25);
+			kernel_synch(KERNEL_ANIM, aa[4], KERNEL_NOW, 0);
+
+			local->poking_action  = TOM_SHUT_UP;
+			local->anim_4_running = true;
+			local->anim_3_running = false;
+			reveal_reset_frame    = -1;
+
+			conv_run(CONV_27_PID_HEAL);
+			conv_export_value(player_has(amulet));
+			break;
+
+		case 63:
+			kernel_abort_animation(aa[3]);
+			aa[1] = kernel_run_animation(kernel_name('t', 1), 0);
+			kernel_reset_animation(aa[1], 3);
+			kernel_synch(KERNEL_ANIM, aa[1], KERNEL_NOW, 0);
+
+			local->poking_action    = TOM_SHUT_UP;
+			local->anim_1_running   = true;
+			local->anim_3_running   = false;
+			reveal_reset_frame      = -1;
+			player.commands_allowed = true;
+
+			id = kernel_add_dynamic(words_Ner_Tom, words_walk_to, SYNTAX_SINGULAR_MASC, KERNEL_NONE,
+			                        0, 0, 0, 0);
+			kernel_dynamic_hot[id].prep = PREP_ON;
+			kernel_dynamic_walk(id, WALK_TO_HERMIT_X, WALK_TO_HERMIT_Y, FACING_NORTHWEST);
+			kernel_dynamic_anim(id, aa[1], 0);
+
+			if (global[llanie_status] != IS_SAVED) {
+				conv_run(CONV_26_PID_PRE_HEAL);
+				conv_export_value(global[put_bundle_on_llanie_504]);
+				conv_export_value(global[said_poem_in_504]);
+				conv_export_value(global[tried_to_heal_llanie_504]);
+				conv_export_value(player_has(shifter_ring));
+			}
+			break;
+		}
+
+		if (reveal_reset_frame >= 0) {
+			kernel_reset_animation(aa[3], reveal_reset_frame);
+			local->reveal_frame = reveal_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_tom_talk() {
+	int tom_talk_reset_frame;
+	int random;
+
+	if (kernel_anim[aa[4]].frame != local->tom_talk_frame) {
+		local->tom_talk_frame = kernel_anim[aa[4]].frame;
+		tom_talk_reset_frame  = -1;
+
+		switch (local->tom_talk_frame) {
+
+		case 25:
+		case 38:
+		case 39:
+			switch (local->tom_talk_action) {
+			case TOM_SHUT_UP:
+				++local->tom_talk_talk_count;
+				if (local->tom_talk_talk_count > imath_random(12, 20)) {
+					local->tom_talk_talk_count = 0;
+					random = imath_random(1, 3);
+					switch (random) {
+					case 1: tom_talk_reset_frame = 24;  break;
+					case 2: tom_talk_reset_frame = 37;  break;
+					case 3: tom_talk_reset_frame = 38;  break;
+					}
+				} else {
+					tom_talk_reset_frame = local->tom_talk_frame - 1;
+				}
+				break;
+
+			case TOM_TALK:
+				tom_talk_reset_frame = 25;
+				break;
+
+			case TOM_HIDE:
+				kernel_abort_animation(aa[4]);
+				aa[3] = kernel_run_animation(kernel_name('t', 2), 0);
+				kernel_reset_animation(aa[3], 40);
+				kernel_synch(KERNEL_ANIM, aa[3], KERNEL_NOW, 0);
+
+				local->poking_action  = TOM_SHUT_UP;
+				local->anim_3_running = true;
+				local->anim_4_running = false;
+				tom_talk_reset_frame  = -1;
+				break;
+			}
+			break;
+
+		case 28:
+		case 29:
+		case 30:
+		case 31:
+		case 32:
+		case 33:
+			switch (local->tom_talk_action) {
+			case TOM_TALK:
+				tom_talk_reset_frame = imath_random(27, 32);
+				++local->tom_talk_talk_count;
+				if (local->tom_talk_talk_count > 17) {
+					local->tom_talk_action     = TOM_SHUT_UP;
+					local->tom_talk_talk_count = 0;
+					tom_talk_reset_frame       = 33;
+				}
+				break;
+
+			case TOM_SHUT_UP:
+				tom_talk_reset_frame = 33;
+				break;
+			}
+			break;
+		}
+
+		if (tom_talk_reset_frame >= 0) {
+			kernel_reset_animation(aa[4], tom_talk_reset_frame);
+			local->tom_talk_frame = tom_talk_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_heal() {
+	int heal_reset_frame;
+
+	if (kernel_anim[aa[2]].frame != local->heal_frame) {
+		local->heal_frame = kernel_anim[aa[2]].frame;
+		heal_reset_frame  = -1;
+
+		switch (local->heal_frame) {
+		case 3:
+			local->heal_talk_count = 0;
+			if (local->purpose_for_healing < HEAL || local->purpose_for_healing == NEW) {
+				heal_reset_frame = 31;
+			}
+			if (local->purpose_for_healing == BUNDLE ||
+			    local->purpose_for_healing == NEW) {
+				sound_play(N_FarEchos);
+			}
+			break;
+
+		case 4:
+			kernel_reset_animation(aa[0], 164);
+			break;
+
+		case 32:
+			if (local->purpose_for_healing == BUNDLE) {
+				inter_move_object(medicine_bundle, 504);
+				text_show(50427);
+				global[player_score] += 2;
+				sound_play(N_TenseMusic);
+
+			} else if (local->purpose_for_healing == NEW) {
+				inter_move_object(new_bundle, 504);
+				text_show(50427);
+				global[player_score] += 2;
+				sound_play(N_TenseMusic);
+
+			} else if (local->purpose_for_healing == POEM) {
+				/* no action */
+
+			} else if (global[put_bundle_on_llanie_504] &&
+			           global[said_poem_in_504]) {
+				if (local->purpose_for_healing == HEAL) {
+					text_show(50428);
+				} else if (local->purpose_for_healing == HEAL_CRYSTAL) {
+					text_show(50439);
+					inter_move_object(crystal_ball, NOWHERE);
+					text_show(970);
+				}
+
+			} else {
+				++local->heal_talk_count;
+				if (local->heal_talk_count < 10) {
+					heal_reset_frame = 31;
+
+				} else if (player_said_1(crystal_ball)) {
+					text_show(50438);
+
+				} else if (game.difficulty == HARD_MODE) {
+					text_show(50430);
+
+				} else {
+					text_show(50429);
+				}
+			}
+			break;
+		}
+
+		if (heal_reset_frame >= 0) {
+			kernel_reset_animation(aa[2], heal_reset_frame);
+			local->heal_frame = heal_reset_frame;
+		}
+	}
+}
+
+static void room_504_init() {
+	int id;
+
+	if (!player.been_here_before) ++global[dragon_high_scene];
+	if (!player.been_here_before) ++global[player_score];
+
+	if (global[monster_is_dead]) {
+		global[found_lani_504] = true;
+	}
 
-void room_504_init() {
+	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->ready_to_heal       = false;
+		local->prevent             = false;
+		local->purpose_for_healing = false;
+		local->pid_is_kneeling     = false;
+		local->line_1[0]           = '\0';
+		local->line_2[0]           = '\0';
+		local->line_3[0]           = '\0';
+		local->working_on_line     = 1;
+		local->got_it              = 0;
+		local->shit                = false;
+	}
 
+	if (global[player_persona] == PLAYER_IS_PID)
+		kernel.quotes = quote_load(quote_poem_one_how,
+		                           quote_poem_one_thou,
+		                           quote_poem_one_soft,
+		                           quote_poem_two_art,
+		                           quote_poem_two_do,
+		                           quote_poem_two_what,
+		                           quote_poem_three_light,
+		                           quote_poem_three_i,
+		                           quote_poem_three_a,
+		                           quote_poem_four_through,
+		                           quote_poem_four_rose,
+		                           quote_poem_four_love,
+		                           quote_poem_five_but,
+		                           quote_poem_five_yonder,
+		                           quote_poem_five_thee,
+		                           quote_poem_six_let,
+		                           quote_poem_six_no,
+		                           quote_poem_six_window,
+		                           quote_poem_seven_breaks,
+		                           quote_poem_seven_for,
+		                           quote_poem_seven_me,
+		                           quote_poem_eight_no,
+		                           quote_poem_eight_count,
+		                           quote_poem_eight_tis,
+		                           quote_poem_nine_rose,
+		                           quote_poem_nine_the,
+		                           quote_poem_nine_bird,
+		                           quote_poem_ten_ways,
+		                           quote_poem_ten_and,
+		                           quote_poem_ten_as,
+		                           quote_poem_eleven_and,
+		                           quote_poem_eleven_fair,
+		                           quote_poem_eleven_one,
+		                           quote_poem_twelve_did,
+		                           quote_poem_twelve_bird,
+		                           quote_poem_twelve_two,
+		                           quote_poem_thirteen_ever,
+		                           quote_poem_thirteen_three,
+		                           quote_poem_thirteen_bird,
+		                           quote_poem_fourteen_are,
+		                           quote_poem_fourteen_is,
+		                           quote_poem_fourteen_grow,
+		                           quote_poem_easy_14_are,
+		                           quote_poem_easy_14_is,
+		                           quote_poem_easy_14_grow,
+		                           quote_poem_fifteen_enough,
+		                           quote_poem_fifteen_in,
+		                           quote_poem_fifteen_the,
+		                           quote_poem_sixteen_for,
+		                           quote_poem_sixteen_any,
+		                           quote_poem_sixteen_sun,
+		                           quote_poem_seventeen_thee,
+		                           quote_poem_seventeen_land,
+		                           quote_poem_seventeen_oh, 0);
+
+	ss[fx_look_at_heal] = kernel_load_series(kernel_name('e', 3), false);
+	ss[fx_lani]         = kernel_load_series(kernel_name('e', 0), false);
+	ss[fx_fire]         = kernel_load_series(kernel_name('x', 1), false);
+
+	seq[fx_fire] = kernel_seq_forward(ss[fx_fire], false, 6, 0, 0, 0);
+	kernel_seq_depth(seq[fx_fire], 14);
+	kernel_seq_range(seq[fx_fire], KERNEL_FIRST, KERNEL_LAST);
+
+	if (previous_room != KERNEL_RESTORING_GAME) {
+		player.x      = PLAYER_X_FROM_503;
+		player.y      = PLAYER_Y_FROM_503;
+		player.facing = FACING_NORTHEAST;
+	}
+
+	if (global[player_persona] == PLAYER_IS_PID) {
+
+		if (!global[make_504_empty]) {
+
+			conv_get(CONV_42_POEM);
+			conv_get(CONV_26_PID_PRE_HEAL);
+			conv_get(CONV_27_PID_HEAL);
+
+			aa[0]                  = kernel_run_animation(kernel_name('l', 1), 0);
+			local->anim_0_running  = true;
+			local->lani_pid_action = LANI_DEAD;
+
+			aa[1]                = kernel_run_animation(kernel_name('t', 1), 0);
+			local->poking_action = TOM_SHUT_UP;
+			local->anim_1_running = true;
+
+			if (global[llanie_status] == IS_SAVED) {
+				local->dynamic_hs = kernel_add_dynamic(words_Ner_Tom, words_walk_to, SYNTAX_SINGULAR_MASC, KERNEL_NONE,
+				                                       0, 0, 0, 0);
+			} else {
+				local->dynamic_hs = kernel_add_dynamic(words_hermit, words_walk_to, SYNTAX_MASC_NOT_PROPER, KERNEL_NONE,
+				                                       0, 0, 0, 0);
+			}
+			kernel_dynamic_hot[local->dynamic_hs].prep = PREP_ON;
+			kernel_dynamic_walk(local->dynamic_hs, WALK_TO_HERMIT_X, WALK_TO_HERMIT_Y, FACING_NORTHWEST);
+			kernel_dynamic_anim(local->dynamic_hs, aa[1], 0);
+
+			if (conv_restore_running == CONV_26_PID_PRE_HEAL) {
+				conv_run(CONV_26_PID_PRE_HEAL);
+				conv_export_value(global[put_bundle_on_llanie_504]);
+				conv_export_value(global[said_poem_in_504]);
+				conv_export_value(global[tried_to_heal_llanie_504]);
+				conv_export_value(player_has(shifter_ring));
+			}
+
+			if (conv_restore_running == CONV_42_POEM) {
+				kernel_init_dialog();
+				kernel_set_interface_mode(INTER_LIMITED_SENTENCES);
+				player.commands_allowed = false;
+				conv_run(CONV_42_POEM);
+				conv_export_value(0);
+				conv_export_value(game.difficulty);
+				conv_show_boxes = false;
+				if (local->line_1[0] != '\0') {
+					local->quote_id = kernel_message_add(local->line_1,
+					                                     8, 5, MESSAGE_COLOR, 999999, 0, 0);
+				}
+				if (local->line_2[0] != '\0') {
+					local->quote_id = kernel_message_add(local->line_2,
+					                                     8, 22, MESSAGE_COLOR, 999999, 0, 0);
+				}
+				if (local->line_3[0] != '\0') {
+					local->quote_id = kernel_message_add(local->line_3,
+					                                     8, 39, MESSAGE_COLOR, 999999, 0, 0);
+				}
+			}
+
+			if (local->pid_is_kneeling) {
+				kernel_reset_animation(aa[0], 28);
+				player.x              = LANI_X;
+				player.y              = LANI_Y;
+				player.facing         = FACING_NORTHEAST;
+				player.walker_visible = false;
+			} else {
+				kernel_reset_animation(aa[0], 114);
+			}
+
+			if (!global[been_in_504_as_pid]) {
+				global[been_in_504_as_pid] = true;
+				player.commands_allowed = false;
+				player_walk(WALK_TO_HERMIT_X, WALK_TO_HERMIT_Y, FACING_NORTHWEST);
+				player_walk_trigger(ROOM_504_TALK_TO_HERMIT);
+			}
+
+		} else {
+			kernel_flip_hotspot(words_blanket, false);
+			kernel_flip_hotspot(words_Llanie, false);
+		}
+
+	} else {
+		if (global[llanie_status] == SHE_FELL) {
+			conv_get(CONV_25_KING_AFTER_FALL);
+
+			aa[0]                  = kernel_run_animation(kernel_name('l', 1), 0);
+			local->anim_0_running  = true;
+			local->lani_pid_action = LANI_DEAD;
+			kernel_reset_animation(aa[0], 114);
+
+			if (!global[seen_lani_dead_1st_time]) {
+				global[seen_lani_dead_1st_time] = true;
+				player.commands_allowed = false;
+				player_walk(WALK_TO_HERMIT_X, WALK_TO_HERMIT_Y, FACING_NORTHWEST);
+				player_walk_trigger(ROOM_504_TALK_TO_HERMIT + 1);
+			}
+
+		} else {
+			conv_get(CONV_24_KING);
+			kernel_flip_hotspot(words_blanket, false);
+			kernel_flip_hotspot(words_Llanie, false);
+		}
+
+		aa[1]                = kernel_run_animation(kernel_name('t', 1), 0);
+		local->poking_action = TOM_SHUT_UP;
+		local->anim_1_running = true;
+
+		id = kernel_add_dynamic(words_hermit, words_walk_to, SYNTAX_MASC_NOT_PROPER, KERNEL_NONE,
+		                        0, 0, 0, 0);
+		kernel_dynamic_hot[id].prep = PREP_ON;
+		kernel_dynamic_walk(id, WALK_TO_HERMIT_X, WALK_TO_HERMIT_Y, FACING_NORTHWEST);
+		kernel_dynamic_anim(id, aa[1], 0);
+
+		if (conv_restore_running == CONV_25_KING_AFTER_FALL) {
+			conv_run(CONV_25_KING_AFTER_FALL);
+		} else if (conv_restore_running == CONV_24_KING) {
+			conv_run(CONV_24_KING);
+		}
+	}
+
+	if (object_is_here(medicine_bundle) || object_is_here(new_bundle)) {
+		if (global[llanie_status] != IS_SAVED) {
+			sound_play(N_TenseMusic);
+		} else {
+			section_5_music();
+		}
+	} else {
+		section_5_music();
+	}
 }
 
-void room_504_daemon() {
+static void room_504_daemon() {
+	if (kernel.trigger == ROOM_504_DONE_HEALING) {
+		kernel_abort_animation(aa[2]);
+		local->anim_2_running = false;
+		kernel_reset_animation(aa[0], 37);
+		kernel_synch(KERNEL_ANIM, aa[0], KERNEL_NOW, 0);
+	}
+
+	if (local->anim_0_running) {
+		handle_animation_lani_pid();
+	}
+
+	if (local->anim_1_running) {
+		handle_animation_tom_poking();
+	}
+
+	if (local->anim_2_running) {
+		handle_animation_heal();
+	}
 
+	if (local->anim_3_running) {
+		handle_animation_reveal();
+	}
+
+	if (local->anim_4_running) {
+		handle_animation_tom_talk();
+	}
+
+	if (kernel.trigger == ROOM_504_TALK_TO_HERMIT) {
+		player.commands_allowed = true;
+		conv_run(CONV_26_PID_PRE_HEAL);
+		conv_export_value(global[put_bundle_on_llanie_504]);
+		conv_export_value(global[said_poem_in_504]);
+		conv_export_value(global[tried_to_heal_llanie_504]);
+		conv_export_value(player_has(shifter_ring));
+	}
+
+	if (kernel.trigger == ROOM_504_TALK_TO_HERMIT + 1) {
+		player.commands_allowed = true;
+		conv_run(CONV_25_KING_AFTER_FALL);
+	}
 }
 
-void room_504_pre_parser() {
+static void process_conv_poem() {
+	int me_trig_flag  = false;
+	int selected      = 0;
+
+	switch (player_verb) {
+	case conv042_one_restart:
+	case conv042_one_abort:
+	case conv042_two_restart:
+	case conv042_two_abort:
+	case conv042_three_restart:
+	case conv042_three_abort:
+	case conv042_four_restart:
+	case conv042_four_abort:
+	case conv042_five_restart:
+	case conv042_five_abort:
+	case conv042_six_restart:
+	case conv042_six_abort:
+	case conv042_seven_restart:
+	case conv042_seven_abort:
+	case conv042_eight_restart:
+	case conv042_eight_abort:
+	case conv042_nine_restart:
+	case conv042_nine_abort:
+	case conv042_ten_restart:
+	case conv042_ten_abort:
+	case conv042_eleven_restart:
+	case conv042_eleven_abort:
+	case conv042_twelve_restart:
+	case conv042_twelve_abort:
+	case conv042_thirteen_restart:
+	case conv042_thirteen_abort:
+	case conv042_fourteen_restart:
+	case conv042_fourteen_abort:
+	case conv042_easy_14_restart:
+	case conv042_easy_14_abort:
+	case conv042_fifteen_restart:
+	case conv042_fifteen_abort:
+	case conv042_sixteen_restart:
+	case conv042_sixteen_abort:
+	case conv042_seventeen_restart:
+	case conv042_seventeen_abort:
+		conv_show_boxes = true;
+		break;
+	}
+
+	if (kernel.trigger == ROOM_504_ME_TALK) {
+		switch (player_verb) {
+		case conv042_one_first:        selected = quote_poem_one_how;        break;
+		case conv042_one_second:       selected = quote_poem_one_thou;       ++local->got_it; break;
+		case conv042_one_third:        selected = quote_poem_one_soft;       break;
+
+		case conv042_two_first:        selected = quote_poem_two_art;        ++local->got_it; break;
+		case conv042_two_second:       selected = quote_poem_two_do;         break;
+		case conv042_two_third:        selected = quote_poem_two_what;       break;
+
+		case conv042_three_first:      selected = quote_poem_three_light;    break;
+		case conv042_three_second:     selected = quote_poem_three_i;        break;
+		case conv042_three_third:      selected = quote_poem_three_a;        ++local->got_it; break;
+
+		case conv042_four_first:       selected = quote_poem_four_through;   break;
+		case conv042_four_second:      selected = quote_poem_four_rose;      ++local->got_it; break;
+		case conv042_four_third:       selected = quote_poem_four_love;      break;
 
+		case conv042_five_first:       selected = quote_poem_five_but;       ++local->got_it; break;
+		case conv042_five_second:      selected = quote_poem_five_yonder;    break;
+		case conv042_five_third:       selected = quote_poem_five_thee;      break;
+
+		case conv042_six_first:        selected = quote_poem_six_let;        break;
+		case conv042_six_second:       selected = quote_poem_six_no;         ++local->got_it; break;
+		case conv042_six_third:        selected = quote_poem_six_window;     break;
+
+		case conv042_seven_first:      selected = quote_poem_seven_breaks;   break;
+		case conv042_seven_second:     selected = quote_poem_seven_for;      ++local->got_it; break;
+		case conv042_seven_third:      selected = quote_poem_seven_me;       break;
+
+		case conv042_eight_first:      selected = quote_poem_eight_no;       ++local->got_it; break;
+		case conv042_eight_second:     selected = quote_poem_eight_count;    break;
+		case conv042_eight_third:      selected = quote_poem_eight_tis;      break;
+
+		case conv042_nine_first:       selected = quote_poem_nine_rose;      ++local->got_it; break;
+		case conv042_nine_second:      selected = quote_poem_nine_the;       break;
+		case conv042_nine_third:       selected = quote_poem_nine_bird;      break;
+
+		case conv042_ten_first:        selected = quote_poem_ten_ways;       break;
+		case conv042_ten_second:       selected = quote_poem_ten_and;        break;
+		case conv042_ten_third:        selected = quote_poem_ten_as;         ++local->got_it; break;
+
+		case conv042_eleven_first:     selected = quote_poem_eleven_and;     break;
+		case conv042_eleven_second:    selected = quote_poem_eleven_fair;    ++local->got_it; break;
+		case conv042_eleven_third:     selected = quote_poem_eleven_one;     break;
+
+		case conv042_twelve_first:     selected = quote_poem_twelve_did;     ++local->got_it; break;
+		case conv042_twelve_second:    selected = quote_poem_twelve_bird;    break;
+		case conv042_twelve_third:     selected = quote_poem_twelve_two;     break;
+
+		case conv042_thirteen_first:   selected = quote_poem_thirteen_ever;  ++local->got_it; break;
+		case conv042_thirteen_second:  selected = quote_poem_thirteen_three; break;
+		case conv042_thirteen_third:   selected = quote_poem_thirteen_bird;  break;
+
+		case conv042_fourteen_first:   selected = quote_poem_fourteen_are;   break;
+		case conv042_fourteen_second:  selected = quote_poem_fourteen_is;    break;
+		case conv042_fourteen_third:   selected = quote_poem_fourteen_grow;  ++local->got_it; break;
+
+		case conv042_easy_14_first:    selected = quote_poem_easy_14_are;    break;
+		case conv042_easy_14_second:   selected = quote_poem_easy_14_is;     break;
+		case conv042_easy_14_third:    selected = quote_poem_easy_14_grow;   ++local->got_it; break;
+
+		case conv042_fifteen_first:    selected = quote_poem_fifteen_enough; break;
+		case conv042_fifteen_second:   selected = quote_poem_fifteen_in;     ++local->got_it; break;
+		case conv042_fifteen_third:    selected = quote_poem_fifteen_the;    break;
+
+		case conv042_sixteen_first:    selected = quote_poem_sixteen_for;    break;
+		case conv042_sixteen_second:   selected = quote_poem_sixteen_any;    ++local->got_it; break;
+		case conv042_sixteen_third:    selected = quote_poem_sixteen_sun;    break;
+
+		case conv042_seventeen_first:  selected = quote_poem_seventeen_thee; break;
+		case conv042_seventeen_second: selected = quote_poem_seventeen_land; ++local->got_it; break;
+		case conv042_seventeen_third:  selected = quote_poem_seventeen_oh;   break;
+
+		case conv042_whoops_b_b:
+			kernel_message_purge();
+			kernel_timing_trigger(HALF_SECOND, ROOM_504_RUN_POEM_CONV);
+			local->working_on_line = 1;
+			local->line_1[0] = '\0';
+			local->line_2[0] = '\0';
+			local->line_3[0] = '\0';
+			local->got_it    = 0;
+			break;
+
+		case conv042_later_b_b:
+			kernel_timing_trigger(HALF_SECOND, ROOM_504_END_POEM + 1);
+			local->working_on_line = 1;
+			local->line_1[0] = '\0';
+			local->line_2[0] = '\0';
+			local->line_3[0] = '\0';
+			local->got_it    = 0;
+			break;
+		}
+
+		if (selected) {
+			local->lani_pid_action = PID_POEM;
+
+			if (local->working_on_line == 1) {
+				if (font_string_width(kernel_message_font, local->line_1, -1) > 278) {
+					++local->working_on_line;
+				} else {
+					if (local->line_1[0] != '\0') {
+						kernel_message_delete(local->quote_id);
+					}
+					Common::strcat_s(local->line_1, quote_string(kernel.quotes, selected));
+					Common::strcat_s(local->line_1, " ");
+					local->quote_id = kernel_message_add(local->line_1,
+					                                     8, 5, MESSAGE_COLOR, 999999, 0, 0);
+				}
+			}
+
+			if (local->working_on_line == 2) {
+				if (font_string_width(kernel_message_font, local->line_2, -1) > 278) {
+					++local->working_on_line;
+				} else {
+					if (local->line_2[0] != '\0') {
+						kernel_message_delete(local->quote_id);
+					}
+					Common::strcat_s(local->line_2, quote_string(kernel.quotes, selected));
+					Common::strcat_s(local->line_2, " ");
+					local->quote_id = kernel_message_add(local->line_2,
+					                                     8, 22, MESSAGE_COLOR, 999999, 0, 0);
+				}
+			}
+
+			if (local->working_on_line == 3) {
+				if (font_string_width(kernel_message_font, local->line_3, -1) > 278) {
+					++local->working_on_line;
+				} else {
+					if (local->line_3[0] != '\0') {
+						kernel_message_delete(local->quote_id);
+					}
+					Common::strcat_s(local->line_3, quote_string(kernel.quotes, selected));
+					Common::strcat_s(local->line_3, " ");
+					local->quote_id = kernel_message_add(local->line_3,
+					                                     8, 39, MESSAGE_COLOR, 999999, 0, 0);
+				}
+			}
+		}
+	}
+
+	if (player_verb == conv042_exit_b_b && !kernel.trigger) {
+		*conv_my_next_start = conv042_pre_poem;
+		conv_abort();
+		me_trig_flag = true;
+
+		if ((game.difficulty == EASY_MODE && local->got_it == 14) ||
+		    (local->got_it == 17)) {
+			kernel_timing_trigger(HALF_SECOND, ROOM_504_END_POEM);
+			global[player_score] += 8;
+
+		} else {
+			local->working_on_line = 1;
+			local->line_1[0] = '\0';
+			local->line_2[0] = '\0';
+			local->line_3[0] = '\0';
+			local->got_it    = 0;
+			kernel_timing_trigger(HALF_SECOND, ROOM_504_END_POEM);
+		}
+	}
+
+	if (!me_trig_flag) {
+		conv_me_trigger(ROOM_504_ME_TALK);
+	}
 }
 
-void room_504_parser() {
+static void process_conv_lani_pid() {
+	int you_trig_flag = false;
+	int me_trig_flag  = false;
+
+	switch (player_verb) {
+	case conv027_inter2_b_b:
+	case conv027_amulet_b_b:
+		conv_hold();
+		you_trig_flag          = true;
+		me_trig_flag           = true;
+		local->lani_pid_action = GIVE;
+		break;
+
+	case conv027_exit_b_b:
+		conv_hold();
+		you_trig_flag          = true;
+		me_trig_flag           = true;
+		local->lani_pid_action = PID_GET_UP;
+		break;
+
+	case conv027_kiss_b_b:
+		conv_hold();
+		you_trig_flag          = true;
+		me_trig_flag           = true;
+		local->lani_pid_action = LANI_KISS;
+		break;
+
+	case conv027_quickie_b_b:
+		conv_hold();
+		you_trig_flag        = true;
+		me_trig_flag         = true;
+		local->poking_action = TOM_REVEAL;
+		break;
+	}
+
+	if (kernel.trigger == ROOM_504_YOU_TALK) {
+		switch (player_verb) {
+		case conv027_seven_only:
+		case conv027_amulet_only:
+		case conv027_stopper_monk:
+		case conv027_inter2_only:
+		case conv027_hello_only:
+		case conv027_explain_one:
+		case conv027_next_one:
+		case conv027_last_one:
+		case conv027_two_only:
+		case conv027_four_only:
+		case conv027_six_only:
+		case conv027_eight_only:
+		case conv027_nogood_hidewhat:
+			if (local->lani_pid_action != LANI_KISS &&
+			    local->lani_pid_action != GIVE       &&
+			    local->lani_pid_action != PID_GET_UP) {
+				local->lani_pid_action = LANI_TALK;
+			}
+			local->tom_talk_action = TOM_SHUT_UP;
+			break;
+
+		case conv027_restart_only:
+			local->poking_action = TOM_TALK;
+			break;
+
+		case conv027_ten_only:
+			break;
+
+		default:
+			if (local->lani_pid_action != LANI_KISS &&
+			    local->lani_pid_action != GIVE       &&
+			    local->lani_pid_action != PID_GET_UP) {
+				local->lani_pid_action = PID_LOOK_TOM;
+			}
+			local->poking_action   = TOM_TALK;
+			local->tom_talk_action = TOM_TALK;
+			break;
+		}
+	}
+
+	if (kernel.trigger == ROOM_504_ME_TALK) {
+		local->lani_pid_action = PID_TALK_TO_LANI;
+		local->tom_talk_action = TOM_SHUT_UP;
+		if (player_verb == conv027_quickie_only ||
+		    player_verb == conv027_hem_only      ||
+		    player_verb == conv027_one_only      ||
+		    player_verb == conv027_two_only) {
+			local->lani_pid_action = PID_LOOK_TOM;
+		}
+	}
+
+	if (!you_trig_flag) {
+		conv_you_trigger(ROOM_504_YOU_TALK);
+	}
 
+	if (!me_trig_flag) {
+		if (player_verb != conv027_restart_only && player_verb != conv027_ten_only) {
+			conv_me_trigger(ROOM_504_ME_TALK);
+		}
+	}
+
+	local->lani_pid_talk_count   = 0;
+	local->tom_talk_talk_count   = 0;
+	local->poking_talk_count     = 0;
+}
+
+static void process_conv_king() {
+	int you_trig_flag = false;
+	int me_trig_flag  = false;
+
+	if (player_verb == conv026_exit_b_b) {
+		if (local->pid_is_kneeling) {
+			local->lani_pid_action = BOTH_SHUT_UP;
+		}
+	}
+
+	if (conv_control.running == CONV_26_PID_PRE_HEAL && player_verb == conv026_last_one) {
+		global[heal_verbs_visible] = true;
+	}
+
+	if (kernel.trigger == ROOM_504_YOU_TALK) {
+		local->poking_action = TOM_TALK;
+	}
+
+	if (kernel.trigger == ROOM_504_ME_TALK) {
+		local->poking_action = TOM_SHUT_UP;
+	}
+
+	if (!you_trig_flag) {
+		conv_you_trigger(ROOM_504_YOU_TALK);
+	}
+
+	if (!me_trig_flag) {
+		conv_me_trigger(ROOM_504_ME_TALK);
+	}
+
+	local->poking_talk_count = 0;
+}
+
+static void room_504_pre_parser() {
+	if (player_said_2(heal, Llanie)) {
+		if (global[llanie_status] != IS_SAVED) {
+			local->prevent = true;
+		}
+	}
+
+	if (player_said_2(invoke_power_of, crystal_ball) ||
+	    player_said_3(put, spirit_bundle, blanket)    ||
+	    player_said_3(put, new_bundle, blanket)        ||
+	    player_said_2(talk_to, Llanie)) {
+		if (global[llanie_status] != IS_SAVED) {
+			player_walk(LANI_X, LANI_Y, FACING_NORTHEAST);
+		}
+	}
+
+	if (local->pid_is_kneeling && player.need_to_walk) {
+		if (player_said_3(put, spirit_bundle, Llanie)  ||
+		    player_said_3(put, spirit_bundle, blanket)  ||
+		    player_said_3(give, spirit_bundle, Llanie)  ||
+		    player_said_3(put, new_bundle, Llanie)      ||
+		    player_said_3(put, new_bundle, blanket)     ||
+		    player_said_3(give, new_bundle, Llanie)     ||
+		    player_said_2(heal, Llanie)                 ||
+		    player_said_2(invoke_power_of, crystal_ball)||
+		    player_said_2(talk_to, hermit)              ||
+		    player_said_2(talk_to, Llanie)) {
+
+			player.need_to_walk = false;
+
+		} else {
+			player.ready_to_walk   = false;
+			local->lani_pid_action = PID_GET_UP;
+		}
+	}
+}
+
+static void room_504_parser() {
+	if (kernel.trigger == ROOM_504_RUN_POEM_CONV) {
+		conv_run(CONV_42_POEM);
+		conv_export_value(0);
+		conv_export_value(game.difficulty);
+		conv_show_boxes = false;
+		player.command_ready = false;
+		return;
+	}
+
+	if (kernel.trigger == ROOM_504_END_POEM + 1) {
+		kernel_message_purge();
+		kernel_set_interface_mode(INTER_BUILDING_SENTENCES);
+		player.commands_allowed = true;
+		player.command_ready = false;
+		return;
+	}
+
+	if (kernel.trigger == ROOM_504_END_POEM) {
+		player.commands_allowed = true;
+		kernel_message_purge();
+		kernel_set_interface_mode(INTER_BUILDING_SENTENCES);
+
+		if ((game.difficulty == EASY_MODE && local->got_it == 14) ||
+		    (local->got_it == 17)) {
+			global[said_poem_in_504] = true;
+			text_show(50426);
+
+		} else {
+			global[tried_to_heal_llanie_504] = true;
+
+			conv_run(CONV_42_POEM);
+			conv_export_value(1);
+			conv_export_value(game.difficulty);
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	if (conv_control.running == CONV_27_PID_HEAL) {
+		process_conv_lani_pid();
+		player.command_ready = false;
+		return;
+	}
+
+	if (conv_control.running == CONV_42_POEM) {
+		process_conv_poem();
+		player.command_ready = false;
+		return;
+	}
+
+	if (conv_control.running == CONV_24_KING          ||
+	    conv_control.running == CONV_25_KING_AFTER_FALL||
+	    conv_control.running == CONV_26_PID_PRE_HEAL) {
+		process_conv_king();
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(walk_through, cave_entrance)) {
+		new_room = 503;
+		player.command_ready = false;
+		return;
+	}
+
+	if (player.look_around) {
+		if (global[make_504_empty]) {
+			text_show(50441);
+
+		} else if (global[player_persona] == PLAYER_IS_KING) {
+			if (global[llanie_status] == BEFORE_FALL) {
+				text_show(50401);
+			} else if (global[llanie_status] == SHE_FELL) {
+				text_show(50411);
+			}
+
+		} else if (global[llanie_status] == IS_SAVED) {
+			text_show(50431);
+
+		} else {
+			text_show(50421);
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_1(look) || player_said_1(look_at)) {
+		if (global[make_504_empty]) {
+			text_show(50442);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(pallet)) {
+			if (global[player_persona] == PLAYER_IS_KING) {
+				if (global[llanie_status] == BEFORE_FALL) {
+					text_show(50402);
+				} else if (global[llanie_status] == SHE_FELL) {
+					text_show(50412);
+				}
+			} else if (global[llanie_status] == IS_SAVED) {
+				text_show(50432);
+			} else {
+				text_show(50422);
+			}
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(Llanie)) {
+			if (global[player_persona] == PLAYER_IS_KING) {
+				text_show(50412);
+			} else if (global[llanie_status] == IS_SAVED) {
+				text_show(50432);
+			} else {
+				text_show(50422);
+			}
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(blanket)) {
+			if (global[player_persona] == PLAYER_IS_KING) {
+				if (global[llanie_status] == BEFORE_FALL) {
+					text_show(50404);
+					player.command_ready = false;
+					return;
+				} else if (global[llanie_status] == SHE_FELL) {
+					text_show(50414);
+					player.command_ready = false;
+					return;
+				}
+			}
+		}
+
+		if (player_said_1(firepit)) {
+			if (global[player_persona] == PLAYER_IS_KING) {
+				if (global[llanie_status] == BEFORE_FALL) {
+					text_show(50407);
+					player.command_ready = false;
+					return;
+				} else if (global[llanie_status] == SHE_FELL) {
+					text_show(50415);
+					player.command_ready = false;
+					return;
+				}
+			} else if (global[llanie_status] == IS_SAVED) {
+				text_show(50434);
+			} else {
+				text_show(50415);
+			}
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(flat_stone)) {
+			text_show(50408);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(cave_entrance)) {
+			if (global[player_persona] == PLAYER_IS_KING) {
+				text_show(50409);
+			} else {
+				text_show(50424);
+			}
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(hermit)) {
+			if (global[llanie_status] == BEFORE_FALL) {
+				text_show(50410);
+			} else if (global[llanie_status] == SHE_FELL) {
+				text_show(50416);
+			}
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(Ner_Tom)) {
+			text_show(50433);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_1(Llanie) || player_said_1(pallet) || player_said_1(blanket)) {
+		if (player_said_1(take) || player_said_1(push) || player_said_1(pull)) {
+			if (global[llanie_status] == SHE_FELL) {
+				text_show(50413);
+				player.command_ready = false;
+				return;
+			}
+		}
+	}
+
+	if (player_said_3(give, soul_egg, Llanie)) {
+		text_show(50435);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(talk_to, hermit)) {
+		if (global[player_persona] == PLAYER_IS_KING) {
+			if (global[llanie_status] == SHE_FELL) {
+				conv_run(CONV_25_KING_AFTER_FALL);
+			} else {
+				conv_run(CONV_24_KING);
+			}
+
+		} else {
+			if (local->pid_is_kneeling) {
+				local->lani_pid_action = PID_LOOK_TOM;
+			}
+			conv_run(CONV_26_PID_PRE_HEAL);
+			conv_export_value(global[put_bundle_on_llanie_504]);
+			conv_export_value(global[said_poem_in_504]);
+			conv_export_value(global[tried_to_heal_llanie_504]);
+			conv_export_value(player_has(shifter_ring));
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(talk_to, Ner_Tom)) {
+		conv_run(CONV_27_PID_HEAL);
+		conv_export_value(player_has(amulet));
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_3(put, spirit_bundle, Llanie)  ||
+	    player_said_3(put, spirit_bundle, blanket)  ||
+	    player_said_3(give, spirit_bundle, Llanie)  ||
+	    player_said_3(put, new_bundle, Llanie)      ||
+	    player_said_3(put, new_bundle, blanket)     ||
+	    player_said_3(give, new_bundle, Llanie)) {
+
+		if (global[put_bundle_on_llanie_504]) {
+			text_show(50445);
+
+		} else if (global[player_persona] == PLAYER_IS_PID) {
+			if (player_said_1(new_bundle)) {
+				local->purpose_for_healing = NEW;
+			} else {
+				local->purpose_for_healing = BUNDLE;
+			}
+			global[put_bundle_on_llanie_504] = true;
+			local->ready_to_heal    = true;
+			local->poking_action    = TOM_LOOK_AT_HEAL;
+			player.commands_allowed = false;
+
+		} else {
+			if (game.difficulty == HARD_MODE) {
+				text_show(50419);
+			} else {
+				text_show(50420);
+			}
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(heal, Llanie) || player_said_2(invoke_power_of, crystal_ball)) {
+		if (global[llanie_status] == IS_SAVED) {
+			if (player_said_1(heal)) {
+				text_show(927);
+				player.command_ready = false;
+				return;
+			}
+		} else {
+			local->ready_to_heal    = true;
+			local->poking_action    = TOM_LOOK_AT_HEAL;
+			player.commands_allowed = false;
+
+			if (!global[said_poem_in_504] || !global[put_bundle_on_llanie_504]) {
+				local->purpose_for_healing = NOTHING;
+
+			} else if (player_said_1(crystal_ball)) {
+				sound_play(N_InvokeCrystalBall);
+				local->purpose_for_healing = HEAL_CRYSTAL;
+			} else {
+				local->purpose_for_healing = HEAL;
+			}
+
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_2(talk_to, Llanie)) {
+		if (global[player_persona] == PLAYER_IS_PID) {
+			if (global[llanie_status] == IS_SAVED) {
+				conv_run(CONV_27_PID_HEAL);
+				conv_export_value(player_has(amulet));
+
+			} else if (global[said_poem_in_504]) {
+				text_show(50440);
+
+			} else {
+				local->lani_pid_action     = BOTH_SHUT_UP;
+				local->purpose_for_healing = POEM;
+				player.commands_allowed    = false;
+			}
+
+		} else {
+			text_show(50418);
+		}
+
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(give, Llanie)) {
+		if (global[player_persona] == PLAYER_IS_PID) {
+			if (global[llanie_status] == IS_SAVED) {
+				text_show(50443);
+			} else {
+				text_show(50423);
+			}
+		} else {
+			text_show(50417);
+		}
+
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(put, firepit) || player_said_2(throw, firepit)) {
+		text_show(50444);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(gaze_into, crystal_ball)) {
+		if (global[player_persona] == PLAYER_IS_PID) {
+			if (!global[said_poem_in_504] || !global[put_bundle_on_llanie_504]) {
+				text_show(50436);
+				player.command_ready = false;
+				return;
+
+			} else if (global[said_poem_in_504] && global[put_bundle_on_llanie_504] &&
+			           global[llanie_status] != IS_SAVED) {
+				text_show(50437);
+				player.command_ready = false;
+				return;
+			}
+		}
+	}
 }
 
 void room_504_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(local->lani_pid_frame);
+	s.syncAsSint16LE(local->lani_pid_action);
+	s.syncAsSint16LE(local->lani_pid_talk_count);
+	s.syncAsSint16LE(local->anim_0_running);
+	s.syncAsSint16LE(local->poking_frame);
+	s.syncAsSint16LE(local->poking_action);
+	s.syncAsSint16LE(local->poking_talk_count);
+	s.syncAsSint16LE(local->anim_1_running);
+	s.syncAsSint16LE(local->heal_frame);
+	s.syncAsSint16LE(local->heal_action);
+	s.syncAsSint16LE(local->heal_talk_count);
+	s.syncAsSint16LE(local->anim_2_running);
+	s.syncAsSint16LE(local->reveal_frame);
+	s.syncAsSint16LE(local->reveal_action);
+	s.syncAsSint16LE(local->reveal_talk_count);
+	s.syncAsSint16LE(local->anim_3_running);
+	s.syncAsSint16LE(local->tom_talk_frame);
+	s.syncAsSint16LE(local->tom_talk_action);
+	s.syncAsSint16LE(local->tom_talk_talk_count);
+	s.syncAsSint16LE(local->anim_4_running);
+	s.syncAsSint16LE(local->ready_to_heal);
+	s.syncAsSint16LE(local->prevent);
+	s.syncAsSint16LE(local->dynamic_hs);
+	s.syncAsSint16LE(local->pid_is_kneeling);
+	s.syncAsSint16LE(local->purpose_for_healing);
+	s.syncAsSint16LE(local->got_it);
+	s.syncBytes((byte *)local->line_1, sizeof(local->line_1));
+	s.syncBytes((byte *)local->line_2, sizeof(local->line_2));
+	s.syncBytes((byte *)local->line_3, sizeof(local->line_3));
+	s.syncAsSint16LE(local->working_on_line);
+	s.syncAsSint16LE(local->quote_id);
+	s.syncAsSint16LE(local->shit);
 }
 
 void room_504_preload() {
-	room_init_code_pointer = room_504_init;
+	room_init_code_pointer       = room_504_init;
 	room_pre_parser_code_pointer = room_504_pre_parser;
-	room_parser_code_pointer = room_504_parser;
-	room_daemon_code_pointer = room_504_daemon;
+	room_parser_code_pointer     = room_504_parser;
+	room_daemon_code_pointer     = room_504_daemon;
+
+	if (global[make_504_empty]) {
+		kernel_initial_variant = 1;
+	}
 
 	section_5_walker();
 	section_5_interface();
+
+	vocab_make_active(words_hermit);
+	vocab_make_active(words_Ner_Tom);
 }
 
 } // namespace Rooms
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room505.cpp b/engines/mads/madsv2/dragonsphere/rooms/room505.cpp
index e18b55604e3..221d1f9a53c 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room505.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room505.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/matte.h"
 #include "mads/madsv2/core/sound.h"
 #include "mads/madsv2/core/text.h"
 #include "mads/madsv2/dragonsphere/mads/conv.h"
@@ -39,40 +41,140 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[15];
+	int16 sequence[15];
+	int16 animation[4];
 };
 
+static Scratch scratch;
+
 #define local (&scratch)
 #define ss    local->sprite
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
+#define ROOM_505_DONE_ANIM       60
 
-void room_505_init() {
+#define PLAYER_X_FROM_503        330
+#define PLAYER_Y_FROM_503        148
+#define WALK_TO_X_FROM_503       306
+#define WALK_TO_Y_FROM_503       143
+#define PLAYER_X_FROM_505        165
+#define PLAYER_Y_FROM_505        144
 
-}
 
-void room_505_daemon() {
+static void room_505_init() {
+	if (previous_room == 511 || previous_room == 512) {
+		if (player_has(magic_belt)) {
+			player.x                = PLAYER_X_FROM_505;
+			player.y                = PLAYER_Y_FROM_505;
+			player.facing           = FACING_SOUTH;
+			aa[0]                   = kernel_run_animation(kernel_name('p', 2), ROOM_505_DONE_ANIM + 1);
+			player.commands_allowed = false;
+			player.walker_visible   = false;
 
-}
+		} else {
+			viewing_at_y = ((video_y - display_y) >> 1);
+			kernel_init_dialog();
+			kernel_set_interface_mode(INTER_LIMITED_SENTENCES);
+
+			sound_play(N_PlayerDies);
+
+			aa[0]                   = kernel_run_animation(kernel_name('p', 1), ROOM_505_DONE_ANIM);
+			player.commands_allowed = false;
+			player.walker_visible   = false;
+		}
 
-void room_505_pre_parser() {
+	} else if (previous_room != KERNEL_RESTORING_GAME) {
+		player_first_walk(PLAYER_X_FROM_503, PLAYER_Y_FROM_503, FACING_NORTHWEST,
+		                  WALK_TO_X_FROM_503, WALK_TO_Y_FROM_503, FACING_NORTHWEST, true);
+	}
 
+	section_5_music();
 }
 
-void room_505_parser() {
+static void room_505_daemon() {
+	if (kernel.trigger == ROOM_505_DONE_ANIM) {
+		if (game.difficulty == EASY_MODE) {
+			text_show(51011);
+		} else {
+			text_show(45);
+		}
+		if (global[pid_just_died]) {
+			global[pid_just_died] = false;
+			new_room = 512;
+		} else {
+			new_room = 510;
+		}
+	}
+
+	if (kernel.trigger == ROOM_505_DONE_ANIM + 1) {
+		player.commands_allowed = true;
+		player.walker_visible   = true;
+		kernel_synch(KERNEL_PLAYER, 0, KERNEL_ANIM, aa[0]);
+	}
+}
+
+static void room_505_pre_parser() {
+	if (player_said_2(walk_down, path_to_east)) {
+		player.walk_off_edge_to_room = 503;
+	}
+}
 
+static void room_505_parser() {
+	if (player.look_around) {
+		text_show(1);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_1(look) || player_said_1(look_at)) {
+		if (player_said_1(rock_tree)) {
+			text_show(2);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(ground)) {
+			text_show(3);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(mountainside)) {
+			text_show(4);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(rock_tumble)) {
+			text_show(5);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(path_to_east)) {
+			text_show(6);
+			player.command_ready = false;
+			return;
+		}
+	}
 }
 
 void room_505_synchronize(Common::Serializer &s) {
-	
+	for (int16 &v : scratch.sprite)    s.syncAsSint16LE(v);
+	for (int16 &v : scratch.sequence)  s.syncAsSint16LE(v);
+	for (int16 &v : scratch.animation) s.syncAsSint16LE(v);
+}
+
+void room_505_error() {
 }
 
 void room_505_preload() {
-	room_init_code_pointer = room_505_init;
+	room_init_code_pointer       = room_505_init;
 	room_pre_parser_code_pointer = room_505_pre_parser;
-	room_parser_code_pointer = room_505_parser;
-	room_daemon_code_pointer = room_505_daemon;
+	room_parser_code_pointer     = room_505_parser;
+	room_daemon_code_pointer     = room_505_daemon;
 
 	section_5_walker();
 	section_5_interface();
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room506.cpp b/engines/mads/madsv2/dragonsphere/rooms/room506.cpp
index 0ae0401388e..4c15f15edac 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room506.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room506.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/matte.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,40 +42,817 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[15];
+	int16 sequence[15];
+	int16 animation[5];
+
+	int16 pid_frame;
+	int16 pid_action;
+	int16 pid_freeze_count;
+	int16 anim_0_running;
+
+	int16 king_frame;
+	int16 king_action;
+	int16 king_talk_count;
+	int16 anim_1_running;
+	int16 anim_2_running;
+	int16 anim_3_running;
+
+	int16 shak_frame;
+	int16 shak_action;
+	int16 shak_count;
+	int16 anim_4_running;
 };
 
+static Scratch scratch;
+
 #define local (&scratch)
 #define ss    local->sprite
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
+#define fx_feather_0   0
+#define fx_feather_1   1
+#define fx_feather_2   2
+#define fx_test_2      3
+
+#define ROOM_506_DONE_KING_ANIM  60
+#define ROOM_506_YOU_TALK        65
+#define ROOM_506_ME_TALK         67
+
+#define PID_FREEZE      0
+#define PID_CLIMB_UP    1
+#define PID_CLIMB_DOWN  2
+#define PID_REACH       3
+
+#define KING_FREEZE     0
+#define KING_REACH      1
+#define KING_BLOW       2
+#define KING_TALK       3
+#define KING_CLIMB_UP   4
+#define KING_CLIMB_DOWN 5
+
+#define FEATHER_X       139
+#define FEATHER_Y       76
+
+#define SHAK_SHUT_UP    0
+#define SHAK_TALK       1
+#define SHAK_LEAVE      2
+
+#define CONV_SHAK       28
+
+
+static void handle_animation_pid() {
+	int pid_reset_frame;
+	int random;
+
+	if (kernel_anim[aa[0]].frame != local->pid_frame) {
+		local->pid_frame = kernel_anim[aa[0]].frame;
+		pid_reset_frame  = -1;
+
+		switch (local->pid_frame) {
+
+		case 206:
+			kernel_seq_delete(seq[fx_feather_1]);
+			kernel_flip_hotspot_loc(words_feathers, false, FEATHER_X, FEATHER_Y);
+			sound_play(N_TakeObjectSnd);
+			inter_give_to_player(feathers);
+			object_examine(feathers, 50611, 0);
+			player.commands_allowed = true;
+			++global[player_score];
+			break;
+
+		case 192:
+			new_room = 508;
+			break;
+
+		case 431:
+			new_room = 502;
+			break;
+
+		case 346:
+		case 85:
+			player.commands_allowed = true;
+			break;
+
+		case 347:
+		case 86:
+		case 219:
+		case 224:
+
+			switch (local->pid_action) {
+
+			case PID_FREEZE:
+				++local->pid_freeze_count;
+				if (local->pid_freeze_count > imath_random(30, 45)) {
+					local->pid_freeze_count = 0;
+					if (imath_random(1, 2) == 1) {
+						pid_reset_frame = 85;
+					} else {
+						pid_reset_frame = 219;
+					}
+				} else {
+					pid_reset_frame = local->pid_frame - 1;
+				}
+				break;
+
+			case PID_CLIMB_UP:
+				pid_reset_frame = 86;
+				break;
+
+			case PID_CLIMB_DOWN:
+				pid_reset_frame = 347;
+				break;
+
+			case PID_REACH:
+				local->pid_action = PID_FREEZE;
+				pid_reset_frame   = 192;
+				break;
+			}
+			break;
+
+		case 222:
+		case 239:
+
+			switch (local->pid_action) {
+
+			case PID_FREEZE:
+				++local->pid_freeze_count;
+				if (local->pid_freeze_count > imath_random(30, 45)) {
+					local->pid_freeze_count = 0;
+					random = imath_random(1, 2) == 1;
+					if (random == 1) {
+						pid_reset_frame = 221;
+					} else if (random == 2) {
+						pid_reset_frame = 222;
+					} else {
+						pid_reset_frame = 224;
+					}
+				} else {
+					pid_reset_frame = local->pid_frame - 1;
+				}
+				break;
+
+			case PID_CLIMB_DOWN:
+			case PID_CLIMB_UP:
+				pid_reset_frame = 222;
+				break;
+
+			case PID_REACH:
+				pid_reset_frame = 224;
+				break;
+			}
+			break;
+
+		case 232:
+
+			switch (local->pid_action) {
+
+			case PID_FREEZE:
+				++local->pid_freeze_count;
+				if (local->pid_freeze_count > imath_random(30, 45)) {
+					local->pid_freeze_count = 0;
+					if (imath_random(1, 2) == 1) {
+						pid_reset_frame = 231;
+					} else {
+						pid_reset_frame = 232;
+					}
+				} else {
+					pid_reset_frame = local->pid_frame - 1;
+				}
+				break;
+
+			case PID_CLIMB_DOWN:
+			case PID_CLIMB_UP:
+				pid_reset_frame = 232;
+				break;
+
+			case PID_REACH:
+				local->pid_action = PID_FREEZE;
+				pid_reset_frame   = 203;
+				break;
+			}
+			break;
+		}
+
+		if (pid_reset_frame >= 0) {
+			kernel_reset_animation(aa[0], pid_reset_frame);
+			local->pid_frame = pid_reset_frame;
+		}
+	}
+}
+
+
+static void handle_animation_climbing_lower() {
+	int king_reset_frame;
+
+	if (kernel_anim[aa[1]].frame != local->king_frame) {
+		local->king_frame = kernel_anim[aa[1]].frame;
+		king_reset_frame  = -1;
+
+		switch (local->king_frame) {
+
+		case 105:
+			kernel_abort_animation(aa[1]);
+			aa[3] = kernel_run_animation(kernel_name('k', 3), 0);
+			kernel_synch(KERNEL_ANIM, aa[3], KERNEL_NOW, 0);
+			player.commands_allowed = true;
+			king_reset_frame        = -1;
+			local->anim_1_running   = false;
+			local->anim_3_running   = true;
+			local->king_action      = KING_FREEZE;
+			local->king_frame       = kernel_anim[aa[3]].frame;
+			break;
+
+		case 211:
+			new_room = 502;
+			break;
+		}
+
+		if (king_reset_frame >= 0) {
+			kernel_reset_animation(aa[1], king_reset_frame);
+			local->king_frame = king_reset_frame;
+		}
+	}
+}
+
+
+static void handle_animation_climbing_upper() {
+	int king_reset_frame;
+
+	if (kernel_anim[aa[2]].frame != local->king_frame) {
+		local->king_frame = kernel_anim[aa[2]].frame;
+		king_reset_frame  = -1;
+
+		switch (local->king_frame) {
+
+		case 200:
+			kernel_abort_animation(aa[2]);
+			aa[3] = kernel_run_animation(kernel_name('k', 3), 0);
+			kernel_synch(KERNEL_ANIM, aa[3], KERNEL_NOW, 0);
+			player.commands_allowed = true;
+			king_reset_frame        = -1;
+			local->anim_2_running   = false;
+			local->anim_3_running   = true;
+			local->king_action      = KING_FREEZE;
+			local->king_frame       = kernel_anim[aa[3]].frame;
+			break;
+
+		case 100:
+			if (!player_has_been_in_room(507)) {
+				new_room = 507;
+			} else {
+				new_room = 508;
+			}
+			break;
+		}
+
+		if (king_reset_frame >= 0) {
+			kernel_reset_animation(aa[2], king_reset_frame);
+			local->king_frame = king_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_king() {
+	int king_reset_frame;
+
+	if (kernel_anim[aa[3]].frame != local->king_frame) {
+		local->king_frame = kernel_anim[aa[3]].frame;
+		king_reset_frame  = -1;
+
+		switch (local->king_frame) {
+		case 18:
+			kernel_seq_delete(seq[fx_feather_1]);
+			kernel_flip_hotspot_loc(words_feathers, false, FEATHER_X, FEATHER_Y);
+			sound_play(N_TakeObjectSnd);
+			inter_give_to_player(feathers);
+			object_examine(feathers, 821, 0);
+			player.commands_allowed = true;
+			++global[player_score];
+			break;
+
+		case 7:
+			if (global[shak_status] == SHAK_MET) {
+				text_show(50621);
+				player.commands_allowed = true;
+			} else {
+				global[shak_status] = SHAK_MET;
+				text_show(50613);
+				aa[4] = kernel_run_animation(kernel_name('s', 1), 0);
+				kernel_synch(KERNEL_ANIM, aa[4], KERNEL_NOW, 0);
+				local->anim_4_running = true;
+				local->shak_action    = SHAK_SHUT_UP;
+			}
+			break;
+
+		case 1:
+		case 8:
+		case 21:
+		case 10:
+		case 11:
+		case 12:
+		case 13:
+		case 14:
+			switch (local->king_action) {
+			case KING_FREEZE:
+				king_reset_frame = 0;
+				break;
+
+			case KING_REACH:
+				king_reset_frame   = 14;
+				local->king_action = KING_FREEZE;
+				break;
+
+			case KING_BLOW:
+				king_reset_frame   = 1;
+				local->king_action = KING_FREEZE;
+				break;
+
+			case KING_CLIMB_DOWN:
+				kernel_abort_animation(aa[3]);
+				aa[1] = kernel_run_animation(kernel_name('k', 1), 0);
+				kernel_synch(KERNEL_ANIM, aa[1], KERNEL_NOW, 0);
+				kernel_reset_animation(aa[1], 106);
+				local->anim_3_running = false;
+				local->anim_1_running = true;
+				king_reset_frame      = -1;
+				break;
 
-void room_506_init() {
+			case KING_CLIMB_UP:
+				kernel_abort_animation(aa[3]);
+				aa[2] = kernel_run_animation(kernel_name('k', 2), 0);
+				kernel_synch(KERNEL_ANIM, aa[2], KERNEL_NOW, 0);
+				local->anim_3_running = false;
+				local->anim_2_running = true;
+				king_reset_frame      = -1;
+				break;
 
+			case KING_TALK:
+				king_reset_frame = imath_random(9, 13);
+				++local->king_talk_count;
+				if (local->king_talk_count > 15) {
+					local->king_action = KING_FREEZE;
+					king_reset_frame   = 0;
+				}
+				break;
+			}
+		}
+
+		if (king_reset_frame >= 0) {
+			kernel_reset_animation(aa[3], king_reset_frame);
+			local->king_frame = king_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_shak() {
+	int shak_reset_frame;
+	int random;
+
+	if (kernel_anim[aa[4]].frame != local->shak_frame) {
+		local->shak_frame = kernel_anim[aa[4]].frame;
+		shak_reset_frame  = -1;
+
+		switch (local->shak_frame) {
+		case 148:
+			player.commands_allowed = true;
+			break;
+
+		case 84:
+			conv_run(CONV_SHAK);
+			if (player_has(red_powerstone) || player_has(yellow_powerstone) ||
+			    player_has(blue_powerstone)) {
+				conv_export_value(true);
+			} else {
+				conv_export_value(false);
+			}
+			break;
+
+		case 85:
+		case 86:
+		case 87:
+		case 88:
+		case 105:
+			switch (local->shak_action) {
+			case SHAK_SHUT_UP:
+				if (imath_random(1, 100) == 1) {
+					shak_reset_frame = 88;
+				} else {
+					shak_reset_frame = 84;
+				}
+				break;
+
+			case SHAK_LEAVE:
+				shak_reset_frame = 106;
+				break;
+
+			case SHAK_TALK:
+				shak_reset_frame = imath_random(85, 87);
+				++local->shak_count;
+				if (local->shak_count > 15) {
+					local->shak_action = SHAK_SHUT_UP;
+					shak_reset_frame   = 84;
+				}
+				break;
+			}
+			break;
+
+		case 97:
+		case 98:
+			if (local->shak_action == SHAK_LEAVE) {
+				shak_reset_frame = 98;
+
+			} else {
+				++local->shak_count;
+				if (local->shak_count > imath_random(8, 15)) {
+					local->shak_count = 0;
+					random = imath_random(1, 3);
+					if (random == 1) {
+						shak_reset_frame = 96;
+					} else if (random == 2) {
+						shak_reset_frame = 97;
+					} else {
+						shak_reset_frame = 98;
+					}
+				} else {
+					shak_reset_frame = local->shak_frame - 1;
+				}
+			}
+			break;
+		}
+
+		if (shak_reset_frame >= 0) {
+			kernel_reset_animation(aa[4], shak_reset_frame);
+			local->shak_frame = shak_reset_frame;
+		}
+	}
+}
+
+static void room_506_init() {
+	conv_get(CONV_SHAK);
+
+	kernel_load_series(kernel_name('a', 4), false);
+
+	local->pid_freeze_count = 0;
+	local->king_talk_count  = 0;
+	local->shak_count       = 0;
+	player.walker_visible   = false;
+
+	if (previous_room != KERNEL_RESTORING_GAME) {
+		local->anim_0_running = false;
+		local->anim_1_running = false;
+		local->anim_2_running = false;
+		local->anim_3_running = false;
+		local->anim_4_running = false;
+	}
+
+	ss[fx_feather_0]  = kernel_load_series(kernel_name('p', 0), false);
+	ss[fx_feather_1]  = kernel_load_series(kernel_name('p', 1), false);
+	ss[fx_feather_2]  = kernel_load_series(kernel_name('p', 2), false);
+
+	seq[fx_feather_0] = kernel_seq_stamp(ss[fx_feather_0], false, KERNEL_FIRST);
+	kernel_seq_depth(seq[fx_feather_0], 1);
+	seq[fx_feather_2] = kernel_seq_stamp(ss[fx_feather_2], false, KERNEL_FIRST);
+	kernel_seq_depth(seq[fx_feather_2], 1);
+
+	if (object_is_here(feathers)) {
+		seq[fx_feather_1] = kernel_seq_stamp(ss[fx_feather_1], false, KERNEL_FIRST);
+		kernel_seq_depth(seq[fx_feather_1], 1);
+	} else {
+		kernel_flip_hotspot_loc(words_feathers, false, FEATHER_X, FEATHER_Y);
+	}
+
+	if (global[player_persona] == PLAYER_IS_PID) {
+		aa[0]                 = kernel_run_animation(kernel_name('p', 1), 0);
+		local->anim_0_running = true;
+		local->pid_action     = PID_FREEZE;
+	}
+
+	if (previous_room == 502) {
+		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;
+		}
+
+	} else if (previous_room == 508) {
+		if (global[pid_just_died]) {
+			aa[3]                 = kernel_run_animation(kernel_name('k', 3), 0);
+			local->anim_3_running = true;
+			local->king_action    = KING_FREEZE;
+			global[pid_just_died] = false;
+
+		} else {
+			player.commands_allowed = false;
+			if (global[player_persona] == PLAYER_IS_PID) {
+				kernel_reset_animation(aa[0], 241);
+			} else {
+				aa[2] = kernel_run_animation(kernel_name('k', 2), 0);
+				kernel_reset_animation(aa[2], 102);
+				local->anim_2_running = true;
+			}
+		}
+
+	} else if (previous_room == KERNEL_RESTORING_GAME) {
+		if (global[player_persona] == PLAYER_IS_PID) {
+			kernel_reset_animation(aa[0], 86);
+
+		} else {
+			aa[3]                 = kernel_run_animation(kernel_name('k', 3), 0);
+			local->anim_3_running = true;
+			local->king_action    = KING_FREEZE;
+
+			if (conv_restore_running == CONV_SHAK) {
+				aa[4]                   = kernel_run_animation(kernel_name('s', 1), 0);
+				local->anim_4_running   = true;
+				local->shak_action      = SHAK_SHUT_UP;
+				player.commands_allowed = false;
+				kernel_reset_animation(aa[4], 84);
+				conv_run(CONV_SHAK);
+				if (player_has(red_powerstone) || player_has(yellow_powerstone) ||
+				    player_has(blue_powerstone)) {
+					conv_export_value(true);
+				} else {
+					conv_export_value(false);
+				}
+			}
+		}
+
+	} else {
+		player.commands_allowed = false;
+	}
+
+	section_5_music();
 }
 
-void room_506_daemon() {
+static void room_506_daemon() {
+	if (local->anim_0_running) {
+		handle_animation_pid();
+	}
+
+	if (local->anim_1_running) {
+		handle_animation_climbing_lower();
+	}
 
+	if (local->anim_2_running) {
+		handle_animation_climbing_upper();
+	}
+
+	if (local->anim_3_running) {
+		handle_animation_king();
+	}
+
+	if (local->anim_4_running) {
+		handle_animation_shak();
+	}
 }
 
-void room_506_pre_parser() {
+static void process_conversation_shak() {
+	int you_trig_flag = false;
+	int me_trig_flag  = false;
+
+	if (player_verb == conv028_exit_b_b) {
+		local->shak_action = SHAK_LEAVE;
+		me_trig_flag       = true;
+		you_trig_flag      = true;
+	}
+
+	if (player_verb == conv028_didnot_innocent) {
+		global[shak_506_angry] = true;
+	}
+
+	switch (kernel.trigger) {
+	case ROOM_506_ME_TALK:
+		if (local->shak_action != SHAK_LEAVE) {
+			local->shak_action = SHAK_SHUT_UP;
+			local->king_action = KING_TALK;
+		}
+		break;
+
+	case ROOM_506_YOU_TALK:
+		if (local->shak_action != SHAK_LEAVE) {
+			local->shak_action = SHAK_TALK;
+			local->king_action = KING_FREEZE;
+		}
+		break;
+	}
+
+	if (!you_trig_flag) {
+		conv_you_trigger(ROOM_506_YOU_TALK);
+	}
+
+	if (!me_trig_flag) {
+		conv_me_trigger(ROOM_506_ME_TALK);
+	}
 
+	local->shak_count      = 0;
+	local->king_talk_count = 0;
 }
 
-void room_506_parser() {
+static void room_506_pre_parser() {
+	player.need_to_walk = false;
+}
+
+static void room_506_parser() {
+	if (conv_control.running == CONV_SHAK) {
+		process_conversation_shak();
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(climb_up, rough_stone)) {
+		if (global[player_persona] == PLAYER_IS_PID) {
+			local->pid_action = PID_CLIMB_UP;
+		} else {
+			local->king_action = KING_CLIMB_UP;
+		}
+		player.commands_allowed = false;
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(climb_down, rough_stone)) {
+		if (global[player_persona] == PLAYER_IS_PID) {
+			local->pid_action = PID_CLIMB_DOWN;
+		} else {
+			local->king_action = KING_CLIMB_DOWN;
+		}
+		player.commands_allowed = false;
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(take, feathers)) {
+		if (object_is_here(feathers)) {
+			if (inter_point_x < 133) {
+				if (game.difficulty == EASY_MODE) {
+					text_show(50617);
+				} else {
+					text_show(50620);
+				}
+			} else {
+				player.commands_allowed = false;
+				if (global[player_persona] == PLAYER_IS_KING) {
+					local->king_action = KING_REACH;
+				} else {
+					local->pid_action = PID_REACH;
+				}
+			}
+		} else if (inter_point_x < 133) {
+			text_show(50618);
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	if (player.look_around) {
+		text_show(50601);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_1(look) || player_said_1(look_at)) {
+
+		if (player_said_1(sky)) {
+			text_show(50602);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(rough_stone)) {
+			if (inter_point_y < 74) {
+				text_show(50604);
+			} else {
+				text_show(50603);
+			}
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(nest)) {
+			if (global[shak_status] == SHAK_NEVER_MET) {
+				text_show(50605);
+			} else {
+				text_show(50606);
+			}
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(mountainside)) {
+			text_show(50609);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(feathers)) {
+			if (player.main_object_source == STROKE_INTERFACE) {
+				if (inter_point_x < 110) {
+					text_show(50610);
+				} else {
+					text_show(50619);
+				}
+				player.command_ready = false;
+				return;
+			}
+		}
+
+		if (player_said_1(shak)) {
+			text_show(50612);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_1(nest)) {
+		if (player_said_1(take) || player_said_1(pull)) {
+			text_show(50607);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_2(put, nest)) {
+		text_show(50608);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(take, feathers)) {
+		text_show(50611);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(make_noise, birdcall)) {
+		if (global[player_persona] == PLAYER_IS_PID) {
+			if (global[shak_status] == SHAK_MET) {
+				text_show(50621);
+				player.command_ready = false;
+				return;
+			}
+
+		} else {
+
+			if (!(global[player_score_flags] & SCORE_MAKE_NOISE_BIRDCALL)) {
+				global[player_score_flags] = global[player_score_flags] | SCORE_MAKE_NOISE_BIRDCALL;
+				global[player_score] += 4;
+			}
+
+			player.commands_allowed = false;
+			local->king_action = KING_BLOW;
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_3(throw, dates, shak) ||
+	    player_said_3(give, dates, shak)) {
+		text_show(50614);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(open, bottle_of_flies) ||
+	    player_said_3(give, bottle_of_flies, shak)) {
+		text_show(50615);
+		player.command_ready = false;
+		return;
+	}
 
+	if (player_said_3(give, feathers, shak)) {
+		text_show(50616);
+		player.command_ready = false;
+		return;
+	}
 }
 
 void room_506_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(local->pid_frame);
+	s.syncAsSint16LE(local->pid_action);
+	s.syncAsSint16LE(local->pid_freeze_count);
+	s.syncAsSint16LE(local->anim_0_running);
+	s.syncAsSint16LE(local->king_frame);
+	s.syncAsSint16LE(local->king_action);
+	s.syncAsSint16LE(local->king_talk_count);
+	s.syncAsSint16LE(local->anim_1_running);
+	s.syncAsSint16LE(local->anim_2_running);
+	s.syncAsSint16LE(local->anim_3_running);
+	s.syncAsSint16LE(local->shak_frame);
+	s.syncAsSint16LE(local->shak_action);
+	s.syncAsSint16LE(local->shak_count);
+	s.syncAsSint16LE(local->anim_4_running);
 }
 
 void room_506_preload() {
-	room_init_code_pointer = room_506_init;
+	room_init_code_pointer       = room_506_init;
 	room_pre_parser_code_pointer = room_506_pre_parser;
-	room_parser_code_pointer = room_506_parser;
-	room_daemon_code_pointer = room_506_daemon;
+	room_parser_code_pointer     = room_506_parser;
+	room_daemon_code_pointer     = room_506_daemon;
 
 	section_5_walker();
 	section_5_interface();
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room507.cpp b/engines/mads/madsv2/dragonsphere/rooms/room507.cpp
index f5757069a46..1617b496bb5 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room507.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room507.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/matte.h"
 #include "mads/madsv2/core/sound.h"
 #include "mads/madsv2/core/text.h"
 #include "mads/madsv2/dragonsphere/mads/conv.h"
@@ -39,40 +41,55 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[15];
+	int16 sequence[15];
+	int16 animation[4];
 };
 
+static Scratch scratch;
+
 #define local (&scratch)
 #define ss    local->sprite
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
 
-void room_507_init() {
+static void room_507_init() {
+	viewing_at_y = ((video_y - display_y) >> 1);
+	kernel_init_dialog();
+	kernel_set_interface_mode(INTER_LIMITED_SENTENCES);
 
-}
+	player.commands_allowed = false;
+	player.walker_visible   = false;
 
-void room_507_daemon() {
+	aa[0] = kernel_run_animation(kernel_name('k', 1), 60);
 
+	section_5_music();
 }
 
-void room_507_pre_parser() {
-
+static void room_507_daemon() {
+	if (kernel.trigger == 60) {
+		new_room = 557;
+	}
 }
 
-void room_507_parser() {
+static void room_507_pre_parser() {
+}
 
+static void room_507_parser() {
 }
 
 void room_507_synchronize(Common::Serializer &s) {
-	
+	for (int16 &v : scratch.sprite)    s.syncAsSint16LE(v);
+	for (int16 &v : scratch.sequence)  s.syncAsSint16LE(v);
+	for (int16 &v : scratch.animation) s.syncAsSint16LE(v);
 }
 
 void room_507_preload() {
-	room_init_code_pointer = room_507_init;
+	room_init_code_pointer       = room_507_init;
 	room_pre_parser_code_pointer = room_507_pre_parser;
-	room_parser_code_pointer = room_507_parser;
-	room_daemon_code_pointer = room_507_daemon;
+	room_parser_code_pointer     = room_507_parser;
+	room_daemon_code_pointer     = room_507_daemon;
 
 	section_5_walker();
 	section_5_interface();
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room508.cpp b/engines/mads/madsv2/dragonsphere/rooms/room508.cpp
index 30cb34a8e2f..b4feec027e0 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room508.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room508.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,15 @@
  *
  */
 
+#include "mads/madsv2/core/config.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/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,43 +43,941 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[15];
+	int16 sequence[15];
+	int16 animation[8];
+	int16 lani_frame;
+	int16 lani_action;
+	int16 lani_count;
+	int16 anim_0_running;
+	int16 beast_frame;
+	int16 beast_action;
+	int16 beast_count;
+	int16 anim_1_running;
+	int16 king_frame;
+	int16 king_frame_cliff;
+	int16 king_frame_aside;
+	int16 king_count;
+	int16 king_action;
+	int16 anim_2_running;
+	int16 anim_3_running;
+	int16 anim_4_running;
+	int16 anim_6_running;
+	int16 anim_7_running;
+	int32 clock;
+	int32 update_clock;
+	int32 death_timer;
+	int16 activate_timer;
 };
 
+static Scratch scratch;
+
 #define local (&scratch)
 #define ss    local->sprite
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
+#define fx_up_onto_ledge        0
+#define fx_water                1
+
+#define ROOM_508_DONE_UP        60
+#define ROOM_508_DONE_DOWN      63
+#define ROOM_508_YOU_TALK       65
+#define ROOM_508_TALK_TO_LANI   67
+#define ROOM_508_LANI_ATTACK    69
+#define ROOM_508_KING_GET_UP    71
+
+#define PLAYER_X_FROM_506       121
+#define PLAYER_Y_FROM_506       121
+
+#define PLAYER_X_FROM_509       6
+#define PLAYER_Y_FROM_509       114
+
+#define LANI_SHUT_UP            0
+#define LANI_TALK               1
+#define LANI_INVISIBLE          2
+#define LANI_SCARED             3
+
+#define LANI_X                  147
+#define LANI_Y                  106
+
+#define CONV_37_LANI            37
+
+#define BEAST_INVISIBLE          0
+#define BEAST_WAIT               1
+#define BEAST_MOVE_IN            2
+
+#define KING_INVISIBLE           0
+#define KING_WAIT                1
+#define KING_SWORD               2
+#define KING_NOTHING             3
+
+#define LENGTH_OF_LIFE            1300
+
+#define RECOVER_X                41
+#define RECOVER_Y                99
+
+#define KING_UP_X                140
+#define KING_UP_Y                79
+
+#define PID_UP_X                 131
+#define PID_UP_Y                 77
+
+
+static void handle_animation_lani() {
+	int lani_reset_frame;
+	int random;
+
+	if (kernel_anim[aa[0]].frame != local->lani_frame) {
+		local->lani_frame = kernel_anim[aa[0]].frame;
+		lani_reset_frame = -1;
+
+		switch (local->lani_frame) {
+
+		case 25:
+			lani_reset_frame = 24;
+			break;
+
+		case 1:
+		case 7:
+		case 15:
+		case 23:
+
+			if (local->anim_3_running || local->anim_4_running || local->activate_timer) {
+				lani_reset_frame = 0;
+
+			} else switch (local->lani_action) {
+
+			case LANI_TALK:
+				random = imath_random(1, 2);
+				if (random == 1) {
+					lani_reset_frame = 1;
+				} else {
+					lani_reset_frame = 7;
+				}
+				local->lani_action = LANI_SHUT_UP;
+				break;
+
+			case LANI_SHUT_UP:
+				++local->lani_count;
+				if (local->lani_count > imath_random(15, 20)) {
+					local->lani_count = 0;
+					random = imath_random(1, 2);
+					if (random == 1) {
+						lani_reset_frame = 0;
+					} else {
+						lani_reset_frame = 15;
+					}
+				} else {
+					lani_reset_frame = 0;
+				}
+				break;
+			}
+			break;
+
+		case 19:
+
+			if (local->anim_3_running || local->anim_4_running || local->activate_timer) {
+				lani_reset_frame = 19;
+
+			} else switch (local->lani_action) {
+
+			case LANI_TALK:
+				lani_reset_frame = 19;
+				break;
+
+			case LANI_SHUT_UP:
+				++local->lani_count;
+				if (local->lani_count > imath_random(15, 20)) {
+					local->lani_count = 0;
+					random = imath_random(1, 2);
+					if (random == 1) {
+						lani_reset_frame = 19;
+					} else {
+						lani_reset_frame = 18;
+					}
+				} else {
+					lani_reset_frame = 18;
+				}
+				break;
+			}
+			break;
+		}
+
+		if (lani_reset_frame >= 0) {
+			kernel_reset_animation(aa[0], lani_reset_frame);
+			local->lani_frame = lani_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_beast() {
+	int beast_reset_frame;
+
+	if (kernel_anim[aa[1]].frame != local->beast_frame) {
+		local->beast_frame = kernel_anim[aa[1]].frame;
+		beast_reset_frame = -1;
+
+		switch (local->beast_frame) {
+
+		case 40:
+			if (local->beast_action == BEAST_INVISIBLE) {
+				beast_reset_frame = 39;
+			} else {
+				beast_reset_frame = 0;
+			}
+			break;
+
+		case 22:
+		case 23:
+		case 24:
+		case 25:
+		case 26:
+
+			if (local->beast_action == BEAST_WAIT) {
+				++local->beast_count;
+				if (local->beast_count > imath_random(7, 15)) {
+					if (local->beast_frame == 22) {
+						beast_reset_frame = imath_random(21, 22);
+					} else if (local->beast_frame == 23) {
+						beast_reset_frame = imath_random(21, 23);
+					} else if (local->beast_frame == 24) {
+						beast_reset_frame = imath_random(22, 24);
+					} else if (local->beast_frame == 25) {
+						beast_reset_frame = imath_random(23, 25);
+					} else if (local->beast_frame == 26) {
+						beast_reset_frame = imath_random(24, 25);
+					}
+					local->beast_count = 0;
+
+				} else {
+					beast_reset_frame = local->beast_frame - 1;
+				}
 
-void room_508_init() {
+			} else {
+				beast_reset_frame     = -1;
+				local->anim_1_running = false;
+				local->activate_timer = false;
+				kernel_abort_animation(aa[1]);
 
+				if (local->king_action == KING_SWORD) {
+					aa[3] = kernel_run_animation(kernel_name('k', 3), ROOM_508_KING_GET_UP);
+					kernel_synch(KERNEL_ANIM, aa[3], KERNEL_NOW, 0);
+					local->anim_3_running = true;
+					global[llanie_status] = SHE_FELL;
+
+				} else {
+					aa[4] = kernel_run_animation(kernel_name('k', 2), 0);
+					kernel_synch(KERNEL_ANIM, aa[4], KERNEL_NOW, 0);
+					local->anim_4_running = true;
+				}
+			}
+			break;
+		}
+
+		if (beast_reset_frame >= 0) {
+			kernel_reset_animation(aa[1], beast_reset_frame);
+			local->beast_frame = beast_reset_frame;
+		}
+	}
 }
 
-void room_508_daemon() {
+static void handle_animation_king_choice() {
+	int king_reset_frame;
+
+	if (kernel_anim[aa[2]].frame != local->king_frame) {
+		local->king_frame = kernel_anim[aa[2]].frame;
+		king_reset_frame = -1;
+
+		switch (local->king_frame) {
+
+		case 21:
+			if (local->king_action == KING_INVISIBLE) {
+				king_reset_frame = 20;
+			} else {
+				king_reset_frame   = 0;
+				local->king_action = KING_WAIT;
+			}
+			break;
+
+		case 7:
+			player.commands_allowed = true;
+			local->beast_action     = BEAST_WAIT;
+			local->activate_timer   = true;
+			break;
+
+		case 9:
+		case 10:
+
+			if (local->king_action == KING_WAIT ||
+			    local->king_action == KING_NOTHING) {
+				++local->king_count;
+				if (local->king_count > imath_random(7, 13)) {
+					local->king_count = 0;
+					king_reset_frame  = imath_random(8, 9);
+
+				} else {
+					king_reset_frame = local->king_frame - 1;
+				}
+			}
+			break;
+
+		case 17:
+			break;
 
+		case 19:
+			local->beast_action = BEAST_MOVE_IN;
+			king_reset_frame = 18;
+			break;
+		}
+
+		if (king_reset_frame >= 0) {
+			kernel_reset_animation(aa[2], king_reset_frame);
+			local->king_frame = king_reset_frame;
+		}
+	}
 }
 
-void room_508_pre_parser() {
+static void handle_animation_king_aside() {
+	int king_reset_frame;
+
+	if (kernel_anim[aa[3]].frame != local->king_frame_aside) {
+		local->king_frame_aside = kernel_anim[aa[3]].frame;
+		king_reset_frame = -1;
+
+		switch (local->king_frame_aside) {
+
+		case 20:
+			kernel_reset_animation(aa[0], 24);
+			kernel_synch(KERNEL_ANIM, aa[0], KERNEL_ANIM, aa[3]);
+			break;
+
+		case 13:
+			kernel_reset_animation(aa[2], 20);
+			local->king_action = KING_INVISIBLE;
+			kernel_synch(KERNEL_ANIM, aa[2], KERNEL_ANIM, aa[3]);
+			break;
+		}
 
+		if (king_reset_frame >= 0) {
+			kernel_reset_animation(aa[3], king_reset_frame);
+			local->king_frame_aside = king_reset_frame;
+		}
+	}
 }
 
-void room_508_parser() {
+static void handle_animation_king_cliff() {
+	int king_reset_frame;
+
+	if (kernel_anim[aa[4]].frame != local->king_frame_cliff) {
+		local->king_frame_cliff = kernel_anim[aa[4]].frame;
+		king_reset_frame = -1;
+
+		switch (local->king_frame_cliff) {
+
+		case 35:
+			global_speech_go(3);
+			break;
+
+		case 42:
+			kernel_reset_animation(aa[0], 24);
+			kernel_synch(KERNEL_ANIM, aa[0], KERNEL_ANIM, aa[4]);
+			break;
 
+		case 49:
+			if (game.difficulty == EASY_MODE) {
+				text_show(50823);
+			} else {
+				text_show(45);
+			}
+			conv_reset(CONV_37_LANI);
+			global[pid_just_died] = true;
+			new_room              = 506;
+			break;
+
+		case 13:
+			kernel_reset_animation(aa[2], 20);
+			local->king_action = KING_INVISIBLE;
+			kernel_synch(KERNEL_ANIM, aa[2], KERNEL_ANIM, aa[4]);
+			break;
+		}
+
+		if (king_reset_frame >= 0) {
+			kernel_reset_animation(aa[4], king_reset_frame);
+			local->king_frame_cliff = king_reset_frame;
+		}
+	}
+}
+
+static void room_508_init() {
+	int id;
+
+	if (global[llanie_status] == IS_SAVED) {
+		global[make_504_empty] = 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_6_running = false;
+		local->anim_7_running = false;
+		local->death_timer    = 0;
+		local->clock          = 0;
+		local->activate_timer = false;
+	}
+
+	ss[fx_water]  = kernel_load_series(kernel_name('x', 0), false);
+	seq[fx_water] = kernel_seq_forward(ss[fx_water], false, 8, 0, 0, 0);
+	kernel_seq_depth(seq[fx_water], 1);
+	kernel_seq_range(seq[fx_water], KERNEL_FIRST, KERNEL_LAST);
+
+	if (kernel.teleported_in) {
+		inter_give_to_player(sword);
+	}
+
+	if (!global[monster_is_dead]) {
+		conv_get(CONV_37_LANI);
+	}
+
+	local->lani_count  = 0;
+	local->king_count  = 0;
+	local->beast_count = 0;
+
+	if (previous_room == 557 || previous_room == 506 || previous_room == 508) {
+
+		player.commands_allowed = false;
+		player.walker_visible   = false;
+
+		if (global[player_persona] == PLAYER_IS_PID) {
+			aa[0] = kernel_run_animation(kernel_name('p', 2), ROOM_508_DONE_UP);
+			player.facing = FACING_NORTH;
+			player.x      = PLAYER_X_FROM_506;
+			player.y      = PLAYER_Y_FROM_506;
+
+		} else {
+			if (!global[monster_is_dead]) {
+				aa[0]                   = kernel_run_animation(kernel_name('l', 1), 0);
+				local->anim_0_running   = true;
+				local->lani_action      = LANI_SHUT_UP;
+				id = kernel_add_dynamic(words_Llanie, words_look_at, SYNTAX_SINGULAR_FEM, KERNEL_NONE,
+				                        0, 0, 0, 0);
+				kernel_dynamic_hot[id].prep = PREP_ON;
+				kernel_dynamic_anim(id, aa[0], 0);
+
+				aa[2]                   = kernel_run_animation(kernel_name('k', 1), 0);
+				local->anim_2_running   = true;
+				local->king_action      = KING_INVISIBLE;
+				kernel_reset_animation(aa[2], 21);
+
+				aa[1]                   = kernel_run_animation(kernel_name('b', 1), 0);
+				local->anim_1_running   = true;
+				local->beast_action     = BEAST_INVISIBLE;
+				kernel_reset_animation(aa[1], 40);
+				id = kernel_add_dynamic(words_beast, words_look_at, SYNTAX_MASC_NOT_PROPER, KERNEL_NONE,
+				                        0, 0, 0, 0);
+				kernel_dynamic_hot[id].prep = PREP_ON;
+				kernel_dynamic_anim(id, aa[1], 0);
+			}
+
+			aa[3] = kernel_run_animation(kernel_name('c', 1), ROOM_508_DONE_UP);
+			player.facing = FACING_NORTHEAST;
+			player.x      = PLAYER_X_FROM_506 + 8;
+			player.y      = PLAYER_Y_FROM_506;
+		}
+
+	} else if (previous_room == 601) {
+		if (global[player_persona] == PLAYER_IS_KING) {
+			player.x      = KING_UP_X;
+			player.y      = KING_UP_Y;
+			player.facing = FACING_NORTH;
+			aa[6]         = kernel_run_animation(kernel_name('k', 4), 0);
+			kernel_synch(KERNEL_ANIM, aa[6], KERNEL_PLAYER, 0);
+			kernel_reset_animation(aa[6], 78);
+			local->anim_6_running   = true;
+
+		} else {
+			player.x      = PID_UP_X;
+			player.y      = PID_UP_Y;
+			player.facing = FACING_NORTH;
+			aa[7]         = kernel_run_animation(kernel_name('p', 1), 0);
+			kernel_synch(KERNEL_ANIM, aa[7], KERNEL_PLAYER, 0);
+			kernel_reset_animation(aa[7], 92);
+			local->anim_7_running   = true;
+		}
+		player.walker_visible   = false;
+		player.commands_allowed = false;
+
+	} else if (previous_room != KERNEL_RESTORING_GAME) {
+		player_first_walk(PLAYER_X_FROM_509,      PLAYER_Y_FROM_509, FACING_EAST,
+		                  PLAYER_X_FROM_509 + 30, PLAYER_Y_FROM_509, FACING_EAST, true);
+
+	} else if (previous_room == KERNEL_RESTORING_GAME) {
+
+		if (!global[monster_is_dead]) {
+
+			local->death_timer      = 0;
+			player.walker_visible   = false;
+
+			aa[0]                   = kernel_run_animation(kernel_name('l', 1), 0);
+			local->anim_0_running   = true;
+			local->lani_action      = LANI_SHUT_UP;
+			id = kernel_add_dynamic(words_Llanie, words_look_at, SYNTAX_SINGULAR_FEM, KERNEL_NONE,
+			                        0, 0, 0, 0);
+			kernel_dynamic_hot[id].prep = PREP_ON;
+			kernel_dynamic_anim(id, aa[0], 0);
+
+			aa[2]                   = kernel_run_animation(kernel_name('k', 1), 0);
+			local->anim_2_running   = true;
+			local->king_action      = KING_WAIT;
+			kernel_reset_animation(aa[2], 9);
+
+			aa[1]                   = kernel_run_animation(kernel_name('b', 1), 0);
+			local->anim_1_running   = true;
+			local->beast_action     = BEAST_WAIT;
+			kernel_reset_animation(aa[1], 23);
+			id = kernel_add_dynamic(words_beast, words_look_at, SYNTAX_MASC_NOT_PROPER, KERNEL_NONE,
+			                        0, 0, 0, 0);
+			kernel_dynamic_hot[id].prep = PREP_ON;
+			kernel_dynamic_anim(id, aa[1], 0);
+		}
+	}
+
+	local->update_clock = kernel.clock;
+
+	section_5_music();
+}
+
+static void room_508_daemon() {
+	int32 dif;
+	int dist;
+
+	if (local->anim_0_running) {
+		handle_animation_lani();
+	}
+
+	if (local->anim_1_running) {
+		handle_animation_beast();
+	}
+
+	if (local->anim_2_running) {
+		handle_animation_king_choice();
+	}
+
+	if (local->anim_3_running) {
+		handle_animation_king_aside();
+	}
+
+	if (local->anim_4_running) {
+		handle_animation_king_cliff();
+	}
+
+	if (kernel.trigger == ROOM_508_DONE_UP) {
+		player.walker_visible   = true;
+		if (!global[monster_is_dead]) {
+			player_walk(LANI_X, LANI_Y, FACING_NORTHEAST);
+			player_walk_trigger(ROOM_508_TALK_TO_LANI);
+			kernel_synch(KERNEL_PLAYER, 0, KERNEL_ANIM, aa[3]);
+		} else {
+			player.commands_allowed = true;
+			kernel_synch(KERNEL_PLAYER, 0, KERNEL_ANIM, aa[0]);
+		}
+	}
+
+	if (kernel.trigger == ROOM_508_TALK_TO_LANI) {
+		conv_run(CONV_37_LANI);
+	}
+
+	if (kernel.trigger == ROOM_508_KING_GET_UP) {
+		sound_play(N_BackgroundMus);
+		kernel_abort_animation(aa[3]);
+		kernel_abort_animation(aa[2]);
+		kernel_abort_animation(aa[0]);
+		local->anim_3_running   = false;
+		local->anim_0_running   = false;
+		local->anim_2_running   = false;
+		player.walker_visible   = true;
+		player.commands_allowed = true;
+		global[monster_is_dead] = true;
+		kernel_synch(KERNEL_PLAYER, 0, KERNEL_NOW, 0);
+		player_demand_location(RECOVER_X, RECOVER_Y);
+		player_demand_facing(FACING_SOUTH);
+		++global[dragon_high_scene];
+		text_show(50817);
+	}
+
+	if (local->activate_timer) {
+		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) {
+			local->king_action      = KING_NOTHING;
+			local->beast_action     = BEAST_MOVE_IN;
+			player.commands_allowed = false;
+			local->activate_timer   = false;
+		}
+	}
+
+	if (local->anim_6_running) {
+		if (kernel_anim[aa[6]].frame == 75) {
+			new_room = 601;
+
+		} else if (kernel_anim[aa[6]].frame == 151) {
+			kernel_abort_animation(aa[6]);
+			kernel_synch(KERNEL_PLAYER, 0, KERNEL_NOW, 0);
+			player.walker_visible   = true;
+			player.commands_allowed = true;
+			local->anim_6_running   = false;
+			player_walk(KING_UP_X + 4, KING_UP_Y + 10, FACING_SOUTH);
+		}
+	}
+
+	if (local->anim_7_running) {
+		if (kernel_anim[aa[7]].frame == 90) {
+			new_room = 601;
+
+		} else if (kernel_anim[aa[7]].frame == 181) {
+			kernel_abort_animation(aa[7]);
+			kernel_synch(KERNEL_PLAYER, 0, KERNEL_NOW, 0);
+			player.walker_visible   = true;
+			player.commands_allowed = true;
+			local->anim_7_running   = false;
+			player_walk(KING_UP_X + 15, KING_UP_Y + 10, FACING_SOUTH);
+		}
+	}
+
+	if (kernel.clock >= local->update_clock) {
+		dist = 127 - ((imath_hypot(player.x - 12, player.y - 119) * 127) / 378);
+		if (!sound_off) {
+			sound_queue(N_005Waterfall, dist);
+		}
+		local->update_clock = kernel.clock + player.frame_delay;
+	}
+}
+
+static void process_conv_lani() {
+	int you_trig_flag = false;
+
+	if (player_verb == conv037_next_b_b) {
+		local->beast_action = BEAST_WAIT;
+		sound_play(N_Battle);
+	}
+
+	if (player_verb == conv037_exit_b_b) {
+		conv_abort();
+		local->king_action      = KING_WAIT;
+		player.walker_visible   = false;
+		player.commands_allowed = false;
+		kernel_reset_animation(aa[2], 0);
+		kernel_synch(KERNEL_PLAYER, 0, KERNEL_ANIM, aa[2]);
+	}
+
+	if (kernel.trigger == ROOM_508_YOU_TALK) {
+		local->lani_action = LANI_TALK;
+	}
+
+	if (!you_trig_flag) {
+		conv_you_trigger(ROOM_508_YOU_TALK);
+	}
+
+	local->lani_count = 0;
+}
+
+static void room_508_pre_parser() {
+	if (player_said_2(climb_down, rough_stone)) {
+		if (global[player_persona] == PLAYER_IS_KING) {
+			player_walk(PLAYER_X_FROM_506 + 8, PLAYER_Y_FROM_506, FACING_NORTHEAST);
+		}
+	}
+
+	if (player_said_2(climb_up, rough_stone)) {
+		if (global[player_persona] == PLAYER_IS_PID) {
+			player_walk(PID_UP_X, PID_UP_Y, FACING_NORTH);
+		}
+	}
+
+	if (player_said_1(path_to_west) && player.need_to_walk) {
+		if (!player_said_1(follow)) {
+			player.need_to_walk = false;
+		}
+	}
+
+	if (local->anim_0_running) {
+		if (player.need_to_walk) {
+			player.need_to_walk = false;
+		}
+	}
+}
+
+static void room_508_parser() {
+	if (conv_control.running == CONV_37_LANI) {
+		process_conv_lani();
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(climb_up, rough_stone)) {
+		if (local->anim_0_running) {
+			text_show(50815);
+			player.command_ready = false;
+			return;
+
+		} else if (global[player_persona] == PLAYER_IS_KING) {
+			aa[6] = kernel_run_animation(kernel_name('k', 4), 0);
+			kernel_synch(KERNEL_ANIM, aa[6], KERNEL_PLAYER, 0);
+			local->anim_6_running   = true;
+
+		} else {
+			aa[7] = kernel_run_animation(kernel_name('p', 1), 0);
+			kernel_synch(KERNEL_ANIM, aa[7], KERNEL_PLAYER, 0);
+			local->anim_7_running   = true;
+		}
+		player.walker_visible   = false;
+		player.commands_allowed = false;
+		player.command_ready = false;
+		return;
+	}
+
+	if (local->anim_0_running) {
+		if (player_said_1(walk_across) ||
+		    player_said_1(walk_to)) {
+			text_show(50815);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (kernel.trigger == ROOM_508_DONE_DOWN) {
+		new_room = 506;
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(invoke, signet_ring)) {
+		if (local->anim_0_running) {
+			text_show(50824);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_2(follow, path_to_west)) {
+		if (local->anim_0_running) {
+			text_show(50815);
+		} else {
+			new_room = 509;
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(climb_up, rough_stone)) {
+		if (local->anim_0_running) {
+			text_show(50815);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_2(climb_down, rough_stone)) {
+		if (local->anim_0_running) {
+			text_show(50815);
+			player.command_ready = false;
+			return;
+
+		} else {
+			player.commands_allowed = false;
+			player.walker_visible   = false;
+
+			if (global[player_persona] == PLAYER_IS_PID) {
+				aa[0] = kernel_run_animation(kernel_name('p', 3), ROOM_508_DONE_DOWN);
+				kernel_synch(KERNEL_ANIM, aa[0], KERNEL_PLAYER, 0);
+
+			} else {
+				aa[0] = kernel_run_animation(kernel_name('c', 2), ROOM_508_DONE_DOWN);
+				kernel_synch(KERNEL_ANIM, aa[0], KERNEL_PLAYER, 0);
+			}
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player.look_around) {
+		text_show(50801);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_1(look) || player_said_1(look_at)) {
+		if (player_said_1(sky)) {
+			text_show(50802);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(edge_of_cliff)) {
+			text_show(50803);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(mountainside)) {
+			text_show(50804);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(rough_stone)) {
+			if (inter_point_y < 100) {
+				text_show(50805);
+			} else {
+				text_show(50806);
+			}
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(path_to_west)) {
+			text_show(50807);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(waterfall)) {
+			text_show(50808);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(ledge)) {
+			text_show(50812);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(beast)) {
+			text_show(50813);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(Llanie)) {
+			text_show(50814);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_3(fill, goblet, waterfall) ||
+	    player_said_3(put, goblet, waterfall)) {
+		text_show(50809);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(put, waterfall)) {
+		if (player_said_1(torch)) {
+			text_show(50810);
+		} else {
+			text_show(50811);
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_3(sword, attack, beast) ||
+	    player_said_3(sword, carve_up, beast) ||
+	    player_said_3(sword, thrust, beast) ||
+	    player_said_2(take, sword)) {
+
+		if (local->anim_0_running) {
+			++global[player_score];
+			local->king_action      = KING_SWORD;
+			player.commands_allowed = false;
+			sound_play(N_Battle);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_3(throw, shieldstone, beast)) {
+		text_show(50818);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(talk_to, Llanie)) {
+		text_show(50820);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(talk_to, beast)) {
+		text_show(50819);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(push, Llanie)) {
+		text_show(50822);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(push, beast)) {
+		text_show(50821);
+		player.command_ready = false;
+		return;
+	}
 }
 
 void room_508_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.lani_frame);
+	s.syncAsSint16LE(scratch.lani_action);
+	s.syncAsSint16LE(scratch.lani_count);
+	s.syncAsSint16LE(scratch.anim_0_running);
+	s.syncAsSint16LE(scratch.beast_frame);
+	s.syncAsSint16LE(scratch.beast_action);
+	s.syncAsSint16LE(scratch.beast_count);
+	s.syncAsSint16LE(scratch.anim_1_running);
+	s.syncAsSint16LE(scratch.king_frame);
+	s.syncAsSint16LE(scratch.king_frame_cliff);
+	s.syncAsSint16LE(scratch.king_frame_aside);
+	s.syncAsSint16LE(scratch.king_count);
+	s.syncAsSint16LE(scratch.king_action);
+	s.syncAsSint16LE(scratch.anim_2_running);
+	s.syncAsSint16LE(scratch.anim_3_running);
+	s.syncAsSint16LE(scratch.anim_4_running);
+	s.syncAsSint16LE(scratch.anim_6_running);
+	s.syncAsSint16LE(scratch.anim_7_running);
+	s.syncAsSint32LE(scratch.clock);
+	s.syncAsSint32LE(scratch.update_clock);
+	s.syncAsSint32LE(scratch.death_timer);
+	s.syncAsSint16LE(scratch.activate_timer);
 }
 
 void room_508_preload() {
-	room_init_code_pointer = room_508_init;
+	room_init_code_pointer       = room_508_init;
 	room_pre_parser_code_pointer = room_508_pre_parser;
-	room_parser_code_pointer = room_508_parser;
-	room_daemon_code_pointer = room_508_daemon;
+	room_parser_code_pointer     = room_508_parser;
+	room_daemon_code_pointer     = room_508_daemon;
 
 	section_5_walker();
 	section_5_interface();
+
+	vocab_make_active(words_beast);
+	vocab_make_active(words_Llanie);
+	vocab_make_active(words_look_at);
 }
 
 } // namespace Rooms
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room509.cpp b/engines/mads/madsv2/dragonsphere/rooms/room509.cpp
index e5d0bd93e54..696f6c63a7d 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room509.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room509.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,14 @@
  *
  */
 
+#include "mads/madsv2/core/config.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/text.h"
 #include "mads/madsv2/dragonsphere/mads/conv.h"
@@ -39,43 +43,640 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[15];
+	int16 sequence[15];
+	int16 animation[4];
+	int16 shak_frame;
+	int16 shak_action;
+	int16 shak_talk_count;
+	int16 anim_0_running;
+	int16 anim_1_running;
+	int16 prevent;
+	int32 update_clock;
 };
 
+static Scratch scratch;
+
 #define local (&scratch)
 #define ss    local->sprite
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
+#define fx_take                 0
+#define fx_water                1
+
+#define ROOM_509_DOOR_CLOSES    60
+#define ROOM_509_YOU_TALK       65
+#define ROOM_509_ME_TALK        67
+#define ROOM_509_FLAP           90
+
+#define PLAYER_X_FROM_508       280
+#define PLAYER_Y_FROM_508       145
+
+#define WALK_TO_X_FROM_508      250
+#define WALK_TO_Y_FROM_508      138
+
+#define PLAYER_X_FROM_510       -15
+#define PLAYER_Y_FROM_510       89
+
+#define WALK_TO_X_FROM_510      12
+#define WALK_TO_Y_FROM_510      89
+
+#define CONV_SHAK_29_IN_WAY     29
+#define CONV_SHAK_30_ON_LEDGE   30
+
+#define SHAK_SHUT_UP            0
+#define SHAK_TALK               1
+#define SHAK_FLAP               2
+
+#define WALK_TO_FLAP_X          133
+#define WALK_TO_FLAP_Y          112
+
+#define WALK_TO_LEDGE_X         128
+#define WALK_TO_LEDGE_Y         109
+
+#define TAKE_MUD_X              260
+#define TAKE_MUD_Y              123
+
+
+static void handle_animation_shak_block() {
+	int shak_reset_frame;
+
+	if (kernel_anim[aa[0]].frame != local->shak_frame) {
+		local->shak_frame = kernel_anim[aa[0]].frame;
+		shak_reset_frame = -1;
+
+		switch (local->shak_frame) {
+		case 60:
+			player.commands_allowed = true;
+			local->prevent          = false;
+			local->shak_action      = SHAK_SHUT_UP;
+			break;
+
+		case 1:
+		case 2:
+		case 3:
+		case 4:
+		case 5:
+		case 6:
+		case 62:
+			switch (local->shak_action) {
+			case SHAK_TALK:
+				shak_reset_frame = imath_random(3, 5);
+				++local->shak_talk_count;
+				if (local->shak_talk_count > 25) {
+					local->shak_action     = SHAK_SHUT_UP;
+					local->shak_talk_count = 0;
+					shak_reset_frame       = 0;
+				}
+				break;
+
+			case SHAK_SHUT_UP:
+				if (local->shak_frame >= 4) {
+					local->shak_frame = 1;
+				}
+				++local->shak_talk_count;
+				if (local->shak_talk_count > imath_random(20, 30)) {
+					if (local->shak_frame == 1) {
+						shak_reset_frame = imath_random(0, 1);
+					} else if (local->shak_frame == 2) {
+						shak_reset_frame = imath_random(0, 2);
+					} else if (local->shak_frame == 3) {
+						shak_reset_frame = imath_random(1, 2);
+					}
+					local->shak_talk_count = 0;
+
+				} else {
+					shak_reset_frame = local->shak_frame - 1;
+				}
+				break;
+
+			case SHAK_FLAP:
+				shak_reset_frame       = 6;
+				local->shak_talk_count = 0;
+				break;
+			}
+			break;
+		}
+
+		if (shak_reset_frame >= 0) {
+			kernel_reset_animation(aa[0], shak_reset_frame);
+			local->shak_frame = shak_reset_frame;
+		}
+	}
+}
+
+static void handle_animation_shak_ledge() {
+	int shak_reset_frame;
+	int random;
+
+	if (kernel_anim[aa[1]].frame != local->shak_frame) {
+		local->shak_frame = kernel_anim[aa[1]].frame;
+		shak_reset_frame = -1;
+
+		switch (local->shak_frame) {
+		case 1:
+		case 2:
+		case 3:
+		case 4:
+		case 5:
+		case 11:
+		case 18:
+		case 29:
+			switch (local->shak_action) {
+			case SHAK_TALK:
+				shak_reset_frame = imath_random(0, 3);
+				++local->shak_talk_count;
+				if (local->shak_talk_count > 30) {
+					local->shak_action     = SHAK_SHUT_UP;
+					local->shak_talk_count = 0;
+					shak_reset_frame       = 4;
+				}
+				break;
+
+			case SHAK_SHUT_UP:
+				++local->shak_talk_count;
+				if (local->shak_talk_count > imath_random(20, 30)) {
+					random = imath_random(1, 4);
+					switch (random) {
+					case 1: shak_reset_frame = 4;  break;
+					case 2: shak_reset_frame = 5;  break;
+					case 3: shak_reset_frame = 18; break;
+					case 4: shak_reset_frame = 11; break;
+					}
+					local->shak_talk_count = 0;
+
+				} else {
+					shak_reset_frame = 4;
+				}
+				break;
+			}
+			break;
+
+		case 8:
+			switch (local->shak_action) {
+			case SHAK_TALK:
+				shak_reset_frame = 8;
+				break;
+
+			case SHAK_SHUT_UP:
+				++local->shak_talk_count;
+				if (local->shak_talk_count > imath_random(20, 30)) {
+					shak_reset_frame       = imath_random(7, 8);
+					local->shak_talk_count = 0;
+
+				} else {
+					shak_reset_frame = 7;
+				}
+				break;
+			}
+			break;
+
+		case 15:
+			switch (local->shak_action) {
+			case SHAK_TALK:
+				shak_reset_frame = 15;
+				break;
+
+			case SHAK_SHUT_UP:
+				++local->shak_talk_count;
+				if (local->shak_talk_count > imath_random(20, 30)) {
+					shak_reset_frame       = imath_random(14, 15);
+					local->shak_talk_count = 0;
+
+				} else {
+					shak_reset_frame = 14;
+				}
+				break;
+			}
+			break;
+
+		case 24:
+			switch (local->shak_action) {
+			case SHAK_TALK:
+				shak_reset_frame = 24;
+				break;
+
+			case SHAK_SHUT_UP:
+				++local->shak_talk_count;
+				if (local->shak_talk_count > imath_random(10, 15)) {
+					shak_reset_frame = imath_random(23, 24);
+					local->shak_talk_count = 0;
+
+				} else {
+					shak_reset_frame = 23;
+				}
+				break;
+			}
+			break;
+		}
+
+		if (shak_reset_frame >= 0) {
+			kernel_reset_animation(aa[1], shak_reset_frame);
+			local->shak_frame = shak_reset_frame;
+		}
+	}
+}
+
+static void room_509_init() {
+	int id;
+
+	kernel.disable_fastwalk = true;
+
+	ss[fx_water]  = kernel_load_series(kernel_name('x', 0), false);
+	seq[fx_water] = kernel_seq_forward(ss[fx_water], false, 8, 0, 0, 0);
+	kernel_seq_depth(seq[fx_water], 1);
+	kernel_seq_range(seq[fx_water], KERNEL_FIRST, KERNEL_LAST);
+
+	if (previous_room != KERNEL_RESTORING_GAME) {
+		local->anim_0_running = false;
+		local->anim_1_running = false;
+		local->prevent        = false;
+	}
+
+	local->shak_talk_count     = 0;
+	global[move_direction_510] = true;
+
+	if (global[player_persona] == PLAYER_IS_KING) {
+		conv_get(CONV_SHAK_29_IN_WAY);
+		kernel.disable_fastwalk = true;
+		aa[0]                   = kernel_run_animation(kernel_name('s', 1), 0);
+		local->anim_0_running   = true;
+		local->shak_action      = SHAK_SHUT_UP;
+
+		id = kernel_add_dynamic(words_shak, words_walk_to, SYNTAX_MASC_NOT_PROPER, KERNEL_NONE,
+		                        0, 0, 0, 0);
+		kernel_dynamic_hot[id].prep = PREP_ON;
+		kernel_dynamic_walk(id, WALK_TO_FLAP_X, WALK_TO_FLAP_Y, FACING_NORTHWEST);
+		kernel_dynamic_anim(id, aa[0], 0);
+
+		if (conv_restore_running == CONV_SHAK_29_IN_WAY) {
+			conv_run(CONV_SHAK_29_IN_WAY);
+			conv_export_value(global[shak_506_angry]);
+		}
+
+	} else {
+		conv_get(CONV_SHAK_30_ON_LEDGE);
+		aa[1]                   = kernel_run_animation(kernel_name('s', 2), 0);
+		local->anim_1_running   = true;
+		local->shak_action      = SHAK_SHUT_UP;
+
+		id = kernel_add_dynamic(words_shak, words_walk_to, SYNTAX_MASC_NOT_PROPER, KERNEL_NONE,
+		                        0, 0, 0, 0);
+		kernel_dynamic_hot[id].prep = PREP_ON;
+		kernel_dynamic_walk(id, WALK_TO_LEDGE_X, WALK_TO_LEDGE_Y, FACING_NORTHEAST);
+		kernel_dynamic_anim(id, aa[1], 0);
+	}
+
+	if (previous_room == 510) {
+		player_first_walk(PLAYER_X_FROM_510, PLAYER_Y_FROM_510, FACING_EAST,
+		                  WALK_TO_X_FROM_510, WALK_TO_Y_FROM_510, FACING_SOUTHEAST, true);
 
-void room_509_init() {
+	} else if ((previous_room == 508) || (previous_room != KERNEL_RESTORING_GAME)) {
+		player_first_walk(PLAYER_X_FROM_508, PLAYER_Y_FROM_508, FACING_WEST,
+		                  WALK_TO_X_FROM_508, WALK_TO_Y_FROM_508, FACING_NORTHWEST, true);
+	}
 
+	local->update_clock = kernel.clock;
+
+	section_5_music();
+}
+
+static void room_509_daemon() {
+	int dist;
+
+	if (local->anim_0_running) {
+		handle_animation_shak_block();
+	}
+
+	if (local->anim_1_running) {
+		handle_animation_shak_ledge();
+	}
+
+	if (global[player_persona] == PLAYER_IS_KING) {
+
+		if ((player.x < 115) && (player.y < 115) && (!local->prevent)) {
+			player.commands_allowed = false;
+			local->shak_action      = SHAK_FLAP;
+			local->prevent          = true;
+			player_walk(WALK_TO_FLAP_X, WALK_TO_FLAP_Y, FACING_NORTHWEST);
+		}
+	}
+
+	if (kernel.clock >= local->update_clock) {
+		dist = 127 - ((imath_hypot(player.x - 284, player.y - 152) * 127) / 378);
+		if (!sound_off) {
+			if (player.x < 38) {
+				sound_queue(N_005Waterfall, 42);
+			} else {
+				sound_queue(N_005Waterfall, dist);
+			}
+		}
+		local->update_clock = kernel.clock + player.frame_delay;
+	}
+}
+
+static void process_conv_shak_in_way() {
+	int you_trig_flag = false;
+	int me_trig_flag  = false;
+
+	if (kernel.trigger == ROOM_509_YOU_TALK) {
+		local->shak_action = SHAK_TALK;
+	}
+
+	if (kernel.trigger == ROOM_509_ME_TALK) {
+		local->shak_action = SHAK_SHUT_UP;
+	}
+
+	if (!you_trig_flag) {
+		conv_you_trigger(ROOM_509_YOU_TALK);
+	}
+
+	if (!me_trig_flag) {
+		conv_me_trigger(ROOM_509_ME_TALK);
+	}
+
+	local->shak_talk_count = 0;
 }
 
-void room_509_daemon() {
+static void process_conv_shak_ledge() {
+	int you_trig_flag = false;
+	int me_trig_flag  = false;
+
+	if (kernel.trigger == ROOM_509_YOU_TALK) {
+		local->shak_action = SHAK_TALK;
+	}
+
+	if (kernel.trigger == ROOM_509_ME_TALK) {
+		local->shak_action = SHAK_SHUT_UP;
+	}
+
+	if (!you_trig_flag) {
+		conv_you_trigger(ROOM_509_YOU_TALK);
+	}
 
+	if (!me_trig_flag) {
+		conv_me_trigger(ROOM_509_ME_TALK);
+	}
+
+	local->shak_talk_count = 0;
 }
 
-void room_509_pre_parser() {
+static void room_509_pre_parser() {
+	if (player_said_1(path_to_east) && player.need_to_walk) {
+		if (!player_said_1(walk_down)) {
+			player.need_to_walk = false;
+		}
+	}
+
+	if (player_said_2(walk_down, path_to_west)) {
+		player.walk_off_edge_to_room = 510;
+	}
 
+	if (player_said_2(take, mud) && !global[has_taken_mud]) {
+		if (!player_has(mud)) {
+			player_walk(TAKE_MUD_X, TAKE_MUD_Y, FACING_NORTH);
+		}
+	}
 }
 
-void room_509_parser() {
+static void room_509_parser() {
+	if (conv_control.running == CONV_SHAK_29_IN_WAY) {
+		process_conv_shak_in_way();
+		player.command_ready = false;
+		return;
+	}
+
+	if (conv_control.running == CONV_SHAK_30_ON_LEDGE) {
+		process_conv_shak_ledge();
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(walk_down, path_to_west)) {
+		if (global[player_persona] == PLAYER_IS_KING) {
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_2(take, mud) && global[has_taken_mud]) {
+		text_show(50924);
+		player.command_ready = false;
+		return;
+
+	} else if (player_said_2(take, mud) && !player_has(mud)) {
+		switch (kernel.trigger) {
+		case 0:
+			player.commands_allowed = false;
+			player.walker_visible   = false;
+			aa[2]                   = kernel_run_animation(kernel_name('t', 1), 1);
+			kernel_synch(KERNEL_ANIM, aa[2], KERNEL_PLAYER, 0);
+			break;
 
+		case 1:
+			kernel_abort_animation(aa[2]);
+			player.walker_visible   = true;
+			player.commands_allowed = true;
+			global[has_taken_mud]   = true;
+			kernel_synch(KERNEL_PLAYER, 0, KERNEL_NOW, 0);
+			++global[player_score];
+			sound_play(N_TakeObjectSnd);
+			inter_give_to_player(mud);
+			object_examine(mud, 50921, 0);
+			break;
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(talk_to, shak)) {
+		if (global[player_persona] == PLAYER_IS_KING) {
+			conv_run(CONV_SHAK_29_IN_WAY);
+			conv_export_value(global[shak_506_angry]);
+		} else {
+			conv_run(CONV_SHAK_30_ON_LEDGE);
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(walk_down, path_to_east)) {
+		new_room = 508;
+		player.command_ready = false;
+		return;
+	}
+
+	if (player.look_around) {
+		if (global[player_persona] == PLAYER_IS_KING) {
+			text_show(50901);
+		} else {
+			text_show(50902);
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_1(look) || player_said_1(look_at)) {
+
+		if (player_said_1(sky)) {
+			text_show(50903);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(edge_of_cliff)) {
+			text_show(50904);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(mountainside)) {
+			text_show(50905);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(path_to_east)) {
+			text_show(50906);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(waterfall)) {
+			text_show(50907);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(ledge)) {
+			text_show(50911);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(boulders)) {
+			text_show(50912);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(landing)) {
+			if (local->anim_0_running) {
+				text_show(50914);
+			} else {
+				text_show(50913);
+			}
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(path_to_west)) {
+			if (local->anim_0_running) {
+				text_show(50915);
+			} else {
+				text_show(50916);
+			}
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(shak)) {
+			text_show(50917);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(mud)) {
+			if (player.main_object_source == STROKE_INTERFACE) {
+				text_show(50920);
+				player.command_ready = false;
+				return;
+			}
+		}
+	}
+
+	if (player_said_3(fill, goblet, waterfall) || player_said_3(put, goblet, waterfall)) {
+		text_show(50908);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_3(throw, dates, shak) || player_said_3(give, dates, shak)) {
+		text_show(50918);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(open, bottle_of_flies) || player_said_3(give, bottle_of_flies, shak)) {
+		text_show(50919);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_3(put, torch, waterfall)) {
+		text_show(50908);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(put, waterfall)) {
+		text_show(50910);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(take, mud)) {
+		text_show(50921);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(make_noise, birdcall)) {
+		sound_play(N_BlowBirdCall);
+		text_show(50923);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_3(sword, attack, shak) ||
+	    player_said_3(sword, carve_up, shak) ||
+	    player_said_3(sword, thrust, shak)) {
+		if (global[said_use_sword_shak]) {
+			text_show(50922);
+		} else {
+			conv_run(CONV_SHAK_29_IN_WAY);
+			conv_export_value(global[shak_506_angry]);
+			global[said_use_sword_shak] = true;
+		}
+		player.command_ready = false;
+		return;
+	}
 }
 
 void room_509_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.shak_frame);
+	s.syncAsSint16LE(scratch.shak_action);
+	s.syncAsSint16LE(scratch.shak_talk_count);
+	s.syncAsSint16LE(scratch.anim_0_running);
+	s.syncAsSint16LE(scratch.anim_1_running);
+	s.syncAsSint16LE(scratch.prevent);
+	s.syncAsSint32LE(scratch.update_clock);
 }
 
 void room_509_preload() {
-	room_init_code_pointer = room_509_init;
+	room_init_code_pointer       = room_509_init;
 	room_pre_parser_code_pointer = room_509_pre_parser;
-	room_parser_code_pointer = room_509_parser;
-	room_daemon_code_pointer = room_509_daemon;
+	room_parser_code_pointer     = room_509_parser;
+	room_daemon_code_pointer     = room_509_daemon;
 
 	section_5_walker();
 	section_5_interface();
+
+	vocab_make_active(words_shak);
 }
 
 } // namespace Rooms
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room510.cpp b/engines/mads/madsv2/dragonsphere/rooms/room510.cpp
index ab452777a86..74ecfda852f 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room510.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room510.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/matte.h"
 #include "mads/madsv2/core/sound.h"
 #include "mads/madsv2/core/text.h"
 #include "mads/madsv2/dragonsphere/mads/conv.h"
@@ -39,40 +41,1094 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[15];
+	int16 sequence[15];
+	int16 animation[4];
+	int16 facing;
+	int16 new_x;
+	int16 new_y;
+	int16 old_x;
+	int16 old_y;
+	int16 old_facing;
+	int16 on_shore;
+	int16 standing_on;
+	int16 pid_frame;
+	int16 pid_action;
+	int16 anim_0_running;
+	int16 move_counter;
+	int16 first_jump;
 };
 
+static Scratch scratch;
+
 #define local (&scratch)
 #define ss    local->sprite
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
+#define fx_n                    0
+#define fx_ew                   1
+#define fx_s                    2
+#define fx_belt                 3
+
+#define ROOM_510_DONE_ENTER_FROM_509 60
+#define ROOM_510_JUMP                65
+#define ROOM_510_END_OF_JUMP         67
+#define ROOM_510_TURN                70
+#define ROOM_510_END_OF_TURN         75
+#define ROOM_510_WHOA_SOUTH          80
+#define ROOM_510_WHOA_NORTH          85
+#define ROOM_510_WAIT_FOR_END_SLIDE  90
+#define ROOM_510_SOUND               120
+
+#define BASE_X                  133
+#define BASE_Y                  19
+
+#define ENTER_509_X_BOTTOM      308
+#define ENTER_509_Y_BOTTOM      48
+
+#define ENTER_512_X_BOTTOM      98
+#define ENTER_512_Y_BOTTOM      106
+
+#define NEITHER                 0
+#define TOP_LEFT                1
+#define BOTTOM_LEFT             2
+#define TOP_RIGHT               3
+#define BOTTOM_RIGHT            4
+
+#define PID_SLIDE               0
+#define PID_LEAVE               1
+#define PID_FREEZE              2
+#define PID_SLIDE_JUMP          3
+
+
+static void handle_animation_pid() {
+	int pid_reset_frame;
+	int no_commands = false;
+
+	if (kernel_anim[aa[0]].frame != local->pid_frame) {
+		local->pid_frame = kernel_anim[aa[0]].frame;
+		pid_reset_frame = -1;
+
+		if (local->pid_action == PID_SLIDE_JUMP) {
+			no_commands = true;
+		}
+
+		switch (local->pid_frame) {
+		case 101:
+		case 115:
+			new_room = 509;
+			break;
+
+		case 122:
+			pid_reset_frame = 101;
+			break;
+
+		case 130:
+			pid_reset_frame = 86;
+			break;
+
+		case 57:
+		case 84:
+		case 14:
+		case 28:
+		case 85:
+		case 86:
+		case 149:
+			if (local->pid_frame == 14 && !player.been_here_before) {
+				pid_reset_frame = 131;
+
+			} else {
+
+				if (local->pid_frame == 57 || local->pid_frame == 84) {
+					local->pid_action = PID_FREEZE;
+				}
+
+				switch (local->pid_action) {
+				case PID_FREEZE:
+					if (!no_commands) {
+						player.commands_allowed = true;
+					}
+					if (local->on_shore == TOP_RIGHT) {
+						pid_reset_frame = 84;
+					} else {
+						pid_reset_frame = 85;
+					}
+					break;
+
+				case PID_SLIDE:
+				case PID_SLIDE_JUMP:
+					player.commands_allowed = false;
+					if (local->on_shore == TOP_RIGHT) {
+						pid_reset_frame = 28;
+						local->on_shore = BOTTOM_RIGHT;
+						if (local->pid_action == PID_SLIDE) {
+							local->new_y    = ENTER_509_Y_BOTTOM;
+						}
+					} else {
+						pid_reset_frame = 57;
+						local->on_shore = TOP_RIGHT;
+						if (local->pid_action == PID_SLIDE) {
+							local->new_y    = ENTER_509_Y_BOTTOM - 29;
+						}
+					}
+					break;
+
+				case PID_LEAVE:
+					player.commands_allowed = false;
+					if (local->on_shore == TOP_RIGHT) {
+						pid_reset_frame = 115;
+					} else {
+						pid_reset_frame = 123;
+					}
+					break;
+				}
+				break;
+			}
+			break;
+		}
+
+		if (pid_reset_frame >= 0) {
+			kernel_reset_animation(aa[0], pid_reset_frame);
+			local->pid_frame = pid_reset_frame;
+		}
+	}
+}
+
+static void room_510_init() {
+	global[grid_position]      = 5;
+	global[grid_position + 1]  = 4;
+	global[grid_position + 2]  = 9;
+	global[grid_position + 3]  = 10;
+	global[grid_position + 4]  = 15;
+	global[grid_position + 5]  = 20;
+	global[grid_position + 6]  = 19;
+	global[grid_position + 7]  = 24;
+	global[grid_position + 8]  = 23;
+	global[grid_position + 9]  = 18;
+
+	global[grid_position + 10] = 13;
+	global[grid_position + 11] = 8;
+	global[grid_position + 12] = 3;
+	global[grid_position + 13] = 2;
+	global[grid_position + 14] = 1;
+	global[grid_position + 15] = 6;
+	global[grid_position + 16] = 7;
+	global[grid_position + 17] = 12;
+
+	global[grid_position + 18] = 17;
+	global[grid_position + 19] = 22;
+	global[grid_position + 20] = 21;
+	global[grid_position + 21] = 16;
+	global[grid_position + 22] = 11;
+
+	if (player_has(magic_belt)) {
+		ss[fx_belt]  = kernel_load_series(kernel_name('p', 0), false);
+		seq[fx_belt] = kernel_seq_stamp(ss[fx_belt], false, KERNEL_FIRST);
+		kernel_seq_depth(seq[fx_belt], 1);
+	}
+
+	if (kernel.teleported_in) {
+		global[player_persona] = PLAYER_IS_PID;
+	}
+
+	local->first_jump = false;
+
+	if (previous_room != KERNEL_RESTORING_GAME) {
+		local->anim_0_running = false;
+		local->standing_on    = 0;
+		if (global[move_direction_510]) {
+			local->move_counter   = 0;
+		} else {
+			local->move_counter   = 0;
+		}
+	}
+
+	ss[fx_n]     = kernel_load_series(kernel_name('b', 0), false);
+	ss[fx_s]     = kernel_load_series(kernel_name('b', 3), false);
+	ss[fx_ew]    = kernel_load_series(kernel_name('b', 1), false);
+
+	player.walker_visible   = false;
+
+	if (previous_room == KERNEL_RESTORING_GAME) {
+
+		if (local->standing_on) {
+			switch (local->facing) {
+			case FACING_NORTH:
+				seq[fx_n] = kernel_seq_stamp(ss[fx_n], false, 13);
+				kernel_seq_loc(seq[fx_n], local->new_x - 1, local->new_y + 11);
+				kernel_seq_depth(seq[fx_n], 1);
+				break;
+
+			case FACING_SOUTH:
+				seq[fx_s] = kernel_seq_stamp(ss[fx_s], true, 12);
+				kernel_seq_loc(seq[fx_s], local->new_x + 3, local->new_y + 36);
+				kernel_seq_depth(seq[fx_s], 1);
+				break;
+
+			case FACING_EAST:
+				seq[fx_ew] = kernel_seq_stamp(ss[fx_ew], true, 13);
+				kernel_seq_loc(seq[fx_ew], local->new_x + 2, local->new_y + 19);
+				kernel_seq_depth(seq[fx_ew], 1);
+				break;
+
+			case FACING_WEST:
+				seq[fx_ew] = kernel_seq_stamp(ss[fx_ew], false, 13);
+				kernel_seq_loc(seq[fx_ew], local->new_x + 2, local->new_y + 19);
+				kernel_seq_depth(seq[fx_ew], 1);
+				break;
+			}
 
-void room_510_init() {
+		} else {
+			aa[0] = kernel_run_animation(kernel_name('p', 1), 0);
+			if (local->on_shore == TOP_RIGHT) {
+				kernel_reset_animation(aa[0], 85);
+			} else {
+				kernel_reset_animation(aa[0], 86);
+			}
+		}
 
+	} else if (previous_room == 512 || (previous_room == 505 && !global[move_direction_510])) {
+		local->on_shore   = false;
+		local->facing     = FACING_EAST;
+		local->old_facing = FACING_EAST;
+		local->old_x      = ENTER_512_X_BOTTOM;
+		local->first_jump = true;
+
+		if (player.x == 1) {
+			local->old_y       = ENTER_512_Y_BOTTOM - 29;
+			local->new_x       = ENTER_512_X_BOTTOM + 35;
+			local->new_y       = ENTER_512_Y_BOTTOM - 29;
+			local->standing_on = 11;
+
+		} else {
+			local->old_y       = ENTER_512_Y_BOTTOM;
+			local->new_x       = ENTER_512_X_BOTTOM + 35;
+			local->new_y       = ENTER_512_Y_BOTTOM;
+			local->standing_on = 16;
+		}
+
+		kernel_timing_trigger(1, ROOM_510_JUMP);
+		player.commands_allowed = false;
+
+	} else if (previous_room == 509 || previous_room != KERNEL_RESTORING_GAME) {
+		aa[0] = kernel_run_animation(kernel_name('p', 1), 0);
+		player.commands_allowed = false;
+		local->anim_0_running   = true;
+		local->pid_action       = PID_FREEZE;
+		local->on_shore         = BOTTOM_RIGHT;
+		local->facing           = FACING_WEST;
+		local->new_x            = ENTER_509_X_BOTTOM;
+		local->new_y            = ENTER_509_Y_BOTTOM;
+	}
+
+	section_5_music();
 }
 
-void room_510_daemon() {
+static void room_510_daemon() {
+	int temp;
+
+	if (local->anim_0_running) {
+		handle_animation_pid();
+	}
+
+	switch (kernel.trigger) {
+	case ROOM_510_JUMP:
+		seq[fx_ew] = kernel_seq_forward(ss[fx_ew], true, 5, 0, 0, 1);
+		kernel_seq_depth(seq[fx_ew], 1);
+		kernel_seq_range(seq[fx_ew], 16, 34);
+		kernel_seq_trigger(seq[fx_ew], KERNEL_TRIGGER_EXPIRE, 0, ROOM_510_END_OF_JUMP);
+		kernel_seq_trigger(seq[fx_ew], KERNEL_TRIGGER_SPRITE, 30, ROOM_510_SOUND);
+		kernel_seq_loc(seq[fx_ew], local->old_x + 2, local->new_y + 19);
+		break;
+
+	case ROOM_510_END_OF_JUMP:
+		temp       = seq[fx_ew];
+		seq[fx_ew] = kernel_seq_stamp(ss[fx_ew], true, 13);
+		kernel_seq_loc(seq[fx_ew], local->new_x + 2, local->new_y + 19);
+		kernel_seq_depth(seq[fx_ew], 1);
+		kernel_synch(KERNEL_SERIES, seq[fx_ew], KERNEL_SERIES, temp);
+
+		if (global[global[max_grid_value]] == local->standing_on) {
+			++local->move_counter;
+		} else {
+			new_room = 511;
+			if (local->first_jump) {
+				global[pid_just_died] = true;
+			}
+		}
+		local->first_jump       = false;
+		player.commands_allowed = true;
+		break;
+	}
 
+	if (kernel.trigger == ROOM_510_SOUND) {
+		sound_play(N_JumpThwang);
+	}
 }
 
-void room_510_pre_parser() {
+static void which_pillar(int *it, int *new_x, int *new_y, int *adjoining) {
+	int offset;
+
+	if (inter_point_x < 150) {
+		offset = 0;
+
+	} else if (inter_point_x < 190) {
+		offset = 1;
+
+	} else if (inter_point_x < 220) {
+		offset = 2;
+
+	} else if (inter_point_x < 260) {
+		offset = 3;
+
+	} else {
+		offset = 4;
+	}
+
+	if (inter_point_y < 35) {
+		*it    = 1 + offset;
+		*new_y = BASE_Y;
+
+	} else if (inter_point_y < 65) {
+		*it    = 6 + offset;
+		*new_y = BASE_Y + 29;
+
+	} else if (inter_point_y < 90) {
+		*it    = 11 + offset;
+		*new_y = BASE_Y + 58;
+
+	} else if (inter_point_y < 120) {
+		*it    = 16 + offset;
+		*new_y = BASE_Y + 87;
 
+	} else {
+		*it    = 21 + offset;
+		*new_y = BASE_Y + 116;
+	}
+
+	*new_x = BASE_X + (35 * offset);
+
+	if (((*adjoining >= 7) && (*adjoining <= 9)) ||
+	    ((*adjoining >= 12) && (*adjoining <= 14)) ||
+	    ((*adjoining >= 17) && (*adjoining <= 19))) {
+		if ((*it == *adjoining + 1) || (*it == *adjoining - 1) ||
+		    (*it == *adjoining + 5) || (*it == *adjoining - 5)) {
+			*adjoining = true;
+		} else {
+			*adjoining = false;
+		}
+
+	} else if ((*adjoining >= 2) && (*adjoining <= 4)) {
+		if ((*it == *adjoining + 5) || (*it == *adjoining + 1) || (*it == *adjoining - 1)) {
+			*adjoining = true;
+		} else {
+			*adjoining = false;
+		}
+
+	} else if ((*adjoining >= 22) && (*adjoining <= 24)) {
+		if ((*it == *adjoining - 5) || (*it == *adjoining + 1) || (*it == *adjoining - 1)) {
+			*adjoining = true;
+		} else {
+			*adjoining = false;
+		}
+
+	} else if ((*adjoining == 6) || (*adjoining == 11) || (*adjoining == 16)) {
+		if ((*it == *adjoining - 5) || (*it == *adjoining + 5) || (*it == *adjoining + 1)) {
+			*adjoining = true;
+		} else {
+			*adjoining = false;
+		}
+
+	} else if ((*adjoining == 10) || (*adjoining == 15) || (*adjoining == 20)) {
+		if ((*it == *adjoining - 5) || (*it == *adjoining + 5) || (*it == *adjoining - 1)) {
+			*adjoining = true;
+		} else {
+			*adjoining = false;
+		}
+
+	} else if (*adjoining == 1) {
+		if ((*it == 2) || (*it == 6)) {
+			*adjoining = true;
+		} else {
+			*adjoining = false;
+		}
+
+	} else if (*adjoining == 5) {
+		if ((*it == 4) || (*it == 10)) {
+			*adjoining = true;
+		} else {
+			*adjoining = false;
+		}
+
+	} else if (*adjoining == 21) {
+		if ((*it == 22) || (*it == 16)) {
+			*adjoining = true;
+		} else {
+			*adjoining = false;
+		}
+	}
 }
 
-void room_510_parser() {
+static void room_510_pre_parser() {
+	player.need_to_walk = false;
+}
+
+static void room_510_parser() {
+	int temp;
+	int selected;
+	int new_x;
+	int new_y;
+	int adjoining;
+
+	if (kernel.trigger == ROOM_510_SOUND) {
+		sound_play(N_JumpThwang);
+		player.command_ready = false;
+		return;
+	}
+
+	switch (kernel.trigger) {
+	case ROOM_510_JUMP:
+		if (local->on_shore) {
+			kernel_abort_animation(aa[0]);
+			local->anim_0_running = false;
+			player.commands_allowed = false;
+
+		} else switch (local->facing) {
+		case FACING_NORTH:
+			kernel_seq_delete(seq[fx_n]);
+			break;
+
+		case FACING_SOUTH:
+			kernel_seq_delete(seq[fx_s]);
+			break;
+
+		case FACING_EAST:
+		case FACING_WEST:
+			kernel_seq_delete(seq[fx_ew]);
+			break;
+		}
+
+		switch (local->facing) {
+		case FACING_NORTH:
+			seq[fx_n] = kernel_seq_forward(ss[fx_n], false, 5, 0, 0, 1);
+			kernel_seq_depth(seq[fx_n], 1);
+			kernel_seq_range(seq[fx_n], 15, 34);
+			kernel_seq_trigger(seq[fx_n], KERNEL_TRIGGER_EXPIRE, 0, ROOM_510_END_OF_JUMP);
+			kernel_seq_trigger(seq[fx_n], KERNEL_TRIGGER_SPRITE, 30, ROOM_510_SOUND);
+			kernel_seq_loc(seq[fx_n], local->new_x, local->new_y + 40);
+			break;
+
+		case FACING_SOUTH:
+			seq[fx_s] = kernel_seq_forward(ss[fx_s], false, 5, 0, 0, 1);
+			kernel_seq_depth(seq[fx_s], 1);
+			kernel_seq_range(seq[fx_s], 15, 33);
+			kernel_seq_trigger(seq[fx_s], KERNEL_TRIGGER_EXPIRE, 0, ROOM_510_END_OF_JUMP);
+			kernel_seq_trigger(seq[fx_s], KERNEL_TRIGGER_SPRITE, 29, ROOM_510_SOUND);
+			kernel_seq_loc(seq[fx_s], local->new_x, local->new_y + 7);
+			break;
+
+		case FACING_EAST:
+			seq[fx_ew] = kernel_seq_forward(ss[fx_ew], true, 5, 0, 0, 1);
+			kernel_seq_depth(seq[fx_ew], 1);
+			kernel_seq_range(seq[fx_ew], 16, 34);
+			kernel_seq_trigger(seq[fx_ew], KERNEL_TRIGGER_EXPIRE, 0, ROOM_510_END_OF_JUMP);
+			kernel_seq_trigger(seq[fx_ew], KERNEL_TRIGGER_SPRITE, 30, ROOM_510_SOUND);
+			if (!local->on_shore) {
+				kernel_seq_loc(seq[fx_ew], local->old_x + 2, local->new_y + 19);
+			}
+			break;
+
+		case FACING_WEST:
+			seq[fx_ew] = kernel_seq_forward(ss[fx_ew], false, 5, 0, 0, 1);
+			kernel_seq_depth(seq[fx_ew], 1);
+			kernel_seq_range(seq[fx_ew], 16, 34);
+			kernel_seq_trigger(seq[fx_ew], KERNEL_TRIGGER_EXPIRE, 0, ROOM_510_END_OF_JUMP);
+			kernel_seq_trigger(seq[fx_ew], KERNEL_TRIGGER_SPRITE, 30, ROOM_510_SOUND);
+			if (local->on_shore == TOP_RIGHT) {
+				kernel_seq_loc(seq[fx_ew], ENTER_509_X_BOTTOM, ENTER_509_Y_BOTTOM - 11);
+				kernel_synch(KERNEL_SERIES, seq[fx_ew], KERNEL_NOW, 0);
+				local->on_shore = NEITHER;
+			} else if (local->on_shore == BOTTOM_RIGHT) {
+				kernel_seq_loc(seq[fx_ew], ENTER_509_X_BOTTOM + 2, ENTER_509_Y_BOTTOM + 17);
+				kernel_synch(KERNEL_SERIES, seq[fx_ew], KERNEL_NOW, 0);
+				local->on_shore = NEITHER;
+			} else if (local->on_shore == NEITHER) {
+				kernel_seq_loc(seq[fx_ew], local->old_x + 3, local->new_y + 19);
+			}
+			break;
+		}
+
+		player.command_ready = false;
+		return;
+
+	case ROOM_510_END_OF_JUMP:
+		if (local->standing_on < 500) {
+			if (global[move_direction_510]) {
+				if (global[grid_position + local->move_counter] != local->standing_on) {
+					new_room = 511;
+				}
+			} else {
+				if (global[global[max_grid_value] - local->move_counter] != local->standing_on) {
+					new_room = 511;
+				}
+			}
+		}
+
+		++local->move_counter;
+
+		switch (local->facing) {
+		case FACING_NORTH:
+			temp      = seq[fx_n];
+			seq[fx_n] = kernel_seq_stamp(ss[fx_n], false, 13);
+			kernel_seq_loc(seq[fx_n], local->new_x - 1, local->new_y + 11);
+			kernel_seq_depth(seq[fx_n], 1);
+			kernel_synch(KERNEL_SERIES, seq[fx_n], KERNEL_SERIES, temp);
+			local->facing           = FACING_NORTH;
+			local->on_shore         = NEITHER;
+			if (imath_random(1, 5) == 1) {
+				kernel_timing_trigger(1, ROOM_510_WHOA_NORTH);
+			} else {
+				player.commands_allowed = true;
+			}
+			break;
+
+		case FACING_SOUTH:
+			temp      = seq[fx_s];
+			seq[fx_s] = kernel_seq_stamp(ss[fx_s], true, 12);
+			kernel_seq_loc(seq[fx_s], local->new_x + 3, local->new_y + 36);
+			kernel_seq_depth(seq[fx_s], 1);
+			kernel_synch(KERNEL_SERIES, seq[fx_s], KERNEL_SERIES, temp);
+			local->facing           = FACING_SOUTH;
+			local->on_shore         = NEITHER;
+			if (imath_random(1, 5) == 1) {
+				kernel_timing_trigger(1, ROOM_510_WHOA_SOUTH);
+			} else {
+				player.commands_allowed = true;
+			}
+			break;
+
+		case FACING_EAST:
+			temp       = seq[fx_ew];
+			if (local->standing_on == 509) {
+				aa[0] = kernel_run_animation(kernel_name('p', 1), 0);
+				kernel_synch(KERNEL_ANIM, aa[0], KERNEL_SERIES, temp);
+				if (local->new_y == ENTER_509_Y_BOTTOM) {
+					kernel_reset_animation(aa[0], 87);
+				} else {
+					kernel_reset_animation(aa[0], 102);
+				}
+				local->anim_0_running = true;
+
+			} else {
+				seq[fx_ew] = kernel_seq_stamp(ss[fx_ew], true, 13);
+				kernel_seq_loc(seq[fx_ew], local->new_x + 2, local->new_y + 19);
+				kernel_seq_depth(seq[fx_ew], 1);
+				kernel_synch(KERNEL_SERIES, seq[fx_ew], KERNEL_SERIES, temp);
+				player.commands_allowed = true;
+				local->facing           = FACING_EAST;
+				local->on_shore         = NEITHER;
+			}
+			break;
+
+		case FACING_WEST:
+			temp       = seq[fx_ew];
+			seq[fx_ew] = kernel_seq_stamp(ss[fx_ew], false, 13);
+			kernel_seq_loc(seq[fx_ew], local->new_x + 2, local->new_y + 19);
+			kernel_seq_depth(seq[fx_ew], 1);
+			kernel_synch(KERNEL_SERIES, seq[fx_ew], KERNEL_SERIES, temp);
+			player.commands_allowed = true;
+			local->facing           = FACING_WEST;
+			local->on_shore         = NEITHER;
+			if (local->standing_on == 512) {
+				if (!(global[player_score_flags] & SCORE_CROSS_PILLARS)) {
+					global[player_score_flags] = global[player_score_flags] | SCORE_CROSS_PILLARS;
+					global[player_score] += 3;
+				}
+				new_room = 512;
+			}
+			break;
+		}
+		player.command_ready = false;
+		return;
+
+	case ROOM_510_TURN:
+		switch (local->old_facing) {
+		case FACING_NORTH:
+			kernel_seq_delete(seq[fx_n]);
+			switch (local->facing) {
+			case FACING_EAST:
+				seq[fx_n] = kernel_seq_forward(ss[fx_n], true, 7, 0, 0, 1);
+				kernel_seq_range(seq[fx_n], 36, 39);
+				kernel_seq_loc(seq[fx_n], local->old_x + 2, local->old_y + 11);
+				break;
+
+			case FACING_WEST:
+				seq[fx_n] = kernel_seq_forward(ss[fx_n], false, 7, 0, 0, 1);
+				kernel_seq_range(seq[fx_n], 36, 39);
+				kernel_seq_loc(seq[fx_n], local->old_x - 1, local->old_y + 11);
+				break;
+
+			case FACING_SOUTH:
+				seq[fx_n] = kernel_seq_forward(ss[fx_n], false, 7, 0, 0, 1);
+				kernel_seq_range(seq[fx_n], 36, 43);
+				kernel_seq_loc(seq[fx_n], local->old_x - 1, local->old_y + 11);
+				break;
+			}
+			kernel_seq_depth(seq[fx_n], 1);
+			kernel_seq_trigger(seq[fx_n], KERNEL_TRIGGER_EXPIRE, 0, ROOM_510_END_OF_TURN);
+			break;
+
+		case FACING_SOUTH:
+			kernel_seq_delete(seq[fx_s]);
+			switch (local->facing) {
+			case FACING_EAST:
+				seq[fx_n] = kernel_seq_backward(ss[fx_n], true, 7, 0, 0, 1);
+				kernel_seq_range(seq[fx_n], 40, 43);
+				kernel_seq_loc(seq[fx_n], local->old_x + 2, local->old_y + 11);
+				break;
+
+			case FACING_WEST:
+				seq[fx_n] = kernel_seq_backward(ss[fx_n], false, 7, 0, 0, 1);
+				kernel_seq_range(seq[fx_n], 40, 43);
+				kernel_seq_loc(seq[fx_n], local->old_x - 1, local->old_y + 11);
+				break;
+
+			case FACING_NORTH:
+				seq[fx_n] = kernel_seq_backward(ss[fx_n], false, 7, 0, 0, 1);
+				kernel_seq_range(seq[fx_n], 36, 43);
+				kernel_seq_loc(seq[fx_n], local->old_x - 1, local->old_y + 11);
+				break;
+			}
+			kernel_seq_depth(seq[fx_n], 1);
+			kernel_seq_trigger(seq[fx_n], KERNEL_TRIGGER_EXPIRE, 0, ROOM_510_END_OF_TURN);
+			break;
+
+		case FACING_WEST:
+			kernel_seq_delete(seq[fx_ew]);
+			switch (local->facing) {
+			case FACING_EAST:
+				seq[fx_n] = kernel_seq_backward(ss[fx_n], false, 7, 0, 0, 1);
+				kernel_seq_range(seq[fx_n], 36, 39);
+				kernel_seq_trigger(seq[fx_n], KERNEL_TRIGGER_EXPIRE, 0, ROOM_510_TURN + 2);
+				kernel_seq_loc(seq[fx_n], local->old_x + 2, local->old_y + 11);
+				break;
+
+			case FACING_NORTH:
+				seq[fx_n] = kernel_seq_backward(ss[fx_n], false, 7, 0, 0, 1);
+				kernel_seq_range(seq[fx_n], 36, 39);
+				kernel_seq_trigger(seq[fx_n], KERNEL_TRIGGER_EXPIRE, 0, ROOM_510_END_OF_TURN);
+				kernel_seq_loc(seq[fx_n], local->old_x + 1, local->old_y + 11);
+				break;
+
+			case FACING_SOUTH:
+				seq[fx_n] = kernel_seq_forward(ss[fx_n], false, 7, 0, 0, 1);
+				kernel_seq_range(seq[fx_n], 40, 43);
+				kernel_seq_trigger(seq[fx_n], KERNEL_TRIGGER_EXPIRE, 0, ROOM_510_END_OF_TURN);
+				kernel_seq_loc(seq[fx_n], local->old_x - 1, local->old_y + 11);
+				break;
+			}
+			kernel_seq_depth(seq[fx_n], 1);
+			break;
+
+		case FACING_EAST:
+			kernel_seq_delete(seq[fx_ew]);
+			switch (local->facing) {
+			case FACING_NORTH:
+				seq[fx_n] = kernel_seq_backward(ss[fx_n], true, 7, 0, 0, 1);
+				kernel_seq_range(seq[fx_n], 36, 39);
+				kernel_seq_trigger(seq[fx_n], KERNEL_TRIGGER_EXPIRE, 0, ROOM_510_END_OF_TURN);
+				kernel_seq_loc(seq[fx_n], local->old_x + 2, local->old_y + 11);
+				break;
+
+			case FACING_WEST:
+				seq[fx_n] = kernel_seq_backward(ss[fx_n], true, 7, 0, 0, 1);
+				kernel_seq_range(seq[fx_n], 36, 39);
+				kernel_seq_trigger(seq[fx_n], KERNEL_TRIGGER_EXPIRE, 0, ROOM_510_TURN + 1);
+				kernel_seq_loc(seq[fx_n], local->old_x + 2, local->old_y + 11);
+				break;
+
+			case FACING_SOUTH:
+				seq[fx_n] = kernel_seq_forward(ss[fx_n], true, 7, 0, 0, 1);
+				kernel_seq_range(seq[fx_n], 40, 43);
+				kernel_seq_trigger(seq[fx_n], KERNEL_TRIGGER_EXPIRE, 0, ROOM_510_END_OF_TURN);
+				kernel_seq_loc(seq[fx_n], local->old_x + 2, local->old_y + 11);
+				break;
+			}
+			kernel_seq_depth(seq[fx_n], 1);
+			break;
+		}
+		player.command_ready = false;
+		return;
+
+	case ROOM_510_TURN + 1:
+		seq[fx_n] = kernel_seq_forward(ss[fx_n], false, 7, 0, 0, 1);
+		kernel_seq_range(seq[fx_n], 36, 39);
+		kernel_seq_depth(seq[fx_n], 1);
+		kernel_seq_loc(seq[fx_n], local->old_x + 2, local->old_y + 11);
+		kernel_seq_trigger(seq[fx_n], KERNEL_TRIGGER_EXPIRE, 0, ROOM_510_END_OF_TURN);
+		player.command_ready = false;
+		return;
+
+	case ROOM_510_TURN + 2:
+		seq[fx_n] = kernel_seq_forward(ss[fx_n], true, 7, 0, 0, 1);
+		kernel_seq_range(seq[fx_n], 36, 39);
+		kernel_seq_depth(seq[fx_n], 1);
+		kernel_seq_loc(seq[fx_n], local->old_x + 2, local->old_y + 11);
+		kernel_seq_trigger(seq[fx_n], KERNEL_TRIGGER_EXPIRE, 0, ROOM_510_END_OF_TURN);
+		player.command_ready = false;
+		return;
+
+	case ROOM_510_END_OF_TURN:
+		switch (local->facing) {
+		case FACING_NORTH:
+			temp      = seq[fx_n];
+			seq[fx_n] = kernel_seq_stamp(ss[fx_n], false, 13);
+			kernel_seq_loc(seq[fx_n], local->old_x - 1, local->old_y + 11);
+			kernel_seq_depth(seq[fx_n], 1);
+			kernel_synch(KERNEL_SERIES, seq[fx_n], KERNEL_SERIES, temp);
+			break;
+
+		case FACING_SOUTH:
+			temp      = seq[fx_n];
+			seq[fx_s] = kernel_seq_stamp(ss[fx_s], true, 12);
+			kernel_seq_loc(seq[fx_s], local->old_x + 3, local->old_y + 36);
+			kernel_seq_depth(seq[fx_s], 1);
+			kernel_synch(KERNEL_SERIES, seq[fx_s], KERNEL_SERIES, temp);
+			break;
+
+		case FACING_EAST:
+			temp       = seq[fx_n];
+			seq[fx_ew] = kernel_seq_stamp(ss[fx_ew], true, 13);
+			kernel_seq_loc(seq[fx_ew], local->old_x + 2, local->old_y + 19);
+			kernel_seq_depth(seq[fx_ew], 1);
+			kernel_synch(KERNEL_SERIES, seq[fx_ew], KERNEL_SERIES, temp);
+			break;
+
+		case FACING_WEST:
+			temp       = seq[fx_n];
+			seq[fx_ew] = kernel_seq_stamp(ss[fx_ew], false, 13);
+			kernel_seq_loc(seq[fx_ew], local->old_x + 2, local->old_y + 19);
+			kernel_seq_depth(seq[fx_ew], 1);
+			kernel_synch(KERNEL_SERIES, seq[fx_ew], KERNEL_SERIES, temp);
+			break;
+		}
+		kernel_timing_trigger(4, ROOM_510_JUMP);
+		player.command_ready = false;
+		return;
+
+	case ROOM_510_WHOA_SOUTH:
+		sound_play(N_CryOfDismay);
+		kernel_seq_delete(seq[fx_s]);
+		seq[fx_s] = kernel_seq_forward(ss[fx_s], false, 6, 0, 0, 1);
+		kernel_seq_depth(seq[fx_s], 1);
+		kernel_seq_range(seq[fx_s], 35, 54);
+		kernel_seq_loc(seq[fx_s], local->new_x + 1, local->new_y + 37);
+		kernel_seq_trigger(seq[fx_s], KERNEL_TRIGGER_EXPIRE, 0, ROOM_510_WHOA_SOUTH + 1);
+		player.command_ready = false;
+		return;
+
+	case ROOM_510_WHOA_SOUTH + 1:
+		temp      = seq[fx_s];
+		seq[fx_s] = kernel_seq_stamp(ss[fx_s], true, 12);
+		kernel_seq_loc(seq[fx_s], local->new_x + 3, local->new_y + 36);
+		kernel_seq_depth(seq[fx_s], 1);
+		kernel_synch(KERNEL_SERIES, seq[fx_s], KERNEL_SERIES, temp);
+		player.commands_allowed = true;
+		player.command_ready = false;
+		return;
+
+	case ROOM_510_WHOA_NORTH:
+		sound_play(N_CryOfDismay);
+		kernel_seq_delete(seq[fx_n]);
+		seq[fx_n] = kernel_seq_forward(ss[fx_n], false, 6, 0, 0, 1);
+		kernel_seq_depth(seq[fx_n], 1);
+		kernel_seq_range(seq[fx_n], 44, 63);
+		kernel_seq_loc(seq[fx_n], local->new_x - 1, local->new_y + 11);
+		kernel_seq_trigger(seq[fx_n], KERNEL_TRIGGER_EXPIRE, 0, ROOM_510_WHOA_NORTH + 1);
+		player.command_ready = false;
+		return;
+
+	case ROOM_510_WHOA_NORTH + 1:
+		temp      = seq[fx_n];
+		seq[fx_n] = kernel_seq_stamp(ss[fx_n], false, 13);
+		kernel_seq_loc(seq[fx_n], local->new_x - 1, local->new_y + 11);
+		kernel_seq_depth(seq[fx_n], 1);
+		kernel_synch(KERNEL_SERIES, seq[fx_n], KERNEL_SERIES, temp);
+		player.commands_allowed = true;
+		player.command_ready = false;
+		return;
+	}
+
+	if (kernel.trigger == ROOM_510_WAIT_FOR_END_SLIDE) {
+		if (local->pid_action != PID_FREEZE) {
+			kernel_timing_trigger(1, ROOM_510_WAIT_FOR_END_SLIDE);
+		} else {
+			kernel_timing_trigger(1, ROOM_510_JUMP);
+		}
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(jump_to, ledge) ||
+	    player_said_2(walk_down, path_to_east) ||
+	    player_said_2(walk_across, ledge)) {
+
+		if (!local->standing_on) {
+			if (inter_point_x > 100) {
+				if (player_said_1(walk_down)) {
+					local->pid_action = PID_LEAVE;
+				} else if (local->on_shore) {
+					local->pid_action = PID_SLIDE;
+				}
+				player.command_ready = false;
+				return;
+
+			} else {
+				text_show(51007);
+				player.command_ready = false;
+				return;
+			}
+
+		} else if (local->standing_on == 11) {
+			if (inter_point_x > 100) {
+				text_show(51008);
+				player.command_ready = false;
+				return;
+
+			} else {
+				local->old_x = local->new_x;
+				local->old_y = local->new_y;
+				local->new_x = ENTER_512_X_BOTTOM - 3;
+				local->new_y = ENTER_512_Y_BOTTOM - 29;
+			}
+
+		} else if (local->standing_on == 16) {
+			if (inter_point_x > 100) {
+				text_show(51008);
+				player.command_ready = false;
+				return;
+
+			} else {
+				local->old_x = local->new_x;
+				local->old_y = local->new_y;
+				local->new_x = ENTER_512_X_BOTTOM - 2;
+				local->new_y = ENTER_512_Y_BOTTOM;
+			}
+
+		} else if (local->standing_on == 5) {
+			if (inter_point_x < 100) {
+				text_show(51008);
+				player.command_ready = false;
+				return;
+
+			} else {
+				local->old_x = local->new_x;
+				local->old_y = local->new_y;
+				local->new_x = ENTER_509_X_BOTTOM - 3;
+				local->new_y = ENTER_509_Y_BOTTOM - 29;
+			}
+
+		} else if (local->standing_on == 10) {
+			if (inter_point_x < 100) {
+				text_show(51008);
+				player.command_ready = false;
+				return;
+
+			} else {
+				local->old_x = local->new_x;
+				local->old_y = local->new_y;
+				local->new_x = ENTER_509_X_BOTTOM - 3;
+				local->new_y = ENTER_509_Y_BOTTOM;
+			}
+
+		} else if (inter_point_x < 100) {
+			text_show(51007);
+			player.command_ready = false;
+			return;
+
+		} else {
+			text_show(51008);
+			player.command_ready = false;
+			return;
+		}
+
+		local->old_facing = local->facing;
+
+		if (local->standing_on == 5 || local->standing_on == 10) {
+			local->facing      = FACING_EAST;
+			local->standing_on = 509;
+
+		} else if (local->standing_on == 11 || local->standing_on == 16) {
+			local->facing      = FACING_WEST;
+			local->standing_on = 512;
+		}
+
+		player.commands_allowed = false;
+
+		if (local->old_facing == local->facing) {
+			kernel_timing_trigger(1, ROOM_510_JUMP);
+		} else {
+			kernel_timing_trigger(1, ROOM_510_TURN);
+		}
+
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(jump_to, pillar)) {
+		local->old_x = local->new_x;
+		local->old_y = local->new_y;
+
+		adjoining = local->standing_on;
+		which_pillar(&selected, &new_x, &new_y, &adjoining);
+
+		if (local->on_shore == TOP_RIGHT) {
+			if (selected == 10) {
+				local->pid_action = PID_SLIDE_JUMP;
+				kernel_timing_trigger(1, ROOM_510_WAIT_FOR_END_SLIDE);
+				local->standing_on      = selected;
+				player.commands_allowed = false;
+				local->new_x = new_x;
+				local->new_y = new_y;
+				player.command_ready = false;
+				return;
+
+			} else if (selected != 5) {
+				text_show(51009);
+				player.command_ready = false;
+				return;
+			}
+
+		} else if (local->on_shore == BOTTOM_RIGHT) {
+			if (selected == 5) {
+				local->pid_action = PID_SLIDE_JUMP;
+				kernel_timing_trigger(1, ROOM_510_WAIT_FOR_END_SLIDE);
+				local->standing_on      = selected;
+				player.commands_allowed = false;
+				local->new_x = new_x;
+				local->new_y = new_y;
+				player.command_ready = false;
+				return;
+
+			} else if (selected != 10) {
+				text_show(51009);
+				player.command_ready = false;
+				return;
+			}
+		}
+
+		if (selected == local->standing_on) {
+			text_show(51010);
+			player.command_ready = false;
+			return;
+
+		} else if (adjoining || local->on_shore) {
+			local->new_x = new_x;
+			local->new_y = new_y;
+
+			local->old_facing = local->facing;
+
+			if (!local->on_shore) {
+				if (selected == local->standing_on + 1) {
+					local->facing = FACING_EAST;
+				} else if (selected == local->standing_on - 1) {
+					local->facing = FACING_WEST;
+				} else if (selected == local->standing_on + 5) {
+					local->facing = FACING_SOUTH;
+				} else if (selected == local->standing_on - 5) {
+					local->facing = FACING_NORTH;
+				}
+			}
+
+			local->standing_on      = selected;
+			player.commands_allowed = false;
+
+			if ((local->old_facing == local->facing) || local->on_shore) {
+				kernel_timing_trigger(1, ROOM_510_JUMP);
+			} else {
+				kernel_timing_trigger(1, ROOM_510_TURN);
+			}
+
+		} else {
+			text_show(51009);
+			player.command_ready = false;
+			return;
+		}
+
+		player.command_ready = false;
+		return;
+	}
+
+	if (player.look_around) {
+		text_show(51001);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_1(look) || player_said_1(look_at)) {
+		if (player_said_1(pillar)) {
+			text_show(51002);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(ledge)) {
+			text_show(51003);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(path_to_east)) {
+			text_show(51004);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(nest)) {
+			text_show(51005);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(abyss)) {
+			text_show(51006);
+			player.command_ready = false;
+			return;
+		}
+	}
 
+	if (player_said_2(look_into, abyss)) {
+		text_show(51006);
+		player.command_ready = false;
+		return;
+	}
 }
 
 void room_510_synchronize(Common::Serializer &s) {
-	
+	for (int16 &v : scratch.sprite)    s.syncAsSint16LE(v);
+	for (int16 &v : scratch.sequence)  s.syncAsSint16LE(v);
+	for (int16 &v : scratch.animation) s.syncAsSint16LE(v);
+	s.syncAsSint16LE(scratch.facing);
+	s.syncAsSint16LE(scratch.new_x);
+	s.syncAsSint16LE(scratch.new_y);
+	s.syncAsSint16LE(scratch.old_x);
+	s.syncAsSint16LE(scratch.old_y);
+	s.syncAsSint16LE(scratch.old_facing);
+	s.syncAsSint16LE(scratch.on_shore);
+	s.syncAsSint16LE(scratch.standing_on);
+	s.syncAsSint16LE(scratch.pid_frame);
+	s.syncAsSint16LE(scratch.pid_action);
+	s.syncAsSint16LE(scratch.anim_0_running);
+	s.syncAsSint16LE(scratch.move_counter);
+	s.syncAsSint16LE(scratch.first_jump);
 }
 
 void room_510_preload() {
-	room_init_code_pointer = room_510_init;
+	room_init_code_pointer       = room_510_init;
 	room_pre_parser_code_pointer = room_510_pre_parser;
-	room_parser_code_pointer = room_510_parser;
-	room_daemon_code_pointer = room_510_daemon;
+	room_parser_code_pointer     = room_510_parser;
+	room_daemon_code_pointer     = room_510_daemon;
 
 	section_5_walker();
 	section_5_interface();
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room511.cpp b/engines/mads/madsv2/dragonsphere/rooms/room511.cpp
index 4df9a0dbf39..2c70f75591b 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room511.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room511.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,8 +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/matte.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,40 +42,106 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[15];
+	int16 sequence[15];
+	int16 animation[4];
+	int16 death_frame;
+	int16 speech_playing;
 };
 
+static Scratch scratch;
+
 #define local (&scratch)
 #define ss    local->sprite
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
 
-void room_511_init() {
+static void room_511_init() {
+	viewing_at_y = ((video_y - display_y) >> 1);
+	kernel_init_dialog();
+	kernel_set_interface_mode(INTER_LIMITED_SENTENCES);
 
-}
+	player.commands_allowed = false;
+	player.walker_visible   = false;
+	local->speech_playing   = false;
 
-void room_511_daemon() {
+	aa[0] = kernel_run_animation(kernel_name('p', 1), 0);
 
+	section_5_music();
 }
 
-void room_511_pre_parser() {
-
+static void room_511_daemon() {
+	int death_reset_frame;
+
+	if (kernel_anim[aa[0]].frame != local->death_frame) {
+		local->death_frame = kernel_anim[aa[0]].frame;
+		death_reset_frame = -1;
+
+		switch (local->death_frame) {
+
+		case 19:
+			if (speech_system_active && speech_on) {
+				global_speech_go(5);
+				local->speech_playing = 5;
+			}
+			break;
+
+		case 33:
+			if (local->speech_playing == 5) {
+				if (speech_system_active && speech_on) {
+					if (speech_status()) {
+						death_reset_frame = 32;
+
+					} else {
+						global_speech_go(2);
+						local->speech_playing = 2;
+						death_reset_frame = 32;
+					}
+				}
+
+			} else if (local->speech_playing == 2) {
+				if (speech_system_active && speech_on) {
+					if (speech_status()) {
+						death_reset_frame = 32;
+
+					} else {
+						new_room = 505;
+					}
+				}
+
+			} else {
+				new_room = 505;
+			}
+			break;
+		}
+
+		if (death_reset_frame >= 0) {
+			kernel_reset_animation(aa[0], death_reset_frame);
+			local->death_frame = death_reset_frame;
+		}
+	}
 }
 
-void room_511_parser() {
+static void room_511_pre_parser() {
+}
 
+static void room_511_parser() {
 }
 
 void room_511_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.death_frame);
+	s.syncAsSint16LE(scratch.speech_playing);
 }
 
 void room_511_preload() {
-	room_init_code_pointer = room_511_init;
+	room_init_code_pointer       = room_511_init;
 	room_pre_parser_code_pointer = room_511_pre_parser;
-	room_parser_code_pointer = room_511_parser;
-	room_daemon_code_pointer = room_511_daemon;
+	room_parser_code_pointer     = room_511_parser;
+	room_daemon_code_pointer     = room_511_daemon;
 
 	section_5_walker();
 	section_5_interface();
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room512.cpp b/engines/mads/madsv2/dragonsphere/rooms/room512.cpp
index 5adf5e3a583..91ad6a4634f 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room512.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room512.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/matte.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,40 +42,398 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[15];
+	int16 sequence[15];
+	int16 animation[4];
+	int16 pid_frame;
+	int16 pid_action;
+	int16 anim_0_running;
+	int16 shak_frame;
+	int16 shak_action;
+	int16 shak_talk_count;
+	int16 anim_1_running;
 };
 
+static Scratch scratch;
+
 #define local (&scratch)
 #define ss    local->sprite
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
+#define ROOM_512_YOU_TALK      60
+#define ROOM_512_ME_TALK       62
+
+#define fx_belt                0
+
+#define PLAYER_X_FROM_510      182
+#define PLAYER_Y_FROM_510      93
+
+#define PID_SHUT_UP            0
+#define PID_TALK               1
+#define PID_LOOK_BELT          2
+#define PID_JUMP               3
+
+#define CONV_33_SHAK           33
+
+#define SHAK_SHUT_UP           0
+#define SHAK_TALK              1
+#define SHAK_FLY               2
+#define SHAK_INVISIBLE         3
+
+
+static void handle_animation_pid() {
+	int pid_reset_frame;
+
+	if (kernel_anim[aa[0]].frame != local->pid_frame) {
+		local->pid_frame = kernel_anim[aa[0]].frame;
+		pid_reset_frame = -1;
+
+		switch (local->pid_frame) {
+
+		case 15:
+			sound_play(N_TakeObjectSnd);
+			inter_give_to_player(magic_belt);
+			object_examine(magic_belt, 51208, 0);
+			kernel_seq_delete(seq[fx_belt]);
+			++global[player_score];
+			break;
+
+		case 101:
+			new_room = 505;
+			break;
+
+		case 30:
+			local->shak_action = SHAK_SHUT_UP;
+			break;
+
+		case 56:
+		case 49:
+		case 38:
+
+			switch (local->pid_action) {
+
+			case PID_TALK:
+				pid_reset_frame = 38;
+				local->pid_action = PID_SHUT_UP;
+				break;
 
-void room_512_init() {
+			case PID_LOOK_BELT:
+				pid_reset_frame = 49;
+				local->pid_action = PID_SHUT_UP;
+				break;
 
+			case PID_SHUT_UP:
+				pid_reset_frame = 37;
+				break;
+
+			case PID_JUMP:
+				pid_reset_frame = 56;
+				break;
+			}
+			break;
+		}
+
+		if (pid_reset_frame >= 0) {
+			kernel_reset_animation(aa[0], pid_reset_frame);
+			local->pid_frame = pid_reset_frame;
+		}
+	}
 }
 
-void room_512_daemon() {
+static void handle_animation_shak() {
+	int shak_reset_frame;
+	int random;
+
+	if (kernel_anim[aa[1]].frame != local->shak_frame) {
+		local->shak_frame = kernel_anim[aa[1]].frame;
+		shak_reset_frame = -1;
+
+		switch (local->shak_frame) {
+
+		case 21:
+			conv_run(CONV_33_SHAK);
+			break;
+
+		case 22:
+		case 26:
+
+			switch (local->shak_action) {
+			case SHAK_SHUT_UP:
+				++local->shak_talk_count;
+				if (local->shak_talk_count > imath_random(20, 30)) {
+					random = imath_random(1, 5);
+					if (random == 1) {
+						shak_reset_frame = 22;
+					} else if (random == 2) {
+						shak_reset_frame = 26;
+					} else {
+						shak_reset_frame = 21;
+					}
+					local->shak_talk_count = 0;
+
+				} else {
+					shak_reset_frame = 21;
+				}
+				break;
+
+			case SHAK_TALK:
+				shak_reset_frame = 22;
+				break;
+
+			case SHAK_FLY:
+				shak_reset_frame   = 30;
+				local->shak_action = SHAK_INVISIBLE;
+				break;
+			}
+			break;
+
+		case 24:
+		case 28:
+		case 29:
+		case 30:
+
+			switch (local->shak_action) {
+
+			case SHAK_TALK:
+				shak_reset_frame = imath_random(27, 29);
+				++local->shak_talk_count;
+				if (local->shak_talk_count > 30) {
+					local->shak_action     = SHAK_SHUT_UP;
+					local->shak_talk_count = 0;
+					shak_reset_frame       = 23;
+				}
+				break;
+
+			case SHAK_SHUT_UP:
+				++local->shak_talk_count;
+				if (local->shak_talk_count > imath_random(20, 30)) {
+					random = imath_random(1, 3);
+					if (random == 1) {
+						shak_reset_frame = 24;
+					} else {
+						shak_reset_frame = 23;
+					}
+					local->shak_talk_count = 0;
+
+				} else {
+					shak_reset_frame = 23;
+				}
+				break;
 
+			case SHAK_FLY:
+				shak_reset_frame = 24;
+				break;
+			}
+			break;
+
+		case 54:
+			local->pid_action = PID_JUMP;
+			break;
+
+		case 57:
+			if (local->shak_action == SHAK_INVISIBLE) {
+				shak_reset_frame = 56;
+			} else {
+				shak_reset_frame = 0;
+			}
+			break;
+		}
+
+		if (shak_reset_frame >= 0) {
+			kernel_reset_animation(aa[1], shak_reset_frame);
+			local->shak_frame = shak_reset_frame;
+		}
+	}
 }
 
-void room_512_pre_parser() {
+static void room_512_init() {
+	if (previous_room != KERNEL_RESTORING_GAME) {
+		local->anim_0_running = false;
+		local->anim_1_running = false;
+	}
+
+	if (object_is_here(magic_belt)) {
+		conv_get(CONV_33_SHAK);
+		ss[fx_belt]  = kernel_load_series(kernel_name('p', 0), false);
+		seq[fx_belt] = kernel_seq_stamp(ss[fx_belt], false, KERNEL_FIRST);
+		kernel_seq_depth(seq[fx_belt], 14);
+
+		aa[1]                   = kernel_run_animation(kernel_name('s', 1), 0);
+		local->anim_1_running   = true;
+		local->shak_action      = SHAK_INVISIBLE;
+		kernel_reset_animation(aa[1], 57);
+
+	} else {
+		kernel_flip_hotspot(words_belt, false);
+	}
+
+	global[move_direction_510] = false;
+	player.x                   = PLAYER_X_FROM_510;
+	player.y                   = PLAYER_Y_FROM_510;
+	player.facing              = FACING_NORTHWEST;
+
+	section_5_music();
+}
+
+static void room_512_daemon() {
+	if (local->anim_0_running) {
+		handle_animation_pid();
+	}
+
+	if (local->anim_1_running) {
+		handle_animation_shak();
+	}
+}
+
+static void process_conv_shak() {
+	int you_trig_flag = false;
+	int me_trig_flag  = false;
+
+	if (player_verb == conv033_exit_b_b) {
+		conv_hold();
+		local->shak_action = SHAK_FLY;
+		you_trig_flag      = true;
+		me_trig_flag       = true;
+	}
+
+	if (kernel.trigger == ROOM_512_YOU_TALK) {
+		local->shak_action = SHAK_TALK;
+		local->pid_action  = PID_SHUT_UP;
+	}
 
+	if (kernel.trigger == ROOM_512_ME_TALK) {
+		if (player_verb == conv033_six_only) {
+			local->pid_action  = PID_LOOK_BELT;
+		} else {
+			local->pid_action  = PID_TALK;
+		}
+		local->shak_action = SHAK_SHUT_UP;
+	}
+
+	if (!you_trig_flag) {
+		conv_you_trigger(ROOM_512_YOU_TALK);
+	}
+
+	if (!me_trig_flag) {
+		conv_me_trigger(ROOM_512_ME_TALK);
+	}
+
+	local->shak_talk_count = 0;
+}
+
+static void room_512_pre_parser() {
 }
 
-void room_512_parser() {
+static void room_512_parser() {
+	if (conv_control.running == CONV_33_SHAK) {
+		process_conv_shak();
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(take, belt)) {
+		player.walker_visible   = false;
+		player.commands_allowed = false;
+		aa[0]                   = kernel_run_animation(kernel_name('p', 1), 0);
+		local->anim_0_running   = true;
+		local->pid_action       = PID_SHUT_UP;
+		kernel_reset_animation(aa[0], 1);
+		kernel_synch(KERNEL_ANIM, aa[0], KERNEL_PLAYER, 0);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_2(jump_to, pillar)) {
+		if (inter_point_x < 183) {
+			player.x = 0;
+		} else {
+			player.x = 1;
+		}
+		new_room = 510;
+		player.command_ready = false;
+		return;
+	}
+
+	if (player.look_around) {
+		text_show(51201);
+		player.command_ready = false;
+		return;
+	}
+
+	if (player_said_1(look) || player_said_1(look_at)) {
+		if (player_said_1(mountainside)) {
+			text_show(51202);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(nest)) {
+			if (object_is_here(magic_belt)) {
+				text_show(51204);
+				player.command_ready = false;
+				return;
+			}
+		}
+
+		if (player_said_1(pillar)) {
+			text_show(51205);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(ledge)) {
+			text_show(51206);
+			player.command_ready = false;
+			return;
+		}
+
+		if (player_said_1(belt)) {
+			if (object_is_here(magic_belt)) {
+				text_show(51207);
+				player.command_ready = false;
+				return;
+			}
+		}
+
+		if (player_said_1(abyss)) {
+			text_show(51203);
+			player.command_ready = false;
+			return;
+		}
+	}
+
+	if (player_said_2(look_into, abyss)) {
+		text_show(51203);
+		player.command_ready = false;
+		return;
+	}
 
+	if (player_said_2(put, nest)) {
+		text_show(51209);
+		player.command_ready = false;
+		return;
+	}
 }
 
 void room_512_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.pid_frame);
+	s.syncAsSint16LE(scratch.pid_action);
+	s.syncAsSint16LE(scratch.anim_0_running);
+	s.syncAsSint16LE(scratch.shak_frame);
+	s.syncAsSint16LE(scratch.shak_action);
+	s.syncAsSint16LE(scratch.shak_talk_count);
+	s.syncAsSint16LE(scratch.anim_1_running);
 }
 
 void room_512_preload() {
-	room_init_code_pointer = room_512_init;
+	room_init_code_pointer       = room_512_init;
 	room_pre_parser_code_pointer = room_512_pre_parser;
-	room_parser_code_pointer = room_512_parser;
-	room_daemon_code_pointer = room_512_daemon;
+	room_parser_code_pointer     = room_512_parser;
+	room_daemon_code_pointer     = room_512_daemon;
 
 	section_5_walker();
 	section_5_interface();
diff --git a/engines/mads/madsv2/dragonsphere/rooms/room557.cpp b/engines/mads/madsv2/dragonsphere/rooms/room557.cpp
index 46c2fd29ba9..104c92264fa 100644
--- a/engines/mads/madsv2/dragonsphere/rooms/room557.cpp
+++ b/engines/mads/madsv2/dragonsphere/rooms/room557.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/matte.h"
 #include "mads/madsv2/core/sound.h"
 #include "mads/madsv2/core/text.h"
 #include "mads/madsv2/dragonsphere/mads/conv.h"
@@ -39,40 +41,97 @@ namespace Dragonsphere {
 namespace Rooms {
 
 struct Scratch {
+	int16 sprite[15];
+	int16 sequence[15];
+	int16 animation[4];
+	int16 king_frame;
+	int16 king_action;
 };
 
+static Scratch scratch;
+
 #define local (&scratch)
 #define ss    local->sprite
 #define seq   local->sequence
 #define aa    local->animation
 
-//static Scratch scratch;
+#define fx_rock_1            0
+#define fx_rock_2            1
 
-void room_557_init() {
+#define ROOM_557_ROCK_SOUND  60
 
-}
 
-void room_557_daemon() {
+static void room_557_init() {
+	ss[fx_rock_1]  = kernel_load_series(kernel_name('x', 0), false);
+	ss[fx_rock_2]  = kernel_load_series(kernel_name('x', 1), false);
+
+	viewing_at_y = ((video_y - display_y) >> 1);
+	kernel_init_dialog();
+	kernel_set_interface_mode(INTER_LIMITED_SENTENCES);
 
+	player.commands_allowed = false;
+	player.walker_visible   = false;
+
+	aa[0] = kernel_run_animation(kernel_name('k', 1), 0);
 }
 
-void room_557_pre_parser() {
+static void room_557_daemon() {
+	int king_reset_frame;
+
+	if (kernel.trigger == ROOM_557_ROCK_SOUND) {
+		sound_play(N_RockClatter);
+	}
+
+	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 153:
+			seq[fx_rock_1] = kernel_seq_forward(ss[fx_rock_1], false, 5, 0, 0, 1);
+			kernel_seq_depth(seq[fx_rock_1], 1);
+			kernel_seq_range(seq[fx_rock_1], KERNEL_FIRST, KERNEL_LAST);
+			kernel_seq_trigger(seq[fx_rock_1], KERNEL_TRIGGER_SPRITE, 5, ROOM_557_ROCK_SOUND);
+			kernel_seq_trigger(seq[fx_rock_1], KERNEL_TRIGGER_SPRITE, 15, ROOM_557_ROCK_SOUND);
+			break;
+
+		case 225:
+			seq[fx_rock_2] = kernel_seq_forward(ss[fx_rock_2], false, 5, 0, 0, 1);
+			kernel_seq_depth(seq[fx_rock_2], 1);
+			kernel_seq_range(seq[fx_rock_2], KERNEL_FIRST, KERNEL_LAST);
+			break;
+
+		case 254:
+			new_room = 508;
+			break;
+		}
+
+		if (king_reset_frame >= 0) {
+			kernel_reset_animation(aa[0], king_reset_frame);
+			local->king_frame = king_reset_frame;
+		}
+	}
+}
 
+static void room_557_pre_parser() {
 }
 
 void room_557_parser() {
-
 }
 
 void room_557_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);
 }
 
 void room_557_preload() {
-	room_init_code_pointer = room_557_init;
+	room_init_code_pointer       = room_557_init;
 	room_pre_parser_code_pointer = room_557_pre_parser;
-	room_parser_code_pointer = room_557_parser;
-	room_daemon_code_pointer = room_557_daemon;
+	room_parser_code_pointer     = room_557_parser;
+	room_daemon_code_pointer     = room_557_daemon;
 
 	section_5_walker();
 	section_5_interface();




More information about the Scummvm-git-logs mailing list