home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / games / cubetris / cubetris.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  27.7 KB  |  1,527 lines

  1. /*
  2.  * Copyright 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include <gl.h>
  18. #include <device.h>
  19. #include <stdio.h>
  20. #include <math.h>
  21. #include <time.h>
  22.  
  23. #define SIZE    6        /* Number of cubes across the playing area */
  24.  
  25. #define ZSPEED    -0.1        /* How fast the pieces fall initially (one */
  26.                 /* unit is one grid space) */
  27. #define ZSPEEDDELTA -0.02    /* Delta for above, every time a plane is */
  28.                 /* cleared. */
  29. #define FASTDROP -1.0        /* How fast it falls if we're going fast. */
  30.  
  31. #define SCOREPIECE    10    /* Score per piece */
  32. #define SCOREFILL    500    /* Score for filling a plane */
  33. #define SCOREFAST    2    /* Score for each frame we have FASTDROP */
  34.  
  35.  
  36.  
  37. #define HALFTONE 1
  38.  
  39. unsigned short halftone[] = {
  40.     0x5555, 0xaaaa, 0x5555, 0xaaaa,
  41.     0x5555, 0xaaaa, 0x5555, 0xaaaa,
  42.     0x5555, 0xaaaa, 0x5555, 0xaaaa,
  43.     0x5555, 0xaaaa, 0x5555, 0xaaaa  };
  44.  
  45.  
  46.  
  47. int board[SIZE][SIZE][SIZE];
  48. int height[SIZE][SIZE];
  49. int planecount[SIZE];
  50.  
  51. typedef struct _PaintRec {
  52.     int x, y, z, m;
  53. } PaintRec, *Paint;
  54.  
  55. PaintRec paintlist[SIZE * SIZE * SIZE];
  56. int numpaint;
  57.  
  58.  
  59.  
  60. typedef int Shape[4][3];
  61.  
  62. typedef struct _PieceRec {
  63.     int rotatevertex;        /* 1 if rotate around vertex, 0 if */
  64.                 /* rotate around face */
  65.     int numshapes;
  66.     int material;
  67.     Shape shapes[6];
  68. } PieceRec, *Piece;
  69.  
  70. PieceRec bar = {
  71.     1, 2, 1,
  72.     {
  73.     {{-3, 1, 0}, {-1, 1, 0}, {1, 1, 0}, {3, 1, 0}},
  74.     {{1, 1, 4}, {1, 1, 2}, {1, 1, 0}, {1, 1, -2}}
  75.     }
  76. };
  77.  
  78. PieceRec square = {
  79.     1, 2, 2,
  80.     {
  81.     {{-1, -1, 0}, {1, -1, 0}, {-1, 1, 0}, {1, 1, 0}},
  82.     {{-1, -1, 0}, {1, -1, 0}, {-1, -1, 2}, {1, -1, 2}}
  83.     }
  84. };
  85.  
  86. PieceRec ell = {
  87.     0, 6, 3,
  88.     {
  89.     {{-2, 0, 0}, {0, 0, 0}, {2, 0, 0}, {2, 2, 0}},
  90.     {{-2, 0, 0}, {0, 0, 0}, {2, 0, 0}, {2, 0, 2}},
  91.     {{-2, 0, 0}, {0, 0, 0}, {2, 0, 0}, {2, -2, 0}},
  92.     {{-2, 0, 0}, {0, 0, 0}, {2, 0, 0}, {2, 0, -2}},
  93.     {{0, -2, 2}, {0, 0, 2}, {0, 0, 0}, {0, 0, -2}},
  94.     {{0, -2, -2}, {0, 0, -2}, {0, 0, 0}, {0, 0, 2}},
  95.     }
  96. };
  97.  
  98. PieceRec axis = {
  99.     1, 2, 4,
  100.     {
  101.     {{-1, 1, 0}, {-1, -1, 0}, {1, -1, 0}, {-1, -1, -2}},
  102.     {{-1, 1, 0}, {-1, -1, 0}, {1, -1, 0}, {-1, -1, 2}}
  103.     }
  104. };
  105.  
  106.  
  107. PieceRec tee = {
  108.     0, 4, 5,
  109.     {
  110.     {{-2, 0, 0}, {0, 0, 0}, {0, 2, 0}, {2, 0, 0}},
  111.     {{-2, 0, 0}, {0, 0, 0}, {0, 0, 2}, {2, 0, 0}},
  112.     {{0, 0, -2}, {0, 0, 0}, {0, 2, 0}, {0, 0, 2}},
  113.     {{-2, 0, 0}, {0, 0, 0}, {0, 0, -2}, {2, 0, 0}}
  114.     }
  115. };
  116.  
  117. PieceRec zig = {
  118.     0, 4, 6,
  119.     {
  120.     {{-2, 0, 0}, {0, 0, 0}, {0, 2, 0}, {2, 2, 0}},
  121.     {{0, 0, 2}, {0, 0, 0}, {0, 2, 0}, {0, 2, -2}},
  122.     {{-2, 2, 0}, {0, 2, 0}, {0, 0, 0}, {2, 0, 0}},
  123.     {{-2, 0, 2}, {0, 0, 2}, {0, 0, 0}, {2, 0, 0}},
  124.     }
  125. };
  126.  
  127. PieceRec twist1 = {
  128.     1, 3, 7,
  129.     {
  130.     {{-1, -1, 2}, {-1, -1, 0}, {-1, 1, 0}, {1, 1, 0}},
  131.     {{-1, -1, 0}, {-1, 1, 0}, {-1, 1, 2}, {1, 1, 2}},
  132.     {{-1, 1, 0}, {-1, 1, 2}, {-1, -1, 2}, {1, -1, 2}}
  133.     }
  134. };
  135.  
  136. PieceRec twist2 = {
  137.     1, 3, 8,
  138.     {
  139.     {{-1, -1, 2}, {-1, -1, 0}, {1, -1, 0}, {1, 1, 0}},
  140.     {{-1, -1, 0}, {1, -1, 0}, {1, -1, 2}, {1, 1, 2}},
  141.     {{1, -1, 0}, {1, -1, 2}, {-1, -1, 2}, {-1, 1, 2}}
  142.     }
  143. };
  144.     
  145.      
  146. Piece pieces[] = {&bar, &square, &ell, &axis, &tee, &zig, &twist1, &twist2};
  147. #define NUMPIECES    8
  148.  
  149.  
  150. int score;
  151. char scorestr[20];
  152. Piece curpiece;
  153. int curshape;
  154. float currot;
  155. Coord curx, cury, curz;
  156. float dropspeed;
  157. float zspeed;
  158. int gameover;
  159. int usebevels = TRUE;
  160.  
  161. int debug = FALSE;
  162.  
  163.  
  164. Matrix objmat = {
  165.     {1.0, 0.0, 0.0, 0.0},
  166.     {0.0, 1.0, 0.0, 0.0},
  167.     {0.0, 0.0, 1.0, 0.0},
  168.     {0.0, 0.0, 0.0, 1.0},
  169. };
  170.  
  171. Matrix idmat = {
  172.     {1.0, 0.0, 0.0, 0.0},
  173.     {0.0, 1.0, 0.0, 0.0},
  174.     {0.0, 0.0, 1.0, 0.0},
  175.     {0.0, 0.0, 0.0, 1.0},
  176. };
  177.  
  178. static int azimuth = 0, elevation = 0;
  179.  
  180. static float light[] = {
  181.  
  182.     AMBIENT, 0.1, 0.1, 0.1,
  183.     LCOLOR, 1.0, 1.0, 1.0,
  184.     POSITION, 1.0, 0.5, 0.5, 0.0,
  185.     LMNULL
  186. };
  187.  
  188.  
  189. #define NUMMATERIALS    9
  190. float materials[NUMMATERIALS][15] = {
  191.     {
  192.     AMBIENT, 0.3, 0.3, 0.3,
  193.     DIFFUSE, 0.8, 0.8, 0.8,
  194.     SPECULAR, 1.0, 1.0, 1.0,
  195.     SHININESS, 30.0,
  196.     LMNULL,
  197.     }, {
  198.     AMBIENT, 0.3, 0.1, 0.1,
  199.     DIFFUSE, 0.8, 0.1, 0.1,
  200.     SPECULAR, 1.0, 0.1, 0.1,
  201.     SHININESS, 30.0,
  202.     LMNULL,
  203.     }, {
  204.     AMBIENT, 0.7, 0.1, 0.3,
  205.     DIFFUSE, 0.1, 0.8, 0.1,
  206.     SPECULAR, 0.1, 1.0, 0.5,
  207.     SHININESS, 30.0,
  208.     LMNULL,
  209.     }, {
  210.     AMBIENT, 0.1, 0.3, 0.1,
  211.     DIFFUSE, 0.1, 0.8, 0.1,
  212.     SPECULAR, 0.1, 1.0, 0.1,
  213.     SHININESS, 30.0,
  214.     LMNULL,
  215.     }, {
  216.     AMBIENT, 0.3, 0.3, 0.1,
  217.     DIFFUSE, 0.8, 0.8, 0.1,
  218.     SPECULAR, 1.0, 1.0, 0.1,
  219.     SHININESS, 30.0,
  220.     LMNULL,
  221.     }, {
  222.     AMBIENT, 0.1, 0.3, 0.3,
  223.     DIFFUSE, 0.1, 0.8, 0.8,
  224.     SPECULAR, 0.1, 1.0, 1.0,
  225.     SHININESS, 30.0,
  226.     LMNULL,
  227.     }, {
  228.     AMBIENT, 0.3, 0.1, 0.3,
  229.     DIFFUSE, 0.8, 0.1, 0.8,
  230.     SPECULAR, 1.0, 0.1, 1.0,
  231.     SHININESS, 30.0,
  232.     LMNULL,
  233.     }, {
  234.     AMBIENT, 0.3, 0.1, 0.7,
  235.     DIFFUSE, 0.1, 0.8, 0.1,
  236.     SPECULAR, 0.5, 1.0, 0.1,
  237.     SHININESS, 30.0,
  238.     LMNULL,
  239.     }, {
  240.     AMBIENT, 0.3, 0.7, 0.1,
  241.     DIFFUSE, 0.1, 0.1, 0.8,
  242.     SPECULAR, 0.1, 0.1, 0.5,
  243.     SHININESS, 30.0,
  244.     LMNULL,
  245.     }
  246. };
  247.  
  248. static float light_model[] = {
  249.  
  250.     AMBIENT, 1.0, 1.0, 1.0,
  251.     LOCALVIEWER, 0.0,
  252.     LMNULL
  253. };
  254.  
  255.  
  256. enum {NOTHING, ORIENT, MOVE} mode;
  257.  
  258. short omx, mx, omy, my;    /* old and new mouse position */
  259.  
  260. /* like qread only compresses extra MOUSEX, MOUSEY events */
  261.  
  262. /*
  263. static long nextqueue(short*);
  264. static long nextqtest();
  265. */
  266.  
  267. #define nextqueue qread
  268. #define nextqtest qtest
  269.  
  270. draw_cube(int x, int y, int z);
  271.  
  272. addscore(int value) {
  273.     score += value;
  274.     sprintf(scorestr, "%d", score);
  275. }
  276.  
  277.  
  278. int getgridloc(int which, int *rx, int *ry, int *rz) {
  279.     int dx, dy, dz, t;
  280.     Shape *s;
  281.     s = curpiece->shapes + curshape;
  282.     dx = (*s)[which][0];
  283.     dy = (*s)[which][1];
  284.     dz = (*s)[which][2];
  285.     if (currot == 90.0) {
  286.     t = dx;
  287.     dx = -dy;
  288.     dy = t;
  289.     } else if (currot == 180.0) {
  290.     dx = -dx;
  291.     dy = -dy;
  292.     } else if (currot == 270.0) {
  293.     t = dx;
  294.     dx = dy;
  295.     dy = -t;
  296.     }
  297.     *rx = (int) ((curx + dx) / 2.0);
  298.     *ry = (int) ((cury + dy) / 2.0);
  299.     *rz = (int) floor((curz + dz) / 2.0);
  300. /*    fprintf(stderr, "%d %d %d %d\n", which, *rx, *ry, *rz); */
  301. }
  302.  
  303.  
  304. setboard(int x, int y, int z, int m) {
  305.     if (board[x][y][z] == 0) {
  306.     Paint ptr = paintlist + numpaint;
  307.     board[x][y][z] = m;
  308.     ptr->x = x;
  309.     ptr->y = y;
  310.     ptr->z = z;
  311.     ptr->m = m;
  312.     numpaint++;
  313.     if (height[x][y] <= z) height[x][y] = z + 1;
  314.     planecount[z]++;
  315.     }
  316. }
  317.     
  318.  
  319. checkfilled() {
  320.     int z, i, j, k;
  321.     for (z=0 ; z<SIZE ; z++) {
  322.     while (planecount[z] == SIZE * SIZE) {
  323.         addscore(SCOREFILL);
  324.         zspeed += ZSPEEDDELTA;
  325.         numpaint = 0;
  326.         for (i=0 ; i<SIZE ; i++) planecount[i] = 0;
  327.         for (i=0 ; i<SIZE ; i++) {
  328.         for (j=0 ; j<SIZE ; j++) {
  329.             height[i][j] = 0;
  330.             for (k=0 ; k<SIZE - 1 ; k++) {
  331.             if (k >= z) board[i][j][k] = board[i][j][k+1];
  332.             if (board[i][j][k]) {
  333.                 int m = board[i][j][k];
  334.                 board[i][j][k] = 0;
  335.                 setboard(i, j, k, m);
  336.             }
  337.             }
  338.             board[i][j][SIZE-1] = 0;
  339.         }
  340.         }
  341.     }
  342.     }
  343. }
  344.  
  345.  
  346. refigurefallenobjects() {
  347.     int i;
  348.     Paint ptr;
  349.     makeobj(2);
  350.     for (i=0, ptr = paintlist ; i<numpaint; i++, ptr++) {
  351.     lmbind(MATERIAL, ptr->m);
  352.     pushmatrix();
  353.     translate(ptr->x + 0.5, ptr->y + 0.5, ptr->z + 0.5);
  354.     draw_cube(ptr->x, ptr->y, ptr->z);
  355.     popmatrix();
  356.     }
  357.     closeobj();
  358. }
  359.  
  360.  
  361. keeppieceonboard() {
  362.     int i, x, y, z;
  363.     for (i=0 ; i<4 ; i++) {
  364.     getgridloc(i, &x, &y, &z);
  365.     if (x < 0) curx += 2.0 * (- x);
  366.     if (y < 0) cury += 2.0 * (- y);
  367.     if (x >= SIZE) curx -= 2.0 * (x - SIZE + 1);
  368.     if (y >= SIZE) cury -= 2.0 * (y - SIZE + 1);
  369.     }
  370. }
  371.  
  372.  
  373. dopause() {
  374.     static char mesg[30][60] = {
  375.     "Paused  -  Press <Return> to continue",
  376.     "  ",
  377.     "Left button either drags the falling piece around,",
  378.     "or rotates the scene if selected somewhere not on",
  379.     "the falling piece.",
  380.     " ",
  381.     "Middle button cycles the piece through all useful",
  382.     "rotations about the X and Y axis.",
  383.     " ",
  384.     "Right button rotates the piece about the Z axis.",
  385.     " ",
  386.     "Numeric pad keys move piece one unit in the XY plane.",
  387.     " ",
  388.     "Space  - quickly drops the piece down (extra points)",
  389.     "B      - Toggles bevelled cubes (helps performance)",
  390.     "P or H - pauses game and shows this help",
  391.     "F1     - Shows view from above",
  392.     "F2     - Shows view from below",
  393.     "Esc    - exits",
  394.     " ",
  395.     "If you fill an entire plane, it will disappear,",
  396.     "and you get 500 points.",
  397.     "",
  398.     };
  399.     int width, height, i;
  400.     short dev, value;
  401.     for (;;) {
  402.     czclear(0, 0);
  403.     getsize(&width, &height);
  404.     loadmatrix(idmat);
  405.     ortho2(0, width, 0, height);
  406.     RGBcolor(0, 255, 0);
  407.     for (i=0 ; mesg[i][0] ; i++) {
  408.         cmov2(2, height - (i + 1) * 14);
  409.         charstr(mesg[i]);
  410.     }
  411.     swapbuffers();
  412.     dev = nextqueue(&value);
  413.     if (dev == ESCKEY) exit(0);
  414.     if (dev == REDRAW) reshapeviewport();
  415.     if (dev == RETKEY) return;
  416.     }
  417. }
  418.  
  419.  
  420.  
  421. int pushit(int dx, int dy) {
  422.     curx += dx * 2;
  423.     cury += dy * 2;
  424.     if (!validposition()) {
  425.     curx -= dx * 2;
  426.     cury -= dy * 2;
  427.     }
  428. }
  429.  
  430.  
  431.  
  432. main(int argc, char **argv) {
  433.  
  434.     int dev;
  435.     short val;
  436.     int i;
  437.     time_t t;
  438.     int finished = FALSE;
  439.  
  440.     for (i=1 ; i<argc ; i++) {
  441.     if (strcmp(argv[i], "-debug") == 0) debug = TRUE;
  442.     else {
  443.         fprintf(stderr, "Usage: %s [-debug]\n", argv[0]);
  444.         exit(1);
  445.     }
  446.     }
  447.  
  448.     time(&t);
  449.     srandom(t);
  450.  
  451.     initialize();
  452.  
  453.     initgame();
  454.  
  455.     while (!finished) {
  456.     draw_scene();
  457.  
  458.     while (!finished && (nextqtest() || gameover)) {
  459.  
  460.         switch(dev=nextqueue(&val)) {
  461.  
  462.           case ESCKEY:
  463.         if (val == 0) finished = TRUE;    /* exit on up, not down */
  464.         break;
  465.  
  466.           case GKEY:
  467.         if (gameover) initgame();
  468.         break;
  469.  
  470.           case HKEY:
  471.           case PKEY:
  472.         dopause();
  473.         break;
  474.  
  475.           case BKEY:
  476.         if (val) {
  477.             usebevels = !usebevels;
  478.             define_cube();
  479.             refigurefallenobjects();
  480.         }
  481.         break;
  482.  
  483.           case SPACEKEY:
  484.         if (val) {
  485.             dropspeed = FASTDROP;
  486.         }
  487.         break;
  488.  
  489.           case F1KEY:
  490.         azimuth = elevation = 0;
  491.         break;
  492.  
  493.           case F2KEY:
  494.         azimuth = 0;
  495.         elevation = 1800;
  496.         break;
  497.  
  498.           case REDRAW:
  499.         reshapeviewport();
  500.         draw_scene();
  501.         break;
  502.  
  503.           case LEFTMOUSE:
  504.         if (nextqtest() == MOUSEX) {
  505.             nextqueue(&mx);
  506.             if (nextqtest() == MOUSEY) nextqueue(&my);
  507.         }
  508.         omx = mx; omy = my;
  509.         if (val) {
  510.             mode = ORIENT;
  511.             if (curpiece) {
  512.             long ox, oy;
  513.             unsigned long pixel;
  514.             czclear(0, 0);
  515.             draw_piece();
  516.             getorigin(&ox, &oy);
  517.             lrectread(mx - ox, my - oy, mx - ox, my - oy, &pixel);
  518.             if (pixel != 0) mode = MOVE;
  519. /*
  520.             short buf[10];
  521.             int numpicked;
  522.             buf[0] = 0;
  523.             pick(buf, 10);
  524.             perspective(400, 5.0/4.0, 2.0, 6.0);
  525.             loadname(0);
  526.             clear();
  527.             loadname(2);
  528.             draw_piece();
  529.             if (endpick(buf) > 1) {
  530.                 mode = MOVE;
  531.             }
  532. */
  533.             }
  534.         } else mode = NOTHING;
  535.         break;
  536.  
  537.           case MIDDLEMOUSE:
  538.         if (val && curpiece) {
  539.             curshape = (curshape + 1) % curpiece->numshapes;
  540.             keeppieceonboard();
  541.         }
  542.         break;
  543.  
  544.           case RIGHTMOUSE:
  545.         if (val && curpiece) {
  546.             currot += 90.0;
  547.             if (currot >= 360.0) currot = 0.0;
  548.             keeppieceonboard();
  549.         }
  550.         break;
  551.  
  552.           case PAD1:
  553.         if (val) pushit(-1, -1);
  554.         break;
  555.           case PAD2:
  556.         if (val) pushit(0, -1);
  557.         break;
  558.           case PAD3:
  559.         if (val) pushit(1, -1);
  560.         break;
  561.           case PAD4:
  562.         if (val) pushit(-1, 0);
  563.         break;
  564.           case PAD6:
  565.         if (val) pushit(1, 0);
  566.         break;
  567.           case PAD7:
  568.         if (val) pushit(-1, 1);
  569.         break;
  570.           case PAD8:
  571.         if (val) pushit(0, 1);
  572.         break;
  573.           case PAD9:
  574.         if (val) pushit(1, 1);
  575.         break;
  576.  
  577.           case MOUSEX:
  578.         omx = mx; mx = val;
  579.         break;
  580.  
  581.           case MOUSEY:
  582.         omy = my; my = val;
  583.  
  584.         update_scene();
  585.         break;
  586.         }
  587.         if (gameover && !nextqtest()) draw_scene();
  588.     }
  589.     if (curpiece) {
  590.         for (i=0 ; i<4 ; i++) {
  591.         int x, y, z;
  592.         getgridloc(i, &x, &y, &z);
  593.         if (z < SIZE) {
  594.             if (z < 0 || board[x][y][z]) {
  595.             do {
  596.                 curz += 2.0;
  597.                 getgridloc(i, &x, &y, &z);
  598.             } while (z < 0);
  599.             for (i=0 ; i<4 ; i++) {
  600.                 getgridloc(i, &x, &y, &z);
  601.                 if (z >= 0 && z < SIZE) {
  602.                 setboard(x, y, z, curpiece->material);
  603.                 } else {
  604.                 gameover = TRUE;
  605.                 curpiece = NULL;
  606.                 break;
  607.                 }
  608.             }
  609.             if (!gameover) {
  610.                 addscore(SCOREPIECE);
  611.                 checkfilled();
  612.                 pickpiece();
  613.             }
  614.             refigurefallenobjects();
  615.             break;
  616.             }
  617.         }
  618.         }
  619.     }
  620.     curz += dropspeed;
  621.     if (dropspeed == FASTDROP && curpiece) addscore(SCOREFAST);
  622.     }
  623. }
  624.  
  625.  
  626. initgame() {
  627.     int i, j, k;
  628.     for (i=0 ; i<SIZE ; i++) {
  629.     planecount[i] = 0;
  630.     for (j=0 ; j<SIZE ; j++) {
  631.         height[i][j] = 0;
  632.         for (k=0 ; k<SIZE ; k++) {
  633.         board[i][j][k] = 0;
  634.         }
  635.     }
  636.     }
  637.     numpaint = 0;
  638.     pickpiece();
  639.     score = 0;
  640.     addscore(0);
  641.     zspeed = ZSPEED;
  642.     gameover = FALSE;
  643.     refigurefallenobjects();
  644.     draw_scene();
  645.     define_cube();
  646. }
  647.  
  648.  
  649. int myran(int t) {
  650.     return random() % t;
  651. }
  652.  
  653.  
  654.  
  655. int outofbounds() {
  656.     int i, x, y, z;
  657.     for (i=0 ; i<4 ; i++) {
  658.     getgridloc(i, &x, &y, &z);
  659.     if (x < 0 || x >= SIZE || y < 0 || y >= SIZE || z < 0) return TRUE;
  660.     }
  661.     return FALSE;
  662. }
  663.  
  664. pickpiece() {
  665.     curpiece = pieces[myran(NUMPIECES)];
  666.     curshape = myran(curpiece->numshapes);
  667.     currot = myran(4) * 90.0;
  668.     curz = (Coord) (SIZE * 2);
  669.     do {
  670.     curx = (Coord) (myran(SIZE) * 2 + curpiece->rotatevertex);
  671.     cury = (Coord) (myran(SIZE) * 2 + curpiece->rotatevertex);
  672.     } while (outofbounds());
  673.     dropspeed = ZSPEED;
  674. }
  675.     
  676.  
  677.  
  678.  
  679. initialize() {
  680.     int i;
  681.  
  682.     if (debug) foreground();
  683.  
  684.     prefsize(500, 400);
  685.     winopen("Cubetris");
  686.     keepaspect(5, 4);
  687.     winconstraints();
  688.     icontitle("Cubetris");
  689.  
  690.     doublebuffer();
  691.     RGBmode();
  692.     backface(TRUE);
  693.     zbuffer(TRUE);
  694. /* fprintf(stderr, "%d, %d\n", getgdesc(GD_ZMAX), getgdesc(GD_ZMIN)); */
  695.     lsetdepth(getgdesc(GD_ZMAX), 0);
  696.     gconfig();
  697.  
  698.     zfunction(ZF_GREATER);
  699.     shademodel(FLAT);
  700.  
  701.     qdevice(ESCKEY);
  702.     qdevice(BKEY);
  703.     qdevice(GKEY);
  704.     qdevice(HKEY);
  705.     qdevice(PKEY);
  706.     qdevice(RETKEY);
  707.     qdevice(SPACEKEY);
  708.     qdevice(F1KEY);
  709.     qdevice(F2KEY);
  710.     qdevice(LEFTMOUSE);
  711.     qdevice(MIDDLEMOUSE);
  712.     qdevice(RIGHTMOUSE);
  713.     qdevice(MOUSEX);
  714.     qdevice(MOUSEY);
  715.     qdevice(PAD1);
  716.     qdevice(PAD2);
  717.     qdevice(PAD3);
  718.     qdevice(PAD4);
  719.     qdevice(PAD5);
  720.     qdevice(PAD6);
  721.     qdevice(PAD7);
  722.     qdevice(PAD8);
  723.     qdevice(PAD9);
  724.  
  725.     tie(LEFTMOUSE, MOUSEX, MOUSEY);
  726.  
  727.     defpattern(HALFTONE, 16, halftone);
  728.  
  729.     mmode(MVIEWING);
  730.  
  731.     lmdef(DEFLIGHT, 1, 0, light);
  732.     lmdef(DEFLMODEL, 1, 0, light_model);
  733.     for (i=0 ; i<NUMMATERIALS ; i++) {
  734.     lmdef(DEFMATERIAL, i+1, 0, materials[i]);
  735.     }
  736. }
  737.  
  738.  
  739. Coord roundit(Coord v, int makeodd) {
  740.     if (makeodd) {
  741.     return 2 * ((int) ((v - 1.0) / 2.0)) + 1;
  742.     } else {
  743.     return 2 * ((int) (v / 2.0));
  744.     }
  745. }
  746.  
  747. Coord max(Coord a, Coord b) {
  748.     return (a > b) ? a : b;
  749. }
  750.     
  751.  
  752. validposition() {
  753.     int i, x, y, z;
  754.     if (outofbounds()) return FALSE;
  755.     for (i=0 ; i<4 ; i++) {
  756.     getgridloc(i, &x, &y, &z);
  757.     if (board[x][y][z]) return FALSE;
  758.     }
  759.     return TRUE;
  760. }
  761.  
  762.  
  763. update_scene() {
  764.     long ox, oy;
  765.     Coord x1, y1, z1, x2, y2, z2, oldx, oldy, destx, desty, dx, dy, z;
  766.     int nsteps, i;
  767.  
  768.     switch (mode) {
  769.  
  770.     case ORIENT:
  771.         orient();
  772.         break;
  773.       case MOVE:
  774.         if (curpiece == NULL) return;
  775.         getorigin(&ox, &oy);
  776.         mapw(1, mx - ox, my - oy, &x1, &y1, &z1, &x2, &y2, &z2);
  777.         if (z1 == z2) break;
  778.         oldx = curx;
  779.         oldy = cury;
  780.         z = curz / 2.0 + 0.5;
  781.         curx = (x2 * (z - z1) - x1 * (z - z2)) / (z2 - z1);
  782.         cury = (y2 * (z - z1) - y1 * (z - z2)) / (z2 - z1);
  783. /*
  784. fprintf(stderr, "%f %f   %f %f %f %f %f %f\n", mx, my, x1, y1, z1, x2, y2, z2);
  785. fprintf(stderr, "%f %f    \n", curx, cury);
  786. */
  787.         curx = roundit((curx - 0.5) * 2, curpiece->rotatevertex);
  788.         cury = roundit((cury - 0.5) * 2, curpiece->rotatevertex);
  789.         keeppieceonboard();
  790.         destx = curx;
  791.         desty = cury;
  792.  
  793.         nsteps = max(fabs(destx - oldx), fabs(desty - cury));
  794.         if (nsteps == 0) break;
  795.         dx = (destx - oldx) / nsteps;
  796.         dy = (desty - oldy) / nsteps;
  797.         for (; nsteps > 0 ; nsteps--) {
  798.         oldx += dx;
  799.         oldy += dy;
  800.         curx = roundit(oldx, curpiece->rotatevertex);
  801.         cury = roundit(oldy, curpiece->rotatevertex);
  802.         if (!validposition()) {
  803.             oldx -= dx;
  804.             oldy -= dy;
  805.             curx = roundit(oldx, curpiece->rotatevertex);
  806.             cury = roundit(oldy, curpiece->rotatevertex);
  807.             break;
  808.         }
  809.         }
  810.         break;
  811.     }
  812.  
  813. /*    if (mode) draw_scene(); */
  814. }
  815.  
  816.  
  817. orient () {
  818.  
  819. /*
  820.     pushmatrix();
  821.  
  822.     loadmatrix(idmat);
  823. */
  824.     azimuth -= mx - omx;
  825.     elevation -= omy - my;
  826. /*
  827.     polarview(0, azimuth, elevation, 0);
  828.     getmatrix(objmat);
  829. */
  830.  
  831. /*
  832.     rotate(mx-omx, 'y');
  833.     rotate(omy-my, 'x');
  834.  
  835.     multmatrix(objmat);
  836.     getmatrix(objmat);
  837. */
  838.  
  839.  
  840. /*    popmatrix(); */
  841. }
  842.  
  843.  
  844. draw_scene() {
  845.     czclear(0, 0);
  846.  
  847.     perspective(400, 5.0/4.0, 2.0, 6.0);
  848.     loadmatrix(idmat);
  849.     translate(0.0, 0.0, -4.0);
  850.  
  851.     RGBcolor(0, 255, 0);
  852.     cmov(-1.3, -1.0, 1.0);
  853.     charstr(scorestr);
  854.     if (gameover) charstr(" Press 'G' for new game");
  855.  
  856.     lmbind(LIGHT0, 1);
  857.     lmbind(LMODEL, 1);
  858.  
  859.  
  860.  
  861. /*    multmatrix(objmat); */
  862.     polarview(0, azimuth, elevation, 0);
  863.  
  864.     /*
  865.      * At this point, we're ready to draw stuff in a cube centered at
  866.      * (0,0,0) and 2 units on a side.
  867.      */
  868.  
  869.     draw_grid();
  870.  
  871.     /*
  872.      * Now, I want to change coordinate axis to range from (0,0,0) to
  873.      * (SIZE,SIZE,SIZE).  This makes each position on a board a unit
  874.      * cube.
  875.      */
  876.  
  877.     translate(-1.0, -1.0, -1.0);
  878.     scale(2.0 / SIZE, 2.0 / SIZE, 2.0 / SIZE);
  879.  
  880.     makeobj(1);
  881.     closeobj();            /* Save these coordinates in an object. */
  882.  
  883.     
  884.     callobj(2);            /* Paint fallen pieces */
  885.  
  886.  
  887.     draw_piece();
  888.  
  889. #define FRAMES 100
  890.     if (debug) {
  891.     static long frames = 1000, lasttime;
  892.     if (++frames >= FRAMES) {
  893.         long t = time((long *) 0);
  894.         if (frames < 1000) {
  895.         fprintf(stderr, "%d frames/sec\n", frames / (t - lasttime));
  896.         }
  897.         lasttime = t;
  898.         frames = 0;
  899.     }
  900.     }
  901.  
  902.  
  903.     swapbuffers();
  904. }
  905.  
  906.  
  907. float cube_vtx[8][3] = {
  908.  
  909.     {0.5, 0.5, -0.5,},
  910.     {0.5, -0.5, -0.5,},
  911.     {-0.5, -0.5, -0.5,},
  912.     {-0.5, 0.5, -0.5,},
  913.     {0.5, 0.5, 0.5,},
  914.     {0.5, -0.5, 0.5,},
  915.     {-0.5, -0.5, 0.5,},
  916.     {-0.5, 0.5, 0.5,},
  917. };
  918.  
  919. float normals[6][3] = {
  920.     {0.0, 0.0, -1.0},
  921.     {1.0, 0.0, 0.0},
  922.     {0.0, 1.0, 0.0},
  923.     {0.0, 0.0, 1.0},
  924.     {-1.0, 0.0, 0.0},
  925.     {0.0, -1.0, 0.0},
  926. };
  927.     
  928.  
  929. /* Drws the playing grid. */
  930.  
  931.  
  932. float wallface[4][3] = {
  933.     {1.0, 1.0, -1.0},
  934.     {1.0, -1.0, -1.0},
  935.     {1.0, -1.0, 1.0},
  936.     {1.0, 1.0, 1.0},
  937. };
  938. float wallnormal[3] = {-1.0, 0.0, 0.0};
  939.     
  940.  
  941.  
  942.  
  943. draw_grid() {
  944.     int i, j;
  945.     Coord x, z;
  946.  
  947.     zbuffer(FALSE);
  948.     
  949.     pushmatrix();
  950.     lmbind(MATERIAL, 1);
  951.     for (i=0 ; i<5 ; i++) {
  952.     bgnpolygon();
  953.     n3f(wallnormal);
  954.     v3f(wallface[0]);
  955.     v3f(wallface[1]);
  956.     v3f(wallface[2]);
  957.     v3f(wallface[3]);
  958.     endpolygon();
  959.     if (i < 3) rotate(900, 'z');
  960.     else if (i == 3) rotate(900, 'y');
  961.     }
  962.  
  963.     popmatrix();
  964.     
  965.     zbuffer(TRUE);
  966.     
  967.     pushmatrix();
  968.  
  969.     RGBcolor(0, 0, 255);
  970.     for (i=0 ; i<2 ; i++) {
  971.     for (j=0 ; j<=SIZE ; j++) {
  972.         x = ((float) j) / (SIZE / 2.0) - 1.0;
  973.         move(x, 1.0, 1.0);
  974.         draw(x, 1.0, -1.0);
  975.         draw(x, -1.0, -1.0);
  976.         draw(x, -1.0, 1.0);
  977.     }
  978.     if (i == 0) rotate(900, 'z');
  979.     }
  980.  
  981.     for (j=0 ; j<=SIZE ; j++) {
  982.     move(-1.0, -1.0, -1.0);
  983.     draw(1.0, -1.0, -1.0);
  984.     draw(1.0, 1.0, -1.0);
  985.     draw(-1.0, 1.0, -1.0);
  986.     draw(-1.0, -1.0, -1.0);
  987.     translate(0.0, 0.0, 2.0 / SIZE);
  988.     }
  989.     
  990.  
  991.     popmatrix();
  992. }
  993.         
  994.     
  995.  
  996.  
  997.  
  998. #define D 0.1            /* Bevel size */
  999.  
  1000. float bevel_vtx[11][3] = {
  1001.     /* Cube face */
  1002.     {0.5, 0.0, 0.0},
  1003.     {0.5, 0.5 - D, 0.0},
  1004.     {0.5, 0.5 - D, 0.5 - D},
  1005.     {0.5, 0.0, 0.5 - D},
  1006.  
  1007.     /* Edge face (Bevel) */
  1008.     {0.5, 0.5 - D, 0.0},
  1009.     {0.5 - D, 0.5, 0.0},
  1010.     {0.5 - D, 0.5, 0.5 - D},
  1011.     {0.5, 0.5 - D, 0.5 - D},
  1012.  
  1013.     /* Vertex face (Bevel) */
  1014.  
  1015.     {0.5, 0.5 - D, 0.5 - D},
  1016.     {0.5 - D, 0.5, 0.5 - D},
  1017.     {0.5 - D, 0.5 - D, 0.5},    /* Wrong, but it will work... */
  1018. };
  1019.  
  1020. float bevel_normals[3][3] = {
  1021.     {1.0, 0.0, 0.0},
  1022.     {0.70710678, 0.70710678, 0.0},        /* = 1/sqrt(2) */
  1023.     {0.57735027, 0.57735027, 0.57735027},    /* = 1/sqrt(3) */
  1024. };
  1025.  
  1026. #undef D
  1027.  
  1028.  
  1029. float face[4][3];
  1030.  
  1031. #define M 0.45
  1032.  
  1033. float flatface[4][3] =  {
  1034.     {M, M, M},
  1035.     {M, -M, M},
  1036.     {M, -M, -M},
  1037.     {M, M, -M},
  1038. };
  1039.  
  1040. #undef M
  1041.  
  1042. #define E 0.5
  1043. #define M 0.4
  1044. #define Z 0.0
  1045.  
  1046. float bevelface[4][3] = {
  1047.     {E, M, M},
  1048.     {E, -M, M},
  1049.     {E, -M, -M},
  1050.     {E, M, -M},
  1051. };
  1052.  
  1053.  
  1054. float edge[4][3] = {
  1055.     {E, M, -M},
  1056.     {M, E, -M},
  1057.     {M, E, M},
  1058.     {E, M, M},
  1059. };
  1060.  
  1061. float vertex[3][3] = {
  1062.     {E, M, M},
  1063.     {M, E, M},
  1064.     {M, M, E},
  1065. };
  1066.  
  1067. float norms[3][3] = {
  1068.     {1.0, 0.0, 0.0},
  1069.     {0.70710678, 0.70710678, 0.0},        /* = 1/sqrt(2) */
  1070.     {0.57735027, 0.57735027, 0.57735027},    /* = 1/sqrt(3) */
  1071. };
  1072.  
  1073. #undef E
  1074. #undef M
  1075. #undef Z
  1076.  
  1077.  
  1078.  
  1079. mydoone(float *x, float *y) {
  1080.     float t = *x;
  1081.     *x = - *y;
  1082.     *y = t;
  1083. }
  1084.  
  1085. myrotit(float obj[][3], int size, char dir) {
  1086.     int i;
  1087.     for (i=0 ; i<size ; i++) {
  1088.     switch (dir) {
  1089.       case 'x':
  1090.         mydoone(&(obj[i][1]), &(obj[i][2]));
  1091.         break;
  1092.       case 'y':
  1093.         mydoone(&(obj[i][2]), &(obj[i][0]));
  1094.         break;
  1095.       case 'z':
  1096.         mydoone(&(obj[i][0]), &(obj[i][1]));
  1097.         break;
  1098.     }
  1099.     }
  1100. }
  1101.  
  1102.  
  1103. myrot(float obj[][3], int size, char dir) {
  1104.     myrotit(obj, size, dir);
  1105.     myrotit(norms, 3, dir);
  1106. }
  1107.     
  1108.  
  1109. copyvector(float a[3], float b[3]) {
  1110.     int i;
  1111.     for (i=0 ; i<3 ; i++) a[i] = b[i];
  1112. }
  1113.  
  1114.  
  1115. float useface[6][4][3];
  1116. float useedge[12][4][3];
  1117. float usevertex[8][4][3];
  1118.  
  1119. float facenorm[6][3];
  1120. float edgenorm[12][3];
  1121. float vertexnorm[8][3];
  1122.  
  1123. /* Draws a cube, a unit on a side, centered at (0, 0, 0). */
  1124.  
  1125. define_cube() {
  1126.     int i, j, k, cur;
  1127.  
  1128.  
  1129.     for (i=0 ; i<4 ; i++) {
  1130.     for (j=0 ; j<3 ; j++) {
  1131.         face[i][j] = usebevels ? bevelface[i][j] : flatface[i][j];
  1132.     }
  1133.     }
  1134.  
  1135.     cur = 0;
  1136.     for (i=0 ; i<4 ; i++) {
  1137.     copyvector(facenorm[cur], norms[0]);
  1138.     for (j=0; j<4; j++) {
  1139.         copyvector(useface[cur][j], face[j]);
  1140.     }
  1141.     cur++;
  1142.     myrot(face, 4, 'z');
  1143.     }
  1144.     myrot(face, 4, 'y');
  1145.     copyvector(facenorm[cur], norms[0]);
  1146.     for (j=0; j<4; j++) {
  1147.     copyvector(useface[cur][j], face[j]);
  1148.     }
  1149.     cur++;
  1150.     myrot(face, 4, 'y');
  1151.     myrot(face, 4, 'y');
  1152.  
  1153.     copyvector(facenorm[cur], norms[0]);
  1154.     for (j=0; j<4; j++) {
  1155.     copyvector(useface[cur][j], face[j]);
  1156.     }
  1157.     cur++;
  1158.     
  1159.     myrot(face, 4, 'y');
  1160.  
  1161.     cur = 0;
  1162.  
  1163.  
  1164.     for (i=0 ; i<3 ; i++) {
  1165.     for (j=0 ; j<4 ; j++) {
  1166.         copyvector(edgenorm[cur], norms[1]);
  1167.         for (k=0; k<4; k++) {
  1168.         copyvector(useedge[cur][k], edge[k]);
  1169.         }
  1170.         cur++;
  1171.         myrot(edge, 4, 'y');
  1172.     }
  1173.     myrot(edge, 4, 'x');
  1174.     }
  1175.     myrot(edge, 4, 'x');
  1176.  
  1177.     cur = 0;
  1178.  
  1179.     for (i=0 ; i<2 ; i++) {
  1180.     for (j=0 ; j<4 ; j++) {
  1181.         copyvector(vertexnorm[cur], norms[2]);
  1182.         for (k=0; k<3; k++) {
  1183.         copyvector(usevertex[cur][k], vertex[k]);
  1184.         }
  1185.         cur++;
  1186.         myrot(vertex, 3, 'y');
  1187.  
  1188.     }
  1189.     myrot(vertex, 3, 'x');
  1190.     myrot(vertex, 3, 'x');
  1191.     }
  1192. }
  1193.     
  1194. draw_cube(int x, int y, int z) {
  1195.  
  1196.     int i;
  1197.  
  1198. #define ISEMPTY(a, b, c) \
  1199.     (!usebevels || a < 0 || a >= SIZE || b < 0 || b >= SIZE || \
  1200.      c < 0 || c >= SIZE || board[a][b][c] == 0)
  1201.  
  1202. #define FACE(i)    {        \
  1203.     bgnpolygon();        \
  1204.     n3f(facenorm[i]);    \
  1205.     v3f(useface[i][0]);    \
  1206.     v3f(useface[i][1]);    \
  1207.     v3f(useface[i][2]);    \
  1208.     v3f(useface[i][3]);    \
  1209.     endpolygon();        \
  1210.     }
  1211.     
  1212.     if (ISEMPTY(x+1, y, z)) FACE(0);
  1213.     if (ISEMPTY(x, y+1, z)) FACE(1);
  1214.     if (ISEMPTY(x-1, y, z)) FACE(2);
  1215.     if (ISEMPTY(x, y-1, z)) FACE(3);
  1216.     if (ISEMPTY(x, y, z-1)) FACE(4);
  1217.     if (ISEMPTY(x, y, z+1)) FACE(5);
  1218.     
  1219.  
  1220.     if (usebevels) {
  1221.     for (i=0 ; i<12 ; i++) {
  1222.         bgnpolygon();
  1223.         n3f(edgenorm[i]);
  1224.         v3f(useedge[i][0]);
  1225.         v3f(useedge[i][1]);
  1226.         v3f(useedge[i][2]);
  1227.         v3f(useedge[i][3]);
  1228.         endpolygon();
  1229.     }
  1230.     for (i=0 ; i<8 ; i++) {
  1231.         bgnpolygon();
  1232.         n3f(vertexnorm[i]);
  1233.         v3f(usevertex[i][0]);
  1234.         v3f(usevertex[i][1]);
  1235.         v3f(usevertex[i][2]);
  1236.         endpolygon();
  1237.     }
  1238.     }
  1239.  
  1240. /*
  1241.     int i, j, k;
  1242.     pushmatrix();
  1243.  
  1244. #define FACE \
  1245.     bgnpolygon();    \
  1246.     n3f(norms[0]);    \
  1247.     v3f(face[0]);    \
  1248.     v3f(face[1]);    \
  1249.     v3f(face[2]);    \
  1250.     v3f(face[3]);    \
  1251.     endpolygon();
  1252.  
  1253.     for (i=0 ; i<4 ; i++) {
  1254.     FACE;
  1255.     rotate(900, 'z');
  1256.     }
  1257.     rotate(900, 'y');
  1258.     FACE;
  1259.     rotate(1800, 'y');
  1260.  
  1261.     FACE;
  1262.     
  1263.  
  1264. #undef FACE
  1265.  
  1266.     popmatrix();
  1267.     pushmatrix();
  1268.  
  1269. #define EDGE    \
  1270.     bgnpolygon();    \
  1271.     n3f(norms[0]);    \
  1272.     v3f(edge[0]);    \
  1273.     v3f(edge[1]);    \
  1274.      v3f(edge[2]);    \
  1275.     v3f(edge[3]);    \
  1276.     endpolygon();
  1277.  
  1278.  
  1279.     for (i=0 ; i<3 ; i++) {
  1280.     for (j=0 ; j<4 ; j++) {
  1281.         EDGE;
  1282.         rotate(900, 'y');
  1283.     }
  1284.     rotate(900, 'x');
  1285.     }
  1286.  
  1287. #undef EDGE
  1288.  
  1289.     popmatrix();
  1290.  
  1291. #define VERTEX    \
  1292.     bgnpolygon();    \
  1293.     n3f(norms[0]);    \
  1294.     v3f(vertex[0]);    \
  1295.     v3f(vertex[1]);    \
  1296.     v3f(vertex[2]);    \
  1297.     endpolygon();
  1298.  
  1299.     for (i=0 ; i<2 ; i++) {
  1300.     for (j=0 ; j<4 ; j++) {
  1301.         VERTEX;
  1302.         rotate(900, 'y');
  1303.  
  1304.     }
  1305.     rotate(1800, 'x');
  1306.     }
  1307.  
  1308. #undef VERTEX
  1309.  
  1310. */
  1311. /*
  1312.     for (i=0 ; i<2 ; i++) {
  1313.     for (j=0 ; j<4 ; j++) {
  1314.         for (k=0 ; k<3 ; k++) {
  1315.         bgnpolygon();
  1316.         n3f(bevel_normals[0]);
  1317.         v3f(bevel_vtx[0]);
  1318.         v3f(bevel_vtx[1]);
  1319.         v3f(bevel_vtx[2]);
  1320.         v3f(bevel_vtx[3]);
  1321.         endpolygon();
  1322.  
  1323.         bgnpolygon();
  1324.         n3f(bevel_normals[1]);
  1325.         v3f(bevel_vtx[4]);
  1326.         v3f(bevel_vtx[5]);
  1327.         v3f(bevel_vtx[6]);
  1328.         v3f(bevel_vtx[7]);
  1329.         endpolygon();
  1330.  
  1331.         bgnpolygon();
  1332.         n3f(bevel_normals[2]);
  1333.         v3f(bevel_vtx[8]);
  1334.         v3f(bevel_vtx[9]);
  1335.         v3f(bevel_vtx[10]);
  1336.         endpolygon();
  1337.  
  1338.         rotate(900, 'z');
  1339.         rotate(900, 'y');
  1340.         }
  1341.         rotate(900, 'y');
  1342.     }
  1343.     rotate(1800, 'x');
  1344.     }
  1345.  
  1346. */
  1347.  
  1348.  
  1349.  
  1350. /*
  1351.     bgnpolygon();
  1352.     n3f(normals[0]);
  1353.     v3f(cube_vtx[0]);
  1354.     v3f(cube_vtx[1]);
  1355.     v3f(cube_vtx[2]);
  1356.     v3f(cube_vtx[3]);
  1357.     endpolygon();
  1358.  
  1359.     bgnpolygon();
  1360.     n3f(normals[1]);
  1361.     v3f(cube_vtx[0]);
  1362.     v3f(cube_vtx[4]);
  1363.     v3f(cube_vtx[5]);
  1364.     v3f(cube_vtx[1]);
  1365.     endpolygon();
  1366.  
  1367.     bgnpolygon();
  1368.     n3f(normals[2]);
  1369.     v3f(cube_vtx[0]);
  1370.     v3f(cube_vtx[3]);
  1371.     v3f(cube_vtx[7]);
  1372.     v3f(cube_vtx[4]);
  1373.     endpolygon();
  1374.  
  1375.     bgnpolygon();
  1376.     n3f(normals[3]);
  1377.     v3f(cube_vtx[7]);
  1378.     v3f(cube_vtx[6]);
  1379.     v3f(cube_vtx[5]);
  1380.     v3f(cube_vtx[4]);
  1381.     endpolygon();
  1382.  
  1383.     bgnpolygon();
  1384.     n3f(normals[4]);
  1385.     v3f(cube_vtx[7]);
  1386.     v3f(cube_vtx[3]);
  1387.     v3f(cube_vtx[2]);
  1388.     v3f(cube_vtx[6]);
  1389.     endpolygon();
  1390.  
  1391.     bgnpolygon();
  1392.     n3f(normals[5]);
  1393.     v3f(cube_vtx[1]);
  1394.     v3f(cube_vtx[5]);
  1395.     v3f(cube_vtx[6]);
  1396.     v3f(cube_vtx[2]);
  1397.     endpolygon();
  1398. */
  1399. /*
  1400.     lmbind(LMODEL, 0);
  1401.     RGBcolor(255, 255, 255);
  1402.  
  1403.     bgnclosedline();
  1404.     v3f(cube_vtx[0]);
  1405.     v3f(cube_vtx[1]);
  1406.     v3f(cube_vtx[2]);
  1407.     v3f(cube_vtx[3]);
  1408.     endclosedline();
  1409.  
  1410.     bgnclosedline();
  1411.     v3f(cube_vtx[4]);
  1412.     v3f(cube_vtx[5]);
  1413.     v3f(cube_vtx[6]);
  1414.     v3f(cube_vtx[7]);
  1415.     endclosedline();
  1416.  
  1417.     bgnline();
  1418.     v3f(cube_vtx[0]);
  1419.     v3f(cube_vtx[4]);
  1420.     endline();
  1421.  
  1422.     bgnline();
  1423.     v3f(cube_vtx[1]);
  1424.     v3f(cube_vtx[5]);
  1425.     endline();
  1426.  
  1427.     bgnline();
  1428.     v3f(cube_vtx[2]);
  1429.     v3f(cube_vtx[6]);
  1430.     endline();
  1431.  
  1432.     bgnline();
  1433.     v3f(cube_vtx[3]);
  1434.     v3f(cube_vtx[7]);
  1435.     endline();
  1436.  
  1437.     RGBcolor(255, 0, 0);
  1438.     str[1] = 0;
  1439.     for (i=0 ; i<8 ; i++) {
  1440.     cmov(cube_vtx[i][0], cube_vtx[i][1], cube_vtx[i][2]);
  1441.     str[0] = i + '0';
  1442.     charstr(str);
  1443.     }
  1444. */
  1445. }
  1446.  
  1447.  
  1448. draw_piece() {
  1449.     int i;
  1450.     Shape *s;
  1451.     if (curpiece == NULL) return;
  1452.     s = curpiece->shapes + curshape;
  1453.     pushmatrix();
  1454.     translate(curx / 2.0 + 0.5, cury / 2.0 + 0.5, curz / 2.0 + 0.5);
  1455.     rot(currot, 'z');
  1456.     lmbind(MATERIAL, curpiece->material);
  1457.     for (i=0 ; i<4 ; i++) {
  1458.     pushmatrix();
  1459.     translate((*s)[i][0] / 2.0, (*s)[i][1] / 2.0, (*s)[i][2] / 2.0);
  1460.     draw_cube(-5, -5, -5);
  1461.     popmatrix();
  1462.     }
  1463.     popmatrix();
  1464.     setpattern(HALFTONE);
  1465.     RGBcolor(0, 0, 0);
  1466.     for (i=0 ; i<4 ; i++) {
  1467.     int x, y, z;
  1468.     Coord fx, fy, fz;
  1469.     getgridloc(i, &x, &y, &z);
  1470.     fx = x;
  1471.     fy = y;
  1472.     fz = height[x][y] + 0.05;
  1473.  
  1474.     pmv(fx, fy, fz);
  1475.     pdr(fx + 1.0, fy, fz);
  1476.     pdr(fx + 1.0, fy + 1.0, fz);
  1477.     pdr(fx, fy + 1.0, fz);
  1478.     pdr(fx, fy, fz);
  1479.     pclos();
  1480.  
  1481.     
  1482.     }
  1483.     setpattern(0);
  1484. }
  1485.     
  1486.     
  1487.  
  1488.  
  1489.  
  1490.  
  1491. /*
  1492.  
  1493. static short qbuf[50];
  1494. static long num;
  1495. static int ptr;
  1496.  
  1497. static long nextqueue(short* val) {
  1498.  
  1499.     short dev;
  1500.  
  1501.     if (ptr>=num) {
  1502.     ptr = 0;
  1503.     num = blkqread(qbuf, 50);
  1504.  
  1505.     if (qbuf[ptr]==MOUSEX && qbuf[ptr+2]==MOUSEY) {
  1506.         ptr += 4;
  1507.         while (ptr+4<num && qbuf[ptr+4]==MOUSEX && qbuf[ptr+6]==MOUSEY) {
  1508.         ptr+=4;
  1509.         }
  1510.     }
  1511.  
  1512.     }
  1513.  
  1514.     dev = qbuf[ptr];
  1515.     *val = qbuf[ptr+1];
  1516.     ptr+=2;
  1517.  
  1518.     return (long)dev;
  1519. }
  1520.  
  1521. static long nextqtest() {
  1522.     if (ptr < num) return qbuf[ptr];
  1523.     return qtest();
  1524. }
  1525.  
  1526. */
  1527.