Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Charles

Pages: [1] 2 3 4
1
SCI Syntax Help / Re: Can someone explain Flags to me?
« on: July 12, 2019, 10:50:10 PM »
I betcha whatís happening is the compiler is interpreting the |= as:
Code: [Select]
(= [gameFlags (/ (/ flagEnum 16) 16)] (| [gameFlags (/ flagEnum 16)] (>> $8000 (mod flagEnum 16))))

So, dividing the flag# by 16, then by 16 again.

If thatís the case, Iíd expect (Bset 16) to actually set flag 0, (Bset 17) to set flag 1, etc. and (Bset 256) to set flag 16.

2
SCI Syntax Help / Re: Can someone explain Flags to me?
« on: July 10, 2019, 11:10:18 PM »
Iím leaning towards there being an error in the Bset procedure.

Try doing some methodical testing:
Code: [Select]
(Bset 0)
(FormatPrint ... the game flag print code)
(Bset 1)
(FormatPrint  blahblah)
(Bset 69)
(FormatPrint ...)

Incidentally, the 8400 from the earlier output translates to binary 1000 0100 0000 0000, i.e. flag 0 and flag 5 are true. An easy way to convert is just ask google (or DuckDuckGo) for ď0x8400 in binaryĒ. With 0x#### being a common shorthand for ďhex numberĒ.


3
SCI Syntax Help / Re: Can someone explain Flags to me?
« on: July 10, 2019, 09:30:38 AM »
Is there a way to flush print the contents of gameFlags all over so I can check if the wrong bit is getting set for the bag?  I wouldn't even know how to go about fixing that, but I really just can't see anything that would cause this behavior and it's the only thought I'm having.

Try using %x instead of %d for the formatting. That'll display the hex value, instead of the signed number.  That'll make it easier to paste into your favorite hex calculator (I love Win10's calculator with it's Programming mode, for seeing hex and binary values).

How many bytes is your flag array?  It sounds like your Bset procedure isn't limiting itself to the specified bit. The code looks fine to me though, so to debug and see exactly what's in the flag arrays try: (so if your flag array is 5 bytes long)
Code: [Select]
(FormatPrint
    "gameFlags: %04x %04x %04x %04x %04x"
    [gameFlags 0]
    [gameFlags 1]
    [gameFlags 2]
    [gameFlags 3]
    [gameFlags 4]
)

Then convert that number into binary, and see the state of each flag.

4
SCI Syntax Help / Re: Can someone explain Flags to me?
« on: June 12, 2019, 02:46:40 PM »
Also considering the AddToScore procedure, which relies on the Btst/Bset/Bclr trio, let's round down to a hypothetical 50 flags being read in a single scene ( i.e. the current script, main.sc, game.sc, and whatever locales and regions are also included with the current script).  Is that a practical consideration?  50 flags read in a single game scene sounds more than sufficient, but I haven't done compared many games.

The only code I've really looked through is QFG1, and I'm struggling to recall if it ever did more than 5 flag read/writes in a single scene.

5
SCI Syntax Help / Re: Can someone explain Flags to me?
« on: June 12, 2019, 12:14:07 PM »
You can put them wherever. You can define then, or use enums. Enums are actually a bit easier to manage.  I mean, heck, if you wanted you could just use numbers for everything and keep it in your head.  Defines and Enums make no difference to the compiled code. They're only for making your code easier to read.  When they get compiled, the compiler will basically just do a find/replace with the defined or enumerated value.  They both have their place.  Defines are great for one-off values. Enums are great if you're defining a bunch of sequential values, like flags.

You could put enums in a seperate .sh file and include that in game.sh (although if you do that, the tooltip may not properly show up in SCICompanion when you hover over it).

I'll show you the more complicated example, and let you pare down as necessary. So if you have 160 flags to play with (as in the template game default), you can make those flags be whatever you want. Let's say your game has 40 rooms, and you want to know if ego has visited any room before. Then you have another 120 flags for game states or puzzle points.  You can break those up into multiple enums for easier readability.

in Game.sh:
Code: [Select]
;;; Sierra Script 1.0 - (do not remove this comment)
;put the Sierra Script comment at the top, so we can use sierra script in the header file
(include gameEnumVisited.sh)

create a new file called gameEnumVisited.sh:
Code: [Select]
;;; Sierra Script 1.0 - (do not remove this comment)
(enum    ;the default starting point is 0, although you can specify another)
   FLAG_VISITED_ROOM1    ;this is given a value of 0
   fVisitedRoom2                 ;this is given a value of 1
   VISITED_RM3                 ;this is given a value of 2
   ;... continue for as many as needed
   ;NOTE, flags can be called whatever you want, but being consistent with your naming will make your code easier to read.
)

(define FLAG_ROOM4  3)  ;we've explicitly given this a value of 3. We could have also made this the next line in the enum

;game states are called out here
(enum 40  ;we're starting this enum at 40, for the game state flags.
    fEgoIsJumping  ; has a value of 40. For when ego's jumping off a massive cliff.
    FLAG_BABAFROG ; has a value of 41. For when ego has turned Baba Yaga into a frog.
)

;puzzle points are defined here, so the user doesn't double-dip on points.
(enum 120
    POINTS_JUMPED ;120.  User jumped. Yay. Give yourself 5 points.
)

Then in each room's script, in the dispose code you would add the following
Code: [Select]
(method (dispose)
(Bset FLAG_VISITED_ROOM1) ; sets flag#0 to 1 (i.e. turns it on, or sets as TRUE)
                ;we'll also give the user some points, because the had to jump to leave the room
                (AddToScore POINTS_JUMPED 5) ;the AddToScore procedure will only add points if the POINTS_JUMPED flag is 0. 
                ;So no other checking is required. The user will only get 5 points once.
(super dispose:)
)

Keep in mind that you can still use Btst to check if points have been awarded. It's still just a flag.

6
SCI Syntax Help / Re: Can someone explain Flags to me?
« on: June 12, 2019, 11:06:55 AM »
It can be fun to learn about bit operations and binary/hex and all of that, but like Kawa said, that's all irrelevant knowledge for the Btst, Bset and Bclr procedures.  They do all the heavy lifting for you.

All you need to remember is that a single variable can hold 16 flags.  So the template game has 10 variables assigned to the gameFlags array. Ergo, 160 flags.  The first flag is flag #0, the last is flag #159. If you need more flags, extend the array; you get 16 more flags for each variable you extend the flag array.

You tell the Btst, Bset and Bclr procedures which flag number you want to test/set/clear.  And you should use an enum to track your flags, just to make things easier to read/follow. The enum's won't use any memory since the compiler will hardcode whatever number the flag is when compiling.

Here's how Btst, Bset, and Bclr compare to similar statements using individual global variables, assuming your global variable is named gVar1 and you want to replace it with a flag defined as FLAG1:
Code: [Select]
(Btst FLAG1)
(== gVar1 TRUE)

(Bset FLAG1)
(= gVar1 TRUE)

(Bclr FLAG1)
(= gVar1 FALSE)

7
SCI Syntax Help / Re: Loading External Scripts on the Fly?
« on: June 10, 2019, 11:50:03 PM »
Two ways come to mind:
I simplified the Tavern example, for simplicity's sake.  The Look external script (again, script 339) is actually:
Code: [Select]
(public
SaidLookTavern 0
TavernLookAround 1
TavernLookAtStool 2
)

(procedure (SaidLookTavern)
(cond
((Said '[<at,around][/!*,room,building,tavern,establishment]')
(TavernLookAround FALSE FALSE)
)
;snip
)
(DisposeScript TAVERN_LOOK)
)

(procedure (TavernLookAround firstTime doDispose)
(HighPrint 339 22)
;The grimy window lets little light into this tavern.  It smells like stale ale and other more unpleasant things.
;The floor is covered with dirt, and the bar with sticky beer.
(HighPrint 339 23)
;Smoke appears to be rising from the center cask behind the bar.  To your right, two gamblers are playing cards.
(if firstTime
(HighPrint 339 24)
;The bartender glares at you as you enter, and so does the ugly goon on the left. You get the impression that you are not welcome.
)
(if doDispose
(DisposeScript TAVERN_LOOK)
)
)

Then in the main Tavern.sc (script 331), when you enter the tavern for the first time, it will call (TavernLookAround TRUE TRUE), which will add the extra bit about the bartender glaring at you, then will unload itself from memory.  So you might be able to rework your local variables enough that you can call global procedures passing those local variables as references. I don't honestly know the memory impact global procedures have vs global variables, but I would assume procedures is less.

The other thing that comes to mind is using Btst, Bset, Bclr global flags, instead of global variables. You may have some global variables that are only used for TRUE/FALSE values, which could be condensed into flags instead.  A flag only uses 1 bit of memory, whereas a global variables uses 16 bits.

8
SCI Syntax Help / Re: Loading External Scripts on the Fly?
« on: June 10, 2019, 11:35:28 AM »
QFG1EGA did this in a couple places. Here's a snippet from the tavern:

TownTavern.sc: (script 331) in the Room's handleEvent:
Code: [Select]
(method (handleEvent event)
(cond
((super handleEvent: event))
((!= (event type?) evSAID))
(Said 'look>')
(SaidLookTavern event)
)
;snip a bunch more cond's
)
)

Then in an external script file, which I named RM331_Look.sc (script 339)
Code: [Select]
(script# TAVERN_LOOK)
(public
SaidLookTavern 0
)

(procedure (SaidLookTavern)
(cond
((Said '[<at,around][/!*,room,building,tavern,establishment]')
(HighPrint 339 22)
)
((Said '/barrel,barrel')
(HighPrint 339 0)
)
((Said '/dirt')
(HighPrint 339 1)
)
;etc...
)
(DisposeScript TAVERN_LOOK)
)

9
SCI Development Tools / Re: Decompilation Archive
« on: May 22, 2019, 01:59:35 PM »
Made some more improvements:
  • fixed two incorrect decompilation lines in rm171 (arenaBearChange)
  • split game.sh into multiple headers
  • manually decompiled Main.sc::EgoDead asm into Sierra Script (script 0)
  • manually decompiled BoxSelector.sc::chAlloc::init asm into Sierra Script (script 203)
  • manually decompiled TargetRange.sc::rm73::init asm into Sierra Script (script 73)

edit: fixed a variable name I copy/pasted incorrectly in arenaBearChange.sc, and fixed a long-standing bug in RandomEncounter.sc, where escaping from a fight sets Ego to Walk instead of Run.

10
SCI Development Tools / Re: Decompilation Archive
« on: May 06, 2019, 01:17:49 PM »
I've done a bit of touch-up work on Eric's excellent QFG1EGA src (v3).  A lot of minor changes:
  • replaced all view reference numbers with defines
  • replaced all OnControl and IllegalBits with defines
  • replaced all EncRoom::entrances with defines
  • replaced some StudioScript constants with SSCI constante (evKEYBOARD->keyDown, evJOYSTICK->direction)
  • gave names to all default global variables
  • renamed gCast, gRegions, gSounds, etc to their original SSCI names
  • fixed the (= controls controls) bug I mentioned in another thread
  • converted FLAGS to enum instead of individual defines
  • converted all Btst, Bclr, Bset flags to use the enum constant instead of a number. If I didn't know what the flag did, i named it FLAG_#, to make it easier to search for and trace later
  • added comments describing how the TrySkill and SkillUsed functions work
  • added defines for certain hardcoded values, like Ogre, kobold, Brutus Max HP; and the skill level needed to solve certain puzzles
  • I think that's the gist of it, but there were many little touches here and there so I may have missed mentioning something

It compiles, and I've done a quick play-through of a couple rooms without noticing any problems, but I haven't done an extensive start-to-finish run yet.

11
SCI Development Tools / Re: Decompiler ambiguity for SCI0 and SCI01
« on: May 06, 2019, 12:57:45 PM »
Thank you, that was exactly what I was looking for!

I don't know enough about assembly to really do anything yet, but I'd like to learn more. I know I came across some pages before on how to decompile SCI byte code, but I haven't been able to find them again for the longest time.

Aha, wait a sec, here we go! This was what I was looking for. An earlier blog post from you: https://mtnphil.wordpress.com/2016/04/09/decompiling-sci-byte-code-part-1/

And a wiki page to help decipher the assembly codes: https://wiki.scummvm.org/index.php/SCI/Specifications/SCI_virtual_machine/The_Sierra_PMachine

I think I'll give those a read when I find the time.  Thanks again for your help.

12
SCI Development Tools / Re: Decompiler ambiguity for SCI0 and SCI01
« on: May 03, 2019, 01:33:45 PM »
In (= controls controls) above, it clearly sets the Rm::controls property to a reference to the controls instance.
I don't think it clearly does that, but I do agree it's the most reasonable assumption.

I know how to rename things to avoid the conflict, but I was hoping to actually confirm the reasonable assumption.

13
SCI Development Tools / Re: Decompiler ambiguity for SCI0 and SCI01
« on: May 02, 2019, 11:47:19 PM »
Iím less concerned with fixing this in the general case for the decompile than I am in solving it manually in this specific case. This feels like an edge case, so my interest is more for accuracyís sake (for both the template and the decompilation archives).

How would one go about figuring out what the original control variables reference in that line? And is there a way without laboriously examining the bytecode?

14
SCI Development Tools / Decompiler ambiguity for SCI0 and SCI01
« on: May 02, 2019, 04:19:14 PM »
I was looking through the decompiled QFG1EGA, and noticed something I think might be decompiling wrong, and I wanted to get other opinions on.

I've tried this in fresh decompilations for LSL3, QFG1EGA and QFG2, all with the same results. In script 994 (GAME.SC) it decompiles to (trimmed unnecessary code):
Code: [Select]
(instance controls of Controls
(properties)
)
(class Rm of Rgn
(properties
controls 0
)

(method (init &tmp temp0)
(= controls controls)
)
)

So there's a script instance called controls, and there's a property in the Rm class called the same thing.  In the Rm class, it's assigning (= controls controls).  Looks like the IDE assumes they're referencing the same thing, the control property (and I assume the compiler does the same), but I believe the original code being decompiled is actually (= <property>controls <instance>controls).

Can anybody confirm what's going on, or am I way off base?

15
Everything-Else / Re: Infocom Source Code Released (in ZIL language)
« on: April 17, 2019, 09:21:24 AM »
Anybody know if there's any easy way to download them all? I'd rather not download 131 individual repositories if it can be avoided.

Pages: [1] 2 3 4

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

Page created in 0.135 seconds with 20 queries.