1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
#!/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, 'sub_start', '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 (not sure what gets drawn in this color yet)' ],
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 = <<EOF;
label { name "${llab}_$label"; addr $sa; size $len; comment "$comment"; };
EOF
return $l;
}
my $range = <<EOF;
range { name "${llab}_$label"; start $sa; end $ea; type $type; comment "$comment"; };
EOF
return $range;
}
@lvnames = (
"Nothing To It",
"Electrocution",
"Dumbwaiter",
"Hellstones",
"Figurits Revenge",
"Walls",
"Zig-Zag",
"Spellbound",
"Blackout",
"HereThereEverywhere",
"Hatchlings",
"Hurricane"
);
for $level (-610,-609,0..11) {
$addr = 0xa000 + $level * 0x40;
for $offset (sort { $a <=> $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 =~ /^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";
}
|