home *** CD-ROM | disk | FTP | other *** search
/ Best Sellers 13: Tetris Hits / BSTETRS2.bin / bstetrs2 / dos / mintris / mintris.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-23  |  60.9 KB  |  1,560 lines

  1. /* Mintris.c                                                          */
  2. /* Programmed by Min S. Kwon                                          */
  3. /* March 3, 1996                                                      */
  4.  
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <stdarg.h>
  8. #include <ctype.h>
  9. #include <malloc.h>
  10. #include <dos.h>
  11. #include <conio.h>
  12. #include <math.h>
  13. #include <bios.h>
  14.  
  15. #define BLOCKSIZE 11
  16. #define DIGITOFFSET0 (190 << 8) + (190 << 6) + 280
  17. #define DIGITOFFSET1 (190 << 8) + (190 << 6) + 290
  18. #define DIGITOFFSET2 (190 << 8) + (190 << 6) + 300
  19. #define LEN 165
  20. #define NUMBLOCKS 4
  21. #define BLOCKBUFF 100
  22. #define SCREENWIDTH 320
  23. #define DEAD 0
  24. #define CENTERX 7
  25. #define CENTERY 16
  26. #define TIMER_KEEPER_INT 0x01C     /* Interrupt for internal timer */
  27. #define PALETTE_MASK 0x3c6
  28. #define PALETTE_REGISTER 0x3c8
  29. #define PALETTE_DATA 0x3c9
  30. #define VGA_INPUT_STATUS_1 0x3da
  31. #define VGA_VSYNC_MASK 0x08        /* VGA retrace */
  32.  
  33. typedef struct {                   /* RGB palette type */
  34.    unsigned char red;
  35.    unsigned char green;
  36.    unsigned char blue;
  37. } rgb_color, *rgb_color_ptr;
  38.  
  39. typedef struct {                   /* PCX picture type */
  40.    rgb_color palette[256];
  41.    char far *buffer;
  42. } pcx_picture, *pcx_picture_ptr;
  43.                                    /* Sprite type */
  44. typedef struct {
  45.    int x, y, xold, yold;
  46.    int type, pos, yhigh, xhigh, xlow;
  47.    char far *frame;
  48.    char far *background[10];
  49. } sprite, *sprite_ptr;
  50.                                    /* 2-D represendation of board */
  51. struct {
  52.    int taken;
  53.    int type;
  54. } filled[20][20];
  55.  
  56. void quit_program(char *, ...);
  57. void load_blocks(unsigned char far *[], pcx_picture_ptr);
  58. void fill_board(sprite_ptr);
  59. void pcx_show_buffer(pcx_picture_ptr);
  60. void pcx_init(pcx_picture_ptr);
  61. void refresh_background();
  62. void pcx_load(char *, pcx_picture_ptr, short int);
  63. void pcx_delete(pcx_picture_ptr);
  64. void pcx_grab_bitmap(pcx_picture_ptr, sprite_ptr);
  65. void set_palette_register(int, rgb_color_ptr);
  66. void setmode(int);
  67. void sprite_init(sprite_ptr sprite, int x, int y, int);
  68. void draw_sprite(sprite_ptr sprite);
  69. void behind_sprite(sprite_ptr sprite);
  70. void erase_sprite(sprite_ptr sprite);
  71. void retrace();
  72. void shift_down();
  73. void do_bound(sprite_ptr);
  74. void do_check(sprite_ptr);
  75. void correct();
  76. void save_background();
  77. void move_right(sprite_ptr);
  78. void draw_block(unsigned int, unsigned int, int);
  79. void move_down(sprite_ptr);
  80. void move_left(sprite_ptr);
  81. void rotate_block(sprite_ptr);
  82. void (interrupt far *old_isr)();
  83. void interrupt far timer();
  84. void clear_filled();
  85. void init_downbuff();
  86. void free_memory(sprite_ptr);
  87. void load_number(pcx_picture_ptr);
  88. void display_number(int, int);
  89. void change_bk();
  90. void game_over();
  91. void print_score(int);
  92. void get_palette_register(int, rgb_color_ptr);
  93. void fade_out();
  94. int move_below();
  95. int check_down(sprite_ptr);
  96. int check_left(sprite_ptr);
  97. int check_right(sprite_ptr);
  98. int pos(int, int);
  99. int rotate_correct();
  100.  
  101. unsigned char get_scan_code();
  102. unsigned char far *vga = (char far *) 0xA0000000L;  /* Pointer to VGA RAM */
  103. unsigned char far *blocks[NUMBLOCKS];
  104. unsigned char far *downbuff;
  105. unsigned char far number[11][70];
  106. /* unsigned char far num_back[510]; */
  107. float timed = 0.0, accumulator = 0.05;
  108. int state = 0, minx, miny, maxy, maxx, row = CENTERY, col = CENTERX;
  109. unsigned int lines = 0, amnt, voffset, numlines = 10, bground;
  110. char stacked = 2, rotate, buf[20];
  111. pcx_picture background, block;
  112. sprite square;
  113.  
  114. int main(int argc, char **argv)
  115. {
  116.    old_isr = _dos_getvect(TIMER_KEEPER_INT);    /* Internal timer */
  117.    _dos_setvect(TIMER_KEEPER_INT, timer);
  118.    srand(time(NULL));
  119.    rotate = rand() % 3;
  120.    bground = (rand() % 7) + 1;
  121.    sprintf(buf, "%d.dat", bground++);
  122.    setmode(0x13);
  123.    clear_filled();
  124.    init_downbuff();
  125.    pcx_init(&background);
  126.    pcx_load(buf, (pcx_picture_ptr) &background, 1);
  127.    pcx_show_buffer(&background);
  128.    load_number(&background);
  129.    load_blocks(&blocks, &background);
  130.    save_background();
  131.    pcx_delete(&background);
  132.    print_score(000);
  133.    sprite_init(&square, 77, 13, rand() % 7);
  134.    square.frame = blocks[rotate++];
  135.    behind_sprite(&square);
  136.    draw_sprite(&square);
  137.    while(1) {
  138.       if(state) {
  139.          square.type = rand() % 7;
  140.          square.pos = 0;
  141.          stacked = 2;
  142.          timed = 0.0;
  143.          if(rotate > 3) rotate = 0;
  144.          square.frame = blocks[rotate++];
  145.          behind_sprite(&square);
  146.          draw_sprite(&square);
  147.          state = 0;
  148.          do_check(&square);
  149.       }
  150.       switch(get_scan_code()) {
  151.          case 77: move_right(&square);
  152.                   break;
  153.          case 75: move_left(&square);
  154.                   break;
  155.          case 57: stacked = 0;
  156.                   while(!stacked) {
  157.                      move_down(&square);
  158.                      delay(20);
  159.                   }
  160.                   break;
  161.          case 80: move_down(&square);
  162.                   break;
  163.          case 72: rotate_block(&square);
  164.                   break;
  165.          case 01: game_over();
  166.                   break;
  167.          default: break;
  168.       }
  169.       retrace();
  170.       if(timed >= 1) {
  171.          if(stacked == 2) move_down(&square);
  172.          timed=0.0;
  173.       }
  174.    }
  175.    setmode(0x03);
  176.    return 0;
  177. }
  178.  
  179. void print_score(int num)
  180. {
  181.    char buf[5], one[5], ten[5], hun[5];
  182.    if(num < 10) {
  183.       display_number(0, DIGITOFFSET0);
  184.       display_number(0, DIGITOFFSET1);
  185.       display_number(num, DIGITOFFSET2);
  186.       return;
  187.    }
  188.    sprintf(buf, "%d", num);
  189.    if(num >= 10 && num < 100) {
  190.       sprintf(ten, "%c", buf[0]);
  191.       sprintf(one, "%c", buf[1]);
  192.       display_number(0, DIGITOFFSET0);
  193.       display_number(atoi(ten), DIGITOFFSET1);
  194.       display_number(atoi(one), DIGITOFFSET2);
  195.       return;
  196.    }
  197.    else {
  198.       sprintf(hun, "%c", buf[0]);
  199.       sprintf(ten, "%c", buf[1]);
  200.       sprintf(one, "%c", buf[2]);
  201.       display_number(atoi(hun), DIGITOFFSET0);
  202.       display_number(atoi(ten), DIGITOFFSET1);
  203.       display_number(atoi(one), DIGITOFFSET2);
  204.    }
  205. }
  206.  
  207. void get_palette_register(int index, rgb_color_ptr color)
  208. {
  209.    outp(PALETTE_MASK, 0xff);
  210.    outp(PALETTE_REGISTER, index);
  211.    color->red = inp(PALETTE_DATA);
  212.    color->green = inp(PALETTE_DATA);
  213.    color->blue = inp(PALETTE_DATA);
  214. }
  215.  
  216. void game_over()
  217. {
  218.    int i;
  219.    pcx_picture gameover;
  220.    pcx_init(&gameover);
  221.    fade_out();
  222.    _fmemcpy(vga, 0, 64000);
  223.    pcx_load("over.dat", &gameover, 0);
  224.    pcx_show_buffer(&gameover);
  225.    for(i = 0; i < 256; i++)
  226.       set_palette_register(i, &gameover.palette[i]);
  227.    getch();
  228.    quit_program("Game Over");
  229. }
  230.  
  231. void fade_out()
  232. {
  233.    int loop1, loop2;
  234.    rgb_color color;
  235.    for(loop1=0; loop1<64; loop1++) {
  236.       retrace();
  237.       for(loop2=0; loop2<256; loop2++) {
  238.          get_palette_register(loop2, &color);
  239.          get_palette_register(loop2, &color);
  240.          if (color.red > 0) color.red--;
  241.          if (color.green > 0) color.green--;
  242.          if (color.blue > 0) color.blue--;
  243.          set_palette_register(loop2, &color);
  244.       }
  245.       retrace();
  246.    }
  247. }
  248.  
  249. void display_number(int num, int off)
  250. {
  251.    unsigned noffset = 0, y, x;
  252.    unsigned char data, len;
  253.    for(y = 0; y < 9; y++) {
  254.       for(x = 0; x < 7; x++) {
  255.          if((data=number[num][noffset+x]))
  256.             vga[off+x] = data;
  257.       }
  258.       off += 320;
  259.       noffset += 7;
  260.    }
  261. }
  262.  
  263. /*
  264. void copy_numback()
  265. {
  266.    int i, off = 0;
  267.    for(i = 190; i <= 200; i++) {
  268.       _fmemcpy(&num_back[off], &vga[320*i+270], 50);
  269.       off+=50;
  270.    }
  271. }
  272.  
  273. void replace_numback()
  274. {
  275.    int i, off = 0;
  276.    for(i = 190; i <= 200; i++) {
  277.       _fmemcpy(&vga[320*i+270], &num_back[off], 50);
  278.       off+=50;
  279.    }
  280. }
  281. */
  282. void load_number(pcx_picture_ptr image)
  283. {
  284.    int i, j;
  285.    for(i = 0; i < 9; i++) {
  286.       j = (i << 8) + (i << 6);
  287.       _fmemcpy(&number[0][i*7], &image->buffer[250+j], 7);
  288.       _fmemcpy(&number[1][i*7], &image->buffer[250+j+7], 7);
  289.       _fmemcpy(&number[2][i*7], &image->buffer[250+j+14], 7);
  290.       _fmemcpy(&number[3][i*7], &image->buffer[250+j+21], 7);
  291.       _fmemcpy(&number[4][i*7], &image->buffer[250+j+28], 7);
  292.       _fmemcpy(&number[5][i*7], &image->buffer[250+j+35], 7);
  293.       _fmemcpy(&number[6][i*7], &image->buffer[250+j+42], 7);
  294.       _fmemcpy(&number[7][i*7], &image->buffer[250+j+49], 7);
  295.       _fmemcpy(&number[8][i*7], &image->buffer[250+j+56], 7);
  296.       _fmemcpy(&number[9][i*7], &image->buffer[250+j+63], 7);
  297.    }
  298. }
  299.  
  300. void refresh_background()
  301. {
  302.    _fmemcpy(vga, downbuff, 64000);
  303. }
  304.  
  305. int rotate_correct()
  306. {
  307.    if(rotate > 3) return (rotate-1);
  308.    return rotate;
  309. }
  310.  
  311. void init_downbuff()
  312. {
  313.    if((downbuff = (char far *) _fmalloc(64000)) == NULL)
  314.       quit_program("Insufficient memory");
  315. }
  316.  
  317. void correct() {
  318.    if(minx<0) minx = 0;
  319.    if(maxy<0) maxy = 0;
  320. }
  321.  
  322. int move_below()         /* Any way to speed this up? */
  323. {
  324.    int i, j, k, x, y, taken, takenonce = 0, allclear;
  325.    for(i = 0; i < 18; i++) {    /* Should use While, not much overhead */
  326.       taken = 1;
  327.       for(j = 0; j < 15; j++)
  328.          if(!filled[i][j].taken) {
  329.             taken = 0;
  330.             break;
  331.          }
  332.       if(taken) {
  333.          for(y = 0; y < 5; y++) {
  334.             for(j = i; j < 18; j++) {
  335.                for(k = 0; k < 15; k++) {
  336.                   filled[j][k] = filled[j+1][k];
  337.                   filled[j+1][k].taken = 0;
  338.                }
  339.             }
  340.             if(++lines >= numlines) {
  341.                accumulator += 0.01;
  342.                numlines += 10;
  343.             }
  344.             allclear = 1;
  345.             for(x = 0; x < 15; x++) if(!filled[i][x].taken) allclear = 0;
  346.             if(!allclear) break;
  347.          }
  348.          takenonce = 1;
  349.       }
  350.    }
  351.    return takenonce;
  352. }
  353.  
  354. void shift_down()
  355. {
  356.    int x, y, xoff;
  357.    if(!move_below()) return;
  358.    refresh_background();
  359.    for(y = 0; y < 18; y++)
  360.       for(x = 0, xoff = 0; x < 15; x++, xoff+=11)
  361.          if(filled[y][x].taken) draw_block(200-((y+1)*11),xoff,filled[y][x].type);
  362.    print_score(lines);
  363.    printf("\a\n");
  364. }
  365.  
  366. void draw_block(unsigned int yoffset, unsigned int xoffset, int type)
  367. {
  368.    int i;
  369.    for(i = 0; i < 11; i++)
  370.       _fmemcpy(&vga[(yoffset*320)+xoffset+320*i],&blocks[type][11*i],11);
  371. }
  372.  
  373. void do_check(sprite_ptr sprite)   /* Tedious bit */
  374. {
  375.    switch(sprite->type) {
  376.       case 0: switch(sprite->pos) {
  377.                  case 0: minx = col-1;
  378.                          maxx = col+1;
  379.                          miny = row+1;
  380.                          maxy = row;
  381.                          break;
  382.                  case 1: minx = col;
  383.                          maxx = col+1;
  384.                          miny = row+1;
  385.                          maxy = row-1;
  386.                          break;
  387.                  case 2: minx = col-1;
  388.                          maxx = col+1;
  389.                          miny = row;
  390.                          maxy = row-1;
  391.                          break;
  392.                  case 3: minx = col-1;
  393.                          maxx = col;
  394.                          miny = row+1;
  395.                          maxy = row-1;
  396.                          break;
  397.                }
  398.                break;
  399.        case 1: switch(sprite->pos) {
  400.                   case 0: minx = col-1;
  401.                           maxx = col+2;
  402.                           miny = row;
  403.                           maxy = row;
  404.                           break;
  405.                   case 1: minx = col;
  406.                           maxx = col;
  407.                           miny = row+2;
  408.                           maxy = row-1;
  409.                           break;
  410.                }
  411.                break;
  412.        case 2: switch(sprite->pos) {
  413.                   case 0: minx = col-1;
  414.                           maxx = col+1;
  415.                           miny = row+1;
  416.                           maxy = row;
  417.                           break;
  418.                   case 1: minx = col;
  419.                           maxx = col+1;
  420.                           miny = row+1;
  421.                           maxy = row-1;
  422.                           break;
  423.                   case 2: minx = col-1;
  424.                           maxx = col+1;
  425.                           miny = row;
  426.                           maxy = row-1;
  427.                           break;
  428.                   case 3: minx = col-1;
  429.                           maxx = col;
  430.                           miny = row+1;
  431.                           maxy = row-1;
  432.                           break;
  433.                }
  434.                break;
  435.        case 3: switch(sprite->pos) {
  436.                   case 0: minx = col-1;
  437.                           maxx = col+1;
  438.                           miny = row+1;
  439.                           maxy = row;
  440.                           break;
  441.                   case 1: minx = col;
  442.                           maxx = col+1;
  443.                           miny = row+1;
  444.                           maxy = row-1;
  445.                           break;
  446.                }
  447.                break;
  448.        case 4: switch(sprite->pos) {
  449.                   case 0: minx = col-1;
  450.                           maxx = col+1;
  451.                           miny = row+1;
  452.                           maxy = row;
  453.                           break;
  454.                   case 1: minx = col-1;
  455.                           maxx = col;
  456.                           miny = row+1;
  457.                           maxy = row-1;
  458.                           break;
  459.                }
  460.                break;
  461.        case 5: switch(sprite->pos) {
  462.                   case 0: minx = col-1;
  463.                           maxx = col+1;
  464.                           miny = row+1;
  465.                           maxy = row;
  466.                           break;
  467.                   case 1: minx = col;
  468.                           maxx = col+1;
  469.                           miny = row+1;
  470.                           maxy = row-1;
  471.                           break;
  472.                   case 2: minx = col-1;
  473.                           maxx = col+1;
  474.                           miny = row;
  475.                           maxy = row-1;
  476.                           break;
  477.                   case 3: minx = col-1;
  478.                           maxx = col;
  479.                           miny = row+1;
  480.                           maxy = row-1;
  481.                           break;
  482.                }
  483.                break;
  484.        case 6: minx = col;
  485.                maxx = col+1;
  486.                miny = row+1;
  487.                maxy = row;
  488.                break;
  489.     }
  490.     correct();
  491. }
  492.  
  493. void rotate_block(sprite_ptr sprite)
  494. {
  495.    int old_pos;
  496.    old_pos = sprite->pos;
  497.    switch(sprite->type) {
  498.        case 2:
  499.        case 5:
  500.        case 0: if(++sprite->pos > 3) sprite->pos = 0;
  501.                break;
  502.        case 3:
  503.        case 4:
  504.        case 1: if(++sprite->pos > 1) sprite->pos = 0;
  505.                break;
  506.  
  507.    }
  508.    do_check(sprite);
  509.    do_bound(sprite);
  510.    if((sprite->xlow < 0)||(sprite->xhigh > 155)||
  511.       (sprite->yhigh > 198)||filled[row][minx].taken||filled[row][maxx].taken||
  512.       filled[miny][minx].taken||filled[miny][maxx].taken||filled[maxy][minx].taken||
  513.       filled[maxy][maxx].taken||filled[row][col].taken||filled[miny][col].taken||
  514.       filled[maxy][col].taken) {
  515.       sprite->pos = old_pos;
  516.       return;
  517.    }
  518.    erase_sprite(sprite);
  519.    behind_sprite(sprite);
  520.    draw_sprite(sprite);
  521. }
  522.  
  523.  
  524. void interrupt far timer()
  525. {
  526.    timed = timed + accumulator;
  527. }
  528.  
  529. void clear_filled()
  530. {
  531.    int i, j;
  532.    for(i = 0; i < 20; i++)
  533.       for(j = 0; j < 20; j++) {
  534.          filled[i][j].taken = 0;
  535.          filled[i][j].type = 0;
  536.       }
  537. }
  538.  
  539. void move_left(sprite_ptr sprite)
  540. {
  541.    int old;
  542.    do_bound(sprite);
  543.    if(check_left(sprite)) return;
  544.    if(sprite->xlow < 8) return;
  545.    col--;
  546.    do_check(sprite);
  547.    erase_sprite(sprite);
  548.    sprite->x-=11;
  549.    behind_sprite(sprite);
  550.    draw_sprite(sprite);
  551. }
  552.  
  553. void move_right(sprite_ptr sprite)
  554. {
  555.    do_bound(sprite);
  556.    if(check_right(sprite)) return;
  557.    if(sprite->xhigh > 153) return;
  558.    erase_sprite(sprite);
  559.    col++;
  560.    do_check(sprite);
  561.    sprite->x+=11;
  562.    behind_sprite(sprite);
  563.    draw_sprite(sprite);
  564. }
  565.  
  566. int pos(int a, int b)
  567. {
  568.    if((a - b) < 0)
  569.       return 0;
  570.    else return(a-b);
  571. }
  572.  
  573. int check_right(sprite_ptr sprite)
  574. {
  575.    switch(sprite->type) {
  576.       case 0: switch(sprite->pos) {
  577.                  case 0: if(filled[miny][col+1].taken||filled[row][maxx+1].taken) return 1;
  578.                          break;
  579.                  case 1: if(filled[miny][col+1].taken||filled[maxy][col+1].taken||filled[row][maxx+1].taken) return 1;
  580.                          break;
  581.                  case 2: if(filled[row][maxx+1].taken||filled[maxy][col+1].taken) return 1;
  582.                          break;
  583.                  case 3: if(filled[miny][col+1].taken||filled[row][col+1].taken||filled[maxy][col+1].taken) return 1;
  584.                          break;
  585.               }
  586.               break;
  587.       case 1: switch(sprite->pos) {
  588.                  case 0: if(filled[row][maxx+1].taken) return 1;
  589.                          break;
  590.                  case 1: if(filled[maxy][col+1].taken||filled[row][col+1].taken||filled[miny-1][col+1].taken||filled[miny][col+1].taken) return 1;
  591.                          break;
  592.               }
  593.               break;
  594.       case 2: switch(sprite->pos) {
  595.                  case 0: if(filled[row][maxx+1].taken||filled[miny][minx+1].taken) return 1;
  596.                          break;
  597.                  case 1: if(filled[row][col+1].taken||filled[maxy][col+1].taken||filled[miny][maxx+1].taken) return 1;
  598.                          break;
  599.                  case 2: if(filled[row][maxx+1].taken||filled[maxy][maxx+1].taken) return 1;
  600.                          break;
  601.                  case 3: if(filled[row][col+1].taken||filled[maxy][col+1].taken||filled[miny][col+1].taken) return 1;
  602.                          break;
  603.               }
  604.               break;
  605.       case 3: switch(sprite->pos) {
  606.                  case 0: if(filled[miny][col+1].taken||filled[row][maxx+1].taken) return 1;
  607.                          break;
  608.                  case 1: if(filled[miny][maxx+1].taken||filled[row][maxx+1].taken||filled[maxy][col+1].taken) return 1;
  609.                          break;
  610.               }
  611.               break;
  612.       case 4: switch(sprite->pos) {
  613.                  case 0: if(filled[miny][maxx+1].taken||filled[row][col+1].taken) return 1;
  614.                          break;
  615.                  case 1: if(filled[row][col+1].taken||filled[miny][minx+1].taken||filled[maxy][col+1].taken) return 1;
  616.                          break;
  617.               }
  618.               break;
  619.       case 5: switch(sprite->pos) {
  620.                  case 0: if(filled[row][maxx+1].taken||filled[miny][maxx+1].taken) return 1;
  621.                          break;
  622.                  case 1: if(filled[row][col+1].taken||filled[miny][col+1].taken||filled[maxy][maxx+1].taken) return 1;
  623.                          break;
  624.                  case 2: if(filled[row][maxx+1].taken||filled[maxy][minx+1].taken) return 1;
  625.                          break;
  626.                  case 3: if(filled[row][col+1].taken||filled[miny][col+1].taken||filled[maxy][col+1].taken) return 1;
  627.                          break;
  628.               }
  629.               break;
  630.       case 6: if(filled[miny][maxx+1].taken||filled[row][maxx+1].taken) return 1;
  631.               break;
  632.    }
  633.  
  634.    return 0;
  635. }
  636. int check_left(sprite_ptr sprite)
  637. {
  638.    switch(sprite->type) {
  639.       case 0: switch(sprite->pos) {
  640.                  case 0: if(filled[row][minx-1].taken||filled[miny][col-1].taken) return 1;
  641.                          break;
  642.                  case 1: if(filled[miny][col-1].taken||filled[row][col-1].taken||filled[maxy][col-1].taken) return 1;
  643.                          break;
  644.                  case 2: if(filled[row][minx-1].taken||filled[maxy][col-1].taken) return 1;
  645.                          break;
  646.                  case 3: if(filled[row][minx-1].taken||filled[miny][col-1].taken||filled[maxy][col-1].taken) return 1;
  647.                          break;
  648.               }
  649.               break;
  650.       case 1: switch(sprite->pos) {
  651.                  case 0: if(filled[row][minx-1].taken) return 1;
  652.                          break;
  653.                  case 1: if(filled[maxy][col-1].taken||filled[row][col-1].taken||filled[miny-1][col-1].taken||filled[miny][col-1].taken) return 1;
  654.                          break;
  655.               }
  656.               break;
  657.       case 2: switch(sprite->pos) {
  658.                  case 0: if(filled[row][minx-1].taken||filled[miny][minx-1].taken) return 1;
  659.                          break;
  660.                  case 1: if(filled[miny][col-1].taken||filled[row][col-1].taken||filled[maxy][col-1].taken) return 1;
  661.                          break;
  662.                  case 2: if(filled[row][minx-1].taken||filled[maxy][maxx-1].taken) return 1;
  663.                          break;
  664.                  case 3: if(filled[miny][col-1].taken||filled[row][col-1].taken||filled[maxy][minx-1].taken) return 1;
  665.                          break;
  666.               }
  667.               break;
  668.       case 3: switch(sprite->pos) {
  669.                  case 0: if(filled[miny][minx-1].taken||filled[row][col-1].taken) return 1;
  670.                          break;
  671.                  case 1: if(filled[row][col-1].taken||filled[miny][maxx-1].taken||filled[maxy][col-1].taken) return 1;
  672.                          break;
  673.               }
  674.               break;
  675.       case 4: switch(sprite->pos) {
  676.                  case 0: if(filled[miny][col-1].taken||filled[row][minx-1].taken) return 1;
  677.                          break;
  678.                  case 1: if(filled[row][minx-1].taken||filled[miny][minx-1].taken||filled[maxy][col-1].taken) return 1;
  679.                          break;
  680.               }
  681.               break;
  682.       case 5: switch(sprite->pos) {
  683.                  case 0: if(filled[row][minx-1].taken||filled[miny][maxx-1].taken) return 1;
  684.                          break;
  685.                  case 1: if(filled[row][col-1].taken||filled[miny][col-1].taken||filled[maxy][col-1].taken) return 1;
  686.                          break;
  687.                  case 2: if(filled[row][minx-1].taken||filled[maxy][minx-1].taken) return 1;
  688.                          break;
  689.                  case 3: if(filled[miny][minx-1].taken||filled[row][col-1].taken||filled[maxy][col-1].taken) return 1;
  690.                          break;
  691.               }
  692.               break;
  693.       case 6: if(filled[row][col-1].taken||filled[miny][col-1].taken) return 1;
  694.               break;
  695.    }
  696.    return 0;
  697. }
  698.  
  699. int check_down(sprite_ptr sprite)
  700. {
  701.    int i;
  702.    switch(sprite->type) {
  703.       case 0: switch(sprite->pos) {
  704.                  case 0: i = pos(row, 1);
  705.                          if(filled[i][minx].taken||filled[i][maxx].taken||filled[i][col].taken)
  706.                             return 1;
  707.                          break;
  708.                  case 1: if(filled[pos(maxy,1)][col].taken||filled[pos(row,1)][maxx].taken) return 1;
  709.                          break;
  710.                  case 2: i = pos(row, 1);
  711.                          if(filled[i][minx].taken||filled[i][maxx].taken||filled[pos(maxy,1)][col].taken) return 1;
  712.                          break;
  713.                  case 3: if(filled[pos(maxy,1)][col].taken||filled[pos(row,1)][minx].taken) return 1;
  714.                          break;
  715.               }
  716.               break;
  717.       case 1: switch(sprite->pos) {
  718.                  case 0: i = pos(row, 1);
  719.                          if(filled[i][minx].taken||filled[i][col].taken||filled[i][col+1].taken||filled[i][maxx].taken) return 1;
  720.                          break;
  721.                  case 1: if(filled[pos(maxy,1)][col].taken) return 1;
  722.                          break;
  723.               }
  724.               break;
  725.       case 2: switch(sprite->pos) {
  726.                  case 0: i = pos(row, 1);
  727.                          if(filled[i][minx].taken||filled[i][maxx].taken||filled[i][col].taken) return 1;
  728.                          break;
  729.                  case 1: if(filled[pos(maxy,1)][col].taken||filled[pos(miny,1)][maxx].taken) return 1;
  730.                          break;
  731.                  case 2: i = pos(row, 1);
  732.                          if(filled[i][minx].taken||filled[i][col].taken||filled[pos(maxy,1)][maxx].taken) return 1;
  733.                          break;
  734.                  case 3: i = pos(maxy, 1);
  735.                          if(filled[i][minx].taken||filled[i][col].taken) return 1;
  736.                          break;
  737.               }
  738.               break;
  739.       case 3: switch(sprite->pos) {
  740.                  case 0: i = pos(row, 1);
  741.                          if(filled[i][col].taken||filled[i][maxx].taken||filled[miny][minx].taken) return 1;
  742.                          break;
  743.                  case 1: if(filled[pos(row,1)][maxx].taken||filled[pos(maxy,1)][col].taken) return 1;
  744.                          break;
  745.               }
  746.               break;
  747.       case 4: switch(sprite->pos) {
  748.                  case 0: i = pos(row, 1);
  749.                          if(filled[i][col].taken||filled[i][minx].taken||filled[miny][maxx].taken) return 1;
  750.                          break;
  751.                  case 1: if(filled[pos(row,1)][minx].taken||filled[pos(maxy,1)][col].taken) return 1;
  752.                          break;
  753.               }
  754.               break;
  755.       case 5: switch(sprite->pos) {
  756.                  case 0: i = pos(row, 1);
  757.                          if(filled[i][minx].taken||filled[i][col].taken||filled[i][maxx].taken) return 1;
  758.                          break;
  759.                  case 1: i = pos(maxy, 1);
  760.                          if(filled[i][col].taken||filled[i][maxx].taken) return 1;
  761.                          break;
  762.                  case 2: i = pos(row, 1);
  763.                          if(filled[i][col].taken||filled[i][maxx].taken||filled[pos(maxy,1)][minx].taken) return 1;
  764.                          break;
  765.                  case 3: if(filled[pos(miny,1)][minx].taken||filled[pos(maxy,1)][col].taken) return 1;
  766.                          break;
  767.               }
  768.               break;
  769.       case 6: i = pos(row, 1);
  770.               if(filled[i][col].taken||filled[i][maxx].taken) return 1;
  771.               break;
  772.    }
  773.    return 0;
  774. }
  775.  
  776. void fill_board(sprite_ptr sprite)
  777. {
  778.    int corrected;
  779.    corrected = rotate_correct();
  780.    switch(sprite->type) {
  781.       case 0: switch(sprite->pos) {
  782.                  case 0: filled[row][minx].taken = 1;
  783.                          filled[row][maxx].taken = 1;
  784.                          filled[row][col].taken = 1;
  785.                          filled[miny][col].taken = 1;
  786.                          filled[row][minx].type = corrected;
  787.                          filled[row][maxx].type = corrected;
  788.                          filled[row][col].type = corrected;
  789.                          filled[miny][col].type = corrected;
  790.                          break;
  791.                  case 1: filled[maxy][col].taken = 1;
  792.                          filled[row][maxx].taken = 1;
  793.                          filled[row][col].taken = 1;
  794.                          filled[miny][col].taken = 1;
  795.                          filled[maxy][col].type = corrected;
  796.                          filled[row][maxx].type = corrected;
  797.                          filled[row][col].type = corrected;
  798.                          filled[miny][col].type = corrected;
  799.                          break;
  800.                  case 2: filled[row][col].taken = 1;
  801.                          filled[maxy][col].taken = 1;
  802.                          filled[row][minx].taken = 1;
  803.                          filled[row][maxx].taken = 1;
  804.                          filled[row][col].type = corrected;
  805.                          filled[maxy][col].type = corrected;
  806.                          filled[row][minx].type = corrected;
  807.                          filled[row][maxx].type = corrected;
  808.                          break;
  809.                  case 3: filled[row][col].taken = 1;
  810.                          filled[row][minx].taken = 1;
  811.                          filled[maxy][col].taken = 1;
  812.                          filled[miny][col].taken = 1;
  813.                          filled[row][col].type = corrected;
  814.                          filled[row][minx].type = corrected;
  815.                          filled[maxy][col].type = corrected;
  816.                          filled[miny][col].type = corrected;
  817.                          break;
  818.               }
  819.               break;
  820.       case 1: switch(sprite->pos) {
  821.                  case 0: filled[row][col].taken = 1;
  822.                          filled[row][minx].taken = 1;
  823.                          filled[row][maxx-1].taken = 1;
  824.                          filled[row][maxx].taken = 1;
  825.                          filled[row][col].type = corrected;
  826.                          filled[row][minx].type = corrected;
  827.                          filled[row][maxx-1].type = corrected;
  828.                          filled[row][maxx].type = corrected;
  829.                          break;
  830.                  case 1: filled[row][col].taken = 1;
  831.                          filled[maxy][col].taken = 1;
  832.                          filled[miny-1][col].taken = 1;
  833.                          filled[miny][col].taken = 1;
  834.                          filled[row][col].type = corrected;
  835.                          filled[maxy][col].type = corrected;
  836.                          filled[miny-1][col].type = corrected;
  837.                          filled[miny][col].type = corrected;
  838.                          break;
  839.               }
  840.               break;
  841.       case 2: switch(sprite->pos) {
  842.                  case 0: filled[row][minx].taken = 1;
  843.                          filled[row][col].taken = 1;
  844.                          filled[row][maxx].taken = 1;
  845.                          filled[miny][minx].taken = 1;
  846.                          filled[row][minx].type = corrected;
  847.                          filled[row][col].type = corrected;
  848.                          filled[row][maxx].type = corrected;
  849.                          filled[miny][minx].type = corrected;
  850.                          break;
  851.                  case 1: filled[row][col].taken = 1;
  852.                          filled[maxy][col].taken = 1;
  853.                          filled[miny][col].taken = 1;
  854.                          filled[miny][maxx].taken = 1;
  855.                          filled[row][col].type = corrected;
  856.                          filled[maxy][col].type = corrected;
  857.                          filled[miny][col].type = corrected;
  858.                          filled[miny][maxx].type = corrected;
  859.                          break;
  860.                  case 2: filled[row][col].taken = 1;
  861.                          filled[row][minx].taken = 1;
  862.                          filled[row][maxx].taken = 1;
  863.                          filled[maxy][maxx].taken = 1;
  864.                          filled[row][col].type = corrected;
  865.                          filled[row][minx].type = corrected;
  866.                          filled[row][maxx].type = corrected;
  867.                          filled[maxy][maxx].type = corrected;
  868.                          break;
  869.                  case 3: filled[row][col].taken = 1;
  870.                          filled[miny][col].taken = 1;
  871.                          filled[maxy][col].taken = 1;
  872.                          filled[maxy][minx].taken = 1;
  873.                          filled[row][col].type = corrected;
  874.                          filled[miny][col].type = corrected;
  875.                          filled[maxy][col].type = corrected;
  876.                          filled[maxy][minx].type = corrected;
  877.                          break;
  878.               }
  879.               break;
  880.       case 3: switch(sprite->pos) {
  881.                  case 0: filled[row][col].taken = 1;
  882.                          filled[row][maxx].taken = 1;
  883.                          filled[miny][col].taken = 1;
  884.                          filled[miny][minx].taken = 1;
  885.                          filled[row][col].type = corrected;
  886.                          filled[row][maxx].type = corrected;
  887.                          filled[miny][col].taken = corrected;
  888.                          filled[miny][minx].taken = corrected;
  889.                          break;
  890.                  case 1: filled[row][col].taken = 1;
  891.                          filled[row][maxx].taken = 1;
  892.                          filled[miny][maxx].taken = 1;
  893.                          filled[maxy][col].taken = 1;
  894.                          filled[row][col].type = corrected;
  895.                          filled[row][maxx].type = corrected;
  896.                          filled[miny][maxx].type = corrected;
  897.                          filled[maxy][col].type = corrected;
  898.                          break;
  899.               }
  900.               break;
  901.       case 4: switch(sprite->pos) {
  902.                  case 0: filled[row][col].taken = 1;
  903.                          filled[row][minx].taken = 1;
  904.                          filled[miny][col].taken = 1;
  905.                          filled[miny][maxx].taken = 1;
  906.                          filled[row][col].type = corrected;
  907.                          filled[row][minx].type = corrected;
  908.                          filled[miny][col].type = corrected;
  909.                          filled[miny][maxx].type = corrected;
  910.                          break;
  911.                  case 1: filled[row][col].taken = 1;
  912.                          filled[row][minx].taken = 1;
  913.                          filled[miny][minx].taken = 1;
  914.                          filled[maxy][col].taken = 1;
  915.                          filled[row][col].type = corrected;
  916.                          filled[row][minx].type = corrected;
  917.                          filled[miny][minx].type = corrected;
  918.                          filled[maxy][col].type = corrected;
  919.                          break;
  920.               }
  921.               break;
  922.       case 5: switch(sprite->pos) {
  923.                  case 0: filled[row][col].taken = 1;
  924.                          filled[row][minx].taken = 1;
  925.                          filled[row][maxx].taken = 1;
  926.                          filled[miny][maxx].taken = 1;
  927.                          filled[row][col].type = corrected;
  928.                          filled[row][minx].type = corrected;
  929.                          filled[row][maxx].type = corrected;
  930.                          filled[miny][maxx].type = corrected;
  931.                          break;
  932.                  case 1: filled[row][col].taken = 1;
  933.                          filled[miny][col].taken = 1;
  934.                          filled[maxy][col].taken = 1;
  935.                          filled[maxy][maxx].taken = 1;
  936.                          filled[row][col].type = corrected;
  937.                          filled[miny][col].type = corrected;
  938.                          filled[maxy][col].type = corrected;
  939.                          filled[maxy][maxx].type = corrected;
  940.                          break;
  941.                  case 2: filled[row][col].taken = 1;
  942.                          filled[row][minx].taken = 1;
  943.                          filled[row][maxx].taken = 1;
  944.                          filled[maxy][minx].taken = 1;
  945.                          filled[row][col].type = corrected;
  946.                          filled[row][minx].type = corrected;
  947.                          filled[row][maxx].type = corrected;
  948.                          filled[maxy][minx].type = corrected;
  949.                          break;
  950.                  case 3: filled[row][col].taken = 1;
  951.                          filled[miny][col].taken = 1;
  952.                          filled[miny][minx].taken = 1;
  953.                          filled[maxy][col].taken = 1;
  954.                          filled[row][col].type = corrected;
  955.                          filled[miny][col].type = corrected;
  956.                          filled[miny][minx].type = corrected;
  957.                          filled[maxy][col].type = corrected;
  958.                          break;
  959.               }
  960.               break;
  961.       case 6: filled[row][col].taken = 1;
  962.               filled[row][maxx].taken = 1;
  963.               filled[miny][col].taken = 1;
  964.               filled[miny][maxx].taken = 1;
  965.               filled[row][col].type = corrected;
  966.               filled[row][maxx].type = corrected;
  967.               filled[miny][col].type = corrected;
  968.               filled[miny][maxx].type = corrected;
  969.               break;
  970.    }
  971. }
  972.  
  973. void move_down(sprite_ptr sprite)
  974. {
  975.    int i;
  976.    do_bound(sprite);
  977.    do_check(sprite);
  978.    if(check_down(sprite)) {
  979.       fill_board(sprite);
  980.       state = 1;
  981.       sprite->y = 13;
  982.       sprite->x = 77;
  983.       col = CENTERX;
  984.       row = CENTERY;
  985.       shift_down();
  986.       stacked = 1;
  987.       for(i = 0; i < 15; i++) if(filled[17][i].taken) game_over();
  988.       return;
  989.    }
  990.    if(sprite->yhigh >= 187) {
  991.       fill_board(sprite);
  992.       state = 1;
  993.       sprite->y = 13;
  994.       sprite->x = 77;
  995.       col = CENTERX;
  996.       row = CENTERY;
  997.       shift_down();
  998.       stacked = 1;
  999.       return;
  1000.    }
  1001.    row--;
  1002.    do_check(sprite);
  1003.    erase_sprite(sprite);
  1004.    sprite->y+=11;
  1005.    behind_sprite(sprite);
  1006.    draw_sprite(sprite);
  1007. }
  1008.  
  1009. void load_blocks(unsigned char far *block[], pcx_picture_ptr image)
  1010. {
  1011.    int i, j;
  1012.    for(i = 0; i < NUMBLOCKS; i++) {
  1013.       block[i] = (char far *) _fmalloc(125);
  1014.       if(block[i] == NULL) quit_program("Insufficient memory");
  1015.    }
  1016.    for(i = 0; i < 11; i++) {
  1017.       j = (i << 8) + (i << 6);
  1018.       _fmemcpy(&block[0][i*11], &image->buffer[j], 11);
  1019.       _fmemcpy(&block[1][i*11], &image->buffer[j+11], 11);
  1020.       _fmemcpy(&block[2][i*11], &image->buffer[j+22], 11);
  1021.       _fmemcpy(&block[3][i*11], &image->buffer[j+33], 11);
  1022.    }
  1023. }
  1024.  
  1025. void save_background()
  1026. {
  1027.    _fmemcpy(downbuff, vga, 64000);
  1028. }
  1029.  
  1030. unsigned char get_scan_code()
  1031. {
  1032.    asm {
  1033.       mov ah,0x01
  1034.       int 0x16
  1035.       jz empty
  1036.       mov ah,0x00
  1037.       int 0x16
  1038.       mov al,ah
  1039.       xor ah,ah
  1040.       jmp done
  1041.    }
  1042.    empty: asm xor ax, ax
  1043.    done: /* none */
  1044. }
  1045.  
  1046. void behind_sprite(sprite_ptr sprite)
  1047. {
  1048.    unsigned int y, i, j, k, l;
  1049.    for(y = 0; y < 11; y++)
  1050.       _fmemcpy(&sprite->background[0][y*11], &vga[((y+sprite->y)<<8)+((y+sprite->y)<<6)+sprite->x], 11);
  1051.    switch(sprite->type) {
  1052.       case 0: for(y = 0; y < 11; y++) {
  1053.                  i = ((y + sprite->y) << 8) + ((y + sprite->y) << 6) + sprite->x;
  1054.                  j = y*11;
  1055.                  _fmemcpy(&sprite->background[1][j],&vga[i-11],11);
  1056.                  _fmemcpy(&sprite->background[2][j],&vga[i+11],11);
  1057.                  _fmemcpy(&sprite->background[3][j],&vga[((y+sprite->y-11)<<8)+((y+sprite->y-11)<<6)+sprite->x],11);
  1058.                  _fmemcpy(&sprite->background[4][j],&vga[((y+sprite->y+11)<<8)+((y+sprite->y+11)<<6)+sprite->x],11);
  1059.               }
  1060.               break;
  1061.       case 1: for(y = 0; y < 11; y++) {
  1062.                  i = ((y + sprite->y) << 8) + ((y + sprite->y) << 6) + sprite->x;
  1063.                  j = y*11;
  1064.                  _fmemcpy(&sprite->background[1][j],&vga[i-11],11);
  1065.                  _fmemcpy(&sprite->background[2][j],&vga[i+11],11);
  1066.                  _fmemcpy(&sprite->background[3][j],&vga[i+22],11);
  1067.                  _fmemcpy(&sprite->background[4][j],&vga[((y+sprite->y+11)<<8)+((y+sprite->y+11)<<6)+sprite->x],11);
  1068.                  _fmemcpy(&sprite->background[5][j],&vga[((y+sprite->y-11)<<8)+((y+sprite->y-11)<<6)+sprite->x],11);
  1069.                  _fmemcpy(&sprite->background[6][j],&vga[((y+sprite->y-22)<<8)+((y+sprite->y-22)<<6)+sprite->x],11);
  1070.               }
  1071.               break;
  1072.       case 5:
  1073.       case 2: for(y = 0; y < 11; y++) {
  1074.                  i = ((y + sprite->y)<<8)+((y+sprite->y)<<6)+sprite->x;
  1075.                  k = ((y + sprite->y + 11)<<8)+((y+sprite->y+11)<<6)+sprite->x;
  1076.                  l = ((y + sprite->y - 11)<<8)+((y+sprite->y-11)<<6)+sprite->x;
  1077.                  j = y * 11;
  1078.                  _fmemcpy(&sprite->background[1][j],&vga[i-11],11);
  1079.                  _fmemcpy(&sprite->background[2][j],&vga[i+11],11);
  1080.                  _fmemcpy(&sprite->background[3][j],&vga[k],11);
  1081.                  _fmemcpy(&sprite->background[4][j],&vga[k-11],11);
  1082.                  _fmemcpy(&sprite->background[5][j],&vga[k+11],11);
  1083.                  _fmemcpy(&sprite->background[6][j],&vga[l],11);
  1084.                  _fmemcpy(&sprite->background[7][j],&vga[l-11],11);
  1085.                  _fmemcpy(&sprite->background[8][j],&vga[l+11],11);
  1086.               }
  1087.               break;
  1088.       case 3: for(y = 0; y < 11; y++) {
  1089.                  k=((y+sprite->y-11)<<8)+((y+sprite->y-11)<<6)+sprite->x;
  1090.                  j = y * 11;
  1091.                  _fmemcpy(&sprite->background[1][j],&vga[((y+sprite->y)<<8)+((y+sprite->y)<<6)+sprite->x+11],11);
  1092.                  _fmemcpy(&sprite->background[2][j],&vga[((y+sprite->y+11)<<8)+((y+sprite->y+11)<<6)+sprite->x],11);
  1093.                  _fmemcpy(&sprite->background[3][j],&vga[k],11);
  1094.                  _fmemcpy(&sprite->background[4][j],&vga[k-11],11);
  1095.                  _fmemcpy(&sprite->background[5][j],&vga[k+11],11);
  1096.               }
  1097.               break;
  1098.       case 4: for(y = 0; y < 11; y++) {
  1099.                  k=((y+sprite->y-11)<<8)+((y+sprite->y-11)<<6)+sprite->x;
  1100.                  j=y*11;
  1101.                  _fmemcpy(&sprite->background[1][j],&vga[((y+sprite->y)<<8)+((y+sprite->y)<<6)+sprite->x-11],11);
  1102.                  _fmemcpy(&sprite->background[2][j],&vga[((y+sprite->y+11)<<8)+((y+sprite->y+11)<<6)+sprite->x],11);
  1103.                  _fmemcpy(&sprite->background[3][j],&vga[k],11);
  1104.                  _fmemcpy(&sprite->background[4][j],&vga[k-11],11);
  1105.                  _fmemcpy(&sprite->background[5][j],&vga[k+11],11);
  1106.               }
  1107.               break;
  1108.       case 6: for(y = 0; y < 11; y++) {
  1109.                  k=((y+sprite->y-11)<<8)+((y+sprite->y-11)<<6)+sprite->x;
  1110.                  j = y * 11;
  1111.                  _fmemcpy(&sprite->background[1][j],&vga[((y + sprite->y)<<8)+((y+sprite->y)<<6)+sprite->x+11],11);
  1112.                  _fmemcpy(&sprite->background[2][j],&vga[k],11);
  1113.                  _fmemcpy(&sprite->background[3][j],&vga[k+11],11);
  1114.               }
  1115.               break;
  1116.    }
  1117. }
  1118.  
  1119. void erase_sprite(sprite_ptr sprite)
  1120. {
  1121.    unsigned int y, i, x, k, l;
  1122.    for(y = 0; y < 11; y++) {
  1123.       i = y * 11;
  1124.       x = ( ((y+sprite->y) << 8) + ((y+sprite->y)<<6)) + sprite->x;
  1125.       switch(sprite->type) {
  1126.          case 0: _fmemcpy(&vga[x], &sprite->background[0][i], 11);
  1127.                  _fmemcpy(&vga[x-11],&sprite->background[1][i],11);
  1128.                  _fmemcpy(&vga[x+11],&sprite->background[2][i],11);
  1129.                  _fmemcpy(&vga[((y+sprite->y-11)<<8)+((y+sprite->y-11)<<6)+sprite->x],&sprite->background[3][i],11);
  1130.                  _fmemcpy(&vga[((y+sprite->y+11)<<8)+((y+sprite->y+11)<<6)+sprite->x],&sprite->background[4][i],11);
  1131.                  break;
  1132.          case 1: _fmemcpy(&vga[x],&sprite->background[0][i],11);
  1133.                  _fmemcpy(&vga[x-11],&sprite->background[1][i],11);
  1134.                  _fmemcpy(&vga[x+11],&sprite->background[2][i],11);
  1135.                  _fmemcpy(&vga[x+22],&sprite->background[3][i],11);
  1136.                  _fmemcpy(&vga[((y+sprite->y+11)<<8)+((y+sprite->y+11)<<6)+sprite->x],&sprite->background[4][i],11);
  1137.                  _fmemcpy(&vga[((y+sprite->y-11)<<8)+((y+sprite->y-11)<<6)+sprite->x],&sprite->background[5][i],11);
  1138.                  _fmemcpy(&vga[((y+sprite->y-22)<<8)+((y+sprite->y-22)<<6)+sprite->x],&sprite->background[6][i],11);
  1139.                  break;
  1140.          case 5:
  1141.          case 2: k = ((y+sprite->y+11)<<8)+((y+sprite->y+11)<<6)+sprite->x;
  1142.                  l = ((y+sprite->y-11)<<8)+((y+sprite->y-11)<<6)+sprite->x;
  1143.                  _fmemcpy(&vga[x],&sprite->background[0][i],11);
  1144.                  _fmemcpy(&vga[x-11],&sprite->background[1][i],11);
  1145.                  _fmemcpy(&vga[x+11],&sprite->background[2][i],11);
  1146.                  _fmemcpy(&vga[k],&sprite->background[3][i],11);
  1147.                  _fmemcpy(&vga[k-11],&sprite->background[4][i],11);
  1148.                  _fmemcpy(&vga[k+11],&sprite->background[5][i],11);
  1149.                  _fmemcpy(&vga[l],&sprite->background[6][i],11);
  1150.                  _fmemcpy(&vga[l-11],&sprite->background[7][i],11);
  1151.                  _fmemcpy(&vga[l+11],&sprite->background[8][i],11);
  1152.                  break;
  1153.          case 3: k = ((y+sprite->y-11)<<8)+((y+sprite->y-11)<<6)+sprite->x;
  1154.                  _fmemcpy(&vga[x],&sprite->background[0][i],11);
  1155.                  _fmemcpy(&vga[x+11],&sprite->background[1][i],11);
  1156.                  _fmemcpy(&vga[((y+sprite->y+11)<<8)+((y+sprite->y+11)<<6)+sprite->x],&sprite->background[2][i],11);
  1157.                  _fmemcpy(&vga[k],&sprite->background[3][i],11);
  1158.                  _fmemcpy(&vga[k-11],&sprite->background[4][i],11);
  1159.                  _fmemcpy(&vga[k+11],&sprite->background[5][i],11);
  1160.                  break;
  1161.          case 4: k = ((y+sprite->y-11)<<8)+((y+sprite->y-11)<<6)+sprite->x;
  1162.                  _fmemcpy(&vga[x],&sprite->background[0][i],11);
  1163.                  _fmemcpy(&vga[x-11],&sprite->background[1][i],11);
  1164.                  _fmemcpy(&vga[((y+sprite->y+11)<<8)+((y+sprite->y+11)<<6)+sprite->x],&sprite->background[2][i],11);
  1165.                  _fmemcpy(&vga[k],&sprite->background[3][i],11);
  1166.                  _fmemcpy(&vga[k-11],&sprite->background[4][i],11);
  1167.                  _fmemcpy(&vga[k+11],&sprite->background[5][i],11);
  1168.                  break;
  1169.          case 6: k = ((y+sprite->y-11)<<8)+((y+sprite->y-11)<<6)+sprite->x;
  1170.                  _fmemcpy(&vga[x],&sprite->background[0][i],11);
  1171.                  _fmemcpy(&vga[x+11],&sprite->background[1][i],11);
  1172.                  _fmemcpy(&vga[k],&sprite->background[2][i],11);
  1173.                  _fmemcpy(&vga[k+11],&sprite->background[3][i],11);
  1174.                  break;
  1175.       }
  1176.  
  1177.    }
  1178. }
  1179.  
  1180. void retrace()
  1181. {
  1182.    while(inp(VGA_INPUT_STATUS_1) & VGA_VSYNC_MASK) { /* Nothing */   }
  1183.    while(!(inp(VGA_INPUT_STATUS_1) & VGA_VSYNC_MASK)) { /* Nothing */  }
  1184. /*
  1185.   _DX = 0x03DA;
  1186.   l1: asm {
  1187.   in  al,dx;
  1188.   and al,0x08;
  1189.   jnz l1;
  1190.   }
  1191.   l2: asm {
  1192.   in  al,dx;
  1193.   and al,0x08;
  1194.   jz  l2;
  1195.   }
  1196.  */
  1197. }
  1198.  
  1199. void do_bound(sprite_ptr sprite)
  1200. {
  1201.    switch(sprite->type) {
  1202.       case 0: switch(sprite->pos) {
  1203.                  case 0: sprite->yhigh = sprite->y;
  1204.                          sprite->xhigh = sprite->x+11;
  1205.                          sprite->xlow = sprite->x-11;
  1206.                          break;
  1207.                  case 3: sprite->yhigh = sprite->y+11;
  1208.                          sprite->xhigh = sprite->x;
  1209.                          sprite->xlow = sprite->x-11;
  1210.                          break;
  1211.                  case 1: sprite->yhigh = sprite->y+11;
  1212.                          sprite->xhigh = sprite->x+11;
  1213.                          sprite->xlow = sprite->x;
  1214.                          break;
  1215.                  case 2: sprite->yhigh = sprite->y+11;
  1216.                          sprite->xhigh = sprite->x+11;
  1217.                          sprite->xlow = sprite->x-11;
  1218.                          break;
  1219.               }
  1220.               break;
  1221.       case 1: switch(sprite->pos) {
  1222.                  case 0: sprite->yhigh = sprite->y;
  1223.                          sprite->xhigh = sprite->x+22;
  1224.                          sprite->xlow = sprite->x-11;
  1225.                          break;
  1226.                  case 1: sprite->yhigh = sprite->y+11;
  1227.                          sprite->xhigh = sprite->x;
  1228.                          sprite->xlow = sprite->x;
  1229.                          break;
  1230.               }
  1231.               break;
  1232.       case 5:
  1233.       case 2: switch(sprite->pos) {
  1234.                  case 0: sprite->yhigh = sprite->y;
  1235.                          sprite->xhigh = sprite->x+11;
  1236.                          sprite->xlow = sprite->x-11;
  1237.                          break;
  1238.                  case 1: sprite->yhigh = sprite->y+11;
  1239.                          sprite->xhigh = sprite->x+11;
  1240.                          sprite->xlow = sprite->x;
  1241.                          break;
  1242.                  case 2: sprite->yhigh = sprite->y+11;
  1243.                          sprite->xhigh = sprite->x+11;
  1244.                          sprite->xlow = sprite->x-11;
  1245.                          break;
  1246.                  case 3: sprite->yhigh = sprite->y+11;
  1247.                          sprite->xhigh = sprite->x;
  1248.                          sprite->xlow = sprite->x-11;
  1249.                          break;
  1250.               }
  1251.               break;
  1252.       case 3: switch(sprite->pos) {
  1253.                  case 0: sprite->yhigh = sprite->y;
  1254.                          sprite->xhigh = sprite->x+11;
  1255.                          sprite->xlow = sprite->x-11;
  1256.                          break;
  1257.                  case 1: sprite->yhigh = sprite->y+11;
  1258.                          sprite->xhigh = sprite->x+11;
  1259.                          sprite->xlow = sprite->x;
  1260.                          break;
  1261.               }
  1262.               break;
  1263.       case 4: switch(sprite->pos) {
  1264.                  case 0: sprite->yhigh = sprite->y;
  1265.                          sprite->xhigh = sprite->x+11;
  1266.                          sprite->xlow = sprite->x-11;
  1267.                          break;
  1268.                  case 1: sprite->yhigh = sprite->y+11;
  1269.                          sprite->xhigh = sprite->x;
  1270.                          sprite->xlow = sprite->x-11;
  1271.                          break;
  1272.               }
  1273.               break;
  1274.       case 6: sprite->yhigh = sprite->y;
  1275.               sprite->xhigh = sprite->x+11;
  1276.               sprite->xlow = sprite->x;
  1277.               break;
  1278.    }
  1279. }
  1280.  
  1281. void draw_sprite(sprite_ptr sprite)
  1282. {
  1283.    int x, j, i;
  1284.    for(i = 0; i < 11; i++)
  1285.       _fmemcpy(&vga[((i+sprite->y)<<8)+((i+sprite->y)<<6)+sprite->x], &sprite->frame[i*11], 11);
  1286.    switch(sprite->type) {
  1287.       case 0: switch(sprite->pos) {
  1288.                  case 0: for(x = 0; x < 11; x++) {
  1289.                             j = ((x + sprite->y) << 8) + ((x + sprite->y) << 6) + sprite->x;
  1290.                             i = x * 11;
  1291.                             _fmemcpy(&vga[j - 11],&sprite->frame[i],11);
  1292.                             _fmemcpy(&vga[j + 11],&sprite->frame[i],11);
  1293.                             _fmemcpy(&vga[((x+sprite->y-11)<<8)+((x+sprite->y-11)<<6)+sprite->x],&sprite->frame[i],11);
  1294.                         } break;
  1295.                  case 3: for(x = 0; x < 11; x++) {
  1296.                             i = x * 11;
  1297.                             _fmemcpy(&vga[((x+sprite->y+11)<<8)+((x+sprite->y+11)<<6)+sprite->x],&sprite->frame[i],11);
  1298.                             _fmemcpy(&vga[((x+sprite->y)<<8) + ((x+sprite->y)<<6) + sprite->x - 11],&sprite->frame[i],11);
  1299.                             _fmemcpy(&vga[((x+sprite->y-11)<<8)+((x+sprite->y-11)<<6)+sprite->x],&sprite->frame[i],11);
  1300.                          }
  1301.                          break;
  1302.                  case 1: for(x = 0; x < 11; x++) {
  1303.                             i = x * 11;
  1304.                             _fmemcpy(&vga[((x+sprite->y)<<8)+((x+sprite->y)<<6)+sprite->x+11],&sprite->frame[i],11);
  1305.                             _fmemcpy(&vga[((x+sprite->y-11)<<8)+((x+sprite->y-11)<<6)+sprite->x],&sprite->frame[i],11);
  1306.                             _fmemcpy(&vga[((x+sprite->y+11)<<8)+((x+sprite->y+11)<<6)+sprite->x],&sprite->frame[i],11);
  1307.                          }
  1308.                          break;
  1309.                  case 2: for(x = 0; x < 11; x++) {
  1310.                             j = ((x+sprite->y)<<8)+((x+sprite->y)<<6)+sprite->x;
  1311.                             i = x * 11;
  1312.                             _fmemcpy(&vga[j-11],&sprite->frame[i],11);
  1313.                             _fmemcpy(&vga[j+11],&sprite->frame[i],11);
  1314.                             _fmemcpy(&vga[((x+sprite->y+11)<<8)+((x+sprite->y+11)<<6)+sprite->x],&sprite->frame[i],11);
  1315.                          }
  1316.                          break;
  1317.               }
  1318.               break;
  1319.       case 1: switch(sprite->pos) {
  1320.                  case 0: for(x = 0; x < 11; x++) {
  1321.                             j = ((x+sprite->y)<<8)+((x+sprite->y)<<6)+sprite->x;
  1322.                             i = x*11;
  1323.                             _fmemcpy(&vga[j-11],&sprite->frame[i],11);
  1324.                             _fmemcpy(&vga[j+11],&sprite->frame[i],11);
  1325.                             _fmemcpy(&vga[j+22],&sprite->frame[i],11);
  1326.                          }
  1327.                          break;
  1328.                  case 1: for(x = 0; x < 11; x++) {
  1329.                             i = x*11;
  1330.                             _fmemcpy(&vga[((x+sprite->y+11)<<8)+((x+sprite->y+11)<<6)+sprite->x],&sprite->frame[i],11);
  1331.                             _fmemcpy(&vga[((x+sprite->y-11)<<8)+((x+sprite->y-11)<<6)+sprite->x],&sprite->frame[i],11);
  1332.                             _fmemcpy(&vga[((x+sprite->y-22)<<8)+((x+sprite->y-22)<<6)+sprite->x],&sprite->frame[i],11);
  1333.                          }
  1334.                          break;
  1335.               }
  1336.               break;
  1337.       case 2: switch(sprite->pos) {
  1338.                  case 0: for(x = 0; x < 11; x++) {
  1339.                             j = ((x+sprite->y)<<8)+((x+sprite->y)<<6)+sprite->x;
  1340.                             i = x * 11;
  1341.                             _fmemcpy(&vga[j-11],&sprite->frame[i],11);
  1342.                             _fmemcpy(&vga[j+11],&sprite->frame[i],11);
  1343.                             _fmemcpy(&vga[((x+sprite->y-11)<<8)+((x+sprite->y-11)<<6)+sprite->x-11],&sprite->frame[i],11);
  1344.                          }
  1345.                          break;
  1346.                  case 1: for(x = 0; x < 11; x++) {
  1347.                             j = ((x+sprite->y-11)<<8)+((x+sprite->y-11)<<6)+sprite->x;
  1348.                             i = x * 11;
  1349.                             _fmemcpy(&vga[((x+sprite->y+11)<<8)+((x+sprite->y+11)<<6)+sprite->x],&sprite->frame[i],11);
  1350.                             _fmemcpy(&vga[j],&sprite->frame[i],11);
  1351.                             _fmemcpy(&vga[j+11],&sprite->frame[i],11);
  1352.                          }
  1353.                          break;
  1354.                  case 2: for(x = 0; x < 11; x++) {
  1355.                             j=((x+sprite->y)<<8)+((x+sprite->y)<<6)+sprite->x;
  1356.                             i = x * 11;
  1357.                             _fmemcpy(&vga[j-11],&sprite->frame[i],11);
  1358.                             _fmemcpy(&vga[j+11],&sprite->frame[i],11);
  1359.                             _fmemcpy(&vga[((x+sprite->y+11)<<8)+((x+sprite->y+11)<<6)+sprite->x+11],&sprite->frame[i],11);
  1360.                          }
  1361.                          break;
  1362.                  case 3: for(x = 0; x < 11; x++) {
  1363.                             j = ((x+sprite->y+11)<<8)+((x+sprite->y+11)<<6)+sprite->x;
  1364.                             i = x * 11;
  1365.                             _fmemcpy(&vga[((x+sprite->y-11)<<8)+((x+sprite->y-11)<<6)+sprite->x],&sprite->frame[i],11);
  1366.                             _fmemcpy(&vga[j],&sprite->frame[i],11);
  1367.                             _fmemcpy(&vga[j-11],&sprite->frame[i],11);
  1368.                          }
  1369.                          break;
  1370.  
  1371.               }
  1372.               break;
  1373.       case 3: switch(sprite->pos) {
  1374.                  case 0: for(x = 0; x < 11; x++) {
  1375.                             i=x*11;
  1376.                             j=((x+sprite->y-11)<<8)+((x+sprite->y-11)<<6)+sprite->x;
  1377.                             _fmemcpy(&vga[((x+sprite->y)<<8)+((x+sprite->y)<<6)+sprite->x+11],&sprite->frame[i],11);
  1378.                             _fmemcpy(&vga[j],&sprite->frame[i],11);
  1379.                             _fmemcpy(&vga[j-11],&sprite->frame[i],11);
  1380.                          }
  1381.                          break;
  1382.                  case 1: for(x = 0; x < 11; x++) {
  1383.                             i = x * 11;
  1384.                             _fmemcpy(&vga[((x+sprite->y)<<8)+((x+sprite->y)<<6)+sprite->x+11],&sprite->frame[i],11);
  1385.                             _fmemcpy(&vga[((x+sprite->y-11)<<8)+((x+sprite->y-11)<<6)+sprite->x+11],&sprite->frame[i],11);
  1386.                             _fmemcpy(&vga[((x+sprite->y+11)<<8)+((x+sprite->y+11)<<6)+sprite->x],&sprite->frame[i],11);
  1387.                          }
  1388.                          break;
  1389.               }
  1390.               break;
  1391.       case 4: switch(sprite->pos) {
  1392.                  case 0: for(x = 0; x < 11; x++) {
  1393.                             i = x * 11;
  1394.                             j=((x+sprite->y-11)<<8)+((x+sprite->y-11)<<6)+sprite->x;
  1395.                             _fmemcpy(&vga[((x+sprite->y)<<8)+((x+sprite->y)<<6)+sprite->x-11],&sprite->frame[i],11);
  1396.                             _fmemcpy(&vga[j],&sprite->frame[i],11);
  1397.                             _fmemcpy(&vga[j+11],&sprite->frame[i],11);
  1398.                           }
  1399.                           break;
  1400.                  case 1: for(x = 0; x < 11; x++) {
  1401.                             i = x * 11;
  1402.                             _fmemcpy(&vga[((x+sprite->y)<<8)+((x+sprite->y)<<6)+sprite->x-11],&sprite->frame[i],11);
  1403.                             _fmemcpy(&vga[((x+sprite->y-11)<<8)+((x+sprite->y-11)<<6)+sprite->x-11],&sprite->frame[i],11);
  1404.                             _fmemcpy(&vga[((x+sprite->y+11)<<8)+((x+sprite->y+11)<<6)+sprite->x],&sprite->frame[i],11);
  1405.                          }
  1406.                          break;
  1407.               }
  1408.               break;
  1409.       case 5: switch(sprite->pos) {
  1410.                  case 0: for(x = 0; x < 11; x++) {
  1411.                             j = ((x+sprite->y)<<8)+((x+sprite->y)<<6)+sprite->x;
  1412.                             i = x * 11;
  1413.                             _fmemcpy(&vga[j-11],&sprite->frame[i],11);
  1414.                             _fmemcpy(&vga[j+11],&sprite->frame[i],11);
  1415.                             _fmemcpy(&vga[((x+sprite->y-11)<<8)+((x+sprite->y-11)<<6)+sprite->x+11],&sprite->frame[i],11);
  1416.                          }
  1417.                          break;
  1418.                  case 1: for(x = 0; x < 11; x++) {
  1419.                             j = ((x+sprite->y+11)<<8)+((x+sprite->y+11)<<6)+sprite->x;
  1420.                             i = x * 11;
  1421.                             _fmemcpy(&vga[((x+sprite->y-11)<<8)+((x+sprite->y-11)<<6)+sprite->x],&sprite->frame[i],11);
  1422.                             _fmemcpy(&vga[j],&sprite->frame[i],11);
  1423.                             _fmemcpy(&vga[j+11],&sprite->frame[i],11);
  1424.                          }
  1425.                          break;
  1426.                  case 2: for(x = 0; x < 11; x++) {
  1427.                             j=((x+sprite->y)<<8)+((x+sprite->y)<<6)+sprite->x;
  1428.                             i = x * 11;
  1429.                             _fmemcpy(&vga[j-11],&sprite->frame[i],11);
  1430.                             _fmemcpy(&vga[j+11],&sprite->frame[i],11);
  1431.                             _fmemcpy(&vga[((x+sprite->y+11)<<8)+((x+sprite->y+11)<<6)+sprite->x-11],&sprite->frame[i],11);
  1432.                          }
  1433.                          break;
  1434.                  case 3: for(x = 0; x < 11; x++) {
  1435.                             j = ((x+sprite->y-11)<<8)+((x+sprite->y-11)<<6)+sprite->x;
  1436.                             i = x * 11;
  1437.                             _fmemcpy(&vga[((x+sprite->y+11)<<8)+((x+sprite->y+11)<<6)+sprite->x],&sprite->frame[i],11);
  1438.                             _fmemcpy(&vga[j],&sprite->frame[i],11);
  1439.                             _fmemcpy(&vga[j-11],&sprite->frame[i],11);
  1440.                          }
  1441.                          break;
  1442.               }
  1443.               break;
  1444.       case 6: for(x = 0; x < 11; x++) {
  1445.                  i = x * 11;
  1446.                  j = ((x+sprite->y-11)<<8)+((x+sprite->y-11)<<6)+sprite->x;
  1447.                  _fmemcpy(&vga[((x+sprite->y)<<8)+((x+sprite->y)<<6)+sprite->x+11],&sprite->frame[i],11);
  1448.                  _fmemcpy(&vga[j],&sprite->frame[i],11);
  1449.                  _fmemcpy(&vga[j+11],&sprite->frame[i],11);
  1450.               }
  1451.               break;
  1452.    }
  1453. }
  1454.  
  1455. void quit_program(char *format, ...)
  1456. {
  1457.    va_list arglist;
  1458.    char buffer[2000];
  1459.    va_start(arglist, format);
  1460.    vsprintf(buffer, format, arglist);
  1461.    va_end(arglist);
  1462.    _dos_setvect(TIMER_KEEPER_INT, old_isr);
  1463.    setmode(0x03);
  1464.    printf("%s\n", buffer);
  1465.    printf("MinTris Version 0.01 (c) 1996 By Min S. Kwon\n");
  1466.    printf("Email: times9@clark.net\n");
  1467.    printf("Background images by: Highland Graphics\n");
  1468.    printf("Highland Graphics: http://www.itsnet.com/home/highland/highland.html\n");
  1469.    exit(0);
  1470. }
  1471.  
  1472. void sprite_init(sprite_ptr sprite, int x, int y, int type)
  1473. {
  1474.    unsigned int index;
  1475.    sprite->x = x;
  1476.    sprite->y = y;
  1477.    sprite->type = type;
  1478.    sprite->pos = 0;
  1479.    for(index = 0; index < 10; index++) {
  1480.       sprite->background[index] = (char far *) _fmalloc(125);
  1481.       if(sprite->background[index] == NULL) quit_program("Insufficient memory");
  1482.    }
  1483. }
  1484.  
  1485. void pcx_delete(pcx_picture_ptr image)
  1486. {
  1487.    _ffree(image->buffer);
  1488. }
  1489.  
  1490. void pcx_show_buffer(pcx_picture_ptr image)
  1491. {
  1492.    _fmemcpy((char far *)vga, (char far *)image->buffer, 64000);
  1493. }
  1494.  
  1495. void pcx_init(pcx_picture_ptr image)
  1496. {
  1497.    if((image->buffer = (char far *) _fmalloc(64000)) == NULL) {
  1498.       setmode(0x03);
  1499.       puts("Insufficient memory.");
  1500.       _ffree(&image);
  1501.       exit(0);
  1502.    }
  1503. }
  1504.  
  1505. void setmode(int mode)
  1506. {
  1507.    union REGS r;
  1508.    r.h.al = mode;
  1509.    r.h.ah = 0;
  1510.    int86(0x10, &r, &r);
  1511. }
  1512.  
  1513. void pcx_load(char *fname, pcx_picture_ptr image, short int enable)
  1514. {
  1515.    FILE *fp;
  1516.    int num_bytes, index;
  1517.    long count;
  1518.    unsigned char data;
  1519.    char far *temp_buffer;
  1520.    fp = fopen(fname, "rb");
  1521.    temp_buffer = (char far *) image;
  1522.    for(index = 0; index < 128; index++) {
  1523.       temp_buffer[index] = getc(fp);
  1524.    }
  1525.    count = 0;
  1526.    while(count <= 64000) {
  1527.       data = getc(fp);
  1528.       if(data >= 192 && data <= 255) {
  1529.          num_bytes = data - 192;
  1530.          data = getc(fp);
  1531.          while(num_bytes-- > 0) {
  1532.             image->buffer[count++] = data;
  1533.          }
  1534.       }
  1535.       else {
  1536.          image->buffer[count++] = data;
  1537.       }
  1538.    }
  1539.    fseek(fp, -768L, SEEK_END);
  1540.    for(index = 0; index < 256; index++) {
  1541.       image->palette[index].red = (getc(fp) >> 2);
  1542.       image->palette[index].green = (getc(fp) >> 2);
  1543.       image->palette[index].blue = (getc(fp) >> 2);
  1544.    }
  1545.    fclose(fp);
  1546.    if(enable)
  1547.       for(index = 0; index < 256; index++)
  1548.          set_palette_register(index, (rgb_color_ptr) &image->palette[index]);
  1549. }
  1550.  
  1551. void set_palette_register(int index, rgb_color_ptr color)
  1552. {
  1553.    outp(PALETTE_MASK, 0xff);
  1554.    outp(PALETTE_REGISTER, index);
  1555.    outp(PALETTE_DATA, color->red);
  1556.    outp(PALETTE_DATA, color->green);
  1557.    outp(PALETTE_DATA, color->blue);
  1558. }
  1559.  
  1560.