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.


Topics - Charles

Pages: [1]
1
SCI Development Tools / SCI01 interp decompiling
« on: December 10, 2020, 04:58:52 PM »
So I was procrastinating on another project and idly wondering what it would take to decompile the SCI01 interpreter and re-incorporate text parser code into SCI11.

This is a nearly 30 year old program.. surely there must be decent decompilation software out there now, right?  I found one called Reko Decompiler that looked promising.  I opened it up, but it reported the file was compressed with LZEXE.  I noticed that Eric already knew that, and has already decompressed it in the SCI01 template.  But when I opened it up again in Reko, I found it was still partially compressed a second time with EXEPACKER.

So after hunting far and wide, I finally found a dead link to a DOS program that can unpack EXEPACKER files. A trip to the WayBackMachine found a working link, and in DOSBOX I was able to uncompress it yet again.

Now, Reko was able to process the thing. And here's where I've reached my level of incompetence. There were a small handful of errors decompressing, but there looks to be actual code -- that is bereft of any ral variable names -- so it might as well be gibberish to me.  Anyway, I've gone as far as I probably can with it, but I thought it was interesting that the EXE was compressed in two different ways, and wanted to share. I've also attached the hard to find unpack.exe, if somebody else wanted to give it a go.

2
SCI Community How To's & Tutorials / Retry/Restore/Quit Death Dialog
« on: December 09, 2020, 02:45:32 PM »
As I detailed in the "What are we working on?" thread earlier, I've modded QFG1EGA to implement a "Retry" feature when the Hero dies.

I was absolutely floored by the positive encouragement I've received in the community, so I wanted to share how I implemented it, so others could also implement in their games (or mod existing Sierra games).

My goal with "Retry" was to remove a potential point of frustration for new (and old) players being punished for exploring the game and trying things. However, I didn't want to eliminate the deaths entirely, because they are a fundamental part of the Sierra experience, and are part of each Sierra game's unique charm.

My particular solution was to replace game-ending deaths with an additional achievement system, which not only keeps track of which deaths the user encountered but also displays them (like QFG1EGA's inventory screen).

I chose a "minimally invasive" approach, whereby I only reverted the specific events that caused the death (and any items directly branched off from that death, if the death wasn't instant), leaving the rest of the users experiences intact.

I had to modify/add five things to make this happen:
  • game.sh (modified)
  • main.sc (modified)
  • menu.sc (modified)
  • DeathSheet.sc (added)
  • any script that calls the EgoDead function

To keep track of each unique death, I created an Enum. Because this can grow fairly large (QFG1EGA had 79 Unique Deaths), I decided to create a new file and reference it in game.sh, rather than putting everything into game.sh itself.
Code: [Select]
;These are death flags. They're used to track which ways the user has died. 
;They will be shown at the end of the game.

; unique deaths
(define DIE_RESTART -2) ;show Restore, Restart, Quit; (same as not specifying anything at all) instead of Retry, Restore, Quit)
(define DIE_RETRY -1) ;show a Retry, Restore, Quit
(define DIE_NOFLAG -1) ; a retry is shown, but nothing is flagged.
;explicitly define the starting number, ending number and death count, which will be used in the DeathSheet script.
(define DIE_START 450)
(define DIE_COUNT 79)
(define DIE_END 528)
;there are roughly 100 deaths, so we'll reserve flags 450-550 for them (with room for 50 more in expansion up to flag 600)
(enum 450
DIE_NOSTAMINA
DIE_PICKNOSE
DIE_ARRESTED
DIE_NIGHTGAUNT
)

Next up is modifying the EgoDeath function in main.sc.  Keeping track of the different deaths is done with the eventFlags variable, and Btst, Bclr, Bset. I don't know if every Sierra game includes them or not, so if they're not present, you'll need to add them. the eventFlags variable must be an array. Each byte of the array can hold 16 bits (or 16 individual flags).  QFG1EGA allocated 50 bytes (800 flags), and didn't use nearly all of them, so I was able to just use them without allocating any more space.
Code: [Select]
(procedure (Bset bit)
(= [eventFlags (/ bit 16)]
(|
[eventFlags (/ bit 16)]
(>> $8000 (mod bit 16))
)
)
)

(procedure (Bclr bit)
(= [eventFlags (/ bit 16)]
(&
[eventFlags (/ bit 16)]
(~ (>> $8000 (mod bit 16)))
)
)
)

(procedure (Btst bit)
(return
(&
[eventFlags (/ bit 16)]
(>> $8000 (mod bit 16))
)
)
)

Then the EgoDeath function. In QFG1EGA it's the first global function in main.sc, so I assume that's constant across all Sierra games.
Code: [Select]
(enum 1
RESTORE
RESTART
QUIT
RETRY
)

(procedure (EgoDead what how &tmp printRet)
;stops all sounds, plays the death music, and gives the player a choice:
; Restore, Restart, Quit or
; Retry, Restore, Quit
;
; 'what' decides what we're doing: Restart or Retry.
; if 'what' == DIE_RETRY (-1), it's a Retry death;
; if 'what' == DIE_RESTART (-2), it's a Restart death (explicitly defined).
; any other values are assumed to be the original EgoDead function, for a Restart death (implicitly defined),
; and should be fully passed to the Print procedure.
;
; 'how' is this specific death's flag, to be set in the eventFlags variable, via the Bset function
;
; (CI: NOTE: This procedure is a recreation, based on Eric Oaklands's SCI01 template)
; https://github.com/EricOakford/SCI01-Template/blob/master/src/Main.sc
; it has been modified to more closely match the original asm, which is commented out but intact above,
; then has been further modified to support a Retry mode.

(HandsOff)
(Wait 100)

(theGame setCursor: normalCursor TRUE)
(sounds eachElementDo: #stop)

(if (!= deathMusic NULL)
(music number: deathMusic priority: 15 init: play:)
)

;if we're specifying a way the player died, then we'll set the flag for that death method.
(if (and (== what DIE_RETRY) (!= how DIE_NOFLAG))
(++ deathCount)
(= prevDeathNum how) ;we're going to flag out *every* time the hero dies.
(if (not (Btst how))
(Bset how)
(++ deathCountUnique)
)
)

(repeat
(= printRet
(cond
;1st priority: the new Retry dialog
((== what DIE_RETRY)
(Print &rest
#width 250
#button { Retry_} RETRY
#button {Restore} RESTORE
#button { Quit_} QUIT
)
)
;2nd priority: an explicit DIE_RESTART flag with no second parameter
((== what DIE_RESTART)
(Print how &rest
#width 250
#button {Restore} RESTORE
#button { Restart_} RESTART
#button { Quit_} QUIT
)
)
;finally, any original script EgoDeath scripts
((>= what 0)
(Print what how &rest
#width 250
#button {Restore} RESTORE
#button { Restart_} RESTART
#button { Quit_} QUIT
)
)
)
)
(switch printRet
(RESTORE ;restore
(theGame restore:)
)
(RESTART ;restart
(theGame restart:)
)
(QUIT ;quit
(= quit TRUE)
(break)
)
(RETRY ;retry
(if (!= deathMusic NULL)
(music stop:)
)
(HandsOn)
(break)
)
)
)
)

If you wanted, you could stop here and compile your game without changing anything else. All existing calls to EgoDead will continue to function as they always have, bringing up the RESTORE/RESTART/QUIT dialog.

I'll describe the DeathSheet and actually implementing the new EgoDead function in game script in the next post.

EDIT: I forgot, I also added a couple of global variables to main.sc.  There were several unused variables in QFG1EGA, so I was able to just rename one of them, without adding any more.
Code: [Select]
deathCount ;added by CI: the total number of times Ego has died (shown on the Death List)
deathCountUnique ;added by CI: the number of unique ways Ego has died (shown on the Death List)
prevDeathNum ;added by CI: Used to highlight the most recent death in the Death List.

3
SCI Syntax Help / editing PICs
« on: October 10, 2020, 12:05:22 PM »
When editing a pic in SCICompanion, is there an easy way to nudge lines, either indivdiually or in a group?

In my specific case, I have a view with three boxes drawn on it, and I want to change where I've put those boxes.  I don't want to redraw the boxes from scratch, because they're fairly intricate, but I no longer like where I've placed them.

4
SCI Syntax Help / Problem recreating QFG2 source
« on: May 02, 2020, 03:56:12 PM »
Im working on recreating the source for QFG2, using a mix Ericís source from the decompilation archive and my own efforts decompiling from scratch.

The problem is Iím seeing what feels like a memory corruption error and I donít even know where to begin to troubleshoot it.

In a nutshell it looks like variables arenít being set properly. Take this one instance in script 000, near the end of Trial:init (which isnít that like the first code the game runs?)
Code: [Select]
(= possibleScore 500)
(Printf {possibleScore is %d} possibleScore)
It prints the message ďpossibleScore is 0Ē

Part of the problem Iím having is that I donít think thereís anywhere *before* there that I can fix. I havenít done any extensive troubleshooting, but given what Iím seeing, I donít know where to begin. Any thoughts?[/code]

5
Didn't see this posted elsewhere on here, and thought everyone'd be interested.

https://www.kickstarter.com/projects/klytos/the-sierra-adventure-the-story-of-sierra-on-line

Shawn Mills, one of the co-founders of Infamous Quests, has written a book about the history of Sierra, and has started a kickstarter to get it professionally edited and printed.

Some of the Backer Rewards include autographed copies from The Coles (already gone), and Josh Mandel.

Looks interesting.


6
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?

7
SCI Development Tools / Recreating complete QFG1 EGA source code
« on: June 12, 2016, 11:05:00 PM »
So I've decompiled QFG1 EGA, and am going through trying to replace any proc# or localproc# with actual descriptive names (same for global variables, etc), and it's going fairly well. I'd say I'm learning a lot about SCI scripting in the process, but there are a couple of items/questions that have come up that I'm not sure how to interpret.

1) in script 968 (SmoothLooper) the doit method of the SmoothLooper class decompiles into this:
Code: [Select]
(method (doit &tmp [temp0 2])
CorruptFunction_CantDetermineCodeBounds
)
So clearly something unexpected is going on with the byte-code. I'm not really too keen on understanding the raw byte-code, but at the very least is there a way to force SCICompanion to try converting it to asm?  Unless anybody has an other suggestion?

2) kernel_113 is called in several scripts (1, 255, 202, 32).  Is this an undocumented kernel call?  No clue what it is supposed to do.

3) DoSound. The documentation (http://scicompanion.com/Documentation/Kernels/DoSound.html?highlight=sndCHECK_DRIVER) says that DoSound(sndCHECK_DRIVER) only returns TRUE or FALSE, depending if the sound driver is installed, however there is code in QFG1 to the effect of (DoSound(sndCHECK_DRIVER) == 1), (DoSound(sndCHECK_DRIVER) <= 4), (DoSound(sndCHECK_DRIVER) > 4), implying it is more along the lines of the number of music channels present.

That's about all I have for now. Thanks for reading.

Pages: [1]

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

Page created in 0.122 seconds with 20 queries.