Author Topic: Java AGI Interpreter by Dr Zoltan  (Read 1498 times)

0 Members and 1 Guest are viewing this topic.

Offline Collector

Re: Java AGI Interpreter by Dr Zoltan
« Reply #15 on: October 29, 2016, 12:21:40 PM »
That is old enough for the old MegaTokyo forums. If only they were still accessible.
KQII Remake Pic

Offline lance.ewing

Re: Java AGI Interpreter by Dr Zoltan
« Reply #16 on: October 30, 2016, 06:09:00 AM »
For those who are interested, this is where I've set up my "fork" of the Java AGI interpreter:

https://github.com/lanceewing/jagi

My current work is under this feature branch:

https://github.com/lanceewing/jagi/tree/feature-appleii-kq2

The first commit was pretty much exactly what was in the sourceforge CVS repo. I say pretty much because I stripped out some native bits and pieces for Mac and Win32 that weren't really needed for what I'm doing. I've worded the project description such that it is focused on the pre-AGIv2 investigation work at this stage. As I go along, I'll probably end up fixing things in the Interpreter code as well (since its not really that playable at present), but for the time being I'm working mainly in the viewer/decompiler/debugger parts.

It has been very useful actually. I've been bringing up each of the LOGIC scripts in the Apple II KQ2 game and wherever it falls over during the decompilation, it is usually due to encountering a test or action command that I haven't yet identified and mapped. So I try to work out what it is at that point. Half the time I can identify what it should be, but the other half I end up assigning an "unknown" action to it. I have defined various unknown test and action commands, one for each number of parameters. This allows the decompilation to continue and ends up displaying something like "unknown(8, 30);" or whatever at that point in the code.  Once the end of the script is reached, I can compare it with the AGI v2 version of KQ2 to see if I can work out what the unknown command might be. The scripts are hardly ever the same between the two versions, the AGI v2 version usually having more code in it, but they're similar enough to be able to help with working things out.

I have noticed a number of scripts where the decompiler code gets itself confused with jumps and ends up falling over. Quite often this is due to a stack over flow error, where it calls the decompile method recursively and never seems to be able to get out of it. It looks like this happens in some of the logic that processes the 0xFE goto/else opcode. I think if it encounters such an unconditional jump in the middle of a block of code that happens to be wrapped in an IF/ELSE structure (but not placed such that it forms part of that structure), and if that jump is to code outside of the IF/ELSE block, then it goes in to a bit of a panic. Such a "goto" scenario is fairly common in AGI scripts, which is why it seems more likely that "goto" was a keyword in the original language rather than all jumps being part of a loop or if/else structure. The Java AGI interpreter's decompiler attempts to identify "for", "while", and "do..while", but I think this might be futile. It is probably best that it does what AGI Studio does, which is that any jump that can't be matched to an if/else structure is output as a goto. - When I get a chance, I'm going to rewrite it's decompile code to make it a bit simpler and to essentially do what AGI Studio does.
« Last Edit: October 30, 2016, 06:14:13 AM by lance.ewing »

Offline OmerMor

Re: Java AGI Interpreter by Dr Zoltan
« Reply #17 on: October 30, 2016, 06:57:57 AM »
Such a "goto" scenario is fairly common in AGI scripts, which is why it seems more likely that "goto" was a keyword in the original language rather than all jumps being part of a loop or if/else structure.

You're correct: goto was indeed a keyword. Here's an example from KQ3:
Code: [Select]
if ((tossed.in ||          [ sent back to hold by pirates
     previous.room == 77)) [ only on his first time in hold
     {
     object = 1;
     hiding.room = 83;

     :takeHisShit;
     if (object < size.of.inventory)    [ last item can't be taken on purpose
          {
          if (object == dough.balls)    [ can't take dough.balls
               {
               ++object;
               goto takeHisShit;
               }
          get.room.f(object,location)
          if (location == inventory)
               {
               set(dontHaveStuff);      [ flag checked in room 83
               set(theyTookHisShitAgain);
               put.f(object,hiding.room);
               }
          ++object;
          goto takeHisShit;
          }

     if (!tossed.in)
          {
          reset( theyTookHisShitAgain); [    skip "again" msg.
          }
     else
          {
          reset(tossed.in);

          ++timesCaught;
          if (timesCaught == 2){
               plankWalk = 1;
               new.room(82);
          }
     }

Offline lance.ewing

Re: Java AGI Interpreter by Dr Zoltan
« Reply #18 on: October 30, 2016, 05:59:41 PM »
That is clearly doing a kind of loop, but using gotos instead of a proper loop keyword. That first goto is a bit like a "continue" in Java. The goto at the bottom is more consistent with a normal loop. You know, I think this particular example probably could be decompiled in to a while loop with a continue in the middle. troflip was seeing things like this happening in the SCI decompiler. But this is a purely academic observation, because clearly they used "goto", so there is no point in decompiling this example in to a while loop. Any backwards jump can be assumed to be a "goto". Any forward jump that isn't within the last 3 bytes of an "if" block is going to be a goto as well. Gets a bit tricky if the original source code had a forward jumping "goto" as the last statement in an "if". The first inclination would be to call this an "else". It would only be an "else" though if the address of the command immediately following the unconditional jump was the negative result destination of an "if" (i.e. the destination of the conditional branch, the AGI 0xFF opcode being equivalent to a "branch not true").

This is what the loop part looks like in AGI Studio:

Code: [Select]
Label1:
        if (v226 < 55) {
          if (v226 == 8) {
            v226++;
            goto(Label1);
          }
          get.room.v(v226,v228);
          if (v228 == 255) {
            set(f185);
            set(f223);
            put.v(v226,v227);
          }
          v226++;
          goto(Label1);
        }

Your version is a bit more descriptive and colourful (I wonder which of the three coders wrote that bit? I doubt it was Robert Heitman).

So it seems like "goto" doesn't require the brackets. The format of the label is different as well. And the increment ++ is on the other side of the variable.

I wonder why they used "get.room.f"? Someone must have named it wrongly at some point. The "f" would imply a flag, but that command uses variables, right? Maybe the "f" meant something other than flag at some point. The "put.f" is using "f" as well.  If you look at the original AGI documentation PDF, some of them do have the "v", but others have the "f" for commands that are also dealing with variables. Strange.

Part of me wants to follow the original AGI syntax, but the other part wants to produce something that might compile in AGI Studio. JAGI is currently producing something that is neither.

Offline lance.ewing

Re: Java AGI Interpreter by Dr Zoltan
« Reply #19 on: October 31, 2016, 08:59:20 AM »
That is old enough for the old MegaTokyo forums. If only they were still accessible.

Stuart George has a backup from 2004 that he says he'll check the contents of before handing over. Apparently it is a dump of the whole DB.

Offline OmerMor

Re: Java AGI Interpreter by Dr Zoltan
« Reply #20 on: October 31, 2016, 09:04:27 AM »
Here are all the strings from the CG compiler (% strings CG.EXE):
Code: [Select]
CC.;
CC.;
CC.;
CC.;
]_^
CC.;
CC.;
h PV
CC.;
CC.;
CC.;
CC.;
CC.;
CC.;
CC.;
CC.;
<@u
?;t?
xu W
CC.;
.:/:/:/
H]_^
';6~
%s: not a valid 'cg' file name: %s
can't open %s
can't create output file (%s)
   %d errors
   Number of symbols: %d
   Number of messages: %d
Maximum hash bin size: %d
Bin size:   Number of bins:
   %2d          %2d
3.14
Adventure Game Compiler Version %s
Copyright (C) 1984 Sierra On-Line, Inc.
use:  cg room [room...] [-o output_directory] [-b buffer_size]
%include
%tokens
%test
%action
%flag
%var
%object
%define
%message
%view
#include
#tokens
#test
#action
#flag
#var
#object
#define
#message
#view
goto
else
FLAG
OBJECT
WORD
MSGNUM
VIEW
WORDLIST
invalid operator
assignv
assignn
addv
addn
subv
subn
lindirectv
lindirectn
rindirect
can't indirect through a number
increment
decrement
invalid operator
invalid include statement
include file nesting too deep
can't open %s
invalid tokens statement
need left parenthesis
'{' must follow if conditions
isset
invalid operator
cannot negate an or-list
already in or-list
invalid seperator
not a test
can't use '&&' in an or-list
'||' not in an or-list
invalid operator
invalid seperator
should be ')', '&&', or '||'
greatern
invalid operator
invalid operator
equaln
lessn
greatern
equalv
lessv
greaterv
must be flag or number
unbalanced right brace
'else' must be followed by '{'
Avis Durgan
   %s line %u:
%s: "%s"
flag
variable
number
object
should be %s: "%s"
Token: %s Type: %u  Value: %u
insufficient memory for %s
need left parenthesis
too many parameters for "%s"
too few parameters for "%s"
seperator must be ', ' or ';'
"%s" already defined
duplicate label: "%s"
too many goto statements
too many labels
label not defined: "%s"
unexpected end of file
identifier is required
message number not defined: %d
number
operator
seperator
parameter
flag
variable
message
word
label
view
object
need
message too long
message directory
message number too large: %d
message number already defined: %d
message string
Not enough room to consolidate messages
left parenthesis required
too many parameters -- maximum of %u
parameter required
parameter required
comma or semi-colon required
output buffer
output buffer overflow
   Logic size:   %u bytes
   Message size: %u bytes
%d unbalanced left brace%s
invalid command, action or test
conditions nested too deeply
attempt to pop from empty condition stack
hash table
multiply defined symbol
out of symbol table space
symbol not defined: "%s"
no more space for symbol names
token file already read in
can't find %s
token file
word not defined: %s
Bad pointer in free.
@@@@@@@@@PPPPP@@@@@@@@@@@@@@@@@@
               
       
     
    @
Too many arguments
HEAD
TAIL
Too many nested indirect files
Too many arguments
Out of memory
Cannot open indirect file:
Filename too long:
{NULL}
0123456789ABCDEF
You must compile with the -f option to include printf() floating point
User abort at 0000
0123456789ABCDEF

You can see all the recognized keywords in it. There appears to be no loop constructs at all.
I don't know who the author of the snippet I provided. The source didn't mention it.

I've no idea about the usage of ".f" vs ".v". I see them both.

As for the syntax, troflip decoupled his decompiler from the syntax, so he could output several flavors. You might want to consider doing the same.


Offline NewRisingSun

Re: Java AGI Interpreter by Dr Zoltan
« Reply #21 on: October 31, 2016, 12:39:38 PM »
Quote from: OmerMor
I've no idea about the usage of ".f" vs ".v". I see them both.
Heh:
Code: [Select]
[
[ sysdefs.al
[
[ AL'S SYSDEFS RE-DEFINES
[
[ 5/13/86
[



[************   AL'S REDEFINES   **************]
%define new.room.v new.room.f
%define load.logics.v load.logics.f
%define call.v call.f
%define put.v put.f
%define load.view.v load.view.f
%define position.v position.f
%define set.view.v set.view.f
%define set.loop.v set.loop.f
%define set.cel.v set.cel.f
%define set.priority.v set.priority.f

Online Kawa

Re: Java AGI Interpreter by Dr Zoltan
« Reply #22 on: October 31, 2016, 05:19:27 PM »
Nice file extension.

Offline lance.ewing

Re: Java AGI Interpreter by Dr Zoltan
« Reply #23 on: October 31, 2016, 06:36:17 PM »
Seems like Al couldn't make sense of the ".f" on the end either.

Offline lance.ewing

Re: Java AGI Interpreter by Dr Zoltan
« Reply #24 on: November 18, 2016, 04:04:38 PM »
One thing that I am intrigued by this is if this could be ported to C# that it might be of use to Visual AGI. I don't know how hard it is to port Java to C#, but the syntax looks very similar.

I've started working through a C# tutorial on my phone whilst on my bus rides to and from work. I think if I was going to port something to C#, it would probably be Meka. I'm fairly sure it was more advanced than what the Java AGI interpreter is, but we're talking of memories from nearly 20 years ago now. Perhaps after finishing the tutorial, I'll have a go at porting it to C# and see how we get on.

Offline Collector

Re: Java AGI Interpreter by Dr Zoltan
« Reply #25 on: November 18, 2016, 05:44:16 PM »
It would be interesting to see.
KQII Remake Pic

Offline lance.ewing

Re: Java AGI Interpreter by Dr Zoltan
« Reply #26 on: November 25, 2016, 02:03:40 PM »
I'm going to start another thread over the next few days to record my progress towards C# proficiency, perhaps under an off topic section of the forums, and then hopefully I'll be able to move it in to a C# AGI interpreter topic under the AGI forums.

Online Kawa

Re: Java AGI Interpreter by Dr Zoltan
« Reply #27 on: November 25, 2016, 02:38:40 PM »
This oughta be interesting.

Offline lance.ewing

Re: Java AGI Interpreter by Dr Zoltan
« Reply #28 on: November 25, 2016, 04:50:33 PM »
Yeah I'm expecting a few laughs as well. Imagine someone who has never touched C#, with 18 years Java experience, trying to pick up C#. I think what you're going to see is someone imposing a Java coding style on a C# program. I'm resisting the temptation to have my method names start in lower case, so hopefully you won't see much of that.   :)

People say that the syntax is similar. That might have been true in the early days, but it seems that things have diverged a bit over the years. The bit that seems the most foreign to me at the moment though is the equivalent of the JDK, which would have always been different. I'm basically lost; everything in there is new. So I'm stopping every few minutes to search on stackoverflow how to do something that I'd just know in Java. It's interesting.


SMF 2.0.11 | SMF © 2015, Simple Machines
Simple Audio Video Embedder

Page created in 0.211 seconds with 21 queries.