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