Community
SCI Programming => SCI Syntax Help => Topic started by: lwc on December 30, 2023, 07:53:59 AM
-
Unlike most SCI games (including its prequel), EcoQuest 2 barely uses flag events (from global110). It instead mostly uses a Main.sc (https://github.com/sluicebox/sci-scripts/blob/main/eco2-dos-1.000.000/src/Main.sc) (script #0) local variable called gCurrentRegionFlags which uses set/test/clear procedures that are defined in Flags.sc (https://github.com/sluicebox/sci-scripts/blob/main/eco2-dos-1.000.000/src/Flags.sc) (script #985).
Thankfully, the kind people here made EcoQuest2's restored debug (https://sciprogramming.com/community/index.php?topic=9150.0) smart enough to handle both types using a yes/no question of "Flag Object?" (for alt+b/l/k). If the player chooses yes, it uses gCurrentRegionFlags set/test/clear and if the player chooses no, it uses the standard SetFlag/TestFlag/ClearFlag.
So my questions are:
- Why would Sierra use 2 different ways to track events possibly only in this game, and why barely using the official way? Because of it ScummVM's console flag feature (sf/tf/cf) (https://github.com/scummvm/scummvm/pull/3900/files#diff-51185e3da67647ad99a178a4505fcfd5767f32784c47fb9676095c111e306bb2) can barely discover anything in this game, since they expect only the rarely used official way...
- Why isn't a global like global110 considered a Flag Object too? After all, it contains multiple flag events inside itself. I mean, why did the people here that restored the debugger consider the answer of "no" to "Flag Object?" to mean using a global that stores many flags?
- Hope it's okay to ask since it's a bit off-topic, but as far as you know, is there any to use breakpoints to discover such flags in ScummVM's debugger console (https://github.com/scummvm/scummvm/blob/master/engines/sci/console.cpp)? The usual way would be bpe 0 3 (since 3 in this game SetFlag is 3), but it isn't worth much due to being barely used. And bpe 0 150 (since gCurrentRegionFlags is 150) is never triggered. Likewise l 150 always shows the same value (assuming because it's an object).
An easy test is in room 840 (https://github.com/sluicebox/sci-scripts/blob/main/eco2-dos-1.000.000/src/rm840.sc) - climb the right wall and every time you pull the snake's tale it either runs gCurrentRegionFlags set: 1 or gCurrentRegionFlags clear: 1.
Stats:
- gCurrentRegionFlags set has 156 matches in 38 files practically in every room
- SetFlag has 21 matches in 12 files out of which just 3 rooms - overall just 7 flags! Feel free to describe them in https://tcrf.net/Notes:Lost_Secret_of_the_Rainforest#Flag_Numbers
- gCurrentRegionFlags test has 458 matches in 34 files practically in every room
- isFlag has 65 matches in 18 files out of which just 9 rooms
- gCurrentRegionFlags clear has 33 matches in 13 files practically in every room
- ClearFlag has 14 matches in 9 files out of which just 2 rooms
Thanks!
-
That seems like a general decision to keep data pertaining to specific regions separate. It does the same thing with inventory items: Usually, inventory items are put on the inventory list once at startup and leaves them there for the duration - Eco2 instead adds and deletes items throughout. Oh, and there's the Ecorder flags too.
-
But there's no separation really because while gCurrentRegionFlags is technically a local, it's declared in Main.sc and thus treated like a global anyway - in the console running l 0 150 is equal to running vv g 150 - in either case the output is 002f:0508 (object 'goldFlags').
About question 3, you would think if bpe can't be used, at least Flags::set should work, but it doesn't. This is even though according to this (https://bugs.scummvm.org/timeline?from=2017-05-15T22%3A03%3A39Z&precision=second) in KQ6 bpx KQ6Print::say works, whereas KQ6Print is a class just like Flags and say is a method just like set (see code (https://github.com/sluicebox/sci-scripts/blob/main/kq6-cd-dos-1.000.00G/src/KQ6Print.s)). According to this (https://bugs.scummvm.org/ticket/10730), it should also be similar to Laura Bow 2's bpx bugsWithMeat::cue (see code (https://github.com/sluicebox/sci-scripts/blob/main/ra-cd-dos-1.1/src/rm600.sc)).
But I've found an interim solution - bpa 000e:00a7 - I don't like it because there's no pasting in ScummVM's console and who wants to type down this address, but it works nonetheless.
Here's how I deduced that Flags' set can be called directly with address 000e:00a7:
- value_type Flags indeed outputs Object.
- scro 985 outputs:
=== SCRIPT 985 inside Segment 000e (14d) ===
001:0154: Flags
- vo 000e:0154 outputs:
[000e:0154] Flags : 11 vars, 6 methods
-- member variables:
(0000) [1000] -objID- = 0000:1234 (4660)
(0001) [1001] -size- = 0000:000b (11)
(0002) [1002] -propDict- = 000e:0008
(0003) [1003] -methDict- = 0000:001e (30)
(0004) [1004] -classScript- = 0000:03d9 (985)
(0005) [1005] -script- = 0000:007d (125)
(0006) [1006] -super- = 0004:092f (Obj)
(0007) [1007] -info- = 0000:8000 (32768)
(0008) [014] name = 000e:016c
(0009) [056] size = 0000:0000 (0)
(000a) [1d5] array = 0000:0000 (0)
-- methods:
[06e] init = 000e:0038
[06f] dispose = 000e:0091
[0ba] setSize = 000e:004a
[0a0] set = 000e:00a7
[26c] clear = 000e:00e7
[26d] test = 000e:0128
[06d] Obj::new = 0004:02cb
[039] Obj::doit = 0004:02d2
[070] Obj::showStr = 0004:02da
[071] Obj::showSelf = 0004:02e3
[060] Obj::perform = 0004:02f7
[072] Obj::isKindOf = 0004:0334
[073] Obj::isMemberOf = 0004:030a
[074] Obj::respondsTo = 0004:0302
[075] Obj::yourself = 0004:036b
-
...why did the people here that restored the debugger consider the answer of "no" to "Flag Object?" to mean using a global that stores many flags?
I recall the debugger script for EQ2 still exists in the resources, so that code was from the Sierra devs and not a conscious decision from anyone here.
Did you report the flag object issue to the ScummVM devs?
-
But there's no separation really because while gCurrentRegionFlags is technically a local, it's declared in Main.sc and thus treated like a global anyway - in the console running l 0 150 is equal to running vv g 150 - in either case the output is 002f:0508 (object 'goldFlags').
No, gCurrentRegionFlags is a pointer to the currently accessible flags. So if gCurrentRegionFlags is pointing to goldFlags, I can't access batFlags, for instance. That script won't even be loaded, so I can't access its flags.
Of course it's a global variable, because every script needs to be able to dereference it.
-
Did you report the flag object issue to the ScummVM devs?
Report what? Since the game also uses standard flags, ScummVM is unlikely to add a special secondary support, especially since last time I asked something about the console (to add a basic "clear" console command (https://bugs.scummvm.org/ticket/13386)) they told me to stay away from console requests as it's an "internal" too.
No, gCurrentRegionFlags is a pointer to the currently accessible flags. So if gCurrentRegionFlags is pointing to goldFlags, I can't access batFlags, for instance. That script won't even be loaded, so I can't access its flags.
Of course it's a global variable, because every script needs to be able to dereference it.
In Main.sc it appears as:
(local
gCurrentRegionFlagsWhere do you see it's a pointer? Other than being declared, it's not defined. It's just used with Flags.sc's set/test/clear.
-
I see these:
Bats.sc: (= gCurrentRegionFlags batFlags)
Cibola.sc: (= gCurrentRegionFlags cibolaFlags)
Docks.sc: (= gCurrentRegionFlags dockFlags)
Flood.sc: (= gCurrentRegionFlags floodFlags)
Gold.sc: (= gCurrentRegionFlags goldFlags)
Jungle.sc: (= gCurrentRegionFlags jungleFlags)
Village.sc: (= gCurrentRegionFlags villageFlags)
which set gCurrentRegionFlags to point at each of those instances at the right time. And yes, they are instances, for example:
(instance villageFlags of Flags
(properties
size 80
)
)
-
True, although from what I've seen so far (just a couple of rooms in different areas) they still don't use the same flag number twice, even though you've established they can.
Now I just wonder how to be able catch Flags' set/test/clear with either bpe or bpx instead of having to use bpa which relies on addresses.
-
So any idea why bpa works in this case while bpx doesn't?
-
Because gCurrentRegionFlags doesn't point to Flags, but to dockFlags etc. You can say
bpx dockFlags::testjust fine.
-
But in each area it's different. In the initial example of room 840 it's goldFlags, not dockFlags, so it would be:
bpx goldFlags::setSo:
- How to find something like goldFlags or dockFlags via the debugger console (instead of browsing the source code)? It doesn't show up when running commands like selectors or class_table (unlike Flags).
- Is there any way to use something that's not area dependent (like bpa above)?
-
I was wondering that myself, how to peek at the value of gCurrentRegionFlags and invoke methods on an object by address instead of name. I don't use the debuggers much lol.
-
I was wondering that myself, how to peek at the value of gCurrentRegionFlags and invoke methods on an object by address instead of name. I don't use the debuggers much lol.
I've explained above the flow to get the address of set/test/clear and then use it in bpa. This should work in 100% of the rooms, but it's not comfortable to work with addresses.
I just look for a bpx alternative with a static name.