home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / pascal / rehack / demosrc / dungeon2.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-28  |  12.0 KB  |  353 lines

  1. //---------------------------------------------------------------------------
  2. //
  3. //      File:           DUNGEON2.CPP
  4. //      Path:           ...\REHACK\graphics
  5. //      Version:                1.1 (first C++ version)
  6. //      Author:         Written by Chris Lampton, 5/26/91
  7. //                      modified 6/26/93 by Dave Boynton
  8. //                      All art by Mike Barrs
  9. //      CIS Id:
  10. //      Created On:     6/26/93
  11. //      Modified On:    6/28/93
  12. //      Description:    Demonstrates tile scrolling through a dungeon
  13. //      requires:       duntil4b.grf & mbs08-b.grf in current directory.
  14. //      Tabs:           4
  15. //
  16. //---------------------------------------------------------------------------
  17. // All contents copyright (c) 1991,1993 by the GAMERS Programming Workshop.
  18.  
  19. // A brief note on data structures:
  20. //   This program is oriented around two arrays that contain two
  21. // different forms of a 48 by 48 tile dungeon map. The first array,
  22. // dungeon[], contains a description of the dungeon in terms of
  23. // "quadtiles," each of which is constructed out of four of the
  24. // small tiles contained in the file DUNTIL4B.GRF, arranged in a
  25. // square. See the #defines below for a list of the 18 types of big
  26. // tile. During initialization, this array is translated into a
  27. // second array, dungeon2[], which contains a description of the
  28. // dungeon in terms of the actual small tiles used on the screen.
  29. // This system, which may or may not be used in the final version
  30. // of REHACK, facilitates dungeon design while allowing more versa-
  31. // tile use of the tile set.
  32.  
  33. //6/28/93 dgb: this quadtile approach has not been modified in this C++
  34. //              version, however, the underlying tiles are now Bitmaps.
  35. //
  36.  
  37. #include <alloc.h>
  38. #include <conio.h>
  39. #include <dos.h>
  40. #include <stdio.h>
  41. #include <stdlib.h>
  42. #include "..\general\types.hpp"
  43. #include "..\graphics\display.hpp"
  44. #include "..\graphics\bitmap.hpp"
  45.  
  46. #define  TILE_NUM 39                    // Number of small tiles
  47. #define  TILE_HEIGHT 21                 // Height of small tile in pixels
  48. #define  TILE_WIDTH 21                  // Width of small tile in pixels
  49. #define  QUAD_TILE_NUM 18               // Number of quadtiles
  50. #define  QUAD_TILE_WIDTH TILE_WIDTH*2   // Width of quadtile in pixels
  51. #define  QUAD_TILE_HEIGHT TILE_HEIGHT*2 // Height of quadtile in pixels
  52. #define  WIND_WIDTH 7                   // Width of dungeon window in small tiles
  53. #define  WIND_HEIGHT 7                  // Height of dungeon window in small tiles
  54. #define  DUNGEON_WIDTH 48               // Width of dungeon map in small tiles
  55. #define  DUNGEON_HEIGHT 48              // Height of dungeon map in small tiles
  56. #define  SCROLL_RATE 21                 // Number of pixels scrolled per frame
  57.  
  58. Point windowStart={10,8}; //I know, I know, this is just a demo ...<g>
  59.  
  60. // The following #defines represent the 18 types of "quadtiles," each
  61. // constructed out of four small tiles, that are the basic building blocks
  62. // of the dungeon in this program.
  63.  
  64. #define  UL 0        // Upper left corner
  65. #define  UR 1        // Upper right corner
  66. #define  FL 2        // Floor
  67. #define  LL 3        // Lower left corner
  68. #define  LR 4        // Lower right corner
  69. #define  HO 5        // Horizontal wall
  70. #define  VE 6        // Vertical wall
  71. #define  NT 7        // North 't' intersection
  72. #define  ST 8        // South 't' intersection
  73. #define  WT 9        // West 't' intersection
  74. #define  ET 10       // East 't' intersection
  75. #define  NE 11       // North wall end
  76. #define  SE 12       // South wall end
  77. #define  WE 13       // West wall end
  78. #define  EE 14       // East wall end
  79. #define  CC 15       // Central cross
  80. #define  HD 16       // Horizontal door
  81. #define  VD 17       // Vertical door
  82.  
  83. // Function prototypes:
  84.  
  85. void translate();
  86. int  load_screen(Canvas &);
  87. void draw_window(Canvas &,int,int,int,int);
  88. void draw_tile(Canvas &,int,int,int,int,int,int,int);
  89.  
  90. Bitmap *tile[TILE_NUM];      // Array of tile bitmaps
  91. byte colregs[3*256];                // Array of color register values
  92. char quadtile[QUAD_TILE_NUM][4]={       // Array of quadtile definitions for translate()
  93.     {0,10,3,4},
  94.     {1,2,6,7},
  95.     {5,5,5,5},
  96.     {8,9,13,14},
  97.     {11,12,15,16},
  98.     {10,10,15,15},
  99.     {3,12,3,12},
  100.     {26,10,6,4},
  101.     {17,9,15,15},
  102.     {19,9,3,4},
  103.     {24,12,6,12},
  104.     {18,2,3,7},
  105.     {25,12,13,27},
  106.     {20,10,13,14},
  107.     {22,2,15,23},
  108.     {21,9,6,4},
  109.     {10,10,29,30},
  110.     {3,32,3,33}
  111. };
  112.  
  113. // Dungeon map defined in terms of quadtiles (see above):
  114.  
  115. char dungeon[DUNGEON_HEIGHT/2][DUNGEON_WIDTH/2]={
  116.     {UL,HO,HO,HO,HO,HO,HO,HO,HO,HO,HO,HO,HO,HO,HO,HO,HO,HO,HO,NT,HO,HO,HO,UR},
  117.     {VD,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,VE,FL,FL,FL,VE},
  118.     {VE,FL,UL,HO,HO,HO,HO,UR,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,WT,HO,UR,FL,VE},
  119.     {VE,FL,VE,FL,FL,FL,FL,VE,FL,FL,UL,HO,HO,HO,HO,HO,HO,UR,FL,VE,FL,VE,FL,VE},
  120.     {VE,FL,VD,FL,FL,FL,FL,VE,FL,FL,VE,FL,FL,FL,FL,FL,FL,VE,FL,VE,FL,SE,FL,VE},
  121.     {VE,FL,VE,FL,FL,FL,FL,VE,FL,FL,VE,FL,FL,FL,FL,FL,FL,VE,FL,VE,FL,FL,FL,VE},
  122.     {VE,FL,LL,HO,HO,HO,HO,LR,FL,FL,LL,HO,UR,FL,FL,UL,HO,LR,FL,VE,FL,NE,FL,VE},
  123.     {VE,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,VE,FL,FL,VE,FL,FL,FL,VE,FL,VE,FL,VE},
  124.     {VE,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,VE,FL,FL,VE,FL,FL,FL,WT,HO,LR,FL,VE},
  125.     {VE,FL,UL,HO,HO,HO,UR,FL,FL,FL,FL,FL,VE,FL,FL,VE,FL,UL,HO,ET,FL,FL,FL,VE},
  126.     {VE,FL,VE,FL,FL,FL,LL,HO,UR,FL,FL,FL,LL,HO,HD,LR,FL,VE,FL,VE,FL,FL,FL,VE},
  127.     {VE,FL,VE,FL,FL,FL,FL,FL,VE,FL,FL,FL,FL,FL,FL,FL,FL,VE,FL,LL,UR,FL,FL,VE},
  128.     {VE,FL,VE,FL,FL,FL,FL,FL,VE,FL,FL,FL,FL,UL,HO,HO,HO,ET,FL,FL,LL,EE,FL,VE},
  129.     {VE,FL,LL,HO,HD,HO,HO,HO,LR,FL,FL,FL,FL,VE,FL,FL,FL,LL,HO,EE,FL,FL,FL,VE},
  130.     {VE,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,VE,FL,NE,FL,FL,FL,FL,FL,FL,FL,VE},
  131.     {VE,FL,UL,HO,HD,UR,FL,FL,FL,FL,FL,FL,FL,WT,HO,LR,FL,WE,HO,NT,HO,UR,FL,VE},
  132.     {VE,FL,VE,FL,FL,LL,HO,UR,FL,FL,FL,FL,FL,VD,FL,FL,FL,FL,FL,VE,FL,VE,FL,VE},
  133.     {VE,FL,VE,FL,FL,FL,FL,VE,FL,FL,FL,FL,FL,VE,FL,FL,FL,FL,FL,VE,FL,VE,FL,VE},
  134.     {VE,FL,LL,HO,UR,FL,FL,LL,HO,UR,FL,FL,FL,WT,HO,HO,HO,UR,FL,VE,FL,VE,FL,VE},
  135.     {VE,FL,FL,FL,VE,FL,FL,FL,FL,VD,FL,FL,FL,VE,FL,FL,FL,VE,FL,VE,FL,VE,FL,VE},
  136.     {VE,FL,FL,FL,VE,FL,FL,FL,FL,VE,FL,FL,FL,VE,FL,NE,FL,VE,FL,VE,FL,VE,FL,VE},
  137.     {VE,FL,FL,FL,LL,HO,HO,HO,HO,LR,FL,FL,FL,VE,FL,LL,HO,ST,HO,LR,FL,SE,FL,VE},
  138.     {VE,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,VE,FL,FL,FL,FL,FL,FL,FL,FL,FL,VE},
  139.     {LL,HO,HO,HO,HO,HO,HO,HO,HO,HO,HO,HO,HO,ST,HO,HO,HO,HO,HO,HO,HO,HO,HO,LR},
  140. };
  141.  
  142. char dungeon2[DUNGEON_HEIGHT][DUNGEON_WIDTH]; // Array for small tile map
  143.  
  144. #pragma argsused
  145. int main(int argc, char *argv[])
  146. {
  147.     int     i,row=0,column=0,xoff,yoff;
  148.     char    ch;
  149.     FILE    *fp;
  150.     //
  151.     DisplayManager  display(0); //try display(1) to disable waiting for the
  152.                                 //retraces, no significant speedup on my
  153.                                 //machine, but no screen-trashing either!
  154.     Canvas theCanvas(display); // returns a full-screen canvas
  155.  
  156.     //set the window Rect
  157.     theCanvas.clipRect.topLeft=windowStart;
  158.     theCanvas.clipRect.bottomRight.x=WIND_WIDTH*TILE_WIDTH+windowStart.x;
  159.     theCanvas.clipRect.bottomRight.y=WIND_HEIGHT*TILE_HEIGHT+windowStart.y;
  160.     //now paints won't affect the whole screen, err.. I hope
  161.     //
  162.  
  163.    // Open file containing bitmaps for tiles
  164.  
  165.     if ( (fp=fopen("duntil4b.grf","rb")) == NULL )
  166.     {
  167.         printf("Cannot open file \"duntil4b.grf\"\n");
  168.         exit(1);
  169.     }
  170.     display.setMode(0x13); // Set graphics mode to 13h
  171.  
  172.    // Load palette from file into colregs[]
  173.     for (i=0; i<(3*256); i++)
  174.         colregs[i]=getc(fp);
  175.     display.setPalette(colregs);  // Set palette to palette in tile file
  176.  
  177.    // Load tiles into tile[]
  178.     for (i=0; i<TILE_NUM; i++)
  179.     {
  180.         tile[i]=new Bitmap(TILE_WIDTH, TILE_HEIGHT);
  181.         tile[i]->load(fp); //assumes the file has the bitmaps sequentially,
  182.                            //not like PCX, which will be different.
  183.     }
  184.     fclose(fp);
  185.  
  186.     translate();   // Translate quadtiles into small tiles
  187.  
  188.     if (!load_screen(theCanvas)) // Load background screen into graphics buffer
  189.     {
  190.         display.setMode(3);
  191.         fprintf(stderr,"Couldn't load the background screen\n");
  192.         exit(1);
  193.     }
  194.     draw_window(theCanvas,0,0,0,0); // Draw initial contents of dungeon window in graphics buffer
  195.     display.putCanvas(theCanvas);   // Move graphics buffer to the screen
  196.  
  197.    // Main program loop
  198.    // Waits for cursor arrow to be pressed, then scrolls dungeon window
  199.  
  200.     do
  201.     {
  202.        ch=getch();
  203.        if (ch==0)
  204.        {
  205.          ch=getch();
  206.          switch (ch)
  207.          {
  208.            case 72: // Up arrow, so scroll up
  209.               if (row>0)
  210.               {
  211.                  --row;
  212.                  for (yoff=(TILE_HEIGHT-SCROLL_RATE);
  213.                       yoff>0; yoff-=SCROLL_RATE)
  214.                     draw_window(theCanvas,column,row,0,yoff);
  215.                  display.putCanvas(theCanvas);
  216.               }
  217.               break;
  218.  
  219.            case 80: // Down arrow, so scroll down
  220.               if (row<(DUNGEON_HEIGHT-WIND_HEIGHT))
  221.               {
  222.                  for (yoff=SCROLL_RATE; yoff<TILE_HEIGHT; yoff+=SCROLL_RATE)
  223.                     draw_window(theCanvas,column,row,0,yoff);
  224.                  display.putCanvas(theCanvas);
  225.                  row++;
  226.               }
  227.               break;
  228.  
  229.            case 75: // Left arrow, so scroll left
  230.               if (column>0)
  231.               {
  232.                  --column;
  233.                  for (xoff=TILE_WIDTH-SCROLL_RATE; xoff>0; xoff-=SCROLL_RATE)
  234.                     draw_window(theCanvas,column,row,xoff,0);
  235.                  display.putCanvas(theCanvas);
  236.               }
  237.               break;
  238.  
  239.            case 77: // Right arrow, so scroll right
  240.               if (column<(DUNGEON_WIDTH-WIND_WIDTH))
  241.               {
  242.                  for (xoff=SCROLL_RATE; xoff<TILE_WIDTH; xoff+=SCROLL_RATE)
  243.                     draw_window(theCanvas,column,row,xoff,0);
  244.                  display.putCanvas(theCanvas);
  245.                  column++;
  246.               }
  247.               break;
  248.  
  249.          } // end switch (ch)
  250.          draw_window(theCanvas,column,row,0,0);
  251.          display.putCanvas(theCanvas);
  252.        } /* end if (ch==0) */
  253.     } while (ch!=27);  // Terminate if ESC pressed
  254.     display.setMode(3);        // Restore DOS screen mode
  255.     return 0;
  256. }
  257.  
  258. // translate()
  259. // Translates dungeon array from quadtile format in dungeon[] to
  260. // small tile format in dungeon2[].
  261. void translate()
  262. {
  263.     int     x,y;
  264.  
  265.    // Translate quadtiles to small tiles
  266.  
  267.     for (x=0;x<DUNGEON_WIDTH/2;x++)
  268.         for (y=0;y<DUNGEON_HEIGHT/2;y++) {
  269.             dungeon2[y*2][x*2]=quadtile[dungeon[y][x]][0];
  270.             dungeon2[y*2][x*2+1]=quadtile[dungeon[y][x]][1];
  271.             dungeon2[y*2+1][x*2]=quadtile[dungeon[y][x]][2];
  272.             dungeon2[y*2+1][x*2+1]=quadtile[dungeon[y][x]][3];
  273.         }
  274.  
  275.    // Add corners of doors to tiles next to door tiles
  276.  
  277.     for (x=0;x<DUNGEON_WIDTH/2;x++)
  278.         for (y=0;y<DUNGEON_HEIGHT/2;y++) {
  279.             if (dungeon[y][x]==HD) dungeon2[y*2+1][x*2-1]=28;
  280.             if (dungeon[y][x]==VD) dungeon2[y*2+2][x*2+1]=34;
  281.         }
  282. }
  283.  
  284. // load_screen()
  285. // Loads background screen from disk into screen_buffer[]
  286. int load_screen(Canvas &aCanvas)
  287. {
  288.     unsigned int i;
  289.     FILE *fp;
  290.  
  291.     if ((fp=fopen("mbs08-b.grf","rb"))==NULL) {
  292.        return 0;
  293.     }
  294.     for (i=0; i<(3*256); i++) getc(fp);
  295.     for (i=0; i<64000U; i++)
  296.         aCanvas.pixels[i]=(unsigned char)getc(fp);
  297.     fclose(fp);
  298.     return 1;
  299. }
  300.  
  301. // draw_window(int xtile,int ytile,int xoff,int yoff)
  302.  
  303. // Draws dungeon window with dimensions (in small tiles) of WIND_WIDTH,
  304. // WIND_HEIGHT at screen coordinates xpos, ypos. The first row and
  305. // column of tiles is offset by xoff, yoff pixels.
  306.  
  307. void draw_window(Canvas &aCanvas,int xtile,int ytile,int xoff,int yoff)
  308. {
  309.     int     x,y,xpos,ypos,xoff1,yoff1,xext,yext;
  310.  
  311.     for (x=0; x<(WIND_WIDTH+1);x++)
  312.         for (y=0; y<(WIND_HEIGHT+1);y++) {
  313.             xpos= (x==0) ? windowStart.x : windowStart.x+x*TILE_WIDTH-xoff;
  314.             ypos= (y==0) ? windowStart.y : windowStart.y+y*TILE_HEIGHT-yoff;
  315.             if (x==0) {
  316.                 xoff1=xoff;
  317.                 xext=TILE_WIDTH-xoff;
  318.             }
  319.             else {
  320.                 xoff1=0;
  321.                 xext=TILE_WIDTH;
  322.             };
  323.             if (y==0) {
  324.                 yoff1=yoff;
  325.                 yext=TILE_HEIGHT-yoff;
  326.             }
  327.             else {
  328.                 yoff1=0;
  329.                 yext=TILE_HEIGHT;
  330.             };
  331.             if (x==WIND_WIDTH) xext=xoff;
  332.             if (y==WIND_HEIGHT) yext=yoff;
  333.             if (!( ((x==WIND_WIDTH)&&(xoff==0)) ||
  334.                    ((y==WIND_HEIGHT)&&(yoff==0)) ))
  335.             {
  336.                 draw_tile(aCanvas,(int)dungeon2[ytile+y][xtile+x],
  337.                           xpos,ypos,xoff1,yoff1,xext,yext);
  338.             }
  339.         }
  340. }
  341.  
  342. // draw_tile(int tnum,int xpos,int ypos,int xoff,int yoff,int xext,int yext)
  343. // Draw xext,yext pixels of tile tnum starting at pixel xoff,yoff at
  344. // screen coordinates xpos,ypos
  345. #pragma argsused
  346. void draw_tile(Canvas &aCanvas,int tnum,int xpos,int ypos,
  347.                                     int xoff,int yoff,int xext,int yext)
  348. {
  349.     Point at= { xpos, ypos };
  350.     tile[tnum]->paint(aCanvas, at);
  351. }
  352.  
  353.