While playing Space Quest 4 – Roger Wilco and The Time Rippers, you travel back and forth between several different time periods, each designated by a sequel number. The introduction and ending are set in SQ4, the main plot in SQ12 – Vohaul’s Revenge II, and from there you travel to SQ1 – The Sarien Encounter, SQ10 – Latex Babes of Estros, and in an easter egg, SQ3 – The Pirates of Pestulon.
While in the SQ1 era, you revisit Ulence Flats. Literally, you arrive just after the original Roger is done there and leaves. In the SCI remake of SQ1, you actually see the time pod from SQ4 arrive right behind you when you leave the area, but SQ4 came out before the SQ1 remake so you revisit the AGI version instead. Sort of. The resolution’s all wrong, but who cares?
One thing you’ll quickly notice is that instead of the usual BorderWindow
frames, this part of the game uses a custom frame meant to evoke AGI’s. It is, however, immediately clear (at least to me) that they fucked it up.
That’s one unsightly black border! Also, the window is light gray instead of white but that’s not the issue here.
If you look closely and remember what I wrote about window style bits before, you might recognize that it’s drawing a white light gray window with a red border, and then a nwTRANSPARENT
window on top. What does the actual code say? Here’s Sq1Window
, which is used in lieu of BorderWindow
in all Ulence Flats rooms:
(class Sq1Window of SysWindow (properties underBits 0 pUnderBits 0 bordWid 3 ) (method (dispose) (SetPort 0) (Graph grRESTORE_BOX underBits) (Graph grRESTORE_BOX pUnderBits) (Graph grREDRAW_BOX lsTop lsLeft lsBottom lsRight) (super dispose:) ) (method (open &tmp temp0 temp1) (SetPort 0) (= color gColor) (= back gBack) (= temp1 1) (if (!= priority -1) (= temp1 (| temp1 $0002))) (= lsTop (- top bordWid)) (= lsLeft (- left bordWid)) (= lsRight (+ right bordWid)) (= lsBottom (+ bottom bordWid)) (= underBits (Graph grSAVE_BOX lsTop lsLeft lsBottom lsRight 1)) (if (!= priority -1) (= pUnderBits (Graph grSAVE_BOX lsTop lsLeft lsBottom lsRight 2)) ) ; Draw the background (Graph grFILL_BOX lsTop lsLeft lsBottom lsRight temp1 back priority) ; Draw the border (Graph grDRAW_LINE (+ lsTop 1) (+ lsLeft 1) (+ lsTop 1) (- lsRight 2) global131 priority) (Graph grDRAW_LINE (- lsBottom 2) (+ lsLeft 1) (- lsBottom 2) (- lsRight 2) global131 priority) (Graph grDRAW_LINE (+ lsTop 1) (+ lsLeft 1) (- lsBottom 2) (+ lsLeft 1) global131 priority) (Graph grDRAW_LINE (+ lsTop 1) (- lsRight 2) (- lsBottom 2) (- lsRight 2) global131 priority) (Graph grUPDATE_BOX lsTop lsLeft lsBottom lsRight 1) ; Open a logical window for the contents to be drawn into (= type 129) (super open:) ) )
And here’s the trick: not only does it open a logical window after drawing it, but it opens one with the wrong style.
Fix idea #1. Open the logical window before drawing it.
(method (open &tmp temp0 temp1) (= type 129) (super open:) (SetPort 0) (= color gColor) ;... )
That ain’t it. Not only does it put the contents of the window in the corner of the screen (because we’re using SetPort
wrong) but when the window closes, the frame appears behind it:
No, no. The way I solved it was like this:
(method (open &tmp port temp1) ; temp0 was unused so we're taking it for proper SetPorting. (= color gColor) (= back gBack) ; Set our type to ONLY wCustom, not wCustom|wNoSave, and open. (= type 128) (super open:) ; Nothing will have appeared because wCustom don't draw anything, but a port has been set up! ; Switch to drawing on the whole screen but also *save the window's port*. (= port (GetPort)) ; 2022-07-29 update, hi sluicebox (SetPort 0) (= temp1 1) ; ... (Graph grUPDATE_BOX lsTop lsLeft lsBottom lsRight 1) ; Reset to the window's port. (SetPort port) )
And that fixes everything!
No extra black border, no misplaced contents, and no leftovers! If you have the CD-ROM edition, you may be able to drop this file in the game’s directory and rename it to 706.scr
.
Now, eagle-eyed viewers might notice that in the very broken screenshot, the text was drawn on a white background, while the window itself is light gray. This is because each graphical port in the system tracks its own color settings, among other things. A logical window is a kind of port, as is the screen as a whole. Since the broken version called (SetPort 0)
after (super open:)
, its contents were drawn on the screen port, not the window’s. And the screen port, by default, has a white background color.
Shoutouts to the Space Quest Historian for putting me on this track with his playthrough video. And as such, see ya on the Chronostream, time jockeh!
And now you should make a ScummVM PR for this!
I just checked and it seems ScummVM either never had this issue, or already has it patched.
On closer investigation, I can see no patch so
perhapsit’s just an implementation difference.Edit: I checked again, and it is an implementation difference near I can tell.