#!/usr/bin/perl -w %struct = ( 0 => [ 2, 'desc', "first 2 bytes are level number in screencodes" ], 2 => [ 2, 'sub0', "a subroutine" ], 4 => [ 2, 'sub1', "a subroutine" ], 6 => [ 2, 'sub2', "a subroutine" ], 8 => [ 2, 'sub3', "a subroutine" ], 10 => [ 1, 'num_bombs', "number of bombs to pick up on this level" ], 11 => [ 1, 'bullet_max', '0 = no bullets, range 0-4.' ], 12 => [ 1, 'y_start', 'jumpman starting Y position' ], 13 => [ 1, 'x_start', 'jumpman starting X position' ], 14 => [ 1, 'fudge_x', 'fudge factor for bomb locations, always $00' ], 15 => [ 1, 'fudge_y', 'fudge factor for bomb locations, always $06' ], 16 => [ 1, 'points_per_bomb', 'points awarded per bomb pickup (always $64 aka 100)' ], 17 => [ 2, 'time_bonus', 'amount of time bonus at start of level' ], 19 => [ 1, 'offs', 'always $00' ], 20 => [ 2, 'unkn_table0', 'pointer to ROM table or $06xx' ], 22 => [ 2, 'map', 'used to draw the level initially (see also map_changes)' ], 24 => [ 2, 'map_bombs', 'start of bombs in map data (which must come last!)' ], 26 => [ 2, 'bomblist', 'addr of list of bombs, indexed by player position on coarse 8x8 grid. 2 bytes each, 1st is coarse-grid position, 2nd is: hi 4 bits = change_map index, lo 4 = indirect sub (unused). terminated by $FF.' ], 28 => [ 2, 'map_changes', 'address of list of addresses of map data, used for changing the map when certain bombs are picked up' ], 30 => [ 2, 'indirect_subs', 'pointer to list of indirect subs, always $0000 in this game' ], 32 => [ 2, 'sub_bomb', 'called when a bomb is picked up. $06E6 for most levels (just an RTS), or else a ROM subroutine' ], 34 => [ 2, 'init', 'called at start of level, $06E6 for some levels, or else a ROM subroutine' ], 36 => [ 2, 'sub6', 'always $9740 aka game_main_loop' ], 38 => [ 2, 'sub_eol', 'called at end of level (all bombs picked up). $06E6 for all but level08' ], 40 => [ 6, 'offs', 'all zeroes' ], 46 => [ 1, 'colpf3', 'color for missiles (aka 5th player)' ], 47 => [ 1, 'colpf0', 'color for girders and up-ropes' ], 48 => [ 1, 'colpf1', 'color for ladders and down-ropes' ], 49 => [ 1, 'colpf2', 'color for bombs' ], 50 => [ 5, 'offs', 'unknown' ], 55 => [ 3, 'offs', 'unknown, always $00 $00 $00' ], 58 => [ 2, 'offs', 'unknown, not a ROM address' ], 60 => [ 4, 'offs', 'unknown, level06 (walls) has $ff $ff $ff $ff, all others $00 $00 $00 $00' ], ); sub mkaddr { return sprintf("\$%04x", $_[0]); } sub mknum { return sprintf("%02d", $_[0]); } sub mkrange { my ($level, $label, $start, $len, $type, $comment) = @_; my $sa = mkaddr($start); my $ea = mkaddr($start + $len - 1); my $llab; if($level >= 0) { my $ll = sprintf("%02d", $level + 1); $llab = "level$ll"; } else { if($level == -609) { $llab = "cur_level"; } else { $llab = "work_level"; } my $l = < $b } keys %struct) { my ($size, $label, $comment) = @{$struct{$offset}}; $comment = "Descriptor for $lvnames[$level]. $comment" if $level >= 0 && $offset == 0; if($level == 0 && $offset == 0) { $comment = "64-byte level descriptors, 12 of them (1 per level). " . $comment; } $type = 'bytetable'; if(($label eq 'bomblist') or ($label eq 'init') or ($label =~ /^sub/) or ($label =~ /^map/) or ($label =~ /^unkn_table/)) { $type = 'addrtable'; } if($label eq 'time_bonus') { $type = 'wordtable'; } if($label eq 'offs') { $label .= "_" . mknum($offset); } print mkrange($level, $label, $addr + $offset, $size, $type, $comment); } print "\n"; }