Author Topic: SCI0 setFlag procedure  (Read 2409 times)

0 Members and 1 Guest are viewing this topic.

Offline robbo007

SCI0 setFlag procedure
« on: January 12, 2026, 07:00:08 AM »
Hi guys,
I've been using the LSL3 setFlag procedures for setting global flags which I have defined in my game.sh. Is there a limit of how many you can use? I'm getting issues using the last two. doneLana and usedElevator do not work , they create anomies when used in my RoomScript changeStates. All the others work fine.

Code: [Select]
(procedure (SetFlag flag)
(= [gFlagArray (/ flag 16)]
(| [gFlagArray (/ flag 16)] (>> $8000 (mod flag 16)))
)
)

Code: [Select]
;***** Enumerations for global flags ******

(enum
forceAtest ;Room 13
seenJodi ;Room 13
beenToFountain ;Room 10
takenMoney ;Room 10
fountainKicked ;Room 10
monnies ;Room 10
slotJackpot ;Room 514
twentyTaken ;Room 027
henchettesActive ;Room 030
gaveThreeRoses ;Room 030
SodaMachineUsed ;Room 033
lottoMachineUsed ;Room 033
gaveWax ;Room 035
mayaScored ;Room 036
gotMembership ;Room 039
sq3Journey ;Room 040
hasBike ;Room 050
doneLana ;Room 080
usedElevator ;Room 505
)



Offline Kawa

Re: SCI0 setFlag procedure
« Reply #1 on: January 12, 2026, 08:03:24 AM »
Assuming your gFlagArray is big enough (two items for 32 bits/flags) I see no reason why the last two of 19 would break. Of course, I've only gone up to nine myself even though I reserved 224. This requires scientific testing!

Code: [Select]
(procedure (TestFlags &tmp i)
(DbugStr "Clearing 4*16 flags...")
(for ((= i 0)) (< i 4) ((++ i))
(= [gFlags i] 0)
)
(DbugStr "gFlags should be cleared. Checking...")
(for ((= i 0)) (< i 4) ((++ i))
(if [gFlags i]
(DbugStr "[gFlags %d] is NOT zero: %d" i [gFlags i])
(DbugStr "Returning early.")
(return)
)
)
(DbugStr "Setting 32 flags in order...")
(for ((= i 0)) (< i 32) ((++ i))
(Bset i)
(DbugStr "%d = %d" i (Btest i))
)
(DbugStr "Clearing flags in order...")
(for ((= i 0)) (< i 32) ((++ i))
(Bclear i)
(DbugStr "%d = %d" i (Btest i))
)
(DbugStr "Test complete. Now let's see what the log has wrought...")
)

Code: [Select]
Clearing 4*16 flags...
gFlags should be cleared. Checking...
Setting 32 flags in order...
0 = -32768
1 = 16384
2 = 8192
3 = 4096
4 = 2048
5 = 1024
6 = 512
7 = 256
8 = 128
9 = 64
10 = 32
11 = 16
12 = 8
13 = 4
14 = 2
15 = 1
16 = -32768
17 = 16384
18 = 8192
19 = 4096
20 = 2048
21 = 1024
22 = 512
23 = 256
24 = 128
25 = 64
26 = 32
27 = 16
28 = 8
29 = 4
30 = 2
31 = 1
Clearing flags in order...
0 = 0
1 = 0
2 = 0
...
29 = 0
30 = 0
31 = 0
gFlags should be cleared. Checking...
Test complete. Now let's see what the log has wrought...

Ho, isn't that interesting? Btest returns the actual power of two for a set bit, which makes the 16th negative because it's a signed value. Now, it's still a truthy value because only zero is false.

Interesting, but ultimately it doesn't answer the question. I see no dummy guard rail entries in LSL5 at least, though it does say "(presently can't be more than 64)" at the end. Let me re-run my experiment with more than the 32 I did just now. 128 should do... and the result is the same.

Offline robbo007

Re: SCI0 setFlag procedure
« Reply #2 on: January 12, 2026, 10:00:31 AM »
ok cool., mine breaks at the 16th flag, so its got to be its not defined correctly.

I can't see where the gFlagArray size is defined? in LSL3 its in the game.sh but that does not seem to work in my game.sh. Or does it need to be setup in the procedure in the main.sc ?

Code: [Select]
flagArray 111

Offline Kawa

Re: SCI0 setFlag procedure
« Reply #3 on: January 12, 2026, 10:39:32 AM »
The flag array is just a global, and having more than 16 just means making it an actual array so the memory works out. For the original leaked games, that's defined in game.sh but doesn't use any array syntax. Perhaps SC's global handler couldn't do that... but it does allow enum blocks inside of global. Wow. For us commonfolk, it's all in main.sc's local block which is very confusingly named.

The difference being, SC's global block uses a "name number" syntax and needs to initialize any non-zero values on startup, while our local block (which isn't local if it's script 0) is much more flexible: "name", "name = value", "[arrayName size]", and "[arrayName size] = [values]" are all allowed, but we can't say a given global must be this index.

So if you look at the original LSL1, 3, and 5 code's game.sh, you get stuff like this:
Code: [Select]
gameFlags 111 ; bit flags start at 111 and end at 118.
endGameFlags 118 ; This gives a maximum of 128 (8*16) flags.
Followed by an enumeration of flag names, split into groups of sixteen. LSL3 helpfully adds the running global number in a comment to the first of each group.

That is, global111 is gameFlags, while global112 to 117 aren't named at all and can only be accessed as [gameFlags i]. This is effectively identical to having [gFlags 8] in an SCI Companion game.

And as such my own game has this in main.sc: [gFlags 14] ;Start of bit set. Room for 14x16 = 224 flags.... which is way more than I need right now.

There's no further setup needed.

So if your flags break the game when you use one too big, you might want to check if your flags global is big enough to fit that many, as you may be clobbering the next global in the list.

Offline robbo007

Re: SCI0 setFlag procedure
« Reply #4 on: January 12, 2026, 11:06:21 AM »
Amazing.
Thanks for the in depth explanation. That make sense now and has resolved the issue. Wohoo! One step closer to Beta haha


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

Page created in 0.05 seconds with 23 queries.