Branch data Line data Source code
1 : : /* Copyright 2000 William D. Tanksley Jr., licensed under the terms of the
2 : : * Omega license as part of Omega. */
3 : : #include "glob.h"
4 : : #include <stdio.h>
5 : : #include <stdarg.h>
6 : : #include <stdlib.h>
7 : : #include <assert.h>
8 : :
9 : : #define MAP_VERSION 2
10 : : #define MAP_HEADER_SIZE 3
11 : : #define MAP_ITEM_SIZE 9
12 : :
13 : : /* I plan to eventually make this code handle ALL map loading, since map
14 : : * loading is largely similar. However, to keep from biting off more than
15 : : * I can chew, I'm going to start by doing just a little bit at a time.
16 : : *
17 : : * For starters, I'm just going to have this load the map, and that's all. */
18 : : struct symbolMapping
19 : : {
20 : : /* Which L_* to assign this character to. */
21 : : int locationFunction;
22 : : /* What argument (if any) to give to the function which constructs that
23 : : * location. */
24 : : int argument;
25 : : };
26 : :
27 : : struct map_type
28 : : {
29 : : int length, width, depth, offset;
30 : : char *sites;
31 : : #if 0
32 : : struct symbolMapping symbols[128-32]; /* Only printable characters.
33 : : * This does assume ASCII. */
34 : : #endif
35 : : };
36 : :
37 : 0 : void error(char *explanation, ...)
38 : : {
39 : : va_list ap;
40 : :
41 : 0 : va_start (ap, explanation);
42 : 0 : vfprintf (stderr, explanation, ap);
43 : 0 : va_end (ap);
44 : 0 : abort();
45 : : }
46 : :
47 : 334 : int fgetint(FILE *f)
48 : : {
49 : : int x;
50 : : assert(sizeof(int) == 4); /* This assumption is explicit here, but it's
51 : : * also elsewhere. */
52 : 334 : x = fgetc(f) &0x000000FF;
53 : 334 : x|= (fgetc(f) << 8) &0x0000FF00;
54 : 334 : x|= (fgetc(f) <<16) &0x00FF0000;
55 : 334 : x|= (fgetc(f) <<24) &0xFF000000;
56 : :
57 [ - + ]: 334 : if ( feof(f) )
58 : 0 : error("Unexpected end of file while parsing binary file.");
59 : :
60 : 334 : return x;
61 : : }
62 : :
63 : 419 : int fgetshort(FILE *f)
64 : : {
65 : : int x;
66 : : assert(sizeof(int) == 4); /* This assumption is explicit here, but it's
67 : : * also elsewhere. */
68 : 419 : x = fgetc(f) &0x000000FF;
69 : 419 : x|= (fgetc(f) << 8) &0x0000FF00;
70 : :
71 [ - + ]: 419 : if ( feof(f) )
72 : 0 : error("Unexpected end of file while parsing binary file.");
73 : :
74 : 419 : return x;
75 : : }
76 : :
77 : 37 : void decode(char **data, int *length)
78 : : {
79 : : /* just testing... Place a sophisticated BWT here. */
80 : 37 : }
81 : :
82 : 19 : int map_getWidth(map *m)
83 : : {
84 : 19 : return m->width;
85 : : }
86 : :
87 : 19 : int map_getLength(map *m)
88 : : {
89 : 19 : return m->length;
90 : : }
91 : :
92 : 9 : int map_getDepth(map *m)
93 : : {
94 : 9 : return m->depth;
95 : : }
96 : :
97 : : /* Read in the indicated sublevel of the current map. Called from
98 : : * map_setLevel. */
99 : 37 : void map_read(map *m, FILE *in, int subLevel)
100 : : {
101 : : int size;
102 : :
103 [ + - ][ - + ]: 37 : if ( subLevel > m->depth || subLevel < 0 )
104 : 0 : error("map has only %d levels; game requested level %d.\n",
105 : : m->depth, subLevel);
106 : :
107 : : /* Seek to the location of the data (as previously calculated). */
108 : 37 : fseek(in,m->offset,SEEK_SET);
109 : :
110 : : do {
111 : : /* Read in the size of the next submap, and if it wasn't the one
112 : : * we're looking for, skip past it. */
113 : 48 : size = fgetshort(in);
114 [ + + ]: 48 : if ( subLevel )
115 : 11 : fseek(in, size, SEEK_CUR);
116 [ + + ]: 48 : } while ( subLevel-- );
117 : :
118 : : /* We now know that we're looking at the right map, and we know its size. */
119 : : /* Read the encoding of the level into a buffer. */
120 : 37 : m->sites = malloc(size);
121 : 37 : fread(m->sites,size,1,in);
122 : :
123 : : /* Decode the level. */
124 : 37 : decode(&m->sites,&size);
125 : :
126 [ - + ]: 37 : if ( size != m->length*m->width )
127 : 0 : error("Map had invalid size: expected %d, got %d.\n",
128 : 0 : m->length*m->width, size);
129 : 37 : }
130 : :
131 : : /* Read the map info out of the header of the mapfile, and load it into
132 : : * the map. */
133 : 37 : void map_readDimensions(map *m, FILE *in, enum map_identifier map)
134 : : {
135 : : int version, maps, items, this_map;
136 : :
137 : 37 : version = fgetc(in); /* The file version */
138 [ - + ]: 37 : if ( version != MAP_VERSION )
139 : 0 : error("Mapfile version mismatch: expected %d, got %d.\n",
140 : : MAP_VERSION, version);
141 : :
142 : 37 : maps = fgetshort(in); /* The number of maps it's supposed to contain */
143 : :
144 : 37 : items = 0;
145 : : do {
146 : 334 : this_map = fgetshort(in);
147 : 334 : m->width = fgetc(in); m->length = fgetc(in); m->depth = fgetc(in);
148 : 334 : m->offset = fgetint(in);
149 : 334 : items++;
150 [ + + ][ + - ]: 334 : } while (this_map != map && items < maps);
151 : :
152 [ - + ][ # # ]: 37 : if ( (items == maps) && (this_map != map) )
153 : 0 : error("Map #%d was not found in mapfile.\n", map );
154 : :
155 : : /* The offset stored in the file was the offset from the end of the table of
156 : : * contents. Fix that to be an absolute offset. */
157 : 37 : m->offset += MAP_HEADER_SIZE + maps*MAP_ITEM_SIZE;
158 : 37 : }
159 : :
160 : 37 : map *map_open(enum map_identifier mapNumber)
161 : : {
162 : 37 : map *m = malloc( sizeof(map) );
163 : : FILE *fd;
164 : :
165 : 37 : strcpy(Str3,Omegalib);
166 : 37 : strcat(Str3,"maps.dat");
167 : 37 : fd = checkfopen(Str3,"rb");
168 : :
169 : 37 : map_readDimensions(m,fd,mapNumber);
170 : :
171 : 37 : fclose(fd);
172 : 37 : return m;
173 : : }
174 : :
175 : 37 : void map_setLevel(map *m, int levelNumber)
176 : : {
177 : : FILE *fd;
178 : :
179 : 37 : strcpy(Str3,Omegalib);
180 : 37 : strcat(Str3,"maps.dat");
181 : 37 : fd = checkfopen(Str3,"rb");
182 : :
183 : 37 : map_read(m,fd,levelNumber);
184 : :
185 : 37 : fclose(fd);
186 : 37 : }
187 : :
188 : 37 : void map_close(map *m)
189 : : {
190 : 37 : free(m->sites);
191 : 37 : free(m);
192 : 37 : }
193 : :
194 : : #if 0
195 : : /* Using the mappings given in this map structure, build an Omega
196 : : * level, using appropriate terrain. */
197 : : void map_buildLevel(map *m, Level *lev)
198 : : {
199 : :
200 : : }
201 : : #endif
202 : :
203 : 86542 : char map_getSiteChar(map *m, int i, int j)
204 : : {
205 [ - + ]: 86542 : assert(i < m->width);
206 [ - + ]: 86542 : assert(j < m->length);
207 [ - + ]: 86542 : assert(m->sites[j*m->width + i]);
208 : 86542 : return m->sites[j*m->width + i];
209 : : }
210 : :
|