Subversion Repositories Games.Prince of Persia

Rev

Blame | 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. // data:27E0
  24. add_table_type ptr_add_table = add_backtable;
  25.  
  26. // data:259C
  27. const piece tile_table[31] = {
  28. {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0}, // 0x00 empty
  29. {  41,   1,   0,  42,   1,   2, 145,   0,  43,   0,   0,   0}, // 0x01 floor
  30. { 127,   1,   0, 133,   1,   2, 145,   0,  43,   0,   0,   0}, // 0x02 spike
  31. {  92,   1,   0,  93,   1,   2,   0,  94,  43,  95,   1,   0}, // 0x03 pillar
  32. {  46,   1,   0,  47,   1,   2,   0,  48,  43,  49,   3,   0}, // 0x04 door
  33. {  41,   1,   1,  35,   1,   3, 145,   0,  36,   0,   0,   0}, // 0x05 stuck floor
  34. {  41,   1,   0,  42,   1,   2, 145,   0,  96,   0,   0,   0}, // 0x06 close button
  35. {  46,   1,   0,   0,   0,   2,   0,   0,  43,  49,   3,   0}, // 0x07 door top with floor
  36. {  86,   1,   0,  87,   1,   2,   0,   0,  43,  88,   1,   0}, // 0x08 big pillar bottom
  37. {   0,   0,   0,  89,   0,   3,   0,  90,   0,  91,   1,   3}, // 0x09 big pillar top
  38. {  41,   1,   0,  42,   1,   2, 145,   0,  43,  12,   2,  -3}, // 0x0A potion
  39. {   0,   1,   0,   0,   0,   0, 145,   0,   0,   0,   0,   0}, // 0x0B loose floor
  40. {   0,   0,   0,   0,   0,   2,   0,   0,  85,  49,   3,   0}, // 0x0C door top
  41. {  75,   1,   0,  42,   1,   2,   0,   0,  43,  77,   0,   0}, // 0x0D mirror
  42. {  97,   1,   0,  98,   1,   2, 145,   0,  43, 100,   0,   0}, // 0x0E debris
  43. { 147,   1,   0,  42,   1,   1, 145,   0, 149,   0,   0,   0}, // 0x0F open button
  44. {  41,   1,   0,  37,   0,   0,   0,  38,  43,   0,   0,   0}, // 0x10 leveldoor left
  45. {   0,   0,   0,  39,   1,   2,   0,  40,  43,   0,   0,   0}, // 0x11 leveldoor right
  46. {   0,   0,   0,  42,   1,   2, 145,   0,  43,   0,   0,   0}, // 0x12 chomper
  47. {  41,   1,   0,  42,   1,   2,   0,   0,  43,   0,   0,   0}, // 0x13 torch
  48. {   0,   0,   0,   1,   1,   2,   0,   2,   0,   0,   0,   0}, // 0x14 wall
  49. {  30,   1,   0,  31,   1,   2,   0,   0,  43,   0,   0,   0}, // 0x15 skeleton
  50. {  41,   1,   0,  42,   1,   2, 145,   0,  43,   0,   0,   0}, // 0x16 sword
  51. {  41,   1,   0,  10,   0,   0,   0,  11,  43,   0,   0,   0}, // 0x17 balcony left
  52. {   0,   0,   0,  12,   1,   2,   0,  13,  43,   0,   0,   0}, // 0x18 balcony right
  53. {  92,   1,   0,  42,   1,   2, 145,   0,  43,  95,   1,   0}, // 0x19 lattice pillar
  54. {   1,   0,   0,   0,   0,   0,   0,   0,   2,   9,   0, -53}, // 0x1A lattice down
  55. {   3,   0, -10,   0,   0,   0,   0,   0,   0,   9,   0, -53}, // 0x1B lattice small
  56. {   4,   0, -10,   0,   0,   0,   0,   0,   0,   9,   0, -53}, // 0x1C lattice left
  57. {   5,   0, -10,   0,   0,   0,   0,   0,   0,   9,   0, -53}, // 0x1D lattice right
  58. {  97,   1,   0,  98,   1,   2,   0,   0,  43, 100,   0,   0}, // 0x1E debris with torch
  59. };
  60.  
  61. // data:4334
  62. short drawn_row;
  63. // data:4352
  64. short draw_bottom_y;
  65. // data:4326
  66. short draw_main_y;
  67. // data:34D0
  68. short drawn_col;
  69.  
  70. // data:6592
  71. byte tile_left;
  72. // data:4CCC
  73. byte modifier_left;
  74.  
  75. // seg008:0006
  76. void __pascal far redraw_room() {
  77.         free_peels();
  78.         memset_near(table_counts, 0, sizeof(table_counts));
  79.         reset_obj_clip();
  80.         draw_room();
  81.         clear_tile_wipes();
  82. }
  83.  
  84. // seg008:0035
  85. void __pascal far load_room_links() {
  86.         room_BR = 0;
  87.         room_BL = 0;
  88.         room_AR = 0;
  89.         room_AL = 0;
  90.         if (drawn_room) {
  91.                 get_room_address(drawn_room);
  92.                 room_L = level.roomlinks[drawn_room-1].left;
  93.                 room_R = level.roomlinks[drawn_room-1].right;
  94.                 room_A = level.roomlinks[drawn_room-1].up;
  95.                 room_B = level.roomlinks[drawn_room-1].down;
  96.                 if (room_A) {
  97.                         room_AL = level.roomlinks[room_A-1].left;
  98.                         room_AR = level.roomlinks[room_A-1].right;
  99.                 } else {
  100.                         if (room_L) {
  101.                                 room_AL = level.roomlinks[room_L-1].up;
  102.                         }
  103.                         if (room_R) {
  104.                                 room_AR = level.roomlinks[room_R-1].up;
  105.                         }
  106.                 }
  107.                 if (room_B) {
  108.                         room_BL = level.roomlinks[room_B-1].left;
  109.                         room_BR = level.roomlinks[room_B-1].right;
  110.                 } else {
  111.                         if (room_L) {
  112.                                 room_BL = level.roomlinks[room_L-1].down;
  113.                         }
  114.                         if (room_R) {
  115.                                 room_BR = level.roomlinks[room_R-1].down;
  116.                         }
  117.                 }
  118.         } else {
  119.                 room_B = 0;
  120.                 room_A = 0;
  121.                 room_R = 0;
  122.                 room_L = 0;
  123.         }
  124. }
  125.  
  126. // seg008:0125
  127. void __pascal far draw_room() {
  128.         word saved_room;
  129.         load_leftroom();
  130.         for (drawn_row = 3; drawn_row--; ) { /*2,1,0*/
  131.                 load_rowbelow();
  132.                 draw_bottom_y = 63 * drawn_row + 65;
  133.                 draw_main_y = draw_bottom_y - 3;
  134.                 for (drawn_col = 0; drawn_col < 10; drawn_col++) {
  135.                         load_curr_and_left_tile();
  136.                         draw_tile();
  137.                 }
  138.         }
  139.         saved_room = drawn_room;
  140.         drawn_room = room_A;
  141.         load_room_links();
  142.         load_leftroom();
  143.         drawn_row = 2;
  144.         load_rowbelow();
  145.         for (drawn_col = 0; drawn_col < 10; ++drawn_col) {
  146.                 load_curr_and_left_tile();
  147.                 draw_main_y = -1;
  148.                 draw_bottom_y = 2;
  149.                 draw_tile_aboveroom();
  150.         }
  151.         drawn_room = saved_room;
  152.         load_room_links();
  153. }
  154.  
  155. // seg008:01C7
  156. void __pascal far draw_tile() {
  157.         draw_tile_floorright();
  158.         draw_tile_anim_topright();
  159.         draw_tile_right();
  160.         draw_tile_anim_right();
  161.         draw_tile_bottom(0);
  162.         draw_loose(0);
  163.         draw_tile_base();
  164.         draw_tile_anim();
  165.         draw_tile_fore();
  166. }
  167.  
  168. // seg008:01F2
  169. void __pascal far draw_tile_aboveroom() {
  170.         draw_tile_floorright();
  171.         draw_tile_anim_topright();
  172.         draw_tile_right();
  173.         draw_tile_bottom(0);
  174.         draw_loose(0);
  175.         draw_tile_fore();
  176. }
  177.  
  178. // seg008:0211
  179. void __pascal far redraw_needed(short tilepos) {
  180.         if (wipe_frames[tilepos]) {
  181.                 --wipe_frames[tilepos];
  182.                 draw_tile_wipe(wipe_heights[tilepos]);
  183.         }
  184.         if (redraw_frames_full[tilepos]) {
  185.                 --redraw_frames_full[tilepos];
  186.                 draw_tile();
  187.         } else {
  188.                 if (redraw_frames_anim[tilepos]) {
  189.                         --redraw_frames_anim[tilepos];
  190.                         draw_tile_anim_topright();
  191.                         draw_tile_anim_right();
  192.                         draw_tile_anim();
  193.                 }
  194.         }
  195.         if (redraw_frames2[tilepos]) {
  196.                 --redraw_frames2[tilepos];
  197.                 draw_other_overlay();
  198.         } else {
  199.                 if (redraw_frames_floor_overlay[tilepos]) {
  200.                         --redraw_frames_floor_overlay[tilepos];
  201.                         draw_floor_overlay();
  202.                 }
  203.         }
  204.         if (tile_object_redraw[tilepos]) {
  205.                 if (tile_object_redraw[tilepos] == 0xFF) {
  206.                         draw_objtable_items_at_tile(tilepos - 1);
  207.                 }
  208.                 draw_objtable_items_at_tile(tilepos);
  209.                 tile_object_redraw[tilepos] = 0;
  210.         }
  211.         if (redraw_frames_fore[tilepos]) {
  212.                 --redraw_frames_fore[tilepos];
  213.                 draw_tile_fore();
  214.         }
  215. }
  216.  
  217. // seg008:02C1
  218. void __pascal far redraw_needed_above(int column) {
  219.         if (redraw_frames_above[column] != 0) {
  220.                 --redraw_frames_above[column];
  221.                 draw_tile_wipe(3);
  222.                 draw_tile_floorright();
  223.                 draw_tile_anim_topright();
  224.                 draw_tile_right();
  225.                 draw_tile_bottom(1);
  226.                 draw_loose(1);
  227.                 draw_tile_fore();
  228.         }
  229. }
  230.  
  231. // seg008:02FE
  232. int __pascal far get_tile_to_draw(int room, int column, int row, byte *ptr_tiletype, byte *ptr_modifier, byte tile_room0) {
  233.         word tilepos = tbl_line[row] + column;
  234.         if (column == -1) {
  235.                 *ptr_tiletype = leftroom_[row].tiletype;
  236.                 *ptr_modifier = leftroom_[row].modifier;
  237.         } else if (room) {
  238.                 *ptr_tiletype = curr_room_tiles[tilepos] & 0x1F;
  239.                 *ptr_modifier = curr_room_modif[tilepos];
  240.         } else {
  241.                 *ptr_modifier = 0;
  242.                 *ptr_tiletype = tile_room0;
  243.         }
  244.         // Is this a pressed button?
  245.         byte tiletype = (*ptr_tiletype) & 0x1F;
  246.         byte modifier = *ptr_modifier;
  247.         if (tiletype == tiles_6_closer) {
  248.                 if (get_doorlink_timer(modifier) > 1) {
  249.                         *ptr_tiletype = tiles_5_stuck;
  250.                 }
  251.         } else if (tiletype == tiles_15_opener) {
  252.                 if (get_doorlink_timer(modifier) > 1) {
  253.                         *ptr_modifier = 0;
  254.                         *ptr_tiletype = tiles_1_floor;
  255.                 }
  256.         }
  257. #ifdef USE_FAKE_TILES
  258.         else if (tiletype == tiles_0_empty) {
  259.                 if (modifier == 4 || modifier == 12) {     // display a fake floor
  260.                         *ptr_tiletype = tiles_1_floor;
  261.                         *ptr_modifier = (modifier == 12) ? 1 : 0; // 12: noblue option
  262.                 }
  263.                 else if (modifier == 5 || modifier == 13) {   // display a fake wall
  264.                         *ptr_tiletype = tiles_20_wall;
  265.                         *ptr_modifier = (modifier == 13) ? 0x80 : 0; // 13: noblue option
  266.                 }
  267.                 else if (modifier == 50) {   // display a fake wall (pattern: no walls left or right)
  268.                         *ptr_tiletype = tiles_20_wall;
  269.                         *ptr_modifier = 0;
  270.                 }
  271.                 else if (modifier == 51) {   // display a fake wall (pattern: wall only to the right)
  272.                         *ptr_tiletype = tiles_20_wall;
  273.                         *ptr_modifier = 1;
  274.                 }
  275.                 else if (modifier == 52) {   // display a fake wall (pattern: wall only to the left)
  276.                         *ptr_tiletype = tiles_20_wall;
  277.                         *ptr_modifier = 2;
  278.                 }
  279.                 else if (modifier == 53) {   // display a fake wall (pattern: wall on both sides)
  280.                         *ptr_tiletype = tiles_20_wall;
  281.                         *ptr_modifier = 3;
  282.                 }
  283.         }
  284.         else if (tiletype == tiles_1_floor) {
  285.                 if (modifier == 6 || modifier == 14) {   // display nothing (invisible floor)
  286.                         *ptr_tiletype = tiles_0_empty;
  287.                         *ptr_modifier = (modifier == 14) ? 1 : 0; // modifier should be '0' for noblue, instead of '1'
  288.                 }
  289.                 else if (modifier == 5 || modifier == 13) {   // display a fake wall
  290.                         *ptr_tiletype = tiles_20_wall;
  291.                         *ptr_modifier = (modifier == 13) ? 0x80 : 0; // 13: noblue option
  292.                 }
  293.                 else if (modifier == 50) {   // display a fake wall (pattern: no walls left or right (noblue))
  294.                         *ptr_tiletype = tiles_20_wall;
  295.                         *ptr_modifier = 0;
  296.                 }
  297.                 else if (modifier == 51) {   // display a fake wall (pattern: wall only to the right)
  298.                         *ptr_tiletype = tiles_20_wall;
  299.                         *ptr_modifier = 1;
  300.                 }
  301.                 else if (modifier == 52) {   // display a fake wall (pattern: wall only to the left)
  302.                         *ptr_tiletype = tiles_20_wall;
  303.                         *ptr_modifier = 2;
  304.                 }
  305.                 else if (modifier == 53) {   // display a fake wall (pattern: wall on both sides)
  306.                         *ptr_tiletype = tiles_20_wall;
  307.                         *ptr_modifier = 3;
  308.                 }
  309.         }
  310.         else if (tiletype == tiles_20_wall) {
  311.                 // Walls are a bit strange, because a lot of modifier information is discarded in load_alter_mod() (seg008.c)
  312.                 // Also, the "noblue" info for the wall tile is moved to the --most significant-- modifier bit there.
  313.  
  314.                 // load_alter_mod() has been tweaked to retain more information (now stored in the most significant 4 bytes)
  315.                 // Modifiers 2-7 are now accessible to define various fake tiles
  316.                 // Modifiers 9-15 'loop back' onto 2-7 (identical tiles), EXCEPT they also have the "noblue" bit set
  317.                 if (((modifier >> 4) & 7) == 4) {     // display a floor (invisible wall)
  318.                         *ptr_tiletype = tiles_1_floor;
  319.                         *ptr_modifier = (modifier >> 7); // modifier should be '1' for noblue option
  320.                 }
  321.                 else if (((modifier >> 4) & 7) == 6) {   // display empty tile (invisible wall)
  322.                         *ptr_tiletype = tiles_0_empty;
  323.                         *ptr_modifier = (modifier >> 7) ? 1 : 0; // modifier should be '0' for noblue, instead of '1'
  324.                 }
  325.         }
  326. #endif
  327. #ifdef FIX_LOOSE_LEFT_OF_POTION
  328.         else if (fix_loose_left_of_potion && tiletype == tiles_11_loose) {
  329.                 if ((*ptr_modifier & 0x7F) == 0) {
  330.                         *ptr_tiletype = tiles_1_floor;
  331.                 }
  332.         }
  333. #endif
  334.         return *ptr_tiletype;
  335. }
  336.  
  337. // data:24C6
  338. const word col_xh[] = {0, 4, 8, 12, 16, 20, 24, 28, 32, 36};
  339. // seg008:03BB
  340. void __pascal far load_curr_and_left_tile() {
  341.         word tiletype;
  342.         tiletype = tiles_20_wall;
  343.         if (drawn_row == 2) {
  344.                 tiletype = drawn_tile_top_level_edge; // floor at top of level (default: tiles_1_floor)
  345.         }
  346.         get_tile_to_draw(drawn_room, drawn_col, drawn_row, &curr_tile, &curr_modifier, tiletype);
  347.         get_tile_to_draw(drawn_room, drawn_col - 1, drawn_row, &tile_left, &modifier_left, tiletype);
  348.         draw_xh = col_xh[drawn_col];
  349. }
  350.  
  351. // seg008:041A
  352. void __pascal far load_leftroom() {
  353.         word row;
  354.         get_room_address(room_L);
  355.         for (row = 0; row < 3; ++row) {
  356.                 // wall at left of level (drawn_tile_left_level_edge), default: tiles_20_wall
  357.                 get_tile_to_draw(room_L, 9, row, &leftroom_[row].tiletype, &leftroom_[row].modifier, drawn_tile_left_level_edge);
  358.         }
  359. }
  360.  
  361. // seg008:0460
  362. void __pascal far load_rowbelow() {
  363.         word row_below;
  364.         word column;
  365.         word room;
  366.         word room_left;
  367.         if (drawn_row == 2) {
  368.                 room = room_B;
  369.                 room_left = room_BL;
  370.                 row_below = 0;
  371.         } else {
  372.                 room = drawn_room;
  373.                 room_left = room_L;
  374.                 row_below = drawn_row + 1;
  375.         }
  376.         get_room_address(room);
  377.         for (column = 1; column < 10; ++column) {
  378.                 get_tile_to_draw(room, column - 1, row_below, &row_below_left_[column].tiletype, &row_below_left_[column].modifier, tiles_0_empty);
  379.         }
  380.         get_room_address(room_left);
  381.         // wall at left of level
  382.         get_tile_to_draw(room_left, 9, row_below, &row_below_left_[0].tiletype, &row_below_left_[0].modifier, tiles_20_wall);
  383.         get_room_address(drawn_room);
  384. }
  385.  
  386. // seg008:04FA
  387. void __pascal far draw_tile_floorright() {
  388.         if (can_see_bottomleft() == 0) return;
  389.         draw_tile_topright();
  390.         if (tile_table[tile_left].floor_right == 0) return;
  391.         add_backtable(id_chtab_6_environment, 42 /*floor right part*/, draw_xh, 0, tile_table[tiles_1_floor].right_y + draw_main_y, blitters_9_black, 1);
  392. }
  393.  
  394. // seg008:053A
  395. int __pascal far can_see_bottomleft() {
  396.         return curr_tile == tiles_0_empty ||
  397.                 curr_tile == tiles_9_bigpillar_top ||
  398.                 curr_tile == tiles_12_doortop ||
  399.                 curr_tile == tiles_26_lattice_down;
  400. }
  401.  
  402. const byte doortop_fram_top[] = {0, 81, 83, 0};
  403.  
  404. // seg008:055A
  405. void __pascal far draw_tile_topright() {
  406.         byte tiletype;
  407.         tiletype = row_below_left_[drawn_col].tiletype;
  408.         if (tiletype == tiles_7_doortop_with_floor || tiletype == tiles_12_doortop) {
  409.                 if (tbl_level_type[current_level] == 0) return;
  410.                 add_backtable(id_chtab_6_environment, doortop_fram_top[row_below_left_[drawn_col].modifier], draw_xh, 0, draw_bottom_y, blitters_2_or, 0);
  411.         } else if (tiletype == tiles_20_wall) {
  412.                 add_backtable(id_chtab_7_environmentwall, 2, draw_xh, 0, draw_bottom_y, blitters_2_or, 0);
  413.         } else {
  414.                 add_backtable(id_chtab_6_environment, tile_table[tiletype].topright_id, draw_xh, 0, draw_bottom_y, blitters_2_or, 0);
  415.         }
  416. }
  417.  
  418. const byte door_fram_top[] = {60, 61, 62, 63, 64, 65, 66, 67};
  419.  
  420. // seg008:05D1
  421. void __pascal far draw_tile_anim_topright() {
  422.         word modifier;
  423.         if (    (curr_tile == tiles_0_empty ||
  424.                 curr_tile == tiles_9_bigpillar_top ||
  425.                 curr_tile == tiles_12_doortop)
  426.                 && row_below_left_[drawn_col].tiletype == tiles_4_gate
  427.         ) {
  428.                 add_backtable(id_chtab_6_environment, 68 /*gate top mask*/, draw_xh, 0, draw_bottom_y, blitters_40h_mono, 0);
  429.                 modifier = row_below_left_[drawn_col].modifier;
  430.                 if (modifier > 188) modifier = 188;
  431.                 add_backtable(id_chtab_6_environment, door_fram_top[(modifier>>2) % 8], draw_xh, 0, draw_bottom_y, blitters_2_or, 0);
  432.         }
  433. }
  434.  
  435. const byte blueline_fram1[] = {0, 124, 125, 126};
  436. const sbyte blueline_fram_y[] = {0, -20, -20, 0};
  437. const byte blueline_fram3[] = {44, 44, 45, 45};
  438. const byte doortop_fram_bot[] = {78, 80, 82, 0};
  439.  
  440. // seg008:066A
  441. void __pascal far draw_tile_right() {
  442.         byte id;
  443.         byte blit;
  444.         byte var_2;
  445.         if (curr_tile == tiles_20_wall) return;
  446.         switch (tile_left) {
  447.                 default:
  448.                         id = tile_table[tile_left].right_id;
  449.                         if (id) {
  450.                                 if (tile_left == tiles_5_stuck) {
  451.                                         blit = blitters_10h_transp;
  452.                                         if (curr_tile == tiles_0_empty || curr_tile == tiles_5_stuck) {
  453.                                                 id = 42; /*floor B*/
  454.                                         }
  455.                                 } else {
  456.                                         blit = blitters_2_or;
  457.                                 }
  458.                                 add_backtable(id_chtab_6_environment, id, draw_xh, 0, tile_table[tile_left].right_y + draw_main_y, blit, 0);
  459.                         }
  460.                         if (tbl_level_type[current_level] != 0) {
  461.                                 add_backtable(id_chtab_6_environment, tile_table[tile_left].stripe_id, draw_xh, 0, draw_main_y - 27, blitters_2_or, 0);
  462.                         }
  463.                         if (tile_left == tiles_19_torch || tile_left == tiles_30_torch_with_debris) {
  464.                                 add_backtable(id_chtab_6_environment, 146 /*torch base*/, draw_xh, 0, draw_bottom_y - 28, blitters_0_no_transp, 0);
  465.                         }
  466.                         break;
  467.                 case tiles_0_empty:
  468.                         if (modifier_left > 3) return;
  469.                         add_backtable(id_chtab_6_environment, blueline_fram1[modifier_left], draw_xh, 0, blueline_fram_y[modifier_left] + draw_main_y, blitters_2_or, 0);
  470.                         break;
  471.                 case tiles_1_floor:
  472.                         ptr_add_table(id_chtab_6_environment, 42 /*floor B*/, draw_xh, 0, tile_table[tile_left].right_y + draw_main_y, blitters_10h_transp, 0);
  473.                         var_2 = modifier_left;
  474.                         if (var_2 > 3) var_2 = 0;
  475.                         if (var_2 == !!tbl_level_type[current_level]) return;
  476.                         add_backtable(id_chtab_6_environment, blueline_fram3[var_2], draw_xh, 0, draw_main_y - 20, blitters_0_no_transp, 0);
  477.                         break;
  478.                 case tiles_7_doortop_with_floor:
  479.                 case tiles_12_doortop:
  480.                         if (tbl_level_type[current_level] == 0) return;
  481.                         add_backtable(id_chtab_6_environment, doortop_fram_bot[modifier_left], draw_xh, 0, tile_table[tile_left].right_y + draw_main_y, blitters_2_or, 0);
  482.                         break;
  483.                 case tiles_20_wall:
  484.                         if (tbl_level_type[current_level] && (modifier_left & 0x80) == 0) {
  485.                                 add_backtable(id_chtab_6_environment, 84 /*wall stripe*/, draw_xh + 3, 0, draw_main_y - 27, blitters_0_no_transp, 0);
  486.                         }
  487.                         add_backtable(id_chtab_7_environmentwall, 1, draw_xh, 0, tile_table[tile_left].right_y + draw_main_y, blitters_2_or, 0);
  488.                         break;
  489.         }
  490. }
  491.  
  492. const byte spikes_fram_right[] = {0, 134, 135, 136, 137, 138, 137, 135, 134, 0};
  493. const byte loose_fram_right[] = {42, 71, 42, 72, 72, 42, 42, 42, 72, 72, 72, 0};
  494.  
  495. // seg008:08A0
  496. int __pascal far get_spike_frame(byte modifier) {
  497.         if (modifier & 0x80) {
  498.                 return 5;
  499.         } else {
  500.                 return modifier;
  501.         }
  502. }
  503.  
  504. // seg008:08B5
  505. void __pascal far draw_tile_anim_right() {
  506.         switch (tile_left) {
  507.                 case tiles_2_spike:
  508.                         add_backtable(id_chtab_6_environment, spikes_fram_right[get_spike_frame(modifier_left)], draw_xh, 0, draw_main_y - 7, blitters_10h_transp, 0);
  509.                 break;
  510.                 case tiles_4_gate:
  511.                         draw_gate_back();
  512.                 break;
  513.                 case tiles_11_loose:
  514.                         add_backtable(id_chtab_6_environment, loose_fram_right[get_loose_frame(modifier_left)], draw_xh, 0, draw_bottom_y - 1, blitters_2_or, 0);
  515.                 break;
  516.                 case tiles_16_level_door_left:
  517.                         draw_leveldoor();
  518.                 break;
  519.                 case tiles_19_torch:
  520.                 case tiles_30_torch_with_debris:
  521.                         if (modifier_left < 9) {
  522.                                 // images 1..9 are the flames
  523.                                 add_backtable(id_chtab_1_flameswordpotion, modifier_left + 1, draw_xh + 1, 0, draw_main_y - 40, blitters_0_no_transp, 0);
  524.                         }
  525.                 break;
  526.         }
  527. }
  528.  
  529. const byte wall_fram_bottom[] = {7, 9, 5, 3};
  530.  
  531. // seg008:0971
  532. void __pascal far draw_tile_bottom(word arg_0) {
  533.         word chtab_id;
  534.         byte id;
  535.         byte blit;
  536.         id = 0;
  537.         blit = blitters_0_no_transp;
  538.         chtab_id = id_chtab_6_environment;
  539.         switch (curr_tile) {
  540.                 case tiles_20_wall:
  541.                         if (tbl_level_type[current_level] == 0 || enable_wda_in_palace || graphics_mode != gmMcgaVga) {
  542.                                 id = wall_fram_bottom[curr_modifier & 0x7F];
  543.                         }
  544.                         chtab_id = id_chtab_7_environmentwall;
  545.                         break;
  546.                 case tiles_12_doortop:
  547.                         blit = blitters_2_or;
  548.                         // fallthrough!
  549.                 default:
  550.                         id = tile_table[curr_tile].bottom_id;
  551.                         break;
  552.         }
  553.         if (ptr_add_table(chtab_id, id, draw_xh, 0, draw_bottom_y, blit, 0) && arg_0) {
  554.                 add_foretable(chtab_id, id, draw_xh, 0, draw_bottom_y, blit, 0);
  555.         }
  556.         if (chtab_id == id_chtab_7_environmentwall && graphics_mode != gmCga && graphics_mode != gmHgaHerc) {
  557.                 wall_pattern(0, 0);
  558.         }
  559. }
  560.  
  561. const byte loose_fram_bottom[] = {43, 73, 43, 74, 74, 43, 43, 43, 74, 74, 74, 0};
  562.  
  563. // seg008:0A38
  564. void __pascal far draw_loose(int arg_0) {
  565.         word id;
  566.         if (curr_tile == tiles_11_loose) {
  567.                 id = loose_fram_bottom[get_loose_frame(curr_modifier)];
  568.                 add_backtable(id_chtab_6_environment, id, draw_xh, 0, draw_bottom_y, blitters_0_no_transp, 0);
  569.                 add_foretable(id_chtab_6_environment, id, draw_xh, 0, draw_bottom_y, blitters_0_no_transp, 0);
  570.         }
  571. }
  572.  
  573. const byte loose_fram_left[] = {41, 69, 41, 70, 70, 41, 41, 41, 70, 70, 70, 0};
  574.  
  575. // seg008:0A8E
  576. void __pascal far draw_tile_base() {
  577.         word ybottom;
  578.         word id;
  579.         ybottom = draw_main_y;
  580.         if (tile_left == tiles_26_lattice_down && curr_tile == tiles_12_doortop) {
  581.                 id = 6; // Lattice + door A
  582.                 ybottom += 3;
  583.         } else if (curr_tile == tiles_11_loose) {
  584.                 id = loose_fram_left[get_loose_frame(curr_modifier)];
  585.         } else if (curr_tile == tiles_15_opener && tile_left == tiles_0_empty && tbl_level_type[current_level] == 0) {
  586.                 id = 148; // left half of open button with no floor to the left
  587.         } else {
  588.                 id = tile_table[curr_tile].base_id;
  589.         }
  590.         ptr_add_table(id_chtab_6_environment, id, draw_xh, 0, tile_table[curr_tile].base_y + ybottom, blitters_10h_transp, 0);
  591. }
  592.  
  593. const byte spikes_fram_left[] = {0, 128, 129, 130, 131, 132, 131, 129, 128, 0};
  594. const byte potion_fram_bubb[] = {0, 16, 17, 18, 19, 20, 21, 22};
  595. const byte chomper_fram1[] = {3, 2, 0, 1, 4, 3, 3, 0};
  596. const byte chomper_fram_bot[] = {101, 102, 103, 104, 105, 0};
  597. const byte chomper_fram_top[] = {0, 0, 111, 112, 113, 0};
  598. const byte chomper_fram_y[] = {0, 0, 0x25, 0x2F, 0x32};
  599.  
  600. // seg008:0B2B
  601. void __pascal far draw_tile_anim() {
  602.         word color;
  603.         word pot_size;
  604.         word var_4;
  605.         pot_size = 0;
  606.         color = 12; // red
  607.         switch (curr_tile) {
  608.                 case tiles_2_spike:
  609.                         ptr_add_table(id_chtab_6_environment, spikes_fram_left[get_spike_frame(curr_modifier)], draw_xh, 0, draw_main_y - 2, blitters_10h_transp, 0);
  610.                         break;
  611.                 case tiles_10_potion:
  612.                         switch((curr_modifier & 0xF8) >> 3) {
  613.                                 case 0:
  614.                                         return; //empty
  615.                                 case 5: // hurt
  616.                                 case 6: // open
  617.                                         color = 9; // blue
  618.                                         break;
  619.                                 case 3: // slow fall
  620.                                 case 4: // upside down
  621.                                         color = 10; // green
  622.                                         // fallthrough!
  623.                                 case 2: // life
  624.                                         pot_size = 1;
  625.                                         break;
  626.                         }
  627.                         add_backtable(id_chtab_1_flameswordpotion, 23 /*bubble mask*/, draw_xh + 3, 1, draw_main_y - (pot_size << 2) - 14, blitters_40h_mono, 0);
  628.                         add_foretable(id_chtab_1_flameswordpotion, potion_fram_bubb[curr_modifier & 0x7], draw_xh + 3, 1, draw_main_y - (pot_size << 2) - 14, color + blitters_40h_mono, 0);
  629.                         break;
  630.                 case tiles_22_sword:
  631.                         add_midtable(id_chtab_1_flameswordpotion, (curr_modifier == 1) + 10, draw_xh, 0, draw_main_y - 3, blitters_10h_transp, curr_modifier == 1);
  632.                         break;
  633.                 case tiles_18_chomper:
  634.                         var_4 = chomper_fram1[MIN(curr_modifier & 0x7F, 6)];
  635.                         add_backtable(id_chtab_6_environment, chomper_fram_bot[var_4], draw_xh, 0, draw_main_y, blitters_10h_transp, 0);
  636.                         if (curr_modifier & 0x80) { // blood
  637.                                 add_backtable(id_chtab_6_environment, var_4 + 114, draw_xh + 1, 4, draw_main_y - 6, blitters_4Ch_mono_12, 0);
  638.                         }
  639.                         add_backtable(id_chtab_6_environment, chomper_fram_top[var_4], draw_xh, 0, draw_main_y - chomper_fram_y[var_4], blitters_10h_transp, 0);
  640.                         break;
  641.         }
  642. }
  643.  
  644. const byte spikes_fram_fore[] = {0, 139, 140, 141, 142, 143, 142, 140, 139, 0};
  645. const byte chomper_fram_for[] = {106, 107, 108, 109, 110, 0};
  646. const byte wall_fram_main[] = {8, 10, 6, 4};
  647.  
  648. // seg008:0D15
  649. void __pascal far draw_tile_fore() {
  650.         word ybottom;
  651.         byte xh;
  652.         word potion_type;
  653.         word id;
  654.         word var_2;
  655.         if (tile_left == tiles_4_gate && Kid.curr_row == drawn_row && Kid.curr_col == drawn_col - 1 && Kid.room != room_R) {
  656.                 draw_gate_fore();
  657.         }
  658.         switch (curr_tile) {
  659.                 case tiles_2_spike:
  660.                         add_foretable(id_chtab_6_environment, spikes_fram_fore[get_spike_frame(curr_modifier)], draw_xh, 0, draw_main_y - 2, blitters_10h_transp, 0);
  661.                         break;
  662.                 case tiles_18_chomper:
  663.                         var_2 = chomper_fram1[MIN(curr_modifier & 0x7F, 6)];
  664.                         add_foretable(id_chtab_6_environment, chomper_fram_for[var_2], draw_xh, 0, draw_main_y, blitters_10h_transp, 0);
  665.                         if (curr_modifier & 0x80) {
  666.                                 add_foretable(id_chtab_6_environment, var_2 + 119, draw_xh + 1, 4, draw_main_y - 6, blitters_4Ch_mono_12, 0);
  667.                         }
  668.                         break;
  669.                 case tiles_20_wall:
  670.                         if (tbl_level_type[current_level] == 0 || enable_wda_in_palace || graphics_mode != gmMcgaVga) {
  671.                                 add_foretable(id_chtab_7_environmentwall, wall_fram_main[curr_modifier & 0x7F], draw_xh, 0, draw_main_y, blitters_0_no_transp, 0);
  672.                         }
  673.                         if (graphics_mode != gmCga && graphics_mode != gmHgaHerc) {
  674.                                 wall_pattern(1, 1);
  675.                         }
  676.                         break;
  677.                 default:
  678.                         id = tile_table[curr_tile].fore_id;
  679.                         if (id == 0) return;
  680.                         if (curr_tile == tiles_10_potion) {
  681.                                 // large pots are drawn for potion types 2, 3, 4
  682.                                 potion_type = (curr_modifier & 0xF8) >> 3;
  683.                                 if (potion_type < 5 && potion_type >= 2) id = 13; // small pot = 12, large pot = 13
  684.                         }
  685.                         xh = tile_table[curr_tile].fore_x + draw_xh;
  686.                         ybottom = tile_table[curr_tile].fore_y + draw_main_y;
  687.                         if (curr_tile == tiles_10_potion) {
  688.                                 // potions look different in the dungeon and the palace
  689.                                 if (tbl_level_type[current_level] != 0) id += 2;
  690.                                 add_foretable(id_chtab_1_flameswordpotion, id, xh, 6, ybottom, blitters_10h_transp, 0);
  691.                         } else {
  692.                                 if ((curr_tile == tiles_3_pillar && tbl_level_type[current_level] == 0) || (curr_tile >= tiles_27_lattice_small && curr_tile < tiles_30_torch_with_debris)) {
  693.                                         add_foretable(id_chtab_6_environment, id, xh, 0, ybottom, blitters_0_no_transp, 0);
  694.                                 } else {
  695.                                         add_foretable(id_chtab_6_environment, id, xh, 0, ybottom, blitters_10h_transp, 0);
  696.                                 }
  697.                         }
  698.                         break;
  699.         }
  700. }
  701.  
  702. // seg008:0FF6
  703. int __pascal far get_loose_frame(byte modifier) {
  704.         if (modifier & 0x80) {
  705.                 modifier &= 0x7F;
  706.                 if (modifier > 10) {
  707.                         return 1;
  708.                 }
  709.         }
  710.         return modifier;
  711. }
  712.  
  713. // Get an image, with index and NULL checks.
  714. image_type* get_image(short chtab_id, int id) {
  715.         if (chtab_id < 0 || chtab_id > COUNT(chtab_addrs)) {
  716.                 printf("Tried to use chtab %d not in 0..%d\n", chtab_id, (int)COUNT(chtab_addrs));
  717.                 return NULL;
  718.         }
  719.         chtab_type* chtab = chtab_addrs[chtab_id];
  720.         if (chtab == NULL) {
  721.                 printf("Tried to use null chtab %d\n", chtab_id);
  722.                 return NULL;
  723.         }
  724.         if (id < 0 || id >= chtab->n_images) {
  725.                 if (id != 255) printf("Tried to use image %d of chtab %d, not in 0..%d\n", id, chtab_id, chtab->n_images-1);
  726.                 return NULL;
  727.         }
  728.         return chtab->images[id];
  729. }
  730.  
  731. // seg008:10A8
  732. int __pascal far add_backtable(short chtab_id, int id, sbyte xh, sbyte xl, int ybottom, byte blit, byte peel) {
  733.         word index;
  734.         if (id == 0) {
  735.                 return 0;
  736.         }
  737.         index = backtable_count;
  738.         if (index >= 200) {
  739.                 show_dialog("BackTable Overflow");
  740.                 return 0; // added
  741.         }
  742.         back_table_type* backtable_item = &backtable[index];
  743.         backtable_item->xh = xh;
  744.         backtable_item->xl = xl;
  745.         backtable_item->chtab_id = chtab_id;
  746.         backtable_item->id = id - 1;
  747.         image_type* image = get_image(chtab_id, id - 1);
  748.         if (image == NULL) {
  749.                 return 0;
  750.         }
  751.         backtable_item->y = ybottom - image->h/*height*/ + 1;
  752.         backtable_item->blit = blit;
  753.         if (draw_mode) {
  754.                 draw_back_fore(0, index);
  755.         }
  756.         ++backtable_count;
  757.         return 1;
  758. }
  759.  
  760. // seg008:1017
  761. int __pascal far add_foretable(short chtab_id, int id, sbyte xh, sbyte xl, int ybottom, byte blit, byte peel) {
  762.         word index;
  763.         if (id == 0) return 0;
  764.         index = foretable_count;
  765.         if (index >= 200) {
  766.                 show_dialog("ForeTable Overflow");
  767.                 return 0; // added
  768.         }
  769.         back_table_type* foretable_item = &foretable[index];
  770.         foretable_item->xh = xh;
  771.         foretable_item->xl = xl;
  772.         foretable_item->chtab_id = chtab_id;
  773.         foretable_item->id = id - 1;
  774.         image_type* image = get_image(chtab_id, id - 1);
  775.         if (image == NULL) {
  776.                 return 0;
  777.         }
  778.         foretable_item->y = ybottom - image->h/*height*/ + 1;
  779.         foretable_item->blit = blit;
  780.         if (draw_mode) {
  781.                 draw_back_fore(1, index);
  782.         }
  783.         ++foretable_count;
  784.         return 1;
  785. }
  786.  
  787. // seg008:113A
  788. int __pascal far add_midtable(short chtab_id, int id, sbyte xh, sbyte xl, int ybottom, byte blit, byte peel) {
  789.         word index;
  790.         if (id == 0) {
  791.                 return 0;
  792.         }
  793.         index = midtable_count;
  794.         if (index >= 50) {
  795.                 show_dialog("MidTable Overflow");
  796.                 return 0; // added
  797.         }
  798.         midtable_type* midtable_item = &midtable[index];
  799.         midtable_item->xh = xh;
  800.         midtable_item->xl = xl;
  801.         midtable_item->chtab_id = chtab_id;
  802.         midtable_item->id = id - 1;
  803.         image_type* image = get_image(chtab_id, id - 1);
  804.         if (image == NULL) {
  805.                 return 0;
  806.         }
  807.         midtable_item->y = ybottom - image->h/*height*/ + 1;
  808.         if (obj_direction == dir_0_right && chtab_flip_clip[chtab_id] != 0) {
  809.                 blit += 0x80;
  810.         }
  811.         midtable_item->blit = blit;
  812.         midtable_item->peel = peel;
  813.         midtable_item->clip.left = obj_clip_left;
  814.         midtable_item->clip.right = obj_clip_right;
  815.         midtable_item->clip.top = obj_clip_top;
  816.         midtable_item->clip.bottom = obj_clip_bottom;
  817.         if (draw_mode) {
  818.                 draw_mid(index);
  819.         }
  820.         ++midtable_count;
  821.         return 1;
  822. }
  823.  
  824. // seg008:1208
  825. void __pascal far add_peel(int left,int right,int top,int height) {
  826.         rect_type rect;
  827.         if (peels_count >= 50) {
  828.                 show_dialog("Peels OverFlow");
  829.                 return /*0*/; // added
  830.         }
  831.         rect.left = left;
  832.         rect.right = right;
  833.         rect.top = top;
  834.         rect.bottom = top + height;
  835.         peels_table[peels_count++] = read_peel_from_screen(&rect);
  836. }
  837.  
  838. // seg008:1254
  839. void __pascal far add_wipetable(sbyte layer,short left,short bottom,sbyte height,short width,sbyte color) {
  840.         word index;
  841.         index = wipetable_count;
  842.         if (index >= 300) {
  843.                 show_dialog("WipeTable Overflow");
  844.                 return /*0*/; // added
  845.         }
  846.         wipetable_type* wipetable_item = &wipetable[index];
  847.         wipetable_item->left = left;
  848.         wipetable_item->bottom = bottom + 1;
  849.         wipetable_item->height = height;
  850.         wipetable_item->width = width;
  851.         wipetable_item->color = color;
  852.         wipetable_item->layer = layer;
  853.         if (draw_mode) {
  854.                 draw_wipe(index);
  855.         }
  856.         ++wipetable_count;
  857. }
  858.  
  859. // seg008:12BB
  860. void __pascal far draw_table(int which_table) {
  861.         short index;
  862.         short count;
  863.         count = table_counts[which_table];
  864.         for (index = 0; index < count; ++index) {
  865.                 if (which_table == 3) {
  866.                         draw_mid(index);
  867.                 } else {
  868.                         draw_back_fore(which_table, index);
  869.                 }
  870.         }
  871. }
  872.  
  873. // seg008:12FE
  874. void __pascal far draw_wipes(int which) {
  875.         word index;
  876.         word count;
  877.         count = wipetable_count;
  878.         for (index = 0; index < count; ++index) {
  879.                 if (which == wipetable[index].layer) {
  880.                         draw_wipe(index);
  881.                 }
  882.         }
  883. }
  884.  
  885. // seg008:133B
  886. void __pascal far draw_back_fore(int which_table,int index) {
  887.         image_type* image;
  888.         image_type* mask;
  889.         back_table_type* table_entry;
  890.         if (which_table == 0) {
  891.                 table_entry = &backtable[index];
  892.         } else /* if (which_table == 1) this is always true */ {
  893.                 table_entry = &foretable[index];
  894.         }
  895.         image = mask = get_image(table_entry->chtab_id, table_entry->id);
  896.         /*
  897.         if ((graphics_mode == gmCga || graphics_mode == gmHgaHerc) &&
  898.                 chtab_shift[table_entry->chtab_id] == 0) {
  899.                 chtab_type* chtab = chtab_addrs[table_entry->chtab_id];
  900.                 mask = chtab->images[chtab->n_images / 2 + table_entry->id];
  901.         }
  902.         */
  903.         draw_image(image, mask, table_entry->xh * 8 + table_entry->xl, table_entry->y, table_entry->blit);
  904. }
  905.  
  906.  
  907. SDL_Surface* hflip(SDL_Surface* input) {
  908.         int width = input->w;
  909.         int height = input->h;
  910.         int source_x, target_x;
  911.  
  912.         // The simplest way to create a surface with same format as input:
  913.         SDL_Surface* output = SDL_ConvertSurface(input, input->format, 0);
  914.         SDL_SetSurfacePalette(output, input->format->palette);
  915.         // The copied image will be overwritten anyway.
  916.         if (output == NULL) {
  917.                 sdlperror("SDL_ConvertSurface");
  918.                 quit(1);
  919.         }
  920.  
  921.         SDL_SetSurfaceBlendMode(input, SDL_BLENDMODE_NONE);
  922.         // Temporarily turn off alpha and colorkey on input. So we overwrite the output image.
  923.         SDL_SetColorKey(input, SDL_FALSE, 0);
  924.         SDL_SetColorKey(output, SDL_FALSE, 0);
  925.         SDL_SetSurfaceAlphaMod(input, 255);
  926.  
  927.         for (source_x = 0, target_x = width-1; source_x < width; ++source_x, --target_x) {
  928.                 SDL_Rect srcrect = {source_x, 0, 1, height};
  929.                 SDL_Rect dstrect = {target_x, 0, 1, height};
  930.                 if (SDL_BlitSurface(input/*32*/, &srcrect, output, &dstrect) != 0) {
  931.                         sdlperror("SDL_BlitSurface");
  932.                         quit(1);
  933.                 }
  934.         }
  935.  
  936.         return output;
  937. }
  938.  
  939.  
  940. // seg008:140C
  941. void __pascal far draw_mid(int index) {
  942.         word need_free_mask;
  943.         word image_id;
  944.         image_type*far mask;
  945.         word chtab_id;
  946.         word blit_flip;
  947.         short ypos;
  948.         short xpos;
  949.         midtable_type* midtable_entry;
  950.         word blit;
  951.         word need_free_image;
  952.         image_type*far image;
  953. //      word image_flipped;
  954.  
  955.         blit_flip = 0;
  956.         need_free_image = 0;
  957.         need_free_mask = 0;
  958.         midtable_entry = &midtable[index];
  959.         image_id = midtable_entry->id;
  960.         chtab_id = midtable_entry->chtab_id;
  961.         image = mask = get_image(chtab_id, image_id);
  962.         /*
  963.         if ((graphics_mode == gmCga || graphics_mode == gmHgaHerc) && chtab_shift[chtab_id]) {
  964.                 mask = chtab_addrs[chtab_id]->images[image_id + chtab_addrs[chtab_id]->n_images / 2];
  965.         }
  966.         */
  967.         xpos = midtable_entry->xh * 8 + midtable_entry->xl;
  968.         ypos = midtable_entry->y;
  969.         blit = midtable_entry->blit;
  970.         if (blit & 0x80) {
  971.                 blit_flip = 0x8000;
  972.                 blit &= 0x7F;
  973.         }
  974.  
  975.         if (chtab_flip_clip[chtab_id]) {
  976.                 set_clip_rect(&midtable_entry->clip);
  977.                 if (chtab_id != id_chtab_0_sword) {
  978.                         xpos = calc_screen_x_coord(xpos);
  979.                 }
  980.         }
  981.         if (blit_flip) {
  982.                 xpos -= image->w/*width*/;
  983.                 // for this version:
  984.                 need_free_image = 1;
  985.                 image = hflip(image);
  986.         }
  987.  
  988.         if (midtable_entry->peel) {
  989.                 add_peel(round_xpos_to_byte(xpos, 0), round_xpos_to_byte(image->w/*width*/ + xpos, 1), ypos, image->h/*height*/);
  990.         }
  991.         //printf("Midtable: drawing (chtab %d, image %d) at (x=%d, y=%d)\n",chtab_id,image_id,xpos,ypos); // debug
  992.         draw_image(image, mask, xpos, ypos, blit);
  993.  
  994.         if (chtab_flip_clip[chtab_id]) {
  995.                 reset_clip_rect();
  996.         }
  997.         if (need_free_image) {
  998.                 //free_far(image);
  999.                 SDL_FreeSurface(image);
  1000.         }
  1001.         if (need_free_mask) {
  1002.                 free_far(mask);
  1003.         }
  1004. }
  1005.  
  1006. // seg008:167B
  1007. void __pascal far draw_image(image_type far *image,image_type far *mask,int xpos,int ypos,int blit) {
  1008.         rect_type rect;
  1009.         switch (blit) {
  1010.                 case blitters_10h_transp:
  1011.                         draw_image_transp(image, mask, xpos, ypos);
  1012.                 break;
  1013.                 case blitters_9_black:
  1014.                         method_6_blit_img_to_scr(mask, xpos, ypos, blitters_9_black);
  1015.                 break;
  1016.                 case blitters_0_no_transp:
  1017.                 case blitters_2_or:
  1018.                 case blitters_3_xor:
  1019.                         method_6_blit_img_to_scr(image, xpos, ypos, blit);
  1020.                 break;
  1021.                 default:
  1022.                         method_3_blit_mono(image, xpos, ypos, 0, blit & 0xBF);
  1023.                 break;
  1024.         }
  1025.         if (need_drects) {
  1026.                 rect.left = rect.right = xpos;
  1027.                 rect.right += image->w/*width*/;
  1028.                 rect.top = rect.bottom = ypos;
  1029.                 rect.bottom += image->h/*height*/;
  1030.                 add_drect(&rect);
  1031.         }
  1032. }
  1033.  
  1034. // seg008:1730
  1035. void __pascal far draw_wipe(int index) {
  1036.         rect_type rect;
  1037.         wipetable_type* ptr;
  1038.         ptr = &wipetable[index];
  1039.         rect.left = rect.right = ptr->left;
  1040.         rect.right += ptr->width;
  1041.         rect.bottom = rect.top = ptr->bottom;
  1042.         rect.top -= ptr->height;
  1043.         draw_rect(&rect, ptr->color);
  1044.         if (need_drects) {
  1045.                 add_drect(&rect);
  1046.         }
  1047. }
  1048.  
  1049. // data:4E8C
  1050. word gate_top_y;
  1051. // data:4CB6
  1052. word gate_openness;
  1053. // data:436C
  1054. word gate_bottom_y;
  1055.  
  1056. // seg008:178E
  1057. void __pascal far calc_gate_pos() {
  1058.         gate_top_y = draw_bottom_y - 62;
  1059.         gate_openness = (MIN(modifier_left, 188) >> 2) + 1;
  1060.         gate_bottom_y = draw_main_y - gate_openness;
  1061. }
  1062.  
  1063. // data:2785
  1064. const byte door_fram_slice[] = {67, 59, 58, 57, 56, 55, 54, 53, 52};
  1065. // seg008:17B7
  1066. void __pascal far draw_gate_back() {
  1067.         short ybottom;
  1068.         word var_2;
  1069.         calc_gate_pos();
  1070.         if (gate_bottom_y + 12 < draw_main_y) {
  1071.                 add_backtable(id_chtab_6_environment, 50 /*gate bottom with B*/, draw_xh, 0, gate_bottom_y, blitters_0_no_transp, 0);
  1072.         } else {
  1073.                 // The following line (erroneously) erases the top-right of the tile below-left (because it is drawn non-transparently).
  1074.                 // -- But it draws something that was already drawn! (in draw_tile_right()).
  1075.                 add_backtable(id_chtab_6_environment, tile_table[tiles_4_gate].right_id, draw_xh, 0,
  1076.                               tile_table[tiles_4_gate].right_y + draw_main_y, blitters_0_no_transp, 0);
  1077.                 // And this line tries to fix it. But it fails if it was a gate or a pillar.
  1078.                 if (can_see_bottomleft()) draw_tile_topright();
  1079. #ifdef FIX_GATE_DRAWING_BUG
  1080.                 if (fix_gate_drawing_bug) {
  1081.                         draw_tile_anim_topright(); // redraw the erased top-right section of the gate below-left
  1082.                 }
  1083. #endif
  1084.                 // The following 3 lines draw things that are drawn after this anyway.
  1085.                 draw_tile_bottom(0);
  1086.                 draw_loose(0);
  1087.                 draw_tile_base();
  1088.                 add_backtable(id_chtab_6_environment, 51 /*gate bottom*/, draw_xh, 0, gate_bottom_y - 2, blitters_10h_transp, 0);
  1089.         }
  1090.         ybottom = gate_bottom_y - 12;
  1091.         if (ybottom < 192) {
  1092.                 for (; ybottom >= 0 && ybottom > 7 && ybottom - 7 > gate_top_y; ybottom -= 8) {
  1093.                         add_backtable(id_chtab_6_environment, 52 /*gate slice 8px*/, draw_xh, 0, ybottom, blitters_0_no_transp, 0);
  1094.                 }
  1095.         }
  1096.         var_2 = ybottom - gate_top_y + 1;
  1097.         if (var_2 > 0 && var_2 < 9) {
  1098.                 add_backtable(id_chtab_6_environment, door_fram_slice[var_2], draw_xh, 0, ybottom, blitters_0_no_transp, 0);
  1099.         }
  1100. }
  1101.  
  1102. // seg008:18BE
  1103. void __pascal far draw_gate_fore() {
  1104.         short ybottom;
  1105.         calc_gate_pos();
  1106.         add_foretable(id_chtab_6_environment, 51 /*gate bottom*/, draw_xh, 0, gate_bottom_y - 2, blitters_10h_transp, 0);
  1107.         ybottom = gate_bottom_y - 12;
  1108.         if (ybottom < 192) {
  1109.                 for (; ybottom >= 0 && ybottom > 7 && ybottom - 7 > gate_top_y; ybottom -= 8) {
  1110.                         add_foretable(id_chtab_6_environment, 52 /*gate slice 8px*/, draw_xh, 0, ybottom, blitters_10h_transp, 0);
  1111.                 }
  1112.         }
  1113. }
  1114.  
  1115. // seg008:1937
  1116. void __pascal far alter_mods_allrm() {
  1117.         word tilepos;
  1118.         word room;
  1119.         for (room = 1; room <= level.used_rooms; room++) {
  1120.                 get_room_address(room);
  1121.                 room_L = level.roomlinks[room-1].left;
  1122.                 room_R = level.roomlinks[room-1].right;
  1123.                 for(tilepos = 0; tilepos < 30; tilepos++) {
  1124.                         load_alter_mod(tilepos);
  1125.                 }
  1126.         }
  1127. }
  1128.  
  1129. // seg008:198E
  1130. void __pascal far load_alter_mod(int tilepos) {
  1131.         word wall_to_right;
  1132.         word tiletype;
  1133.         word wall_to_left;
  1134.         byte* curr_tile_modif;
  1135.         curr_tile_modif = tilepos + curr_room_modif;
  1136.         tiletype = curr_room_tiles[tilepos] & 0x1F;
  1137.         switch (tiletype) {
  1138.                 case tiles_4_gate:
  1139.                         if (*curr_tile_modif == 1) {
  1140.                                 *curr_tile_modif = 188;
  1141.                         } else {
  1142.                                 *curr_tile_modif = 0;
  1143.                         }
  1144.                         break;
  1145.                 case tiles_11_loose:
  1146.                         *curr_tile_modif = 0;
  1147.                         break;
  1148.                 case tiles_10_potion:
  1149.                         *curr_tile_modif <<= 3;
  1150. #ifdef USE_COPYPROT
  1151.                         if (current_level == 15) {
  1152.                                 // Copy protection
  1153.                                 if (copyprot_room[copyprot_plac] == loaded_room &&
  1154.                                         copyprot_tile[copyprot_plac] == tilepos
  1155.                                 ) {
  1156.                                         *curr_tile_modif = 6 << 3; // place open potion
  1157.                                 }
  1158.                         }
  1159. #endif
  1160.                         break;
  1161.  
  1162.  
  1163.                 case tiles_20_wall:
  1164.                 {
  1165.                         byte stored_modif = *curr_tile_modif;
  1166.                         //*curr_tile_modif <<= 7; // original: "no blue" mod becomes most significant bit
  1167.                         if (stored_modif == 1) *curr_tile_modif = 0x80;
  1168.                         else *curr_tile_modif = (stored_modif << 4);
  1169.                         // retain three bits more information:
  1170.                         // most significant bit:       1 ==> "no blue"
  1171.                         // next 3 bits:                for displaying various fake tiles (invisible walls)
  1172.                         // ..
  1173.                         // least significant 2 bits:   wall to left/right?
  1174.                 }
  1175.                         // fallthrough: not done yet, just moving to another scope
  1176.                         goto label_wall_continued;
  1177.  
  1178. #ifdef USE_FAKE_TILES
  1179.                 // Need to deal with the possibility that certain tiles can impersonate walls
  1180.                 case tiles_0_empty:
  1181.                 case tiles_1_floor:
  1182.                         if ((*curr_tile_modif & 7) != 5) break;
  1183.                         // if tile is a fake wall, fall through
  1184. #endif
  1185.  
  1186.                         label_wall_continued:
  1187.                 {
  1188.                         // Here, ahead of time, we define the condition for a neighbouring tile to be seen as a wall connection
  1189.                         #ifndef USE_FAKE_TILES
  1190.                         #define read_adj_tile_modif_in_curr_room()      // nop; access to modifier of adjacent tiles is not needed
  1191.                         #define read_adj_tile_modif_in_external_room()  // nop
  1192.                         #define WALL_CONNECTION_CONDITION (adj_tile == tiles_20_wall)
  1193.  
  1194.                         #else // #ifdef USE_FAKE_TILES
  1195.                         // When determining wall connections for fake walls, we need access to the tile modifier of adjacent tiles
  1196.                         #define read_adj_tile_modif_in_curr_room() \
  1197.                         int adj_tile_modif = curr_room_modif[adj_tile_index];
  1198.                         #define read_adj_tile_modif_in_external_room() \
  1199.                         int adj_tile_modif = level.bg[adj_tile_index];
  1200.                         // Now redefine the condition for what tiletype / modifier combination counts as a valid "wall"
  1201.                         #define WALL_CONNECTION_CONDITION (                                                                       \
  1202.                                 (adj_tile == tiles_20_wall && adj_tile_modif != 4 && (adj_tile_modif >> 4) != 4 &&                    \
  1203.                                              adj_tile_modif != 6 && (adj_tile_modif >> 4) != 6) ||                                    \
  1204.                                 (adj_tile == tiles_0_empty && (adj_tile_modif == 5 || adj_tile_modif == 13 ||                         \
  1205.                                              (adj_tile_modif >= 50 && adj_tile_modif <= 53))) ||                                      \
  1206.                                 (adj_tile == tiles_1_floor && (adj_tile_modif == 5 || adj_tile_modif == 13 ||                         \
  1207.                                              (adj_tile_modif >= 50 && adj_tile_modif <= 53))))
  1208.                         #endif
  1209.  
  1210.                         if (graphics_mode != gmCga && graphics_mode != gmHgaHerc) {
  1211.                                 wall_to_right = 1;
  1212.                                 wall_to_left = 1;
  1213.                                 int adj_tile_index, adj_tile;
  1214.                                 if (tilepos % 10 == 0) {
  1215.                                         if (room_L) {
  1216.                                                 adj_tile_index = 30*(room_L-1)+tilepos+9;
  1217.                                                 adj_tile = (level.fg[adj_tile_index] & 0x1F);
  1218.                                                 read_adj_tile_modif_in_external_room(); // only executed when fake tiles are enabled
  1219.                                                 wall_to_left = WALL_CONNECTION_CONDITION;
  1220.                                         }
  1221.                                 } else {
  1222.                                         adj_tile_index = tilepos-1;
  1223.                                         adj_tile = (curr_room_tiles[adj_tile_index] & 0x1F);
  1224.                                         read_adj_tile_modif_in_curr_room();
  1225.                                         wall_to_left = WALL_CONNECTION_CONDITION;
  1226.                                 }
  1227.                                 if (tilepos % 10 == 9) {
  1228.                                         if (room_R) {
  1229.                                                 adj_tile_index = 30*(room_R-1)+tilepos-9;
  1230.                                                 adj_tile = (level.fg[adj_tile_index] & 0x1F);
  1231.                                                 read_adj_tile_modif_in_external_room();
  1232.                                                 wall_to_right = WALL_CONNECTION_CONDITION;
  1233.                                         }
  1234.                                 } else {
  1235.                                         adj_tile_index = tilepos+1;
  1236.                                         adj_tile = (curr_room_tiles[adj_tile_index] & 0x1F);
  1237.                                         read_adj_tile_modif_in_curr_room();
  1238.                                         wall_to_right = WALL_CONNECTION_CONDITION;
  1239.                                 }
  1240.  
  1241.                                 #ifdef USE_FAKE_TILES
  1242.                                 if (tiletype == tiles_1_floor || tiletype == tiles_0_empty) {
  1243.                                         if (wall_to_left && wall_to_right) {
  1244.                                                 *curr_tile_modif = 53;
  1245.                                         } else if (wall_to_left) {
  1246.                                                 *curr_tile_modif = 52;
  1247.                                         } else if (wall_to_right) {
  1248.                                                 *curr_tile_modif = 51;
  1249.                                         }
  1250.                                         break;
  1251.                                 }
  1252.                                 #endif
  1253.  
  1254.                                 if (wall_to_left && wall_to_right) {
  1255.                                         *curr_tile_modif |= 3;
  1256.                                 } else if (wall_to_left) {
  1257.                                         *curr_tile_modif |= 2;
  1258.                                 } else if (wall_to_right) {
  1259.                                         *curr_tile_modif |= 1;
  1260.                                 }
  1261.                         } else {
  1262.                                 *curr_tile_modif = 3;
  1263.                         }
  1264.                 }
  1265.                         break;
  1266.         }
  1267. }
  1268.  
  1269. // seg008:1AF8
  1270. void __pascal far draw_moving() {
  1271.         draw_mobs();
  1272.         draw_people();
  1273.         redraw_needed_tiles();
  1274. }
  1275.  
  1276. // seg008:1B06
  1277. void __pascal far redraw_needed_tiles() {
  1278.         word saved_drawn_room;
  1279.         load_leftroom();
  1280.         draw_objtable_items_at_tile(30);
  1281.         for (drawn_row = 3; drawn_row--; ) {
  1282.                 load_rowbelow();
  1283.                 draw_bottom_y = 63 * drawn_row + 65;
  1284.                 draw_main_y = draw_bottom_y - 3;
  1285.                 for (drawn_col = 0; drawn_col < 10; ++drawn_col) {
  1286.                         load_curr_and_left_tile();
  1287.                         redraw_needed(tbl_line[drawn_row] + drawn_col);
  1288.                 }
  1289.         }
  1290.         saved_drawn_room = drawn_room;
  1291.         drawn_room = room_A;
  1292.         load_room_links();
  1293.         load_leftroom();
  1294.         drawn_row = 2;
  1295.         load_rowbelow();
  1296.         for (drawn_col = 0; drawn_col < 10; ++drawn_col) {
  1297.                 load_curr_and_left_tile();
  1298.                 draw_main_y = -1;
  1299.                 draw_bottom_y = 2;
  1300.                 redraw_needed_above(drawn_col);
  1301.         }
  1302.         drawn_room = saved_drawn_room;
  1303.         load_room_links();
  1304.         draw_objtable_items_at_tile(-1);
  1305. }
  1306.  
  1307. // seg008:1BCB
  1308. void __pascal far draw_tile_wipe(byte height) {
  1309.         add_wipetable(0, draw_xh*8, draw_bottom_y, height, 4*8, 0);
  1310. }
  1311.  
  1312. // seg008:1BEB
  1313. void __pascal far draw_tables() {
  1314.         drects_count = 0;
  1315.         current_target_surface = offscreen_surface;
  1316.         if (is_blind_mode) {
  1317.                 draw_rect(&rect_top, 0);
  1318.         }
  1319.         restore_peels();
  1320.         draw_wipes(0);
  1321.         draw_table(0); // backtable
  1322.         //printf("midtable_count = %d\n", midtable_count); // debug
  1323.         draw_table(3); // midtable
  1324.         draw_wipes(1);
  1325.         draw_table(1); // foretable
  1326.         current_target_surface = onscreen_surface_;
  1327.         show_copyprot(1);
  1328. }
  1329.  
  1330. // seg008:1C4E
  1331. void __pascal far restore_peels() {
  1332.         peel_type* peel;
  1333.         while (peels_count--) {
  1334.                 peel = peels_table[peels_count];
  1335.                 if (need_drects) {
  1336.                         add_drect(&peel->rect); // ?
  1337.                 }
  1338.                 restore_peel(peel);
  1339.         }
  1340.         peels_count = 0;
  1341. }
  1342.  
  1343. // seg008:1C8F
  1344. void __pascal far add_drect(rect_type *source) {
  1345.         rect_type* far current_drect;
  1346.         short index;
  1347.         rect_type target_rect;
  1348.         for (index = 0; index < drects_count; ++index) {
  1349.                 if (intersect_rect(&target_rect, shrink2_rect(&target_rect, source, -1, -1), &drects[index])) {
  1350.                         current_drect = &drects[index];
  1351.                         union_rect(current_drect, current_drect, source);
  1352.                         return;
  1353.                 }
  1354.         }
  1355.         if (drects_count >= 30){
  1356.                 show_dialog("DRects Overflow");
  1357.                 return /*0*/; // added
  1358.         }
  1359.         drects[drects_count++] = *source;
  1360. }
  1361.  
  1362. // seg008:1D29
  1363. void __pascal far draw_leveldoor() {
  1364.         word var_6;
  1365.         word ybottom;
  1366.         ybottom = draw_main_y - 13;
  1367.         leveldoor_right = (draw_xh<<3)+48;
  1368.         if (tbl_level_type[current_level]) leveldoor_right += 8;
  1369.         add_backtable(id_chtab_6_environment, 99 /*leveldoor stairs bottom*/, draw_xh + 1, 0, ybottom, blitters_0_no_transp, 0);
  1370.         if (modifier_left) {
  1371.                 if (level.start_room != drawn_room) {
  1372.                         add_backtable(id_chtab_6_environment, 144 /*level door stairs*/, draw_xh + 1, 0, ybottom - 4, blitters_0_no_transp, 0);
  1373.                 }
  1374.                 else {
  1375.                         short leveldoor_width = (tbl_level_type[current_level] == 0) ? 39 : 48;
  1376.                         sbyte x_low = (tbl_level_type[current_level] == 0) ? 2 : 0; // dungeon level doors are shifted 2px to the right
  1377.                         add_wipetable(0, 8*(draw_xh + 1) + x_low, ybottom - 4, 45, leveldoor_width, 0);
  1378.                 }
  1379.         }
  1380.         leveldoor_ybottom = ybottom - (modifier_left & 3) - 48;
  1381.         for (var_6 = ybottom - modifier_left;
  1382.                 add_backtable(id_chtab_6_environment, 33 /*level door bottom*/, draw_xh + 1, 0, leveldoor_ybottom, blitters_0_no_transp, 0),
  1383.                         var_6 > leveldoor_ybottom;
  1384.                 leveldoor_ybottom += 4) {
  1385.                 ;
  1386.         } // runs at least once?
  1387.         add_backtable(id_chtab_6_environment, 34 /*level door top*/, draw_xh + 1, 0, draw_main_y - 64, blitters_0_no_transp, 0);
  1388. }
  1389.  
  1390. // seg008:1E0C
  1391. void __pascal far get_room_address(int room) {
  1392.         loaded_room = (word) room;
  1393.         if (room) {
  1394.                 curr_room_tiles = &level.fg[(room-1)*30];
  1395.                 curr_room_modif = &level.bg[(room-1)*30];
  1396.         }
  1397. }
  1398.  
  1399. // data:286A
  1400. const word floor_left_overlay[] = {32, 151, 151, 150, 150, 151, 32, 32};
  1401.  
  1402. // seg008:1E3A
  1403. void __pascal far draw_floor_overlay() {
  1404. #ifdef FIX_BIGPILLAR_CLIMB
  1405.         if (tile_left != tiles_0_empty) {
  1406.                 // Bug: When climbing up to a floor with a big pillar top behind, turned right, Kid sees through floor.
  1407.                 // The bigpillar_top tile should be treated similarly to an empty tile here.
  1408.                 if (!fix_bigpillar_climb || (tile_left != tiles_9_bigpillar_top)) {
  1409.                         return;
  1410.                 }
  1411.         }
  1412. #else
  1413.         if (tile_left != tiles_0_empty) return;
  1414. #endif
  1415.         if (curr_tile == tiles_1_floor ||
  1416.                 curr_tile == tiles_3_pillar ||
  1417.                 curr_tile == tiles_5_stuck ||
  1418.                 curr_tile == tiles_19_torch
  1419.         ) {
  1420.                 // frames 137..144: climb
  1421.                 // index overflow here?
  1422.                 if (Kid.frame >= frame_137_climbing_3 && Kid.frame <= frame_144_climbing_10) {
  1423.                         add_midtable(id_chtab_6_environment, floor_left_overlay[Kid.frame - 137], draw_xh, 0, (curr_tile == tiles_5_stuck) + draw_main_y, blitters_10h_transp, 0);
  1424.                 } else {
  1425.                         // triggered by 02-random-broken
  1426.                         printf("draw_floor_overlay: attempted to draw floor overlay with frame %d not in 137..144\n", Kid.frame);
  1427.                         //quit(1);
  1428.                 }
  1429.                 ptr_add_table = &add_midtable;
  1430.                 draw_tile_bottom(0);
  1431.                 ptr_add_table = &add_backtable;
  1432.         } else {
  1433.                 draw_other_overlay();
  1434.         }
  1435. }
  1436.  
  1437. // seg008:1EB5
  1438. void __pascal far draw_other_overlay() {
  1439.         byte tiletype;
  1440.         byte modifier;
  1441.         if (tile_left == tiles_0_empty) {
  1442.                 ptr_add_table = &add_midtable;
  1443.                 draw_tile2();
  1444.         } else if (curr_tile != tiles_0_empty && drawn_col > 0 &&
  1445.                 get_tile_to_draw(drawn_room, drawn_col - 2, drawn_row, &tiletype, &modifier, tiles_0_empty) == tiles_0_empty
  1446.         ) {
  1447.                 ptr_add_table = &add_midtable;
  1448.                 draw_tile2();
  1449.                 ptr_add_table = &add_backtable;
  1450.                 draw_tile2();
  1451.                 tile_object_redraw[tbl_line[drawn_row] + drawn_col] = 0xFF;
  1452.         }
  1453.         ptr_add_table = &add_backtable;
  1454. }
  1455.  
  1456. // seg008:1F48
  1457. void __pascal far draw_tile2() {
  1458.         draw_tile_right();
  1459.         draw_tile_anim_right();
  1460.         draw_tile_base();
  1461.         draw_tile_anim();
  1462.         draw_tile_bottom(0);
  1463.         draw_loose(0);
  1464. }
  1465.  
  1466. // seg008:1F67
  1467. void __pascal far draw_objtable_items_at_tile(byte tilepos) {
  1468.         //printf("draw_objtable_items_at_tile(%d)\n",tilepos); // debug
  1469.         short obj_count;
  1470.         short obj_index;
  1471.         obj_count = objtable_count;
  1472.         if (obj_count) {
  1473.                 for (obj_index = obj_count - 1, n_curr_objs = 0; obj_index >= 0; --obj_index) {
  1474.                         if (objtable[obj_index].tilepos == tilepos) {
  1475.                                 curr_objs[n_curr_objs++] = obj_index;
  1476.                         }
  1477.                 }
  1478.                 if (n_curr_objs) {
  1479.                         sort_curr_objs();
  1480.                         for (obj_index = 0; obj_index < n_curr_objs; ++obj_index) {
  1481.                                 draw_objtable_item(curr_objs[obj_index]);
  1482.                         }
  1483.                 }
  1484.         }
  1485. }
  1486.  
  1487. // seg008:1FDE
  1488. void __pascal far sort_curr_objs() {
  1489.         short swapped;
  1490.         short temp;
  1491.         short last;
  1492.         short index;
  1493.         // bubble sort
  1494.         last = n_curr_objs - 1;
  1495.         do {
  1496.                 for (swapped = index = 0; index < last; ++index) {
  1497.                         if (compare_curr_objs(index, index + 1)) {
  1498.                                 temp = curr_objs[index];
  1499.                                 curr_objs[index] = curr_objs[index + 1];
  1500.                                 curr_objs[index + 1] = temp;
  1501.                                 swapped = 1;
  1502.                         }
  1503.                 }
  1504.                 // --last ?
  1505.         } while (swapped);
  1506. }
  1507.  
  1508. // seg008:203C
  1509. int __pascal far compare_curr_objs(int index1,int index2) {
  1510.         short obj_index1;
  1511.         short obj_index2;
  1512.         obj_index1 = curr_objs[index1];
  1513.         if (objtable[obj_index1].obj_type == 1) return 1;
  1514.         obj_index2 = curr_objs[index2];
  1515.         if (objtable[obj_index2].obj_type == 1) return 0;
  1516.         if (objtable[obj_index1].obj_type == 0x80 &&
  1517.                 objtable[obj_index2].obj_type == 0x80
  1518.         ) {
  1519.                 return (objtable[obj_index1].y < objtable[obj_index2].y);
  1520.         } else {
  1521.                 return (objtable[obj_index1].y > objtable[obj_index2].y);
  1522.         }
  1523.         return 1;
  1524. }
  1525.  
  1526. // seg008:20CA
  1527. void __pascal far draw_objtable_item(int index) {
  1528.         switch (load_obj_from_objtable(index)) {
  1529.                 case 0: // Kid
  1530.                 case 4: // mirror image
  1531.                         //printf("index = %d, obj_id = %d\n", index, obj_id); // debug
  1532.                         if (obj_id == 0xFF) return;
  1533.                         // the Kid blinks a bit after uniting with shadow
  1534.                         if (united_with_shadow && (united_with_shadow % 2) == 0) goto shadow;
  1535.                 case 2: // Guard
  1536.                 case 3: // sword
  1537.                 case 5: // hurt splash
  1538.                         add_midtable(obj_chtab, obj_id + 1, obj_xh, obj_xl, obj_y, blitters_10h_transp, 1);
  1539.                 break;
  1540.                 case 1: // shadow
  1541.                 shadow:
  1542.                         if (united_with_shadow == 2) {
  1543.                                 play_sound(sound_41_end_level_music); // united with shadow
  1544.                         }
  1545.                         add_midtable(obj_chtab, obj_id + 1, obj_xh, obj_xl, obj_y, blitters_2_or, 1);
  1546.                         add_midtable(obj_chtab, obj_id + 1, obj_xh, obj_xl + 1, obj_y, blitters_3_xor, 1);
  1547.                 break;
  1548.                 case 0x80: // loose floor
  1549.                         obj_direction = dir_FF_left;
  1550.                         add_midtable(obj_chtab, loose_fram_left[obj_id], obj_xh, obj_xl, obj_y - 3, blitters_10h_transp, 1);
  1551.                         add_midtable(obj_chtab, loose_fram_bottom[obj_id], obj_xh, obj_xl, obj_y, 0, 1);
  1552.                         add_midtable(obj_chtab, loose_fram_right[obj_id], obj_x + 4, obj_xl, obj_y - 1, blitters_10h_transp, 1);
  1553.                 break;
  1554.         }
  1555. }
  1556.  
  1557. // seg008:2228
  1558. int __pascal far load_obj_from_objtable(int index) {
  1559.         objtable_type* curr_obj;
  1560.         curr_obj = &objtable[index];
  1561.         obj_xh = obj_x = curr_obj->xh;
  1562.         obj_xl = curr_obj->xl;
  1563.         obj_y = curr_obj->y;
  1564.         obj_id = curr_obj->id;
  1565.         obj_chtab = curr_obj->chtab_id;
  1566.         obj_direction = curr_obj->direction;
  1567.         obj_clip_top = curr_obj->clip.top;
  1568.         obj_clip_bottom = curr_obj->clip.bottom;
  1569.         obj_clip_left = curr_obj->clip.left;
  1570.         obj_clip_right = curr_obj->clip.right;
  1571.         return curr_obj->obj_type;
  1572. }
  1573.  
  1574. // seg008:228A
  1575. void __pascal far draw_people() {
  1576.         check_mirror();
  1577.         draw_kid();
  1578.         draw_guard();
  1579.         reset_obj_clip();
  1580.         draw_hp();
  1581. }
  1582.  
  1583. // seg008:22A2
  1584. void __pascal far draw_kid() {
  1585.         if (Kid.room != 0 && Kid.room == drawn_room) {
  1586.                 add_kid_to_objtable();
  1587.                 if (hitp_delta < 0) {
  1588.                         draw_hurt_splash();
  1589.                 }
  1590.                 add_sword_to_objtable();
  1591.         }
  1592. }
  1593.  
  1594. // seg008:22C9
  1595. void __pascal far draw_guard() {
  1596.         if (Guard.direction != dir_56_none && Guard.room == drawn_room) {
  1597.                 add_guard_to_objtable();
  1598.                 if (guardhp_delta < 0) {
  1599.                         draw_hurt_splash();
  1600.                 }
  1601.                 add_sword_to_objtable();
  1602.         }
  1603. }
  1604.  
  1605. // seg008:22F0
  1606. void __pascal far add_kid_to_objtable() {
  1607.         //printf("add_kid_to_objtable\n");
  1608.         loadkid();
  1609.         load_fram_det_col();
  1610.         load_frame_to_obj();
  1611.         stuck_lower();
  1612.         set_char_collision();
  1613.         set_objtile_at_char();
  1614.         redraw_at_char();
  1615.         redraw_at_char2();
  1616.         clip_char();
  1617.         add_objtable(0); // Kid
  1618. }
  1619.  
  1620. // seg008:2324
  1621. void __pascal far add_guard_to_objtable() {
  1622.         word obj_type;
  1623.         loadshad();
  1624.         load_fram_det_col();
  1625.         load_frame_to_obj();
  1626.         stuck_lower();
  1627.         set_char_collision();
  1628.         set_objtile_at_char();
  1629.         redraw_at_char();
  1630.         redraw_at_char2();
  1631.         clip_char();
  1632.         if (Char.charid == charid_1_shadow) {
  1633.                 // Special event: shadow is clipped: may appear only right from the mirror
  1634.                 if (current_level == 4 && Char.room == 4) {
  1635.                         obj_clip_left = 137;
  1636.                 }
  1637.                 obj_type = 1; // shadow
  1638.         } else {
  1639.                 obj_type = 2; // Guard
  1640.         }
  1641.         add_objtable(obj_type);
  1642. }
  1643.  
  1644. // seg008:2388
  1645. void __pascal far add_objtable(byte obj_type) {
  1646.         word index;
  1647.         objtable_type* entry_addr;
  1648.         //printf("in add_objtable: objtable_count = %d\n",objtable_count); // debug
  1649.         index = objtable_count++;
  1650.         //printf("in add_objtable: objtable_count = %d\n",objtable_count); // debug
  1651.         if (index >= 50) {
  1652.                 show_dialog("ObjTable Overflow");
  1653.                 return /*0*/; // added
  1654.         }
  1655.         entry_addr = &objtable[index];
  1656.         entry_addr->obj_type = obj_type;
  1657.         x_to_xh_and_xl(obj_x, &entry_addr->xh, &entry_addr->xl);
  1658.         entry_addr->y = obj_y;
  1659.         entry_addr->clip.top = obj_clip_top;
  1660.         entry_addr->clip.bottom = obj_clip_bottom;
  1661.         entry_addr->clip.left = obj_clip_left;
  1662.         entry_addr->clip.right = obj_clip_right;
  1663.         entry_addr->chtab_id = obj_chtab;
  1664.         entry_addr->id = obj_id;
  1665.         entry_addr->direction = obj_direction;
  1666.         mark_obj_tile_redraw(index);
  1667. }
  1668.  
  1669. // seg008:2423
  1670. void __pascal far mark_obj_tile_redraw(int index) {
  1671.         //printf("mark_obj_tile_redraw: obj_tile = %d\n", obj_tile); // debug
  1672.         objtable[index].tilepos = obj_tilepos;
  1673.         if (obj_tilepos < 30) {
  1674.                 tile_object_redraw[obj_tilepos] = 1;
  1675.         }
  1676. }
  1677.  
  1678. // seg008:2448
  1679. void __pascal far load_frame_to_obj() {
  1680.         word chtab_base;
  1681.         chtab_base = id_chtab_2_kid;
  1682.         reset_obj_clip();
  1683.         load_frame();
  1684.         obj_direction = Char.direction;
  1685.         obj_id = cur_frame.image;
  1686.         // top 6 bits of sword are the chtab
  1687.         obj_chtab = chtab_base + (cur_frame.sword >> 6);
  1688.         obj_x = (char_dx_forward(cur_frame.dx) << 1) - 116;
  1689.         obj_y = cur_frame.dy + Char.y;
  1690.         if ((sbyte)(cur_frame.flags ^ obj_direction) >= 0) {
  1691.                 // 0x80: even/odd pixel
  1692.                 ++obj_x;
  1693.         }
  1694. }
  1695.  
  1696. // seg008:24A8
  1697. void __pascal far show_time() {
  1698.         char sprintf_temp[40];
  1699.         word rem_sec;
  1700.         if (Kid.alive < 0 &&
  1701.                 #ifdef FREEZE_TIME_DURING_END_MUSIC
  1702.                 (!(enable_freeze_time_during_end_music && next_level != current_level)) &&
  1703.                 #endif
  1704.                 #ifdef ALLOW_INFINITE_TIME
  1705.                 // prevent overflow
  1706.                 (!(rem_min == INT16_MIN && rem_tick == 1)) &&
  1707.                 #endif
  1708.                 rem_min != 0 &&
  1709.                 (current_level < 13 || (current_level == 13 && leveldoor_open == 0)) &&
  1710.                 current_level < 15
  1711.         ) {
  1712.                 // Time passes
  1713.                 --rem_tick;
  1714.                 if (rem_tick == 0) {
  1715.                         rem_tick = 719; // 720=12*60 ticks = 1 minute
  1716.                         --rem_min;
  1717. #ifndef ALLOW_INFINITE_TIME
  1718.                         if (rem_min != 0 && (rem_min <= 5 || rem_min % 5 == 0)) {
  1719.                                 is_show_time = 1;
  1720.                         }
  1721. #else
  1722.                         if (rem_min > 0 && (rem_min <= 5 || rem_min % 5 == 0)) {
  1723.                                 is_show_time = 1;
  1724.                         } else if (rem_min < 0) {
  1725.                                 is_show_time = ((~rem_min) % 5 == 0 ) ? 1 : 0;
  1726.                         }
  1727. #endif
  1728.                 } else {
  1729.                         if (rem_min == 1 && rem_tick % 12 == 0) {
  1730.                                 is_show_time = 1;
  1731.                                 text_time_remaining = 0;
  1732.                         }
  1733.                 }
  1734.         }
  1735.         if (is_show_time && text_time_remaining == 0) {
  1736.                 text_time_remaining = text_time_total = 24;
  1737.                 if (rem_min > 0) {
  1738.                         if (rem_min == 1) {
  1739.                                 rem_sec = (rem_tick + 1) / 12;
  1740.                                 if (rem_sec == 1) {
  1741.                                         strncpy(sprintf_temp, "1 SECOND LEFT", sizeof(sprintf_temp));
  1742.                                         text_time_remaining = text_time_total = 12;
  1743.                                 } else {
  1744.                                         snprintf(sprintf_temp, sizeof(sprintf_temp), "%d SECONDS LEFT", rem_sec);
  1745.                                 }
  1746.                         } else {
  1747.                                 snprintf(sprintf_temp, sizeof(sprintf_temp), "%d MINUTES LEFT", rem_min);
  1748.                         }
  1749.                         display_text_bottom(sprintf_temp);
  1750.                 } else {
  1751.  
  1752. #ifdef ALLOW_INFINITE_TIME
  1753.                         if (rem_min < 0) {
  1754.                                 if (~rem_min == 0) {
  1755.                                         // don't display time elapsed in the first minute
  1756.                                         text_time_remaining = 0;
  1757.                                         text_time_total = 0;
  1758.                                 }
  1759.                                 else if (~rem_min == 1) {
  1760.                                         snprintf(sprintf_temp, sizeof(sprintf_temp), "1 MINUTE PASSED");
  1761.                                 } else {
  1762.                                         snprintf(sprintf_temp, sizeof(sprintf_temp), "%d MINUTES PASSED", ~rem_min);
  1763.                                 }
  1764.                                 display_text_bottom(sprintf_temp);
  1765.                         }
  1766.  
  1767.                         else if (rem_min == 0) // may also be negative, don't report "expired" in that case!
  1768. #endif
  1769.  
  1770.                         display_text_bottom("TIME HAS EXPIRED!");
  1771.                 }
  1772.                 is_show_time = 0;
  1773.         }
  1774. }
  1775.  
  1776. // seg008:25A8
  1777. void __pascal far show_level() {
  1778.         byte disp_level;
  1779.         char sprintf_temp[32];
  1780.         disp_level = current_level;
  1781.         if (disp_level != 0 && disp_level < 14 && seamless == 0) {
  1782.                 if (disp_level == 13) {
  1783.                         disp_level = 12;
  1784.                 }
  1785.                 text_time_remaining = text_time_total = 24;
  1786.                 snprintf(sprintf_temp, sizeof(sprintf_temp), "LEVEL %d", disp_level);
  1787.                 display_text_bottom(sprintf_temp);
  1788.                 is_show_time = 1;
  1789.         }
  1790.         seamless = 0;
  1791. }
  1792.  
  1793. // seg008:2602
  1794. short __pascal far calc_screen_x_coord(short logical_x) {
  1795.         return logical_x*320/280;
  1796. }
  1797.  
  1798. // seg008:2627
  1799. void __pascal far free_peels() {
  1800.         while (peels_count > 0) {
  1801.                 --peels_count;
  1802.                 free_peel(peels_table[peels_count]);
  1803.         }
  1804. }
  1805.  
  1806.  
  1807. // seg008:2644
  1808. void __pascal far display_text_bottom(const char near *text) {
  1809.         draw_rect(&rect_bottom_text, 0);
  1810.         show_text(&rect_bottom_text, 0, 1, text);
  1811. #ifndef USE_TEXT
  1812.         SDL_WM_SetCaption(text, NULL);
  1813. #endif
  1814. }
  1815.  
  1816. // seg008:266D
  1817. void __pascal far erase_bottom_text(int arg_0) {
  1818.         draw_rect(&rect_bottom_text, 0);
  1819.         if (arg_0) {
  1820.                 text_time_total = 0;
  1821.                 text_time_remaining = 0;
  1822.         }
  1823. #ifndef USE_TEXT
  1824.         SDL_WM_SetCaption("", NULL);
  1825. #endif
  1826. }
  1827.  
  1828. // Dungeon wall drawing algorithm by HTamas
  1829.  
  1830. #define RSET_WALL              7
  1831.  
  1832. #define RES_WALL_FACE_MAIN     1    //(face stack main.bmp)
  1833. #define RES_WALL_FACE_TOP      2    //(face stack top.bmp)
  1834. #define RES_WALL_CENTRE_BASE   3    //(centre stack base.bmp)
  1835. #define RES_WALL_CENTRE_MAIN   4    //(centre stack main.bmp)
  1836. #define RES_WALL_RIGHT_BASE    5    //(right stack base.bmp)
  1837. #define RES_WALL_RIGHT_MAIN    6    //(right stack main.bmp)
  1838. #define RES_WALL_SINGLE_BASE   7    //(single stack base.bmp)
  1839. #define RES_WALL_SINGLE_MAIN   8    //(single stack main.bmp)
  1840. #define RES_WALL_LEFT_BASE     9    //(left stack base.bmp)
  1841. #define RES_WALL_LEFT_MAIN    10    //(left stack main.bmp)
  1842. #define RES_WALL_DIVIDER1     11    //(divider01.bmp, the broad divider)
  1843. #define RES_WALL_DIVIDER2     12    //(divider02.bmp, the narrow divider)
  1844. #define RES_WALL_RNDBLOCK     13    //(random block.bmp)
  1845. #define RES_WALL_MARK_TL      14    //(mark01.bmp, top left mark)
  1846. #define RES_WALL_MARK_BL      15    //(mark02.bmp, bottom left mark)
  1847. #define RES_WALL_MARK_TR      16    //(mark03.bmp, top right mark)
  1848. #define RES_WALL_MARK_BR      17    //(mark04.bmp, bottom right mark)
  1849.  
  1850. #define BLIT_NO_TRANS          0
  1851. #define BLIT_OR                2
  1852. #define BLIT_XOR               3
  1853. #define BLIT_BLACK             9
  1854. #define BLIT_TRANS            16
  1855.  
  1856. #define GRAPHICS_CGA          1
  1857. #define GRAPHICS_HERCULES     2
  1858. #define GRAPHICS_EGA          3
  1859. #define GRAPHICS_TANDY        4
  1860. #define GRAPHICS_VGA          5
  1861.  
  1862. #define DESIGN_DUNGEON        0
  1863. #define DESIGN_PALACE         1
  1864.  
  1865. #define WALL_MODIFIER_SWS     0
  1866. #define WALL_MODIFIER_SWW     1
  1867. #define WALL_MODIFIER_WWS     2
  1868. #define WALL_MODIFIER_WWW     3
  1869.  
  1870.  
  1871. // seg008:268F
  1872. void __pascal far wall_pattern(int which_part,int which_table) {
  1873.         // local variables
  1874.         add_table_type saved_sim;
  1875.         word v2; word v3; byte v4; byte v5;
  1876.         byte bg_modifier;
  1877.         dword saved_prng_state;
  1878.         word is_dungeon;
  1879.         // save the value for the sprite insertion method, so that it can be restored
  1880.         saved_sim = ptr_add_table;
  1881.         // set the sprite insertion method based on the arguments
  1882.         if (which_table == 0) {
  1883.                 ptr_add_table = &add_backtable;
  1884.         } else {
  1885.                 ptr_add_table = &add_foretable;
  1886.         }
  1887.         // save the state of the pseudorandom number generator
  1888.         saved_prng_state = random_seed;
  1889.         // set the new seed
  1890.         random_seed = drawn_room + tbl_line[drawn_row] + drawn_col;
  1891.         prandom(1); // fetch a random number and discard it
  1892.         is_dungeon = (tbl_level_type[current_level] < DESIGN_PALACE) || enable_wda_in_palace;
  1893.         if ( (!is_dungeon) && (graphics_mode== GRAPHICS_VGA) ) {
  1894.                 // I haven't traced the palace WDA
  1895.                 //[...]
  1896.                 if (which_part) {
  1897.                         add_wipetable(which_table, 8*(draw_xh)    , draw_main_y - 40, 20, 4*8, palace_wall_colors[44 * drawn_row +      drawn_col]);
  1898.                         add_wipetable(which_table, 8*(draw_xh)    , draw_main_y - 19, 21, 2*8, palace_wall_colors[44 * drawn_row + 11 + drawn_col]);
  1899.                         add_wipetable(which_table, 8*(draw_xh + 2), draw_main_y - 19, 21, 2*8, palace_wall_colors[44 * drawn_row + 12 + drawn_col]);
  1900.                         add_wipetable(which_table, 8*(draw_xh)    , draw_main_y     , 19, 1*8, palace_wall_colors[44 * drawn_row + 22 + drawn_col]);
  1901.                         add_wipetable(which_table, 8*(draw_xh + 1), draw_main_y     , 19, 3*8, palace_wall_colors[44 * drawn_row + 23 + drawn_col]);
  1902.                         ptr_add_table(id_chtab_7_environmentwall, prandom(2) +  3, draw_xh + 3, 0, draw_main_y - 53, blitters_46h_mono_6, 0);
  1903.                         ptr_add_table(id_chtab_7_environmentwall, prandom(2) +  6, draw_xh    , 0, draw_main_y - 34, blitters_46h_mono_6, 0);
  1904.                         ptr_add_table(id_chtab_7_environmentwall, prandom(2) +  9, draw_xh    , 0, draw_main_y - 13, blitters_46h_mono_6, 0);
  1905.                         ptr_add_table(id_chtab_7_environmentwall, prandom(2) + 12, draw_xh    , 0, draw_main_y     , blitters_46h_mono_6, 0);
  1906.                 }
  1907.                 add_wipetable(which_table, 8*draw_xh    , draw_bottom_y   ,  3, 4*8, palace_wall_colors[44 * drawn_row + 33 + drawn_col]);
  1908.                 ptr_add_table(id_chtab_7_environmentwall, prandom(2) + 15, draw_xh    , 0, draw_bottom_y   , blitters_46h_mono_6, 0);
  1909.         } else {
  1910.                 v3 = prandom(1);
  1911.                 v5 = prandom(4);
  1912.                 v2 = prandom(1);
  1913.                 v4 = prandom(4);
  1914.                 // store the background modifier for the current tile in a local variable
  1915.                 // apparently, for walls, the modifier stores whether there are adjacent walls
  1916.                 bg_modifier = curr_modifier & 0x7F;
  1917.                 switch (bg_modifier) {
  1918.                         case WALL_MODIFIER_WWW:
  1919.                                 if (which_part != 0) {
  1920.                                         if (prandom(4) == 0) {
  1921.                                                 ptr_add_table(RSET_WALL, RES_WALL_RNDBLOCK, draw_xh, 0, draw_bottom_y - 42, BLIT_NO_TRANS, 0);
  1922.                                         }
  1923.                                         ptr_add_table(RSET_WALL, RES_WALL_DIVIDER1 + v3, draw_xh + 1, v5, draw_bottom_y - 21, BLIT_TRANS, 0);
  1924.                                 }
  1925.                                 ptr_add_table(RSET_WALL, RES_WALL_DIVIDER1 + v2, draw_xh, v4, draw_bottom_y, BLIT_TRANS, 0);
  1926.                                 if (which_part != 0) {
  1927.                                         if (is_dungeon) {
  1928.                                                 if (prandom(4) == 0) {
  1929.                                                         draw_right_mark(prandom(3), v5);
  1930.                                                 }
  1931.                                                 if (prandom(4) == 0) {
  1932.                                                         draw_left_mark(prandom(4), v5 - v3, v4 - v2);
  1933.                                                 }
  1934.                                         }
  1935.                                 }
  1936.                                 break;
  1937.                         case WALL_MODIFIER_SWS:
  1938.                                 if (is_dungeon) {
  1939.                                         if (which_part != 0) {
  1940.                                                 if (prandom(6) == 0) {
  1941.                                                         draw_left_mark(prandom(1), v5 - v3, v4 - v2);
  1942.                                                 }
  1943.                                         }
  1944.                                 }
  1945.                                 break;
  1946.                         case WALL_MODIFIER_SWW:
  1947.                                 if (which_part != 0) {
  1948.                                         if (prandom(4) == 0) {
  1949.                                                 ptr_add_table(RSET_WALL, RES_WALL_RNDBLOCK, draw_xh, 0, draw_bottom_y - 42, BLIT_NO_TRANS, 0);
  1950.                                         }
  1951.                                         ptr_add_table(RSET_WALL, RES_WALL_DIVIDER1 + v3, draw_xh + 1 /*fix*/ , v5, draw_bottom_y - 21, BLIT_TRANS, 0);
  1952.                                         if (is_dungeon) {
  1953.                                                 if (prandom(4) == 0) {
  1954.                                                         draw_right_mark(prandom(3), v5);
  1955.                                                 }
  1956.                                                 if (prandom(4) == 0) {
  1957.                                                         draw_left_mark(prandom(3), v5 - v3, v4 - v2);
  1958.                                                 }
  1959.                                         }
  1960.                                 }
  1961.                                 break;
  1962.                         case WALL_MODIFIER_WWS:
  1963.                                 if (which_part != 0) {
  1964.                                         ptr_add_table(RSET_WALL, RES_WALL_DIVIDER1 + v3, draw_xh + 1, v5, draw_bottom_y - 21, BLIT_TRANS, 0);
  1965.                                 }
  1966.                                 ptr_add_table(RSET_WALL, RES_WALL_DIVIDER1 + v2, draw_xh, v4, draw_bottom_y, BLIT_TRANS, 0);
  1967.                                 if (which_part != 0) {
  1968.                                         if (is_dungeon) {
  1969.                                                 if (prandom(4) == 0) {
  1970.                                                         draw_right_mark(prandom(1) + 2, v5);
  1971.                                                 }
  1972.                                                 if (prandom(4) == 0) {
  1973.                                                         draw_left_mark(prandom(4), v5 - v3, v4 - v2);
  1974.                                                 }
  1975.                                         }
  1976.                                 }
  1977.                                 break;
  1978.                 }
  1979.         }
  1980.         random_seed = saved_prng_state;
  1981.         ptr_add_table = saved_sim;
  1982. }
  1983.  
  1984. void __pascal far draw_left_mark (word arg3, word arg2, word arg1) {
  1985.         word lv1; word lv2;
  1986.         static const word LPOS[] = {58, 41, 37, 20, 16};
  1987.         lv1 = RES_WALL_MARK_TL;
  1988.         lv2 = 0;
  1989.         if (arg3 % 2) {
  1990.                 lv1 = RES_WALL_MARK_BL;
  1991.         }
  1992.         if (arg3 > 3) {
  1993.                 lv2 = arg1 + 6;
  1994.         } else if (arg3 > 1) {
  1995.                 lv2 = arg2 + 6;
  1996.         }
  1997.         ptr_add_table(RSET_WALL, lv1, draw_xh + (arg3 == 2 || arg3 == 3), lv2, draw_bottom_y - LPOS[arg3], BLIT_TRANS, 0);
  1998. }
  1999.  
  2000. void __pascal far draw_right_mark (word arg2, word arg1) {
  2001.         word rv;
  2002.         static const word RPOS[] = {52, 42, 31, 21};
  2003.         rv = RES_WALL_MARK_TR;
  2004.         if (arg2 % 2) {
  2005.                 rv = RES_WALL_MARK_BR;
  2006.         }
  2007.         if (arg2 < 2) {
  2008.                 arg1 = 24;
  2009.         } else {
  2010.                 arg1 -= 3;
  2011.         }
  2012.         ptr_add_table(RSET_WALL, rv, draw_xh + (arg2 > 1), arg1, draw_bottom_y - RPOS[arg2], BLIT_TRANS, 0);
  2013. }
  2014.