aboutsummaryrefslogtreecommitdiff
path: root/level_maps.txt
diff options
context:
space:
mode:
Diffstat (limited to 'level_maps.txt')
-rw-r--r--level_maps.txt188
1 files changed, 188 insertions, 0 deletions
diff --git a/level_maps.txt b/level_maps.txt
new file mode 100644
index 0000000..b114485
--- /dev/null
+++ b/level_maps.txt
@@ -0,0 +1,188 @@
+Level Maps
+----------
+
+level00_map:
+ .byte $FE,$33,$9C,$FD,$04,$00,$44,$05 ; A300 FE 33 9C FD 04 00 44 05 .3....D.
+ .byte $06,$04,$15,$0A,$74,$15,$0A,$24 ; A308 06 04 15 0A 74 15 0A 24 ....t..$
+ .byte $22,$02,$74,$22,$02,$24,$25,$16 ; A310 22 02 74 22 02 24 25 16 ".t".$%.
+ .byte $04,$45,$04,$44,$45,$06,$8C,$45 ; A318 04 45 04 44 45 06 8C 45 .E.DE..E
+ .byte $04,$04,$55,$08,$34,$55,$0E,$7C ; A320 04 04 55 08 34 55 0E 7C ..U.4U.|
+ .byte $55,$08,$FD,$04,$FF,$34,$09,$04 ; A328 55 08 FD 04 FF 34 09 04 U....4..
+ .byte $5C,$44,$0A,$FD,$04,$01,$5C,$06 ; A330 5C 44 0A FD 04 01 5C 06 \D....\.
+ .byte $04,$1C,$3B,$0A,$FE,$5F,$9C,$FD ; A338 04 1C 3B 0A FE 5F 9C FD ..;.._..
+ .byte $00,$04,$0C,$41,$05,$8C,$41,$05 ; A340 00 04 0C 41 05 8C 41 05 ...A..A.
+ .byte $24,$01,$05,$74,$01,$05,$4C,$01 ; A348 24 01 05 74 01 05 4C 01 $..t..L.
+ .byte $15,$FE,$C9,$9C,$06,$18,$0A,$99 ; A350 15 FE C9 9C 06 18 0A 99 ........
+ .byte $18,$0A,$FE,$DA,$9C,$1D,$38,$06 ; A358 18 0A FE DA 9C 1D 38 06 ......8.
+ .byte $81,$38,$06,$FE,$B3,$9C ; A360 81 38 06 FE B3 9C .8....
+
+A300: FE 33 9C selects a shape (in this case, a girder)
+A303: FD 04 00 sets the X and Y delta (4 pixels X, 0 lines Y)
+A306: 44 is the X starting position
+A307: 05 is the Y starting position
+A308: 06 is the number of copies to draw (length of line)
+A309: 04 is another X position (same shape type, still drawing girders)
+A30A: 15 is another Y position (same shape type)
+A30B: 0A is the number of copies to draw
+
+...more x/y/length tuples here, all drawn with dx=4, dy=0, aka
+horizontally from left to right.
+
+A32A: $FD,$04,$FF sets a new X/Y delta. now we're drawing left and
+down, for the diagonal girders (aka ramps) that run SW to NE.
+
+A333: $FD,$04,$01 is X/Y delta, drawing left and up, for the ramps
+that run NW to SE (tilted the other way from the previous set).
+
+A33C: $FE,$5F,$9C selects a different shape (ladders)
+
+so eventually, I need ca65 macros that resemble instructions that assemble
+into map data. Something like:
+
+set_gfx $9Cee
+set_delta $04,$00
+draw_gfx $44,$05,$06
+draw_gfx $04,$15,$0A
+
+...notionally the drawing engine is a little CPU with 3 16-bit registers:
+a program counter (stored at $C0), gfx (the graphic object it draws)
+and delta (2 8-bit signed ints). It has 5 opcodes:
+
+$FC - gfx_jump (operand = 16-bit target address)
+$FD - gfx_delta (operand = 2 8-bit signed ints)
+$FE - gfx_shape (operand = 16-bit address of shape, see below)
+$FF - gfx_end (done drawing)
+Anything else - gfx_draw (opcode is X start, next 2 bytes are Y and length)
+
+All the opcodes other than gfx_end are 3 bytes. Write macros for ca65 and a
+disassembler in perl.
+
+There are 13 primary maps (one per level, plus the WELL DONE screen). Some
+(all?) levels also have secondary map data, which I think is used for
+changing parts of the map during the level (e.g. the disappearing girders
+on level 1).
+
+Shapes
+------
+
+Actual graphics data (girder sections, ladders, etc) is stored less
+efficiently. I'm not going to call these "sprites" because they don't
+move, and I'm not going to call them "tiles" because they aren't (they
+can be placed at arbitrary X/Y positions, not limited to a character
+map style grid). So I'll refer them as a "shape".
+
+Each shape is at least one pixel wide and at least 1 pixel tall. Pixels
+are 2 bits wide (4-color GR.7 mode), and are stored unpacked (2 bits
+per byte).
+
+Here's what the girder section looks like:
+
+girder: .byte $04,$00,$00,$01,$01,$01,$01,$04 ; 9C33 04 00 00 01 01 01 01 04 ........
+ .byte $00,$01,$01,$00,$01,$00,$04,$00 ; 9C3B 00 01 01 00 01 00 04 00 ........
+ .byte $02,$01,$01,$01,$01,$FF,$xx,$xx ; 9C43 02 01 01 01 01 FF xx xx ........
+
+That's from the disassembly, the xx's are "don't care" because they're
+actually part of the next shape in the table.
+
+Here's the same thing, laid out in a more human-readable way [*]
+
+girder:
+girder_row0:
+girder_row0_width: .byte $04
+girder_row0_x_offset: .byte $00
+girder_row0_y_offset: .byte $00
+girder_row0_pixels: .byte $01,$01,$01,$01
+girder_row1:
+girder_row1_width: .byte $04
+girder_row1_x_offset: .byte $00
+girder_row1_y_offset: .byte $01
+girder_row1_pixels: .byte $01,$00,$01,$00
+girder_row2:
+girder_row2_width: .byte $04
+girder_row2_x_offset: .byte $00
+girder_row2_y_offset: .byte $02
+girder_row2_pixels: .byte $01,$01,$01,$01
+girder_end: .byte $FF
+
+ [*] Getting da65 to emit this would be possible but unwieldy, it'll have
+ to wait until I've mapped out all the 'unknown' code/data sections
+ and can start manually editing the disassembly to turn it into
+ proper source.
+
+This makes a shape like this:
+
+XXXX
+X X
+XXXX
+
+...which you'll recognize as a girder segment, if you squint a little.
+
+Notice the use of $FF as an end marker. If it occurs in place of a width,
+the dm_draw_gfx routine knows it's done, and exits immediately.
+
+Here's the next shape in the table:
+
+blank:
+blank_row0:
+blank_row0_width: .byte $04
+blank_row0_x_offset: .byte $00
+blank_row0_y_offset: .byte $00
+blank_row0_pixels: .byte $00,$00,$00,$00
+blank_row1:
+blank_row1_width: .byte $04
+blank_row1_x_offset: .byte $00
+blank_row1_y_offset: .byte $01
+blank_row1_pixels: .byte $00,$00,$00,$00
+blank_row2:
+blank_row2_width: .byte $04
+blank_row2_x_offset: .byte $00
+blank_row2_y_offset: .byte $02
+blank_row2_pixels: .byte $00,$00,$00,$00
+blank_end: .byte $FF
+
+This is a 4x4 block of empty pixels. It's probably used to erase parts
+of the level (e.g. the disappearing platforms on level 1).
+
+Next:
+
+xxx:
+xxx_row0:
+xxx_row0_width: .byte $02
+xxx_row0_x_offset: .byte $00
+xxx_row0_y_offset: .byte $00
+xxx_row0_pixels: .byte $02,$02
+
+xxx_row1_width: .byte $02
+xxx_row1_x_offset: .byte $06
+xxx_row1_y_offset: .byte $00
+xxx_row1_pixels: .byte $02,$02
+
+xxx_row2_width: .byte $02
+xxx_row2_x_offset: .byte $00
+xxx_row2_y_offset: .byte $01
+xxx_row2_pixels: .byte $02,$02
+
+xxx_row3_width: .byte $02
+xxx_row3_x_offset: .byte $06
+xxx_row3_y_offset: .byte $01
+xxx_row3_pixels: .byte $02,$02
+
+xxx_row4_width: .byte $08
+xxx_row4_x_offset: .byte $00
+xxx_row4_y_offset: .byte $02
+xxx_row4_pixels: .byte $02,$02,$02,$02,$02,$02,$02,$02
+
+xxx_row5_width: .byte $02
+xxx_row5_x_offset: .byte $00
+xxx_row5_y_offset: .byte $03
+xxx_row5_pixels: .byte $02,$02
+
+xxx_row6_width: .byte $02
+xxx_row6_x_offset: .byte $06
+xxx_row6_y_offset: .byte $03
+xxx_row6_pixels: .byte $02,$02
+
+xxx_end: .byte $FF
+
+In this one, all the pixels are $02. Most of the shapes will be like
+this, only using one color.