1 /*
2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
12 */
13
14 #ifdef HAVE_CONFIG_H
15 #include <conf.h>
16 #endif
17
18 #ifndef MACINTOSH // I'm going to totally seperate these routines -- yeeech!!!!
19 // see end of file for macintosh equivs
20
21 #ifdef WINDOWS
22 #define WIN32_LEAN_AND_MEAN
23 #include <windows.h>
24 #include "winapp.h"
25 #else
26 #endif
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <ctype.h>
32
33 #include "pstypes.h"
34 #include "game.h"
35 #include "menu.h"
36 #include "movie.h"
37 #include "digi.h"
38 #include "kconfig.h"
39 #include "palette.h"
40 #include "joy.h"
41 #include "songs.h"
42 #include "args.h"
43 #include "player.h"
44 #include "mission.h"
45 #include "mono.h"
46 #include "pa_enabl.h"
47
48
49
50 #ifdef RCS
51 static char rcsid[] = "$Id: config.c,v 1.6 2003/03/22 04:04:47 btb Exp $";
52 #endif
53
54 ubyte Config_digi_volume = 8;
55 ubyte Config_midi_volume = 8;
56 ubyte Config_redbook_volume = 8;
57 ubyte Config_control_type = 0;
58 ubyte Config_channels_reversed = 0;
59 ubyte Config_joystick_sensitivity = 8;
60
61 #ifdef __MSDOS__
62 static char *digi_dev8_str = "DigiDeviceID8";
63 static char *digi_dev16_str = "DigiDeviceID16";
64 static char *digi_port_str = "DigiPort";
65 static char *digi_irq_str = "DigiIrq";
66 static char *digi_dma8_str = "DigiDma8";
67 static char *digi_dma16_str = "DigiDma16";
68 static char *midi_dev_str = "MidiDeviceID";
69 static char *midi_port_str = "MidiPort";
70
71 #define _CRYSTAL_LAKE_8_ST 0xe201
72 #define _CRYSTAL_LAKE_16_ST 0xe202
73 #define _AWE32_8_ST 0xe208
74 #define _AWE32_16_ST 0xe209
75 #endif
76 static char *digi_volume_str = "DigiVolume";
77 static char *midi_volume_str = "MidiVolume";
78 static char *redbook_enabled_str = "RedbookEnabled";
79 static char *redbook_volume_str = "RedbookVolume";
80 static char *detail_level_str = "DetailLevel";
81 static char *gamma_level_str = "GammaLevel";
82 static char *stereo_rev_str = "StereoReverse";
83 static char *joystick_min_str = "JoystickMin";
84 static char *joystick_max_str = "JoystickMax";
85 static char *joystick_cen_str = "JoystickCen";
86 static char *last_player_str = "LastPlayer";
87 static char *last_mission_str = "LastMission";
88 static char *config_vr_type_str = "VR_type";
89 static char *config_vr_resolution_str = "VR_resolution";
90 static char *config_vr_tracking_str = "VR_tracking";
91 static char *movie_hires_str = "MovieHires";
92
93 char config_last_player[CALLSIGN_LEN+1] = "";
94 char config_last_mission[MISSION_NAME_LEN+1] = "";
95
96 int Config_digi_type = 0;
97 int Config_digi_dma = 0;
98 int Config_midi_type = 0;
99
100 #ifdef WINDOWS
101 int DOSJoySaveMin[4];
102 int DOSJoySaveCen[4];
103 int DOSJoySaveMax[4];
104
105 char win95_current_joyname[256];
106 #endif
107
108
109
110 int Config_vr_type = 0;
111 int Config_vr_resolution = 0;
112 int Config_vr_tracking = 0;
113
114 int digi_driver_board_16;
115 int digi_driver_dma_16;
116
117 extern byte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
118
119 void set_custom_detail_vars(void);
120
121
122 #define CL_MC0 0xF8F
123 #define CL_MC1 0xF8D
124 /*
125 void CrystalLakeWriteMCP( ushort mc_addr, ubyte mc_data )
126 {
127 _disable();
128 outp( CL_MC0, 0xE2 ); // Write password
129 outp( mc_addr, mc_data ); // Write data
130 _enable();
131 }
132
133 ubyte CrystalLakeReadMCP( ushort mc_addr )
134 {
135 ubyte value;
136 _disable();
137 outp( CL_MC0, 0xE2 ); // Write password
138 value = inp( mc_addr ); // Read data
139 _enable();
140 return value;
141 }
142
143 void CrystalLakeSetSB()
144 {
145 ubyte tmp;
146 tmp = CrystalLakeReadMCP( CL_MC1 );
147 tmp &= 0x7F;
148 CrystalLakeWriteMCP( CL_MC1, tmp );
149 }
150
151 void CrystalLakeSetWSS()
152 {
153 ubyte tmp;
154 tmp = CrystalLakeReadMCP( CL_MC1 );
155 tmp |= 0x80;
156 CrystalLakeWriteMCP( CL_MC1, tmp );
157 }
158 */
159 //MovieHires might be changed by -nohighres, so save a "real" copy of it
160 int SaveMovieHires;
161 int save_redbook_enabled;
162
163 #ifdef WINDOWS
CheckMovieAttributes()164 void CheckMovieAttributes()
165 {
166 HKEY hKey;
167 DWORD len, type, val;
168 long lres;
169
170 lres = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Parallax\\Descent II\\1.1\\INSTALL",
171 0, KEY_READ, &hKey);
172 if (lres == ERROR_SUCCESS) {
173 len = sizeof(val);
174 lres = RegQueryValueEx(hKey, "HIRES", NULL, &type, &val, &len);
175 if (lres == ERROR_SUCCESS) {
176 MovieHires = val;
177 logentry("HIRES=%d\n", val);
178 }
179 RegCloseKey(hKey);
180 }
181 }
182 #endif
183
184
185
ReadConfigFile()186 int ReadConfigFile()
187 {
188 FILE *infile;
189 char line[80], *token, *value, *ptr;
190 ubyte gamma;
191 int joy_axis_min[7];
192 int joy_axis_center[7];
193 int joy_axis_max[7];
194 int i;
195
196 strcpy( config_last_player, "" );
197
198 joy_axis_min[0] = joy_axis_min[1] = joy_axis_min[2] = joy_axis_min[3] = 0;
199 joy_axis_max[0] = joy_axis_max[1] = joy_axis_max[2] = joy_axis_max[3] = 0;
200 joy_axis_center[0] = joy_axis_center[1] = joy_axis_center[2] = joy_axis_center[3] = 0;
201
202 #ifdef WINDOWS
203 memset(&joy_axis_min[0], 0, sizeof(int)*7);
204 memset(&joy_axis_max[0], 0, sizeof(int)*7);
205 memset(&joy_axis_center[0], 0, sizeof(int)*7);
206 //@@ joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
207 #else
208 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
209 #endif
210
211 /*digi_driver_board = 0;
212 digi_driver_port = 0;
213 digi_driver_irq = 0;
214 digi_driver_dma = 0;
215
216 digi_midi_type = 0;
217 digi_midi_port = 0;*/
218
219 Config_digi_volume = 8;
220 Config_midi_volume = 8;
221 Config_redbook_volume = 8;
222 Config_control_type = 0;
223 Config_channels_reversed = 0;
224
225 //set these here in case no cfg file
226 SaveMovieHires = MovieHires;
227 save_redbook_enabled = Redbook_enabled;
228
229 infile = fopen("descent.cfg", "rt");
230 if (infile == NULL) {
231 WIN(CheckMovieAttributes());
232 return 1;
233 }
234 while (!feof(infile)) {
235 memset(line, 0, 80);
236 fgets(line, 80, infile);
237 ptr = &(line[0]);
238 while (isspace(*ptr))
239 ptr++;
240 if (*ptr != '\0') {
241 token = strtok(ptr, "=");
242 value = strtok(NULL, "=");
243 if (value[strlen(value)-1] == '\n')
244 value[strlen(value)-1] = 0;
245 /* if (!strcmp(token, digi_dev8_str))
246 digi_driver_board = strtol(value, NULL, 16);
247 else if (!strcmp(token, digi_dev16_str))
248 digi_driver_board_16 = strtol(value, NULL, 16);
249 else if (!strcmp(token, digi_port_str))
250 digi_driver_port = strtol(value, NULL, 16);
251 else if (!strcmp(token, digi_irq_str))
252 digi_driver_irq = strtol(value, NULL, 10);
253 else if (!strcmp(token, digi_dma8_str))
254 digi_driver_dma = strtol(value, NULL, 10);
255 else if (!strcmp(token, digi_dma16_str))
256 digi_driver_dma_16 = strtol(value, NULL, 10);
257 else*/ if (!strcmp(token, digi_volume_str))
258 Config_digi_volume = strtol(value, NULL, 10);
259 else/* if (!strcmp(token, midi_dev_str))
260 digi_midi_type = strtol(value, NULL, 16);
261 else if (!strcmp(token, midi_port_str))
262 digi_midi_port = strtol(value, NULL, 16);
263 else*/ if (!strcmp(token, midi_volume_str))
264 Config_midi_volume = strtol(value, NULL, 10);
265 else if (!strcmp(token, redbook_enabled_str))
266 Redbook_enabled = save_redbook_enabled = strtol(value, NULL, 10);
267 else if (!strcmp(token, redbook_volume_str))
268 Config_redbook_volume = strtol(value, NULL, 10);
269 else if (!strcmp(token, stereo_rev_str))
270 Config_channels_reversed = strtol(value, NULL, 10);
271 else if (!strcmp(token, gamma_level_str)) {
272 gamma = strtol(value, NULL, 10);
273 gr_palette_set_gamma( gamma );
274 }
275 else if (!strcmp(token, detail_level_str)) {
276 Detail_level = strtol(value, NULL, 10);
277 if (Detail_level == NUM_DETAIL_LEVELS-1) {
278 int count,dummy,oc,od,wd,wrd,da,sc;
279
280 count = sscanf (value, "%d,%d,%d,%d,%d,%d,%d\n",&dummy,&oc,&od,&wd,&wrd,&da,&sc);
281
282 if (count == 7) {
283 Object_complexity = oc;
284 Object_detail = od;
285 Wall_detail = wd;
286 Wall_render_depth = wrd;
287 Debris_amount = da;
288 SoundChannels = sc;
289 set_custom_detail_vars();
290 }
291 #ifdef PA_3DFX_VOODOO // Set to highest detail because you can't change em
292 Object_complexity=Object_detail=Wall_detail=
293 Wall_render_depth=Debris_amount=SoundChannels = NUM_DETAIL_LEVELS-1;
294 Detail_level=NUM_DETAIL_LEVELS-1;
295 set_custom_detail_vars();
296 #endif
297 }
298 }
299 else if (!strcmp(token, joystick_min_str)) {
300 sscanf( value, "%d,%d,%d,%d", &joy_axis_min[0], &joy_axis_min[1], &joy_axis_min[2], &joy_axis_min[3] );
301 }
302 else if (!strcmp(token, joystick_max_str)) {
303 sscanf( value, "%d,%d,%d,%d", &joy_axis_max[0], &joy_axis_max[1], &joy_axis_max[2], &joy_axis_max[3] );
304 }
305 else if (!strcmp(token, joystick_cen_str)) {
306 sscanf( value, "%d,%d,%d,%d", &joy_axis_center[0], &joy_axis_center[1], &joy_axis_center[2], &joy_axis_center[3] );
307 }
308 else if (!strcmp(token, last_player_str)) {
309 char * p;
310 strncpy( config_last_player, value, CALLSIGN_LEN );
311 p = strchr( config_last_player, '\n');
312 if ( p ) *p = 0;
313 }
314 else if (!strcmp(token, last_mission_str)) {
315 char * p;
316 strncpy( config_last_mission, value, MISSION_NAME_LEN );
317 p = strchr( config_last_mission, '\n');
318 if ( p ) *p = 0;
319 } else if (!strcmp(token, config_vr_type_str)) {
320 Config_vr_type = strtol(value, NULL, 10);
321 } else if (!strcmp(token, config_vr_resolution_str)) {
322 Config_vr_resolution = strtol(value, NULL, 10);
323 } else if (!strcmp(token, config_vr_tracking_str)) {
324 Config_vr_tracking = strtol(value, NULL, 10);
325 } else if (!strcmp(token, movie_hires_str)) {
326 SaveMovieHires = MovieHires = strtol(value, NULL, 10);
327 }
328 }
329 }
330
331 fclose(infile);
332
333 #ifdef WINDOWS
334 for (i=0;i<4;i++)
335 {
336 DOSJoySaveMin[i]=joy_axis_min[i];
337 DOSJoySaveCen[i]=joy_axis_center[i];
338 DOSJoySaveMax[i]=joy_axis_max[i];
339 }
340 #else
341 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
342 #endif
343
344 i = FindArg( "-volume" );
345
346 if ( i > 0 ) {
347 i = atoi( Args[i+1] );
348 if ( i < 0 ) i = 0;
349 if ( i > 100 ) i = 100;
350 Config_digi_volume = (i*8)/100;
351 Config_midi_volume = (i*8)/100;
352 Config_redbook_volume = (i*8)/100;
353 }
354
355 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
356 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
357 if ( Config_redbook_volume > 8 ) Config_redbook_volume = 8;
358
359 digi_set_volume( (Config_digi_volume*32768)/8, (Config_midi_volume*128)/8 );
360 /*
361 printf( "DigiDeviceID: 0x%x\n", digi_driver_board );
362 printf( "DigiPort: 0x%x\n", digi_driver_port );
363 printf( "DigiIrq: 0x%x\n", digi_driver_irq );
364 printf( "DigiDma: 0x%x\n", digi_driver_dma );
365 printf( "MidiDeviceID: 0x%x\n", digi_midi_type );
366 printf( "MidiPort: 0x%x\n", digi_midi_port );
367 key_getch();
368 */
369
370 /*Config_midi_type = digi_midi_type;
371 Config_digi_type = digi_driver_board;
372 Config_digi_dma = digi_driver_dma;*/
373
374 #if 0
375 if (digi_driver_board_16 > 0 && !FindArg("-no16bit") && digi_driver_board_16 != _GUS_16_ST) {
376 digi_driver_board = digi_driver_board_16;
377 digi_driver_dma = digi_driver_dma_16;
378 }
379
380 // HACK!!!
381 //Hack to make some cards look like others, such as
382 //the Crytal Lake look like Microsoft Sound System
383 if ( digi_driver_board == _CRYSTAL_LAKE_8_ST ) {
384 ubyte tmp;
385 tmp = CrystalLakeReadMCP( CL_MC1 );
386 if ( !(tmp & 0x80) )
387 atexit( CrystalLakeSetSB ); // Restore to SB when done.
388 CrystalLakeSetWSS();
389 digi_driver_board = _MICROSOFT_8_ST;
390 } else if ( digi_driver_board == _CRYSTAL_LAKE_16_ST ) {
391 ubyte tmp;
392 tmp = CrystalLakeReadMCP( CL_MC1 );
393 if ( !(tmp & 0x80) )
394 atexit( CrystalLakeSetSB ); // Restore to SB when done.
395 CrystalLakeSetWSS();
396 digi_driver_board = _MICROSOFT_16_ST;
397 } else if ( digi_driver_board == _AWE32_8_ST ) {
398 digi_driver_board = _SB16_8_ST;
399 } else if ( digi_driver_board == _AWE32_16_ST ) {
400 digi_driver_board = _SB16_16_ST;
401 } else
402 digi_driver_board = digi_driver_board;
403 #else
404 infile = fopen("descentw.cfg", "rt");
405 if (infile) {
406 while (!feof(infile)) {
407 memset(line, 0, 80);
408 fgets(line, 80, infile);
409 ptr = &(line[0]);
410 while (isspace(*ptr))
411 ptr++;
412 if (*ptr != '\0') {
413 token = strtok(ptr, "=");
414 value = strtok(NULL, "=");
415 if (value[strlen(value)-1] == '\n')
416 value[strlen(value)-1] = 0;
417 if (!strcmp(token, joystick_min_str)) {
418 sscanf( value, "%d,%d,%d,%d,%d,%d,%d", &joy_axis_min[0], &joy_axis_min[1], &joy_axis_min[2], &joy_axis_min[3], &joy_axis_min[4], &joy_axis_min[5], &joy_axis_min[6] );
419 }
420 else if (!strcmp(token, joystick_max_str)) {
421 sscanf( value, "%d,%d,%d,%d,%d,%d,%d", &joy_axis_max[0], &joy_axis_max[1], &joy_axis_max[2], &joy_axis_max[3], &joy_axis_max[4], &joy_axis_max[5], &joy_axis_max[6] );
422 }
423 else if (!strcmp(token, joystick_cen_str)) {
424 sscanf( value, "%d,%d,%d,%d,%d,%d,%d", &joy_axis_center[0], &joy_axis_center[1], &joy_axis_center[2], &joy_axis_center[3], &joy_axis_center[4], &joy_axis_center[5], &joy_axis_center[6] );
425 }
426 }
427 }
428 fclose(infile);
429 }
430 #endif
431
432 return 0;
433 }
434
WriteConfigFile()435 int WriteConfigFile()
436 {
437 FILE *infile;
438 char str[256];
439 int joy_axis_min[7];
440 int joy_axis_center[7];
441 int joy_axis_max[7];
442 ubyte gamma = gr_palette_get_gamma();
443
444 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
445
446 #ifdef WINDOWS
447 for (i=0;i<4;i++)
448 {
449 joy_axis_min[i]=DOSJoySaveMin[i];
450 joy_axis_center[i]=DOSJoySaveCen[i];
451 joy_axis_max[i]=DOSJoySaveMax[i];
452 }
453 #endif
454
455 infile = fopen("descent.cfg", "wt");
456 if (infile == NULL) {
457 return 1;
458 }
459 /*sprintf (str, "%s=0x%x\n", digi_dev8_str, Config_digi_type);
460 fputs(str, infile);
461 sprintf (str, "%s=0x%x\n", digi_dev16_str, digi_driver_board_16);
462 fputs(str, infile);
463 sprintf (str, "%s=0x%x\n", digi_port_str, digi_driver_port);
464 fputs(str, infile);
465 sprintf (str, "%s=%d\n", digi_irq_str, digi_driver_irq);
466 fputs(str, infile);
467 sprintf (str, "%s=%d\n", digi_dma8_str, Config_digi_dma);
468 fputs(str, infile);
469 sprintf (str, "%s=%d\n", digi_dma16_str, digi_driver_dma_16);
470 fputs(str, infile);*/
471 sprintf (str, "%s=%d\n", digi_volume_str, Config_digi_volume);
472 fputs(str, infile);
473 /*sprintf (str, "%s=0x%x\n", midi_dev_str, Config_midi_type);
474 fputs(str, infile);
475 sprintf (str, "%s=0x%x\n", midi_port_str, digi_midi_port);
476 fputs(str, infile);*/
477 sprintf (str, "%s=%d\n", midi_volume_str, Config_midi_volume);
478 fputs(str, infile);
479 sprintf (str, "%s=%d\n", redbook_enabled_str, FindArg("-noredbook")?save_redbook_enabled:Redbook_enabled);
480 fputs(str, infile);
481 sprintf (str, "%s=%d\n", redbook_volume_str, Config_redbook_volume);
482 fputs(str, infile);
483 sprintf (str, "%s=%d\n", stereo_rev_str, Config_channels_reversed);
484 fputs(str, infile);
485 sprintf (str, "%s=%d\n", gamma_level_str, gamma);
486 fputs(str, infile);
487 if (Detail_level == NUM_DETAIL_LEVELS-1)
488 sprintf (str, "%s=%d,%d,%d,%d,%d,%d,%d\n", detail_level_str, Detail_level,
489 Object_complexity,Object_detail,Wall_detail,Wall_render_depth,Debris_amount,SoundChannels);
490 else
491 sprintf (str, "%s=%d\n", detail_level_str, Detail_level);
492 fputs(str, infile);
493
494 sprintf (str, "%s=%d,%d,%d,%d\n", joystick_min_str, joy_axis_min[0], joy_axis_min[1], joy_axis_min[2], joy_axis_min[3] );
495 fputs(str, infile);
496 sprintf (str, "%s=%d,%d,%d,%d\n", joystick_cen_str, joy_axis_center[0], joy_axis_center[1], joy_axis_center[2], joy_axis_center[3] );
497 fputs(str, infile);
498 sprintf (str, "%s=%d,%d,%d,%d\n", joystick_max_str, joy_axis_max[0], joy_axis_max[1], joy_axis_max[2], joy_axis_max[3] );
499 fputs(str, infile);
500
501 sprintf (str, "%s=%s\n", last_player_str, Players[Player_num].callsign );
502 fputs(str, infile);
503 sprintf (str, "%s=%s\n", last_mission_str, config_last_mission );
504 fputs(str, infile);
505 sprintf (str, "%s=%d\n", config_vr_type_str, Config_vr_type );
506 fputs(str, infile);
507 sprintf (str, "%s=%d\n", config_vr_resolution_str, Config_vr_resolution );
508 fputs(str, infile);
509 sprintf (str, "%s=%d\n", config_vr_tracking_str, Config_vr_tracking );
510 fputs(str, infile);
511 sprintf (str, "%s=%d\n", movie_hires_str, (FindArg("-nohires") || FindArg("-nohighres") || FindArg("-lowresmovies"))?SaveMovieHires:MovieHires);
512 fputs(str, infile);
513
514 fclose(infile);
515
516 #ifdef WINDOWS
517 {
518 // Save Windows Config File
519 char joyname[256];
520
521
522 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
523
524 infile = fopen("descentw.cfg", "wt");
525 if (infile == NULL) return 1;
526
527 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_min_str,
528 joy_axis_min[0], joy_axis_min[1], joy_axis_min[2], joy_axis_min[3],
529 joy_axis_min[4], joy_axis_min[5], joy_axis_min[6]);
530 fputs(str, infile);
531 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_cen_str,
532 joy_axis_center[0], joy_axis_center[1], joy_axis_center[2], joy_axis_center[3],
533 joy_axis_center[4], joy_axis_center[5], joy_axis_center[6]);
534 fputs(str, infile);
535 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_max_str,
536 joy_axis_max[0], joy_axis_max[1], joy_axis_max[2], joy_axis_max[3],
537 joy_axis_max[4], joy_axis_max[5], joy_axis_max[6]);
538 fputs(str, infile);
539
540 fclose(infile);
541 }
542 CheckMovieAttributes();
543 #endif
544
545 return 0;
546 }
547
548 #else // !defined(MACINTOSH)
549
550 #include <stdio.h>
551 #include <stdlib.h>
552 #include <string.h>
553 #include <ctype.h>
554
555 #include <Memory.h>
556 #include <Folders.h>
557 #include <GestaltEqu.h>
558 #include <Errors.h>
559 #include <Processes.h>
560 #include <Resources.h>
561 #include <LowMem.h>
562
563 #include "pa_enabl.h" // because some prefs rely on this fact
564 #include "error.h"
565 #include "pstypes.h"
566 #include "game.h"
567 #include "digi.h"
568 #include "kconfig.h"
569 #include "palette.h"
570 #include "joy.h"
571 #include "args.h"
572 #include "player.h"
573 #include "mission.h"
574 #include "prefs.h" // prefs file for configuration stuff -- from DeSalvo
575
576 #if defined(POLY_ACC)
577 #include "poly_acc.h"
578 #endif
579
580 #ifdef RCS
581 static char rcsid[] = "$Id: config.c,v 1.6 2003/03/22 04:04:47 btb Exp $";
582 #endif
583
584 #define MAX_CTB_LEN 512
585
586 typedef struct preferences {
587 ubyte digi_volume;
588 ubyte midi_volume;
589 ubyte stereo_reverse;
590 ubyte detail_level;
591 ubyte oc; // object complexity
592 ubyte od; // object detail
593 ubyte wd; // wall detail
594 ubyte wrd; // wall render depth
595 ubyte da; // debris amount
596 ubyte sc; // sound channels
597 ubyte gamma_level;
598 ubyte pixel_double;
599 int joy_axis_min[4];
600 int joy_axis_max[4];
601 int joy_axis_center[4];
602 char lastplayer[CALLSIGN_LEN+1];
603 char lastmission[MISSION_NAME_LEN+1];
604 char ctb_config[MAX_CTB_LEN];
605 int ctb_tool;
606 ubyte master_volume;
607 ubyte display_dialog;
608 ubyte change_resolution;
609 ubyte nosound;
610 ubyte nomidi;
611 ubyte sound_11k;
612 ubyte no_movies;
613 ubyte game_monitor;
614 ubyte redbook_volume;
615 ubyte enable_rave;
616 ubyte enable_input_sprockets;
617 } Preferences;
618
619 char config_last_player[CALLSIGN_LEN+1] = "";
620 char config_last_mission[MISSION_NAME_LEN+1] = "";
621 char config_last_ctb_cfg[MAX_CTB_LEN] = "";
622 int config_last_ctb_tool;
623 ubyte Config_master_volume = 4;
624 ubyte Config_digi_volume = 8;
625 ubyte Config_midi_volume = 8;
626 ubyte Config_redbook_volume = 8;
627 ubyte Config_control_type = 0;
628 ubyte Config_channels_reversed = 0;
629 ubyte Config_joystick_sensitivity = 8;
630
631 int Config_vr_type = 0;
632 int Config_vr_resolution = 0;
633 int Config_vr_tracking = 0;
634
635 extern byte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
636 extern void digi_set_master_volume( int volume );
637
638 void set_custom_detail_vars(void);
639
640 static ubyte have_prefs = 0;
641
642 //� ------------------------------ Private Definitions
643 //� ------------------------------ Private Types
644
645 typedef struct
646 {
647 Str31 fileName;
648 OSType creator;
649 OSType fileType;
650 OSType resType;
651 short resID;
652 } PrefsInfo, *PrefsInfoPtr, **PrefsInfoHandle;
653
654 //� ------------------------------ Private Variables
655
656 static PrefsInfo prefsInfo;
657 static Boolean prefsInited = 0;
658
659 //� ------------------------------ Private Functions
660
661 static void Pstrcpy(StringPtr dst, StringPtr src);
662 static void Pstrcat(StringPtr dst, StringPtr src);
663 static Boolean FindPrefsFile(short *prefVRefNum, long *prefDirID);
664
665 //� -------------------- Pstrcpy
666
667 static void
Pstrcpy(StringPtr dst,StringPtr src)668 Pstrcpy(StringPtr dst, StringPtr src)
669 {
670 BlockMove(src, dst, (*src) + 1);
671 }
672
673 //� -------------------- Pstrcat
674
675 static void
Pstrcat(StringPtr dst,StringPtr src)676 Pstrcat(StringPtr dst, StringPtr src)
677 {
678 BlockMove(src + 1, dst + (*dst) + 1, *src);
679 *dst += *src;
680 }
681
682 //� -------------------- FindPrefsFile
683
684 static Boolean
FindPrefsFile(short * prefVRefNum,long * prefDirID)685 FindPrefsFile(short *prefVRefNum, long *prefDirID)
686 {
687 OSErr theErr;
688 long response;
689 CInfoPBRec infoPB;
690
691 if (! prefsInited)
692 return (0);
693
694 theErr = Gestalt(gestaltFindFolderAttr, &response);
695 if (theErr == noErr && ((response >> gestaltFindFolderPresent) & 1))
696 {
697 //� Find (or make) it the easy way...
698 theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, prefVRefNum, prefDirID);
699 }
700 else
701 {
702 SysEnvRec theSysEnv;
703 StringPtr prefFolderName = "\pPreferences";
704
705 //� yeachh -- we have to do it all by hand!
706 theErr = SysEnvirons(1, &theSysEnv);
707 if (theErr != noErr)
708 return (0);
709
710 *prefVRefNum = theSysEnv.sysVRefNum;
711
712 //� Check whether Preferences folder already exists
713 infoPB.hFileInfo.ioCompletion = 0;
714 infoPB.hFileInfo.ioNamePtr = prefFolderName;
715 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
716 infoPB.hFileInfo.ioFDirIndex = 0;
717 infoPB.hFileInfo.ioDirID = 0;
718
719 theErr = PBGetCatInfo(&infoPB, 0);
720 if (theErr == noErr)
721 {
722 *prefDirID = infoPB.hFileInfo.ioDirID;
723 }
724 else if (theErr == fnfErr) //� Preferences doesn't already exist
725 {
726 HParamBlockRec dirPB;
727
728 //� Create "Preferences" folder
729 dirPB.fileParam.ioCompletion = 0;
730 dirPB.fileParam.ioVRefNum = *prefVRefNum;
731 dirPB.fileParam.ioNamePtr = prefFolderName;
732 dirPB.fileParam.ioDirID = 0;
733
734 theErr = PBDirCreate(&dirPB, 0);
735 if (theErr == noErr)
736 *prefDirID = dirPB.fileParam.ioDirID;
737 }
738 }
739
740 //� If we make it here OK, create Preferences file if necessary
741 if (theErr == noErr)
742 {
743 infoPB.hFileInfo.ioCompletion = 0;
744 infoPB.hFileInfo.ioNamePtr = prefsInfo.fileName;
745 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
746 infoPB.hFileInfo.ioFDirIndex = 0;
747 infoPB.hFileInfo.ioDirID = *prefDirID;
748
749 theErr = PBGetCatInfo(&infoPB, 0);
750 if (theErr == fnfErr)
751 {
752 theErr = HCreate(*prefVRefNum, *prefDirID, prefsInfo.fileName, prefsInfo.creator, prefsInfo.fileType);
753 if (theErr == noErr)
754 {
755 HCreateResFile(*prefVRefNum, *prefDirID, prefsInfo.fileName);
756 theErr = ResError();
757 }
758 }
759 }
760
761 return (theErr == noErr);
762 }
763
764 //� -------------------- InitPrefsFile
765
766 #define UNKNOWN_TYPE 0x3f3f3f3f
767
768 void
InitPrefsFile(OSType creator)769 InitPrefsFile(OSType creator)
770 {
771 OSErr err;
772 PrefsInfoHandle piHdl;
773
774 if ((piHdl = (PrefsInfoHandle) GetResource('PRFI', 0)) == nil)
775 {
776 ProcessSerialNumber thePSN;
777 ProcessInfoRec thePIR;
778 FSSpec appSpec;
779 StringPtr app_string;
780
781 #if 0
782 GetCurrentProcess(&thePSN);
783 thePIR.processName = nil;
784 thePIR.processAppSpec = &appSpec;
785
786 //� Set default to '�Application� Prefs', PREF 0
787 err = GetProcessInformation(&thePSN, &thePIR);
788 if (err)
789 Int3();
790 #endif
791 app_string = LMGetCurApName();
792 // Pstrcpy(prefsInfo.fileName, appSpec.name);
793 Pstrcpy(prefsInfo.fileName, app_string);
794 Pstrcat(prefsInfo.fileName, "\p Preferences");
795
796 //� Set creator to calling application's signature (should be able to
797 //� Determine this automatically, but unable to for some reason)
798 prefsInfo.creator = creator;
799 prefsInfo.fileType = 'pref';
800 prefsInfo.resType = 'pref';
801 prefsInfo.resID = 0;
802 }
803 else
804 {
805 //� Get Preferences file setup from PRFI 0
806 BlockMove(*piHdl, &prefsInfo, sizeof (prefsInfo));
807 ReleaseResource((Handle) piHdl);
808
809 if (prefsInfo.creator == UNKNOWN_TYPE)
810 prefsInfo.creator = creator;
811 }
812
813 prefsInited = 1;
814 }
815
816 //� -------------------- LoadPrefsFile
817
818 OSErr
LoadPrefsFile(Handle prefsHdl)819 LoadPrefsFile(Handle prefsHdl)
820 {
821 short prefVRefNum, prefRefNum;
822 long prefDirID;
823 OSErr theErr = noErr;
824 Handle origHdl;
825 Size prefSize, origSize;
826
827 if (prefsHdl == nil)
828 return (nilHandleErr);
829
830 prefSize = GetHandleSize(prefsHdl);
831
832 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
833 return (fnfErr);
834
835 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
836 if (prefRefNum == -1)
837 return (ResError());
838
839 //� Not finding the resource is not an error -- caller will use default data
840 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
841 {
842 origSize = GetHandleSize(origHdl);
843 if (origSize > prefSize) //� Extend handle for extra stored data
844 SetHandleSize(prefsHdl, origSize);
845
846 BlockMove(*origHdl, *prefsHdl, origSize);
847 ReleaseResource(origHdl);
848 }
849
850 CloseResFile(prefRefNum);
851
852 if (theErr == noErr)
853 theErr = ResError();
854
855 return (theErr);
856 }
857
858 //� -------------------- SavePrefsFile
859
860 OSErr
SavePrefsFile(Handle prefHdl)861 SavePrefsFile(Handle prefHdl)
862 {
863 short prefVRefNum, prefRefNum;
864 long prefDirID;
865 Handle origHdl = nil;
866 Size origSize, prefSize;
867 OSErr theErr = noErr;
868
869 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
870 return (fnfErr);
871
872 if (prefHdl == nil)
873 return (nilHandleErr);
874
875 prefSize = GetHandleSize(prefHdl);
876
877 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
878 if (prefRefNum == -1)
879 return (ResError());
880
881 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
882 {
883 //� Overwrite existing preferences
884 origSize = GetHandleSize(origHdl);
885 if (prefSize > origSize)
886 SetHandleSize(origHdl, prefSize);
887
888 BlockMove(*prefHdl, *origHdl, prefSize);
889 ChangedResource(origHdl);
890 WriteResource(origHdl);
891 ReleaseResource(origHdl);
892 }
893 else
894 {
895 //� Store specified preferences for the first time
896 AddResource(prefHdl, prefsInfo.resType, prefsInfo.resID, "\p");
897 WriteResource(prefHdl);
898 DetachResource(prefHdl);
899 }
900
901 CloseResFile(prefRefNum);
902
903 if (theErr == noErr)
904 theErr = ResError();
905
906 return (theErr);
907 }
908
909 //� -------------------------------------------------------------------------------------------
910
911 /*
912
913 This module provides the ability to save and load a preferences file in the
914 Preferences folder in the System Folder. An optional resource, PRFI 0,
915 is used to provide specifications for the preferences file (creator, etc.).
916
917 Three functions are provided:
918
919 void InitPrefsFile(OSType creator)
920
921 This function will initialize the preferences file, that is, it will create
922 it in the appropriate place if it doesn't currently exist. It should be
923 called with the creator code for the application. Note that the creator
924 code specified in PRFI 0 (if any) will be used only if the creator code
925 passed to this function is '????'. Without the PRFI 0 resource, the default
926 specifications are:
927
928 File Name: "{Application} Prefs" (i.e., the name of the app plus " Prefs"
929 Creator: the creator passed to InitPrefsFile
930 Type: 'PREF'
931 Pref Resource Type: 'PREF'
932 Pref Resource ID: 0
933
934 The PRFI 0 resource allows you to specify overrides for each of the above
935 values. This is useful for development, since the application name might
936 go through changes, but the preferences file name is held constant.
937
938 OSErr LoadPrefsFile(Handle prefsHndl)
939
940 This function will attempt to copy the data stored in the preferences
941 file to the given handle (which must be pre-allocated). If the handle is too
942 small, then it will be enlarged. If it is too large, it will not be resized.
943 The data in the preferences file (normally in PREF 0) will then be copied
944 into the handle. If the preferences file did not exist, the original data
945 in the handle will not change.
946
947 OSErr SavePrefsFile(Handle prefsHndl)
948
949 This function will attempt to save the given handle to the preferences
950 file. Its contents will completely replace the previous data (normally
951 the PREF 0 resource).
952
953 In typical use, you will use InitPrefsFile once, then allocate a handle large
954 enough to contain your preferences data, and initialize it with default values.
955 Throughout the course of your program, the handle will undergo modification as
956 user preferences change. You can use SavePrefsFile anytime to update the
957 preferences file, or wait until program exit to do so.
958
959 */
960
ReadConfigFile()961 int ReadConfigFile()
962 {
963 int i;
964 OSErr err;
965 Handle prefs_handle;
966 Preferences *prefs;
967 char *p;
968
969 if (!have_prefs) { // not initialized....get a handle to the preferences file
970 InitPrefsFile('DCT2');
971 have_prefs = 1;
972 }
973
974 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
975 if (prefs_handle == NULL)
976 return;
977
978 prefs = (Preferences *)(*prefs_handle);
979 err = LoadPrefsFile(prefs_handle);
980 if (err) {
981 DisposeHandle(prefs_handle);
982 return -1;
983 }
984
985 p = (char *)prefs;
986 for (i = 0; i < sizeof(Preferences); i++) {
987 if (*p != 0)
988 break;
989 p++;
990 }
991 if ( i == sizeof(Preferences) )
992 return -1;
993
994 Config_digi_volume = prefs->digi_volume;
995 Config_midi_volume = prefs->midi_volume;
996 Config_master_volume = prefs->master_volume;
997 Config_redbook_volume = prefs->redbook_volume;
998 Config_channels_reversed = prefs->stereo_reverse;
999 gr_palette_set_gamma( (int)(prefs->gamma_level) );
1000
1001 Scanline_double = (int)prefs->pixel_double;
1002 if ( PAEnabled )
1003 Scanline_double = 0; // can't double with hardware acceleration
1004
1005 Detail_level = prefs->detail_level;
1006 if (Detail_level == NUM_DETAIL_LEVELS-1) {
1007 Object_complexity = prefs->oc;
1008 Object_detail = prefs->od;
1009 Wall_detail = prefs->wd;
1010 Wall_render_depth = prefs->wrd;
1011 Debris_amount = prefs->da;
1012 SoundChannels = prefs->sc;
1013 set_custom_detail_vars();
1014 }
1015 #ifdef PA_3DFX_VOODOO // Set to highest detail because you can't change em
1016 Object_complexity=Object_detail=Wall_detail=
1017 Wall_render_depth=Debris_amount=SoundChannels = NUM_DETAIL_LEVELS-1;
1018 Detail_level=NUM_DETAIL_LEVELS-1;
1019 set_custom_detail_vars();
1020 #endif
1021
1022 strncpy( config_last_player, prefs->lastplayer, CALLSIGN_LEN );
1023 p = strchr(config_last_player, '\n' );
1024 if (p) *p = 0;
1025
1026 strncpy(config_last_mission, prefs->lastmission, MISSION_NAME_LEN);
1027 p = strchr(config_last_mission, '\n' );
1028 if (p) *p = 0;
1029
1030 strcpy(config_last_ctb_cfg, prefs->ctb_config);
1031
1032 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
1033
1034 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
1035
1036 joy_set_cal_vals( prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
1037 digi_set_volume( (Config_digi_volume*256)/8, (Config_midi_volume*256)/8 );
1038 digi_set_master_volume(Config_master_volume);
1039
1040 gConfigInfo.mDoNotDisplayOptions = prefs->display_dialog;
1041 gConfigInfo.mUse11kSounds = prefs->sound_11k;
1042 gConfigInfo.mDisableSound = prefs->nosound;
1043 gConfigInfo.mDisableMIDIMusic = prefs->nomidi;
1044 gConfigInfo.mChangeResolution = prefs->change_resolution;
1045 gConfigInfo.mDoNotPlayMovies = prefs->no_movies;
1046 gConfigInfo.mGameMonitor = prefs->game_monitor;
1047 gConfigInfo.mAcceleration = prefs->enable_rave;
1048 gConfigInfo.mInputSprockets = prefs->enable_input_sprockets;
1049
1050 DisposeHandle(prefs_handle);
1051 return 0;
1052 }
1053
WriteConfigFile()1054 int WriteConfigFile()
1055 {
1056 OSErr err;
1057 Handle prefs_handle;
1058 Preferences *prefs;
1059
1060 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
1061 if (prefs_handle == NULL)
1062 return;
1063
1064 prefs = (Preferences *)(*prefs_handle);
1065
1066 joy_get_cal_vals(prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
1067 prefs->digi_volume = Config_digi_volume;
1068 prefs->midi_volume = Config_midi_volume;
1069 prefs->stereo_reverse = Config_channels_reversed;
1070 prefs->detail_level = Detail_level;
1071 if (Detail_level == NUM_DETAIL_LEVELS-1) {
1072 prefs->oc = Object_complexity;
1073 prefs->od = Object_detail;
1074 prefs->wd = Wall_detail;
1075 prefs->wrd = Wall_render_depth;
1076 prefs->da = Debris_amount;
1077 prefs->sc = SoundChannels;
1078 }
1079 prefs->gamma_level = (ubyte)gr_palette_get_gamma();
1080
1081 if ( !PAEnabled )
1082 prefs->pixel_double = (ubyte)Scanline_double; // hmm..don't write this out if doing hardware accel.
1083
1084 strncpy( prefs->lastplayer, Players[Player_num].callsign, CALLSIGN_LEN );
1085 strncpy( prefs->lastmission, config_last_mission, MISSION_NAME_LEN );
1086 strcpy( prefs->ctb_config, config_last_ctb_cfg);
1087 prefs->ctb_tool = config_last_ctb_tool;
1088 prefs->master_volume = Config_master_volume;
1089 prefs->display_dialog = gConfigInfo.mDoNotDisplayOptions;
1090 prefs->change_resolution = gConfigInfo.mChangeResolution;
1091 prefs->nosound = gConfigInfo.mDisableSound;
1092 prefs->nomidi = gConfigInfo.mDisableMIDIMusic;
1093 prefs->sound_11k = gConfigInfo.mUse11kSounds;
1094 prefs->no_movies = gConfigInfo.mDoNotPlayMovies;
1095 prefs->game_monitor = gConfigInfo.mGameMonitor;
1096 prefs->redbook_volume = Config_redbook_volume;
1097 prefs->enable_rave = gConfigInfo.mAcceleration;
1098 prefs->enable_input_sprockets = gConfigInfo.mInputSprockets;
1099
1100 err = SavePrefsFile(prefs_handle);
1101 DisposeHandle(prefs_handle);
1102 return (int)err;
1103 }
1104
1105 #endif
1106
1107