What is this bug in Windows Frotz?

In the Dialog compiler’s Z-machine veneer, there’s a specific bit of code that checks if the interpreter’s reported screen width is less than 40; if it is, the veneer returns 40 instead.

A comment in the code marks this as “workaround for winfrotz bug”. Unfortunately, it’s now causing problems when I try to support screens less than 40 characters wide.

Does anyone know what bug in particular is being worked around here? Ideally I’d like to find a workaround that doesn’t interfere with supporting smaller screens. (For example, I’m typing this message on a phone screen 32 characters wide, thanks to my poor eyesight.)

Aha, perhaps it’s this?

If so, that’s unfortunately going to be hard to work around any other way…

Or rather this: Screen width · Issue #20 · DavidKinder/Windows-Frotz · GitHub

Given that even Trinity can’t run on earlier versions of Frotz, I’m inclined to break compatibility with earlier versions in order to ensure compatibility with modern interpreters on small screens. There probably aren’t too many people running pre-2021 versions of Frotz on monitors more than 255 columns wide, right? I expect most people using old versions are doing so on old hardware too.

In Z5 the header also has the screen width in units as a 16bit number, would that help?

Unfortunately not, because as far as I can tell, there’s no way to know what an interpreter considers a “unit” outside version 6.

Though, maybe I could assume that any interpreter whose width is more than 255 characters would also have a width of more than 255 units…

That should work, I think! At least, if we can trust interpreters to supply that information. Let’s try that.

Right after the screen size in units is the font in units, which you should be able to use to calculate the size in characters. Though most non-Z6 terps should just say 1 for the units. (Of course you’ll have to check that they’re not 0.)

1 Like

Aha! Okay, I can work with that! Presumably no screen in the near future will be big enough to overflow a whole word.

New code, in pseudo-Inform syntax:

[ GetFullWidth x0 x1 x2;
    @loadb 0->$21 -> x0;
    @loadw 0->$22 -> x1;
    @loadb 0->$26 -> x2;
    
    ! Don't divide by zero
    @jz x2 ?l1;
    @div x1 x2 -> x1;
    
    ! Now, if reported width < 255
    ! and calculated width >= 255,
    ! use the calculated value
    @jge x0 255 ?l1;
    @jl x1 255 ?l1;
    @ret x1;
    
    ! Otherwise, use the reported value
    .l1
    @ret x0;
];
1 Like