mirror of
https://github.com/ganelson/inform.git
synced 2024-07-02 23:14:57 +03:00
IE-0022: Tidy and reoganise the startup sequence (https://github.com/ganelson/inform-evolution/pull/22)
This commit is contained in:
parent
d96e3477b8
commit
aa7c11eb0f
|
@ -147,16 +147,58 @@ The language of play is a natural language that varies.
|
|||
The parameter-object is an object that varies.
|
||||
The parameter-object variable is defined by Inter as "parameter_value".
|
||||
|
||||
Chapter - Startup
|
||||
|
||||
Startup rules is a rulebook.
|
||||
The startup rulebook is accessible to Inter as "STARTUP_RB".
|
||||
Startup rules have outcomes allow startup (success) and deny startup (failure).
|
||||
|
||||
Shutdown rules is a rulebook.
|
||||
The shutdown rulebook is accessible to Inter as "SHUTDOWN_RB".
|
||||
|
||||
Starting the virtual machine (documented at act_startvm) is an activity.
|
||||
The starting the virtual machine activity is accessible to Inter as "STARTING_VIRTUAL_MACHINE_ACT".
|
||||
The final code startup rule is listed first in for starting the virtual machine.
|
||||
The final code startup rule is defined by Inter as "FINAL_CODE_STARTUP_R".
|
||||
The for starting the virtual machine rules have default no outcome.
|
||||
|
||||
First startup rule (this is the virtual machine startup rule):
|
||||
carry out the starting the virtual machine activity.
|
||||
|
||||
Section - Startup A (for Glulx only)
|
||||
|
||||
The start capturing startup text rule is listed in the before starting the virtual machine rules.
|
||||
The start capturing startup text rule translates into Inter as "CAPTURE_STARTUP_TEXT_R".
|
||||
|
||||
The enable Glulx acceleration rule is listed in the before starting the virtual machine rules.
|
||||
The enable Glulx acceleration rule translates into Inter as "FINAL_CODE_STARTUP_R".
|
||||
|
||||
Section - Startup B
|
||||
|
||||
The initialise memory rule is listed in the before starting the virtual machine rules.
|
||||
The initialise memory rule translates into Inter as "INITIALISE_MEMORY_R".
|
||||
|
||||
The seed random number generator rule is listed in the before starting the virtual machine rules.
|
||||
The seed random number generator rule translates into Inter as "SEED_RANDOM_NUMBER_GENERATOR_R".
|
||||
|
||||
Section - Startup C (for Z-Machine only)
|
||||
|
||||
The final code startup rule is listed in the for starting the virtual machine rules.
|
||||
The final code startup rule translates into Inter as "FINAL_CODE_STARTUP_R".
|
||||
|
||||
Section - Startup D (for Glulx only)
|
||||
|
||||
The recover Glk objects rule is listed in the before starting the virtual machine rules.
|
||||
The recover Glk objects rule translates into Inter as "GGRecoverObjects".
|
||||
|
||||
The sound channel initialisation rule is listed in the for starting the virtual machine rules.
|
||||
The sound channel initialisation rule translates into Inter as "SOUND_CHANNEL_INIT_R".
|
||||
|
||||
The open built-in windows rule is listed in the for starting the virtual machine rules.
|
||||
The open built-in windows rule translates into Inter as "OPEN_BUILT_IN_WINDOWS_R".
|
||||
|
||||
The display captured startup text rule is listed in the for starting the virtual machine rules.
|
||||
The display captured startup text rule translates into Inter as "END_CAPTURE_STARTUP_TEXT_R".
|
||||
|
||||
Chapter - Printing activities
|
||||
|
||||
Printing the name of something (hidden in RULES command) (documented at act_pn) is an activity.
|
||||
The printing the name activity is accessible to Inter as "PRINTING_THE_NAME_ACT".
|
||||
|
|
|
@ -2,30 +2,8 @@ Startup Template.
|
|||
|
||||
How programs for this architecture start up the virtual machine.
|
||||
|
||||
@ |VM_PreInitialise()| is called; then the "starting the virtual machine"
|
||||
activity runs; and then |VM_Initialise()| is called.
|
||||
@ |VM_Check_Functionality()| doesn't need to do anything in Z-Code.
|
||||
|
||||
=
|
||||
[ VM_PreInitialise;
|
||||
];
|
||||
|
||||
[ VM_Initialise i;
|
||||
standard_interpreter = HDR_TERPSTANDARD-->0;
|
||||
|
||||
dict_start = HDR_DICTIONARY-->0;
|
||||
dict_entry_size = dict_start->(dict_start->0 + 1);
|
||||
dict_start = dict_start + dict_start->0 + 4;
|
||||
dict_end = dict_start + ((dict_start - 2)-->0) * dict_entry_size;
|
||||
|
||||
buffer->0 = INPUT_BUFFER_LEN;
|
||||
buffer2->0 = INPUT_BUFFER_LEN;
|
||||
buffer3->0 = INPUT_BUFFER_LEN;
|
||||
parse->0 = 15;
|
||||
parse2->0 = 15;
|
||||
|
||||
if (BasicInformKit`FIX_RNG_CFGF) {
|
||||
@random 10000 -> i;
|
||||
i = -i-2000;
|
||||
@random i -> i;
|
||||
}
|
||||
[ VM_Check_Functionality;
|
||||
];
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
Capabilities Template.
|
||||
|
||||
Miscellaneous capabilities of the 16-bit architecture.
|
||||
Miscellaneous capabilities of the 32-bit architecture.
|
||||
|
||||
@h Summary.
|
||||
The 32-bit architecture is currently the default targeted by Inform, and is
|
||||
|
|
|
@ -882,6 +882,81 @@ Constant wintype_TextGrid = 4;
|
|||
return ret;
|
||||
];
|
||||
|
||||
@ |GGRecoverObjects| handles recovering the Glk objects after restarting or restoring.
|
||||
|
||||
=
|
||||
[ GGRecoverObjects id;
|
||||
! If GGRecoverObjects() has been called, all these stored IDs are
|
||||
! invalid, so we start by clearing them all out.
|
||||
! (In fact, after a restoreundo, some of them may still be good.
|
||||
! For simplicity, though, we assume the general case.)
|
||||
gg_mainwin = 0;
|
||||
gg_statuswin = 0;
|
||||
gg_quotewin = 0;
|
||||
gg_scriptfref = 0;
|
||||
gg_scriptstr = 0;
|
||||
gg_savestr = 0;
|
||||
statuswin_cursize = 0;
|
||||
gg_foregroundchan = 0;
|
||||
gg_backgroundchan = 0;
|
||||
gg_commandstr = 0;
|
||||
gg_command_reading = false;
|
||||
! Also tell the game to clear its object references.
|
||||
IdentifyGlkObject(0);
|
||||
|
||||
id = glk_stream_iterate(0, gg_arguments);
|
||||
while (id) {
|
||||
switch (gg_arguments-->0) {
|
||||
GG_SAVESTR_ROCK: gg_savestr = id;
|
||||
GG_SCRIPTSTR_ROCK: gg_scriptstr = id;
|
||||
GG_COMMANDWSTR_ROCK: gg_commandstr = id;
|
||||
gg_command_reading = false;
|
||||
GG_COMMANDRSTR_ROCK: gg_commandstr = id;
|
||||
gg_command_reading = true;
|
||||
default: IdentifyGlkObject(1, 1, id, gg_arguments-->0);
|
||||
}
|
||||
id = glk_stream_iterate(id, gg_arguments);
|
||||
}
|
||||
|
||||
id = glk_window_iterate(0, gg_arguments);
|
||||
while (id) {
|
||||
switch (gg_arguments-->0) {
|
||||
GG_MAINWIN_ROCK: gg_mainwin = id;
|
||||
GG_STATUSWIN_ROCK: gg_statuswin = id;
|
||||
GG_QUOTEWIN_ROCK: gg_quotewin = id;
|
||||
default: IdentifyGlkObject(1, 0, id, gg_arguments-->0);
|
||||
}
|
||||
id = glk_window_iterate(id, gg_arguments);
|
||||
}
|
||||
|
||||
id = glk_fileref_iterate(0, gg_arguments);
|
||||
while (id) {
|
||||
switch (gg_arguments-->0) {
|
||||
GG_SCRIPTFREF_ROCK: gg_scriptfref = id;
|
||||
default: IdentifyGlkObject(1, 2, id, gg_arguments-->0);
|
||||
}
|
||||
id = glk_fileref_iterate(id, gg_arguments);
|
||||
}
|
||||
|
||||
if (glk_gestalt(gestalt_Sound, 0)) {
|
||||
id = glk_schannel_iterate(0, gg_arguments);
|
||||
while (id) {
|
||||
switch (gg_arguments-->0) {
|
||||
GG_FOREGROUNDCHAN_ROCK: gg_foregroundchan = id;
|
||||
GG_BACKGROUNDCHAN_ROCK: gg_backgroundchan = id;
|
||||
default: IdentifyGlkObject(1, 3, id, gg_arguments-->0);
|
||||
}
|
||||
id = glk_schannel_iterate(id, gg_arguments);
|
||||
}
|
||||
if (gg_foregroundchan ~= 0) { glk_schannel_stop(gg_foregroundchan); }
|
||||
if (gg_backgroundchan ~= 0) { glk_schannel_stop(gg_backgroundchan); }
|
||||
}
|
||||
|
||||
! Tell the game to tie up any loose ends.
|
||||
IdentifyGlkObject(2);
|
||||
rfalse;
|
||||
];
|
||||
|
||||
@h Debugging verb.
|
||||
This powers the GLKLIST command, when there's a command parser to read it.
|
||||
|
||||
|
|
|
@ -2,176 +2,121 @@ Startup Template.
|
|||
|
||||
How programs for this architecture start up the virtual machine.
|
||||
|
||||
@ This variable is set at startup, to avoid asking the interpreter over
|
||||
and over again.
|
||||
@ |VM_Check_Functionality| checks that we are running in a Glk interpreter,
|
||||
as well as that it supports the minimum requirements, which are currently
|
||||
that Glk supports unicode, and Glulx supports real numbers. If one of those
|
||||
requirements is not met an error message will be shown before quitting.
|
||||
|
||||
=
|
||||
Global unicode_gestalt_ok; ! Set if interpreter supports Unicode
|
||||
[ VM_Check_Functionality res;
|
||||
@gestalt 4 2 res; ! Test if this interpreter has Glk...
|
||||
if (res == 0) quit; ! ...without which there would be nothing we could do
|
||||
|
||||
@ |VM_Initialise()| is almost the first routine called, except that the
|
||||
"starting the virtual machine" activity is allowed to go first; and,
|
||||
come to think of it, memory allocation has to be set up before even that,
|
||||
and that in turn calls |VM_PreInitialise()| to do the absolute minimum.
|
||||
! Set the VM's I/O system to be Glk.
|
||||
@setiosys 2 0;
|
||||
|
||||
Arrangements are a little different here compared with the 16-bit architecture,
|
||||
because some data is retained in the case of a restart.
|
||||
if (~~glk_gestalt(gestalt_Unicode, 0)) {
|
||||
Fatal_Error("This storyfile can only be run in an unicode interpreter.");
|
||||
}
|
||||
|
||||
(Many thanks are due to Eliuk Blau, who found several tricky timing errors
|
||||
here and elsewhere in the Glulx-specific code. Frankly, I feel like hanging
|
||||
a sign on the following routines which reads "Congratulations on bringing
|
||||
light to the Dark Room.")
|
||||
|
||||
=
|
||||
[ VM_PreInitialise res;
|
||||
@gestalt 4 2 res; ! Test if this interpreter has Glk...
|
||||
if (res == 0) quit; ! ...without which there would be nothing we could do
|
||||
|
||||
unicode_gestalt_ok = false;
|
||||
if (glk_gestalt(gestalt_Unicode, 0))
|
||||
unicode_gestalt_ok = true;
|
||||
|
||||
! Set the VM's I/O system to be Glk.
|
||||
@setiosys 2 0;
|
||||
@gestalt 11 0 res; ! Test if this interpreter supports real numbers...
|
||||
if (res == 0) {
|
||||
Fatal_Error("This storyfile can only be run in a Glulx interpreter that supports floating-point arithmetic.");
|
||||
}
|
||||
];
|
||||
|
||||
[ VM_Initialise res sty i;
|
||||
@gestalt 4 2 res; ! Test if this interpreter has Glk...
|
||||
if (res == 0) quit; ! ...without which there would be nothing we could do
|
||||
[ Fatal_Error msg;
|
||||
gg_mainwin = glk_window_open(0, 0, 0, wintype_TextBuffer, GG_MAINWIN_ROCK);
|
||||
glk_set_window(gg_mainwin);
|
||||
print "Fatal Error: ", (string) msg, "^";
|
||||
quit;
|
||||
];
|
||||
|
||||
! First, we must go through all the Glk objects that exist, and see
|
||||
! if we created any of them. One might think this strange, since the
|
||||
! program has just started running, but remember that the player might
|
||||
! have just typed "restart".
|
||||
@h Capture startup text.
|
||||
It is a semi-common problem for authors to do something which results in text
|
||||
being printed before any Glk windows have been opened, which results in a fatal
|
||||
interpreter error. (Or even worse, an extension is the cause, which the author
|
||||
should not be expected to know the internal details of.) This is very frustrating,
|
||||
as the author often will not know what is the cause of the error as any error
|
||||
messages can't be shown until a Glk window is created; indeed it's often an error
|
||||
message that is trying to be printed, which the author will never see. To help
|
||||
authors, while we wait for the virtual machine to be set up (including a Glk
|
||||
window) we can instead send any text to a memory stream. Then once the VM is ready
|
||||
we can check if any text was sent to the memory stream, and then finally display
|
||||
it in the window. We only capture 256 bytes, which may not be all that is attempted
|
||||
to be printed, but hopefully it gives authors enough to identify the problem.
|
||||
|
||||
GGRecoverObjects();
|
||||
=
|
||||
Constant PRE_STARTUP_TEXT_CAPTURE_MAX_LEN = 256;
|
||||
Array Pre_Startup_Text_Capture_Buffer -> PRE_STARTUP_TEXT_CAPTURE_MAX_LEN;
|
||||
Array Pre_Startup_Text_Capture_Results --> 2;
|
||||
Global Pre_Startup_Text_Capture_Stream;
|
||||
|
||||
! Sound channel initialisation, and RNG fixing, must be done now rather
|
||||
! than later in case InitGlkWindow() returns a non-zero value.
|
||||
[ CAPTURE_STARTUP_TEXT_R;
|
||||
Pre_Startup_Text_Capture_Stream = glk_stream_open_memory(Pre_Startup_Text_Capture_Buffer, PRE_STARTUP_TEXT_CAPTURE_MAX_LEN, filemode_Write, 0);
|
||||
glk_stream_set_current(Pre_Startup_Text_Capture_Stream);
|
||||
rfalse;
|
||||
];
|
||||
|
||||
[ END_CAPTURE_STARTUP_TEXT_R len;
|
||||
glk_stream_close(Pre_Startup_Text_Capture_Stream, Pre_Startup_Text_Capture_Results);
|
||||
len = Pre_Startup_Text_Capture_Results-->1;
|
||||
if (len) {
|
||||
if (len > PRE_STARTUP_TEXT_CAPTURE_MAX_LEN) {
|
||||
len = PRE_STARTUP_TEXT_CAPTURE_MAX_LEN;
|
||||
}
|
||||
glk_put_buffer(Pre_Startup_Text_Capture_Buffer, len);
|
||||
}
|
||||
rfalse;
|
||||
];
|
||||
|
||||
@h Set up the Glk objects.
|
||||
|
||||
=
|
||||
[ SOUND_CHANNEL_INIT_R;
|
||||
if (glk_gestalt(gestalt_Sound, 0)) {
|
||||
if (gg_foregroundchan == 0)
|
||||
if (gg_foregroundchan == 0) {
|
||||
gg_foregroundchan = glk_schannel_create(GG_FOREGROUNDCHAN_ROCK);
|
||||
if (gg_backgroundchan == 0)
|
||||
}
|
||||
if (gg_backgroundchan == 0) {
|
||||
gg_backgroundchan = glk_schannel_create(GG_BACKGROUNDCHAN_ROCK);
|
||||
}
|
||||
|
||||
if (BasicInformKit`FIX_RNG_CFGF) {
|
||||
@random 10000 i;
|
||||
i = -i-2000;
|
||||
@setrandom i;
|
||||
}
|
||||
|
||||
res = InitGlkWindow(0);
|
||||
if (res ~= 0) return;
|
||||
|
||||
! Now, gg_mainwin and gg_storywin might already be set. If not, set them.
|
||||
|
||||
if (gg_mainwin == 0) {
|
||||
! Open the story window.
|
||||
res = InitGlkWindow(GG_MAINWIN_ROCK);
|
||||
if (res == 0) {
|
||||
! Left-justify the header style
|
||||
glk_stylehint_set(wintype_TextBuffer, style_Header, stylehint_Justification, 0);
|
||||
! Try to make emphasized type in italics and not boldface
|
||||
glk_stylehint_set(wintype_TextBuffer, style_Emphasized, stylehint_Weight, 0);
|
||||
glk_stylehint_set(wintype_TextBuffer, style_Emphasized, stylehint_Oblique, 1);
|
||||
gg_mainwin = glk_window_open(0, 0, 0, wintype_TextBuffer, GG_MAINWIN_ROCK);
|
||||
}
|
||||
if (gg_mainwin == 0) quit; ! If we can't even open one window, give in
|
||||
} else {
|
||||
! There was already a story window. We should erase it.
|
||||
glk_window_clear(gg_mainwin);
|
||||
}
|
||||
|
||||
if (gg_statuswin == 0) {
|
||||
res = InitGlkWindow(GG_STATUSWIN_ROCK);
|
||||
if (res == 0) {
|
||||
statuswin_cursize = statuswin_size;
|
||||
for (sty=0: sty<style_NUMSTYLES: sty++)
|
||||
glk_stylehint_set(wintype_TextGrid, sty, stylehint_ReverseColor, 1);
|
||||
gg_statuswin =
|
||||
glk_window_open(gg_mainwin, winmethod_Fixed + winmethod_Above,
|
||||
statuswin_cursize, wintype_TextGrid, GG_STATUSWIN_ROCK);
|
||||
}
|
||||
}
|
||||
! It's possible that the status window couldn't be opened, in which case
|
||||
! gg_statuswin is now zero. We must allow for that later on.
|
||||
|
||||
glk_set_window(gg_mainwin);
|
||||
|
||||
InitGlkWindow(1);
|
||||
|
||||
! Empty the parse buffer (see bug 0001451)
|
||||
buffer3-->0 = 0;
|
||||
}
|
||||
rfalse;
|
||||
];
|
||||
|
||||
[ GGRecoverObjects id;
|
||||
! If GGRecoverObjects() has been called, all these stored IDs are
|
||||
! invalid, so we start by clearing them all out.
|
||||
! (In fact, after a restoreundo, some of them may still be good.
|
||||
! For simplicity, though, we assume the general case.)
|
||||
gg_mainwin = 0;
|
||||
gg_statuswin = 0;
|
||||
gg_quotewin = 0;
|
||||
gg_scriptfref = 0;
|
||||
gg_scriptstr = 0;
|
||||
gg_savestr = 0;
|
||||
statuswin_cursize = 0;
|
||||
gg_foregroundchan = 0;
|
||||
gg_backgroundchan = 0;
|
||||
gg_commandstr = 0;
|
||||
gg_command_reading = false;
|
||||
! Also tell the game to clear its object references.
|
||||
IdentifyGlkObject(0);
|
||||
[ OPEN_BUILT_IN_WINDOWS_R res sty;
|
||||
! gg_mainwin and gg_storywin might already be set. If not, create them.
|
||||
|
||||
id = glk_stream_iterate(0, gg_arguments);
|
||||
while (id) {
|
||||
switch (gg_arguments-->0) {
|
||||
GG_SAVESTR_ROCK: gg_savestr = id;
|
||||
GG_SCRIPTSTR_ROCK: gg_scriptstr = id;
|
||||
GG_COMMANDWSTR_ROCK: gg_commandstr = id;
|
||||
gg_command_reading = false;
|
||||
GG_COMMANDRSTR_ROCK: gg_commandstr = id;
|
||||
gg_command_reading = true;
|
||||
default: IdentifyGlkObject(1, 1, id, gg_arguments-->0);
|
||||
}
|
||||
id = glk_stream_iterate(id, gg_arguments);
|
||||
}
|
||||
|
||||
id = glk_window_iterate(0, gg_arguments);
|
||||
while (id) {
|
||||
switch (gg_arguments-->0) {
|
||||
GG_MAINWIN_ROCK: gg_mainwin = id;
|
||||
GG_STATUSWIN_ROCK: gg_statuswin = id;
|
||||
GG_QUOTEWIN_ROCK: gg_quotewin = id;
|
||||
default: IdentifyGlkObject(1, 0, id, gg_arguments-->0);
|
||||
}
|
||||
id = glk_window_iterate(id, gg_arguments);
|
||||
}
|
||||
|
||||
id = glk_fileref_iterate(0, gg_arguments);
|
||||
while (id) {
|
||||
switch (gg_arguments-->0) {
|
||||
GG_SCRIPTFREF_ROCK: gg_scriptfref = id;
|
||||
default: IdentifyGlkObject(1, 2, id, gg_arguments-->0);
|
||||
}
|
||||
id = glk_fileref_iterate(id, gg_arguments);
|
||||
}
|
||||
|
||||
if (glk_gestalt(gestalt_Sound, 0)) {
|
||||
id = glk_schannel_iterate(0, gg_arguments);
|
||||
while (id) {
|
||||
switch (gg_arguments-->0) {
|
||||
GG_FOREGROUNDCHAN_ROCK: gg_foregroundchan = id;
|
||||
GG_BACKGROUNDCHAN_ROCK: gg_backgroundchan = id;
|
||||
default: IdentifyGlkObject(1, 3, id, gg_arguments-->0);
|
||||
}
|
||||
id = glk_schannel_iterate(id, gg_arguments);
|
||||
if (gg_mainwin == 0) {
|
||||
! Open the story window.
|
||||
! Left-justify the header style
|
||||
glk_stylehint_set(wintype_TextBuffer, style_Header, stylehint_Justification, 0);
|
||||
! Try to make emphasized type in italics and not boldface
|
||||
glk_stylehint_set(wintype_TextBuffer, style_Emphasized, stylehint_Weight, 0);
|
||||
glk_stylehint_set(wintype_TextBuffer, style_Emphasized, stylehint_Oblique, 1);
|
||||
gg_mainwin = glk_window_open(0, 0, 0, wintype_TextBuffer, GG_MAINWIN_ROCK);
|
||||
if (gg_mainwin == 0) {
|
||||
! If we can't even open one window, give in
|
||||
quit;
|
||||
}
|
||||
if (gg_foregroundchan ~= 0) { glk_schannel_stop(gg_foregroundchan); }
|
||||
if (gg_backgroundchan ~= 0) { glk_schannel_stop(gg_backgroundchan); }
|
||||
} else {
|
||||
! There was already a story window. We should erase it.
|
||||
glk_window_clear(gg_mainwin);
|
||||
}
|
||||
|
||||
! Tell the game to tie up any loose ends.
|
||||
IdentifyGlkObject(2);
|
||||
if (gg_statuswin == 0) {
|
||||
statuswin_cursize = statuswin_size;
|
||||
for (sty=0: sty < style_NUMSTYLES: sty++) {
|
||||
glk_stylehint_set(wintype_TextGrid, sty, stylehint_ReverseColor, 1);
|
||||
}
|
||||
gg_statuswin =
|
||||
glk_window_open(gg_mainwin, winmethod_Fixed + winmethod_Above,
|
||||
statuswin_cursize, wintype_TextGrid, GG_STATUSWIN_ROCK);
|
||||
}
|
||||
! It's possible that the status window couldn't be opened, in which case
|
||||
! gg_statuswin is now zero. We must allow for that later on.
|
||||
|
||||
glk_set_window(gg_mainwin);
|
||||
rfalse;
|
||||
];
|
||||
|
|
|
@ -214,7 +214,6 @@ Constant RTP_FILEIOERROR = 48;
|
|||
Constant RTP_HEAPERROR = 49;
|
||||
Constant RTP_LISTRANGEERROR = 50;
|
||||
Constant RTP_REGEXPSYNTAXERROR = 51;
|
||||
Constant RTP_NOGLULXUNICODE = 52;
|
||||
Constant RTP_BACKDROPONLY = 53;
|
||||
Constant RTP_NOTTHING = 54;
|
||||
Constant RTP_SCENEHASNTSTARTED = 55;
|
||||
|
|
|
@ -154,8 +154,6 @@ Array RTP_Buffer --> (-1) 0 0 0 0 0 0;
|
|||
"always be 0 or more.^";
|
||||
RTP_REGEXPSYNTAXERROR:
|
||||
print "Syntax error in regular expression.^";
|
||||
RTP_NOGLULXUNICODE:
|
||||
print "This interpreter does not support Unicode.^";
|
||||
RTP_NEGATIVEROOT:
|
||||
print "You can't take the square root of a negative number.^";
|
||||
RTP_CANTITERATE:
|
||||
|
|
|
@ -2,26 +2,124 @@ Startup Template.
|
|||
|
||||
How the program starts up, in a Basic Inform project.
|
||||
|
||||
@ Because the functions below are replaced by |WorldModelKit| alternatives
|
||||
@h Summary.
|
||||
These rules perform the essential tasks required for setting up the virtual
|
||||
machine. This includes checking that we are running in a compatible interpreter,
|
||||
and setting up various built in Glk objects (when running in a Glk interpreter).
|
||||
|
||||
These rules here are the ones which get the basic machinery working
|
||||
to the point where it is safe to run arbitrary I7 source text. They necessarily
|
||||
do very low-level things, and it is not guaranteed that I7 phrases will behave
|
||||
to specification if executed before these early rules have finished. So it
|
||||
is hazardous to obstruct or alter them.
|
||||
|
||||
Arrangements are a little different here on the Z-machine, because some
|
||||
data is retained in the case of a restart.
|
||||
|
||||
(Many thanks are due to Eliuk Blau, who found several tricky timing errors
|
||||
here and elsewhere in the Glulx-specific code. Frankly, I feel like hanging
|
||||
a sign on the following routines which reads "Congratulations on bringing
|
||||
light to the Dark Room.")
|
||||
|
||||
@h The startup sequence.
|
||||
As of IE-0022 we have a simplified startup sequence. |Main| calls the |Startup|
|
||||
function, which does two things: run an Architecture16Kit/Architecture32Kit function
|
||||
|VM_Check_Functionality| which checks the VM meets the minimum requirements for Inform
|
||||
(in Glulx it would test a few Glulx/Glk gestalts; in Z-Code it would probably do
|
||||
nothing.) Then it runs the Startup Rules. And that's it - everything else in the
|
||||
startup sequence is now in Inform-accessible rules.
|
||||
|
||||
Because the functions below are replaced by |WorldModelKit| alternatives
|
||||
if that kit is present, the following applies only to Basic Inform programs
|
||||
where |WorldModelKit| is not involved.
|
||||
|
||||
=
|
||||
[ Main;
|
||||
self = COL_HSIZE; ! To ensure this definition is not optimised out
|
||||
Startup();
|
||||
Submain();
|
||||
];
|
||||
|
||||
[ Startup;
|
||||
VM_Check_Functionality();
|
||||
FollowRulebook(STARTUP_RB);
|
||||
rfalse;
|
||||
];
|
||||
|
||||
@h Initialise Memory Rule.
|
||||
This rule amalgamates some minimal initialisations which all need to happen
|
||||
before we can risk using some of the more exotic I7 kinds:
|
||||
|
||||
(a) The language definition might call for initialisation, although the
|
||||
default language of play (English) does not.
|
||||
|
||||
(b) We start the machinery needed to check that property accesses are
|
||||
valid during play.
|
||||
|
||||
(c) We initialise the memory allocation heap, and expand the literal
|
||||
constants, as hinted above: these are called "block constants" since
|
||||
they occupy blocks of memory.
|
||||
|
||||
(d) Some platform-specific dictionary and parse buffer related globals
|
||||
are initialised.
|
||||
|
||||
=
|
||||
[ INITIALISE_MEMORY_R;
|
||||
VM_PreInitialise();
|
||||
LanguageInitialise();
|
||||
|
||||
HeapInitialise(); ! Create a completely unused memory allocation heap
|
||||
StackFramingInitialise(); ! Create an empty stack
|
||||
CreateDynamicRelations(); ! Create relation structures on the heap
|
||||
|
||||
#Ifdef TARGET_GLULX;
|
||||
! Empty the parse buffer (see bug 0001451)
|
||||
buffer3-->0 = 0;
|
||||
#Ifnot;
|
||||
standard_interpreter = HDR_TERPSTANDARD-->0;
|
||||
|
||||
dict_start = HDR_DICTIONARY-->0;
|
||||
dict_entry_size = dict_start->(dict_start->0 + 1);
|
||||
dict_start = dict_start + dict_start->0 + 4;
|
||||
dict_end = dict_start + ((dict_start - 2)-->0) * dict_entry_size;
|
||||
|
||||
buffer->0 = INPUT_BUFFER_LEN;
|
||||
buffer2->0 = INPUT_BUFFER_LEN;
|
||||
buffer3->0 = INPUT_BUFFER_LEN;
|
||||
parse->0 = 15;
|
||||
parse2->0 = 15;
|
||||
#Endif;
|
||||
|
||||
rfalse;
|
||||
];
|
||||
|
||||
[ Main;
|
||||
self = COL_HSIZE; ! To ensure this definition is not optimised out
|
||||
VM_Initialise();
|
||||
INITIALISE_MEMORY_R();
|
||||
SEED_RANDOM_NUMBER_GENERATOR_R();
|
||||
Submain();
|
||||
@h Seed Random Number Generator Rule.
|
||||
Unless a seed is provided by Inform, and it won't be for released story files,
|
||||
the VM's interpreter is supposed to start up with a good seed in its random
|
||||
number generator: something usually derived from, say, the milliseconds part
|
||||
of the current time of day, which is unlikely to repeat or show any pattern
|
||||
in real-world use. However, early Z-machine interpreters often did this quite
|
||||
badly, starting with poor seed values which meant that the first few random
|
||||
numbers always had something in common (being fairly small in their range,
|
||||
for instance). To obviate this we extract and throw away 100 random numbers
|
||||
to get the generator going, shaking out more obvious early patterns, but
|
||||
that cannot really help much if the VM interpreter's RNG is badly written.
|
||||
"Anyone who considers arithmetical methods of producing random digits is,
|
||||
of course, in a state of sin" (von Neumann).
|
||||
|
||||
=
|
||||
[ SEED_RANDOM_NUMBER_GENERATOR_R i;
|
||||
if (BasicInformKit`FIX_RNG_CFGF) {
|
||||
#Ifdef TARGET_GLULX;
|
||||
@random 10000 i;
|
||||
i = -i-2000;
|
||||
@setrandom i;
|
||||
#Ifnot;
|
||||
@random 10000 -> i;
|
||||
i = -i-2000;
|
||||
@random i -> i;
|
||||
#Endif;
|
||||
}
|
||||
if (RNG_SEED_AT_START_OF_PLAY) VM_Seed_RNG(RNG_SEED_AT_START_OF_PLAY);
|
||||
for (i=1: i<=100: i++) random(i);
|
||||
rfalse;
|
||||
];
|
||||
|
|
|
@ -284,49 +284,45 @@ it's clearer to give two definitions, so:
|
|||
FlexError("ran out with too many simultaneous text conversions");
|
||||
}
|
||||
|
||||
if (unicode_gestalt_ok) {
|
||||
SuspendRTP();
|
||||
.RetryWithLargerBuffer;
|
||||
saved_stream = glk_stream_get_current();
|
||||
stream = glk_stream_open_memory_uni(buffer, RawBufferSize, filemode_Write, 0);
|
||||
glk_stream_set_current(stream);
|
||||
SuspendRTP();
|
||||
.RetryWithLargerBuffer;
|
||||
saved_stream = glk_stream_get_current();
|
||||
stream = glk_stream_open_memory_uni(buffer, RawBufferSize, filemode_Write, 0);
|
||||
glk_stream_set_current(stream);
|
||||
|
||||
@push say__p; @push say__pc;
|
||||
ClearParagraphing(7);
|
||||
if (from_snippet) print (PrintSnippet) from_value;
|
||||
else print (PrintI6Text) from_value;
|
||||
@pull say__pc; @pull say__p;
|
||||
@push say__p; @push say__pc;
|
||||
ClearParagraphing(7);
|
||||
if (from_snippet) print (PrintSnippet) from_value;
|
||||
else print (PrintI6Text) from_value;
|
||||
@pull say__pc; @pull say__p;
|
||||
|
||||
results = buffer + buffer_size - 2*WORDSIZE;
|
||||
glk_stream_close(stream, results);
|
||||
if (saved_stream) glk_stream_set_current(saved_stream);
|
||||
ResumeRTP();
|
||||
results = buffer + buffer_size - 2*WORDSIZE;
|
||||
glk_stream_close(stream, results);
|
||||
if (saved_stream) glk_stream_set_current(saved_stream);
|
||||
ResumeRTP();
|
||||
|
||||
len = results-->1;
|
||||
if (len > RawBufferSize-1) {
|
||||
! Glulx had to truncate text output because the buffer ran out:
|
||||
! len is the number of characters which it tried to print
|
||||
news = RawBufferSize;
|
||||
while (news < len) news=news*2;
|
||||
i = VM_AllocateMemory(news*WORDSIZE);
|
||||
if (i ~= 0) {
|
||||
if (memory_to_free) VM_FreeMemory(memory_to_free);
|
||||
memory_to_free = i;
|
||||
buffer = i;
|
||||
RawBufferSize = news;
|
||||
buffer_size = (RawBufferSize + 2)*WORDSIZE;
|
||||
jump RetryWithLargerBuffer;
|
||||
}
|
||||
! Memory allocation refused: all we can do is to truncate the text
|
||||
len = RawBufferSize-1;
|
||||
len = results-->1;
|
||||
if (len > RawBufferSize-1) {
|
||||
! Glulx had to truncate text output because the buffer ran out:
|
||||
! len is the number of characters which it tried to print
|
||||
news = RawBufferSize;
|
||||
while (news < len) news=news*2;
|
||||
i = VM_AllocateMemory(news*WORDSIZE);
|
||||
if (i ~= 0) {
|
||||
if (memory_to_free) VM_FreeMemory(memory_to_free);
|
||||
memory_to_free = i;
|
||||
buffer = i;
|
||||
RawBufferSize = news;
|
||||
buffer_size = (RawBufferSize + 2)*WORDSIZE;
|
||||
jump RetryWithLargerBuffer;
|
||||
}
|
||||
buffer-->(len) = 0;
|
||||
|
||||
TEXT_TY_CastPrimitiveNesting--;
|
||||
BlkValueMassCopyFromArray(to_txt, buffer, 4, len+1);
|
||||
} else {
|
||||
RunTimeProblem(RTP_NOGLULXUNICODE);
|
||||
! Memory allocation refused: all we can do is to truncate the text
|
||||
len = RawBufferSize-1;
|
||||
}
|
||||
buffer-->(len) = 0;
|
||||
|
||||
TEXT_TY_CastPrimitiveNesting--;
|
||||
BlkValueMassCopyFromArray(to_txt, buffer, 4, len+1);
|
||||
if (memory_to_free) VM_FreeMemory(memory_to_free);
|
||||
];
|
||||
#endif;
|
||||
|
|
|
@ -318,27 +318,6 @@ This is not quite so efficient as Memcpy, but not terrible.
|
|||
rfalse;
|
||||
];
|
||||
|
||||
@h Seed Random Number Generator Rule.
|
||||
Unless a seed is provided by Inform, and it won't be for released story files,
|
||||
the VM's interpreter is supposed to start up with a good seed in its random
|
||||
number generator: something usually derived from, say, the milliseconds part
|
||||
of the current time of day, which is unlikely to repeat or show any pattern
|
||||
in real-world use. However, early Z-machine interpreters often did this quite
|
||||
badly, starting with poor seed values which meant that the first few random
|
||||
numbers always had something in common (being fairly small in their range,
|
||||
for instance). To obviate this we extract and throw away 100 random numbers
|
||||
to get the generator going, shaking out more obvious early patterns, but
|
||||
that cannot really help much if the VM interpreter's RNG is badly written.
|
||||
"Anyone who considers arithmetical methods of producing random digits is,
|
||||
of course, in a state of sin" (von Neumann).
|
||||
|
||||
=
|
||||
[ SEED_RANDOM_NUMBER_GENERATOR_R i;
|
||||
if (RNG_SEED_AT_START_OF_PLAY) VM_Seed_RNG(RNG_SEED_AT_START_OF_PLAY);
|
||||
for (i=1: i<=100: i++) random(i);
|
||||
rfalse;
|
||||
];
|
||||
|
||||
@h Regarding.
|
||||
These are used with adaptive text.
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
"defines-Main": false,
|
||||
"provides-kinds": [ "Macros.neptune", "Protocols.neptune", "Core.neptune", "Punctuation.neptune", "Files.neptune" ],
|
||||
"indexes-with-structure": "Basic.indext",
|
||||
"configuration-flags": [ "AMERICAN_DIALECT", "AUTHORIAL_MODESTY", "ECHO_COMMANDS", "FIX_RNG", "MEMORY_ECONOMY", "NO_DEPRECATED", "NUMBERED_RULES", "PRINT_ENGINEER_EXPS", "SERIAL_COMMA", "NO_AUTO_PLURAL_NAMES" ],
|
||||
"configuration-flags": [ "AMERICAN_DIALECT", "AUTHORIAL_MODESTY", "ECHO_COMMANDS", "FIX_RNG", "MEMORY_ECONOMY", "NO_AUTO_PLURAL_NAMES", "NO_DEPRECATED", "NUMBERED_RULES", "PRINT_ENGINEER_EXPS", "SERIAL_COMMA" ],
|
||||
"configuration-values": [ "STACK_FRAME_CAPACITY", "TEXT_BUFFER_SIZE", "DICT_RESOLUTION" ]
|
||||
}
|
||||
}
|
|
@ -24,7 +24,7 @@ Global IterationsOfTurnSequence;
|
|||
+replacing(from BasicInformKit) [ Main;
|
||||
say__pc = say__pc | PARA_NORULEBOOKBREAKS;
|
||||
rulebook_without_variables = ACTION_PROCESSING_RB;
|
||||
FollowRulebook(STARTUP_RB);
|
||||
Startup();
|
||||
if (say__pc & PARA_NORULEBOOKBREAKS) say__pc = say__pc - PARA_NORULEBOOKBREAKS;
|
||||
while (true) {
|
||||
while (deadflag == false) {
|
||||
|
@ -38,17 +38,14 @@ Global IterationsOfTurnSequence;
|
|||
}
|
||||
];
|
||||
|
||||
@h Virtual Machine Startup Rule.
|
||||
We delegate to the appropriate VM-specific section of code for the real work.
|
||||
@h Initial Whitespace Rule.
|
||||
The printing of three blank lines at the start of play is traditional: on early
|
||||
Z-machine interpreters such as InfoTaskForce and Zip it was a necessity because
|
||||
of the way they buffered output. On modern windowed ones it still helps to
|
||||
space the opening text better.
|
||||
|
||||
=
|
||||
[ VIRTUAL_MACHINE_STARTUP_R;
|
||||
CarryOutActivity(STARTING_VIRTUAL_MACHINE_ACT);
|
||||
VM_Initialise();
|
||||
[ INITIAL_WHITESPACE_R;
|
||||
! It is now safe for the paragraph breaking between rules mechanism to work
|
||||
if (say__pc & PARA_NORULEBOOKBREAKS) say__pc = say__pc - PARA_NORULEBOOKBREAKS;
|
||||
print "^^^";
|
||||
|
@ -71,13 +68,10 @@ reads, say, "Mrs Bridges is a woman. The player is Mrs Bridges."): in
|
|||
other circumstances they are often correct, but this must not be relied on.
|
||||
|
||||
@h Initialise Memory Rule.
|
||||
This rule amalgamates some minimal initialisations which all need to happen
|
||||
before we can risk using some of the more exotic I7 kinds:
|
||||
In addition to BasicInformKit's memory initialisation, this rule sets up
|
||||
the initial situation:
|
||||
|
||||
(a) The language definition might call for initialisation, although the
|
||||
default language of play (English) does not.
|
||||
|
||||
(b) A handful of variables are filled in. |I7_LOOKMODE| is a constant
|
||||
A handful of variables are filled in. |I7_LOOKMODE| is a constant
|
||||
created by the use options "use full-length room descriptions" or
|
||||
"use abbreviated room descriptions", but otherwise not existing. It is
|
||||
particularly important that |player| have the correct value, as the
|
||||
|
@ -91,22 +85,14 @@ we know better. We do this so that the "update chronological records rule"
|
|||
cannot see where the player is: see the Standard Rules for an explanation
|
||||
of why this is, albeit perhaps dubiously, a good thing.
|
||||
|
||||
(c) We start the machinery needed to check that property accesses are
|
||||
valid during play.
|
||||
|
||||
(d) And we initialise the memory allocation heap, and expand the literal
|
||||
constants, as hinted above: these are called "block constants" since
|
||||
they occupy blocks of memory.
|
||||
|
||||
The |not_yet_in_play| flag, which is cleared when the first command is
|
||||
about to be read from the keyboard, suppresses the standard status line
|
||||
text: thus, if there is some long text to read before the player finds out
|
||||
where he is, the surprise will not be spoiled.
|
||||
|
||||
=
|
||||
+replacing(from BasicInformKit) [ INITIALISE_MEMORY_R;
|
||||
VM_PreInitialise();
|
||||
LanguageInitialise();
|
||||
+replacing(keeping)(from BasicInformKit) [ INITIALISE_MEMORY_R;
|
||||
replaced`INITIALISE_MEMORY_R();
|
||||
|
||||
not_yet_in_play = true;
|
||||
lookmode = WorldModelKit`ROOM_DESC_DETAIL_CFGV;
|
||||
|
@ -115,10 +101,6 @@ where he is, the surprise will not be spoiled.
|
|||
real_location = nothing;
|
||||
location = nothing;
|
||||
|
||||
HeapInitialise(); ! Create a completely unused memory allocation heap
|
||||
StackFramingInitialise(); ! Create an empty stack
|
||||
CreateDynamicRelations(); ! Create relation structures on the heap
|
||||
|
||||
rfalse;
|
||||
];
|
||||
|
||||
|
|
|
@ -78,22 +78,93 @@ Be wary modifying these: rulebooks and activities must be defined in exactly
|
|||
the right order, matching definitions both in the Inform 7 compiler and in the
|
||||
template libraries. (Remember that creating an activity creates three rulebooks.)
|
||||
|
||||
These rules here are the ones which get the basic machinery working
|
||||
to the point where it is safe to run arbitrary I7 source text. They necessarily
|
||||
do very low-level things, and it is not guaranteed that I7 phrases will behave
|
||||
to specification if executed before these early rules have finished. So it
|
||||
is hazardous to obstruct or alter them.
|
||||
|
||||
(a) The "virtual machine startup rule" carries out necessary steps to
|
||||
begin execution on the virtual machine in use: this entails relatively little
|
||||
on the Z-machine versions 5 or 8, but can involve extensive work to get the
|
||||
screen display working on Glulx or Z6.
|
||||
|
||||
(b) The "initialise memory rule" starts up the memory allocation heap,
|
||||
if there is one, and sets some essential I6 variables. If there is any rule
|
||||
not to meddle with, this is it.
|
||||
|
||||
(c) The "seed random number generator rule" seeds the RNG to a fixed value
|
||||
if Inform has requested this (which it does in response to the |-rng| command
|
||||
line switch, which is in turn used by the |intest| testing utility: it's a
|
||||
way to make deterministic tests of programs which use random values).
|
||||
|
||||
(d) The "recover Glk objects rule" runs the object recovery process in order to
|
||||
identify and pre-existing Glk objects after a restart.
|
||||
|
||||
(e) The "open built-in windows rule" opens the Glk windows; only after this
|
||||
point is it safe to print anything.
|
||||
|
||||
=
|
||||
Chapter - Startup
|
||||
|
||||
Startup rules is a rulebook.
|
||||
The startup rulebook is accessible to Inter as "STARTUP_RB".
|
||||
Startup rules have outcomes allow startup (success) and deny startup (failure).
|
||||
|
||||
Shutdown rules is a rulebook.
|
||||
The shutdown rulebook is accessible to Inter as "SHUTDOWN_RB".
|
||||
|
||||
Starting the virtual machine (documented at act_startvm) is an activity.
|
||||
The starting the virtual machine activity is accessible to Inter as "STARTING_VIRTUAL_MACHINE_ACT".
|
||||
The final code startup rule is listed first in for starting the virtual machine.
|
||||
The final code startup rule is defined by Inter as "FINAL_CODE_STARTUP_R".
|
||||
The for starting the virtual machine rules have default no outcome.
|
||||
|
||||
First startup rule (this is the virtual machine startup rule):
|
||||
carry out the starting the virtual machine activity.
|
||||
|
||||
Section - Startup A (for Glulx only)
|
||||
|
||||
The start capturing startup text rule is listed in the before starting the virtual machine rules.
|
||||
The start capturing startup text rule translates into Inter as "CAPTURE_STARTUP_TEXT_R".
|
||||
|
||||
The enable Glulx acceleration rule is listed in the before starting the virtual machine rules.
|
||||
The enable Glulx acceleration rule translates into Inter as "FINAL_CODE_STARTUP_R".
|
||||
|
||||
Section - Startup B
|
||||
|
||||
The initialise memory rule is listed in the before starting the virtual machine rules.
|
||||
The initialise memory rule translates into Inter as "INITIALISE_MEMORY_R".
|
||||
|
||||
The seed random number generator rule is listed in the before starting the virtual machine rules.
|
||||
The seed random number generator rule translates into Inter as "SEED_RANDOM_NUMBER_GENERATOR_R".
|
||||
|
||||
Section - Startup C (for Z-Machine only)
|
||||
|
||||
The final code startup rule is listed in the for starting the virtual machine rules.
|
||||
The final code startup rule translates into Inter as "FINAL_CODE_STARTUP_R".
|
||||
|
||||
Section - Startup D (for Glulx only)
|
||||
|
||||
The recover Glk objects rule is listed in the before starting the virtual machine rules.
|
||||
The recover Glk objects rule translates into Inter as "GGRecoverObjects".
|
||||
|
||||
@ These rules now set up the built in sound channels and windows.
|
||||
|
||||
=
|
||||
The sound channel initialisation rule is listed in the for starting the virtual machine rules.
|
||||
The sound channel initialisation rule translates into Inter as "SOUND_CHANNEL_INIT_R".
|
||||
|
||||
The open built-in windows rule is listed in the for starting the virtual machine rules.
|
||||
The open built-in windows rule translates into Inter as "OPEN_BUILT_IN_WINDOWS_R".
|
||||
|
||||
The display captured startup text rule is listed in the for starting the virtual machine rules.
|
||||
The display captured startup text rule translates into Inter as "END_CAPTURE_STARTUP_TEXT_R".
|
||||
|
||||
@ However, the two activities for printing names of objects are indeed
|
||||
functional in Basic Inform.
|
||||
|
||||
=
|
||||
Chapter - Printing activities
|
||||
|
||||
Printing the name of something (hidden in RULES command) (documented at act_pn) is an activity.
|
||||
The printing the name activity is accessible to Inter as "PRINTING_THE_NAME_ACT".
|
||||
|
||||
|
|
|
@ -328,7 +328,7 @@ A thing can be privately-named or publicly-named. A thing is usually publicly-na
|
|||
A thing can be undescribed or described. A thing is usually described.
|
||||
A thing can be marked for listing or unmarked for listing. A thing is usually
|
||||
unmarked for listing.
|
||||
A thing can be mentioned or unmentioned. A thing is usually mentioned.
|
||||
A thing can be mentioned or unmentioned. A thing is usually unmentioned.
|
||||
|
||||
@ We now have a mixed bag of value properties, all descriptive -- it's an
|
||||
interesting reflection on how qualitative English text usually is that the
|
||||
|
|
|
@ -481,35 +481,19 @@ Section 2 - The Standard Rules
|
|||
The little-used do nothing rule is defined by Inter as "LITTLE_USED_DO_NOTHING_R".
|
||||
|
||||
@h Startup.
|
||||
Every rulebook contains a (possibly empty) run of "first" rules, then
|
||||
a (possibly empty) run of miscellaneous rules, then a (possibly empty)
|
||||
run of "last" rules. It's unusual to have more than one rule anchored
|
||||
to either end as "first" or "last", but entirely legal, and we make
|
||||
use of that ability here.
|
||||
These startup rules prepare the various world model specific systems.
|
||||
|
||||
The "first" rules here are the ones which get the basic machinery working
|
||||
to the point where it is safe to run arbitrary I7 source text. They necessarily
|
||||
do very low-level things, and it is not guaranteed that I7 phrases will behave
|
||||
to specification if executed before these early rules have finished. So it
|
||||
is hazardous to obstruct or alter them.
|
||||
(a) The printing of three blank lines at the start of play is traditional: on early
|
||||
Z-machine interpreters such as InfoTaskForce and Zip it was a necessity because
|
||||
of the way they buffered output. On modern windowed ones it still helps to
|
||||
space the opening text better.
|
||||
|
||||
(a) The "initialise memory rule" starts up the memory allocation heap,
|
||||
if there is one, and sets some essential I6 variables. If there is any rule
|
||||
not to meddle with, this is it.
|
||||
(b) The "position player in model world rule" completes the initial
|
||||
construction of the spatial model world.
|
||||
|
||||
(b) The "virtual machine startup rule" carries out necessary steps to
|
||||
begin execution on the virtual machine in use: this entails relatively little
|
||||
on the Z-machine versions 5 or 8, but can involve extensive work to get the
|
||||
screen display working on Glulx or Z6. Before anything else happens, however,
|
||||
the "starting the virtual machine" activity (see below) is carried out.
|
||||
|
||||
(c) The "seed random number generator rule" seeds the RNG to a fixed value
|
||||
if Inform has requested this (which it does in response to the |-rng| command
|
||||
line switch, which is in turn used by the |intest| testing utility: it's a
|
||||
way to make deterministic tests of programs which use random values).
|
||||
|
||||
(d) The "update chronological records rule" is described in further detail
|
||||
below, since it appears both here and also in the turn sequence rulebook.
|
||||
(c) The "prepare chronological records rule" is described in further detail
|
||||
below (where it's called the "update chronological records rule), since it appears
|
||||
both here and also in the turn sequence rulebook.
|
||||
Here it's providing us with a baseline of initial truths from which we can
|
||||
later assess conditions such as "the marble door has been open". A subtle
|
||||
and questionable point of the design is that this rule is placed at a time
|
||||
|
@ -520,12 +504,7 @@ Dining Room for three turns". It's as if the player teleports into an
|
|||
already-existing world, like some Star Trek crewman, just in time for the
|
||||
first command.
|
||||
|
||||
(e) All items begin unmentioned, as might be expected.
|
||||
|
||||
(f) And the "position player in model world rule" completes the initial
|
||||
construction of the spatial model world.
|
||||
|
||||
(g) The "start in the correct scenes rule" ensures that we start out
|
||||
(d) The "start in the correct scenes rule" ensures that we start out
|
||||
in the correct scenes. (This can't wait, because it's just conceivable
|
||||
that somebody has written a rule with a preamble like "When play
|
||||
begins during the Hunting Season...": it's also where the scene
|
||||
|
@ -533,24 +512,24 @@ Entire Game begins.) That completes the necessary preliminaries before
|
|||
ordinary I7 rules can be run.
|
||||
|
||||
=
|
||||
The start in the correct scenes rule is listed first in the startup rulebook. [7th.]
|
||||
The position player in model world rule is listed first in the startup rulebook. [6th.]
|
||||
This is the declare everything initially unmentioned rule:
|
||||
repeat with item running through things:
|
||||
now the item is not mentioned.
|
||||
The declare everything initially unmentioned rule is listed first in the startup rulebook. [5th]
|
||||
The update chronological records rule is listed first in the startup rulebook. [4th.]
|
||||
The seed random number generator rule is listed first in the startup rulebook. [3rd.]
|
||||
The virtual machine startup rule is listed first in the startup rulebook. [2nd.]
|
||||
The initialise memory rule is listed first in the startup rulebook. [1st.]
|
||||
The initial whitespace rule is listed first in the after starting the virtual machine rules.
|
||||
The initial whitespace rule translates into Inter as "INITIAL_WHITESPACE_R".
|
||||
|
||||
The virtual machine startup rule is defined by Inter as "VIRTUAL_MACHINE_STARTUP_R".
|
||||
The initialise memory rule is defined by Inter as "INITIALISE_MEMORY_R".
|
||||
The seed random number generator rule is defined by Inter as "SEED_RANDOM_NUMBER_GENERATOR_R".
|
||||
The update chronological records rule is defined by Inter as "UPDATE_CHRONOLOGICAL_RECORDS_R".
|
||||
The position player in model world rule is defined by Inter as "POSITION_PLAYER_IN_MODEL_R".
|
||||
The position player in model world rule is listed in the after starting the virtual machine rules.
|
||||
The position player in model world rule translates into Inter as "POSITION_PLAYER_IN_MODEL_R".
|
||||
|
||||
This is the start in the correct scenes rule: follow the scene changing rules.
|
||||
The prepare chronological records rule is listed in the after starting the virtual machine rules.
|
||||
The prepare chronological records rule translates into Inter as "PREPARE_CHRONOLOGICAL_RECORDS_R".
|
||||
|
||||
Include (-
|
||||
! Awkward hack to get around rulebook basis issues that mean we can't simply include the one rule everywhere we need to
|
||||
[ PREPARE_CHRONOLOGICAL_RECORDS_R;
|
||||
UPDATE_CHRONOLOGICAL_RECORDS_R();
|
||||
];
|
||||
-).
|
||||
|
||||
After starting the virtual machine (this is the start in the correct scenes rule):
|
||||
follow the scene changing rules.
|
||||
|
||||
@ The remaining rules, though, are fair game for alteration, and as if to
|
||||
prove the point they are all written in standard I7 source text. Note that
|
||||
|
@ -561,18 +540,17 @@ a change to be notified to the player as if it has happened through some
|
|||
action.
|
||||
|
||||
=
|
||||
The when play begins stage rule is listed in the startup rulebook.
|
||||
The fix baseline scoring rule is listed in the startup rulebook.
|
||||
The display banner rule is listed in the startup rulebook.
|
||||
The initial room description rule is listed in the startup rulebook.
|
||||
Startup rule (this is the when play begins stage rule):
|
||||
follow the when play begins rulebook.
|
||||
|
||||
This is the when play begins stage rule: follow the when play begins rulebook.
|
||||
Startup rule (this is the fix baseline scoring rule):
|
||||
now the last notified score is the score.
|
||||
|
||||
This is the fix baseline scoring rule: now the last notified score is the score.
|
||||
Startup rule (this is the display banner rule):
|
||||
say "[banner text]".
|
||||
|
||||
This is the display banner rule: say "[banner text]".
|
||||
|
||||
This is the initial room description rule: try looking.
|
||||
Startup rule (this is the initial room description rule):
|
||||
try looking.
|
||||
|
||||
@h The turn sequence.
|
||||
In each turn, a command is read and parsed from the keyboard, and any
|
||||
|
@ -633,6 +611,9 @@ A first turn sequence rule (this is the every turn stage rule):
|
|||
A first turn sequence rule (this is the early scene changing stage rule):
|
||||
follow the scene changing rules. [4th.]
|
||||
The generate action rule is listed first in the turn sequence rulebook. [3rd.]
|
||||
This is the declare everything initially unmentioned rule:
|
||||
repeat with item running through things:
|
||||
now the item is not mentioned.
|
||||
The declare everything initially unmentioned rule is listed first in the turn sequence rulebook. [2nd.]
|
||||
The parse command rule is listed first in the turn sequence rulebook. [1st.]
|
||||
|
||||
|
@ -658,6 +639,7 @@ points", which are strategic moments during play, and this is one of them.
|
|||
The timed events rule is listed in the turn sequence rulebook.
|
||||
The advance time rule is listed in the turn sequence rulebook.
|
||||
The update chronological records rule is listed in the turn sequence rulebook.
|
||||
The update chronological records rule translates into Inter as "UPDATE_CHRONOLOGICAL_RECORDS_R".
|
||||
|
||||
@ We now come to the rules anchored at the end, using "last". This part of
|
||||
the rulebook is reserved for book-keeping which has to happen positively
|
||||
|
|
Loading…
Reference in a new issue