[Scummvm-git-logs] scummvm master -> 9102f40bfd1adb80cac9494325757a79370485c8

athrxx athrxx at scummvm.org
Tue Apr 27 21:15:08 UTC 2021


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

Summary:
e10af53359 KYRA: (MR/Chinese) - add detection etc. and fix installer archive loading
8cbe9489c0 KYRA: (MR/Chinese) - add support for 4th language in the options menu
94d5cea3b5 KYRA: (MR/Chinese) - Chinese font drawing + main menu fixes
897173cbac KYRA: (MR/Chinese) - more font related tweaks
0afbbd6b20 KYRA: (LOL) - add support for playable talkie demo
5c9b5e0968 KYRA: (LOL) - monster stats fix
9102f40bfd NEWS: mention KYRA3 Chinese and LOL demo


Commit: e10af53359da6ad6e566ac760f213b66970069f2
    https://github.com/scummvm/scummvm/commit/e10af53359da6ad6e566ac760f213b66970069f2
Author: athrxx (athrxx at scummvm.org)
Date: 2021-04-27T22:06:32+02:00

Commit Message:
KYRA: (MR/Chinese) - add detection etc. and fix installer archive loading

(also add LOL-CD demo resources to reduce number of binary git pushs)

Changed paths:
  A devtools/create_kyradat/resources/lol_dos_cddemo.h
  A devtools/create_kyradat/resources/mr_dos_cd_chinese_simplified.h
  A devtools/create_kyradat/resources/mr_dos_cd_english.h
  A devtools/create_kyradat/resources/mr_dos_cd_french.h
  A devtools/create_kyradat/resources/mr_dos_cd_german.h
  A devtools/create_kyradat/resources/mr_dos_cd_italian.h
  A devtools/create_kyradat/resources/mr_dos_cd_russian.h
  A devtools/create_kyradat/resources/mr_dos_cd_spanish.h
    devtools/create_kyradat/create_kyradat.cpp
    devtools/create_kyradat/create_kyradat.h
    devtools/create_kyradat/games.cpp
    devtools/create_kyradat/resources.cpp
    devtools/create_kyradat/resources/mr_dos_cd.h
    dists/engine-data/kyra.dat
    engines/kyra/detection.h
    engines/kyra/detection_tables.h
    engines/kyra/resource/resource.h
    engines/kyra/resource/resource_intern.cpp
    engines/kyra/resource/staticres.cpp


diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp
index 8dd77bdfd8..38d3f8799e 100644
--- a/devtools/create_kyradat/create_kyradat.cpp
+++ b/devtools/create_kyradat/create_kyradat.cpp
@@ -45,7 +45,7 @@
 
 
 enum {
-	kKyraDatVersion = 108
+	kKyraDatVersion = 109
 };
 
 const ExtractFilename extractFilenames[] = {
@@ -205,7 +205,7 @@ const ExtractFilename extractFilenames[] = {
 
 
 	// MALCOLM'S REVENGE
-	{ k3MainMenuStrings, kStringList, false },
+	{ k3MainMenuStrings, kStringList, true },
 	{ k3MusicFiles, kStringList, false },
 	{ k3ScoreTable, kRawData, false },
 	{ k3SfxFiles, kStringList, false },
@@ -213,6 +213,9 @@ const ExtractFilename extractFilenames[] = {
 	{ k3ItemAnimData, k2ItemAnimDefinition, false },
 	{ k3ItemMagicTable, kRawData, false },
 	{ k3ItemStringMap, kRawData, false },
+	{ k3FontData, kRawData, true },
+	{ k3VqaSubtitlesIntro, kStringList, true },
+	{ k3VqaSubtitlesBoat, kStringList, true },
 
 	// EYE OF THE BEHOLDER COMMON
 	{ kEoBBaseChargenStrings1, kStringList, true },
@@ -1202,6 +1205,7 @@ const TypeTable languageTable[] = {
 	{ JA_JPN, 6 },
 	{ RU_RUS, 7 },
 	{ HE_ISR, 8 },
+	{ ZH_CNA, 9 },
 	{ -1, -1 }
 };
 
diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h
index 84e303d296..df2bc8dc77 100644
--- a/devtools/create_kyradat/create_kyradat.h
+++ b/devtools/create_kyradat/create_kyradat.h
@@ -177,6 +177,9 @@ enum kExtractID {
 	k3ItemAnimData,
 	k3ItemMagicTable,
 	k3ItemStringMap,
+	k3FontData,
+	k3VqaSubtitlesIntro,
+	k3VqaSubtitlesBoat,
 
 	kRpgCommonMoreStrings,
 	kRpgCommonDscShapeIndex,
diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index 7637224db1..dbf2c6f0b8 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -98,6 +98,7 @@ const Game kyra3Games[] = {
 	{ kKyra3, kPlatformDOS, kTalkieVersion, IT_ITA },
 	{ kKyra3, kPlatformDOS, kTalkieVersion, ES_ESP },
 	{ kKyra3, kPlatformDOS, kTalkieVersion, RU_RUS },
+	{ kKyra3, kPlatformDOS, kTalkieVersion, ZH_CNA },
 
 	GAME_DUMMY_ENTRY
 };
@@ -150,6 +151,10 @@ const Game lolGames[] = {
 	{ kLoL, kPlatformDOS, kTalkieVersion, RU_RUS },
 	{ kLoL, kPlatformDOS, kTalkieVersion, ES_ESP },
 
+	{ kLoL, kPlatformDOS, kTalkieDemoVersion, EN_ANY },
+	{ kLoL, kPlatformDOS, kTalkieDemoVersion, FR_FRA },
+	{ kLoL, kPlatformDOS, kTalkieDemoVersion, DE_DEU },
+
 	{ kLoL, kPlatformPC98, kNoSpecial, JA_JPN },
 
 	{ kLoL, kPlatformFMTowns, kNoSpecial, JA_JPN },
@@ -801,6 +806,9 @@ const int kyra3Need[] = {
 	k3ItemAnimData,
 	k3ItemMagicTable,
 	k3ItemStringMap,
+	k3FontData,
+	k3VqaSubtitlesIntro,
+	k3VqaSubtitlesBoat,
 	-1
 };
 
@@ -1146,6 +1154,90 @@ const int lolCDNeed[] = {
 	-1
 };
 
+const int lolCDDemoNeed[] = {
+	kLoLCharacterDefs,
+	kLoLIngameSfxFiles,
+	kLoLIngameSfxIndex,
+	kLoLMusicTrackMap,
+	kLoLIngameGMSfxIndex,
+	kLoLIngameMT32SfxIndex,
+	kLoLIngamePcSpkSfxIndex,
+	kLoLSpellProperties,
+	kLoLGameShapeMap,
+	kLoLSceneItemOffs,
+	kLoLCharInvIndex,
+	kLoLCharInvDefs,
+	kLoLCharDefsMan,
+	kLoLCharDefsAkshel,
+	kLoLExpRequirements,
+	kLoLMonsterModifiers1,
+	kLoLMonsterModifiers2,
+	kLoLMonsterModifiers3,
+	kLoLMonsterModifiers4,
+	kLoLMonsterShiftOffsets,
+	kLoLMonsterDirFlags,
+	kLoLMonsterScaleY,
+	kLoLMonsterScaleX,
+	kLoLMonsterScaleWH,
+	kLoLFlyingObjectShp,
+	kLoLInventoryDesc,
+
+	kLoLLevelShpList,
+	kLoLLevelDatList,
+	kLoLCompassDefs,
+	kLoLItemPrices,
+	kLoLStashSetup,
+	kLoLDscWalls,
+	kRpgCommonDscShapeIndex,
+	kLoLDscOvlMap,
+	kLoLDscScaleWidthData,
+	kLoLDscScaleHeightData,
+	kRpgCommonDscX,
+	kLoLBaseDscY,
+	kRpgCommonDscTileIndex,
+	kRpgCommonDscDoorShapeIndex,
+	kRpgCommonDscDimData1,
+	kRpgCommonDscDimData2,
+	kRpgCommonDscBlockMap,
+	kRpgCommonDscDimMap,
+	kLoLDscOvlIndex,
+	kRpgCommonDscBlockIndex,
+	kRpgCommonDscDoorY2,
+	kRpgCommonDscDoorFrameY1,
+	kRpgCommonDscDoorFrameY2,
+	kRpgCommonDscDoorScaleOffs,
+	kLoLDscDoorScale,
+	kLoLDscDoor4,
+	kLoLDscDoorX,
+	kLoLDscDoorY,
+
+	kLoLScrollXTop,
+	kLoLScrollYTop,
+	kLoLScrollXBottom,
+	kLoLScrollYBottom,
+
+	kLoLButtonDefs,
+	kLoLButtonList1,
+	kLoLButtonList2,
+	kLoLButtonList3,
+	kLoLButtonList4,
+	kLoLButtonList5,
+	kLoLButtonList6,
+	kLoLButtonList7,
+	kLoLButtonList8,
+
+	kLoLLegendData,
+	kLoLMapCursorOvl,
+	kLoLMapStringId,
+
+	kLoLSpellbookAnim,
+	kLoLSpellbookCoords,
+	kLoLHealShapeFrames,
+	kLoLLightningDefs,
+
+	-1
+};
+
 const int lolDemoNeed[] = {
 	k2SeqplayPakFiles,
 	k2SeqplayStrings,
diff --git a/devtools/create_kyradat/resources.cpp b/devtools/create_kyradat/resources.cpp
index 5936f03436..1ccb67b6ec 100644
--- a/devtools/create_kyradat/resources.cpp
+++ b/devtools/create_kyradat/resources.cpp
@@ -92,6 +92,13 @@
 
 // Malcolm's Revenge
 #include "resources/mr_dos_cd.h"
+#include "resources/mr_dos_cd_english.h"
+#include "resources/mr_dos_cd_french.h"
+#include "resources/mr_dos_cd_german.h"
+#include "resources/mr_dos_cd_italian.h"
+#include "resources/mr_dos_cd_spanish.h"
+#include "resources/mr_dos_cd_russian.h"
+#include "resources/mr_dos_cd_chinese_simplified.h"
 
 // Eye of the Beholder
 #include "resources/eob1_dos.h"
@@ -124,6 +131,7 @@
 // Lands of Lore
 #include "resources/lol_dos_demo.h"
 #include "resources/lol_dos_demo_english.h"
+#include "resources/lol_dos_cddemo.h"
 
 #include "resources/lol_dos.h"
 #include "resources/lol_dos_english.h"
@@ -1004,7 +1012,13 @@ static const ResourceProvider resourceProviders[] = {
 	{ k2IngameTimJpStrings, kKyra2, kPlatformPC98, kNoSpecial, UNK_LANG, &k2IngameTimJpStringsPC98Provider },
 	{ k2IngameShapeAnimData, kKyra2, kPlatformPC98, kNoSpecial, UNK_LANG, &k2IngameShapeAnimDataPC98Provider },
 	{ k2SeqplayStrings, kKyra2, kPlatformPC98, kNoSpecial, JA_JPN, &k2SeqplayStringsPC98JapaneseProvider },
-	{ k3MainMenuStrings, kKyra3, kPlatformDOS, kTalkieVersion, UNK_LANG, &k3MainMenuStringsDOSCDProvider },
+	{ k3MainMenuStrings, kKyra3, kPlatformDOS, kTalkieVersion, EN_ANY, &k3MainMenuStringsDOSCDEnglishProvider },
+	{ k3MainMenuStrings, kKyra3, kPlatformDOS, kTalkieVersion, FR_FRA, &k3MainMenuStringsDOSCDFrenchProvider },
+	{ k3MainMenuStrings, kKyra3, kPlatformDOS, kTalkieVersion, DE_DEU, &k3MainMenuStringsDOSCDGermanProvider },
+	{ k3MainMenuStrings, kKyra3, kPlatformDOS, kTalkieVersion, IT_ITA, &k3MainMenuStringsDOSCDItalianProvider },
+	{ k3MainMenuStrings, kKyra3, kPlatformDOS, kTalkieVersion, ES_ESP, &k3MainMenuStringsDOSCDSpanishProvider },
+	{ k3MainMenuStrings, kKyra3, kPlatformDOS, kTalkieVersion, RU_RUS, &k3MainMenuStringsDOSCDRussianProvider },
+	{ k3MainMenuStrings, kKyra3, kPlatformDOS, kTalkieVersion, ZH_CNA, &k3MainMenuStringsDOSCDChineseSmplProvider },
 	{ k3MusicFiles, kKyra3, kPlatformDOS, kTalkieVersion, UNK_LANG, &k3MusicFilesDOSCDProvider },
 	{ k3ScoreTable, kKyra3, kPlatformDOS, kTalkieVersion, UNK_LANG, &k3ScoreTableDOSCDProvider },
 	{ k3SfxFiles, kKyra3, kPlatformDOS, kTalkieVersion, UNK_LANG, &k3SfxFilesDOSCDProvider },
@@ -1012,6 +1026,27 @@ static const ResourceProvider resourceProviders[] = {
 	{ k3ItemAnimData, kKyra3, kPlatformDOS, kTalkieVersion, UNK_LANG, &k3ItemAnimDataDOSCDProvider },
 	{ k3ItemMagicTable, kKyra3, kPlatformDOS, kTalkieVersion, UNK_LANG, &k3ItemMagicTableDOSCDProvider },
 	{ k3ItemStringMap, kKyra3, kPlatformDOS, kTalkieVersion, UNK_LANG, &k3ItemStringMapDOSCDProvider },
+	{ k3FontData, kKyra3, kPlatformDOS, kTalkieVersion, EN_ANY, &k3DummyDataDOSCDProvider },
+	{ k3FontData, kKyra3, kPlatformDOS, kTalkieVersion, FR_FRA, &k3DummyDataDOSCDProvider },
+	{ k3FontData, kKyra3, kPlatformDOS, kTalkieVersion, DE_DEU, &k3DummyDataDOSCDProvider },
+	{ k3FontData, kKyra3, kPlatformDOS, kTalkieVersion, IT_ITA, &k3DummyDataDOSCDProvider },
+	{ k3FontData, kKyra3, kPlatformDOS, kTalkieVersion, ES_ESP, &k3DummyDataDOSCDProvider },
+	{ k3FontData, kKyra3, kPlatformDOS, kTalkieVersion, RU_RUS, &k3DummyDataDOSCDProvider },
+	{ k3FontData, kKyra3, kPlatformDOS, kTalkieVersion, ZH_CNA, &k3FontDataDOSCDChineseSmplProvider },
+	{ k3VqaSubtitlesIntro, kKyra3, kPlatformDOS, kTalkieVersion, EN_ANY, &k3VqaSubtitlesIntroDOSCDEnglishProvider },
+	{ k3VqaSubtitlesIntro, kKyra3, kPlatformDOS, kTalkieVersion, FR_FRA, &k3VqaSubtitlesIntroDOSCDFrenchProvider },
+	{ k3VqaSubtitlesIntro, kKyra3, kPlatformDOS, kTalkieVersion, DE_DEU, &k3VqaSubtitlesIntroDOSCDGermanProvider },
+	{ k3VqaSubtitlesIntro, kKyra3, kPlatformDOS, kTalkieVersion, IT_ITA, &k3VqaSubtitlesIntroDOSCDItalianProvider },
+	{ k3VqaSubtitlesIntro, kKyra3, kPlatformDOS, kTalkieVersion, ES_ESP, &k3VqaSubtitlesIntroDOSCDSpanishProvider },
+	{ k3VqaSubtitlesIntro, kKyra3, kPlatformDOS, kTalkieVersion, RU_RUS, &k3VqaSubtitlesIntroDOSCDRussianProvider },
+	{ k3VqaSubtitlesIntro, kKyra3, kPlatformDOS, kTalkieVersion, ZH_CNA, &k3VqaSubtitlesIntroDOSCDChineseSmplProvider },
+	{ k3VqaSubtitlesBoat, kKyra3, kPlatformDOS, kTalkieVersion, EN_ANY, &k3VqaSubtitlesBoatDOSCDEnglishProvider },
+	{ k3VqaSubtitlesBoat, kKyra3, kPlatformDOS, kTalkieVersion, FR_FRA, &k3VqaSubtitlesBoatDOSCDFrenchProvider },
+	{ k3VqaSubtitlesBoat, kKyra3, kPlatformDOS, kTalkieVersion, DE_DEU, &k3VqaSubtitlesBoatDOSCDGermanProvider },
+	{ k3VqaSubtitlesBoat, kKyra3, kPlatformDOS, kTalkieVersion, IT_ITA, &k3VqaSubtitlesBoatDOSCDItalianProvider },
+	{ k3VqaSubtitlesBoat, kKyra3, kPlatformDOS, kTalkieVersion, ES_ESP, &k3VqaSubtitlesBoatDOSCDSpanishProvider },
+	{ k3VqaSubtitlesBoat, kKyra3, kPlatformDOS, kTalkieVersion, RU_RUS, &k3VqaSubtitlesBoatDOSCDRussianProvider },
+	{ k3VqaSubtitlesBoat, kKyra3, kPlatformDOS, kTalkieVersion, ZH_CNA, &k3VqaSubtitlesBoatDOSCDChineseSmplProvider },
 	{ kEoBBaseNpcPresetsNames, kEoB1, kPlatformDOS, kNoSpecial, EN_ANY, &kEoB1NpcPresetsNamesDOSEnglishProvider },
 	{ kEoBBaseChargenStrings1, kEoB1, kPlatformDOS, kNoSpecial, EN_ANY, &kEoB1ChargenStrings1DOSEnglishProvider },
 	{ kEoBBaseChargenStrings2, kEoB1, kPlatformDOS, kNoSpecial, EN_ANY, &kEoB1ChargenStrings2DOSEnglishProvider },
@@ -4453,6 +4488,82 @@ static const ResourceProvider resourceProviders[] = {
 	{ kLoLCharacterDefs, kLoL, kPlatformDOS, kTalkieVersion, IT_ITA, &kLoLCharacterDefsDOSCDItalianProvider },
 	{ kLoLCharacterDefs, kLoL, kPlatformDOS, kTalkieVersion, RU_RUS, &kLoLCharacterDefsDOSCDRussianProvider },
 	{ kLoLCharacterDefs, kLoL, kPlatformDOS, kTalkieVersion, ES_ESP, &kLoLCharacterDefsDOSCDSpanishProvider },
+	{ kLoLIngameSfxFiles, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLIngameSfxFilesDOSCDDemoProvider },
+	{ kLoLIngameSfxIndex, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLIngameSfxIndexDOSCDDemoProvider },
+	{ kLoLMusicTrackMap, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLMusicTrackMapDOSCDDemoProvider },
+	{ kLoLIngameGMSfxIndex, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLIngameGMSfxIndexDOSCDDemoProvider },
+	{ kLoLIngameMT32SfxIndex, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLIngameMT32SfxIndexDOSCDDemoProvider },
+	{ kLoLIngamePcSpkSfxIndex, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLIngamePcSpkSfxIndexDOSCDDemoProvider },
+	{ kLoLSpellProperties, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLSpellPropertiesDOSCDDemoProvider },
+	{ kLoLGameShapeMap, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLGameShapeMapDOSCDDemoProvider },
+	{ kLoLSceneItemOffs, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLSceneItemOffsDOSCDDemoProvider },
+	{ kLoLCharInvIndex, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLCharInvIndexDOSCDDemoProvider },
+	{ kLoLCharInvDefs, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLCharInvDefsDOSCDDemoProvider },
+	{ kLoLCharDefsMan, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLCharDefsManDOSCDDemoProvider },
+	{ kLoLCharDefsAkshel, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLCharDefsAkshelDOSCDDemoProvider },
+	{ kLoLExpRequirements, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLExpRequirementsDOSCDDemoProvider },
+	{ kLoLMonsterModifiers1, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLMonsterModifiers1DOSCDDemoProvider },
+	{ kLoLMonsterModifiers2, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLMonsterModifiers2DOSCDDemoProvider },
+	{ kLoLMonsterModifiers3, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLMonsterModifiers3DOSCDDemoProvider },
+	{ kLoLMonsterModifiers4, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLMonsterModifiers4DOSCDDemoProvider },
+	{ kLoLMonsterShiftOffsets, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLMonsterShiftOffsetsDOSCDDemoProvider },
+	{ kLoLMonsterDirFlags, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLMonsterDirFlagsDOSCDDemoProvider },
+	{ kLoLMonsterScaleY, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLMonsterScaleYDOSCDDemoProvider },
+	{ kLoLMonsterScaleX, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLMonsterScaleXDOSCDDemoProvider },
+	{ kLoLMonsterScaleWH, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLMonsterScaleWHDOSCDDemoProvider },
+	{ kLoLFlyingObjectShp, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLFlyingObjectShpDOSCDDemoProvider },
+	{ kLoLInventoryDesc, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLInventoryDescDOSCDDemoProvider },
+	{ kLoLLevelShpList, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLLevelShpListDOSCDDemoProvider },
+	{ kLoLLevelDatList, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLLevelDatListDOSCDDemoProvider },
+	{ kLoLCompassDefs, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLCompassDefsDOSCDDemoProvider },
+	{ kLoLItemPrices, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLItemPricesDOSCDDemoProvider },
+	{ kLoLStashSetup, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLStashSetupDOSCDDemoProvider },
+	{ kLoLDscWalls, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLDscWallsDOSCDDemoProvider },
+	{ kRpgCommonDscShapeIndex, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLDscShapeIndexDOSCDDemoProvider },
+	{ kLoLDscOvlMap, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLDscOvlMapDOSCDDemoProvider },
+	{ kLoLDscScaleWidthData, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLDscScaleWidthDataDOSCDDemoProvider },
+	{ kLoLDscScaleHeightData, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLDscScaleHeightDataDOSCDDemoProvider },
+	{ kRpgCommonDscX, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLDscXDOSCDDemoProvider },
+	{ kLoLBaseDscY, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLBaseDscYDOSCDDemoProvider },
+	{ kRpgCommonDscTileIndex, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLDscTileIndexDOSCDDemoProvider },
+	{ kRpgCommonDscDoorShapeIndex, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLDscDoorShapeIndexDOSCDDemoProvider },
+	{ kRpgCommonDscDimData1, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLDscDimData1DOSCDDemoProvider },
+	{ kRpgCommonDscDimData2, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLDscDimData2DOSCDDemoProvider },
+	{ kRpgCommonDscBlockMap, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLDscBlockMapDOSCDDemoProvider },
+	{ kRpgCommonDscDimMap, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLDscDimMapDOSCDDemoProvider },
+	{ kLoLDscOvlIndex, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLDscOvlIndexDOSCDDemoProvider },
+	{ kRpgCommonDscBlockIndex, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLDscBlockIndexDOSCDDemoProvider },
+	{ kRpgCommonDscDoorY2, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLDscDoorY2DOSCDDemoProvider },
+	{ kRpgCommonDscDoorFrameY1, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLDscDoorFrameY1DOSCDDemoProvider },
+	{ kRpgCommonDscDoorFrameY2, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLDscDoorFrameY2DOSCDDemoProvider },
+	{ kRpgCommonDscDoorScaleOffs, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLDscDoorScaleOffsDOSCDDemoProvider },
+	{ kLoLDscDoorScale, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLDscDoorScaleDOSCDDemoProvider },
+	{ kLoLDscDoor4, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLDscDoor4DOSCDDemoProvider },
+	{ kLoLDscDoorX, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLDscDoorXDOSCDDemoProvider },
+	{ kLoLDscDoorY, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLDscDoorYDOSCDDemoProvider },
+	{ kLoLScrollXTop, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLScrollXTopDOSCDDemoProvider },
+	{ kLoLScrollYTop, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLScrollYTopDOSCDDemoProvider },
+	{ kLoLScrollXBottom, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLScrollXBottomDOSCDDemoProvider },
+	{ kLoLScrollYBottom, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLScrollYBottomDOSCDDemoProvider },
+	{ kLoLButtonDefs, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLButtonDefsDOSCDDemoProvider },
+	{ kLoLButtonList1, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLButtonList1DOSCDDemoProvider },
+	{ kLoLButtonList2, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLButtonList2DOSCDDemoProvider },
+	{ kLoLButtonList3, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLButtonList3DOSCDDemoProvider },
+	{ kLoLButtonList4, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLButtonList4DOSCDDemoProvider },
+	{ kLoLButtonList5, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLButtonList5DOSCDDemoProvider },
+	{ kLoLButtonList6, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLButtonList6DOSCDDemoProvider },
+	{ kLoLButtonList7, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLButtonList7DOSCDDemoProvider },
+	{ kLoLButtonList8, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLButtonList8DOSCDDemoProvider },
+	{ kLoLLegendData, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLLegendDataDOSCDDemoProvider },
+	{ kLoLMapCursorOvl, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLMapCursorOvlDOSCDDemoProvider },
+	{ kLoLMapStringId, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLMapStringIdDOSCDDemoProvider },
+	{ kLoLSpellbookAnim, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLSpellbookAnimDOSCDDemoProvider },
+	{ kLoLSpellbookCoords, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLSpellbookCoordsDOSCDDemoProvider },
+	{ kLoLHealShapeFrames, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLHealShapeFramesDOSCDDemoProvider },
+	{ kLoLLightningDefs, kLoL, kPlatformDOS, kTalkieDemoVersion, UNK_LANG, &kLoLLightningDefsDOSCDDemoProvider },
+	{ kLoLCharacterDefs, kLoL, kPlatformDOS, kTalkieDemoVersion, EN_ANY, &kLoLCharacterDefsDOSCDDemoProvider },
+	{ kLoLCharacterDefs, kLoL, kPlatformDOS, kTalkieDemoVersion, FR_FRA, &kLoLCharacterDefsDOSCDDemoProvider },
+	{ kLoLCharacterDefs, kLoL, kPlatformDOS, kTalkieDemoVersion, DE_DEU, &kLoLCharacterDefsDOSCDDemoProvider },
 	{ kMaxResIDs, kKyra1, kPlatformDOS, kNoSpecial, UNK_LANG, NULL }
 };
 
diff --git a/devtools/create_kyradat/resources/lol_dos_cddemo.h b/devtools/create_kyradat/resources/lol_dos_cddemo.h
new file mode 100644
index 0000000000..36ec81e7e9
--- /dev/null
+++ b/devtools/create_kyradat/resources/lol_dos_cddemo.h
@@ -0,0 +1,1495 @@
+static const LoLCharacter kLoLCharacterDefsDOSCDDemo[9] = {
+	{ 0x0001, "Michael", 0, -1, 0, 0, 17,
+	  { 0, 0, 0, 0, 0, 0, 0, 0 },
+	  { 256, 256, 256, 256, 256, 256, 256, 256 },
+	  0, 20, 20, 6, 6, 0, 0, 0, 384, 320, 5, 2, 0,
+	  { 44, 0, 0, 0, 0, 138, 0, 0, 162, 0, 0 },
+	  { 1, 1, 1 }, { 0, 0, 0 }, { 1, 1, 1 },
+	  { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
+	{ 0x0001, "Timothy", 0, 2, 0, 0, 22,
+	  { 0, 0, 0, 0, 0, 0, 0, 0 },
+	  { 256, 256, 256, 256, 256, 256, 256, 256 },
+	  0, 27, 27, 5, 5, 0, 0, 0, 256, 256, 0, 0, 0,
+	  { 93, 131, 0, 0, 0, 153, 0, 0, 162, 0, 0 },
+	  { 3, 2, 1 }, { 0, 0, 0 }, { 2500, 1000, 250 },
+	  { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
+	{ 0x0001, "Baccata", 3, 3, 0, 0, 23,
+	  { 0, 0, 0, 0, 0, 0, 0, 0 },
+	  { 256, 256, 256, 256, 256, 256, 256, 256 },
+	  0, 22, 22, 18, 18, 0, 0, 0, 256, 256, 0, 0, 0,
+	  { 108, 149, 0, 0, 145, 153, 0, 0, 129, 0, 0 },
+	  { 1, 1, 3 }, { 0, 0, 0 }, { 1, 1, 4000 },
+	  { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
+	{ 0x0001, "Lora", 1, 4, 0, 0, 24,
+	  { 0, 0, 0, 0, 0, 0, 0, 0 },
+	  { 256, 256, 256, 256, 256, 256, 256, 256 },
+	  0, 25, 48, 5, 5, 0, 0, 0, 256, 256, 0, 0, 0,
+	  { 0, 0, 0, 0, 0, 137, 0, 0, 162, 0, 0 },
+	  { 1, 4, 1 }, { 0, 0, 0 }, { 1, 15001, 1 },
+	  { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
+	{ 0x0001, "Conrad", 0, -5, 0, 0, 26,
+	  { 0, 0, 0, 0, 0, 0, 0, 0 },
+	  { 256, 256, 256, 256, 256, 256, 256, 256 },
+	  0, 23, 23, 10, 10, 0, 0, 0, 366, 358, 2, 3, 0,
+	  { 44, 0, 0, 0, 0, 138, 0, 0, 162, 0, 0 },
+	  { 1, 1, 1 }, { 0, 0, 0 }, { 1, 1, 1 },
+	  { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
+	{ 0x0001, "Paulson", 0, 6, 0, 0, 25,
+	  { 0, 0, 0, 0, 0, 0, 0, 0 },
+	  { 256, 256, 256, 256, 256, 256, 256, 256 },
+	  0, 105, 105, 45, 45, 0, 0, 0, 256, 256, 0, 0, 0,
+	  { 0, 0, 0, 0, 0, 138, 0, 0, 129, 0, 0 },
+	  { 5, 2, 3 }, { 0, 0, 0 }, { 40000, 501, 3500 },
+	  { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
+	{ 0x0001, "Dawn", 1, 7, 0, 0, 24,
+	  { 0, 0, 0, 0, 0, 0, 0, 0 },
+	  { 256, 256, 256, 256, 256, 256, 256, 256 },
+	  0, 50, 50, 80, 80, 0, 0, 0, 256, 256, 0, 0, 0,
+	  { 0, 0, 0, 0, 0, 138, 0, 0, 129, 0, 0 },
+	  { 1, 2, 10 }, { 1, 254, 177 }, { 1, 501, 1 },
+	  { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
+	{ 0x0001, "Kieran", 2, -8, 0, 0, 21,
+	  { 0, 0, 0, 0, 0, 0, 0, 0 },
+	  { 256, 256, 256, 256, 256, 256, 256, 256 },
+	  0, 23, 23, 8, 8, 0, 0, 0, 422, 332, 5, 1, 0,
+	  { 44, 0, 0, 0, 0, 138, 0, 0, 162, 0, 0 },
+	  { 1, 1, 1 }, { 0, 0, 0 }, { 1, 1, 1 },
+	  { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } },
+	{ 0x0001, "Ak'shel", 4, -9, 0, 0, 20,
+	  { 0, 0, 0, 0, 0, 0, 0, 0 },
+	  { 256, 256, 256, 256, 256, 256, 256, 256 },
+	  0, 128, 128, 132, 132, 0, 0, 0, 320, 256, 1, 1, 0,
+	  { 44, 0, 0, 0, 0, 138, 0, 0, 162, 0, 0 },
+	  { 4, 4, 4 }, { 0, 0, 0 }, { 24500, 24500, 24500 },
+	  { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } }
+};
+
+static const LoLCharacterProvider kLoLCharacterDefsDOSCDDemoProvider = { ARRAYSIZE(kLoLCharacterDefsDOSCDDemo), kLoLCharacterDefsDOSCDDemo };
+
+static const char *const kLoLIngameSfxFilesDOSCDDemo[230] = {
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"XXXXXXXX",
+	"DOORMTOP",
+	"DOORMTCL",
+	"PMETLHI",
+	"SWING6",
+	"MDAMAGE2",
+	"LEVERDN",
+	"LEVERUP",
+	"MTLDRSLM",
+	"DOORWDOP",
+	"DOORWDCL",
+	"KEYOPEN",
+	"KEYLOCK",
+	"PORTCUL",
+	"PORTCULD",
+	"LOKPICK",
+	"OCEAN2",
+	"NUNCHUK",
+	"SWING",
+	"SHWING1",
+	"SWING6",
+	"THROW",
+	"CROSSBOW",
+	"HEAL1",
+	"FIRESPL1",
+	"PRESSIN",
+	"PRESSOUT",
+	"PLATEON",
+	"PLATEOFF",
+	"DORWDSLM",
+	"LITENIN1",
+	"ICESPEL2",
+	"SPELL4B",
+	"SHIELD1",
+	"3BOLTC",
+	"2BOLTC",
+	"1BOLTC",
+	"DAWNSPL1",
+	"HEALKING",
+	"SPELL7",
+	"SWING1",
+	"EXPLODE",
+	"CROWCAW",
+	"MORPH2",
+	"CHEST",
+	"MONEY",
+	"SPELBK2",
+	"AUTOMAP",
+	"MINECRT3",
+	"CREAK1",
+	"TURNPAG2",
+	"POLGULP1",
+	"GOOEY2",
+	"BUCKBELL",
+	"KEEPXIT2",
+	"VSCREAM4",
+	"EMPTY",
+	"GOOEY1",
+	"GOOEY2",
+	"RIPPOD4",
+	"PODSKEL1",
+	"INVISO",
+	"OPENBOX2",
+	"ACCEPT2",
+	"BOW2",
+	"HACHUCKM",
+	"FOUNDRY2",
+	"FOUNDRY2",
+	"FOUNDRY4",
+	"FOUNDRY6",
+	"CLEANGL1",
+	"CLEANGL2",
+	"GLOWY1",
+	"DORSTNOP",
+	"DORSTNCL",
+	"EMPTY",
+	"EMPTY",
+	"EMPTY",
+	"EMPTY",
+	"ADAMAGE1",
+	"HDAMAGE1",
+	"TDAMAGE1",
+	"BDAMAGE1",
+	"LDAMAGE1",
+	"TDAMAGE2",
+	"CDAMAGE1",
+	"EMPTY",
+	"EMPTY",
+	"EMPTY",
+	"GOOD1",
+	"GOOD2",
+	"EMPTY",
+	"EMPTY",
+	"EMPTY",
+	"LITENIN1",
+	"COMPASS2",
+	"KINGDOR1",
+	"GLASBRK2",
+	"FLUTTER3",
+	"NUNCHUK",
+	"WALLFALL",
+	"WALLHIT",
+	"MWHOA1",
+	"LADDER",
+	"WHITTL3",
+	"ROWBOAT1",
+	"HORSEY2",
+	"SNORT",
+	"PUMPDOR1",
+	"PUMPSM2",
+	"PUMPSM3",
+	"SPARK1",
+	"BEZEL",
+	"SWARM",
+	"CHEST1",
+	"WRIT1",
+	"CAUSFOG",
+	"VAELAN2",
+	"ROARSPL1",
+	"RATTLER",
+	"WINK1",
+	"HANDFATE",
+	"QUAKE1",
+	"WIZLAMP1",
+	"SAP2",
+	"MSTDOOM1",
+	"GARDIAN1",
+	"VORTEX1",
+	"LION1",
+	"STEAM",
+	"SQUAWCK",
+	"SLIDEMUG",
+	"SPARKHIT",
+	"SPARKHIT2",
+	"SPARKHIT3",
+	"ICEFORM",
+	"ICEXPLOD",
+	"EXPLODE2",
+	"EXPLODE3",
+	"BOLTQUK2",
+	"BOLT2",
+	"BOLT3",
+	"SNKBITE",
+	"HANDGLOW",
+	"MSTDOOM2",
+	"MSTDOOM3",
+	"GARDIAN2",
+	"PLUSPOWR",
+	"MINSPOWR",
+	"BLUDCURL",
+	"LORAGASP",
+	"POURH2O",
+	"AWHOA2",
+	"HWHOA1",
+	"CWHOA1",
+	"AFALL2",
+	"EMPTY",
+	"CFALL2",
+	"MFALL2",
+	"EMPTY",
+	"EMPTY",
+	"EMPTY",
+	"EMPTY",
+	"EMPTY",
+	"EMPTY",
+	"EMPTY",
+	"EMPTY",
+	"WRIT2",
+	"WRIT3",
+	"WRIT4",
+	"WRIT5",
+	"WRIT6",
+	"RUCKUS1",
+	"RUCKUS3",
+	"CHANT1",
+	"EMPTY",
+	"EMPTY",
+	"EMPTY",
+	"CHANT2",
+	"CHANT3",
+	""
+};
+
+static const StringListProvider kLoLIngameSfxFilesDOSCDDemoProvider = { ARRAYSIZE(kLoLIngameSfxFilesDOSCDDemo), kLoLIngameSfxFilesDOSCDDemo };
+
+static const uint16 kLoLIngameSfxIndexDOSCDDemo[500] = {
+	0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000,
+	0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000,
+	0xffff, 0x0000, 0xffff, 0x0000, 0x0034, 0x006f, 0x007c, 0x0000, 0x007d, 0x0000,
+	0x007e, 0x0000, 0x007f, 0x0000, 0x0036, 0x0073, 0x0035, 0xff9c, 0xffff, 0x0000,
+	0x0080, 0x0073, 0x0081, 0x0073, 0x0082, 0x0073, 0x0083, 0x0073, 0x0084, 0x0073,
+	0x0085, 0x0073, 0x0086, 0x0073, 0x00d7, 0x0076, 0x0087, 0x0065, 0x0038, 0x005f,
+	0x0037, 0x005f, 0x0032, 0x000a, 0x0033, 0x0064, 0x0039, 0x0065, 0x003a, 0x000a,
+	0x003b, 0x0014, 0x004e, 0x0065, 0x007a, 0x0064, 0x007b, 0x0064, 0x0088, 0x0065,
+	0x003c, 0x0065, 0x003d, 0x0064, 0x0089, 0x0000, 0x008e, 0x0014, 0x003e, 0x0000,
+	0x003f, 0x0000, 0x0040, 0x0065, 0x0041, 0x0000, 0x00c9, 0x0072, 0x00ca, 0x0072,
+	0x00cb, 0x0072, 0x00cc, 0x0074, 0x00cd, 0x0074, 0x00ce, 0x0074, 0x00cf, 0x0074,
+	0x00d0, 0x0073, 0x00d1, 0x0073, 0x00d2, 0x0073, 0x00d3, 0x0073, 0x00d4, 0x0072,
+	0x00d5, 0x0072, 0x00d6, 0x0072, 0x0042, 0x006f, 0x0043, 0x006f, 0x0044, 0x006f,
+	0x0045, 0x006f, 0x0046, 0x006f, 0x0047, 0x006f, 0x0048, 0x0077, 0x0049, 0xff89,
+	0x004f, 0xff89, 0x0050, 0xff89, 0x00a0, 0xff8a, 0x00a1, 0xff89, 0x00a2, 0xff89,
+	0xffff, 0x0000, 0x00a3, 0xff89, 0x00a4, 0xff89, 0x004a, 0x0013, 0x004b, 0x0013,
+	0x004c, 0x0032, 0x004d, 0x0032, 0x005f, 0x000a, 0x0051, 0x0000, 0x0052, 0x0000,
+	0x008f, 0x0000, 0x0053, 0x0000, 0x0054, 0x0000, 0x0055, 0x0000, 0x0056, 0x0000,
+	0x0057, 0x0000, 0x0058, 0x0077, 0x0060, 0x0000, 0x005d, 0x006a, 0x008a, 0x006f,
+	0x008b, 0x006f, 0x008c, 0x0000, 0x008d, 0x0000, 0x005a, 0x0077, 0x005c, 0x0000,
+	0x005b, 0x0000, 0x005e, 0x006f, 0x0061, 0x0076, 0xffff, 0x0000, 0x0062, 0x0076,
+	0x0063, 0x003c, 0x0064, 0x006d, 0x0065, 0x0000, 0x0066, 0x0000, 0x0067, 0x0000,
+	0x0068, 0x0000, 0x0069, 0x0000, 0x006a, 0x0000, 0x006b, 0x0000, 0x006c, 0x0000,
+	0x006d, 0x0000, 0x006e, 0x0000, 0x006f, 0x0000, 0x0070, 0xff88, 0xffff, 0x0000,
+	0x0071, 0x0000, 0x0072, 0x0000, 0x0073, 0x0074, 0x0074, 0x0000, 0x0075, 0x0000,
+	0x0076, 0x0000, 0x0077, 0x0000, 0x0078, 0x0000, 0x0079, 0x0077, 0x0090, 0x0000,
+	0x0091, 0x0000, 0x0092, 0x0077, 0x0093, 0x001e, 0x0094, 0xff89, 0x0095, 0x0077,
+	0x0096, 0x0076, 0x0097, 0x0072, 0x0098, 0x0000, 0x0099, 0x0050, 0x009a, 0x0078,
+	0x009b, 0x0064, 0x009c, 0x005a, 0x009d, 0x0064, 0x009e, 0x0065, 0x009f, 0x0066,
+	0x00a5, 0xff89, 0x00a6, 0xff89, 0x00a7, 0x0077, 0x00a8, 0x0076, 0xffff, 0x0000,
+	0x00a9, 0x0077, 0x00aa, 0x0077, 0x00ab, 0x0077, 0x00ac, 0x0077, 0x00ad, 0x0077,
+	0x00ae, 0x0077, 0x00af, 0x0076, 0x00b0, 0x0077, 0x00b1, 0x0064, 0x00b2, 0x006f,
+	0x00b3, 0x006e, 0x00b4, 0x006e, 0x00b5, 0x0077, 0x00b6, 0x0077, 0x00b7, 0x0077,
+	0x00b8, 0x0076, 0x00b9, 0x0077, 0x00ba, 0x0077, 0x00bb, 0x0077, 0x00bc, 0x0077,
+	0x00bd, 0x0077, 0x00be, 0x0077, 0x00bf, 0x0077, 0x00c0, 0x0076, 0x00c1, 0x0077,
+	0x00c2, 0x0077, 0x00c3, 0x0077, 0x00c4, 0x006e, 0x00c5, 0x006e, 0x00c6, 0x007d,
+	0x00c7, 0x0078, 0x00c8, 0x0078, 0x00d8, 0x0077, 0x00d9, 0x0077, 0x00da, 0x0077,
+	0x00db, 0x0077, 0x00dc, 0x0077, 0x00dd, 0x0078, 0x00de, 0x0078, 0xffff, 0x0000,
+	0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x00e3, 0x0077,
+	0x00e4, 0x0077, 0x00e0, 0x001e, 0x00df, 0x0077, 0x00e1, 0x0005, 0x00e2, 0x000a,
+	0x0000, 0x0050, 0x0001, 0x0050, 0x0002, 0x0050, 0x0003, 0x0050, 0x0004, 0x0050,
+	0x0005, 0x0050, 0x0006, 0x0050, 0x0007, 0x0050, 0x0008, 0x0050, 0x0009, 0x0050,
+	0x000a, 0x0050, 0x000b, 0x0050, 0x000c, 0x0050, 0x000d, 0x0050, 0x000e, 0x0050,
+	0x000f, 0x0050, 0x0010, 0x0050, 0x0011, 0x005a, 0x0012, 0x005a, 0x0013, 0x005a,
+	0x0014, 0x005a, 0x0015, 0x005a, 0x0016, 0x005a, 0x0017, 0x005a, 0x0018, 0x005a,
+	0x0019, 0x005a, 0x001a, 0x005a, 0x001b, 0x005a, 0x001c, 0x005a, 0x001d, 0x005a,
+	0x001e, 0x005a, 0x001f, 0x005a, 0x0020, 0x005a, 0x0021, 0x0073, 0x0022, 0x0073,
+	0x0023, 0x0073, 0x0024, 0x0073, 0x0025, 0x0073, 0x0026, 0x0073, 0x0027, 0x0073,
+	0x0028, 0x0073, 0x0029, 0x0073, 0x002a, 0x0073, 0x002b, 0x0050, 0x002c, 0x005a,
+	0x002d, 0x005a, 0x002e, 0x005a, 0x002f, 0x005a, 0x0030, 0x005a, 0x0031, 0x005a
+};
+
+static const Uint16Provider kLoLIngameSfxIndexDOSCDDemoProvider = { ARRAYSIZE(kLoLIngameSfxIndexDOSCDDemo), kLoLIngameSfxIndexDOSCDDemo };
+
+static const byte kLoLMusicTrackMapDOSCDDemo[240] = {
+	0x01, 0x61, 0x02, 0x01, 0x61, 0x03, 0x01, 0x61,
+	0x04, 0x01, 0x61, 0x05, 0x03, 0x61, 0x03, 0x01,
+	0x61, 0x07, 0x01, 0x61, 0x08, 0x01, 0x62, 0x02,
+	0x01, 0x64, 0x03, 0x01, 0x62, 0x04, 0x01, 0x62,
+	0x05, 0x01, 0x62, 0x06, 0x01, 0x62, 0x07, 0x01,
+	0x62, 0x08, 0x01, 0x62, 0x09, 0x01, 0x63, 0x02,
+	0x01, 0x63, 0x03, 0x01, 0x63, 0x04, 0x01, 0x63,
+	0x05, 0x01, 0x63, 0x06, 0x01, 0x63, 0x07, 0x01,
+	0x64, 0x02, 0x02, 0x61, 0x02, 0x02, 0x61, 0x03,
+	0x02, 0x61, 0x04, 0x02, 0x61, 0x05, 0x02, 0x61,
+	0x06, 0x02, 0x61, 0x07, 0x02, 0x61, 0x08, 0x02,
+	0x61, 0x09, 0x03, 0x61, 0x02, 0x03, 0x61, 0x03,
+	0x03, 0x61, 0x04, 0x03, 0x61, 0x05, 0x03, 0x61,
+	0x06, 0x03, 0x61, 0x07, 0x04, 0x61, 0x02, 0x04,
+	0x61, 0x03, 0x04, 0x61, 0x04, 0x05, 0x61, 0x02,
+	0x05, 0x61, 0x03, 0x05, 0x61, 0x04, 0x05, 0x61,
+	0x05, 0x05, 0x61, 0x06, 0x06, 0x61, 0x03, 0x06,
+	0x61, 0x05, 0x06, 0x61, 0x06, 0x06, 0x62, 0x02,
+	0x06, 0x61, 0x02, 0x06, 0x61, 0x04, 0x08, 0x61,
+	0x02, 0x08, 0x61, 0x03, 0x08, 0x61, 0x04, 0x08,
+	0x61, 0x05, 0x08, 0x61, 0x06, 0x08, 0x61, 0x07,
+	0x08, 0x62, 0x02, 0x08, 0x62, 0x03, 0x01, 0x61,
+	0x09, 0x03, 0x62, 0x02, 0x03, 0x62, 0x03, 0x03,
+	0x62, 0x04, 0x03, 0x62, 0x05, 0x03, 0x62, 0x06,
+	0x03, 0x62, 0x07, 0x03, 0x62, 0x08, 0x04, 0x61,
+	0x05, 0x04, 0x61, 0x06, 0x04, 0x61, 0x07, 0x04,
+	0x61, 0x08, 0x05, 0x62, 0x02, 0x05, 0x62, 0x03,
+	0x05, 0x62, 0x04, 0x07, 0x61, 0x02, 0x07, 0x61,
+	0x03, 0x01, 0x64, 0x0A, 0x03, 0x62, 0x09, 0x01,
+	0x64, 0x04, 0x05, 0x62, 0x05, 0x05, 0x62, 0x06
+};
+
+static const ByteProvider kLoLMusicTrackMapDOSCDDemoProvider = { ARRAYSIZE(kLoLMusicTrackMapDOSCDDemo), kLoLMusicTrackMapDOSCDDemo };
+
+static const byte kLoLIngameGMSfxIndexDOSCDDemo[250] = {
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xFF, 0xFF, 0x1A, 0x0B, 0xFF, 0xFF, 0xFF,
+	0xFF, 0x25, 0x0B, 0x07, 0x25, 0x25, 0x25, 0x25,
+	0x25, 0x25, 0x25, 0x1A, 0x11, 0x0E, 0x0E, 0x05,
+	0x05, 0x11, 0x05, 0x05, 0x11, 0x05, 0x05, 0x11,
+	0x2A, 0x2B, 0x06, 0xFF, 0x05, 0x05, 0x2B, 0x00,
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x25,
+	0x25, 0x25, 0x25, 0xFF, 0xFF, 0xFF, 0x0C, 0x0C,
+	0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x29, 0x29, 0x27,
+	0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x01, 0x0E,
+	0x09, 0x09, 0x0A, 0x12, 0xE7, 0x29, 0xFF, 0xFF,
+	0xFF, 0xFF, 0x18, 0x27, 0x13, 0x10, 0x1A, 0x1A,
+	0xFF, 0xFF, 0x12, 0x26, 0xFF, 0x02, 0x05, 0x05,
+	0x0F, 0xFF, 0xFF, 0xFF, 0x02, 0x05, 0x21, 0x1A,
+	0xFF, 0xFF, 0xFF, 0xFF, 0x28, 0x0A, 0x19, 0xFF,
+	0x0B, 0x06, 0x02, 0x02, 0x03, 0x02, 0xFF, 0xFF,
+	0x0A, 0x0A, 0x0F, 0xFF, 0xFF, 0x0C, 0x1B, 0x22,
+	0xFF, 0x1A, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, 0x02,
+	0x03, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
+	0x29, 0x0A, 0x0A, 0x27, 0x0A, 0x28, 0x0A, 0x0A,
+	0x06, 0xFF, 0x29, 0x29, 0x29, 0x28, 0x12, 0x12,
+	0x12, 0x29, 0x29, 0x29, 0x25, 0x29, 0x27, 0x27,
+	0x0C, 0x1A, 0xFF, 0xFF, 0xFF, 0xFF, 0x19, 0x19,
+	0x19, 0x19, 0x19, 0x22, 0x1B, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0x16, 0xFF, 0x16, 0x16, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xFF, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+	0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+	0x0C, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
+	0x22, 0x22, 0x22, 0x16, 0x0C, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xFF
+};
+
+static const ByteProvider kLoLIngameGMSfxIndexDOSCDDemoProvider = { ARRAYSIZE(kLoLIngameGMSfxIndexDOSCDDemo), kLoLIngameGMSfxIndexDOSCDDemo };
+
+static const byte kLoLIngameMT32SfxIndexDOSCDDemo[250] = {
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xFF, 0xFF, 0x30, 0x2E, 0xFF, 0xFF, 0xFF,
+	0xFF, 0x2C, 0x31, 0x02, 0x2C, 0x2C, 0x2C, 0x2C,
+	0x2C, 0x2C, 0x2C, 0x1A, 0x0C, 0x03, 0x04, 0x0B,
+	0x0A, 0x0C, 0x0B, 0x0A, 0x0C, 0x0B, 0x0A, 0x0C,
+	0x24, 0x25, 0x0D, 0x02, 0x0B, 0x0A, 0x25, 0xFF,
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2C,
+	0x2C, 0x2C, 0x2C, 0xFF, 0xFF, 0xFF, 0x2E, 0x2E,
+	0x2E, 0x2E, 0x31, 0x31, 0x1B, 0x10, 0x23, 0x21,
+	0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x03, 0x04,
+	0x2B, 0x2A, 0x32, 0x21, 0x18, 0x23, 0x1B, 0x1B,
+	0x1B, 0xFF, 0x17, 0x33, 0x32, 0x08, 0x1A, 0x19,
+	0x02, 0x02, 0x0E, 0x32, 0x09, 0x17, 0x0B, 0x0B,
+	0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0x0B, 0x01, 0x1A,
+	0xFF, 0xFF, 0xFF, 0xFF, 0x33, 0x08, 0x34, 0xFF,
+	0x31, 0x0D, 0x05, 0x06, 0x05, 0x06, 0xFF, 0xFF,
+	0x0F, 0x34, 0x07, 0xFF, 0xFF, 0x31, 0x1A, 0x26,
+	0xFF, 0x30, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x05,
+	0x06, 0x33, 0x34, 0x34, 0x34, 0x34, 0x34, 0x33,
+	0x32, 0x34, 0x34, 0x32, 0x34, 0x33, 0x34, 0xFF,
+	0x27, 0xFF, 0x23, 0x23, 0x23, 0x21, 0x0E, 0x0E,
+	0x0E, 0x23, 0x23, 0x23, 0x2C, 0x32, 0x33, 0x33,
+	0x2F, 0x19, 0xFF, 0xFF, 0xFF, 0x18, 0x17, 0x18,
+	0x18, 0x17, 0x18, 0x26, 0x06, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0x15, 0xFF, 0x15, 0x15, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xFF, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
+	0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
+	0x31, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
+	0x26, 0x26, 0x26, 0x15, 0x31, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xFF
+};
+
+static const ByteProvider kLoLIngameMT32SfxIndexDOSCDDemoProvider = { ARRAYSIZE(kLoLIngameMT32SfxIndexDOSCDDemo), kLoLIngameMT32SfxIndexDOSCDDemo };
+
+static const byte kLoLIngamePcSpkSfxIndexDOSCDDemo[250] = {
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xFF, 0xFF, 0x04, 0x0C, 0xFF, 0xFF, 0xFF,
+	0xFF, 0x17, 0x0C, 0x10, 0x17, 0x17, 0x17, 0x17,
+	0x17, 0x17, 0x17, 0x04, 0x14, 0x02, 0x02, 0x05,
+	0x05, 0x14, 0x05, 0x05, 0x05, 0x14, 0x05, 0x05,
+	0x14, 0x00, 0x00, 0x10, 0x05, 0x05, 0x01, 0xFF,
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x17,
+	0x17, 0x17, 0x17, 0xFF, 0xFF, 0xFF, 0x0C, 0x0C,
+	0x0C, 0x0C, 0x0C, 0x0C, 0x12, 0x0E, 0x0F, 0x11,
+	0x0F, 0x11, 0x12, 0x11, 0x12, 0x12, 0x01, 0x01,
+	0x02, 0x0A, 0x15, 0x12, 0x0A, 0x0F, 0x15, 0x15,
+	0x15, 0xFF, 0x0A, 0xFF, 0x16, 0x05, 0x0A, 0x0A,
+	0x10, 0x10, 0x07, 0x15, 0xFF, 0x0A, 0xFF, 0xFF,
+	0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x10, 0x0A,
+	0x13, 0x13, 0xFF, 0xFF, 0xFF, 0x01, 0x0A, 0xFF,
+	0x0C, 0x00, 0x02, 0x02, 0x02, 0x02, 0xFF, 0xFF,
+	0xFF, 0x15, 0x05, 0xFF, 0xFF, 0x0C, 0x16, 0x0B,
+	0xFF, 0x0A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xFF, 0x12, 0x11, 0x12, 0x11, 0x12, 0x11, 0x12,
+	0x11, 0x12, 0x11, 0x12, 0x11, 0x12, 0x03, 0xFF,
+	0x02, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x08, 0x08,
+	0x08, 0x16, 0x16, 0x16, 0x17, 0x16, 0x16, 0x16,
+	0x0B, 0x0A, 0xFF, 0xFF, 0xFF, 0x0A, 0x0A, 0x0A,
+	0x0A, 0x0A, 0x0A, 0x06, 0x10, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0x14, 0xFF, 0x14, 0x14, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xFF, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
+	0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
+	0x0B, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D,
+	0x0D, 0x0D, 0x0D, 0x14, 0x0B, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xFF
+};
+
+static const ByteProvider kLoLIngamePcSpkSfxIndexDOSCDDemoProvider = { ARRAYSIZE(kLoLIngamePcSpkSfxIndexDOSCDDemo), kLoLIngamePcSpkSfxIndexDOSCDDemo };
+
+static const SpellProperty kLoLSpellPropertiesDOSCDDemo[17] = {
+	{ 16436, { 5, 10, 15, 25 }, 0, 0, { 0, 0, 0, 0 }, 0, 0, 0x0100 },
+	{ 16437, { 5, 10, 25, 60 }, 0, 0, { 0, 0, 0, 0 }, 0, 0, 0x0001 },
+	{ 16438, { 8, 15, 30, 80 }, 0, 0, { 0, 0, 0, 0 }, 0, 0, 0x0102 },
+	{ 16440, { 20, 35, 65, 100 }, 0, 0, { 0, 0, 0, 0 }, 0, 0, 0x0103 },
+	{ 16441, { 30, 60, 90, 120 }, 0, 0, { 0, 0, 0, 0 }, 0, 0, 0x0104 },
+	{ 16442, { 30, 60, 90, 150 }, 0, 0, { 0, 0, 0, 0 }, 0, 0, 0x0105 },
+	{ 16439, { 25, 30, 50, 100 }, 0, 0, { 0, 0, 0, 0 }, 0, 0, 0x0106 },
+	{ 16443, { 3, 6, 12, 24 }, 0, 0, { 0, 0, 0, 0 }, 0, 0, 0x0107 },
+	{ 16975, { 15, 15, 15, 15 }, 0, 0, { 0, 0, 0, 0 }, 0, 0, 0x0108 },
+	{ 16975, { 15, 15, 15, 15 }, 15, 0, { 0, 0, 0, 0 }, 0, 0, 0x0108 },
+	{ 0, { 0, 0, 0, 0 }, 0, 0, { 0, 0, 0, 0 }, 0, 0, 0 },
+	{ 0, { 0, 0, 0, 0 }, 0, 0, { 0, 0, 0, 0 }, 0, 0, 0 },
+	{ 0, { 0, 0, 0, 0 }, 0, 0, { 0, 0, 0, 0 }, 0, 0, 0 },
+	{ 0, { 0, 0, 0, 0 }, 0, 0, { 0, 0, 0, 0 }, 0, 0, 0 },
+	{ 0, { 0, 0, 0, 0 }, 0, 0, { 0, 0, 0, 0 }, 0, 0, 0 },
+	{ 0, { 0, 0, 0, 0 }, 0, 0, { 0, 0, 0, 0 }, 0, 0, 0 },
+	{ 0, { 0, 0, 0, 0 }, 0, 0, { 0, 0, 0, 0 }, 0, 0, 0 }
+};
+
+static const SpellPropertyProvider kLoLSpellPropertiesDOSCDDemoProvider = { ARRAYSIZE(kLoLSpellPropertiesDOSCDDemo), kLoLSpellPropertiesDOSCDDemo };
+
+static const byte kLoLGameShapeMapDOSCDDemo[276] = {
+	0x15, 0x5A, 0x05, 0x37, 0x09, 0x38, 0x00, 0x36,
+	0x00, 0x36, 0x00, 0x36, 0x00, 0x3C, 0x26, 0x3D,
+	0x05, 0x37, 0x07, 0x39, 0x18, 0x40, 0x0D, 0x3E,
+	0x06, 0x42, 0x06, 0x3F, 0x01, 0x5A, 0x01, 0x5A,
+	0x0A, 0x5A, 0x0A, 0x5A, 0x0A, 0x5A, 0x04, 0x5A,
+	0x04, 0x5A, 0x2D, 0x5A, 0x2D, 0x5A, 0x0B, 0x3B,
+	0x24, 0x5A, 0x03, 0x3A, 0x00, 0x3C, 0x1E, 0x3E,
+	0x1E, 0x3E, 0x1B, 0x5A, 0x14, 0x5A, 0x29, 0x5A,
+	0x02, 0x5A, 0x0C, 0x5A, 0x22, 0x5A, 0x21, 0x41,
+	0x0D, 0x3E, 0x25, 0x5A, 0x1A, 0x41, 0x04, 0x5A,
+	0x30, 0x5A, 0x31, 0x5A, 0x32, 0x5A, 0x32, 0x5A,
+	0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36,
+	0x17, 0x5A, 0x17, 0x5A, 0x0E, 0x5A, 0x0E, 0x5A,
+	0x0E, 0x5A, 0x26, 0x3D, 0x2C, 0x5A, 0x21, 0x41,
+	0x07, 0x39, 0x27, 0x5A, 0x1B, 0x5A, 0x1B, 0x5A,
+	0x1B, 0x5A, 0x1B, 0x5A, 0x1B, 0x5A, 0x1B, 0x5A,
+	0x1B, 0x5A, 0x1B, 0x5A, 0x22, 0x5A, 0x22, 0x5A,
+	0x16, 0x5A, 0x2D, 0x5A, 0x3B, 0x5A, 0x3B, 0x5A,
+	0x3A, 0x5A, 0x17, 0x5A, 0x1B, 0x5A, 0x1B, 0x5A,
+	0x17, 0x5A, 0x0A, 0x5A, 0x0A, 0x5A, 0x0A, 0x5A,
+	0x1F, 0x5A, 0x17, 0x5A, 0x27, 0x5A, 0x1B, 0x5A,
+	0x1E, 0x3E, 0x2A, 0x5A, 0x2F, 0x5A, 0x2F, 0x5A,
+	0x2F, 0x5A, 0x2F, 0x5A, 0x2F, 0x5A, 0x2F, 0x5A,
+	0x2C, 0x5A, 0x2C, 0x5A, 0x2C, 0x5A, 0x2C, 0x5A,
+	0x34, 0x5A, 0x0F, 0x5A, 0x35, 0x43, 0x1B, 0x5A,
+	0x1B, 0x5A, 0x1B, 0x5A, 0x1B, 0x5A, 0x2B, 0x5A,
+	0x1D, 0x5A, 0x1D, 0x5A, 0x28, 0x5A, 0x28, 0x5A,
+	0x28, 0x5A, 0x28, 0x5A, 0x01, 0x5A, 0x14, 0x5A,
+	0x14, 0x5A, 0x14, 0x5A, 0x14, 0x5A, 0x1B, 0x5A,
+	0x27, 0x5A, 0x1B, 0x5A, 0x1B, 0x5A, 0x1B, 0x5A,
+	0x1B, 0x5A, 0x36, 0x5A, 0x37, 0x5A, 0x38, 0x5A,
+	0x39, 0x5A, 0x1B, 0x5A, 0x1B, 0x5A, 0x1B, 0x5A,
+	0x1B, 0x5A, 0x27, 0x5A, 0x2E, 0x5A, 0x2E, 0x5A,
+	0x2E, 0x5A, 0x2E, 0x5A, 0x17, 0x5A, 0x01, 0x5A,
+	0x1C, 0x5A, 0x1C, 0x5A
+};
+
+static const ByteProvider kLoLGameShapeMapDOSCDDemoProvider = { ARRAYSIZE(kLoLGameShapeMapDOSCDDemo), kLoLGameShapeMapDOSCDDemo };
+
+static const byte kLoLSceneItemOffsDOSCDDemo[8] = {
+	0x00, 0xFE, 0x01, 0xFF, 0x02, 0x00, 0x01, 0xFF
+};
+
+static const ByteProvider kLoLSceneItemOffsDOSCDDemoProvider = { ARRAYSIZE(kLoLSceneItemOffsDOSCDDemo), kLoLSceneItemOffsDOSCDDemo };
+
+static const byte kLoLCharInvIndexDOSCDDemo[5] = {
+	0x00, 0x00, 0x03, 0x01, 0x02
+};
+
+static const ByteProvider kLoLCharInvIndexDOSCDDemoProvider = { ARRAYSIZE(kLoLCharInvIndexDOSCDDemo), kLoLCharInvIndexDOSCDDemo };
+
+static const byte kLoLCharInvDefsDOSCDDemo[88] = {
+	0x05, 0x34, 0x50, 0x34, 0xFF, 0xFF, 0xFF, 0xFF,
+	0x05, 0x04, 0x05, 0x1C, 0x50, 0x04, 0x50, 0x1C,
+	0x05, 0x5D, 0x0F, 0x4E, 0x50, 0x4E, 0x05, 0x19,
+	0x50, 0x19, 0x05, 0x49, 0x50, 0x49, 0x05, 0x01,
+	0x05, 0x31, 0x50, 0x01, 0x50, 0x31, 0x05, 0x61,
+	0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x34, 0x50, 0x34,
+	0xFF, 0xFF, 0xFF, 0xFF, 0x05, 0x04, 0x05, 0x1C,
+	0x50, 0x04, 0x50, 0x1C, 0x05, 0x5D, 0x0F, 0x4E,
+	0x50, 0x4E, 0x05, 0x34, 0x50, 0x34, 0xFF, 0xFF,
+	0xFF, 0xFF, 0x05, 0x04, 0x05, 0x1C, 0x50, 0x04,
+	0x50, 0x1C, 0xFF, 0xFF, 0x0F, 0x4E, 0x50, 0x4E
+};
+
+static const ByteProvider kLoLCharInvDefsDOSCDDemoProvider = { ARRAYSIZE(kLoLCharInvDefsDOSCDDemo), kLoLCharInvDefsDOSCDDemo };
+
+static const uint16 kLoLCharDefsManDOSCDDemo[9] = {
+	0x0100, 0x0100, 0x0100, 0x0032, 0x0100, 0x0100, 0x0100, 0x0100,
+	0x0004
+};
+
+static const Uint16Provider kLoLCharDefsManDOSCDDemoProvider = { ARRAYSIZE(kLoLCharDefsManDOSCDDemo), kLoLCharDefsManDOSCDDemo };
+
+static const uint16 kLoLCharDefsAkshelDOSCDDemo[9] = {
+	0x00C0, 0x00C0, 0x0140, 0x0032, 0x0100, 0x0180, 0x0180, 0x0100,
+	0x0004
+};
+
+static const Uint16Provider kLoLCharDefsAkshelDOSCDDemoProvider = { ARRAYSIZE(kLoLCharDefsAkshelDOSCDDemo), kLoLCharDefsAkshelDOSCDDemo };
+
+static const uint32 kLoLExpRequirementsDOSCDDemo[11] = {
+	0x00000000, 0x000001F4, 0x000005DC, 0x00001388, 0x000061A8, 0x0000C350, 0x00013880, 0x0001D4C0,
+	0x0002BF20, 0x00041EB0, 0x7FFFFFFF
+};
+
+static const Uint32Provider kLoLExpRequirementsDOSCDDemoProvider = { ARRAYSIZE(kLoLExpRequirementsDOSCDDemo), kLoLExpRequirementsDOSCDDemo };
+
+static const uint16 kLoLMonsterModifiers1DOSCDDemo[3] = {
+	0x0066, 0x0100, 0x0180
+};
+
+static const Uint16Provider kLoLMonsterModifiers1DOSCDDemoProvider = { ARRAYSIZE(kLoLMonsterModifiers1DOSCDDemo), kLoLMonsterModifiers1DOSCDDemo };
+
+static const uint16 kLoLMonsterModifiers2DOSCDDemo[3] = {
+	0x0100, 0x0100, 0x00C0
+};
+
+static const Uint16Provider kLoLMonsterModifiers2DOSCDDemoProvider = { ARRAYSIZE(kLoLMonsterModifiers2DOSCDDemo), kLoLMonsterModifiers2DOSCDDemo };
+
+static const uint16 kLoLMonsterModifiers3DOSCDDemo[3] = {
+	0x0140, 0x0100, 0x0080
+};
+
+static const Uint16Provider kLoLMonsterModifiers3DOSCDDemoProvider = { ARRAYSIZE(kLoLMonsterModifiers3DOSCDDemo), kLoLMonsterModifiers3DOSCDDemo };
+
+static const uint16 kLoLMonsterModifiers4DOSCDDemo[3] = {
+	0x0080, 0x0100, 0x0100
+};
+
+static const Uint16Provider kLoLMonsterModifiers4DOSCDDemoProvider = { ARRAYSIZE(kLoLMonsterModifiers4DOSCDDemo), kLoLMonsterModifiers4DOSCDDemo };
+
+static const byte kLoLMonsterShiftOffsetsDOSCDDemo[32] = {
+	0x01, 0x01, 0x01, 0x00, 0x01, 0xFF, 0x00, 0xFF,
+	0x00, 0x00, 0x00, 0x01, 0xFF, 0x01, 0xFF, 0x00,
+	0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x01,
+	0x01, 0x01, 0x01, 0x00, 0x01, 0xFF, 0x00, 0x00
+};
+
+static const ByteProvider kLoLMonsterShiftOffsetsDOSCDDemoProvider = { ARRAYSIZE(kLoLMonsterShiftOffsetsDOSCDDemo), kLoLMonsterShiftOffsetsDOSCDDemo };
+
+static const byte kLoLMonsterDirFlagsDOSCDDemo[16] = {
+	0x08, 0x14, 0x00, 0x04, 0x04, 0x08, 0x14, 0x00,
+	0x00, 0x04, 0x08, 0x14, 0x14, 0x00, 0x04, 0x08
+};
+
+static const ByteProvider kLoLMonsterDirFlagsDOSCDDemoProvider = { ARRAYSIZE(kLoLMonsterDirFlagsDOSCDDemo), kLoLMonsterDirFlagsDOSCDDemo };
+
+static const byte kLoLMonsterScaleYDOSCDDemo[30] = {
+	0x7C, 0x78, 0x74, 0x70, 0x6C, 0x68, 0x65, 0x62,
+	0x5F, 0x5C, 0x59, 0x56, 0x53, 0x50, 0x4D, 0x4A,
+	0x48, 0x46, 0x44, 0x43, 0x41, 0x40, 0x3E, 0x3D,
+	0x3C, 0x3B, 0x3A, 0x39, 0x38, 0x38
+};
+
+static const ByteProvider kLoLMonsterScaleYDOSCDDemoProvider = { ARRAYSIZE(kLoLMonsterScaleYDOSCDDemo), kLoLMonsterScaleYDOSCDDemo };
+
+static const byte kLoLMonsterScaleXDOSCDDemo[32] = {
+	0x98, 0x98, 0x90, 0x88, 0x80, 0x76, 0x6E, 0x68,
+	0x62, 0x5C, 0x58, 0x54, 0x50, 0x4A, 0x44, 0x40,
+	0x3C, 0x38, 0x36, 0x32, 0x30, 0x2C, 0x2A, 0x28,
+	0x26, 0x24, 0x22, 0x20, 0x20, 0x1E, 0x18, 0x10
+};
+
+static const ByteProvider kLoLMonsterScaleXDOSCDDemoProvider = { ARRAYSIZE(kLoLMonsterScaleXDOSCDDemo), kLoLMonsterScaleXDOSCDDemo };
+
+static const uint16 kLoLMonsterScaleWHDOSCDDemo[65] = {
+	0x0041, 0x0045, 0x0049, 0x004D, 0x0051, 0x0055, 0x0059, 0x005D,
+	0x0062, 0x0066, 0x006A, 0x006E, 0x0072, 0x0076, 0x007A, 0x007E,
+	0x0082, 0x0086, 0x008A, 0x008E, 0x0092, 0x0096, 0x009A, 0x009E,
+	0x00A3, 0x00A7, 0x00AB, 0x00AF, 0x00B3, 0x00B7, 0x00BB, 0x00BF,
+	0x00C3, 0x00C7, 0x00CB, 0x00CF, 0x00D3, 0x00D7, 0x00DB, 0x00DF,
+	0x00E4, 0x00E8, 0x00EC, 0x00F0, 0x00F4, 0x00F8, 0x00FC, 0x0100,
+	0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
+	0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
+	0x0100
+};
+
+static const Uint16Provider kLoLMonsterScaleWHDOSCDDemoProvider = { ARRAYSIZE(kLoLMonsterScaleWHDOSCDDemo), kLoLMonsterScaleWHDOSCDDemo };
+
+static const FlyingObjectShape kLoLFlyingObjectShpDOSCDDemo[13] = {
+	{ 0, 0, 1, 0x00, 0x40, },
+	{ 2, 2, 3, 0x00, 0x00, },
+	{ 4, 4, 4, 0x00, 0x00, },
+	{ 5, 5, 5, 0x20, 0x00, },
+	{ 6, 6, 6, 0x20, 0x00, },
+	{ 7, 7, 7, 0x20, 0x00, },
+	{ 9, 8, 15, 0x00, 0x00, },
+	{ 11, 10, 12, 0x00, 0x00, },
+	{ 12, 12, 12, 0x20, 0x00, },
+	{ 14, 13, 15, 0x00, 0x00, },
+	{ 16, 16, 16, 0x00, 0x00, },
+	{ 17, 17, 17, 0x20, 0x00, },
+	{ 18, 18, 18, 0x00, 0x00, }
+};
+
+static const FlyingObjectShapeProvider kLoLFlyingObjectShpDOSCDDemoProvider = { ARRAYSIZE(kLoLFlyingObjectShpDOSCDDemo), kLoLFlyingObjectShpDOSCDDemo };
+
+static const uint16 kLoLInventoryDescDOSCDDemo[11] = {
+	0x417A, 0x417B, 0x417A, 0x417B, 0x417C, 0x417D, 0x417E, 0x417F,
+	0x4180, 0x4181, 0x4181
+};
+
+static const Uint16Provider kLoLInventoryDescDOSCDDemoProvider = { ARRAYSIZE(kLoLInventoryDescDOSCDDemo), kLoLInventoryDescDOSCDDemo };
+
+static const char *const kLoLLevelShpListDOSCDDemo[4] = {
+	"KEEP.SHP",
+	"FOREST1.SHP",
+	"MANOR.SHP",
+	"CAVE1.SHP"
+};
+
+static const StringListProvider kLoLLevelShpListDOSCDDemoProvider = { ARRAYSIZE(kLoLLevelShpListDOSCDDemo), kLoLLevelShpListDOSCDDemo };
+
+static const char *const kLoLLevelDatListDOSCDDemo[4] = {
+	"KEEP.DAT",
+	"FOREST1.DAT",
+	"MANOR.DAT",
+	"CAVE1.DAT"
+};
+
+static const StringListProvider kLoLLevelDatListDOSCDDemoProvider = { ARRAYSIZE(kLoLLevelDatListDOSCDDemo), kLoLLevelDatListDOSCDDemo };
+
+static const CompassDef kLoLCompassDefsDOSCDDemo[32] = {
+	{ 0,  3, -3, 0x00 },
+	{ 1,  3, -3, 0x00 },
+	{ 2,  3, -3, 0x00 },
+	{ 3,  5, -3, 0x00 },
+	{ 4,  5, -3, 0x00 },
+	{ 5,  6, -3, 0x00 },
+	{ 6,  6, -3, 0x00 },
+	{ 7,  6, -3, 0x00 },
+	{ 8,  6, -3, 0x00 },
+	{ 7,  6,  4, 0x02 },
+	{ 6,  6,  4, 0x02 },
+	{ 5,  6,  4, 0x02 },
+	{ 4,  5,  4, 0x02 },
+	{ 3,  5,  4, 0x02 },
+	{ 2,  3,  4, 0x02 },
+	{ 1,  3,  4, 0x02 },
+	{ 0,  3,  4, 0x02 },
+	{ 1,  2,  4, 0x03 },
+	{ 2,  2,  4, 0x03 },
+	{ 3,  0,  4, 0x03 },
+	{ 4,  0,  4, 0x03 },
+	{ 5, -1,  4, 0x03 },
+	{ 6, -1,  4, 0x03 },
+	{ 7, -1,  4, 0x03 },
+	{ 8, -1, -3, 0x01 },
+	{ 7, -1, -3, 0x01 },
+	{ 6, -1, -3, 0x01 },
+	{ 5, -1, -3, 0x01 },
+	{ 4,  0, -3, 0x01 },
+	{ 3,  0, -3, 0x01 },
+	{ 2,  2, -3, 0x01 },
+	{ 1,  2, -3, 0x01 }
+};
+
+static const CompassDefProvider kLoLCompassDefsDOSCDDemoProvider = { ARRAYSIZE(kLoLCompassDefsDOSCDDemo), kLoLCompassDefsDOSCDDemo };
+
+static const uint16 kLoLItemPricesDOSCDDemo[46] = {
+	0x0001, 0x0005, 0x0008, 0x000A, 0x000F, 0x0014, 0x0019, 0x001E,
+	0x0023, 0x0028, 0x002D, 0x0032, 0x0037, 0x003C, 0x0041, 0x0046,
+	0x004B, 0x0050, 0x005A, 0x0064, 0x0069, 0x0078, 0x007D, 0x0082,
+	0x008C, 0x0096, 0x00A0, 0x00AF, 0x00C8, 0x00E1, 0x00FA, 0x0113,
+	0x012C, 0x0145, 0x015E, 0x0177, 0x0190, 0x01A9, 0x01C2, 0x01DB,
+	0x01F4, 0x0230, 0x03E8, 0x05DC, 0x0BB8, 0x0000
+};
+
+static const Uint16Provider kLoLItemPricesDOSCDDemoProvider = { ARRAYSIZE(kLoLItemPricesDOSCDDemo), kLoLItemPricesDOSCDDemo };
+
+static const byte kLoLStashSetupDOSCDDemo[12] = {
+	0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x03,
+	0x03, 0x00, 0x01, 0x01
+};
+
+static const ByteProvider kLoLStashSetupDOSCDDemoProvider = { ARRAYSIZE(kLoLStashSetupDOSCDDemo), kLoLStashSetupDOSCDDemo };
+
+static const byte kLoLDscWallsDOSCDDemo[36] = {
+	0xFF, 0xFF, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF,
+	0x02, 0x03, 0x02, 0x03, 0xFF, 0xFF, 0x02, 0x01,
+	0x02, 0x01, 0x02, 0xFF, 0x02, 0x03, 0x02, 0x03,
+	0x02, 0x01, 0x02, 0xFF, 0x02, 0x03, 0xFF, 0x01,
+	0x02, 0xFF, 0xFF, 0x03
+};
+
+static const ByteProvider kLoLDscWallsDOSCDDemoProvider = { ARRAYSIZE(kLoLDscWallsDOSCDDemo), kLoLDscWallsDOSCDDemo };
+
+static const byte kLoLDscShapeIndexDOSCDDemo[36] = {
+	0x03, 0x09, 0x03, 0x08, 0x03, 0x07, 0x03, 0x03,
+	0x03, 0xF9, 0x03, 0xF8, 0x03, 0xF7, 0x02, 0x09,
+	0x02, 0x06, 0x02, 0x02, 0x02, 0xFA, 0x02, 0xF7,
+	0x01, 0x05, 0x01, 0x01, 0x01, 0xFB, 0x00, 0x04,
+	0x00, 0x00, 0x00, 0xFC
+};
+
+static const ByteProvider kLoLDscShapeIndexDOSCDDemoProvider = { ARRAYSIZE(kLoLDscShapeIndexDOSCDDemo), kLoLDscShapeIndexDOSCDDemo };
+
+static const byte kLoLDscOvlMapDOSCDDemo[10] = {
+	0x00, 0x01, 0x01, 0x01, 0x04, 0x05, 0x05, 0x05,
+	0x05, 0x04
+};
+
+static const ByteProvider kLoLDscOvlMapDOSCDDemoProvider = { ARRAYSIZE(kLoLDscOvlMapDOSCDDemo), kLoLDscOvlMapDOSCDDemo };
+
+static const uint16 kLoLDscScaleWidthDataDOSCDDemo[36] = {
+	0x0060, 0x0000, 0x0060, 0x00CE, 0x0060, 0x0055, 0x0060, 0x0000,
+	0x0060, 0x0055, 0x0060, 0x00CE, 0x0060, 0x0000, 0x00A0, 0x00AE,
+	0x00A0, 0x00AA, 0x00A0, 0x0000, 0x00A0, 0x00AA, 0x00A0, 0x00AE,
+	0x0100, 0x0100, 0x0100, 0x0000, 0x0100, 0x0100, 0x0000, 0x0100,
+	0x0100, 0x0000, 0x0000, 0x0100
+};
+
+static const Uint16Provider kLoLDscScaleWidthDataDOSCDDemoProvider = { ARRAYSIZE(kLoLDscScaleWidthDataDOSCDDemo), kLoLDscScaleWidthDataDOSCDDemo };
+
+static const uint16 kLoLDscScaleHeightDataDOSCDDemo[36] = {
+	0x006A, 0x0000, 0x006A, 0x006A, 0x006A, 0x006A, 0x006A, 0x0000,
+	0x006A, 0x006A, 0x006A, 0x006A, 0x006A, 0x0000, 0x00AA, 0x0056,
+	0x00AA, 0x00AA, 0x00AA, 0x0000, 0x00AA, 0x00AA, 0x00AA, 0x0056,
+	0x0100, 0x0100, 0x0100, 0x0000, 0x0100, 0x0100, 0x0000, 0x0100,
+	0x0100, 0x0000, 0x0000, 0x0100
+};
+
+static const Uint16Provider kLoLDscScaleHeightDataDOSCDDemoProvider = { ARRAYSIZE(kLoLDscScaleHeightDataDOSCDDemo), kLoLDscScaleHeightDataDOSCDDemo };
+
+static const uint16 kLoLDscXDOSCDDemo[36] = {
+	0xFFB0, 0xFFE0, 0xFFE0, 0x0010, 0x0010, 0x0040, 0x0040, 0x0000,
+	0x0070, 0x0070, 0x00A0, 0x00A0, 0x00D0, 0x00D0, 0xFF86, 0x0000,
+	0xFFE0, 0x0030, 0x0030, 0x0000, 0x0080, 0x0080, 0x00D0, 0x00B0,
+	0xFF98, 0x0018, 0x0018, 0x0000, 0x0098, 0x0098, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x00B0, 0x00B0
+};
+
+static const Uint16Provider kLoLDscXDOSCDDemoProvider = { ARRAYSIZE(kLoLDscXDOSCDDemo), kLoLDscXDOSCDDemo };
+
+static const byte kLoLBaseDscYDOSCDDemo[36] = {
+	0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B,
+	0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x14, 0x1C,
+	0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x1C,
+	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00
+};
+
+static const ByteProvider kLoLBaseDscYDOSCDDemoProvider = { ARRAYSIZE(kLoLBaseDscYDOSCDDemo), kLoLBaseDscYDOSCDDemo };
+
+static const byte kLoLDscTileIndexDOSCDDemo[18] = {
+	0x00, 0x06, 0x01, 0x05, 0x02, 0x04, 0x03, 0x07,
+	0x0B, 0x08, 0x0A, 0x09, 0x0C, 0x0E, 0x0D, 0x0F,
+	0x11, 0x10
+};
+
+static const ByteProvider kLoLDscTileIndexDOSCDDemoProvider = { ARRAYSIZE(kLoLDscTileIndexDOSCDDemo), kLoLDscTileIndexDOSCDDemo };
+
+static const byte kLoLDscDoorScaleOffsDOSCDDemo[23] = {
+	0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03,
+	0x08, 0x08, 0x08, 0x08, 0x08, 0x0D, 0x0D, 0x0D,
+	0x0D, 0x0D, 0x12, 0x12, 0x12, 0x12, 0x12
+};
+
+static const ByteProvider kLoLDscDoorScaleOffsDOSCDDemoProvider = { ARRAYSIZE(kLoLDscDoorScaleOffsDOSCDDemo), kLoLDscDoorScaleOffsDOSCDDemo };
+
+static const byte kLoLDscDoorShapeIndexDOSCDDemo[23] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
+};
+
+static const ByteProvider kLoLDscDoorShapeIndexDOSCDDemoProvider = { ARRAYSIZE(kLoLDscDoorShapeIndexDOSCDDemo), kLoLDscDoorShapeIndexDOSCDDemo };
+
+static const byte kLoLDscDimData1DOSCDDemo[324] = {
+	0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7,
+	0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7,
+	0xD8, 0xD7, 0xD8, 0xD8, 0x02, 0xD8, 0xD8, 0xD8,
+	0xD8, 0xFE, 0xD7, 0xD8, 0xD8, 0xD8, 0xD7, 0x03,
+	0xD8, 0xFD, 0xD8, 0xD8, 0xD8, 0xFE, 0xD8, 0x08,
+	0xD8, 0xD8, 0xD8, 0xFE, 0xF8, 0x06, 0xD8, 0xD8,
+	0xFA, 0x03, 0xD8, 0xFD, 0xD8, 0xD8, 0xD8, 0xD8,
+	0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xFA, 0xD7,
+	0x10, 0xD8, 0xFA, 0xD7, 0x10, 0xD8, 0xD8, 0xD8,
+	0xD8, 0xD8, 0xD8, 0xF2, 0xD8, 0x14, 0xD8, 0xD8,
+	0xD8, 0xF0, 0x0E, 0x14, 0xD8, 0xED, 0x10, 0xD8,
+	0xD8, 0x13, 0xD8, 0xD8, 0xD8, 0xD8, 0xEC, 0xD8,
+	0xD8, 0xD8, 0xD8, 0xD8, 0xD7, 0x14, 0xD8, 0xED,
+	0xD7, 0xD8, 0xD8, 0x13, 0xD7, 0xD7, 0xD7, 0xD7,
+	0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7,
+	0xD7, 0xD7, 0xD7, 0xD7, 0xD8, 0xD7, 0xD8, 0xD8,
+	0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD7, 0xD8,
+	0xD8, 0xD8, 0xD7, 0xD8, 0xD8, 0xD7, 0xD8, 0xD8,
+	0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8,
+	0xD8, 0x06, 0xD8, 0xD8, 0xFA, 0x03, 0xD8, 0xFD,
+	0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8,
+	0xD8, 0xD8, 0xFA, 0xD8, 0x10, 0xD8, 0xFA, 0xD7,
+	0x10, 0xFD, 0xD8, 0x13, 0xD8, 0xD8, 0xD8, 0xD8,
+	0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xF0, 0xD8, 0xD8,
+	0xD8, 0xED, 0x10, 0xD8, 0xD8, 0x13, 0xD8, 0xD8,
+	0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8,
+	0xD7, 0xD8, 0xD8, 0xD8, 0xD7, 0xD8, 0xD8, 0xD7,
+	0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8,
+	0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0x03, 0xD8, 0xFD,
+	0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8,
+	0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xFD, 0xD8,
+	0x13, 0xFD, 0xD8, 0x13, 0xD8, 0xD8, 0xD8, 0xD8,
+	0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8,
+	0xD8, 0xED, 0xD8, 0xD8, 0xD8, 0x13, 0xD8, 0xD8,
+	0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8,
+	0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8,
+	0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8,
+	0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8,
+	0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8,
+	0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8,
+	0xD8, 0xD8, 0xD8, 0xD8
+};
+
+static const ByteProvider kLoLDscDimData1DOSCDDemoProvider = { ARRAYSIZE(kLoLDscDimData1DOSCDDemo), kLoLDscDimData1DOSCDDemo };
+
+static const byte kLoLDscDimData2DOSCDDemo[648] = {
+	0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00,
+	0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00,
+	0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00,
+	0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00,
+	0x00, 0x16, 0x16, 0x00, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x02, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x02, 0x16, 0x00, 0x04, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x16, 0x00, 0x00, 0x03,
+	0x00, 0x16, 0x03, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x02, 0x16, 0x00, 0x16, 0x00, 0x08,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x02,
+	0x16, 0x00, 0x00, 0x06, 0x00, 0x16, 0x00, 0x16,
+	0x06, 0x16, 0x00, 0x03, 0x00, 0x16, 0x03, 0x00,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x06, 0x16, 0x08, 0x0E,
+	0x00, 0x10, 0x00, 0x16, 0x03, 0x16, 0x06, 0x10,
+	0x00, 0x13, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x0E, 0x16,
+	0x00, 0x16, 0x00, 0x14, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x10, 0x16, 0x16, 0x00, 0x00, 0x14,
+	0x00, 0x16, 0x13, 0x16, 0x00, 0x10, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x13, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x14, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x12, 0x16, 0x14, 0x16, 0x00, 0x16, 0x13, 0x16,
+	0x16, 0x00, 0x00, 0x16, 0x00, 0x16, 0x00, 0x13,
+	0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00,
+	0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00,
+	0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00,
+	0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00,
+	0x00, 0x16, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00,
+	0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00,
+	0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00,
+	0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00,
+	0x16, 0x00, 0x16, 0x00, 0x00, 0x16, 0x16, 0x00,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x06, 0x00, 0x16, 0x00, 0x16,
+	0x06, 0x16, 0x00, 0x03, 0x00, 0x16, 0x03, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x06, 0x16, 0x00, 0x16,
+	0x00, 0x10, 0x00, 0x16, 0x03, 0x16, 0x07, 0x0F,
+	0x00, 0x13, 0x03, 0x16, 0x00, 0x16, 0x00, 0x13,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x10, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x13, 0x16, 0x00, 0x10, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x13, 0x16, 0x00, 0x16, 0x00,
+	0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00,
+	0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00,
+	0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00,
+	0x16, 0x00, 0x16, 0x00, 0x00, 0x16, 0x16, 0x00,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x03, 0x00, 0x16, 0x03, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x03, 0x16, 0x00, 0x16,
+	0x00, 0x13, 0x03, 0x16, 0x00, 0x16, 0x00, 0x13,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x13, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x13, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16,
+	0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16
+};
+
+static const ByteProvider kLoLDscDimData2DOSCDDemoProvider = { ARRAYSIZE(kLoLDscDimData2DOSCDDemo), kLoLDscDimData2DOSCDDemo };
+
+static const byte kLoLDscBlockMapDOSCDDemo[12] = {
+	0x02, 0x03, 0x00, 0x01, 0x01, 0x02, 0x03, 0x00,
+	0x03, 0x00, 0x01, 0x02
+};
+
+static const ByteProvider kLoLDscBlockMapDOSCDDemoProvider = { ARRAYSIZE(kLoLDscBlockMapDOSCDDemo), kLoLDscBlockMapDOSCDDemo };
+
+static const byte kLoLDscDimMapDOSCDDemo[18] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+	0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03,
+	0x03, 0x03
+};
+
+static const ByteProvider kLoLDscDimMapDOSCDDemoProvider = { ARRAYSIZE(kLoLDscDimMapDOSCDDemo), kLoLDscDimMapDOSCDDemo };
+
+static const byte kLoLDscOvlIndexDOSCDDemo[20] = {
+	0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x03,
+	0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x05, 0x06,
+	0x06, 0x07, 0x07, 0x07
+};
+
+static const ByteProvider kLoLDscOvlIndexDOSCDDemoProvider = { ARRAYSIZE(kLoLDscOvlIndexDOSCDDemo), kLoLDscOvlIndexDOSCDDemo };
+
+static const byte kLoLDscBlockIndexDOSCDDemo[72] = {
+	0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xBE,
+	0xBF, 0xC0, 0xC1, 0xC2, 0xDF, 0xE0, 0xE1, 0xFF,
+	0x00, 0x01, 0xA3, 0xC3, 0xE3, 0x03, 0x23, 0x43,
+	0x63, 0xC2, 0xE2, 0x02, 0x22, 0x42, 0xE1, 0x01,
+	0x21, 0xE0, 0x00, 0x20, 0x63, 0x62, 0x61, 0x60,
+	0x5F, 0x5E, 0x5D, 0x42, 0x41, 0x40, 0x3F, 0x3E,
+	0x21, 0x20, 0x1F, 0x01, 0x00, 0xFF, 0x5D, 0x3D,
+	0x1D, 0xFD, 0xDD, 0xBD, 0x9D, 0x3E, 0x1E, 0xFE,
+	0xDE, 0xBE, 0x1F, 0xFF, 0xDF, 0x20, 0x00, 0xE0
+};
+
+static const ByteProvider kLoLDscBlockIndexDOSCDDemoProvider = { ARRAYSIZE(kLoLDscBlockIndexDOSCDDemo), kLoLDscBlockIndexDOSCDDemo };
+
+static const byte kLoLDscDoorY2DOSCDDemo[128] = {
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+	0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+	0x10, 0x11, 0x12, 0x13, 0x14, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x0D, 0x08, 0x03, 0x12, 0x0E, 0x09, 0x04, 0x00,
+	0x13, 0x0F, 0x0A, 0x05, 0x01, 0x14, 0x10, 0x0B,
+	0x06, 0x02, 0x11, 0x0C, 0x07, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D,
+	0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05,
+	0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x07, 0x0C, 0x11, 0x02, 0x06, 0x0B, 0x10, 0x14,
+	0x01, 0x05, 0x0A, 0x0F, 0x13, 0x00, 0x04, 0x09,
+	0x0E, 0x12, 0x03, 0x08, 0x0D, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static const ByteProvider kLoLDscDoorY2DOSCDDemoProvider = { ARRAYSIZE(kLoLDscDoorY2DOSCDDemo), kLoLDscDoorY2DOSCDDemo };
+
+static const byte kLoLDscDoorFrameY1DOSCDDemo[4] = {
+	0x1E, 0x18, 0x10, 0x00
+};
+
+static const ByteProvider kLoLDscDoorFrameY1DOSCDDemoProvider = { ARRAYSIZE(kLoLDscDoorFrameY1DOSCDDemo), kLoLDscDoorFrameY1DOSCDDemo };
+
+static const byte kLoLDscDoorFrameY2DOSCDDemo[4] = {
+	0x3B, 0x47, 0x56, 0x78
+};
+
+static const ByteProvider kLoLDscDoorFrameY2DOSCDDemoProvider = { ARRAYSIZE(kLoLDscDoorFrameY2DOSCDDemo), kLoLDscDoorFrameY2DOSCDDemo };
+
+static const uint16 kLoLDscDoorScaleDOSCDDemo[8] = {
+	0x0075, 0x006A, 0x00B9, 0x00B2, 0x0100, 0x0100, 0x0000, 0x0000
+};
+
+static const Uint16Provider kLoLDscDoorScaleDOSCDDemoProvider = { ARRAYSIZE(kLoLDscDoorScaleDOSCDDemo), kLoLDscDoorScaleDOSCDDemo };
+
+static const uint16 kLoLDscDoor4DOSCDDemo[4] = {
+	0x0005, 0x0002, 0x0008, 0x787C
+};
+
+static const Uint16Provider kLoLDscDoor4DOSCDDemoProvider = { ARRAYSIZE(kLoLDscDoor4DOSCDDemo), kLoLDscDoor4DOSCDDemo };
+
+static const uint16 kLoLDscDoorXDOSCDDemo[576] = {
+	0xFF98, 0xFFA0, 0xFFA8, 0xFF90, 0xFF98, 0xFFA0, 0xFFA8, 0xFFB0,
+	0xFF74, 0xFF7E, 0xFF88, 0xFF92, 0xFF9C, 0xFF74, 0xFF7E, 0xFF88,
+	0xFF92, 0xFF9C, 0xFF64, 0xFF70, 0xFF7C, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFFB8, 0xFFC0, 0xFFC8, 0xFFB0, 0xFFB8, 0xFFC0, 0xFFC8, 0xFFD0,
+	0xFF9C, 0xFFA6, 0xFFB0, 0xFFBA, 0xFFC4, 0xFF9C, 0xFFA6, 0xFFB0,
+	0xFFBA, 0xFFC4, 0xFF94, 0xFFA0, 0xFFAC, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFFD8, 0xFFE0, 0xFFE8, 0xFFD0, 0xFFD8, 0xFFE0, 0xFFE8, 0xFFF0,
+	0xFFC4, 0xFFCE, 0xFFD8, 0xFFE2, 0xFFEC, 0xFFC4, 0xFFCE, 0xFFD8,
+	0xFFE2, 0xFFEC, 0xFFC4, 0xFFD0, 0xFFDC, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFFF8, 0x0000, 0x0008, 0xFFF0, 0xFFF8, 0x0000, 0x0008, 0x0010,
+	0xFFEC, 0xFFF6, 0x0000, 0x000A, 0x0014, 0xFFEC, 0xFFF6, 0x0000,
+	0x000A, 0x0014, 0xFFF4, 0x0000, 0x000C, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0018, 0x0020, 0x0028, 0x0010, 0x0018, 0x0020, 0x0028, 0x0030,
+	0x0014, 0x001E, 0x0028, 0x0032, 0x003C, 0x0014, 0x001E, 0x0028,
+	0x0032, 0x003C, 0x0024, 0x0030, 0x003C, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0038, 0x0040, 0x0048, 0x0030, 0x0038, 0x0040, 0x0048, 0x0050,
+	0x003C, 0x0046, 0x0050, 0x005A, 0x0064, 0x003C, 0x0046, 0x0050,
+	0x005A, 0x0064, 0x0054, 0x0060, 0x006C, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0058, 0x0060, 0x0068, 0x0050, 0x0058, 0x0060, 0x0068, 0x0070,
+	0x0064, 0x006E, 0x0078, 0x0082, 0x008C, 0x0064, 0x006E, 0x0078,
+	0x0082, 0x008C, 0x0084, 0x0090, 0x009C, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFF94, 0xFFA0, 0xFFAC, 0xFF7E, 0xFF8B, 0xFF98, 0xFFA5, 0xFFB2,
+	0xFF6C, 0xFF7B, 0xFF8A, 0xFF99, 0xFFA7, 0xFF60, 0xFF70, 0xFF80,
+	0xFF90, 0xFFA0, 0xFF4C, 0xFF60, 0xFF74, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFFC4, 0xFFD0, 0xFFDC, 0xFFB2, 0xFFBF, 0xFFCC, 0xFFD9, 0xFFE6,
+	0xFFA7, 0xFFB6, 0xFFC5, 0xFFD4, 0xFFE2, 0xFFA0, 0xFFB0, 0xFFC0,
+	0xFFD0, 0xFFE0, 0xFF9C, 0xFFB0, 0xFFC4, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFFF4, 0x0000, 0x000C, 0xFFE6, 0xFFF3, 0x0000, 0x000D, 0x001A,
+	0xFFE2, 0xFFF1, 0x0000, 0x000F, 0x001E, 0xFFE0, 0xFFF0, 0x0000,
+	0x0010, 0x0020, 0xFFEC, 0x0000, 0x0014, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0024, 0x0030, 0x003C, 0x001A, 0x0027, 0x0034, 0x0041, 0x004E,
+	0x001E, 0x002C, 0x003B, 0x004A, 0x0059, 0x0020, 0x0030, 0x0040,
+	0x0050, 0x0060, 0x003C, 0x0050, 0x0064, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0054, 0x0060, 0x006C, 0x004E, 0x005B, 0x0068, 0x0075, 0x0082,
+	0x0059, 0x0067, 0x0076, 0x0085, 0x0094, 0x0060, 0x0070, 0x0080,
+	0x0090, 0x00A0, 0x008C, 0x00A0, 0x00B4, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFF9C, 0xFFB0, 0xFFC4, 0xFF7C, 0xFF92, 0xFFA8, 0xFFBE, 0xFFD4,
+	0xFF6D, 0xFF85, 0xFF9E, 0xFFB6, 0xFFCF, 0xFF5E, 0xFF79, 0xFF94,
+	0xFFAF, 0xFFCA, 0xFF60, 0xFF80, 0xFFA0, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFFEC, 0x0000, 0x0014, 0xFFD4, 0xFFEA, 0x0000, 0x0016, 0x002C,
+	0xFFCF, 0xFFE7, 0x0000, 0x0019, 0x0031, 0xFFCA, 0xFFE5, 0x0000,
+	0x001B, 0x0036, 0xFFE0, 0x0000, 0x0020, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x003C, 0x0050, 0x0064, 0x002C, 0x0042, 0x0058, 0x006E, 0x0084,
+	0x0031, 0x004A, 0x0062, 0x007B, 0x0093, 0x0036, 0x0051, 0x006C,
+	0x0087, 0x00A2, 0x0060, 0x0080, 0x00A0, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFF60, 0xFF80, 0xFFA0, 0xFF1C, 0xFF42, 0xFF68, 0xFF8E, 0xFFB4,
+	0xFF40, 0xFF60, 0xFF80, 0xFFA0, 0xFFC0, 0xFF1C, 0xFF42, 0xFF68,
+	0xFF8E, 0xFFB4, 0xFF60, 0xFF80, 0xFFA0, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFFE0, 0x0000, 0x0020, 0xFFB4, 0xFFDA, 0x0000, 0x0026, 0x004C,
+	0xFFC0, 0xFFE0, 0x0000, 0x0020, 0x0040, 0xFFB4, 0xFFDA, 0x0000,
+	0x0026, 0x004C, 0xFFE0, 0x0000, 0x0020, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0060, 0x0080, 0x00A0, 0x004C, 0x0072, 0x0098, 0x00BE, 0x00E4,
+	0x0040, 0x0060, 0x0080, 0x00A0, 0x00C0, 0x004C, 0x0072, 0x0098,
+	0x00BE, 0x00E4, 0x0060, 0x0080, 0x00A0, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+static const Uint16Provider kLoLDscDoorXDOSCDDemoProvider = { ARRAYSIZE(kLoLDscDoorXDOSCDDemo), kLoLDscDoorXDOSCDDemo };
+
+static const uint16 kLoLDscDoorYDOSCDDemo[576] = {
+	0xFFBF, 0xFFBF, 0xFFBF, 0xFFC1, 0xFFC1, 0xFFC1, 0xFFC1, 0xFFC1,
+	0xFFC3, 0xFFC3, 0xFFC3, 0xFFC3, 0xFFC3, 0xFFC5, 0xFFC5, 0xFFC5,
+	0xFFC5, 0xFFC5, 0xFFC9, 0xFFC9, 0xFFC9, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFFBF, 0xFFBF, 0xFFBF, 0xFFC1, 0xFFC1, 0xFFC1, 0xFFC1, 0xFFC1,
+	0xFFC3, 0xFFC3, 0xFFC3, 0xFFC3, 0xFFC3, 0xFFC5, 0xFFC5, 0xFFC5,
+	0xFFC5, 0xFFC5, 0xFFC9, 0xFFC9, 0xFFC9, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFFBF, 0xFFBF, 0xFFBF, 0xFFC1, 0xFFC1, 0xFFC1, 0xFFC1, 0xFFC1,
+	0xFFC3, 0xFFC3, 0xFFC3, 0xFFC3, 0xFFC3, 0xFFC5, 0xFFC5, 0xFFC5,
+	0xFFC5, 0xFFC5, 0xFFC9, 0xFFC9, 0xFFC9, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFFBF, 0xFFBF, 0xFFBF, 0xFFC1, 0xFFC1, 0xFFC1, 0xFFC1, 0xFFC1,
+	0xFFC3, 0xFFC3, 0xFFC3, 0xFFC3, 0xFFC3, 0xFFC5, 0xFFC5, 0xFFC5,
+	0xFFC5, 0xFFC5, 0xFFC9, 0xFFC9, 0xFFC9, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFFBF, 0xFFBF, 0xFFBF, 0xFFC1, 0xFFC1, 0xFFC1, 0xFFC1, 0xFFC1,
+	0xFFC3, 0xFFC3, 0xFFC3, 0xFFC3, 0xFFC3, 0xFFC5, 0xFFC5, 0xFFC5,
+	0xFFC5, 0xFFC5, 0xFFC9, 0xFFC9, 0xFFC9, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFFBF, 0xFFBF, 0xFFBF, 0xFFC1, 0xFFC1, 0xFFC1, 0xFFC1, 0xFFC1,
+	0xFFC3, 0xFFC3, 0xFFC3, 0xFFC3, 0xFFC3, 0xFFC5, 0xFFC5, 0xFFC5,
+	0xFFC5, 0xFFC5, 0xFFC9, 0xFFC9, 0xFFC9, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFFBF, 0xFFBF, 0xFFBF, 0xFFC1, 0xFFC1, 0xFFC1, 0xFFC1, 0xFFC1,
+	0xFFC3, 0xFFC3, 0xFFC3, 0xFFC3, 0xFFC3, 0xFFC5, 0xFFC5, 0xFFC5,
+	0xFFC5, 0xFFC5, 0xFFC9, 0xFFC9, 0xFFC9, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFFC9, 0xFFC9, 0xFFC9, 0xFFCB, 0xFFCB, 0xFFCB, 0xFFCB, 0xFFCB,
+	0xFFCE, 0xFFCE, 0xFFCE, 0xFFCE, 0xFFCE, 0xFFD3, 0xFFD3, 0xFFD3,
+	0xFFD3, 0xFFD3, 0xFFD7, 0xFFD7, 0xFFD7, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFFC9, 0xFFC9, 0xFFC9, 0xFFCB, 0xFFCB, 0xFFCB, 0xFFCB, 0xFFCB,
+	0xFFCE, 0xFFCE, 0xFFCE, 0xFFCE, 0xFFCE, 0xFFD3, 0xFFD3, 0xFFD3,
+	0xFFD3, 0xFFD3, 0xFFD7, 0xFFD7, 0xFFD7, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFFC9, 0xFFC9, 0xFFC9, 0xFFCB, 0xFFCB, 0xFFCB, 0xFFCB, 0xFFCB,
+	0xFFCE, 0xFFCE, 0xFFCE, 0xFFCE, 0xFFCE, 0xFFD3, 0xFFD3, 0xFFD3,
+	0xFFD3, 0xFFD3, 0xFFD7, 0xFFD7, 0xFFD7, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFFC9, 0xFFC9, 0xFFC9, 0xFFCB, 0xFFCB, 0xFFCB, 0xFFCB, 0xFFCB,
+	0xFFCE, 0xFFCE, 0xFFCE, 0xFFCE, 0xFFCE, 0xFFD3, 0xFFD3, 0xFFD3,
+	0xFFD3, 0xFFD3, 0xFFD7, 0xFFD7, 0xFFD7, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFFC9, 0xFFC9, 0xFFC9, 0xFFCB, 0xFFCB, 0xFFCB, 0xFFCB, 0xFFCB,
+	0xFFCE, 0xFFCE, 0xFFCE, 0xFFCE, 0xFFCE, 0xFFD3, 0xFFD3, 0xFFD3,
+	0xFFD3, 0xFFD3, 0xFFD7, 0xFFD7, 0xFFD7, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFFD7, 0xFFD7, 0xFFD7, 0xFFDD, 0xFFDD, 0xFFDD, 0xFFDD, 0xFFDD,
+	0xFFE2, 0xFFE2, 0xFFE2, 0xFFE2, 0xFFE2, 0xFFEA, 0xFFEA, 0xFFEA,
+	0xFFEA, 0xFFEA, 0xFFF8, 0xFFF8, 0xFFF8, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFFD7, 0xFFD7, 0xFFD7, 0xFFDD, 0xFFDD, 0xFFDD, 0xFFDD, 0xFFDD,
+	0xFFE2, 0xFFE2, 0xFFE2, 0xFFE2, 0xFFE2, 0xFFEA, 0xFFEA, 0xFFEA,
+	0xFFEA, 0xFFEA, 0xFFF8, 0xFFF8, 0xFFF8, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFFD7, 0xFFD7, 0xFFD7, 0xFFDD, 0xFFDD, 0xFFDD, 0xFFDD, 0xFFDD,
+	0xFFE2, 0xFFE2, 0xFFE2, 0xFFE2, 0xFFE2, 0xFFEA, 0xFFEA, 0xFFEA,
+	0xFFEA, 0xFFEA, 0xFFF8, 0xFFF8, 0xFFF8, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFFF8, 0xFFF8, 0xFFF8, 0xFFFC, 0xFFFC, 0xFFFC, 0xFFFC, 0xFFFC,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFFF8, 0xFFF8, 0xFFF8, 0xFFFC, 0xFFFC, 0xFFFC, 0xFFFC, 0xFFFC,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0xFFF8, 0xFFF8, 0xFFF8, 0xFFFC, 0xFFFC, 0xFFFC, 0xFFFC, 0xFFFC,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+static const Uint16Provider kLoLDscDoorYDOSCDDemoProvider = { ARRAYSIZE(kLoLDscDoorYDOSCDDemo), kLoLDscDoorYDOSCDDemo };
+
+static const byte kLoLScrollXTopDOSCDDemo[5] = {
+	0x05, 0x0A, 0x0F, 0x14, 0x19
+};
+
+static const ByteProvider kLoLScrollXTopDOSCDDemoProvider = { ARRAYSIZE(kLoLScrollXTopDOSCDDemo), kLoLScrollXTopDOSCDDemo };
+
+static const byte kLoLScrollYTopDOSCDDemo[5] = {
+	0x02, 0x04, 0x07, 0x09, 0x0C
+};
+
+static const ByteProvider kLoLScrollYTopDOSCDDemoProvider = { ARRAYSIZE(kLoLScrollYTopDOSCDDemo), kLoLScrollYTopDOSCDDemo };
+
+static const byte kLoLScrollXBottomDOSCDDemo[5] = {
+	0x05, 0x0A, 0x0F, 0x14, 0x19
+};
+
+static const ByteProvider kLoLScrollXBottomDOSCDDemoProvider = { ARRAYSIZE(kLoLScrollXBottomDOSCDDemo), kLoLScrollXBottomDOSCDDemo };
+
+static const byte kLoLScrollYBottomDOSCDDemo[5] = {
+	0x04, 0x08, 0x0C, 0x10, 0x14
+};
+
+static const ByteProvider kLoLScrollYBottomDOSCDDemoProvider = { ARRAYSIZE(kLoLScrollYBottomDOSCDDemo), kLoLScrollYBottomDOSCDDemo };
+
+static const LoLButtonDef kLoLButtonDefsDOSCDDemo[95] = {
+	{ 0x1100,  96, 352,  33, 131,  22,  19, 0x0000,  0 },
+	{ 0x1100,  97, 353,  33, 150,  22,  18, 0x0000,  0 },
+	{ 0x1100,  98, 354,  33, 150,  22,  18, 0x0000,  0 },
+	{ 0x1100,  92, 348,  11, 150,  22,  18, 0x0000,  0 },
+	{ 0x1100, 102, 358,  53, 150,  22,  18, 0x0000,  0 },
+	{ 0x1100,  91, 347,  11, 131,  22,  19, 0x0000,  0 },
+	{ 0x1100, 101, 357,  53, 131,  22,  19, 0x0000,  0 },
+	{ 0x0100, 112,   0,  80, 143,  22,  17, 0x0000,  0 },
+	{ 0x0100, 113,   0,  80, 143,  22,  17, 0x0001,  0 },
+	{ 0x0100, 114,   0,  80, 143,  22,  17, 0x0002,  0 },
+	{ 0x0100, 115,   0,  80, 143,  22,  17, 0x0003,  0 },
+	{ 0x1100,   0,   0,  80, 160,  22,  17, 0x0000,  0 },
+	{ 0x1100,   0,   0,  80, 160,  22,  17, 0x0001,  0 },
+	{ 0x1100,   0,   0,  80, 160,  22,  17, 0x0002,  0 },
+	{ 0x1100,   0,   0,  80, 160,  22,  17, 0x0003,  0 },
+	{ 0x1100,   0,   0,  80, 144,  22,  32, 0x0000,  0 },
+	{ 0x1100, 110,   0,   0,   0, 320, 200, 0x0003,  0 },
+	{ 0x0100,   0,   0,  80, 143,  33,  34, 0x0000,  0 },
+	{ 0x0100,   0,   0,  80, 143,  33,  34, 0x0001,  0 },
+	{ 0x0100,   0,   0,  80, 143,  33,  34, 0x0002,  0 },
+	{ 0x0100,   0,   0,  80, 143,  33,  34, 0x0003,  0 },
+	{ 0x0100,   0,   0,  80, 143,  66,  34, 0x0000,  0 },
+	{ 0x0100,   0,   0,  80, 143,  66,  34, 0x0001,  0 },
+	{ 0x0100,   0,   0,  80, 143,  66,  34, 0x0002,  0 },
+	{ 0x0100,   0,   0,  80, 143,  66,  34, 0x0003,  0 },
+	{ 0x0100,   0,   0,  80, 143,  12,  34, 0x0000,  0 },
+	{ 0x0100,   0,   0,  80, 143,  12,  34, 0x0001,  0 },
+	{ 0x0100,   0,   0,  80, 143,  12,  34, 0x0002,  0 },
+	{ 0x0100,   0,   0,  80, 143,  12,  34, 0x0003,  0 },
+	{ 0x1000,   0,   0,  80, 143,  66,  34, 0x0000,  0 },
+	{ 0x1000,   0,   0,  80, 143,  66,  34, 0x0001,  0 },
+	{ 0x1000,   0,   0,  80, 143,  66,  34, 0x0002,  0 },
+	{ 0x1000,   0,   0,  80, 143,  66,  34, 0x0003,  0 },
+	{ 0x1100,   0,   0,   0,   0,  20,  19, 0x0000,  2 },
+	{ 0x1100,   0,   0,   0,   0,  20,  19, 0x0001,  2 },
+	{ 0x1100,   0,   0,   0,   0,  20,  19, 0x0002,  2 },
+	{ 0x1100,   0,   0,   0,   0,  20,  19, 0x0003,  2 },
+	{ 0x1100,   0,   0,   0,   0,  20,  19, 0x0004,  2 },
+	{ 0x1100,   0,   0,   0,   0,  20,  19, 0x0005,  2 },
+	{ 0x1100,   0,   0,   0,   0,  20,  19, 0x0006,  2 },
+	{ 0x1100,   0,   0,   0,   0,  20,  19, 0x0007,  2 },
+	{ 0x1100,   0,   0,   0,   0,  20,  19, 0x0008,  2 },
+	{ 0x1100,   0,   0,   0,   0,  12,  11, 0x0009,  2 },
+	{ 0x1100,   0,   0,   0,   0,  12,  11, 0x000A,  2 },
+	{ 0x1100, 110,   0, 160,  93,  43,  19, 0x0000,  2 },
+	{ 0x1100,   0,   0,   0, 102,  88,  19, 0x0000,  2 },
+	{ 0x1100,   0,   0,  88, 102,  88,  19, 0x0001,  2 },
+	{ 0x1100,   0,   0,   0,  85,  88,  17, 0x0002,  2 },
+	{ 0x1100,   0,   0,  88,  85,  88,  17, 0x0003,  2 },
+	{ 0x1100,   0,   0,   0,   0, 176, 120, 0x0000,  2 },
+	{ 0x1100,   0,   0, 106, 179,  21,  21, 0x0000,  0 },
+	{ 0x1100,   0,   0, 127, 179,  21,  21, 0x0001,  0 },
+	{ 0x1100,   0,   0, 148, 179,  21,  21, 0x0002,  0 },
+	{ 0x1100,   0,   0, 169, 179,  21,  21, 0x0003,  0 },
+	{ 0x1100,   0,   0, 190, 179,  21,  21, 0x0004,  0 },
+	{ 0x1100,   0,   0, 211, 179,  21,  21, 0x0005,  0 },
+	{ 0x1100,   0,   0, 232, 179,  21,  21, 0x0006,  0 },
+	{ 0x1100,   0,   0, 253, 179,  21,  21, 0x0007,  0 },
+	{ 0x1100,   0,   0, 274, 179,  21,  21, 0x0008,  0 },
+	{ 0x1100,   0,   0, 274, 179,  21,  21, 0x0009,  0 },
+	{ 0x1100,   0,   0,  85, 179,  21,  21, 0xFFFF,  0 },
+	{ 0x1100,   0,   0, 295, 179,  22,  21, 0x0001,  0 },
+	{ 0x1100,   0,   0,  24,   8, 128,  96, 0x0001,  2 },
+	{ 0x1100,   0,   0,   0,   0, 176, 120, 0x0000,  2 },
+	{ 0x1100,   0,   0,   0,   0,   0,   0, 0x0000,  0 },
+	{ 0x1100,   0,   0, 112,   0, 176,  16, 0x0001,  0 },
+	{ 0x1100,   0,   0, 112, 110, 176,  26, 0x0001,  0 },
+	{ 0x1100,   0,   0,  96,  88,  32,  32, 0x0001,  0 },
+	{ 0x1100,   0,   0, 272,  88,  32,  32, 0x0001,  0 },
+	{ 0x1100,   0,   0,  96,  16,  32,  72, 0x0001,  0 },
+	{ 0x1100,   0,   0, 272,  16,  32,  72, 0x0001,  0 },
+	{ 0x1100,   0,   0,  24,  15,  61,   9, 0x0000,  0 },
+	{ 0x1100,   0,   0,  24,  24,  61,   9, 0x0000,  0 },
+	{ 0x1100,   0,   0,  24,  33,  61,   9, 0x0000,  0 },
+	{ 0x1100,   0,   0,  24,  42,  61,   9, 0x0000,  0 },
+	{ 0x1100,   0,   0,  24,  51,  61,   9, 0x0000,  0 },
+	{ 0x1100,   0,   0,  24,  60,  61,   9, 0x0000,  0 },
+	{ 0x1100,   0,   0,  24,  69,  61,   9, 0x0000,  0 },
+	{ 0x1100,   0,   0,  24,  78,  61,   9, 0x0000,  0 },
+	{ 0x1100,   0,   0,  24,  87,  61,   9, 0x0000,  0 },
+	{ 0x1100,   0,   0,  24,  96,  61,   9, 0x0000,  0 },
+	{ 0x0100,   0,   0,  80, 143,  66,  34, 0x0000,  0 },
+	{ 0x0100,   0,   0,  80, 143,  66,  34, 0x0001,  0 },
+	{ 0x0100,   0,   0,  80, 143,  66,  34, 0x0002,  0 },
+	{ 0x0100,   0,   0,  80, 143,  66,  34, 0x0003,  0 },
+	{ 0x1100, 110,   0,   0,   0, 320, 200, 0x0003,  0 },
+	{ 0x0100,   0,   0, 112,   0,  88,  80, 0x0000,  0 },
+	{ 0x0100,   0,   0, 200,   0,  88,  80, 0x0001,  0 },
+	{ 0x1100,  25, 110,  11, 178,  21,  22, 0x0000,  0 },
+	{ 0x0100,  20,   0,  32, 178,  22,  22, 0x0000,  0 },
+	{ 0x0100,   0,   0, 291,  96,  27,  24, 0x0000,  0 },
+	{ 0x0100,   0,   0, 289,   0,  31,  28, 0x0000,  0 },
+	{ 0x0100,  52,   0, 289,  31,  31,  23, 0x0000,  0 },
+	{ 0x0100,   0,   0, 291,  56,  29,  24, 0x0000,  0 },
+	{ 0x1100,   0,   0, 220,  98,  43,  19, 0x0000,  0 }
+};
+
+static const LoLButtonDefProvider kLoLButtonDefsDOSCDDemoProvider = { ARRAYSIZE(kLoLButtonDefsDOSCDDemo), kLoLButtonDefsDOSCDDemo };
+
+static const byte kLoLButtonList1DOSCDDemo[40] = {
+	0x59, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x31,
+	0x3E, 0x2D, 0x2E, 0x2F, 0x30, 0x56, 0x57, 0x01,
+	0x02, 0x00, 0x03, 0x04, 0x05, 0x06, 0x32, 0x33,
+	0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
+	0x3C, 0x3D, 0x58, 0x5A, 0x5B, 0x5C, 0x5D, 0xFF
+};
+
+static const ByteProvider kLoLButtonList1DOSCDDemoProvider = { ARRAYSIZE(kLoLButtonList1DOSCDDemo), kLoLButtonList1DOSCDDemo };
+
+static const byte kLoLButtonList2DOSCDDemo[15] = {
+	0x2C, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
+	0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x5E, 0xFF
+};
+
+static const ByteProvider kLoLButtonList2DOSCDDemoProvider = { ARRAYSIZE(kLoLButtonList2DOSCDDemo), kLoLButtonList2DOSCDDemo };
+
+static const byte kLoLButtonList3DOSCDDemo[2] = {
+	0x40, 0xFF
+};
+
+static const ByteProvider kLoLButtonList3DOSCDDemoProvider = { ARRAYSIZE(kLoLButtonList3DOSCDDemo), kLoLButtonList3DOSCDDemo };
+
+static const byte kLoLButtonList4DOSCDDemo[15] = {
+	0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+	0x3A, 0x3B, 0x3C, 0x3D, 0x5A, 0x5B, 0xFF
+};
+
+static const ByteProvider kLoLButtonList4DOSCDDemoProvider = { ARRAYSIZE(kLoLButtonList4DOSCDDemo), kLoLButtonList4DOSCDDemo };
+
+static const byte kLoLButtonList5DOSCDDemo[16] = {
+	0x01, 0x02, 0x00, 0x03, 0x04, 0x05, 0x06, 0x41,
+	0x42, 0x43, 0x44, 0x45, 0x46, 0x5A, 0x5B, 0xFF
+};
+
+static const ByteProvider kLoLButtonList5DOSCDDemoProvider = { ARRAYSIZE(kLoLButtonList5DOSCDDemo), kLoLButtonList5DOSCDDemo };
+
+static const byte kLoLButtonList6DOSCDDemo[14] = {
+	0x2C, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
+	0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF
+};
+
+static const ByteProvider kLoLButtonList6DOSCDDemoProvider = { ARRAYSIZE(kLoLButtonList6DOSCDDemo), kLoLButtonList6DOSCDDemo };
+
+static const byte kLoLButtonList7DOSCDDemo[3] = {
+	0x0F, 0x10, 0xFF
+};
+
+static const ByteProvider kLoLButtonList7DOSCDDemoProvider = { ARRAYSIZE(kLoLButtonList7DOSCDDemo), kLoLButtonList7DOSCDDemo };
+
+static const byte kLoLButtonList8DOSCDDemo[2] = {
+	0x55, 0xFF
+};
+
+static const ByteProvider kLoLButtonList8DOSCDDemoProvider = { ARRAYSIZE(kLoLButtonList8DOSCDDemo), kLoLButtonList8DOSCDDemo };
+
+static const byte kLoLLegendDataDOSCDDemo[60] = {
+	0x0E, 0x00, 0x00, 0x07, 0x42, 0x19, 0x00, 0x00,
+	0x08, 0x42, 0x1A, 0x00, 0x00, 0x09, 0x42, 0x0D,
+	0x00, 0x00, 0x0A, 0x42, 0x0A, 0x00, 0x00, 0x0B,
+	0x42, 0x0B, 0x00, 0x00, 0x0C, 0x42, 0x0F, 0x00,
+	0x00, 0x0D, 0x42, 0x16, 0x00, 0x00, 0x0E, 0x42,
+	0x17, 0x00, 0x00, 0x0F, 0x42, 0x11, 0x00, 0x00,
+	0x10, 0x42, 0x12, 0x00, 0xFB, 0x51, 0x42, 0xFF,
+	0xFF, 0xFF, 0xFF, 0xFF
+};
+
+static const ByteProvider kLoLLegendDataDOSCDDemoProvider = { ARRAYSIZE(kLoLLegendDataDOSCDDemo), kLoLLegendDataDOSCDDemo };
+
+static const byte kLoLMapCursorOvlDOSCDDemo[25] = {
+	0x00, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86,
+	0x87, 0x88, 0x01, 0x01, 0x01, 0x01, 0x01, 0x88,
+	0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80,
+	0x80
+};
+
+static const ByteProvider kLoLMapCursorOvlDOSCDDemoProvider = { ARRAYSIZE(kLoLMapCursorOvlDOSCDDemo), kLoLMapCursorOvlDOSCDDemo };
+
+static const uint16 kLoLMapStringIdDOSCDDemo[30] = {
+	0xFFFF, 0x4211, 0x4212, 0x4213, 0x4214, 0x4215, 0x4216, 0x4217,
+	0x4218, 0x4219, 0x421A, 0x421B, 0x421C, 0x421D, 0x421E, 0x421F,
+	0x4220, 0x4221, 0x4222, 0x4223, 0x4224, 0x4225, 0x4226, 0x4227,
+	0x4228, 0x4229, 0x422A, 0x422B, 0x422C, 0x422D
+};
+
+static const Uint16Provider kLoLMapStringIdDOSCDDemoProvider = { ARRAYSIZE(kLoLMapStringIdDOSCDDemo), kLoLMapStringIdDOSCDDemo };
+
+static const byte kLoLSpellbookAnimDOSCDDemo[28] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x04, 0x00, 0x13, 0xB6, 0x04, 0x00, 0x13, 0x4D,
+	0x04, 0x00, 0x13, 0xB9, 0x04, 0x00, 0x13, 0xB8,
+	0x04, 0x00, 0x13, 0xBA
+};
+
+static const ByteProvider kLoLSpellbookAnimDOSCDDemoProvider = { ARRAYSIZE(kLoLSpellbookAnimDOSCDDemo), kLoLSpellbookAnimDOSCDDemo };
+
+static const byte kLoLSpellbookCoordsDOSCDDemo[12] = {
+	0x16, 0x16, 0x16, 0x1F, 0x16, 0x28, 0x16, 0x31,
+	0x16, 0x3A, 0x16, 0x43
+};
+
+static const ByteProvider kLoLSpellbookCoordsDOSCDDemoProvider = { ARRAYSIZE(kLoLSpellbookCoordsDOSCDDemo), kLoLSpellbookCoordsDOSCDDemo };
+
+static const byte kLoLHealShapeFramesDOSCDDemo[80] = {
+	0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02,
+	0x02, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03,
+	0x03, 0x03, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+	0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00,
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+	0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+};
+
+static const ByteProvider kLoLHealShapeFramesDOSCDDemoProvider = { ARRAYSIZE(kLoLHealShapeFramesDOSCDDemo), kLoLHealShapeFramesDOSCDDemo };
+
+static const byte kLoLLightningDefsDOSCDDemo[20] = {
+	0x06, 0x05, 0xAB, 0x00, 0x06, 0x04, 0xAB, 0x00,
+	0x08, 0x04, 0xAA, 0x00, 0x06, 0x03, 0xAA, 0x00,
+	0x06, 0x02, 0xA9, 0x00
+};
+
+static const ByteProvider kLoLLightningDefsDOSCDDemoProvider = { ARRAYSIZE(kLoLLightningDefsDOSCDDemo), kLoLLightningDefsDOSCDDemo };
+
+
diff --git a/devtools/create_kyradat/resources/mr_dos_cd.h b/devtools/create_kyradat/resources/mr_dos_cd.h
index 9dffa33a1d..62344998a1 100644
--- a/devtools/create_kyradat/resources/mr_dos_cd.h
+++ b/devtools/create_kyradat/resources/mr_dos_cd.h
@@ -1,20 +1,3 @@
-static const char *const k3MainMenuStringsDOSCD[12] = {
-	"Start a new game",
-	"Introduction",
-	"Load a game",
-	"Exit the game",
-	"Nouvelle Partie",
-	"Introduction",
-	"Charger une partie",
-	"Quitter le jeu",
-	"Neues Spiel starten",
-	"Intro",
-	"Spielstand laden",
-	"Spiel beenden"
-};
-
-static const StringListProvider k3MainMenuStringsDOSCDProvider = { ARRAYSIZE(k3MainMenuStringsDOSCD), k3MainMenuStringsDOSCD };
-
 static const char *const k3MusicFilesDOSCD[43] = {
 	"ARREST1",
 	"BATH1",
@@ -554,3 +537,8 @@ static const byte k3ItemStringMapDOSCD[72] = {
 
 static const ByteProvider k3ItemStringMapDOSCDProvider = { ARRAYSIZE(k3ItemStringMapDOSCD), k3ItemStringMapDOSCD };
 
+static const byte k3DummyDataDOSCD[1] = {
+	0
+};
+
+static const ByteProvider k3DummyDataDOSCDProvider = { ARRAYSIZE(k3DummyDataDOSCD), k3DummyDataDOSCD };
diff --git a/devtools/create_kyradat/resources/mr_dos_cd_chinese_simplified.h b/devtools/create_kyradat/resources/mr_dos_cd_chinese_simplified.h
new file mode 100644
index 0000000000..f963f30341
--- /dev/null
+++ b/devtools/create_kyradat/resources/mr_dos_cd_chinese_simplified.h
@@ -0,0 +1,251 @@
+static const char *const k3MainMenuStringsDOSCDChineseSmpl[4] = {
+	"\xbf\xa0\x80\xa1\x81\xa1\x82\xa1\x83\xa1",
+	"\x84\xa1"" ""\x85\xa1"" ""\x86\xa1"" ""\x87\xa1",
+	"\x88\xa1\x89\xa1\x82\xa1\x83\xa1\x8a\xa1\x8b\xa1",
+	"\x8c\xa1"" ""\x8d\xa1"" ""\x82\xa1"" ""\x83\xa1"
+};
+
+static const StringListProvider k3MainMenuStringsDOSCDChineseSmplProvider = { ARRAYSIZE(k3MainMenuStringsDOSCDChineseSmpl), k3MainMenuStringsDOSCDChineseSmpl };
+
+static const char *const k3VqaSubtitlesIntroDOSCDChineseSmpl[] = {
+	""// TODO
+};
+
+static const StringListProvider k3VqaSubtitlesIntroDOSCDChineseSmplProvider = { ARRAYSIZE(k3VqaSubtitlesIntroDOSCDChineseSmpl), k3VqaSubtitlesIntroDOSCDChineseSmpl };
+
+static const char *const k3VqaSubtitlesBoatDOSCDChineseSmpl[] = {
+	""// TODO
+};
+
+static const StringListProvider k3VqaSubtitlesBoatDOSCDChineseSmplProvider = { ARRAYSIZE(k3VqaSubtitlesBoatDOSCDChineseSmpl), k3VqaSubtitlesBoatDOSCDChineseSmpl };
+
+static const byte k3FontDataDOSCDChineseSmpl[1806] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x3e, 0x41, 0x55, 0x55, 0x41, 0x63, 0x5d, 0x41,
+	0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x7f,
+	0x6b, 0x6b, 0x7f, 0x5d, 0x63, 0x7f, 0x3e, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x22, 0x77, 0x7f, 0x7f,
+	0x3e, 0x3e, 0x1c, 0x1c, 0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x1c, 0x1c, 0x3e, 0x7f, 0x3e,
+	0x1c, 0x1c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x3e, 0x1c, 0x2a, 0x7f, 0x7f, 0x2a, 0x08,
+	0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1c,
+	0x3e, 0x3e, 0x7f, 0x7f, 0x7f, 0x2a, 0x1c, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+	0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3,
+	0xc3, 0xe7, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x18, 0x24, 0x24, 0x24, 0x18,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+	0xff, 0xe7, 0xdb, 0xdb, 0xdb, 0xe7, 0xff, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x1f, 0x05, 0x09, 0x10,
+	0x20, 0x3c, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x1c, 0x22, 0x22, 0x1c, 0x08, 0x08,
+	0x3e, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x10, 0x14, 0x14, 0x12, 0x10, 0x10, 0x10, 0x30,
+	0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x12,
+	0x19, 0x15, 0x13, 0x31, 0x71, 0x63, 0x06, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5d, 0x22,
+	0x63, 0x22, 0x5d, 0x08, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x20, 0x38, 0x3c, 0x3e, 0x3f, 0x3e,
+	0x3c, 0x38, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x02, 0x0e, 0x1e, 0x3e, 0x7e, 0x3e, 0x1e, 0x0e,
+	0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3e,
+	0x7f, 0x1c, 0x1c, 0x1c, 0x7f, 0x3e, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x24, 0x24,
+	0x24, 0x24, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x1f, 0x49, 0x49, 0x59, 0x29, 0x09,
+	0x09, 0x09, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x1c, 0x20, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x02,
+	0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x3e, 0x1c, 0x1c,
+	0x1c, 0x3e, 0x1c, 0x08, 0x7f, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x3e, 0x7f, 0x1c, 0x1c, 0x1c,
+	0x1c, 0x1c, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x7f, 0x3e,
+	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+	0x0c, 0x06, 0x7f, 0x06, 0x0c, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x18, 0x30,
+	0x7f, 0x30, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0x60, 0x60,
+	0x60, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x22, 0x63, 0x7f, 0x63, 0x22, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1c,
+	0x1c, 0x1c, 0x3e, 0x3e, 0x3e, 0x7f, 0x7f, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x3e, 0x3e,
+	0x3e, 0x1c, 0x1c, 0x1c, 0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18,
+	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66,
+	0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x7e, 0x24,
+	0x24, 0x24, 0x7e, 0x24, 0x24, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x3e, 0x41, 0x40, 0x3e, 0x01,
+	0x41, 0x3e, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x31, 0x4a, 0x4c, 0x34, 0x08, 0x16, 0x19, 0x29,
+	0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44,
+	0x28, 0x10, 0x28, 0x48, 0x45, 0x42, 0x3d, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x10, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x02, 0x04, 0x08, 0x08, 0x08, 0x10, 0x10, 0x10,
+	0x10, 0x10, 0x08, 0x08, 0x08, 0x04, 0x20, 0x10,
+	0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04,
+	0x08, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x22,
+	0x14, 0x08, 0x7f, 0x08, 0x14, 0x22, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08,
+	0x7f, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x30, 0x30, 0x10, 0x20, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04,
+	0x08, 0x08, 0x10, 0x10, 0x20, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xd6, 0xe6,
+	0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x18, 0x38, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18,
+	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
+	0xc6, 0x06, 0x1c, 0x70, 0xc0, 0xc0, 0xfe, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x06,
+	0x3c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x3c, 0x6c, 0x6c, 0xcc, 0xcc, 0xcc,
+	0xcc, 0xfe, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0xc6, 0xc6,
+	0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
+	0xc6, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0x7c, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0x0c,
+	0x18, 0x18, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6,
+	0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0xc6, 0xc6,
+	0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
+	0x00, 0x18, 0x18, 0x08, 0x10, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x20, 0x10,
+	0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+	0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x06, 0x0c,
+	0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x1c, 0x42, 0x4e, 0x52, 0x52, 0x52,
+	0x4c, 0x40, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6,
+	0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc6,
+	0xc6, 0xc6, 0xfc, 0xc6, 0xc6, 0xc6, 0xfc, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc0,
+	0xc0, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+	0xc6, 0xc6, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x7e, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0,
+	0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xc0,
+	0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc0,
+	0xce, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6,
+	0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+	0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06,
+	0x06, 0x06, 0x06, 0x06, 0xc6, 0xc6, 0x7c, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xcc, 0xd8,
+	0xf8, 0xd8, 0xcc, 0xc6, 0xc6, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
+	0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xc6, 0xc6, 0xee, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6,
+	0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6,
+	0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6,
+	0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xfc, 0xc0,
+	0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xcc,
+	0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc6,
+	0xc6, 0xc6, 0xfc, 0xcc, 0xcc, 0xc6, 0xc6, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc0,
+	0x7c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18,
+	0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+	0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6,
+	0xc6, 0x6c, 0x6c, 0x6c, 0x38, 0x38, 0x38, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6,
+	0xd6, 0xfe, 0xee, 0xc6, 0xc6, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x6c, 0x38, 0x6c,
+	0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x30,
+	0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06,
+	0x0c, 0x58, 0x38, 0x34, 0x60, 0xc0, 0xfe, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x0e, 0x08, 0x08, 0x08,
+	0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x40, 0x20, 0x20, 0x10, 0x10, 0x08,
+	0x08, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x70, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x22,
+	0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x18, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x7c, 0x06, 0x7e, 0xc6, 0xc6,
+	0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0,
+	0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
+	0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x06, 0x06, 0x06, 0x7e, 0xc6, 0xc6,
+	0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0,
+	0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x36,
+	0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
+	0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0xc6, 0x7c, 0x00,
+	0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6,
+	0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18,
+	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
+	0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc,
+	0x78, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc6, 0xcc,
+	0xd8, 0xf0, 0xd8, 0xcc, 0xc6, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+	0x18, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0xc6, 0xee, 0xfe, 0xd6, 0xc6,
+	0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
+	0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc6, 0xc6,
+	0xc6, 0xfc, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e,
+	0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x6c, 0x76, 0x66, 0x60, 0x60, 0x60, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
+	0xc6, 0x70, 0x1c, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x30, 0x30, 0x30, 0xfc, 0x30, 0x30,
+	0x30, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+	0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0xc6, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6,
+	0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x30,
+	0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3e,
+	0x06, 0x0c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0xfe, 0x06, 0x1c, 0x70, 0xc0, 0xfe, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x04, 0x04,
+	0x04, 0x08, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
+	0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x20, 0x20,
+	0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x46,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x14, 0x14,
+	0x22, 0x22, 0x41, 0x41, 0x7f, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0,
+	0xc0, 0xc6, 0x7c, 0x08, 0x38, 0x00
+};
+
+static const ByteProvider k3FontDataDOSCDChineseSmplProvider = { ARRAYSIZE(k3FontDataDOSCDChineseSmpl), k3FontDataDOSCDChineseSmpl };
diff --git a/devtools/create_kyradat/resources/mr_dos_cd_english.h b/devtools/create_kyradat/resources/mr_dos_cd_english.h
new file mode 100644
index 0000000000..1f1eaf897f
--- /dev/null
+++ b/devtools/create_kyradat/resources/mr_dos_cd_english.h
@@ -0,0 +1,20 @@
+static const char *const k3MainMenuStringsDOSCDEnglish[4] = {
+	"Start a new game",
+	"Introduction",
+	"Load a game",
+	"Exit the game"
+};
+
+static const StringListProvider k3MainMenuStringsDOSCDEnglishProvider = { ARRAYSIZE(k3MainMenuStringsDOSCDEnglish), k3MainMenuStringsDOSCDEnglish };
+
+static const char *const k3VqaSubtitlesIntroDOSCDEnglish[] = {
+	""// TODO
+};
+
+static const StringListProvider k3VqaSubtitlesIntroDOSCDEnglishProvider = { ARRAYSIZE(k3VqaSubtitlesIntroDOSCDEnglish), k3VqaSubtitlesIntroDOSCDEnglish };
+
+static const char *const k3VqaSubtitlesBoatDOSCDEnglish[] = {
+	""// TODO
+};
+
+static const StringListProvider k3VqaSubtitlesBoatDOSCDEnglishProvider = { ARRAYSIZE(k3VqaSubtitlesBoatDOSCDEnglish), k3VqaSubtitlesBoatDOSCDEnglish };
diff --git a/devtools/create_kyradat/resources/mr_dos_cd_french.h b/devtools/create_kyradat/resources/mr_dos_cd_french.h
new file mode 100644
index 0000000000..77ffc4148c
--- /dev/null
+++ b/devtools/create_kyradat/resources/mr_dos_cd_french.h
@@ -0,0 +1,20 @@
+static const char *const k3MainMenuStringsDOSCDFrench[4] = {
+	"Nouvelle Partie",
+	"Introduction",
+	"Charger une partie",
+	"Quitter le jeu"
+};
+
+static const StringListProvider k3MainMenuStringsDOSCDFrenchProvider = { ARRAYSIZE(k3MainMenuStringsDOSCDFrench), k3MainMenuStringsDOSCDFrench };
+
+static const char *const k3VqaSubtitlesIntroDOSCDFrench[] = {
+	""// TODO
+};
+
+static const StringListProvider k3VqaSubtitlesIntroDOSCDFrenchProvider = { ARRAYSIZE(k3VqaSubtitlesIntroDOSCDFrench), k3VqaSubtitlesIntroDOSCDFrench };
+
+static const char *const k3VqaSubtitlesBoatDOSCDFrench[] = {
+	""// TODO
+};
+
+static const StringListProvider k3VqaSubtitlesBoatDOSCDFrenchProvider = { ARRAYSIZE(k3VqaSubtitlesBoatDOSCDFrench), k3VqaSubtitlesBoatDOSCDFrench };
diff --git a/devtools/create_kyradat/resources/mr_dos_cd_german.h b/devtools/create_kyradat/resources/mr_dos_cd_german.h
new file mode 100644
index 0000000000..f8e463f519
--- /dev/null
+++ b/devtools/create_kyradat/resources/mr_dos_cd_german.h
@@ -0,0 +1,20 @@
+static const char *const k3MainMenuStringsDOSCDGerman[4] = {
+	"Neues Spiel starten",
+	"Intro",
+	"Spielstand laden",
+	"Spiel beenden"
+};
+
+static const StringListProvider k3MainMenuStringsDOSCDGermanProvider = { ARRAYSIZE(k3MainMenuStringsDOSCDGerman), k3MainMenuStringsDOSCDGerman };
+
+static const char *const k3VqaSubtitlesIntroDOSCDGerman[] = {
+	""// TODO
+};
+
+static const StringListProvider k3VqaSubtitlesIntroDOSCDGermanProvider = { ARRAYSIZE(k3VqaSubtitlesIntroDOSCDGerman), k3VqaSubtitlesIntroDOSCDGerman };
+
+static const char *const k3VqaSubtitlesBoatDOSCDGerman[] = {
+	""// TODO
+};
+
+static const StringListProvider k3VqaSubtitlesBoatDOSCDGermanProvider = { ARRAYSIZE(k3VqaSubtitlesBoatDOSCDGerman), k3VqaSubtitlesBoatDOSCDGerman };
diff --git a/devtools/create_kyradat/resources/mr_dos_cd_italian.h b/devtools/create_kyradat/resources/mr_dos_cd_italian.h
new file mode 100644
index 0000000000..3b7de6a8ca
--- /dev/null
+++ b/devtools/create_kyradat/resources/mr_dos_cd_italian.h
@@ -0,0 +1,20 @@
+static const char *const k3MainMenuStringsDOSCDItalian[4] = {
+	"Nuova Partita",
+	"Introduzione",
+	"Carica una partita",
+	"Esci dal gioco"
+};
+
+static const StringListProvider k3MainMenuStringsDOSCDItalianProvider = { ARRAYSIZE(k3MainMenuStringsDOSCDItalian), k3MainMenuStringsDOSCDItalian };
+
+static const char *const k3VqaSubtitlesIntroDOSCDItalian[] = {
+	""// TODO
+};
+
+static const StringListProvider k3VqaSubtitlesIntroDOSCDItalianProvider = { ARRAYSIZE(k3VqaSubtitlesIntroDOSCDItalian), k3VqaSubtitlesIntroDOSCDItalian };
+
+static const char *const k3VqaSubtitlesBoatDOSCDItalian[] = {
+	""// TODO
+};
+
+static const StringListProvider k3VqaSubtitlesBoatDOSCDItalianProvider = { ARRAYSIZE(k3VqaSubtitlesBoatDOSCDItalian), k3VqaSubtitlesBoatDOSCDItalian };
diff --git a/devtools/create_kyradat/resources/mr_dos_cd_russian.h b/devtools/create_kyradat/resources/mr_dos_cd_russian.h
new file mode 100644
index 0000000000..e7c37cbf03
--- /dev/null
+++ b/devtools/create_kyradat/resources/mr_dos_cd_russian.h
@@ -0,0 +1,20 @@
+static const char *const k3MainMenuStringsDOSCDRussian[4] = {
+	"Start a new game",
+	"Introduction",
+	"Load a game",
+	"Exit the game"
+};
+
+static const StringListProvider k3MainMenuStringsDOSCDRussianProvider = { ARRAYSIZE(k3MainMenuStringsDOSCDRussian), k3MainMenuStringsDOSCDRussian };
+
+static const char *const k3VqaSubtitlesIntroDOSCDRussian[] = {
+	""// TODO
+};
+
+static const StringListProvider k3VqaSubtitlesIntroDOSCDRussianProvider = { ARRAYSIZE(k3VqaSubtitlesIntroDOSCDRussian), k3VqaSubtitlesIntroDOSCDRussian };
+
+static const char *const k3VqaSubtitlesBoatDOSCDRussian[] = {
+	""// TODO
+};
+
+static const StringListProvider k3VqaSubtitlesBoatDOSCDRussianProvider = { ARRAYSIZE(k3VqaSubtitlesBoatDOSCDRussian), k3VqaSubtitlesBoatDOSCDRussian };
diff --git a/devtools/create_kyradat/resources/mr_dos_cd_spanish.h b/devtools/create_kyradat/resources/mr_dos_cd_spanish.h
new file mode 100644
index 0000000000..5dc9a22abd
--- /dev/null
+++ b/devtools/create_kyradat/resources/mr_dos_cd_spanish.h
@@ -0,0 +1,20 @@
+static const char *const k3MainMenuStringsDOSCDSpanish[4] = {
+	"Nueva Partida",
+	"Ver Intro",
+	"Restaurar",
+	"Finalizar"
+};
+
+static const StringListProvider k3MainMenuStringsDOSCDSpanishProvider = { ARRAYSIZE(k3MainMenuStringsDOSCDSpanish), k3MainMenuStringsDOSCDSpanish };
+
+static const char *const k3VqaSubtitlesIntroDOSCDSpanish[] = {
+	""// TODO
+};
+
+static const StringListProvider k3VqaSubtitlesIntroDOSCDSpanishProvider = { ARRAYSIZE(k3VqaSubtitlesIntroDOSCDSpanish), k3VqaSubtitlesIntroDOSCDSpanish };
+
+static const char *const k3VqaSubtitlesBoatDOSCDSpanish[] = {
+	""// TODO
+};
+
+static const StringListProvider k3VqaSubtitlesBoatDOSCDSpanishProvider = { ARRAYSIZE(k3VqaSubtitlesBoatDOSCDSpanish), k3VqaSubtitlesBoatDOSCDSpanish };
diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat
index a7d577f17c..e139290557 100644
Binary files a/dists/engine-data/kyra.dat and b/dists/engine-data/kyra.dat differ
diff --git a/engines/kyra/detection.h b/engines/kyra/detection.h
index a1e94410dd..f2e4ed9d7f 100644
--- a/engines/kyra/detection.h
+++ b/engines/kyra/detection.h
@@ -54,6 +54,7 @@ struct GameFlags {
 	bool useHiColorMode       : 1;
 	bool useDigSound          : 1;
 	bool useInstallerPackage  : 1;
+	bool hasExtraLanguage     : 1;
 
 	byte gameID;
 };
diff --git a/engines/kyra/detection_tables.h b/engines/kyra/detection_tables.h
index ece5dbb9c8..36c811f43d 100644
--- a/engines/kyra/detection_tables.h
+++ b/engines/kyra/detection_tables.h
@@ -22,49 +22,51 @@
 
 namespace {
 
-#define FLAGS(x, y, z, a, b, c, d, e, f, id) { Common::UNK_LANG, Common::UNK_LANG, Common::UNK_LANG, Common::kPlatformUnknown, x, y, z, a, b, c, d, e, f, id }
-#define FLAGS_FAN(fanLang, repLang, x, y, z, a, b, c, d, e, f, id) { Common::UNK_LANG, fanLang, repLang, Common::kPlatformUnknown, x, y, z, a, b, c, d, e, f, id }
-
-#define KYRA1_FLOPPY_FLAGS FLAGS(false, false, false, false, false, false, false, false, false, Kyra::GI_KYRA1)
-#define KYRA1_FLOPPY_CMP_FLAGS FLAGS(false, false, false, false, false, false, false, false, true, Kyra::GI_KYRA1)
-#define KYRA1_OLDFLOPPY_FLAGS FLAGS(false, false, false, true, false, false, false, false, false, Kyra::GI_KYRA1)
-#define KYRA1_AMIGA_FLAGS FLAGS(false, false, false, false, false, false, false, false, false, Kyra::GI_KYRA1)
-#define KYRA1_TOWNS_FLAGS FLAGS(false, true, false, false, false, false, false, false, false, Kyra::GI_KYRA1)
-#define KYRA1_TOWNS_SJIS_FLAGS FLAGS(false, true, false, false, true, false, false, false, false, Kyra::GI_KYRA1)
-#define KYRA1_CD_FLAGS FLAGS(false, true, true, false, false, false, false, false, false, Kyra::GI_KYRA1)
-#define KYRA1_CD_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, true, true, false, false, false, false, false, false, Kyra::GI_KYRA1)
-#define KYRA1_DEMO_FLAGS FLAGS(true, false, false, false, false, false, false, false, false, Kyra::GI_KYRA1)
-#define KYRA1_DEMO_CD_FLAGS FLAGS(true, true, true, false, false, false, false, false, false, Kyra::GI_KYRA1)
-
-#define KYRA2_FLOPPY_FLAGS FLAGS(false, false, false, false, false, false, false, false, false, Kyra::GI_KYRA2)
-#define KYRA2_FLOPPY_CMP_FLAGS FLAGS(false, false, false, false, false, false, false, false, true, Kyra::GI_KYRA2)
-#define KYRA2_FLOPPY_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, false, false, false, false, false, false, false, Kyra::GI_KYRA2)
-#define KYRA2_CD_FLAGS FLAGS(false, false, true, false, false, false, false, false, false, Kyra::GI_KYRA2)
-#define KYRA2_CD_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, true, false, false, false, false, false, false, Kyra::GI_KYRA2)
-#define KYRA2_CD_DEMO_FLAGS FLAGS(true, false, true, false, false, false, false, false, false, Kyra::GI_KYRA2)
-#define KYRA2_DEMO_FLAGS FLAGS(true, false, false, false, false, false, false, false, false, Kyra::GI_KYRA2)
-#define KYRA2_TOWNS_FLAGS FLAGS(false, false, false, false, false, false, false, false, false, Kyra::GI_KYRA2)
-#define KYRA2_TOWNS_SJIS_FLAGS FLAGS(false, false, false, false, true, false, false, false, false, Kyra::GI_KYRA2)
-
-#define KYRA3_CD_FLAGS FLAGS(false, false, true, false, false, false, false, true, true, Kyra::GI_KYRA3)
-#define KYRA3_CD_INS_FLAGS FLAGS(false, false, true, false, false, false, false, true, false, Kyra::GI_KYRA3)
-#define KYRA3_CD_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, true, false, false, false, false, true, false, Kyra::GI_KYRA3)
-
-#define LOL_CD_FLAGS FLAGS(false, false, true, false, false, false, false, false, false, Kyra::GI_LOL)
-#define LOL_CD_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, true, false, false, false, false, false, false, Kyra::GI_LOL)
-#define LOL_FLOPPY_FLAGS FLAGS(false, false, false, false, false, false, false, false, false, Kyra::GI_LOL)
-#define LOL_FLOPPY_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, false, false, false, false, false, false, false, Kyra::GI_LOL)
-#define LOL_FLOPPY_CMP_FLAGS FLAGS(false, false, false, false, false, false, false, false, true, Kyra::GI_LOL)
-#define LOL_PC9801_FLAGS FLAGS(false, false, false, false, true, true, false, false, false, Kyra::GI_LOL)
-#define LOL_FMTOWNS_FLAGS FLAGS(false, false, false, false, true, false, false, false, false, Kyra::GI_LOL)
-#define LOL_DEMO_FLAGS FLAGS(true, true, false, false, false, false, false, false, false, Kyra::GI_LOL)
-#define LOL_KYRA2_DEMO_FLAGS FLAGS(true, false, false, false, false, false, false, false, false, Kyra::GI_KYRA2)
-
-#define EOB_FLAGS FLAGS(false, false, false, false, false, false, false, false, false, Kyra::GI_EOB1)
-#define EOB_SPANISH_FLAGS FLAGS(false, false, false, true, false, false, false, false, false, Kyra::GI_EOB1)
-#define EOB_PC98_FLAGS FLAGS(false, false, false, false, true, true, false, false, false, Kyra::GI_EOB1)
-#define EOB2_FLAGS FLAGS(false, false, false, false, false, false, false, false, false, Kyra::GI_EOB2)
-#define EOB2_FMTOWNS_FLAGS FLAGS(false, false, false, false, true, false, true, false, false, Kyra::GI_EOB2)
+#define FLAGS(x, y, z, a, b, c, d, e, f, g, id) { Common::UNK_LANG, Common::UNK_LANG, Common::UNK_LANG, Common::kPlatformUnknown, x, y, z, a, b, c, d, e, f, g, id }
+#define FLAGS_FAN(fanLang, repLang, x, y, z, a, b, c, d, e, f, g, id) { Common::UNK_LANG, fanLang, repLang, Common::kPlatformUnknown, x, y, z, a, b, c, d, e, f, g, id }
+
+#define KYRA1_FLOPPY_FLAGS FLAGS(false, false, false, false, false, false, false, false, false, false, Kyra::GI_KYRA1)
+#define KYRA1_FLOPPY_CMP_FLAGS FLAGS(false, false, false, false, false, false, false, false, true, false, Kyra::GI_KYRA1)
+#define KYRA1_OLDFLOPPY_FLAGS FLAGS(false, false, false, true, false, false, false, false, false, false, Kyra::GI_KYRA1)
+#define KYRA1_AMIGA_FLAGS FLAGS(false, false, false, false, false, false, false, false, false, false, Kyra::GI_KYRA1)
+#define KYRA1_TOWNS_FLAGS FLAGS(false, true, false, false, false, false, false, false, false, false, Kyra::GI_KYRA1)
+#define KYRA1_TOWNS_SJIS_FLAGS FLAGS(false, true, false, false, true, false, false, false, false, false, Kyra::GI_KYRA1)
+#define KYRA1_CD_FLAGS FLAGS(false, true, true, false, false, false, false, false, false, false, Kyra::GI_KYRA1)
+#define KYRA1_CD_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, true, true, false, false, false, false, false, false, false, Kyra::GI_KYRA1)
+#define KYRA1_DEMO_FLAGS FLAGS(true, false, false, false, false, false, false, false, false, false, Kyra::GI_KYRA1)
+#define KYRA1_DEMO_CD_FLAGS FLAGS(true, true, true, false, false, false, false, false, false, false, Kyra::GI_KYRA1)
+
+#define KYRA2_FLOPPY_FLAGS FLAGS(false, false, false, false, false, false, false, false, false, false, Kyra::GI_KYRA2)
+#define KYRA2_FLOPPY_CMP_FLAGS FLAGS(false, false, false, false, false, false, false, false, true, false, Kyra::GI_KYRA2)
+#define KYRA2_FLOPPY_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, false, false, false, false, false, false, false, false, Kyra::GI_KYRA2)
+#define KYRA2_CD_FLAGS FLAGS(false, false, true, false, false, false, false, false, false, false, Kyra::GI_KYRA2)
+#define KYRA2_CD_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, true, false, false, false, false, false, false, false, Kyra::GI_KYRA2)
+#define KYRA2_CD_DEMO_FLAGS FLAGS(true, false, true, false, false, false, false, false, false, false, Kyra::GI_KYRA2)
+#define KYRA2_DEMO_FLAGS FLAGS(true, false, false, false, false, false, false, false, false, false, Kyra::GI_KYRA2)
+#define KYRA2_TOWNS_FLAGS FLAGS(false, false, false, false, false, false, false, false, false, false, Kyra::GI_KYRA2)
+#define KYRA2_TOWNS_SJIS_FLAGS FLAGS(false, false, false, false, true, false, false, false, false, false, Kyra::GI_KYRA2)
+
+#define KYRA3_CD_FLAGS FLAGS(false, false, true, false, false, false, false, true, true, false, Kyra::GI_KYRA3)
+#define KYRA3_CD_INS_FLAGS FLAGS(false, false, true, false, false, false, false, true, false, false, Kyra::GI_KYRA3)
+#define KYRA3_CD_4LANG_FLAGS FLAGS(false, false, true, false, false, false, false, true, true, true, Kyra::GI_KYRA3)
+#define KYRA3_CD_INS_4LANG_FLAGS FLAGS(false, false, true, false, false, false, false, true, false, true, Kyra::GI_KYRA3)
+#define KYRA3_CD_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, true, false, false, false, false, true, false, false, Kyra::GI_KYRA3)
+
+#define LOL_CD_FLAGS FLAGS(false, false, true, false, false, false, false, false, false, false, Kyra::GI_LOL)
+#define LOL_CD_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, true, false, false, false, false, false, false, false, Kyra::GI_LOL)
+#define LOL_FLOPPY_FLAGS FLAGS(false, false, false, false, false, false, false, false, false, false, Kyra::GI_LOL)
+#define LOL_FLOPPY_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, false, false, false, false, false, false, false, false, Kyra::GI_LOL)
+#define LOL_FLOPPY_CMP_FLAGS FLAGS(false, false, false, false, false, false, false, false, true, false, Kyra::GI_LOL)
+#define LOL_PC9801_FLAGS FLAGS(false, false, false, false, true, true, false, false, false, false, Kyra::GI_LOL)
+#define LOL_FMTOWNS_FLAGS FLAGS(false, false, false, false, true, false, false, false, false, false, Kyra::GI_LOL)
+#define LOL_DEMO_FLAGS FLAGS(true, true, false, false, false, false, false, false, false, false, Kyra::GI_LOL)
+#define LOL_KYRA2_DEMO_FLAGS FLAGS(true, false, false, false, false, false, false, false, false, false, Kyra::GI_KYRA2)
+
+#define EOB_FLAGS FLAGS(false, false, false, false, false, false, false, false, false, false, Kyra::GI_EOB1)
+#define EOB_SPANISH_FLAGS FLAGS(false, false, false, true, false, false, false, false, false, false, Kyra::GI_EOB1)
+#define EOB_PC98_FLAGS FLAGS(false, false, false, false, true, true, false, false, false, false, Kyra::GI_EOB1)
+#define EOB2_FLAGS FLAGS(false, false, false, false, false, false, false, false, false, false, Kyra::GI_EOB2)
+#define EOB2_FMTOWNS_FLAGS FLAGS(false, false, false, false, true, false, true, false, false, false, Kyra::GI_EOB2)
 
 #define GAMEOPTION_KYRA3_AUDIENCE GUIO_GAMEOPTIONS1
 #define GAMEOPTION_KYRA3_SKIP     GUIO_GAMEOPTIONS2
@@ -950,19 +952,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA3_CD_FLAGS
 	},
-	{ // Provided by AquariumTroop. Bugreport #11934
-		{
-			"kyra3",
-			_s("Missing game code"), // Reason for being unsupported
-			AD_ENTRY2s("ONETIME.PAK", "93b4ca2847ab7cfe52188cbde2ffe561", 485162,
-					   "WESTWOOD.001", "c782e09a3b80510962af1426acf5a130", 10426962),
-			Common::ZH_CNA,
-			Common::kPlatformDOS,
-			ADGF_DROPLANGUAGE | ADGF_UNSUPPORTED,
-			GUIO5(GUIO_NOMIDI, GUIO_RENDERVGA, GAMEOPTION_KYRA3_AUDIENCE, GAMEOPTION_KYRA3_SKIP, GAMEOPTION_KYRA3_HELIUM)
-		},
-		KYRA3_CD_FLAGS
-	},
+
 	{ // Provided by AquariumTroop. Bugreport #11935
 		{
 			"kyra3",
@@ -1157,6 +1147,126 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA3_CD_FAN_FLAGS(Common::RU_RUS, Common::DE_DEU)
 	},
+	{ // non installed version
+		{
+			"kyra3",
+			0,
+			AD_ENTRY2s("ONETIME.PAK", "93b4ca2847ab7cfe52188cbde2ffe561", -1,
+					   "WESTWOOD.001", "c782e09a3b80510962af1426acf5a130", -1),
+			Common::ZH_CNA,
+			Common::kPlatformDOS,
+			ADGF_DROPLANGUAGE,
+			GUIO5(GUIO_NOMIDI, GUIO_RENDERVGA, GAMEOPTION_KYRA3_AUDIENCE, GAMEOPTION_KYRA3_SKIP, GAMEOPTION_KYRA3_HELIUM)
+		},
+		KYRA3_CD_4LANG_FLAGS
+	},
+	{
+		{
+			"kyra3",
+			0,
+			AD_ENTRY2s("ONETIME.PAK", "93b4ca2847ab7cfe52188cbde2ffe561", -1,
+					   "WESTWOOD.001", "c782e09a3b80510962af1426acf5a130", -1),
+			Common::EN_ANY,
+			Common::kPlatformDOS,
+			ADGF_DROPLANGUAGE,
+			GUIO5(GUIO_NOMIDI, GUIO_RENDERVGA, GAMEOPTION_KYRA3_AUDIENCE, GAMEOPTION_KYRA3_SKIP, GAMEOPTION_KYRA3_HELIUM)
+		},
+		KYRA3_CD_4LANG_FLAGS
+	},
+	{
+		{
+			"kyra3",
+			0,
+			AD_ENTRY2s("ONETIME.PAK", "93b4ca2847ab7cfe52188cbde2ffe561", -1,
+					   "WESTWOOD.001", "c782e09a3b80510962af1426acf5a130", -1),
+			Common::FR_FRA,
+			Common::kPlatformDOS,
+			ADGF_DROPLANGUAGE,
+			GUIO5(GUIO_NOMIDI, GUIO_RENDERVGA, GAMEOPTION_KYRA3_AUDIENCE, GAMEOPTION_KYRA3_SKIP, GAMEOPTION_KYRA3_HELIUM)
+		},
+		KYRA3_CD_4LANG_FLAGS
+	},
+	{
+		{
+			"kyra3",
+			0,
+			AD_ENTRY2s("ONETIME.PAK", "93b4ca2847ab7cfe52188cbde2ffe561", -1,
+					   "WESTWOOD.001", "c782e09a3b80510962af1426acf5a130", -1),
+			Common::DE_DEU,
+			Common::kPlatformDOS,
+			ADGF_DROPLANGUAGE,
+			GUIO5(GUIO_NOMIDI, GUIO_RENDERVGA, GAMEOPTION_KYRA3_AUDIENCE, GAMEOPTION_KYRA3_SKIP, GAMEOPTION_KYRA3_HELIUM)
+		},
+		KYRA3_CD_4LANG_FLAGS
+	},
+	{ // installed version
+		{
+			"kyra3",
+			0,
+			{
+				{ "ONETIME.PAK", 0, "93b4ca2847ab7cfe52188cbde2ffe561", -1 },
+				{ "MALCOLM.PAK", 0, "a31bd451f50f38b2bac9bebbca1d14cb", -1 },
+				{ "AUD.PAK", 0, 0, -1 },
+				AD_LISTEND
+			},
+			Common::ZH_CNA,
+			Common::kPlatformDOS,
+			ADGF_DROPLANGUAGE,
+			GUIO5(GUIO_NOMIDI, GUIO_RENDERVGA, GAMEOPTION_KYRA3_AUDIENCE, GAMEOPTION_KYRA3_SKIP, GAMEOPTION_KYRA3_HELIUM)
+		},
+		KYRA3_CD_INS_4LANG_FLAGS
+	},
+	{
+		{
+			"kyra3",
+			0,
+			{
+				{ "ONETIME.PAK", 0, "93b4ca2847ab7cfe52188cbde2ffe561", -1 },
+				{ "MALCOLM.PAK", 0, "a31bd451f50f38b2bac9bebbca1d14cb", -1 },
+				{ "AUD.PAK", 0, 0, -1 },
+				AD_LISTEND
+			},
+			Common::EN_ANY,
+			Common::kPlatformDOS,
+			ADGF_DROPLANGUAGE,
+			GUIO5(GUIO_NOMIDI, GUIO_RENDERVGA, GAMEOPTION_KYRA3_AUDIENCE, GAMEOPTION_KYRA3_SKIP, GAMEOPTION_KYRA3_HELIUM)
+		},
+		KYRA3_CD_INS_4LANG_FLAGS
+	},
+	{
+		{
+			"kyra3",
+			0,
+			{
+				{ "ONETIME.PAK", 0, "93b4ca2847ab7cfe52188cbde2ffe561", -1 },
+				{ "MALCOLM.PAK", 0, "a31bd451f50f38b2bac9bebbca1d14cb", -1 },
+				{ "AUD.PAK", 0, 0, -1 },
+				AD_LISTEND
+			},
+			Common::FR_FRA,
+			Common::kPlatformDOS,
+			ADGF_DROPLANGUAGE,
+			GUIO5(GUIO_NOMIDI, GUIO_RENDERVGA, GAMEOPTION_KYRA3_AUDIENCE, GAMEOPTION_KYRA3_SKIP, GAMEOPTION_KYRA3_HELIUM)
+		},
+		KYRA3_CD_INS_4LANG_FLAGS
+	},
+	{
+		{
+			"kyra3",
+			0,
+			{
+				{ "ONETIME.PAK", 0, "93b4ca2847ab7cfe52188cbde2ffe561", -1 },
+				{ "MALCOLM.PAK", 0, "a31bd451f50f38b2bac9bebbca1d14cb", -1 },
+				{ "AUD.PAK", 0, 0, -1 },
+				AD_LISTEND
+			},
+			Common::DE_DEU,
+			Common::kPlatformDOS,
+			ADGF_DROPLANGUAGE,
+			GUIO5(GUIO_NOMIDI, GUIO_RENDERVGA, GAMEOPTION_KYRA3_AUDIENCE, GAMEOPTION_KYRA3_SKIP, GAMEOPTION_KYRA3_HELIUM)
+		},
+		KYRA3_CD_INS_4LANG_FLAGS
+	},
 
 	// Lands of Lore CD
 	{
diff --git a/engines/kyra/resource/resource.h b/engines/kyra/resource/resource.h
index 48eef32a4b..b51d50ffc9 100644
--- a/engines/kyra/resource/resource.h
+++ b/engines/kyra/resource/resource.h
@@ -258,6 +258,10 @@ enum KyraResources {
 	k3ItemAnimData,
 	k3ItemMagicTable,
 	k3ItemStringMap,
+	k3FontData,
+
+	k3VqaSubtitlesIntro,
+	k3VqaSubtitlesBoat,
 
 #if defined(ENABLE_EOB) || defined(ENABLE_LOL)
 	kRpgCommonMoreStrings,
diff --git a/engines/kyra/resource/resource_intern.cpp b/engines/kyra/resource/resource_intern.cpp
index 7fdfd178b6..502ac369e0 100644
--- a/engines/kyra/resource/resource_intern.cpp
+++ b/engines/kyra/resource/resource_intern.cpp
@@ -394,11 +394,11 @@ bool ResLoaderInsMalcolm::isLoadable(const Common::String &filename, Common::See
 	if (size + 7 > stream.size())
 		return false;
 
-	stream.seek(size + 5, SEEK_SET);
-	uint8 buffer[2];
-	stream.read(&buffer, 2);
+	stream.seek(size + 4, SEEK_SET);
+	uint8 buffer[3];
+	stream.read(&buffer, 3);
 
-	return (buffer[0] == 0x0D && buffer[1] == 0x0A);
+	return (buffer[0] == 0x0D && buffer[1] == 0x0A) || (buffer[1] == 0x0D && buffer[2] == 0x0A);
 }
 
 Common::Archive *ResLoaderInsMalcolm::load(Common::ArchiveMemberPtr memberFile, Common::SeekableReadStream &stream) const {
@@ -426,6 +426,7 @@ Common::Archive *ResLoaderInsMalcolm::load(Common::ArchiveMemberPtr memberFile,
 			++i;
 
 			filenames.push_back(temp);
+			temp.clear();
 		} else {
 			temp += (char)c;
 		}
diff --git a/engines/kyra/resource/staticres.cpp b/engines/kyra/resource/staticres.cpp
index 4da557a2b1..4b18feeed0 100644
--- a/engines/kyra/resource/staticres.cpp
+++ b/engines/kyra/resource/staticres.cpp
@@ -39,7 +39,7 @@
 
 namespace Kyra {
 
-#define RESFILE_VERSION 108
+#define RESFILE_VERSION 109
 
 namespace {
 bool checkKyraDat(Common::SeekableReadStream *file) {
@@ -95,6 +95,7 @@ const IndexTable iLanguageTable[] = {
 	{ Common::JA_JPN, 6 },
 	{ Common::RU_RUS, 7 },
 	{ Common::HE_ISR, 8 },
+	{ Common::ZH_CNA, 9 },
 	{ -1, -1 }
 };
 


Commit: 8cbe9489c0db66c19a004727f1f4f7a0ba9e2215
    https://github.com/scummvm/scummvm/commit/8cbe9489c0db66c19a004727f1f4f7a0ba9e2215
Author: athrxx (athrxx at scummvm.org)
Date: 2021-04-27T22:06:52+02:00

Commit Message:
KYRA: (MR/Chinese) - add support for 4th language in the options menu

The Chinese version still supports ENG/FRE/GER. It does not replace one of these languages like the fan translations usually do.

Changed paths:
    engines/kyra/engine/kyra_mr.cpp
    engines/kyra/engine/kyra_v2.cpp
    engines/kyra/engine/kyra_v2.h
    engines/kyra/gui/gui_hof.cpp
    engines/kyra/gui/gui_mr.cpp
    engines/kyra/resource/staticres.cpp


diff --git a/engines/kyra/engine/kyra_mr.cpp b/engines/kyra/engine/kyra_mr.cpp
index 50be26b3bf..519cde653c 100644
--- a/engines/kyra/engine/kyra_mr.cpp
+++ b/engines/kyra/engine/kyra_mr.cpp
@@ -1397,6 +1397,10 @@ void KyraEngine_MR::writeSettings() {
 		_flags.lang = Common::DE_DEU;
 		break;
 
+	case 3:
+		_flags.lang = Common::ZH_CNA;
+		break;
+
 	case 0:
 	default:
 		_flags.lang = Common::EN_ANY;
diff --git a/engines/kyra/engine/kyra_v2.cpp b/engines/kyra/engine/kyra_v2.cpp
index c9ee314001..ed21a66b8a 100644
--- a/engines/kyra/engine/kyra_v2.cpp
+++ b/engines/kyra/engine/kyra_v2.cpp
@@ -29,7 +29,7 @@
 
 namespace Kyra {
 
-KyraEngine_v2::KyraEngine_v2(OSystem *system, const GameFlags &flags, const EngineDesc &desc) : KyraEngine_v1(system, flags), _desc(desc) {
+KyraEngine_v2::KyraEngine_v2(OSystem *system, const GameFlags &flags, const EngineDesc &desc) : KyraEngine_v1(system, flags), _desc(desc), _numLang(flags.hasExtraLanguage ? 4 : 3) {
 	memset(&_sceneAnims, 0, sizeof(_sceneAnims));
 	memset(&_sceneAnimMovie, 0, sizeof(_sceneAnimMovie));
 
@@ -98,6 +98,7 @@ KyraEngine_v2::KyraEngine_v2(OSystem *system, const GameFlags &flags, const Engi
 		break;
 
 	case Common::JA_JPN:
+	case Common::ZH_CNA:
 		_lang = 3;
 		break;
 
diff --git a/engines/kyra/engine/kyra_v2.h b/engines/kyra/engine/kyra_v2.h
index 24f8fec572..36c2b6b963 100644
--- a/engines/kyra/engine/kyra_v2.h
+++ b/engines/kyra/engine/kyra_v2.h
@@ -93,6 +93,7 @@ protected:
 
 	// detection
 	int _lang;
+	const int _numLang;
 
 	// Input
 	virtual int inputSceneChange(int x, int y, int unk1, int unk2) = 0;
diff --git a/engines/kyra/gui/gui_hof.cpp b/engines/kyra/gui/gui_hof.cpp
index ec581a8ab0..0314c9b42c 100644
--- a/engines/kyra/gui/gui_hof.cpp
+++ b/engines/kyra/gui/gui_hof.cpp
@@ -984,7 +984,7 @@ int GUI_HoF::gameOptionsTalkie(Button *caller) {
 int GUI_HoF::changeLanguage(Button *caller) {
 	updateMenuButton(caller);
 	++_vm->_lang;
-	_vm->_lang %= 3;
+	_vm->_lang %= _vm->_numLang;
 	setupOptionsButtons();
 	renewHighlight(_gameOptions);
 	return 0;
diff --git a/engines/kyra/gui/gui_mr.cpp b/engines/kyra/gui/gui_mr.cpp
index a1ad7b1cdb..c960b90e6a 100644
--- a/engines/kyra/gui/gui_mr.cpp
+++ b/engines/kyra/gui/gui_mr.cpp
@@ -1408,7 +1408,7 @@ int GUI_MR::changeLanguage(Button *caller) {
 	updateMenuButton(caller);
 	if (!_vm->queryGameFlag(0x1B2)) {
 		++_vm->_lang;
-		_vm->_lang %= 3;
+		_vm->_lang %= _vm->_numLang;
 		setupOptionsButtons();
 		renewHighlight(_gameOptions);
 	}
diff --git a/engines/kyra/resource/staticres.cpp b/engines/kyra/resource/staticres.cpp
index 4b18feeed0..eea27d5c8c 100644
--- a/engines/kyra/resource/staticres.cpp
+++ b/engines/kyra/resource/staticres.cpp
@@ -1823,9 +1823,10 @@ const uint8 KyraEngine_HoF::_rainbowRoomData[] = {
 const char *const KyraEngine_MR::_languageExtension[] = {
 	"TRE",
 	"TRF",
-	"TRG"/*,
-	"TRI",      Italian and Spanish were never included, the supported fan translations are using
-	"TRS"       English/French extensions thus overwriting these languages */
+	"TRG",
+	"TRC"
+	// Italian, Spanish and Russian don't have dedicated language files. The supported fan translations
+	// use one of the existing extensions (English, French or German) thus overwriting that language. 
 };
 
 const int KyraEngine_MR::_languageExtensionSize = ARRAYSIZE(KyraEngine_MR::_languageExtension);


Commit: 94d5cea3b588a9a96971fad074211b04187b8701
    https://github.com/scummvm/scummvm/commit/94d5cea3b588a9a96971fad074211b04187b8701
Author: athrxx (athrxx at scummvm.org)
Date: 2021-04-27T22:07:06+02:00

Commit Message:
KYRA: (MR/Chinese) - Chinese font drawing + main menu fixes

Things kind of work now, but many specific tweaks (font shading) still need to be added.

Changed paths:
    engines/kyra/engine/kyra_mr.cpp
    engines/kyra/engine/kyra_mr.h
    engines/kyra/graphics/screen.cpp
    engines/kyra/graphics/screen.h
    engines/kyra/graphics/screen_mr.cpp
    engines/kyra/gui/gui_mr.cpp
    engines/kyra/gui/gui_v1.cpp
    engines/kyra/resource/staticres.cpp
    engines/kyra/text/text_mr.cpp


diff --git a/engines/kyra/engine/kyra_mr.cpp b/engines/kyra/engine/kyra_mr.cpp
index 519cde653c..74231b1665 100644
--- a/engines/kyra/engine/kyra_mr.cpp
+++ b/engines/kyra/engine/kyra_mr.cpp
@@ -222,6 +222,16 @@ Common::Error KyraEngine_MR::init() {
 	_screen->loadFont(Screen::FID_8_FNT, "8FAT.FNT");
 	_screen->loadFont(Screen::FID_BOOKFONT_FNT, "BOOKFONT.FNT");
 	_screen->setFont(Screen::FID_8_FNT);
+
+	if (_flags.hasExtraLanguage) {
+		// We don't check the language setting here, since we want to load the file even if the language is currently set to English, French or German.
+		if (_res->exists("MALCOLM.PAK")) {
+			_screen->loadFont(Screen::FID_CHINESE_FNT, "MALCOLM.PAK");
+			_screen->setFont(Screen::FID_CHINESE_FNT);
+			_screen->_lineSpacing = 4;
+		}
+	}
+
 	_screen->setAnimBlockPtr(3500);
 	_screen->setScreenDim(0);
 
@@ -282,7 +292,7 @@ Common::Error KyraEngine_MR::go() {
 
 		_eventList.clear();
 
-		switch (_menu->handle(3)) {
+		switch (_menu->handle((_flags.hasExtraLanguage && _lang == 3) ? 4 : 3)) {
 		case 2:
 			_menuDirectlyToLoad = true;
 			// fall through
@@ -330,20 +340,12 @@ void KyraEngine_MR::initMainMenu() {
 
 	_menu = new MainMenu(this);
 	MainMenu::StaticData data = {
-		{ _mainMenuStrings[_lang*4+0], _mainMenuStrings[_lang*4+1], _mainMenuStrings[_lang*4+2], _mainMenuStrings[_lang*4+3], 0 },
+		{ _mainMenuStrings[0], _mainMenuStrings[1], _mainMenuStrings[2], _mainMenuStrings[3], 0 },
 		{ 0x01, 0x04, 0x0C, 0x04, 0x00, 0x80, 0xFF },
 		{ 0x16, 0x19, 0x1A, 0x16 },
-		Screen::FID_8_FNT, 240
+		_flags.hasExtraLanguage && _lang == 3 ? Screen::FID_CHINESE_FNT : Screen::FID_8_FNT, 240
 	};
 
-	if (_flags.lang == Common::ES_ESP) {
-		for (int i = 0; i < 4; ++i)
-			data.strings[i] = _mainMenuSpanishFan[i];
-	} else if (_flags.lang == Common::IT_ITA) {
-		for (int i = 0; i < 4; ++i)
-			data.strings[i] = _mainMenuItalianFan[i];
-	}
-
 	MainMenu::Animation anim;
 	anim.anim = _menuAnim;
 	anim.startFrame = 29;
@@ -516,7 +518,7 @@ void KyraEngine_MR::startup() {
 	_interface = new uint8[17920];
 	_interfaceCommandLine = new uint8[3840];
 
-	_screen->setFont(Screen::FID_8_FNT);
+	_screen->setFont((_flags.hasExtraLanguage && _lang == 3) ? Screen::FID_CHINESE_FNT : Screen::FID_8_FNT);
 
 	_stringBuffer = new char[500];
 	allocAnimObjects(1, 16, 50);
diff --git a/engines/kyra/engine/kyra_mr.h b/engines/kyra/engine/kyra_mr.h
index 32c1e06f2f..ecb81bf0d0 100644
--- a/engines/kyra/engine/kyra_mr.h
+++ b/engines/kyra/engine/kyra_mr.h
@@ -185,9 +185,6 @@ private:
 	const char *const *_mainMenuStrings;
 	int _mainMenuStringsSize;
 
-	static const char *const _mainMenuSpanishFan[];
-	static const char *const _mainMenuItalianFan[];
-
 	// animator
 	uint8 *_gamePlayBuffer;
 	void restorePage3() override;
diff --git a/engines/kyra/graphics/screen.cpp b/engines/kyra/graphics/screen.cpp
index 4f8094e783..f299fd3924 100644
--- a/engines/kyra/graphics/screen.cpp
+++ b/engines/kyra/graphics/screen.cpp
@@ -1335,10 +1335,13 @@ bool Screen::loadFont(FontId fontId, const char *filename) {
 	}
 
 	Font *&fnt = _fonts[fontId];
+	int temp = 0;
 
 	if (!fnt) {
 		if (_vm->game() == GI_KYRA1 && _isAmiga)
 			fnt = new AMIGAFont();
+		else if (_vm->game() == GI_KYRA3 && fontId == FID_CHINESE_FNT)
+			fnt = new Big5Font(_vm->staticres()->loadRawData(k3FontData, temp), SCREEN_W);
 		else
 			fnt = new DOSFont();
 
@@ -1373,7 +1376,7 @@ int Screen::getFontWidth() const {
 
 int Screen::getCharWidth(uint16 c) const {
 	const int width = _fonts[_currentFont]->getCharWidth(c);
-	return width + ((_currentFont != FID_SJIS_FNT && _currentFont != FID_SJIS_LARGE_FNT && _currentFont != FID_SJIS_SMALL_FNT) ? _charSpacing : 0);
+	return width + (_isSegaCD || _fonts[_currentFont]->getType() == Font::kASCII ? _charSpacing : 0);
 }
 
 int Screen::getCharHeight(uint16 c) const {
@@ -1486,7 +1489,7 @@ uint16 Screen::fetchChar(const char *&s) const {
 
 	uint16 ch = (uint8)*s++;
 
-	if (ch <= 0x7F || (ch >= 0xA1 && ch <= 0xDF))
+	if ((_fonts[_currentFont]->getType() == Font::kSJIS && (ch <= 0x7F || (ch >= 0xA1 && ch <= 0xDF))) || (_fonts[_currentFont]->getType() == Font::kBIG5 && ch < 0x7F))
 		return ch;
 
 	ch |= (uint8)(*s++) << 8;
diff --git a/engines/kyra/graphics/screen.h b/engines/kyra/graphics/screen.h
index 7b1a8170c4..b6e2904242 100644
--- a/engines/kyra/graphics/screen.h
+++ b/engines/kyra/graphics/screen.h
@@ -67,7 +67,8 @@ public:
 	 */
 	enum Type {
 		kASCII = 0,
-		kSJIS
+		kSJIS,
+		kBIG5
 	};
 
 public:
@@ -123,11 +124,12 @@ public:
 	enum FontStyle {
 		kStyleNone			=	0,
 		kStyleLeftShadow	=	1	<<	0,
-		kStyleFat			=	1	<<	1,
-		kStyleNarrow1		=	1	<<	2,
-		kStyleNarrow2		=	1	<<	3,
-		kStyleFullWidth		=	1	<<	4,
-		kStyleForceOneByte	=	1	<<	5
+		kStyleRightShadow	=	1	<<	1,
+		kStyleFat			=	1	<<	2,
+		kStyleNarrow1		=	1	<<	3,
+		kStyleNarrow2		=	1	<<	4,
+		kStyleFullWidth		=	1	<<	5,
+		kStyleForceOneByte	=	1	<<	6
 	};
 
 	/**
@@ -253,6 +255,30 @@ private:
 	const int _sjisWidthOffset;
 };
 
+class Big5Font : public Font {
+public:
+	Big5Font(const uint8 *oneByteData, int pitch);
+	~Big5Font() override;
+
+	Type getType() const override { return kBIG5; }
+
+	bool load(Common::SeekableReadStream &data) override;
+	int getHeight() const override { return 14; }
+	int getWidth() const override { return 18; }
+	int getCharWidth(uint16 c) const override;
+	void setColorMap(const uint8 *src) override { _colorMap = src; }
+	void setStyles(int styles) override { _shadowMode = (styles & kStyleRightShadow); }
+	void drawChar(uint16 c, byte *dst, int pitch, int) const override;
+
+private:
+	const uint8 *_oneByteData;
+	const uint8 *_twoByteData;
+	uint32 _twoByteDataSize;
+	const uint8 *_colorMap;
+	const uint16 _pitch;
+	bool _shadowMode;
+};
+
 /**
  * A class that manages KYRA palettes.
  *
@@ -421,6 +447,7 @@ public:
 		FID_SJIS_TEXTMODE_FNT,
 		FID_SJIS_LARGE_FNT,
 		FID_SJIS_SMALL_FNT,
+		FID_CHINESE_FNT,
 		FID_NUM
 	};
 
diff --git a/engines/kyra/graphics/screen_mr.cpp b/engines/kyra/graphics/screen_mr.cpp
index c83ce9dd31..e573902d36 100644
--- a/engines/kyra/graphics/screen_mr.cpp
+++ b/engines/kyra/graphics/screen_mr.cpp
@@ -131,4 +131,71 @@ void Screen_MR::drawFilledBox(int x1, int y1, int x2, int y2, uint8 c1, uint8 c2
 	drawClippedLine(x1, y2-1, x2-1, y2-1, c3);
 }
 
+Big5Font::Big5Font(const uint8 *oneByteData, int pitch) : Font(), _oneByteData(oneByteData), _twoByteData(0), _twoByteDataSize(0), _pitch(pitch), _shadowMode(false) {
+	assert(_oneByteData);
+}
+
+Big5Font::~Big5Font() {
+	delete[] _twoByteData;
+}
+
+bool Big5Font::load(Common::SeekableReadStream &data) {
+	delete[] _twoByteData;
+	_twoByteData = 0;
+
+	if (!data.size())
+		return false;
+
+	_twoByteDataSize = data.size();
+	uint8 *dst = new uint8[_twoByteDataSize];
+	if (!dst)
+		return false;
+
+	data.read(dst, _twoByteDataSize);
+	_twoByteData = dst;
+
+	return true;
+}
+
+int Big5Font::getCharWidth(uint16 c) const {
+	return (c & 0x80) ? 18 : 9;
+}
+
+void Big5Font::drawChar(uint16 c, byte *dst, int pitch, int) const {
+	static const int16 shadowParam[13] = { 1, 0, 0, 0, 1, 0, 1, 2, 0, 0, 0, 1, -1 };
+	const uint8 *glyphData = &_oneByteData[(c & 0x7F) * 14];
+	int w = 7;
+
+	if (c == 0x6187) {
+		glyphData = &_oneByteData[128];
+	} else if (c & 0x80) {
+		c = ((c & 0x7F00) >> 2) | (c & 0x3F);
+		assert(c * 28 < _twoByteDataSize);
+		glyphData = &_twoByteData[c * 28];
+		w = 15;
+	}
+
+	for (const int16 *i = (_shadowMode ? shadowParam : shadowParam + 9); *i != -1; i += 3) {
+		const uint8 *data = glyphData;
+		uint8 *dst3 = dst;
+		dst = &dst3[i[0] + i[1] * _pitch];
+		for (int h = 0; h < 14; ++h) {
+			uint8 in = 0;
+			int bt = -1;
+			uint8 *dst2 = dst;
+			for (int x = 0; x < w; ++x) {
+				if (bt == -1) {
+					in = *data++;
+					bt = 7;
+				}
+				if (in & (1 << (bt--)))
+					*dst = _colorMap[i[2]];
+				dst++;
+			}
+			dst = dst2 + _pitch;
+		}
+		dst = dst3;
+	}
+}
+
 } // End of namespace Kyra
diff --git a/engines/kyra/gui/gui_mr.cpp b/engines/kyra/gui/gui_mr.cpp
index c960b90e6a..8127e82b7e 100644
--- a/engines/kyra/gui/gui_mr.cpp
+++ b/engines/kyra/gui/gui_mr.cpp
@@ -308,7 +308,7 @@ void KyraEngine_MR::drawMalcolmsMoodText() {
 
 	const char *string = (const char *)getTableEntry(_cCodeFile, stringId[_malcolmsMood]);
 
-	Screen::FontId oldFont = _screen->setFont(Screen::FID_8_FNT);
+	Screen::FontId oldFont = _screen->setFont((_flags.hasExtraLanguage && _lang == 3) ? Screen::FID_CHINESE_FNT : Screen::FID_8_FNT);
 	_screen->_charSpacing = -2;
 
 	int width = _screen->getTextWidth(string);
diff --git a/engines/kyra/gui/gui_v1.cpp b/engines/kyra/gui/gui_v1.cpp
index f322e30a00..5dc7a387f7 100644
--- a/engines/kyra/gui/gui_v1.cpp
+++ b/engines/kyra/gui/gui_v1.cpp
@@ -511,6 +511,8 @@ int MainMenu::handle(int dim) {
 	int fh = _screen->getFontHeight();
 	if (_vm->gameFlags().lang == Common::JA_JPN)
 		fh++;
+	else if (_vm->gameFlags().hasExtraLanguage && _vm->gameFlags().lang == Common::ZH_CNA)
+		fh--;
 
 	int textPos = ((_screen->_curDim->w >> 1) + _screen->_curDim->sx) << 3;
 
@@ -563,6 +565,8 @@ void MainMenu::draw(int select) {
 	int fh = _screen->getFontHeight();
 	if (_vm->gameFlags().lang == Common::JA_JPN)
 		fh++;
+	else if (_vm->gameFlags().hasExtraLanguage && _vm->gameFlags().lang == Common::ZH_CNA)
+		fh--;
 
 	for (int i = 0; i < _static.menuTable[3]; ++i) {
 		int curY = top + i * fh;
diff --git a/engines/kyra/resource/staticres.cpp b/engines/kyra/resource/staticres.cpp
index eea27d5c8c..1908b5dc4a 100644
--- a/engines/kyra/resource/staticres.cpp
+++ b/engines/kyra/resource/staticres.cpp
@@ -1079,7 +1079,8 @@ const ScreenDim Screen_MR::_screenDimTable[] = {
 	{ 0x00, 0x00, 0x28, 0xC8, 0xFF, 0xF0, 0x00, 0x00 },
 	{ 0x08, 0x48, 0x18, 0x38, 0xFF, 0xF0, 0x00, 0x00 },
 	{ 0x00, 0x00, 0x28, 0xBC, 0xFF, 0xF0, 0x00, 0x00 },
-	{ 0x0A, 0x96, 0x14, 0x30, 0x19, 0xF0, 0x00, 0x00 }
+	{ 0x0A, 0x96, 0x14, 0x30, 0x19, 0xF0, 0x00, 0x00 },
+	{ 0x0A, 0x8E, 0x14, 0x3A, 0x19, 0xF0, 0x00, 0x00 }
 };
 
 const int Screen_MR::_screenDimTableCount = ARRAYSIZE(Screen_MR::_screenDimTable);
@@ -1831,20 +1832,6 @@ const char *const KyraEngine_MR::_languageExtension[] = {
 
 const int KyraEngine_MR::_languageExtensionSize = ARRAYSIZE(KyraEngine_MR::_languageExtension);
 
-const char *const KyraEngine_MR::_mainMenuSpanishFan[] = {
-	"Nueva Partida",
-	"Ver Intro",
-	"Restaurar",
-	"Finalizar"
-};
-
-const char *const KyraEngine_MR::_mainMenuItalianFan[] = {
-	"Nuova Partita",
-	"Introduzione",
-	"Carica una partita",
-	"Esci dal gioco"
-};
-
 const KyraEngine_MR::ShapeDesc KyraEngine_MR::_shapeDescs[] = {
 	{ 57, 91, -31, -82 },
 	{ 57, 91, -31, -82 },
diff --git a/engines/kyra/text/text_mr.cpp b/engines/kyra/text/text_mr.cpp
index 941e5f12a6..4da9eca889 100644
--- a/engines/kyra/text/text_mr.cpp
+++ b/engines/kyra/text/text_mr.cpp
@@ -44,40 +44,65 @@ char *TextDisplayer_MR::preprocessString(const char *str) {
 	}
 
 	p = _talkBuffer;
-	Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
-	_screen->_charSpacing = -2;
 
-	const int maxTextWidth = (_vm->language() == 0) ? 176 : 240;
-	int textWidth = _screen->getTextWidth(p);
-
-	if (textWidth > maxTextWidth) {
-		int count = 0, offs = 0;
-		if (textWidth > (3*maxTextWidth)) {
-			count = getCharLength(p, textWidth/4);
-			offs = dropCRIntoString(p, count, getCharLength(p, maxTextWidth));
-			p += count + offs;
-			// No update of textWidth here
+	if (_vm->gameFlags().hasExtraLanguage && _vm->_lang == 3) {
+		Screen::FontId curFont = _screen->setFont(Screen::FID_CHINESE_FNT);
+		int textLen = Common::strnlen(p, sizeof(_talkBuffer));
+		int maxTextWidth;
+
+		if (textLen > 68) {
+			maxTextWidth = ((textLen + 3) / 3) & ~1;
+			for (int i = textLen + 1; i >= maxTextWidth; --i)
+				p[i + 1] = p[i];
+			p[maxTextWidth] = '\r';
+			++p;
+			textLen -= maxTextWidth;
 		}
 
-		if (textWidth > (2*maxTextWidth)) {
-			count = getCharLength(p, textWidth/3);
-			offs = dropCRIntoString(p, count, getCharLength(p, maxTextWidth));
-			p += count + offs;
-			textWidth = _screen->getTextWidth(p);
+		if (textLen > 34) {
+			maxTextWidth = ((textLen + 2) / 2) & ~1;
+			for (int i = textLen + 1; i >= maxTextWidth; --i)
+				p[i + 1] = p[i];
+			p[maxTextWidth] = '\r';
 		}
 
-		count = getCharLength(p, textWidth/2);
-		offs = dropCRIntoString(p, count, getCharLength(p, maxTextWidth));
-		p += count + offs;
-		textWidth = _screen->getTextWidth(p);
+		_screen->setFont(curFont);
+	} else {
+		Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
+		_screen->_charSpacing = -2;
+
+		const int maxTextWidth = (_vm->language() == 0) ? 176 : 240;
+		int textWidth = _screen->getTextWidth(p);
 
 		if (textWidth > maxTextWidth) {
+			int count = 0, offs = 0;
+			if (textWidth > (3*maxTextWidth)) {
+				count = getCharLength(p, textWidth/4);
+				offs = dropCRIntoString(p, count, getCharLength(p, maxTextWidth));
+				p += count + offs;
+				// No update of textWidth here
+			}
+
+			if (textWidth > (2*maxTextWidth)) {
+				count = getCharLength(p, textWidth/3);
+				offs = dropCRIntoString(p, count, getCharLength(p, maxTextWidth));
+				p += count + offs;
+				textWidth = _screen->getTextWidth(p);
+			}
+
 			count = getCharLength(p, textWidth/2);
 			offs = dropCRIntoString(p, count, getCharLength(p, maxTextWidth));
+			p += count + offs;
+			textWidth = _screen->getTextWidth(p);
+
+			if (textWidth > maxTextWidth) {
+				count = getCharLength(p, textWidth/2);
+				offs = dropCRIntoString(p, count, getCharLength(p, maxTextWidth));
+			}
 		}
+		_screen->setFont(curFont);
 	}
 
-	_screen->setFont(curFont);
 	return _talkBuffer;
 }
 
@@ -137,7 +162,8 @@ void TextDisplayer_MR::printText(const Common::String &str, int x, int y, uint8
 	uint8 colorMap[] = { 0, 255, 240, 240 };
 	colorMap[3] = c1;
 	_screen->setTextColor(colorMap, 0, 3);
-	_screen->_charSpacing = -2;
+	if (!(_vm->gameFlags().hasExtraLanguage && _vm->gameFlags().lang == 3))
+		_screen->_charSpacing = -2;
 	_screen->printText(str.c_str(), x, y, c0, c2);
 	_screen->_charSpacing = 0;
 }
@@ -248,10 +274,10 @@ void KyraEngine_MR::objectChatInit(const char *str, int object, int vocHigh, int
 		xPos = _talkObjectList[object].x;
 	}
 
-	yPos -= lineNum * 10;
+	_text->_talkMessageH = lineNum * (_screen->getFontHeight() + _screen->_lineSpacing);
+	yPos -= _text->_talkMessageH;
 	yPos = MAX(yPos, 0);
 	_text->_talkMessageY = yPos;
-	_text->_talkMessageH = lineNum*10;
 
 	int width = _text->getWidestLineWidth(lineNum);
 	_text->calcWidestLineBounds(xPos, yPos, width, xPos);
@@ -287,8 +313,7 @@ void KyraEngine_MR::objectChatPrintText(const Common::String &str0, int object)
 
 	for (int i = 0; i < lineNum; ++i) {
 		str = Common::String(&_text->_talkSubstrings[i*_text->maxSubstringLen()]);
-
-		int y = _text->_talkMessageY + i * 10;
+		int y = _text->_talkMessageY + i * (_screen->getFontHeight() + _screen->_lineSpacing);
 		x = _text->getCenterStringX(str, cX1, cX2);
 
 		_text->printText(str, x, y, c1, 0xF0, 0);
@@ -525,10 +550,10 @@ void KyraEngine_MR::albumChatInit(const char *str, int object, int vocHigh, int
 		xPos = _talkObjectList[object].x;
 	}
 
-	yPos -= lineNum * 10;
+	_text->_talkMessageH = lineNum * (_screen->getFontHeight() + _screen->_lineSpacing);
+	yPos -= _text->_talkMessageH;
 	yPos = MAX(yPos, 0);
 	_text->_talkMessageY = yPos;
-	_text->_talkMessageH = lineNum*10;
 
 	int width = _text->getWidestLineWidth(lineNum);
 	_text->calcWidestLineBounds(xPos, yPos, width, xPos);


Commit: 897173cbacf9a1c905323cda7cc04c0ff24cf239
    https://github.com/scummvm/scummvm/commit/897173cbacf9a1c905323cda7cc04c0ff24cf239
Author: athrxx (athrxx at scummvm.org)
Date: 2021-04-27T22:07:24+02:00

Commit Message:
KYRA: (MR/Chinese) - more font related tweaks

(font shading and placement, interface adjustments, etc)

Changed paths:
    engines/kyra/engine/kyra_mr.cpp
    engines/kyra/engine/kyra_mr.h
    engines/kyra/engine/scene_mr.cpp
    engines/kyra/graphics/animator_mr.cpp
    engines/kyra/graphics/screen.h
    engines/kyra/graphics/screen_mr.cpp
    engines/kyra/graphics/screen_mr.h
    engines/kyra/gui/gui_mr.cpp
    engines/kyra/gui/gui_mr.h
    engines/kyra/gui/gui_v1.cpp
    engines/kyra/gui/gui_v2.cpp
    engines/kyra/script/script_mr.cpp
    engines/kyra/sequence/sequences_mr.cpp
    engines/kyra/text/text_mr.cpp


diff --git a/engines/kyra/engine/kyra_mr.cpp b/engines/kyra/engine/kyra_mr.cpp
index 74231b1665..2487dc0a28 100644
--- a/engines/kyra/engine/kyra_mr.cpp
+++ b/engines/kyra/engine/kyra_mr.cpp
@@ -62,6 +62,13 @@ KyraEngine_MR::KyraEngine_MR(OSystem *system, const GameFlags &flags) : KyraEngi
 	_itemFile = 0;
 	_gamePlayBuffer = 0;
 	_interface = _interfaceCommandLine = 0;
+	// The slightly larger interface is used in the Chinese version regardless of the actual language setting.
+	_interfaceCommandLineSize = flags.hasExtraLanguage ? 4800 : 3840;
+	_interfaceCommandLineH = _interfaceCommandLineSize / Screen::SCREEN_W;
+	_interfaceCommandLineY1 = Screen::SCREEN_H - _interfaceCommandLineH;
+	_interfaceCommandLineY2 = 156 - _interfaceCommandLineH;
+	_interfaceSize = flags.hasExtraLanguage ? 18880 : 17920;
+	_interfaceH = _interfaceSize / Screen::SCREEN_W;
 	_costPalBuffer = 0;
 	memset(_sceneShapes, 0, sizeof(_sceneShapes));
 	memset(_sceneAnimMovie, 0, sizeof(_sceneAnimMovie));
@@ -227,8 +234,10 @@ Common::Error KyraEngine_MR::init() {
 		// We don't check the language setting here, since we want to load the file even if the language is currently set to English, French or German.
 		if (_res->exists("MALCOLM.PAK")) {
 			_screen->loadFont(Screen::FID_CHINESE_FNT, "MALCOLM.PAK");
-			_screen->setFont(Screen::FID_CHINESE_FNT);
-			_screen->_lineSpacing = 4;
+			if (_lang == 3) {
+				_screen->setFont(Screen::FID_CHINESE_FNT);
+				_screen->_lineSpacing = 2;
+			}
 		}
 	}
 
@@ -292,7 +301,7 @@ Common::Error KyraEngine_MR::go() {
 
 		_eventList.clear();
 
-		switch (_menu->handle((_flags.hasExtraLanguage && _lang == 3) ? 4 : 3)) {
+		switch (_menu->handle(_lang == 3 ? 4 : 3)) {
 		case 2:
 			_menuDirectlyToLoad = true;
 			// fall through
@@ -343,7 +352,7 @@ void KyraEngine_MR::initMainMenu() {
 		{ _mainMenuStrings[0], _mainMenuStrings[1], _mainMenuStrings[2], _mainMenuStrings[3], 0 },
 		{ 0x01, 0x04, 0x0C, 0x04, 0x00, 0x80, 0xFF },
 		{ 0x16, 0x19, 0x1A, 0x16 },
-		_flags.hasExtraLanguage && _lang == 3 ? Screen::FID_CHINESE_FNT : Screen::FID_8_FNT, 240
+		_lang == 3 ? Screen::FID_CHINESE_FNT : Screen::FID_8_FNT, 240
 	};
 
 	MainMenu::Animation anim;
@@ -477,8 +486,15 @@ void KyraEngine_MR::playStudioSFX(const char *str) {
 		return;
 
 	const int strSize = strlen(str) - 1;
-	if (str[strSize] != '?' && str[strSize] != '!')
-		return;
+	if (_flags.lang == Common::ZH_CNA) {
+		// WORKAROUND: The studio sfx is broken in the original, since it still has the
+		// check for '!' and '?' even if the language is set to Chinese. I have fixed this here...
+		if (str[strSize] != '\x80' || !(str[strSize - 1] == '\x81' || str[strSize - 1] == '\x91'))
+			return;
+	} else {
+		if (str[strSize] != '?' && str[strSize] != '!')
+			return;
+	}
 
 	snd_playSoundEffect(_curStudioSFX++, 128);
 
@@ -515,10 +531,10 @@ void KyraEngine_MR::startup() {
 
 	_gamePlayBuffer = new uint8[64000];
 
-	_interface = new uint8[17920];
-	_interfaceCommandLine = new uint8[3840];
+	_interface = new uint8[_interfaceSize];
+	_interfaceCommandLine = new uint8[_interfaceCommandLineSize];
 
-	_screen->setFont((_flags.hasExtraLanguage && _lang == 3) ? Screen::FID_CHINESE_FNT : Screen::FID_8_FNT);
+	_screen->setFont(_lang == 3 ? Screen::FID_CHINESE_FNT : Screen::FID_8_FNT);
 
 	_stringBuffer = new char[500];
 	allocAnimObjects(1, 16, 50);
@@ -643,8 +659,8 @@ void KyraEngine_MR::loadInterfaceShapes() {
 
 void KyraEngine_MR::loadInterface() {
 	_screen->loadBitmap("INTRFACE.CPS", 3, 3, 0);
-	memcpy(_interface, _screen->getCPagePtr(3), 17920);
-	memcpy(_interfaceCommandLine, _screen->getCPagePtr(3), 3840);
+	memcpy(_interface, _screen->getCPagePtr(3), _interfaceSize);
+	memcpy(_interfaceCommandLine, _screen->getCPagePtr(3), _interfaceCommandLineSize);
 }
 
 void KyraEngine_MR::initItems() {
@@ -973,7 +989,7 @@ void KyraEngine_MR::handleInput(int x, int y) {
 	} else if (_itemInHand >= 0 && _savedMouseState >= 0) {
 		if (_itemInHand == 27) {
 			makeCharFacingMouse();
-		} else if (y <= 187) {
+		} else if (y < _interfaceCommandLineY1) {
 			if (_itemInHand == 43)
 				removeHandItem();
 			else
@@ -983,7 +999,7 @@ void KyraEngine_MR::handleInput(int x, int y) {
 	} else if (_savedMouseState == -3) {
 		return;
 	} else {
-		if (y > 187 && _savedMouseState > -4)
+		if (y >= _interfaceCommandLineY1 && _savedMouseState > -4)
 			return;
 		if (_unk5) {
 			_unk5 = 0;
@@ -1083,7 +1099,7 @@ void KyraEngine_MR::updateMouse() {
 	Common::Point mouse = getMousePos();
 	bool hasItemCollision = checkItemCollision(mouse.x, mouse.y) != -1;
 
-	if (mouse.y > 187) {
+	if (mouse.y >= _interfaceCommandLineY1) {
 		bool setItemCursor = false;
 		if (_mouseState == -6) {
 			if (mouse.x < 311)
@@ -1191,7 +1207,7 @@ void KyraEngine_MR::updateMouse() {
 		_screen->setMouseCursor(offsetX, offsetY, _gameShapes[shape]);
 	} else if (type == 0 && _mouseState != _itemInHand && mouse.x > 8 && mouse.x < 311 && mouse.y < 171 && mouse.y > 8) {
 		setItemMouseCursor();
-	} else if (mouse.y > 187 && _mouseState > -4 && type == 0 && !_inventoryState) {
+	} else if (mouse.y >= _interfaceCommandLineY1 && _mouseState > -4 && type == 0 && !_inventoryState) {
 		showInventory();
 	}
 }
diff --git a/engines/kyra/engine/kyra_mr.h b/engines/kyra/engine/kyra_mr.h
index ecb81bf0d0..613d3386a7 100644
--- a/engines/kyra/engine/kyra_mr.h
+++ b/engines/kyra/engine/kyra_mr.h
@@ -222,7 +222,13 @@ private:
 
 	// interface
 	uint8 *_interface;
+	uint32 _interfaceSize;
+	uint16 _interfaceH;
 	uint8 *_interfaceCommandLine;
+	uint32 _interfaceCommandLineSize;
+	uint16 _interfaceCommandLineY1;
+	uint16 _interfaceCommandLineY2;
+	uint16 _interfaceCommandLineH;
 
 	void loadInterfaceShapes();
 	void loadInterface();
diff --git a/engines/kyra/engine/scene_mr.cpp b/engines/kyra/engine/scene_mr.cpp
index 7b59a9a511..944ba984b7 100644
--- a/engines/kyra/engine/scene_mr.cpp
+++ b/engines/kyra/engine/scene_mr.cpp
@@ -159,7 +159,7 @@ void KyraEngine_MR::enterNewScene(uint16 sceneId, int facing, int unk1, int unk2
 		}
 
 		Common::Point pos = getMousePos();
-		if (pos.y > 187)
+		if (pos.y >= _interfaceCommandLineY1)
 			setMousePos(pos.x, 179);
 	}
 	_screen->showMouse();
@@ -559,7 +559,7 @@ void KyraEngine_MR::initSceneAnims(int unk1) {
 }
 
 void KyraEngine_MR::initSceneScreen(int unk1) {
-	_screen->copyBlockToPage(2, 0, 188, 320, 12, _interfaceCommandLine);
+	_screen->copyBlockToPage(2, 0, _interfaceCommandLineY1, 320, _interfaceCommandLineH, _interfaceCommandLine);
 
 	if (_unkSceneScreenFlag1) {
 		_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
@@ -707,7 +707,7 @@ int KyraEngine_MR::checkSceneChange() {
 	return 1;
 }
 int KyraEngine_MR::runSceneScript1(int x, int y) {
-	if (y > 187 && _savedMouseState > -4)
+	if (y >= _interfaceCommandLineY1 && _savedMouseState > -4)
 		return 0;
 	if (_deathHandler >= 0)
 		return 0;
@@ -767,7 +767,7 @@ bool KyraEngine_MR::lineIsPassable(int x, int y) {
 		return false;
 	if ((_pathfinderFlag & 8) && x < 0)
 		return false;
-	if (y > 187)
+	if (y >= _interfaceCommandLineY1)
 		return false;
 
 	uint width = widthTable[getScale(x, y) >> 5];
diff --git a/engines/kyra/graphics/animator_mr.cpp b/engines/kyra/graphics/animator_mr.cpp
index 11b1bcb45a..be987331e3 100644
--- a/engines/kyra/graphics/animator_mr.cpp
+++ b/engines/kyra/graphics/animator_mr.cpp
@@ -162,15 +162,15 @@ void KyraEngine_MR::refreshAnimObjects(int force) {
 			y -= (0x100 - scale) >> 3;
 		if (y < 0)
 			y = 0;
-		if (y >= 187)
-			y = 186;
+		if (y >= (_interfaceCommandLineY1 - 1))
+			y = _interfaceCommandLineY1 - 2;
 
 		int width = curObject->width + curObject->width2 + 8;
 		int height = curObject->height + curObject->height2*2;
 		if (width + x > 320)
 			width -= width + x - 322;
 
-		const int maxY = _inventoryState ? 143 : 187;
+		const int maxY = (_inventoryState ? _interfaceCommandLineY2 : _interfaceCommandLineY1) - 1;
 		if (height + y > maxY)
 			height -= height + y - (maxY + 1);
 
diff --git a/engines/kyra/graphics/screen.h b/engines/kyra/graphics/screen.h
index b6e2904242..0082fadd7c 100644
--- a/engines/kyra/graphics/screen.h
+++ b/engines/kyra/graphics/screen.h
@@ -124,7 +124,7 @@ public:
 	enum FontStyle {
 		kStyleNone			=	0,
 		kStyleLeftShadow	=	1	<<	0,
-		kStyleRightShadow	=	1	<<	1,
+		kStyleBorder		=	1	<<	1,
 		kStyleFat			=	1	<<	2,
 		kStyleNarrow1		=	1	<<	3,
 		kStyleNarrow2		=	1	<<	4,
@@ -263,11 +263,11 @@ public:
 	Type getType() const override { return kBIG5; }
 
 	bool load(Common::SeekableReadStream &data) override;
-	int getHeight() const override { return 14; }
+	int getHeight() const override { return _border ? 16 : 14; }
 	int getWidth() const override { return 18; }
 	int getCharWidth(uint16 c) const override;
-	void setColorMap(const uint8 *src) override { _colorMap = src; }
-	void setStyles(int styles) override { _shadowMode = (styles & kStyleRightShadow); }
+	void setColorMap(const uint8 *src) override;
+	void setStyles(int styles) override { _border = (styles & kStyleBorder); }
 	void drawChar(uint16 c, byte *dst, int pitch, int) const override;
 
 private:
@@ -275,8 +275,9 @@ private:
 	const uint8 *_twoByteData;
 	uint32 _twoByteDataSize;
 	const uint8 *_colorMap;
+	uint16 _textColor[2];
 	const uint16 _pitch;
-	bool _shadowMode;
+	bool _border;
 };
 
 /**
diff --git a/engines/kyra/graphics/screen_mr.cpp b/engines/kyra/graphics/screen_mr.cpp
index e573902d36..33836503e1 100644
--- a/engines/kyra/graphics/screen_mr.cpp
+++ b/engines/kyra/graphics/screen_mr.cpp
@@ -26,7 +26,7 @@
 namespace Kyra {
 
 Screen_MR::Screen_MR(KyraEngine_MR *vm, OSystem *system)
-	: Screen_v2(vm, system, _screenDimTable, _screenDimTableCount) {
+	: Screen_v2(vm, system, _screenDimTable, _screenDimTableCount), _interfaceCommandLineY1(vm->gameFlags().hasExtraLanguage ? 185 : 188) {
 }
 
 Screen_MR::~Screen_MR() {
@@ -40,8 +40,8 @@ int Screen_MR::getLayer(int x, int y) {
 
 	if (y < 0) {
 		y = 0;
-	} else if (y >= 188) {
-		y = 187;
+	} else if (y >= _interfaceCommandLineY1) {
+		y = _interfaceCommandLineY1 - 1;
 		// The original actually limits the _maskMin/MaxY check to cases where y has already been clipped to 187.
 		// Whether this was intentional or not: Scenes actually require that we do it that way or animations may
 		// be drawn on the wrong layer (bug #11312).
@@ -131,8 +131,9 @@ void Screen_MR::drawFilledBox(int x1, int y1, int x2, int y2, uint8 c1, uint8 c2
 	drawClippedLine(x1, y2-1, x2-1, y2-1, c3);
 }
 
-Big5Font::Big5Font(const uint8 *oneByteData, int pitch) : Font(), _oneByteData(oneByteData), _twoByteData(0), _twoByteDataSize(0), _pitch(pitch), _shadowMode(false) {
+Big5Font::Big5Font(const uint8 *oneByteData, int pitch) : Font(), _oneByteData(oneByteData), _twoByteData(0), _twoByteDataSize(0), _pitch(pitch), _border(false) {
 	assert(_oneByteData);
+	_textColor[0] = _textColor[1] = 0;
 }
 
 Big5Font::~Big5Font() {
@@ -161,8 +162,21 @@ int Big5Font::getCharWidth(uint16 c) const {
 	return (c & 0x80) ? 18 : 9;
 }
 
+void Big5Font::setColorMap(const uint8 *src) {
+	_colorMap = src;
+	_textColor[0] = _colorMap[1] | (_colorMap[1] << 8);
+	if (_textColor[0]) {
+		_textColor[0] -= 0x100;
+		if (_colorMap[1] == 0xFF)
+			_textColor[0] -= 0x100;
+	}
+	_textColor[0] = TO_LE_16(_textColor[0]);
+	_textColor[1] = _colorMap[0] | (_colorMap[0] << 8);
+}
+
 void Big5Font::drawChar(uint16 c, byte *dst, int pitch, int) const {
-	static const int16 shadowParam[13] = { 1, 0, 0, 0, 1, 0, 1, 2, 0, 0, 0, 1, -1 };
+	static const int8 drawSeqNormal[4] = { 0, 0, 0, -1 };
+	static const int8 drawSeqOutline[19] = { 1, 0, 1, 0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 0, -1 };
 	const uint8 *glyphData = &_oneByteData[(c & 0x7F) * 14];
 	int w = 7;
 
@@ -175,7 +189,7 @@ void Big5Font::drawChar(uint16 c, byte *dst, int pitch, int) const {
 		w = 15;
 	}
 
-	for (const int16 *i = (_shadowMode ? shadowParam : shadowParam + 9); *i != -1; i += 3) {
+	for (const int8 *i = _border ? drawSeqOutline : drawSeqNormal; *i != -1; i += 3) {
 		const uint8 *data = glyphData;
 		uint8 *dst3 = dst;
 		dst = &dst3[i[0] + i[1] * _pitch];
@@ -189,7 +203,7 @@ void Big5Font::drawChar(uint16 c, byte *dst, int pitch, int) const {
 					bt = 7;
 				}
 				if (in & (1 << (bt--)))
-					*dst = _colorMap[i[2]];
+					*(uint16*)dst = _textColor[i[2]];
 				dst++;
 			}
 			dst = dst2 + _pitch;
diff --git a/engines/kyra/graphics/screen_mr.h b/engines/kyra/graphics/screen_mr.h
index c82eb37108..db74701c37 100644
--- a/engines/kyra/graphics/screen_mr.h
+++ b/engines/kyra/graphics/screen_mr.h
@@ -46,6 +46,7 @@ public:
 private:
 	static const ScreenDim _screenDimTable[];
 	static const int _screenDimTableCount;
+	const int _interfaceCommandLineY1;
 };
 
 } // End of namespace Kyra
diff --git a/engines/kyra/gui/gui_mr.cpp b/engines/kyra/gui/gui_mr.cpp
index 8127e82b7e..0c4981b21b 100644
--- a/engines/kyra/gui/gui_mr.cpp
+++ b/engines/kyra/gui/gui_mr.cpp
@@ -26,6 +26,7 @@
 #include "kyra/resource/resource.h"
 #include "kyra/engine/timer.h"
 #include "kyra/sound/sound_digital_mr.h"
+#include "kyra/graphics/screen.h"
 
 #include "common/system.h"
 
@@ -112,7 +113,20 @@ void KyraEngine_MR::showMessage(const char *string, uint8 c0, uint8 c1) {
 		int x = _text->getCenterStringX(string, 0, 320);
 		int pageBackUp = _screen->_curPage;
 		_screen->_curPage = 0;
-		_text->printText(string, x, _commandLineY, c0, c1, 0);
+		int y = _commandLineY;
+
+		if (_lang == 3) {
+			_screen->setFontStyles(_screen->_currentFont, Font::kStyleNone);
+			y -= 3;
+			_text->printText(string, x, y, 0, 0, 0);
+			x++;
+		}
+
+		_text->printText(string, x, y, c0, c1, 0);
+
+		if (_lang == 3)
+			_screen->setFontStyles(_screen->_currentFont, Font::kStyleBorder);
+
 		_screen->_curPage = pageBackUp;
 		_screen->updateScreen();
 		setCommandLineRestoreTimer(7);
@@ -127,14 +141,18 @@ void KyraEngine_MR::updateItemCommand(Item item, int str, uint8 c0) {
 	char buffer[100];
 	char *src = (char *)getTableEntry(_itemFile, item);
 
-	while (*src != ' ')
+	if (_lang != 3) {
+		while (*src != ' ')
+			++src;
 		++src;
-	++src;
-
-	*src = toupper(*src);
+		*src = toupper(*src);
+	}
 
 	strcpy(buffer, src);
-	strcat(buffer, " ");
+
+	if (_lang != 3)
+		strcat(buffer, " ");
+
 	strcat(buffer, (const char *)getTableEntry(_cCodeFile, str));
 
 	showMessage(buffer, c0, 0xF0);
@@ -148,8 +166,8 @@ void KyraEngine_MR::updateCommandLine() {
 }
 
 void KyraEngine_MR::restoreCommandLine() {
-	int y = _inventoryState ? 144 : 188;
-	_screen->copyBlockToPage(0, 0, y, 320, 12, _interfaceCommandLine);
+	int y = _inventoryState ? _interfaceCommandLineY2 : _interfaceCommandLineY1;
+	_screen->copyBlockToPage(0, 0, y, 320, _interfaceCommandLineH, _interfaceCommandLine);
 }
 
 void KyraEngine_MR::updateCLState() {
@@ -165,7 +183,7 @@ void KyraEngine_MR::showInventory() {
 	if (queryGameFlag(3))
 		return;
 
-	_screen->copyBlockToPage(3, 0, 0, 320, 56, _interface);
+	_screen->copyBlockToPage(3, 0, 0, 320, _interfaceH, _interface);
 	drawMalcolmsMoodText();
 
 	_inventoryState = true;
@@ -185,14 +203,14 @@ void KyraEngine_MR::showInventory() {
 		_screen->setMouseCursor(0, 0, getShapePtr(0));
 	}
 
-	_screen->copyRegion(0, 188, 0, 0, 320, 12, 0, 2, Screen::CR_NO_P_CHECK);
+	_screen->copyRegion(0, _interfaceCommandLineY1, 0, 0, 320, _interfaceCommandLineH, 0, 2, Screen::CR_NO_P_CHECK);
 
 	if (_inventoryScrollSpeed == -1) {
 		uint32 endTime = _system->getMillis() + _tickLength * 15;
 		int times = 0;
 		while (_system->getMillis() < endTime) {
-			_screen->copyRegion(0, 188, 0, 0, 320, 12, 0, 2, Screen::CR_NO_P_CHECK);
-			_screen->copyRegion(0, 188, 0, 0, 320, 12, 0, 2, Screen::CR_NO_P_CHECK);
+			_screen->copyRegion(0, _interfaceCommandLineY1, 0, 0, 320, _interfaceCommandLineH, 0, 2, Screen::CR_NO_P_CHECK);
+			_screen->copyRegion(0, _interfaceCommandLineY1, 0, 0, 320, _interfaceCommandLineH, 0, 2, Screen::CR_NO_P_CHECK);
 			++times;
 		}
 
@@ -207,12 +225,12 @@ void KyraEngine_MR::showInventory() {
 			_inventoryScrollSpeed = speed;
 	}
 
-	int height = 12;
-	int y = 188;
+	int height = _interfaceCommandLineH;
+	int y = _interfaceCommandLineY1;
 	int times = 0;
 	uint32 waitTill = _system->getMillis() + _tickLength;
 
-	while (y > 144) {
+	while (y > _interfaceCommandLineY2) {
 		_screen->copyRegion(0, 0, 0, y, 320, height, 2, 0, Screen::CR_NO_P_CHECK);
 		_screen->updateScreen();
 
@@ -228,7 +246,7 @@ void KyraEngine_MR::showInventory() {
 		y -= _inventoryScrollSpeed;
 	}
 
-	_screen->copyRegion(0, 0, 0, 144, 320, 56, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->copyRegion(0, 0, 0, _interfaceCommandLineY2, 320, _interfaceH, 2, 0, Screen::CR_NO_P_CHECK);
 	_screen->updateScreen();
 
 	initMainButtonList(false);
@@ -245,20 +263,20 @@ void KyraEngine_MR::hideInventory() {
 	updateCLState();
 	initMainButtonList(true);
 
-	_screen->copyBlockToPage(3, 0, 0, 320, 56, _interface);
+	_screen->copyBlockToPage(3, 0, 0, 320, _interfaceH, _interface);
 	_screen->hideMouse();
 
 	restorePage3();
 	flagAnimObjsForRefresh();
 	drawAnimObjects();
-	_screen->copyRegion(0, 144, 0, 0, 320, 56, 0, 2, Screen::CR_NO_P_CHECK);
+	_screen->copyRegion(0, _interfaceCommandLineY2, 0, 0, 320, _interfaceH, 0, 2, Screen::CR_NO_P_CHECK);
 
 	if (_inventoryScrollSpeed == -1) {
 		uint32 endTime = _system->getMillis() + _tickLength * 15;
 		int times = 0;
 		while (_system->getMillis() < endTime) {
-			_screen->copyRegion(0, 144, 0, 0, 320, 12, 0, 2, Screen::CR_NO_P_CHECK);
-			_screen->copyRegion(0, 144, 0, 0, 320, 12, 0, 2, Screen::CR_NO_P_CHECK);
+			_screen->copyRegion(0, _interfaceCommandLineY2, 0, 0, 320, _interfaceCommandLineH, 0, 2, Screen::CR_NO_P_CHECK);
+			_screen->copyRegion(0, _interfaceCommandLineY2, 0, 0, 320, _interfaceCommandLineH, 0, 2, Screen::CR_NO_P_CHECK);
 			++times;
 		}
 
@@ -273,13 +291,13 @@ void KyraEngine_MR::hideInventory() {
 			_inventoryScrollSpeed = speed;
 	}
 
-	int y = 144;
-	int y2 = 144 + _inventoryScrollSpeed;
+	int y = _interfaceCommandLineY2;
+	int y2 = _interfaceCommandLineY2 + _inventoryScrollSpeed;
 	uint32 waitTill = _system->getMillis() + _tickLength;
 	int times = 0;
 
-	while (y2 < 188) {
-		_screen->copyRegion(0, 0, 0, y2, 320, 56, 2, 0, Screen::CR_NO_P_CHECK);
+	while (y2 < _interfaceCommandLineY1) {
+		_screen->copyRegion(0, 0, 0, y2, 320, _interfaceH, 2, 0, Screen::CR_NO_P_CHECK);
 		_screen->copyRegion(0, y, 0, y, 320, _inventoryScrollSpeed, 2, 0, Screen::CR_NO_P_CHECK);
 		_screen->updateScreen();
 
@@ -295,8 +313,8 @@ void KyraEngine_MR::hideInventory() {
 		y2 += _inventoryScrollSpeed;
 	}
 
-	_screen->copyRegion(0, 0, 0, 188, 320, 56, 2, 0, Screen::CR_NO_P_CHECK);
-	_screen->copyRegion(0, y, 0, y, 320, 188-y, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->copyRegion(0, 0, 0, _interfaceCommandLineY1, 320, _interfaceH, 2, 0, Screen::CR_NO_P_CHECK);
+	_screen->copyRegion(0, y, 0, y, 320, _interfaceCommandLineY1 - y, 2, 0, Screen::CR_NO_P_CHECK);
 	_screen->showMouse();
 }
 
@@ -308,7 +326,7 @@ void KyraEngine_MR::drawMalcolmsMoodText() {
 
 	const char *string = (const char *)getTableEntry(_cCodeFile, stringId[_malcolmsMood]);
 
-	Screen::FontId oldFont = _screen->setFont((_flags.hasExtraLanguage && _lang == 3) ? Screen::FID_CHINESE_FNT : Screen::FID_8_FNT);
+	Screen::FontId oldFont = _screen->setFont(_lang == 3 ? Screen::FID_CHINESE_FNT : Screen::FID_8_FNT);
 	_screen->_charSpacing = -2;
 
 	int width = _screen->getTextWidth(string);
@@ -320,15 +338,23 @@ void KyraEngine_MR::drawMalcolmsMoodText() {
 	const int x = 280 - (width / 2);
 	int y = 0;
 	if (_inventoryState) {
-		y = 189;
+		y = _interfaceCommandLineY1 + 1;
 		_screen->_curPage = 0;
 	} else {
 		y = 45;
 		_screen->_curPage = 2;
 	}
 
-	_screen->drawShape(_screen->_curPage, getShapePtr(432), 244, 189, 0, 0);
-	_text->printText(string, x, y+1, 0xFF, 0xF0, 0x00);
+	_screen->drawShape(_screen->_curPage, getShapePtr(432), 244, _interfaceCommandLineY1 + 1, 0, 0);
+
+	if (_lang == 3) {
+		_screen->setFontStyles(_screen->_currentFont, Font::kStyleNone);
+		_text->printText(string, x, y, 0x00, 0x00, 0x00);
+		_text->printText(string, x + 1, y, 0xFF, 0x00, 0x00);
+		_screen->setFontStyles(_screen->_currentFont, Font::kStyleBorder);
+	} else {
+		_text->printText(string, x, y + (_flags.hasExtraLanguage ? 3 : 1), 0xFF, 0xF0, 0x00);
+	}
 	_screen->_curPage = pageBackUp;
 }
 
@@ -346,7 +372,7 @@ void KyraEngine_MR::drawMalcolmsMoodPointer(int frame, int page) {
 		_invWsa->displayFrame(frame, 0, 0, 0, 0, 0, 0);
 		_screen->updateScreen();
 	} else if (page == 30) {
-		_invWsa->displayFrame(frame, 2, 0, -144, 0, 0, 0);
+		_invWsa->displayFrame(frame, 2, 0, -_interfaceCommandLineY2, 0, 0, 0);
 	}
 
 	_invWsaFrame = frame;
@@ -356,7 +382,7 @@ void KyraEngine_MR::drawJestersStaff(int type, int page) {
 	int y = 155;
 	if (page == 30) {
 		page = 2;
-		y -= 144;
+		y -= _interfaceCommandLineY2;
 	}
 
 	int shape = (type != 0) ? 454 : 453;
@@ -366,18 +392,18 @@ void KyraEngine_MR::drawJestersStaff(int type, int page) {
 void KyraEngine_MR::drawScore(int page, int x, int y) {
 	if (page == 30) {
 		page = 2;
-		y -= 144;
+		y -= _interfaceCommandLineY2;
 	}
 
 	int shape1 = _score / 100;
 	int shape2 = (_score - shape1*100) / 10;
 	int shape3 = _score % 10;
 
-	_screen->drawShape(page, getShapePtr(shape1+433), x, y, 0, 0);
+	_screen->drawShape(page, getShapePtr(shape1 + 433), x, y, 0, 0);
 	x += 8;
-	_screen->drawShape(page, getShapePtr(shape2+433), x, y, 0, 0);
+	_screen->drawShape(page, getShapePtr(shape2 + 433), x, y, 0, 0);
 	x += 8;
-	_screen->drawShape(page, getShapePtr(shape3+433), x, y, 0, 0);
+	_screen->drawShape(page, getShapePtr(shape3 + 433), x, y, 0, 0);
 }
 
 void KyraEngine_MR::drawScoreCounting(int oldScore, int newScore, int drawOld, const int x) {
@@ -431,7 +457,7 @@ void KyraEngine_MR::redrawInventory(int page) {
 
 	if (page == 30) {
 		page = 2;
-		yOffset = -144;
+		yOffset = -_interfaceCommandLineY2;
 	}
 
 	int pageBackUp = _screen->_curPage;
@@ -455,7 +481,7 @@ void KyraEngine_MR::clearInventorySlot(int slot, int page) {
 	int yOffset = 0;
 	if (page == 30) {
 		page = 2;
-		yOffset = -144;
+		yOffset = -_interfaceCommandLineY2;
 	}
 
 	_screen->drawShape(page, getShapePtr(slot+422), _inventoryX[slot], _inventoryY[slot] + yOffset, 0, 0);
@@ -465,10 +491,10 @@ void KyraEngine_MR::drawInventorySlot(int page, Item item, int slot) {
 	int yOffset = 0;
 	if (page == 30) {
 		page = 2;
-		yOffset = -144;
+		yOffset = -_interfaceCommandLineY2;
 	}
 
-	_screen->drawShape(page, getShapePtr(item+248), _inventoryX[slot], _inventoryY[slot] + yOffset, 0, 0);
+	_screen->drawShape(page, getShapePtr(item + 248), _inventoryX[slot], _inventoryY[slot] + yOffset, 0, 0);
 }
 
 int KyraEngine_MR::buttonInventory(Button *button) {
@@ -752,13 +778,13 @@ void KyraEngine_MR::printAlbumPageText() {
 
 	for (int i = 0; i < 5; ++i) {
 		const char *str = (const char *)getTableEntry(_album.file, _album.curPage*5+i);
-		int y = i * 10 + leftY + 20;
+		int y = i * (_screen->getFontHeight() + _screen->_lineSpacing) + leftY + 20;
 		printAlbumText(2, str, 20, y, 10);
 	}
 
 	for (int i = 0; i < 5; ++i) {
 		const char *str = (const char *)getTableEntry(_album.file, (_album.curPage+1)*5+i);
-		int y = i * 10 + rightY + 20;
+		int y = i * (_screen->getFontHeight() + _screen->_lineSpacing) + rightY + 20;
 		printAlbumText(2, str, 176, y, 10);
 	}
 
@@ -774,9 +800,14 @@ void KyraEngine_MR::printAlbumText(int page, const char *str, int x, int y, uint
 
 	Screen::FontId oldFont = _screen->setFont(Screen::FID_BOOKFONT_FNT);
 	_screen->_charSpacing = -2;
+	if (_lang == 3) {
+		_screen->setFont(Screen::FID_CHINESE_FNT);
+		_screen->setFontStyles(_screen->_currentFont, Font::kStyleNone);
+	}
 
 	_screen->printText(str, x, y, c0, 0);
 
+	_screen->setFontStyles(_screen->_currentFont, Font::kStyleBorder);
 	_screen->_charSpacing = 0;
 	_screen->setFont(oldFont);
 	_screen->_curPage = oldPage;
@@ -1155,6 +1186,8 @@ int GUI_MR::optionsButton(Button *button) {
 	if (!_screen->isMouseVisible() && button && !_vm->_menuDirectlyToLoad)
 		return 0;
 
+	_screen->setFontStyles(_screen->_currentFont, Font::kStyleNone);
+
 	_vm->showMessage(0, 0xF0, 0xF0);
 
 	if (_vm->_mouseState < -1) {
@@ -1178,15 +1211,7 @@ int GUI_MR::optionsButton(Button *button) {
 		_menuButtons[i].data1Callback = _menuButtons[i].data2Callback = _redrawButtonFunctor;
 	}
 
-	initMenuLayout(_mainMenu);
-	initMenuLayout(_gameOptions);
-	initMenuLayout(_audioOptions);
-	initMenuLayout(_choiceMenu);
-	_loadMenu.numberOfItems = 6;
-	initMenuLayout(_loadMenu);
-	initMenuLayout(_saveMenu);
-	initMenuLayout(_savenameMenu);
-	initMenuLayout(_deathMenu);
+	fontBasedMenuResize();
 
 	_currentMenu = &_mainMenu;
 
@@ -1344,6 +1369,15 @@ int GUI_MR::gameOptions(Button *caller) {
 		_vm->saveGameStateIntern(999, "Autosave", &thumb);
 		thumb.free();
 
+		if (_vm->_lang == 3) {
+			_screen->setFont(Screen::FID_CHINESE_FNT);
+			_screen->setFontStyles(Screen::FID_CHINESE_FNT, Font::kStyleNone);
+			_screen->_lineSpacing = 2;
+		} else {
+			_screen->setFont(Screen::FID_8_FNT);
+			_screen->_lineSpacing = 0;
+		}
+
 		if (!_vm->loadLanguageFile("ITEMS.", _vm->_itemFile))
 			error("Couldn't load ITEMS");
 		if (!_vm->loadLanguageFile("SCORE.", _vm->_scoreFile))
@@ -1356,6 +1390,9 @@ int GUI_MR::gameOptions(Button *caller) {
 			error("Couldn't load OPTIONS");
 		if (!_vm->loadLanguageFile("_ACTOR.", _vm->_actorFile))
 			error("couldn't load _ACTOR");
+
+		if (_vm->_lang == 3 || lang == 3)
+			fontBasedMenuResize();
 	}
 
 	_vm->writeSettings();
@@ -1389,6 +1426,10 @@ void GUI_MR::setupOptionsButtons() {
 		_gameOptions.item[1].itemId = 33;
 		break;
 
+	case 3:
+		_gameOptions.item[1].itemId = 48;
+		break;
+
 	default:
 		break;
 	}
@@ -1404,6 +1445,49 @@ void GUI_MR::setupOptionsButtons() {
 		_gameOptions.item[3].itemId = 17;
 }
 
+void GUI_MR::resizeMenu(Menu &menu, int menuHeight, int menuTitleY, int menuItemYstart, int menuItemYinc, int menuItemHeight, int menuItemYend, int labelYstart, int labelYend) {
+	menu.x = menu.y = -1;
+	menu.height = menuHeight;
+	menu.titleY = menuTitleY;
+	for (int i = 0; i < menu.numberOfItems - 1; ++i) {
+		menu.item[i].y = menuItemYstart + i * menuItemYinc;
+		menu.item[i].height = menuItemHeight;
+		menu.item[i].labelY = labelYstart ? (labelYstart + i * menuItemYinc) : 0;
+	}
+	menu.item[menu.numberOfItems - 1].y = menuItemYend;
+	menu.item[menu.numberOfItems - 1].height = menuItemHeight;
+	menu.item[menu.numberOfItems - 1].labelY = labelYend;
+	initMenuLayout(menu);
+}
+
+void GUI_MR::fontBasedMenuResize() {
+	if (_vm->_lang == 3) {
+		resizeMenu(_mainMenu, 192, 6, 26, 22, 20, 161, 0, 0);
+		resizeMenu(_gameOptions, 174, 8, 30, 22, 20, 145, 32, 0);
+		resizeMenu(_audioOptions, 140, 8, 28, 22, 20, 110, 30, 0);
+		_audioOptions.item[3].y = 81;
+		_audioOptions.item[3].labelY = 83;
+		resizeMenu(_choiceMenu, 56, 8, 30, 0, 20, 30, 0, 0);
+		_loadMenu.numberOfItems = 6;
+		resizeMenu(_loadMenu, 182, 6, 39, 22, 20, 155, 0, 0);
+		resizeMenu(_saveMenu, 182, 6, 39, 22, 20, 155, 0, 0);
+		_loadMenu.scrollDownButtonY = _saveMenu.scrollDownButtonY = 149;
+		resizeMenu(_savenameMenu, 72, 8, 44, 0, 20, 44, 0, 0);
+		resizeMenu(_deathMenu, 80, 8, 30, 0, 20, 52, 0, 0);
+	} else {
+		resizeMenu(_mainMenu, 172, 8, 30, 17, 15, 144, 0, 0);
+		resizeMenu(_gameOptions, 154, 8, 30, 17, 15, 127, 32, 0);
+		resizeMenu(_audioOptions, 136, 8, 30, 17, 15, 110, 32, 0);
+		resizeMenu(_choiceMenu, 56, 8, 30, 0, 15, 30, 0, 0);
+		_loadMenu.numberOfItems = 6;
+		resizeMenu(_loadMenu, 160, 8, 39, 17, 15, 134, 0, 0);
+		resizeMenu(_saveMenu, 160, 8, 39, 17, 15, 134, 0, 0);
+		_loadMenu.scrollDownButtonY = _saveMenu.scrollDownButtonY = 124;
+		resizeMenu(_savenameMenu, 67, 8, 44, 0, 15, 44, 0, 0);
+		resizeMenu(_deathMenu, 76, 8, 30, 0, 15, 47, 0, 0);
+	}
+}
+
 int GUI_MR::changeLanguage(Button *caller) {
 	updateMenuButton(caller);
 	if (!_vm->queryGameFlag(0x1B2)) {
diff --git a/engines/kyra/gui/gui_mr.h b/engines/kyra/gui/gui_mr.h
index 80b31d625f..836aee499d 100644
--- a/engines/kyra/gui/gui_mr.h
+++ b/engines/kyra/gui/gui_mr.h
@@ -67,6 +67,8 @@ private:
 
 	int gameOptions(Button *button);
 	void setupOptionsButtons() override;
+	void resizeMenu(Menu &menu, int menuHeight, int menuTitleY, int menuItemYstart, int menuItemYinc, int menuItemHeight, int menuItemYend, int labelYstart, int labelYend);
+	void fontBasedMenuResize();
 
 	int audioOptions(Button *button);
 
diff --git a/engines/kyra/gui/gui_v1.cpp b/engines/kyra/gui/gui_v1.cpp
index 5dc7a387f7..8e8719a635 100644
--- a/engines/kyra/gui/gui_v1.cpp
+++ b/engines/kyra/gui/gui_v1.cpp
@@ -139,7 +139,7 @@ void GUI_v1::initMenu(Menu &menu) {
 			} else {
 				Screen::FontId of = _screen->_currentFont;
 				if (menu.item[i].saveSlot > 0)
-					_screen->setFont(Screen::FID_8_FNT);
+					_screen->setFont(_vm->gameFlags().lang == Common::ZH_CNA ? Screen::FID_CHINESE_FNT : Screen::FID_8_FNT);
 
 				if (_vm->gameFlags().platform != Common::kPlatformAmiga)
 					printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
@@ -259,7 +259,7 @@ void GUI_v1::redrawText(const Menu &menu) {
 	} else {
 		Screen::FontId of = _screen->_currentFont;
 		if (menu.item[i].saveSlot > 0)
-			_screen->setFont(Screen::FID_8_FNT);
+			_screen->setFont(_vm->gameFlags().lang == Common::ZH_CNA ? Screen::FID_CHINESE_FNT : Screen::FID_8_FNT);
 		if (_vm->gameFlags().platform != Common::kPlatformAmiga)
 			printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
 		printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 0);
@@ -289,7 +289,7 @@ void GUI_v1::redrawHighlight(const Menu &menu) {
 	} else {
 		Screen::FontId of = _screen->_currentFont;
 		if (menu.item[i].saveSlot > 0)
-			_screen->setFont(Screen::FID_8_FNT);
+			_screen->setFont(_vm->gameFlags().lang == Common::ZH_CNA ? Screen::FID_CHINESE_FNT : Screen::FID_8_FNT);
 		if (_vm->gameFlags().platform != Common::kPlatformAmiga)
 			printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
 		printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 0);
@@ -511,7 +511,7 @@ int MainMenu::handle(int dim) {
 	int fh = _screen->getFontHeight();
 	if (_vm->gameFlags().lang == Common::JA_JPN)
 		fh++;
-	else if (_vm->gameFlags().hasExtraLanguage && _vm->gameFlags().lang == Common::ZH_CNA)
+	else if (_vm->gameFlags().lang == Common::ZH_CNA)
 		fh--;
 
 	int textPos = ((_screen->_curDim->w >> 1) + _screen->_curDim->sx) << 3;
@@ -565,7 +565,7 @@ void MainMenu::draw(int select) {
 	int fh = _screen->getFontHeight();
 	if (_vm->gameFlags().lang == Common::JA_JPN)
 		fh++;
-	else if (_vm->gameFlags().hasExtraLanguage && _vm->gameFlags().lang == Common::ZH_CNA)
+	else if (_vm->gameFlags().lang == Common::ZH_CNA)
 		fh--;
 
 	for (int i = 0; i < _static.menuTable[3]; ++i) {
diff --git a/engines/kyra/gui/gui_v2.cpp b/engines/kyra/gui/gui_v2.cpp
index 371892f965..b4a3578c24 100644
--- a/engines/kyra/gui/gui_v2.cpp
+++ b/engines/kyra/gui/gui_v2.cpp
@@ -520,6 +520,7 @@ int GUI_v2::scrollDownButton(Button *button) {
 int GUI_v2::resumeGame(Button *caller) {
 	updateMenuButton(caller);
 	_displayMenu = false;
+	_screen->setFontStyles(_screen->_currentFont, Font::kStyleBorder);
 	return 0;
 }
 
@@ -625,6 +626,7 @@ int GUI_v2::saveMenu(Button *caller) {
 	thumb.free();
 
 	_displayMenu = false;
+	_screen->setFontStyles(_screen->_currentFont, Font::kStyleBorder);
 	_madeSave = true;
 
 	return 0;
diff --git a/engines/kyra/script/script_mr.cpp b/engines/kyra/script/script_mr.cpp
index 2f5cc81f75..c042c8bbee 100644
--- a/engines/kyra/script/script_mr.cpp
+++ b/engines/kyra/script/script_mr.cpp
@@ -170,8 +170,8 @@ int KyraEngine_MR::o3_addItemToCurScene(EMCState *script) {
 
 	if (y < 18)
 		y = 18;
-	else if (y > 187)
-		y = 187;
+	else if (y >= _interfaceCommandLineY1)
+		y = _interfaceCommandLineY1 - 1;
 
 	if (itemSlot >= 0) {
 		_itemList[itemSlot].x = x;
@@ -731,24 +731,49 @@ int KyraEngine_MR::o3_daggerWarning(EMCState *script) {
 	int curPageBackUp = _screen->_curPage;
 	_screen->_curPage = 2;
 
+	
+	int y1 = 0xAA;
+	int y2 = 0xBA;
+	if (_lang == 3) {
+		y1 -= 2;
+		y2 += 4;
+	}
+
 	_screen->drawFilledBox(0, 0, 0x13F, 0xC7, 0xB4, 0xB3, 0xB6);
-	_screen->drawFilledBox(0xF, 0xAA, 0x68, 0xBA, 0xB4, 0xB3, 0xB6);
-	_screen->drawFilledBox(0x73, 0xAA, 0xCC, 0xBA, 0xB4, 0xB3, 0xB6);
-	_screen->drawFilledBox(0xD6, 0xAA, 0x12F, 0xBA, 0xB4, 0xB3, 0xB6);
+	_screen->drawFilledBox(0xF, y1, 0x68, y2, 0xB4, 0xB3, 0xB6);
+	_screen->drawFilledBox(0x73, y1, 0xCC, y2, 0xB4, 0xB3, 0xB6);
+	_screen->drawFilledBox(0xD6, y1, 0x12F, y2, 0xB4, 0xB3, 0xB6);
 
 	int y = 15;
-	for (int i = 100; i <= 107; ++i) {
+	int last = 107;
+	int yInc = 10;
+
+	if (_lang == 3) {
+		y = 6;
+		last = 105;
+		yInc = 16;
+	}
+
+	for (int i = 100; i <= last; ++i) {
 		const char *str = (const char *)getTableEntry(_cCodeFile, i);
 		int x = _text->getCenterStringX(str, 0, 0x13F);
 		_text->printText(str, x, y, 0xFF, 0xF0, 0x00);
-		y += 10;
+		y += yInc;
+	}
+
+	if (_lang == 3) {
+		y += 6;
+		last = 112;
+	} else {
+		y += 15;
+		last = 113;
 	}
-	y += 15;
-	for (int i = 110; i <= 113; ++i) {
+
+	for (int i = 110; i <= last; ++i) {
 		const char *str = (const char *)getTableEntry(_cCodeFile, i);
 		int x = _text->getCenterStringX(str, 0, 0x13F);
 		_text->printText(str, x, y, 0xFF, 0xF0, 0x00);
-		y += 10;
+		y += yInc;
 	}
 
 	const char *str = 0;
diff --git a/engines/kyra/sequence/sequences_mr.cpp b/engines/kyra/sequence/sequences_mr.cpp
index 286db2736d..0c733456e6 100644
--- a/engines/kyra/sequence/sequences_mr.cpp
+++ b/engines/kyra/sequence/sequences_mr.cpp
@@ -62,7 +62,7 @@ void KyraEngine_MR::showBadConscience() {
 		"GUNFR00.WSA", "GUNFR01.WSA", "GUNFR02.WSA", "GUNFR03.WSA", "GUNFR04.WSA", "GUNFR05.WSA", "GUNFR06.WSA", "GUNFR07.WSA"
 	};
 
-	setupSceneAnimObject(0x0E, 9, 0, 187, -1, -1, -1, -1, 0, 0, 0, -1, animFilenames[anim]);
+	setupSceneAnimObject(0x0E, 9, 0, _interfaceCommandLineY1 - 1, -1, -1, -1, -1, 0, 0, 0, -1, animFilenames[anim]);
 	for (uint i = 0; i <= _badConscienceFrameTable[_badConscienceAnim]; ++i) {
 		if (i == 8)
 			snd_playSoundEffect(0x1B, 0xC8);
diff --git a/engines/kyra/text/text_mr.cpp b/engines/kyra/text/text_mr.cpp
index 4da9eca889..9356504851 100644
--- a/engines/kyra/text/text_mr.cpp
+++ b/engines/kyra/text/text_mr.cpp
@@ -45,7 +45,7 @@ char *TextDisplayer_MR::preprocessString(const char *str) {
 
 	p = _talkBuffer;
 
-	if (_vm->gameFlags().hasExtraLanguage && _vm->_lang == 3) {
+	if (_vm->_lang == 3) {
 		Screen::FontId curFont = _screen->setFont(Screen::FID_CHINESE_FNT);
 		int textLen = Common::strnlen(p, sizeof(_talkBuffer));
 		int maxTextWidth;
@@ -162,8 +162,7 @@ void TextDisplayer_MR::printText(const Common::String &str, int x, int y, uint8
 	uint8 colorMap[] = { 0, 255, 240, 240 };
 	colorMap[3] = c1;
 	_screen->setTextColor(colorMap, 0, 3);
-	if (!(_vm->gameFlags().hasExtraLanguage && _vm->gameFlags().lang == 3))
-		_screen->_charSpacing = -2;
+	_screen->_charSpacing = -2;
 	_screen->printText(str.c_str(), x, y, c0, c2);
 	_screen->_charSpacing = 0;
 }
@@ -303,7 +302,8 @@ void KyraEngine_MR::objectChatInit(const char *str, int object, int vocHigh, int
 }
 
 void KyraEngine_MR::objectChatPrintText(const Common::String &str0, int object) {
-	int c1 = _talkObjectList[object].color;
+	int c1 = (_lang == 3 && _albumChatActive) ? 0xEE : _talkObjectList[object].color;
+	int c2 = (_lang == 3) ? 0 : 0xF0;
 	Common::String str = _text->preprocessString(str0.c_str());
 	int lineNum = _text->buildMessageSubstrings(str.c_str());
 	int maxWidth = _text->getWidestLineWidth(lineNum);
@@ -312,11 +312,11 @@ void KyraEngine_MR::objectChatPrintText(const Common::String &str0, int object)
 	_text->calcWidestLineBounds(cX1, cX2, maxWidth, x);
 
 	for (int i = 0; i < lineNum; ++i) {
-		str = Common::String(&_text->_talkSubstrings[i*_text->maxSubstringLen()]);
+		str = Common::String(&_text->_talkSubstrings[i * _text->maxSubstringLen()]);
 		int y = _text->_talkMessageY + i * (_screen->getFontHeight() + _screen->_lineSpacing);
 		x = _text->getCenterStringX(str, cX1, cX2);
 
-		_text->printText(str, x, y, c1, 0xF0, 0);
+		_text->printText(str, x, y, c1, c2, 0);
 	}
 }
 
@@ -503,7 +503,7 @@ void KyraEngine_MR::goodConscienceChatWaitToFinish() {
 
 void KyraEngine_MR::albumChat(const char *str, int vocHigh, int vocLow) {
 	_talkObjectList[1].x = 190;
-	_talkObjectList[1].y = 188;
+	_talkObjectList[1].y = _interfaceCommandLineY1;
 
 	_chatVocHigh = _chatVocLow = -1;
 	_albumChatActive = true;


Commit: 0afbbd6b207f26fea1c426848d183a1bbd628347
    https://github.com/scummvm/scummvm/commit/0afbbd6b207f26fea1c426848d183a1bbd628347
Author: athrxx (athrxx at scummvm.org)
Date: 2021-04-27T23:12:12+02:00

Commit Message:
KYRA: (LOL) - add support for playable talkie demo

Changed paths:
    devtools/create_kyradat/games.cpp
    engines/kyra/detection_tables.h
    engines/kyra/engine/kyra_hof.cpp
    engines/kyra/engine/lol.cpp
    engines/kyra/engine/lol.h
    engines/kyra/engine/util.h
    engines/kyra/gui/gui_lol.cpp
    engines/kyra/resource/staticres.cpp
    engines/kyra/resource/staticres_lol.cpp
    engines/kyra/script/script_lol.cpp
    engines/kyra/script/script_mr.cpp
    engines/kyra/script/script_tim.cpp
    engines/kyra/sequence/sequences_lol.cpp
    engines/kyra/sound/sound_pc_midi.cpp
    engines/kyra/sound/sound_pc_v1.cpp


diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp
index dbf2c6f0b8..09dced3f0a 100644
--- a/devtools/create_kyradat/games.cpp
+++ b/devtools/create_kyradat/games.cpp
@@ -4420,6 +4420,7 @@ const GameNeed gameNeedTable[] = {
 	{ kLoL, kPlatformFMTowns, kNoSpecial, lolFMTownsNeed },
 
 	{ kLoL, kPlatformDOS, kTalkieVersion, lolCDNeed },
+	{ kLoL, kPlatformDOS, kTalkieDemoVersion, lolCDDemoNeed },
 
 	{ kEoB1, kPlatformDOS, kNoSpecial, eob1FloppyNeed },
 	{ kEoB1, kPlatformDOS, kOldFloppy, eob1FloppyOldNeed },
diff --git a/engines/kyra/detection_tables.h b/engines/kyra/detection_tables.h
index 36c811f43d..2975d4700a 100644
--- a/engines/kyra/detection_tables.h
+++ b/engines/kyra/detection_tables.h
@@ -60,6 +60,7 @@ namespace {
 #define LOL_PC9801_FLAGS FLAGS(false, false, false, false, true, true, false, false, false, false, Kyra::GI_LOL)
 #define LOL_FMTOWNS_FLAGS FLAGS(false, false, false, false, true, false, false, false, false, false, Kyra::GI_LOL)
 #define LOL_DEMO_FLAGS FLAGS(true, true, false, false, false, false, false, false, false, false, Kyra::GI_LOL)
+#define LOL_CD_DEMO_FLAGS FLAGS(true, false, true, false, false, false, false, false, false, false, Kyra::GI_LOL)
 #define LOL_KYRA2_DEMO_FLAGS FLAGS(true, false, false, false, false, false, false, false, false, false, Kyra::GI_KYRA2)
 
 #define EOB_FLAGS FLAGS(false, false, false, false, false, false, false, false, false, false, Kyra::GI_EOB1)
@@ -79,7 +80,9 @@ namespace {
 #define GAMEOPTION_EOB_HPGRAPHS   GUIO_GAMEOPTIONS6
 #define GAMEOPTION_EOB_MOUSESWAP  GUIO_GAMEOPTIONS7
 
-static const char msgUnsupportedFanTranslation[] = _s("The fan translator does not wish his translation to be incorporated into ScummVM.");
+static const char msg_missingLangResources[]			= _s("Missing language specific game code and/or resources.");
+static const char msg_fanTrans_missingLangResources[]	= _s("Missing language specific game code and/or resources for this fan translation.");
+static const char msg_fanTrans_unsupportiveTranslator[]	= _s("The fan translator does not wish his translation to be incorporated into ScummVM.");
 
 const KYRAGameDescription adGameDescs[] = {
 	/* disable these targets until they get supported
@@ -135,6 +138,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA1_FLOPPY_FLAGS
 	},
+
 	{
 		{
 			"kyra1",
@@ -147,6 +151,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA1_FLOPPY_FLAGS
 	},
+
 	{
 		{
 			"kyra1",
@@ -159,6 +164,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA1_FLOPPY_FLAGS
 	},
+
 	{ // from Arne.F
 		{
 			"kyra1",
@@ -171,6 +177,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA1_FLOPPY_FLAGS
 	},
+
 	{ // russian fan translation
 		{
 			"kyra1",
@@ -183,6 +190,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA1_OLDFLOPPY_FLAGS
 	},
+
 	{ // from VooD
 		{
 			"kyra1",
@@ -195,6 +203,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA1_FLOPPY_FLAGS
 	},
+
 	{ // floppy 1.8 from clemmy
 		{
 			"kyra1",
@@ -207,6 +216,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA1_FLOPPY_FLAGS
 	},
+
 	{ // from gourry
 		{
 			"kyra1",
@@ -223,7 +233,7 @@ const KYRAGameDescription adGameDescs[] = {
 	{ // Bugreport #7773
 		{
 			"kyra1",
-			_s("Missing game code"), // Reason for being unsupported
+			msg_fanTrans_missingLangResources, // Reason for being unsupported
 			AD_ENTRY1s("GEMCUT.EMC", "20f876423f4caa20f5de6b4fc5dfafeb", 6686),
 			Common::CZ_CZE,
 			Common::kPlatformDOS,
@@ -236,7 +246,7 @@ const KYRAGameDescription adGameDescs[] = {
 	{ // from trembyle
 		{
 			"kyra1",
-			_s("Missing game code"), // Reason for being unsupported
+			msg_missingLangResources, // Reason for being unsupported
 			AD_ENTRY1("GEMCUT.EMC", "3f319d6908830a46ff42229a39a2c7ec"),
 			Common::ZH_TWN,
 			Common::kPlatformDOS,
@@ -249,7 +259,7 @@ const KYRAGameDescription adGameDescs[] = {
 	{ // from trembyle
 		{
 			"kyra1",
-			_s("Missing game code"), // Reason for being unsupported
+			msg_missingLangResources, // Reason for being unsupported
 			AD_ENTRY1("GEMCUT.EMC", "57907d931675dbd16386c1d81d18fee4"),
 			Common::KO_KOR,
 			Common::kPlatformDOS,
@@ -327,6 +337,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA1_TOWNS_FLAGS
 	},
+
 	{
 		{
 			"kyra1",
@@ -341,8 +352,7 @@ const KYRAGameDescription adGameDescs[] = {
 		KYRA1_TOWNS_SJIS_FLAGS
 	},
 
-	// PC-9801 floppy + CD / PC-9821 floppy version are all using the same data files,
-	// thus we will mark it as non CD game.
+	// PC-9801 floppy + CD / PC-9821 floppy version all use the same data files, thus we mark it as non-CD game.
 	{
 		{
 			"kyra1",
@@ -395,6 +405,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA1_CD_FLAGS
 	},
+
 	{
 		{
 			"kyra1",
@@ -447,6 +458,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA1_CD_FLAGS
 	},
+
 	{ // Polish fan translation of Macintosh CD version
 		{
 			"kyra1",
@@ -460,6 +472,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA1_CD_FLAGS
 	},
+
 	{
 		{
 			"kyra1",
@@ -473,6 +486,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA1_CD_FLAGS
 	},
+
 	{
 		{
 			"kyra1",
@@ -499,10 +513,11 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA1_DEMO_FLAGS
 	},
+
 	{ // Modern fan-made Russian translation by Siberian GRemlin
 		{
 			"kyra1",
-			msgUnsupportedFanTranslation,
+			msg_fanTrans_unsupportiveTranslator,
 			AD_ENTRY1("MAIN_ENG.CPS", "535765395e3594bfd9b727834028e288"),
 			Common::RU_RUS,
 			Common::kPlatformDOS,
@@ -511,6 +526,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA1_CD_FAN_FLAGS(Common::RU_RUS, Common::EN_ANY)
 	},
+
 	{	// Special Kyrandia 1 CD demo
 		{
 			"kyra1",
@@ -618,7 +634,7 @@ const KYRAGameDescription adGameDescs[] = {
 	{ // Floppy version extracted
 		{
 			"kyra2",
-			_s("Missing game code"), // Reason for being unsupported
+			msg_missingLangResources, // Reason for being unsupported
 			AD_ENTRY1("FATE.PAK", "5bfc4dd48778ca1f3a9e001e345a9774"),
 			Common::ZH_TWN,
 			Common::kPlatformDOS,
@@ -631,7 +647,7 @@ const KYRAGameDescription adGameDescs[] = {
 	{ // Floppy version extracted. Bugreport #7666
 		{
 			"kyra2",
-			_s("Missing game code"), // Reason for being unsupported
+			msg_fanTrans_missingLangResources, // Reason for being unsupported
 			AD_ENTRY1s("FATE.PAK", "ac81bcd4aa6e0921a87eb099827a8b06", 107309),
 			Common::PL_POL,
 			Common::kPlatformDOS,
@@ -679,6 +695,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA2_CD_FLAGS
 	},
+
 	{
 		{
 			"kyra2",
@@ -691,6 +708,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA2_CD_FLAGS
 	},
+
 	{
 		{
 			"kyra2",
@@ -717,6 +735,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA2_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
 	},
+
 	{
 		{
 			"kyra2",
@@ -729,6 +748,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA2_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY)
 	},
+
 	{
 		{
 			"kyra2",
@@ -785,7 +805,7 @@ const KYRAGameDescription adGameDescs[] = {
 	{ // CD version
 		{
 			"kyra2",
-			msgUnsupportedFanTranslation,
+			msg_fanTrans_unsupportiveTranslator,
 			AD_ENTRY1("FERRY.CPS", "763e2103858347d4ffffc329910d323f"),
 			Common::RU_RUS,
 			Common::kPlatformDOS,
@@ -873,6 +893,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA2_TOWNS_FLAGS
 	},
+
 	{
 		{
 			"kyra2",
@@ -885,6 +906,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA2_TOWNS_SJIS_FLAGS
 	},
+
 	{ // PC-9821
 		{
 			"kyra2",
@@ -897,6 +919,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA2_TOWNS_FLAGS
 	},
+
 	{
 		{
 			"kyra2",
@@ -912,8 +935,7 @@ const KYRAGameDescription adGameDescs[] = {
 
 	// Kyra3
 
-	// non installed version
-	{
+	{ // non installed version
 		{
 			"kyra3",
 			0,
@@ -926,6 +948,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA3_CD_FLAGS
 	},
+
 	{
 		{
 			"kyra3",
@@ -939,6 +962,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA3_CD_FLAGS
 	},
+
 	{
 		{
 			"kyra3",
@@ -981,6 +1005,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA3_CD_INS_FLAGS
 	},
+
 	{
 		{
 			"kyra3",
@@ -994,6 +1019,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA3_CD_INS_FLAGS
 	},
+
 	{
 		{
 			"kyra3",
@@ -1022,6 +1048,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA3_CD_INS_FLAGS
 	},
+
 	{
 		{
 			"kyra3",
@@ -1035,6 +1062,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA3_CD_INS_FLAGS
 	},
+
 	{
 		{
 			"kyra3",
@@ -1055,7 +1083,7 @@ const KYRAGameDescription adGameDescs[] = {
 			"kyra3",
 			0,
 			AD_ENTRY2s("ONETIME.PAK", "9aaca21d2a205ca02ec53132f2911794", -1,
-					"AUD.PAK", 0, -1),
+					   "AUD.PAK", 0, -1),
 			Common::ES_ESP,
 			Common::kPlatformDOS,
 			ADGF_DROPLANGUAGE,
@@ -1063,12 +1091,13 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA3_CD_FAN_FLAGS(Common::ES_ESP, Common::EN_ANY)
 	},
+
 	{
 		{
 			"kyra3",
 			0,
 			AD_ENTRY2s("ONETIME.PAK", "9aaca21d2a205ca02ec53132f2911794", -1,
-					"AUD.PAK", 0, -1),
+					   "AUD.PAK", 0, -1),
 			Common::DE_DEU,
 			Common::kPlatformDOS,
 			ADGF_DROPLANGUAGE,
@@ -1076,6 +1105,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA3_CD_FAN_FLAGS(Common::ES_ESP, Common::EN_ANY)
 	},
+
 	{
 		{
 			"kyra3",
@@ -1104,6 +1134,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA3_CD_FAN_FLAGS(Common::IT_ITA, Common::FR_FRA)
 	},
+
 	{
 		{
 			"kyra3",
@@ -1117,6 +1148,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA3_CD_FAN_FLAGS(Common::IT_ITA, Common::FR_FRA)
 	},
+
 	{
 		{
 			"kyra3",
@@ -1130,6 +1162,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA3_CD_FAN_FLAGS(Common::IT_ITA, Common::FR_FRA)
 	},
+
 	{
 		{
 			"kyra3",
@@ -1147,6 +1180,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA3_CD_FAN_FLAGS(Common::RU_RUS, Common::DE_DEU)
 	},
+
 	{ // non installed version
 		{
 			"kyra3",
@@ -1160,6 +1194,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA3_CD_4LANG_FLAGS
 	},
+
 	{
 		{
 			"kyra3",
@@ -1173,6 +1208,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA3_CD_4LANG_FLAGS
 	},
+
 	{
 		{
 			"kyra3",
@@ -1186,6 +1222,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA3_CD_4LANG_FLAGS
 	},
+
 	{
 		{
 			"kyra3",
@@ -1199,6 +1236,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA3_CD_4LANG_FLAGS
 	},
+
 	{ // installed version
 		{
 			"kyra3",
@@ -1216,6 +1254,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA3_CD_INS_4LANG_FLAGS
 	},
+
 	{
 		{
 			"kyra3",
@@ -1233,6 +1272,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA3_CD_INS_4LANG_FLAGS
 	},
+
 	{
 		{
 			"kyra3",
@@ -1250,6 +1290,7 @@ const KYRAGameDescription adGameDescs[] = {
 		},
 		KYRA3_CD_INS_4LANG_FLAGS
 	},
+
 	{
 		{
 			"kyra3",
@@ -1749,8 +1790,7 @@ const KYRAGameDescription adGameDescs[] = {
 		LOL_PC9801_FLAGS
 	},
 
-	// Russian fan translation
-	{
+	{ // Russian fan translation
 		{
 			"lol",
 			"Extracted",
@@ -1819,18 +1859,46 @@ const KYRAGameDescription adGameDescs[] = {
 		LOL_DEMO_FLAGS
 	},
 
-	// Interactive CD demo, Bugreport #6777
-	{
+	{ // Interactive CD demo, Bugreport #6777
 		{
 			"lol",
-			_s("Missing game code"), // Reason for being unsupported
-			AD_ENTRY1s("GENERAL.PAK", "17e442d3b6109d4ae8354fa55d6c8121", 710633),
+			"CD/Demo",
+			AD_ENTRY2s("GENERAL.PAK",	"17e442d3b6109d4ae8354fa55d6c8121", -1,
+					   "L01.PAK",		"759a0ac26808d77ea968bd392355ba1d", -1),
 			Common::EN_ANY,
 			Common::kPlatformDOS,
-			ADGF_DEMO | ADGF_UNSUPPORTED,
-			GUIO5(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA)
+			ADGF_DROPLANGUAGE | ADGF_CD,
+			GUIO8(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA, GAMEOPTION_LOL_SCROLLING, GAMEOPTION_LOL_CURSORS, GAMEOPTION_LOL_SAVENAMES)
 		},
-		LOL_DEMO_FLAGS
+		LOL_CD_DEMO_FLAGS
+	},
+
+	{ // Interactive CD demo, Bugreport #6777
+		{
+			"lol",
+			"CD/Demo",
+			AD_ENTRY2s("GENERAL.PAK",	"17e442d3b6109d4ae8354fa55d6c8121", -1,
+					   "L01.PAK",		"759a0ac26808d77ea968bd392355ba1d", -1),
+			Common::FR_FRA,
+			Common::kPlatformDOS,
+			ADGF_DROPLANGUAGE | ADGF_CD,
+			GUIO8(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA, GAMEOPTION_LOL_SCROLLING, GAMEOPTION_LOL_CURSORS, GAMEOPTION_LOL_SAVENAMES)
+		},
+		LOL_CD_DEMO_FLAGS
+	},
+
+	{ // Interactive CD demo, Bugreport #6777
+		{
+			"lol",
+			"CD/Demo",
+			AD_ENTRY2s("GENERAL.PAK",	"17e442d3b6109d4ae8354fa55d6c8121", -1,
+					   "L01.PAK",		"759a0ac26808d77ea968bd392355ba1d", -1),
+			Common::DE_DEU,
+			Common::kPlatformDOS,
+			ADGF_DROPLANGUAGE | ADGF_CD,
+			GUIO8(GUIO_MIDIADLIB, GUIO_MIDIMT32, GUIO_MIDIGM, GUIO_MIDIPCSPK, GUIO_RENDERVGA, GAMEOPTION_LOL_SCROLLING, GAMEOPTION_LOL_CURSORS, GAMEOPTION_LOL_SAVENAMES)
+		},
+		LOL_CD_DEMO_FLAGS
 	},
 
 	{
@@ -1995,7 +2063,7 @@ const KYRAGameDescription adGameDescs[] = {
 	{
 		{
 			"eob2",
-			_s("Missing game code"), // Reason for being unsupported
+			msg_missingLangResources, // Reason for being unsupported
 			AD_ENTRY1s("LEVEL15.INF", "f972f628d21bae404a7d52bb287c0012", -1),
 			Common::ZH_ANY,
 			Common::kPlatformDOS,
@@ -2044,7 +2112,7 @@ const KYRAGameDescription adGameDescs[] = {
 		EOB2_FLAGS
 	},
 
-	{ AD_TABLE_END_MARKER, FLAGS(0, 0, 0, 0, 0, 0, 0, 0, 0, 0) }
+	{ AD_TABLE_END_MARKER, FLAGS(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) }
 };
 
 const PlainGameDescriptor gameList[] = {
diff --git a/engines/kyra/engine/kyra_hof.cpp b/engines/kyra/engine/kyra_hof.cpp
index a8265351a3..b9b462e527 100644
--- a/engines/kyra/engine/kyra_hof.cpp
+++ b/engines/kyra/engine/kyra_hof.cpp
@@ -872,19 +872,19 @@ void KyraEngine_HoF::showChapterMessage(int id, int16 palIndex) {
 void KyraEngine_HoF::updateCommandLineEx(int str1, int str2, int16 palIndex) {
 	Common::String str = getTableString(str1, _cCodeBuffer, true);
 
- 	if (_flags.lang != Common::JA_JPN) {
+	if (_flags.lang != Common::JA_JPN) {
 		if (uint32 i = (uint32)str.findFirstOf(' ') + 1) {
 			str.erase(0, i);
 			str.setChar(toupper(str[0]), 0);
 		}
- 	}
- 
- 	if (str2 > 0) {
- 		if (_flags.lang != Common::JA_JPN)
+	}
+
+	if (str2 > 0) {
+		if (_flags.lang != Common::JA_JPN)
 			str += " ";
 		str += getTableString(str2, _cCodeBuffer, 1);
- 	}
- 
+	}
+
 	showMessage(str, palIndex);
 }
 
diff --git a/engines/kyra/engine/lol.cpp b/engines/kyra/engine/lol.cpp
index 5062fc40d4..14b5191c4b 100644
--- a/engines/kyra/engine/lol.cpp
+++ b/engines/kyra/engine/lol.cpp
@@ -500,7 +500,7 @@ Common::Error LoLEngine::go() {
 			return Common::kNoError;
 	}
 
-	if (_flags.isTalkie && !_flags.isDemo) {
+	if (_flags.isTalkie) {
 		if (!_res->loadFileList("FILEDATA.FDT"))
 			error("Couldn't load file list: 'FILEDATA.FDT'");
 	} else if (_pakFileList) {
@@ -834,6 +834,35 @@ void LoLEngine::startupNew() {
 	_inventory[1] = makeItem(217, 0, 0);
 	_inventory[2] = makeItem(218, 0, 0);
 
+	if (_flags.isDemo) {
+		_inventory[5] = makeItem(32, 0, 0);
+		_inventory[6] = makeItem(40, 0, 0);
+		_inventory[7] = makeItem(51, 0, 0);
+		_inventory[8] = makeItem(64, 0, 0);
+		_inventory[10] = makeItem(76, 0, 0);
+		_inventory[11] = makeItem(234, 0, 0);
+		_inventory[12] = makeItem(118, 0, 0);
+		_inventory[13] = makeItem(123, 0, 0);
+		_inventory[14] = makeItem(125, 0, 0);
+		_inventory[15] = makeItem(37, 0, 0);
+		_inventory[16] = makeItem(140, 0, 0);
+		_inventory[17] = makeItem(150, 0, 0);
+		_inventory[18] = makeItem(158, 0, 0);
+		_inventory[19] = makeItem(215, 0, 0);
+		_inventory[20] = makeItem(215, 0, 0);
+		_inventory[21] = makeItem(216, 0, 0);
+		_inventory[22] = makeItem(216, 0, 0);
+		_inventory[23] = makeItem(219, 0, 0);
+		_inventory[24] = makeItem(225, 0, 0);
+		_inventory[27] = makeItem(267, 0, 0);
+		_inventory[28] = makeItem(270, 0, 0);
+		_inventory[29] = makeItem(271, 0, 0);
+		_availableSpells[1] = 1;
+		_availableSpells[2] = 4;
+		_availableSpells[3] = 6;
+		_flagsTable[31] |= 0x20;
+	}
+
 	_availableSpells[0] = 0;
 	setupScreenDims();
 
diff --git a/engines/kyra/engine/lol.h b/engines/kyra/engine/lol.h
index a5d2f7b840..72c6a38c48 100644
--- a/engines/kyra/engine/lol.h
+++ b/engines/kyra/engine/lol.h
@@ -1218,7 +1218,6 @@ private:
 	int8 _availableSpells[8];
 	int _selectedSpell;
 	const SpellProperty *_spellProperties;
-	//int _spellPropertiesSize;
 	int _subMenuIndex;
 
 	LightningProperty *_lightningProps;
diff --git a/engines/kyra/engine/util.h b/engines/kyra/engine/util.h
index 5858d4d509..e14f960d15 100644
--- a/engines/kyra/engine/util.h
+++ b/engines/kyra/engine/util.h
@@ -34,7 +34,7 @@ public:
 	static void decodeString2(const char *src, char *dst);
 	static Common::String decodeString1(const Common::String &src);
 	static Common::String decodeString2(const Common::String &src);
-	
+
 
 	// Since our current GUI font uses ISO-8859-1, this
 	// conversion functionallty uses that as a base.
diff --git a/engines/kyra/gui/gui_lol.cpp b/engines/kyra/gui/gui_lol.cpp
index 4fe58697b7..fa71897f31 100644
--- a/engines/kyra/gui/gui_lol.cpp
+++ b/engines/kyra/gui/gui_lol.cpp
@@ -322,7 +322,6 @@ void LoLEngine::gui_changeCharacterStats(int charNum) {
 
 void LoLEngine::gui_drawCharInventoryItem(int itemIndex) {
 	static const uint8 slotShapes[] = { 0x30, 0x34, 0x30, 0x34, 0x2E, 0x2F, 0x32, 0x33, 0x31, 0x35, 0x35 };
-	//2Eh, 32h, 2Eh, 32h, 2Ch, 2Dh, 30h, 31h, 2Fh, 33h, 33h
 	const uint8 *coords = &_charInvDefs[_charInvIndex[_characters[_selectedCharacter].raceClassSex] * 22 + itemIndex * 2];
 	uint8 x = *coords++;
 	uint8 y = *coords;
diff --git a/engines/kyra/resource/staticres.cpp b/engines/kyra/resource/staticres.cpp
index 1908b5dc4a..f49a33f4f9 100644
--- a/engines/kyra/resource/staticres.cpp
+++ b/engines/kyra/resource/staticres.cpp
@@ -1827,7 +1827,7 @@ const char *const KyraEngine_MR::_languageExtension[] = {
 	"TRG",
 	"TRC"
 	// Italian, Spanish and Russian don't have dedicated language files. The supported fan translations
-	// use one of the existing extensions (English, French or German) thus overwriting that language. 
+	// use one of the existing extensions (English, French or German) thus overwriting that language.
 };
 
 const int KyraEngine_MR::_languageExtensionSize = ARRAYSIZE(KyraEngine_MR::_languageExtension);
diff --git a/engines/kyra/resource/staticres_lol.cpp b/engines/kyra/resource/staticres_lol.cpp
index 77d4f05616..1c7c9bd54d 100644
--- a/engines/kyra/resource/staticres_lol.cpp
+++ b/engines/kyra/resource/staticres_lol.cpp
@@ -249,7 +249,7 @@ void LoLEngine::initStaticResource() {
 		_sound->initAudioResourceInfo(kMusicFinale, &resInfoFinale);
 	}
 
-	if (_flags.isDemo)
+	if (_flags.isDemo && !_flags.isTalkie)
 		return;
 
 	int tempSize;
diff --git a/engines/kyra/script/script_lol.cpp b/engines/kyra/script/script_lol.cpp
index 976346c0a8..33f8e674f9 100644
--- a/engines/kyra/script/script_lol.cpp
+++ b/engines/kyra/script/script_lol.cpp
@@ -1397,22 +1397,27 @@ int LoLEngine::olol_countAllMonsters(EMCState *script) {
 int LoLEngine::olol_playEndSequence(EMCState *script) {
 	debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_playEndSequence(%p)", (const void *)script);
 
-	int c = 0;
-	if (_characters[0].id == -9)
-		c = 1;
-	else if (_characters[0].id == -5)
-		c = 3;
-	else if (_characters[0].id == -1)
-		c = 2;
+	if (_flags.isDemo) {
+		_screen->fadeToBlack(150);
+	} else {
+		int c = 0;
+		if (_characters[0].id == -9)
+			c = 1;
+		else if (_characters[0].id == -5)
+			c = 3;
+		else if (_characters[0].id == -1)
+			c = 2;
 
-	while (snd_updateCharacterSpeech())
-		delay(_tickLength);
+		while (snd_updateCharacterSpeech())
+			delay(_tickLength);
 
-	_eventList.clear();
-	_screen->hideMouse();
-	_screen->getPalette(1).clear();
+		_eventList.clear();
+		_screen->hideMouse();
+		_screen->getPalette(1).clear();
+
+		showOutro(c, (_monsterDifficulty == 2));
+	}
 
-	showOutro(c, (_monsterDifficulty == 2));
 	// Don't call quitGame() on a return to launcher request (because this would
 	// make the next game launched from the launcher quit instantly.
 	if (!shouldQuit())
diff --git a/engines/kyra/script/script_mr.cpp b/engines/kyra/script/script_mr.cpp
index c042c8bbee..4a7e44788d 100644
--- a/engines/kyra/script/script_mr.cpp
+++ b/engines/kyra/script/script_mr.cpp
@@ -731,7 +731,7 @@ int KyraEngine_MR::o3_daggerWarning(EMCState *script) {
 	int curPageBackUp = _screen->_curPage;
 	_screen->_curPage = 2;
 
-	
+
 	int y1 = 0xAA;
 	int y2 = 0xBA;
 	if (_lang == 3) {
diff --git a/engines/kyra/script/script_tim.cpp b/engines/kyra/script/script_tim.cpp
index 4e73ddfa52..b92ae96ec1 100644
--- a/engines/kyra/script/script_tim.cpp
+++ b/engines/kyra/script/script_tim.cpp
@@ -462,7 +462,7 @@ void TIMInterpreter::setupTextPalette(uint index, int fadePalette) {
 int TIMInterpreter::initAnimStruct(int index, const char *filename, int x, int y, int, int offscreenBuffer, uint16 wsaFlags) {
 	Movie *wsa = 0;
 
-	const bool isLoLDemo = _vm->gameFlags().isDemo && _vm->game() == GI_LOL;
+	const bool isLoLDemo = _vm->gameFlags().isDemo && !_vm->gameFlags().isTalkie && _vm->game() == GI_LOL;
 
 	if (isLoLDemo || _vm->gameFlags().platform == Common::kPlatformPC98 || _currentTim->isLoLOutro)
 		_drawPage2 = 0;
diff --git a/engines/kyra/sequence/sequences_lol.cpp b/engines/kyra/sequence/sequences_lol.cpp
index 27e08b7a98..626c1cc254 100644
--- a/engines/kyra/sequence/sequences_lol.cpp
+++ b/engines/kyra/sequence/sequences_lol.cpp
@@ -47,7 +47,7 @@ int LoLEngine::processPrologue() {
 			showIntro();
 	}
 
-	if (_flags.isDemo) {
+	if (_flags.isDemo && !_flags.isTalkie) {
 		_screen->fadePalette(_screen->getPalette(1), 30, 0);
 		_screen->loadBitmap("FINAL.CPS", 2, 2, &_screen->getPalette(0));
 		_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
@@ -78,11 +78,11 @@ int LoLEngine::processPrologue() {
 		_screen->updateScreen();
 
 		_eventList.clear();
-		int selection = mainMenu();
 
-		if (selection != 3) {
-			_screen->hideMouse();
+		int selection = _flags.isDemo ? 0 : mainMenu();
 
+		if (!_flags.isDemo && selection != 3) {
+			_screen->hideMouse();
 			// Unlike the original, we add a nice fade to black
 			_screen->getPalette(0).clear();
 			_screen->fadeToBlack(0x54);
@@ -122,9 +122,18 @@ int LoLEngine::processPrologue() {
 	}
 
 	if (processSelection == 0) {
-		_sound->loadSoundFile(0);
-		_sound->playTrack(6);
-		chooseCharacter();
+		if (_flags.isDemo) {
+			_charSelection = 0;
+			_screen->loadBitmap("ITEMICN.SHP", 3, 3, 0);
+			_screen->setMouseCursor(0, 0, _screen->getPtrToShape(_screen->getCPagePtr(3), 0));
+			while (!_screen->isMouseVisible())
+				_screen->showMouse();
+			delay(500);
+		} else {
+			_sound->loadSoundFile(0);
+			_sound->playTrack(6);
+			chooseCharacter();
+		}
 		_sound->playTrack(1);
 		_screen->fadeToBlack();
 	}
@@ -142,6 +151,13 @@ void LoLEngine::setupPrologueData(bool load) {
 		"HISTORY.PAK", 0
 	};
 
+	static const char *const fileListCDDemo[] = {
+		"GENERAL.PAK", "INTROVOC.PAK", "ISTARTUP.PAK", "INTRO1.PAK",
+		"INTRO2.PAK", "INTRO3.PAK", "INTRO4.PAK", "INTRO5.PAK",
+		"INTRO6.PAK", "INTRO7.PAK", "INTRO8.PAK", "INTRO9.PAK",
+		0
+	};
+
 	static const char *const fileListFloppy[] = {
 		"INTRO.PAK", "INTROVOC.PAK", 0
 	};
@@ -150,13 +166,13 @@ void LoLEngine::setupPrologueData(bool load) {
 		"INTRO.PAK", "TINTROVO.PAK", 0
 	};
 
-	const char *const *fileList = _flags.isTalkie ? fileListCD : (_flags.platform == Common::kPlatformFMTowns ? fileListTowns : fileListFloppy);
+	const char *const *fileList = _flags.isTalkie ? (_flags.isDemo ? fileListCDDemo : fileListCD) : (_flags.platform == Common::kPlatformFMTowns ? fileListTowns : fileListFloppy);
 
 	char filename[32];
 	for (uint i = 0; fileList[i]; ++i) {
 		filename[0] = '\0';
 
-		if (_flags.isTalkie) {
+		if (_flags.isTalkie && !_flags.isDemo) {
 			strcpy(filename, _languageExt[_lang]);
 			strcat(filename, "/");
 		}
@@ -196,7 +212,7 @@ void LoLEngine::setupPrologueData(bool load) {
 		if (_flags.platform == Common::kPlatformPC98)
 			_sound->loadSoundFile("SOUND.DAT");
 
-		if (_flags.isDemo)
+		if (_flags.isDemo && !_flags.isTalkie)
 			_sound->loadSoundFile("LOREINTR");
 	} else {
 		delete _chargenWSA; _chargenWSA = 0;
@@ -241,7 +257,7 @@ void LoLEngine::showIntro() {
 	while (!_tim->finished() && !shouldQuit() && !skipFlag()) {
 		updateInput();
 		_tim->exec(intro, false);
-		if (!_flags.isDemo && _flags.platform != Common::kPlatformPC98)
+		if (!(_flags.isDemo && !_flags.isTalkie) && _flags.platform != Common::kPlatformPC98)
 			_screen->checkedPageUpdate(8, 4);
 
 		if (_tim->_palDiff) {
diff --git a/engines/kyra/sound/sound_pc_midi.cpp b/engines/kyra/sound/sound_pc_midi.cpp
index 96341ef0c7..15b1e0436a 100644
--- a/engines/kyra/sound/sound_pc_midi.cpp
+++ b/engines/kyra/sound/sound_pc_midi.cpp
@@ -137,7 +137,9 @@ bool SoundMidiPC::init() {
 			midiFile = "LOREINTR";
 
 			if (_vm->gameFlags().isDemo) {
-				if (_vm->resource()->exists("INTROVOC.PAK")) {
+				if (_vm->gameFlags().isTalkie) {
+					pakFile = "ISTARTUP.PAK";
+				} else if (_vm->resource()->exists("INTROVOC.PAK")) {
 					// Intro demo
 					pakFile = "INTROVOC.PAK";
 				} else {
diff --git a/engines/kyra/sound/sound_pc_v1.cpp b/engines/kyra/sound/sound_pc_v1.cpp
index 67da0e8cd1..1cfb97d9f8 100644
--- a/engines/kyra/sound/sound_pc_v1.cpp
+++ b/engines/kyra/sound/sound_pc_v1.cpp
@@ -53,7 +53,7 @@ SoundPC_v1::SoundPC_v1(KyraEngine_v1 *vm, Audio::Mixer *mixer, kType type)
 
 	switch (vm->game()) {
 	case GI_LOL:
-		_version = _vm->gameFlags().isDemo ? 3 : 4;
+		_version = (_vm->gameFlags().isDemo && !_vm->gameFlags().isTalkie) ? 3 : 4;
 		break;
 	case GI_KYRA2:
 		_version = 4;


Commit: 5c9b5e0968a0d48fd78a11d8f8f28928d168363f
    https://github.com/scummvm/scummvm/commit/5c9b5e0968a0d48fd78a11d8f8f28928d168363f
Author: athrxx (athrxx at scummvm.org)
Date: 2021-04-27T23:12:28+02:00

Commit Message:
KYRA: (LOL) - monster stats fix

Changed paths:
    engines/kyra/engine/sprites_lol.cpp


diff --git a/engines/kyra/engine/sprites_lol.cpp b/engines/kyra/engine/sprites_lol.cpp
index 910447c45a..66c0660048 100644
--- a/engines/kyra/engine/sprites_lol.cpp
+++ b/engines/kyra/engine/sprites_lol.cpp
@@ -482,7 +482,7 @@ int LoLEngine::calcMonsterSkillLevel(int id, int a) {
 	int r = (a << 8) / c[4];
 
 	if (id & 0x8000) {
-		r = (r * _monsterModifiers2[3 + _monsterDifficulty]) >> 8;
+		r = (r * _monsterModifiers2[_monsterDifficulty]) >> 8;
 	} else {
 		if (_characters[id].skillLevels[1] > 7)
 			r = (r - (r >> 1));


Commit: 9102f40bfd1adb80cac9494325757a79370485c8
    https://github.com/scummvm/scummvm/commit/9102f40bfd1adb80cac9494325757a79370485c8
Author: athrxx (athrxx at scummvm.org)
Date: 2021-04-27T23:12:31+02:00

Commit Message:
NEWS: mention KYRA3 Chinese and LOL demo

Changed paths:
    NEWS.md


diff --git a/NEWS.md b/NEWS.md
index 6554e6a7e7..ee24f73023 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -60,6 +60,8 @@ For a more comprehensive changelog of the latest experimental code, see:
  Kyra:
    - Added support for the Japanese Sega-CD version of Eye of the Beholder.
    - Added support for the Hebrew fan translation of Legend of Kyrandia.
+   - Added support for the Simplified Chinese version of Legend of Kyrandia 3.
+   - Added support for the playable demo of Lands of Lore.
 
  Lure:
    - Fixed fire animation in first room when loading saves.




More information about the Scummvm-git-logs mailing list