Author Topic: C# AGILE  (Read 83341 times)

0 Members and 1 Guest are viewing this topic.

Offline lance.ewing

Re: C# AGI Interpreter
« Reply #270 on: December 29, 2022, 09:49:19 AM »
No, it seems like the double "return" in LOGIC.13 is decoded fine.

It looks to me like it might be LOGIC.99 that is the problem. The 274 key value is actually in relation to LOGIC 99. Viewing that LOGIC in WinAGI shows that the "if" at the end of the script is missing an ending } which makes me wonder if maybe the LOGIC is missing something for it to jump to, i.e. the location the conditional jump is jumping to doesn't exist. I guess I could either add some code to always ensure that the decoded LOGIC has a "return" at the end, so that in cases like this there is always something to jump to, or I instead make the conditional branch more robust, so that it assumes that a missing jump location means to the end.

That second option doesn't feel clean to mean though. I think I prefer the decoding adding a "return" at the end if there isn't one.

Offline lance.ewing

Re: C# AGI Interpreter
« Reply #271 on: December 29, 2022, 10:19:42 AM »
I think I prefer the decoding adding a "return" at the end if there isn't one.

I've made this change locally on my machine and it seems to fix the issue. Unfortunately there is another issue lurking behind that one, something to do with AGI String 0, being that that String is null. I added a quick hack for that to interpret that as an empty string and that has allowed it to continue and now it appears to be showing the Christmas card without any further issues, looping back to the beginning once it has been through all the screens.

I'll make these changes permanently at some point over the next day or so. I just want to think more about why the AGI String was null and why it is only this XMAS card that it is happening on. I assume something to do with the older interpreter version.

Offline AGKorson

Re: C# AGI Interpreter
« Reply #272 on: December 29, 2022, 03:25:45 PM »
The other thing I noticed in WinAGI is that this LOGIC has two return statements at the end of it.

The extra return command is because Sierra's compiler (cg.exe) automatically adds a return statement at the end of every logic. If the programmer included a return in their source code, the compiled logic would then end with two return statements. (Goldrush also has a few examples of this phenomenon.)

It does not have any effect on gameplay; the extra return statement is never used.
« Last Edit: January 16, 2023, 04:20:24 PM by AGKorson »

Offline AGKorson

Re: C# AGI Interpreter
« Reply #273 on: December 29, 2022, 03:51:07 PM »
No, it seems like the double "return" in LOGIC.13 is decoded fine.

It looks to me like it might be LOGIC.99 that is the problem. The 274 key value is actually in relation to LOGIC 99. Viewing that LOGIC in WinAGI shows that the "if" at the end of the script is missing an ending } which makes me wonder if maybe the LOGIC is missing something for it to jump to, i.e. the location the conditional jump is jumping to doesn't exist. I guess I could either add some code to always ensure that the decoded LOGIC has a "return" at the end, so that in cases like this there is always something to jump to, or I instead make the conditional branch more robust, so that it assumes that a missing jump location means to the end.

That second option doesn't feel clean to mean though. I think I prefer the decoding adding a "return" at the end if there isn't one.
The reason for this odd situation is because this logic (it's a debug logic, probably borrowed from some other game) ends with a quit command, but was originally compiled in version 2.089 (or earlier) when the quit command didn't take an argument. So the last byte of the logic, before the message section, is in fact a return (byte code 00). But since the interpreter packaged with the game is 2.272, WinAGI thinks the quit command needs an argument, so it uses the 00 byte code. (If you change the target interpreter version to 2.089, the logic decompiles correctly.)

I know it was compiled in a version that uses no arguments for quit because of the size of the 'if' block that the quit command is inside of. It correctly points to the byte code 00 when the 'if' block returns false.

Even though the logic is being run in version 2.272 interpreter, it works fine in MSDOS because the 'if' block has the correct offset value. And if the 'said' command evaluates to TRUE, you also don't see any effect of this when run in MSDOS because the quit command terminates the game immediately, and never tries to read past the end of the logic.

You did help me find an obscure bug in WinAGI's decompiler. Since the decompiler thinks the last byte is part of the quit command, it hiccups when it then tries to add the ending bracket because the decompiler's index is one past the expected value. That's why the bracket is missing. I've added a check for this in case it comes up in any other games.

Offline AGKorson

Re: C# AGI Interpreter
« Reply #274 on: December 29, 2022, 03:59:59 PM »
Unfortunately there is another issue lurking behind that one, something to do with AGI String 0, being that that String is null. I added a quick hack for that to interpret that as an empty string and that has allowed it to continue and now it appears to be showing the Christmas card without any further issues, looping back to the beginning once it has been through all the screens.

I'll make these changes permanently at some point over the next day or so. I just want to think more about why the AGI String was null and why it is only this XMAS card that it is happening on. I assume something to do with the older interpreter version.
The concept of a null string has no meaning in the MSDOS interpreter. When a game starts, the string table starts as all zeros. So any functions that read the string values will return a valid string of zero length. My guess is that your interpreter is not setting all 24 (or 12, depending on version) strings to valid zero length strings on start up. If you do that, you shouldn't have any problems with 'uninitialized' strings.

Offline lance.ewing

Re: C# AGI Interpreter
« Reply #275 on: December 30, 2022, 06:04:18 AM »
The reason for this odd situation is because this logic (it's a debug logic, probably borrowed from some other game) ends with a quit command, but was originally compiled in version 2.089 (or earlier) when the quit command didn't take an argument. So the last byte of the logic, before the message section, is in fact a return (byte code 00). But since the interpreter packaged with the game is 2.272, WinAGI thinks the quit command needs an argument, so it uses the 00 byte code. (If you change the target interpreter version to 2.089, the logic decompiles correctly.)

I know it was compiled in a version that uses no arguments for quit because of the size of the 'if' block that the quit command is inside of. It correctly points to the byte code 00 when the 'if' block returns false.

I'm trying to think through if that is the cause of the original issue that Collector reported and I think it is. AGILE will also be seeing that it is interpreter version 2.272 and will therefore decode the "quit" command with the parameter, which explains why the decoded LOGIC doesn't have a "return" at the end. AGILE does support the "quit" command without the parameter, but only if it thinks it is 2.089.

My workaround fixes the issue, and I guess it isn't going to harm anything, i.e. having an additional "return" statement at the end. It can't really determine that the LOGIC was compiled for 2.089, not when the XMAS card "game" was presumably compiled with a mixture of different CG compiler versions. I could add an interpreter version to the game detection data, but that would assume it applies to all LOGICs in the game, so it wouldn't work for this XMAS card game, unless we assume all LOGICs were compiled under 2.089.

Offline lance.ewing

Re: C# AGI Interpreter
« Reply #276 on: December 30, 2022, 06:08:27 AM »
The concept of a null string has no meaning in the MSDOS interpreter. When a game starts, the string table starts as all zeros. So any functions that read the string values will return a valid string of zero length. My guess is that your interpreter is not setting all 24 (or 12, depending on version) strings to valid zero length strings on start up. If you do that, you shouldn't have any problems with 'uninitialized' strings.

I suspected that this was the case, i.e. that AGI doesn't have this distinction. Thanks for confirming this. Yeah, your suspicion is correct, that AGILE doesn't initialise the AGI strings to be empty. I'll fix this now.

Edit: This is now fixed and pushed to my github repo.
« Last Edit: December 30, 2022, 06:29:16 AM by lance.ewing »

Offline Collector

Re: C# AGI Interpreter
« Reply #277 on: May 13, 2024, 08:46:58 PM »
Lance, did you ever decide on the license you want to use for AGILE?
KQII Remake Pic

Offline lance.ewing

Re: C# AGI Interpreter
« Reply #278 on: May 14, 2024, 02:03:21 AM »
I might go with GPLV2. That is what I went with for agile-gdx but that was mainly because the original JAGI was using that, from where agile-gdx borrowed some of the AGI resource reading code. I don't think it matters too much and it is what you have for the NSIS-Installer anyway. I think that's fine.

Offline Collector

Re: C# AGI Interpreter
« Reply #279 on: May 14, 2024, 09:46:23 AM »
The license I had for the installer was just a placeholder. I'll leave it as is, then. I have created initial Wiki pages for the C# AGILE and AGILE-gdx. I needed a license to complete those as well.

http://agiwiki.sierrahelp.com/index.php/AGILE

http://agiwiki.sierrahelp.com//index.php/AGILE-gdx

Feel free to make whatever changes you want to.
KQII Remake Pic

Offline Collector

Re: C# AGILE
« Reply #280 on: May 29, 2024, 06:40:49 PM »
Hey Lance, were you going to incorporate your changes into the C# version that adds support for AGI Mouse and the other hacks?
KQII Remake Pic

Offline lance.ewing

Re: C# AGILE
« Reply #281 on: May 30, 2024, 04:33:07 AM »
Yeah, it is definitely on my todo list. You might be one of the first to notice when I begin working on that, as I think I would be starting by making changes to the AGI Library first, then submit a PR to you to get it merged into the master of the library in your repo. Not sure at the moment when I'll be taking a look at that. I'm still a bit distracted with a few mysteries in relation to the original AGI interpreter source code.

My mind is more in research mode rather than coding mode at the moment. I'm thinking about writing a follow up article to the Space Quest II Master Disk article, but I doubt it would be as popular, as I'm thinking of something a bit more technical. Recently I've been compiling some files in the original AGI source using the Mark Williams C compiler, which appears to be what they used for compiling, and then linking them with PLINK86, which appears to be what they used for linking.

I don't think I'm using the same versions as they used, as the version spread for those tools, as far as availability online is concerned, is very limited. I've found several fragments of OBJ module files on the KQ3 v2.14 720K disk 1 that suggest Sierra used version 2.3.8 of the Mark Williams C compiler. I can't find any trace of that on the Internet, but I have found a v3 and a v4 version. The v3 version doesn't compile to the standard OBJ module format though, but the v4 one does. So that's the one I'm experimenting with at the moment. That version was apparently released in 1987, in fact prior to the assumed date of the AGI source on the SQ2 disk, so it feels somewhat appropriate to use that version, even if Sierra may have been using an older version of the compiler.

PLINK86 is what provides the overlay mechanism that AGI uses. The memory map file hidden on the SQ2 disk is an output file from the PLINK86 tool. When the MAP option is used with that tool, it produces a file of that format, and the one on the SQ2 disk is essentially complete. It is missing the first 4-5 pages, but I was able to recreate most of that, since the missing bit was mostly an alphabetic list of symbols with their addresses. That same information is in the Modules section but arranged in a different way, i.e. within each module. So I used that to recreate the missing bits from pages 1-5. The only bit that is missing now is the top 10 lines. I'm playing around with PLINK86 with some test modules to see what would normally be in those 10 lines, the idea being that maybe I can guestimate what the AGI memory MAP file had in it for those lines. Long story short, the memory map file is essentially complete. I'm planning to add it to the agi repo on github once I think I have it as close to what it originally was as possible.

It would be an interesting exercise to see if these two tools, i.e. MWC and PLINK86, can be used to compile the complete AGI.EXE from the original source, with the missing 20% of the code perhaps borrowed from NAGI and the various disassemblies that we have. I reassessed the amount of original AGI source code that we have, stating now in the github repo README that it is 80%. My original estimate was based on the number of files, which is still calculated to be about 75%, with the inclusion of the extra source files from the KQ3 disk, but if we look instead at the actual amount of code across all modules, then it works out to be 82%. I rounded that down to 80% in the readme, as I didn't want to be too exact, as it probably depends a little on what exactly you count.

Offline Collector

Re: C# AGILE
« Reply #282 on: May 30, 2024, 08:10:21 AM »
No rush. Sounds like a full plate. I was just going to build the latest of my version tool for Threepwang to help with adding a few missing pieces of game versions and I included AGILE with it as a tool to help determine what information can be found in game. A command line tool to decompile the logics of the target game might be better, though. Most of the missing bits are the fan games with hacks. I guess I can do a build with AGILE in its current form for now.
KQII Remake Pic

Offline Collector

Re: C# AGILE
« Reply #283 on: June 04, 2024, 05:24:13 PM »
Another thought. How possible would it be to add support for AGI games from other platforms like SVM does? If possible, would it be too much work to do so? If it can be I would say at least Apple, Mac, Atari ST and Amiga would be the main alternative platforms to support.
KQII Remake Pic

Offline lance.ewing

Re: C# AGILE
« Reply #284 on: June 05, 2024, 12:31:32 AM »
I am definitely very keen to support the Apple II games. Does scummvm support those? From what I can tell, every AGI game except for Manhunter: San Francisco was released for the Apple II. I have all of the disk images ready to try at some point. Can't remember now whether they released a version of KQ1 for the Apple II that wasn't GAL, so support for KQ1 on the Apple II would depend on that, I mean, I wouldn't try to support GAL. After the Apple II games, I think I would then attempt the Atari ST, then Amiga, Mac and Apple IIgs. If they all used roughly the same data formats, then it shouldn't be too difficult, in fact all the work would be in the AGI Library and what comes out of there would look the same as far as AGILE is concerned. Some of the data formats are known to be slightly different though, e.g. AGKorson mentioned to me that the Amiga OBJECT files are different. So the work would involve adding the code to find the data on the disk images and then the handling of any differences in the way the data is stored. If it turns out that on a particular platform they had to use a different screen coordinate system, and modified the AGI commands that deal with AGI screen positions, then that would be a lot more difficult to handle, as that would start to leak into the AGILE code itself.


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

Page created in 0.048 seconds with 24 queries.