Yes:ZeroZero wrote:Did you read the city map post???
"street names in NM10"
Uh...
Y'know, I actually understood that entire bit of ML coding.ZeroZero wrote:The teleport in sinister street...
... is located in file NM09, which handles the city.
It is at file-offset 5e7 (incl. 2 bytes for prg load address)
In memory it will be loaded at b3e5.
This assembler snippet shows, how the party's position
in town ($28 for north, $29 for east) will be tested for
N 2, E 25, and if it matches, positions the party at N 7, E 25.
That's the whole thing...
Code: Select all
b3e5:05e7:1 a5 28 lda $28 b3e7:05e9:1 c9 02 cmp #$02 b3e9:05eb:1 d0 0e bne $b3f9 b3eb:05ed:1 a5 29 lda $29 b3ed:05ef:1 c9 19 cmp #$19 b3ef:05f1:1 d0 08 bne $b3f9 b3f1:05f3:1 a9 07 lda #$07 b3f3:05f5:1 85 28 sta $28 b3f5:05f7:1 a9 19 lda #$19 b3f7:05f9:1 85 29 sta $29 b3f9:05fb:1 60 rts
Code: Select all
Note: cf is used for both captial "O" and zero.
c0=? c1=A c2=B c5=E c6=F c7=G c8=H cb=K cc=L cf=0/0 cd=M ce=N d0=P d2=R d3=S d4=T d9=Y
00=[CR]a0=_ a1=! a2=" a7=' a8=( a9=) ac=, ad=- ae=. ba=: bb=; b1=1 b5=5
e1=a e2=b e3=c e4=d e5=e e6=f e7=g e8=h e9=i ea=j eb=k
ec=l ed=m ee=n ef=o f0=p f2=r f3=s f4=t f5=u f6=v f7=w f8=x
f9=y bf=? db=[ dd=] ff=>
dc=[end]
Code: Select all
The graphics from the NM50 to NM90 files all have
a size of 76 x 86 pixels, where on the CBM64 the
pixels are double-width in multicolor mode.
Due to the organization of the CBM64's hires memory
the program uses several tables to create the correct
offsets.
At $c900 is a table of lo-bytes for a pointer into the
hires memory to address where a certain graphic byte
goes to. The hi-bytes are in a table at $ca00.
For animation there are modifier tables that modify the
address evaluated from $C900 and $ca00, they are located
at $40c2 for lo-bytes and $4162 for the hi-bytes.
If the position byte occurs, the next two bytes do not
specify the x,y position of the frame, but the offsets
into the above tables to evaluate the hires mem position
at that that frame is to be drawn.
However, to simply decode the pictures you can take the
next two bytes and substract 8 from each to get the
position in the picture. The first byte following is the
Y-Position or row, and the second byte is the X or column.
Now for the gfx data itself, this was nicely explained by
tedious.
The files contain:
byte 0, 1 file load address
One or more frames. First frame always is the main frame.
After each frame there is another byte that gives the time
that that frame will stay on screen before the next frame
starts (in about 1/8th of seconds).
The first frame ends upon the last byte decoded at
position y=85 and x=36. The next byte is its frame time
byte. If this is zero, there are no more frames.
Every next frame can end upon either of this two conditions:
a) a position tag is given with the X or column having
the value of $ff. The next byte then has the frame time,
if it were zero, the file is done and the byte after this
has the timecode.
b) while decoding you reach the last byte position at
row 85 and column 10 (10 bytes x 4 pixeld = 40!). The
next byte then has the time code for the animation. If
it were 0, it indicates end of file and the next byte
has the time code.
The main frame is called directly after loading the file with
a jump into $4000. Animated frames are handled during the
interrupt by calling a sub at $401f.
For animation, each frame builds up on the complete former
frame, this means: you cannot directly put frame 3 on frame 1
and have the same result that you get, when you correctly
put frame 1, on that frame 2 and then on that frame 3.
Consequently, after the animation flips over, it starts
again with the main frame with the full picture data.
Every frame has this structure in the file:
byte 0 tag for the runlength encoding. It is
always a byte, that does not occur in
the gfx data, because else it had to be
escaped during encoding. Since the encoding
requires 3 bytes, it only happens if more
than three same bytes follow in sequence.
The amount of equal bytes is the byte that
follows the tag + 3 more (for the minimum
of 3). The byte to multiply is the second
byte after the tag.
byte 1 tag for position change. It is always a byte,
that does not occur in the gfx data, because
else it had to be escaped during encoding.
The two bytes following such a tag are the
offsets (see above) into the pointer tables.
If the second byte is $ff, that frame is
finished.
For decoding, you can simply substract 8 from
the next two bytes for the Y and X position.
byte 3 the data.
A data byte represent 4 pixels in a row, two
bits per pixel. Bit values mean:
00 = color 0, always black
01 = color 1, see below
10 = color 2, see below
11 = color 3, always white
If a pos tag occurs, the new byte offset into
hires mem is retrieved from the following two
bytes and drawing continues at the newly
calculated byte position.
If a run tag occurs, the next byte indicates
the number of repeated bytes, increased by the
minimum of 3. The byte after that holds the
data byte.
If another value is found, that value is a
data byte that only is used for one repeat.
byte x frame time in 1/8th of seconds. For the last
frame of an animation this contains 0 and
another byte is read for the frame time.
The picture data is build vertically and interlaced, since the
Apple II used interlaced graphics, and that is the system BT1
was first made for.
So graphic data will be build up like this:
- every other line in first column for whole pic height
(0, 2, 4, ..., 84)
- same for every next column. The result is a whole pic with every
other line painted.
- back to first column, but this time start at line 1 for
every other line (1, 3, 5, ..., 85). Again full column height.
- same for every next column. Picture complete.
The colours 1 and 2 used for a pic (white and black are always
the colors 0 and 3) are retrieved from a table at $0d9d. The
index into that table is the NMxx file number (50 to 81) minus
$50. For instance for NM50 (inside guild) this value is 26, so
red and blue, for NM51 (inside Garth) it is 56, so green and blue.
The files NM82 to NM90 (or higher) have fixed red and blue.
That table you find on the boot disk, depending on whether you have
copies with the pirate slayer removed or intact. If intact, that
list is still x'ored with $EA and you find it looking for "CC BC CC".
The first CC is also the first 26, resp. later $0d9d,x with x = 0.
With copy protect removed you simply search for 26 56 26, the first
26 again is the first offset.
The biggest animation I found in BT1 is NM74, the treasure,
with the main frame plus 13 animation frames.