From 0736bf435fb37e9a4e04177a14cea10135a4ba44 Mon Sep 17 00:00:00 2001 From: Graham Nelson Date: Sat, 17 Sep 2022 19:49:46 +0100 Subject: [PATCH] Runtime representation of dialogue beats --- README.md | 2 +- build.txt | 4 +- .../Chapter 5/Project Services.w | 31 +- .../supervisor-module/Chapter 6/Source Text.w | 5 + .../BasicInformExtrasKit/kit_metadata.json | 2 +- .../Inter/BasicInformKit/kit_metadata.json | 2 +- .../Inter/CommandParserKit/kit_metadata.json | 2 +- .../Inter/DialogueKit/Sections/Director.i6t | 102 ++++++ .../Internal/Inter/DialogueKit/arch-16.interb | Bin 3834 -> 14553 bytes .../Inter/DialogueKit/arch-16d.interb | Bin 3855 -> 14574 bytes .../Internal/Inter/DialogueKit/arch-32.interb | Bin 3840 -> 14559 bytes .../Inter/DialogueKit/arch-32d.interb | Bin 3861 -> 14580 bytes .../EnglishLanguageKit/kit_metadata.json | 2 +- .../Inter/WorldModelKit/kit_metadata.json | 2 +- inform7/Tests/Test Cases/DialogueBeats.txt | 96 +++++ .../_Results_Ideal/DialogueBeats.txt | 65 ++++ .../core-module/Chapter 1/How To Compile.w | 4 +- .../Sections/Variables and Rulebooks.w | 32 +- inform7/if-module/Chapter 6/Dialogue Beats.w | 2 +- .../if-module/Chapter 6/Dialogue Choices.w | 2 +- inform7/if-module/Chapter 6/Dialogue Lines.w | 2 +- inform7/if-module/Chapter 6/Dialogue.w | 22 ++ inform7/runtime-module/Chapter 2/Hierarchy.w | 20 +- .../Chapter 5/Dialogue Beat Instances.w | 340 ++++++++++++++++++ .../Chapter 5/Dialogue Choice Instances.w | 36 ++ .../Chapter 5/Dialogue Line Instances.w | 35 ++ inform7/runtime-module/Chapter 5/Dialogue.w | 160 --------- inform7/runtime-module/Chapter 5/Instances.w | 9 + inform7/runtime-module/Contents.w | 4 +- inter/pipeline-module/Chapter 5/Dialogue.w | 46 +++ .../Chapter 5/Make Synoptic Module Stage.w | 1 + .../Chapter 5/Synoptic Hierarchy.w | 10 + inter/pipeline-module/Contents.w | 1 + services/syntax-module/Chapter 3/Sentences.w | 5 + 34 files changed, 863 insertions(+), 183 deletions(-) create mode 100644 inform7/Tests/Test Cases/DialogueBeats.txt create mode 100644 inform7/Tests/Test Cases/_Results_Ideal/DialogueBeats.txt create mode 100644 inform7/runtime-module/Chapter 5/Dialogue Beat Instances.w create mode 100644 inform7/runtime-module/Chapter 5/Dialogue Choice Instances.w create mode 100644 inform7/runtime-module/Chapter 5/Dialogue Line Instances.w delete mode 100644 inform7/runtime-module/Chapter 5/Dialogue.w create mode 100644 inter/pipeline-module/Chapter 5/Dialogue.w diff --git a/README.md b/README.md index 57fd6d4fe..d95dc7393 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Inform 7 -[Version](notes/versioning.md): 10.2.0-beta+6V62 'Krypton' (16 September 2022) +[Version](notes/versioning.md): 10.2.0-beta+6V63 'Krypton' (17 September 2022) ## About Inform diff --git a/build.txt b/build.txt index d2c7adc39..739d7bd10 100644 --- a/build.txt +++ b/build.txt @@ -1,3 +1,3 @@ Prerelease: beta -Build Date: 16 September 2022 -Build Number: 6V62 +Build Date: 17 September 2022 +Build Number: 6V63 diff --git a/inbuild/supervisor-module/Chapter 5/Project Services.w b/inbuild/supervisor-module/Chapter 5/Project Services.w index 30f23669c..9b533ef5b 100644 --- a/inbuild/supervisor-module/Chapter 5/Project Services.w +++ b/inbuild/supervisor-module/Chapter 5/Project Services.w @@ -3,8 +3,7 @@ Behaviour specific to copies of either the projectbundle or projectfile genres. @h Scanning metadata. -Metadata for pipelines -- or rather, the complete lack of same -- is stored -in the following structure. +Metadata for projects is stored in the following structure. = typedef struct inform_project { @@ -563,7 +562,8 @@ because of the following sort: kit_dependency *kd; LOOP_OVER_LINKED_LIST(kd, kit_dependency, project->kits_to_include) if ((Str::eq(kd->kit->as_copy->edition->work->title, I"CommandParserKit")) || - (Str::eq(kd->kit->as_copy->edition->work->title, I"WorldModelKit"))) + (Str::eq(kd->kit->as_copy->edition->work->title, I"WorldModelKit")) || + (Str::eq(kd->kit->as_copy->edition->work->title, I"DialogueKit"))) basic = FALSE; if (basic == FALSE) { TEMPORARY_TEXT(err) @@ -699,6 +699,25 @@ filename *Projects::get_primary_output(inform_project *proj) { } } +@h Detecting dialogue. +There's an awkward timing issue with detecting dialogue in the source text. +The rule is that an Inform project should depend on DialogueKit if it contains +content under a dialogue section, but not otherwise. That in turn activates +the "dialogue" compiler feature. On the other hand, the source text also has +material placed under headings which are for use with dialogue only. So we +can't read the entire source text first and then decide: we have to switch +on the dialogue feature the moment any dialogue matter is found. This is +done by having the //syntax// module call the following: + += +inform_project *project_being_scanned = NULL; +void Projects::dialogue_present(void) { + if (project_being_scanned) { + Projects::add_kit_dependency(project_being_scanned, I"DialogueKit", NULL, NULL, NULL); + Projects::activate_elements(project_being_scanned); + } +} + @h The full graph. This can be quite grandiose even though most of it will never come to anything, rather like a family tree for a minor European royal family. @@ -708,11 +727,9 @@ void Projects::construct_graph(inform_project *proj) { if (proj == NULL) return; if (proj->chosen_build_target == NULL) { Projects::finalise_kit_dependencies(proj); + project_being_scanned = proj; Copies::get_source_text(proj->as_copy); - if (proj->syntax_tree->contains_dialogue) { - Projects::add_kit_dependency(proj, I"DialogueKit", NULL, NULL, NULL); - Projects::activate_elements(proj); - } + project_being_scanned = NULL; build_vertex *V = proj->as_copy->vertex; @; @; diff --git a/inbuild/supervisor-module/Chapter 6/Source Text.w b/inbuild/supervisor-module/Chapter 6/Source Text.w index 0309fb282..98653720f 100644 --- a/inbuild/supervisor-module/Chapter 6/Source Text.w +++ b/inbuild/supervisor-module/Chapter 6/Source Text.w @@ -290,6 +290,11 @@ void SourceText::new_beginend(parse_node *pn, inbuild_copy *C) { if (Node::get_type(pn) == ENDHERE_NT) Inclusions::check_ends_here(pn, E); } +@ This callback is called by //syntax// when it first reaches a dialogue line +or beat. + +@d DIALOGUE_WARNING_SYNTAX_CALLBACK Projects::dialogue_present + @ Lastly, this callback is called by //syntax// when it hits a sentence like: >> Use interactive fiction language element. diff --git a/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json b/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json index d28e0b220..41e77609a 100644 --- a/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json +++ b/inform7/Internal/Inter/BasicInformExtrasKit/kit_metadata.json @@ -2,7 +2,7 @@ "is": { "type": "kit", "title": "BasicInformExtrasKit", - "version": "10.2.0-beta+6V62" + "version": "10.2.0-beta+6V63" }, "kit-details": { "has-priority": 1 diff --git a/inform7/Internal/Inter/BasicInformKit/kit_metadata.json b/inform7/Internal/Inter/BasicInformKit/kit_metadata.json index d5063a322..77a570da3 100644 --- a/inform7/Internal/Inter/BasicInformKit/kit_metadata.json +++ b/inform7/Internal/Inter/BasicInformKit/kit_metadata.json @@ -2,7 +2,7 @@ "is": { "type": "kit", "title": "BasicInformKit", - "version": "10.2.0-beta+6V62" + "version": "10.2.0-beta+6V63" }, "needs": [ { "unless": { diff --git a/inform7/Internal/Inter/CommandParserKit/kit_metadata.json b/inform7/Internal/Inter/CommandParserKit/kit_metadata.json index ac508704f..e38f4a861 100644 --- a/inform7/Internal/Inter/CommandParserKit/kit_metadata.json +++ b/inform7/Internal/Inter/CommandParserKit/kit_metadata.json @@ -2,7 +2,7 @@ "is": { "type": "kit", "title": "CommandParserKit", - "version": "10.2.0-beta+6V62" + "version": "10.2.0-beta+6V63" }, "needs": [ { "need": { diff --git a/inform7/Internal/Inter/DialogueKit/Sections/Director.i6t b/inform7/Internal/Inter/DialogueKit/Sections/Director.i6t index 122df21f7..70d1f2096 100644 --- a/inform7/Internal/Inter/DialogueKit/Sections/Director.i6t +++ b/inform7/Internal/Inter/DialogueKit/Sections/Director.i6t @@ -5,6 +5,108 @@ Run-time support for dialogue. @h Placeholder. = +Global latest_performed_beat = 0; +Array DialogueTopicPool --> 20; + +[ DirectorEmptyDialogueTopicPool; + DialogueTopicPool-->0 = 0; +]; + +[ DirectorAddLiveSubjectList obj i; + for (i=18:i>0:i--) DialogueTopicPool-->i = DialogueTopicPool-->(i-1); + DialogueTopicPool-->0 = obj; + DialogueTopicPool-->19 = 0; +]; + +[ DirectorRemoveLiveSubjectList obj i j; + for (i=0:i<20:i++) { + if (DialogueTopicPool-->i == 0) return; + if (DialogueTopicPool-->i == obj) { + for (j=i:j<19:j++) DialogueTopicPool-->j = DialogueTopicPool-->(j+1); + } + } + DialogueTopicPool-->19 = 0; +]; + +[ DirectorLiveSubjectList list len i; + if ((list==0) || (BlkValueWeakKind(list) ~= LIST_OF_TY)) return 0; + len = 0; + while (DialogueTopicPool-->len) len++; + LIST_OF_TY_SetLength(list, len); + for (i=0: ii); + return list; +]; + +[ DirectorAlterLiveSubjectList list len i; + if ((list==0) || (BlkValueWeakKind(list) ~= LIST_OF_TY)) return 0; + len = BlkValueRead(list, LIST_LENGTH_F); + if (len > 19) len = 19; + for (i=0: ii = BlkValueRead(list, LIST_ITEM_BASE+i); + DialogueTopicPool-->len = 0; + DialogueTopicPool-->19 = 0; +]; + [ DirectorBegin; + DirectorEmptyDialogueTopicPool(); + latest_performed_beat = 0; rfalse; ]; + +[ DirectorPerform db; + print "Performing beat ", (PrintDialogueBeatName) db, "^"; + latest_performed_beat = db; +]; + +[ DirectorListLiveTopics i t; + for (i=0: i<20: i++) { + t = DialogueTopicPool-->i; + if (t == 0) return; + print (name) t, "^"; + } +]; + +[ DirectorBeatAvailable db fn; + if ((db == 0) || (db > TableOfDialogueBeats-->0)) rfalse; + fn = TableOfDialogueBeats-->(3*db - 2); + if (fn) { + return (fn)(latest_performed_beat); + } + rtrue; +]; + +[ DirectorBeatRelevant db fn; + if ((db == 0) || (db > TableOfDialogueBeats-->0)) rfalse; + fn = TableOfDialogueBeats-->(3*db - 1); + if (fn) { + return (fn)(DialogueTopicPool); + } + rfalse; +]; + +[ DirectorBeatPrintStructure db tab pc which depth i; + if ((db == 0) || (db > TableOfDialogueBeats-->0)) return; + print (PrintDialogueBeatName) db; + print " ("; + if (DirectorBeatAvailable(db)) print "available"; else print "unavailable"; + print ", "; + if (DirectorBeatRelevant(db)) print "relevant"; else print "irrelevant"; + print "):^"; + tab = TableOfDialogueBeats-->(3*db); + if (tab) { + pc = 0; + while (tab-->pc) { + which = (tab-->pc)/100; + depth = (tab-->pc)%100; + for (i=0: i(pc+1), "^"; + 2: print "Choice ", (PrintDialogueChoiceName) tab-->(pc+1), "^"; + 3: print "Decision of type ", tab-->(pc+1), "^"; + default: print "*** Unimplemented ***^"; + } + pc = pc + 2; + } + } +]; diff --git a/inform7/Internal/Inter/DialogueKit/arch-16.interb b/inform7/Internal/Inter/DialogueKit/arch-16.interb index a02d30e0cb686e91743886f60bdcb10a63af723b..771ab469f1182e72204c0534552a6b8ac6a5533e 100644 GIT binary patch literal 14553 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 GD*qR1t@^V7 delta 283 zcmcav_)B)edL|L^i5o>W3o}k|Z&$s)>?oS&Bmc3-jR1HlKI_b8RIa)^pCi?K2>i%quDkal{& z_}_tnA%$OnLx7DL!buer;t*nEfp8LpMVLhdS(!yx*;qw{*}$s3*hHk*84ofrFo1*s D4HZjv diff --git a/inform7/Internal/Inter/DialogueKit/arch-16d.interb b/inform7/Internal/Inter/DialogueKit/arch-16d.interb index 71bd495f927e8ee2caf9e47801a2524a672c883d..a8ecdb129e2cc33e1bb6c664a8e770db66bac430 100644 GIT binary patch literal 14574 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

-j8_}*YSVbNNxTH4Y8cg4%n^jZOU)hN zxz_>jIw-FJJH$)+L4}z*4T_L!laQ=xf^-pPh@x$8n1v`e<7ys|{dQfUQiZM6H;Vn5GObnZGRt^>QC)ir?H#WC$BT@(`&E8sUUe;4yv ztmMopfa~KtPXB1oIh)7%L>RAxx^RB(-xa zx^R`j6$nY+cpVvY*J&Tj7g|*bQelJ4%3ZApB#!tL2JToj3mB5_eCaZx96Q73Uxoj6G#SUuMSiV_!aMUl9u1_u_+bv+~v4BCc|PtAI=tO&8+u|rD3V9Q*BkTvaSiGiXn9Yqq9 zlPg*a#iNs_%v#2gWXySd7BsF8xvyB&Hw%Mf*~D zM~WCr3RdpRH;IbR> zoa~XBMGHywhE#pwV(6ly`chw29~D`k4+i>RpieE2R`;>S;4NaAWi`afvqfT>S+4?p z@TX7uv*L)8QZoKR8t=axy6hMq7_1uP3da-Y^dMXqgbRbpg%~KRfI(EipswgaHh{vU zIoX*d3k^Wc9pJgw73-k925dT~2T^u|s_ej`t*VAAnkca-Y42wVqE73{vLbLM4dP51 zL@`Oc2f0$P|6vDPOu1ZkbVU^__%4M>puCizT)7&$>VOg(sv2TY@B}DB0A&cE3@K3h zLCL^Rfzq9NNW&uuz@z7ytMwdM6zh=cMv6cbLx4t$k1KK3Kt(o$qz6a0dGWuCkceE=bEea99RV2hz3s*0B;1~Y4LF-&Kd~3 z5r8+M!6Vb8fxG1jFDkRzRi#!06any*D+UBKcq1CT3X`lsf~TA-Yb~qJVscD&B!Yt~ z?{f*>=#9_~2fVTIs&NJnPaHUSuJCh}pKJVFHv;1TbsV6MYtKMwP{$om$2F*u03>>@ zxmwSGMWBvLP&X6-P{#qP79UsQ*jKQK<9A%*P@*A65ml_^Vn`qxrVOlA1qzgXTN_n(sPl9L@Kb^(ruqQc>QP!J<-8!wn2W#;S4}MdE=^ z*M`ER?3g8mVMxlGhhFO@;R=*`urE8J&=AI4Evk3?a2?ou>s+-Y{lDKT{;mK3 delta 283 zcmca#*dRAyJ(Gy|#El}Gg&C)_Pd>~cQZE~=;F4LCnp~1!H7K&-8$SK>$TTd|Dn*h=rGdpEIpAFS#T$Kd)F2q>L9u83Th5ivWWlhF)PN1`!q^ zCSj;*1E{s4Ob?haOb}z?WD(^`&d;Y^)-}Y+%)1Y$8(Zj0YJQ7(l`R Dl4eT} diff --git a/inform7/Internal/Inter/DialogueKit/arch-32d.interb b/inform7/Internal/Inter/DialogueKit/arch-32d.interb index 67bf802f18c1f896cde3f82f65aecca07ccf5710..f4900a5891f7443cb42cc787f371e528e8c8e9a5 100644 GIT binary patch literal 14580 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 delta 321 zcmexTI8|=KdL|L^i5o>W3o|ZcuV>(8;bh?9cF9c4$xkm$_0BBeW0Z|naLFu6O)kkV za!O6l%(Ld=EJ{nvDNeQKinZqAXL`WEAb_GEJ}nO@#KOzK&zV-5mt2yWpI0mhQpSs- zjDbOjMSwvNS+7fG9#FF|6N3ng5R)*fa#5xSOc*AJv2e18awX^I<$>K-Ec!t3!RBL1 z?X0PyV$5Q!Okm8(%E%1F9Gq;74;lYEFfb(Z@N)37F+BitQuqZp1lX7%oK!&}4k0!c j2q!^Ugjqz8m05(9ja5XL4XoOWO+<>F@gM^O14tME@oi9! diff --git a/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json b/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json index 7b237451b..65761b33e 100644 --- a/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json +++ b/inform7/Internal/Inter/EnglishLanguageKit/kit_metadata.json @@ -2,7 +2,7 @@ "is": { "type": "kit", "title": "EnglishLanguageKit", - "version": "10.2.0-beta+6V62" + "version": "10.2.0-beta+6V63" }, "needs": [ { "need": { diff --git a/inform7/Internal/Inter/WorldModelKit/kit_metadata.json b/inform7/Internal/Inter/WorldModelKit/kit_metadata.json index ddeb0585c..ef9699b9b 100644 --- a/inform7/Internal/Inter/WorldModelKit/kit_metadata.json +++ b/inform7/Internal/Inter/WorldModelKit/kit_metadata.json @@ -2,7 +2,7 @@ "is": { "type": "kit", "title": "WorldModelKit", - "version": "10.2.0-beta+6V62" + "version": "10.2.0-beta+6V63" }, "needs": [ { "need": { diff --git a/inform7/Tests/Test Cases/DialogueBeats.txt b/inform7/Tests/Test Cases/DialogueBeats.txt new file mode 100644 index 000000000..ea5bb778d --- /dev/null +++ b/inform7/Tests/Test Cases/DialogueBeats.txt @@ -0,0 +1,96 @@ +The Cricket History Museum is a room. The bat, the ball and the pads are here. Daphne is a woman in the Museum. The trophy case is in the Museum. The urn and the scoring pencil are in the case. + +Daphne can be honest or disingenuous. + +A dialogue beat can be dramatic, quiet or subdued. + +Spoken rapidly is a performance style. + +When play begins: + say "== The stock..."; + showme the list of dialogue beats; + showme the list of dialogue lines; + showme the list of dialogue choices; + say "== Dual scene and beat naming..."; + showme the alpha scene; + showme the alpha beat; + say "== Properties..."; + showme the list of dramatic dialogue beats; + showme the list of subdued dialogue beats; + say "== Performance..."; + showme the list of unperformed dialogue beats; + perform the alpha beat; + showme the list of unperformed dialogue beats; + say "== The live conversational subject list..."; + showme the live conversational subject list; + make the bat a live conversational subject; + make the ball a live conversational subject; + showme the live conversational subject list; + make the bat a dead conversational subject; + showme the live conversational subject list; + make the ball a dead conversational subject; + showme the live conversational subject list; + make the ball a dead conversational subject; + showme the live conversational subject list; + alter the live conversational subject list to { Daphne, the pads }; + showme the live conversational subject list; + say "== Relevance..."; + alter the live conversational subject list to { the bat }; + showme the live conversational subject list; + showme the list of relevant dialogue beats; + alter the live conversational subject list to { the ball }; + showme the live conversational subject list; + showme the list of relevant dialogue beats; + alter the live conversational subject list to { the bat, the scoring pencil }; + showme the live conversational subject list; + showme the list of relevant dialogue beats; + say "== Availability..."; + now every dialogue beat is unperformed; + showme the list of available dialogue beats; + perform the gamma beat; + showme the list of available dialogue beats; + perform the nu beat; + showme the list of available dialogue beats; + now Daphne is honest; + showme the list of available dialogue beats; + say "== Structure..."; + repeat with B running through dialogue beats: + showme the beat structure of B; + +Section 1 - Meeting (dialogue) + +(This is the alpha scene.) + +Daphne: "Welcome to the Museum of Cricket." + +(This is the beta beat. About the bat.) + +Daphne: "Made of willow, the cricket bat is sprung to provide a good drive." + +(This is the gamma beat. About the ball and everything in the case.) + +Daphne: "A cricket ball is made with a core of cork, which is layered with tightly wound string, and covered by a leather case with a slightly raised sewn seam." + +(This is the delta beat. Immediately after the gamma beat. Quiet.) + +Daphne: "I forgot to mention, British Standard BS 5993 specifies the construction details, dimensions, quality and performance of cricket balls." + +(This is the epsilon beat. After the gamma beat. Subdued.) + +Daphne: "Dukes balls have a prouder seam and will tend to swing more than Kookaburra balls." + +(This is the nu beat.) + +Daphne: "Cricket's kind of dull, when you think about it." + + Ball (this is the disgruntled ball line): "I disagree!" + + Bat: "I especially enjoy it." + +(This is the mu beat. If Daphne is honest.) + +Daphne: "I prefer softball, honestly." + +(This is the eta beat. Before the nu beat.) + +Daphne: "This is the foremost museum in New South Wales." diff --git a/inform7/Tests/Test Cases/_Results_Ideal/DialogueBeats.txt b/inform7/Tests/Test Cases/_Results_Ideal/DialogueBeats.txt new file mode 100644 index 000000000..743488f0e --- /dev/null +++ b/inform7/Tests/Test Cases/_Results_Ideal/DialogueBeats.txt @@ -0,0 +1,65 @@ + Cricket History Museum + == The stock... + "list of dialogue beats" = list of dialogue beats: {alpha beat, beta beat, gamma beat, delta beat, epsilon beat, nu beat, mu beat, eta beat} + "list of dialogue lines" = list of dialogue lines: {line-1, line-2, line-3, line-4, line-5, line-6, disgruntled ball line, line-8, line-9, line-10} + "list of dialogue choices" = list of dialogue choices: {} + == Dual scene and beat naming... + scene: alpha scene + dialogue beat: alpha beat + == Properties... + "list of dramatic dialogue beats" = list of dialogue beats: {alpha beat, beta beat, gamma beat, nu beat, mu beat, eta beat} + "list of subdued dialogue beats" = list of dialogue beats: {epsilon beat} + == Performance... + "list of unperformed dialogue beats" = list of dialogue beats: {alpha beat, beta beat, gamma beat, delta beat, epsilon beat, nu beat, mu beat, eta beat} + Performing beat alpha beat + "list of unperformed dialogue beats" = list of dialogue beats: {beta beat, gamma beat, delta beat, epsilon beat, nu beat, mu beat, eta beat} + == The live conversational subject list... + "live conversational subject list" = list of objects: {} + "live conversational subject list" = list of objects: {ball, bat} + "live conversational subject list" = list of objects: {ball} + "live conversational subject list" = list of objects: {} + "live conversational subject list" = list of objects: {} + "live conversational subject list" = list of objects: {Daphne, pads} + == Relevance... + "live conversational subject list" = list of objects: {bat} + "list of relevant dialogue beats" = list of dialogue beats: {beta beat, gamma beat} + "live conversational subject list" = list of objects: {ball} + "list of relevant dialogue beats" = list of dialogue beats: {gamma beat} + "live conversational subject list" = list of objects: {bat, scoring pencil} + "list of relevant dialogue beats" = list of dialogue beats: {beta beat, gamma beat} + == Availability... + "list of available dialogue beats" = list of dialogue beats: {alpha beat, beta beat, gamma beat, nu beat, eta beat} + Performing beat gamma beat + "list of available dialogue beats" = list of dialogue beats: {alpha beat, beta beat, gamma beat, epsilon beat, nu beat, eta beat} + Performing beat nu beat + "list of available dialogue beats" = list of dialogue beats: {alpha beat, beta beat, gamma beat, epsilon beat, nu beat} + "list of available dialogue beats" = list of dialogue beats: {alpha beat, beta beat, gamma beat, epsilon beat, nu beat, mu beat} + == Structure... + alpha beat (available, irrelevant): + Line line-1 + beta beat (available, relevant): + Line line-2 + gamma beat (available, relevant): + Line line-3 + delta beat (unavailable, irrelevant): + Line line-4 + epsilon beat (available, irrelevant): + Line line-5 + nu beat (available, irrelevant): + Line line-6 + Line disgruntled ball line + Line line-8 + mu beat (available, irrelevant): + Line line-9 + eta beat (unavailable, irrelevant): + Line line-10 + + Welcome + An Interactive Fiction + Release 1 / Serial number 160428 / Inform 7 v10.2.0 / D + + Cricket History Museum + You can see a bat, a ball, a pads, Daphne and a trophy case (in which are an urn and a scoring pencil) here. + +> > Cricket History Museum +> Are you sure you want to quit? \ No newline at end of file diff --git a/inform7/core-module/Chapter 1/How To Compile.w b/inform7/core-module/Chapter 1/How To Compile.w index e9fee677f..4030caebc 100644 --- a/inform7/core-module/Chapter 1/How To Compile.w +++ b/inform7/core-module/Chapter 1/How To Compile.w @@ -211,7 +211,9 @@ here, which only happens when special runs are made for compiler testing. BENCH(RTTableColumns::compile) BENCH(RTEquations::compile) BENCH(ImperativeDefinitions::compile_first_block) - BENCH(RTDialogue::compile) + BENCH(RTDialogueBeats::compile) + BENCH(RTDialogueLines::compile) + BENCH(RTDialogueChoices::compile) BENCH(RTRules::compile) BENCH(RTRulebooks::compile) BENCH(RTRulebooks::compile_nros) diff --git a/inform7/extensions/standard_rules/Sections/Variables and Rulebooks.w b/inform7/extensions/standard_rules/Sections/Variables and Rulebooks.w index cc020e2a0..f1dfca2b2 100644 --- a/inform7/extensions/standard_rules/Sections/Variables and Rulebooks.w +++ b/inform7/extensions/standard_rules/Sections/Variables and Rulebooks.w @@ -1269,6 +1269,36 @@ The print protagonist internal rule translates into Inter as @h Dialogue support. = -Section 10 - Performance Styles (for dialogue language element only) +Section 10 - Dialogue (for dialogue language element only) There is a performance style called spoken normally. + +A dialogue beat can be performed or unperformed. A dialogue beat is usually +unperformed. +A dialogue beat can be recurring or non-recurring. A dialogue beat is usually +non-recurring. + +To make (T - an object) a live conversational subject: + (- DirectorAddLiveSubjectList({T}); -). +To make (T - an object) a dead conversational subject: + (- DirectorRemoveLiveSubjectList({T}); -). + +To decide what list of objects is the live conversational subject list: + (- DirectorLiveSubjectList({-new:list of objects}) -). +To alter the live conversational subject list to (L - list of objects): + (- DirectorAlterLiveSubjectList({-by-reference:L}); -). + +To perform (B - a dialogue beat): + ask DialogueKit to perform B; + now B is performed. + +To ask DialogueKit to perform (B - a dialogue beat): + (- DirectorPerform({B}); -). + +To showme the beat structure of (B - dialogue beat): (- DirectorBeatPrintStructure({B}); -). + +Definition: A dialogue beat is available rather than unavailable if Inter routine + "DirectorBeatAvailable" says so (it meets all its after or before, if and unless conditions). + +Definition: A dialogue beat is relevant rather than irrelevant if Inter routine + "DirectorBeatRelevant" says so (one of the topics it is about is currently live). diff --git a/inform7/if-module/Chapter 6/Dialogue Beats.w b/inform7/if-module/Chapter 6/Dialogue Beats.w index d0d4882e8..ca72be6f1 100644 --- a/inform7/if-module/Chapter 6/Dialogue Beats.w +++ b/inform7/if-module/Chapter 6/Dialogue Beats.w @@ -106,7 +106,7 @@ typedef struct dialogue_beat { db->some_time_before = NEW_LINKED_LIST(parse_node); db->about_list = NEW_LINKED_LIST(parse_node); db->root = NULL; - db->compilation_data = RTDialogue::new_beat(PN, db); + db->compilation_data = RTDialogueBeats::new_beat(PN, db); @ Each clause can be one of about 10 possibilities, as follows, and the wording tells us immediately which possibility it is, even early in the run. diff --git a/inform7/if-module/Chapter 6/Dialogue Choices.w b/inform7/if-module/Chapter 6/Dialogue Choices.w index 910470b67..cb8b26ef3 100644 --- a/inform7/if-module/Chapter 6/Dialogue Choices.w +++ b/inform7/if-module/Chapter 6/Dialogue Choices.w @@ -50,7 +50,7 @@ typedef struct dialogue_choice { dc->selection_parameter = EMPTY_WORDING; dc->to_perform = NULL; dc->selection_type = BLANK_DSEL; - dc->compilation_data = RTDialogue::new_choice(PN, dc); + dc->compilation_data = RTDialogueChoices::new(PN, dc); @ Each choice produces an instance of the kind |dialogue choice|, using the name given in its clauses if one was. diff --git a/inform7/if-module/Chapter 6/Dialogue Lines.w b/inform7/if-module/Chapter 6/Dialogue Lines.w index 2b85988bb..30de03554 100644 --- a/inform7/if-module/Chapter 6/Dialogue Lines.w +++ b/inform7/if-module/Chapter 6/Dialogue Lines.w @@ -56,7 +56,7 @@ typedef struct dialogue_line { dl->speaker_text = EMPTY_WORDING; dl->speaker_description = NULL; dl->without_speaking = FALSE; - dl->compilation_data = RTDialogue::new_line(PN, dl); + dl->compilation_data = RTDialogueLines::new(PN, dl); dl->speech_text = EMPTY_WORDING; dl->mentioning = NEW_LINKED_LIST(parse_node); dl->how_performed = PerformanceStyles::default(); diff --git a/inform7/if-module/Chapter 6/Dialogue.w b/inform7/if-module/Chapter 6/Dialogue.w index 632863209..7bd7e6213 100644 --- a/inform7/if-module/Chapter 6/Dialogue.w +++ b/inform7/if-module/Chapter 6/Dialogue.w @@ -11,6 +11,7 @@ handles that kind, so it won't be dealt with in the code for this feature. = void Dialogue::start(void) { Dialogue::declare_annotations(); + PluginCalls::plug(NEW_PROPERTY_NOTIFY_PLUG, Dialogue::new_property_notify); PluginCalls::plug(NEW_BASE_KIND_NOTIFY_PLUG, Dialogue::new_base_kind_notify); PluginCalls::plug(COMPARE_CONSTANT_PLUG, Dialogue::compare_CONSTANT); } @@ -37,6 +38,27 @@ int Dialogue::new_base_kind_notify(kind *new_base, text_stream *name, wording W) return FALSE; } +@ The following either/or property needs some compiler support: + += (early code) +property *P_performed = NULL; + +@ We will need to compile code using this. + += + ::= + performed + +@ = +int Dialogue::new_property_notify(property *prn) { + if ((prn->name)) { + switch (<>) { + case 0: P_performed = prn; break; + } + } + return FALSE; +} + @ The rest of this section is to some extent boiler-plate code: it provides for specific beats and lines to be represented as rvalues, both inside the compiler (and when typechecking) and at runtime. diff --git a/inform7/runtime-module/Chapter 2/Hierarchy.w b/inform7/runtime-module/Chapter 2/Hierarchy.w index cbb0f13a7..e323ff620 100644 --- a/inform7/runtime-module/Chapter 2/Hierarchy.w +++ b/inform7/runtime-module/Chapter 2/Hierarchy.w @@ -959,7 +959,15 @@ void Hierarchy::establish(void) { @e INLINE_PROPERTIES_HAP @e INLINE_PROPERTY_HL @e DIRECTION_HL -@e BEAT_FILTER_FN_HL +@e INSTANCE_IS_DB_MD_HL +@e INSTANCE_IS_DL_MD_HL +@e INSTANCE_IS_DC_MD_HL +@e BEAT_AVAILABLE_MD_HL +@e BEAT_AVAILABLE_FN_HL +@e BEAT_RELEVANT_MD_HL +@e BEAT_RELEVANT_FN_HL +@e BEAT_STRUCTURE_MD_HL +@e BEAT_STRUCTURE_HL @ = submodule_identity *instances = LargeScale::register_submodule_identity(I"instances"); @@ -1052,7 +1060,15 @@ void Hierarchy::establish(void) { H_F_G(REGION_FOUND_IN_FN_HL, I"region_found_in_fn", I"RFI_for_I") H_F_G(TSD_DOOR_DIR_FN_HL, I"tsd_door_dir_fn", I"TSD_door_dir_value") H_F_G(TSD_DOOR_TO_FN_HL, I"tsd_door_to_fn", I"TSD_door_to_value") - H_F_G(BEAT_FILTER_FN_HL, I"beat_filter_fn", I"DB_filter") + H_C_U(INSTANCE_IS_DB_MD_HL, I"^is_dialogue_beat") + H_C_U(INSTANCE_IS_DL_MD_HL, I"^is_dialogue_line") + H_C_U(INSTANCE_IS_DC_MD_HL, I"^is_dialogue_choice") + H_C_U(BEAT_AVAILABLE_MD_HL, I"^available") + H_F_U(BEAT_AVAILABLE_FN_HL, I"available_fn") + H_C_U(BEAT_RELEVANT_MD_HL, I"^relevant") + H_F_U(BEAT_RELEVANT_FN_HL, I"relevant_fn") + H_C_U(BEAT_STRUCTURE_MD_HL, I"^structure") + H_C_U(BEAT_STRUCTURE_HL, I"structure") H_F_U(INST_SHOWME_FN_HL, I"showme_fn") H_BEGIN_AP(INLINE_PROPERTIES_HAP, I"inline_property", I"_inline_property") H_C_U(INLINE_PROPERTY_HL, I"inline") diff --git a/inform7/runtime-module/Chapter 5/Dialogue Beat Instances.w b/inform7/runtime-module/Chapter 5/Dialogue Beat Instances.w new file mode 100644 index 000000000..6b0ef8977 --- /dev/null +++ b/inform7/runtime-module/Chapter 5/Dialogue Beat Instances.w @@ -0,0 +1,340 @@ +[RTDialogueBeats::] Dialogue Beat Instances. + +To compile any dialogue details in the instances submodule. + +@h Compilation data for dialogue beats. +Each |dialogue_beat| object contains this data: + += +typedef struct dialogue_beat_compilation_data { + struct parse_node *where_created; + struct inter_name *available_function; + struct inter_name *relevant_function; + struct inter_name *structure_array; +} dialogue_beat_compilation_data; + +dialogue_beat_compilation_data RTDialogueBeats::new_beat(parse_node *PN, dialogue_beat *db) { + dialogue_beat_compilation_data dbcd; + dbcd.where_created = PN; + dbcd.available_function = NULL; + dbcd.relevant_function = NULL; + dbcd.structure_array = NULL; + return dbcd; +} + +package_request *RTDialogueBeats::package(dialogue_beat *db) { + if (db->as_instance == NULL) internal_error("not available yet"); + return RTInstances::package(db->as_instance); +} + +inter_name *RTDialogueBeats::available_fn_iname(dialogue_beat *db) { + if (db->compilation_data.available_function == NULL) + db->compilation_data.available_function = + Hierarchy::make_iname_in(BEAT_AVAILABLE_FN_HL, RTDialogueBeats::package(db)); + return db->compilation_data.available_function; +} + +inter_name *RTDialogueBeats::relevant_fn_iname(dialogue_beat *db) { + if (db->compilation_data.relevant_function == NULL) + db->compilation_data.relevant_function = + Hierarchy::make_iname_in(BEAT_RELEVANT_FN_HL, RTDialogueBeats::package(db)); + return db->compilation_data.relevant_function; +} + +inter_name *RTDialogueBeats::structure_fn_iname(dialogue_beat *db) { + if (db->compilation_data.structure_array == NULL) + db->compilation_data.structure_array = + Hierarchy::make_iname_in(BEAT_STRUCTURE_HL, RTDialogueBeats::package(db)); + return db->compilation_data.structure_array; +} + +@h Compilation of dialogue. + += +void RTDialogueBeats::compile(void) { + dialogue_beat *db; + LOOP_OVER(db, dialogue_beat) { + text_stream *desc = Str::new(); + WRITE_TO(desc, "dialogue beat %d", db->allocation_id); + Sequence::queue(&RTDialogueBeats::beat_compilation_agent, STORE_POINTER_dialogue_beat(db), desc); + } +} + +void RTDialogueBeats::beat_compilation_agent(compilation_subtask *ct) { + dialogue_beat *db = RETRIEVE_POINTER_dialogue_beat(ct->data); + current_sentence = db->compilation_data.where_created; + package_request *PR = RTDialogueBeats::package(db); + @; + @; + @; +} + +@ = + int conditions = 0; + for (parse_node *clause = db->cue_at->down; clause; clause = clause->next) { + int c = Annotations::read_int(clause, dialogue_beat_clause_ANNOT); + if ((c == IF_DBC) || (c == UNLESS_DBC)) conditions++; + } + if ((db->immediately_after) || + (LinkedLists::len(db->some_time_after) > 0) || + (LinkedLists::len(db->some_time_before) > 0) || + (conditions > 0)) { + Hierarchy::apply_metadata_from_iname(PR, + BEAT_AVAILABLE_MD_HL, RTDialogueBeats::available_fn_iname(db)); + @; + } + +@ = + packaging_state save = Functions::begin(RTDialogueBeats::available_fn_iname(db)); + local_variable *latest = LocalVariables::new_internal_commented(I"latest", I"most recently performed beat"); + LocalVariables::set_kind(latest, K_dialogue_beat); + inter_symbol *latest_s = LocalVariables::declare(latest); + if (db->immediately_after) @; + @; + @; + EmitCode::rtrue(); + Functions::end(save); + +@ = + EmitCode::inv(IF_BIP); + EmitCode::down(); + EmitCode::inv(NE_BIP); + EmitCode::down(); + EmitCode::val_symbol(K_value, latest_s); + EmitCode::val_number(0); + EmitCode::up(); + EmitCode::code(); + EmitCode::down(); + @; + EmitCode::rfalse(); + EmitCode::up(); + EmitCode::up(); + +@ = + EmitCode::inv(IF_BIP); + EmitCode::down(); + instance *I = Rvalues::to_instance(db->immediately_after); + if (I) { + EmitCode::inv(NE_BIP); + EmitCode::down(); + EmitCode::val_symbol(K_value, latest_s); + EmitCode::val_iname(K_dialogue_beat, RTInstances::value_iname(I)); + EmitCode::up(); + } else { + pcalc_prop *prop = Propositions::negate(Descriptions::to_proposition(db->immediately_after)); + if (prop) { + TypecheckPropositions::type_check(prop, + TypecheckPropositions::tc_no_problem_reporting()); + CompilePropositions::to_test_as_condition(Lvalues::new_LOCAL_VARIABLE(EMPTY_WORDING, latest), prop); + } else { + internal_error("cannot test"); + } + } + EmitCode::code(); + EmitCode::down(); + EmitCode::rfalse(); + EmitCode::up(); + EmitCode::up(); + +@ = + parse_node *desc; + LOOP_OVER_LINKED_LIST(desc, parse_node, db->some_time_after) { + int negate_me = FALSE; + @; + } + LOOP_OVER_LINKED_LIST(desc, parse_node, db->some_time_before) { + int negate_me = TRUE; + @; + } + +@ = + instance *I = Rvalues::to_instance(desc); + pcalc_prop *prop = NULL; + adjective *adj = EitherOrProperties::as_adjective(P_performed); + if (I) { + prop = AdjectivalPredicates::new_atom(adj, negate_me, Terms::new_constant(desc)); + } else { + pcalc_prop *exists = Atoms::QUANTIFIER_new(exists_quantifier, 0, 0); + pcalc_prop *domain = KindPredicates::new_atom(K_dialogue_beat, Terms::new_variable(0)); + pcalc_prop *performed = AdjectivalPredicates::new_atom(adj, negate_me, Terms::new_variable(0)); + pcalc_prop *desc_prop = Descriptions::to_proposition(desc); + prop = Propositions::concatenate(exists, + Propositions::concatenate(domain, + Propositions::concatenate(performed, + desc_prop))); + } + prop = Propositions::negate(prop); + EmitCode::inv(IF_BIP); + EmitCode::down(); + TypecheckPropositions::type_check(prop, + TypecheckPropositions::tc_no_problem_reporting()); + CompilePropositions::to_test_as_condition(NULL, prop); + EmitCode::code(); + EmitCode::down(); + EmitCode::rfalse(); + EmitCode::up(); + EmitCode::up(); + +@ = + current_sentence = db->cue_at; + for (parse_node *clause = db->cue_at->down; clause; clause = clause->next) { + wording CW = Node::get_text(clause); + int c = Annotations::read_int(clause, dialogue_beat_clause_ANNOT); + switch (c) { + case IF_DBC: + case UNLESS_DBC: { + (CW); + wording A = GET_RW(, 1); + if ((A)) { + parse_node *cond = <>; + if (Dash::validate_conditional_clause(cond)) { + EmitCode::inv(IF_BIP); + EmitCode::down(); + if (c == IF_DBC) { + EmitCode::inv(NOT_BIP); + EmitCode::down(); + } + CompileValues::to_code_val_of_kind(cond, K_truth_state); + if (c == IF_DBC) { + EmitCode::up(); + } + EmitCode::code(); + EmitCode::down(); + EmitCode::rfalse(); + EmitCode::up(); + EmitCode::up(); + } + } + break; + } + } + } + +@ = + if (LinkedLists::len(db->about_list) > 0) { + Hierarchy::apply_metadata_from_iname(PR, + BEAT_RELEVANT_MD_HL, RTDialogueBeats::relevant_fn_iname(db)); + @; + } + +@ = + packaging_state save = Functions::begin(RTDialogueBeats::relevant_fn_iname(db)); + local_variable *pool = LocalVariables::new_internal_commented(I"pool", I"pool of live topics"); + local_variable *iv = LocalVariables::new_internal_commented(I"iv", I"index variable"); + local_variable *topic = LocalVariables::new_internal_commented(I"topic", I"live topic"); + inter_symbol *pool_s = LocalVariables::declare(pool); + inter_symbol *iv_s = LocalVariables::declare(iv); + inter_symbol *topic_s = LocalVariables::declare(topic); + @; + EmitCode::rfalse(); + Functions::end(save); + +@ = + inter_symbol *loop_label = EmitCode::reserve_label(I"about_loop"); + EmitCode::place_label(loop_label); + EmitCode::inv(STORE_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, topic_s); + EmitCode::inv(LOOKUP_BIP); + EmitCode::down(); + EmitCode::val_symbol(K_value, pool_s); + EmitCode::val_symbol(K_value, iv_s); + EmitCode::up(); + EmitCode::up(); + EmitCode::inv(IF_BIP); + EmitCode::down(); + EmitCode::inv(NE_BIP); + EmitCode::down(); + EmitCode::val_symbol(K_value, topic_s); + EmitCode::val_number(0); + EmitCode::up(); + EmitCode::code(); + EmitCode::down(); + parse_node *desc; + LOOP_OVER_LINKED_LIST(desc, parse_node, db->about_list) { + instance *I = Rvalues::to_instance(desc); + EmitCode::inv(IF_BIP); + EmitCode::down(); + if (I) { + EmitCode::inv(EQ_BIP); + EmitCode::down(); + EmitCode::val_symbol(K_value, topic_s); + EmitCode::val_iname(K_value, RTInstances::value_iname(I)); + EmitCode::up(); + } else { + pcalc_prop *prop = Descriptions::to_proposition(desc); + if (prop) { + TypecheckPropositions::type_check(prop, + TypecheckPropositions::tc_no_problem_reporting()); + CompilePropositions::to_test_as_condition( + Lvalues::new_LOCAL_VARIABLE(EMPTY_WORDING, topic), prop); + } else { + internal_error("cannot test"); + } + } + EmitCode::code(); + EmitCode::down(); + EmitCode::rtrue(); + EmitCode::up(); + EmitCode::up(); + } + EmitCode::inv(POSTINCREMENT_BIP); + EmitCode::down(); + EmitCode::ref_symbol(K_value, iv_s); + EmitCode::up(); + EmitCode::inv(JUMP_BIP); + EmitCode::down(); + EmitCode::lab(loop_label); + EmitCode::up(); + EmitCode::up(); + EmitCode::up(); + EmitCode::rfalse(); + +@ And this is always present. + +@ = + Hierarchy::apply_metadata_from_iname(PR, + BEAT_STRUCTURE_MD_HL, RTDialogueBeats::structure_fn_iname(db)); + packaging_state save = + EmitArrays::begin_word(RTDialogueBeats::structure_fn_iname(db), K_value); + RTDialogueBeats::compile_structure_r(db->root, 1); + EmitArrays::numeric_entry(0); + EmitArrays::end(save); + +@ = +void RTDialogueBeats::compile_structure_r(dialogue_node *dn, inter_ti depth) { + while (dn) { + if (dn->if_line) { + EmitArrays::numeric_entry(depth + 100); + EmitArrays::iname_entry(RTInstances::value_iname(dn->if_line->as_instance)); + } else if (dn->if_choice) { + EmitArrays::numeric_entry(depth + 200); + EmitArrays::iname_entry(RTInstances::value_iname(dn->if_choice->as_instance)); + } else if (dn->if_decision) { + EmitArrays::numeric_entry(depth + 300); + EmitArrays::numeric_entry((inter_ti) (dn->if_decision->decision_type)); + } else internal_error("unimplemented dialogue node compilation"); + if (dn->child_node) + RTDialogueBeats::compile_structure_r(dn->child_node, depth+1); + dn = dn->next_node; + } +} + +@ = +void RTDialogueBeats::log_r(dialogue_node *dn) { + while (dn) { + if (dn->if_line) + LOG("Line %d = %W\n", + dn->if_line->allocation_id, Node::get_text(dn->if_line->compilation_data.where_created)); + if (dn->if_choice) + LOG("Choice %d = %W\n", + dn->if_choice->allocation_id, Node::get_text(dn->if_choice->compilation_data.where_created)); + if (dn->child_node) { + if (dn->child_node->parent_node != dn) LOG("*** Broken parentage ***\n"); + LOG_INDENT; + RTDialogueBeats::log_r(dn->child_node); + LOG_OUTDENT; + } + dn = dn->next_node; + } +} diff --git a/inform7/runtime-module/Chapter 5/Dialogue Choice Instances.w b/inform7/runtime-module/Chapter 5/Dialogue Choice Instances.w new file mode 100644 index 000000000..7dc9c912d --- /dev/null +++ b/inform7/runtime-module/Chapter 5/Dialogue Choice Instances.w @@ -0,0 +1,36 @@ +[RTDialogueChoices::] Dialogue Choice Instances. + +To compile any dialogue details in the instances submodule. + +@h Compilation data for dialogue choices. +Each |dialogue_choice| object contains this data: + += +typedef struct dialogue_choice_compilation_data { + struct parse_node *where_created; +} dialogue_choice_compilation_data; + +dialogue_choice_compilation_data RTDialogueChoices::new(parse_node *PN, dialogue_choice *dc) { + dialogue_choice_compilation_data dlcd; + dlcd.where_created = PN; + return dlcd; +} + +@h Compilation of dialogue. + += +void RTDialogueChoices::compile(void) { + dialogue_choice *dc; + LOOP_OVER(dc, dialogue_choice) { + text_stream *desc = Str::new(); + WRITE_TO(desc, "dialogue choice %d", dc->allocation_id); + Sequence::queue(&RTDialogueChoices::choice_compilation_agent, + STORE_POINTER_dialogue_choice(dc), desc); + } +} + +@ = +void RTDialogueChoices::choice_compilation_agent(compilation_subtask *ct) { + dialogue_choice *dc = RETRIEVE_POINTER_dialogue_choice(ct->data); + current_sentence = dc->compilation_data.where_created; +} diff --git a/inform7/runtime-module/Chapter 5/Dialogue Line Instances.w b/inform7/runtime-module/Chapter 5/Dialogue Line Instances.w new file mode 100644 index 000000000..50062b9dd --- /dev/null +++ b/inform7/runtime-module/Chapter 5/Dialogue Line Instances.w @@ -0,0 +1,35 @@ +[RTDialogueLines::] Dialogue. + +To compile any dialogue details in the instances submodule. + +@h Compilation data for dialogue lines. +Each |dialogue_line| object contains this data: + += +typedef struct dialogue_line_compilation_data { + struct parse_node *where_created; +} dialogue_line_compilation_data; + +dialogue_line_compilation_data RTDialogueLines::new(parse_node *PN, dialogue_line *dl) { + dialogue_line_compilation_data dlcd; + dlcd.where_created = PN; + return dlcd; +} + +@h Compilation of dialogue. + += +void RTDialogueLines::compile(void) { + dialogue_line *dl; + LOOP_OVER(dl, dialogue_line) { + text_stream *desc = Str::new(); + WRITE_TO(desc, "dialogue line %d", dl->allocation_id); + Sequence::queue(&RTDialogueLines::line_compilation_agent, STORE_POINTER_dialogue_line(dl), desc); + } +} + +@ = +void RTDialogueLines::line_compilation_agent(compilation_subtask *ct) { + dialogue_line *dl = RETRIEVE_POINTER_dialogue_line(ct->data); + current_sentence = dl->compilation_data.where_created; +} diff --git a/inform7/runtime-module/Chapter 5/Dialogue.w b/inform7/runtime-module/Chapter 5/Dialogue.w deleted file mode 100644 index 03246cac9..000000000 --- a/inform7/runtime-module/Chapter 5/Dialogue.w +++ /dev/null @@ -1,160 +0,0 @@ -[RTDialogue::] Dialogue. - -To compile the dialogue submodule for a compilation unit, which contains -something to be worked out. - -@h Compilation data for dialogue beats. -Each |dialogue_beat| object contains this data: - -= -typedef struct dialogue_beat_compilation_data { - struct parse_node *where_created; - struct inter_name *usage_filter_function; -} dialogue_beat_compilation_data; - -dialogue_beat_compilation_data RTDialogue::new_beat(parse_node *PN, dialogue_beat *db) { - dialogue_beat_compilation_data dbcd; - dbcd.where_created = PN; - dbcd.usage_filter_function = NULL; - - return dbcd; -} - -inter_name *RTDialogue::beat_filter(dialogue_beat *db) { - if (db->compilation_data.usage_filter_function == NULL) - db->compilation_data.usage_filter_function = - Hierarchy::make_iname_in(BEAT_FILTER_FN_HL, RTInstances::package(db->as_instance)); - return db->compilation_data.usage_filter_function; -} - -@h Compilation data for dialogue lines. -Each |dialogue_line| object contains this data: - -= -typedef struct dialogue_line_compilation_data { - struct parse_node *where_created; -} dialogue_line_compilation_data; - -dialogue_line_compilation_data RTDialogue::new_line(parse_node *PN, dialogue_line *dl) { - dialogue_line_compilation_data dlcd; - dlcd.where_created = PN; - return dlcd; -} - -@h Compilation data for dialogue choices. -Each |dialogue_choice| object contains this data: - -= -typedef struct dialogue_choice_compilation_data { - struct parse_node *where_created; -} dialogue_choice_compilation_data; - -dialogue_choice_compilation_data RTDialogue::new_choice(parse_node *PN, dialogue_choice *dc) { - dialogue_choice_compilation_data dlcd; - dlcd.where_created = PN; - return dlcd; -} - -@h Compilation of dialogue. - -= -void RTDialogue::compile(void) { - dialogue_beat *db; - LOOP_OVER(db, dialogue_beat) { - text_stream *desc = Str::new(); - WRITE_TO(desc, "dialogue beat %d", db->allocation_id); - Sequence::queue(&RTDialogue::beat_compilation_agent, STORE_POINTER_dialogue_beat(db), desc); - } - dialogue_line *dl; - LOOP_OVER(dl, dialogue_line) { - text_stream *desc = Str::new(); - WRITE_TO(desc, "dialogue line %d", dl->allocation_id); - Sequence::queue(&RTDialogue::line_compilation_agent, STORE_POINTER_dialogue_line(dl), desc); - } -} - -void RTDialogue::beat_compilation_agent(compilation_subtask *ct) { - dialogue_beat *db = RETRIEVE_POINTER_dialogue_beat(ct->data); - current_sentence = db->compilation_data.where_created; - LOG("Beat %d = %W name '%W' scene '%W'\n", - db->allocation_id, Node::get_text(current_sentence), db->beat_name, db->scene_name); - RTDialogue::log_r(db->root); - packaging_state save = Functions::begin(RTDialogue::beat_filter(db)); - local_variable *latest = LocalVariables::new_internal_commented(I"latest", I"most recently performed beat"); - LocalVariables::set_kind(latest, K_dialogue_beat); - local_variable *pool = LocalVariables::new_internal_commented(I"pool", I"pool of live topics"); - inter_symbol *latest_s = LocalVariables::declare(latest); - inter_symbol *pool_s = LocalVariables::declare(pool); - if (db->immediately_after) { - EmitCode::inv(IF_BIP); - EmitCode::down(); - EmitCode::inv(NE_BIP); - EmitCode::down(); - EmitCode::val_symbol(K_value, latest_s); - EmitCode::val_number(0); - EmitCode::up(); - EmitCode::code(); - EmitCode::down(); - @; - EmitCode::rfalse(); - EmitCode::up(); - EmitCode::up(); - } - EmitCode::inv(STORE_BIP); - EmitCode::down(); - EmitCode::ref_symbol(K_value, pool_s); - EmitCode::val_number(0); - EmitCode::up(); - EmitCode::rfalse(); - Functions::end(save); -} - -@ = - EmitCode::inv(IF_BIP); - EmitCode::down(); - LOG("IA cond is $T\n", db->immediately_after); - instance *I = Rvalues::to_instance(db->immediately_after); - if (I) { - EmitCode::inv(EQ_BIP); - EmitCode::down(); - EmitCode::val_symbol(K_value, latest_s); - EmitCode::val_iname(K_dialogue_beat, RTInstances::value_iname(I)); - EmitCode::up(); - } else { - pcalc_prop *prop = Descriptions::to_proposition(db->immediately_after); - if (prop) { - CompilePropositions::to_test_as_condition(Lvalues::new_LOCAL_VARIABLE(EMPTY_WORDING, latest), prop); - } else { - internal_error("cannot test"); - } - } - EmitCode::code(); - EmitCode::down(); - EmitCode::rtrue(); - EmitCode::up(); - EmitCode::up(); - -@ = -void RTDialogue::line_compilation_agent(compilation_subtask *ct) { - dialogue_line *dl = RETRIEVE_POINTER_dialogue_line(ct->data); - current_sentence = dl->compilation_data.where_created; - LOG("Line %d = %W name '%W'\n", dl->allocation_id, Node::get_text(current_sentence), dl->line_name); -} - -void RTDialogue::log_r(dialogue_node *dn) { - while (dn) { - if (dn->if_line) - LOG("Line %d = %W\n", - dn->if_line->allocation_id, Node::get_text(dn->if_line->compilation_data.where_created)); - if (dn->if_choice) - LOG("Choice %d = %W\n", - dn->if_choice->allocation_id, Node::get_text(dn->if_choice->compilation_data.where_created)); - if (dn->child_node) { - if (dn->child_node->parent_node != dn) LOG("*** Broken parentage ***\n"); - LOG_INDENT; - RTDialogue::log_r(dn->child_node); - LOG_OUTDENT; - } - dn = dn->next_node; - } -} diff --git a/inform7/runtime-module/Chapter 5/Instances.w b/inform7/runtime-module/Chapter 5/Instances.w index 799a12dae..69f91542c 100644 --- a/inform7/runtime-module/Chapter 5/Instances.w +++ b/inform7/runtime-module/Chapter 5/Instances.w @@ -157,6 +157,15 @@ void RTInstances::compilation_agent(compilation_subtask *t) { if ((K_sound_name) && (Kinds::eq(K, K_sound_name))) Hierarchy::apply_metadata_from_number(pack, INSTANCE_IS_SOUND_MD_HL, 1); + if ((K_dialogue_beat) && (Kinds::eq(K, K_dialogue_beat))) + Hierarchy::apply_metadata_from_number(pack, + INSTANCE_IS_DB_MD_HL, 1); + if ((K_dialogue_line) && (Kinds::eq(K, K_dialogue_line))) + Hierarchy::apply_metadata_from_number(pack, + INSTANCE_IS_DL_MD_HL, 1); + if ((K_dialogue_choice) && (Kinds::eq(K, K_dialogue_choice))) + Hierarchy::apply_metadata_from_number(pack, + INSTANCE_IS_DC_MD_HL, 1); if ((K_figure_name) && (Kinds::eq(K, K_figure_name))) Hierarchy::apply_metadata_from_number(pack, INSTANCE_IS_FIGURE_MD_HL, 1); diff --git a/inform7/runtime-module/Contents.w b/inform7/runtime-module/Contents.w index 34cd7f633..c4e3b8cfc 100644 --- a/inform7/runtime-module/Contents.w +++ b/inform7/runtime-module/Contents.w @@ -61,7 +61,9 @@ Chapter 5: Provision Submodules Multimedia Tables Table Columns - Dialogue + Dialogue Beat Instances + Dialogue Line Instances + Dialogue Choice Instances Rules Rulebooks Variables diff --git a/inter/pipeline-module/Chapter 5/Dialogue.w b/inter/pipeline-module/Chapter 5/Dialogue.w new file mode 100644 index 000000000..11acd7c13 --- /dev/null +++ b/inter/pipeline-module/Chapter 5/Dialogue.w @@ -0,0 +1,46 @@ +[SynopticDialogue::] Dialogue. + +To compile the main/synoptic/dialogue submodule. + +@ Our inventory |inv| already contains a list |inv->instance_nodes| of all packages +in the tree with type |_instance|. + +For the moment, at least, it seems too ambitious to dynamically renumber instances +in the linking stage. Until then, this section is something of a placeholder, +making only a debugging function. + += +void SynopticDialogue::compile(inter_tree *I, pipeline_step *step, tree_inventory *inv) { + if (InterNodeList::array_len(inv->instance_nodes) > 0) + InterNodeList::array_sort(inv->instance_nodes, MakeSynopticModuleStage::module_order); + @; +} + +@ = + inter_ti count = 0; + for (int i=0; iinstance_nodes); i++) { + inter_package *pack = + PackageInstruction::at_this_head(inv->instance_nodes->list[i].node); + if (Metadata::read_optional_numeric(pack, I"^is_dialogue_beat")) count++; + } + + inter_name *iname = HierarchyLocations::iname(I, DIALOGUEBEATS_HL); + Synoptic::begin_array(I, step, iname); + Synoptic::numeric_entry(count); + if (count == 0) Synoptic::numeric_entry(0); + for (int i=0; iinstance_nodes); i++) { + inter_package *pack = + PackageInstruction::at_this_head(inv->instance_nodes->list[i].node); + if (Metadata::read_optional_numeric(pack, I"^is_dialogue_beat")) { + inter_symbol *filter = Metadata::optional_symbol(pack, I"^available"); + if (filter) Synoptic::symbol_entry(filter); + else Synoptic::numeric_entry(0); + inter_symbol *rel = Metadata::optional_symbol(pack, I"^relevant"); + if (rel) Synoptic::symbol_entry(rel); + else Synoptic::numeric_entry(0); + inter_symbol *str = Metadata::optional_symbol(pack, I"^structure"); + if (str) Synoptic::symbol_entry(str); + else Synoptic::numeric_entry(0); + } + } + Synoptic::end_array(I); diff --git a/inter/pipeline-module/Chapter 5/Make Synoptic Module Stage.w b/inter/pipeline-module/Chapter 5/Make Synoptic Module Stage.w index 2742c9c9b..2c34babdf 100644 --- a/inter/pipeline-module/Chapter 5/Make Synoptic Module Stage.w +++ b/inter/pipeline-module/Chapter 5/Make Synoptic Module Stage.w @@ -28,6 +28,7 @@ int MakeSynopticModuleStage::run(pipeline_step *step) { SynopticChronology::compile(I, step, inv); SynopticExtensions::compile(I, step, inv); SynopticInstances::compile(I, step, inv); + SynopticDialogue::compile(I, step, inv); SynopticKinds::compile(I, step, inv); SynopticMultimedia::compile(I, step, inv); SynopticProperties::compile(I, step, inv); diff --git a/inter/pipeline-module/Chapter 5/Synoptic Hierarchy.w b/inter/pipeline-module/Chapter 5/Synoptic Hierarchy.w index fd51987d3..bdcc8537e 100644 --- a/inter/pipeline-module/Chapter 5/Synoptic Hierarchy.w +++ b/inter/pipeline-module/Chapter 5/Synoptic Hierarchy.w @@ -21,6 +21,7 @@ void SynopticHierarchy::establish(inter_tree *I) { @; @; @; + @; @; @; @; @@ -117,6 +118,15 @@ The |/main/synoptic/conjugations| submodule. SYN_SUBMD(I"conjugations") SYN_CONST(TABLEOFVERBS_HL, I"TableOfVerbs") +@h Dialogue. +The |/main/synoptic/dialogue| submodule. + +@e DIALOGUEBEATS_HL + +@ = + SYN_SUBMD(I"dialogue") + SYN_CONST(DIALOGUEBEATS_HL, I"TableOfDialogueBeats") + @h Extensions. The |/main/synoptic/extensions| submodule. diff --git a/inter/pipeline-module/Contents.w b/inter/pipeline-module/Contents.w index 606ebccba..0e2c1dc5a 100644 --- a/inter/pipeline-module/Contents.w +++ b/inter/pipeline-module/Contents.w @@ -41,6 +41,7 @@ Chapter 5: Synoptic Module Activities Actions Instances + Dialogue Kinds Properties Relations diff --git a/services/syntax-module/Chapter 3/Sentences.w b/services/syntax-module/Chapter 3/Sentences.w index a76c8ae4b..a57916a7d 100644 --- a/services/syntax-module/Chapter 3/Sentences.w +++ b/services/syntax-module/Chapter 3/Sentences.w @@ -706,6 +706,11 @@ here. This hand-tooled parser is annoyingly long to write out, but only in order to catch improbable unmatched-bracket errors with tidy error messages. @ = + #ifdef DIALOGUE_WARNING_SYNTAX_CALLBACK + if (T->contains_dialogue == FALSE) { + DIALOGUE_WARNING_SYNTAX_CALLBACK(); + } + #endif T->contains_dialogue = TRUE; if ((Lexer::word(Wordings::first_wn(W)) == OPENBRACKET_V) && (Lexer::word(Wordings::last_wn(W)) == CLOSEBRACKET_V))