1 /*   SCCS Id: @(#)pctiles.c   3.3     95/07/31		     */
2 /*   Copyright (c) NetHack PC Development Team 1993, 1994           */
3 /*   NetHack may be freely redistributed.  See license for details. */
4 /*                                                                  */
5 /*
6  * pctiles.c - PC Graphical Tile Support Routines
7  *
8  *Edit History:
9  *     Initial Creation              M. Allison      93/10/30
10  *
11  */
12 
13 #include "hack.h"
14 
15 #ifdef USE_TILES
16 
17 #if defined(__GO32__) || defined(__DJGPP__)
18 #include <unistd.h>
19 #define TILES_IN_RAM	/* allow tiles to be read into ram */
20 #endif
21 
22 # if defined(_MSC_VER)
23 #  if _MSC_VER >= 700
24 #pragma warning(disable:4018)	/* signed/unsigned mismatch */
25 #pragma warning(disable:4127)	/* conditional expression is constant */
26 #pragma warning(disable:4131)	/* old style declarator */
27 #pragma warning(disable:4309)	/* initializing */
28 #  endif
29 #include <conio.h>
30 # endif
31 
32 #include "pcvideo.h"
33 #include "tile.h"
34 #include "pctiles.h"
35 
36 STATIC_VAR FILE *tilefile;
37 STATIC_VAR FILE *tilefile_O;
38 extern short glyph2tile[];              /* in tile.c (made from tilemap.c) */
39 
40 #ifdef TILES_IN_RAM
41 struct planar_cell_struct *ramtiles;
42 struct overview_planar_cell_struct *oramtiles;
43 boolean tiles_in_ram = FALSE;
44 boolean otiles_in_ram = FALSE;
45 extern int total_tiles_used;		/* tile.c */
46 #endif
47 
48 # ifdef OVLB
49 
50 /*
51  * Read the header/palette information at the start of the
52  * NetHack.tib file.
53  *
54  * There is 1024 bytes (1K) of header information
55  * at the start of the file, including a palette.
56  *
57  */
ReadTileFileHeader(tibhdr,filestyle)58 int ReadTileFileHeader(tibhdr, filestyle)
59 struct tibhdr_struct *tibhdr;
60 boolean filestyle;
61 {
62 	FILE *x;
63 	x = filestyle ? tilefile_O : tilefile;
64 	if (fseek(x,0L,SEEK_SET)) {
65 		return 1;
66 	} else {
67 	  	fread(tibhdr, sizeof(struct tibhdr_struct), 1, x);
68 	}
69 	return 0;
70 }
71 
72 /*
73  * Open the requested tile file.
74  *
75  * NetHack1.tib file is a series of
76  * 'struct planar_tile_struct' structures, one for each
77  * glyph tile.
78  *
79  * NetHack2.tib file is a series of
80  * char arrays [TILE_Y][TILE_X] in dimensions, one for each
81  * glyph tile.
82  *
83  * There is 1024 bytes (1K) of header information
84  * at the start of each .tib file. The first glyph tile starts at
85  * location 1024.
86  *
87  */
88 int
OpenTileFile(tilefilename,filestyle)89 OpenTileFile(tilefilename, filestyle)
90 char *tilefilename;
91 boolean filestyle;
92 {
93 	FILE *x;
94 #ifdef TILES_IN_RAM
95 	int k;
96 #endif
97 	if (filestyle) {
98 		tilefile_O = fopen(tilefilename,"rb");
99 		if (tilefile_O == (FILE *)0) return 1;
100 	} else {
101 		tilefile = fopen(tilefilename,"rb");
102 		if (tilefile == (FILE *)0) return 1;
103 	}
104 #ifdef TILES_IN_RAM
105     if (iflags.preload_tiles) {
106 	if (filestyle) {
107 	    struct overview_planar_cell_struct *gp;
108 	    long ram_needed = sizeof(struct overview_planar_cell_struct) *
109 				total_tiles_used;
110 	    if (fseek(tilefile_O,(long)TIBHEADER_SIZE, SEEK_SET)) { /*failure*/
111 	    }
112 	    oramtiles = (struct overview_planar_cell_struct *)alloc(ram_needed);
113 	    /* Todo: fall back to file method here if alloc failed */
114 	    gp = oramtiles;
115 	    for(k=0; k < total_tiles_used; ++k) {
116 		fread(gp, sizeof(struct overview_planar_cell_struct),
117 			1, tilefile_O);
118 		++gp;
119 	    }
120 #ifdef DEBUG_RAMTILES
121 	    pline("%d overview tiles read into ram.", k);
122 	    mark_synch();
123 #endif
124 	    otiles_in_ram = TRUE;
125 	} else {
126 	    struct planar_cell_struct *gp;
127 	    long ram_needed = sizeof(struct planar_cell_struct) *
128 				total_tiles_used;
129 	    if (fseek(tilefile,(long)TIBHEADER_SIZE, SEEK_SET)) { /*failure*/
130 	    }
131 	    ramtiles = (struct planar_cell_struct *)alloc(ram_needed);
132 	    /* Todo: fall back to file method here if alloc failed */
133 	    gp = ramtiles;
134 	    for(k=0; k < total_tiles_used; ++k) {
135 		fread(gp, sizeof(struct planar_cell_struct),
136 			1, tilefile);
137 		++gp;
138 	    }
139 #ifdef DEBUG_RAMTILES
140 	    pline("%d tiles read into ram.", k);
141 	    mark_synch();
142 #endif
143 	    tiles_in_ram = TRUE;
144 	}
145     }
146 #endif
147 	return 0;
148 }
149 
150 void
CloseTileFile(filestyle)151 CloseTileFile(filestyle)
152 boolean filestyle;
153 {
154 	fclose(filestyle ? tilefile_O : tilefile);
155 #ifdef TILES_IN_RAM
156 	if (!filestyle && tiles_in_ram) {
157 		if (ramtiles) free((genericptr_t) ramtiles);
158 		tiles_in_ram = FALSE;
159 	} else if (filestyle && otiles_in_ram) {
160 		if (oramtiles) free((genericptr_t) oramtiles);
161 		otiles_in_ram = FALSE;
162 	}
163 #endif
164 }
165 # endif /* OVLB      */
166 
167 # ifdef OVL0
168 
169 struct planar_cell_struct plancell;
170 struct overview_planar_cell_struct oplancell;
171 
172 /* This routine retrieves the requested NetHack glyph tile
173  * from the planar style binary .tib file.
174  * This is currently done 'on demand', so if the player
175  * is running without a disk cache (ie. smartdrv) operating,
176  * things can really be slowed down.  We don't have any
177  * base memory under MSDOS, in which to store the pictures.
178  *
179  * Todo: Investigate the possibility of loading the glyph
180  *       tiles into extended or expanded memory using
181  *       the MSC virtual memory routines.
182  *
183  * Under an environment like djgpp, it should be possible to
184  * read the entire set of glyph tiles into a large
185  * array of 'struct planar_cell_struct' structures at
186  * game initialization time, and recall them from the array
187  * as needed.  That should speed things up (at the cost of
188  * increasing the memory requirement - can't have everything).
189  *
190  */
191 #  ifdef PLANAR_FILE
ReadPlanarTileFile(tilenum,gp)192 int ReadPlanarTileFile(tilenum,gp)
193 int tilenum;
194 struct planar_cell_struct **gp;
195 {
196 	long fpos;
197 
198 #ifdef TILES_IN_RAM
199 	if (tiles_in_ram) {
200 	    *gp = ramtiles + tilenum;
201 	    return 0;
202 	}
203 #endif
204 	fpos = ((long)(tilenum) * (long)sizeof(struct planar_cell_struct)) +
205 		(long)TIBHEADER_SIZE;
206 	if (fseek(tilefile,fpos,SEEK_SET)) {
207 		return 1;
208 	} else {
209 	      fread(&plancell, sizeof(struct planar_cell_struct), 1, tilefile);
210 	}
211 	*gp = &plancell;
212 	return 0;
213 }
ReadPlanarTileFile_O(tilenum,gp)214 int ReadPlanarTileFile_O(tilenum,gp)
215 int tilenum;
216 struct overview_planar_cell_struct **gp;
217 {
218 	long fpos;
219 
220 #ifdef TILES_IN_RAM
221 	if (otiles_in_ram) {
222 	    *gp = oramtiles + tilenum;
223 	    return 0;
224 	}
225 #endif
226 	fpos = ((long)(tilenum) *
227 		(long)sizeof(struct overview_planar_cell_struct)) +
228 		(long)TIBHEADER_SIZE;
229 	if (fseek(tilefile_O,fpos,SEEK_SET)) {
230 		return 1;
231 	} else {
232 	  	fread(&oplancell, sizeof(struct overview_planar_cell_struct),
233 			1, tilefile_O);
234 	}
235 	*gp = &oplancell;
236 	return 0;
237 }
238 #  endif
239 
240 #  ifdef PACKED_FILE
ReadPackedTileFile(tilenum,pta)241 int ReadPackedTileFile(tilenum,pta)
242 int tilenum;
243 char (*pta)[TILE_X];
244 {
245 	long fpos;
246 
247 	fpos = ((long)(tilenum) * (long)(TILE_Y * TILE_X) +
248 		(long)TIBHEADER_SIZE;
249 	if (fseek(tilefile,fpos,SEEK_SET)) {
250 		return 1;
251 	} else {
252 	  	fread(pta, (TILE_Y * TILE_X), 1, tilefile);
253 	}
254 	return 0;
255 }
256 #  endif
257 # endif /* OVL0 */
258 #endif /* USE_TILES */
259 
260 /* pctiles.c */
261