Subversion Repositories Games.Prince of Persia

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 1
/*
2
SDLPoP, a port/conversion of the DOS game Prince of Persia.
3
Copyright (C) 2013-2018  Dávid Nagy
4
 
5
This program is free software: you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation, either version 3 of the License, or
8
(at your option) any later version.
9
 
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
GNU General Public License for more details.
14
 
15
You should have received a copy of the GNU General Public License
16
along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 
18
The authors of this program may be contacted at http://forum.princed.org
19
*/
20
 
21
#include "common.h"
22
 
23
#define SEQTBL_BASE 0x196E
24
#define SEQTBL_0 (seqtbl - SEQTBL_BASE)
25
extern const byte seqtbl[]; // the sequence table is defined in seqtbl.c
26
 
27
// seg006:0006
28
int __pascal far get_tile(int room,int col,int row) {
29
        curr_room = room;
30
        tile_col = col;
31
        tile_row = row;
32
        curr_room = find_room_of_tile();
33
        // bugfix: check_chomped_kid may call with room = -1
34
        if (curr_room > 0) {
35
                get_room_address(curr_room);
36
                curr_tilepos = tbl_line[tile_row] + tile_col;
37
                curr_tile2 = curr_room_tiles[curr_tilepos] & 0x1F;
38
        } else {
39
                // wall in room 0
40
                curr_tile2 = level_edge_hit_tile; // tiles_20_wall
41
        }
42
        return curr_tile2;
43
}
44
 
45
// seg006:005D
46
int __pascal far find_room_of_tile() {
47
        again:
48
        if (tile_col < 0) {
49
                tile_col += 10;
50
                if (curr_room) {
51
                        curr_room = level.roomlinks[curr_room - 1].left;
52
                }
53
                //find_room_of_tile();
54
                goto again;
55
        } else if (tile_col >= 10) {
56
                tile_col -= 10;
57
                if (curr_room) {
58
                        curr_room = level.roomlinks[curr_room - 1].right;
59
                }
60
                //find_room_of_tile();
61
                goto again;
62
        } else if (tile_row < 0) {
63
                tile_row += 3;
64
                if (curr_room) {
65
                        curr_room = level.roomlinks[curr_room - 1].up;
66
                }
67
                //find_room_of_tile();
68
                goto again;
69
        } else if (tile_row >= 3) {
70
                tile_row -= 3;
71
                if (curr_room) {
72
                        curr_room = level.roomlinks[curr_room - 1].down;
73
                }
74
                //find_room_of_tile();
75
                goto again;
76
        }
77
        return curr_room;
78
}
79
 
80
// seg006:00EC
81
int __pascal far get_tilepos(int tile_col,int tile_row) {
82
        if (tile_row < 0) {
83
                return -(tile_col + 1);
84
        } else if (tile_row >= 3 || tile_col >= 10 || tile_col < 0) {
85
                return 30;
86
        } else {
87
                return tbl_line[tile_row] + tile_col;
88
        }
89
}
90
 
91
// seg006:0124
92
int __pascal far get_tilepos_nominus(int tile_col,int tile_row) {
93
        short var_2;
94
        var_2 = get_tilepos(tile_col, tile_row);
95
        if (var_2 < 0) return 30; else return var_2;
96
}
97
 
98
// seg006:0144
99
void __pascal far load_fram_det_col() {
100
        load_frame();
101
        determine_col();
102
}
103
 
104
// seg006:014D
105
void __pascal far determine_col() {
106
        Char.curr_col = get_tile_div_mod_m7(dx_weight());
107
}
108
 
109
// data:0FE0
110
const frame_type frame_table_kid[] = {
111
{ 255, 0x00| 0,   0,   0, 0x00| 0},
112
{   0, 0x00| 0,   1,   0, 0xC0| 4},
113
{   1, 0x00| 0,   1,   0, 0x40| 4},
114
{   2, 0x00| 0,   3,   0, 0x40| 7},
115
{   3, 0x00| 0,   4,   0, 0x40| 8},
116
{   4, 0x00| 0,   0,   0, 0xE0| 6},
117
{   5, 0x00| 0,   0,   0, 0x40| 9},
118
{   6, 0x00| 0,   0,   0, 0x40|10},
119
{   7, 0x00| 0,   0,   0, 0xC0| 5},
120
{   8, 0x00| 0,   0,   0, 0x40| 4},
121
{   9, 0x00| 0,   0,   0, 0x40| 7},
122
{  10, 0x00| 0,   0,   0, 0x40|11},
123
{  11, 0x00| 0,   0,   0, 0x40| 3},
124
{  12, 0x00| 0,   0,   0, 0xC0| 3},
125
{  13, 0x00| 0,   0,   0, 0x40| 7},
126
{  14, 0x00| 9,   0,   0, 0x40| 3},
127
{  15, 0x00| 0,   0,   0, 0xC0| 3},
128
{  16, 0x00| 0,   0,   0, 0x40| 4},
129
{  17, 0x00| 0,   0,   0, 0x40| 6},
130
{  18, 0x00| 0,   0,   0, 0x40| 8},
131
{  19, 0x00| 0,   0,   0, 0x80| 9},
132
{  20, 0x00| 0,   0,   0, 0x00|11},
133
{  21, 0x00| 0,   0,   0, 0x80|11},
134
{  22, 0x00| 0,   0,   0, 0x00|17},
135
{  23, 0x00| 0,   0,   0, 0x00| 7},
136
{  24, 0x00| 0,   0,   0, 0x00| 5},
137
{  25, 0x00| 0,   0,   0, 0xC0| 1},
138
{  26, 0x00| 0,   0,   0, 0xC0| 6},
139
{  27, 0x00| 0,   0,   0, 0x40| 3},
140
{  28, 0x00| 0,   0,   0, 0x40| 8},
141
{  29, 0x00| 0,   0,   0, 0x40| 2},
142
{  30, 0x00| 0,   0,   0, 0x40| 2},
143
{  31, 0x00| 0,   0,   0, 0xC0| 2},
144
{  32, 0x00| 0,   0,   0, 0xC0| 2},
145
{  33, 0x00| 0,   0,   0, 0x40| 3},
146
{  34, 0x00| 0,   0,   0, 0x40| 8},
147
{  35, 0x00| 0,   0,   0, 0xC0|14},
148
{  36, 0x00| 0,   0,   0, 0xC0| 1},
149
{  37, 0x00| 0,   0,   0, 0x40| 5},
150
{  38, 0x00| 0,   0,   0, 0x80|14},
151
{  39, 0x00| 0,   0,   0, 0x00|11},
152
{  40, 0x00| 0,   0,   0, 0x80|11},
153
{  41, 0x00| 0,   0,   0, 0x80|10},
154
{  42, 0x00| 0,   0,   0, 0x00| 1},
155
{  43, 0x00| 0,   0,   0, 0xC0| 4},
156
{  44, 0x00| 0,   0,   0, 0xC0| 3},
157
{  45, 0x00| 0,   0,   0, 0xC0| 3},
158
{  46, 0x00| 0,   0,   0, 0xA0| 5},
159
{  47, 0x00| 0,   0,   0, 0xA0| 4},
160
{  48, 0x00| 0,   0,   0, 0x60| 6},
161
{  49, 0x00| 0,   4,   0, 0x60| 7},
162
{  50, 0x00| 0,   3,   0, 0x60| 6},
163
{  51, 0x00| 0,   1,   0, 0x40| 4},
164
{  64, 0x00| 0,   0,   0, 0xC0| 2},
165
{  65, 0x00| 0,   0,   0, 0x40| 1},
166
{  66, 0x00| 0,   0,   0, 0x40| 2},
167
{  67, 0x00| 0,   0,   0, 0x00| 0},
168
{  68, 0x00| 0,   0,   0, 0x00| 0},
169
{  69, 0x00| 0,   0,   0, 0x80| 0},
170
{  70, 0x00| 0,   0,   0, 0x00| 0},
171
{  71, 0x00| 0,   0,   0, 0x80| 0},
172
{  72, 0x00| 0,   0,   0, 0x00| 0},
173
{  73, 0x00| 0,   0,   0, 0x80| 0},
174
{  74, 0x00| 0,   0,   0, 0x00| 0},
175
{  75, 0x00| 0,   0,   0, 0x00| 0},
176
{  76, 0x00| 0,   0,   0, 0x80| 0},
177
{ 255, 0x00| 0,   0,   0, 0x00| 0},
178
{  80, 0x00| 0,  -2,   0, 0x40| 1},
179
{  81, 0x00| 0,  -2,   0, 0x40| 1},
180
{  82, 0x00| 0,  -1,   0, 0xC0| 2},
181
{  83, 0x00| 0,  -2,   0, 0x40| 2},
182
{  84, 0x00| 0,  -2,   0, 0x40| 1},
183
{  85, 0x00| 0,  -2,   0, 0x40| 1},
184
{  86, 0x00| 0,  -2,   0, 0x40| 1},
185
{  87, 0x00| 0,  -1,   0, 0x00| 7},
186
{  88, 0x00| 0,  -1,   0, 0x00| 5},
187
{  89, 0x00| 0,   2,   0, 0x00| 7},
188
{  90, 0x00| 0,   2,   0, 0x00| 7},
189
{  91, 0x00| 0,   2,  -3, 0x00| 0},
190
{  92, 0x00| 0,   2, -10, 0x00| 0},
191
{  93, 0x00| 0,   2, -11, 0x80| 0},
192
{  94, 0x00| 0,   3,  -2, 0x40| 3},
193
{  95, 0x00| 0,   3,   0, 0xC0| 3},
194
{  96, 0x00| 0,   3,   0, 0xC0| 3},
195
{  97, 0x00| 0,   3,   0, 0x60| 3},
196
{  98, 0x00| 0,   4,   0, 0xE0| 3},
197
{  28, 0x00| 0,   0,   0, 0x00| 0},
198
{  99, 0x00| 0,   7, -14, 0x80| 0},
199
{ 100, 0x00| 0,   7, -12, 0x80| 0},
200
{ 101, 0x00| 0,   4, -12, 0x00| 0},
201
{ 102, 0x00| 0,   3, -10, 0x80| 0},
202
{ 103, 0x00| 0,   2, -10, 0x80| 0},
203
{ 104, 0x00| 0,   1, -10, 0x80| 0},
204
{ 105, 0x00| 0,   0, -11, 0x00| 0},
205
{ 106, 0x00| 0,  -1, -12, 0x00| 0},
206
{ 107, 0x00| 0,  -1, -14, 0x00| 0},
207
{ 108, 0x00| 0,  -1, -14, 0x00| 0},
208
{ 109, 0x00| 0,  -1, -15, 0x80| 0},
209
{ 110, 0x00| 0,  -1, -15, 0x80| 0},
210
{ 111, 0x00| 0,   0, -15, 0x00| 0},
211
{ 255, 0x00| 0,   0,   0, 0x00| 0},
212
{ 255, 0x00| 0,   0,   0, 0x00| 0},
213
{ 112, 0x00| 0,   0,   0, 0xC0| 6},
214
{ 113, 0x00| 0,   0,   0, 0x40| 6},
215
{ 114, 0x00| 0,   0,   0, 0xC0| 5},
216
{ 115, 0x00| 0,   0,   0, 0x40| 5},
217
{ 116, 0x00| 0,   0,   0, 0xC0| 2},
218
{ 117, 0x00| 0,   0,   0, 0xC0| 4},
219
{ 118, 0x00| 0,   0,   0, 0xC0| 5},
220
{ 119, 0x00| 0,   0,   0, 0x40| 6},
221
{ 120, 0x00| 0,   0,   0, 0x40| 7},
222
{ 121, 0x00| 0,   0,   0, 0x40| 7},
223
{ 122, 0x00| 0,   0,   0, 0x40| 9},
224
{ 123, 0x00| 0,   0,   0, 0xC0| 8},
225
{ 124, 0x00| 0,   0,   0, 0xC0| 9},
226
{ 125, 0x00| 0,   0,   0, 0x40| 9},
227
{ 126, 0x00| 0,   0,   0, 0x40| 5},
228
{ 127, 0x00| 0,   2,   0, 0x40| 5},
229
{ 128, 0x00| 0,   2,   0, 0xC0| 5},
230
{ 129, 0x00| 0,   0,   0, 0xC0| 3},
231
{ 255, 0x00| 0,   0,   0, 0x00| 0},
232
{ 133, 0x00| 0,   0,   0, 0x40| 3},
233
{ 134, 0x00| 0,   0,   0, 0xC0| 4},
234
{ 135, 0x00| 0,   0,   0, 0xC0| 5},
235
{ 136, 0x00| 0,   0,   0, 0x40| 8},
236
{ 137, 0x00| 0,   0,   0, 0x60|12},
237
{ 138, 0x00| 0,   0,   0, 0xE0|15},
238
{ 139, 0x00| 0,   0,   0, 0x60| 3},
239
{ 140, 0x00| 0,   0,   0, 0xC0| 3},
240
{ 141, 0x00| 0,   0,   0, 0x40| 3},
241
{ 142, 0x00| 0,   0,   0, 0x40| 3},
242
{ 143, 0x00| 0,   0,   0, 0x40| 4},
243
{ 144, 0x00| 0,   0,   0, 0x40| 4},
244
{ 172, 0x00| 0,   0,   1, 0xC0| 1},
245
{ 173, 0x00| 0,   0,   1, 0xC0| 7},
246
{ 145, 0x00| 0,   0, -12, 0x00| 1},
247
{ 146, 0x00| 0,   0, -21, 0x00| 0},
248
{ 147, 0x00| 0,   1, -26, 0x80| 0},
249
{ 148, 0x00| 0,   4, -32, 0x80| 0},
250
{ 149, 0x00| 0,   6, -36, 0x80| 1},
251
{ 150, 0x00| 0,   7, -41, 0x80| 2},
252
{ 151, 0x00| 0,   2,  17, 0x40| 2},
253
{ 152, 0x00| 0,   4,   9, 0xC0| 4},
254
{ 153, 0x00| 0,   4,   5, 0xC0| 9},
255
{ 154, 0x00| 0,   4,   4, 0xC0| 8},
256
{ 155, 0x00| 0,   5,   0, 0x60| 9},
257
{ 156, 0x00| 0,   5,   0, 0xE0| 9},
258
{ 157, 0x00| 0,   5,   0, 0xE0| 8},
259
{ 158, 0x00| 0,   5,   0, 0x60| 9},
260
{ 159, 0x00| 0,   5,   0, 0x60| 9},
261
{ 184, 0x00|16,   0,   2, 0x80| 0},
262
{ 174, 0x00|26,   0,   2, 0x80| 0},
263
{ 175, 0x00|18,   3,   2, 0x00| 0},
264
{ 176, 0x00|22,   7,   2, 0xC0| 4},
265
{ 177, 0x00|21,  10,   2, 0x00| 0},
266
{ 178, 0x00|23,   7,   2, 0x80| 0},
267
{ 179, 0x00|25,   4,   2, 0x80| 0},
268
{ 180, 0x00|24,   0,   2, 0xC0|14},
269
{ 181, 0x00|15,   0,   2, 0xC0|13},
270
{ 182, 0x00|20,   3,   2, 0x00| 0},
271
{ 183, 0x00|31,   3,   2, 0x00| 0},
272
{ 184, 0x00|16,   0,   2, 0x80| 0},
273
{ 185, 0x00|17,   0,   2, 0x80| 0},
274
{ 186, 0x00|32,   0,   2, 0x00| 0},
275
{ 187, 0x00|33,   0,   2, 0x80| 0},
276
{ 188, 0x00|34,   2,   2, 0xC0| 3},
277
{  14, 0x00| 0,   0,   0, 0x40| 3},
278
{ 189, 0x00|19,   7,   2, 0x80| 0},
279
{ 190, 0x00|14,   1,   2, 0x80| 0},
280
{ 191, 0x00|27,   0,   2, 0x80| 0},
281
{ 181, 0x00|15,   0,   2, 0xC0|13},
282
{ 181, 0x00|15,   0,   2, 0xC0|13},
283
{ 112, 0x00|43,   0,   0, 0xC0| 6},
284
{ 113, 0x00|44,   0,   0, 0x40| 6},
285
{ 114, 0x00|45,   0,   0, 0xC0| 5},
286
{ 115, 0x00|46,   0,   0, 0x40| 5},
287
{ 114, 0x00| 0,   0,   0, 0xC0| 5},
288
{  78, 0x00| 0,   0,   3, 0x80|10},
289
{  77, 0x00| 0,   4,   3, 0x80| 7},
290
{ 211, 0x00| 0,   0,   1, 0x40| 4},
291
{ 212, 0x00| 0,   0,   1, 0x40| 4},
292
{ 213, 0x00| 0,   0,   1, 0x40| 4},
293
{ 214, 0x00| 0,   0,   1, 0x40| 7},
294
{ 215, 0x00| 0,   0,   7, 0x40|11},
295
{ 255, 0x00| 0,   0,   0, 0x00| 0},
296
{  79, 0x00| 0,   4,   7, 0x40| 9},
297
{ 130, 0x00| 0,   0,   0, 0x40| 4},
298
{ 131, 0x00| 0,   0,   0, 0x40| 4},
299
{ 132, 0x00| 0,   0,   2, 0x40| 4},
300
{ 255, 0x00| 0,   0,   0, 0x00| 0},
301
{ 255, 0x00| 0,   0,   0, 0x00| 0},
302
{ 192, 0x00| 0,   0,   0, 0x00| 0},
303
{ 193, 0x00| 0,   0,   1, 0x00| 0},
304
{ 194, 0x00| 0,   0,   0, 0x80| 0},
305
{ 195, 0x00| 0,   0,   0, 0x00| 0},
306
{ 196, 0x00| 0,  -1,   0, 0x00| 0},
307
{ 197, 0x00| 0,  -1,   0, 0x00| 0},
308
{ 198, 0x00| 0,  -1,   0, 0x00| 0},
309
{ 199, 0x00| 0,  -4,   0, 0x00| 0},
310
{ 200, 0x00| 0,  -4,   0, 0x80| 0},
311
{ 201, 0x00| 0,  -4,   0, 0x00| 0},
312
{ 202, 0x00| 0,  -4,   0, 0x00| 0},
313
{ 203, 0x00| 0,  -4,   0, 0x00| 0},
314
{ 204, 0x00| 0,  -4,   0, 0x00| 0},
315
{ 205, 0x00| 0,  -5,   0, 0x00| 0},
316
{ 206, 0x00| 0,  -5,   0, 0x00| 0},
317
{ 255, 0x00| 0,   0,   0, 0x00| 0},
318
{ 207, 0x00| 0,   0,   1, 0x40| 6},
319
{ 208, 0x00| 0,   0,   1, 0xC0| 6},
320
{ 209, 0x00| 0,   0,   1, 0xC0| 8},
321
{ 210, 0x00| 0,   0,   1, 0x40|10},
322
{ 255, 0x00| 0,   0,   0, 0x00| 0},
323
{ 255, 0x00| 0,   0,   0, 0x00| 0},
324
{ 255, 0x00| 0,   0,   0, 0x00| 0},
325
{ 255, 0x00| 0,   0,   0, 0x00| 0},
326
{ 255, 0x00| 0,   0,   0, 0x00| 0},
327
{ 255, 0x00| 0,   0,   0, 0x00| 0},
328
{  52, 0x00| 0,   0,   0, 0x80| 0},
329
{  53, 0x00| 0,   0,   0, 0x00| 0},
330
{  54, 0x00| 0,   0,   0, 0x00| 0},
331
{  55, 0x00| 0,   0,   0, 0x00| 0},
332
{  56, 0x00| 0,   0,   0, 0x80| 0},
333
{  57, 0x00| 0,   0,   0, 0x00| 0},
334
{  58, 0x00| 0,   0,   0, 0x00| 0},
335
{  59, 0x00| 0,   0,   0, 0x00| 0},
336
{  60, 0x00| 0,   0,   0, 0x80| 0},
337
{  61, 0x00| 0,   0,   0, 0x00| 0},
338
{  62, 0x00| 0,   0,   0, 0x80| 0},
339
{  63, 0x00| 0,   0,   0, 0x00| 0},
340
{ 160, 0x00|35,   1,   1, 0xC0| 3},
341
{ 161, 0x00|36,   0,   1, 0x40| 9},
342
{ 162, 0x00|37,   0,   1, 0xC0| 3},
343
{ 163, 0x00|38,   0,   1, 0x40| 9},
344
{ 164, 0x00|39,   0,   1, 0xC0| 3},
345
{ 165, 0x00|40,   1,   1, 0x40| 9},
346
{ 166, 0x00|41,   1,   1, 0x40| 3},
347
{ 167, 0x00|42,   1,   1, 0xC0| 9},
348
{ 168, 0x00| 0,   4,   1, 0xC0| 6},
349
{ 169, 0x00| 0,   3,   1, 0xC0|10},
350
{ 170, 0x00| 0,   1,   1, 0x40| 3},
351
{ 171, 0x00| 0,   1,   1, 0xC0| 8},
352
};
353
 
354
// data:1496
355
const frame_type frame_tbl_guard[] = {
356
{ 255, 0x00| 0,   0,   0, 0x00| 0},
357
{  12, 0xC0|13,   2,   1, 0x00| 0},
358
{   2, 0xC0| 1,   3,   1, 0x00| 0},
359
{   3, 0xC0| 2,   4,   1, 0x00| 0},
360
{   4, 0xC0| 3,   7,   1, 0x40| 4},
361
{   5, 0xC0| 4,  10,   1, 0x00| 0},
362
{   6, 0xC0| 5,   7,   1, 0x80| 0},
363
{   7, 0xC0| 6,   4,   1, 0x80| 0},
364
{   8, 0xC0| 7,   0,   1, 0x80| 0},
365
{   9, 0xC0| 8,   0,   1, 0xC0|13},
366
{  10, 0xC0|11,   7,   1, 0x80| 0},
367
{  11, 0xC0|12,   3,   1, 0x00| 0},
368
{  12, 0xC0|13,   2,   1, 0x00| 0},
369
{  13, 0xC0| 0,   2,   1, 0x00| 0},
370
{  14, 0xC0|28,   0,   1, 0x00| 0},
371
{  15, 0xC0|29,   0,   1, 0x80| 0},
372
{  16, 0xC0|30,   2,   1, 0xC0| 3},
373
{  17, 0xC0| 9,  -1,   1, 0x40| 8},
374
{  18, 0xC0|10,   7,   1, 0x80| 0},
375
{  19, 0xC0|14,   3,   1, 0x80| 0},
376
{   9, 0xC0| 8,   0,   1, 0x80| 0},
377
{  20, 0xC0| 8,   0,   1, 0xC0|13},
378
{  21, 0xC0| 8,   0,   1, 0xC0|13},
379
{  22, 0xC0|47,   0,   0, 0xC0| 6},
380
{  23, 0xC0|48,   0,   0, 0x40| 6},
381
{  24, 0xC0|49,   0,   0, 0xC0| 5},
382
{  24, 0xC0|49,   0,   0, 0xC0| 5},
383
{  24, 0xC0|49,   0,   0, 0xC0| 5},
384
{  26, 0xC0| 0,   0,   3, 0x80|10},
385
{  27, 0xC0| 0,   4,   4, 0x80| 7},
386
{  28, 0xC0| 0,  -2,   1, 0x40| 4},
387
{  29, 0xC0| 0,  -2,   1, 0x40| 4},
388
{  30, 0xC0| 0,  -2,   1, 0x40| 4},
389
{  31, 0xC0| 0,  -2,   2, 0x40| 7},
390
{  32, 0xC0| 0,  -2,   2, 0x40|10},
391
{ 255, 0x00| 0,   0,   0, 0x00| 0},
392
{  33, 0xC0| 0,   3,   4, 0xC0| 9},
393
{ 255, 0x00| 0,   0,   0, 0x00| 0},
394
{ 255, 0x00| 0,   0,   0, 0x00| 0},
395
{ 255, 0x00| 0,   0,   0, 0x00| 0},
396
{ 255, 0x00| 0,   0,   0, 0x00| 0},
397
};
398
 
399
// data:1564
400
const frame_type frame_tbl_cuts[] = {
401
{ 255, 0x00| 0,   0,   0, 0x00| 0},
402
{  15, 0x40| 0,   0,   0, 0x00| 0},
403
{   1, 0x40| 0,   0,   0, 0x80| 0},
404
{   2, 0x40| 0,   0,   0, 0x80| 0},
405
{   3, 0x40| 0,   0,   0, 0x80| 0},
406
{   4, 0x40| 0,  -1,   0, 0x00| 0},
407
{   5, 0x40| 0,   2,   0, 0x80| 0},
408
{   6, 0x40| 0,   2,   0, 0x00| 0},
409
{   7, 0x40| 0,   0,   0, 0x80| 0},
410
{   8, 0x40| 0,   1,   0, 0x80| 0},
411
{ 255, 0x00| 0,   0,   0, 0x00| 0},
412
{   0, 0x40| 0,   0,   0, 0x80| 0},
413
{   9, 0x40| 0,   0,   0, 0x80| 0},
414
{  10, 0x40| 0,   0,   0, 0x00| 0},
415
{  11, 0x40| 0,   0,   0, 0x80| 0},
416
{  12, 0x40| 0,   0,   0, 0x80| 0},
417
{  13, 0x40| 0,   0,   0, 0x80| 0},
418
{  14, 0x40| 0,   0,   0, 0x00| 0},
419
{  16, 0x40| 0,   0,   0, 0x00| 0},
420
{   0, 0x80| 0,   0,   0, 0x00| 0},
421
{   2, 0x80| 0,   0,   0, 0x00| 0},
422
{   3, 0x80| 0,   0,   0, 0x00| 0},
423
{   4, 0x80| 0,   0,   0, 0x80| 0},
424
{   5, 0x80| 0,   0,   0, 0x00| 0},
425
{   6, 0x80| 0,   0,   0, 0x80| 0},
426
{   7, 0x80| 0,   0,   0, 0x80| 0},
427
{   8, 0x80| 0,   0,   0, 0x00| 0},
428
{   9, 0x80| 0,   0,   0, 0x00| 0},
429
{  10, 0x80| 0,   0,   0, 0x00| 0},
430
{  11, 0x80| 0,   0,   0, 0x00| 0},
431
{  12, 0x80| 0,   0,   0, 0x00| 0},
432
{  13, 0x80| 0,   0,   0, 0x00| 0},
433
{  14, 0x80| 0,   0,   0, 0x00| 0},
434
{  15, 0x80| 0,   0,   0, 0x00| 0},
435
{  16, 0x80| 0,   0,   0, 0x00| 0},
436
{  17, 0x80| 0,   0,   0, 0x00| 0},
437
{  18, 0x80| 0,   0,   0, 0x00| 0},
438
{  19, 0x80| 0,   0,   0, 0x00| 0},
439
{  20, 0x80| 0,   0,   0, 0x80| 0},
440
{  21, 0x80| 0,   0,   0, 0x80| 0},
441
{  22, 0x80| 0,   1,   0, 0x00| 0},
442
{  23, 0x80| 0,  -1,   0, 0x00| 0},
443
{  24, 0x80| 0,   2,   0, 0x00| 0},
444
{  25, 0x80| 0,   1,   0, 0x80| 0},
445
{  26, 0x80| 0,   0,   0, 0x80| 0},
446
{  27, 0x80| 0,   0,   0, 0x80| 0},
447
{  28, 0x80| 0,   0,   0, 0x80| 0},
448
{  29, 0x80| 0,  -1,   0, 0x00| 0},
449
{   0, 0x80| 0,   0,   0, 0x80| 0},
450
{   1, 0x80| 0,   0,   0, 0x80| 0},
451
{   2, 0x80| 0,   0,   0, 0x80| 0},
452
{   3, 0x80| 0,   0,   0, 0x00| 0},
453
{   4, 0x80| 0,   0,   0, 0x00| 0},
454
{   5, 0x80| 0,   0,   0, 0x80| 0},
455
{   6, 0x80| 0,   0,   0, 0x80| 0},
456
{   7, 0x80| 0,   0,   0, 0x80| 0},
457
{   8, 0x80| 0,   0,   0, 0x80| 0},
458
{   9, 0x80| 0,   0,   0, 0x80| 0},
459
{  10, 0x80| 0,   0,   0, 0x80| 0},
460
{  11, 0x80| 0,   0,   0, 0x80| 0},
461
{  12, 0x80| 0,   0,   0, 0x80| 0},
462
{  13, 0x80| 0,   0,   0, 0x00| 0},
463
{  14, 0x80| 0,   0,   0, 0x80| 0},
464
{  15, 0x80| 0,   0,   0, 0x00| 0},
465
{  16, 0x80| 0,   0,   0, 0x00| 0},
466
{  17, 0x80| 0,   0,   0, 0x80| 0},
467
{  18, 0x80| 0,   0,   0, 0x00| 0},
468
{  19, 0x80| 0,   3,   0, 0x00| 0},
469
{  20, 0x80| 0,   3,   0, 0x00| 0},
470
{  21, 0x80| 0,   3,   0, 0x00| 0},
471
{  22, 0x80| 0,   2,   0, 0x00| 0},
472
{  23, 0x80| 0,   3,   0, 0x80| 0},
473
{  24, 0x80| 0,   5,   0, 0x00| 0},
474
{  25, 0x80| 0,   5,   0, 0x00| 0},
475
{  26, 0x80| 0,   1,   0, 0x80| 0},
476
{  27, 0x80| 0,   2,   0, 0x80| 0},
477
{  28, 0x80| 0,   2,   0, 0x80| 0},
478
{  29, 0x80| 0,   1,   0, 0x80| 0},
479
{  30, 0x80| 0,   1,   0, 0x00| 0},
480
{  31, 0x80| 0,   2,   0, 0x00| 0},
481
{  32, 0x80| 0,   3,   0, 0x00| 0},
482
{  33, 0x80| 0,   3,   0, 0x00| 0},
483
{  34, 0x80| 0,   0,   0, 0x80| 0},
484
{  35, 0x80| 0,   2,   0, 0x80| 0},
485
{  36, 0x80| 0,   2,   0, 0x80| 0},
486
{  37, 0x80| 0,   1,   0, 0x00| 0},
487
};
488
 
489
 
490
void get_frame_internal(const frame_type frame_table[], int frame, const char* frame_table_name, int count) {
491
        if (frame >= 0 && frame < count) {
492
                cur_frame = frame_table[frame];
493
        } else {
494
                printf("Tried to use %s[%d], not in 0..%d\n", frame_table_name, frame, count-1);
495
                static const frame_type blank_frame = {255, 0, 0, 0, 0};
496
                cur_frame = blank_frame;
497
        }
498
}
499
#define get_frame(frame_table, frame) get_frame_internal(frame_table, frame, #frame_table, COUNT(frame_table))
500
 
501
// seg006:015A
502
void __pascal far load_frame() {
503
        short frame;
504
        short add_frame;
505
        frame = Char.frame;
506
        add_frame = 0;
507
        switch (Char.charid) {
508
                case charid_0_kid:
509
                case charid_24_mouse:
510
                use_table_kid:
511
                        get_frame(frame_table_kid, frame);
512
                break;
513
                case charid_2_guard:
514
                case charid_4_skeleton:
515
                        if (frame >= 102 && frame < 107) add_frame = 70;
516
                        goto use_table_guard;
517
                case charid_1_shadow:
518
                        if (frame < 150 || frame >= 190) goto use_table_kid;
519
                use_table_guard:
520
                        get_frame(frame_tbl_guard, frame + add_frame - 149);
521
                break;
522
                case charid_5_princess:
523
                case charid_6_vizier:
524
//              use_table_cutscene:
525
                        get_frame(frame_tbl_cuts, frame);
526
                break;
527
        }
528
}
529
#undef get_frame
530
 
531
// seg006:01F5
532
short __pascal far dx_weight() {
533
        sbyte var_2;
534
        var_2 = cur_frame.dx - (cur_frame.flags & FRAME_WEIGHT_X);
535
        return char_dx_forward(var_2);
536
}
537
 
538
// seg006:0213
539
int __pascal far char_dx_forward(int delta_x) {
540
        if (Char.direction < dir_0_right) {
541
                delta_x = -delta_x;
542
        }
543
        return delta_x + Char.x;
544
}
545
 
546
// seg006:0234
547
int __pascal far obj_dx_forward(int delta_x) {
548
        if (obj_direction < dir_0_right) {
549
                delta_x = -delta_x;
550
        }
551
        obj_x += delta_x;
552
        return obj_x;
553
}
554
 
555
// seg006:0254
556
void __pascal far play_seq() {
557
        for (;;) {
558
                byte item = *(SEQTBL_0 + Char.curr_seq++);
559
                switch (item) {
560
                        case SEQ_DX: // dx
561
                                Char.x = char_dx_forward(*(SEQTBL_0 + Char.curr_seq++));
562
                                break;
563
                        case SEQ_DY: // dy
564
                                Char.y += *(SEQTBL_0 + Char.curr_seq++);
565
                                break;
566
                        case SEQ_FLIP: // flip
567
                                Char.direction = ~Char.direction;
568
                                break;
569
                        case SEQ_JMP_IF_FEATHER: // jump if feather
570
                                if (!is_feather_fall) {
571
                                        ++Char.curr_seq;
572
                                        ++Char.curr_seq;
573
                                        break;
574
                                }
575
                                // fallthrough!
576
                        case SEQ_JMP: // jump
577
                                Char.curr_seq = *(const word*)(SEQTBL_0 + Char.curr_seq);
578
                                break;
579
                        case SEQ_UP: // up
580
                                --Char.curr_row;
581
                                start_chompers();
582
                                break;
583
                        case SEQ_DOWN: // down
584
                                inc_curr_row();
585
                                start_chompers();
586
                                break;
587
                        case SEQ_ACTION: // action
588
                                Char.action = *(SEQTBL_0 + Char.curr_seq++);
589
                                break;
590
                        case SEQ_SET_FALL: // set fall
591
                                Char.fall_x = *(SEQTBL_0 + Char.curr_seq++);
592
                                Char.fall_y = *(SEQTBL_0 + Char.curr_seq++);
593
                                break;
594
                        case SEQ_KNOCK_UP: // knock up
595
                                knock = 1;
596
                                break;
597
                        case SEQ_KNOCK_DOWN: // knock down
598
                                knock = -1;
599
                                break;
600
                        case SEQ_SOUND: // sound
601
                                switch (*(SEQTBL_0 + Char.curr_seq++)) {
602
                                        case SND_SILENT: // no sound actually played, but guards still notice the kid
603
                                                is_guard_notice = 1;
604
                                                break;
605
                                        case SND_FOOTSTEP: // feet
606
                                                play_sound(sound_23_footstep); // footstep
607
                                                is_guard_notice = 1;
608
                                                break;
609
                                        case SND_BUMP: // bump
610
                                                play_sound(sound_8_bumped); // touching a wall
611
                                                is_guard_notice = 1;
612
                                                break;
613
                                        case SND_DRINK: // drink
614
                                                play_sound(sound_18_drink); // drink
615
                                                break;
616
                                        case SND_LEVEL: // level
617
#ifdef USE_REPLAY
618
                                                if (recording || replaying) break; // don't do end level music in replays
619
#endif
620
 
621
                                                if (is_sound_on) {
622
                                                        if (current_level == 4) {
623
                                                                play_sound(sound_32_shadow_music); // end level with shadow (level 4)
624
                                                        } else if (current_level != 13 && current_level != 15) {
625
                                                                play_sound(sound_41_end_level_music); // end level
626
                                                        }
627
                                                }
628
                                                break;
629
                                }
630
                                break;
631
                        case SEQ_END_LEVEL: // end level
632
                                ++next_level;
633
#ifdef USE_REPLAY
634
                                // Preserve the seed in this frame, to ensure reproducibility of the replay in the next level,
635
                                // regardless of how long the sound is still playing *after* this frame.
636
                                // Animations (e.g. torch) can change the seed!
637
                                keep_last_seed = 1;
638
                                if (replaying && skipping_replay) stop_sounds();
639
#endif
640
                                break;
641
                        case SEQ_GET_ITEM: // get item
642
                                if (*(SEQTBL_0 + Char.curr_seq++) == 1) {
643
                                        proc_get_object();
644
                                }
645
                                break;
646
                        case SEQ_DIE: // nop
647
                                break;
648
                        default:
649
                                Char.frame = item;
650
                                //if (Char.frame == 185) Char.frame = 185;
651
                                return;
652
                }
653
        }
654
}
655
 
656
// seg006:03DE
657
int __pascal far get_tile_div_mod_m7(int xpos) {
658
        return get_tile_div_mod(xpos - 7);
659
}
660
 
661
// data:22A6
662
const sbyte tile_div_tbl[256] = {
663
                                    -5,-5,
664
-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
665
-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
666
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
667
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
668
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
669
 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
670
 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
671
 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
672
 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
673
 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
674
 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
675
 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
676
 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
677
 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
678
10,10,10,10,10,10,10,10,10,10,10,10,10,10,
679
11,11,11,11,11,11,11,11,11,11,11,11,11,11,
680
12,12,12,12,12,12,12,12,12,12,12,12,12,12,
681
13,13,13,13,13,13,13,13,13,13,13,13,13,13,
682
14,14
683
};
684
 
685
// data:23A6
686
const byte tile_mod_tbl[256] = {
687
                                      12, 13,
688
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
689
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
690
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
691
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
692
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
693
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
694
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
695
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
696
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
697
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
698
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
699
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
700
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
701
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
702
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
703
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
704
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
705
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
706
0, 1
707
};
708
 
709
// seg006:03F0
710
int __pascal far get_tile_div_mod(int xpos) {
711
        // xpos might be negative if the kid is far off left.
712
        // In this case, the array index overflows.
713
/*      if (xpos < 0 || xpos >= 256) {
714
                printf("get_tile_div_mod(): xpos = %d\n", xpos);
715
        }*/
716
//      obj_xl = tile_mod_tbl[xpos];
717
//      return tile_div_tbl[xpos];
718
        int x = xpos - 58;
719
        int xl = x % 14;
720
        int xh = x / 14;
721
        if (xl < 0) {
722
                // Integer division rounds towards zero, but we want to round down.
723
                --xh;
724
                // Modulo returns a negative number if x is negative, but we want 0 <= xl < 14.
725
                xl += 14;
726
        }
727
        obj_xl = xl;
728
        return xh;
729
}
730
 
731
// seg006:0433
732
int __pascal far y_to_row_mod4(int ypos) {
733
        return (ypos + 60) / 63 % 4 - 1;
734
}
735
 
736
// seg006:044F
737
void __pascal far loadkid() {
738
        Char = Kid;
739
}
740
 
741
// seg006:0464
742
void __pascal far savekid() {
743
        Kid = Char;
744
}
745
 
746
// seg006:0479
747
void __pascal far loadshad() {
748
        Char = Guard;
749
}
750
 
751
// seg006:048E
752
void __pascal far saveshad() {
753
        Guard = Char;
754
}
755
 
756
// seg006:04A3
757
void __pascal far loadkid_and_opp() {
758
        loadkid();
759
        Opp = Guard;
760
}
761
 
762
// seg006:04BC
763
void __pascal far savekid_and_opp() {
764
        savekid();
765
        Guard = Opp;
766
}
767
 
768
// seg006:04D5
769
void __pascal far loadshad_and_opp() {
770
        loadshad();
771
        Opp = Kid;
772
}
773
 
774
// seg006:04EE
775
void __pascal far saveshad_and_opp() {
776
        saveshad();
777
        Kid = Opp;
778
}
779
 
780
// seg006:0507
781
void __pascal far reset_obj_clip() {
782
        obj_clip_left = 0;
783
        obj_clip_top = 0;
784
        obj_clip_right = 320;
785
        obj_clip_bottom = 192;
786
}
787
 
788
// seg006:051C
789
void __pascal far x_to_xh_and_xl(int xpos, sbyte *xh_addr, sbyte *xl_addr) {
790
        if (xpos < 0) {
791
                *xh_addr = -((ABS(-xpos) >> 3) + 1);
792
                *xl_addr = - ((-xpos - 1) % 8 - 7);
793
        } else {
794
                *xh_addr = ABS(xpos) >> 3;
795
                *xl_addr = xpos % 8;
796
        }
797
}
798
 
799
// seg006:057C
800
void __pascal far fall_accel() {
801
        if (Char.action == actions_4_in_freefall) {
802
                if (is_feather_fall) {
803
                        ++Char.fall_y;
804
                        if (Char.fall_y > 4) Char.fall_y = 4;
805
                } else {
806
                        Char.fall_y += 3;
807
                        if (Char.fall_y > 33) Char.fall_y = 33;
808
                }
809
        }
810
}
811
 
812
// seg006:05AE
813
void __pascal far fall_speed() {
814
        Char.y += Char.fall_y;
815
        if (Char.action == actions_4_in_freefall) {
816
                Char.x = char_dx_forward(Char.fall_x);
817
                load_fram_det_col();
818
        }
819
}
820
 
821
// seg006:05CD
822
void __pascal far check_action() {
823
        short frame;
824
        short action;
825
        action = Char.action;
826
        frame = Char.frame;
827
        // frame 109: crouching
828
        if (action == actions_6_hang_straight ||
829
                action == actions_5_bumped
830
        ) {
831
                if (frame == frame_109_crouch
832
 
833
                        #ifdef FIX_STAND_ON_THIN_AIR
834
                        || (fix_stand_on_thin_air &&
835
                                frame >= frame_110_stand_up_from_crouch_1 && frame <= frame_119_stand_up_from_crouch_10)
836
                        #endif
837
 
838
                                ) {
839
                        check_on_floor();
840
                }
841
        } else if (action == actions_4_in_freefall) {
842
                do_fall();
843
        } else if (action == actions_3_in_midair) {
844
                // frame 102..106: start fall + fall
845
                if (frame >= frame_102_start_fall_1 && frame < frame_106_fall) {
846
                        check_grab();
847
                }
848
        } else if (action != actions_2_hang_climb) {
849
                check_on_floor();
850
        }
851
}
852
 
853
// seg006:0628
854
int __pascal far tile_is_floor(int tiletype) {
855
        switch (tiletype) {
856
                case tiles_0_empty:
857
                case tiles_9_bigpillar_top:
858
                case tiles_12_doortop:
859
                case tiles_20_wall:
860
                case tiles_26_lattice_down:
861
                case tiles_27_lattice_small:
862
                case tiles_28_lattice_left:
863
                case tiles_29_lattice_right:
864
                        return 0;
865
                default:
866
                        return 1;
867
        }
868
}
869
 
870
// seg006:0658
871
void __pascal far check_spiked() {
872
        short harmful;
873
        short frame;
874
        frame = Char.frame;
875
        if (get_tile(Char.room, Char.curr_col, Char.curr_row) == tiles_2_spike) {
876
                harmful = is_spike_harmful();
877
                // frames 7..14: running
878
                // frames 34..39: start run-jump
879
                // frame 43: land from run-jump
880
                // frame 26: lang from standing jump
881
                if (
882
                        (harmful >= 2 && ((frame>= frame_7_run && frame<15) || (frame>=frame_34_start_run_jump_1 && frame<40))) ||
883
                        ((frame == frame_43_running_jump_4 || frame == frame_26_standing_jump_11) && harmful != 0)
884
                ) {
885
                        spiked();
886
                }
887
        }
888
}
889
 
890
// seg006:06BD
891
int __pascal far take_hp(int count) {
892
        word dead;
893
        dead = 0;
894
        if (Char.charid == charid_0_kid) {
895
                if (count >= hitp_curr) {
896
                        hitp_delta = -hitp_curr;
897
                        dead = 1;
898
                } else {
899
                        hitp_delta = -count;
900
                }
901
        } else {
902
                if (count >= guardhp_curr) {
903
                        guardhp_delta = -guardhp_curr;
904
                        dead = 1;
905
                } else {
906
                        guardhp_delta = -count;
907
                }
908
        }
909
        return dead;
910
}
911
 
912
// seg006:070D
913
int __pascal far get_tile_at_char() {
914
        return get_tile(Char.room, Char.curr_col, Char.curr_row);
915
}
916
 
917
// seg006:0723
918
void __pascal far set_char_collision() {
919
        image_type* image = get_image(obj_chtab, obj_id);
920
        if (image == NULL) {
921
                char_width_half = 0;
922
                char_height = 0;
923
        } else {
924
                char_width_half = (image->/*width*/w + 1) / 2;
925
                char_height = image->/*height*/h;
926
        }
927
        char_x_left = obj_x / 2 + 58;
928
        if (Char.direction >= dir_0_right) {
929
                char_x_left -= char_width_half;
930
        }
931
        char_x_left_coll = char_x_left;
932
        char_x_right_coll = char_x_right = char_x_left + char_width_half;
933
        char_top_y = obj_y - char_height + 1;
934
        if (char_top_y >= 192) {
935
                char_top_y = 0;
936
        }
937
        char_top_row = y_to_row_mod4(char_top_y);
938
        char_bottom_row = y_to_row_mod4(obj_y);
939
        if (char_bottom_row == -1) {
940
                char_bottom_row = 3;
941
        }
942
        char_col_left = MAX(get_tile_div_mod(char_x_left), 0);
943
        char_col_right = MIN(get_tile_div_mod(char_x_right), 9);
944
        if (cur_frame.flags & FRAME_THIN) {
945
                // "thin" this frame for collision detection
946
                char_x_left_coll += 4;
947
                char_x_right_coll -= 4;
948
        }
949
}
950
 
951
// seg006:0815
952
void __pascal far check_on_floor() {
953
        if (cur_frame.flags & FRAME_NEEDS_FLOOR) {
954
                if (get_tile_at_char() == tiles_20_wall) {
955
                        in_wall();
956
                }
957
                if (! tile_is_floor(curr_tile2)) {
958
                        // Special event: floors appear
959
                        if (current_level == 12 &&
960
                                united_with_shadow < 0 &&
961
                                Char.curr_row == 0 &&
962
                                (Char.room == 2 || (Char.room == 13 && tile_col >= 6))
963
                        ) {
964
                                curr_room_tiles[curr_tilepos] = tiles_1_floor;
965
                                set_wipe(curr_tilepos, 1);
966
                                set_redraw_full(curr_tilepos, 1);
967
                                ++curr_tilepos;
968
                                set_wipe(curr_tilepos, 1);
969
                                set_redraw_full(curr_tilepos, 1);
970
                        } else {
971
 
972
#ifdef FIX_STAND_ON_THIN_AIR
973
                                if (fix_stand_on_thin_air &&
974
                                        Char.frame >= frame_110_stand_up_from_crouch_1 && Char.frame <= frame_119_stand_up_from_crouch_10)
975
                                {
976
                                        // We need to prevent the Kid from stepping off a ledge accidentally while standing up.
977
                                        // (This can happen because the "standing up" frames now require a floor.)
978
                                        // --> Cancel the fall, if the tile at dx=2 behind the kid is a valid floor.
979
                                        int col = get_tile_div_mod_m7(dx_weight() + back_delta_x(2));
980
                                        if (tile_is_floor(get_tile(Char.room, col, Char.curr_row))) {
981
                                                return;
982
                                        }
983
                                }
984
#endif
985
 
986
                                start_fall();
987
                        }
988
                }
989
        }
990
}
991
 
992
// seg006:08B9
993
void __pascal far start_fall() {
994
        short frame;
995
        word seq_id;
996
        frame = Char.frame;
997
        Char.sword = sword_0_sheathed;
998
        inc_curr_row();
999
        start_chompers();
1000
        fall_frame = frame;
1001
        if (frame == frame_9_run) {
1002
                // frame 9: run
1003
                seq_id = seq_7_fall; // fall (when?)
1004
        } else if (frame == frame_13_run) {
1005
                // frame 13: run
1006
                seq_id = seq_19_fall; // fall (when?)
1007
        } else if (frame == frame_26_standing_jump_11) {
1008
                // frame 26: land after standing jump
1009
                seq_id = seq_18_fall_after_standing_jump; // fall after standing jump
1010
        } else if (frame == frame_44_running_jump_5) {
1011
                // frame 44: land after running jump
1012
                seq_id = seq_21_fall_after_running_jump; // fall after running jump
1013
        } else if (frame >= frame_81_hangdrop_1 && frame < 86) {
1014
                // frame 81..85: land after jump up
1015
                seq_id = seq_19_fall; // fall after jumping up
1016
                Char.x = char_dx_forward(5);
1017
                load_fram_det_col();
1018
        } else if (frame >= 150 && frame < 180) {
1019
                // frame 150..179: with sword + fall + dead
1020
                if (Char.charid == charid_2_guard) {
1021
                        if (Char.curr_row == 3 && Char.curr_col == 10) {
1022
                                clear_char();
1023
                                return;
1024
                        }
1025
                        if (Char.fall_x < 0) {
1026
                                seq_id = seq_82_guard_pushed_off_ledge; // Guard is pushed off the ledge
1027
                                if (Char.direction < dir_0_right && distance_to_edge_weight() <= 7) {
1028
                                        Char.x = char_dx_forward(-5);
1029
                                }
1030
                        } else {
1031
                                droppedout = 0;
1032
                                seq_id = seq_83_guard_fall; // fall after forwarding with sword
1033
                        }
1034
                } else {
1035
                        droppedout = 1;
1036
                        if (Char.direction < dir_0_right && distance_to_edge_weight() <= 7) {
1037
                                Char.x = char_dx_forward(-5);
1038
                        }
1039
                        seq_id = seq_81_kid_pushed_off_ledge; // fall after backing with sword / Kid is pushed off the ledge
1040
                }
1041
        } else {
1042
                seq_id = seq_7_fall; // fall after stand, run, step, crouch
1043
        }
1044
        seqtbl_offset_char(seq_id);
1045
        play_seq();
1046
        load_fram_det_col();
1047
        if (get_tile_at_char() == tiles_20_wall) {
1048
                in_wall();
1049
                return;
1050
        }
1051
        int tile = get_tile_infrontof_char();
1052
        if (tile == tiles_20_wall
1053
 
1054
                #ifdef FIX_RUNNING_JUMP_THROUGH_TAPESTRY
1055
                        // Also treat tapestries (when approached to the left) like a wall here.
1056
                || (fix_running_jump_through_tapestry && Char.direction == dir_FF_left &&
1057
                        (tile == tiles_12_doortop || tile == tiles_7_doortop_with_floor))
1058
                #endif
1059
 
1060
                        ) {
1061
                if (fall_frame != 44 || distance_to_edge_weight() >= 6) {
1062
                        Char.x = char_dx_forward(-1);
1063
                } else {
1064
                        seqtbl_offset_char(seq_104_start_fall_in_front_of_wall); // start fall (when?)
1065
                        play_seq();
1066
                }
1067
                load_fram_det_col();
1068
        }
1069
}
1070
 
1071
// seg006:0A19
1072
void __pascal far check_grab() {
1073
        word old_x;
1074
 
1075
        #ifdef FIX_GRAB_FALLING_SPEED
1076
        #define MAX_GRAB_FALLING_SPEED (fix_grab_falling_speed ? 30 : 32)
1077
        #else
1078
        #define MAX_GRAB_FALLING_SPEED 32
1079
        #endif
1080
 
1081
        if (control_shift < 0 && // press shift to grab
1082
                Char.fall_y < MAX_GRAB_FALLING_SPEED && // you can't grab if you're falling too fast ...
1083
                Char.alive < 0 && // ... or dead
1084
                (word)y_land[Char.curr_row + 1] <= (word)(Char.y + 25)
1085
        ) {
1086
                //printf("Falling speed: %d\t x: %d\n", Char.fall_y, Char.x);
1087
                old_x = Char.x;
1088
                Char.x = char_dx_forward(-8);
1089
                load_fram_det_col();
1090
                if ( ! can_grab_front_above()) {
1091
                        Char.x = old_x;
1092
                } else {
1093
                        Char.x = char_dx_forward(distance_to_edge_weight());
1094
                        Char.y = y_land[Char.curr_row + 1];
1095
                        Char.fall_y = 0;
1096
                        seqtbl_offset_char(seq_15_grab_ledge_midair); // grab a ledge (after falling)
1097
                        play_seq();
1098
                        grab_timer = 12;
1099
                        play_sound(sound_9_grab); // grab
1100
                        is_screaming = 0;
1101
#ifdef FIX_CHOMPERS_NOT_STARTING
1102
                        if (fix_chompers_not_starting) start_chompers();
1103
#endif
1104
                }
1105
        }
1106
}
1107
 
1108
// seg006:0ABD
1109
int __pascal far can_grab_front_above() {
1110
        through_tile = get_tile_above_char();
1111
        get_tile_front_above_char();
1112
        return can_grab();
1113
}
1114
 
1115
// seg006:0ACD
1116
void __pascal far in_wall() {
1117
        short delta_x;
1118
        delta_x = distance_to_edge_weight();
1119
        if (delta_x >= 8 || get_tile_infrontof_char() == tiles_20_wall) {
1120
                delta_x = 6 - delta_x;
1121
        } else {
1122
                delta_x += 4;
1123
        }
1124
        Char.x = char_dx_forward(delta_x);
1125
        load_fram_det_col();
1126
        get_tile_at_char();
1127
}
1128
 
1129
// seg006:0B0C
1130
int __pascal far get_tile_infrontof_char() {
1131
        return get_tile(Char.room, infrontx = dir_front[Char.direction + 1] + Char.curr_col, Char.curr_row);
1132
}
1133
 
1134
// seg006:0B30
1135
int __pascal far get_tile_infrontof2_char() {
1136
        short var_2;
1137
        var_2 = dir_front[Char.direction + 1];
1138
        return get_tile(Char.room, infrontx = (var_2 << 1) + Char.curr_col, Char.curr_row);
1139
}
1140
 
1141
// seg006:0B66
1142
int __pascal far get_tile_behind_char() {
1143
        return get_tile(Char.room, dir_behind[Char.direction + 1] + Char.curr_col, Char.curr_row);
1144
}
1145
 
1146
// seg006:0B8A
1147
int __pascal far distance_to_edge_weight() {
1148
        return distance_to_edge(dx_weight());
1149
}
1150
 
1151
// seg006:0B94
1152
int __pascal far distance_to_edge(int xpos) {
1153
        short distance;
1154
        get_tile_div_mod_m7(xpos);
1155
        distance = obj_xl;
1156
        if (Char.direction == dir_0_right) {
1157
                distance = 13 - distance;
1158
        }
1159
        return distance;
1160
}
1161
 
1162
// seg006:0BC4
1163
void __pascal far fell_out() {
1164
        if (Char.alive < 0 && Char.room == 0) {
1165
                take_hp(100);
1166
                Char.alive = 0;
1167
                erase_bottom_text(1);
1168
                Char.frame = frame_185_dead; // dead
1169
        }
1170
}
1171
 
1172
// seg006:0BEE
1173
void __pascal far play_kid() {
1174
        fell_out();
1175
        control_kid();
1176
        if (Char.alive >= 0 && is_dead()) {
1177
                if (resurrect_time) {
1178
                        stop_sounds();
1179
                        loadkid();
1180
                        hitp_delta = hitp_max;
1181
                        seqtbl_offset_char(seq_2_stand); // stand
1182
                        Char.x += 8;
1183
                        play_seq();
1184
                        load_fram_det_col();
1185
                        set_start_pos();
1186
                }
1187
                if (check_sound_playing() && current_sound != 5) { // gate opening
1188
                        return;
1189
                }
1190
                is_show_time = 0;
1191
                if (Char.alive < 0 || Char.alive >= 6) {
1192
                        if (Char.alive == 6) {
1193
                                if (is_sound_on &&
1194
                                        current_level != 0 && // no death music on demo level
1195
                                        current_level != 15 // no death music on potions level
1196
                                ) {
1197
                                        play_death_music();
1198
                                }
1199
                        } else {
1200
                                if (Char.alive != 7 || check_sound_playing()) return;
1201
                                if (rem_min == 0) {
1202
                                        expired();
1203
                                }
1204
                                if (current_level != 0 && // no message if died on demo level
1205
                                        current_level != 15 // no message if died on potions level
1206
                                ) {
1207
                                        text_time_remaining = text_time_total = 288;
1208
                                        display_text_bottom("Press Button to Continue");
1209
                                } else {
1210
                                        text_time_remaining = text_time_total = 36;
1211
                                }
1212
                        }
1213
                }
1214
                ++Char.alive;
1215
        }
1216
}
1217
 
1218
// seg006:0CD1
1219
void __pascal far control_kid() {
1220
        word key;
1221
        if (Char.alive < 0 && hitp_curr == 0) {
1222
                Char.alive = 0;
1223
        }
1224
        if (grab_timer != 0) {
1225
                --grab_timer;
1226
        }
1227
        if (current_level == 0) {
1228
                do_demo();
1229
                control();
1230
                // we can start the game or load a game while the demo
1231
                key = key_test_quit();
1232
                if (key == 0x0C) { // ctrl-L
1233
                        if (load_game()) {
1234
                                start_game();
1235
                        }
1236
                } else {
1237
                        if (key) {
1238
                                start_level = first_level; // 1
1239
                                start_game();
1240
                        }
1241
                }
1242
        } else {
1243
                rest_ctrl_1();
1244
                do_paused();
1245
                #ifdef USE_REPLAY
1246
                if (recording) add_replay_move();
1247
                if (replaying) do_replay_move();
1248
                #endif
1249
                read_user_control();
1250
                user_control();
1251
                save_ctrl_1();
1252
        }
1253
}
1254
 
1255
const auto_move_type demo_moves[] = {
1256
{0x00, 0},
1257
{0x01, 1},
1258
{0x0D, 0},
1259
{0x1E, 1},
1260
{0x25, 5},
1261
{0x2F, 0},
1262
{0x30, 1},
1263
{0x41, 0},
1264
{0x49, 2},
1265
{0x4B, 0},
1266
{0x63, 2},
1267
{0x64, 0},
1268
{0x73, 5},
1269
{0x80, 6},
1270
{0x88, 3},
1271
{0x9D, 7},
1272
{0x9E, 0},
1273
{0x9F, 1},
1274
{0xAB, 4},
1275
{0xB1, 0},
1276
{0xB2, 1},
1277
{0xBC, 0},
1278
{0xC1, 1},
1279
{0xCD, 0},
1280
{0xE9,-1},
1281
};
1282
 
1283
// seg006:0D49
1284
void __pascal far do_demo() {
1285
        if (checkpoint) {
1286
                control_shift2 = release_arrows();
1287
                control_forward = control_x = -1;
1288
        } else if (Char.sword) {
1289
                guard_skill = 10;
1290
                autocontrol_opponent();
1291
                guard_skill = 11;
1292
        } else {
1293
                do_auto_moves(demo_moves);
1294
        }
1295
}
1296
 
1297
// seg006:0D85
1298
void __pascal far play_guard() {
1299
        if (Char.charid == charid_24_mouse) {
1300
                autocontrol_opponent();
1301
        } else {
1302
                if (Char.alive < 0) {
1303
                        if (guardhp_curr == 0) {
1304
                                Char.alive = 0;
1305
                                on_guard_killed();
1306
                        } else {
1307
                                goto loc_7A65;
1308
                        }
1309
                }
1310
                if (Char.charid == charid_1_shadow) {
1311
                        clear_char();
1312
                }
1313
                loc_7A65:
1314
                autocontrol_opponent();
1315
                control();
1316
        }
1317
}
1318
 
1319
// seg006:0DC0
1320
void __pascal far user_control() {
1321
        if (Char.direction >= dir_0_right) {
1322
                flip_control_x();
1323
                control();
1324
                flip_control_x();
1325
        } else {
1326
                control();
1327
        }
1328
}
1329
 
1330
// seg006:0DDC
1331
void __pascal far flip_control_x() {
1332
        byte temp;
1333
        control_x = -control_x;
1334
        temp = control_forward;
1335
        control_forward = control_backward;
1336
        control_backward = temp;
1337
}
1338
 
1339
// seg006:0E00
1340
int __pascal far release_arrows() {
1341
        control_backward = control_forward = control_up = control_down = 0;
1342
        return 1;
1343
}
1344
 
1345
// seg006:0E12
1346
void __pascal far save_ctrl_1() {
1347
        ctrl1_forward = control_forward;
1348
        ctrl1_backward = control_backward;
1349
        ctrl1_up = control_up;
1350
        ctrl1_down = control_down;
1351
        ctrl1_shift2 = control_shift2;
1352
}
1353
 
1354
// seg006:0E31
1355
void __pascal far rest_ctrl_1() {
1356
        control_forward = ctrl1_forward;
1357
        control_backward = ctrl1_backward;
1358
        control_up = ctrl1_up;
1359
        control_down = ctrl1_down;
1360
        control_shift2 = ctrl1_shift2;
1361
}
1362
 
1363
// seg006:0E8E
1364
void __pascal far clear_saved_ctrl() {
1365
        ctrl1_forward = ctrl1_backward = ctrl1_up = ctrl1_down = ctrl1_shift2 = 0;
1366
}
1367
 
1368
// seg006:0EAF
1369
void __pascal far read_user_control() {
1370
        if (control_forward >= 0) {
1371
                if (control_x < 0) {
1372
                        if (control_forward == 0) {
1373
                                control_forward = -1;
1374
                        }
1375
                } else {
1376
                        control_forward = 0;
1377
                }
1378
        }
1379
        if (control_backward >= 0) {
1380
                if (control_x == 1) {
1381
                        if (control_backward == 0) {
1382
                                control_backward = -1;
1383
                        }
1384
                } else {
1385
                        control_backward = 0;
1386
                }
1387
        }
1388
        if (control_up >= 0) {
1389
                if (control_y < 0) {
1390
                        if (control_up == 0) {
1391
                                control_up = -1;
1392
                        }
1393
                } else {
1394
                        control_up = 0;
1395
                }
1396
        }
1397
        if (control_down >= 0) {
1398
                if (control_y == 1) {
1399
                        if (control_down == 0) {
1400
                                control_down = -1;
1401
                        }
1402
                } else {
1403
                        control_down = 0;
1404
                }
1405
        }
1406
        if (control_shift2 >= 0) {
1407
                if (control_shift < 0) {
1408
                        if (control_shift2 == 0) {
1409
                                control_shift2 = -1;
1410
                        }
1411
                } else {
1412
                        control_shift2 = 0;
1413
                }
1414
        }
1415
}
1416
 
1417
// seg006:0F55
1418
int __pascal far can_grab() {
1419
        // Can char grab curr_tile2 through through_tile?
1420
        byte modifier;
1421
        modifier = curr_room_modif[curr_tilepos];
1422
        // can't grab through wall
1423
        if (through_tile == tiles_20_wall) return 0;
1424
        // can't grab through a door top if looking right
1425
        if (through_tile == tiles_12_doortop && Char.direction >= dir_0_right) return 0;
1426
        // can't grab through floor
1427
        if (tile_is_floor(through_tile)) return 0;
1428
        // can't grab a shaking loose floor
1429
        if (curr_tile2 == tiles_11_loose && modifier != 0) return 0;
1430
        // a doortop with floor can be grabbed only from the left (looking right)
1431
        if (curr_tile2 == tiles_7_doortop_with_floor && Char.direction < dir_0_right) return 0;
1432
        // can't grab something that has no floor
1433
        if ( ! tile_is_floor(curr_tile2)) return 0;
1434
        return 1;
1435
}
1436
 
1437
// seg006:0FC3
1438
int __pascal far wall_type(byte tiletype) {
1439
        switch (tiletype) {
1440
                case tiles_4_gate:
1441
                case tiles_7_doortop_with_floor:
1442
                case tiles_12_doortop:
1443
                        return 1; // wall at right
1444
                case tiles_13_mirror:
1445
                        return 2; // wall at left
1446
                case tiles_18_chomper:
1447
                        return 3; // chomper at left
1448
                case tiles_20_wall:
1449
                        return 4; // wall at both sides
1450
                default:
1451
                        return 0; // no wall
1452
        }
1453
}
1454
 
1455
// seg006:1005
1456
int __pascal far get_tile_above_char() {
1457
        return get_tile(Char.room, Char.curr_col, Char.curr_row - 1);
1458
}
1459
 
1460
// seg006:1020
1461
int __pascal far get_tile_behind_above_char() {
1462
        return get_tile(Char.room, dir_behind[Char.direction + 1] + Char.curr_col, Char.curr_row - 1);
1463
}
1464
 
1465
// seg006:1049
1466
int __pascal far get_tile_front_above_char() {
1467
        return get_tile(Char.room, infrontx = dir_front[Char.direction + 1] + Char.curr_col, Char.curr_row - 1);
1468
}
1469
 
1470
// seg006:1072
1471
int __pascal far back_delta_x(int delta_x) {
1472
        if (Char.direction < dir_0_right) {
1473
                // direction = left
1474
                return delta_x;
1475
        } else {
1476
                // direction = right
1477
                return -delta_x;
1478
        }
1479
}
1480
 
1481
// seg006:108A
1482
void __pascal far do_pickup(int obj_type) {
1483
        pickup_obj_type = obj_type;
1484
        control_shift2 = 1;
1485
        // erase picked up item
1486
        curr_room_tiles[curr_tilepos] = tiles_1_floor;
1487
        curr_room_modif[curr_tilepos] = 0;
1488
        redraw_height = 35;
1489
        set_wipe(curr_tilepos, 1);
1490
        set_redraw_full(curr_tilepos, 1);
1491
}
1492
 
1493
// seg006:10E6
1494
void __pascal far check_press() {
1495
        short frame;
1496
        short action;
1497
        frame = Char.frame;
1498
        action = Char.action;
1499
        // frames 87..99: hanging
1500
        // frames 135..140: start climb up
1501
        if ((frame >= frame_87_hanging_1 && frame < 100) || (frame >= frame_135_climbing_1 && frame < frame_141_climbing_7)) {
1502
                // the pressed tile is the one that the char is grabbing
1503
                get_tile_above_char();
1504
        } else if (action == actions_7_turn || action == actions_5_bumped || action < actions_2_hang_climb) {
1505
                // frame 79: jumping up
1506
                if (frame == frame_79_jumphang && get_tile_above_char() == tiles_11_loose) {
1507
                        // break a loose floor from above
1508
                        make_loose_fall(1);
1509
                } else {
1510
                        // the pressed tile is the one that the char is standing on
1511
                        if (! (cur_frame.flags & FRAME_NEEDS_FLOOR)) return;
1512
                        #ifdef FIX_PRESS_THROUGH_CLOSED_GATES
1513
                        if (fix_press_through_closed_gates) determine_col();
1514
                        #endif
1515
                        get_tile_at_char();
1516
                }
1517
        } else {
1518
                return;
1519
        }
1520
        if (curr_tile2 == tiles_15_opener || curr_tile2 == tiles_6_closer) {
1521
                if (Char.alive < 0) {
1522
                        trigger_button(1, 0, -1);
1523
                } else {
1524
                        died_on_button();
1525
                }
1526
        } else if (curr_tile2 == tiles_11_loose) {
1527
                is_guard_notice = 1;
1528
                make_loose_fall(1);
1529
        }
1530
}
1531
 
1532
// seg006:1199
1533
void __pascal far check_spike_below() {
1534
        short not_finished;
1535
        short room;
1536
        short row;
1537
        short col;
1538
        short right_col;
1539
        right_col = get_tile_div_mod_m7(char_x_right);
1540
        if (right_col < 0) return;
1541
        row = Char.curr_row;
1542
        room = Char.room;
1543
        for (col = get_tile_div_mod_m7(char_x_left); col <= right_col; ++col) {
1544
                row = Char.curr_row;
1545
                do {
1546
                        not_finished = 0;
1547
                        if (get_tile(room, col, row) == tiles_2_spike) {
1548
                                start_anim_spike(curr_room, curr_tilepos);
1549
                        } else if (
1550
                                ! tile_is_floor(curr_tile2) &&
1551
                                curr_room != 0 &&
1552
#ifdef FIX_INFINITE_DOWN_BUG
1553
                                (fix_infinite_down_bug ? (row <= 2) : (room == curr_room))
1554
#else
1555
                                room == curr_room
1556
#endif
1557
                        ) {
1558
                                ++row;
1559
                                not_finished = 1;
1560
                        }
1561
                } while(not_finished);
1562
        }
1563
}
1564
 
1565
// seg006:1231
1566
void __pascal far clip_char() {
1567
        short frame;
1568
        short room;
1569
        short action;
1570
        short col;
1571
        short var_A;
1572
        short row;
1573
        short var_E;
1574
        frame = Char.frame;
1575
        action = Char.action;
1576
        room = Char.room;
1577
        row = Char.curr_row;
1578
        reset_obj_clip();
1579
        // frames 217..228: going up the level door
1580
        if (frame >= frame_224_exit_stairs_8 && frame < 229) {
1581
                obj_clip_top = leveldoor_ybottom + 1;
1582
                obj_clip_right = leveldoor_right;
1583
        } else {
1584
                if (
1585
                        get_tile(room, char_col_left, char_top_row) == tiles_20_wall ||
1586
                        tile_is_floor(curr_tile2)
1587
                ) {
1588
                        // frame 79: jump up, frame 81: grab
1589
                        if ((action == actions_0_stand && (frame == frame_79_jumphang || frame == frame_81_hangdrop_1)) ||
1590
                                get_tile(room, char_col_right, char_top_row) == tiles_20_wall ||
1591
                                tile_is_floor(curr_tile2)
1592
                        ) {
1593
                                var_E = row + 1;
1594
                                if (var_E == 1 ||
1595
                                        ((var_A = y_clip[var_E]) < obj_y && var_A - 15 < char_top_y)
1596
                                ) {
1597
                                        obj_clip_top = char_top_y = y_clip[var_E];
1598
                                }
1599
                        }
1600
                }
1601
                col = get_tile_div_mod(char_x_left_coll - 4);
1602
                if (get_tile(room, col + 1, row) == tiles_7_doortop_with_floor ||
1603
                        curr_tile2 == tiles_12_doortop
1604
                ) {
1605
                        obj_clip_right = (tile_col << 5) + 32;
1606
                } else {
1607
                        if ((get_tile(room, col, row) != tiles_7_doortop_with_floor &&
1608
                                curr_tile2 != tiles_12_doortop) ||
1609
                                action == actions_3_in_midair ||
1610
                                (action == actions_4_in_freefall && frame == frame_106_fall) ||
1611
                                (action == actions_5_bumped && frame == frame_107_fall_land_1) ||
1612
                                (Char.direction < dir_0_right && (
1613
                                        action == actions_2_hang_climb ||
1614
                                        action == actions_6_hang_straight ||
1615
                                        (action == actions_1_run_jump &&
1616
                                        frame >= frame_137_climbing_3 && frame < frame_140_climbing_6)
1617
                                ))
1618
                        ) {
1619
                                if (
1620
                                        (get_tile(room, col = get_tile_div_mod(char_x_right_coll), row) == tiles_20_wall ||
1621
                                        (curr_tile2 == tiles_13_mirror && Char.direction == dir_0_right)) &&
1622
                                        (get_tile(room, col, char_top_row) == tiles_20_wall ||
1623
                                        curr_tile2 == tiles_13_mirror) &&
1624
                                        room == curr_room
1625
                                ) {
1626
                                        obj_clip_right = tile_col << 5;
1627
                                }
1628
                        } else {
1629
                                obj_clip_right = (tile_col << 5) + 32;
1630
                        }
1631
                }
1632
        }
1633
}
1634
 
1635
// seg006:13E6
1636
void __pascal far stuck_lower() {
1637
        if (get_tile_at_char() == tiles_5_stuck) {
1638
                ++Char.y;
1639
        }
1640
}
1641
 
1642
// seg006:13F3
1643
void __pascal far set_objtile_at_char() {
1644
        short char_frame;
1645
        short char_action;
1646
        char_frame = Char.frame;
1647
        char_action = Char.action;
1648
        if (char_action == actions_1_run_jump) {
1649
                tile_row = char_bottom_row;
1650
                tile_col = char_col_left;
1651
        } else {
1652
                tile_row = Char.curr_row;
1653
                tile_col = Char.curr_col;
1654
        }
1655
        // frame 135..148: climbing
1656
        if ((char_frame >= frame_135_climbing_1 && char_frame < 149) ||
1657
                char_action == actions_2_hang_climb ||
1658
                char_action == actions_3_in_midair ||
1659
                char_action == actions_4_in_freefall ||
1660
                char_action == actions_6_hang_straight
1661
        ) {
1662
                --tile_col;
1663
        }
1664
        obj_tilepos = get_tilepos_nominus(tile_col, tile_row);
1665
        //printf("set_objtile_at_char: obj_tile = %d\n", obj_tile); // debug
1666
}
1667
 
1668
// seg006:1463
1669
void __pascal far proc_get_object() {
1670
        if (Char.charid != charid_0_kid || pickup_obj_type == 0) return;
1671
        if (pickup_obj_type == -1) {
1672
                have_sword = -1;
1673
                play_sound(sound_37_victory); // get sword
1674
                flash_color = color_14_brightyellow;
1675
                flash_time = 8;
1676
        } else {
1677
                switch (--pickup_obj_type) {
1678
                        case 0: // health
1679
                                if (hitp_curr != hitp_max) {
1680
                                        stop_sounds();
1681
                                        play_sound(sound_33_small_potion); // small potion
1682
                                        hitp_delta = 1;
1683
                                        flash_color = color_4_red;
1684
                                        flash_time = 2;
1685
                                }
1686
                        break;
1687
                        case 1: // life
1688
                                stop_sounds();
1689
                                play_sound(sound_30_big_potion); // big potion
1690
                                flash_color = color_4_red;
1691
                                flash_time = 4;
1692
                                add_life();
1693
                        break;
1694
                        case 2: // feather
1695
                                feather_fall();
1696
                        break;
1697
                        case 3: // invert
1698
                                toggle_upside();
1699
                        break;
1700
                        case 5: // open
1701
                                get_tile(8, 0, 0);
1702
                                trigger_button(0, 0, -1);
1703
                        break;
1704
                        case 4: // hurt
1705
                                stop_sounds();
1706
                                play_sound(sound_13_kid_hurt); // Kid hurt (by potion)
1707
                                // Special event: blue potions on potions level take half of HP
1708
                                if (current_level == 15) {
1709
                                        hitp_delta = - ((hitp_max + 1) >> 1);
1710
                                } else {
1711
                                        hitp_delta = -1;
1712
                                }
1713
                        break;
1714
                }
1715
        }
1716
}
1717
 
1718
// seg006:1599
1719
int __pascal far is_dead() {
1720
        // 177: spiked, 178: chomped, 185: dead
1721
        // or maybe this was a switch-case?
1722
        return Char.frame >= frame_177_spiked && (Char.frame <= frame_178_chomped || Char.frame == frame_185_dead);
1723
}
1724
 
1725
// seg006:15B5
1726
void __pascal far play_death_music() {
1727
        word sound_id;
1728
        if (Guard.charid == charid_1_shadow) {
1729
                sound_id = sound_32_shadow_music; // killed by shadow
1730
        } else if (holding_sword) {
1731
                sound_id = sound_28_death_in_fight; // death in fight
1732
        } else {
1733
                sound_id = sound_24_death_regular; // death not in fight
1734
        }
1735
        play_sound(sound_id);
1736
}
1737
 
1738
// seg006:15E8
1739
void __pascal far on_guard_killed() {
1740
        if (current_level == 0) {
1741
                // demo level: after killing Guard, run out of room
1742
                checkpoint = 1;
1743
                demo_index = demo_time = 0;
1744
        } else if (current_level == 13) {
1745
                // Jaffar's level: flash
1746
                flash_color = color_15_brightwhite; // white
1747
                flash_time = 18;
1748
                is_show_time = 1;
1749
                leveldoor_open = 2;
1750
                play_sound(sound_43_victory_Jaffar); // Jaffar's death
1751
        } else if (Char.charid != charid_1_shadow) {
1752
                play_sound(sound_37_victory); // Guard's death
1753
        }
1754
}
1755
 
1756
// seg006:1634
1757
void __pascal far clear_char() {
1758
        Char.direction = dir_56_none;
1759
        Char.alive = 0;
1760
        Char.action = 0;
1761
        draw_guard_hp(0, guardhp_curr);
1762
        guardhp_curr = 0;
1763
}
1764
 
1765
// data:42EC
1766
byte obj2_tilepos;
1767
// data:34A6
1768
word obj2_x;
1769
// data:34A8
1770
byte obj2_y;
1771
// data:599E
1772
sbyte obj2_direction;
1773
// data:5948
1774
byte obj2_id;
1775
// data:42BE
1776
byte obj2_chtab;
1777
// data:4D90
1778
short obj2_clip_top;
1779
// data:460C
1780
short obj2_clip_bottom;
1781
// data:4C94
1782
short obj2_clip_left;
1783
// data:4CDE
1784
short obj2_clip_right;
1785
 
1786
// seg006:1654
1787
void __pascal far save_obj() {
1788
        obj2_tilepos = obj_tilepos;
1789
        obj2_x = obj_x;
1790
        obj2_y = obj_y;
1791
        obj2_direction = obj_direction;
1792
        obj2_id = obj_id;
1793
        obj2_chtab = obj_chtab;
1794
        obj2_clip_top = obj_clip_top;
1795
        obj2_clip_bottom = obj_clip_bottom;
1796
        obj2_clip_left = obj_clip_left;
1797
        obj2_clip_right = obj_clip_right;
1798
}
1799
 
1800
// seg006:1691
1801
void __pascal far load_obj() {
1802
        obj_tilepos = obj2_tilepos;
1803
        obj_x = obj2_x;
1804
        obj_y = obj2_y;
1805
        obj_direction = obj2_direction;
1806
        obj_id = obj2_id;
1807
        obj_chtab = obj2_chtab;
1808
        obj_clip_top = obj2_clip_top;
1809
        obj_clip_bottom = obj2_clip_bottom;
1810
        obj_clip_left = obj2_clip_left;
1811
        obj_clip_right = obj2_clip_right;
1812
}
1813
 
1814
// seg006:16CE
1815
void __pascal far draw_hurt_splash() {
1816
        short frame;
1817
        frame = Char.frame;
1818
        if (frame != frame_178_chomped) { // chomped
1819
                save_obj();
1820
                obj_tilepos = -1;
1821
                // frame 185: dead
1822
                // frame 106..110: fall + land
1823
                if (frame == frame_185_dead || (frame>= frame_106_fall && frame<111)) {
1824
                        obj_y += 4;
1825
                        obj_dx_forward(5);
1826
                } else if (frame == frame_177_spiked) { // spiked
1827
                        obj_dx_forward(-5);
1828
                } else {
1829
                        obj_y -= ((Char.charid == charid_0_kid) << 2) + 11;
1830
                        obj_dx_forward(5);
1831
                }
1832
                if (Char.charid == charid_0_kid) {
1833
                        obj_chtab = id_chtab_2_kid;
1834
                        obj_id = 218; // splash!
1835
                } else {
1836
                        obj_chtab = id_chtab_5_guard;
1837
                        obj_id = 1; // splash!
1838
                }
1839
                reset_obj_clip();
1840
                add_objtable(5); // hurt splash
1841
                load_obj();
1842
        }
1843
}
1844
 
1845
// seg006:175D
1846
void __pascal far check_killed_shadow() {
1847
        // Special event: killed the shadow
1848
        if (current_level == 12) {
1849
                if ((Char.charid | Opp.charid) == charid_1_shadow &&
1850
                        Char.alive < 0 && Opp.alive >= 0
1851
                ) {
1852
                        flash_color = color_15_brightwhite; // white
1853
                        flash_time = 5;
1854
                        take_hp(100);
1855
                }
1856
        }
1857
}
1858
 
1859
// data:1712
1860
const sword_table_type sword_tbl[] = {
1861
{ 255,   0,   0},
1862
{   0,   0,  -9},
1863
{   5,  -9, -29},
1864
{   1,   7, -25},
1865
{   2,  17, -26},
1866
{   6,   7, -14},
1867
{   7,   0,  -5},
1868
{   3,  17, -16},
1869
{   4,  16, -19},
1870
{  30,  12,  -9},
1871
{   8,  13, -34},
1872
{   9,   7, -25},
1873
{  10,  10, -16},
1874
{  11,  10, -11},
1875
{  12,  22, -21},
1876
{  13,  28, -23},
1877
{  14,  13, -35},
1878
{  15,   0, -38},
1879
{  16,   0, -29},
1880
{  17,  21, -19},
1881
{  18,  14, -23},
1882
{  19,  21, -22},
1883
{  19,  22, -23},
1884
{  17,   7, -13},
1885
{  17,  15, -18},
1886
{   7,   0,  -8},
1887
{   1,   7, -27},
1888
{  28,  14, -28},
1889
{   8,   7, -27},
1890
{   4,   6, -23},
1891
{   4,   9, -21},
1892
{  10,  11, -18},
1893
{  13,  24, -23},
1894
{  13,  19, -23},
1895
{  13,  21, -23},
1896
{  20,   7, -32},
1897
{  21,  14, -32},
1898
{  22,  14, -31},
1899
{  23,  14, -29},
1900
{  24,  28, -28},
1901
{  25,  28, -28},
1902
{  26,  21, -25},
1903
{  27,  14, -22},
1904
{ 255,  14, -25},
1905
{ 255,  21, -25},
1906
{  29,   0, -16},
1907
{   8,   8, -37},
1908
{  31,  14, -24},
1909
{  32,  14, -24},
1910
{  33,   7, -14},
1911
{   8,   8, -37},
1912
};
1913
 
1914
// seg006:1798
1915
void __pascal far add_sword_to_objtable() {
1916
        short frame;
1917
        short sword_frame;
1918
        frame = Char.frame;
1919
        if ((frame >= frame_229_found_sword && frame < 238) || // found sword + put sword away
1920
                Char.sword != sword_0_sheathed ||
1921
                (Char.charid == charid_2_guard && Char.alive < 0)
1922
        ) {
1923
                sword_frame = cur_frame.sword & 0x3F;
1924
                if (sword_frame) {
1925
                        obj_id = sword_tbl[sword_frame].id;
1926
                        if (obj_id != 0xFF) {
1927
                                obj_x = calc_screen_x_coord(obj_x);
1928
                                obj_dx_forward(sword_tbl[sword_frame].x);
1929
                                obj_y += sword_tbl[sword_frame].y;
1930
                                obj_chtab = id_chtab_0_sword;
1931
                                add_objtable(3); // sword
1932
                        }
1933
                }
1934
        }
1935
}
1936
 
1937
// seg006:1827
1938
void __pascal far control_guard_inactive() {
1939
        if (Char.frame == frame_166_stand_inactive && control_down < 0) {
1940
                if (control_forward < 0) {
1941
                        draw_sword();
1942
                } else {
1943
                        control_down = 1;
1944
                        seqtbl_offset_char(seq_80_stand_flipped); // stand flipped
1945
                }
1946
        }
1947
}
1948
 
1949
// seg006:1852
1950
int __pascal far char_opp_dist() {
1951
        // >0 if Opp is in front of char
1952
        // <0 if Opp is behind char
1953
        short distance;
1954
        if (Char.room != Opp.room) {
1955
                return 999;
1956
        }
1957
        distance = Opp.x - Char.x;
1958
        if (Char.direction < dir_0_right) {
1959
                distance = -distance;
1960
        }
1961
        if (distance >= 0 && Char.direction != Opp.direction) {
1962
                distance += 13;
1963
        }
1964
        return distance;
1965
}
1966
 
1967
// seg006:189B
1968
void __pascal far inc_curr_row() {
1969
        ++Char.curr_row;
1970
}