DavidGriffith / frotz

Infocom-style interactive fiction player for Unix and DOS (moved to https://gitlab.com/DavidGriffith/frotz)
GNU General Public License v2.0
209 stars 64 forks source link

Terminal resizing #65

Closed tkorvola closed 6 years ago

tkorvola commented 6 years ago

Resizing now works fairly well in my testing, mostly with Beyond Zork and some other V5 games. Curses automatically reprints from the top left. For the lower window that works poorly when the number of rows shrinks. To fix that resize_screen restores the lower window so that the old cursor position remains on screen. Effectively it scrolls up so that the cursor ends up on the last row.

Only the lower window height is adjusted. If there is no space left for the lower window, it is resized to one row and placed at the bottom of the screen, overlapping whatever is there. In theory that should help finish the current input line, after which the game could notice the screen resize and adjust the top window accordingly. Fat chance of that with Beyond Zork. Better not resize it so that the top part does not fit.

None of this complicated stuff is done for V6 games. We just set the refresh flag and hope that the game sorts out its windows. If it doesn't or until it gets a chance to, it's just the curses top left reprint. I haven't tested with V6 games at all.

I had to add a new interface function os_repaint_window, which I am not too happy about. However, it seems the least messy alternative. I added dummy versions of the new function to dfrotz and the dos version, although I don't even have a compiler for the latter.

Both SIGWINCH and ^Z are handled. There may be bugs but they'll likely need more eyeballs than mine to find.

Fixes #42.

DavidGriffith commented 6 years ago

There are two compilation problems that I'd like to see fixed.

src/curses/ux_input.c: In function ‘os_read_line’:
src/curses/ux_input.c:500:13: warning: variable ‘x2’ set but not used [-Wunused-but-set-variable]
         int x2, max;
             ^~
At top level:
src/curses/ux_input.c:123:12: warning: ‘timeout_to_ms’ defined but not used [-Wunused-functio]
 static int timeout_to_ms()

Shrinking the terminal by scrolling up is perfect.

Resizing horizontally needs to be done by reformatting the text rather than cropping the right-hand side. Fizmo does this by maintaining an output buffer and running it through a line wrapping algorithm every time a horizontal resize is done. Can you do this?

tkorvola commented 6 years ago

Re-wrapping without a history buffer would be difficult. One could try some heuristic screen-scraping (we have a copy of the pre-resize screen) but there is no reliable way to recognize newlines added by wrapping (and was it buffered or not?) from those explicitly printed - unless that information was recorded at the time of printing, and then we'd be keeping a history buffer.

I think -Wunused-parameter is rather useless but -Wunused-but-set-variable might sometimes catch an error. Unfortunately the UNUSED macro does not help there, so it took a silly kluge to eliminate the warning.

tkorvola commented 6 years ago

Implementing an output history buffer would be useful but quite an undertaking, one which I don't think I can manage in the near future.

DavidGriffith commented 6 years ago

I have some ideas for implementing a history buffer that shouldn't cause too much distress.