home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / TETRIS.ZIP / Tetris2.cc < prev   
C/C++ Source or Header  |  1997-01-30  |  22KB  |  609 lines

  1. /**********************************************************
  2.  *  T E T R I S v1.0
  3.  *  programming and graphics Andrew Deren
  4.  *
  5.  *  1 / 30 / 97
  6.  **********************************************************/
  7.  
  8. //inlucde files
  9. #include <stdio.h>
  10. #include <allegro.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <time.h>
  14. #include <dir.h>
  15. #include "tdat.h"    //header file for data file created by grabber
  16.  
  17. //high score stucture name not implemented yet
  18. struct HiScoreStruct {
  19.     int score;
  20.    char name[12];
  21. };
  22.  
  23. //musics used from tdat.dat
  24. int Music[3] = {MUSIC01, MUSIC02, MUSIC03};
  25. int start_level;            //start from level selected under options
  26. int start_blocks;            //number of initial rows on the map
  27. int block[4][4];            //current block
  28. int next_block;            //next block to be put
  29. int map[10][20];            //map
  30. int block_x, block_y;    //location of the block
  31. int x_size, y_size;        //size of the block
  32. volatile int timer;        //timer of the game
  33. int current_block;        //current block type
  34. int speed;                    //speed of the game
  35. int score, dels;            //game score and number of rows deleted
  36. char text[256];            //some text used for using textout
  37. struct HiScoreStruct HiScore;        //high score
  38. int current_music;        //music currently played
  39. BITMAP *map_buffer;        //double buffer for map displaying
  40. DATAFILE *graphics;        //data file with graphics and sounds
  41. BITMAP *temp_bitmap;        //temp 640x480 bitmap used by options and initial screens
  42. int MusicVolume;            //current volume of the music
  43. int SoundVolume;            //current volume of the sounds
  44. bool soundOn;                //sounds on or not
  45. bool musicOn;                //music on or not
  46.  
  47. //function prototypes
  48. int Random(int x);
  49. void IncrementTimer(...);
  50. void DeleteRow(void);
  51. int CanPut(void);
  52. void NewGame(void);
  53. void SetVolume(void);
  54. void PlayGame(void);
  55. void DrawVolume(int pos);
  56. void SetVolume(void);
  57. void Error(char *);
  58. void InitGame(void);
  59. void ClearBlock(void);
  60. void GenerateBlock(int);
  61. void DrawFrame(void);
  62. void GenerateNew(void);
  63. void PutBlock(void);
  64. void RotateBlock(void);
  65. void DrawMap(void);
  66. void NewGame(void);
  67. void DrawMenu(void);
  68. void MainMenu(void);
  69. void PlayGame(void);
  70.  
  71. //returns random number up to x-1
  72. int Random(int x) {return random() % x;}
  73.  
  74. //increment game timer
  75. void IncrementTimer(...)
  76. {
  77.      timer++;
  78. }
  79. END_OF_FUNCTION(IncrementTimer);
  80.  
  81. //draw the options screen with cursor at pos
  82. void DrawVolume(int pos)
  83. {
  84.      clear(temp_bitmap);    //clear temp bitmap
  85.    text_mode(-1);            //set transparent text mode
  86.    //set drawing mode to pattern from datafile
  87.    drawing_mode(DRAW_MODE_COPY_PATTERN, (BITMAP*)graphics[PATTERN].dat, 0, 0);
  88.    //fill the temp buffer
  89.    rectfill(temp_bitmap, 0, 0, 640, 480, 0);
  90.    //put some text
  91.    textout(temp_bitmap, font, "O P T I O N S", 140, 10, 36);
  92.    textout(temp_bitmap, font, "Sound: ", 100, 50, 36);
  93.    textout(temp_bitmap, font, "Music: ", 100, 100, 36);
  94.  
  95.    if (soundOn) textout(temp_bitmap, font, " On", 250, 50, 36);
  96.    else textout(temp_bitmap, font, "Off", 250, 50, 36);
  97.    if (musicOn) textout(temp_bitmap, font, " On", 250, 100, 36);
  98.    else textout(temp_bitmap, font, "Off", 250, 100, 36);
  99.  
  100.     sprintf(text, "Sound Volume: %4d", SoundVolume);
  101.    textout(temp_bitmap, font, text, 150, 130, 36);
  102.    sprintf(text, "Music Volume: %4d", MusicVolume);
  103.    textout(temp_bitmap, font, text, 150, 180, 36);
  104.    sprintf(text, "Start Level: %4d", start_level);
  105.    textout(temp_bitmap, font, text, 150, 230, 36);
  106.    sprintf(text, "Start Blocks: %4d", start_blocks);
  107.    textout(temp_bitmap, font, text, 150, 280, 36);
  108.    //draw all the scorlbars
  109.    for (int i=0; i<10; i++) {
  110.         draw_sprite(temp_bitmap, (BITMAP*)graphics[BAR].dat, 106+i*25, 150);
  111.       draw_sprite(temp_bitmap, (BITMAP*)graphics[BAR].dat, 106+i*25, 200);
  112.       draw_sprite(temp_bitmap, (BITMAP*)graphics[BAR].dat, 106+i*25, 250);
  113.       draw_sprite(temp_bitmap, (BITMAP*)graphics[BAR].dat, 106+i*25, 300);
  114.    }
  115.    draw_sprite(temp_bitmap, (BITMAP*)graphics[BAR2].dat, 100+SoundVolume, 150);
  116.    draw_sprite(temp_bitmap, (BITMAP*)graphics[BAR2].dat, 100+MusicVolume, 200);
  117.    draw_sprite(temp_bitmap, (BITMAP*)graphics[BAR2].dat, 100+start_level*25, 250);
  118.    draw_sprite(temp_bitmap, (BITMAP*)graphics[BAR2].dat, 100+start_blocks*25, 300);
  119.    draw_sprite(temp_bitmap, (BITMAP*)graphics[CURSOR].dat, 80, pos*50);
  120.    textout(temp_bitmap, font, "Press arrow keys to change, ESC to exit", 100, 400, 36);
  121.     blit(temp_bitmap, screen, 0, 0, 0, 0, 640, 480);
  122. }
  123.  
  124. //options screen
  125. void SetVolume(void)
  126. {
  127.      int ch;
  128.    int position = 1;
  129.    DrawVolume(1);
  130.     do {
  131.          if (keypressed()) {
  132.             ch = readkey();
  133.          if ((ch >> 8) == KEY_DOWN) {position++; if (position == 7) position = 1;}
  134.           else if ((ch >> 8) == KEY_UP) {position--; if (position == 0) position = 6;}
  135.          else if ( ((ch >> 8) == KEY_RIGHT) || ((ch >>8) == KEY_LEFT)){
  136.               if (position == 1) {if (soundOn) soundOn = FALSE; else soundOn = TRUE;}
  137.              else if (position == 2) {if (musicOn) musicOn = FALSE; else musicOn = TRUE;}
  138.             else if (position == 3) {
  139.                   if ((ch >> 8) == KEY_RIGHT) {
  140.                      SoundVolume+= 25;
  141.                   if (SoundVolume > 255) SoundVolume=255;
  142.                }
  143.                 else {SoundVolume-=25;if (SoundVolume < 0) SoundVolume=0;}
  144.             }
  145.             else if (position == 4) {
  146.                   if ((ch >> 8) == KEY_RIGHT) {
  147.                      MusicVolume+= 25;
  148.                   if (MusicVolume > 255) MusicVolume=255;
  149.                }
  150.                 else {MusicVolume-=25; if (MusicVolume < 0) MusicVolume = 0;}
  151.             }
  152.              else if (position == 5) {
  153.                if ((ch >> 8) == KEY_RIGHT) {
  154.                      start_level++;
  155.                   if (start_level > 10) start_level = 10;
  156.                }
  157.                 else {start_level--; if (start_level < 0) start_level = 0;}
  158.             }
  159.              else if ( position == 6) {
  160.                   if ((ch >> 8) == KEY_RIGHT) {
  161.                      start_blocks++;
  162.                   if (start_blocks > 10) start_blocks = 10;
  163.                 }
  164.                 else {start_blocks--; if (start_blocks < 0) start_blocks = 0;}
  165.             }
  166.          } //end key up or down
  167.           else if ((ch >> 8) == KEY_ESC) break;
  168.          DrawVolume(position);
  169.       }//end keypressed;
  170.    }while (1==1);
  171.     set_volume(SoundVolume, MusicVolume);
  172.     clear(screen);
  173. }
  174.  
  175. void Error(char *string)
  176. {
  177.      allegro_exit();
  178.      printf("Error: %s\n", string);
  179.    exit(1);
  180. }
  181.  
  182. void InitGame(void)
  183. {
  184.       allegro_init();              //initialize allegro
  185.    install_keyboard();      //install keyboard handler
  186.    install_timer();            //install timer
  187.    set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0);    //set graphics mode to 640x480x256
  188.     srandom((int)time(NULL));
  189.    if (install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, NULL) != 0)
  190.         Error("Error initializing sound.");
  191.    if (!file_exists("tdat.dat", FA_RDONLY | FA_ARCH, NULL))
  192.        Error("Cannot find tdat.dat file.");
  193.     graphics = load_datafile("tdat.dat");    //load graphics
  194.       map_buffer = create_bitmap(200, 400);    //create double buffer
  195.    temp_bitmap = create_bitmap(640, 480);
  196.    timer = 0;
  197.    LOCK_FUNCTION(IncrementTimer);
  198.    LOCK_VARIABLE(timer);
  199.    install_int(IncrementTimer, 20);
  200.    speed = 15;
  201.    set_clip(map_buffer, 0, 0, 200, 400);
  202.    score = 0;
  203.    dels = 1;
  204.       FILE *file = fopen("tetris.hsc", "rb");
  205.     if (file) {
  206.        fread(&HiScore, sizeof(struct HiScoreStruct), 1, file);
  207.       fclose(file);
  208.    }
  209.       else {
  210.          HiScore.score = 0;
  211.       strcpy(HiScore.name, "Unknown");
  212.    }
  213.     font = (FONT*)graphics[TECH_FONT].dat;
  214.    soundOn = TRUE;
  215.    musicOn = TRUE;
  216.    SoundVolume = 180;
  217.    MusicVolume = 180;
  218.    set_volume(SoundVolume, MusicVolume);
  219.    start_level = 0;
  220.    start_blocks = 0;
  221.    current_music = Random(3);
  222.    set_pallete(black_pallete);
  223. }
  224.  
  225. void DrawFrame(void)
  226. {
  227.      draw_sprite(screen, (BITMAP*)graphics[WALL03].dat, 80, 20);
  228.    draw_sprite(screen, (BITMAP*)graphics[WALL04].dat, 300, 20);
  229.    draw_sprite(screen, (BITMAP*)graphics[WALL05].dat, 80, 440);
  230.    draw_sprite(screen, (BITMAP*)graphics[WALL06].dat, 300, 440);
  231.  
  232.    draw_sprite(screen, (BITMAP*)graphics[WALL03].dat, 340, 20);
  233.    draw_sprite(screen, (BITMAP*)graphics[WALL04].dat, 580, 20);
  234.    draw_sprite(screen, (BITMAP*)graphics[WALL05].dat, 340, 100);
  235.    draw_sprite(screen, (BITMAP*)graphics[WALL06].dat, 580, 100);
  236.  
  237.    draw_sprite(screen, (BITMAP*)graphics[WALL03].dat, 340, 140);
  238.    draw_sprite(screen, (BITMAP*)graphics[WALL04].dat, 440, 140);
  239.    draw_sprite(screen, (BITMAP*)graphics[WALL05].dat, 340, 200);
  240.    draw_sprite(screen, (BITMAP*)graphics[WALL06].dat, 440, 200);
  241.  
  242.    for (int i=0; i<11; i++) {
  243.       draw_sprite(screen, (BITMAP*)graphics[WALL01].dat, 360+i*20, 20);
  244.       draw_sprite(screen, (BITMAP*)graphics[WALL01].dat, 360+i*20, 100);
  245.    }
  246.     for (int i=0; i<3; i++) {
  247.       draw_sprite(screen, (BITMAP*)graphics[WALL02].dat, 340, 40+i*20);
  248.       draw_sprite(screen, (BITMAP*)graphics[WALL02].dat, 580, 40+i*20);
  249.  
  250.     }
  251.     for (int i=0; i<4; i++) {
  252.       draw_sprite(screen, (BITMAP*)graphics[WALL01].dat, 360+i*20, 140);
  253.       draw_sprite(screen, (BITMAP*)graphics[WALL01].dat, 360+i*20, 200);
  254.    }
  255.    for (int i=0; i<10; i++) {
  256.         draw_sprite(screen, (BITMAP*)graphics[WALL01].dat, 100+i*20, 20);
  257.       draw_sprite(screen, (BITMAP*)graphics[WALL01].dat, 100+i*20, 440);
  258.    }
  259.     for (int i=0; i<2; i++) {
  260.       draw_sprite(screen, (BITMAP*)graphics[WALL02].dat, 340, 160+i*20);
  261.       draw_sprite(screen, (BITMAP*)graphics[WALL02].dat, 440, 160+i*20);
  262.    }
  263.     for (int i=0; i<20; i++) {
  264.          draw_sprite(screen, (BITMAP*)graphics[WALL02].dat, 80, 40+i*20);
  265.       draw_sprite(screen, (BITMAP*)graphics[WALL02].dat, 300, 40+i*20);
  266.    }
  267. }
  268.  
  269. void ClearBlock(void)
  270. {
  271.      for (int i=0; i<4; i++)  for (int j=0; j<4; j++) block[i][j] = 0;
  272. }
  273.  
  274. void GenerateBlock(int kind)
  275. {
  276.      ClearBlock();
  277.     switch (kind) {
  278.     case  1: block[1][0] = block[2][0] = block[0][1] = block[1][1] = 1; break;
  279.    case 11: block[0][0] = block[0][1] = block[1][1] = block[1][2] = 1; break;
  280.    case 21: block[1][0] = block[2][0] = block[0][1] = block[1][1] = 1; break;
  281.    case 31: block[0][0] = block[0][1] = block[1][1] = block[1][2] = 1; break;
  282.  
  283.    case  2:    block[0][0] = block[1][0] = block[1][1] = block[2][1] = 1; break;
  284.     case 12:    block[1][0] = block[1][1] = block[0][1] = block[0][2] = 1; break;
  285.     case 22:    block[0][0] = block[1][0] = block[1][1] = block[2][1] = 1; break;
  286.     case 32:    block[1][0] = block[1][1] = block[0][1] = block[0][2] = 1; break;
  287.  
  288.     case  3: block[0][0] = block[0][1] = block[1][0] = block[1][1] = 1; break;
  289.     case 13: block[0][0] = block[0][1] = block[1][0] = block[1][1] = 1; break;
  290.     case 23: block[0][0] = block[0][1] = block[1][0] = block[1][1] = 1; break;
  291.     case 33: block[0][0] = block[0][1] = block[1][0] = block[1][1] = 1; break;
  292.  
  293.     case  4: block[1][0] = block[0][1] = block[1][1] = block[2][1] = 1; break;
  294.     case 14: block[0][0] = block[0][1] = block[0][2] = block[1][1] = 1; break;
  295.    case 24: block[0][0] = block[1][0] = block[2][0] = block[1][1] = 1; break;
  296.    case 34: block[0][1] = block[1][0] = block[1][1] = block[1][2] = 1; break;
  297.  
  298.    case  5: block[2][0] = block[0][1] = block[1][1] = block[2][1] = 1; break;
  299.    case 15: block[0][0] = block[0][1] = block[0][2] = block[1][2] = 1; break;
  300.    case 25: block[0][0] = block[1][0] = block[2][0] = block[0][1] = 1; break;
  301.     case 35: block[0][0] = block[1][0] = block[1][1] = block[1][2] = 1; break;
  302.  
  303.     case  6: block[0][0] = block[0][1] = block[1][1] = block[2][1] = 1; break;
  304.     case 16: block[0][0] = block[1][0] = block[0][1] = block[0][2] = 1; break;
  305.    case 26: block[0][0] = block[1][0] = block[2][0] = block[2][1] = 1; break;
  306.    case 36: block[1][0] = block[1][1] = block[1][2] = block[0][2] = 1; break;
  307.  
  308.    case  7: block[0][0] = block[1][0] = block[2][0] = block[3][0] = 1; break;
  309.     case 17: block[0][0] = block[0][1] = block[0][2] = block[0][3] = 1; break;
  310.    case 27: block[0][0] = block[1][0] = block[2][0] = block[3][0] = 1; break;
  311.     case 37: block[0][0] = block[0][1] = block[0][2] = block[0][3] = 1; break;
  312.     default: Error("Unknown element to be generated."); break;
  313.     }
  314.  
  315.    if ((kind == 7) || (kind == 27)) {x_size = 4; y_size = 1; }
  316.     else if ((kind == 17) || (kind == 37)) {x_size = 1; y_size = 4;}
  317.     else if (kind % 10 == 3) {x_size = 2; y_size = 2; }
  318.     else if ((kind / 10 == 0) || (kind / 10 == 2)) {x_size = 3; y_size = 2;}
  319.     else if ((kind / 10 == 1) || (kind / 10 == 3)) {x_size = 2; y_size = 3;}
  320.    current_block = kind;
  321. }
  322.  
  323. void GenerateNew(void)
  324. {
  325.     int temp = next_block;
  326.    next_block = Random(7)+1;
  327.    GenerateBlock(next_block);
  328.     for (int i=0; i<4; i++) {
  329.       for (int j=0; j<2; j++) {
  330.          if (block[i][j] == 1)
  331.                draw_sprite(screen, (BITMAP*)graphics[BLOCK].dat, 360+i*20, 160+j*20);
  332.             else draw_sprite(screen, (BITMAP*)graphics[EMPTY].dat, 360+i*20, 160+j*20);
  333.         }
  334.       }
  335.     GenerateBlock(temp);
  336.    block_x = 3;
  337.    block_y = 0;
  338.    if (!CanPut()) {
  339.       text_mode(-1);
  340.       textout_centre(screen, font, "G A M E", 202, 152, 42);
  341.         textout_centre(screen, font, "G A M E", 200, 150, 15);
  342.       textout_centre(screen, font, "O V E R", 202, 202, 42);
  343.       textout_centre(screen, font, "O V E R", 200, 200, 15);
  344.         textout_centre(screen, (FONT*)graphics[GAME_FONT].dat, "Press Enter to", 202, 252, 42);
  345.         textout_centre(screen, (FONT*)graphics[GAME_FONT].dat, "to start a new game", 202, 277, 42);
  346.       textout_centre(screen, (FONT*)graphics[GAME_FONT].dat, "Press Enter to", 200, 250, 15);
  347.       textout_centre(screen, (FONT*)graphics[GAME_FONT].dat, "to start a new game", 200, 275, 15);
  348.       sprintf(text, "%3d", score);
  349.       textout_centre(screen, (FONT*)graphics[GAME_FONT].dat, text, 202, 302, 42);
  350.       textout_centre(screen, (FONT*)graphics[GAME_FONT].dat, text, 200, 300, 15);
  351.         clear_keybuf();
  352.         do {
  353.             if (key[KEY_ENTER]) break;
  354.       } while (1==1);
  355.        clear_keybuf();
  356.       NewGame();
  357.    }
  358. }
  359.  
  360. void PutBlock(void)
  361. {
  362.    for (int i=0; i<4; i++) {
  363.       for (int j=0; j<4; j++) {
  364.          if (block[i][j] == 1)
  365.              map[block_x+i][block_y+j] = block[i][j];
  366.       }
  367.    }
  368.     if (soundOn) play_sample((SAMPLE*)graphics[MOVE_SOUND].dat, SoundVolume, 125, 1000, FALSE);
  369.     DeleteRow();
  370. }
  371.  
  372. void RotateBlock(void)
  373. {
  374.      int old_block = current_block;
  375.      current_block += 10;
  376.    if (current_block > 40) current_block -= 40;
  377.    GenerateBlock(current_block);
  378.    if (!CanPut())  {
  379.          current_block = old_block;
  380.       GenerateBlock(current_block);
  381.    }
  382. }
  383.  
  384.  
  385. int CanPut(void)
  386. {
  387.     for (int i=0; i<4; i++) {
  388.         for (int j=0; j<4; j++) {
  389.             if (block[i][j] == 1) {
  390.            if (block_x + i > 9) return FALSE;
  391.            if (block_x + i < 0) return FALSE;
  392.            if (block_y + j > 19) return FALSE;
  393.            if (map[block_x+i][block_y+j] == 1) return FALSE;
  394.          }
  395.         }
  396.    }
  397.     return TRUE;
  398. }
  399.  
  400.  
  401. void DrawMap(void)
  402. {
  403.      clear(map_buffer);
  404.     for (int i=0; i<10; i++) {
  405.          for (int j=0; j<20; j++) {
  406.          if (map[i][j] == 1)
  407.                draw_sprite(map_buffer, (BITMAP*)graphics[BLOCK].dat, i*20, j*20);
  408.       }
  409.    }
  410.     for (int i=0; i<4; i++) {
  411.       for (int j=0; j<4; j++) {
  412.          if (block[i][j] == 1)
  413.                draw_sprite(map_buffer, (BITMAP*)graphics[BLOCK].dat, block_x*20+i*20, block_y*20+j*20);
  414.  
  415.          }
  416.    }
  417.     blit(map_buffer, screen, 0, 0, 100, 40, 200, 400);
  418.    text_mode(0);
  419.    sprintf(text, "%7d", score);
  420.    textout(screen, font, text, 570-text_length(font, text), 50, 15);
  421.    sprintf(text, "%7d", dels / 10);
  422.    textout(screen, font, text, 570-text_length(font, text), 65, 15);
  423. }
  424.  
  425. void DeleteRow(void)
  426. {
  427.      int sum, i, j, del = 0;
  428.     for (i=19; i>=0; i--) {
  429.       sum = 0;
  430.       for (j=0; j<10; j++) sum += map[j][i];
  431.         if (sum == 10) {
  432.             for (j=i; j>=1; j--) for (int k=0; k<10; k++) map[k][j] = map[k][j-1];
  433.          i += 2;
  434.          del++;
  435.         }
  436.    }
  437.     if (del > 0)
  438.          if (soundOn)
  439.             play_sample((SAMPLE*)graphics[DELETE_SOUND].dat, SoundVolume, 125, 1000, FALSE);
  440.    dels += del;
  441.    if (del > 0) score += (100*del)+((del-1)*25)+(dels/10)*25;
  442.    speed = 25-(dels/10)*2;
  443.    if (speed < 2) speed = 2;
  444. }
  445.  
  446. void NewGame(void)
  447. {
  448.      if (score > HiScore.score) HiScore.score = score;
  449.      for (int i=0; i<20; i++)
  450.       for (int j=0; j<10; j++) map[j][i] = 0;
  451.    score = 0;
  452.    next_block = Random(7)+1;
  453.    GenerateNew();
  454.    DrawMap();
  455.    dels = start_level*10;
  456.    speed = 25-(dels/10)*2;
  457.    text_mode(0);
  458.    sprintf(text, "Score:");
  459.    textout(screen, font, text, 365, 50, 15);
  460.    sprintf(text, "Level:");
  461.    textout(screen, font, text, 365, 65, 15);
  462.    sprintf(text, "High Score: ");
  463.    textout(screen, font, text, 365, 80, 15);
  464.    sprintf(text, "%7d", HiScore.score);
  465.    textout(screen, font, text, 570-text_length(font, text), 80, 15);
  466.    for (int i=0; i<start_blocks; i++) {
  467.       for (int j=0; j<10; j++) {
  468.          if (Random(2)) map[j][19-i] = 1;
  469.       }
  470.    }
  471.     timer = 0;
  472. }
  473.  
  474. void DrawMenu(int pos)
  475. {
  476.      text_mode(-1);
  477.     clear(temp_bitmap);
  478.    drawing_mode(DRAW_MODE_COPY_PATTERN, (BITMAP*)graphics[PATTERN].dat, 0, 0);
  479.    rectfill(temp_bitmap, 0, 0, 640, 480, 0);
  480.    draw_sprite(temp_bitmap, (BITMAP*)graphics[TITLE].dat, 170, 10);
  481.    textout(temp_bitmap, font, "N E W  G A M E", 100, 200, 36);
  482.    textout(temp_bitmap, font, "N E W  G A M E", 101, 201, 1);
  483.    textout(temp_bitmap, font, "O P T I O N S", 100, 250, 36);
  484.    textout(temp_bitmap, font, "O P T I O N S", 101, 251, 1);
  485.    textout(temp_bitmap, font, "E X I T", 100, 300, 36);
  486.    textout(temp_bitmap, font, "E X I T", 101, 301, 1);
  487.    draw_sprite(temp_bitmap, (BITMAP*)graphics[CURSOR].dat, 80, (pos-1)*50+200);
  488.     blit(temp_bitmap, screen, 0, 0, 0, 0, 640, 480);
  489. }
  490.  
  491. void MainMenu()
  492. {
  493.      int ch;
  494.    int pos = 1;
  495.      DrawMenu(1);
  496.    fade_in((RGB*)graphics[GAME_PALLETE].dat, 2);             //fade in slowly
  497.    do {
  498.          if (keypressed()) {
  499.             ch = readkey();
  500.          if ((ch >> 8) == KEY_UP) {pos--; if (pos == 0) pos = 3;}
  501.          else if ((ch >>8) == KEY_DOWN) {pos++; if (pos==4) pos=1;}
  502.          else if ((ch >> 8) == KEY_ENTER) {
  503.                if (pos == 1) {
  504.                   PlayGame();
  505.             }
  506.             else if (pos == 2)
  507.                   SetVolume();
  508.             else if (pos == 3)
  509.                   break;
  510.          }
  511.           else if ((ch >> 8) == KEY_ESC) break;
  512.           DrawMenu(pos);
  513.       } // end if keypressed
  514.    } while (1==1);
  515.     fade_out(1);
  516.    if (musicOn) stop_midi();
  517. }
  518.  
  519. void PlayGame(void)
  520. {
  521.      int ch;
  522.    rectfill(screen, 0, 0, 640, 480, 0);
  523.    DrawFrame();
  524.    drawing_mode(DRAW_MODE_SOLID, NULL, 0, 0);
  525.    rectfill(screen, 360, 40, 580, 100, 0);
  526.    current_music = Random(3);
  527.    if (musicOn) play_midi((MIDI*)graphics[Music[current_music]].dat, TRUE);
  528.    draw_sprite(screen, (BITMAP*)graphics[TETRIS].dat, 340, 300);
  529.    NewGame();
  530.    while (1==1) {
  531.          if (keypressed()) {
  532.          ch = readkey();
  533.              if ((ch >> 8) == KEY_LEFT) {block_x--; if (!CanPut()) block_x++;
  534.          }
  535.             if ((ch >> 8) == KEY_RIGHT) {block_x++; if (!CanPut()) block_x--;
  536.             }
  537.           if ((ch >> 8) == KEY_UP)   RotateBlock();
  538.           if ((ch >> 8) == KEY_DOWN) {
  539.                while (CanPut()) {DrawMap();    block_y++;
  540.             };
  541.              block_y--;
  542.          }
  543.           if ((ch >> 8) == KEY_F2) NewGame();
  544.          else if ((ch >> 8) == KEY_F5) {
  545.             if (musicOn) {
  546.                   stop_midi();
  547.                current_music++;
  548.                if (current_music > 2) current_music = 0;
  549.                play_midi((MIDI*)graphics[Music[current_music]].dat, TRUE);
  550.             }
  551.          }
  552.            else if ((ch >> 8) == KEY_ESC) {
  553.            text_mode(-1);
  554.            textout(screen, font, "Do you really want", 125, 200, 15);
  555.            textout(screen, font, "to quit? (Y/N)", 125, 225, 15);
  556.            if ((ch = readkey()) >> 8 == KEY_Y)  break;
  557.          }
  558.           else if ((ch >> 8) == KEY_F12){
  559.                BITMAP* bmp;
  560.             bmp = create_sub_bitmap(screen, 0, 0, SCREEN_W, SCREEN_H);
  561.             save_pcx("tetdat.pcx", bmp, (RGB*)graphics[GAME_PALLETE].dat);
  562.             destroy_bitmap(bmp);
  563.          }
  564.             clear_keybuf();
  565.       }
  566.         if (timer > speed) {
  567.            block_y++;
  568.          if (!CanPut()) {block_y--;  PutBlock();  GenerateNew();
  569.          }
  570.           timer = 0;
  571.       }
  572.       if (!CanPut()) {PutBlock(); GenerateNew();
  573.       }
  574.       DrawMap();
  575.    }
  576.     stop_midi();
  577. }
  578.  
  579.  
  580. main()
  581. {
  582.      InitGame();
  583.    MainMenu();
  584.     allegro_exit();
  585.    FILE *file;
  586.    file = fopen("tetris.hsc", "wt");
  587.    if (file) {
  588.          fwrite(&HiScore, sizeof(struct HiScoreStruct), 1, file);
  589.       fclose(file);
  590.    }
  591.     printf("                             Ader Software 1997                        \n");
  592.    printf("                             T E T R I S   v1.0                        \n");
  593.    printf(" --------------------------------------------------------------------- \n");
  594.    printf("                         Programing and Graphics by                    \n");
  595.    printf("                              Andrew     Deren                         \n");
  596.    printf("                             aderen@eecs.uic.edu                       \n");
  597.    printf("           http://www.eecs.uic.edu/~aderen/ader/main.html         \n");
  598.    printf(" --------------------------------------------------------------------- \n");
  599.    printf("                            Special Thanks To:                         \n");
  600.    printf("                      DJ Delorie - for making DJGPP                    \n");
  601.    printf("           Shawn Hargreaves - for making allegro game library          \n");
  602.    printf("              and all the other people who contributed to              \n");
  603.    printf("                 DJGPP development tools and utilities.                \n");
  604.    printf(" --------------------------------------------------------------------- \n");
  605.    printf("\n\n\n");
  606. }
  607.  
  608.  
  609.