Author Topic: Customized Dialogue Windows  (Read 1051 times)

0 Members and 1 Guest are viewing this topic.

Offline NilG

Customized Dialogue Windows
« on: February 15, 2019, 10:56:08 AM »
Hi again.  Most of the code for the demo is done (act 1 of a 3 act game).  Still a ton to do, replace edited Sierra backgrounds with original ones, add and pretty up some views, clean up some code (aside from a bit of scripting and the C++ courses I took in high school 20 years ago, I'm not a programmer), and waaaaay too many "responseless" possibilities.  Still, there are two complete positive paths through the end of the section I have, it's been amazingly rewarding, and thank you so much for the help with my absolute beginner's questions.

One thing that isn't necessary, but I'd love to include, and I realize it may require a ton of rewrites or additions, is customized dialogue boxes for conversation, similar to QfG2.  Basically just background and text colors customized depending on who's speaking.  Snail Trek (love it and looking forward to Cascadia Quest) also has something very similar; I don't know that speech bubbles would fit stylistically here, but it is basically that idea.

I've looked at the code and guess what's there can be used to implement this, but as a non-coder, my method for doing so would probably be super convoluted.  Is there any kind of built-in method for the customization of dialogue boxes, or a sample of code that doesn't suck for doing so?  I can certainly add sucky code, but I know many of you have been here for a long time doing these things, so figured I'd ask before tromping ahead recklessly.  :D  Thanks!



Offline Kawa

Re: Customized Dialogue Windows
« Reply #1 on: February 15, 2019, 03:18:22 PM »
It's interesting that you'd specify Quest for Glory 2, since that game already had a concept of a Talker. Assuming you want an SCI11 game, you could suffice by simply giving each of your characters' Talker instances different color and back values. It seems to already be all set up to pass these values along to a clone of gWindow. That means the only thing preventing these colors from showing up correctly is that the SCI11 template's gWindow is a BorderWindow by default. If you were to change this to a SysWindow (look for instance mainWindow of BorderWindow in Main.sc), that'd simplify things a lot and you get title bars back.

As for how custom window frames work in general... basically just like how a BorderWindow does it. Instead of letting the interpreter draw the window, they set the Custom bit ($80) and draw it themselves.

Here's the custom window frame from The Colonel's Bequest, with my annotations, as an example:
Code: [Select]
(class myWindow of SysWindow
(properties
top 0
left 0
bottom 0
right 0
color 15
back 8
priority -1
window 0
type $0081 ;Custom, no save
title 0
brTop 0
brLeft 0
brBottom 190
brRight 320
underBits 0
)

(method (dispose)
(SetPort 0)
(Graph grRESTORE_BOX underBits)
(Graph grREDRAW_BOX (- top 8) (- left 8) (+ bottom 8) (+ right 8))
(DisposeWindow window)
(DisposeClone self)
)

(method (open &tmp screens t l b r trHeight blHeight tlHeight tlWidth)
(= tlHeight (CelHigh 657 0 0))
(= trHeight (CelHigh 657 0 1))
(= blHeight (CelHigh 657 1 0))
(= tlWidth (CelWide 657 0 0))
(SetPort 0)

; Make room for the corners
(= t (- top 8))
(= l (- left 8))
(= b (+ bottom 8))
(= r (+ right 8))

(= screens VISUAL)
(if (!= priority -1) (= screens (| screens PRIORITY)))

;We've set the No Save bit, so the kernel won't do it for us.
(= underBits (Graph grSAVE_BOX t l b r screens))

;Fill in the box to start with.
(Graph grFILL_BOX t l b r screens back priority)

;Draw the corners
(DrawCel 657 0 0 l t -1)
(DrawCel 657 0 1 l (- b trHeight) -1)
(DrawCel 657 1 0 (- r blHeight) t -1)
(DrawCel 657 1 2 (- r blHeight) (- b trHeight) -1)

;Draw the double edges
(Graph grDRAW_LINE t (+ l tlWidth) t (- r tlWidth) 31 -1 -1) ;top
(Graph grDRAW_LINE (+ t 2) (+ l tlWidth) (+ t 2) (- r tlWidth) 31 -1 -1)
(Graph grDRAW_LINE (- b 1) (+ l tlWidth) (- b 1) (- r tlWidth) 31 -1 -1) ;bottom
(Graph grDRAW_LINE (- b 3) (+ l tlWidth) (- b 3) (- r tlWidth) 31 -1 -1)
(Graph grDRAW_LINE (+ t tlHeight) l (- b tlHeight) l 31 -1 -1) ; left
(Graph grDRAW_LINE (+ t tlHeight) (+ l 2) (- b tlHeight) (+ l 2) 31 -1 -1)
(Graph grDRAW_LINE (+ t tlHeight) (- r 1) (- b tlHeight) (- r 1) 31 -1 -1) ;right
(Graph grDRAW_LINE (+ t tlHeight) (- r 3) (- b tlHeight) (- r 3) 31 -1 -1)

;Make sure we can see it on screen.
(Graph grREDRAW_BOX t l b r 1)

;Make sure we're still (| Custom NoSave)
(= type $81)

;Let the kernel worry about the rest
(super open:)
)
)

Offline NilG

Re: Customized Dialogue Windows
« Reply #2 on: March 07, 2019, 08:43:35 AM »
Nice, Kawa, thank you.  I'd fixed a workaround by just created intermediate procedures for each character that change gWndColor and gBackColor, pass the params onto Print() proper, then revert the color changes, but I'm going to take a closer look at sysWindow and how these games did things to execute it a bit more properly.

This one's SC10, so I don't think the Talker is an option yet; I hadn't realized it had already been implemented for QFG2, though I think I vaguely recall reading that was the first SC11 game?  Which would make sense.  Is it the only SC11 parser/EGA only game Sierra produced?  Also, I could just be inventing memories; that's a thing that sometimes happens.

Offline Kawa

Re: Customized Dialogue Windows
« Reply #3 on: March 07, 2019, 12:36:33 PM »
QFG2 is an SCI01 game actually. And a Talker is most certainly an option!

Talker is just the name of a class in the end, a class being passed a line of text and each instance represents a particular character. SCI11 has the Message resource type to help automate the everloving shit out of things. In the end, if you wanted, you could just have
Code: [Select]
(Stephen_Colbert say: "Every thing that Trump accuses other people of, he's guilty of himself OH MY GOD!")
(Jon_Batiste say: "What's that?")
(Stephen_Colbert say: "Trump was born in Kenya!")
instead of
Code: [Select]
(Print "Every thing that Trump accuses other people of, he's guilty of himself OH MY GOD!" #title "Stephen Colbert" #at 8 -1)
(Print "What's that?" #title "Jon Batiste" #at 160 -1)
(Print "Trump was born in Kenya!" #title "Stephen Colbert" #at 8 -1)
given a Talker class with a say method that takes a text parameter and wraps around že olde Print, something like this maybe?
Code: [Select]
(method (say text
  (Print text #title name #at x y)
)
Bam.

Or if you want QFG2 per-character window colors,
Code: [Select]
(method (say text &tmp oldColor oldBack)
  (= oldColor gWndColor)
  (= oldBack gWndBack)
  (= gWndColor color)
  (= gWndBack back)
  (Print text #title name #at x y)
  (= gWndColor oldColor)
  (= gWndBack oldBack)
)

Edit: this incidentally turns out to be a very gross simplification of how SCI11 Talkers actually work. The message resources are entirely handled by the Messager class, and the Narrator/Talker literally gets a string of text passed to its say method. And/or a set of audio keys. So in an SCI11 game, you could literally just do (Stephen_Colbert say: "ALLEGEDLY!")!

Edit the second: I went ahead and implemented this real quick just to see if I'm full of shit. Besides a minor difficulty in having to switch back to Studio script, it worked exactly as I'd planned.
« Last Edit: March 12, 2019, 10:13:41 PM by Kawa »

Online cosmicr

Re: Customized Dialogue Windows
« Reply #4 on: September 05, 2020, 11:52:11 PM »
Here's the custom window frame from The Colonel's Bequest, with my annotations, as an example:
Code: [Select]
;Make sure we can see it on screen.
(Graph grREDRAW_BOX t l b r 1)

Hi sorry to necro a thread, but I was using this example from Colonel's bequest to make my own custom dialog box.... Only to pull my hair out for hours trying to understand why my views were still drawing on top of my window.

I ended up examining the decompilation of the actual game(Colonel's Bequest) to discover that Kawa's code above had a mistake! The code should read:

Code: [Select]
;Make sure we can see it on screen.
(Graph grUPDATE_BOX t l b r 1)

Phew! At least I learned a lot through the process and now consider myself well learned on custom windows haha! Anyway thought it was worth posting in case someone finds this code and wants to use it for themselves. It makes it pretty easy to adapt to something else.

If anyone does want to implement this, don't forget that after you create your custom window class if you want to override the default Print procedure with yours you need to update this section in "Controls.sc" (edit: this isn't the best way to do it):
Code: [Select]
(method (open theType thePriority)
(if (and (PicNotValid) gCast)
(Animate (gCast elements?) 0)
)
(= window (myWindow new:)) ; originally just "Window" type
(window
top: nsTop
left: nsLeft
bottom: nsBottom
right: nsRight
title: text
type: theType
priority: thePriority
color: gWndColor
back: gWndBack
open:
)
(= seconds time)
(self draw:)
)

And here's my annotated version of the Colonel's Bequest code, from the decompilation:

Code: [Select]
(class myWindow of SysWindow
(properties
top 0
left 0
bottom 0
right 0
color 15
back 8
priority -1 ;negative 1 is no priority
window 0
type (| nwTRANSPARENT nwON_TOP)
title 0
brTop 0
brLeft 0
brBottom 190
brRight 320
underBits 0
)

(method (dispose)
(SetPort 0) ; use the window graphics port (0)
(Graph grRESTORE_BOX underBits) ; restore what was under the window
(Graph grREDRAW_BOX (- top 8) (- left 8) (+ bottom 8) (+ right 8) ) ; redraw the area
(DisposeWindow window) ; delete the window handle
(DisposeClone self) ; unload this instance
)

(method (open &tmp screens t l b r trHeight blHeight tlHeight tlWidth)
; get the dimensions of the corners
(= tlHeight (CelHigh 657 0 0)) ; view number 657 contains the corner images
(= trHeight (CelHigh 657 0 1)) ; loop 0, cel 1
(= blHeight (CelHigh 657 1 0)) ; loop 1, cel 0
(= tlWidth (CelWide 657 0 0))  ; loop 0, cell 0
; set to window port (0)
(SetPort 0)
; set the new bounds of the window
(= t (- top 8))
(= l (- left 8))
(= b (+ bottom 8))
(= r (+ right 8))
; visual screen
(= screens VISUAL)
; draw to priority also if priority value is present
(if (!= priority -1) (= screens (| screens PRIORITY)))
; save a buffer of the screen
(= underBits (Graph grSAVE_BOX t l b r screens) )
; draw background box
(Graph grFILL_BOX t l b r screens back priority)
; draw corners
(DrawCel 657 0 0 l t -1) ; top left
(DrawCel 657 0 1 l (- b trHeight) -1) ; bottom left
(DrawCel 657 1 0 (- r blHeight) t -1) ; top right
; note: there was a mistake made by sierra here, I have corrected it.
;       the cel number was set to 2, not 1.
(DrawCel 657 1 1 (- r blHeight) (- b trHeight) -1) ; bottom right
; draw borders
(Graph grDRAW_LINE t (+ l tlWidth) t (- r tlWidth) 31 -1 -1) ;top outside (31 is white)
(Graph grDRAW_LINE (+ t 2) (+ l tlWidth) (+ t 2) (- r tlWidth) 31 -1 -1) ;top inside
(Graph grDRAW_LINE (- b 1) (+ l tlWidth) (- b 1) (- r tlWidth) 31 -1 -1) ;bottom outside
(Graph grDRAW_LINE (- b 3) (+ l tlWidth) (- b 3) (- r tlWidth) 31 -1 -1) ;bottom inside
(Graph grDRAW_LINE (+ t tlHeight) l (- b tlHeight) l 31 -1 -1) ;left outside
(Graph grDRAW_LINE (+ t tlHeight) (+ l 2) (- b tlHeight) (+ l 2) 31 -1 -1) ;left inside
(Graph grDRAW_LINE (+ t tlHeight) (- r 1) (- b tlHeight) (- r 1) 31 -1 -1) ;right outside
(Graph grDRAW_LINE (+ t tlHeight) (- r 3) (- b tlHeight) (- r 3) 31 -1 -1) ;right inside
; update the draw area
(Graph grUPDATE_BOX t l b r VISUAL)
; update type incase it changed
(= type (| nwTRANSPARENT nwON_TOP))
; call the base class (SysWindow) open procedure
(super open:)
)
)
« Last Edit: September 06, 2020, 12:54:05 AM by cosmicr »

Offline Kawa

Re: Customized Dialogue Windows
« Reply #5 on: September 06, 2020, 06:31:23 AM »
It's all good. This is a good necro-ing.


SMF 2.0.14 | SMF © 2017, Simple Machines
Simple Audio Video Embedder

Page created in 0.118 seconds with 23 queries.