Author Topic: Can events flags be set in Internal Debugger?  (Read 5109 times)

0 Members and 1 Guest are viewing this topic.

Offline lwc

Can events flags be set in Internal Debugger?
« on: January 11, 2024, 07:57:40 PM »
Surprisingly, SCI0 games' internal debugger doesn't offer direct support for the most basic plot features in SCI - teleport and setting event flags.
But at least for teleport the wiki suggests an indirect way - to modify global variable 13 into the desired room number.
Is there a similar indirect way to set/test/clear event flags (the debugger allows changing global, local and temp flags, but not event ones which are a subset of global variables)?
« Last Edit: January 12, 2024, 03:08:38 PM by lwc »



Offline doomlazer

Re: Can events flags be set in Internal Debugger?
« Reply #1 on: January 11, 2024, 11:14:25 PM »
Some SCI0 games predate Sierra's use of flags, like KQIV and SQ3 which have none.

PQ2 is the first SCI0 game I know uses them, but if you look at the code for PQ2 and LSL3 the flags begin at different globals. PQ2 starts at global250 and LSL3 at global111.

To use the internal debugger you'd need to first know which global the flags start at for each specific game, figure out which subsequent global the flag is stored in, know the existing value of that global, and finally calculate the correct new value to set the proper flag while preserving the other 15 flags.

IMO, that's way too much work when you can use the script debugger which does all this for you.

Edit: LOL, your question made me realize I made a dumb mistake misusing flags in a project last year that I'll need to fix. Never take anything at face value I guess.

« Last Edit: January 12, 2024, 03:15:52 AM by doomlazer »

Offline lwc

Re: Can events flags be set in Internal Debugger?
« Reply #2 on: January 12, 2024, 06:01:38 AM »
IMO, that's way too much work when you can use the script debugger which does all this for you.
Well, all the SCI0 games I know, like QFG1EGA, QFG2 (not the non SCI fan remake) and LSL3 don't have anything like flag control in their script debuggers, despite using flags for everything. I would have mentioned SQ3 too, but judging from its code you seem to be right that it predates flags.

Quote
Edit: LOL, your question made me realize I made a dumb mistake misusing flags in a project last year that I'll need to fix. Never take anything at face value I guess.
At your service...
« Last Edit: January 12, 2024, 03:10:29 PM by lwc »

Offline doomlazer

Re: Can events flags be set in Internal Debugger?
« Reply #3 on: January 12, 2024, 02:17:19 PM »
I guess you're right, they don't have flag commands in the script debuggers. That is weird. WTH?

Offline doomlazer

Re: Can events flags be set in Internal Debugger?
« Reply #4 on: January 12, 2024, 04:23:06 PM »
It's easy to add this feature, and I guess I already did in my Debug repo for PQ2:

Code: [Select]
script.801:

debugRm::handleEvent

        ...
(KEY_ALT_f ;add flag set and clear
(= i (proc255_3 {Flag Number:}))
(if (proc0_18 i)
(proc255_0 {clearing flag})
(proc0_17 i)
else
(proc255_0 {setting flag})
(proc0_16 i)
)
)
        ...

I should go through all the SCI0 games and add Test/Set/Clear for them eventually.
« Last Edit: January 12, 2024, 04:48:03 PM by doomlazer »

Offline lwc

Re: Can events flags be set in Internal Debugger?
« Reply #5 on: January 13, 2024, 07:56:48 AM »
I should go through all the SCI0 games and add Test/Set/Clear for them eventually.
But each will need a different shortcut (e.g. in LSL3 alt+f is already taken).

To use the internal debugger you'd need to first know which global the flags start at for each specific game, figure out which subsequent global the flag is stored in, know the existing value of that global, and finally calculate the correct new value to set the proper flag while preserving the other 15 flags.
What do you mean start at VS stored at? All SCI games that have event flags have just a single global for event flags (disregarding alternate dedicated event flags like eco2's Ecorder).
Anyway, in the example of lsl3 if you check global 111 after running various setflag it seems to stay at 0 if the setflag is > 15 (e.g. look at plaque or use binocular at room 200), so how can you tell any flag from a value of 0?
« Last Edit: January 14, 2024, 07:54:27 AM by lwc »

Offline doomlazer

Re: Can events flags be set in Internal Debugger?
« Reply #6 on: January 13, 2024, 04:19:38 PM »
Each global can only store 16 flags. According to this list of flags fLookedAtPlaque is flag 18.

If global111 stores flags 0-15, global112 would contain flag 18. When no other flag is set in global112, looking at the plaque should change the value from zero to four since it is setting the third bit.

According to the SDA, LSL3 Main.sc reserves global111-global117 for flags. That's a total of 112 possible flags, even though less than 80 flags are actually used by the game. Using flag 112 or above in LSL3 would start altering globals reserved for other uses and likely introduce bugs.

Of course I've been wrong before, so you should verify all of this before accepting it as fact.


Offline Kawa

Re: Can events flags be set in Internal Debugger?
« Reply #7 on: January 13, 2024, 04:31:48 PM »
I can confirm everything doomlazer just said. There are 80 defined flags in the OG source and beenIn203 as it's called there is #18.

The 117th global is named lastFlag and is not, to my knowledge, used. The next likely things to affect by changing flags higher than 78 are the player's name, the nature of the closest person, the speed test result, and the filth level. None of those are too bad when corrupted but then we get to the event handlers at global 125-127.

Offline lwc

Re: Can events flags be set in Internal Debugger?
« Reply #8 on: January 13, 2024, 05:25:53 PM »
Thanks! I wonder why sluicebox's newer repository has no SH files, if they're that useful.

But be it as it may, in ScummVM they always look in just 1 single global, in this case they look just at flag 111, so how would they know to continue looking until 117?

Offline lskovlun

Re: Can events flags be set in Internal Debugger?
« Reply #9 on: January 13, 2024, 06:03:39 PM »
But be it as it may, in ScummVM they always look in just 1 single global, in this case they look just at flag 111, so how would they know to continue looking until 117?
That function simply returns the first global used for flags, as doomlazer said. Look instead at the code in console.cpp that does the actual flag manipulation. It only does very basic range checking (are you trying to read/write past the last global variable?), but does check that the global is a number, because no flag variable should ever be anything else:
Code: [Select]
               // read the global that contains the flag
                uint16 globalNumber = _gameFlagsGlobal + (flagNumber / 16);
                if (globalNumber > s->variablesMax[VAR_GLOBAL]) {
                        debugPrintf("Invalid flag: %d (global var %d is out of range)\n", flagNumber, globalNumber);
                        continue;
                }
                reg_t *globalReg = &s->variables[VAR_GLOBAL][globalNumber];
                if (!globalReg->isNumber()) {
                        debugPrintf("Invalid flag: %d (global var %d is not a number)\n", flagNumber, globalNumber);
                        continue;
                }
                uint16 globalValue = globalReg->toUint16();
                uint16 flagMask;
                if (g_sci->_features->isGameFlagBitOrderNormal()) {
                        flagMask = 0x0001 << (flagNumber % 16);
                } else {
                        flagMask = 0x8000 >> (flagNumber % 16);
                }
The last bit of code also answers your question about how to change the flag variables. Some games order their flags from MSB to LSB, others do the opposite.
« Last Edit: January 13, 2024, 06:10:07 PM by lskovlun »

Offline doomlazer

Re: Can events flags be set in Internal Debugger?
« Reply #10 on: January 13, 2024, 07:02:04 PM »
Thanks! I wonder why sluicebox's newer repository has no SH files, if they're that useful.

The flag defines don't exist in the resources for a decompiler to recover. It's my understanding that EO sussed out the flags in that file I linked from examining the code by hand.
« Last Edit: January 13, 2024, 08:21:52 PM by doomlazer »

Offline lwc

Re: Can events flags be set in Internal Debugger?
« Reply #11 on: January 13, 2024, 08:50:11 PM »
That function simply returns the first global used for flags, as doomlazer said. Look instead at the code in console.cpp that does the actual flag manipulation.
Not sure I understand, how does it know what is the last global used for flags? There's not even a loop there.

Offline lskovlun

Re: Can events flags be set in Internal Debugger?
« Reply #12 on: January 13, 2024, 09:39:48 PM »
It doesn't. "It only does very basic range checking".

Offline Kawa

Re: Can events flags be set in Internal Debugger?
« Reply #13 on: January 14, 2024, 03:43:13 AM »
It knows only how many global variables there are, so if there's let's say 128 global variables and the flags start at global 111, you know for a fact any flag number divided by 16, plus 111, cannot result in a number higher than 128. So flag 12 is fine (12/16=0), flag 73 is fine (73/16=4, 4+111=115), flag 99 is fine (99/16=6, 6+111=117). Flag 420 is out of bounds (420/16=26, 26+111=137) because we know there's only 128 globals (this is defined by the heap part of script 0). But neither the game nor ScummVM can tell how far the flags go (though lastFlag could help here, it doesn't really need to for the programmer's sake because of the defined flag names), so it's perfectly allowed to play LSL3, set flag 128, and find your character's name is altered.

Offline lwc

Re: Can events flags be set in Internal Debugger?
« Reply #14 on: January 14, 2024, 07:58:48 AM »
flag 73 is fine (73/16=4, 4+111=115), flag 99 is fine (99/16=6, 6+111=117).
So the general formula is:
Code: [Select]
initialGlobal+int(flag/16)
Does it mean in LSL3's room's initial room 200 when you look at the plaque, flag event 18 is set in global 112 due to 111+int(18/16) (111+1) and likewise when you use binocular for flag event 16 due to 111+int(16/16)?


SMF 2.0.19 | SMF © 2021, Simple Machines
Simple Audio Video Embedder

Page created in 0.04 seconds with 24 queries.