I6: clearing the screen in RestoreColours() if COLOUR is set

When processing RestoreColours() in a game that has the color flag set, the screen will be cleared. In the Library, RestoreColours() is called only twice: when processing an UNDO and when processing a SAVE. I’ve tried a sample game that changes the foreground color at will with the call to ClearScreen() commented out and not. In both cases, the foreground color was reset to the default when UNDO is typed. When ClearScreen() is disabled, the other color changes remain in place. Does anyone here know why this decision was made? Would anyone object if I remove that ClearScreen() call?

Reference: inform7.com/mantis/view.php?id=1755

The inform6 release notes file has a section describing new library routines that were added in 6/11 to abstract away zcode/glulx platform differences.

ClearScreen and SetColour are both listed. RestoreColours isn’t mentioned; it seems to be a private routine used in conjunction with SetColour to maintain the correct color settings after a restore or undo.

The description of SetColour says:

I took your UNDO AND COLOR test program, changed the @set_colour calls to SetColour() calls, removed the ClearScreen() call from RestoreColours, and compiled it for both zcode and glulx. (I did not add ClearScreen() calls after the SetColour() calls.)

On zcode, it behaves as you describe: the color changes each time the player looks into a sphere, and the screen is not cleared. After “LOOK INTO RED SPHERE / LOOK INTO GREEN SPHERE / LOOK INTO BLUE SPHERE / UNDO”, the text turns from blue back to green. (The issue on github says it turns white at this point. Typo?)

On glulx, the same commands caused the screen to be cleared after each SetColour and after the undo, even though the ClearScreen() call was commented out of RestoreColours. (*)

So, one reason to keep the call would be to make zcode and glulx games behave identically.

As for why Glulx SetColour clears the screen in the first place, maybe because an abrupt color scheme change in the middle of a screen of text was thought to look bad. (Edit: See Dannii’s post below for the real reason.)

(*) The screen didn’t actually change colors with any of the several glulx interpreters that I tried. A search here on the forums for “glulx SetColour” turns up a couple of interesting threads (1, 2) suggesting that it never worked.

Glk doesn’t allow you to change colours (or any styles) once a window has been opened. It must be closed and reopened for the changes to be applied.

One other thing:

When I did add these calls, the program behaved differently under zcode (unix frotz) and glulx (glulxe+glkterm). On zcode, the status line covered up the first line of text that was printed after ClearScreen(). On glulx, the status line did not overlap with the text after ClearScreen().

It might be the same issue as this newline at startup discrepancy.

Zcode interpreters are inconsistent about this, which is why Inform prints a handful of newlines at startup time. Just in case.

Is there any reason why this is so? I’ve been clamoring on and off about possibly updating the specs for Glulx and Glk to allow for stuff like this. I’d very much like there to be nothing the Zmachine can do that Glulx cannot.

Section 5.5.1 of the glk spec:

Speaking of glk, I notice that the library now ships with infglk.h, but the lib is still full of calls like “glk($002A, gg_mainwin);”. I wonder if it would be worth the dependency on infglk.h to include it in parserm.h and rewrite these calls in a more readable way. An added bonus would be that this inclusion would be available to games using parser.h.

More on the RestoreColours/ClearScreen issue.

Glulx authors are stuck having the screen cleared after SetColour regardless of our decision, so we can focus on zcode here.

If we remove the call to ClearScreen, an author who wants the screen cleared after restore/undo will need to do something like this:

Object RestoreUndoHook LibraryExtensions
  with ext_messages [;
           Restore: if (lm_n == 2) { ClearScreen(); print "^"; }
           Miscellany: if (lm_n == 13) { ClearScreen(); print "^"; }
       ];

If we keep the call to ClearScreen, an author who doesn’t want the screen cleared after restore/undo will need to Replace RestoreColours. For a fair comparison, we can assume that the author knows he’s defining COLOUR and isn’t compiling to v6. That gives us:

Replace RestoreColours;

Include "Parser";

[ RestoreColours;    ! L61007, L61113
    gg_statuswin_cursize = -1;    ! Force window split in StatusLineHeight()
    if (clr_on) { ! check colour has been used
        SetColour(clr_fg, clr_bg, 2); ! make sure both sets of variables are restored
        SetColour(clr_fgstatus, clr_bgstatus, 1, true);
    }
];

In the one case, the author needs to be familiar with the intricacies of LibraryMessages or ext_messages. In the other, the author needs to be aware of the private RestoreColours routine and how it interacts with SetColour and ClearScreen. I prefer the former, because it uses the library’s documented public API instead of requiring knowledge of library internals.

An author who wants consistent behavior between zcode and glulx is forced to clear the screen after SetColour. He can accomplish this by calling ClearScreen after each explicit call to SetColour for the benefit of the zcode version. (If we decide to remove the ClearScreen call, he’ll also have to use the ext_messages technique above.) These ClearScreen calls will be superfluous for glulx, but not harmful.

Another consideration is old code that’s recompiled against 6/12. If we remove the ClearScreen call, old games may see a change in behavior after restore/undo.

An open question is which screen-clearing preference is an author likely to have if he knows that both options are available. We’d want the library to support the most common preference by default and let others use one of the two techniques above to obtain the alternate behavior.

I spent some time researching the history of RestoreColours, looking for a rationale for the ClearScreen call. I wasn’t able to locate the change other than to place it between L61007, which introduced the precursor to RestoreColours, and L61113, which added the gg_statuswin_cursize assignment.

Can we get the ball rolling on examining this limitation in depth and what, if anything, can be done to alter the specs to allow for color changes of the sort that the Zmachine can do but Glulx can’t?

It does seem like a good idea. Earlier there was potential trouble with this because the state of infglk.h’s license was ambiguous. See github.com/DavidGriffith/inform6lib/issues/35. Dannii pointed out that Zarf applied a “crayon license” to glk-dev and cheapglk, that while inelegant, did satisfy the person in charge of packaging Inform6 for Debian. So that problem is now solved.

There was some very recent discussion on this topic here: [INFORM] The Reliques Of Tolti-Aph - right now we need an extension to output Glk calls?