aboutsummaryrefslogtreecommitdiff
path: root/engines/glk/adrift/sctafpar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/glk/adrift/sctafpar.cpp')
-rw-r--r--engines/glk/adrift/sctafpar.cpp5840
1 files changed, 2883 insertions, 2957 deletions
diff --git a/engines/glk/adrift/sctafpar.cpp b/engines/glk/adrift/sctafpar.cpp
index 269308a953..9880603faf 100644
--- a/engines/glk/adrift/sctafpar.cpp
+++ b/engines/glk/adrift/sctafpar.cpp
@@ -42,9 +42,9 @@ namespace Adrift {
/* Assorted definitions and constants. */
static const sc_char NUL = '\0';
-enum
-{ PARSE_TEMP_LENGTH = 256,
- PARSE_MAX_DEPTH = 32
+enum {
+ PARSE_TEMP_LENGTH = 256,
+ PARSE_MAX_DEPTH = 32
};
/* Multiline separator sequences for the various versions supported. */
@@ -71,257 +71,382 @@ static const sc_byte V380_SEPARATOR[SEPARATOR_SIZE] = {0x2a, 0x2a, 0x00};
* |...| - fixup specials for versions < 4
* {special} - because some things just defy description
*/
-typedef struct
-{
- const sc_char *const class_name;
- const sc_char *const descriptor;
+typedef struct {
+ const sc_char *const class_name;
+ const sc_char *const descriptor;
} sc_parse_schema_t;
/* Version 4.0 TAF file properties descriptor table. */
static const sc_parse_schema_t V400_PARSE_SCHEMA[] = {
- {"_GAME_",
- "<HEADER>Header <GLOBAL>Globals V<ROOM>Rooms V<OBJECT>Objects V<TASK>Tasks"
- " V<EVENT>Events V<NPC>NPCs V<ROOM_GROUP>RoomGroups V<SYNONYM>Synonyms"
- " V<VARIABLE>Variables V<ALR>ALRs BCustomFont ?BCustomFont:$FontNameSize"
- " $CompileDate"},
- {"HEADER",
- "MStartupText #StartRoom MWinText"},
- {"GLOBAL",
- "$GameName $GameAuthor $DontUnderstand #Perspective BShowExits #WaitTurns"
- " BDispFirstRoom BBattleSystem #MaxScore $PlayerName BPromptName $PlayerDesc"
- " #Task ?!#Task=0:$AltDesc #Position #ParentObject #PlayerGender"
- " #MaxSize #MaxWt ?GBattleSystem:<BATTLE>Battle BEightPointCompass bNoDebug"
- " BNoScoreNotify BNoMap bNoAutoComplete bNoControlPanel bNoMouse BSound"
- " BGraphics <RESOURCE>IntroRes <RESOURCE>WinRes BStatusBox $StatusBoxText"
- " iUnk1 iUnk2 BEmbedded"},
- {"BATTLE",
- "iStaminaLo iStaminaHi iStrengthLo iStrengthHi iAccuracyLo iAccuracyHi"
- " iDefenseLo iDefenseHi iAgilityLo iAgilityHi iRecovery"},
- {"ROOM",
- "$Short $Long ?GEightPointCompass:[12]<ROOM_EXIT>Exits"
- " ?!GEightPointCompass:[8]<ROOM_EXIT>Exits <RESOURCE>Res V<ROOM_ALT>Alts"
- " ?!GNoMap:bHideOnMap"},
- {"ROOM_EXIT",
- "{V400_ROOM_EXIT:#Dest_#Var1_#Var2_#Var3}"},
- {"ROOM_ALT",
- "$M1 #Type <RESOURCE>Res1 $M2 #Var2 <RESOURCE>Res2 #HideObjects $Changed"
- " #Var3 #DisplayRoom"},
- {"RESOURCE",
- "?GSound:$SoundFile,#SoundLen,ZSoundOffset"
- " ?GGraphics:$GraphicFile,#GraphicLen,ZGraphicOffset {V400_RESOURCE}"},
- {"OBJECT",
- "$Prefix $Short V$Alias BStatic $Description #InitialPosition #Task"
- " BTaskNotDone $AltDesc ?BStatic:<ROOM_LIST1>Where BContainer BSurface"
- " #Capacity ?!BStatic:BWearable,#SizeWeight,#Parent"
- " ?BStatic:{OBJECT:#Parent} #Openable ?#Openable=5:#Key ?#Openable=6:#Key"
- " ?#Openable=7:#Key #SitLie ?!BStatic:BEdible BReadable ?BReadable:$ReadText"
- " ?!BStatic:BWeapon #CurrentState ?!#CurrentState=0:$States,BStateListed"
- " BListFlag <RESOURCE>Res1 <RESOURCE>Res2 ?GBattleSystem:<OBJ_BATTLE>Battle"
- " $InRoomDesc #OnlyWhenNotMoved"},
- {"OBJ_BATTLE",
- "iProtectionValue iHitValue iMethod iAccuracy"},
- {"ROOM_LIST1",
- "#Type {ROOM_LIST1}"},
- {"TASK",
- "V$Command $CompleteText $ReverseMessage $RepeatText $AdditionalMessage"
- " #ShowRoomDesc BRepeatable BReversible V$ReverseCommand <ROOM_LIST0>Where"
- " $Question ?$Question:$Hint1,$Hint2 V<TASK_RESTR>Restrictions"
- " V<TASK_ACTION>Actions $RestrMask <RESOURCE>Res"},
- {"TASK_RESTR",
- "#Type ?#Type=0:#Var1,#Var2,#Var3 ?#Type=1:#Var1,#Var2 ?#Type=2:#Var1,#Var2"
- " ?#Type=3:#Var1,#Var2,#Var3 ?#Type=4:#Var1,#Var2,#Var3,$Var4 $FailMessage"},
- {"TASK_ACTION",
- "#Type ?#Type=0:#Var1,#Var2,#Var3 ?#Type=1:#Var1,#Var2,#Var3"
- " ?#Type=2:#Var1,#Var2 ?#Type=3:#Var1,#Var2,#Var3,$Expr,#Var5"
- " ?#Type=4:#Var1 ?#Type=5:#Var1,#Var2 ?#Type=6:#Var1,#Var2,#Var3"
- " ?#Type=7:iVar1,iVar2,iVar3"},
- {"ROOM_LIST0",
- "#Type {ROOM_LIST0}"},
- {"EVENT",
- "$Short #StarterType ?#StarterType=2:#StartTime,#EndTime"
- " ?#StarterType=3:#TaskNum #RestartType BTaskFinished #Time1 #Time2"
- " $StartText $LookText $FinishText <ROOM_LIST0>Where #PauseTask"
- " BPauserCompleted #PrefTime1 $PrefText1 #ResumeTask BResumerCompleted"
- " #PrefTime2 $PrefText2 #Obj2 #Obj2Dest #Obj3 #Obj3Dest #Obj1 #Obj1Dest"
- " #TaskAffected [5]<RESOURCE>Res"},
- {"NPC",
- "$Name $Prefix V$Alias $Descr #StartRoom $AltText #Task V<TOPIC>Topics"
- " V<WALK>Walks BShowEnterExit ?BShowEnterExit:$EnterText,$ExitText"
- " $InRoomText #Gender [4]<RESOURCE>Res ?GBattleSystem:<NPC_BATTLE>Battle"},
- {"NPC_BATTLE",
- "iAttitude iStaminaLo iStaminaHi iStrengthLo iStrengthHi iAccuracyLo"
- " iAccuracyHi iDefenseLo iDefenseHi iAgilityLo iAgilityHi iSpeed"
- " iKilledTask iRecovery iStaminaTask"},
- {"TOPIC",
- "$Subject $Reply #Task $AltReply"},
- {"WALK",
- "#NumStops BLoop #StartTask #CharTask #MeetObject #ObjectTask #StoppingTask"
- " #MeetChar $ChangedDesc {WALK:#Rooms_#Times}"},
- {"ROOM_GROUP",
- "$Name {ROOM_GROUP:[]BList}"},
- {"SYNONYM",
- "$Replacement $Original"},
- {"VARIABLE",
- "$Name #Type $Value"},
- {"ALR",
- "$Original $Replacement"},
- {NULL, NULL}
+ {
+ "_GAME_",
+ "<HEADER>Header <GLOBAL>Globals V<ROOM>Rooms V<OBJECT>Objects V<TASK>Tasks"
+ " V<EVENT>Events V<NPC>NPCs V<ROOM_GROUP>RoomGroups V<SYNONYM>Synonyms"
+ " V<VARIABLE>Variables V<ALR>ALRs BCustomFont ?BCustomFont:$FontNameSize"
+ " $CompileDate"
+ },
+ {
+ "HEADER",
+ "MStartupText #StartRoom MWinText"
+ },
+ {
+ "GLOBAL",
+ "$GameName $GameAuthor $DontUnderstand #Perspective BShowExits #WaitTurns"
+ " BDispFirstRoom BBattleSystem #MaxScore $PlayerName BPromptName $PlayerDesc"
+ " #Task ?!#Task=0:$AltDesc #Position #ParentObject #PlayerGender"
+ " #MaxSize #MaxWt ?GBattleSystem:<BATTLE>Battle BEightPointCompass bNoDebug"
+ " BNoScoreNotify BNoMap bNoAutoComplete bNoControlPanel bNoMouse BSound"
+ " BGraphics <RESOURCE>IntroRes <RESOURCE>WinRes BStatusBox $StatusBoxText"
+ " iUnk1 iUnk2 BEmbedded"
+ },
+ {
+ "BATTLE",
+ "iStaminaLo iStaminaHi iStrengthLo iStrengthHi iAccuracyLo iAccuracyHi"
+ " iDefenseLo iDefenseHi iAgilityLo iAgilityHi iRecovery"
+ },
+ {
+ "ROOM",
+ "$Short $Long ?GEightPointCompass:[12]<ROOM_EXIT>Exits"
+ " ?!GEightPointCompass:[8]<ROOM_EXIT>Exits <RESOURCE>Res V<ROOM_ALT>Alts"
+ " ?!GNoMap:bHideOnMap"
+ },
+ {
+ "ROOM_EXIT",
+ "{V400_ROOM_EXIT:#Dest_#Var1_#Var2_#Var3}"
+ },
+ {
+ "ROOM_ALT",
+ "$M1 #Type <RESOURCE>Res1 $M2 #Var2 <RESOURCE>Res2 #HideObjects $Changed"
+ " #Var3 #DisplayRoom"
+ },
+ {
+ "RESOURCE",
+ "?GSound:$SoundFile,#SoundLen,ZSoundOffset"
+ " ?GGraphics:$GraphicFile,#GraphicLen,ZGraphicOffset {V400_RESOURCE}"
+ },
+ {
+ "OBJECT",
+ "$Prefix $Short V$Alias BStatic $Description #InitialPosition #Task"
+ " BTaskNotDone $AltDesc ?BStatic:<ROOM_LIST1>Where BContainer BSurface"
+ " #Capacity ?!BStatic:BWearable,#SizeWeight,#Parent"
+ " ?BStatic:{OBJECT:#Parent} #Openable ?#Openable=5:#Key ?#Openable=6:#Key"
+ " ?#Openable=7:#Key #SitLie ?!BStatic:BEdible BReadable ?BReadable:$ReadText"
+ " ?!BStatic:BWeapon #CurrentState ?!#CurrentState=0:$States,BStateListed"
+ " BListFlag <RESOURCE>Res1 <RESOURCE>Res2 ?GBattleSystem:<OBJ_BATTLE>Battle"
+ " $InRoomDesc #OnlyWhenNotMoved"
+ },
+ {
+ "OBJ_BATTLE",
+ "iProtectionValue iHitValue iMethod iAccuracy"
+ },
+ {
+ "ROOM_LIST1",
+ "#Type {ROOM_LIST1}"
+ },
+ {
+ "TASK",
+ "V$Command $CompleteText $ReverseMessage $RepeatText $AdditionalMessage"
+ " #ShowRoomDesc BRepeatable BReversible V$ReverseCommand <ROOM_LIST0>Where"
+ " $Question ?$Question:$Hint1,$Hint2 V<TASK_RESTR>Restrictions"
+ " V<TASK_ACTION>Actions $RestrMask <RESOURCE>Res"
+ },
+ {
+ "TASK_RESTR",
+ "#Type ?#Type=0:#Var1,#Var2,#Var3 ?#Type=1:#Var1,#Var2 ?#Type=2:#Var1,#Var2"
+ " ?#Type=3:#Var1,#Var2,#Var3 ?#Type=4:#Var1,#Var2,#Var3,$Var4 $FailMessage"
+ },
+ {
+ "TASK_ACTION",
+ "#Type ?#Type=0:#Var1,#Var2,#Var3 ?#Type=1:#Var1,#Var2,#Var3"
+ " ?#Type=2:#Var1,#Var2 ?#Type=3:#Var1,#Var2,#Var3,$Expr,#Var5"
+ " ?#Type=4:#Var1 ?#Type=5:#Var1,#Var2 ?#Type=6:#Var1,#Var2,#Var3"
+ " ?#Type=7:iVar1,iVar2,iVar3"
+ },
+ {
+ "ROOM_LIST0",
+ "#Type {ROOM_LIST0}"
+ },
+ {
+ "EVENT",
+ "$Short #StarterType ?#StarterType=2:#StartTime,#EndTime"
+ " ?#StarterType=3:#TaskNum #RestartType BTaskFinished #Time1 #Time2"
+ " $StartText $LookText $FinishText <ROOM_LIST0>Where #PauseTask"
+ " BPauserCompleted #PrefTime1 $PrefText1 #ResumeTask BResumerCompleted"
+ " #PrefTime2 $PrefText2 #Obj2 #Obj2Dest #Obj3 #Obj3Dest #Obj1 #Obj1Dest"
+ " #TaskAffected [5]<RESOURCE>Res"
+ },
+ {
+ "NPC",
+ "$Name $Prefix V$Alias $Descr #StartRoom $AltText #Task V<TOPIC>Topics"
+ " V<WALK>Walks BShowEnterExit ?BShowEnterExit:$EnterText,$ExitText"
+ " $InRoomText #Gender [4]<RESOURCE>Res ?GBattleSystem:<NPC_BATTLE>Battle"
+ },
+ {
+ "NPC_BATTLE",
+ "iAttitude iStaminaLo iStaminaHi iStrengthLo iStrengthHi iAccuracyLo"
+ " iAccuracyHi iDefenseLo iDefenseHi iAgilityLo iAgilityHi iSpeed"
+ " iKilledTask iRecovery iStaminaTask"
+ },
+ {
+ "TOPIC",
+ "$Subject $Reply #Task $AltReply"
+ },
+ {
+ "WALK",
+ "#NumStops BLoop #StartTask #CharTask #MeetObject #ObjectTask #StoppingTask"
+ " #MeetChar $ChangedDesc {WALK:#Rooms_#Times}"
+ },
+ {
+ "ROOM_GROUP",
+ "$Name {ROOM_GROUP:[]BList}"
+ },
+ {
+ "SYNONYM",
+ "$Replacement $Original"
+ },
+ {
+ "VARIABLE",
+ "$Name #Type $Value"
+ },
+ {
+ "ALR",
+ "$Original $Replacement"
+ },
+ {NULL, NULL}
};
/* Version 3.9 TAF file properties descriptor table. */
static const sc_parse_schema_t V390_PARSE_SCHEMA[] = {
- {"_GAME_",
- "<HEADER>Header <GLOBAL>Globals V<ROOM>Rooms V<OBJECT>Objects V<TASK>Tasks"
- " V<EVENT>Events V<NPC>NPCs V<ROOM_GROUP>RoomGroups V<SYNONYM>Synonyms"
- " V<VARIABLE>Variables V<ALR>ALRs BCustomFont ?BCustomFont:$FontNameSize"
- " $CompileDate sPassword"},
- {"HEADER",
- "MStartupText #StartRoom MWinText"},
- {"GLOBAL",
- "$GameName $GameAuthor $DontUnderstand #Perspective BShowExits #WaitTurns"
- " BDispFirstRoom BBattleSystem #MaxScore $PlayerName BPromptName $PlayerDesc"
- " #Task ?!#Task=0:$AltDesc #Position #ParentObject #PlayerGender"
- " #MaxSize #MaxWt ?GBattleSystem:<BATTLE>Battle BEightPointCompass bNoDebug"
- " BNoScoreNotify BNoMap bNoAutoComplete bNoControlPanel bNoMouse"
- " BSound BGraphics <RESOURCE>IntroRes <RESOURCE>WinRes FStatusBox"
- " EStatusBoxText iUnk1 iUnk2 FEmbedded"},
- {"BATTLE",
- "iStamina iStrength iDefense"},
- {"ROOM",
- "$Short $Long $LastDesc ?GEightPointCompass:[12]<ROOM_EXIT>Exits"
- " ?!GEightPointCompass:[8]<ROOM_EXIT>Exits $AddDesc1 #Task1 $AddDesc2 #Task2"
- " #Obj $AltDesc #TypeHideObjects <RESOURCE>Res <RESOURCE>LastRes"
- " <RESOURCE>Task1Res <RESOURCE>Task2Res <RESOURCE>AltRes"
- " ?!GNoMap:bHideOnMap |V390_ROOM:_Alts_|"},
- {"ROOM_EXIT",
- "{V390_V380_ROOM_EXIT:#Dest_#Var1_#Var2_ZVar3}"},
- {"RESOURCE",
- "?GSound:$SoundFile,ZSoundLen,ZSoundOffset"
- " ?GGraphics:$GraphicFile,ZGraphicLen,ZGraphicOffset"},
- {"OBJECT",
- "$Prefix $Short"
- " [1]$Alias BStatic $Description #InitialPosition #Task BTaskNotDone"
- " $AltDesc ?BStatic:<ROOM_LIST1>Where BContainer BSurface #Capacity"
- " ?!BStatic:BWearable,#SizeWeight,#Parent ?BStatic:{OBJECT:#Parent}"
- " #Openable |V390_OBJECT:_Openable_,Key| #SitLie ?!BStatic:BEdible BReadable"
- " ?BReadable:$ReadText ?!BStatic:BWeapon ZCurrentState FListFlag"
- " <RESOURCE>Res1 <RESOURCE>Res2 ?GBattleSystem:<OBJ_BATTLE>Battle"
- " EInRoomDesc ZOnlyWhenNotMoved"},
- {"OBJ_BATTLE",
- "iProtectionValue iHitValue iMethod"},
- {"ROOM_LIST1",
- "#Type {ROOM_LIST1}"},
- {"TASK",
- "W$Command $CompleteText $ReverseMessage $RepeatText $AdditionalMessage"
- " #ShowRoomDesc BRepeatable BReversible W$ReverseCommand <ROOM_LIST0>Where"
- " $Question ?$Question:$Hint1,$Hint2 V<TASK_RESTR>Restrictions"
- " V<TASK_ACTION>Actions |V390_TASK:$RestrMask| <RESOURCE>Res"},
- {"TASK_RESTR",
- "#Type ?#Type=0:#Var1,#Var2,#Var3 ?#Type=1:#Var1,#Var2 ?#Type=2:#Var1,#Var2"
- " ?#Type=3:#Var1,#Var2,#Var3 ?#Type=4:#Var1,#Var2,#Var3,EVar4"
- ",|V390_TASK_RESTR:Var1>0?#Var1++| $FailMessage"},
- {"TASK_ACTION",
- "#Type |V390_TASK_ACTION:Type>4?#Type++| ?#Type=0:#Var1,#Var2,#Var3"
- " ?#Type=1:#Var1,#Var2,#Var3 ?#Type=2:#Var1,#Var2"
- " ?#Type=3:#Var1,#Var2,#Var3,|V390_TASK_ACTION:$Expr_#Var5|"
- " ?#Type=4:#Var1 ?#Type=6:#Var1,ZVar2,ZVar3 ?#Type=7:iVar1,iVar2,iVar3"},
- {"ROOM_LIST0",
- "#Type {ROOM_LIST0}"},
- {"EVENT",
- "$Short #StarterType ?#StarterType=2:#StartTime,#EndTime"
- " ?#StarterType=3:#TaskNum #RestartType BTaskFinished #Time1 #Time2"
- " $StartText $LookText $FinishText <ROOM_LIST0>Where #PauseTask"
- " BPauserCompleted #PrefTime1 $PrefText1 #ResumeTask BResumerCompleted"
- " #PrefTime2 $PrefText2 #Obj2 #Obj2Dest #Obj3 #Obj3Dest #Obj1 #Obj1Dest"
- " #TaskAffected [5]<RESOURCE>Res"},
- {"NPC",
- "$Name $Prefix [1]$Alias $Descr #StartRoom $AltText #Task V<TOPIC>Topics"
- " V<WALK>Walks BShowEnterExit ?BShowEnterExit:$EnterText,$ExitText"
- " $InRoomText #Gender [4]<RESOURCE>Res ?GBattleSystem:<NPC_BATTLE>Battle"},
- {"NPC_BATTLE",
- "iAttitude iStamina iStrength iDefense iSpeed iKilledTask"},
- {"TOPIC",
- "$Subject $Reply #Task $AltReply"},
- {"WALK",
- "#NumStops BLoop #StartTask #CharTask #MeetObject #ObjectTask #StoppingTask"
- " ZMeetChar $ChangedDesc {WALK:#Rooms_#Times}"},
- {"ROOM_GROUP",
- "$Name {ROOM_GROUP:[]BList}"},
- {"SYNONYM",
- "$Replacement $Original"},
- {"VARIABLE",
- "$Name ZType $Value"},
- {"ALR",
- "$Original $Replacement"},
- {NULL, NULL}
+ {
+ "_GAME_",
+ "<HEADER>Header <GLOBAL>Globals V<ROOM>Rooms V<OBJECT>Objects V<TASK>Tasks"
+ " V<EVENT>Events V<NPC>NPCs V<ROOM_GROUP>RoomGroups V<SYNONYM>Synonyms"
+ " V<VARIABLE>Variables V<ALR>ALRs BCustomFont ?BCustomFont:$FontNameSize"
+ " $CompileDate sPassword"
+ },
+ {
+ "HEADER",
+ "MStartupText #StartRoom MWinText"
+ },
+ {
+ "GLOBAL",
+ "$GameName $GameAuthor $DontUnderstand #Perspective BShowExits #WaitTurns"
+ " BDispFirstRoom BBattleSystem #MaxScore $PlayerName BPromptName $PlayerDesc"
+ " #Task ?!#Task=0:$AltDesc #Position #ParentObject #PlayerGender"
+ " #MaxSize #MaxWt ?GBattleSystem:<BATTLE>Battle BEightPointCompass bNoDebug"
+ " BNoScoreNotify BNoMap bNoAutoComplete bNoControlPanel bNoMouse"
+ " BSound BGraphics <RESOURCE>IntroRes <RESOURCE>WinRes FStatusBox"
+ " EStatusBoxText iUnk1 iUnk2 FEmbedded"
+ },
+ {
+ "BATTLE",
+ "iStamina iStrength iDefense"
+ },
+ {
+ "ROOM",
+ "$Short $Long $LastDesc ?GEightPointCompass:[12]<ROOM_EXIT>Exits"
+ " ?!GEightPointCompass:[8]<ROOM_EXIT>Exits $AddDesc1 #Task1 $AddDesc2 #Task2"
+ " #Obj $AltDesc #TypeHideObjects <RESOURCE>Res <RESOURCE>LastRes"
+ " <RESOURCE>Task1Res <RESOURCE>Task2Res <RESOURCE>AltRes"
+ " ?!GNoMap:bHideOnMap |V390_ROOM:_Alts_|"
+ },
+ {
+ "ROOM_EXIT",
+ "{V390_V380_ROOM_EXIT:#Dest_#Var1_#Var2_ZVar3}"
+ },
+ {
+ "RESOURCE",
+ "?GSound:$SoundFile,ZSoundLen,ZSoundOffset"
+ " ?GGraphics:$GraphicFile,ZGraphicLen,ZGraphicOffset"
+ },
+ {
+ "OBJECT",
+ "$Prefix $Short"
+ " [1]$Alias BStatic $Description #InitialPosition #Task BTaskNotDone"
+ " $AltDesc ?BStatic:<ROOM_LIST1>Where BContainer BSurface #Capacity"
+ " ?!BStatic:BWearable,#SizeWeight,#Parent ?BStatic:{OBJECT:#Parent}"
+ " #Openable |V390_OBJECT:_Openable_,Key| #SitLie ?!BStatic:BEdible BReadable"
+ " ?BReadable:$ReadText ?!BStatic:BWeapon ZCurrentState FListFlag"
+ " <RESOURCE>Res1 <RESOURCE>Res2 ?GBattleSystem:<OBJ_BATTLE>Battle"
+ " EInRoomDesc ZOnlyWhenNotMoved"
+ },
+ {
+ "OBJ_BATTLE",
+ "iProtectionValue iHitValue iMethod"
+ },
+ {
+ "ROOM_LIST1",
+ "#Type {ROOM_LIST1}"
+ },
+ {
+ "TASK",
+ "W$Command $CompleteText $ReverseMessage $RepeatText $AdditionalMessage"
+ " #ShowRoomDesc BRepeatable BReversible W$ReverseCommand <ROOM_LIST0>Where"
+ " $Question ?$Question:$Hint1,$Hint2 V<TASK_RESTR>Restrictions"
+ " V<TASK_ACTION>Actions |V390_TASK:$RestrMask| <RESOURCE>Res"
+ },
+ {
+ "TASK_RESTR",
+ "#Type ?#Type=0:#Var1,#Var2,#Var3 ?#Type=1:#Var1,#Var2 ?#Type=2:#Var1,#Var2"
+ " ?#Type=3:#Var1,#Var2,#Var3 ?#Type=4:#Var1,#Var2,#Var3,EVar4"
+ ",|V390_TASK_RESTR:Var1>0?#Var1++| $FailMessage"
+ },
+ {
+ "TASK_ACTION",
+ "#Type |V390_TASK_ACTION:Type>4?#Type++| ?#Type=0:#Var1,#Var2,#Var3"
+ " ?#Type=1:#Var1,#Var2,#Var3 ?#Type=2:#Var1,#Var2"
+ " ?#Type=3:#Var1,#Var2,#Var3,|V390_TASK_ACTION:$Expr_#Var5|"
+ " ?#Type=4:#Var1 ?#Type=6:#Var1,ZVar2,ZVar3 ?#Type=7:iVar1,iVar2,iVar3"
+ },
+ {
+ "ROOM_LIST0",
+ "#Type {ROOM_LIST0}"
+ },
+ {
+ "EVENT",
+ "$Short #StarterType ?#StarterType=2:#StartTime,#EndTime"
+ " ?#StarterType=3:#TaskNum #RestartType BTaskFinished #Time1 #Time2"
+ " $StartText $LookText $FinishText <ROOM_LIST0>Where #PauseTask"
+ " BPauserCompleted #PrefTime1 $PrefText1 #ResumeTask BResumerCompleted"
+ " #PrefTime2 $PrefText2 #Obj2 #Obj2Dest #Obj3 #Obj3Dest #Obj1 #Obj1Dest"
+ " #TaskAffected [5]<RESOURCE>Res"
+ },
+ {
+ "NPC",
+ "$Name $Prefix [1]$Alias $Descr #StartRoom $AltText #Task V<TOPIC>Topics"
+ " V<WALK>Walks BShowEnterExit ?BShowEnterExit:$EnterText,$ExitText"
+ " $InRoomText #Gender [4]<RESOURCE>Res ?GBattleSystem:<NPC_BATTLE>Battle"
+ },
+ {
+ "NPC_BATTLE",
+ "iAttitude iStamina iStrength iDefense iSpeed iKilledTask"
+ },
+ {
+ "TOPIC",
+ "$Subject $Reply #Task $AltReply"
+ },
+ {
+ "WALK",
+ "#NumStops BLoop #StartTask #CharTask #MeetObject #ObjectTask #StoppingTask"
+ " ZMeetChar $ChangedDesc {WALK:#Rooms_#Times}"
+ },
+ {
+ "ROOM_GROUP",
+ "$Name {ROOM_GROUP:[]BList}"
+ },
+ {
+ "SYNONYM",
+ "$Replacement $Original"
+ },
+ {
+ "VARIABLE",
+ "$Name ZType $Value"
+ },
+ {
+ "ALR",
+ "$Original $Replacement"
+ },
+ {NULL, NULL}
};
/* Version 3.8 TAF file properties descriptor table. */
static const sc_parse_schema_t V380_PARSE_SCHEMA[] = {
- {"_GAME_",
- "<HEADER>Header <GLOBAL>Globals V<ROOM>Rooms V<OBJECT>Objects V<TASK>Tasks"
- " V<EVENT>Events V<NPC>NPCs V<ROOM_GROUP>RoomGroups V<SYNONYM>Synonyms"
- " FCustomFont $CompileDate sPassword |V380_GLOBAL:_MaxScore_|"
- " |V380_OBJECT:_InitialPositions_|"},
- {"HEADER",
- "MStartupText #StartRoom MWinText"},
- {"GLOBAL",
- "$GameName $GameAuthor #MaxCarried |V380_MaxSize_MaxWt_| $DontUnderstand"
- " #Perspective BShowExits #WaitTurns FDispFirstRoom FBattleSystem"
- " EPlayerName FPromptName EPlayerDesc ZTask ZPosition ZParentObject"
- " ZPlayerGender FEightPointCompass TNoScoreNotify FSound FGraphics"
- " FStatusBox EStatusBoxText FEmbedded"},
- {"ROOM",
- "$Short $Long $LastDesc [8]<ROOM_EXIT>Exits $AddDesc1 #Task1 $AddDesc2"
- " #Task2 #Obj $AltDesc #TypeHideObjects |V380_ROOM:_Alts_|"},
- {"ROOM_EXIT",
- "{V390_V380_ROOM_EXIT:#Dest_#Var1_#Var2_ZVar3}"},
- {"OBJECT",
- "$Prefix $Short [1]$Alias BStatic $Description #InitialPosition #Task"
- " BTaskNotDone $AltDesc ?BStatic:<ROOM_LIST1>Where #SurfaceContainer"
- " FSurface ?#SurfaceContainer=2:TSurface FContainer"
- " ?#SurfaceContainer=1:TContainer #Capacity |V380_OBJECT:#Capacity*10+2|"
- " ?!BStatic:BWearable,#SizeWeight,#Parent ?BStatic:{OBJECT:#Parent}"
- " #Openable |V380_OBJECT:_Openable_,Key| #SitLie ?!BStatic:BEdible BReadable"
- " ?BReadable:$ReadText ?!BStatic:BWeapon ZCurrentState FListFlag"
- " EInRoomDesc ZOnlyWhenNotMoved"},
- {"ROOM_LIST1",
- "#Type {ROOM_LIST1}"},
- {"TASK",
- "W$Command $CompleteText $ReverseMessage $RepeatText $AdditionalMessage"
- " #ShowRoomDesc BRepeatable #Score BSingleScore [6]<TASK_MOVE>Movements"
- " BReversible W$ReverseCommand #WearObj1 #WearObj2 #HoldObj1 #HoldObj2"
- " #HoldObj3 #Obj1 #Task BTaskNotDone $TaskMsg $HoldMsg $WearMsg $CompanyMsg"
- " BNotInSameRoom #NPC $Obj1Msg #Obj1Room <ROOM_LIST0>Where BKillsPlayer"
- " BHoldingSameRoom $Question ?$Question:$Hint1,$Hint2 #Obj2"
- " ?!#Obj2=0:#Obj2Var1,#Obj2Var2,$Obj2Msg BWinGame |V380_TASK:_Actions_|"
- " |V380_TASK:_Restrictions_|"},
- {"TASK_MOVE",
- "#Var1 #Var2 #Var3"},
- {"ROOM_LIST0",
- "#Type {ROOM_LIST0}"},
- {"EVENT",
- "$Short #StarterType ?#StarterType=2:#StartTime,#EndTime"
- " ?#StarterType=3:#TaskNum #RestartType BTaskFinished #Time1 #Time2"
- " $StartText $LookText $FinishText <ROOM_LIST0>Where #PauseTask"
- " BPauserCompleted #PrefTime1 $PrefText1 #ResumeTask BResumerCompleted"
- " #PrefTime2 $PrefText2 #Obj2 #Obj2Dest #Obj3 #Obj3Dest #Obj1 #Obj1Dest"
- " #TaskAffected"},
- {"NPC",
- "$Name $Prefix [1]$Alias $Descr #StartRoom $AltText #Task V<TOPIC>Topics"
- " V<WALK>Walks BShowEnterExit ?BShowEnterExit:$EnterText,$ExitText"
- " $InRoomText ZGender"},
- {"TOPIC",
- "$Subject $Reply #Task $AltReply"},
- {"WALK",
- "#NumStops BLoop #StartTask #CharTask #MeetObject"
- " ?!#MeetObject=0:|V380_WALK:_MeetObject_| #ObjectTask ZMeetChar"
- " {WALK:#Rooms_#Times} ZStoppingTask EChangedDesc"},
- {"ROOM_GROUP",
- "$Name {ROOM_GROUP:[]BList}"},
- {"SYNONYM",
- "$Replacement $Original"},
- {NULL, NULL}
+ {
+ "_GAME_",
+ "<HEADER>Header <GLOBAL>Globals V<ROOM>Rooms V<OBJECT>Objects V<TASK>Tasks"
+ " V<EVENT>Events V<NPC>NPCs V<ROOM_GROUP>RoomGroups V<SYNONYM>Synonyms"
+ " FCustomFont $CompileDate sPassword |V380_GLOBAL:_MaxScore_|"
+ " |V380_OBJECT:_InitialPositions_|"
+ },
+ {
+ "HEADER",
+ "MStartupText #StartRoom MWinText"
+ },
+ {
+ "GLOBAL",
+ "$GameName $GameAuthor #MaxCarried |V380_MaxSize_MaxWt_| $DontUnderstand"
+ " #Perspective BShowExits #WaitTurns FDispFirstRoom FBattleSystem"
+ " EPlayerName FPromptName EPlayerDesc ZTask ZPosition ZParentObject"
+ " ZPlayerGender FEightPointCompass TNoScoreNotify FSound FGraphics"
+ " FStatusBox EStatusBoxText FEmbedded"
+ },
+ {
+ "ROOM",
+ "$Short $Long $LastDesc [8]<ROOM_EXIT>Exits $AddDesc1 #Task1 $AddDesc2"
+ " #Task2 #Obj $AltDesc #TypeHideObjects |V380_ROOM:_Alts_|"
+ },
+ {
+ "ROOM_EXIT",
+ "{V390_V380_ROOM_EXIT:#Dest_#Var1_#Var2_ZVar3}"
+ },
+ {
+ "OBJECT",
+ "$Prefix $Short [1]$Alias BStatic $Description #InitialPosition #Task"
+ " BTaskNotDone $AltDesc ?BStatic:<ROOM_LIST1>Where #SurfaceContainer"
+ " FSurface ?#SurfaceContainer=2:TSurface FContainer"
+ " ?#SurfaceContainer=1:TContainer #Capacity |V380_OBJECT:#Capacity*10+2|"
+ " ?!BStatic:BWearable,#SizeWeight,#Parent ?BStatic:{OBJECT:#Parent}"
+ " #Openable |V380_OBJECT:_Openable_,Key| #SitLie ?!BStatic:BEdible BReadable"
+ " ?BReadable:$ReadText ?!BStatic:BWeapon ZCurrentState FListFlag"
+ " EInRoomDesc ZOnlyWhenNotMoved"
+ },
+ {
+ "ROOM_LIST1",
+ "#Type {ROOM_LIST1}"
+ },
+ {
+ "TASK",
+ "W$Command $CompleteText $ReverseMessage $RepeatText $AdditionalMessage"
+ " #ShowRoomDesc BRepeatable #Score BSingleScore [6]<TASK_MOVE>Movements"
+ " BReversible W$ReverseCommand #WearObj1 #WearObj2 #HoldObj1 #HoldObj2"
+ " #HoldObj3 #Obj1 #Task BTaskNotDone $TaskMsg $HoldMsg $WearMsg $CompanyMsg"
+ " BNotInSameRoom #NPC $Obj1Msg #Obj1Room <ROOM_LIST0>Where BKillsPlayer"
+ " BHoldingSameRoom $Question ?$Question:$Hint1,$Hint2 #Obj2"
+ " ?!#Obj2=0:#Obj2Var1,#Obj2Var2,$Obj2Msg BWinGame |V380_TASK:_Actions_|"
+ " |V380_TASK:_Restrictions_|"
+ },
+ {
+ "TASK_MOVE",
+ "#Var1 #Var2 #Var3"
+ },
+ {
+ "ROOM_LIST0",
+ "#Type {ROOM_LIST0}"
+ },
+ {
+ "EVENT",
+ "$Short #StarterType ?#StarterType=2:#StartTime,#EndTime"
+ " ?#StarterType=3:#TaskNum #RestartType BTaskFinished #Time1 #Time2"
+ " $StartText $LookText $FinishText <ROOM_LIST0>Where #PauseTask"
+ " BPauserCompleted #PrefTime1 $PrefText1 #ResumeTask BResumerCompleted"
+ " #PrefTime2 $PrefText2 #Obj2 #Obj2Dest #Obj3 #Obj3Dest #Obj1 #Obj1Dest"
+ " #TaskAffected"
+ },
+ {
+ "NPC",
+ "$Name $Prefix [1]$Alias $Descr #StartRoom $AltText #Task V<TOPIC>Topics"
+ " V<WALK>Walks BShowEnterExit ?BShowEnterExit:$EnterText,$ExitText"
+ " $InRoomText ZGender"
+ },
+ {
+ "TOPIC",
+ "$Subject $Reply #Task $AltReply"
+ },
+ {
+ "WALK",
+ "#NumStops BLoop #StartTask #CharTask #MeetObject"
+ " ?!#MeetObject=0:|V380_WALK:_MeetObject_| #ObjectTask ZMeetChar"
+ " {WALK:#Rooms_#Times} ZStoppingTask EChangedDesc"
+ },
+ {
+ "ROOM_GROUP",
+ "$Name {ROOM_GROUP:[]BList}"
+ },
+ {
+ "SYNONYM",
+ "$Replacement $Original"
+ },
+ {NULL, NULL}
};
@@ -331,21 +456,19 @@ static const sc_parse_schema_t V380_PARSE_SCHEMA[] = {
* Select one of the parse schemata based on a TAF file.
*/
static const sc_parse_schema_t *
-parse_select_schema (sc_tafref_t taf)
-{
- /* Switch based on the TAF file version. */
- switch (taf_get_version (taf))
- {
- case TAF_VERSION_400:
- return V400_PARSE_SCHEMA;
- case TAF_VERSION_390:
- return V390_PARSE_SCHEMA;
- case TAF_VERSION_380:
- return V380_PARSE_SCHEMA;
- default:
- sc_fatal ("parse_select_schema: invalid TAF file version\n");
- return NULL;
- }
+parse_select_schema(sc_tafref_t taf) {
+ /* Switch based on the TAF file version. */
+ switch (taf_get_version(taf)) {
+ case TAF_VERSION_400:
+ return V400_PARSE_SCHEMA;
+ case TAF_VERSION_390:
+ return V390_PARSE_SCHEMA;
+ case TAF_VERSION_380:
+ return V380_PARSE_SCHEMA;
+ default:
+ sc_fatal("parse_select_schema: invalid TAF file version\n");
+ return NULL;
+ }
}
@@ -377,24 +500,22 @@ static sc_int parse_depth = 0;
* off on unwind.
*/
static void
-parse_push_key (sc_vartype_t vt_key, sc_char type)
-{
- if (parse_depth == PARSE_MAX_DEPTH)
- sc_fatal ("parse_push_key: stack overrun\n");
-
- /* Push the key, and its associated type. */
- parse_vt_key[parse_depth] = vt_key;
- parse_format[parse_depth] = type;
- parse_depth++;
+parse_push_key(sc_vartype_t vt_key, sc_char type) {
+ if (parse_depth == PARSE_MAX_DEPTH)
+ sc_fatal("parse_push_key: stack overrun\n");
+
+ /* Push the key, and its associated type. */
+ parse_vt_key[parse_depth] = vt_key;
+ parse_format[parse_depth] = type;
+ parse_depth++;
}
static void
-parse_pop_key (void)
-{
- /* Check the stack has something to pop, then pop it. */
- if (parse_depth == 0)
- sc_fatal ("parse_pop_key: stack underrun\n");
- parse_depth--;
+parse_pop_key(void) {
+ /* Check the stack has something to pop, then pop it. */
+ if (parse_depth == 0)
+ sc_fatal("parse_pop_key: stack underrun\n");
+ parse_depth--;
}
@@ -406,35 +527,30 @@ parse_pop_key (void)
* value
*/
static void
-parse_retrieve_stack (sc_char format[], sc_vartype_t vt_key[], sc_int *depth)
-{
- sc_int index_;
-
- /* Switch index-string key pairs. */
- for (index_ = 0; index_ < parse_depth; index_++)
- {
- if (index_ < parse_depth - 1
- && parse_format[index_] == PROP_KEY_INTEGER
- && parse_format[index_ + 1] == PROP_KEY_STRING)
- {
- /* Swap format and key elements. */
- format[index_] = parse_format[index_ + 1];
- format[index_ + 1] = parse_format[index_];
- vt_key[index_] = parse_vt_key[index_ + 1];
- vt_key[index_ + 1] = parse_vt_key[index_];
-
- index_++;
- }
- else
- {
- /* Simple copy of format and key elements. */
- format[index_] = parse_format[index_];
- vt_key[index_] = parse_vt_key[index_];
- }
- }
-
- /* Return the parse depth. */
- *depth = parse_depth;
+parse_retrieve_stack(sc_char format[], sc_vartype_t vt_key[], sc_int *depth) {
+ sc_int index_;
+
+ /* Switch index-string key pairs. */
+ for (index_ = 0; index_ < parse_depth; index_++) {
+ if (index_ < parse_depth - 1
+ && parse_format[index_] == PROP_KEY_INTEGER
+ && parse_format[index_ + 1] == PROP_KEY_STRING) {
+ /* Swap format and key elements. */
+ format[index_] = parse_format[index_ + 1];
+ format[index_ + 1] = parse_format[index_];
+ vt_key[index_] = parse_vt_key[index_ + 1];
+ vt_key[index_ + 1] = parse_vt_key[index_];
+
+ index_++;
+ } else {
+ /* Simple copy of format and key elements. */
+ format[index_] = parse_format[index_];
+ vt_key[index_] = parse_vt_key[index_];
+ }
+ }
+
+ /* Return the parse depth. */
+ *depth = parse_depth;
}
@@ -445,33 +561,31 @@ parse_retrieve_stack (sc_char format[], sc_vartype_t vt_key[], sc_int *depth)
* be a bad game.
*/
static void
-parse_stack_backtrace (void)
-{
- sc_vartype_t vt_key[PARSE_MAX_DEPTH];
- sc_char format[PARSE_MAX_DEPTH];
- sc_int depth, index_;
-
- parse_retrieve_stack (format, vt_key, &depth);
-
- sc_error ("parse_stack_backtrace: version %s schema parsed to depth %ld\n",
- (parse_schema == V400_PARSE_SCHEMA) ? "4.00" :
- (parse_schema == V390_PARSE_SCHEMA) ? "3.90" :
- (parse_schema == V380_PARSE_SCHEMA) ? "3.80" : "[Invalid]",
- depth);
-
- sc_error ("parse_stack_backtrace: parse stack backtrace follows...\n");
- for (index_ = 0; index_ < depth; index_++)
- {
- sc_char type;
-
- type = format[index_];
- if (type == PROP_KEY_INTEGER)
- sc_error ("%2ld - [%c] %ld\n", index_, type, vt_key[index_].integer);
- else if (type == PROP_KEY_STRING)
- sc_error ("%2ld - [%c] \"%s\"\n", index_, type, vt_key[index_].string);
- else
- sc_error ("%2ld - [%c] %p\n", index_, type, vt_key[index_].voidp);
- }
+parse_stack_backtrace(void) {
+ sc_vartype_t vt_key[PARSE_MAX_DEPTH];
+ sc_char format[PARSE_MAX_DEPTH];
+ sc_int depth, index_;
+
+ parse_retrieve_stack(format, vt_key, &depth);
+
+ sc_error("parse_stack_backtrace: version %s schema parsed to depth %ld\n",
+ (parse_schema == V400_PARSE_SCHEMA) ? "4.00" :
+ (parse_schema == V390_PARSE_SCHEMA) ? "3.90" :
+ (parse_schema == V380_PARSE_SCHEMA) ? "3.80" : "[Invalid]",
+ depth);
+
+ sc_error("parse_stack_backtrace: parse stack backtrace follows...\n");
+ for (index_ = 0; index_ < depth; index_++) {
+ sc_char type;
+
+ type = format[index_];
+ if (type == PROP_KEY_INTEGER)
+ sc_error("%2ld - [%c] %ld\n", index_, type, vt_key[index_].integer);
+ else if (type == PROP_KEY_STRING)
+ sc_error("%2ld - [%c] \"%s\"\n", index_, type, vt_key[index_].string);
+ else
+ sc_error("%2ld - [%c] %p\n", index_, type, vt_key[index_].voidp);
+ }
}
@@ -482,48 +596,46 @@ parse_stack_backtrace (void)
* Write or read a property based on the keys amassed so far.
*/
static void
-parse_put_property (sc_vartype_t vt_value, sc_char type)
-{
- sc_vartype_t vt_key[PARSE_MAX_DEPTH];
- sc_char format[PARSE_MAX_DEPTH + 4];
- sc_int depth;
-
- /* Retrieve the adjusted stack. */
- parse_retrieve_stack (format + 3, vt_key, &depth);
-
- /* Complete the format for the property put. */
- format[0] = type;
- format[1] = '-';
- format[2] = '>';
- format[depth + 3] = NUL;
-
- /* Store the property under the stacked keys. */
- assert (parse_bundle);
- prop_put (parse_bundle, format, vt_value, vt_key);
+parse_put_property(sc_vartype_t vt_value, sc_char type) {
+ sc_vartype_t vt_key[PARSE_MAX_DEPTH];
+ sc_char format[PARSE_MAX_DEPTH + 4];
+ sc_int depth;
+
+ /* Retrieve the adjusted stack. */
+ parse_retrieve_stack(format + 3, vt_key, &depth);
+
+ /* Complete the format for the property put. */
+ format[0] = type;
+ format[1] = '-';
+ format[2] = '>';
+ format[depth + 3] = NUL;
+
+ /* Store the property under the stacked keys. */
+ assert(parse_bundle);
+ prop_put(parse_bundle, format, vt_value, vt_key);
}
static sc_bool
-parse_get_property (sc_vartype_t *vt_rvalue, sc_char type)
-{
- sc_vartype_t vt_key[PARSE_MAX_DEPTH];
- sc_char format[PARSE_MAX_DEPTH + 4];
- sc_int depth;
- sc_bool status;
-
- /* Retrieve the adjusted stack. */
- parse_retrieve_stack (format + 3, vt_key, &depth);
-
- /* Complete the format for the property put. */
- format[0] = type;
- format[1] = '<';
- format[2] = '-';
- format[depth + 3] = NUL;
-
- /* Retrieve the property using the stacked keys. */
- assert (parse_bundle);
- status = prop_get (parse_bundle, format, vt_rvalue, vt_key);
-
- return status;
+parse_get_property(sc_vartype_t *vt_rvalue, sc_char type) {
+ sc_vartype_t vt_key[PARSE_MAX_DEPTH];
+ sc_char format[PARSE_MAX_DEPTH + 4];
+ sc_int depth;
+ sc_bool status;
+
+ /* Retrieve the adjusted stack. */
+ parse_retrieve_stack(format + 3, vt_key, &depth);
+
+ /* Complete the format for the property put. */
+ format[0] = type;
+ format[1] = '<';
+ format[2] = '-';
+ format[depth + 3] = NUL;
+
+ /* Retrieve the property using the stacked keys. */
+ assert(parse_bundle);
+ status = prop_get(parse_bundle, format, vt_rvalue, vt_key);
+
+ return status;
}
@@ -535,14 +647,13 @@ parse_get_property (sc_vartype_t *vt_rvalue, sc_char type)
* no such node exists.
*/
static sc_int
-parse_get_child_count (void)
-{
- sc_vartype_t vt_rvalue;
+parse_get_child_count(void) {
+ sc_vartype_t vt_rvalue;
- if (!parse_get_property (&vt_rvalue, PROP_INTEGER))
- vt_rvalue.integer = 0;
+ if (!parse_get_property(&vt_rvalue, PROP_INTEGER))
+ vt_rvalue.integer = 0;
- return vt_rvalue.integer;
+ return vt_rvalue.integer;
}
@@ -555,36 +666,33 @@ parse_get_child_count (void)
* a fatal error if the property does not exist.
*/
static sc_int
-parse_get_integer_property (void)
-{
- sc_vartype_t vt_rvalue;
+parse_get_integer_property(void) {
+ sc_vartype_t vt_rvalue;
- if (!parse_get_property (&vt_rvalue, PROP_INTEGER))
- sc_fatal ("parse_get_integer_property: missing property\n");
+ if (!parse_get_property(&vt_rvalue, PROP_INTEGER))
+ sc_fatal("parse_get_integer_property: missing property\n");
- return vt_rvalue.integer;
+ return vt_rvalue.integer;
}
static sc_bool
-parse_get_boolean_property (void)
-{
- sc_vartype_t vt_rvalue;
+parse_get_boolean_property(void) {
+ sc_vartype_t vt_rvalue;
- if (!parse_get_property (&vt_rvalue, PROP_BOOLEAN))
- sc_fatal ("parse_get_boolean_property: missing property\n");
+ if (!parse_get_property(&vt_rvalue, PROP_BOOLEAN))
+ sc_fatal("parse_get_boolean_property: missing property\n");
- return vt_rvalue.boolean;
+ return vt_rvalue.boolean;
}
static const sc_char *
-parse_get_string_property (void)
-{
- sc_vartype_t vt_rvalue;
+parse_get_string_property(void) {
+ sc_vartype_t vt_rvalue;
- if (!parse_get_property (&vt_rvalue, PROP_STRING))
- sc_fatal ("parse_get_string_property: missing property\n");
+ if (!parse_get_property(&vt_rvalue, PROP_STRING))
+ sc_fatal("parse_get_string_property: missing property\n");
- return vt_rvalue.string;
+ return vt_rvalue.string;
}
@@ -606,132 +714,121 @@ static sc_bool parse_use_pushback = FALSE;
* TAF line pushback.
*/
static const sc_char *
-parse_get_taf_string (void)
-{
- const sc_char *line;
-
- /* If pushback requested, use that instead of reading. */
- if (parse_use_pushback)
- {
- /* Use the pushback line, and clear the request. */
- assert (parse_pushback_line);
- line = parse_pushback_line;
- parse_use_pushback = FALSE;
- }
- else
- {
- /* Get the next line, and complain if absent. */
- line = taf_next_line (parse_taf);
- if (!line)
- {
- sc_error ("parse_get_taf_string:"
- " out of TAF data at line %ld\n", parse_tafline);
- parse_stack_backtrace ();
- longjmp (parse_taf_error, 1);
- }
-
- /* Note this line for possible pushback. */
- parse_pushback_line = line;
- }
-
- /* Print out the line we're parsing if tracing. */
- if (parse_trace)
- sc_trace ("Parse: read in line %ld : %s\n", parse_tafline, line);
-
- parse_tafline++;
- return line;
+parse_get_taf_string(void) {
+ const sc_char *line;
+
+ /* If pushback requested, use that instead of reading. */
+ if (parse_use_pushback) {
+ /* Use the pushback line, and clear the request. */
+ assert(parse_pushback_line);
+ line = parse_pushback_line;
+ parse_use_pushback = FALSE;
+ } else {
+ /* Get the next line, and complain if absent. */
+ line = taf_next_line(parse_taf);
+ if (!line) {
+ sc_error("parse_get_taf_string:"
+ " out of TAF data at line %ld\n", parse_tafline);
+ parse_stack_backtrace();
+ longjmp(parse_taf_error, 1);
+ }
+
+ /* Note this line for possible pushback. */
+ parse_pushback_line = line;
+ }
+
+ /* Print out the line we're parsing if tracing. */
+ if (parse_trace)
+ sc_trace("Parse: read in line %ld : %s\n", parse_tafline, line);
+
+ parse_tafline++;
+ return line;
}
static sc_int
-parse_get_taf_integer (void)
-{
- const sc_char *line;
- sc_int integer;
-
- /* Get line, and scan for a single integer; return it. */
- line = parse_get_taf_string ();
- if (sscanf (line, "%ld", &integer) != 1)
- {
- sc_error ("parse_get_taf_integer:"
- " invalid integer at line %ld\n", parse_tafline - 1);
- parse_stack_backtrace ();
- longjmp (parse_taf_error, 1);
- }
-
- return integer;
+parse_get_taf_integer(void) {
+ const sc_char *line;
+ sc_int integer;
+
+ /* Get line, and scan for a single integer; return it. */
+ line = parse_get_taf_string();
+ if (sscanf(line, "%ld", &integer) != 1) {
+ sc_error("parse_get_taf_integer:"
+ " invalid integer at line %ld\n", parse_tafline - 1);
+ parse_stack_backtrace();
+ longjmp(parse_taf_error, 1);
+ }
+
+ return integer;
}
static sc_bool
-parse_get_taf_boolean (void)
-{
- const sc_char *line;
- sc_uint boolean;
-
- /*
- * Get line, and scan for a single integer; check it's a valid-looking flag,
- * and return it.
- */
- line = parse_get_taf_string ();
- if (sscanf (line, "%lu", &boolean) != 1)
- {
- sc_error ("parse_get_taf_boolean:"
- " invalid boolean at line %ld\n", parse_tafline - 1);
- parse_stack_backtrace ();
- longjmp (parse_taf_error, 1);
- }
- if (boolean != 0 && boolean != 1)
- {
- sc_error ("parse_get_taf_boolean:"
- " warning: suspect boolean at line %ld\n", parse_tafline - 1);
- }
-
- return boolean != 0;
+parse_get_taf_boolean(void) {
+ const sc_char *line;
+ sc_uint boolean;
+
+ /*
+ * Get line, and scan for a single integer; check it's a valid-looking flag,
+ * and return it.
+ */
+ line = parse_get_taf_string();
+ if (sscanf(line, "%lu", &boolean) != 1) {
+ sc_error("parse_get_taf_boolean:"
+ " invalid boolean at line %ld\n", parse_tafline - 1);
+ parse_stack_backtrace();
+ longjmp(parse_taf_error, 1);
+ }
+ if (boolean != 0 && boolean != 1) {
+ sc_error("parse_get_taf_boolean:"
+ " warning: suspect boolean at line %ld\n", parse_tafline - 1);
+ }
+
+ return boolean != 0;
}
static void
-parse_taf_pushback (void)
-{
- if (parse_use_pushback || !parse_pushback_line)
- sc_fatal ("parse_taf_pushback: too much pushback requested\n");
-
- /* Set pushback request, and decrement line counter. */
- parse_use_pushback = TRUE;
- parse_tafline--;
-
- /* Note pushback for tracing purposes. */
- if (parse_trace)
- sc_trace ("Parse: push back at line %ld\n", parse_tafline);
+parse_taf_pushback(void) {
+ if (parse_use_pushback || !parse_pushback_line)
+ sc_fatal("parse_taf_pushback: too much pushback requested\n");
+
+ /* Set pushback request, and decrement line counter. */
+ parse_use_pushback = TRUE;
+ parse_tafline--;
+
+ /* Note pushback for tracing purposes. */
+ if (parse_trace)
+ sc_trace("Parse: push back at line %ld\n", parse_tafline);
}
/* Enumerations of parse types found in the parse schema. */
-enum
-{ PARSE_INTEGER = '#',
- PARSE_DEFAULT_ZERO = 'Z',
- PARSE_BOOLEAN = 'B',
- PARSE_DEFAULT_FALSE = 'F',
- PARSE_DEFAULT_TRUE = 'T',
- PARSE_STRING = '$',
- PARSE_DEFAULT_EMPTY = 'E',
- PARSE_MULTILINE = 'M',
- PARSE_VECTOR = 'V',
- PARSE_VECTOR_ALTERNATE = 'W',
- PARSE_ARRAY = '[',
- PARSE_EXPRESSION = '?',
- PARSE_EXPRESSION_NOT = '!',
- PARSE_GLOBAL_EXPRESSION = 'G',
- PARSE_CLASS = '<',
- PARSE_FIXUP = '|',
- PARSE_SPECIAL = '{',
- PARSE_IGNORE_INTEGER = 'i',
- PARSE_IGNORE_BOOLEAN = 'b',
- PARSE_IGNORE_STRING = 's'
+enum {
+ PARSE_INTEGER = '#',
+ PARSE_DEFAULT_ZERO = 'Z',
+ PARSE_BOOLEAN = 'B',
+ PARSE_DEFAULT_FALSE = 'F',
+ PARSE_DEFAULT_TRUE = 'T',
+ PARSE_STRING = '$',
+ PARSE_DEFAULT_EMPTY = 'E',
+ PARSE_MULTILINE = 'M',
+ PARSE_VECTOR = 'V',
+ PARSE_VECTOR_ALTERNATE = 'W',
+ PARSE_ARRAY = '[',
+ PARSE_EXPRESSION = '?',
+ PARSE_EXPRESSION_NOT = '!',
+ PARSE_GLOBAL_EXPRESSION = 'G',
+ PARSE_CLASS = '<',
+ PARSE_FIXUP = '|',
+ PARSE_SPECIAL = '{',
+ PARSE_IGNORE_INTEGER = 'i',
+ PARSE_IGNORE_BOOLEAN = 'b',
+ PARSE_IGNORE_STRING = 's'
};
/* Forward declarations of parse functions for recursion. */
-static void parse_element (const sc_char *element);
-static void parse_class (const sc_char *class_);
-static void parse_descriptor (const sc_char *descriptor);
+static void parse_element(const sc_char *element);
+static void parse_class(const sc_char *class_);
+static void parse_descriptor(const sc_char *descriptor);
/*
* parse_array()
@@ -739,33 +836,31 @@ static void parse_descriptor (const sc_char *descriptor);
* Parse a descriptor [] array.
*/
static void
-parse_array (const sc_char *array)
-{
- sc_int count, index_;
- sc_char element[PARSE_TEMP_LENGTH];
+parse_array(const sc_char *array) {
+ sc_int count, index_;
+ sc_char element[PARSE_TEMP_LENGTH];
- if (parse_trace)
- sc_trace ("Parse: entering array %s\n", array);
+ if (parse_trace)
+ sc_trace("Parse: entering array %s\n", array);
- /* Find the count of elements in the array, and the element itself. */
- if (sscanf (array, "[%ld]%[^ ]", &count, element) != 2)
- sc_fatal ("parse_array: bad array, %s\n", array);
+ /* Find the count of elements in the array, and the element itself. */
+ if (sscanf(array, "[%ld]%[^ ]", &count, element) != 2)
+ sc_fatal("parse_array: bad array, %s\n", array);
- /* Parse the element for array count iterations, each a key. */
- for (index_ = 0; index_ < count; index_++)
- {
- sc_vartype_t vt_key;
+ /* Parse the element for array count iterations, each a key. */
+ for (index_ = 0; index_ < count; index_++) {
+ sc_vartype_t vt_key;
- vt_key.integer = index_;
- parse_push_key (vt_key, PROP_KEY_INTEGER);
+ vt_key.integer = index_;
+ parse_push_key(vt_key, PROP_KEY_INTEGER);
- parse_element (element);
+ parse_element(element);
- parse_pop_key ();
- }
+ parse_pop_key();
+ }
- if (parse_trace)
- sc_trace ("Parse: leaving array %s\n", array);
+ if (parse_trace)
+ sc_trace("Parse: leaving array %s\n", array);
}
@@ -777,54 +872,50 @@ parse_array (const sc_char *array)
* Parse a variable-length vector of properties.
*/
static void
-parse_vector_common (const sc_char *vector, sc_int count)
-{
- sc_int index_;
+parse_vector_common(const sc_char *vector, sc_int count) {
+ sc_int index_;
- /* Parse the vector property count times, pushing a key on each. */
- for (index_ = 0; index_ < count; index_++)
- {
- sc_vartype_t vt_key;
+ /* Parse the vector property count times, pushing a key on each. */
+ for (index_ = 0; index_ < count; index_++) {
+ sc_vartype_t vt_key;
- vt_key.integer = index_;
- parse_push_key (vt_key, PROP_KEY_INTEGER);
+ vt_key.integer = index_;
+ parse_push_key(vt_key, PROP_KEY_INTEGER);
- parse_element (vector + 1);
+ parse_element(vector + 1);
- parse_pop_key ();
- }
+ parse_pop_key();
+ }
}
static void
-parse_vector (const sc_char *vector)
-{
- sc_int count;
+parse_vector(const sc_char *vector) {
+ sc_int count;
- if (parse_trace)
- sc_trace ("Parse: entering vector %s\n", vector);
+ if (parse_trace)
+ sc_trace("Parse: entering vector %s\n", vector);
- /* Find the count of elements in the vector, and parse. */
- count = parse_get_taf_integer ();
- parse_vector_common (vector, count);
+ /* Find the count of elements in the vector, and parse. */
+ count = parse_get_taf_integer();
+ parse_vector_common(vector, count);
- if (parse_trace)
- sc_trace ("Parse: leaving vector %s\n", vector);
+ if (parse_trace)
+ sc_trace("Parse: leaving vector %s\n", vector);
}
static void
-parse_vector_alternate (const sc_char *vector)
-{
- sc_int count;
+parse_vector_alternate(const sc_char *vector) {
+ sc_int count;
- if (parse_trace)
- sc_trace ("Parse: entering alternate vector %s\n", vector);
+ if (parse_trace)
+ sc_trace("Parse: entering alternate vector %s\n", vector);
- /* Element count, this is a vector described by size - 1. */
- count = parse_get_taf_integer () + 1;
- parse_vector_common (vector, count);
+ /* Element count, this is a vector described by size - 1. */
+ count = parse_get_taf_integer() + 1;
+ parse_vector_common(vector, count);
- if (parse_trace)
- sc_trace ("Parse: leaving alternate vector %s\n", vector);
+ if (parse_trace)
+ sc_trace("Parse: leaving alternate vector %s\n", vector);
}
@@ -835,112 +926,105 @@ parse_vector_alternate (const sc_char *vector)
* Parse a conditional field definition, with runtime test.
*/
static sc_bool
-parse_test_expression (const sc_char *test_expression)
-{
- sc_vartype_t vt_key;
- sc_char plhs[PARSE_TEMP_LENGTH];
- sc_int rhs;
- sc_bool retval = FALSE;
-
- /* Identify the type of expression to evaluate. */
- switch (test_expression[0])
- {
- case PARSE_BOOLEAN:
- /* Read boolean property and return its value. */
- vt_key.string = test_expression + 1;
- parse_push_key (vt_key, PROP_KEY_STRING);
- retval = parse_get_boolean_property ();
- parse_pop_key ();
- break;
-
- case PARSE_INTEGER:
- /* Get the left and right sides of = comparison. */
- if (sscanf (test_expression, "#%[^=]=%ld", plhs, &rhs) != 2)
- {
- sc_fatal ("parse_test_expression: bad = compare, %s\n",
- test_expression + 1);
- }
-
- /* Read integer property and return comparison. */
- vt_key.string = plhs;
- parse_push_key (vt_key, PROP_KEY_STRING);
- retval = (parse_get_integer_property () == rhs);
- parse_pop_key ();
- break;
-
- case PARSE_STRING:
- /* Read property and return TRUE if not an empty string. */
- vt_key.string = test_expression + 1;
- parse_push_key (vt_key, PROP_KEY_STRING);
- retval = !sc_strempty (parse_get_string_property ());
- parse_pop_key ();
- break;
-
- case PARSE_GLOBAL_EXPRESSION:
- {
- sc_vartype_t vt_gkey[2];
-
- /* Read the given Global boolean property and return it. */
- vt_gkey[0].string = "Globals";
- vt_gkey[1].string = test_expression + 1;
- retval = prop_get_boolean (parse_bundle, "B<-ss", vt_gkey);
- break;
- }
-
- default:
- sc_fatal ("parse_test_expression:"
- " bad expression, %s\n", test_expression + 1);
- }
-
- if (parse_trace)
- sc_trace ("Parse: expression is %s\n", retval ? "true" : "false");
-
- return retval;
+parse_test_expression(const sc_char *test_expression) {
+ sc_vartype_t vt_key;
+ sc_char plhs[PARSE_TEMP_LENGTH];
+ sc_int rhs;
+ sc_bool retval = FALSE;
+
+ /* Identify the type of expression to evaluate. */
+ switch (test_expression[0]) {
+ case PARSE_BOOLEAN:
+ /* Read boolean property and return its value. */
+ vt_key.string = test_expression + 1;
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ retval = parse_get_boolean_property();
+ parse_pop_key();
+ break;
+
+ case PARSE_INTEGER:
+ /* Get the left and right sides of = comparison. */
+ if (sscanf(test_expression, "#%[^=]=%ld", plhs, &rhs) != 2) {
+ sc_fatal("parse_test_expression: bad = compare, %s\n",
+ test_expression + 1);
+ }
+
+ /* Read integer property and return comparison. */
+ vt_key.string = plhs;
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ retval = (parse_get_integer_property() == rhs);
+ parse_pop_key();
+ break;
+
+ case PARSE_STRING:
+ /* Read property and return TRUE if not an empty string. */
+ vt_key.string = test_expression + 1;
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ retval = !sc_strempty(parse_get_string_property());
+ parse_pop_key();
+ break;
+
+ case PARSE_GLOBAL_EXPRESSION: {
+ sc_vartype_t vt_gkey[2];
+
+ /* Read the given Global boolean property and return it. */
+ vt_gkey[0].string = "Globals";
+ vt_gkey[1].string = test_expression + 1;
+ retval = prop_get_boolean(parse_bundle, "B<-ss", vt_gkey);
+ break;
+ }
+
+ default:
+ sc_fatal("parse_test_expression:"
+ " bad expression, %s\n", test_expression + 1);
+ }
+
+ if (parse_trace)
+ sc_trace("Parse: expression is %s\n", retval ? "true" : "false");
+
+ return retval;
}
static void
-parse_expression (const sc_char *expression)
-{
- sc_char test_expression[PARSE_TEMP_LENGTH];
- sc_bool is_present;
-
- if (parse_trace)
- sc_trace ("Parse: entering expression %s\n", expression);
-
- /* Isolate the test part of the expression. */
- if (sscanf (expression, "?%[^:]", test_expression) != 1)
- sc_fatal ("parse_expression: bad expression, %s\n", expression);
-
- /* Handle the remainder of the expression only if test passes. */
- is_present = (test_expression[0] == PARSE_EXPRESSION_NOT)
- ? !parse_test_expression (test_expression + 1)
- : parse_test_expression (test_expression);
- if (is_present)
- {
- sc_int next;
-
- /*
- * Following the ':' may be a single element, or a comma-separated list.
- */
- for (next = strlen (test_expression) + 2; expression[next] != NUL; )
- {
- sc_char element[PARSE_TEMP_LENGTH];
-
- /* Get the next individual element to parse. */
- if (sscanf (expression + next, "%[^,]", element) != 1)
- sc_fatal ("parse_expression: bad list, %s\n", expression + next);
-
- /* Parse this isolated element. */
- parse_element (element);
-
- /* Advance to the start of the next element. */
- next += strlen (element);
- next += strspn (expression + next, ",");
- }
- }
-
- if (parse_trace)
- sc_trace ("Parse: leaving expression %s\n", expression);
+parse_expression(const sc_char *expression) {
+ sc_char test_expression[PARSE_TEMP_LENGTH];
+ sc_bool is_present;
+
+ if (parse_trace)
+ sc_trace("Parse: entering expression %s\n", expression);
+
+ /* Isolate the test part of the expression. */
+ if (sscanf(expression, "?%[^:]", test_expression) != 1)
+ sc_fatal("parse_expression: bad expression, %s\n", expression);
+
+ /* Handle the remainder of the expression only if test passes. */
+ is_present = (test_expression[0] == PARSE_EXPRESSION_NOT)
+ ? !parse_test_expression(test_expression + 1)
+ : parse_test_expression(test_expression);
+ if (is_present) {
+ sc_int next;
+
+ /*
+ * Following the ':' may be a single element, or a comma-separated list.
+ */
+ for (next = strlen(test_expression) + 2; expression[next] != NUL;) {
+ sc_char element[PARSE_TEMP_LENGTH];
+
+ /* Get the next individual element to parse. */
+ if (sscanf(expression + next, "%[^,]", element) != 1)
+ sc_fatal("parse_expression: bad list, %s\n", expression + next);
+
+ /* Parse this isolated element. */
+ parse_element(element);
+
+ /* Advance to the start of the next element. */
+ next += strlen(element);
+ next += strspn(expression + next, ",");
+ }
+ }
+
+ if (parse_trace)
+ sc_trace("Parse: leaving expression %s\n", expression);
}
@@ -951,46 +1035,43 @@ parse_expression (const sc_char *expression)
* string is malloc'ed, and the caller needs to handle that.
*/
static sc_char *
-parse_read_multiline (void)
-{
- const sc_byte *separator = NULL;
- const sc_char *line;
- sc_char *multiline;
-
- /* Select the appropriate multiline separator. */
- switch (taf_get_version (parse_taf))
- {
- case TAF_VERSION_400:
- separator = V400_SEPARATOR;
- break;
- case TAF_VERSION_390:
- separator = V390_SEPARATOR;
- break;
- case TAF_VERSION_380:
- separator = V380_SEPARATOR;
- break;
- default:
- sc_fatal ("parse_read_multiline: invalid TAF file version\n");
- break;
- }
-
- /* Take a simple copy of the first line. */
- line = parse_get_taf_string ();
- multiline = (sc_char *)sc_malloc (strlen (line) + 1);
- strcpy (multiline, line);
-
- /* Now concatenate until separator found. */
- line = parse_get_taf_string ();
- while (memcmp (line, separator, SEPARATOR_SIZE) != 0)
- {
- multiline = (sc_char *)sc_realloc (multiline,
- strlen (multiline) + strlen (line) + 2);
- strcat (multiline, "\n");
- strcat (multiline, line);
- line = parse_get_taf_string ();
- }
-
- return multiline;
+parse_read_multiline(void) {
+ const sc_byte *separator = NULL;
+ const sc_char *line;
+ sc_char *multiline;
+
+ /* Select the appropriate multiline separator. */
+ switch (taf_get_version(parse_taf)) {
+ case TAF_VERSION_400:
+ separator = V400_SEPARATOR;
+ break;
+ case TAF_VERSION_390:
+ separator = V390_SEPARATOR;
+ break;
+ case TAF_VERSION_380:
+ separator = V380_SEPARATOR;
+ break;
+ default:
+ sc_fatal("parse_read_multiline: invalid TAF file version\n");
+ break;
+ }
+
+ /* Take a simple copy of the first line. */
+ line = parse_get_taf_string();
+ multiline = (sc_char *)sc_malloc(strlen(line) + 1);
+ strcpy(multiline, line);
+
+ /* Now concatenate until separator found. */
+ line = parse_get_taf_string();
+ while (memcmp(line, separator, SEPARATOR_SIZE) != 0) {
+ multiline = (sc_char *)sc_realloc(multiline,
+ strlen(multiline) + strlen(line) + 2);
+ strcat(multiline, "\n");
+ strcat(multiline, line);
+ line = parse_get_taf_string();
+ }
+
+ return multiline;
}
@@ -1000,76 +1081,74 @@ parse_read_multiline (void)
* Common handler for string, integer, boolean, and multiline parse terminals.
*/
static void
-parse_terminal (const sc_char *terminal)
-{
- sc_vartype_t vt_key, vt_value;
-
- if (parse_trace)
- sc_trace ("Parse: entering terminal %s\n", terminal);
-
- /* Push the key string. */
- vt_key.string = terminal + 1;
- parse_push_key (vt_key, PROP_KEY_STRING);
-
- /* Retrieve, or invent, then store the value. */
- switch (terminal[0])
- {
- case PARSE_INTEGER:
- vt_value.integer = parse_get_taf_integer ();
- parse_put_property (vt_value, PROP_INTEGER);
- break;
- case PARSE_DEFAULT_ZERO:
- vt_value.integer = 0;
- parse_put_property (vt_value, PROP_INTEGER);
- break;
-
- case PARSE_BOOLEAN:
- vt_value.boolean = parse_get_taf_boolean ();
- parse_put_property (vt_value, PROP_BOOLEAN);
- break;
- case PARSE_DEFAULT_FALSE:
- case PARSE_DEFAULT_TRUE:
- vt_value.boolean = (terminal[0] == PARSE_DEFAULT_TRUE);
- parse_put_property (vt_value, PROP_BOOLEAN);
- break;
-
- case PARSE_STRING:
- vt_value.string = parse_get_taf_string ();
- parse_put_property (vt_value, PROP_STRING);
- break;
- case PARSE_DEFAULT_EMPTY:
- vt_value.string = "";
- parse_put_property (vt_value, PROP_STRING);
- break;
-
- case PARSE_MULTILINE:
- /* Assign to and adopt mutable string rather than const string. */
- vt_value.mutable_string = parse_read_multiline ();
- parse_put_property (vt_value, PROP_STRING);
-
- assert (parse_bundle);
- prop_adopt (parse_bundle, vt_value.mutable_string);
- break;
-
- case PARSE_IGNORE_INTEGER:
- (void) parse_get_taf_integer ();
- break;
- case PARSE_IGNORE_BOOLEAN:
- (void) parse_get_taf_boolean ();
- break;
- case PARSE_IGNORE_STRING:
- (void) parse_get_taf_string ();
- break;
-
- default:
- sc_fatal ("parse_terminal: bad type, %c\n", terminal[0]);
- }
-
- /* Pop terminal key. */
- parse_pop_key ();
-
- if (parse_trace)
- sc_trace ("Parse: leaving terminal %s\n", terminal);
+parse_terminal(const sc_char *terminal) {
+ sc_vartype_t vt_key, vt_value;
+
+ if (parse_trace)
+ sc_trace("Parse: entering terminal %s\n", terminal);
+
+ /* Push the key string. */
+ vt_key.string = terminal + 1;
+ parse_push_key(vt_key, PROP_KEY_STRING);
+
+ /* Retrieve, or invent, then store the value. */
+ switch (terminal[0]) {
+ case PARSE_INTEGER:
+ vt_value.integer = parse_get_taf_integer();
+ parse_put_property(vt_value, PROP_INTEGER);
+ break;
+ case PARSE_DEFAULT_ZERO:
+ vt_value.integer = 0;
+ parse_put_property(vt_value, PROP_INTEGER);
+ break;
+
+ case PARSE_BOOLEAN:
+ vt_value.boolean = parse_get_taf_boolean();
+ parse_put_property(vt_value, PROP_BOOLEAN);
+ break;
+ case PARSE_DEFAULT_FALSE:
+ case PARSE_DEFAULT_TRUE:
+ vt_value.boolean = (terminal[0] == PARSE_DEFAULT_TRUE);
+ parse_put_property(vt_value, PROP_BOOLEAN);
+ break;
+
+ case PARSE_STRING:
+ vt_value.string = parse_get_taf_string();
+ parse_put_property(vt_value, PROP_STRING);
+ break;
+ case PARSE_DEFAULT_EMPTY:
+ vt_value.string = "";
+ parse_put_property(vt_value, PROP_STRING);
+ break;
+
+ case PARSE_MULTILINE:
+ /* Assign to and adopt mutable string rather than const string. */
+ vt_value.mutable_string = parse_read_multiline();
+ parse_put_property(vt_value, PROP_STRING);
+
+ assert(parse_bundle);
+ prop_adopt(parse_bundle, vt_value.mutable_string);
+ break;
+
+ case PARSE_IGNORE_INTEGER:
+ (void) parse_get_taf_integer();
+ break;
+ case PARSE_IGNORE_BOOLEAN:
+ (void) parse_get_taf_boolean();
+ break;
+ case PARSE_IGNORE_STRING:
+ (void) parse_get_taf_string();
+ break;
+
+ default:
+ sc_fatal("parse_terminal: bad type, %c\n", terminal[0]);
+ }
+
+ /* Pop terminal key. */
+ parse_pop_key();
+
+ if (parse_trace)
+ sc_trace("Parse: leaving terminal %s\n", terminal);
}
@@ -1078,12 +1157,11 @@ parse_terminal (const sc_char *terminal)
* for the various sound and graphic resources encountered on parsing
* version 4.0 games. It's unused if the version is not 4.0.
*/
-typedef struct
-{
- sc_char *name;
- sc_uint hash;
- sc_int length;
- sc_int offset;
+typedef struct {
+ sc_char *name;
+ sc_uint hash;
+ sc_int length;
+ sc_int offset;
} sc_parse_resource_t;
enum { RESOURCE_GROW_INCREMENT = 32 };
@@ -1098,21 +1176,19 @@ static sc_parse_resource_t *parse_resources = NULL;
* Free and clear down the version 4.0 resources table.
*/
static void
-parse_clear_v400_resources_table (void)
-{
- /* Free allocated memory and return to initial values. */
- if (parse_resources)
- {
- sc_int index_;
-
- for (index_ = 0; index_ < parse_resources_length; index_++)
- sc_free (parse_resources[index_].name);
-
- sc_free (parse_resources);
- parse_resources = NULL;
- }
- parse_resources_length = 0;
- parse_resources_size = 0;
+parse_clear_v400_resources_table(void) {
+ /* Free allocated memory and return to initial values. */
+ if (parse_resources) {
+ sc_int index_;
+
+ for (index_ = 0; index_ < parse_resources_length; index_++)
+ sc_free(parse_resources[index_].name);
+
+ sc_free(parse_resources);
+ parse_resources = NULL;
+ }
+ parse_resources_length = 0;
+ parse_resources_size = 0;
}
@@ -1130,77 +1206,71 @@ parse_clear_v400_resources_table (void)
* length with real_length to see if that happened.
*/
static sc_int
-parse_get_v400_resource_offset (const sc_char *name,
- sc_int length, sc_int *real_length)
-{
- sc_char *clean_name;
- sc_uint hash;
- sc_int index_, offset;
-
- /*
- * Take a copy of the name, and remove any trailing "##" looping sound
- * indicator flag. Who thinks this junk up?
- */
- clean_name = (sc_char *)sc_malloc (strlen (name) + 1);
- strcpy (clean_name, name);
- if (strcmp (clean_name + strlen (clean_name) - 2, "##") == 0)
- clean_name[strlen (clean_name) - 2] = NUL;
-
- /*
- * Scan the current resources list for a matching name, and if the resource
- * is already known, return its offset. The hash check is an attempt to
- * improve the search times, relative to using only string comparisons --
- * the table's not fully hashed. If found, we need to also pass back the
- * corrected length.
- */
- offset = -1;
- hash = sc_hash (clean_name);
- for (index_ = 0; index_ < parse_resources_length; index_++)
- {
- if (parse_resources[index_].hash == hash
- && strcmp (parse_resources[index_].name, clean_name) == 0)
- {
- offset = parse_resources[index_].offset;
- break;
- }
- }
- if (offset != -1)
- {
- *real_length = parse_resources[index_].length;
- sc_free (clean_name);
- return offset;
- }
-
- /* Resize the resources table if required. */
- if (parse_resources_length == parse_resources_size)
- {
- parse_resources_size += RESOURCE_GROW_INCREMENT;
- parse_resources = (sc_parse_resource_t *)sc_realloc (parse_resources,
- parse_resources_size *
- sizeof (parse_resources[0]));
- }
-
- /*
- * Calculate the offset. For the first resource, it's zero; for others,
- * it's one after the prior entry's offset and length.
- */
- if (parse_resources_length == 0)
- offset = 0;
- else
- {
- offset = parse_resources[parse_resources_length - 1].offset
- + parse_resources[parse_resources_length - 1].length + 1;
- }
-
- /* Add details to the table. */
- parse_resources[parse_resources_length].name = clean_name;
- parse_resources[parse_resources_length].hash = hash;
- parse_resources[parse_resources_length].offset = offset;
- parse_resources[parse_resources_length].length = length;
- parse_resources_length++;
-
- *real_length = length;
- return offset;
+parse_get_v400_resource_offset(const sc_char *name,
+ sc_int length, sc_int *real_length) {
+ sc_char *clean_name;
+ sc_uint hash;
+ sc_int index_, offset;
+
+ /*
+ * Take a copy of the name, and remove any trailing "##" looping sound
+ * indicator flag. Who thinks this junk up?
+ */
+ clean_name = (sc_char *)sc_malloc(strlen(name) + 1);
+ strcpy(clean_name, name);
+ if (strcmp(clean_name + strlen(clean_name) - 2, "##") == 0)
+ clean_name[strlen(clean_name) - 2] = NUL;
+
+ /*
+ * Scan the current resources list for a matching name, and if the resource
+ * is already known, return its offset. The hash check is an attempt to
+ * improve the search times, relative to using only string comparisons --
+ * the table's not fully hashed. If found, we need to also pass back the
+ * corrected length.
+ */
+ offset = -1;
+ hash = sc_hash(clean_name);
+ for (index_ = 0; index_ < parse_resources_length; index_++) {
+ if (parse_resources[index_].hash == hash
+ && strcmp(parse_resources[index_].name, clean_name) == 0) {
+ offset = parse_resources[index_].offset;
+ break;
+ }
+ }
+ if (offset != -1) {
+ *real_length = parse_resources[index_].length;
+ sc_free(clean_name);
+ return offset;
+ }
+
+ /* Resize the resources table if required. */
+ if (parse_resources_length == parse_resources_size) {
+ parse_resources_size += RESOURCE_GROW_INCREMENT;
+ parse_resources = (sc_parse_resource_t *)sc_realloc(parse_resources,
+ parse_resources_size *
+ sizeof(parse_resources[0]));
+ }
+
+ /*
+ * Calculate the offset. For the first resource, it's zero; for others,
+ * it's one after the prior entry's offset and length.
+ */
+ if (parse_resources_length == 0)
+ offset = 0;
+ else {
+ offset = parse_resources[parse_resources_length - 1].offset
+ + parse_resources[parse_resources_length - 1].length + 1;
+ }
+
+ /* Add details to the table. */
+ parse_resources[parse_resources_length].name = clean_name;
+ parse_resources[parse_resources_length].hash = hash;
+ parse_resources[parse_resources_length].offset = offset;
+ parse_resources[parse_resources_length].length = length;
+ parse_resources_length++;
+
+ *real_length = length;
+ return offset;
}
@@ -1221,104 +1291,97 @@ parse_get_v400_resource_offset (const sc_char *name,
* our parse_resources table, but not always...
*/
static void
-parse_handle_v400_resources (sc_bool has_sound, sc_bool has_graphics)
-{
- sc_vartype_t vt_key, vt_value;
- const sc_char *file;
- sc_int length, offset;
-
- /*
- * Retrieve the file and length for the sound just parsed. If there's a
- * file of non-zero length, rewrite its offset.
- */
- if (has_sound)
- {
- /* Retrieve the file and length information. */
- vt_key.string = "SoundFile";
- parse_push_key (vt_key, PROP_KEY_STRING);
- file = parse_get_string_property ();
- parse_pop_key ();
-
- vt_key.string = "SoundLen";
- parse_push_key (vt_key, PROP_KEY_STRING);
- length = parse_get_integer_property ();
- parse_pop_key ();
-
- /*
- * If defined and has a length, rewrite the offset, and also the length
- * in case changed.
- */
- if (!sc_strempty (file) && length != 0)
- {
- sc_int real_length;
-
- offset = parse_get_v400_resource_offset (file, length, &real_length);
- vt_key.string = "SoundOffset";
- parse_push_key (vt_key, PROP_KEY_STRING);
-
- vt_value.integer = offset;
- parse_put_property (vt_value, PROP_INTEGER);
-
- parse_pop_key ();
-
- /* Rewrite length if changed. */
- if (real_length != length)
- {
- vt_key.string = "SoundLen";
- parse_push_key (vt_key, PROP_KEY_STRING);
-
- vt_value.integer = real_length;
- parse_put_property (vt_value, PROP_INTEGER);
-
- parse_pop_key ();
- }
- }
- }
-
- /* Now do the same thing for graphics. */
- if (has_graphics)
- {
- /* Retrieve the file and length information. */
- vt_key.string = "GraphicFile";
- parse_push_key (vt_key, PROP_KEY_STRING);
- file = parse_get_string_property ();
- parse_pop_key ();
-
- vt_key.string = "GraphicLen";
- parse_push_key (vt_key, PROP_KEY_STRING);
- length = parse_get_integer_property ();
- parse_pop_key ();
-
- /*
- * If defined and has a length, rewrite the offset, and also the length
- * in case changed.
- */
- if (!sc_strempty (file) && length != 0)
- {
- sc_int real_length;
-
- offset = parse_get_v400_resource_offset (file, length, &real_length);
- vt_key.string = "GraphicOffset";
- parse_push_key (vt_key, PROP_KEY_STRING);
-
- vt_value.integer = offset;
- parse_put_property (vt_value, PROP_INTEGER);
-
- parse_pop_key ();
-
- /* Rewrite length if changed. */
- if (real_length != length)
- {
- vt_key.string = "GraphicLen";
- parse_push_key (vt_key, PROP_KEY_STRING);
-
- vt_value.integer = real_length;
- parse_put_property (vt_value, PROP_INTEGER);
-
- parse_pop_key ();
- }
- }
- }
+parse_handle_v400_resources(sc_bool has_sound, sc_bool has_graphics) {
+ sc_vartype_t vt_key, vt_value;
+ const sc_char *file;
+ sc_int length, offset;
+
+ /*
+ * Retrieve the file and length for the sound just parsed. If there's a
+ * file of non-zero length, rewrite its offset.
+ */
+ if (has_sound) {
+ /* Retrieve the file and length information. */
+ vt_key.string = "SoundFile";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ file = parse_get_string_property();
+ parse_pop_key();
+
+ vt_key.string = "SoundLen";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ length = parse_get_integer_property();
+ parse_pop_key();
+
+ /*
+ * If defined and has a length, rewrite the offset, and also the length
+ * in case changed.
+ */
+ if (!sc_strempty(file) && length != 0) {
+ sc_int real_length;
+
+ offset = parse_get_v400_resource_offset(file, length, &real_length);
+ vt_key.string = "SoundOffset";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+
+ vt_value.integer = offset;
+ parse_put_property(vt_value, PROP_INTEGER);
+
+ parse_pop_key();
+
+ /* Rewrite length if changed. */
+ if (real_length != length) {
+ vt_key.string = "SoundLen";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+
+ vt_value.integer = real_length;
+ parse_put_property(vt_value, PROP_INTEGER);
+
+ parse_pop_key();
+ }
+ }
+ }
+
+ /* Now do the same thing for graphics. */
+ if (has_graphics) {
+ /* Retrieve the file and length information. */
+ vt_key.string = "GraphicFile";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ file = parse_get_string_property();
+ parse_pop_key();
+
+ vt_key.string = "GraphicLen";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ length = parse_get_integer_property();
+ parse_pop_key();
+
+ /*
+ * If defined and has a length, rewrite the offset, and also the length
+ * in case changed.
+ */
+ if (!sc_strempty(file) && length != 0) {
+ sc_int real_length;
+
+ offset = parse_get_v400_resource_offset(file, length, &real_length);
+ vt_key.string = "GraphicOffset";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+
+ vt_value.integer = offset;
+ parse_put_property(vt_value, PROP_INTEGER);
+
+ parse_pop_key();
+
+ /* Rewrite length if changed. */
+ if (real_length != length) {
+ vt_key.string = "GraphicLen";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+
+ vt_value.integer = real_length;
+ parse_put_property(vt_value, PROP_INTEGER);
+
+ parse_pop_key();
+ }
+ }
+ }
}
@@ -1329,238 +1392,222 @@ parse_handle_v400_resources (sc_bool has_sound, sc_bool has_graphics)
* therefore need careful treatment.
*/
static void
-parse_special (const sc_char *special)
-{
- if (parse_trace)
- sc_trace ("Parse: entering special %s\n", special);
-
- /* Special handling for version 4.0 resources. */
- if (strcmp (special, "{V400_RESOURCE}") == 0)
- {
- sc_vartype_t vt_key[2];
- sc_bool has_sound, has_graphics;
-
- /* Get sound and graphics global flags. */
- vt_key[0].string = "Globals";
- vt_key[1].string = "Sound";
- has_sound = prop_get_boolean (parse_bundle, "B<-ss", vt_key);
-
- vt_key[1].string = "Graphics";
- has_graphics = prop_get_boolean (parse_bundle, "B<-ss", vt_key);
-
- /* Apply special handling to the resources. */
- parse_handle_v400_resources (has_sound, has_graphics);
- }
-
- /* Parse a version 4.0 optional set of room exit information. */
- else if (strcmp (special, "{V400_ROOM_EXIT:#Dest_#Var1_#Var2_#Var3}") == 0)
- {
- sc_int flag;
-
- /* Get next flag, and if true, pushback and parse. */
- flag = parse_get_taf_integer ();
- if (flag != 0)
- {
- parse_taf_pushback ();
- parse_descriptor ("#Dest #Var1 #Var2 #Var3");
- }
- }
-
- /* Parse version 3.9 and version 3.8 optional room exit information. */
- else if (strcmp (special,
- "{V390_V380_ROOM_EXIT:#Dest_#Var1_#Var2_ZVar3}") == 0)
- {
- sc_int flag;
-
- /* Get next flag, and if true, pushback and parse. */
- flag = parse_get_taf_integer ();
- if (flag != 0)
- {
- parse_taf_pushback ();
- parse_descriptor ("#Dest #Var1 #Var2 ZVar3");
- }
- }
-
- /* Parse room lists, with optional extra room. */
- else if (strcmp (special, "{ROOM_LIST0}") == 0
- || strcmp (special, "{ROOM_LIST1}") == 0)
- {
- sc_vartype_t vt_key, vt_value;
- sc_int room_count, num_rooms, type, index_;
-
- /* Retrieve the room list type. */
- vt_key.string = "Type";
- parse_push_key (vt_key, PROP_KEY_STRING);
- type = parse_get_integer_property ();
- parse_pop_key ();
-
- /* Write remaining room list depending on the type. */
- switch (type)
- {
- case ROOMLIST_NO_ROOMS:
- case ROOMLIST_ALL_ROOMS:
- case ROOMLIST_NPC_PART:
- break;
-
- case ROOMLIST_ONE_ROOM:
- /* Store this room as the single list entry. */
- parse_element ("#Room");
- break;
-
- case ROOMLIST_SOME_ROOMS:
- /* Get count of rooms defined, add one if necessary. */
- vt_key.string = "Rooms";
- room_count = prop_get_child_count (parse_bundle, "I<-s", &vt_key);
-
- if (strcmp (special, "{ROOM_LIST1}") == 0)
- num_rooms = room_count + 1;
- else
- num_rooms = room_count;
-
- /* Store an array of rooms flags for each room. */
- vt_key.string = "Rooms";
- parse_push_key (vt_key, PROP_KEY_STRING);
- for (index_ = 0; index_ < num_rooms; index_++)
- {
- sc_bool this_room;
-
- /* Get flag for this room. */
- this_room = parse_get_taf_boolean ();
-
- /* Store flag directly. */
- vt_key.integer = index_;
- parse_push_key (vt_key, PROP_KEY_INTEGER);
- vt_value.boolean = this_room;
- parse_put_property (vt_value, PROP_BOOLEAN);
- parse_pop_key ();
- }
- parse_pop_key ();
- break;
-
- default:
- sc_fatal ("parse_special: bad type, %ld\n", type);
- }
- }
-
- /* Parse Parent number iff this object is an NPC part. */
- else if (strcmp (special, "{OBJECT:#Parent}") == 0)
- {
- sc_vartype_t vt_key;
- sc_int type;
-
- /* Check object's Where room list Type for NPC part. */
- vt_key.string = "Where";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_key.string = "Type";
- parse_push_key (vt_key, PROP_KEY_STRING);
- type = parse_get_integer_property ();
- parse_pop_key ();
- parse_pop_key ();
-
- /* Get Parent if the object is part of an NPC. */
- if (type == ROOMLIST_NPC_PART)
- parse_element ("#Parent");
- }
-
- /* Parse a list of rooms and times for a walk. */
- else if (strcmp (special, "{WALK:#Rooms_#Times}") == 0)
- {
- sc_vartype_t vt_key, vt_value;
- sc_int num_stops, index_;
-
- /* Obtain the count of stops in this walk. */
- vt_key.string = "NumStops";
- parse_push_key (vt_key, PROP_KEY_STRING);
- num_stops = parse_get_integer_property ();
- parse_pop_key ();
-
- /* Look for a room and time for each stop. */
- for (index_ = 0; index_ < num_stops; index_++)
- {
- sc_int room, time;
-
- /* Parse and store Rooms[index_]. */
- vt_key.string = "Rooms";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_key.integer = index_;
- parse_push_key (vt_key, PROP_KEY_INTEGER);
-
- room = parse_get_taf_integer ();
-
- vt_value.integer = room;
- parse_put_property (vt_value, PROP_INTEGER);
- parse_pop_key ();
- parse_pop_key ();
-
- /* Parse and store Times[index_]. */
- vt_key.string = "Times";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_key.integer = index_;
- parse_push_key (vt_key, PROP_KEY_INTEGER);
-
- time = parse_get_taf_integer ();
-
- vt_value.integer = time;
- parse_put_property (vt_value, PROP_INTEGER);
- parse_pop_key ();
- parse_pop_key ();
- }
- }
-
- /* Parse a room group variable size boolean list. */
- else if (strcmp (special, "{ROOM_GROUP:[]BList}") == 0)
- {
- sc_vartype_t vt_key, vt_value;
- sc_int num_rooms, index_, l2index_;
- sc_bool in_group;
-
- /* Get the count of rooms defined. */
- vt_key.string = "Rooms";
- num_rooms = prop_get_integer (parse_bundle, "I<-s", &vt_key);
-
- /* Read a boolean for each room. */
- l2index_ = 0;
- for (index_ = 0; index_ < num_rooms; index_++)
- {
- in_group = parse_get_taf_boolean ();
-
- /* Store raw flag as List[index_]. */
- vt_key.string = "List";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_key.integer = index_;
- parse_push_key (vt_key, PROP_KEY_INTEGER);
- vt_value.boolean = in_group;
- parse_put_property (vt_value, PROP_BOOLEAN);
-
- parse_pop_key ();
- parse_pop_key ();
-
- /* Store in-group index'es as List2[0..n]. */
- if (in_group)
- {
- vt_key.string = "List2";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_key.integer = l2index_;
- parse_push_key (vt_key, PROP_KEY_INTEGER);
- vt_value.integer = index_;
- parse_put_property (vt_value, PROP_INTEGER);
-
- parse_pop_key ();
- parse_pop_key ();
-
- l2index_++;
- }
- }
- }
-
- /* Error if no special handler available. */
- else
- {
- sc_fatal ("parse_special: no handler for \"%s\"\n", special);
- }
-
- if (parse_trace)
- sc_trace ("Parse: leaving special %s\n", special);
+parse_special(const sc_char *special) {
+ if (parse_trace)
+ sc_trace("Parse: entering special %s\n", special);
+
+ /* Special handling for version 4.0 resources. */
+ if (strcmp(special, "{V400_RESOURCE}") == 0) {
+ sc_vartype_t vt_key[2];
+ sc_bool has_sound, has_graphics;
+
+ /* Get sound and graphics global flags. */
+ vt_key[0].string = "Globals";
+ vt_key[1].string = "Sound";
+ has_sound = prop_get_boolean(parse_bundle, "B<-ss", vt_key);
+
+ vt_key[1].string = "Graphics";
+ has_graphics = prop_get_boolean(parse_bundle, "B<-ss", vt_key);
+
+ /* Apply special handling to the resources. */
+ parse_handle_v400_resources(has_sound, has_graphics);
+ }
+
+ /* Parse a version 4.0 optional set of room exit information. */
+ else if (strcmp(special, "{V400_ROOM_EXIT:#Dest_#Var1_#Var2_#Var3}") == 0) {
+ sc_int flag;
+
+ /* Get next flag, and if true, pushback and parse. */
+ flag = parse_get_taf_integer();
+ if (flag != 0) {
+ parse_taf_pushback();
+ parse_descriptor("#Dest #Var1 #Var2 #Var3");
+ }
+ }
+
+ /* Parse version 3.9 and version 3.8 optional room exit information. */
+ else if (strcmp(special,
+ "{V390_V380_ROOM_EXIT:#Dest_#Var1_#Var2_ZVar3}") == 0) {
+ sc_int flag;
+
+ /* Get next flag, and if true, pushback and parse. */
+ flag = parse_get_taf_integer();
+ if (flag != 0) {
+ parse_taf_pushback();
+ parse_descriptor("#Dest #Var1 #Var2 ZVar3");
+ }
+ }
+
+ /* Parse room lists, with optional extra room. */
+ else if (strcmp(special, "{ROOM_LIST0}") == 0
+ || strcmp(special, "{ROOM_LIST1}") == 0) {
+ sc_vartype_t vt_key, vt_value;
+ sc_int room_count, num_rooms, type, index_;
+
+ /* Retrieve the room list type. */
+ vt_key.string = "Type";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ type = parse_get_integer_property();
+ parse_pop_key();
+
+ /* Write remaining room list depending on the type. */
+ switch (type) {
+ case ROOMLIST_NO_ROOMS:
+ case ROOMLIST_ALL_ROOMS:
+ case ROOMLIST_NPC_PART:
+ break;
+
+ case ROOMLIST_ONE_ROOM:
+ /* Store this room as the single list entry. */
+ parse_element("#Room");
+ break;
+
+ case ROOMLIST_SOME_ROOMS:
+ /* Get count of rooms defined, add one if necessary. */
+ vt_key.string = "Rooms";
+ room_count = prop_get_child_count(parse_bundle, "I<-s", &vt_key);
+
+ if (strcmp(special, "{ROOM_LIST1}") == 0)
+ num_rooms = room_count + 1;
+ else
+ num_rooms = room_count;
+
+ /* Store an array of rooms flags for each room. */
+ vt_key.string = "Rooms";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ for (index_ = 0; index_ < num_rooms; index_++) {
+ sc_bool this_room;
+
+ /* Get flag for this room. */
+ this_room = parse_get_taf_boolean();
+
+ /* Store flag directly. */
+ vt_key.integer = index_;
+ parse_push_key(vt_key, PROP_KEY_INTEGER);
+ vt_value.boolean = this_room;
+ parse_put_property(vt_value, PROP_BOOLEAN);
+ parse_pop_key();
+ }
+ parse_pop_key();
+ break;
+
+ default:
+ sc_fatal("parse_special: bad type, %ld\n", type);
+ }
+ }
+
+ /* Parse Parent number iff this object is an NPC part. */
+ else if (strcmp(special, "{OBJECT:#Parent}") == 0) {
+ sc_vartype_t vt_key;
+ sc_int type;
+
+ /* Check object's Where room list Type for NPC part. */
+ vt_key.string = "Where";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_key.string = "Type";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ type = parse_get_integer_property();
+ parse_pop_key();
+ parse_pop_key();
+
+ /* Get Parent if the object is part of an NPC. */
+ if (type == ROOMLIST_NPC_PART)
+ parse_element("#Parent");
+ }
+
+ /* Parse a list of rooms and times for a walk. */
+ else if (strcmp(special, "{WALK:#Rooms_#Times}") == 0) {
+ sc_vartype_t vt_key, vt_value;
+ sc_int num_stops, index_;
+
+ /* Obtain the count of stops in this walk. */
+ vt_key.string = "NumStops";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ num_stops = parse_get_integer_property();
+ parse_pop_key();
+
+ /* Look for a room and time for each stop. */
+ for (index_ = 0; index_ < num_stops; index_++) {
+ sc_int room, time;
+
+ /* Parse and store Rooms[index_]. */
+ vt_key.string = "Rooms";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_key.integer = index_;
+ parse_push_key(vt_key, PROP_KEY_INTEGER);
+
+ room = parse_get_taf_integer();
+
+ vt_value.integer = room;
+ parse_put_property(vt_value, PROP_INTEGER);
+ parse_pop_key();
+ parse_pop_key();
+
+ /* Parse and store Times[index_]. */
+ vt_key.string = "Times";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_key.integer = index_;
+ parse_push_key(vt_key, PROP_KEY_INTEGER);
+
+ time = parse_get_taf_integer();
+
+ vt_value.integer = time;
+ parse_put_property(vt_value, PROP_INTEGER);
+ parse_pop_key();
+ parse_pop_key();
+ }
+ }
+
+ /* Parse a room group variable size boolean list. */
+ else if (strcmp(special, "{ROOM_GROUP:[]BList}") == 0) {
+ sc_vartype_t vt_key, vt_value;
+ sc_int num_rooms, index_, l2index_;
+ sc_bool in_group;
+
+ /* Get the count of rooms defined. */
+ vt_key.string = "Rooms";
+ num_rooms = prop_get_integer(parse_bundle, "I<-s", &vt_key);
+
+ /* Read a boolean for each room. */
+ l2index_ = 0;
+ for (index_ = 0; index_ < num_rooms; index_++) {
+ in_group = parse_get_taf_boolean();
+
+ /* Store raw flag as List[index_]. */
+ vt_key.string = "List";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_key.integer = index_;
+ parse_push_key(vt_key, PROP_KEY_INTEGER);
+ vt_value.boolean = in_group;
+ parse_put_property(vt_value, PROP_BOOLEAN);
+
+ parse_pop_key();
+ parse_pop_key();
+
+ /* Store in-group index'es as List2[0..n]. */
+ if (in_group) {
+ vt_key.string = "List2";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_key.integer = l2index_;
+ parse_push_key(vt_key, PROP_KEY_INTEGER);
+ vt_value.integer = index_;
+ parse_put_property(vt_value, PROP_INTEGER);
+
+ parse_pop_key();
+ parse_pop_key();
+
+ l2index_++;
+ }
+ }
+ }
+
+ /* Error if no special handler available. */
+ else {
+ sc_fatal("parse_special: no handler for \"%s\"\n", special);
+ }
+
+ if (parse_trace)
+ sc_trace("Parse: leaving special %s\n", special);
}
@@ -1571,219 +1618,205 @@ parse_special (const sc_char *special)
* version 4.0 room alts for version 3.9 and version 3.8 games.
*/
static void
-parse_fixup_v390_v380_room_alt (const sc_char *m1, sc_int type,
- const sc_char *resource1,
- const sc_char *m2, sc_int var2,
- const sc_char *resource2,
- sc_int hide_objects,
- const sc_char *changed,
- sc_int var3, sc_int display_room)
-{
- sc_vartype_t vt_key, vt_value, vt_gkey[2];
- sc_bool has_sound, has_graphics;
- sc_int alt_count;
- const sc_char *soundfile1, *graphicfile1;
- const sc_char *soundfile2, *graphicfile2;
-
- /*
- * Initialize resource files to empty, for cases where no resource is copied
- * over from the main room (NULL resource1/2).
- */
- soundfile1 = "";
- graphicfile1 = "";
- soundfile2 = "";
- graphicfile2 = "";
-
- /* Get sound and graphics flags, always FALSE for version 3.8. */
- vt_gkey[0].string = "Globals";
- vt_gkey[1].string = "Sound";
- has_sound = prop_get_boolean (parse_bundle, "B<-ss", vt_gkey);
-
- vt_gkey[1].string = "Graphics";
- has_graphics = prop_get_boolean (parse_bundle, "B<-ss", vt_gkey);
-
- /* Get a count of alts so far defined for the room. */
- vt_key.string = "Alts";
- parse_push_key (vt_key, PROP_KEY_STRING);
- alt_count = parse_get_child_count ();
- parse_pop_key ();
-
- /*
- * Lookup any resource details now, and save them. Because this is not
- * version 4.0, we can ignore lengths, and set them to zero when needed.
- */
- if (has_sound || has_graphics)
- {
- if (resource1)
- {
- vt_key.string = resource1;
- parse_push_key (vt_key, PROP_KEY_STRING);
- if (has_sound)
- {
- vt_key.string = "SoundFile";
- parse_push_key (vt_key, PROP_KEY_STRING);
- soundfile1 = parse_get_string_property ();
- parse_pop_key ();
- }
- if (has_graphics)
- {
- vt_key.string = "GraphicFile";
- parse_push_key (vt_key, PROP_KEY_STRING);
- graphicfile1 = parse_get_string_property ();
- parse_pop_key ();
- }
- parse_pop_key ();
- }
-
- if (resource2)
- {
- vt_key.string = resource2;
- parse_push_key (vt_key, PROP_KEY_STRING);
- if (has_sound)
- {
- vt_key.string = "SoundFile";
- parse_push_key (vt_key, PROP_KEY_STRING);
- soundfile2 = parse_get_string_property ();
- parse_pop_key ();
- }
- if (has_graphics)
- {
- vt_key.string = "GraphicFile";
- parse_push_key (vt_key, PROP_KEY_STRING);
- graphicfile2 = parse_get_string_property ();
- parse_pop_key ();
- }
- parse_pop_key ();
- }
- }
-
- /*
- * Create a room alt to match data passed in. Start with the Alts string
- * and the index to the alt being written. To correctly emulate the parse,
- * we also have to reverse the "Alts" and the index, as parse_put_property()
- * will swap them. Madness.
- */
- vt_key.integer = alt_count;
- parse_push_key (vt_key, PROP_KEY_INTEGER);
- vt_key.string = "Alts";
- parse_push_key (vt_key, PROP_KEY_STRING);
-
- /* Write M1 and Type. */
- vt_key.string = "M1";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.string = m1;
- parse_put_property (vt_value, PROP_STRING);
- parse_pop_key ();
- vt_key.string = "Type";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.integer = type;
- parse_put_property (vt_value, PROP_INTEGER);
- parse_pop_key ();
-
- /* If resources, add these as retrieved above. */
- if (has_sound || has_graphics)
- {
- vt_key.string = "Res1";
- parse_push_key (vt_key, PROP_KEY_STRING);
- if (has_sound)
- {
- vt_key.string = "SoundFile";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.string = soundfile1;
- parse_put_property (vt_value, PROP_STRING);
- parse_pop_key ();
- vt_key.string = "SoundLen";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.integer = 0;
- parse_put_property (vt_value, PROP_INTEGER);
- parse_pop_key ();
- }
- if (has_graphics)
- {
- vt_key.string = "GraphicFile";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.string = graphicfile1;
- parse_put_property (vt_value, PROP_STRING);
- parse_pop_key ();
- vt_key.string = "GraphicLen";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.integer = 0;
- parse_put_property (vt_value, PROP_INTEGER);
- parse_pop_key ();
- }
- parse_pop_key ();
- }
-
- /* Write M2 and Var2. */
- vt_key.string = "M2";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.string = m2;
- parse_put_property (vt_value, PROP_STRING);
- parse_pop_key ();
- vt_key.string = "Var2";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.integer = var2;
- parse_put_property (vt_value, PROP_INTEGER);
- parse_pop_key ();
-
- /* If resources, again add these as retrieved above. */
- if (has_sound || has_graphics)
- {
- vt_key.string = "Res2";
- parse_push_key (vt_key, PROP_KEY_STRING);
- if (has_sound)
- {
- vt_key.string = "SoundFile";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.string = soundfile2;
- parse_put_property (vt_value, PROP_STRING);
- parse_pop_key ();
- vt_key.string = "SoundLen";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.integer = 0;
- parse_put_property (vt_value, PROP_INTEGER);
- parse_pop_key ();
- }
- if (has_graphics)
- {
- vt_key.string = "GraphicFile";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.string = graphicfile2;
- parse_put_property (vt_value, PROP_STRING);
- parse_pop_key ();
- vt_key.string = "GraphicLen";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.integer = 0;
- parse_put_property (vt_value, PROP_INTEGER);
- parse_pop_key ();
- }
- parse_pop_key ();
- }
-
- /* Finish off with the last four alt properties. */
- vt_key.string = "HideObjects";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.integer = hide_objects;
- parse_put_property (vt_value, PROP_INTEGER);
- parse_pop_key ();
- vt_key.string = "Changed";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.string = changed;
- parse_put_property (vt_value, PROP_STRING);
- parse_pop_key ();
- vt_key.string = "Var3";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.integer = var3;
- parse_put_property (vt_value, PROP_INTEGER);
- parse_pop_key ();
- vt_key.string = "DisplayRoom";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.integer = display_room;
- parse_put_property (vt_value, PROP_INTEGER);
- parse_pop_key ();
-
- parse_pop_key ();
- parse_pop_key ();
+parse_fixup_v390_v380_room_alt(const sc_char *m1, sc_int type,
+ const sc_char *resource1,
+ const sc_char *m2, sc_int var2,
+ const sc_char *resource2,
+ sc_int hide_objects,
+ const sc_char *changed,
+ sc_int var3, sc_int display_room) {
+ sc_vartype_t vt_key, vt_value, vt_gkey[2];
+ sc_bool has_sound, has_graphics;
+ sc_int alt_count;
+ const sc_char *soundfile1, *graphicfile1;
+ const sc_char *soundfile2, *graphicfile2;
+
+ /*
+ * Initialize resource files to empty, for cases where no resource is copied
+ * over from the main room (NULL resource1/2).
+ */
+ soundfile1 = "";
+ graphicfile1 = "";
+ soundfile2 = "";
+ graphicfile2 = "";
+
+ /* Get sound and graphics flags, always FALSE for version 3.8. */
+ vt_gkey[0].string = "Globals";
+ vt_gkey[1].string = "Sound";
+ has_sound = prop_get_boolean(parse_bundle, "B<-ss", vt_gkey);
+
+ vt_gkey[1].string = "Graphics";
+ has_graphics = prop_get_boolean(parse_bundle, "B<-ss", vt_gkey);
+
+ /* Get a count of alts so far defined for the room. */
+ vt_key.string = "Alts";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ alt_count = parse_get_child_count();
+ parse_pop_key();
+
+ /*
+ * Lookup any resource details now, and save them. Because this is not
+ * version 4.0, we can ignore lengths, and set them to zero when needed.
+ */
+ if (has_sound || has_graphics) {
+ if (resource1) {
+ vt_key.string = resource1;
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ if (has_sound) {
+ vt_key.string = "SoundFile";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ soundfile1 = parse_get_string_property();
+ parse_pop_key();
+ }
+ if (has_graphics) {
+ vt_key.string = "GraphicFile";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ graphicfile1 = parse_get_string_property();
+ parse_pop_key();
+ }
+ parse_pop_key();
+ }
+
+ if (resource2) {
+ vt_key.string = resource2;
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ if (has_sound) {
+ vt_key.string = "SoundFile";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ soundfile2 = parse_get_string_property();
+ parse_pop_key();
+ }
+ if (has_graphics) {
+ vt_key.string = "GraphicFile";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ graphicfile2 = parse_get_string_property();
+ parse_pop_key();
+ }
+ parse_pop_key();
+ }
+ }
+
+ /*
+ * Create a room alt to match data passed in. Start with the Alts string
+ * and the index to the alt being written. To correctly emulate the parse,
+ * we also have to reverse the "Alts" and the index, as parse_put_property()
+ * will swap them. Madness.
+ */
+ vt_key.integer = alt_count;
+ parse_push_key(vt_key, PROP_KEY_INTEGER);
+ vt_key.string = "Alts";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+
+ /* Write M1 and Type. */
+ vt_key.string = "M1";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.string = m1;
+ parse_put_property(vt_value, PROP_STRING);
+ parse_pop_key();
+ vt_key.string = "Type";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.integer = type;
+ parse_put_property(vt_value, PROP_INTEGER);
+ parse_pop_key();
+
+ /* If resources, add these as retrieved above. */
+ if (has_sound || has_graphics) {
+ vt_key.string = "Res1";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ if (has_sound) {
+ vt_key.string = "SoundFile";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.string = soundfile1;
+ parse_put_property(vt_value, PROP_STRING);
+ parse_pop_key();
+ vt_key.string = "SoundLen";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.integer = 0;
+ parse_put_property(vt_value, PROP_INTEGER);
+ parse_pop_key();
+ }
+ if (has_graphics) {
+ vt_key.string = "GraphicFile";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.string = graphicfile1;
+ parse_put_property(vt_value, PROP_STRING);
+ parse_pop_key();
+ vt_key.string = "GraphicLen";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.integer = 0;
+ parse_put_property(vt_value, PROP_INTEGER);
+ parse_pop_key();
+ }
+ parse_pop_key();
+ }
+
+ /* Write M2 and Var2. */
+ vt_key.string = "M2";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.string = m2;
+ parse_put_property(vt_value, PROP_STRING);
+ parse_pop_key();
+ vt_key.string = "Var2";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.integer = var2;
+ parse_put_property(vt_value, PROP_INTEGER);
+ parse_pop_key();
+
+ /* If resources, again add these as retrieved above. */
+ if (has_sound || has_graphics) {
+ vt_key.string = "Res2";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ if (has_sound) {
+ vt_key.string = "SoundFile";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.string = soundfile2;
+ parse_put_property(vt_value, PROP_STRING);
+ parse_pop_key();
+ vt_key.string = "SoundLen";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.integer = 0;
+ parse_put_property(vt_value, PROP_INTEGER);
+ parse_pop_key();
+ }
+ if (has_graphics) {
+ vt_key.string = "GraphicFile";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.string = graphicfile2;
+ parse_put_property(vt_value, PROP_STRING);
+ parse_pop_key();
+ vt_key.string = "GraphicLen";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.integer = 0;
+ parse_put_property(vt_value, PROP_INTEGER);
+ parse_pop_key();
+ }
+ parse_pop_key();
+ }
+
+ /* Finish off with the last four alt properties. */
+ vt_key.string = "HideObjects";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.integer = hide_objects;
+ parse_put_property(vt_value, PROP_INTEGER);
+ parse_pop_key();
+ vt_key.string = "Changed";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.string = changed;
+ parse_put_property(vt_value, PROP_STRING);
+ parse_pop_key();
+ vt_key.string = "Var3";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.integer = var3;
+ parse_put_property(vt_value, PROP_INTEGER);
+ parse_pop_key();
+ vt_key.string = "DisplayRoom";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.integer = display_room;
+ parse_put_property(vt_value, PROP_INTEGER);
+ parse_pop_key();
+
+ parse_pop_key();
+ parse_pop_key();
}
@@ -1798,127 +1831,122 @@ enum { V390_V380_ALT_TYPEHIDE_MULT = 10 };
* an equivalent array of version 4.0 style room alts.
*/
static void
-parse_fixup_v390_v380_room_alts (void)
-{
- sc_vartype_t vt_key;
- const sc_char *m1, *m2, *changed;
- sc_int type, var2, hide_objects, var3, display_room;
-
- /* Room alt invariants. */
- m2 = ""; /* No else text */
- changed = ""; /* No changed room name */
-
- /*
- * Create a room alt to override all others, controlled by an object
- * condition and with optional object hiding.
- */
- type = 2; /* Object condition */
- display_room = 0; /* Override all others */
-
- vt_key.string = "Obj";
- parse_push_key (vt_key, PROP_KEY_STRING);
- var3 = parse_get_integer_property ();
- parse_pop_key ();
-
- if (var3 > 0)
- {
- sc_int typehideobjects;
-
- vt_key.string = "AltDesc";
- parse_push_key (vt_key, PROP_KEY_STRING);
- m1 = parse_get_string_property ();
- parse_pop_key ();
-
- vt_key.string = "TypeHideObjects";
- parse_push_key (vt_key, PROP_KEY_STRING);
- typehideobjects = parse_get_integer_property ();
- parse_pop_key ();
-
- var2 = typehideobjects / V390_V380_ALT_TYPEHIDE_MULT;
- hide_objects = typehideobjects % V390_V380_ALT_TYPEHIDE_MULT;
-
- parse_fixup_v390_v380_room_alt (m1, type, "AltRes",
- m2, var2, NULL,
- hide_objects, changed, var3,
- display_room);
- }
-
- /*
- * If a second task alternate description is defined, create a room alt to
- * add after the main description, one that stops printing once done.
- */
- type = 0; /* Task condition */
- display_room = 1; /* Print after main and stop */
-
- vt_key.string = "Task2";
- parse_push_key (vt_key, PROP_KEY_STRING);
- var2 = parse_get_integer_property ();
- parse_pop_key ();
-
- if (var2 > 0)
- {
- vt_key.string = "AddDesc2";
- parse_push_key (vt_key, PROP_KEY_STRING);
- m1 = parse_get_string_property ();
- parse_pop_key ();
-
- var3 = 0;
- hide_objects = 0;
-
- parse_fixup_v390_v380_room_alt (m1, type, "Task2Res",
- m2, var2, NULL,
- hide_objects, changed, var3,
- display_room);
- }
-
- /* Do the same for any first task additional description. */
- type = 0; /* Task condition */
- display_room = 1; /* Print after main and stop */
-
- vt_key.string = "Task1";
- parse_push_key (vt_key, PROP_KEY_STRING);
- var2 = parse_get_integer_property ();
- parse_pop_key ();
-
- if (var2 > 0)
- {
- vt_key.string = "AddDesc1";
- parse_push_key (vt_key, PROP_KEY_STRING);
- m1 = parse_get_string_property ();
- parse_pop_key ();
-
- var3 = 0;
- hide_objects = 0;
-
- parse_fixup_v390_v380_room_alt (m1, type, "Task1Res",
- m2, var2, NULL,
- hide_objects, changed, var3,
- display_room);
- }
-
- /*
- * If still printing at this point, we need a catch-all room alt that will
- * print. So create one with an always true condition.
- */
- type = 0; /* Task condition */
- display_room = 2; /* Lowest priority output */
-
- vt_key.string = "LastDesc";
- parse_push_key (vt_key, PROP_KEY_STRING);
- m1 = parse_get_string_property ();
- parse_pop_key ();
-
- if (!sc_strempty (m1))
- {
- var2 = 0; /* No task - always TRUE */
- var3 = 0;
- hide_objects = 0;
-
- parse_fixup_v390_v380_room_alt (m1, type, "LastRes",
- m2, var2, NULL,
- hide_objects, changed, var3,
- display_room);
- }
+parse_fixup_v390_v380_room_alts(void) {
+ sc_vartype_t vt_key;
+ const sc_char *m1, *m2, *changed;
+ sc_int type, var2, hide_objects, var3, display_room;
+
+ /* Room alt invariants. */
+ m2 = ""; /* No else text */
+ changed = ""; /* No changed room name */
+
+ /*
+ * Create a room alt to override all others, controlled by an object
+ * condition and with optional object hiding.
+ */
+ type = 2; /* Object condition */
+ display_room = 0; /* Override all others */
+
+ vt_key.string = "Obj";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ var3 = parse_get_integer_property();
+ parse_pop_key();
+
+ if (var3 > 0) {
+ sc_int typehideobjects;
+
+ vt_key.string = "AltDesc";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ m1 = parse_get_string_property();
+ parse_pop_key();
+
+ vt_key.string = "TypeHideObjects";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ typehideobjects = parse_get_integer_property();
+ parse_pop_key();
+
+ var2 = typehideobjects / V390_V380_ALT_TYPEHIDE_MULT;
+ hide_objects = typehideobjects % V390_V380_ALT_TYPEHIDE_MULT;
+
+ parse_fixup_v390_v380_room_alt(m1, type, "AltRes",
+ m2, var2, NULL,
+ hide_objects, changed, var3,
+ display_room);
+ }
+
+ /*
+ * If a second task alternate description is defined, create a room alt to
+ * add after the main description, one that stops printing once done.
+ */
+ type = 0; /* Task condition */
+ display_room = 1; /* Print after main and stop */
+
+ vt_key.string = "Task2";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ var2 = parse_get_integer_property();
+ parse_pop_key();
+
+ if (var2 > 0) {
+ vt_key.string = "AddDesc2";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ m1 = parse_get_string_property();
+ parse_pop_key();
+
+ var3 = 0;
+ hide_objects = 0;
+
+ parse_fixup_v390_v380_room_alt(m1, type, "Task2Res",
+ m2, var2, NULL,
+ hide_objects, changed, var3,
+ display_room);
+ }
+
+ /* Do the same for any first task additional description. */
+ type = 0; /* Task condition */
+ display_room = 1; /* Print after main and stop */
+
+ vt_key.string = "Task1";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ var2 = parse_get_integer_property();
+ parse_pop_key();
+
+ if (var2 > 0) {
+ vt_key.string = "AddDesc1";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ m1 = parse_get_string_property();
+ parse_pop_key();
+
+ var3 = 0;
+ hide_objects = 0;
+
+ parse_fixup_v390_v380_room_alt(m1, type, "Task1Res",
+ m2, var2, NULL,
+ hide_objects, changed, var3,
+ display_room);
+ }
+
+ /*
+ * If still printing at this point, we need a catch-all room alt that will
+ * print. So create one with an always true condition.
+ */
+ type = 0; /* Task condition */
+ display_room = 2; /* Lowest priority output */
+
+ vt_key.string = "LastDesc";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ m1 = parse_get_string_property();
+ parse_pop_key();
+
+ if (!sc_strempty(m1)) {
+ var2 = 0; /* No task - always TRUE */
+ var3 = 0;
+ hide_objects = 0;
+
+ parse_fixup_v390_v380_room_alt(m1, type, "LastRes",
+ m2, var2, NULL,
+ hide_objects, changed, var3,
+ display_room);
+ }
}
@@ -1929,151 +1957,138 @@ parse_fixup_v390_v380_room_alts (void)
* 3.9 format into version 4.0.
*/
static void
-parse_fixup_v390 (const sc_char *fixup)
-{
- if (parse_trace)
- sc_trace ("Parse: entering version 3.9 fixup %s\n", fixup);
-
- /* Fixup a version 3.9 task action by incrementing Type > 4. */
- if (strcmp (fixup, "|V390_TASK_ACTION:Type>4?#Type++|") == 0)
- {
- sc_vartype_t vt_key, vt_value;
- sc_int type;
-
- /* Retrieve Type, and if > 4, increment. */
- vt_key.string = "Type";
- parse_push_key (vt_key, PROP_KEY_STRING);
- type = parse_get_integer_property ();
-
- if (type > 4)
- {
- vt_value.integer = type + 1;
- parse_put_property (vt_value, PROP_INTEGER);
- }
-
- parse_pop_key ();
- }
-
- /* Handle either Expr or Var5 for version 3.9 task actions. */
- else if (strcmp (fixup, "|V390_TASK_ACTION:$Expr_#Var5|") == 0)
- {
- sc_vartype_t vt_key;
- sc_int var2;
-
- /* Either Expr or Var5, depending on Var2. */
- vt_key.string = "Var2";
- parse_push_key (vt_key, PROP_KEY_STRING);
- var2 = parse_get_integer_property ();
- parse_pop_key ();
-
- if (var2 == 5)
- parse_descriptor ("$Expr ZVar5");
- else
- parse_descriptor ("EExpr #Var5");
- }
-
- /*
- * Exchange openable values 5 and 6, and write -1 key for openable objects.
- */
- else if (strcmp (fixup, "|V390_OBJECT:_Openable_,Key|") == 0)
- {
- sc_vartype_t vt_key, vt_value;
- sc_int openable;
-
- /* Retrieve Openable, and if 5 or 6, exchange. */
- vt_key.string = "Openable";
- parse_push_key (vt_key, PROP_KEY_STRING);
- openable = parse_get_integer_property ();
-
- if (openable == 5 || openable == 6)
- {
- vt_value.integer = (openable == 5) ? 6 : 5;
- parse_put_property (vt_value, PROP_INTEGER);
- }
-
- parse_pop_key ();
-
- /* For openable objects, store a Key of -1. */
- if (openable == 5 || openable == 6)
- {
- vt_key.string = "Key";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.integer = -1;
- parse_put_property (vt_value, PROP_INTEGER);
- parse_pop_key ();
- }
- }
-
- /* Create a RestrMask that 'and's all the restrictions together. */
- else if (strcmp (fixup, "|V390_TASK:$RestrMask|") == 0)
- {
- sc_vartype_t vt_key, vt_value;
- sc_int restriction_count;
-
- /* Get a count of restrictions. */
- vt_key.string = "Restrictions";
- parse_push_key (vt_key, PROP_KEY_STRING);
- restriction_count = parse_get_child_count ();
- parse_pop_key ();
-
- /* Allocate and fill a new mask for these restrictions. */
- if (restriction_count > 0)
- {
- sc_char *restrmask;
- sc_int index_;
-
- restrmask = (sc_char *)sc_malloc (2 * restriction_count);
- strcpy (restrmask, "#");
- for (index_ = 1; index_ < restriction_count; index_++)
- strcat (restrmask, "A#");
-
- vt_key.string = "RestrMask";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.string = restrmask;
- parse_put_property (vt_value, PROP_STRING);
- parse_pop_key ();
-
- prop_adopt (parse_bundle, restrmask);
- }
- }
-
- /*
- * Increment var1 for variable restrictions to compensate for there being no
- * referenced text comparison (no string variables).
- */
- else if (strcmp (fixup, "|V390_TASK_RESTR:Var1>0?#Var1++|") == 0)
- {
- sc_vartype_t vt_key, vt_value;
- sc_int var1;
-
- /* Retrieve Var1, and if greater than zero, increment. */
- vt_key.string = "Var1";
- parse_push_key (vt_key, PROP_KEY_STRING);
- var1 = parse_get_integer_property ();
-
- if (var1 > 0)
- {
- vt_value.integer = var1 + 1;
- parse_put_property (vt_value, PROP_INTEGER);
- }
-
- parse_pop_key ();
- }
-
- /* Convert version 3.9 fixed alts into a version 4.0 array. */
- else if (strcmp (fixup, "|V390_ROOM:_Alts_|") == 0)
- {
- parse_fixup_v390_v380_room_alts ();
- }
-
- /* Error if no fixup special handler available. */
- else
- {
- sc_fatal ("parse_fixup_v390: no handler for \"%s\"\n", fixup);
- }
-
- if (parse_trace)
- sc_trace ("Parse: leaving version 3.9 fixup %s\n", fixup);
+parse_fixup_v390(const sc_char *fixup) {
+ if (parse_trace)
+ sc_trace("Parse: entering version 3.9 fixup %s\n", fixup);
+
+ /* Fixup a version 3.9 task action by incrementing Type > 4. */
+ if (strcmp(fixup, "|V390_TASK_ACTION:Type>4?#Type++|") == 0) {
+ sc_vartype_t vt_key, vt_value;
+ sc_int type;
+
+ /* Retrieve Type, and if > 4, increment. */
+ vt_key.string = "Type";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ type = parse_get_integer_property();
+
+ if (type > 4) {
+ vt_value.integer = type + 1;
+ parse_put_property(vt_value, PROP_INTEGER);
+ }
+
+ parse_pop_key();
+ }
+
+ /* Handle either Expr or Var5 for version 3.9 task actions. */
+ else if (strcmp(fixup, "|V390_TASK_ACTION:$Expr_#Var5|") == 0) {
+ sc_vartype_t vt_key;
+ sc_int var2;
+
+ /* Either Expr or Var5, depending on Var2. */
+ vt_key.string = "Var2";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ var2 = parse_get_integer_property();
+ parse_pop_key();
+
+ if (var2 == 5)
+ parse_descriptor("$Expr ZVar5");
+ else
+ parse_descriptor("EExpr #Var5");
+ }
+
+ /*
+ * Exchange openable values 5 and 6, and write -1 key for openable objects.
+ */
+ else if (strcmp(fixup, "|V390_OBJECT:_Openable_,Key|") == 0) {
+ sc_vartype_t vt_key, vt_value;
+ sc_int openable;
+
+ /* Retrieve Openable, and if 5 or 6, exchange. */
+ vt_key.string = "Openable";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ openable = parse_get_integer_property();
+
+ if (openable == 5 || openable == 6) {
+ vt_value.integer = (openable == 5) ? 6 : 5;
+ parse_put_property(vt_value, PROP_INTEGER);
+ }
+
+ parse_pop_key();
+
+ /* For openable objects, store a Key of -1. */
+ if (openable == 5 || openable == 6) {
+ vt_key.string = "Key";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.integer = -1;
+ parse_put_property(vt_value, PROP_INTEGER);
+ parse_pop_key();
+ }
+ }
+
+ /* Create a RestrMask that 'and's all the restrictions together. */
+ else if (strcmp(fixup, "|V390_TASK:$RestrMask|") == 0) {
+ sc_vartype_t vt_key, vt_value;
+ sc_int restriction_count;
+
+ /* Get a count of restrictions. */
+ vt_key.string = "Restrictions";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ restriction_count = parse_get_child_count();
+ parse_pop_key();
+
+ /* Allocate and fill a new mask for these restrictions. */
+ if (restriction_count > 0) {
+ sc_char *restrmask;
+ sc_int index_;
+
+ restrmask = (sc_char *)sc_malloc(2 * restriction_count);
+ strcpy(restrmask, "#");
+ for (index_ = 1; index_ < restriction_count; index_++)
+ strcat(restrmask, "A#");
+
+ vt_key.string = "RestrMask";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.string = restrmask;
+ parse_put_property(vt_value, PROP_STRING);
+ parse_pop_key();
+
+ prop_adopt(parse_bundle, restrmask);
+ }
+ }
+
+ /*
+ * Increment var1 for variable restrictions to compensate for there being no
+ * referenced text comparison (no string variables).
+ */
+ else if (strcmp(fixup, "|V390_TASK_RESTR:Var1>0?#Var1++|") == 0) {
+ sc_vartype_t vt_key, vt_value;
+ sc_int var1;
+
+ /* Retrieve Var1, and if greater than zero, increment. */
+ vt_key.string = "Var1";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ var1 = parse_get_integer_property();
+
+ if (var1 > 0) {
+ vt_value.integer = var1 + 1;
+ parse_put_property(vt_value, PROP_INTEGER);
+ }
+
+ parse_pop_key();
+ }
+
+ /* Convert version 3.9 fixed alts into a version 4.0 array. */
+ else if (strcmp(fixup, "|V390_ROOM:_Alts_|") == 0) {
+ parse_fixup_v390_v380_room_alts();
+ }
+
+ /* Error if no fixup special handler available. */
+ else {
+ sc_fatal("parse_fixup_v390: no handler for \"%s\"\n", fixup);
+ }
+
+ if (parse_trace)
+ sc_trace("Parse: leaving version 3.9 fixup %s\n", fixup);
}
@@ -2092,57 +2107,54 @@ enum { V380_TASK_MOVEMENTS = 6 };
* Helper for parse_fixup_v380(), adds a task action.
*/
static void
-parse_fixup_v380_action (sc_int type, sc_int var_count,
- sc_int var1, sc_int var2, sc_int var3)
-{
- sc_vartype_t vt_key, vt_value;
- sc_int action_count;
-
- /* Get a count of actions so far defined for the task. */
- vt_key.string = "Actions";
- parse_push_key (vt_key, PROP_KEY_STRING);
- action_count = parse_get_child_count ();
- parse_pop_key ();
-
- /* Write actions key, reversed to emulate parse actions. */
- vt_key.integer = action_count;
- parse_push_key (vt_key, PROP_KEY_INTEGER);
- vt_key.string = "Actions";
- parse_push_key (vt_key, PROP_KEY_STRING);
-
- /* Write new action according to the given arguments. */
- vt_key.string = "Type";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.integer = type;
- parse_put_property (vt_value, PROP_INTEGER);
- parse_pop_key ();
-
- vt_key.string = "Var1";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.integer = var1;
- parse_put_property (vt_value, PROP_INTEGER);
- parse_pop_key ();
-
- if (var_count > 1)
- {
- vt_key.string = "Var2";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.integer = var2;
- parse_put_property (vt_value, PROP_INTEGER);
- parse_pop_key ();
- }
-
- if (var_count > 2)
- {
- vt_key.string = "Var3";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.integer = var3;
- parse_put_property (vt_value, PROP_INTEGER);
- parse_pop_key ();
- }
-
- parse_pop_key ();
- parse_pop_key ();
+parse_fixup_v380_action(sc_int type, sc_int var_count,
+ sc_int var1, sc_int var2, sc_int var3) {
+ sc_vartype_t vt_key, vt_value;
+ sc_int action_count;
+
+ /* Get a count of actions so far defined for the task. */
+ vt_key.string = "Actions";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ action_count = parse_get_child_count();
+ parse_pop_key();
+
+ /* Write actions key, reversed to emulate parse actions. */
+ vt_key.integer = action_count;
+ parse_push_key(vt_key, PROP_KEY_INTEGER);
+ vt_key.string = "Actions";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+
+ /* Write new action according to the given arguments. */
+ vt_key.string = "Type";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.integer = type;
+ parse_put_property(vt_value, PROP_INTEGER);
+ parse_pop_key();
+
+ vt_key.string = "Var1";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.integer = var1;
+ parse_put_property(vt_value, PROP_INTEGER);
+ parse_pop_key();
+
+ if (var_count > 1) {
+ vt_key.string = "Var2";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.integer = var2;
+ parse_put_property(vt_value, PROP_INTEGER);
+ parse_pop_key();
+ }
+
+ if (var_count > 2) {
+ vt_key.string = "Var3";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.integer = var3;
+ parse_put_property(vt_value, PROP_INTEGER);
+ parse_pop_key();
+ }
+
+ parse_pop_key();
+ parse_pop_key();
}
@@ -2152,83 +2164,79 @@ parse_fixup_v380_action (sc_int type, sc_int var_count,
* Helper for parse_fixup_v380(), converts a task movement into an action.
*/
static void
-parse_fixup_v380_movement (sc_int mvar1, sc_int mvar2, sc_int mvar3)
-{
- sc_int var1;
-
- /* If nothing was selected to move, ignore the call. */
- if (mvar1 == 0)
- return;
-
- /*
- * Accept only player moves into rooms. Other combinations, such as move
- * player to worn by player, are unlikely. And move player to same room as
- * player isn't useful.
- */
- if (mvar1 == 1)
- {
- if (mvar3 == 0 && mvar2 >= 2)
- parse_fixup_v380_action (1, 3, 0, 0, mvar2 - 2);
- return;
- }
-
- /*
- * Convert movement var1 into action var1. Var1 is the dynamic object + 3,
- * or 2 for referenced object, or 0 for all held.
- */
- switch (mvar1)
- {
- case 2:
- var1 = 2;
- break; /* Referenced obj */
- case 3:
- var1 = 0;
- break; /* All held */
- default:
- var1 = mvar1 - 1;
- break; /* Dynamic obj */
- }
-
- /* Dissect the rest of the movement. */
- switch (mvar3)
- {
- case 0: /* To room */
- /*
- * Convert movement var2 into action var2 and var3. Var2 is 0 for move
- * to room, 6 for move to player room. Var3 is 0 for hidden, otherwise
- * the room number plus one.
- */
- if (mvar2 == 0) /* Hidden */
- parse_fixup_v380_action (0, 3, var1, 0, 0);
- else if (mvar2 == 1) /* Player room */
- parse_fixup_v380_action (0, 3, var1, 6, 0);
- else /* Specified room */
- parse_fixup_v380_action (0, 3, var1, 0, mvar2 - 1);
- break;
-
- case 1: /* To inside */
- case 2: /* To onto */
- /*
- * Convert movement var2 and var3 into action var3 and var2, a simple
- * conversion, but check that var2 is not 'not selected' first.
- */
- if (mvar2 > 0)
- parse_fixup_v380_action (0, 3, var1, mvar3 + 1, mvar2 - 1);
- break;
-
- case 3: /* To held by */
- case 4: /* To worn by */
- /*
- * Convert movement var2 and var3 into action var3 and var2, in this
- * case a simple conversion, since version 4.0 task actions are close
- * here.
- */
- parse_fixup_v380_action (0, 3, var1, mvar3 + 1, mvar2);
- break;
-
- default:
- sc_fatal ("parse_fixup_v380_movement: invalid mvar3, %ld\n", mvar3);
- }
+parse_fixup_v380_movement(sc_int mvar1, sc_int mvar2, sc_int mvar3) {
+ sc_int var1;
+
+ /* If nothing was selected to move, ignore the call. */
+ if (mvar1 == 0)
+ return;
+
+ /*
+ * Accept only player moves into rooms. Other combinations, such as move
+ * player to worn by player, are unlikely. And move player to same room as
+ * player isn't useful.
+ */
+ if (mvar1 == 1) {
+ if (mvar3 == 0 && mvar2 >= 2)
+ parse_fixup_v380_action(1, 3, 0, 0, mvar2 - 2);
+ return;
+ }
+
+ /*
+ * Convert movement var1 into action var1. Var1 is the dynamic object + 3,
+ * or 2 for referenced object, or 0 for all held.
+ */
+ switch (mvar1) {
+ case 2:
+ var1 = 2;
+ break; /* Referenced obj */
+ case 3:
+ var1 = 0;
+ break; /* All held */
+ default:
+ var1 = mvar1 - 1;
+ break; /* Dynamic obj */
+ }
+
+ /* Dissect the rest of the movement. */
+ switch (mvar3) {
+ case 0: /* To room */
+ /*
+ * Convert movement var2 into action var2 and var3. Var2 is 0 for move
+ * to room, 6 for move to player room. Var3 is 0 for hidden, otherwise
+ * the room number plus one.
+ */
+ if (mvar2 == 0) /* Hidden */
+ parse_fixup_v380_action(0, 3, var1, 0, 0);
+ else if (mvar2 == 1) /* Player room */
+ parse_fixup_v380_action(0, 3, var1, 6, 0);
+ else /* Specified room */
+ parse_fixup_v380_action(0, 3, var1, 0, mvar2 - 1);
+ break;
+
+ case 1: /* To inside */
+ case 2: /* To onto */
+ /*
+ * Convert movement var2 and var3 into action var3 and var2, a simple
+ * conversion, but check that var2 is not 'not selected' first.
+ */
+ if (mvar2 > 0)
+ parse_fixup_v380_action(0, 3, var1, mvar3 + 1, mvar2 - 1);
+ break;
+
+ case 3: /* To held by */
+ case 4: /* To worn by */
+ /*
+ * Convert movement var2 and var3 into action var3 and var2, in this
+ * case a simple conversion, since version 4.0 task actions are close
+ * here.
+ */
+ parse_fixup_v380_action(0, 3, var1, mvar3 + 1, mvar2);
+ break;
+
+ default:
+ sc_fatal("parse_fixup_v380_movement: invalid mvar3, %ld\n", mvar3);
+ }
}
@@ -2238,64 +2246,61 @@ parse_fixup_v380_movement (sc_int mvar1, sc_int mvar2, sc_int mvar3)
* Helper for parse_fixup_v380(), adds a task restriction.
*/
static void
-parse_fixup_v380_restr (sc_int type, sc_int var_count,
- sc_int var1, sc_int var2, sc_int var3,
- const sc_char *failmessage)
-{
- sc_vartype_t vt_key, vt_value;
- sc_int restriction_count;
-
- /* Get a count of restrictions so far defined for the task. */
- vt_key.string = "Restrictions";
- parse_push_key (vt_key, PROP_KEY_STRING);
- restriction_count = parse_get_child_count ();
- parse_pop_key ();
-
- /* Write restrictions key, reversed to emulate parse actions. */
- vt_key.integer = restriction_count;
- parse_push_key (vt_key, PROP_KEY_INTEGER);
- vt_key.string = "Restrictions";
- parse_push_key (vt_key, PROP_KEY_STRING);
-
- /* Write new restriction according to the given arguments. */
- vt_key.string = "Type";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.integer = type;
- parse_put_property (vt_value, PROP_INTEGER);
- parse_pop_key ();
-
- vt_key.string = "Var1";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.integer = var1;
- parse_put_property (vt_value, PROP_INTEGER);
- parse_pop_key ();
-
- if (var_count > 1)
- {
- vt_key.string = "Var2";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.integer = var2;
- parse_put_property (vt_value, PROP_INTEGER);
- parse_pop_key ();
- }
-
- if (var_count > 2)
- {
- vt_key.string = "Var3";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.integer = var3;
- parse_put_property (vt_value, PROP_INTEGER);
- parse_pop_key ();
- }
-
- vt_key.string = "FailMessage";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.string = failmessage;
- parse_put_property (vt_value, PROP_STRING);
- parse_pop_key ();
-
- parse_pop_key ();
- parse_pop_key ();
+parse_fixup_v380_restr(sc_int type, sc_int var_count,
+ sc_int var1, sc_int var2, sc_int var3,
+ const sc_char *failmessage) {
+ sc_vartype_t vt_key, vt_value;
+ sc_int restriction_count;
+
+ /* Get a count of restrictions so far defined for the task. */
+ vt_key.string = "Restrictions";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ restriction_count = parse_get_child_count();
+ parse_pop_key();
+
+ /* Write restrictions key, reversed to emulate parse actions. */
+ vt_key.integer = restriction_count;
+ parse_push_key(vt_key, PROP_KEY_INTEGER);
+ vt_key.string = "Restrictions";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+
+ /* Write new restriction according to the given arguments. */
+ vt_key.string = "Type";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.integer = type;
+ parse_put_property(vt_value, PROP_INTEGER);
+ parse_pop_key();
+
+ vt_key.string = "Var1";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.integer = var1;
+ parse_put_property(vt_value, PROP_INTEGER);
+ parse_pop_key();
+
+ if (var_count > 1) {
+ vt_key.string = "Var2";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.integer = var2;
+ parse_put_property(vt_value, PROP_INTEGER);
+ parse_pop_key();
+ }
+
+ if (var_count > 2) {
+ vt_key.string = "Var3";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.integer = var3;
+ parse_put_property(vt_value, PROP_INTEGER);
+ parse_pop_key();
+ }
+
+ vt_key.string = "FailMessage";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.string = failmessage;
+ parse_put_property(vt_value, PROP_STRING);
+ parse_pop_key();
+
+ parse_pop_key();
+ parse_pop_key();
}
@@ -2310,223 +2315,201 @@ parse_fixup_v380_restr (sc_int type, sc_int var_count,
* Helper handlers for parse_fixup_v380(); create task restrictions.
*/
static void
-parse_fixup_v380_obj_restr (sc_bool holding,
- sc_int holdobj, const sc_char *failmessage)
-{
- /* Ignore if no object selected. */
- if (holdobj > 0)
- {
- sc_int var1, var2;
-
- /*
- * Create version 4.0 task restriction to check for either the
- * referenced object or a dynamic object being either held or in the
- * same room (visible to player).
- */
- var1 = (holdobj == 1) ? 2 : holdobj + 1;
- var2 = holding ? 1 : 3;
- parse_fixup_v380_restr (0, 3, var1, var2, 0, failmessage);
- }
+parse_fixup_v380_obj_restr(sc_bool holding,
+ sc_int holdobj, const sc_char *failmessage) {
+ /* Ignore if no object selected. */
+ if (holdobj > 0) {
+ sc_int var1, var2;
+
+ /*
+ * Create version 4.0 task restriction to check for either the
+ * referenced object or a dynamic object being either held or in the
+ * same room (visible to player).
+ */
+ var1 = (holdobj == 1) ? 2 : holdobj + 1;
+ var2 = holding ? 1 : 3;
+ parse_fixup_v380_restr(0, 3, var1, var2, 0, failmessage);
+ }
}
static void
-parse_fixup_v380_task_restr (sc_bool tasknotdone, sc_int task,
- const sc_char *failmessage)
-{
- /* Ignore if no task selected. */
- if (task > 0)
- {
- sc_int var2;
-
- /* Create version 4.0 restriction to check task state. */
- var2 = tasknotdone ? 1 : 0;
- parse_fixup_v380_restr (2, 2, task, var2, 0, failmessage);
- }
+parse_fixup_v380_task_restr(sc_bool tasknotdone, sc_int task,
+ const sc_char *failmessage) {
+ /* Ignore if no task selected. */
+ if (task > 0) {
+ sc_int var2;
+
+ /* Create version 4.0 restriction to check task state. */
+ var2 = tasknotdone ? 1 : 0;
+ parse_fixup_v380_restr(2, 2, task, var2, 0, failmessage);
+ }
}
static void
-parse_fixup_v380_wear_restr (sc_int wearobj, const sc_char *failmessage)
-{
- /* Ignore if no object selected. */
- if (wearobj > 0)
- {
- sc_vartype_t vt_key[3];
- sc_int object_count, object, dynamic, obj_index;
-
- /*
- * Create version 4.0 restrictions for something or nothing worn by
- * player.
- */
- if (wearobj == 1)
- {
- parse_fixup_v380_restr (0, 3, 1, 2, 0, failmessage);
- return;
- }
- else if (wearobj == 2)
- {
- parse_fixup_v380_restr (0, 3, 0, 2, 0, failmessage);
- return;
- }
-
- /* Get the count of objects defined. */
- vt_key[0].string = "Objects";
- object_count = prop_get_child_count (parse_bundle, "I<-s", vt_key);
-
- /* Convert wearobj from worn index to object index. */
- wearobj -= 2;
- for (object = 0; object < object_count && wearobj > 0; object++)
- {
- sc_bool bstatic, wearable;
-
- vt_key[1].integer = object;
- vt_key[2].string = "Static";
- bstatic = prop_get_boolean (parse_bundle, "B<-sis", vt_key);
- if (!bstatic)
- {
- vt_key[2].string = "Wearable";
- wearable = prop_get_boolean (parse_bundle, "B<-sis", vt_key);
- if (wearable)
- wearobj--;
- }
- }
- obj_index = object - 1;
-
- /* Now convert wearobj from object index to dynamic index. */
- dynamic = 0;
- for (object = 0; object <= obj_index; object++)
- {
- sc_bool bstatic;
-
- vt_key[1].integer = object;
- vt_key[2].string = "Static";
- bstatic = prop_get_boolean (parse_bundle, "B<-sis", vt_key);
- if (!bstatic)
- dynamic++;
- }
- dynamic--;
-
- /* Create version 4.0 restriction for object worn by player. */
- parse_fixup_v380_restr (0, 3, dynamic + 3, 2, 0, failmessage);
- }
+parse_fixup_v380_wear_restr(sc_int wearobj, const sc_char *failmessage) {
+ /* Ignore if no object selected. */
+ if (wearobj > 0) {
+ sc_vartype_t vt_key[3];
+ sc_int object_count, object, dynamic, obj_index;
+
+ /*
+ * Create version 4.0 restrictions for something or nothing worn by
+ * player.
+ */
+ if (wearobj == 1) {
+ parse_fixup_v380_restr(0, 3, 1, 2, 0, failmessage);
+ return;
+ } else if (wearobj == 2) {
+ parse_fixup_v380_restr(0, 3, 0, 2, 0, failmessage);
+ return;
+ }
+
+ /* Get the count of objects defined. */
+ vt_key[0].string = "Objects";
+ object_count = prop_get_child_count(parse_bundle, "I<-s", vt_key);
+
+ /* Convert wearobj from worn index to object index. */
+ wearobj -= 2;
+ for (object = 0; object < object_count && wearobj > 0; object++) {
+ sc_bool bstatic, wearable;
+
+ vt_key[1].integer = object;
+ vt_key[2].string = "Static";
+ bstatic = prop_get_boolean(parse_bundle, "B<-sis", vt_key);
+ if (!bstatic) {
+ vt_key[2].string = "Wearable";
+ wearable = prop_get_boolean(parse_bundle, "B<-sis", vt_key);
+ if (wearable)
+ wearobj--;
+ }
+ }
+ obj_index = object - 1;
+
+ /* Now convert wearobj from object index to dynamic index. */
+ dynamic = 0;
+ for (object = 0; object <= obj_index; object++) {
+ sc_bool bstatic;
+
+ vt_key[1].integer = object;
+ vt_key[2].string = "Static";
+ bstatic = prop_get_boolean(parse_bundle, "B<-sis", vt_key);
+ if (!bstatic)
+ dynamic++;
+ }
+ dynamic--;
+
+ /* Create version 4.0 restriction for object worn by player. */
+ parse_fixup_v380_restr(0, 3, dynamic + 3, 2, 0, failmessage);
+ }
}
static void
-parse_fixup_v380_npc_restr (sc_bool notinsameroom, sc_int npc,
- const sc_char *failmessage)
-{
- /* Ignore if no NPC selected. */
- if (npc > 0)
- {
- sc_int var2;
-
- if (npc == 1)
- {
- /* Create restriction to look for alone, or not. */
- var2 = notinsameroom ? 3 : 2;
- parse_fixup_v380_restr (3, 3, 0, var2, 0, failmessage);
- return;
- }
-
- /* Create restriction to look for company. */
- var2 = notinsameroom ? 1 : 0;
- parse_fixup_v380_restr (3, 3, 0, var2, npc, failmessage);
- }
+parse_fixup_v380_npc_restr(sc_bool notinsameroom, sc_int npc,
+ const sc_char *failmessage) {
+ /* Ignore if no NPC selected. */
+ if (npc > 0) {
+ sc_int var2;
+
+ if (npc == 1) {
+ /* Create restriction to look for alone, or not. */
+ var2 = notinsameroom ? 3 : 2;
+ parse_fixup_v380_restr(3, 3, 0, var2, 0, failmessage);
+ return;
+ }
+
+ /* Create restriction to look for company. */
+ var2 = notinsameroom ? 1 : 0;
+ parse_fixup_v380_restr(3, 3, 0, var2, npc, failmessage);
+ }
}
static void
-parse_fixup_v380_objroom_restr (sc_int obj, sc_int objroom,
- const sc_char *failmessage)
-{
- /* Ignore if no object selected. */
- if (obj > 0)
- {
- /* Create version 4.0 restriction to check object in room. */
- parse_fixup_v380_restr (0, 3, obj + 1, 0, objroom, failmessage);
- }
+parse_fixup_v380_objroom_restr(sc_int obj, sc_int objroom,
+ const sc_char *failmessage) {
+ /* Ignore if no object selected. */
+ if (obj > 0) {
+ /* Create version 4.0 restriction to check object in room. */
+ parse_fixup_v380_restr(0, 3, obj + 1, 0, objroom, failmessage);
+ }
}
static void
-parse_fixup_v380_objstate_restr (sc_int obj, sc_int ivar1, sc_int ivar2,
- const sc_char *failmessage)
-{
- sc_vartype_t vt_key[3];
- sc_int object, dynamic, var2, var3;
-
- /* Initialize variables to avoid gcc warnings. */
- var2 = -1;
- var3 = -1;
-
- /* Ignore restrictions with no "type". */
- if (ivar1 == 0)
- return;
-
- /* Look for opened/closed restrictions, convert and return. */
- if (ivar1 == 3 || ivar1 == 4)
- {
- sc_int stateful;
-
- /* Convert obj from object to openable (stateful) index. */
- stateful = 0;
- for (object = 0; object <= obj - 1; object++)
- {
- sc_int openable;
-
- vt_key[0].string = "Objects";
- vt_key[1].integer = object;
- vt_key[2].string = "Openable";
- openable = prop_get_integer (parse_bundle, "I<-sis", vt_key);
- if (openable > 0)
- stateful++;
- }
- stateful--;
-
- /*
- * Create a version 4.0 restriction that checks that an object's state
- * is open (var2 = 0) or closed (var2 = 1).
- */
- var2 = (ivar1 == 3) ? 0 : 1;
- parse_fixup_v380_restr (1, 2, stateful + 1, var2, 0, failmessage);
- return;
- }
-
- /* Convert obj from object to dynamic index. */
- dynamic = 0;
- for (object = 0; object <= obj - 1; object++)
- {
- sc_bool bstatic;
-
- vt_key[0].string = "Objects";
- vt_key[1].integer = object;
- vt_key[2].string = "Static";
- bstatic = prop_get_boolean (parse_bundle, "B<-sis", vt_key);
- if (!bstatic)
- dynamic++;
- }
- dynamic--;
-
- /* Create version 4.0 object location restrictions for the rest. */
- switch (ivar1)
- {
- case 1:
- var2 = 4;
- var3 = ivar2;
- break; /* Inside */
- case 2:
- var2 = 5;
- var3 = ivar2;
- break; /* On */
- case 5:
- var2 = 1;
- var3 = ivar2 + 1;
- break; /* Held by */
- case 6:
- var2 = 2;
- var3 = ivar2 + 1;
- break; /* Worn by */
- default:
- sc_fatal ("parse_fixup_v380_objstate_restr: invalid ivar1, %ld\n", ivar1);
- }
- parse_fixup_v380_restr (0, 3, dynamic + 3, var2, var3, failmessage);
+parse_fixup_v380_objstate_restr(sc_int obj, sc_int ivar1, sc_int ivar2,
+ const sc_char *failmessage) {
+ sc_vartype_t vt_key[3];
+ sc_int object, dynamic, var2, var3;
+
+ /* Initialize variables to avoid gcc warnings. */
+ var2 = -1;
+ var3 = -1;
+
+ /* Ignore restrictions with no "type". */
+ if (ivar1 == 0)
+ return;
+
+ /* Look for opened/closed restrictions, convert and return. */
+ if (ivar1 == 3 || ivar1 == 4) {
+ sc_int stateful;
+
+ /* Convert obj from object to openable (stateful) index. */
+ stateful = 0;
+ for (object = 0; object <= obj - 1; object++) {
+ sc_int openable;
+
+ vt_key[0].string = "Objects";
+ vt_key[1].integer = object;
+ vt_key[2].string = "Openable";
+ openable = prop_get_integer(parse_bundle, "I<-sis", vt_key);
+ if (openable > 0)
+ stateful++;
+ }
+ stateful--;
+
+ /*
+ * Create a version 4.0 restriction that checks that an object's state
+ * is open (var2 = 0) or closed (var2 = 1).
+ */
+ var2 = (ivar1 == 3) ? 0 : 1;
+ parse_fixup_v380_restr(1, 2, stateful + 1, var2, 0, failmessage);
+ return;
+ }
+
+ /* Convert obj from object to dynamic index. */
+ dynamic = 0;
+ for (object = 0; object <= obj - 1; object++) {
+ sc_bool bstatic;
+
+ vt_key[0].string = "Objects";
+ vt_key[1].integer = object;
+ vt_key[2].string = "Static";
+ bstatic = prop_get_boolean(parse_bundle, "B<-sis", vt_key);
+ if (!bstatic)
+ dynamic++;
+ }
+ dynamic--;
+
+ /* Create version 4.0 object location restrictions for the rest. */
+ switch (ivar1) {
+ case 1:
+ var2 = 4;
+ var3 = ivar2;
+ break; /* Inside */
+ case 2:
+ var2 = 5;
+ var3 = ivar2;
+ break; /* On */
+ case 5:
+ var2 = 1;
+ var3 = ivar2 + 1;
+ break; /* Held by */
+ case 6:
+ var2 = 2;
+ var3 = ivar2 + 1;
+ break; /* Worn by */
+ default:
+ sc_fatal("parse_fixup_v380_objstate_restr: invalid ivar1, %ld\n", ivar1);
+ }
+ parse_fixup_v380_restr(0, 3, dynamic + 3, var2, var3, failmessage);
}
@@ -2537,516 +2520,489 @@ parse_fixup_v380_objstate_restr (sc_int obj, sc_int ivar1, sc_int ivar2,
* 3.8 format into version 4.0.
*/
static void
-parse_fixup_v380 (const sc_char *fixup)
-{
- if (parse_trace)
- sc_trace ("Parse: entering version 3.8 fixup %s\n", fixup);
-
- /* Convert container capacity attributes to version 4.0 values. */
- if (strcmp (fixup, "|V380_OBJECT:#Capacity*10+2|") == 0)
- {
- sc_vartype_t vt_key, vt_value;
- sc_int surfacecontainer;
-
- /* Get the object surface and container attributes. */
- vt_key.string = "SurfaceContainer";
- parse_push_key (vt_key, PROP_KEY_STRING);
- surfacecontainer = parse_get_integer_property ();
- parse_pop_key ();
-
- /* Convert capacity from version 3.8 format to version 4.0. */
- if (surfacecontainer == V380_OBJ_IS_CONTAINER)
- {
- sc_int capacity;
-
- vt_key.string = "Capacity";
- parse_push_key (vt_key, PROP_KEY_STRING);
- capacity = parse_get_integer_property ();
-
- capacity = capacity * V380_OBJ_CAPACITY_MULT + V380_OBJ_DEFAULT_SIZE;
-
- vt_value.integer = capacity;
- parse_put_property (vt_value, PROP_INTEGER);
- parse_pop_key ();
- }
- }
-
- /*
- * Exchange openable values 5 and 6, watch for a possible 1 from a 3.8 game
- * (interpret as 0), and write -1 key for openable objects.
- */
- else if (strcmp (fixup, "|V380_OBJECT:_Openable_,Key|") == 0)
- {
- sc_vartype_t vt_key, vt_value;
- sc_int openable;
-
- /* Retrieve Openable, and if 5 or 6, exchange. */
- vt_key.string = "Openable";
- parse_push_key (vt_key, PROP_KEY_STRING);
- openable = parse_get_integer_property ();
-
- if (openable == 5 || openable == 6)
- {
- vt_value.integer = (openable == 5) ? 6 : 5;
- parse_put_property (vt_value, PROP_INTEGER);
- }
-
- /* If the odd value of 1, rewrite as zero. */
- else if (openable == 1)
- {
- vt_value.integer = 0;
- parse_put_property (vt_value, PROP_INTEGER);
- }
-
- parse_pop_key ();
-
- /* For openable objects, store a Key of -1. */
- if (openable == 5 || openable == 6)
- {
- vt_key.string = "Key";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.integer = -1;
- parse_put_property (vt_value, PROP_INTEGER);
- parse_pop_key ();
- }
- }
-
- /* Create version 4.0 task actions from a version 3.8 task. */
- else if (strcmp (fixup, "|V380_TASK:_Actions_|") == 0)
- {
- sc_vartype_t vt_key;
- sc_int score;
- sc_bool killsplayer, wingame;
- sc_int movement;
-
- /* Retrieve the score change for the task. */
- vt_key.string = "Score";
- parse_push_key (vt_key, PROP_KEY_STRING);
- score = parse_get_integer_property ();
- parse_pop_key ();
-
- /* Create any appropriate score change action. */
- if (score != 0)
- parse_fixup_v380_action (4, 1, score, 0, 0);
-
- /* Get player death and game winning flags. */
- vt_key.string = "KillsPlayer";
- parse_push_key (vt_key, PROP_KEY_STRING);
- killsplayer = parse_get_boolean_property ();
- parse_pop_key ();
- vt_key.string = "WinGame";
- parse_push_key (vt_key, PROP_KEY_STRING);
- wingame = parse_get_boolean_property ();
- parse_pop_key ();
-
- /* Create any appropriate game ending actions. */
- if (killsplayer)
- parse_fixup_v380_action (6, 1, 2, 0, 0);
- if (wingame)
- parse_fixup_v380_action (6, 1, 0, 0, 0);
-
- /* Handle each defined movement for the task. */
- for (movement = 0; movement < V380_TASK_MOVEMENTS; movement++)
- {
- sc_int mvar1, mvar2, mvar3;
-
- vt_key.integer = movement;
- parse_push_key (vt_key, PROP_KEY_INTEGER);
- vt_key.string = "Movements";
- parse_push_key (vt_key, PROP_KEY_STRING);
-
- /* Retrieve the movement parameters. */
- vt_key.string = "Var1";
- parse_push_key (vt_key, PROP_KEY_STRING);
- mvar1 = parse_get_integer_property ();
- parse_pop_key ();
- vt_key.string = "Var2";
- parse_push_key (vt_key, PROP_KEY_STRING);
- mvar2 = parse_get_integer_property ();
- parse_pop_key ();
- vt_key.string = "Var3";
- parse_push_key (vt_key, PROP_KEY_STRING);
- mvar3 = parse_get_integer_property ();
- parse_pop_key ();
-
- parse_pop_key ();
- parse_pop_key ();
-
- /* Create the corresponding task action. */
- parse_fixup_v380_movement (mvar1, mvar2, mvar3);
- }
- }
-
- /* Create version 4.0 task restrictions from a version 3.8 task. */
- else if (strcmp (fixup, "|V380_TASK:_Restrictions_|") == 0)
- {
- sc_vartype_t vt_key, vt_value;
- sc_bool holding, tasknotdone, notinsameroom;
- sc_int holdobj1, holdobj2, holdobj3, task;
- sc_int wearobj1, wearobj2, npc, obj1, obj1room, obj2;
- const sc_char *holdmsg, *taskmsg, *wearmsg, *companymsg;
- const sc_char *obj1msg;
- sc_int restriction_count;
-
- /* Create restrictions for objects not held or absent. */
- vt_key.string = "HoldingSameRoom";
- parse_push_key (vt_key, PROP_KEY_STRING);
- holding = parse_get_boolean_property ();
- parse_pop_key ();
-
- vt_key.string = "HoldObj1";
- parse_push_key (vt_key, PROP_KEY_STRING);
- holdobj1 = parse_get_integer_property ();
- parse_pop_key ();
-
- vt_key.string = "HoldObj2";
- parse_push_key (vt_key, PROP_KEY_STRING);
- holdobj2 = parse_get_integer_property ();
- parse_pop_key ();
-
- vt_key.string = "HoldObj3";
- parse_push_key (vt_key, PROP_KEY_STRING);
- holdobj3 = parse_get_integer_property ();
- parse_pop_key ();
-
- vt_key.string = "HoldMsg";
- parse_push_key (vt_key, PROP_KEY_STRING);
- holdmsg = parse_get_string_property ();
- parse_pop_key ();
-
- parse_fixup_v380_obj_restr (holding, holdobj1, holdmsg);
- parse_fixup_v380_obj_restr (holding, holdobj2, holdmsg);
- parse_fixup_v380_obj_restr (holding, holdobj3, holdmsg);
-
- /* Create any task state restriction. */
- vt_key.string = "TaskNotDone";
- parse_push_key (vt_key, PROP_KEY_STRING);
- tasknotdone = parse_get_boolean_property ();
- parse_pop_key ();
-
- vt_key.string = "Task";
- parse_push_key (vt_key, PROP_KEY_STRING);
- task = parse_get_integer_property ();
- parse_pop_key ();
-
- vt_key.string = "TaskMsg";
- parse_push_key (vt_key, PROP_KEY_STRING);
- taskmsg = parse_get_string_property ();
- parse_pop_key ();
-
- parse_fixup_v380_task_restr (tasknotdone, task, taskmsg);
-
- /* Create any object not worn restrictions. */
- vt_key.string = "WearObj1";
- parse_push_key (vt_key, PROP_KEY_STRING);
- wearobj1 = parse_get_integer_property ();
- parse_pop_key ();
-
- vt_key.string = "WearObj2";
- parse_push_key (vt_key, PROP_KEY_STRING);
- wearobj2 = parse_get_integer_property ();
- parse_pop_key ();
-
- vt_key.string = "WearMsg";
- parse_push_key (vt_key, PROP_KEY_STRING);
- wearmsg = parse_get_string_property ();
- parse_pop_key ();
-
- parse_fixup_v380_wear_restr (wearobj1, wearmsg);
- parse_fixup_v380_wear_restr (wearobj2, wearmsg);
-
- /* Check for presence/absence of NPCs restriction. */
- vt_key.string = "NotInSameRoom";
- parse_push_key (vt_key, PROP_KEY_STRING);
- notinsameroom = parse_get_boolean_property ();
- parse_pop_key ();
-
- vt_key.string = "NPC";
- parse_push_key (vt_key, PROP_KEY_STRING);
- npc = parse_get_integer_property ();
- parse_pop_key ();
-
- vt_key.string = "CompanyMsg";
- parse_push_key (vt_key, PROP_KEY_STRING);
- companymsg = parse_get_string_property ();
- parse_pop_key ();
-
- parse_fixup_v380_npc_restr (notinsameroom, npc, companymsg);
-
- /* Create any object location restriction. */
- vt_key.string = "Obj1";
- parse_push_key (vt_key, PROP_KEY_STRING);
- obj1 = parse_get_integer_property ();
- parse_pop_key ();
-
- vt_key.string = "Obj1Room";
- parse_push_key (vt_key, PROP_KEY_STRING);
- obj1room = parse_get_integer_property ();
- parse_pop_key ();
-
- vt_key.string = "Obj1Msg";
- parse_push_key (vt_key, PROP_KEY_STRING);
- obj1msg = parse_get_string_property ();
- parse_pop_key ();
-
- parse_fixup_v380_objroom_restr (obj1, obj1room, obj1msg);
-
- /* And finally, any object state restriction. */
- vt_key.string = "Obj2";
- parse_push_key (vt_key, PROP_KEY_STRING);
- obj2 = parse_get_integer_property ();
- parse_pop_key ();
-
- if (obj2 > 0)
- {
- sc_int var1, var2;
- const sc_char *obj2msg;
-
- vt_key.string = "Obj2Var1";
- parse_push_key (vt_key, PROP_KEY_STRING);
- var1 = parse_get_integer_property ();
- parse_pop_key ();
-
- vt_key.string = "Obj2Var2";
- parse_push_key (vt_key, PROP_KEY_STRING);
- var2 = parse_get_integer_property ();
- parse_pop_key ();
-
- vt_key.string = "Obj2Msg";
- parse_push_key (vt_key, PROP_KEY_STRING);
- obj2msg = parse_get_string_property ();
- parse_pop_key ();
-
- parse_fixup_v380_objstate_restr (obj2, var1, var2, obj2msg);
- }
-
- /* Get a count of restrictions created. */
- vt_key.string = "Restrictions";
- parse_push_key (vt_key, PROP_KEY_STRING);
- restriction_count = parse_get_child_count ();
- parse_pop_key ();
-
- /* Allocate and fill a new mask for these restrictions. */
- if (restriction_count > 0)
- {
- sc_char *restrmask;
- sc_int index_;
-
- restrmask = (sc_char *)sc_malloc (2 * restriction_count);
- strcpy (restrmask, "#");
- for (index_ = 1; index_ < restriction_count; index_++)
- strcat (restrmask, "A#");
-
- vt_key.string = "RestrMask";
- parse_push_key (vt_key, PROP_KEY_STRING);
- vt_value.string = restrmask;
- parse_put_property (vt_value, PROP_STRING);
- parse_pop_key ();
-
- prop_adopt (parse_bundle, restrmask);
- }
- }
-
- /*
- * Adjust dynamic object initial positions and parents (where contained
- * or on surfaces) into version 4.0 range.
- */
- else if (strcmp (fixup, "|V380_OBJECT:_InitialPositions_|") == 0)
- {
- sc_vartype_t vt_key[3];
- sc_int object_count, object, *object_type;
-
- /* Get a count of objects. */
- vt_key[0].string = "Objects";
- object_count = prop_get_child_count (parse_bundle, "I<-s", vt_key);
-
- /* Build an array of object container/surface types. */
- object_type = (sc_int *)sc_malloc (object_count * sizeof (*object_type));
- for (object = 0; object < object_count; object++)
- {
- vt_key[1].integer = object;
- vt_key[2].string = "SurfaceContainer";
- object_type[object] = prop_get_integer (parse_bundle,
- "I<-sis", vt_key);
- }
-
- /* Adjust each object's initial position if necessary. */
- for (object = 0; object < object_count; object++)
- {
- sc_vartype_t vt_value;
- sc_bool is_static;
- sc_int initialposition;
-
- /* Ignore static objects; we only want dynamic ones. */
- vt_key[1].integer = object;
- vt_key[2].string = "Static";
- is_static = prop_get_boolean (parse_bundle, "B<-sis", vt_key);
- if (is_static)
- continue;
-
- /* If initial position is above on/in, increment. */
- vt_key[1].integer = object;
- vt_key[2].string = "InitialPosition";
- initialposition = prop_get_integer (parse_bundle, "I<-sis", vt_key);
- if (initialposition > 2)
- {
- vt_value.integer = initialposition + 1;
- prop_put (parse_bundle, "I->sis", vt_value, vt_key);
- }
-
- /*
- * If initial position is on or in, decide which, depending on the
- * type of the parent. From this, expand initial position into a
- * version 4.0 value.
- */
- if (initialposition == 2)
- {
- sc_int count, parent, index_;
-
- /* Get parent container/surface index. */
- vt_key[1].integer = object;
- vt_key[2].string = "Parent";
- count = prop_get_integer (parse_bundle, "I<-sis", vt_key);
-
- /* Convert container/surface index. */
- for (parent = 0; parent < object_count && count >= 0; parent++)
- {
- if (object_type[parent] == V380_OBJ_IS_CONTAINER
- || object_type[parent] == V380_OBJ_IS_SURFACE)
- count--;
- }
- parent--;
-
- /* If parent is a surface, adjust position. */
- if (object_type[parent] == V380_OBJ_IS_SURFACE)
- {
- vt_key[2].string = "InitialPosition";
- vt_value.integer = initialposition + 1;
- prop_put (parse_bundle, "I->sis", vt_value, vt_key);
- }
-
- /*
- * For both, adjust parent to be an object index for that type
- * of object only.
- */
- count = 0;
- for (index_ = 0; index_ < parent; index_++)
- {
- if (object_type[index_] == object_type[parent])
- count++;
- }
- vt_key[2].string = "Parent";
- vt_value.integer = count;
- prop_put (parse_bundle, "I->sis", vt_value, vt_key);
- }
- }
-
- /* Done with temporary array. */
- sc_free (object_type);
- }
-
- /* Convert carry limit into version 4.0-like size and weight limits. */
- else if (strcmp (fixup, "|V380_MaxSize_MaxWt_|") == 0)
- {
- sc_vartype_t vt_key, vt_value;
- sc_int maxcarried;
-
- vt_key.string = "MaxCarried";
- parse_push_key (vt_key, PROP_KEY_STRING);
- maxcarried = parse_get_integer_property ();
- parse_pop_key ();
-
- vt_value.integer = maxcarried * V380_OBJ_CAPACITY_MULT
- + V380_OBJ_DEFAULT_SIZE;
-
- vt_key.string = "MaxSize";
- parse_push_key (vt_key, PROP_KEY_STRING);
- parse_put_property (vt_value, PROP_INTEGER);
- parse_pop_key ();
-
- vt_key.string = "MaxWt";
- parse_push_key (vt_key, PROP_KEY_STRING);
- parse_put_property (vt_value, PROP_INTEGER);
- parse_pop_key ();
- }
-
- /* Add up positive scoring tasks to arrive at max score. */
- else if (strcmp (fixup, "|V380_GLOBAL:_MaxScore_|") == 0)
- {
- sc_vartype_t vt_key[3], vt_value;
- sc_int task_count, maxscore, task;
-
- /* Get a count of tasks. */
- vt_key[0].string = "Tasks";
- task_count = prop_get_child_count (parse_bundle, "I<-s", vt_key);
-
- /* Sum positive scoring tasks. */
- maxscore = 0;
- for (task = 0; task < task_count; task++)
- {
- sc_int score;
-
- vt_key[1].integer = task;
- vt_key[2].string = "Score";
- score = prop_get_integer (parse_bundle, "I<-sis", vt_key);
- if (score > 0)
- maxscore += score;
- }
-
- /* Write MaxScore global property. */
- vt_key[0].string = "Globals";
- vt_key[1].string = "MaxScore";
- vt_value.integer = maxscore;
- prop_put (parse_bundle, "I->ss", vt_value, vt_key);
- }
-
- /* Convert walk meetobject from dynamic index to object. */
- else if (strcmp (fixup, "|V380_WALK:_MeetObject_|") == 0)
- {
- sc_vartype_t vt_key, vt_value, vt_gkey[3];
- sc_int meetobject, count, object_count, object;
-
- vt_key.string = "MeetObject";
- parse_push_key (vt_key, PROP_KEY_STRING);
- meetobject = parse_get_integer_property ();
-
- /* Get a count of objects. */
- vt_gkey[0].string = "Objects";
- object_count = prop_get_child_count (parse_bundle, "I<-s", vt_gkey);
-
- /* Convert dynamic index to object, and rewrite. */
- count = meetobject - 1;
- for (object = 0; object < object_count && count >= 0; object++)
- {
- sc_bool bstatic;
-
- vt_gkey[1].integer = object;
- vt_gkey[2].string = "Static";
- bstatic = prop_get_boolean (parse_bundle, "B<-sis", vt_gkey);
- if (!bstatic)
- count--;
- }
- object--;
-
- vt_value.integer = object;
- parse_put_property (vt_value, PROP_INTEGER);
- parse_pop_key ();
- }
-
- /* Convert version 3.8 room data into a version 4.0 alts array. */
- else if (strcmp (fixup, "|V380_ROOM:_Alts_|") == 0)
- {
- parse_fixup_v390_v380_room_alts ();
- }
-
- /* Error if no fixup special handler available. */
- else
- {
- sc_fatal ("parse_fixup_v380: no handler for \"%s\"\n", fixup);
- }
-
- if (parse_trace)
- sc_trace ("Parse: leaving version 3.8 fixup %s\n", fixup);
+parse_fixup_v380(const sc_char *fixup) {
+ if (parse_trace)
+ sc_trace("Parse: entering version 3.8 fixup %s\n", fixup);
+
+ /* Convert container capacity attributes to version 4.0 values. */
+ if (strcmp(fixup, "|V380_OBJECT:#Capacity*10+2|") == 0) {
+ sc_vartype_t vt_key, vt_value;
+ sc_int surfacecontainer;
+
+ /* Get the object surface and container attributes. */
+ vt_key.string = "SurfaceContainer";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ surfacecontainer = parse_get_integer_property();
+ parse_pop_key();
+
+ /* Convert capacity from version 3.8 format to version 4.0. */
+ if (surfacecontainer == V380_OBJ_IS_CONTAINER) {
+ sc_int capacity;
+
+ vt_key.string = "Capacity";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ capacity = parse_get_integer_property();
+
+ capacity = capacity * V380_OBJ_CAPACITY_MULT + V380_OBJ_DEFAULT_SIZE;
+
+ vt_value.integer = capacity;
+ parse_put_property(vt_value, PROP_INTEGER);
+ parse_pop_key();
+ }
+ }
+
+ /*
+ * Exchange openable values 5 and 6, watch for a possible 1 from a 3.8 game
+ * (interpret as 0), and write -1 key for openable objects.
+ */
+ else if (strcmp(fixup, "|V380_OBJECT:_Openable_,Key|") == 0) {
+ sc_vartype_t vt_key, vt_value;
+ sc_int openable;
+
+ /* Retrieve Openable, and if 5 or 6, exchange. */
+ vt_key.string = "Openable";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ openable = parse_get_integer_property();
+
+ if (openable == 5 || openable == 6) {
+ vt_value.integer = (openable == 5) ? 6 : 5;
+ parse_put_property(vt_value, PROP_INTEGER);
+ }
+
+ /* If the odd value of 1, rewrite as zero. */
+ else if (openable == 1) {
+ vt_value.integer = 0;
+ parse_put_property(vt_value, PROP_INTEGER);
+ }
+
+ parse_pop_key();
+
+ /* For openable objects, store a Key of -1. */
+ if (openable == 5 || openable == 6) {
+ vt_key.string = "Key";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.integer = -1;
+ parse_put_property(vt_value, PROP_INTEGER);
+ parse_pop_key();
+ }
+ }
+
+ /* Create version 4.0 task actions from a version 3.8 task. */
+ else if (strcmp(fixup, "|V380_TASK:_Actions_|") == 0) {
+ sc_vartype_t vt_key;
+ sc_int score;
+ sc_bool killsplayer, wingame;
+ sc_int movement;
+
+ /* Retrieve the score change for the task. */
+ vt_key.string = "Score";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ score = parse_get_integer_property();
+ parse_pop_key();
+
+ /* Create any appropriate score change action. */
+ if (score != 0)
+ parse_fixup_v380_action(4, 1, score, 0, 0);
+
+ /* Get player death and game winning flags. */
+ vt_key.string = "KillsPlayer";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ killsplayer = parse_get_boolean_property();
+ parse_pop_key();
+ vt_key.string = "WinGame";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ wingame = parse_get_boolean_property();
+ parse_pop_key();
+
+ /* Create any appropriate game ending actions. */
+ if (killsplayer)
+ parse_fixup_v380_action(6, 1, 2, 0, 0);
+ if (wingame)
+ parse_fixup_v380_action(6, 1, 0, 0, 0);
+
+ /* Handle each defined movement for the task. */
+ for (movement = 0; movement < V380_TASK_MOVEMENTS; movement++) {
+ sc_int mvar1, mvar2, mvar3;
+
+ vt_key.integer = movement;
+ parse_push_key(vt_key, PROP_KEY_INTEGER);
+ vt_key.string = "Movements";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+
+ /* Retrieve the movement parameters. */
+ vt_key.string = "Var1";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ mvar1 = parse_get_integer_property();
+ parse_pop_key();
+ vt_key.string = "Var2";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ mvar2 = parse_get_integer_property();
+ parse_pop_key();
+ vt_key.string = "Var3";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ mvar3 = parse_get_integer_property();
+ parse_pop_key();
+
+ parse_pop_key();
+ parse_pop_key();
+
+ /* Create the corresponding task action. */
+ parse_fixup_v380_movement(mvar1, mvar2, mvar3);
+ }
+ }
+
+ /* Create version 4.0 task restrictions from a version 3.8 task. */
+ else if (strcmp(fixup, "|V380_TASK:_Restrictions_|") == 0) {
+ sc_vartype_t vt_key, vt_value;
+ sc_bool holding, tasknotdone, notinsameroom;
+ sc_int holdobj1, holdobj2, holdobj3, task;
+ sc_int wearobj1, wearobj2, npc, obj1, obj1room, obj2;
+ const sc_char *holdmsg, *taskmsg, *wearmsg, *companymsg;
+ const sc_char *obj1msg;
+ sc_int restriction_count;
+
+ /* Create restrictions for objects not held or absent. */
+ vt_key.string = "HoldingSameRoom";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ holding = parse_get_boolean_property();
+ parse_pop_key();
+
+ vt_key.string = "HoldObj1";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ holdobj1 = parse_get_integer_property();
+ parse_pop_key();
+
+ vt_key.string = "HoldObj2";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ holdobj2 = parse_get_integer_property();
+ parse_pop_key();
+
+ vt_key.string = "HoldObj3";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ holdobj3 = parse_get_integer_property();
+ parse_pop_key();
+
+ vt_key.string = "HoldMsg";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ holdmsg = parse_get_string_property();
+ parse_pop_key();
+
+ parse_fixup_v380_obj_restr(holding, holdobj1, holdmsg);
+ parse_fixup_v380_obj_restr(holding, holdobj2, holdmsg);
+ parse_fixup_v380_obj_restr(holding, holdobj3, holdmsg);
+
+ /* Create any task state restriction. */
+ vt_key.string = "TaskNotDone";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ tasknotdone = parse_get_boolean_property();
+ parse_pop_key();
+
+ vt_key.string = "Task";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ task = parse_get_integer_property();
+ parse_pop_key();
+
+ vt_key.string = "TaskMsg";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ taskmsg = parse_get_string_property();
+ parse_pop_key();
+
+ parse_fixup_v380_task_restr(tasknotdone, task, taskmsg);
+
+ /* Create any object not worn restrictions. */
+ vt_key.string = "WearObj1";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ wearobj1 = parse_get_integer_property();
+ parse_pop_key();
+
+ vt_key.string = "WearObj2";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ wearobj2 = parse_get_integer_property();
+ parse_pop_key();
+
+ vt_key.string = "WearMsg";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ wearmsg = parse_get_string_property();
+ parse_pop_key();
+
+ parse_fixup_v380_wear_restr(wearobj1, wearmsg);
+ parse_fixup_v380_wear_restr(wearobj2, wearmsg);
+
+ /* Check for presence/absence of NPCs restriction. */
+ vt_key.string = "NotInSameRoom";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ notinsameroom = parse_get_boolean_property();
+ parse_pop_key();
+
+ vt_key.string = "NPC";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ npc = parse_get_integer_property();
+ parse_pop_key();
+
+ vt_key.string = "CompanyMsg";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ companymsg = parse_get_string_property();
+ parse_pop_key();
+
+ parse_fixup_v380_npc_restr(notinsameroom, npc, companymsg);
+
+ /* Create any object location restriction. */
+ vt_key.string = "Obj1";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ obj1 = parse_get_integer_property();
+ parse_pop_key();
+
+ vt_key.string = "Obj1Room";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ obj1room = parse_get_integer_property();
+ parse_pop_key();
+
+ vt_key.string = "Obj1Msg";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ obj1msg = parse_get_string_property();
+ parse_pop_key();
+
+ parse_fixup_v380_objroom_restr(obj1, obj1room, obj1msg);
+
+ /* And finally, any object state restriction. */
+ vt_key.string = "Obj2";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ obj2 = parse_get_integer_property();
+ parse_pop_key();
+
+ if (obj2 > 0) {
+ sc_int var1, var2;
+ const sc_char *obj2msg;
+
+ vt_key.string = "Obj2Var1";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ var1 = parse_get_integer_property();
+ parse_pop_key();
+
+ vt_key.string = "Obj2Var2";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ var2 = parse_get_integer_property();
+ parse_pop_key();
+
+ vt_key.string = "Obj2Msg";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ obj2msg = parse_get_string_property();
+ parse_pop_key();
+
+ parse_fixup_v380_objstate_restr(obj2, var1, var2, obj2msg);
+ }
+
+ /* Get a count of restrictions created. */
+ vt_key.string = "Restrictions";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ restriction_count = parse_get_child_count();
+ parse_pop_key();
+
+ /* Allocate and fill a new mask for these restrictions. */
+ if (restriction_count > 0) {
+ sc_char *restrmask;
+ sc_int index_;
+
+ restrmask = (sc_char *)sc_malloc(2 * restriction_count);
+ strcpy(restrmask, "#");
+ for (index_ = 1; index_ < restriction_count; index_++)
+ strcat(restrmask, "A#");
+
+ vt_key.string = "RestrMask";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ vt_value.string = restrmask;
+ parse_put_property(vt_value, PROP_STRING);
+ parse_pop_key();
+
+ prop_adopt(parse_bundle, restrmask);
+ }
+ }
+
+ /*
+ * Adjust dynamic object initial positions and parents (where contained
+ * or on surfaces) into version 4.0 range.
+ */
+ else if (strcmp(fixup, "|V380_OBJECT:_InitialPositions_|") == 0) {
+ sc_vartype_t vt_key[3];
+ sc_int object_count, object, *object_type;
+
+ /* Get a count of objects. */
+ vt_key[0].string = "Objects";
+ object_count = prop_get_child_count(parse_bundle, "I<-s", vt_key);
+
+ /* Build an array of object container/surface types. */
+ object_type = (sc_int *)sc_malloc(object_count * sizeof(*object_type));
+ for (object = 0; object < object_count; object++) {
+ vt_key[1].integer = object;
+ vt_key[2].string = "SurfaceContainer";
+ object_type[object] = prop_get_integer(parse_bundle,
+ "I<-sis", vt_key);
+ }
+
+ /* Adjust each object's initial position if necessary. */
+ for (object = 0; object < object_count; object++) {
+ sc_vartype_t vt_value;
+ sc_bool is_static;
+ sc_int initialposition;
+
+ /* Ignore static objects; we only want dynamic ones. */
+ vt_key[1].integer = object;
+ vt_key[2].string = "Static";
+ is_static = prop_get_boolean(parse_bundle, "B<-sis", vt_key);
+ if (is_static)
+ continue;
+
+ /* If initial position is above on/in, increment. */
+ vt_key[1].integer = object;
+ vt_key[2].string = "InitialPosition";
+ initialposition = prop_get_integer(parse_bundle, "I<-sis", vt_key);
+ if (initialposition > 2) {
+ vt_value.integer = initialposition + 1;
+ prop_put(parse_bundle, "I->sis", vt_value, vt_key);
+ }
+
+ /*
+ * If initial position is on or in, decide which, depending on the
+ * type of the parent. From this, expand initial position into a
+ * version 4.0 value.
+ */
+ if (initialposition == 2) {
+ sc_int count, parent, index_;
+
+ /* Get parent container/surface index. */
+ vt_key[1].integer = object;
+ vt_key[2].string = "Parent";
+ count = prop_get_integer(parse_bundle, "I<-sis", vt_key);
+
+ /* Convert container/surface index. */
+ for (parent = 0; parent < object_count && count >= 0; parent++) {
+ if (object_type[parent] == V380_OBJ_IS_CONTAINER
+ || object_type[parent] == V380_OBJ_IS_SURFACE)
+ count--;
+ }
+ parent--;
+
+ /* If parent is a surface, adjust position. */
+ if (object_type[parent] == V380_OBJ_IS_SURFACE) {
+ vt_key[2].string = "InitialPosition";
+ vt_value.integer = initialposition + 1;
+ prop_put(parse_bundle, "I->sis", vt_value, vt_key);
+ }
+
+ /*
+ * For both, adjust parent to be an object index for that type
+ * of object only.
+ */
+ count = 0;
+ for (index_ = 0; index_ < parent; index_++) {
+ if (object_type[index_] == object_type[parent])
+ count++;
+ }
+ vt_key[2].string = "Parent";
+ vt_value.integer = count;
+ prop_put(parse_bundle, "I->sis", vt_value, vt_key);
+ }
+ }
+
+ /* Done with temporary array. */
+ sc_free(object_type);
+ }
+
+ /* Convert carry limit into version 4.0-like size and weight limits. */
+ else if (strcmp(fixup, "|V380_MaxSize_MaxWt_|") == 0) {
+ sc_vartype_t vt_key, vt_value;
+ sc_int maxcarried;
+
+ vt_key.string = "MaxCarried";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ maxcarried = parse_get_integer_property();
+ parse_pop_key();
+
+ vt_value.integer = maxcarried * V380_OBJ_CAPACITY_MULT
+ + V380_OBJ_DEFAULT_SIZE;
+
+ vt_key.string = "MaxSize";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ parse_put_property(vt_value, PROP_INTEGER);
+ parse_pop_key();
+
+ vt_key.string = "MaxWt";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ parse_put_property(vt_value, PROP_INTEGER);
+ parse_pop_key();
+ }
+
+ /* Add up positive scoring tasks to arrive at max score. */
+ else if (strcmp(fixup, "|V380_GLOBAL:_MaxScore_|") == 0) {
+ sc_vartype_t vt_key[3], vt_value;
+ sc_int task_count, maxscore, task;
+
+ /* Get a count of tasks. */
+ vt_key[0].string = "Tasks";
+ task_count = prop_get_child_count(parse_bundle, "I<-s", vt_key);
+
+ /* Sum positive scoring tasks. */
+ maxscore = 0;
+ for (task = 0; task < task_count; task++) {
+ sc_int score;
+
+ vt_key[1].integer = task;
+ vt_key[2].string = "Score";
+ score = prop_get_integer(parse_bundle, "I<-sis", vt_key);
+ if (score > 0)
+ maxscore += score;
+ }
+
+ /* Write MaxScore global property. */
+ vt_key[0].string = "Globals";
+ vt_key[1].string = "MaxScore";
+ vt_value.integer = maxscore;
+ prop_put(parse_bundle, "I->ss", vt_value, vt_key);
+ }
+
+ /* Convert walk meetobject from dynamic index to object. */
+ else if (strcmp(fixup, "|V380_WALK:_MeetObject_|") == 0) {
+ sc_vartype_t vt_key, vt_value, vt_gkey[3];
+ sc_int meetobject, count, object_count, object;
+
+ vt_key.string = "MeetObject";
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ meetobject = parse_get_integer_property();
+
+ /* Get a count of objects. */
+ vt_gkey[0].string = "Objects";
+ object_count = prop_get_child_count(parse_bundle, "I<-s", vt_gkey);
+
+ /* Convert dynamic index to object, and rewrite. */
+ count = meetobject - 1;
+ for (object = 0; object < object_count && count >= 0; object++) {
+ sc_bool bstatic;
+
+ vt_gkey[1].integer = object;
+ vt_gkey[2].string = "Static";
+ bstatic = prop_get_boolean(parse_bundle, "B<-sis", vt_gkey);
+ if (!bstatic)
+ count--;
+ }
+ object--;
+
+ vt_value.integer = object;
+ parse_put_property(vt_value, PROP_INTEGER);
+ parse_pop_key();
+ }
+
+ /* Convert version 3.8 room data into a version 4.0 alts array. */
+ else if (strcmp(fixup, "|V380_ROOM:_Alts_|") == 0) {
+ parse_fixup_v390_v380_room_alts();
+ }
+
+ /* Error if no fixup special handler available. */
+ else {
+ sc_fatal("parse_fixup_v380: no handler for \"%s\"\n", fixup);
+ }
+
+ if (parse_trace)
+ sc_trace("Parse: leaving version 3.8 fixup %s\n", fixup);
}
@@ -3057,27 +3013,25 @@ parse_fixup_v380 (const sc_char *fixup)
* 3.9 and version 3.8 formats into version 4.0.
*/
static void
-parse_fixup (const sc_char *fixup)
-{
- /*
- * Pick a fixup handler specific to the TAF version. This helps keep
- * fixup code separate, rather than glommed into one large function.
- */
- switch (taf_get_version (parse_taf))
- {
- case TAF_VERSION_400:
- sc_fatal ("parse_fixup: unexpected call\n");
- break;
- case TAF_VERSION_390:
- parse_fixup_v390 (fixup);
- break;
- case TAF_VERSION_380:
- parse_fixup_v380 (fixup);
- break;
- default:
- sc_fatal ("parse_fixup: invalid TAF file version\n");
- break;
- }
+parse_fixup(const sc_char *fixup) {
+ /*
+ * Pick a fixup handler specific to the TAF version. This helps keep
+ * fixup code separate, rather than glommed into one large function.
+ */
+ switch (taf_get_version(parse_taf)) {
+ case TAF_VERSION_400:
+ sc_fatal("parse_fixup: unexpected call\n");
+ break;
+ case TAF_VERSION_390:
+ parse_fixup_v390(fixup);
+ break;
+ case TAF_VERSION_380:
+ parse_fixup_v380(fixup);
+ break;
+ default:
+ sc_fatal("parse_fixup: invalid TAF file version\n");
+ break;
+ }
}
@@ -3087,55 +3041,53 @@ parse_fixup (const sc_char *fixup)
* Parse a class descriptor element.
*/
static void
-parse_element (const sc_char *element)
-{
- if (parse_trace)
- sc_trace ("Parse: entering element %s\n", element);
-
- /* Determine the element type from the first character. */
- switch (element[0])
- {
- case PARSE_ARRAY:
- parse_array (element);
- break;
- case PARSE_VECTOR:
- parse_vector (element);
- break;
- case PARSE_VECTOR_ALTERNATE:
- parse_vector_alternate (element);
- break;
- case PARSE_CLASS:
- parse_class (element);
- break;
- case PARSE_EXPRESSION:
- parse_expression (element);
- break;
- case PARSE_SPECIAL:
- parse_special (element);
- break;
- case PARSE_FIXUP:
- parse_fixup (element);
- break;
-
- case PARSE_INTEGER:
- case PARSE_DEFAULT_ZERO:
- case PARSE_BOOLEAN:
- case PARSE_DEFAULT_TRUE:
- case PARSE_DEFAULT_FALSE:
- case PARSE_STRING:
- case PARSE_DEFAULT_EMPTY:
- case PARSE_IGNORE_INTEGER:
- case PARSE_IGNORE_BOOLEAN:
- case PARSE_IGNORE_STRING:
- case PARSE_MULTILINE:
- parse_terminal (element);
- break;
- default:
- sc_fatal ("parse_element: bad type, %c\n", element[0]);
- }
-
- if (parse_trace)
- sc_trace ("Parse: leaving element %s\n", element);
+parse_element(const sc_char *element) {
+ if (parse_trace)
+ sc_trace("Parse: entering element %s\n", element);
+
+ /* Determine the element type from the first character. */
+ switch (element[0]) {
+ case PARSE_ARRAY:
+ parse_array(element);
+ break;
+ case PARSE_VECTOR:
+ parse_vector(element);
+ break;
+ case PARSE_VECTOR_ALTERNATE:
+ parse_vector_alternate(element);
+ break;
+ case PARSE_CLASS:
+ parse_class(element);
+ break;
+ case PARSE_EXPRESSION:
+ parse_expression(element);
+ break;
+ case PARSE_SPECIAL:
+ parse_special(element);
+ break;
+ case PARSE_FIXUP:
+ parse_fixup(element);
+ break;
+
+ case PARSE_INTEGER:
+ case PARSE_DEFAULT_ZERO:
+ case PARSE_BOOLEAN:
+ case PARSE_DEFAULT_TRUE:
+ case PARSE_DEFAULT_FALSE:
+ case PARSE_STRING:
+ case PARSE_DEFAULT_EMPTY:
+ case PARSE_IGNORE_INTEGER:
+ case PARSE_IGNORE_BOOLEAN:
+ case PARSE_IGNORE_STRING:
+ case PARSE_MULTILINE:
+ parse_terminal(element);
+ break;
+ default:
+ sc_fatal("parse_element: bad type, %c\n", element[0]);
+ }
+
+ if (parse_trace)
+ sc_trace("Parse: leaving element %s\n", element);
}
@@ -3145,26 +3097,24 @@ parse_element (const sc_char *element)
* Parse a class's properties descriptor list.
*/
static void
-parse_descriptor (const sc_char *descriptor)
-{
- sc_int next;
-
- /* Find and parse each element in the descriptor. */
- for (next = 0; descriptor[next] != NUL; )
- {
- sc_char element[PARSE_TEMP_LENGTH];
-
- /* Isolate the next descriptor element. */
- if (sscanf (descriptor + next, "%[^ ]", element) != 1)
- sc_fatal ("parse_element: no element, %s\n", descriptor + next);
-
- /* Parse this isolated element. */
- parse_element (element);
-
- /* Advance over the element and any trailing whitespace. */
- next += strlen (element);
- next += strspn (descriptor + next, " ");
- }
+parse_descriptor(const sc_char *descriptor) {
+ sc_int next;
+
+ /* Find and parse each element in the descriptor. */
+ for (next = 0; descriptor[next] != NUL;) {
+ sc_char element[PARSE_TEMP_LENGTH];
+
+ /* Isolate the next descriptor element. */
+ if (sscanf(descriptor + next, "%[^ ]", element) != 1)
+ sc_fatal("parse_element: no element, %s\n", descriptor + next);
+
+ /* Parse this isolated element. */
+ parse_element(element);
+
+ /* Advance over the element and any trailing whitespace. */
+ next += strlen(element);
+ next += strspn(descriptor + next, " ");
+ }
}
@@ -3174,47 +3124,44 @@ parse_descriptor (const sc_char *descriptor)
* Parse a class of properties.
*/
static void
-parse_class (const sc_char *class_)
-{
- sc_char class_name[PARSE_TEMP_LENGTH];
- sc_int index_;
- sc_vartype_t vt_key;
-
- /* Isolate the class name. */
- if (sscanf (class_, "<%[^>]", class_name) != 1)
- sc_fatal ("parse_class: error in class, %s\n", class_);
- if (parse_trace)
- sc_trace ("Parse: entering class %s\n", class_name);
-
- /* Find the class in the parse schema, and fail if not found. */
- for (index_ = 0; parse_schema[index_].class_name; index_++)
- {
- if (strcmp (parse_schema[index_].class_name, class_name) == 0)
- break;
- }
- if (!parse_schema[index_].class_name)
- sc_fatal ("parse_class: class not described, %s\n", class_name);
-
- /*
- * Unless we are at the top level of the parse schema, push the class tag
- * as a key. The top level is "_GAME_", index_ 0, and isn't part of key
- * formation.
- */
- if (index_ > 0)
- {
- vt_key.string = class_ + strlen (class_name) + 2;
- parse_push_key (vt_key, PROP_KEY_STRING);
- }
-
- /* Parse each element in the descriptor. */
- parse_descriptor (parse_schema[index_].descriptor);
-
- /* Pop a key if the class tag was pushed above. */
- if (index_ > 0)
- parse_pop_key ();
-
- if (parse_trace)
- sc_trace ("Parse: leaving class %s\n", class_name);
+parse_class(const sc_char *class_) {
+ sc_char class_name[PARSE_TEMP_LENGTH];
+ sc_int index_;
+ sc_vartype_t vt_key;
+
+ /* Isolate the class name. */
+ if (sscanf(class_, "<%[^>]", class_name) != 1)
+ sc_fatal("parse_class: error in class, %s\n", class_);
+ if (parse_trace)
+ sc_trace("Parse: entering class %s\n", class_name);
+
+ /* Find the class in the parse schema, and fail if not found. */
+ for (index_ = 0; parse_schema[index_].class_name; index_++) {
+ if (strcmp(parse_schema[index_].class_name, class_name) == 0)
+ break;
+ }
+ if (!parse_schema[index_].class_name)
+ sc_fatal("parse_class: class not described, %s\n", class_name);
+
+ /*
+ * Unless we are at the top level of the parse schema, push the class tag
+ * as a key. The top level is "_GAME_", index_ 0, and isn't part of key
+ * formation.
+ */
+ if (index_ > 0) {
+ vt_key.string = class_ + strlen(class_name) + 2;
+ parse_push_key(vt_key, PROP_KEY_STRING);
+ }
+
+ /* Parse each element in the descriptor. */
+ parse_descriptor(parse_schema[index_].descriptor);
+
+ /* Pop a key if the class tag was pushed above. */
+ if (index_ > 0)
+ parse_pop_key();
+
+ if (parse_trace)
+ sc_trace("Parse: leaving class %s\n", class_name);
}
@@ -3225,54 +3172,50 @@ parse_class (const sc_char *class_)
* that occurs after the TAF file has been successfully parsed.
*/
static void
-parse_add_walkalerts (sc_prop_setref_t bundle)
-{
- sc_vartype_t vt_key[5];
- sc_int npcs_count, npc;
-
- /* Get the count of NPCs. */
- vt_key[0].string = "NPCs";
- npcs_count = prop_get_child_count (bundle, "I<-s", vt_key);
-
- /* Set up each NPC. */
- for (npc = 0; npc < npcs_count; npc++)
- {
- sc_int walk_count, walk;
-
- /* Get NPC walk details. */
- vt_key[1].integer = npc;
- vt_key[2].string = "Walks";
- walk_count = prop_get_child_count (bundle, "I<-sis", vt_key);
-
- for (walk = 0; walk < walk_count; walk++)
- {
- sc_int starttask;
-
- /* Get start task of walk. */
- vt_key[3].integer = walk;
- vt_key[4].string = "StartTask";
- starttask = prop_get_integer (bundle, "I<-sisis", vt_key) - 1;
- if (starttask >= 0)
- {
- sc_vartype_t vt_key2[4], vt_value;
- sc_int count;
-
- /* Count existing walkalerts for the task. */
- vt_key2[0].string = "Tasks";
- vt_key2[1].integer = starttask;
- vt_key2[2].string = "NPCWalkAlert";
- count = prop_get_child_count (bundle, "I<-sis", vt_key2);
-
- /* Add two more -- NPC and walk. */
- vt_key2[3].integer = count;
- vt_value.integer = npc;
- prop_put (bundle, "I->sisi", vt_value, vt_key2);
- vt_key2[3].integer = count + 1;
- vt_value.integer = walk;
- prop_put (bundle, "I->sisi", vt_value, vt_key2);
- }
- }
- }
+parse_add_walkalerts(sc_prop_setref_t bundle) {
+ sc_vartype_t vt_key[5];
+ sc_int npcs_count, npc;
+
+ /* Get the count of NPCs. */
+ vt_key[0].string = "NPCs";
+ npcs_count = prop_get_child_count(bundle, "I<-s", vt_key);
+
+ /* Set up each NPC. */
+ for (npc = 0; npc < npcs_count; npc++) {
+ sc_int walk_count, walk;
+
+ /* Get NPC walk details. */
+ vt_key[1].integer = npc;
+ vt_key[2].string = "Walks";
+ walk_count = prop_get_child_count(bundle, "I<-sis", vt_key);
+
+ for (walk = 0; walk < walk_count; walk++) {
+ sc_int starttask;
+
+ /* Get start task of walk. */
+ vt_key[3].integer = walk;
+ vt_key[4].string = "StartTask";
+ starttask = prop_get_integer(bundle, "I<-sisis", vt_key) - 1;
+ if (starttask >= 0) {
+ sc_vartype_t vt_key2[4], vt_value;
+ sc_int count;
+
+ /* Count existing walkalerts for the task. */
+ vt_key2[0].string = "Tasks";
+ vt_key2[1].integer = starttask;
+ vt_key2[2].string = "NPCWalkAlert";
+ count = prop_get_child_count(bundle, "I<-sis", vt_key2);
+
+ /* Add two more -- NPC and walk. */
+ vt_key2[3].integer = count;
+ vt_value.integer = npc;
+ prop_put(bundle, "I->sisi", vt_value, vt_key2);
+ vt_key2[3].integer = count + 1;
+ vt_value.integer = walk;
+ prop_put(bundle, "I->sisi", vt_value, vt_key2);
+ }
+ }
+ }
}
@@ -3283,56 +3226,51 @@ parse_add_walkalerts (sc_prop_setref_t bundle)
* occurs after the TAF file has been successfully parsed.
*/
static void
-parse_add_movetimes (sc_prop_setref_t bundle)
-{
- sc_vartype_t vt_key[6];
- sc_int npcs_count, npc;
-
- /* Get the count of NPCs. */
- vt_key[0].string = "NPCs";
- npcs_count = prop_get_child_count (bundle, "I<-s", vt_key);
-
- /* Set up each NPC. */
- for (npc = 0; npc < npcs_count; npc++)
- {
- sc_int walk_count, walk;
-
- /* Get NPC walk details. */
- vt_key[1].integer = npc;
- vt_key[2].string = "Walks";
- walk_count = prop_get_child_count (bundle, "I<-sis", vt_key);
-
- for (walk = 0; walk < walk_count; walk++)
- {
- sc_int waittimes;
- sc_int *movetimes, index_;
- sc_vartype_t vt_value;
-
- vt_key[3].integer = walk;
- vt_key[4].string = "Times";
- waittimes = prop_get_child_count (bundle, "I<-sisis", vt_key);
-
- movetimes = (sc_int *)sc_malloc ((waittimes + 1) * sizeof (*movetimes));
- memset (movetimes, 0, (waittimes + 1) * sizeof (*movetimes));
- for (index_ = waittimes - 1; index_ >= 0; index_--)
- {
- vt_key[4].string = "Times";
- vt_key[5].integer = index_;
- movetimes[index_] = prop_get_integer (bundle, "I<-sisisi", vt_key)
- + movetimes[index_ + 1];
- }
- movetimes[waittimes] = -2;
-
- for (index_ = 0; index_ <= waittimes; index_++)
- {
- vt_key[4].string = "MoveTimes";
- vt_key[5].integer = index_;
- vt_value.integer = movetimes[index_];
- prop_put (bundle, "I->sisisi", vt_value, vt_key);
- }
- sc_free (movetimes);
- }
- }
+parse_add_movetimes(sc_prop_setref_t bundle) {
+ sc_vartype_t vt_key[6];
+ sc_int npcs_count, npc;
+
+ /* Get the count of NPCs. */
+ vt_key[0].string = "NPCs";
+ npcs_count = prop_get_child_count(bundle, "I<-s", vt_key);
+
+ /* Set up each NPC. */
+ for (npc = 0; npc < npcs_count; npc++) {
+ sc_int walk_count, walk;
+
+ /* Get NPC walk details. */
+ vt_key[1].integer = npc;
+ vt_key[2].string = "Walks";
+ walk_count = prop_get_child_count(bundle, "I<-sis", vt_key);
+
+ for (walk = 0; walk < walk_count; walk++) {
+ sc_int waittimes;
+ sc_int *movetimes, index_;
+ sc_vartype_t vt_value;
+
+ vt_key[3].integer = walk;
+ vt_key[4].string = "Times";
+ waittimes = prop_get_child_count(bundle, "I<-sisis", vt_key);
+
+ movetimes = (sc_int *)sc_malloc((waittimes + 1) * sizeof(*movetimes));
+ memset(movetimes, 0, (waittimes + 1) * sizeof(*movetimes));
+ for (index_ = waittimes - 1; index_ >= 0; index_--) {
+ vt_key[4].string = "Times";
+ vt_key[5].integer = index_;
+ movetimes[index_] = prop_get_integer(bundle, "I<-sisisi", vt_key)
+ + movetimes[index_ + 1];
+ }
+ movetimes[waittimes] = -2;
+
+ for (index_ = 0; index_ <= waittimes; index_++) {
+ vt_key[4].string = "MoveTimes";
+ vt_key[5].integer = index_;
+ vt_value.integer = movetimes[index_];
+ prop_put(bundle, "I->sisisi", vt_value, vt_key);
+ }
+ sc_free(movetimes);
+ }
+ }
}
@@ -3343,65 +3281,60 @@ parse_add_movetimes (sc_prop_setref_t bundle)
* that ALR replacements look at longer strings before shorter ones.
*/
static void
-parse_add_alrs_index (sc_prop_setref_t bundle)
-{
- sc_vartype_t vt_key[3];
- sc_int alr_count, index_, alr;
- sc_int *alr_lengths, longest, shortest, length;
-
- /* Count ALRs, and set invariant part of properties key. */
- vt_key[0].string = "ALRs";
- alr_count = prop_get_child_count (bundle, "I<-s", vt_key);
-
- /*
- * Set up an array of the lengths of ALR original strings, and while at it,
- * get the shortest and longest defined.
- */
- alr_lengths = (sc_int *)sc_malloc(alr_count * sizeof (*alr_lengths));
- shortest = INT_MAX;
- longest = 0;
- for (index_ = 0; index_ < alr_count; index_++)
- {
- const sc_char *original;
-
- vt_key[1].integer = index_;
- vt_key[2].string = "Original";
- original = prop_get_string (bundle, "S<-sis", vt_key);
- length = strlen (original);
-
- alr_lengths[index_] = length;
- shortest = (length < shortest) ? length : shortest;
- longest = (length > longest) ? length : longest;
- }
-
- /*
- * Now write a set of secondary properties that define the order of handling
- * for ALRs. Our friend qsort() can't help here as it doesn't define the
- * final ordering of equal members, and we need here to retain file ordering
- * for ALR originals of the same length.
- */
- vt_key[0].string = "ALRs2";
- alr = 0;
- for (length = longest; length >= shortest; length--)
- {
- /* Find and add each ALR of this length. */
- for (index_ = 0; index_ < alr_count; index_++)
- {
- if (alr_lengths[index_] == length)
- {
- sc_vartype_t vt_value;
-
- vt_key[1].integer = alr++;
- vt_key[2].string = "ALRIndex";
- vt_value.integer = index_;
- prop_put (bundle, "I->sis", vt_value, vt_key);
- }
- }
- }
- assert (alr == alr_count);
-
- /* Done with ALR lengths array. */
- sc_free (alr_lengths);
+parse_add_alrs_index(sc_prop_setref_t bundle) {
+ sc_vartype_t vt_key[3];
+ sc_int alr_count, index_, alr;
+ sc_int *alr_lengths, longest, shortest, length;
+
+ /* Count ALRs, and set invariant part of properties key. */
+ vt_key[0].string = "ALRs";
+ alr_count = prop_get_child_count(bundle, "I<-s", vt_key);
+
+ /*
+ * Set up an array of the lengths of ALR original strings, and while at it,
+ * get the shortest and longest defined.
+ */
+ alr_lengths = (sc_int *)sc_malloc(alr_count * sizeof(*alr_lengths));
+ shortest = INT_MAX;
+ longest = 0;
+ for (index_ = 0; index_ < alr_count; index_++) {
+ const sc_char *original;
+
+ vt_key[1].integer = index_;
+ vt_key[2].string = "Original";
+ original = prop_get_string(bundle, "S<-sis", vt_key);
+ length = strlen(original);
+
+ alr_lengths[index_] = length;
+ shortest = (length < shortest) ? length : shortest;
+ longest = (length > longest) ? length : longest;
+ }
+
+ /*
+ * Now write a set of secondary properties that define the order of handling
+ * for ALRs. Our friend qsort() can't help here as it doesn't define the
+ * final ordering of equal members, and we need here to retain file ordering
+ * for ALR originals of the same length.
+ */
+ vt_key[0].string = "ALRs2";
+ alr = 0;
+ for (length = longest; length >= shortest; length--) {
+ /* Find and add each ALR of this length. */
+ for (index_ = 0; index_ < alr_count; index_++) {
+ if (alr_lengths[index_] == length) {
+ sc_vartype_t vt_value;
+
+ vt_key[1].integer = alr++;
+ vt_key[2].string = "ALRIndex";
+ vt_value.integer = index_;
+ prop_put(bundle, "I->sis", vt_value, vt_key);
+ }
+ }
+ }
+ assert(alr == alr_count);
+
+ /* Done with ALR lengths array. */
+ sc_free(alr_lengths);
}
@@ -3413,25 +3346,24 @@ parse_add_alrs_index (sc_prop_setref_t bundle)
* zero; only version 4.0 games can embed their resources into the TAF file.
*/
static void
-parse_add_resources_offset (sc_prop_setref_t bundle, sc_tafref_t taf)
-{
- sc_vartype_t vt_key[2], vt_value;
- sc_bool embedded;
- sc_int offset;
-
- /*
- * Get the resources offset from the TAF, or default to zero. The resources
- * offset is one byte after the end of game data.
- */
- vt_key[0].string = "Globals";
- vt_key[1].string = "Embedded";
- embedded = prop_get_boolean (bundle, "B<-ss", vt_key);
- offset = embedded ? taf_get_game_data_length (taf) + 1 : 0;
-
- /* Add this offset to the properties. */
- vt_key[0].string = "ResourceOffset";
- vt_value.integer = offset;
- prop_put (bundle, "I->s", vt_value, vt_key);
+parse_add_resources_offset(sc_prop_setref_t bundle, sc_tafref_t taf) {
+ sc_vartype_t vt_key[2], vt_value;
+ sc_bool embedded;
+ sc_int offset;
+
+ /*
+ * Get the resources offset from the TAF, or default to zero. The resources
+ * offset is one byte after the end of game data.
+ */
+ vt_key[0].string = "Globals";
+ vt_key[1].string = "Embedded";
+ embedded = prop_get_boolean(bundle, "B<-ss", vt_key);
+ offset = embedded ? taf_get_game_data_length(taf) + 1 : 0;
+
+ /* Add this offset to the properties. */
+ vt_key[0].string = "ResourceOffset";
+ vt_value.integer = offset;
+ prop_put(bundle, "I->s", vt_value, vt_key);
}
@@ -3442,34 +3374,32 @@ parse_add_resources_offset (sc_prop_setref_t bundle, sc_tafref_t taf)
* for convenience.
*/
static void
-parse_add_version (sc_prop_setref_t bundle, sc_tafref_t taf)
-{
- sc_vartype_t vt_key, vt_value;
-
- /* Add the version integer to the properties. */
- vt_key.string = "Version";
- vt_value.integer = taf_get_version (taf);
- prop_put (bundle, "I->s", vt_value, &vt_key);
-
- /* Add the version string to the properties. */
- switch (taf_get_version (taf))
- {
- case TAF_VERSION_400:
- vt_value.string = "4.00";
- break;
- case TAF_VERSION_390:
- vt_value.string = "3.90";
- break;
- case TAF_VERSION_380:
- vt_value.string = "3.80";
- break;
- default:
- sc_error ("parse_add_version_string: invalid TAF file version\n");
- vt_value.string = "[Unknown version]";
- break;
- }
- vt_key.string = "VersionString";
- prop_put (bundle, "S->s", vt_value, &vt_key);
+parse_add_version(sc_prop_setref_t bundle, sc_tafref_t taf) {
+ sc_vartype_t vt_key, vt_value;
+
+ /* Add the version integer to the properties. */
+ vt_key.string = "Version";
+ vt_value.integer = taf_get_version(taf);
+ prop_put(bundle, "I->s", vt_value, &vt_key);
+
+ /* Add the version string to the properties. */
+ switch (taf_get_version(taf)) {
+ case TAF_VERSION_400:
+ vt_value.string = "4.00";
+ break;
+ case TAF_VERSION_390:
+ vt_value.string = "3.90";
+ break;
+ case TAF_VERSION_380:
+ vt_value.string = "3.80";
+ break;
+ default:
+ sc_error("parse_add_version_string: invalid TAF file version\n");
+ vt_value.string = "[Unknown version]";
+ break;
+ }
+ vt_key.string = "VersionString";
+ prop_put(bundle, "S->s", vt_value, &vt_key);
}
@@ -3480,60 +3410,57 @@ parse_add_version (sc_prop_setref_t bundle, sc_tafref_t taf)
* it encountered an error reading the TAF file.
*/
sc_bool parse_game(sc_tafref_t taf, sc_prop_setref_t bundle) {
- assert (taf && bundle);
-
- /* Store the TAF to read from, and the bundle to store into. */
- parse_taf = taf;
- parse_bundle = bundle;
- parse_schema = parse_select_schema (parse_taf);
- parse_depth = 0;
-
- /* Try parsing, and catch errors from longjmp. */
- if (setjmp (parse_taf_error) == 0)
- {
- /* Parse a complete game. */
- taf_first_line (parse_taf);
- parse_tafline = 0;
- parse_class ("<_GAME_>");
- }
- else
- {
- /* Error with one of the TAF file lines. */
- parse_clear_v400_resources_table ();
- parse_taf = NULL;
- parse_bundle = NULL;
- parse_schema = NULL;
- parse_depth = 0;
- return FALSE;
- }
-
- /* Free the accumulated version 4.0 resources details. */
- parse_clear_v400_resources_table ();
-
- /* See if we reached the end of the TAF. */
- if (taf_more_lines (parse_taf))
- sc_error ("parse_game: unexpected trailing data\n");
-
- /* Append post-processing walkalerts and move times. */
- parse_add_walkalerts (parse_bundle);
- parse_add_movetimes (parse_bundle);
-
- /* Append sorted ALR list and resources offset. */
- parse_add_alrs_index (parse_bundle);
- parse_add_resources_offset (parse_bundle, parse_taf);
-
- /* Add a note of the TAF file version. */
- parse_add_version (parse_bundle, parse_taf);
-
- /* Trim excess allocations from properties. */
- prop_solidify (parse_bundle);
-
- /* Return successfully. */
- parse_taf = NULL;
- parse_bundle = NULL;
- parse_schema = NULL;
- parse_depth = 0;
- return TRUE;
+ assert(taf && bundle);
+
+ /* Store the TAF to read from, and the bundle to store into. */
+ parse_taf = taf;
+ parse_bundle = bundle;
+ parse_schema = parse_select_schema(parse_taf);
+ parse_depth = 0;
+
+ /* Try parsing, and catch errors from longjmp. */
+ if (setjmp(parse_taf_error) == 0) {
+ /* Parse a complete game. */
+ taf_first_line(parse_taf);
+ parse_tafline = 0;
+ parse_class("<_GAME_>");
+ } else {
+ /* Error with one of the TAF file lines. */
+ parse_clear_v400_resources_table();
+ parse_taf = NULL;
+ parse_bundle = NULL;
+ parse_schema = NULL;
+ parse_depth = 0;
+ return FALSE;
+ }
+
+ /* Free the accumulated version 4.0 resources details. */
+ parse_clear_v400_resources_table();
+
+ /* See if we reached the end of the TAF. */
+ if (taf_more_lines(parse_taf))
+ sc_error("parse_game: unexpected trailing data\n");
+
+ /* Append post-processing walkalerts and move times. */
+ parse_add_walkalerts(parse_bundle);
+ parse_add_movetimes(parse_bundle);
+
+ /* Append sorted ALR list and resources offset. */
+ parse_add_alrs_index(parse_bundle);
+ parse_add_resources_offset(parse_bundle, parse_taf);
+
+ /* Add a note of the TAF file version. */
+ parse_add_version(parse_bundle, parse_taf);
+
+ /* Trim excess allocations from properties. */
+ prop_solidify(parse_bundle);
+
+ /* Return successfully. */
+ parse_taf = NULL;
+ parse_bundle = NULL;
+ parse_schema = NULL;
+ parse_depth = 0;
+ return TRUE;
}
@@ -3543,9 +3470,8 @@ sc_bool parse_game(sc_tafref_t taf, sc_prop_setref_t bundle) {
* Set parse tracing on/off.
*/
void
-parse_debug_trace (sc_bool flag)
-{
- parse_trace = flag;
+parse_debug_trace(sc_bool flag) {
+ parse_trace = flag;
}
} // End of namespace Adrift