Author Topic: Pre-AGI2 versions  (Read 2145 times)

0 Members and 1 Guest are viewing this topic.

Offline lance.ewing

Re: Pre-AGI2 versions
« Reply #30 on: October 28, 2016, 06:26:28 PM »
The OBJECT data in the Apple II KQ2 is very similar to early AGI v2 games (i.e. where the item names are in plain text and not XORed with Avis Durgan), but it seems to be missing these three bytes from the start:

Code: [Select]
    Byte  Meaning
    ----- -----------------------------------------------------------
     0-1  Offset of the start of inventory item names
      2   Maximum number of animated objects
    ----- -----------------------------------------------------------

A small tweak to account for that and JAGI's Object viewer can list all the inventory items.

Offline lance.ewing

Re: Pre-AGI2 versions
« Reply #31 on: October 28, 2016, 09:01:11 PM »
I'm also starting to realise that there is no "has" test command. Instead it appears to be using flags to keep track of whether an item is in the inventory or not.

Turns out this is wrong. I'd misidentified test command 0x08. This is issetv in AGIv2, but appears to be "has" in the Apple II KQ2. I'm certain that 0x07 is "isset", which is the same as in AGI v2, but if there is an "issetv", then it doesn't immediately follow isset.

Offline lance.ewing

Re: Pre-AGI2 versions
« Reply #32 on: October 29, 2016, 04:50:09 AM »
The WORDS data is different from the AGI v2 version in a number of ways:

* The words appear in there entirety rather than referring to parts of the previous word.
* The text is not XORed with 0x7F but instead appears in it's plain ASCII form.
* All 2-byte offset values are stored in the normal LO-HI seen elsewhere in AGI rather than the HI-LO that the AGI v2 WORDS.TOK uses.
« Last Edit: October 29, 2016, 08:35:25 AM by lance.ewing »

Offline lance.ewing

Re: Pre-AGI2 versions
« Reply #33 on: October 30, 2016, 06:42:53 PM » in the Apple II KQ2 1.0H version has only the first six parameters.

Offline NewRisingSun

Re: Pre-AGI2 versions
« Reply #34 on: November 04, 2016, 08:18:28 PM »
I have debugged the PC interpreters of both KQ2 v1.1H (no interpreter version number) and BC v1.1M (interpreter v1.12) and compared my disassembly with that of later game versions. There are a few quite unique commands such as bit test/set/clear commands and the mysterious (tentatively named) "", which seems to only exist in that one interpreter version.
Code: [Select]
%test equaln(VAR,NUM) 1
%test equalv(VAR,VAR) 2
%test lessn(VAR,NUM) 3
%test lessv(VAR,VAR) 4
%test greatern(VAR,NUM) 5
%test greaterv(VAR,NUM) 6
%test isset(FLAG) 7
%test has(OBJECT) 8
%test   said(WORD,WORD) 9
%test posn(OBJECT,NUM,NUM,NUM,NUM) 10
%test controller(NUM) 11
%test, VAR) 12
%test   said3(WORD,WORD,WORD) 13
%test have.key() 14
%test   said1(WORD) 15
%test   bit.set(NUM,VAR) 16

%action return() 0
%action increment(VAR) 1
%action decrement(VAR) 2
%action assignn(VAR,NUM) 3
%action assignv(VAR,VAR) 4
%action addn(VAR,NUM) 5
%action addv(VAR,VAR) 6
%action subn(VAR,NUM) 7
%action subv(VAR,VAR) 8
%action load.view(VIEW) 9
%action animate.obj(OBJECT) 10
%action 11
%action draw.pic(VAR) 12
%action print(MSGNUM) 13
%action status() 14
%action 15
%action 16
%action init.disk() 17
%action 18
%action random(VAR) 19
%action get(OBJECT) 20
%action drop(OBJECT) 21
%action draw(OBJECT) 22
%action erase(OBJECT) 23
%action position(OBJECT,NUM,NUM) 24
%action position.f(OBJECT,VAR,VAR) 25
%action get.posn(OBJECT,VAR,VAR) 26
%action set.cel(OBJECT,NUM) 27
%action set.loop(OBJECT,NUM) 28
%action end.of.loop(OBJECT,FLAG) 29
%action reverse.loop(OBJECT,FLAG) 30
%action move.obj(OBJECT,NUM,NUM,NUM,FLAG) 31
%action set.view(OBJECT,VIEW) 32
%action follow.ego(OBJECT,NUM,FLAG) 33
%action block(NUM,NUM,NUM,NUM) 34
%action unblock() 35
%action ignore.blocks(OBJECT) 36
%action observe.blocks(OBJECT) 37
%action wander(OBJECT) 38
%action reposition(OBJECT,VAR,VAR) 39
%action stop.motion(OBJECT) 40
%action start.motion(OBJECT) 41
%action stop.cycling(OBJECT) 42
%action start.cycling(OBJECT) 43
%action stop.update(OBJECT) 44
%action start.update(OBJECT) 45
%action program.control() 46
%action player.control() 47
%action set.priority(OBJECT,NUM) 48
%action release.priority(OBJECT) 49
%action,NUM,NUM,NUM,NUM,NUM) 50
%action set.horizon(NUM) 51
%action ignore.horizon(OBJECT) 52
%action observe.horizon(OBJECT) 53
%action load.logics(NUM) 54
%action object.on.water(OBJECT) 55
%action load.pic(VAR) 56
%action load.sound(NUM) 57
%action sound(NUM,FLAG) 58
%action stop.sound() 59
%action set(FLAG) 60
%action reset(FLAG) 61
%action toggle(FLAG) 62
%action 63
%action call(NUM) 64
%action quit() 65
%action set.speed(VAR) 66
%action move.obj.f(OBJECT,VAR,VAR,VAR,FLAG) 67
%action get.num(MSGNUM,VAR) 68
%action get.f(VAR) 69
%action lindirectv(VAR, VAR) 70
%action print.flag.value(VAR) 71
%action get.priority(OBJECT,VAR) 72
%action ignore.objs(OBJECT) 73
%action observe.objs(OBJECT) 74
%action distance(OBJECT,OBJECT,VAR) 75
%action 76
%action set.priority.f(OBJECT,VAR) 77
%action show.obj(VIEW) 78
%action load.last.logics(NUM) 79
%action display(NUM,NUM,NUM,MSGNUM) 80
%action prevent.input() 81
%action nop1() 82
%action text.screen.attribute(NUM) 83
%action graphics() 84
%action clear.bottom.lines() 85
%action discard.view(VIEW) 86
%action discard.pic(VAR) 87 [ Last command in KQ2 v1.1H
%action set.key(NUM,FLAG) 88
%action reverse.cycle(OBJECT) 89
%action step.size(OBJECT,VAR) 90
%action last.cel(OBJECT,VAR) 91
%action normal.cycle(OBJECT) 92
%action load.view(VIEW) 93 [ Verified duplicate
%action nop2(NUM) 94
%action,VAR) 95 [ returns 250 if the distance is too great. Seems to take ego's direction into account as well.
%action set.bit(NUM,VAR) 96
%action clear.bit(NUM,VAR) 97 [ Last command in BC v1.1M

%var 1
%var 2
%var edge.ego.hit 3
%var score 6

%flag have.input 9
%flag init.log 13
%flag 15
While there is a call command, logics loaded with load.logics seem to simply get appended to an execution queue, while load.last.logics is guaranteed to be executed last.

From what I can see, Donald Duck's Playground version 1.0Q does justice to its v2.001 interpreter version and seems to decompile well with the regular AGI SYSDEFS.
« Last Edit: November 04, 2016, 08:25:11 PM by NewRisingSun »

Offline lance.ewing

Re: Pre-AGI2 versions
« Reply #35 on: November 05, 2016, 05:16:13 AM »
I've compared those test command and action command numbers to what I've identified so far in the Apple II KQ2 game and they all appear to line up exactly. I still had quite a few unidentified commands, but what you've listed makes sense for the gaps I have.

There is one action command with number 88 in the Apple II KQ2 game that I haven't yet identified, and your list says that the PC KQ2 commands end before that. It may end up being set.key as you have for BC, but I'll need to see if the parameters in the places where it is used make sense for that. It could end up being something different. When used, it is usually one of the first commands to be called in a room.

I had some additional flag names identified. This is my current list:


For the vars, I currently have the same four that you have.

Offline NewRisingSun

Re: Pre-AGI2 versions
« Reply #36 on: November 05, 2016, 07:44:57 AM »
I'll post my customizable AGI decompiler later, which may be useful to you. Customizable as in allowing (and requiring) you to supply a SYSDEFS file that specifies all action and test commands with parameters. I spent the last few days finding and fixing all edge cases of resolving implicit GOTOs into ELSE block, and keeping them as GOTOs where they cannot be resolved. To do this, I studied rm14 of Donald Duck's Playground --- the dreaded payroll room --- extensively.

I would also like to support Apple II disk images, but am hesitant because it seems that the locations of the various directories are hard-coded somewhere inside the machine code. At least I could not find something similar to the INITDIR that the PC v1.x AGI games have in track 0, sector 9.
« Last Edit: November 05, 2016, 01:26:22 PM by NewRisingSun »

Offline lance.ewing

Re: Pre-AGI2 versions
« Reply #37 on: November 06, 2016, 01:14:25 PM »
I haven't yet found where the offsets are stored either, although I didn't do more than try searching for the offset values across the first disk.

Regarding resolving implicit GOTOs into ELSE blocks, I guess due to the existence of the explicit goto keyword, there will be situations where we can't be certain what the original source code had in it. They may have chosen to use a goto where an else could also have been used. So the decompiler has to choose in that scenario between the two, and I guess the preference would be for the ELSE.

Offline lance.ewing

Re: Pre-AGI2 versions
« Reply #38 on: November 06, 2016, 05:50:54 PM »
Something just dawned on me.

In AGI v1, are variables and flags essentially the same thing? Is there one 256 byte var/flag table?

I ask this for two reasons:

1. The first is due to the pattern of my currently unidentified flags and variables:

Code: [Select]

# Variables

i.e. the identified vars interleave in to the gaps of the unidentified flags.

2. The second reasons is due to this code from the Apple II KQ2 game:

Code: [Select]
    if (said(fast))
    if (said(normal))
        v203 = 2;
    if (said(slow))
        v203 = 4;

It seems like there was some kind of var/flag duality going on. The reset(f203) is actually setting var 203 to 0.

This might answer the mystery as to why the var commands initially had ".f" at the end of their names.


The more I look, the more evidence I find, this time from the AGI v2 docs. The list of AGI v2 flag positions when compared with the AGI v1 positions would be the same if the variables were not interleaved between the v1 flags. This is why init.log is 0x05 in AGI v2 but 0x0D in AGI v1. I was initially thinking that they removed some flags that had become redundant, but actually they align if you account for the shared var/flag table space.

I think we can use this observation to make an educated guess as to what var 7 and var 8 are. At position 6 we have score, and position 12 we have ego.dir. According to the AGI v2 docs, there are only two vars between those two (obj.hit.edge and edge.obj.hit). The only two available slots between 6 and 12 are 7 and 8, due to the others being used by flags.
« Last Edit: November 06, 2016, 06:07:27 PM by lance.ewing »

Offline NewRisingSun

Re: Pre-AGI2 versions
« Reply #39 on: November 06, 2016, 06:12:27 PM »
From PC KQ2 v1.0W's interpreter:
Code: [Select]
%action assignn(VAR,NUM) 3
mov bx, si
inc si
mov al, [bx]
sub ah, ah
mov [bp-2], ax
mov bx, si
inc si
mov al, [bx]
mov [bp-18], ax
mov bx, [bp-2]
mov al, [bp-18]
mov [bx+0025], al
jmp 0215
%action set(FLAG) 60
mov bx, si
inc si
mov al, [bx]
sub ah, ah
mov bx, ax
mov byte ptr [bx+0025], 1
jmp 0215
The BX+0025 is the array on which both "assignn" and "set" operate. This indicates that variables and flags really are identical. Good job spotting that. I debugged that interpreter before but did not notice that the commands operated on the same array.

Offline lance.ewing

Re: Pre-AGI2 versions
« Reply #40 on: November 06, 2016, 06:39:35 PM »
Following on with the pattern, var 14 must be max.score. It seems to fit for KQ2. I can see it being set to 185 in logic 0.

Offline lance.ewing

Re: Pre-AGI2 versions
« Reply #41 on: November 09, 2016, 06:38:28 PM »
There is something that has been puzzling me about the Apple II KQ2 game for a while. The first named object in the OBJECT file starts at inventory item number 50. The first 50 slots prior to that have no name, and yet quite a few of them have a value for the room number, which is somewhat strange.

I checked the AGIv2 version of KQ2 and the inventory items start at number 50 in that case as well, but both AGI Studio and WinAGI are showing a value of 0 for the room numbers of all of the first 50 nameless objects. I haven't checked the raw data yet to see if those tools are correct about this, but I have to assume that they are.

So whatever those room number values were in the AGIv1 version, the data doesn't seem to have been important in the AGIv2 version.

Are there any clues from the PC version of the AGIv1 KQ2 game as to what those first 50 slots in the OBJECT file might be?

Offline Collector

Re: Pre-AGI2 versions
« Reply #42 on: November 09, 2016, 10:49:03 PM »
I emailed you Transcopy images of my KQ Tandy booter disks to explore. They will boot in a special build of DOSBox by NRS that supports Transcopy images. It is version 01.00.00. Not sure of the interpreter version.
KQII Remake Pic

Offline lance.ewing

Re: Pre-AGI2 versions
« Reply #43 on: November 12, 2016, 05:22:44 AM »
Code: [Select]
%action clear.bit(NUM,VAR) 97 [ Last command in BC v1.1M

Apparently there is a 98 action command in the Apple II version of BC. It isn't just an obscure command either. It seems to appear at the top of every init.log block of almost every LOGIC. It could well be Apple II only though.

Offline lance.ewing

Re: Pre-AGI2 versions
« Reply #44 on: November 12, 2016, 05:29:53 AM »
Further analysis and comparison with the KQ2 Apple II version suggestions that this command (i.e. 98, or 0x62) in BC might be the same as command 88 (or 0x58) in the KQ2 Apple II game. They are used in the same way and have the same number of parameters.

In the BC Apple II game, it would appear that 88 (0x58) has now become set.key, as was identified in the PC version.

This seems to be a case where an action command (possibly an Apple II specific one?) has moved location.

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

Page created in 0.168 seconds with 22 queries.