text: /*   SCCS Id: @(#)pctiles.c   3.4     1995/07/31		     */
  /*   Copyright (c) NetHack PC Development Team 1993, 1994           */
  /*   NetHack may be freely redistributed.  See license for details. */
  /*                                                                  */
  /*
   * pctiles.c - PC Graphical Tile Support Routines
   *                                                  
   *Edit History:
   *     Initial Creation              M. Allison      93/10/30
   *
   */
  
  #include "hack.h"
  
  #ifdef USE_TILES
  
  #if defined(__GO32__) || defined(__DJGPP__)
  #include <unistd.h>
  #define TILES_IN_RAM	/* allow tiles to be read into ram */
  #endif
  
  # if defined(_MSC_VER)
  #  if _MSC_VER >= 700
  #pragma warning(disable:4018)	/* signed/unsigned mismatch */
  #pragma warning(disable:4127)	/* conditional expression is constant */
  #pragma warning(disable:4131)	/* old style declarator */
  #pragma warning(disable:4309)	/* initializing */
  #  endif
  #include <conio.h>
  # endif
  
  #include "pcvideo.h"
  #include "tile.h"
  #include "pctiles.h"
  
  STATIC_VAR FILE *tilefile;
  STATIC_VAR FILE *tilefile_O;
  extern short glyph2tile[];              /* in tile.c (made from tilemap.c) */
  
  #ifdef TILES_IN_RAM
  struct planar_cell_struct *ramtiles;
  struct overview_planar_cell_struct *oramtiles;
  boolean tiles_in_ram = FALSE;
  boolean otiles_in_ram = FALSE;
  extern int total_tiles_used;		/* tile.c */
  #endif
  
  # ifdef OVLB
  
  /*
   * Read the header/palette information at the start of the
   * NetHack.tib file.
   *
   * There is 1024 bytes (1K) of header information
   * at the start of the file, including a palette.
   *
   */
  int ReadTileFileHeader(tibhdr, filestyle)
  struct tibhdr_struct *tibhdr;
  boolean filestyle;
  {
  	FILE *x;
  	x = filestyle ? tilefile_O : tilefile;
  	if (fseek(x,0L,SEEK_SET)) {
  		return 1;
  	} else {
  	  	fread(tibhdr, sizeof(struct tibhdr_struct), 1, x);
  	}
  	return 0;
  } 
  
  /*
   * Open the requested tile file.
   *
   * NetHack1.tib file is a series of
   * 'struct planar_tile_struct' structures, one for each
   * glyph tile.
   *
   * NetHack2.tib file is a series of
   * char arrays [TILE_Y][TILE_X] in dimensions, one for each
   * glyph tile.
   *
   * There is 1024 bytes (1K) of header information
   * at the start of each .tib file. The first glyph tile starts at
   * location 1024.
   *
   */
  int
  OpenTileFile(tilefilename, filestyle)
  char *tilefilename;
  boolean filestyle;
  {
  #ifdef TILES_IN_RAM
  	int k;
  #endif
  	if (filestyle) { 
  		tilefile_O = fopen(tilefilename,"rb");
  		if (tilefile_O == (FILE *)0) return 1;
  	} else {
  		tilefile = fopen(tilefilename,"rb");
  		if (tilefile == (FILE *)0) return 1;
  	}
  #ifdef TILES_IN_RAM
      if (iflags.preload_tiles) {
  	if (filestyle) {
  	    struct overview_planar_cell_struct *gp;
  	    long ram_needed = sizeof(struct overview_planar_cell_struct) *
  				total_tiles_used;
  	    if (fseek(tilefile_O,(long)TIBHEADER_SIZE, SEEK_SET)) { /*failure*/
  	    }
  	    oramtiles = (struct overview_planar_cell_struct *)alloc(ram_needed);
  	    /* Todo: fall back to file method here if alloc failed */
  	    gp = oramtiles;
  	    for(k=0; k < total_tiles_used; ++k) {
  		fread(gp, sizeof(struct overview_planar_cell_struct), 
  			1, tilefile_O);
  		++gp;
  	    }
  #ifdef DEBUG_RAMTILES
  	    pline("%d overview tiles read into ram.", k);
  	    mark_synch();
  #endif
  	    otiles_in_ram = TRUE;
  	} else {
  	    struct planar_cell_struct *gp;
  	    long ram_needed = sizeof(struct planar_cell_struct) *
  				total_tiles_used;
  	    if (fseek(tilefile,(long)TIBHEADER_SIZE, SEEK_SET)) { /*failure*/
  	    }
  	    ramtiles = (struct planar_cell_struct *)alloc(ram_needed);
  	    /* Todo: fall back to file method here if alloc failed */
  	    gp = ramtiles;
  	    for(k=0; k < total_tiles_used; ++k) {
  		fread(gp, sizeof(struct planar_cell_struct), 
  			1, tilefile);
  		++gp;
  	    }
  #ifdef DEBUG_RAMTILES
  	    pline("%d tiles read into ram.", k);
  	    mark_synch();
  #endif
  	    tiles_in_ram = TRUE;
  	}
      }
  #endif
  	return 0;
  }
  
  void
  CloseTileFile(filestyle)
  boolean filestyle;
  {
  	fclose(filestyle ? tilefile_O : tilefile);
  #ifdef TILES_IN_RAM
  	if (!filestyle && tiles_in_ram) {
  		if (ramtiles) free((genericptr_t) ramtiles);
  		tiles_in_ram = FALSE;
  	} else if (filestyle && otiles_in_ram) {
  		if (oramtiles) free((genericptr_t) oramtiles);
  		otiles_in_ram = FALSE;
  	}
  #endif
  }
  # endif /* OVLB      */
  
  # ifdef OVL0
  
  struct planar_cell_struct plancell;
  struct overview_planar_cell_struct oplancell;
  
  /* This routine retrieves the requested NetHack glyph tile
   * from the planar style binary .tib file.
   * This is currently done 'on demand', so if the player
   * is running without a disk cache (ie. smartdrv) operating,
   * things can really be slowed down.  We don't have any
   * base memory under MSDOS, in which to store the pictures.
   *
   * Todo: Investigate the possibility of loading the glyph
   *       tiles into extended or expanded memory using
   *       the MSC virtual memory routines.
   *
   * Under an environment like djgpp, it should be possible to
   * read the entire set of glyph tiles into a large
   * array of 'struct planar_cell_struct' structures at
   * game initialization time, and recall them from the array
   * as needed.  That should speed things up (at the cost of
   * increasing the memory requirement - can't have everything).
   *
   */
  #  ifdef PLANAR_FILE
  int ReadPlanarTileFile(tilenum,gp)
  int tilenum;
  struct planar_cell_struct **gp;
  {
  	long fpos;
  
  #ifdef TILES_IN_RAM
  	if (tiles_in_ram) {
  	    *gp = ramtiles + tilenum;
  	    return 0;
  	}
  #endif
  	fpos = ((long)(tilenum) * (long)sizeof(struct planar_cell_struct)) +
  		(long)TIBHEADER_SIZE;
  	if (fseek(tilefile,fpos,SEEK_SET)) {
  		return 1;
  	} else {
  	      fread(&plancell, sizeof(struct planar_cell_struct), 1, tilefile);
  	}
  	*gp = &plancell;
  	return 0;
  }
  int ReadPlanarTileFile_O(tilenum,gp)
  int tilenum;
  struct overview_planar_cell_struct **gp;
  {
  	long fpos;
  
  #ifdef TILES_IN_RAM
  	if (otiles_in_ram) {
  	    *gp = oramtiles + tilenum;
  	    return 0;
  	}
  #endif
  	fpos = ((long)(tilenum) * 
  		(long)sizeof(struct overview_planar_cell_struct)) +
  		(long)TIBHEADER_SIZE;
  	if (fseek(tilefile_O,fpos,SEEK_SET)) {
  		return 1;
  	} else {
  	  	fread(&oplancell, sizeof(struct overview_planar_cell_struct),
  			1, tilefile_O);
  	}
  	*gp = &oplancell;
  	return 0;
  }
  #  endif
  
  #  ifdef PACKED_FILE
  int ReadPackedTileFile(tilenum,pta)
  int tilenum;
  char (*pta)[TILE_X];
  {
  	long fpos;
  	
  	fpos = ((long)(tilenum) * (long)(TILE_Y * TILE_X) +
  		(long)TIBHEADER_SIZE;
  	if (fseek(tilefile,fpos,SEEK_SET)) {
  		return 1;
  	} else {
  	  	fread(pta, (TILE_Y * TILE_X), 1, tilefile);
  	}
  	return 0;
  }
  #  endif
  # endif /* OVL0 */
  #endif /* USE_TILES */
  
  /* pctiles.c */
  