diff options
Diffstat (limited to 'engines/sci/engine/kernel_tables.h')
-rw-r--r-- | engines/sci/engine/kernel_tables.h | 587 |
1 files changed, 452 insertions, 135 deletions
diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h index 0c2fd4e3ea..6e141e7f3b 100644 --- a/engines/sci/engine/kernel_tables.h +++ b/engines/sci/engine/kernel_tables.h @@ -34,6 +34,15 @@ namespace Sci { // . -> any type // i* -> optional multiple integers // .* -> any parameters afterwards (or none) +// +// data types: +// i - regular integer +// o - object +// r - reference +// n - node +// 0 - NULL +// . - any +// ! - invalid reference/offset struct SciKernelMapSubEntry { SciVersion fromVersion; @@ -51,12 +60,19 @@ struct SciKernelMapSubEntry { #define SCI_SUBOPENTRY_TERMINATOR { SCI_VERSION_NONE, SCI_VERSION_NONE, 0, NULL, NULL, NULL, NULL } -#define SIG_SCIALL SCI_VERSION_NONE, SCI_VERSION_NONE -#define SIG_SCI0 SCI_VERSION_NONE, SCI_VERSION_01 -#define SIG_SCI1 SCI_VERSION_1_EGA_ONLY, SCI_VERSION_1_LATE -#define SIG_SCI11 SCI_VERSION_1_1, SCI_VERSION_1_1 -#define SIG_SINCE_SCI11 SCI_VERSION_1_1, SCI_VERSION_NONE -#define SIG_SCI21 SCI_VERSION_2_1, SCI_VERSION_3 +#define SIG_SCIALL SCI_VERSION_NONE, SCI_VERSION_NONE +#define SIG_SCI0 SCI_VERSION_NONE, SCI_VERSION_01 +#define SIG_SCI1 SCI_VERSION_1_EGA_ONLY, SCI_VERSION_1_LATE +#define SIG_SCI11 SCI_VERSION_1_1, SCI_VERSION_1_1 +#define SIG_SINCE_SCI11 SCI_VERSION_1_1, SCI_VERSION_NONE +#define SIG_SCI2 SCI_VERSION_2, SCI_VERSION_2 +#define SIG_SCI21EARLY SCI_VERSION_2_1_EARLY, SCI_VERSION_2_1_EARLY +#define SIG_UNTIL_SCI21EARLY SCI_VERSION_2, SCI_VERSION_2_1_EARLY +#define SIG_UNTIL_SCI21MID SCI_VERSION_2, SCI_VERSION_2_1_MIDDLE +#define SIG_SINCE_SCI21 SCI_VERSION_2_1_EARLY, SCI_VERSION_3 +#define SIG_SINCE_SCI21MID SCI_VERSION_2_1_MIDDLE, SCI_VERSION_3 +#define SIG_SINCE_SCI21LATE SCI_VERSION_2_1_LATE, SCI_VERSION_3 +#define SIG_SCI3 SCI_VERSION_3, SCI_VERSION_3 #define SIG_SCI16 SCI_VERSION_NONE, SCI_VERSION_1_1 #define SIG_SCI32 SCI_VERSION_2, SCI_VERSION_NONE @@ -65,7 +81,7 @@ struct SciKernelMapSubEntry { #define SIG_SOUNDSCI0 SCI_VERSION_0_EARLY, SCI_VERSION_0_LATE #define SIG_SOUNDSCI1EARLY SCI_VERSION_1_EARLY, SCI_VERSION_1_EARLY #define SIG_SOUNDSCI1LATE SCI_VERSION_1_LATE, SCI_VERSION_1_LATE -#define SIG_SOUNDSCI21 SCI_VERSION_2_1, SCI_VERSION_3 +#define SIG_SOUNDSCI21 SCI_VERSION_2_1_EARLY, SCI_VERSION_3 #define SIGFOR_ALL 0x3f #define SIGFOR_DOS 1 << 0 @@ -86,7 +102,7 @@ struct SciKernelMapSubEntry { static const SciKernelMapSubEntry kDoSound_subops[] = { { SIG_SOUNDSCI0, 0, MAP_CALL(DoSoundInit), "o", NULL }, { SIG_SOUNDSCI0, 1, MAP_CALL(DoSoundPlay), "o", NULL }, - { SIG_SOUNDSCI0, 2, MAP_CALL(DoSoundRestore), "(o)", NULL }, + { SIG_SOUNDSCI0, 2, MAP_EMPTY(DoSoundRestore), "(o)", NULL }, { SIG_SOUNDSCI0, 3, MAP_CALL(DoSoundDispose), "o", NULL }, { SIG_SOUNDSCI0, 4, MAP_CALL(DoSoundMute), "(i)", NULL }, { SIG_SOUNDSCI0, 5, MAP_CALL(DoSoundStop), "o", NULL }, @@ -99,16 +115,12 @@ static const SciKernelMapSubEntry kDoSound_subops[] = { { SIG_SOUNDSCI0, 12, MAP_CALL(DoSoundStopAll), "", NULL }, { SIG_SOUNDSCI1EARLY, 0, MAP_CALL(DoSoundMasterVolume), NULL, NULL }, { SIG_SOUNDSCI1EARLY, 1, MAP_CALL(DoSoundMute), NULL, NULL }, - { SIG_SOUNDSCI1EARLY, 2, MAP_CALL(DoSoundRestore), NULL, NULL }, + { SIG_SOUNDSCI1EARLY, 2, MAP_EMPTY(DoSoundRestore), NULL, NULL }, { SIG_SOUNDSCI1EARLY, 3, MAP_CALL(DoSoundGetPolyphony), NULL, NULL }, { SIG_SOUNDSCI1EARLY, 4, MAP_CALL(DoSoundUpdate), NULL, NULL }, { SIG_SOUNDSCI1EARLY, 5, MAP_CALL(DoSoundInit), NULL, NULL }, { SIG_SOUNDSCI1EARLY, 6, MAP_CALL(DoSoundDispose), NULL, NULL }, { SIG_SOUNDSCI1EARLY, 7, MAP_CALL(DoSoundPlay), "oi", NULL }, - // ^^ TODO: In SCI1-SCI1.1 DoSound (play) is called by 2 methods of the Sound object: play and - // playBed. The methods are the same, apart from the second integer parameter: it's 0 in - // play and 1 in playBed, to distinguish the caller. It's passed on, we should find out what - // it actually does internally { SIG_SOUNDSCI1EARLY, 8, MAP_CALL(DoSoundStop), NULL, NULL }, { SIG_SOUNDSCI1EARLY, 9, MAP_CALL(DoSoundPause), "[o0]i", NULL }, { SIG_SOUNDSCI1EARLY, 10, MAP_CALL(DoSoundFade), "oiiii", kDoSoundFade_workarounds }, @@ -116,11 +128,11 @@ static const SciKernelMapSubEntry kDoSound_subops[] = { { SIG_SOUNDSCI1EARLY, 12, MAP_CALL(DoSoundSendMidi), "oiii", NULL }, { SIG_SOUNDSCI1EARLY, 13, MAP_CALL(DoSoundGlobalReverb), "(i)", NULL }, { SIG_SOUNDSCI1EARLY, 14, MAP_CALL(DoSoundSetHold), "oi", NULL }, - { SIG_SOUNDSCI1EARLY, 15, MAP_CALL(DoSoundDummy), "", NULL }, + { SIG_SOUNDSCI1EARLY, 15, MAP_EMPTY(DoSoundDummy), "", NULL }, // ^^ Longbow demo { SIG_SOUNDSCI1LATE, 0, MAP_CALL(DoSoundMasterVolume), NULL, NULL }, { SIG_SOUNDSCI1LATE, 1, MAP_CALL(DoSoundMute), NULL, NULL }, - { SIG_SOUNDSCI1LATE, 2, MAP_CALL(DoSoundRestore), "", NULL }, + { SIG_SOUNDSCI1LATE, 2, MAP_EMPTY(DoSoundRestore), "", NULL }, { SIG_SOUNDSCI1LATE, 3, MAP_CALL(DoSoundGetPolyphony), NULL, NULL }, { SIG_SOUNDSCI1LATE, 4, MAP_CALL(DoSoundGetAudioCapability), "", NULL }, { SIG_SOUNDSCI1LATE, 5, MAP_CALL(DoSoundSuspend), "i", NULL }, @@ -131,7 +143,7 @@ static const SciKernelMapSubEntry kDoSound_subops[] = { { SIG_SOUNDSCI1LATE, 10, MAP_CALL(DoSoundPause), NULL, NULL }, { SIG_SOUNDSCI1LATE, 11, MAP_CALL(DoSoundFade), "oiiii(i)", kDoSoundFade_workarounds }, { SIG_SOUNDSCI1LATE, 12, MAP_CALL(DoSoundSetHold), NULL, NULL }, - { SIG_SOUNDSCI1LATE, 13, MAP_CALL(DoSoundDummy), NULL, NULL }, + { SIG_SOUNDSCI1LATE, 13, MAP_EMPTY(DoSoundDummy), NULL, NULL }, { SIG_SOUNDSCI1LATE, 14, MAP_CALL(DoSoundSetVolume), "oi", NULL }, { SIG_SOUNDSCI1LATE, 15, MAP_CALL(DoSoundSetPriority), "oi", NULL }, { SIG_SOUNDSCI1LATE, 16, MAP_CALL(DoSoundSetLoop), "oi", NULL }, @@ -140,36 +152,100 @@ static const SciKernelMapSubEntry kDoSound_subops[] = { { SIG_SOUNDSCI1LATE, 19, MAP_CALL(DoSoundGlobalReverb), NULL, NULL }, { SIG_SOUNDSCI1LATE, 20, MAP_CALL(DoSoundUpdate), NULL, NULL }, #ifdef ENABLE_SCI32 - { SIG_SOUNDSCI21, 0, MAP_CALL(DoSoundMasterVolume), NULL, NULL }, - { SIG_SOUNDSCI21, 1, MAP_CALL(DoSoundMute), NULL, NULL }, - { SIG_SOUNDSCI21, 2, MAP_CALL(DoSoundRestore), NULL, NULL }, - { SIG_SOUNDSCI21, 3, MAP_CALL(DoSoundGetPolyphony), NULL, NULL }, - { SIG_SOUNDSCI21, 4, MAP_CALL(DoSoundGetAudioCapability), NULL, NULL }, - { SIG_SOUNDSCI21, 5, MAP_CALL(DoSoundSuspend), NULL, NULL }, - { SIG_SOUNDSCI21, 6, MAP_CALL(DoSoundInit), NULL, NULL }, - { SIG_SOUNDSCI21, 7, MAP_CALL(DoSoundDispose), NULL, NULL }, - { SIG_SOUNDSCI21, 8, MAP_CALL(DoSoundPlay), "o(i)", NULL }, + { SIG_SOUNDSCI21, 0, MAP_CALL(DoSoundMasterVolume), "(i)", NULL }, + { SIG_SOUNDSCI21, 1, MAP_CALL(DoSoundMute), "(i)", NULL }, + { SIG_SOUNDSCI21, 2, MAP_EMPTY(DoSoundRestore), NULL, NULL }, + { SIG_SOUNDSCI21, 3, MAP_CALL(DoSoundGetPolyphony), "", NULL }, + { SIG_SOUNDSCI21, 4, MAP_CALL(DoSoundGetAudioCapability), "", NULL }, + { SIG_SOUNDSCI21, 5, MAP_CALL(DoSoundSuspend), "i", NULL }, + { SIG_SOUNDSCI21, 6, MAP_CALL(DoSoundInit), "o", NULL }, + { SIG_SOUNDSCI21, 7, MAP_CALL(DoSoundDispose), "o", NULL }, + { SIG_SOUNDSCI21, 8, MAP_CALL(DoSoundPlay), "o", kDoSoundPlay_workarounds }, // ^^ TODO: if this is really the only change between SCI1LATE AND SCI21, we could rename the // SIG_SOUNDSCI1LATE #define to SIG_SINCE_SOUNDSCI1LATE and make it being SCI1LATE+. Although // I guess there are many more changes somewhere // TODO: Quest for Glory 4 (SCI2.1) uses the old scheme, we need to detect it accordingly // signature for SCI21 should be "o" - { SIG_SOUNDSCI21, 9, MAP_CALL(DoSoundStop), NULL, NULL }, - { SIG_SOUNDSCI21, 10, MAP_CALL(DoSoundPause), NULL, NULL }, - { SIG_SOUNDSCI21, 11, MAP_CALL(DoSoundFade), NULL, kDoSoundFade_workarounds }, - { SIG_SOUNDSCI21, 12, MAP_CALL(DoSoundSetHold), NULL, NULL }, - { SIG_SOUNDSCI21, 13, MAP_CALL(DoSoundDummy), NULL, NULL }, - { SIG_SOUNDSCI21, 14, MAP_CALL(DoSoundSetVolume), NULL, NULL }, - { SIG_SOUNDSCI21, 15, MAP_CALL(DoSoundSetPriority), NULL, NULL }, - { SIG_SOUNDSCI21, 16, MAP_CALL(DoSoundSetLoop), NULL, NULL }, - { SIG_SOUNDSCI21, 17, MAP_CALL(DoSoundUpdateCues), NULL, NULL }, - { SIG_SOUNDSCI21, 18, MAP_CALL(DoSoundSendMidi), NULL, NULL }, - { SIG_SOUNDSCI21, 19, MAP_CALL(DoSoundGlobalReverb), NULL, NULL }, - { SIG_SOUNDSCI21, 20, MAP_CALL(DoSoundUpdate), NULL, NULL }, + { SIG_SOUNDSCI21, 9, MAP_CALL(DoSoundStop), "o", NULL }, + { SIG_SOUNDSCI21, 10, MAP_CALL(DoSoundPause), "[o0]i", NULL }, + { SIG_SOUNDSCI21, 11, MAP_CALL(DoSoundFade), "oiiii", kDoSoundFade_workarounds }, + { SIG_SOUNDSCI21, 12, MAP_CALL(DoSoundSetHold), "oi", NULL }, + { SIG_SOUNDSCI21, 13, MAP_EMPTY(DoSoundDummy), NULL, NULL }, + { SIG_SOUNDSCI21, 14, MAP_CALL(DoSoundSetVolume), "oi", NULL }, + { SIG_SOUNDSCI21, 15, MAP_CALL(DoSoundSetPriority), "oi", NULL }, + { SIG_SOUNDSCI21, 16, MAP_CALL(DoSoundSetLoop), "oi", NULL }, + { SIG_SOUNDSCI21, 17, MAP_CALL(DoSoundUpdateCues), "o", NULL }, + { SIG_SOUNDSCI21, 18, MAP_CALL(DoSoundSendMidi), "oiiii", NULL }, + { SIG_SOUNDSCI21, 19, MAP_CALL(DoSoundGlobalReverb), "(i)", NULL }, + { SIG_SOUNDSCI21, 20, MAP_CALL(DoSoundUpdate), "o", NULL }, #endif SCI_SUBOPENTRY_TERMINATOR }; +#ifdef ENABLE_SCI32 +// NOTE: In SSCI, some 'unused' kDoAudio subops are actually called indirectly +// by kDoSound: +// +// kDoSoundGetAudioCapability -> kDoAudioGetCapability +// kDoSoundPlay -> kDoAudioPlay, kDoAudioStop +// kDoSoundPause -> kDoAudioPause, kDoAudioResume +// kDoSoundFade -> kDoAudioFade +// kDoSoundSetVolume -> kDoAudioVolume +// kDoSoundSetLoop -> kDoAudioSetLoop +// kDoSoundUpdateCues -> kDoAudioPosition +// +// In ScummVM, logic inside these kernel functions has been moved to methods of +// Audio32, and direct calls to Audio32 are made from kDoSound instead. +// +// Some kDoAudio methods are esoteric and appear to be used only by one or two +// games: +// +// - kDoAudioMixing: Phantasmagoria (other games call this function, but only +// to disable the feature) +// - kDoAudioHasSignal: SQ6 TalkRandCycle +// - kDoAudioPan: Rama RegionSFX::pan method +// - kDoAudioCritical: Phantasmagoria, chapter 3, nursery (room 14200), during +// the "ghost lullaby" event. It is used to make the +// lullaby sound exclusive, but it really doesn't make any +// major difference. Returning 0 means "non-critical", i.e. +// normal audio behavior. +// +// Finally, there is a split in SCI2.1mid audio code. QFG4CD & SQ6 do not have +// opcodes 18 and 19, but they exist in GK2, KQ7 2.00b, Phantasmagoria 1, +// PQ:SWAT, and Torin. It is unknown if they exist in MUMG Deluxe or Shivers 1; +// they are not used in either of these games. + +// version, subId, function-mapping, signature, workarounds +static const SciKernelMapSubEntry kDoAudio_subops[] = { + { SIG_SCI32, 0, MAP_CALL(DoAudioInit), "", NULL }, + // SCI2 includes a Sync script that would call + // kDoAudioWaitForPlay, but SSCI has no opcode 1 until + // SCI2.1early + { SIG_SINCE_SCI21, 1, MAP_CALL(DoAudioWaitForPlay), "(i)(i)(i)(i)(i)(i)(i)", NULL }, + { SIG_SCI32, 2, MAP_CALL(DoAudioPlay), "(i)(i)(i)(i)(i)(i)(i)", NULL }, + { SIG_SCI32, 3, MAP_CALL(DoAudioStop), "(i)(i)(i)(i)(i)", NULL }, + { SIG_SCI32, 4, MAP_CALL(DoAudioPause), "(i)(i)(i)(i)(i)", NULL }, + { SIG_SCI32, 5, MAP_CALL(DoAudioResume), "(i)(i)(i)(i)(i)", NULL }, + { SIG_SCI32, 6, MAP_CALL(DoAudioPosition), "(i)(i)(i)(i)(i)", NULL }, + { SIG_SCI32, 7, MAP_CALL(DoAudioRate), "(i)", NULL }, + { SIG_SCI32, 8, MAP_CALL(DoAudioVolume), "(i)(i)(i)(i)(i)(i)", NULL }, + { SIG_SCI32, 9, MAP_CALL(DoAudioGetCapability), "", NULL }, + { SIG_SCI32, 10, MAP_CALL(DoAudioBitDepth), "(i)", NULL }, + { SIG_SCI32, 11, MAP_DUMMY(DoAudioDistort), "(i)", NULL }, + { SIG_SCI32, 12, MAP_CALL(DoAudioMixing), "(i)", NULL }, + { SIG_SCI32, 13, MAP_CALL(DoAudioChannels), "(i)", NULL }, + { SIG_SCI32, 14, MAP_CALL(DoAudioPreload), "(i)", NULL }, + { SIG_SINCE_SCI21MID, 15, MAP_CALL(DoAudioFade), "(iiii)(i)(i)", NULL }, + { SIG_SINCE_SCI21MID, 16, MAP_DUMMY(DoAudioFade36), "iiiii(iii)(i)", NULL }, + { SIG_SINCE_SCI21MID, 17, MAP_CALL(DoAudioHasSignal), "", NULL }, + { SIG_SINCE_SCI21MID, 18, MAP_EMPTY(DoAudioCritical), "(i)", NULL }, + { SIG_SINCE_SCI21MID, 19, MAP_CALL(DoAudioSetLoop), "iii(o)", NULL }, + { SIG_SCI3, 20, MAP_DUMMY(DoAudioPan), "", NULL }, + { SIG_SCI3, 21, MAP_DUMMY(DoAudioPanOff), "", NULL }, + SCI_SUBOPENTRY_TERMINATOR +}; +#endif + // version, subId, function-mapping, signature, workarounds static const SciKernelMapSubEntry kGraph_subops[] = { { SIG_SCI32, 1, MAP_CALL(StubNull), "", NULL }, // called by gk1 sci32 right at the start @@ -194,31 +270,44 @@ static const SciKernelMapSubEntry kGraph_subops[] = { // version, subId, function-mapping, signature, workarounds static const SciKernelMapSubEntry kPalVary_subops[] = { - { SIG_SCI21, 0, MAP_CALL(PalVaryInit), "ii(i)(i)(i)", NULL }, - { SIG_SCIALL, 0, MAP_CALL(PalVaryInit), "ii(i)(i)", NULL }, - { SIG_SCIALL, 1, MAP_CALL(PalVaryReverse), "(i)(i)(i)", NULL }, - { SIG_SCIALL, 2, MAP_CALL(PalVaryGetCurrentStep), "", NULL }, - { SIG_SCIALL, 3, MAP_CALL(PalVaryDeinit), "", NULL }, - { SIG_SCIALL, 4, MAP_CALL(PalVaryChangeTarget), "i", NULL }, - { SIG_SCIALL, 5, MAP_CALL(PalVaryChangeTicks), "i", NULL }, - { SIG_SCIALL, 6, MAP_CALL(PalVaryPauseResume), "i", NULL }, + { SIG_SCI16, 0, MAP_CALL(PalVaryInit), "ii(i)(i)", NULL }, + { SIG_SCI16, 1, MAP_CALL(PalVaryReverse), "(i)(i)(i)", NULL }, + { SIG_SCI16, 2, MAP_CALL(PalVaryGetCurrentStep), "", NULL }, + { SIG_SCI16, 3, MAP_CALL(PalVaryDeinit), "", NULL }, + { SIG_SCI16, 4, MAP_CALL(PalVaryChangeTarget), "i", NULL }, + { SIG_SCI16, 5, MAP_CALL(PalVaryChangeTicks), "i", NULL }, + { SIG_SCI16, 6, MAP_CALL(PalVaryPauseResume), "i", NULL }, #ifdef ENABLE_SCI32 - { SIG_SCI32, 8, MAP_CALL(PalVaryUnknown), "i", NULL }, - { SIG_SCI32, 9, MAP_CALL(PalVaryUnknown2), "i", NULL }, + { SIG_SCI32, 0, MAP_CALL(PalVarySetVary), "i(i)(i)(ii)", NULL }, + { SIG_SCI32, 1, MAP_CALL(PalVarySetPercent), "(i)(i)", kPalVarySetPercent_workarounds }, + { SIG_SCI32, 2, MAP_CALL(PalVaryGetPercent), "", NULL }, + { SIG_SCI32, 3, MAP_CALL(PalVaryOff), "", NULL }, + { SIG_SCI32, 4, MAP_CALL(PalVaryMergeTarget), "i", NULL }, + { SIG_SCI32, 5, MAP_CALL(PalVarySetTime), "i", NULL }, + { SIG_SCI32, 6, MAP_CALL(PalVaryPauseResume), "i", NULL }, + { SIG_SCI32, 7, MAP_CALL(PalVarySetTarget), "i", NULL }, + { SIG_SCI32, 8, MAP_CALL(PalVarySetStart), "i", NULL }, + { SIG_SCI32, 9, MAP_CALL(PalVaryMergeStart), "i", NULL }, #endif SCI_SUBOPENTRY_TERMINATOR }; // version, subId, function-mapping, signature, workarounds static const SciKernelMapSubEntry kPalette_subops[] = { - { SIG_SCIALL, 1, MAP_CALL(PaletteSetFromResource), "i(i)", NULL }, - { SIG_SCIALL, 2, MAP_CALL(PaletteSetFlag), "iii", NULL }, - { SIG_SCIALL, 3, MAP_CALL(PaletteUnsetFlag), "iii", kPaletteUnsetFlag_workarounds }, - { SIG_SCIALL, 4, MAP_CALL(PaletteSetIntensity), "iii(i)", NULL }, - { SIG_SCIALL, 5, MAP_CALL(PaletteFindColor), "iii", NULL }, - { SIG_SCIALL, 6, MAP_CALL(PaletteAnimate), "i*", NULL }, - { SIG_SCIALL, 7, MAP_CALL(PaletteSave), "", NULL }, - { SIG_SCIALL, 8, MAP_CALL(PaletteRestore), "[r0]", NULL }, + { SIG_SCI16, 1, MAP_CALL(PaletteSetFromResource), "i(i)", NULL }, + { SIG_SCI16, 2, MAP_CALL(PaletteSetFlag), "iii", NULL }, + { SIG_SCI16, 3, MAP_CALL(PaletteUnsetFlag), "iii", kPaletteUnsetFlag_workarounds }, + { SIG_SCI16, 4, MAP_CALL(PaletteSetIntensity), "iii(i)", NULL }, + { SIG_SCI16, 5, MAP_CALL(PaletteFindColor), "iii", NULL }, + { SIG_SCI16, 6, MAP_CALL(PaletteAnimate), "i*", NULL }, + { SIG_SCI16, 7, MAP_CALL(PaletteSave), "", NULL }, + { SIG_SCI16, 8, MAP_CALL(PaletteRestore), "[r0]", NULL }, +#ifdef ENABLE_SCI32 + { SIG_SCI32, 1, MAP_CALL(PaletteSetFromResource32), "i(i)", NULL }, + { SIG_SCI32, 2, MAP_CALL(PaletteSetFade), "iii", NULL }, + { SIG_SCI32, 3, MAP_CALL(PaletteFindColor32), "iii", NULL }, + { SIG_SCI3, 4, MAP_CALL(PaletteSetGamma), "i", NULL }, +#endif SCI_SUBOPENTRY_TERMINATOR }; @@ -250,6 +339,17 @@ static const SciKernelMapSubEntry kFileIO_subops[] = { #ifdef ENABLE_SCI32 +// version, subId, function-mapping, signature, workarounds +static const SciKernelMapSubEntry kPalCycle_subops[] = { + { SIG_SCI32, 0, MAP_CALL(PalCycleSetCycle), "iii(i)", NULL }, + { SIG_SCI32, 1, MAP_CALL(PalCycleDoCycle), "i(i)", NULL }, + { SIG_SCI32, 2, MAP_CALL(PalCyclePause), "(i)", NULL }, + { SIG_SCI32, 3, MAP_CALL(PalCycleOn), "(i)", NULL }, + { SIG_SCI32, 4, MAP_CALL(PalCycleOff), "(i)", NULL }, + SCI_SUBOPENTRY_TERMINATOR +}; + +// version, subId, function-mapping, signature, workarounds static const SciKernelMapSubEntry kSave_subops[] = { { SIG_SCI32, 0, MAP_CALL(SaveGame), "[r0]i[r0](r0)", NULL }, { SIG_SCI32, 1, MAP_CALL(RestoreGame), "[r0]i[r0]", NULL }, @@ -264,32 +364,214 @@ static const SciKernelMapSubEntry kSave_subops[] = { }; // version, subId, function-mapping, signature, workarounds +static const SciKernelMapSubEntry kFont_subops[] = { + { SIG_SINCE_SCI21MID, 0, MAP_CALL(SetFontHeight), "i", NULL }, + { SIG_SINCE_SCI21MID, 1, MAP_CALL(SetFontRes), "ii", NULL }, + SCI_SUBOPENTRY_TERMINATOR +}; + +// version, subId, function-mapping, signature, workarounds +static const SciKernelMapSubEntry kText_subops[] = { + { SIG_SINCE_SCI21MID, 0, MAP_CALL(TextSize32), "r[r0]i(i)(i)", NULL }, + { SIG_SINCE_SCI21MID, 1, MAP_CALL(TextWidth), "ri", NULL }, + SCI_SUBOPENTRY_TERMINATOR +}; + +// version, subId, function-mapping, signature, workarounds +static const SciKernelMapSubEntry kBitmap_subops[] = { + { SIG_SINCE_SCI21, 0, MAP_CALL(BitmapCreate), "iiii(i)(i)(i)", NULL }, + { SIG_SINCE_SCI21, 1, MAP_CALL(BitmapDestroy), "[r!]", NULL }, + { SIG_SINCE_SCI21, 2, MAP_CALL(BitmapDrawLine), "riiiii(i)(i)", NULL }, + { SIG_SINCE_SCI21, 3, MAP_CALL(BitmapDrawView), "riii(i)(i)(0)(i)(i)", NULL }, + { SIG_SINCE_SCI21, 4, MAP_CALL(BitmapDrawText), "rriiiiiiiiiii", NULL }, + { SIG_SINCE_SCI21, 5, MAP_CALL(BitmapDrawColor), "riiiii", NULL }, + { SIG_SINCE_SCI21, 6, MAP_CALL(BitmapDrawBitmap), "rr(i)(i)(i)", NULL }, + { SIG_SINCE_SCI21, 7, MAP_CALL(BitmapInvert), "riiiiii", NULL }, + { SIG_SINCE_SCI21MID, 8, MAP_CALL(BitmapSetDisplace), "rii", NULL }, + { SIG_SINCE_SCI21MID, 9, MAP_CALL(BitmapCreateFromView), "iii(i)(i)(i)([r0])", NULL }, + { SIG_SINCE_SCI21MID, 10, MAP_CALL(BitmapCopyPixels), "rr", NULL }, + { SIG_SINCE_SCI21MID, 11, MAP_CALL(BitmapClone), "r", NULL }, + { SIG_SINCE_SCI21LATE, 12, MAP_CALL(BitmapGetInfo), "r(i)(i)", NULL }, + { SIG_SINCE_SCI21LATE, 13, MAP_CALL(BitmapScale), "r...ii", NULL }, + { SIG_SCI3, 14, MAP_CALL(BitmapCreateFromUnknown), "......", NULL }, + { SIG_SCI3, 15, MAP_EMPTY(Bitmap), "(.*)", NULL }, + { SIG_SCI3, 16, MAP_EMPTY(Bitmap), "(.*)", NULL }, + SCI_SUBOPENTRY_TERMINATOR +}; + +// version, subId, function-mapping, signature, workarounds +static const SciKernelMapSubEntry kCD_subops[] = { + { SIG_SINCE_SCI21MID, 0, MAP_CALL(CheckCD), "(i)", NULL }, + { SIG_SINCE_SCI21MID, 1, MAP_CALL(GetSavedCD), "", NULL }, + SCI_SUBOPENTRY_TERMINATOR +}; + +// version, subId, function-mapping, signature, workarounds static const SciKernelMapSubEntry kList_subops[] = { - { SIG_SCI21, 0, MAP_CALL(NewList), "", NULL }, - { SIG_SCI21, 1, MAP_CALL(DisposeList), "l", NULL }, - { SIG_SCI21, 2, MAP_CALL(NewNode), ".(.)", NULL }, - { SIG_SCI21, 3, MAP_CALL(FirstNode), "[l0]", NULL }, - { SIG_SCI21, 4, MAP_CALL(LastNode), "l", NULL }, - { SIG_SCI21, 5, MAP_CALL(EmptyList), "l", NULL }, - { SIG_SCI21, 6, MAP_CALL(NextNode), "n", NULL }, - { SIG_SCI21, 7, MAP_CALL(PrevNode), "n", NULL }, - { SIG_SCI21, 8, MAP_CALL(NodeValue), "[n0]", NULL }, - { SIG_SCI21, 9, MAP_CALL(AddAfter), "lnn.", NULL }, - { SIG_SCI21, 10, MAP_CALL(AddToFront), "ln.", NULL }, - { SIG_SCI21, 11, MAP_CALL(AddToEnd), "ln(.)", NULL }, - { SIG_SCI21, 12, MAP_CALL(AddBefore), "ln.", NULL }, - { SIG_SCI21, 13, MAP_CALL(MoveToFront), "ln", NULL }, - { SIG_SCI21, 14, MAP_CALL(MoveToEnd), "ln", NULL }, - { SIG_SCI21, 15, MAP_CALL(FindKey), "l.", NULL }, - { SIG_SCI21, 16, MAP_CALL(DeleteKey), "l.", NULL }, - { SIG_SCI21, 17, MAP_CALL(ListAt), "li", NULL }, - { SIG_SCI21, 18, MAP_CALL(ListIndexOf) , "l[io]", NULL }, - { SIG_SCI21, 19, MAP_CALL(ListEachElementDo), "li(.*)", NULL }, - { SIG_SCI21, 20, MAP_CALL(ListFirstTrue), "li(.*)", NULL }, - { SIG_SCI21, 21, MAP_CALL(ListAllTrue), "li(.*)", NULL }, - { SIG_SCI21, 22, MAP_CALL(Sort), "ooo", NULL }, + { SIG_SINCE_SCI21, 0, MAP_CALL(NewList), "", NULL }, + { SIG_SINCE_SCI21, 1, MAP_CALL(DisposeList), "l", NULL }, + { SIG_SINCE_SCI21, 2, MAP_CALL(NewNode), ".(.)", NULL }, + { SIG_SINCE_SCI21, 3, MAP_CALL(FirstNode), "[l0]", NULL }, + { SIG_SINCE_SCI21, 4, MAP_CALL(LastNode), "l", NULL }, + { SIG_SINCE_SCI21, 5, MAP_CALL(EmptyList), "l", NULL }, + { SIG_SINCE_SCI21, 6, MAP_CALL(NextNode), "n", NULL }, + { SIG_SINCE_SCI21, 7, MAP_CALL(PrevNode), "n", NULL }, + { SIG_SINCE_SCI21, 8, MAP_CALL(NodeValue), "[n0]", NULL }, + { SIG_SINCE_SCI21, 9, MAP_CALL(AddAfter), "lnn(.)", NULL }, + { SIG_SINCE_SCI21, 10, MAP_CALL(AddToFront), "ln(.)", NULL }, + { SIG_SINCE_SCI21, 11, MAP_CALL(AddToEnd), "ln(.)", NULL }, + { SIG_SINCE_SCI21, 12, MAP_CALL(AddBefore), "ln.", NULL }, + { SIG_SINCE_SCI21, 13, MAP_CALL(MoveToFront), "ln", NULL }, + { SIG_SINCE_SCI21, 14, MAP_CALL(MoveToEnd), "ln", NULL }, + { SIG_SINCE_SCI21, 15, MAP_CALL(FindKey), "l.", NULL }, + { SIG_SINCE_SCI21, 16, MAP_CALL(DeleteKey), "l.", NULL }, + { SIG_SINCE_SCI21, 17, MAP_CALL(ListAt), "li", NULL }, + { SIG_SINCE_SCI21, 18, MAP_CALL(ListIndexOf) , "l[io]", NULL }, + { SIG_SINCE_SCI21, 19, MAP_CALL(ListEachElementDo), "li(.*)", NULL }, + { SIG_SINCE_SCI21, 20, MAP_CALL(ListFirstTrue), "li(.*)", NULL }, + { SIG_SINCE_SCI21, 21, MAP_CALL(ListAllTrue), "li(.*)", NULL }, + { SIG_SINCE_SCI21, 22, MAP_CALL(Sort), "ooo", NULL }, + SCI_SUBOPENTRY_TERMINATOR +}; + +// version, subId, function-mapping, signature, workarounds +static const SciKernelMapSubEntry kShowMovieWin_subops[] = { + { SIG_SCI2, 0, MAP_CALL(ShowMovieWinOpen), "r", NULL }, + { SIG_SCI2, 1, MAP_CALL(ShowMovieWinInit), "ii(ii)", NULL }, + { SIG_SCI2, 2, MAP_CALL(ShowMovieWinPlay), "i", NULL }, + { SIG_SCI2, 6, MAP_CALL(ShowMovieWinClose), "", NULL }, + { SIG_SINCE_SCI21, 0, MAP_CALL(ShowMovieWinOpen), "ir", NULL }, + { SIG_SINCE_SCI21, 1, MAP_CALL(ShowMovieWinInit), "iii(ii)", NULL }, + { SIG_SINCE_SCI21, 2, MAP_CALL(ShowMovieWinPlay), "i(ii)(i)(i)", NULL }, + { SIG_SINCE_SCI21, 6, MAP_CALL(ShowMovieWinClose), "i", NULL }, + // Since movies are rendered within the graphics engine in ScummVM, + // it is not necessary to copy the palette from SCI to MCI, so this + // can be a no-op + { SIG_SINCE_SCI21, 7, MAP_EMPTY(ShowMovieWinSetPalette), "i", NULL }, + { SIG_SINCE_SCI21, 8, MAP_CALL(ShowMovieWinGetDuration), "i", NULL }, + { SIG_SINCE_SCI21, 11, MAP_CALL(ShowMovieWinCue), "ii", NULL }, + { SIG_SINCE_SCI21, 14, MAP_CALL(ShowMovieWinPlayUntilEvent), "i(i)", NULL }, + { SIG_SINCE_SCI21, 15, MAP_CALL(ShowMovieWinInitDouble), "iii", NULL }, + SCI_SUBOPENTRY_TERMINATOR +}; + +// There are a lot of subops to PlayVMD, but only a few of them are ever +// actually used by games +// version, subId, function-mapping, signature, workarounds +static const SciKernelMapSubEntry kPlayVMD_subops[] = { + { SIG_SINCE_SCI21, 0, MAP_CALL(PlayVMDOpen), "r(i)(i)", NULL }, + { SIG_SINCE_SCI21, 1, MAP_CALL(PlayVMDInit), "ii(i)(i)(ii)", NULL }, + { SIG_SINCE_SCI21, 6, MAP_CALL(PlayVMDClose), "", NULL }, + { SIG_SINCE_SCI21, 10, MAP_CALL(PlayVMDGetStatus), "", NULL }, + { SIG_SINCE_SCI21, 14, MAP_CALL(PlayVMDPlayUntilEvent), "i(i)(i)", NULL }, + { SIG_SINCE_SCI21, 16, MAP_CALL(PlayVMDShowCursor), "i", NULL }, + { SIG_SINCE_SCI21, 17, MAP_DUMMY(PlayVMDStartBlob), "", NULL }, + { SIG_SINCE_SCI21, 18, MAP_DUMMY(PlayVMDStopBlobs), "", NULL }, + { SIG_SINCE_SCI21, 21, MAP_CALL(PlayVMDSetBlackoutArea), "iiii", NULL }, + { SIG_SINCE_SCI21, 23, MAP_CALL(PlayVMDRestrictPalette), "ii", NULL }, + { SIG_SCI3, 28, MAP_EMPTY(PlayVMDSetPreload), "i", NULL }, + SCI_SUBOPENTRY_TERMINATOR +}; + +// version, subId, function-mapping, signature, workarounds +static const SciKernelMapSubEntry kRobot_subops[] = { + { SIG_SINCE_SCI21, 0, MAP_CALL(RobotOpen), "ioiii(i)", NULL }, + { SIG_SINCE_SCI21, 1, MAP_CALL(RobotShowFrame), "i(ii)", NULL }, + { SIG_SINCE_SCI21, 2, MAP_CALL(RobotGetFrameSize), "r", NULL }, + { SIG_SINCE_SCI21, 4, MAP_CALL(RobotPlay), "", NULL }, + { SIG_SINCE_SCI21, 5, MAP_CALL(RobotGetIsFinished), "", NULL }, + { SIG_SINCE_SCI21, 6, MAP_CALL(RobotGetIsPlaying), "", NULL }, + { SIG_SINCE_SCI21, 7, MAP_CALL(RobotClose), "", NULL }, + { SIG_SINCE_SCI21, 8, MAP_CALL(RobotGetCue), "o", NULL }, + { SIG_SINCE_SCI21, 10, MAP_CALL(RobotPause), "", NULL }, + { SIG_SINCE_SCI21, 11, MAP_CALL(RobotGetFrameNo), "", NULL }, + { SIG_SINCE_SCI21, 12, MAP_CALL(RobotSetPriority), "i", NULL }, + SCI_SUBOPENTRY_TERMINATOR +}; + +// version, subId, function-mapping, signature, workarounds +static const SciKernelMapSubEntry kRemapColors_subops[] = { + { SIG_SCI32, 0, MAP_CALL(RemapColorsOff), "(i)", NULL }, + { SIG_SCI32, 1, MAP_CALL(RemapColorsByRange), "iiii(i)", NULL }, + { SIG_SCI32, 2, MAP_CALL(RemapColorsByPercent), "ii(i)", NULL }, + { SIG_SCI32, 3, MAP_CALL(RemapColorsToGray), "ii(i)", NULL }, + { SIG_SCI32, 4, MAP_CALL(RemapColorsToPercentGray), "iii(i)", NULL }, + { SIG_SCI32, 5, MAP_CALL(RemapColorsBlockRange), "ii", NULL }, + SCI_SUBOPENTRY_TERMINATOR +}; + +// version, subId, function-mapping, signature, workarounds +static const SciKernelMapSubEntry kString_subops[] = { + { SIG_SCI32, 0, MAP_CALL(StringNew), "i(i)", NULL }, + { SIG_SCI32, 1, MAP_CALL(StringSize), "[or]", NULL }, + { SIG_SCI32, 2, MAP_CALL(StringAt), "[or]i", NULL }, + { SIG_SCI32, 3, MAP_CALL(StringPutAt), "[or]i(i*)", kStringPutAt_workarounds }, + // StringFree accepts invalid references + { SIG_SCI32, 4, MAP_CALL(StringFree), "[or0!]", NULL }, + { SIG_SCI32, 5, MAP_CALL(StringFill), "[or]ii", NULL }, + { SIG_SCI32, 6, MAP_CALL(StringCopy), "[or]i[or]ii", NULL }, + { SIG_SCI32, 7, MAP_CALL(StringCompare), "[or][or](i)", NULL }, + + // =SCI2, SCI2.1 Early and SCI2.1 Middle= + { SIG_UNTIL_SCI21MID, 8, MAP_CALL(StringDup), "[or]", NULL }, + // TODO: This gets called with null references in Torin. Check if this is correct, or it's + // caused by missing functionality + { SIG_UNTIL_SCI21MID, 9, MAP_CALL(StringGetData), "[or0]", NULL }, + { SIG_UNTIL_SCI21MID, 10, MAP_CALL(StringLen), "[or]", NULL }, + { SIG_UNTIL_SCI21MID, 11, MAP_CALL(StringPrintf), "[or](.*)", NULL }, + { SIG_UNTIL_SCI21MID, 12, MAP_CALL(StringPrintfBuf), "[or](.*)", NULL }, + { SIG_UNTIL_SCI21MID, 13, MAP_CALL(StringAtoi), "[or]", NULL }, + { SIG_UNTIL_SCI21MID, 14, MAP_CALL(StringTrim), "[or]i", NULL }, + { SIG_UNTIL_SCI21MID, 15, MAP_CALL(StringUpper), "[or]", NULL }, + { SIG_UNTIL_SCI21MID, 16, MAP_CALL(StringLower), "[or]", NULL }, + // the following 2 are unknown atm (happen in Phantasmagoria) + // possibly translate? + { SIG_UNTIL_SCI21MID, 17, MAP_CALL(StringTrn), "[or]", NULL }, + { SIG_UNTIL_SCI21MID, 18, MAP_CALL(StringTrnExclude), "[or]", NULL }, + + // SCI2.1 Late + SCI3 - kStringDup + kStringGetData were removed + { SIG_SINCE_SCI21LATE, 8, MAP_CALL(StringLen), "[or]", NULL }, + { SIG_SINCE_SCI21LATE, 9, MAP_CALL(StringPrintf), "[or](.*)", NULL }, + { SIG_SINCE_SCI21LATE,10, MAP_CALL(StringPrintfBuf), "[or](.*)", NULL }, + { SIG_SINCE_SCI21LATE,11, MAP_CALL(StringAtoi), "[or]", NULL }, + { SIG_SINCE_SCI21LATE,12, MAP_CALL(StringTrim), "[or]i", NULL }, + { SIG_SINCE_SCI21LATE,13, MAP_CALL(StringUpper), "[or]", NULL }, + { SIG_SINCE_SCI21LATE,14, MAP_CALL(StringLower), "[or]", NULL }, + { SIG_SINCE_SCI21LATE,15, MAP_CALL(StringTrn), "[or]", NULL }, + { SIG_SINCE_SCI21LATE,16, MAP_CALL(StringTrnExclude), "[or]", NULL }, + SCI_SUBOPENTRY_TERMINATOR +}; + +// version, subId, function-mapping, signature, workarounds +static const SciKernelMapSubEntry kScrollWindow_subops[] = { + { SIG_SCI32, 0, MAP_CALL(ScrollWindowCreate), "oi", NULL }, + { SIG_SCI32, 1, MAP_CALL(ScrollWindowAdd), "iriii(i)", kScrollWindowAdd_workarounds }, + { SIG_SCI32, 2, MAP_DUMMY(ScrollWindowClear), "i", NULL }, + { SIG_SCI32, 3, MAP_CALL(ScrollWindowPageUp), "i", NULL }, + { SIG_SCI32, 4, MAP_CALL(ScrollWindowPageDown), "i", NULL }, + { SIG_SCI32, 5, MAP_CALL(ScrollWindowUpArrow), "i", NULL }, + { SIG_SCI32, 6, MAP_CALL(ScrollWindowDownArrow), "i", NULL }, + { SIG_SCI32, 7, MAP_CALL(ScrollWindowHome), "i", NULL }, + { SIG_SCI32, 8, MAP_CALL(ScrollWindowEnd), "i", NULL }, + { SIG_SCI32, 9, MAP_DUMMY(ScrollWindowResize), "i.", NULL }, + { SIG_SCI32, 10, MAP_CALL(ScrollWindowWhere), "ii", NULL }, + { SIG_SCI32, 11, MAP_CALL(ScrollWindowGo), "i..", NULL }, + { SIG_SCI32, 12, MAP_DUMMY(ScrollWindowInsert), "i.....", NULL }, + { SIG_SCI32, 13, MAP_DUMMY(ScrollWindowDelete), "i.", NULL }, + { SIG_SCI32, 14, MAP_CALL(ScrollWindowModify), "iiriii(i)", NULL }, + { SIG_SCI32, 15, MAP_CALL(ScrollWindowHide), "i", NULL }, + { SIG_SCI32, 16, MAP_CALL(ScrollWindowShow), "i", NULL }, + { SIG_SCI32, 17, MAP_CALL(ScrollWindowDestroy), "i", NULL }, + // LSL6hires uses kScrollWindowText and kScrollWindowReconstruct to try to save + // and restore the content of the game's subtitle window, but this feature did not + // use the normal save/load functionality of the engine and was actually broken + // (all text formatting was missing on restore). Since there is no real reason to + // save the subtitle scrollback anyway, we just ignore calls to these two functions. + { SIG_SCI32, 18, MAP_EMPTY(ScrollWindowText), "i", NULL }, + { SIG_SCI32, 19, MAP_EMPTY(ScrollWindowReconstruct), "i.", NULL }, SCI_SUBOPENTRY_TERMINATOR }; + #endif struct SciKernelMapEntry { @@ -316,14 +598,21 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(Animate), SIG_EVERYWHERE, "(l0)(i)", NULL, NULL }, { MAP_CALL(AssertPalette), SIG_EVERYWHERE, "i", NULL, NULL }, { MAP_CALL(AvoidPath), SIG_EVERYWHERE, "ii(.*)", NULL, NULL }, - { MAP_CALL(BaseSetter), SIG_EVERYWHERE, "o", NULL, NULL }, + { MAP_CALL(BaseSetter), SIG_SCI16, SIGFOR_ALL, "o", NULL, NULL }, +#ifdef ENABLE_SCI32 + { "BaseSetter", kBaseSetter32, SIG_SCI32, SIGFOR_ALL, "o", NULL, NULL }, +#endif { MAP_CALL(CanBeHere), SIG_EVERYWHERE, "o(l)", NULL, NULL }, + { MAP_CALL(CantBeHere), SIG_SCI16, SIGFOR_ALL, "o(l)", NULL, NULL }, +#ifdef ENABLE_SCI32 + { MAP_CALL(CantBeHere), SIG_SCI32, SIGFOR_ALL, "ol", NULL, NULL }, +#endif + { MAP_CALL(CelHigh), SIG_SCI16, SIGFOR_ALL, "ii(i)", NULL, kCelHigh_workarounds }, + { MAP_CALL(CelWide), SIG_SCI16, SIGFOR_ALL, "ii(i)", NULL, kCelWide_workarounds }, #ifdef ENABLE_SCI32 - { "CantBeHere", kCantBeHere32, SIG_SCI32, SIGFOR_ALL, "ol", NULL, NULL }, + { "CelHigh", kCelHigh32, SIG_SCI32, SIGFOR_ALL, "iii", NULL, NULL }, + { "CelWide", kCelWide32, SIG_SCI32, SIGFOR_ALL, "iii", NULL, kCelWide_workarounds }, #endif - { MAP_CALL(CantBeHere), SIG_EVERYWHERE, "o(l)", NULL, NULL }, - { MAP_CALL(CelHigh), SIG_EVERYWHERE, "ii(i)", NULL, kCelHigh_workarounds }, - { MAP_CALL(CelWide), SIG_EVERYWHERE, "ii(i)", NULL, kCelWide_workarounds }, { MAP_CALL(CheckFreeSpace), SIG_SCI32, SIGFOR_ALL, "r.*", NULL, NULL }, { MAP_CALL(CheckFreeSpace), SIG_SCI11, SIGFOR_ALL, "r(i)", NULL, NULL }, { MAP_CALL(CheckFreeSpace), SIG_EVERYWHERE, "r", NULL, NULL }, @@ -341,7 +630,10 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(DisposeList), SIG_EVERYWHERE, "l", NULL, NULL }, { MAP_CALL(DisposeScript), SIG_EVERYWHERE, "i(i*)", NULL, kDisposeScript_workarounds }, { MAP_CALL(DisposeWindow), SIG_EVERYWHERE, "i(i)", NULL, NULL }, - { MAP_CALL(DoAudio), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, // subop + { MAP_CALL(DoAudio), SCI_VERSION_NONE, SCI_VERSION_2, SIGFOR_ALL, "i(.*)", NULL, NULL }, // subop +#ifdef ENABLE_SCI32 + { "DoAudio", kDoAudio32, SIG_SINCE_SCI21, SIGFOR_ALL, "(.*)", kDoAudio_subops, NULL }, +#endif { MAP_CALL(DoAvoider), SIG_EVERYWHERE, "o(i)", NULL, NULL }, { MAP_CALL(DoBresen), SIG_EVERYWHERE, "o", NULL, NULL }, { MAP_CALL(DoSound), SIG_EVERYWHERE, "i(.*)", kDoSound_subops, NULL }, @@ -378,8 +670,10 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(GetSaveDir), SIG_EVERYWHERE, "", NULL, NULL }, { MAP_CALL(GetSaveFiles), SIG_EVERYWHERE, "rrr", NULL, NULL }, { MAP_CALL(GetTime), SIG_EVERYWHERE, "(i)", NULL, NULL }, - { MAP_CALL(GlobalToLocal), SIG_SCI32, SIGFOR_ALL, "oo", NULL, NULL }, - { MAP_CALL(GlobalToLocal), SIG_EVERYWHERE, "o", NULL, NULL }, + { MAP_CALL(GlobalToLocal), SIG_SCI16, SIGFOR_ALL, "o", NULL, NULL }, +#ifdef ENABLE_SCI32 + { "GlobalToLocal", kGlobalToLocal32, SIG_SCI32, SIGFOR_ALL, "oo", NULL, NULL }, +#endif { MAP_CALL(Graph), SIG_EVERYWHERE, NULL, kGraph_subops, NULL }, { MAP_CALL(HaveMouse), SIG_EVERYWHERE, "", NULL, NULL }, { MAP_CALL(HiliteControl), SIG_EVERYWHERE, "o", NULL, NULL }, @@ -390,8 +684,10 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(Joystick), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, // subop { MAP_CALL(LastNode), SIG_EVERYWHERE, "l", NULL, NULL }, { MAP_CALL(Load), SIG_EVERYWHERE, "ii(i*)", NULL, NULL }, - { MAP_CALL(LocalToGlobal), SIG_SCI32, SIGFOR_ALL, "oo", NULL, NULL }, - { MAP_CALL(LocalToGlobal), SIG_EVERYWHERE, "o", NULL, NULL }, + { MAP_CALL(LocalToGlobal), SIG_SCI16, SIGFOR_ALL, "o", NULL, NULL }, +#ifdef ENABLE_SCI32 + { "LocalToGlobal", kLocalToGlobal32, SIG_SCI32, SIGFOR_ALL, "oo", NULL, NULL }, +#endif { MAP_CALL(Lock), SIG_EVERYWHERE, "ii(i)", NULL, NULL }, { MAP_CALL(MapKeyToDir), SIG_EVERYWHERE, "o", NULL, NULL }, { MAP_CALL(Memory), SIG_EVERYWHERE, "i(.*)", NULL, kMemory_workarounds }, // subop @@ -416,15 +712,19 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(Palette), SIG_EVERYWHERE, "i(.*)", kPalette_subops, NULL }, { MAP_CALL(Parse), SIG_EVERYWHERE, "ro", NULL, NULL }, { MAP_CALL(PicNotValid), SIG_EVERYWHERE, "(i)", NULL, NULL }, - { MAP_CALL(Platform), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_CALL(Platform), SIG_SCI16, SIGFOR_ALL, "(.*)", NULL, NULL }, +#ifdef ENABLE_SCI32 + { "Platform", kPlatform32, SIG_SCI32, SIGFOR_MAC, "(.*)", NULL, NULL }, + { "Platform", kPlatform32, SIG_SCI32, SIGFOR_ALL, "(i)", NULL, NULL }, +#endif { MAP_CALL(Portrait), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, // subop { MAP_CALL(PrevNode), SIG_EVERYWHERE, "n", NULL, NULL }, { MAP_CALL(PriCoord), SIG_EVERYWHERE, "i", NULL, NULL }, - { MAP_CALL(Random), SIG_EVERYWHERE, "i(i)(i)", NULL, NULL }, + { MAP_CALL(Random), SIG_EVERYWHERE, "i(i)(i)", NULL, kRandom_workarounds }, { MAP_CALL(ReadNumber), SIG_EVERYWHERE, "r", NULL, kReadNumber_workarounds }, { MAP_CALL(RemapColors), SIG_SCI11, SIGFOR_ALL, "i(i)(i)(i)(i)", NULL, NULL }, #ifdef ENABLE_SCI32 - { "RemapColors", kRemapColors32, SIG_SCI32, SIGFOR_ALL, "i(i)(i)(i)(i)(i)", NULL, NULL }, + { "RemapColors", kRemapColors32, SIG_SCI32, SIGFOR_ALL, "i(i)(i)(i)(i)(i)", kRemapColors_subops, NULL }, #endif { MAP_CALL(ResCheck), SIG_EVERYWHERE, "ii(iiii)", NULL, NULL }, { MAP_CALL(RespondsTo), SIG_EVERYWHERE, ".i", NULL, NULL }, @@ -433,20 +733,32 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(Said), SIG_EVERYWHERE, "[r0]", NULL, NULL }, { MAP_CALL(SaveGame), SIG_EVERYWHERE, "[r0]i[r0](r0)", NULL, NULL }, { MAP_CALL(ScriptID), SIG_EVERYWHERE, "[io](i)", NULL, NULL }, - { MAP_CALL(SetCursor), SIG_SCI21, SIGFOR_ALL, "i(i)([io])(i*)", NULL, NULL }, - // TODO: SCI2.1 may supply an object optionally (mother goose sci21 right on startup) - find out why { MAP_CALL(SetCursor), SIG_SCI11, SIGFOR_ALL, "i(i)(i)(i)(iiiiii)", NULL, NULL }, - { MAP_CALL(SetCursor), SIG_EVERYWHERE, "i(i)(i)(i)(i)", NULL, kSetCursor_workarounds }, + { MAP_CALL(SetCursor), SIG_SCI16, SIGFOR_ALL, "i(i)(i)(i)(i)", NULL, kSetCursor_workarounds }, +#ifdef ENABLE_SCI32 + { "SetCursor", kSetCursor32, SIG_SCI32, SIGFOR_ALL, "i(i)(i)(i)", NULL, kSetCursor_workarounds }, +#endif { MAP_CALL(SetDebug), SIG_EVERYWHERE, "(i*)", NULL, NULL }, { MAP_CALL(SetJump), SIG_EVERYWHERE, "oiii", NULL, NULL }, { MAP_CALL(SetMenu), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, - { MAP_CALL(SetNowSeen), SIG_EVERYWHERE, "o(i)", NULL, NULL }, + { MAP_CALL(SetNowSeen), SIG_SCI16, SIGFOR_ALL, "o(i)", NULL, NULL }, +#ifdef ENABLE_SCI32 + { "SetNowSeen", kSetNowSeen32, SIG_SCI32, SIGFOR_ALL, "o", NULL, NULL }, +#endif { MAP_CALL(SetPort), SIG_EVERYWHERE, "i(iiiii)(i)", NULL, kSetPort_workarounds }, { MAP_CALL(SetQuitStr), SIG_EVERYWHERE, "r", NULL, NULL }, { MAP_CALL(SetSynonyms), SIG_EVERYWHERE, "o", NULL, NULL }, { MAP_CALL(SetVideoMode), SIG_EVERYWHERE, "i", NULL, NULL }, - { MAP_CALL(ShakeScreen), SIG_EVERYWHERE, "(i)(i)", NULL, NULL }, - { MAP_CALL(ShowMovie), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_CALL(ShakeScreen), SIG_SCI16, SIGFOR_ALL, "(i)(i)", NULL, NULL }, +#ifdef ENABLE_SCI32 + { "ShakeScreen", kShakeScreen32, SIG_SCI32, SIGFOR_ALL, "i(i)", NULL, NULL }, +#endif + { MAP_CALL(ShowMovie), SIG_SCI16, SIGFOR_ALL, "(.*)", NULL, NULL }, +#ifdef ENABLE_SCI32 + { "ShowMovie", kShowMovie32, SIG_SCI32, SIGFOR_DOS, "ri(i)(i)", NULL, NULL }, + { "ShowMovie", kShowMovie32, SIG_SCI32, SIGFOR_MAC, "ri(i)(i)", NULL, NULL }, + { "ShowMovie", kShowMovieWin, SIG_SCI32, SIGFOR_WIN, "(.*)", kShowMovieWin_subops, NULL }, +#endif { MAP_CALL(Show), SIG_EVERYWHERE, "i", NULL, NULL }, { MAP_CALL(SinDiv), SIG_EVERYWHERE, "ii", NULL, NULL }, { MAP_CALL(Sort), SIG_EVERYWHERE, "ooo", NULL, NULL }, @@ -458,10 +770,10 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(StrEnd), SIG_EVERYWHERE, "r", NULL, NULL }, { MAP_CALL(StrLen), SIG_EVERYWHERE, "[r0]", NULL, kStrLen_workarounds }, { MAP_CALL(StrSplit), SIG_EVERYWHERE, "rr[r0]", NULL, NULL }, - { MAP_CALL(TextColors), SIG_EVERYWHERE, "(i*)", NULL, NULL }, - { MAP_CALL(TextFonts), SIG_EVERYWHERE, "(i*)", NULL, NULL }, - { MAP_CALL(TextSize), SIG_SCIALL, SIGFOR_MAC, "r[r0]i(i)(r0)(i)", NULL, NULL }, - { MAP_CALL(TextSize), SIG_EVERYWHERE, "r[r0]i(i)(r0)", NULL, NULL }, + { MAP_CALL(TextColors), SIG_SCI16, SIGFOR_ALL, "(i*)", NULL, NULL }, + { MAP_CALL(TextFonts), SIG_SCI16, SIGFOR_ALL, "(i*)", NULL, NULL }, + { MAP_CALL(TextSize), SIG_SCI16, SIGFOR_MAC, "r[r0]i(i)(r0)(i)", NULL, NULL }, + { MAP_CALL(TextSize), SIG_SCI16, SIGFOR_ALL, "r[r0]i(i)(r0)", NULL, NULL }, { MAP_CALL(TimesCos), SIG_EVERYWHERE, "ii", NULL, NULL }, { "CosMult", kTimesCos, SIG_EVERYWHERE, "ii", NULL, NULL }, { MAP_CALL(TimesCot), SIG_EVERYWHERE, "ii", NULL, NULL }, @@ -493,14 +805,18 @@ static SciKernelMapEntry s_kernelMap[] = { #ifdef ENABLE_SCI32 // SCI2 Kernel Functions // TODO: whoever knows his way through those calls, fix the signatures. + { "TextSize", kTextSize32, SIG_UNTIL_SCI21EARLY, SIGFOR_ALL, "r[r0]i(i)", NULL, NULL }, + { MAP_DUMMY(TextColors), SIG_UNTIL_SCI21EARLY, SIGFOR_ALL, "(.*)", NULL, NULL }, + { MAP_DUMMY(TextFonts), SIG_UNTIL_SCI21EARLY, SIGFOR_ALL, "(.*)", NULL, NULL }, + { MAP_CALL(AddPlane), SIG_EVERYWHERE, "o", NULL, NULL }, { MAP_CALL(AddScreenItem), SIG_EVERYWHERE, "o", NULL, NULL }, { MAP_CALL(Array), SIG_EVERYWHERE, "(.*)", NULL, NULL }, { MAP_CALL(CreateTextBitmap), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, { MAP_CALL(DeletePlane), SIG_EVERYWHERE, "o", NULL, NULL }, { MAP_CALL(DeleteScreenItem), SIG_EVERYWHERE, "o", NULL, NULL }, - { MAP_CALL(DisposeTextBitmap), SIG_EVERYWHERE, "r", NULL, NULL }, - { MAP_CALL(FrameOut), SIG_EVERYWHERE, "", NULL, NULL }, + { "DisposeTextBitmap", kBitmapDestroy, SIG_SCI2, SIGFOR_ALL, "[r!]", NULL, NULL }, + { MAP_CALL(FrameOut), SIG_EVERYWHERE, "(i)", NULL, NULL }, { MAP_CALL(GetHighPlanePri), SIG_EVERYWHERE, "", NULL, NULL }, { MAP_CALL(InPolygon), SIG_EVERYWHERE, "iio", NULL, NULL }, { MAP_CALL(IsHiRes), SIG_EVERYWHERE, "", NULL, NULL }, @@ -509,6 +825,8 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(ListEachElementDo), SIG_EVERYWHERE, "li(.*)", NULL, NULL }, { MAP_CALL(ListFirstTrue), SIG_EVERYWHERE, "li(.*)", NULL, NULL }, { MAP_CALL(ListIndexOf), SIG_EVERYWHERE, "l[o0]", NULL, NULL }, + // kMessageBox is used only by KQ7 1.51 + { MAP_CALL(MessageBox), SIG_SCI32, SIGFOR_ALL, "rri", NULL, NULL }, { "OnMe", kIsOnMe, SIG_EVERYWHERE, "iioi", NULL, NULL }, // Purge is used by the memory manager in SSCI to ensure that X number of bytes (the so called "unmovable // memory") are available when the current room changes. This is similar to the SCI0-SCI1.1 FlushResources @@ -517,15 +835,15 @@ static SciKernelMapEntry s_kernelMap[] = { // our garbage collector (i.e. the SCI0-SCI1.1 semantics). { "Purge", kFlushResources, SIG_EVERYWHERE, "i", NULL, NULL }, { MAP_CALL(SetShowStyle), SIG_EVERYWHERE, "ioiiiii([ri])(i)", NULL, NULL }, - { MAP_CALL(String), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_CALL(String), SIG_EVERYWHERE, "(.*)", kString_subops, NULL }, { MAP_CALL(UpdatePlane), SIG_EVERYWHERE, "o", NULL, NULL }, { MAP_CALL(UpdateScreenItem), SIG_EVERYWHERE, "o", NULL, NULL }, { MAP_CALL(ObjectIntersect), SIG_EVERYWHERE, "oo", NULL, NULL }, { MAP_CALL(EditText), SIG_EVERYWHERE, "o", NULL, NULL }, { MAP_CALL(MakeSaveCatName), SIG_EVERYWHERE, "rr", NULL, NULL }, { MAP_CALL(MakeSaveFileName), SIG_EVERYWHERE, "rri", NULL, NULL }, - { MAP_CALL(SetScroll), SIG_EVERYWHERE, "oiiiii(i)", NULL, NULL }, - { MAP_CALL(PalCycle), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, + { MAP_CALL(SetScroll), SIG_EVERYWHERE, "oiiii(i)(i)", NULL, NULL }, + { MAP_CALL(PalCycle), SIG_EVERYWHERE, "(.*)", kPalCycle_subops, NULL }, // SCI2 Empty functions @@ -561,39 +879,37 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_DUMMY(MarkMemory), SIG_EVERYWHERE, "(.*)", NULL, NULL }, { MAP_DUMMY(GetHighItemPri), SIG_EVERYWHERE, "(.*)", NULL, NULL }, { MAP_DUMMY(ShowStylePercent), SIG_EVERYWHERE, "(.*)", NULL, NULL }, - { MAP_DUMMY(InvertRect), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_DUMMY(InvertRect), SIG_UNTIL_SCI21EARLY, SIGFOR_ALL, "(.*)", NULL, NULL }, { MAP_DUMMY(InputText), SIG_EVERYWHERE, "(.*)", NULL, NULL }, - { MAP_DUMMY(TextWidth), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_CALL(TextWidth), SIG_UNTIL_SCI21EARLY, SIGFOR_ALL, "ri", NULL, NULL }, { MAP_DUMMY(PointSize), SIG_EVERYWHERE, "(.*)", NULL, NULL }, - // SetScroll is called by script 64909, Styler::doit(), but it doesn't seem to - // be used at all (plus, it was then changed to a dummy function in SCI3). - // Since this is most likely unused, and we got no test case, error out when - // it is called in order to find an actual call to it. - { MAP_DUMMY(SetScroll), SIG_EVERYWHERE, "(.*)", NULL, NULL }, // SCI2.1 Kernel Functions - { MAP_CALL(CD), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_CALL(CD), SIG_SINCE_SCI21MID, SIGFOR_ALL, "(.*)", kCD_subops, NULL }, { MAP_CALL(IsOnMe), SIG_EVERYWHERE, "iioi", NULL, NULL }, - { MAP_CALL(List), SIG_SCI21, SIGFOR_ALL, "(.*)", kList_subops, NULL }, + { MAP_CALL(List), SIG_SINCE_SCI21, SIGFOR_ALL, "(.*)", kList_subops, NULL }, { MAP_CALL(MulDiv), SIG_EVERYWHERE, "iii", NULL, NULL }, - { MAP_CALL(PlayVMD), SIG_EVERYWHERE, "(.*)", NULL, NULL }, - { MAP_CALL(Robot), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_CALL(PlayVMD), SIG_EVERYWHERE, "(.*)", kPlayVMD_subops, NULL }, + { MAP_CALL(Robot), SIG_EVERYWHERE, "(.*)", kRobot_subops, NULL }, { MAP_CALL(Save), SIG_EVERYWHERE, "i(.*)", kSave_subops, NULL }, - { MAP_CALL(Text), SIG_EVERYWHERE, "(.*)", NULL, NULL }, - { MAP_CALL(AddPicAt), SIG_EVERYWHERE, "oiii", NULL, NULL }, + { MAP_CALL(Text), SIG_SINCE_SCI21MID, SIGFOR_ALL, "i(.*)", kText_subops, NULL }, + { MAP_CALL(AddPicAt), SIG_EVERYWHERE, "oiii(i)(i)", NULL, NULL }, { MAP_CALL(GetWindowsOption), SIG_EVERYWHERE, "i", NULL, NULL }, { MAP_CALL(WinHelp), SIG_EVERYWHERE, "(.*)", NULL, NULL }, { MAP_CALL(GetConfig), SIG_EVERYWHERE, "ro", NULL, NULL }, { MAP_CALL(GetSierraProfileInt), SIG_EVERYWHERE, "rri", NULL, NULL }, - { MAP_CALL(CelInfo), SIG_EVERYWHERE, "iiiiii", NULL, NULL }, - { MAP_CALL(SetLanguage), SIG_EVERYWHERE, "r", NULL, NULL }, - { MAP_CALL(ScrollWindow), SIG_EVERYWHERE, "io(.*)", NULL, NULL }, - { MAP_CALL(SetFontRes), SIG_EVERYWHERE, "ii", NULL, NULL }, - { MAP_CALL(Font), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, - { MAP_CALL(Bitmap), SIG_EVERYWHERE, "(.*)", NULL, NULL }, - { MAP_CALL(AddLine), SIG_EVERYWHERE, "oiiiiiiiii", NULL, NULL }, - { MAP_CALL(UpdateLine), SIG_EVERYWHERE, "[r0]oiiiiiiiii", NULL, NULL }, - { MAP_CALL(DeleteLine), SIG_EVERYWHERE, "[r0]o", NULL, NULL }, + { MAP_CALL(CelInfo), SIG_SINCE_SCI21MID, SIGFOR_ALL, "iiiiii", NULL, NULL }, + { MAP_CALL(SetLanguage), SIG_SINCE_SCI21MID, SIGFOR_ALL, "r", NULL, NULL }, + { MAP_CALL(ScrollWindow), SIG_EVERYWHERE, "i(.*)", kScrollWindow_subops, NULL }, + { MAP_CALL(SetFontRes), SIG_SCI21EARLY, SIGFOR_ALL, "ii", NULL, NULL }, + { MAP_CALL(Font), SIG_SINCE_SCI21MID, SIGFOR_ALL, "i(.*)", kFont_subops, NULL }, + { MAP_CALL(Bitmap), SIG_EVERYWHERE, "(.*)", kBitmap_subops, NULL }, + { MAP_CALL(AddLine), SIG_EVERYWHERE, "oiiii(iiiii)", NULL, NULL }, + // The first argument is a ScreenItem instance ID that is created by the + // engine, not the VM; as a result, in ScummVM, this argument looks like + // an integer and not an object, although it is an object reference. + { MAP_CALL(UpdateLine), SIG_EVERYWHERE, "ioiiii(iiiii)", NULL, NULL }, + { MAP_CALL(DeleteLine), SIG_EVERYWHERE, "io", NULL, NULL }, // SCI2.1 Empty Functions @@ -642,16 +958,18 @@ static SciKernelMapEntry s_kernelMap[] = { // <lskovlun> The idea, if I understand correctly, is that the engine generates events // of a special HotRect type continuously when the mouse is on that rectangle - // MovePlaneItems - used by SQ6 to scroll through the inventory via the up/down buttons - // SetPalStyleRange - 2 integer parameters, start and end. All styles from start-end - // (inclusive) are set to 0 - // MorphOn - used by SQ6, script 900, the datacorder reprogramming puzzle (from room 270) + // Used by SQ6 to scroll through the inventory via the up/down buttons + { MAP_CALL(MovePlaneItems), SIG_SINCE_SCI21, SIGFOR_ALL, "oii(i)", NULL, NULL }, + + { MAP_CALL(SetPalStyleRange), SIG_EVERYWHERE, "ii", NULL, NULL }, + + { MAP_CALL(MorphOn), SIG_EVERYWHERE, "", NULL, NULL }, // SCI3 Kernel Functions - { MAP_CALL(PlayDuck), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_CALL(PlayDuck), SIG_EVERYWHERE, "(.*)", NULL, NULL }, #endif - { NULL, NULL, SIG_EVERYWHERE, NULL, NULL, NULL } + { NULL, NULL, SIG_EVERYWHERE, NULL, NULL, NULL } }; /** Default kernel name table. */ @@ -945,7 +1263,6 @@ static const char *const sci2_default_knames[] = { /*0x89*/ "TextWidth", // for debugging(?), only in SCI2, not used in any SCI2 game /*0x8a*/ "PointSize", // for debugging(?), only in SCI2, not used in any SCI2 game - // GK2 Demo (and similar) only kernel functions /*0x8b*/ "AddLine", /*0x8c*/ "DeleteLine", /*0x8d*/ "UpdateLine", |