I have used PDCurses to port Rogue V3.6 to Win32 using MinGW and all works well except for the RIP screen. The usual headstone is printed and then the cursor moves to the last line of the screen in order to print the scores.
The problem is that the value used for LINES is the corresponding row of the windows console screen buffer rather than the actual physical number of lines on the console. For example, I usually use a console window with 25 lines but a screen buffer of 256 lines.
Without using any of the internal PDCurses functions, how can I get/set the LINES variable to the actual screen dimensions?
LINES should already reflect the visible screen size, not the buffer size. Further, the Win32 port of PDCurses disables the scrollback buffer while it's running, by making the buffer and physical screen match. However, this can get messed up if the program calls endwin() before it stops output, or in a few other situations.
Do you have a URL for source I can check?
Sure, I'm grateful for any help recieved with this. The source is http://www.martinsobservationpost.net/system/rogue361test.zip and is being compiled with MinGW-gcc V3.4.2 and PDCurses V2.7.
The critical portion is rip.c, function "death". As you will see, endwin is indeed called as the last thing before exiting, after all output, but I don't know what the "few other situations" are.
If you check the scrollback buffer, you can see that what is happening is that the headstone is printed at the top of the screen where it ought to be, but "move(LINES-1,0)" moves to the bottom of the scroll buffer (line 256 (1-based) in my case) so the headstone is simply scrolled off the screen.
This even happens when the screen is set to full screen mode (ALT-Enter); presumably the buffer isn't being disabled when that happens.
OK, it's got nothing to do with the value of LINES, which is correct. (Notice what changes when you take that line out, BTW: nothing.) And endwin() is NOT being called last -- there's an endwin() call early in the score() function (the one in death() is redundant). It's called after printing the tombstone, but before the pause.
It's endwin() that reexpands the buffer -- leaving the curses screen at the top of it. (And yes, the buffer is still shrunken and expanded in full-screen mode.) I agree that this behavior is not ideal.
Meanwhile, I played with rogueMH for a while. With the mix and match of curses and stdio calls, it's not easy to achieve the desired effect without bad side effects. One solution is below -- not quite ideal, because it lets you read the tombstone, but still scrolls it up afterwards.
*** ../rogue2/rip.c 2006-02-27 12:27:15.000000000 -0500
--- ./rip.c 2006-02-27 17:42:57.000000000 -0500
*** 101,108 ****
"A total winner",
- if (flags != -1)
* Open file and read list
--- 101,106 ----
*** 128,136 ****
if (flags != -1)
! printf("[Press return to continue]");
if (strcmp(prbuf, "names") == 0)
--- 126,134 ----
if (flags != -1)
! printw("[Press return to continue]");
if (strcmp(prbuf, "names") == 0)
Thanks, I understand a little more of what's going on here now. I have never had to deal with curses before so am not used to this kind of thing.
Your solution is quite useful; however, the problem for me is that as soon as any printf or whatever is used, it goes to the BOTTOM of the screen buffer, which is now off-screen.
Is there any way to have pdcurses reset the console after any call to endwin() such that the screen is left EXACTLY as it is after a "cls" command is entered at the command prompt?
In other words, (a) the entire screen is cleared, (b) the cursor is now at the TOP of the screen, (c) the screen buffer (below the physical screen) is cleared and any further stdio output immediately after the final endwin() will start from the TOP of the screen downwards, not at the bottom line of the screen buffer.
I see no way for you to do that, no.
I'm going to look into improving the handling of the scrollback buffer. But I suggest that you a) not mix curses and stdio, b) not expect any curses output to be left onscreen after endwin(), and c) not depend on the state of the terminal after endwin().
Some curses programs ported from Unix, like this one, make assumptions about the interaction of curses and stdio that are not valid with PDCurses. So it's best to just do all your I/O via curses. (Programs written to a pure curses API are portable back and forth; programs that mix in stdio, terminfo or termcap calls are not.)
Thanks for your help; at least I know how to go about it. I wanted to see how far I could get making such an old program work in the modern world and a challenge it certainly is.
If it's any help, I was able to mimic CLS by moving the in-buffer/screen console viewport ("window") back to the top, preserving the headstone etc without destroying or erasing the console screen buffer (though it could do that as well if required). In terms of not having to make a total rewrite of rip.c until I have the time to do so, this could be a basis for the solution. In case you find it useful, have a look at the file http://www.martinsobservationpost.net/system/ripcls.c; though not a complete solution, it might useful as a basis for resetting a screen the way the CLS command does. The original version filled the console buffer with spaces and was inspired by this microsoft KB article: http://support.microsoft.com/kb/q99261.
Anyway, thanks again, you can consider this closed.
Sign up for the SourceForge newsletter:
You seem to have CSS turned off.
Please don't fill out this field.