Subversion Repositories Games.Prince of Persia

Rev

Rev 1 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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.                                 }
  574.                                 Char.curr_seq = *(const word*)(SEQTBL_0 + Char.curr_seq);
  575.                                 break;
  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. }
  1971.