Overfilling the status line

As part of an experiment, I wanted to see what would happen if I printed more text in a Dialog status bar than could fit—specifically on the Z-machine, where there’s a defined limit (on the Å-machine it comes down to well-documented CSS). So I compiled this program:

(style class @status)
	height: 3em;

(program entry point)
	(status bar @status) {
		alpha bravo charlie delta echo foxtrot golf hotel india juliett kilo lima mike november oscar papa quebec romeo sierra tango uniform victor whiskey xray yankee zulu alpha bravo charlie delta echo foxtrot golf hotel india juliett kilo lima mike november oscar papa quebec romeo sierra tango uniform victor whiskey xray yankee zulu alpha bravo charlie delta echo foxtrot golf hotel india juliett kilo lima mike november oscar papa quebec romeo sierra tango uniform victor whiskey xray yankee zulu
	}
	(get input $)

The result:

alpha bravo charlie delta echo foxtrot golf hotel india juliett kilo lima mike november oscar papa quebec romeo sierra tango uniform victor wh

se ryyne uuapabaocaledlaeh oto ofhtlidajletkl iamk oebrocrpp ubcrmoser ag nfr itrwikyxa akezl lh rv hri et cofxrtgl oe ni uit iolm ienvme sa a

aqee oe iratnouiomvco hse ryyne uu

I assume this cannot possibly be the intended behavior. What’s going on here? I’d expected it to simply stop when it reached the right edge of the screen, not continue and output nonsense.

test.z5 (6.4 KB)

1 Like

I assume the status line text normally fills up some sort of buffer, and it’s assumed that within that buffer there will be a terminator, but since there isn’t, the status line drawing routine is continuing to decode and output the contents of arbitrary memory? The nonsense on your second line looks similar to what you get when you treat a bunch of random bits as a Z-encoded string.

Seems weird that the contents of the status line would be stored as an encoded string though since it’s dynamically generated, so I could be way off.

Looking at the z-file, the compiler seems to store the string correct, it splits it up in two high strings, 255 characters and 239 characters.

01864 S0001 "alpha bravo charlie delta echo foxtrot golf hotel india juliett kilo lima mike november oscar papa quebec romeo sierra tango uniform victor whiskey xray yankee zulu alpha bravo charlie delta echo foxtrot golf hotel india juliett kilo lima mike november os"
01910 S0002 "car papa quebec romeo sierra tango uniform victor whiskey xray yankee zulu alpha bravo charlie delta echo foxtrot golf hotel india juliett kilo lima mike november oscar papa quebec romeo sierra tango uniform victor whiskey xray yankee zulu"

The garbled text is probaly interpreter dependent, because if I run it in Windows Frotz so is the first line printed correctly, but line two and three are empty.

My guess is that it’s something wrong in the library function that prints the statusbar (or is it a backend_z function?).

1 Like

In my interpreter, all the text is fine, so this is definitely an interpreter problem – unix frotz does the garbled thing too btw.

1 Like

Looks good in Parchment: 1P7P3kN69tYeZCX8V9UWe0JasD3.z5 - Parchment

Bocfel on the testing site only prints to 1 line: Parchment

1 Like

Oh, that doesn’t follow at all. :)

(If it’s an unterminated string, the interpreter would run off and try to decode bytes that are not meant to be string data. Surprises follow, but it would be the game file’s fault.)

I don’t think it’s an unterminated string, because that’s approximately how much text should be printed, and it’s repeating with the correct period—the decoding is just going wonky somewhere in there.

Which interpreter is it?

Unix Frotz, the ncurses version.

Have tried an aa compilation? Have you tried a similiar orogram from Inform6 in the same interpreter?

On Å-machine there’s only one reference interpreter and its behavior is straightforward: it obeys whatever CSS “overflow” property you specify. (In other words it just sticks all the text in a div and lets the browser handle the details.)

Haven’t tried with I6 yet; I’ll see if I can get the compiler for that working later.

Minimal Inform6 code

[Main;
	@split_window 3;
	@set_window 1;
	style fixed;
	style reverse;
	@erase_window 1;
	@set_cursor 1 1;
	print "alpha bravo charlie delta echo foxtrot golf hotel india juliett kilo lima mike november oscar papa quebec romeo sierra tango uniform victor whiskey xray yankee zulu alpha bravo charlie delta echo foxtrot golf hotel india juliett kilo lima mike november oscar papa quebec romeo sierra tango uniform victor whiskey xray yankee zulu alpha bravo charlie delta echo foxtrot golf hotel india juliett kilo lima mike november oscar papa quebec romeo sierra tango uniform victor whiskey xray yankee zulu";
	@set_window 0;
];

This give the exact same output as the Dialog code.

Most interpreters doesn’t wordwrap in the upper window, instead it prints as much text as fits with current width of window. Unix Frotz seems to attempt a wordwrap (as Parchment, but does something wrong and loses track when decoding the z-chars after the wrap. I would say that this is a bug in Unix Frotz.

test_inf.z5 (2 KB)

2 Likes

Word-wrap in the lower window works fine.

[Main;
	@split_window 3;
	@set_window 1;
	style fixed;
	style reverse;
	@erase_window 1;
	@set_cursor 1 1;
	print "alpha bravo charlie delta echo foxtrot golf hotel india juliett kilo lima mike november oscar papa quebec romeo sierra tango uniform victor whiskey xray yankee zulu alpha bravo charlie delta echo foxtrot golf hotel india juliett kilo lima mike november oscar papa quebec romeo sierra tango uniform victor whiskey xray yankee zulu alpha bravo charlie delta echo foxtrot golf hotel india juliett kilo lima mike november oscar papa quebec romeo sierra tango uniform victor whiskey xray yankee zulu";
	@set_window 0;
	style roman;
	print "alpha bravo charlie delta echo foxtrot golf hotel india juliett kilo lima mike november oscar papa quebec romeo sierra tango uniform victor whiskey xray yankee zulu alpha bravo charlie delta echo foxtrot golf hotel india juliett kilo lima mike november oscar papa quebec romeo sierra tango uniform victor whiskey xray yankee zulu alpha bravo charlie delta echo foxtrot golf hotel india juliett kilo lima mike november oscar papa quebec romeo sierra tango uniform victor whiskey xray yankee zulu";
];

test_inf.z5 (2 KB)

Doing some digging in Window Frotz vs Unix Frotz, I find that in the function units_left in screen.c look like this in Windows Frotz.

static int units_left (void)
{
    if (os_wrap_window (cwp - wp) == 0) return 999;

    return cwp->x_size - cwp->right - cwp->x_cursor + 1;

}/* units_left */

and in Unix Frotz

static int units_left(void)
{
	return cwp->x_size - cwp->right - cwp->x_cursor + 1;
} /* units_left */

Changing Unix Frotz to:

static int units_left(void)
{
	if (cwin == 1) return 999;
	return cwp->x_size - cwp->right - cwp->x_cursor + 1;
} /* units_left */

Have this effect…

This hack is definitely not the final fix, but maybe points in the right direction…

1 Like

Remarks in the standard make it sound like word-wrapping in the upper window is incorrect behavior.

The standard doesn’t directly say this though.

Doing the most logical thing with the Inform 6 version of this issue:

$ inform -a2 minOFSL.inf >minOFSL.lst
$ less minOFSL.lst

I got perhaps where the key of the issue hides, but I’m not much into z-machine definitions and the z-code 'terp implementation:

Inform 6.42 for Linux (10th February 2024)

    0  +00000  [ Main__ 

    0  +00001     call_vs      long_0 (ref to Main) -> TEMP1 
                               e0 3f {main}00 00 ff 
    0  +00006     quit         
                               ba 

    1  +00008  [ Main 

    2  +00009 <*> split_window short_3 
                               ea 7f 03 
    3  +0000c <*> set_window   short_1 
                               eb 7f 01 
    4  +0000f <*> set_text_style short_8 
                               f1 7f 08 
    5  +00012 <*> set_text_style short_1 
                               f1 7f 01 
    6  +00015 <*> erase_window short_1 
                               ed 7f 01 
    7  +00018 <*> set_cursor   short_1 short_1 
                               ef 5f 01 01 
    8  +0001c <*> print_paddr  long_0 (string literal) 
                               8d {str}00 00 
    9  +0001f <*> set_window   short_0 
                               eb 7f 00 
   10  +00022 <*> rtrue        
                               b0 

   11  +00024  [ Symb__Tab dummy1 dummy2 

   11  +00025     rfalse       
                               b1 

Hope that this actually helps, and

Best regards from Italy,
dott. Piergiorgio.

(hiding in my computing lab until xmas dinner… thanks for the elegant excusing out for a respite from enlarged family ! :slight_smile: )

I have also always thought that the upper window don’t wrap. Unix Frotz’s behaviour with garbage chars is strange, but even with my fix it doesn’t do word-wrap, instead it just cuts the string mid-word and continues on the next line. I think this wrapping is the behaviour of the curses library (for screen handling, not the game).

Are there games which depend on continuing on the next line in the upper window, or would it be ok to just stop at the end of the line?

No idea, but because most (well of the few I checked) interpreters don’t do it, I guess not.

I was hoping it would work, for some upcoming projects, because Dialog doesn’t let user code access the screen width to do the wrapping manually. But I’m sure I can find a workaround.