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