home *** CD-ROM | disk | FTP | other *** search
- //---------------------------------------------------------------------------
- //
- // File: DUNGEON2.CPP
- // Path: ...\REHACK\graphics
- // Version: 1.2
- // Author: Written by Chris Lampton, 5/26/91
- // modified from 6/26/93 on by Dave Boynton
- // All art by Mike Barrs
- // CIS Id: (Dave Boynton) 71043,317
- // Created On: 6/26/93
- // Modified On: 7/25/93
- // Description: Demonstrates tile scrolling through a dungeon and
- // the use of the display, bitmap, and pcx256 classes.
- // requires: duntiles.pcx, rehack.pcx, and rehack.pal.
- // (in the current directory)
- //
- // Tabs: 4
- //
- //---------------------------------------------------------------------------
- // copyright (c) 1991,1993 by the GAMERS Forum, Rehack project team.
- // All rights reserved.
-
- // A brief note on data structures:
- // This program is oriented around two arrays that contain two
- // different forms of a 48 by 48 tile dungeon map. The first array,
- // dungeon[], contains a description of the dungeon in terms of
- // "quadTiles," each of which is constructed out of four of the
- // small tiles contained in the file DUNTIL4B.GRF, arranged in a
- // square. See the #defines below for a list of the 18 types of big
- // tile. During initialization, this array is translated into a
- // second array, dungeon2[], which contains a description of the
- // dungeon in terms of the actual small tiles used on the screen.
- // This system, which may or may not be used in the final version
- // of REHACK, facilitates dungeon design while allowing more versa-
- // tile use of the tile set.
-
- //6/28/93 dgb: this quadTile approach has not been modified in this C++
- // version, however, the underlying tiles are now Bitmaps.
- //7/21/93 dgb: converted data files to pcx, and implemented pcx/vga/img
- // support.
- //
-
- #include <alloc.h>
- #include <conio.h>
- #include <dos.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <malloc.h>
- #include "..\general\types.hpp"
- #include "..\graphics\display.hpp"
- #include "..\graphics\bitmap.hpp"
- #include "..\graphics\pcx.hpp"
-
- // this data is depend on the images in duntiles.pcx
- const word
- tileNum=40, // Number of small tiles
- tileHeight=21, // Height of small tile in pixels
- tileWidth=21, // Width of small tile in pixels
- blankTile=39;
- const Point tileSize={tileWidth,tileHeight};
- const word scrollRate=tileWidth; // should be set to something that can be
- // evenly divided into both tileWidth & tileHeight
-
- // the code in this file is flexible enough so you can move the window
- // around just be changing the constants here.
- const Point windowStart={8,6};
- const Point windowEnd={ 159, 157 };
- const Rect windowRect( windowStart, windowEnd );
- const word windWidth= ((windowEnd.x - windowStart.x - 1)/tileWidth) + 1;
- const word windHeight= ((windowEnd.y - windowStart.y - 1)/tileHeight) + 1;
-
- // the "quad tile" approach is useful for "architecture", unnecessary for
- // anything else.
- #define quadTileNum 18 // Number of quadTiles
- #define quadTileWidth tileWidth*2 // Width of quadTile in pixels
- #define quadTileHeight tileHeight*2 // Height of quadTile in pixels
- #define DUNGEON_WIDTH 48 // Width of dungeon map in small tiles
- #define DUNGEON_HEIGHT 48 // Height of dungeon map in small tiles
-
- // The following #defines represent the 18 types of "quadTiles," each
- // constructed out of four small tiles, that are the basic building blocks
- // of the dungeon in this program.
- #define UL 0 // Upper left corner
- #define UR 1 // Upper right corner
- #define FL 2 // Floor
- #define LL 3 // Lower left corner
- #define LR 4 // Lower right corner
- #define HO 5 // Horizontal wall
- #define VE 6 // Vertical wall
- #define NT 7 // North 't' intersection
- #define ST 8 // South 't' intersection
- #define WT 9 // West 't' intersection
- #define ET 10 // East 't' intersection
- #define NE 11 // North wall end
- #define SE 12 // South wall end
- #define WE 13 // West wall end
- #define EE 14 // East wall end
- #define CC 15 // Central cross
- #define HD 16 // Horizontal door
- #define VD 17 // Vertical door
- char quadTile[quadTileNum][4]={ // Array of quadTile definitions for translate()
- {0,10,3,4},
- {1,2,6,7},
- {5,5,5,5},
- {8,9,13,14},
- {11,12,15,16},
- {10,10,15,15},
- {3,12,3,12},
- {26,10,6,4},
- {17,9,15,15},
- {19,9,3,4},
- {24,12,6,12},
- {18,2,3,7},
- {25,12,13,27},
- {20,10,13,14},
- {22,2,15,23},
- {21,9,6,4},
- {10,10,29,30},
- {3,32,3,33}
- };
- // Dungeon map defined in terms of quadTiles (see above):
- char dungeon[DUNGEON_HEIGHT/2][DUNGEON_WIDTH/2]={
- {UL,HO,HO,HO,HO,HO,HO,HO,HO,HO,HO,HO,HO,HO,HO,HO,HO,HO,HO,NT,HO,HO,HO,UR},
- {VD,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,VE,FL,FL,FL,VE},
- {VE,FL,UL,HO,HO,HO,HO,UR,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,WT,HO,UR,FL,VE},
- {VE,FL,VE,FL,FL,FL,FL,VE,FL,FL,UL,HO,HO,HO,HO,HO,HO,UR,FL,VE,FL,VE,FL,VE},
- {VE,FL,VD,FL,FL,FL,FL,VE,FL,FL,VE,FL,FL,FL,FL,FL,FL,VE,FL,VE,FL,SE,FL,VE},
- {VE,FL,VE,FL,FL,FL,FL,VE,FL,FL,VE,FL,FL,FL,FL,FL,FL,VE,FL,VE,FL,FL,FL,VE},
- {VE,FL,LL,HO,HO,HO,HO,LR,FL,FL,LL,HO,UR,FL,FL,UL,HO,LR,FL,VE,FL,NE,FL,VE},
- {VE,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,VE,FL,FL,VE,FL,FL,FL,VE,FL,VE,FL,VE},
- {VE,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,VE,FL,FL,VE,FL,FL,FL,WT,HO,LR,FL,VE},
- {VE,FL,UL,HO,HO,HO,UR,FL,FL,FL,FL,FL,VE,FL,FL,VE,FL,UL,HO,ET,FL,FL,FL,VE},
- {VE,FL,VE,FL,FL,FL,LL,HO,UR,FL,FL,FL,LL,HO,HD,LR,FL,VE,FL,VE,FL,FL,FL,VE},
- {VE,FL,VE,FL,FL,FL,FL,FL,VE,FL,FL,FL,FL,FL,FL,FL,FL,VE,FL,LL,UR,FL,FL,VE},
- {VE,FL,VE,FL,FL,FL,FL,FL,VE,FL,FL,FL,FL,UL,HO,HO,HO,ET,FL,FL,LL,EE,FL,VE},
- {VE,FL,LL,HO,HD,HO,HO,HO,LR,FL,FL,FL,FL,VE,FL,FL,FL,LL,HO,EE,FL,FL,FL,VE},
- {VE,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,VE,FL,NE,FL,FL,FL,FL,FL,FL,FL,VE},
- {VE,FL,UL,HO,HD,UR,FL,FL,FL,FL,FL,FL,FL,WT,HO,LR,FL,WE,HO,NT,HO,UR,FL,VE},
- {VE,FL,VE,FL,FL,LL,HO,UR,FL,FL,FL,FL,FL,VD,FL,FL,FL,FL,FL,VE,FL,VE,FL,VE},
- {VE,FL,VE,FL,FL,FL,FL,VE,FL,FL,FL,FL,FL,VE,FL,FL,FL,FL,FL,VE,FL,VE,FL,VE},
- {VE,FL,LL,HO,UR,FL,FL,LL,HO,UR,FL,FL,FL,WT,HO,HO,HO,UR,FL,VE,FL,VE,FL,VE},
- {VE,FL,FL,FL,VE,FL,FL,FL,FL,VD,FL,FL,FL,VE,FL,FL,FL,VE,FL,VE,FL,VE,FL,VE},
- {VE,FL,FL,FL,VE,FL,FL,FL,FL,VE,FL,FL,FL,VE,FL,NE,FL,VE,FL,VE,FL,VE,FL,VE},
- {VE,FL,FL,FL,LL,HO,HO,HO,HO,LR,FL,FL,FL,VE,FL,LL,HO,ST,HO,LR,FL,SE,FL,VE},
- {VE,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,FL,VE,FL,FL,FL,FL,FL,FL,FL,FL,FL,VE},
- {LL,HO,HO,HO,HO,HO,HO,HO,HO,HO,HO,HO,HO,ST,HO,HO,HO,HO,HO,HO,HO,HO,HO,LR},
- };
- char dungeon2[DUNGEON_HEIGHT][DUNGEON_WIDTH]; // Array for small tile map
- // filled in by translate()
-
- // ------------- Function prototypes: -------------------------
- #define DebugMsg(b,s) { if (b) {\
- printf("%s/%u: %s\n",__FILE__,__LINE__,s); \
- getch(); } }
-
- void translate(); // convert the dungeon map into quad tiles
-
- void draw_window(Bitmap *,word,word,word,word); // draw the dungeon window
-
- void draw_tile(Bitmap *aBitmap,word tnum, Point &destAt, Point &srcOffset);
- // draw one tile in the dungeon window
-
- BitmapArray *tiles; // bitmap with all the tiles, from duntiles.pcx
- Bitmap *background; // background screen, from rehack.pcx
- byte colregs[3*256]; // Array of color register values, from rehack.pal
-
- FILE *debugFile=NULL; // will be "dungeon2.dbg", if opened
- bool doDebug=false;
-
- // ********************************************************************
- //
- //
- // ********************************************************************
- int main(int argc, char *argv[])
- {
- bool doRetrace, doDirect;
- doRetrace=doDirect=doDebug=false;
-
- while ( argc > 1 )
- {
- if ( ( *argv[1] == '/' ) || ( *argv[1] == '-' ) )
- {
- if ( *(argv[1]+1) == 'f' )
- doRetrace=true;
- if ( *(argv[1]+1) == 'b' )
- doDirect=true;
- if ( ( *(argv[1]+1) == 'd' ) &&
- ( (debugFile=fopen("dungeon2.dbg","w")) != NULL ) )
- {
- doDebug=true;
- fprintf(debugFile,"draw_window(,xtile,ytile,xoff,yoff)\n");
- fprintf(debugFile,"draw_tile(,tnum,xpos,ypos,xoff,yoff,xext,yext)\n");
- }
- }
- argc--;
- argv++;
- }
- translate(); // Translate quadTiles into small tiles
-
- DisplayManager display(doRetrace);
-
- // ------------------- read files rehack.pal, rehack.pcx -------------
- FILE *fp;
- // Load palette from file "rehack.pal" into colregs[]
- if ( (fp=fopen("rehack.pal","rb")) == NULL )
- {
- printf("Couldn't open 'rehack.pal'.\n");
- return 1;
- }
- if ( fread(&colregs,768,1,fp) != 1 )
- {
- fclose(fp);
- printf("Couldn't load 'rehack.pal'.\n");
- return 1;
- }
-
- display.setMode(0x13); // Set graphics mode to 13h
- display.blankScreen(); // avoid trashy display while loading
- display.setPalette(colregs); // Set palette to palette in tile file
-
- // ----------- load in background image ------------------
- background= new Bitmap("rehack.pcx");
- if ( doDebug )
- {
- assert( background->validFlag );
- assert( background->bits );
- assert(heapcheck() != _HEAPCORRUPT);
- }
- display.putBitmap(background);
- // now that we've displayed background, we could probably shuffle it out
- // to xms memory, since we won't use it that often.
-
- // -------------- Load tiles from duntiles.pcx ----------------
- tiles= new BitmapArray("duntiles.pcx", tileSize, 10, 4);
- if ( doDebug )
- {
- assert( tiles->validFlag );
- assert( tiles->bits );
- assert(heapcheck() != _HEAPCORRUPT);
- }
-
- // --------------------------------------------------
- // create a dungeon window and draw the initial state into it
- // --------------------------------------------------
- Bitmap *canvas;
- if ( doDirect )
- {
- canvas=display.getDirectBitmap();
- assert( canvas->validFlag );
- assert( canvas->bits );
- canvas->setViewPort((Rect &)windowRect);
- } else {
- canvas=new Bitmap(windowRect); //viewPort & ownerBounds are set
- assert( canvas->validFlag );
- assert( canvas->bits );
- }
-
- if ( doDebug )
- {
- assert(heapcheck() != _HEAPCORRUPT);
- }
-
- // Draw initial contents of dungeon window in graphics buffer
- draw_window(canvas,0,0,0,0);
-
- // Move graphics buffer to the screen. If canvas is a "direct" screenmap,
- // putBitmap() just returns.
- display.putBitmap(canvas);
- display.unblankScreen();
-
- // Main program loop
- // Waits for cursor arrow to be pressed, then redraws dungeon window
- char ch;
- int row=0,column=0,xoff,yoff;
- do
- {
- ch=getch();
- if (ch==0)
- {
- ch=getch();
- if ( doDebug )
- fprintf(debugFile,"<do loop> getch()=%u\n", ch);
- switch (ch)
- {
- case 72: // Up arrow, so scroll up
- if (row>0)
- {
- --row;
- // display the non-zero yoff's, let the end-of-switch
- // draw_window take care of the zero offset.
- for ( yoff=(tileHeight-scrollRate); yoff>0;
- yoff-=scrollRate )
- {
- draw_window(canvas,column,row,0,yoff);
- display.putBitmap(canvas);
- }
- }
- break;
-
- case 80: // Down arrow, so scroll down
- if (row<=(DUNGEON_HEIGHT-windHeight))
- {
- // display the non-zero yoff's, let the end-of-switch
- // draw_window take care of the zero offset.
- for (yoff=scrollRate; yoff<tileHeight; yoff+=scrollRate)
- {
- draw_window(canvas,column,row,0,yoff);
- display.putBitmap(canvas);
- }
- row++;
- }
- break;
-
- case 75: // Left arrow, so scroll left
- if (column>0)
- {
- --column;
- // display the non-zero xoff's, let the end-of-switch
- // draw_window take care of the zero offset.
- for (xoff=tileWidth-scrollRate; xoff>0; xoff-=scrollRate)
- {
- draw_window(canvas,column,row,xoff,0);
- display.putBitmap(canvas);
- }
- }
- break;
-
- case 77: // Right arrow, so scroll right
- if (column<=(DUNGEON_WIDTH-windWidth))
- {
- // display the non-zero xoff's, let the end-of-switch
- // draw_window take care of the zero offset.
- for (xoff=scrollRate; xoff<tileWidth; xoff+=scrollRate)
- {
- draw_window(canvas,column,row,xoff,0);
- display.putBitmap(canvas);
- if ( doDebug ) getch();
- }
- column++;
- }
- break;
-
- } // end switch (ch)
- draw_window(canvas,column,row,0,0);
- display.putBitmap(canvas);
- if ( doDebug )
- assert(heapcheck() != _HEAPCORRUPT);
-
- } /* end if (ch==0) */
- } while (ch!=27); // Terminate if ESC pressed
-
- display.setMode(3); // Restore DOS screen mode
- if ( doDebug )
- fclose(debugFile);
- return 0;
- }
-
- // ********************************************************************
- // draw_window(int xtile,int ytile,int xoff,int yoff)
- // Draws dungeon window with dimensions (in small tiles) of windWidth,
- // windHeight at screen coordinates windowRect. The first row and
- // column of tiles is moved by xoff, yoff pixels.
- // ********************************************************************
- void draw_window(Bitmap *aBitmap,
- word xtile,word ytile, // current upper left position in the
- // dungeon map.
- word xoff,word yoff) // offset into tile for sequenced scrolls
- {
- if ( doDebug)
- {
- fprintf(debugFile,"draw_window(, %i,%i, %i,%i)\n",
- xtile, ytile, xoff, yoff);
- }
- int x,y, quadX, quadY;
- Point pos, offset;
-
- for (x=0; x<(windWidth+1);x++)
- for (y=0; y<(windHeight+1);y++) {
- quadX=xtile+x;
- if ( quadX == 0 ) {
- offset.x=0;
- pos.x=0;
- } else {
- offset.x=xoff;
- pos.x=x*tileWidth-xoff;
- }
- quadY=ytile+y;
- if ( quadY == 0 ) {
- offset.y=0;
- pos.y=0;
- } else {
- offset.y=yoff;
- pos.y=y*tileHeight-yoff;
- }
- if ( (quadX < DUNGEON_WIDTH) && (quadY < DUNGEON_HEIGHT) )
- draw_tile(aBitmap, dungeon2[quadY][quadX], pos, offset);
- else
- draw_tile(aBitmap, blankTile, pos, offset);
- }
- }
-
- // ********************************************************************
- // Draw tile tnum starting at pixel srcOffset (within tile) at
- // screen coordinates destAt (local to windowRect)
- // ********************************************************************
- void draw_tile(Bitmap *aBitmap,word tnum, Point &destAt, Point &srcOffset)
- {
- tiles->setIndex(tnum); // this sets viewPort to the entire size of
- // the tile needed.
-
- Rect r=tiles->getViewPort();
- if ( srcOffset.x > 0 )
- r.topLeft.x += srcOffset.x;
- if ( srcOffset.y > 0 )
- r.topLeft.y += srcOffset.y;
- tiles->setViewPort(r);
- tiles->paint(aBitmap, destAt);
- }
-
- // **********************************************
- // convert dungeon map into small tile format
- // **********************************************
- void translate()
- {
- int x,y;
-
- // Translate quadTiles to small tiles
-
- for (x=0;x<DUNGEON_WIDTH/2;x++)
- for (y=0;y<DUNGEON_HEIGHT/2;y++) {
- dungeon2[y*2][x*2]=quadTile[dungeon[y][x]][0];
- dungeon2[y*2][x*2+1]=quadTile[dungeon[y][x]][1];
- dungeon2[y*2+1][x*2]=quadTile[dungeon[y][x]][2];
- dungeon2[y*2+1][x*2+1]=quadTile[dungeon[y][x]][3];
- }
-
- // Add corners of doors to tiles next to door tiles
-
- for (x=0;x<DUNGEON_WIDTH/2;x++)
- for (y=0;y<DUNGEON_HEIGHT/2;y++) {
- if (dungeon[y][x]==HD) dungeon2[y*2+1][x*2-1]=28;
- if (dungeon[y][x]==VD) dungeon2[y*2+2][x*2+1]=34;
- }
- }
-
-