The routine creates the reverse-colour bar by printing spaces, and old versions printed one fewer space than the character width of the screen.
The relevant code from the 6/1 library:
@split_window 1; @set_window 1; @set_cursor 1 1; style reverse;
width = 0->33; posa = width-26; posb = width-13;
spaces (width-1);
The code from the current library:
width = ScreenWidth();
posa = width-26; posb = width-13;
spaces width;
(the ScreenWidth() routine just pulls the screen width in columns from the header and returns it.)
Mm, yes, that makes sense. Sorry for the misreading.
To make up for it, Iāll look through the I6 library updates⦠the change to āspaces widthā was in the 6/4 lib release.
From the Standard:
8.1.4
The specification of the "picture font" is unknown
(conjecturally, it was intended to provide pictures before
Version 6 was properly developed). Interpreters should not
implement it, and should refuse permission to any game
requesting it.
From Infocomās xzip spec:
3.10.2 Interaction of Pictures and Fonts
The āpicture libraryā is a selection of images which are
referenceable using small integers as an index. In this way, a
picture library is very much like a font. In a font, the images
are characters, and in a picture library they are pictures.
Consequently, font 2 is defined to be the picture library. If
FONT 2 is executed, subsequent character output to the screen is
displayed from the picture library. If there is no picture
library, then FONT 2 is a no-op.
*Note: Do pictures need a way of saying that the horizontal and
vertical position shouldnāt change when they are displayed?
I donāt think we can reasonably add font 2 to the Standard proper, but given that we now know how it is supposed to work, I think rewording this section significantly is worthwhile.
I would propose something like
8.1.4
The specification of the "picture font" was unknown when
this Standard was written, and it is therefore not a formal part
of the Standard. See the remarks for more information.
with a brief description of how the font works in the remarks.
The Remarks in Section 9 (Sound effects) says:
A further difficulty with 'TLH' is that it assumes the interpreter
is as slow as Infocom's Amiga interpreter was: it fires off
several sound effects in one game round, assuming there will be
time for it to play most of each one. To simulate this,
sound_effect must be rewritten to pause sometimes:
if a new sound effect is begun while there is still one playing
which was started since the last keyboard input, then wait until
that earlier one finishes one cycle before replacing it with the
new sound effect.
Itās not entirely clear whether this should be for Lurking Horror alone, or all games. As itās not part of the main Standard text, I assume itās just a hack to fix Lurking Horror, and that interpreters should not apply it outside of that context.
If this is generally agreed, a slight edit should be made to the text to make it completely clear.
I think there is no harm in suggesting it applies to all V3 games with soundā¦which as far as I am aware is a set consisting of only one game: TLH. I hate making game specific hacks.
Edit: Actually the remark isnāt specific enough to make TLH work properly either. In exactly two places in the game TLH will fire off a sound followed almost immediately by a second sound. Equally important is that in both instances the second sound is followed almost immediately by a third sound_effect action. In the first instance it is a āstopā targeting the second sound, while in the second instance it is a āstop allā command. Queuing the sounds is insufficient if one doesnāt also delay or alter the action of the subsequent stop/stop all.
What I do is (in V3 only) allow a single extra sound to be queued (no more than this is needed to make TLH work), and the act of queueing changes the play count of the first sound to ā1ā, to break any looping and stops the sound if it has already completed at least one cycle. A subsequent stop command does the same for any targeted sound while a āstop allā applies to both the current and any queued sound equally. This queuing is obviously only done when multiple sound_effect commands are encountered between keyboard reads. If a third sound were attempted (never needed for TLH) and the other two sounds were still playing/queued, then I would ignore it and any further attempts to play more sounds until either the current one had finished, or a keyboard read had occurred.
Itās a set consisting of only one game so far. Thereās definitely no indication in the Standard as currently written that this applies to v3 as a whole but no other versions.
I understand the distaste for making game specific hacks, but I think thatās why itās in the remarks. It is perfectly valid for a Standard interpreter to just not do any of this, in which case The Lurking Horror wonāt work properly (this is currently my approach). At the end of the day, it is just a hack in the Standard to get around a poor design decision in The Lurking Horror.
Anyway, I donāt think v3 should work significantly different from later versions in this regard. Thatās just seems unnecessarily confusing. Which would mean: either a hack for one game, or a hack for all versions.
Youāre probably right. Iāll likely just remove the version check and let it apply to all games.
I do think implementing the standard should be enough to at the very least make Infocomās games run properly, but I realize this is a small detail that many may not care about. As TLH is one of my favorite games, it matters to me.
Another issue with an Infocom game that I havenāt yet solved without a game specific hack is Bureaucracyās delay routine. Any interpreter on even close to modern hardware is so fast as to make the delay nonexistent. Itās too bad Infocom didnāt think to make a delay opcode.
Note for any future V9: Add a time delay opcode.
Iām in favor of this being a TLH-only thing. I think itās reasonable to consider it a ābugā in TLH, but with a workaround available for interpreters to implement if they so desire.
The most useful new opcode proposal Iāve ever seen!
This sounds like something that could be done with read_charās timed input.
Speaking of read_char, the definition includes the sentence
time and routine are optional (in Versions 4 and later only)
and dealt with as in read above.
As read_char is a v4+ opcode, the ā(in Versions 4 and later only)ā note here is redundant.
And speaking of āmaking Infocomās games work as they did at the timeā, I think itād be handy to add notes about problems like this to the Standard, possibly in the Remarks (although itās difficult to know which section to place them in).
Sort of. Timed input mimicking a delay opcode would be a hassle. Player input can always shortcut the wait by ending the operation. Sometimes thatās what you want, but sometimes it isnāt. Preventing it would take a lot of messing about with timeout routines and storing the elapsed time in memory somewhere. Detaching the time delay from input altogether makes it much simpler.
I agree. Off the top of my head besides Bureaucracy and TLH, thereās the non-standard read terminator characters used in Beyond Zork (which should be considered standard IMHO), and Cutthroatsā 99:99 clock thing. Also, maybe some mention of Border Zone using read within the interrupt of a timed read?
Thatās good, though. Any time you put a delay in a game, someoneās going to want to click through it.
The timed read opcode has been used this way before (even ignoring Freefall) and it works fine.
ā¦it works ok. For animation, a tenth of a second resolution isnāt particularly good though - bare minimum really. Since this is for a hypothetical V9 which isnāt likely to happen anyway - instead of a brand new opcode, perhaps changing the first argument for read_char from 1 to 2 changes the meaning of the timeout value from 0.1 seconds to milliseconds. This would allow up to a 65 second delay with millisecond resolution.
If we wanted to make a way to alter the period of timed input, that doesnāt need a new z-machine version (v9), just a new standard (1.2).
2Ā¢: the only new features Iād seriously advocate for are the proposed @gestalt opcode and a suggestion I havenāt seen before: make it legal for @loadw/@loadb (GET/GETB) to read memory beyond the 64k watershed when the base address + array index would exceed 65535 (e.g., base address 65534 + array index 1000). This is currently illegal per §1.1.2-3 and the opcode definitions, but allowing it would significantly alleviate the 64k static-memory limitation by allowing the story file to store up to 128k of additional static byte-addressable data beyond the 64k watershed. At present, the only way to do this is by writing routines in high memory that manually store data byte-by-byte into a low-memory buffer (slow and wasteful - the most compact way to do this wastes 2-3 bytes per word of data), or to do evil hackery like encoding base-16 data into a zstring, printing it to stream 3, and then converting it back to binary data.
The Infocom ZIP documentation does not actually specify what GET/GETB should do in this case except to generally advise that ātables must all fall within the low 64K of the gameās locations, as tables are always referenced by a direct byte number.ā Presumably passing an index outside this range was undefined behavior. The behavior in modern interpreters is mixed: Filfre, Fweep, and ZMPP allow it, while Parchment, Frotz, Bocfel, and ZIP all silently wrap around and begin reading the start of low memory again (treating the summed address as a 16-bit value, presumably also what Infocomās interpreters did).
In any case, Iām not aware of any games that would break if this behavior were changed, though likewise, any future game that relied on it would have to assume patchy interpreter support.
The definition for sound_effect in 1.0 makes reference to
@sound_effect 0 3/4
will stop (and unload) all sounds - music and effects.
but the 1.0 Standard doesnāt specify a difference between music and effects (or samples) anywhere. (An artefact of copy/pasting clarifications from the 1.1 document when I was originally updating the 1.0 Standard).
Iām going to change this to just
@sound_effect 0 3/4
will stop (and unload) any sound currently playing.
for the 1.0 spec.
I find it interesting that the standard adopted this to mean stop/unload all because that isnāt at all what Infocomās interpreters treated it as. I find it even more so that stop needed a sound number argument at all, since only one sound at a time was ever played. Itās almost as if Infocom planned for multiple simultaneous sounds from the beginning.