A popular style of window seen in SCI1 games like Police Quest and Space Quest is the
BorderWindow. By default it’s thick and gray, but it can really have any thickness and set of five colors you want.
|The default looks something like this. Your exact colors may vary as I use a custom palette instead of the standard SCI1 palette, and Space Quest 5 has somewhat tinted grays.|
|If one were to edit the
|…as can the
But how does this work exactly? Let’s take the actual
BorderWindow script code and walk through it.
(class BorderWindow of SysWindow (properties ; All other properties inherited from SysWindow back 5 topBordColor 7 lftBordColor 6 rgtBordColor 4 botBordColor 3 bevelWid 3 shadowWid 2 ) (method (dispose) (super dispose:) (SetPort 0) ) (method (show) (Graph grUPDATE_BOX top left bottom right VISUAL) ) (method (open &tmp oldPort screens) (SetPort 0) ; Use the entire screen. ; If we have a priority set, render to that screen too. (= screens VISUAL) (if (!= priority -1) (= screens (| screens PRIORITY))) ; Make some room in the "last seen" rect to fit the border. (= lsTop (- top bevelWid)) (= lsLeft (- left bevelWid)) (= lsRight (+ right bevelWid shadowWid)) (= lsBottom (+ bottom bevelWid shadowWid)) (= type 128) ; We are custom, as described in the ; previous post. (super open:) ; Let a SysWindow open itself. ; This actually just calls the NewWindow kernel call ; and saves the returned handle to our window property. (drawWindow top left bottom right back topBordColor lftBordColor botBordColor rgtBordColor bevelWid shadowWid priority screens ) (= oldPort (GetPort)) ; Remember our current port. (SetPort 0) ; Use the whole screen again. ; Show what we have wrought. (Graph grUPDATE_BOX lsTop lsLeft lsBottom lsRight VISUAL) (SetPort oldPort) ) )
That’s not so bad. The meat of the dish is in
(procedure (drawWindow t l b r theColor topColor leftColor bottomColor rightColor theBevelWid theShadowWid thePri theMaps &tmp savePort i) ; Again, we remember the current port and use the whole screen. (= savePort (GetPort)) (SetPort 0) ; Fill in the window background. (Graph grFILL_BOX t l (+ b 1) (+ r 1) theMaps theColor thePri) ; Extend our rect to include the bevel. (-= t theBevelWid) (-= l theBevelWid) (+= r theBevelWid) (+= b theBevelWid) ; Draw the top and bottom bevels as simple boxes. (Graph grFILL_BOX t l (+ t theBevelWid) r theMaps topColor thePri ) (Graph grFILL_BOX (- b theBevelWid) l b r theMaps bottomColor thePri ) ; Draw the left and right bevels line by line. (for ((= i 0)) (< i theBevelWid) ((++ i)) (Graph grDRAW_LINE (+ t i) (+ l i) (- b (+ i 1)) (+ l i) leftColor thePri -1 ) (Graph grDRAW_LINE (+ t i) (- r (+ i 1)) (- b (+ i 1)) (- r (+ i 1)) rightColor thePri -1 ) ) ; Draw the shadow last. Unlike SysWindows, ; these are done as two boxes. (if theShadowWid (Graph grFILL_BOX (+ t theShadowWid) r (+ b theShadowWid) (+ r theShadowWid) theMaps 0 thePri ) (Graph grFILL_BOX b (+ l theShadowWid) (+ b theShadowWid) r theMaps 0 thePri ) ) (SetPort savePort) )
To visualize, a BorderWindow (sans shadow) renders like this:
Next time, we take a step back and look at King’s Quest.