Deepening the status line troubles

I’m working on a project with a default status line of 3 lines depth ala Emily Short’s Basic Screen Effects. These lines are used show a lot of player stats. Its contents are also configurable, so if you remove enough elements from display, it shrinks to 2 or 1 lines, or grows back to 3.

Over time and testing, I’m starting to realise a few problems. The first one is that the line flickers significantly every turn, especially on slower interpreters. This is both distracting and, given the critical nature of the info in the status line, too annoying for the player. I’m guessing this happens because by default, Inform makes the status line 1 at the start of each turn, then the ‘rules for constructing the status line’ kick in again and they inflate it to 3 lines anew. So it’s like a really fast venetian blind roll up and down every turn.

I’ve got a side-effect in this particular game - I’ve got extra windows spawned by Flexible windows. Their contents are created at the moment the status line is 1, then when it jumps back up to full size (3), those windows get pushed down the screen. Their bottoms disappear from sight, presumably because all the calculations about them were made when the status line was only at a depth of 1.

I’ve got a feeling the flexible windows problem would be harder to solve than the jumpy status line problem. I wondered if there’s an easy i6 replacement I could add that would simply set the visible status window at a depth of 3 permanently. I’d lose the coolness of the fact the status line is resizing itself to suit what info you ask it to display, but it would seem to solve all the other problems.

I’m sort of making educated guesses about the nature of the problem. I’ve also got Mark Tilford’s automap extension running but it does its business in a portion of the status window that’s out of view (line 4) (I don’t actually display the map in the status window… I funnel the data to one of the flexible windows) and that works fine, so I don’t think it’s affecting what’s going on.

Thanks for any help.

  • Wade

I dimly recall that there have been various bugs related to this, but I thought that they had been squashed. Looking back through old emails I can find discussion about something similar in 2008, but that appears to have been fixed: I7 should keep track of what size the status line is, and not reset it to 1.

Have you got a reasonably short example that demonstrates the problem?

That is exactly what happens.

It happens I was just looking at this last night, for one of my own projects.

Include Basic Screen Effects by Emily Short.

The Kitchen is a room. 

Rule for constructing the status line:
	deepen the status line to 3 rows.

However, the flicker is only visible on some interpreters. An interpreter can “optimize” window size changes, by holding up all redraws and resizes until the beginning of the input cycle. Quixe does this, for example. But Zoom and the Mac IDE do not. I suspect that Windows users aren’t seeing it.

(Ironically, it’s good that the Mac IDE is not optimal about this. You want potential problems to show up in development.)

I’m not going to mandate this sort of optimization, so it is a legitimate I7 bug.

However, the fix is not obvious. Should we move the VM_StatusLineHeight(1) call inside the default “constructing the status line” activity? That would break existing source code. (Any game that replaces the “constructing the status line” activity would mandatorily have to set a height. Currently, you don’t have to set that – it defaults to 1 because of the initial setting.)

You can work around the flicker problem at the I6 level by replacing the DrawStatusLine() entirely, but that isn’t for everybody.

You can work around the flicker at the I7 level by reimplementing the status line using Flexible Windows, which can also manage text-grid windows. The helper functions needed are all there, I believe (i.e., to calculate the width of the window, draw a character at any position in the window, etc.)

The issue with output being pushed off the bottom of the screen in Gargoyle doesn’t sound like a Flexible Windows problem. Assuming that you are using window-drawing rules that fully reconstruct the desired state of your windows each time they are called, the windows should be redrawn automatically (by the “arranging all rule”) to fit their new size. If you are bypassing that rule in some way, you may just need to ensure that the glulx arranging rules can reconstruct your window’s contents.

An abysmally bad design decision was made for Gargoyle: having new text buffer windows fill from the bottom up instead of the top down. (Inconsistently, Gargoyle fills text-grid windows from the top down). Is it possible that it’s just this that you’re seeing?

–Erik

Hm, is that bad? It should only make a noticeable difference if the status window resizes while the text window contains less than a page of text. And then, actually, Gargoyle’s display will be more stable – the displayed text will remain in the same physical location.

In any case it doesn’t sound like what severedhand is describing. I agree that if you’re using Flexible Windows correctly, the displayed text (in a status window) will have the correct height to match the window height. If that isn’t happening, please post a test case.

Thanks for all the ideas guys.

Hm, a test case might take awhile, if it comes to that. This is a big complicated project with Glimmr and multiple windows etc etc. The code that does all these things is everywhere. I will need to distil it down.

Erik, the windows that are being shoved downwards are

(a) a flexible window to the right of the play area containing a Glimmr graphical map, or

(b) when in textmap mode, a flexible window to the right of the play area containing an ascii map

I don’t think I’m interfering in how the graphical map is produced in any way because it’s basically ‘fire and forget’ ala your extension. I turn it on using nice commands like ‘open up the map window’, then I forget about it, at least in terms of me ever having to issue commands to update it. Then every turn, the status window momentarily shrinks to 1 line height, and the graphic automap appears over there with the grey pane at the bottom for zooming in and out buttons. Then the status window inflates to 3 and the grey pane is shoved out of sight. Also, watching the map bump up and down is annoying! This is in both Zoom and Gargoyle.

EDIT!!!@#!@#!!---- ACTUALLY, the bumping only happens in Zoom and the Mac IDE. Gargoyle doesn’t do the map bumping. I haven’t been able to test on Windows terps.

Perhaps I can send you a demo so you can see what things are happening. I’ll PM you.

  • Wade

I say it’s bad only because it looks bad and it would be a lot of fussy work from the author to get it to look good. Text in pretty much every other computer window (Word, text editors, Excel, web browsers, etc.) starts at the top of the page–most books too!. Windows with a small amount of text (inventory windows, status windows, etc.) look darned silly hunkered at the bottom of Gargoyle’s screen, with all of the white space above. Anyway, I agree that this by itself isn’t likely to be what Wade describes–but possibly it contributes…?

Anyway, this bothers me because the kind of text you typically want in subsidiary text windows is precisely small blocks like inventories, status, descriptions, etc., both because this is the best thing for player convenience (doesn’t have to deal with scrolling windows to see the content) and for player sanity (small bites of text as opposed to mountains).

–Erik

You know, I’m thinking I will have to redo the status line as a flexible window. Because I’ve got another problem.

I change the colour of the background of the status line at times with Glulx Status Window Control (and this colour change is absolutely essential). If I just do this per se, the status window suddenly shrinks to only be as wide as the left main window beneath it, and the right window (the map window) springs up to devour space all the way to the top of the screen :neutral_face:

I discovered a way to stop that happening, which is to temporarily close the map window before rebuilding the status window for the colour change, then reopening the map window. This works to preserve the status line’s width. But on Zoom, it is sluggish and causes a bigass white flash in the map area. Argh!!!

PS I actually like the way the text comes from the bottom in Gargoyle :slight_smile: … but I have noted it as another inconsistency amongst all these interpreters that remains a kind of bugbear of the project of having people’s games just work how they thought they programmed them.

PPS Erik, I edited my previous post.

  • Wade

Ah, OK, glad to hear it’s only Zoom doing the flicker thing. As Zarf said above, this is due to Zoom’s handling of window updates. Even standard menus look like crap in Zoom due to the flicker from the status line. I would tell folks to use Gargoyle until that’s fixed!

The issue you describe with the status line shrinking when you change its color is due to the order in which you’re opening windows. The status window has to be closed and reopened with the new color due to a limitation with Glulx background colors. When you close it, you remove it from the “tree”, and then when you reopen it, you insert it at a different place. This article might help if this is tough to conceptualize: gwindows.trenchcoatsoft.com/gwin3.htm

An easy fix: Open up a 1-pixel-high graphics window before opening the status window, and make that window the parent of the status line. That way, when you close the status window, you don’t mess with the rest of the window tree, and when you reopen it will be the same width as its 1-pixel parent. (There are other possible fixes as well, depending on your layout.)

–Erik

P.S. On the question of flowing text in from the bottom in Gargoyle, here’s a screenshot of Kerkerkruip with status windows. These would be a real aid to gameplay–I think I type STATUS or INVENTORY every few turns!–but they just look silly like this:

RIght thanks. Okay, I looked into this, but the problem I’m having is that the status line is not a g-window, so I don’t think it can be anyone’s parent. Everything must grow from the main-window.

I also tried spawning the pixel bar upward from the main-window before spawning the map window to the main-window’s right, but I got unexpected behaviour, according to the Flexible Windows docs. They say:

"So for example, to creating a banner between the main screen and the status, we would write

The banner-window is a g-window. The main-window spawns the banner-window. The position of the banner-window is g-placeabove."

Now I did exactly that, but the banner doesn’t appear between the main screen and status, but above the status line.

I even tried sneaking a second window spawned by the pixel window beneath the pixel window, but it appears below the pixel window and above the status window. IE - The status window is clearly built into the main-window. I can’t get inbetween it and the scrolling text atm.

I wondered if to g-windowise the status line, I could use Emily Short’s Simple Graphical Window, which was not already present in this project. But adding it (in multiple orders) immediately caused the game to fail to compile (it’s gotta be fighting with all of Glimmr, Flexible Windows, Glulx Status Window Control - though the latter two are designed to fit with it, but maybe Glimmr as well is too many complications.)

The errors look like:

  • Wade

Isn’t it just that the call to VM_StatusLineHeight() in Printing.i6t should be

VM_StatusLineHeight(statuswin_size); instead of

  VM_StatusLineHeight(1);

It can be, but currently there isn’t a hook in any of the libraries for that. Glulx Status Window Control could have offered Flexible Windows attributes, but I conceived it as being independent from Flexible Windows so I didn’t include those abilities, and in any case Flexible Windows itself should be the utility that offers full g-windowized control. Anyway, if you include this after your inclusion of Glulx Status Window Control, you should be good to go, more or less:

[code]To initialize/initialise the/-- status window with parent (win - a g-window) position (pos - g-window-position) :
(- InitGStatusWindow({win}, {pos}, ); -)

To open the/-- status window:
if the status window is already open, rule fails;
initialize the status window with parent (YourNewWindow) position (g-placeabove);

Include
(-

[ InitStatusGWindow win pos sty;
if (gg_statuswin == 0) {
statuswin_cursize = statuswin_size;
if ( (+ status window background reversed +) ) {
for (sty=0: sty<style_NUMSTYLES: sty++)
glk_stylehint_set(wintype_TextGrid, sty, stylehint_ReverseColor, 1);
}
gg_statuswin =
glk_window_open({win}.ref_num, {pos}, statuswin_cursize, wintype_TextGrid, GG_STATUSWIN_ROCK);
}
];
-)[/code]

This should override the corresponding phrases in GSWC and allow opening the status window with any parent and position you like. I haven’t tested it, but the I7 library code for status window utilities seems to be pretty robust about dealing with the window’s parent, so hopefully you wouldn’t need to alter any of the library routines. You still will need to fix Printing.i6 as DavidK mentioned to prevent the flicker, of course.

SGW and Flexible Windows aren’t compatible, and in any case SGW isn’t designed to address this problem (SGW is a much more limited attempt to do what FW is doing). What’s really needed in my opinion is a reworking of the standard library in conjunction with an expansion of FW, to provide full hooks into every conceivable part of the windowing process.

–Erik

Big thanks, Erik and David. I will sort through all the code and point-outs you’ve given me and try them out when I’ve next got the chance.

  • Wade

That can be part of it, but (a) no code is currently set up to change statuswin_size, (b) a for-constructing rule still doesn’t have the opportunity to set that phrase until after the VM_StatusLineHeight call. So you’ll still get a flicker on startup, and another every time you change the height.

It would suffice to have a before-constructing rule that contains a call to set statuswin_size. Then we’d have to deprecate “deepen the status line to…”

It’s worth noting that the Box veneer hardcodes a line height of one, though I think that’s zcode only.

Erik, Inform 7’s having trouble with this line from the code:

gg_statuswin =
glk_window_open({win}.ref_num, {pos}, statuswin_cursize, wintype_TextGrid, GG_STATUSWIN_ROCK)

It says:
bug.png

I scanned it with my eyes and lack of i6 knowledge, but couldn’t see a mismatched bracket.

  • Wade

In some good news, by changing VM_StatusLineHeight(1) to 3 in printing.i6, I made the default status line 3 and killed the flickering (when I also removed the need to deepen the status line every turn.)

But now that I have an inch, I want more. Which is to say – I would still like to be able to change the status line depth, but only when I ask it to change, without it going via a warp to a default size every turn. I haven’t been able to work this out. DavidK’s suggestion of ‘VM_StatusLineHeight(statuswin_size)’ results in a 1 line status bar.

  • Wade

What my original suggestion was meant to mean was that you would change the call in Printing.i6 to

VM_StatusLineHeight(statuswin_size);

This should stop the resetting of the status line height to 1 every turn. In addition, you would also need to make the call to deepen your status line when you want it (and not every turn).

Of course, I haven’t tested any of this: this is just from looking at the code.

Oops, shouldn’t have tried to do that from memory. This should work:

glk_window_open({win}.ref_number, GetPos({pos},{win}), statuswin_cursize, wintype_TextGrid, GG_STATUSWIN_ROCK)

–Erik

Sorry, now we’ve got more errors that I can screenshot, and copy/paste doesn’t work :slight_smile: … Starts with ‘( without matching )’ twice, then ‘expected ; but found {’ then ‘expected assignment or statement but found constant’ etc.

  • Wade