1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-08 18:14:21 +03:00
inform7/docs/standard_rules/S-gt.html

292 lines
15 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>S/ft</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<!--Weave of 'S/gt' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">standard_rules Template Library</a></li><li><b>Glulx Template</b></li></ul><p class="purpose">To provide Glulx-specific actions.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. GlkList Command</a></li><li><a href="#SP2">&#167;2. Undo</a></li><li><a href="#SP3">&#167;3. Quit The Game Rule</a></li><li><a href="#SP4">&#167;4. Restart The Game Rule</a></li><li><a href="#SP5">&#167;5. Restore The Game Rule</a></li><li><a href="#SP6">&#167;6. Save The Game Rule</a></li><li><a href="#SP7">&#167;7. Verify The Story File Rule</a></li><li><a href="#SP8">&#167;8. Switch Transcript On Rule</a></li><li><a href="#SP9">&#167;9. Switch Transcript Off Rule</a></li><li><a href="#SP10">&#167;10. Announce Story File Version Rule</a></li><li><a href="#SP11">&#167;11. Descend To Specific Action Rule</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. GlkList Command. </b>GLKLIST is a testing command best used by those who understand Glulx and its
ways: it isn't documented in the I7 manual, because it is pretty inscrutable
for "real" users, but it's probably worth keeping just the same.
</p>
<pre class="display">
<span class="plain">#Ifdef DEBUG;</span>
<span class="plain">[ GlkListSub id val;</span>
<span class="plain">id = glk_window_iterate(0, gg_arguments);</span>
<span class="plain">while (id) {</span>
<span class="plain">print "Window ", id, " (", gg_arguments--&gt;0, "): ";</span>
<span class="plain">val = glk_window_get_type(id);</span>
<span class="plain">switch (val) {</span>
<span class="plain">1: print "pair";</span>
<span class="plain">2: print "blank";</span>
<span class="plain">3: print "textbuffer";</span>
<span class="plain">4: print "textgrid";</span>
<span class="plain">5: print "graphics";</span>
<span class="plain">default: print "unknown";</span>
<span class="plain">}</span>
<span class="plain">val = glk_window_get_parent(id);</span>
<span class="plain">if (val) print ", parent is window ", val;</span>
<span class="plain">else print ", no parent (root)";</span>
<span class="plain">val = glk_window_get_stream(id);</span>
<span class="plain">print ", stream ", val;</span>
<span class="plain">val = glk_window_get_echo_stream(id);</span>
<span class="plain">if (val) print ", echo stream ", val;</span>
<span class="plain">print "^";</span>
<span class="plain">id = glk_window_iterate(id, gg_arguments);</span>
<span class="plain">}</span>
<span class="plain">id = glk_stream_iterate(0, gg_arguments);</span>
<span class="plain">while (id) {</span>
<span class="plain">print "Stream ", id, " (", gg_arguments--&gt;0, ")^";</span>
<span class="plain">id = glk_stream_iterate(id, gg_arguments);</span>
<span class="plain">}</span>
<span class="plain">id = glk_fileref_iterate(0, gg_arguments);</span>
<span class="plain">while (id) {</span>
<span class="plain">print "Fileref ", id, " (", gg_arguments--&gt;0, ")^";</span>
<span class="plain">id = glk_fileref_iterate(id, gg_arguments);</span>
<span class="plain">}</span>
<span class="plain">if (glk_gestalt(gestalt_Sound, 0)) {</span>
<span class="plain">id = glk_schannel_iterate(0, gg_arguments);</span>
<span class="plain">while (id) {</span>
<span class="plain">print "Soundchannel ", id, " (", gg_arguments--&gt;0, ")^";</span>
<span class="plain">id = glk_schannel_iterate(id, gg_arguments);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">];</span>
<span class="plain">Verb meta 'glklist'</span>
<span class="plain">* -&gt; GlkList;</span>
<span class="plain">#Endif;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. Undo. </b>These are really emulations of the Z-machine's conventions on UNDO: Glulx's
undo opcodes used different result codes while providing essentially the same
functionality, for reasons which are opaque, but no trouble is caused thereby.
</p>
<pre class="display">
<span class="plain">[ VM_Undo result_code;</span>
<span class="plain">@restoreundo result_code;</span>
<span class="plain">return (~~result_code);</span>
<span class="plain">];</span>
<span class="plain">[ VM_Save_Undo result_code;</span>
<span class="plain">@saveundo result_code;</span>
<span class="plain">if (result_code == -1) { GGRecoverObjects(); return 2; }</span>
<span class="plain">return (~~result_code);</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. Quit The Game Rule. </b></p>
<pre class="display">
<span class="plain">[ QUIT_THE_GAME_R;</span>
<span class="plain">if (actor ~= player) rfalse;</span>
<span class="plain">if ((actor == player) &amp;&amp; (untouchable_silence == false))</span>
<span class="plain">QUIT_THE_GAME_RM('A');</span>
<span class="plain">if (YesOrNo()~=0) quit;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. Restart The Game Rule. </b></p>
<pre class="display">
<span class="plain">[ RESTART_THE_GAME_R;</span>
<span class="plain">if (actor ~= player) rfalse;</span>
<span class="plain">RESTART_THE_GAME_RM('A');</span>
<span class="plain">if (YesOrNo()~=0) {</span>
<span class="plain">@restart;</span>
<span class="plain">RESTART_THE_GAME_RM('B'); new_line;</span>
<span class="plain">}</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Restore The Game Rule. </b></p>
<pre class="display">
<span class="plain">[ RESTORE_THE_GAME_R res fref;</span>
<span class="plain">if (actor ~= player) rfalse;</span>
<span class="plain">fref = glk_fileref_create_by_prompt($01, $02, 0);</span>
<span class="plain">if (fref == 0) jump RFailed;</span>
<span class="plain">gg_savestr = glk_stream_open_file(fref, $02, GG_SAVESTR_ROCK);</span>
<span class="plain">glk_fileref_destroy(fref);</span>
<span class="plain">if (gg_savestr == 0) jump RFailed;</span>
<span class="plain">@restore gg_savestr res;</span>
<span class="plain">glk_stream_close(gg_savestr, 0);</span>
<span class="plain">gg_savestr = 0;</span>
<span class="plain">.RFailed;</span>
<span class="plain">RESTORE_THE_GAME_RM('A'); new_line;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Save The Game Rule. </b></p>
<pre class="display">
<span class="plain">[ SAVE_THE_GAME_R res fref;</span>
<span class="plain">if (actor ~= player) rfalse;</span>
<span class="plain">fref = glk_fileref_create_by_prompt($01, $01, 0);</span>
<span class="plain">if (fref == 0) jump SFailed;</span>
<span class="plain">gg_savestr = glk_stream_open_file(fref, $01, GG_SAVESTR_ROCK);</span>
<span class="plain">glk_fileref_destroy(fref);</span>
<span class="plain">if (gg_savestr == 0) jump SFailed;</span>
<span class="plain">@save gg_savestr res;</span>
<span class="plain">if (res == -1) {</span>
<span class="plain">! The player actually just typed "restore". We first have to recover</span>
<span class="plain">! all the Glk objects; the values in our global variables are all wrong.</span>
<span class="plain">GGRecoverObjects();</span>
<span class="plain">glk_stream_close(gg_savestr, 0); ! stream_close</span>
<span class="plain">gg_savestr = 0;</span>
<span class="plain">RESTORE_THE_GAME_RM('B'); new_line;</span>
<span class="plain">rtrue;</span>
<span class="plain">}</span>
<span class="plain">glk_stream_close(gg_savestr, 0); ! stream_close</span>
<span class="plain">gg_savestr = 0;</span>
<span class="plain">if (res == 0) { SAVE_THE_GAME_RM('B'); new_line; rtrue; }</span>
<span class="plain">.SFailed;</span>
<span class="plain">SAVE_THE_GAME_RM('A'); new_line;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. Verify The Story File Rule. </b>This is a fossil now, really, but in the days of Infocom, the 110K story
file occupying an entire disc was a huge data set: floppy discs were by no
means a reliable medium, and cheap hardware often used hit-and-miss
components, as on the notorious Commodore 64 disc controller. If somebody
experienced an apparent bug in play, it could easily be that he had a
corrupt disc or was unable to read data of that density. So the VERIFY
command, which took up to ten minutes on some early computers, would chug
through the entire story file and compute a checksum, compare it against a
known result in the header, and determine that the story file could or
could not properly be read. The Z-machine provided this service as an
opcode, and so Glulx followed suit.
</p>
<pre class="display">
<span class="plain">[ VERIFY_THE_STORY_FILE_R res;</span>
<span class="plain">if (actor ~= player) rfalse;</span>
<span class="plain">@verify res;</span>
<span class="plain">if (res == 0) { VERIFY_THE_STORY_FILE_RM('A'); new_line; rtrue; }</span>
<span class="plain">VERIFY_THE_STORY_FILE_RM('B'); new_line;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. Switch Transcript On Rule. </b></p>
<pre class="display">
<span class="plain">[ SWITCH_TRANSCRIPT_ON_R;</span>
<span class="plain">if (actor ~= player) rfalse;</span>
<span class="plain">if (gg_scriptstr ~= 0) { SWITCH_TRANSCRIPT_ON_RM('A'); new_line; rtrue; }</span>
<span class="plain">if (gg_scriptfref == 0) {</span>
<span class="plain">gg_scriptfref = glk_fileref_create_by_prompt($102, $05, GG_SCRIPTFREF_ROCK);</span>
<span class="plain">if (gg_scriptfref == 0) jump S1Failed;</span>
<span class="plain">}</span>
<span class="plain">! stream_open_file</span>
<span class="plain">gg_scriptstr = glk_stream_open_file(gg_scriptfref, $05, GG_SCRIPTSTR_ROCK);</span>
<span class="plain">if (gg_scriptstr == 0) jump S1Failed;</span>
<span class="plain">glk_window_set_echo_stream(gg_mainwin, gg_scriptstr);</span>
<span class="plain">SWITCH_TRANSCRIPT_ON_RM('B'); new_line;</span>
<span class="plain">VersionSub();</span>
<span class="plain">return;</span>
<span class="plain">.S1Failed;</span>
<span class="plain">SWITCH_TRANSCRIPT_ON_RM('C'); new_line;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. Switch Transcript Off Rule. </b></p>
<pre class="display">
<span class="plain">[ SWITCH_TRANSCRIPT_OFF_R;</span>
<span class="plain">if (actor ~= player) rfalse;</span>
<span class="plain">if (gg_scriptstr == 0) { SWITCH_TRANSCRIPT_OFF_RM('A'); new_line; rtrue; }</span>
<span class="plain">SWITCH_TRANSCRIPT_OFF_RM('B'); new_line;</span>
<span class="plain">glk_stream_close(gg_scriptstr, 0); ! stream_close</span>
<span class="plain">gg_scriptstr = 0;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. Announce Story File Version Rule. </b></p>
<pre class="display">
<span class="plain">[ ANNOUNCE_STORY_FILE_VERSION_R ix;</span>
<span class="plain">if (actor ~= player) rfalse;</span>
<span class="plain">Banner();</span>
<span class="plain">print "Identification number: ";</span>
<span class="plain">for (ix=6: ix &lt;= UUID_ARRAY-&gt;0: ix++) print (char) UUID_ARRAY-&gt;ix;</span>
<span class="plain">print "^";</span>
<span class="plain">@gestalt 1 0 ix;</span>
<span class="plain">print "Interpreter version ", ix / $10000, ".", (ix &amp; $FF00) / $100,</span>
<span class="plain">".", ix &amp; $FF, " / ";</span>
<span class="plain">@gestalt 0 0 ix;</span>
<span class="plain">print "VM ", ix / $10000, ".", (ix &amp; $FF00) / $100, ".", ix &amp; $FF, "^";</span>
<span class="plain">ShowExtensionVersions();</span>
<span class="plain">say__p = 1;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP11"></a><b>&#167;11. Descend To Specific Action Rule. </b>There are 100 or so actions, typically, and this rule is for efficiency's
sake: rather than perform 100 or so comparisons to see which routine to
call, we indirect through a jump table. The routines called are the <code class="display"><span class="extract">-Sub</span></code>
routines: thus, for instance, if <code class="display"><span class="extract">action</span></code> is <code class="display"><span class="extract">##Wait</span></code> then <code class="display"><span class="extract">WaitSub</span></code> is
called. It is essential that this routine not be called for fake actions:
in I7 use this is guaranteed, since fake actions are not allowed into the
action machinery at all.
</p>
<p class="inwebparagraph">Strangely, Glulx's action routines table is numbered in an off-by-one way
compared to the Z-machine's: hence the <code class="display"><span class="extract">+1</span></code>.
</p>
<pre class="display">
<span class="plain">[ DESCEND_TO_SPECIFIC_ACTION_R;</span>
<span class="plain">indirect(#actions_table--&gt;(action+1));</span>
<span class="plain">rtrue;</span>
<span class="plain">];</span>
</pre>
<p class="inwebparagraph"></p>
<hr class="tocbar">
<ul class="toc"><li><a href="S-ft.html">Back to 'Figures Template'</a></li><li><a href="S-lt.html">Continue with 'Language Template'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>