| Z-Machine Standard 1.1 Document | |
| ------------------------------- | |
| Authors: Kevin Bracey & Jason C. Penney | |
| Minor revisions: David Kinder | |
| INTRODUCTION | |
| ============ | |
| This revision of the Z-Machine Standards Document has been written with | |
| the following aims: | |
| 1) To clarify problem areas in Standard 1.0, and correct errors | |
| 2) To allow more probing of interpreter capabilities | |
| 3) To clarify the use of Blorb with Standard 1.0 | |
| 4) To add some simple extensions to the Version 5 and Version 6 | |
| screen models to increase flexibility | |
| As ever, interpreters *FULLY* implementing this Standard (apart from any | |
| optional parts whose absence are signalled through header bits) for a given | |
| Version shall indicate this by setting the Standard revision bytes in the | |
| header to $01 $01. (An interpreter might meet the Standard for all Versions | |
| other than V6, in which case it would not fill in the revision bytes when | |
| playing a V6 game). | |
| There have been instances in the past of interpreters that do not fully meet | |
| Standard 1.0 claiming Standard 1.0 compliance in the header. This sort of | |
| behaviour is dangerous, and likely to cause games that would otherwise work | |
| to break. | |
| Conversely, games that absolutely require Standard 1.1 features should not | |
| refuse outright to run on a non-Standard 1.1 interpreter - it may be | |
| implementing the new features you require, being deficient only in other | |
| areas. Instead, a warning should be issued to the user before proceeding. | |
| Of course, whereever possible games should have alternative behaviour | |
| automatically invoked for older interpreters. | |
| As with the rest of the Standard, all references to Version 5 in this | |
| document apply equally to Versions 7 and 8. | |
| The word SHOULD in this document denotes a strong recommendation - | |
| implementors may take other action if they have a good reason. | |
| Other specific phrasing, such as MUST, SHALL, WILL, DOES or ARE, indicates an | |
| absolute requirement of the Standard. Any deviation indicates non-compliance. | |
| UPDATES/CLARIFICATIONS | |
| ====================== | |
| Memory layout | |
| ------------- | |
| Version 6 and 7 story files are both limited to 512K , not 320K. The 320K | |
| limitation was an artificial one imposed by the Inform compiler - this has | |
| now been addressed by a compiler patch. | |
| Padding | |
| ------- | |
| The standard currently states that story file padding beyond the length | |
| specified in the header must be all zero bytes. Many Infocom story files in | |
| fact contain non-zero data in the padding, so interpreters must be sure to | |
| exclude the padding from checksum calculations. | |
| Character set | |
| ------------- | |
| In the past, not just in the Z-machine world, there has been general | |
| confusion over the rendering of ASCII/ZSCII/Latin-1/Unicode characters $27 | |
| and $60. For the Z-machine, the traditional interpretations of | |
| right-single-quote/apostrophe and left-single-quote are preferred over the | |
| modern neutral-single-quote and grave accent - see Table 2A of the Inform | |
| Designer's Manual. $22 is a neutral double-quote. | |
| An alternative rendering is to interpret both $27 and $60 as neutral quotes, | |
| but interpreting $60 as a grave accent is to be avoided. | |
| No doubt aware of this confusion, Infocom never used character $60, and used | |
| $27 almost exclusively as an apostrophe - hardly any single quotes appear in | |
| Infocom games. Modern authors would do well to follow their lead. | |
| The few Infocom games that do use single quotes use $27 for both opening and | |
| closing - but even on many of their interpreters this looked a little odd, so | |
| suggesting that $27 be a right quote introduces no extra compatibility | |
| problems. | |
| Encoded text | |
| ------------ | |
| In Version 3 and later, many of Infocom's interpreters (and some subsequent | |
| interpreters, such as ITF's) treat two consecutive Z-characters 4 or 5 as | |
| shift locks, contrary to the Standard. As a result, story files should not | |
| use multiple consecutive 4 or 5 codes except for padding at the end of | |
| strings and dictionary words. In any case, these shift locks are not used in | |
| dictionary words, or any of Infocom's story files. | |
| Two extra rules apply to encoding text for dictionary words in Versions 1 and | |
| 2 only (see 3.7). If the truncation to 6 Z-characters leaves a multi- | |
| Z-character construction incomplete, the end-bit of the last word is not set. | |
| Also, shift-lock Z-characters 4 and 5 are used instead of the single-shift | |
| Z-characters 2 and 3 when the next two characters come from the same | |
| alphabet. These two rules affect the dictionary of Zork I, which contains | |
| "nasty-" (looking), "storm-" (tossed) and "pdp10". Arguably, the first rule | |
| could be a bug, but the 3 extant V1 and V2 files are consistent. The games | |
| are still winnable without access to those dictionary words. | |
| Unicode | |
| ------- | |
| The Z-machine is not expected to handle complex Unicode formatting like | |
| combining characters, bidirectional formatting and unusual line-wrapping | |
| rules - it remains firmly based in the world of left-to-right text with space | |
| breaks between words - every character is viewed as separate spacing glyph. | |
| All output is in presentation order, from left to right. To handle languages | |
| like Arabic or Hebrew, text would have to be output "visually", with manual | |
| line breaks (possibly via an in-game formatting engine). | |
| Far eastern languages are generally straightforward, except they usually use | |
| no spaces, and line wraps can occur almost anywhere. The easiest to way to | |
| handle this would be for the game to turn off buffering. A more sophisticated | |
| game might include its own formatting engine. Also, fixed-space output is | |
| liable to be problematical with most Far Eastern fonts, which use a mixture | |
| of "full width" and "half width" forms - all half-width characters would have | |
| to be forced to full width. | |
| The Z-machine does not provide access to non-BMP characters (ie characters | |
| outside the range U+0000 to U+FFFF). | |
| Unicode characters U+0000 to U+001F and U+007F to U+009F are control codes, | |
| and must not be used. | |
| Header capabilities bits | |
| ------------------------ | |
| The (Version 6) sound and graphics bits in Flags 1 indicate general | |
| availability of sound and graphics - ie whether the associated opcodes are | |
| available and functional. | |
| The bits in Flags 2 and 3 should ideally be set reflecting current | |
| availability, rather than general support. In other words, if no Blorb (or | |
| other) resources for this story file have been found, or if the Blorb file | |
| contains no graphics or no sound, the corresponding bits should be cleared. | |
| Also, it is recommended that interpreters that would prompt for an auxiliary | |
| Blorb file should do so immediately on start up if any of the "game wants to | |
| use sound/music/graphics" bits are set; this allows the bits to be cleared if | |
| no file is forthcoming, before the game starts execution. The game can then | |
| take appropriate action. | |
| Bit 4 of Flags 1 indicates the availability of the fixed-pitch style, not | |
| Font 4. | |
| The fixed-pitch header bit | |
| -------------------------- | |
| Use of the fixed-pitch bit in the header is deprecated in Version 5 and | |
| later - it is an irregularity in the Z-machine that complicates the | |
| implementation of buffering and text style handling in the interpreter, and | |
| may even slow down all memory stores. | |
| Font 4 (or Fixed Pitch style) should be used instead. Infocom did not use the | |
| fixed-pitch bit after Version 4, and it is not implemented in at least some | |
| of their later interpreters. | |
| However, the fixed-pitch bit is modified by the "font" statement in | |
| Inform 6, so is used by many current Inform generated files. Therefore | |
| interpreter authors must support it in Version 5. Support in Version 6 is not | |
| required. | |
| Operand evaluation | |
| ------------------ | |
| Opcode operands are always evaluated from first to last - this order is | |
| important when the stack pointer appears as an argument. Thus | |
| "@sub sp sp" subtracts the second-from-top stack item from the topmost | |
| stack item. | |
| Indirect variable references | |
| ---------------------------- | |
| In the seven opcodes that take indirect variable references (inc, dec, | |
| inc_chk, dec_chk, load, store, pull), an indirect reference to the stack | |
| pointer does not push or pull the top item of the stack - it is read | |
| or written in place. | |
| @je | |
| --- | |
| je can take between 2 and 4 operands. je with just 1 operand is not | |
| permitted. | |
| @art_shift and @log_shift | |
| ------------------------- | |
| The "places" operand must be in the range -15 to +15, otherwise behaviour | |
| is undefined. (This is because most interpreters will be implementing the | |
| opcodes using C's << and >> operators, and this is the range of ISO C | |
| standard-defined behaviour for shifts of a 16-bit type). | |
| @jump | |
| ----- | |
| The destination of the jump opcode is | |
| Address after instruction + Offset - 2 | |
| This is analogous to the calculation for branch offsets. | |
| @read | |
| ----- | |
| Read must return 13 when terminated by the user pressing "enter". See | |
| section 3. | |
| @scan_table | |
| ----------- | |
| The dictionary of opcodes currently states that bit 8 of form indicates | |
| words - this should be bit 7. | |
| @tokenise | |
| --------- | |
| The dictionary and flag operands of tokenise are optional. | |
| Output streams | |
| -------------- | |
| Section 7.1.2 is incorrect - output streams 3 and 4 are present only in | |
| Version 5 and later. | |
| Version 6 windows | |
| ----------------- | |
| Interpreter authors are advised that all 8 windows in Version 6 must be | |
| treated identically. The only ways in which they are distinguished are: | |
| * Different default positions + sizes | |
| * Different default attributes | |
| * @split_window manipulates windows 0 and 1 specifically | |
| * Window 1 is the default mouse window | |
| Differences in interpreter behaviour must only arise from differences in | |
| window attributes and properties. | |
| @set_text_style | |
| --------------- | |
| It was previously unclear in the Standard whether instructions like | |
| @set_text_style 5; ! Reverse+Italic | |
| were legal. None of Infocom's game files make use of such forms, and many | |
| interpreters will not handle them correctly. Such instructions should be | |
| avoided; instead you can use multiple @set_text_style opcodes specifying each | |
| style in turn, with the most important last, thus: | |
| @set_text_style 4; ! Italic | |
| @set_text_style 1; ! Reverse - overrides if combination not available | |
| However, Standard 1.1 does now require such combinations in a single opcode | |
| to be supported, as they are in some of Infocom's later interpreters - see | |
| below. But unless a game absolutely requires Standard 1.1 anyway (eg for true | |
| colour support), it is probably best to request only one style per opcode for | |
| backwards compatibility. | |
| @set_font | |
| --------- | |
| Font 2 (the picture font) is undefined. No Standard interpreter will | |
| implement it, and set_font 2 will always return 0. Any new fonts will have | |
| numbers higher than 4. Fonts 5-1023 are reserved for future Standards to | |
| specify. Local use may be made of higher font numbers. | |
| @get_prop_len | |
| ------------- | |
| @get_prop_len 0 must return 0. This is required by some Infocom games and | |
| files generated by old versions of Inform. | |
| @set_cursor | |
| ----------- | |
| S8.7.2.3 states that it is illegal to move the cursor outside the current | |
| size of the upper window. S8.8.3.5 gives the equivalent rule for Version 6. | |
| Many modern games have been lax in obeying this rule; in particular some | |
| of the standard Inform menu libraries have violated it. Infocom's Sherlock | |
| also miscalculated the size of the upper window to use for box quotes. | |
| It is recommended that if the cursor is moved below the split position in | |
| V4/V5, interpreters should execute an implicit "split_window" to contain the | |
| requested cursor position, if possible. Diagnostics should be produced, but | |
| should be suppressable. | |
| In V6, it is legal to position the cursor up against the right or bottom of a | |
| window - eg at (1,1) in a zero-sized window or at (641,401) in 640x400 | |
| window. Indeed, this is the default state of windows 1 to 7, and the cursor | |
| may be left at the right-hand side of a window when wrapping is off. | |
| Attempting to print text (including new-lines) when the cursor is fewer than | |
| font_height units from the bottom of the window results in undefined | |
| behaviour - this precludes any printing in windows less than font_height | |
| units high. | |
| @split_window | |
| ------------- | |
| In Version 6, the Standard states that the cursor remains in the same | |
| absolute position. This is an extension to the Z-machine, as this rule is not | |
| followed by Infocom's own interpreters, which keep the same window-relative | |
| position. The Standard behaviour more closely mimics Version 5's | |
| split_window. | |
| The opcode dictionary incorrectly states that "the width and x-coordinates of | |
| windows 0 and 1 are not altered." The correct behaviour is detailed in | |
| S8.8.4.1. | |
| @output_stream | |
| -------------- | |
| Interpreter authors are reminded that "nested" uses of @output_stream 3 | |
| have been required since Standard 1.0; see S7.1.2.1.1. | |
| @read_mouse | |
| ----------- | |
| @read_mouse is realtime. When called it must read the current mouse | |
| location, whether or not the mouse is inside the current mouse window. Most | |
| modern interpreters get this wrong, but Infocom's interpreters behave this | |
| way. Interpreters are allowed to show positions and button states outside the | |
| Z-machine screen if the pointer is outside the interpreter's own user | |
| interface (using negative values if needed). | |
| Programs must be prepared to cope with this. For example in a painting | |
| program you might want to ignore all buttons down outside the screen. When | |
| dragging something you might want to keep trying to follow the pointer, even | |
| outside the screen, until the buttons are released. | |
| Interpreters may constrain the pointer to the screen as long as buttons are | |
| held down - this might aid dragging operations - although this is not | |
| required. | |
| Previous revisions of the Standard stated that mouse buttons were numbered in | |
| the following fashion: "low bits on the right of the mouse, rising as one | |
| looks left". This is a rather non-portable implementation and should be | |
| abandoned in modern interpreters in favour of the "primary" button being the | |
| lowest bit, the "secondary" (if present) being the next lowest bit, and so | |
| on, up to a potential 16 buttons. The ordering of buttons should be that | |
| which is most natural for the host system. Here are some suggested | |
| assignments: | |
| Button assignments | |
| Platform Bit 0 (low) Bit 1 Bit 2 | |
| ---------------------------------------- | |
| RISC OS Select Adjust Menu | |
| MacOS Primary/only Secondary Tertiary ... | |
| Windows Left Right Middle | |
| X Left Right Middle | |
| There is no way for a story file to ascertain how many buttons are available | |
| to the user, so it is recommended that vital functions are not accessible | |
| only via secondary mouse buttons. Some of a platform's buttons may be | |
| reserved for the interpreter's use and not visible to the story file, in | |
| which case the remaining buttons must be packed down to the lowest bits. | |
| Mouse clicks | |
| ------------ | |
| In Version 5, mouse clicks are always represented with an input ZSCII code of | |
| 254. | |
| In Version 6, a single click, or the first click of a double-click, is passed | |
| in as 254. The second click of a double-click is passed in as 253. | |
| Mouse co-ordinates | |
| ------------------ | |
| Mouse co-ordinates, whether returned by the @read_mouse opcode or written | |
| into the header during input, are always relative to the top of the display | |
| at (1,1), regardless of the position of the current mouse window. | |
| @picture_data | |
| ------------- | |
| @picture_data 0 branches if any pictures are available. | |
| @sound_effect | |
| ------------- | |
| To clarify: | |
| @sound_effect number 3/4 | |
| will stop (and optionally unload) sound "number" if it is currently playing | |
| (or loaded). Otherwise it is ignored. | |
| @sound_effect 0 3/4 | |
| will stop (and unload) all sounds - music and effects. | |
| The "repeats" parameter in Version 5 indicates the total number of times to | |
| play the sound, not the number of times to repeat it after the first play. | |
| Setting repeats to zero in V5 is illegal - it is suggested that interpreters | |
| treat this as a request to play the sound once, and maybe issue a warning. | |
| Callback routines are only called when the sound has played the requested | |
| number of times. If manually stopped or interrupted by another sound, the | |
| routine is not called. | |
| The Blorb specification effectively revised Standard 1.0, as follows: | |
| "Sound" is split into two classes - "music" (eg Blorb SONG and MOD) and | |
| "effects" (eg Infocom .SND or Blorb AIFF). | |
| The "sound requested" header bit is left set if the interpreter supports | |
| either effects or music. It is only cleared if the interpreter can provide | |
| neither effects nor music. | |
| Music and effects are treated as two separate channels. Playing a new effect | |
| interrupts the current effect, but not the music, and vice versa. Whether | |
| loading a new sound (with @sound_effect n 1) stops the current one is | |
| implementation defined. | |
| Volume guidelines | |
| ----------------- | |
| [ This would better live in the Blorb specification, but is partly | |
| Z-machine specific. ] | |
| When using Blorb resources, the default interpreter behaviour (unless over- | |
| ridden by the player) should be for samples played at maximum volume (64), in | |
| one channel of a SONG or MOD played at volume 8, to be of equal volume to | |
| samples played at maximum volume (8) as an effect. This will be the natural | |
| behaviour if effects use one physical channel and MODs/SONGs use four | |
| physical channels. | |
| Ideally, a sound played at volume <n> in a SONG played at volume <m> should | |
| sound the same as when played as an effect at volume <n*m/64>. This mandates | |
| that the volume scale for effects be equivalent to the scale defined for | |
| samples in the MOD specification. | |
| If multi-channel effects are used, the overall volume should be independent | |
| of the number of channels used in the sound. Thus a stereo AIFF containing | |
| the same samples for left and right should sound as loud as a mono AIFF | |
| containing the same data. This will need adjustment of volume if stereo AIFFs | |
| use two physical channels and mono AIFFs use one. No adjustment would be | |
| required if an interpreter reduced all AIFFs to mono. | |
| Colour numbers | |
| -------------- | |
| The presence of the "under the cursor" colour option, and in Standard 1.1 | |
| the set_true_colour opcode (see below), raises the possibility of | |
| non-standard colour numbers appearing in window property 11. In addition, an | |
| interpreter may offer non-standard default colours, which need to appear in | |
| the story file header. We now give more detailed implementation guidelines. | |
| If a true colour, or an "under the cursor" colour, has been requested by the | |
| game, then the foreground or background colour shown in window property 11 is | |
| implementation defined, except that: | |
| 1) If the colour selected was one of the standard set (2-15), then | |
| that colour is indicated in property 11. | |
| 2) If the colour selected was not one of the standard set, the colour | |
| shown in property 11 will be >= 16. | |
| It is legal for interpreters to always show the same value in property 11 if | |
| a true or sampled colour is in use. As a result, story files cannot assume | |
| that setting a value that was read from property 11 will give the same | |
| colour, if @set_true_colour or @set_colour -1 has been used in that window. | |
| The same rules apply if an interpreter offers non-standard default colours | |
| (which need to be shown in the header) although in this case it would be | |
| ill-advised to show the same colour numbers for foreground and background - | |
| unless they can be distinguished, non-standard default colours should | |
| probably not be offered. | |
| If the interpreter offers a limited palette, then there is no problem, as it | |
| can be arranged for there to be fewer than 240 distinct non-standard colours. | |
| In an interpreter with a higher colour-depth, a good implementation would be | |
| to use colours 16-255 to represent the last 240 distinct non-standard colours | |
| used, re-using numbers after 240 colours have been used. This will minimize | |
| potential problems caused by non-standard colours, particularly when set as | |
| defaults. | |
| Regardless of the limitations on colour numbers, in Version 6 each window | |
| must remember accurately the colour pair selected, so it is preserved across | |
| window switches. | |
| Status line redraw | |
| ------------------ | |
| The bit in the header described as "requesting status line redraw" would | |
| better be described as "requesting screen redraw". This may be set by | |
| modern interpreters after, for example, resizing the "screen"; games should | |
| ideally redraw the screen if they see this bit set. This will usually mean | |
| the game clears the screen contents and rearranges borders, etc, so the bit | |
| should not be set except when necessary. | |
| Behaviour after loading | |
| ----------------------- | |
| Given the existence of Quetzal, a portable saved file format, it is quite | |
| possible that after loading, the game may be running on a different | |
| interpreter to that on which the game started. As a result, it is strongly | |
| advisable to recheck any interpreter capabilities (eg Standard version, | |
| unicode support, etc) after loading. | |
| ADDITIONS | |
| ========= | |
| Blorb | |
| ----- | |
| Blorb is the standard resource format for the Z-machine. Games should be | |
| distributed as | |
| a) a single story file; | |
| b) a story file with accompanying Blorb file; | |
| or c) a stand-alone executable Blorb file. | |
| To minimise user confusion, Standard 1.1 interpreters should be able to run | |
| Z-code executables contained in either a plain story file, or embedded in a | |
| stand-alone Blorb 1.1 file. If the interpreter supports sound or graphics, it | |
| should be able to obtain those resources from either a stand-alone or | |
| separate Blorb 1.1 file (although the Standard does not preclude other | |
| formats). | |
| Embedded interpreters, or interpreters running on small platforms, may accept | |
| either Z-code or resources in some custom format, but these should come with | |
| some form of conversion utility. In the minimum case of a text-only | |
| interpreter, this might take the form of a Blorb to story file converter. | |
| Quetzal | |
| ------- | |
| Quetzal is the standard saved game format for the Z-machine. Standard 1.1 | |
| interpreters are recommended to be able to load Quetzal 1.4 files, and | |
| to save games in Quetzal 1.4 format by default. | |
| Header Extension | |
| ---------------- | |
| If the interpreter claims Standard 1.1 compliance then it supports the | |
| following extra words in the header extension table. If the header extension | |
| table is present, and the extra words are present, then a Standard 1.1 | |
| interpreter will examine and update them. | |
| If the interpreter is not Standard 1.1, then the extra words will be ignored. | |
| Guidelines on behaviour in this case are supplied in the descriptions below. | |
| Note that the header extension table itself is a Version 5 feature, so the | |
| extra information here is not available in earlier Versions, despite the | |
| fact that some fields could be applicable. | |
| The new flags are placed in a new word, rather than in Flags 2, to minimize | |
| potential compatibility problems. To prevent future compatibility problems, | |
| all reserved bits in the Flags 3 word MUST be cleared by the interpreter. | |
| Word V Dyn Int Rst Contents | |
| ---- --- --- --- --- -------------------------------- | |
| 4 5 Flags 3: | |
| 6 * * 0: If set, game wants to use transparency | |
| (For all bits, Int clears again if it cannot provide | |
| the requested effect). | |
| 5 5 * * True default foreground colour | |
| 6 5 * * True default background colour | |
| 0: If set, game wants to use transparency | |
| In Version 6 colour 15 is defined as transparent. If an | |
| interpreter cannot provide transparency then it must clear | |
| this bit. | |
| Transparency is a new feature in Standard 1.1. Older interpreters | |
| will not support this. | |
| All other bits in the flags word must be cleared by the interpreter. | |
| @save and @restore | |
| ------------------ | |
| EXT:0 0 5/* save table bytes name prompt -> (result) | |
| EXT:1 1 5/* restore table bytes name prompt -> (result) | |
| As of Standard 1.1 an additional optional parameter, prompt, is allowed on | |
| Version 5 extended save/restore. This allows a game author to tell the | |
| interpreter whether it should ask for confirmation of the provided file name | |
| (prompt=1), or just silently save/restore using the provided filename | |
| (prompt=0). | |
| If the parameter is not provided, whether to prompt or not is a matter for | |
| the interpreter - this might be globally user-configurable. Infocom's | |
| interpreters do prompt for filenames, many modern ones do not. | |
| @buffer_screen | |
| -------------- | |
| New opcode in Standard 1.1, for Version 6 | |
| EXT:29 1D 6/* buffer_screen mode -> (result) | |
| Interpreters may use a backing store to store the Z-machine screen state, | |
| rather than plotting directly to the screen. This would normally be the case | |
| in a windowed operating system environment. If a backing store is in use, | |
| display changes executed by the Z-machine may not be immediately made visible | |
| to the user. Standard 1.1 adds the new opcode @buffer_screen to Version 6 to | |
| control screen updates. An interpreter is free to ignore the opcode if it | |
| doesn't fit its display model (in which case it must act as if buffer_screen | |
| is always set to 0). | |
| When buffer_screen is set to 0 (the default), all display changes are | |
| expected to become visible to the user either immediately, or within a short | |
| period of time, at the interpreter's discretion. At a minimum, all updates | |
| become visible before waiting for input. Any intermediate display states | |
| between input requests may not be seen; for example when printing a large | |
| amount of new text into a scrolling window, all the intermediate scroll | |
| positions may or may not be shown. | |
| When buffer_screen is set to 1, the interpreter need not change the visible | |
| display at all. Any display changes can be done purely in the backing store. | |
| A program may set buffer_screen to 1 before carrying out a complex layered | |
| graphical composition, to indicate that the intermediate states are not worth | |
| showing. When buffer_mode is set back to 0, the display is not necessarily | |
| updated immediately - if this is required, buffer_mode -1 must be issued as | |
| well. It would be extremely ill-advised to prompt for input with | |
| @buffer_screen set to 1. | |
| With buffer_screen in either state, an update of the visible display can be | |
| forced immediately by issuing @buffer_screen -1, without altering the current | |
| buffering state. Note that @buffer_screen -1 does NOT flush the text buffer. | |
| @buffer_screen returns the old buffer_screen state. | |
| @set_text_style | |
| --------------- | |
| As of Standard 1.1, it is legal to request style combinations in a | |
| single @set_text_style opcode by adding the values (which are powers of two) | |
| together. If the parameter is non-zero, then all the styles given are | |
| activated. If the parameter is zero, then all styles are deactivated. | |
| If the interpreter is unable to provide the requested style combination, it | |
| shall give precedence first to the styles requested in the most recent call | |
| to @set_text_style, and within that to the highest bit, making the priority | |
| Fixed, Italic, Bold, Reverse. | |
| Although a story file can determine which individual styles are available by | |
| inspecting the header, there is no indication of which styles can be | |
| combined. To improve this situation, at least for Version 6, Standard 1.1 | |
| requires window property 10 to show the actual style combination currently in | |
| use; with this a story file can probe for the availability of particular | |
| combinations. Pre-existing interpreters may or may not already do this | |
| correctly. | |
| @set_font | |
| --------- | |
| EXT:4 4 6/- set_font font window -> (result) | |
| In Version 6, set_font has an optional window parameter, as for set_colour. | |
| This was part of the original Infocom design, but omitted by earlier | |
| Standards. It is reinstated here, as it is useful to be able to measure | |
| a font that is about to be used in another window, so that window can be | |
| sized before attempting to place the cursor in it. A window number of -3 | |
| signifies "the currently selected window" | |
| @set_colour | |
| ----------- | |
| In Version 6 only, colour 15 is defined as transparent. This is only valid | |
| as a background colour; an attempt to select it for the foreground should | |
| produce a diagnostic. Interpreters not supporting transparency shall ignore | |
| any attempt to select colour 15. | |
| If the current background colour is transparent, then printed text is | |
| superimposed on the current window contents, without filling the background | |
| behind the text. @erase_window, @erase_line and @erase_picture become null | |
| operations. | |
| The intent is to make it possible to superimpose text on non-uniform images. | |
| Up until now, only uniform images could be satisfactorily written on | |
| by sampling the background colour - that in itself would be problematical if | |
| the interpreter used dithering. | |
| Scrolling with the background set to transparent is not permitted, so | |
| transparent should only be requested in a non-scrolling window. It is not | |
| valid to use Reverse Video style with the background set to transparent. | |
| Instructions that prompt for user input, such as @read and @save, should be | |
| avoided when the background is set to transparent, as it will not generally | |
| be possible for text entry to take place satisfactorily in the absence of | |
| a defined background colour. | |
| Printing text multiple times on top itself with the background set to | |
| transparent should be avoided, as the interpreter may use anti-aliasing, | |
| resulting in the text getting progressively heavier. | |
| Standard 1.1 interpreters must provide the following basic colour set, | |
| regardless of machine type, in both Version 5 and Version 6: | |
| -1 = sample (true -3) [V6 only] | |
| 0 = current (true -2) | |
| 1 = default (true -1) | |
| 2 = black (true $0000, $$0000000000000000) | |
| 3 = red (true $001D, $$0000000000011101) | |
| 4 = green (true $0340, $$0000001101000000) | |
| 5 = yellow (true $03BD, $$0000001110111101) | |
| 6 = blue (true $59A0, $$0101100110100000) | |
| 7 = magenta (true $7C1F, $$0111110000011111) | |
| 8 = cyan (true $77A0, $$0111011110100000) | |
| 9 = white (true $7FFF, $$0111111111111111) | |
| 10 = light grey (true $5AD6, $$0101101011010110) | |
| 11 = medium grey (true $4631, $$0100011000110001) | |
| 12 = dark grey (true $2D6B, $$0010110101101011) | |
| 13 reserved | |
| 14 reserved | |
| 15 = transparent (true -4) [V6 only] | |
| This is the original Amiga Version 6 colour set. The colours have been gamma | |
| adjusted from the original 8-bit values used on the Amiga, on the assumption | |
| that the Amiga's system gamma is 1/1.8, using the following formula: | |
| Z component = 31 * [(Amiga component / 15) ^ (1.8/2.2)] | |
| The equivalences between the colour numbers and true colours are recommended. | |
| The interpreter may allow the user to change the mapping, but the given | |
| values should be the default. If necessary, the game can check what true | |
| colour is being used for a given colour number using window properties 17 and | |
| 18. | |
| Interpreters may provide different colours (eg making colour 10 dark grey), | |
| but if and only if they can detect they are running an original Infocom story | |
| file. | |
| Standard 1.1 interpreters should support multiple text colours on-screen | |
| simultaneously, and not implement the Amiga-style behaviour described in | |
| Standard 1.0 (changing all text already on screen to the current colour). If | |
| the multiple-colour model is in use, the interpreter number header byte should | |
| not be set to "Amiga" (4), except by explicit user action, as this has | |
| historically been examined to determine the colour model in use. | |
| When running story files in which the Flags 3 word is present, the multiple- | |
| colour model must be used. | |
| @set_true_colour | |
| ---------------- | |
| New opcode in Standard 1.1, for Version 5 or later, if Flags 1 bit 0 is set. | |
| EXT:13 D 5/* @set_true_colour foreground background | |
| 6/* @set_true_colour foreground background window | |
| fg and bg are 15-bit colour values - bit 15 = 0 | |
| bits 14-10 blue | |
| bits 9-5 green | |
| bits 4-0 red | |
| Magic values in the opcode are: (-1) = default setting | |
| (-2) = current setting | |
| (-3) = colour under cursor (V6 only) | |
| (-4) = transparent (V6 only) | |
| The interpreter selects the closest approximations available to | |
| the requested colours. In V6, the interpreter may store the approximations | |
| in window properties 16 and 17, so the program can tell how close it got | |
| (although it is acceptable for the interpreter to just store the requested | |
| value). | |
| In the minimal implementation, interpreters just need to match to the closest | |
| of the standard colours and internally call @set_colour (although that would | |
| have to ensure window properties 16 and 17 were updated). In a full | |
| implementation this would be turned around and @set_colour would internally | |
| call @set_true_colour. | |
| The default true colours are stored in the header extension table. | |
| The optional window parameter is only allowed in V6, and operates the same as | |
| in @set_colour. | |
| True colour specifications are in the sRGB colour space, $0000 being black | |
| and $7FFF being white. Colours should be gamma adjusted if necessary. See the | |
| PNG specification for a good introduction to colour spaces and gamma | |
| correction. | |
| @get_wind_prop | |
| -------------- | |
| With the addition of true colours, two new Version 6 window properties are | |
| defined. | |
| The two new window properties are: | |
| 16: true foreground colour | |
| 17: true background colour | |
| These are not writable with @put_wind_prop. | |
| The true foreground and background colours show the actual colour being | |
| used for the foreground and background, whether it was set using @set_colour | |
| or @set_true_colour. Transparent is indicated as -4. If the colour was | |
| sampled from a picture then the value shown may be a 15-bit rounding of a | |
| more precise colour, leading to a slight inaccuracy if the colour is read | |
| and then written back. | |
| New opcode summary: | |
| ------------------- | |
| St Br Opcode Hex V Inform name and syntax | |
| * EXT:0 0 5/* save table bytes name prompt -> (result) | |
| * EXT:1 1 5/* restore table bytes name prompt -> (result) | |
| * EXT:4 4 6/- set_font font window -> (result) | |
| EXT:13 D 5/* set_true_colour foreground background | |
| 6/* set_true_colour foreground background window | |
| * EXT:29 1D 6/* buffer_screen mode -> (result) | |
| set_true_colour is not a good candidate for taking a 2OP encoding like | |
| set_colour, as it will have a low usage frequency, and it will rarely take | |
| small constants. | |
Xet Storage Details
- Size:
- 34.7 kB
- Xet hash:
- d532bbe1290913cb327e43e8bc867318584b81eee32402f4448d551d0aee8e83
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.