84bbd123 |
1 | /* |
2 | * Elite - The New Kind. |
3 | * |
4 | * Reverse engineered from the BBC disk version of Elite. |
5 | * Additional material by C.J.Pinder. |
6 | * |
7 | * The original Elite code is (C) I.Bell & D.Braben 1984. |
8 | * This version re-engineered in C by C.J.Pinder 1999-2001. |
9 | * |
10 | * email: <christian@newkind.co.uk> |
11 | * |
12 | * |
13 | */ |
14 | |
15 | /* |
16 | * file.c |
17 | */ |
18 | |
19 | #include <ctype.h> |
20 | #include <stdio.h> |
21 | #include <stdlib.h> |
22 | #include <string.h> |
23 | |
24 | #include "elite.h" |
25 | #include "config.h" |
26 | #include "file.h" |
27 | |
28 | void write_config_file (void) |
29 | { |
30 | FILE *fp; |
31 | |
32 | fp = fopen ("newkind.cfg", "w"); |
33 | if (fp == NULL) |
34 | return; |
35 | |
36 | fprintf (fp, "%d\t\t# Game Speed, the lower the number the faster the game.\n", speed_cap); |
37 | |
38 | fprintf (fp, "%d\t\t# Graphics: 0 = Solid, 1 = Wireframe\n", wireframe); |
39 | |
40 | fprintf (fp, "%d\t\t# Anti-Alias Wireframe: 0 = Normal, 1 = Anti-Aliased\n", anti_alias_gfx); |
41 | |
42 | fprintf (fp, "%d\t\t# Planet style: 0 = Wireframe, 1 = Green, 2 = SNES, 3 = Fractal\n", planet_render_style); |
43 | |
44 | fprintf (fp, "%d\t\t# Planet Descriptions: 0 = Tree Grubs, 1 = Hoopy Casinos\n", hoopy_casinos); |
45 | |
46 | fprintf (fp, "%d\t\t# Instant dock: 0 = off, 1 = on\n", instant_dock); |
47 | |
48 | fprintf (fp, "newscan.cfg\t# Name of scanner config file to use.\n"); |
1a8abebd |
49 | fprintf (fp, "%d\t\t# Run in a window: 0 = off, 1 = on\n", prefer_window); |
19ea9ef5 |
50 | fprintf (fp, "%d\t\t# Remap keys in alternate views: 0 = off, 1 = on\n", remap_keys); |
84bbd123 |
51 | |
52 | fclose (fp); |
53 | } |
54 | |
55 | |
56 | /* |
57 | * Read a line from a .cfg file. |
58 | * Ignore blanks, comments and strip white space. |
59 | */ |
60 | |
61 | void read_cfg_line (char *str, int max_size, FILE *fp) |
62 | { |
63 | char *s; |
64 | |
65 | do |
66 | { |
67 | fgets (str, max_size, fp); |
68 | |
69 | for (s = str; *s; s++) /* End of line at LF or # */ |
70 | { |
71 | if ((*s == '\n') || (*s == '#')) |
72 | { |
73 | *s = '\0'; |
74 | break; |
75 | } |
76 | } |
77 | |
78 | if (s != str) /* Trim any trailing white space */ |
79 | { |
80 | s--; |
81 | while (isspace(*s)) |
82 | { |
83 | *s = '\0'; |
84 | if (s == str) |
85 | break; |
86 | s--; |
87 | } |
88 | } |
89 | |
90 | } while (*str == '\0'); |
91 | } |
92 | |
93 | |
94 | /* |
95 | * Read in the scanner .cfg file. |
96 | */ |
97 | |
98 | void read_scanner_config_file (char *filename) |
99 | { |
100 | FILE *fp; |
101 | char str[256]; |
102 | |
103 | fp = fopen (filename, "r"); |
104 | if (fp == NULL) |
105 | return; |
106 | |
107 | read_cfg_line (str, sizeof(str), fp); |
108 | strcpy (scanner_filename, str); |
109 | |
110 | read_cfg_line (str, sizeof(str), fp); |
111 | sscanf (str, "%d,%d", &scanner_cx, &scanner_cy); |
112 | scanner_cy += 385; |
113 | |
114 | read_cfg_line (str, sizeof(str), fp); |
115 | sscanf (str, "%d,%d", &compass_centre_x, &compass_centre_y); |
116 | compass_centre_y += 385; |
117 | |
1a8abebd |
118 | read_cfg_line (str, sizeof(str), fp); |
119 | sscanf (str, "%d,%d,%d", &condition_x, &condition_y, &condition_r); |
120 | condition_y += 385; |
121 | |
122 | read_cfg_line (str, sizeof(str), fp); |
123 | sscanf (str, "%d,%d", &zoom_x, &zoom_y); |
124 | zoom_y += 385; |
125 | |
84bbd123 |
126 | fclose (fp); |
127 | } |
128 | |
129 | /* |
130 | * Read in the newkind.cfg file. |
131 | */ |
132 | |
133 | void read_config_file (void) |
134 | { |
135 | FILE *fp; |
136 | char str[256]; |
137 | |
138 | fp = fopen ("newkind.cfg", "r"); |
139 | if (fp == NULL) |
140 | return; |
141 | |
142 | read_cfg_line (str, sizeof(str), fp); |
143 | sscanf (str, "%d", &speed_cap); |
144 | |
145 | read_cfg_line (str, sizeof(str), fp); |
146 | sscanf (str, "%d", &wireframe); |
147 | |
148 | read_cfg_line (str, sizeof(str), fp); |
149 | sscanf (str, "%d", &anti_alias_gfx); |
150 | |
151 | read_cfg_line (str, sizeof(str), fp); |
152 | sscanf (str, "%d", &planet_render_style); |
153 | |
154 | read_cfg_line (str, sizeof(str), fp); |
155 | sscanf (str, "%d", &hoopy_casinos); |
156 | |
157 | read_cfg_line (str, sizeof(str), fp); |
158 | sscanf (str, "%d", &instant_dock); |
159 | |
160 | read_cfg_line (str, sizeof(str), fp); |
161 | read_scanner_config_file (str); |
1a8abebd |
162 | |
163 | read_cfg_line (str, sizeof(str), fp); |
164 | sscanf (str, "%d", &prefer_window); |
84bbd123 |
165 | |
19ea9ef5 |
166 | read_cfg_line (str, sizeof(str), fp); |
167 | sscanf (str, "%d", &remap_keys); |
168 | |
84bbd123 |
169 | fclose (fp); |
170 | } |
171 | |
172 | int checksum (unsigned char *block) |
173 | { |
174 | int acc,carry; |
175 | int i; |
176 | |
177 | acc = 0x49; |
178 | carry = 0; |
179 | for (i = 0x49; i > 0; i--) |
180 | { |
181 | acc += block[i-1] + carry; |
182 | carry = acc >> 8; |
183 | acc &= 255; |
184 | acc ^= block[i]; |
185 | } |
186 | |
187 | return acc; |
188 | } |
189 | |
190 | |
191 | int save_commander_file (char *path) |
192 | { |
193 | FILE *fp; |
194 | unsigned char block[256]; |
195 | int i; |
196 | int chk; |
197 | |
198 | fp = fopen (path, "wb"); |
199 | if (fp == NULL) |
200 | return 1; |
201 | |
202 | block[0] = cmdr.mission; |
203 | block[1] = docked_planet.d; |
204 | block[2] = docked_planet.b; |
205 | block[3] = cmdr.galaxy.a; |
206 | block[4] = cmdr.galaxy.b; |
207 | block[5] = cmdr.galaxy.c; |
208 | block[6] = cmdr.galaxy.d; |
209 | block[7] = cmdr.galaxy.e; |
210 | block[8] = cmdr.galaxy.f; |
211 | block[9] = (cmdr.credits >> 24) & 255; |
212 | block[10] = (cmdr.credits >> 16) & 255; |
213 | block[11] = (cmdr.credits >> 8) & 255; |
214 | block[12] = cmdr.credits & 255; |
215 | block[13] = cmdr.fuel; |
216 | block[14] = 4; |
217 | block[15] = cmdr.galaxy_number; |
218 | block[16] = cmdr.front_laser; |
219 | block[17] = cmdr.rear_laser; |
220 | block[18] = cmdr.left_laser; |
221 | block[19] = cmdr.right_laser; |
222 | block[20] = 0; |
223 | block[21] = 0; |
224 | block[22] = cmdr.cargo_capacity + 2; |
225 | |
226 | for (i = 0; i < NO_OF_STOCK_ITEMS; i++) |
227 | block[23+i] = cmdr.current_cargo[i]; |
228 | |
229 | block[40] = cmdr.ecm ? 255 : 0; |
230 | block[41] = cmdr.fuel_scoop ? 255 : 0; |
231 | block[42] = cmdr.energy_bomb ? 0x7F : 0; |
232 | block[43] = cmdr.energy_unit; |
233 | block[44] = cmdr.docking_computer ? 255 : 0; |
234 | block[45] = cmdr.galactic_hyperdrive ? 255 : 0; |
235 | block[46] = cmdr.escape_pod ? 255 : 0; |
236 | block[47] = 0; |
237 | block[48] = 0; |
238 | block[49] = 0; |
239 | block[50] = 0; |
240 | block[51] = cmdr.missiles; |
241 | block[52] = cmdr.legal_status; |
242 | |
243 | for (i = 0; i < NO_OF_STOCK_ITEMS; i++) |
244 | block[53+i] = stock_market[i].current_quantity; |
245 | |
246 | block[70] = cmdr.market_rnd; |
247 | block[71] = cmdr.score & 255; |
248 | block[72] = cmdr.score >> 8; |
249 | block[73] = 0x20; |
250 | |
251 | chk = checksum (block); |
252 | |
253 | block[74] = chk ^ 0xA9; |
254 | block[75] = chk; |
255 | |
256 | for (i = 76; i < 256; i++) |
257 | block[i] = 0; |
258 | |
259 | if (fwrite (block, 256, 1, fp) != 1) |
260 | return 1; |
261 | |
262 | if (fclose (fp) == EOF) |
263 | return 1; |
264 | |
265 | return 0; |
266 | } |
267 | |
268 | |
269 | int load_commander_file (char *path) |
270 | { |
271 | FILE *fp; |
272 | unsigned char block[256]; |
273 | int i; |
274 | int chk; |
275 | |
276 | fp = fopen (path, "rb"); |
277 | if (fp == NULL) |
278 | return 1; |
279 | |
280 | if (fread (block, 256, 1, fp) != 1) |
281 | return 1; |
282 | |
283 | chk = checksum (block); |
284 | |
285 | if ((block[74] != (chk ^ 0xA9)) || (block[75] != chk)) |
286 | return 1; |
287 | |
288 | saved_cmdr.mission = block[0]; |
289 | |
290 | saved_cmdr.ship_x = block[1]; |
291 | saved_cmdr.ship_y = block[2]; |
292 | |
293 | saved_cmdr.galaxy.a = block[3]; |
294 | saved_cmdr.galaxy.b = block[4]; |
295 | saved_cmdr.galaxy.c = block[5]; |
296 | saved_cmdr.galaxy.d = block[6]; |
297 | saved_cmdr.galaxy.e = block[7]; |
298 | saved_cmdr.galaxy.f = block[8];; |
299 | |
300 | saved_cmdr.credits = block[9] << 24; |
301 | saved_cmdr.credits += block[10] << 16; |
302 | saved_cmdr.credits += block[11] << 8; |
303 | saved_cmdr.credits += block[12]; |
304 | |
305 | saved_cmdr.fuel = block[13]; |
306 | |
307 | saved_cmdr.galaxy_number = block[15]; |
308 | saved_cmdr.front_laser = block[16]; |
309 | saved_cmdr.rear_laser = block[17]; |
310 | saved_cmdr.left_laser = block[18]; |
311 | saved_cmdr.right_laser = block[19]; |
312 | |
313 | saved_cmdr.cargo_capacity = block[22] - 2; |
314 | |
315 | for (i = 0; i < NO_OF_STOCK_ITEMS; i++) |
316 | saved_cmdr.current_cargo[i] = block[23+i]; |
317 | |
318 | saved_cmdr.ecm = block[40]; |
319 | saved_cmdr.fuel_scoop = block[41]; |
320 | saved_cmdr.energy_bomb = block[42]; |
321 | saved_cmdr.energy_unit = block[43]; |
322 | saved_cmdr.docking_computer = block[44]; |
323 | saved_cmdr.galactic_hyperdrive = block[45]; |
324 | saved_cmdr.escape_pod = block[46]; |
325 | saved_cmdr.missiles = block[51]; |
326 | saved_cmdr.legal_status = block[52]; |
327 | |
328 | for (i = 0; i < NO_OF_STOCK_ITEMS; i++) |
329 | saved_cmdr.station_stock[i] = block[53+i]; |
330 | |
331 | saved_cmdr.market_rnd = block[70]; |
332 | |
333 | saved_cmdr.score = block[71]; |
334 | saved_cmdr.score += block[72] << 8; |
335 | |
336 | if (fclose (fp) == EOF) |
337 | return 1; |
338 | |
339 | return 0; |
340 | } |
341 | |
342 | |
343 | |
344 | |