1 /* $Id: config.c,v 1.10 2003-10-04 20:03:11 btb Exp $ */
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
17 * contains routine(s) to read in the configuration file which contains
18 * game configuration stuff like detail level, sound card, etc
21 * Revision 1.8 1995/10/27 10:52:20 allender
22 * call digi_set_master_volume when prefs are read in to
23 * set the master volume of the mac
25 * Revision 1.7 1995/10/24 17:08:39 allender
26 * Config_master_volume added for saving sound manager volume
29 * Revision 1.6 1995/10/20 00:49:31 allender
30 * use default values when no prefs file
32 * Revision 1.5 1995/09/21 10:06:58 allender
33 * set digi and midi volume appropriately
35 * Revision 1.4 1995/09/13 08:49:38 allender
38 * Revision 1.3 1995/09/05 08:47:37 allender
41 * Revision 1.2 1995/05/26 06:54:14 allender
42 * removed midi and digi references from config file
44 * Revision 1.1 1995/05/16 15:23:45 allender
47 * Revision 2.2 1995/03/27 09:42:59 john
48 * Added VR Settings in config file.
50 * Revision 2.1 1995/03/16 11:20:40 john
51 * Put in support for Crystal Lake soundcard.
53 * Revision 2.0 1995/02/27 11:30:13 john
54 * New version 2.0, which has no anonymous unions, builds with
55 * Watcom 10.0, and doesn't require parsing BITMAPS.TBL.
57 * Revision 1.14 1995/02/11 16:19:36 john
58 * Added code to make the default mission be the one last played.
60 * Revision 1.13 1995/01/18 13:23:24 matt
61 * Made curtom detail level vars initialize properly at load
63 * Revision 1.12 1995/01/04 22:15:36 matt
64 * Fixed stupid bug using scanf() to read bytes
66 * Revision 1.11 1995/01/04 13:14:21 matt
67 * Made custom detail level settings save in config file
69 * Revision 1.10 1994/12/12 21:35:09 john
70 * *** empty log message ***
72 * Revision 1.9 1994/12/12 21:31:51 john
73 * Made volume work better by making sure volumes are valid
74 * and set correctly at program startup.
76 * Revision 1.8 1994/12/12 13:58:01 john
78 * Fixed GUS hang at exit by deinitializing digi before midi.
80 * Revision 1.7 1994/12/08 10:01:33 john
81 * Changed the way the player callsign stuff works.
83 * Revision 1.6 1994/12/01 11:24:07 john
84 * Made volume/gamma/joystick sliders all be the same length. 0-->8.
86 * Revision 1.5 1994/11/29 02:01:07 john
87 * Added code to look at -volume command line arg.
89 * Revision 1.4 1994/11/14 20:14:11 john
90 * Fixed some warnings.
92 * Revision 1.3 1994/11/14 19:51:01 john
93 * Added joystick cal values to descent.cfg.
95 * Revision 1.2 1994/11/14 17:53:09 allender
96 * read and write descent.cfg file
98 * Revision 1.1 1994/11/14 16:28:08 allender
108 #ifndef MACINTOSH // I'm going to totally seperate these routines -- yeeech!!!!
109 // see end of file for macintosh equivs
112 #define WIN32_LEAN_AND_MEAN
136 #include "pa_enabl.h"
141 static char rcsid[] = "$Id: config.c,v 1.10 2003-10-04 20:03:11 btb Exp $";
144 ubyte Config_digi_volume = 8;
145 ubyte Config_midi_volume = 8;
146 ubyte Config_redbook_volume = 8;
147 ubyte Config_control_type = 0;
148 ubyte Config_channels_reversed = 0;
149 ubyte Config_joystick_sensitivity = 8;
152 static char *digi_dev8_str = "DigiDeviceID8";
153 static char *digi_dev16_str = "DigiDeviceID16";
154 static char *digi_port_str = "DigiPort";
155 static char *digi_irq_str = "DigiIrq";
156 static char *digi_dma8_str = "DigiDma8";
157 static char *digi_dma16_str = "DigiDma16";
158 static char *midi_dev_str = "MidiDeviceID";
159 static char *midi_port_str = "MidiPort";
161 #define _CRYSTAL_LAKE_8_ST 0xe201
162 #define _CRYSTAL_LAKE_16_ST 0xe202
163 #define _AWE32_8_ST 0xe208
164 #define _AWE32_16_ST 0xe209
166 static char *digi_volume_str = "DigiVolume";
167 static char *midi_volume_str = "MidiVolume";
168 static char *redbook_enabled_str = "RedbookEnabled";
169 static char *redbook_volume_str = "RedbookVolume";
170 static char *detail_level_str = "DetailLevel";
171 static char *gamma_level_str = "GammaLevel";
172 static char *stereo_rev_str = "StereoReverse";
173 static char *joystick_min_str = "JoystickMin";
174 static char *joystick_max_str = "JoystickMax";
175 static char *joystick_cen_str = "JoystickCen";
176 static char *last_player_str = "LastPlayer";
177 static char *last_mission_str = "LastMission";
178 static char *config_vr_type_str = "VR_type";
179 static char *config_vr_resolution_str = "VR_resolution";
180 static char *config_vr_tracking_str = "VR_tracking";
181 static char *movie_hires_str = "MovieHires";
183 char config_last_player[CALLSIGN_LEN+1] = "";
184 char config_last_mission[MISSION_NAME_LEN+1] = "";
186 int Config_digi_type = 0;
187 int Config_digi_dma = 0;
188 int Config_midi_type = 0;
191 int DOSJoySaveMin[4];
192 int DOSJoySaveCen[4];
193 int DOSJoySaveMax[4];
195 char win95_current_joyname[256];
200 int Config_vr_type = 0;
201 int Config_vr_resolution = 0;
202 int Config_vr_tracking = 0;
204 int digi_driver_board_16;
205 int digi_driver_dma_16;
207 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
209 void set_custom_detail_vars(void);
215 void CrystalLakeWriteMCP( ushort mc_addr, ubyte mc_data )
218 outp( CL_MC0, 0xE2 ); // Write password
219 outp( mc_addr, mc_data ); // Write data
223 ubyte CrystalLakeReadMCP( ushort mc_addr )
227 outp( CL_MC0, 0xE2 ); // Write password
228 value = inp( mc_addr ); // Read data
233 void CrystalLakeSetSB()
236 tmp = CrystalLakeReadMCP( CL_MC1 );
238 CrystalLakeWriteMCP( CL_MC1, tmp );
241 void CrystalLakeSetWSS()
244 tmp = CrystalLakeReadMCP( CL_MC1 );
246 CrystalLakeWriteMCP( CL_MC1, tmp );
249 //MovieHires might be changed by -nohighres, so save a "real" copy of it
251 int save_redbook_enabled;
254 void CheckMovieAttributes()
257 DWORD len, type, val;
260 lres = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Parallax\\Descent II\\1.1\\INSTALL",
262 if (lres == ERROR_SUCCESS) {
264 lres = RegQueryValueEx(hKey, "HIRES", NULL, &type, &val, &len);
265 if (lres == ERROR_SUCCESS) {
267 logentry("HIRES=%d\n", val);
279 char line[80], *token, *value, *ptr;
282 int joy_axis_center[7];
286 strcpy( config_last_player, "" );
288 joy_axis_min[0] = joy_axis_min[1] = joy_axis_min[2] = joy_axis_min[3] = 0;
289 joy_axis_max[0] = joy_axis_max[1] = joy_axis_max[2] = joy_axis_max[3] = 0;
290 joy_axis_center[0] = joy_axis_center[1] = joy_axis_center[2] = joy_axis_center[3] = 0;
293 memset(&joy_axis_min[0], 0, sizeof(int)*7);
294 memset(&joy_axis_max[0], 0, sizeof(int)*7);
295 memset(&joy_axis_center[0], 0, sizeof(int)*7);
296 //@@ joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
298 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
301 /*digi_driver_board = 0;
302 digi_driver_port = 0;
307 digi_midi_port = 0;*/
309 Config_digi_volume = 8;
310 Config_midi_volume = 8;
311 Config_redbook_volume = 8;
312 Config_control_type = 0;
313 Config_channels_reversed = 0;
315 //set these here in case no cfg file
316 SaveMovieHires = MovieHires;
317 save_redbook_enabled = Redbook_enabled;
319 infile = cfopen("descent.cfg", "rt");
320 if (infile == NULL) {
321 WIN(CheckMovieAttributes());
324 while (!cfeof(infile))
327 cfgets(line, 80, infile);
329 while (isspace(*ptr))
332 token = strtok(ptr, "=");
333 value = strtok(NULL, "=");
334 if (value[strlen(value)-1] == '\n')
335 value[strlen(value)-1] = 0;
336 /* if (!strcmp(token, digi_dev8_str))
337 digi_driver_board = strtol(value, NULL, 16);
338 else if (!strcmp(token, digi_dev16_str))
339 digi_driver_board_16 = strtol(value, NULL, 16);
340 else if (!strcmp(token, digi_port_str))
341 digi_driver_port = strtol(value, NULL, 16);
342 else if (!strcmp(token, digi_irq_str))
343 digi_driver_irq = strtol(value, NULL, 10);
344 else if (!strcmp(token, digi_dma8_str))
345 digi_driver_dma = strtol(value, NULL, 10);
346 else if (!strcmp(token, digi_dma16_str))
347 digi_driver_dma_16 = strtol(value, NULL, 10);
348 else*/ if (!strcmp(token, digi_volume_str))
349 Config_digi_volume = strtol(value, NULL, 10);
350 else/* if (!strcmp(token, midi_dev_str))
351 digi_midi_type = strtol(value, NULL, 16);
352 else if (!strcmp(token, midi_port_str))
353 digi_midi_port = strtol(value, NULL, 16);
354 else*/ if (!strcmp(token, midi_volume_str))
355 Config_midi_volume = strtol(value, NULL, 10);
356 else if (!strcmp(token, redbook_enabled_str))
357 Redbook_enabled = save_redbook_enabled = strtol(value, NULL, 10);
358 else if (!strcmp(token, redbook_volume_str))
359 Config_redbook_volume = strtol(value, NULL, 10);
360 else if (!strcmp(token, stereo_rev_str))
361 Config_channels_reversed = strtol(value, NULL, 10);
362 else if (!strcmp(token, gamma_level_str)) {
363 gamma = strtol(value, NULL, 10);
364 gr_palette_set_gamma( gamma );
366 else if (!strcmp(token, detail_level_str)) {
367 Detail_level = strtol(value, NULL, 10);
368 if (Detail_level == NUM_DETAIL_LEVELS-1) {
369 int count,dummy,oc,od,wd,wrd,da,sc;
371 count = sscanf (value, "%d,%d,%d,%d,%d,%d,%d\n",&dummy,&oc,&od,&wd,&wrd,&da,&sc);
374 Object_complexity = oc;
377 Wall_render_depth = wrd;
380 set_custom_detail_vars();
382 #ifdef PA_3DFX_VOODOO // Set to highest detail because you can't change em
383 Object_complexity=Object_detail=Wall_detail=
384 Wall_render_depth=Debris_amount=SoundChannels = NUM_DETAIL_LEVELS-1;
385 Detail_level=NUM_DETAIL_LEVELS-1;
386 set_custom_detail_vars();
390 else if (!strcmp(token, joystick_min_str)) {
391 sscanf( value, "%d,%d,%d,%d", &joy_axis_min[0], &joy_axis_min[1], &joy_axis_min[2], &joy_axis_min[3] );
393 else if (!strcmp(token, joystick_max_str)) {
394 sscanf( value, "%d,%d,%d,%d", &joy_axis_max[0], &joy_axis_max[1], &joy_axis_max[2], &joy_axis_max[3] );
396 else if (!strcmp(token, joystick_cen_str)) {
397 sscanf( value, "%d,%d,%d,%d", &joy_axis_center[0], &joy_axis_center[1], &joy_axis_center[2], &joy_axis_center[3] );
399 else if (!strcmp(token, last_player_str)) {
401 strncpy( config_last_player, value, CALLSIGN_LEN );
402 p = strchr( config_last_player, '\n');
405 else if (!strcmp(token, last_mission_str)) {
407 strncpy( config_last_mission, value, MISSION_NAME_LEN );
408 p = strchr( config_last_mission, '\n');
410 } else if (!strcmp(token, config_vr_type_str)) {
411 Config_vr_type = strtol(value, NULL, 10);
412 } else if (!strcmp(token, config_vr_resolution_str)) {
413 Config_vr_resolution = strtol(value, NULL, 10);
414 } else if (!strcmp(token, config_vr_tracking_str)) {
415 Config_vr_tracking = strtol(value, NULL, 10);
416 } else if (!strcmp(token, movie_hires_str)) {
417 SaveMovieHires = MovieHires = strtol(value, NULL, 10);
427 DOSJoySaveMin[i]=joy_axis_min[i];
428 DOSJoySaveCen[i]=joy_axis_center[i];
429 DOSJoySaveMax[i]=joy_axis_max[i];
432 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
435 i = FindArg( "-volume" );
438 i = atoi( Args[i+1] );
440 if ( i > 100 ) i = 100;
441 Config_digi_volume = (i*8)/100;
442 Config_midi_volume = (i*8)/100;
443 Config_redbook_volume = (i*8)/100;
446 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
447 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
448 if ( Config_redbook_volume > 8 ) Config_redbook_volume = 8;
450 digi_set_volume( (Config_digi_volume*32768)/8, (Config_midi_volume*128)/8 );
452 printf( "DigiDeviceID: 0x%x\n", digi_driver_board );
453 printf( "DigiPort: 0x%x\n", digi_driver_port );
454 printf( "DigiIrq: 0x%x\n", digi_driver_irq );
455 printf( "DigiDma: 0x%x\n", digi_driver_dma );
456 printf( "MidiDeviceID: 0x%x\n", digi_midi_type );
457 printf( "MidiPort: 0x%x\n", digi_midi_port );
461 /*Config_midi_type = digi_midi_type;
462 Config_digi_type = digi_driver_board;
463 Config_digi_dma = digi_driver_dma;*/
466 if (digi_driver_board_16 > 0 && !FindArg("-no16bit") && digi_driver_board_16 != _GUS_16_ST) {
467 digi_driver_board = digi_driver_board_16;
468 digi_driver_dma = digi_driver_dma_16;
472 //Hack to make some cards look like others, such as
473 //the Crytal Lake look like Microsoft Sound System
474 if ( digi_driver_board == _CRYSTAL_LAKE_8_ST ) {
476 tmp = CrystalLakeReadMCP( CL_MC1 );
478 atexit( CrystalLakeSetSB ); // Restore to SB when done.
480 digi_driver_board = _MICROSOFT_8_ST;
481 } else if ( digi_driver_board == _CRYSTAL_LAKE_16_ST ) {
483 tmp = CrystalLakeReadMCP( CL_MC1 );
485 atexit( CrystalLakeSetSB ); // Restore to SB when done.
487 digi_driver_board = _MICROSOFT_16_ST;
488 } else if ( digi_driver_board == _AWE32_8_ST ) {
489 digi_driver_board = _SB16_8_ST;
490 } else if ( digi_driver_board == _AWE32_16_ST ) {
491 digi_driver_board = _SB16_16_ST;
493 digi_driver_board = digi_driver_board;
495 infile = cfopen("descentw.cfg", "rt");
497 while (!cfeof(infile))
500 cfgets(line, 80, infile);
502 while (isspace(*ptr))
505 token = strtok(ptr, "=");
506 value = strtok(NULL, "=");
507 if (value[strlen(value)-1] == '\n')
508 value[strlen(value)-1] = 0;
509 if (!strcmp(token, joystick_min_str)) {
510 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] );
512 else if (!strcmp(token, joystick_max_str)) {
513 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] );
515 else if (!strcmp(token, joystick_cen_str)) {
516 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] );
527 int WriteConfigFile()
532 int joy_axis_center[7];
534 ubyte gamma = gr_palette_get_gamma();
536 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
541 joy_axis_min[i]=DOSJoySaveMin[i];
542 joy_axis_center[i]=DOSJoySaveCen[i];
543 joy_axis_max[i]=DOSJoySaveMax[i];
547 infile = cfopen("descent.cfg", "wt");
548 if (infile == NULL) {
551 /*sprintf (str, "%s=0x%x\n", digi_dev8_str, Config_digi_type);
553 sprintf (str, "%s=0x%x\n", digi_dev16_str, digi_driver_board_16);
555 sprintf (str, "%s=0x%x\n", digi_port_str, digi_driver_port);
557 sprintf (str, "%s=%d\n", digi_irq_str, digi_driver_irq);
559 sprintf (str, "%s=%d\n", digi_dma8_str, Config_digi_dma);
561 sprintf (str, "%s=%d\n", digi_dma16_str, digi_driver_dma_16);
562 cfputs(str, infile);*/
563 sprintf (str, "%s=%d\n", digi_volume_str, Config_digi_volume);
565 /*sprintf (str, "%s=0x%x\n", midi_dev_str, Config_midi_type);
567 sprintf (str, "%s=0x%x\n", midi_port_str, digi_midi_port);
568 cfputs(str, infile);*/
569 sprintf (str, "%s=%d\n", midi_volume_str, Config_midi_volume);
571 sprintf (str, "%s=%d\n", redbook_enabled_str, FindArg("-noredbook")?save_redbook_enabled:Redbook_enabled);
573 sprintf (str, "%s=%d\n", redbook_volume_str, Config_redbook_volume);
575 sprintf (str, "%s=%d\n", stereo_rev_str, Config_channels_reversed);
577 sprintf (str, "%s=%d\n", gamma_level_str, gamma);
579 if (Detail_level == NUM_DETAIL_LEVELS-1)
580 sprintf (str, "%s=%d,%d,%d,%d,%d,%d,%d\n", detail_level_str, Detail_level,
581 Object_complexity,Object_detail,Wall_detail,Wall_render_depth,Debris_amount,SoundChannels);
583 sprintf (str, "%s=%d\n", detail_level_str, Detail_level);
586 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] );
588 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] );
590 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] );
593 sprintf (str, "%s=%s\n", last_player_str, Players[Player_num].callsign );
595 sprintf (str, "%s=%s\n", last_mission_str, config_last_mission );
597 sprintf (str, "%s=%d\n", config_vr_type_str, Config_vr_type );
599 sprintf (str, "%s=%d\n", config_vr_resolution_str, Config_vr_resolution );
601 sprintf (str, "%s=%d\n", config_vr_tracking_str, Config_vr_tracking );
603 sprintf (str, "%s=%d\n", movie_hires_str, (FindArg("-nohires") || FindArg("-nohighres") || FindArg("-lowresmovies"))?SaveMovieHires:MovieHires);
610 // Save Windows Config File
614 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
616 infile = cfopen("descentw.cfg", "wt");
617 if (infile == NULL) return 1;
619 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_min_str,
620 joy_axis_min[0], joy_axis_min[1], joy_axis_min[2], joy_axis_min[3],
621 joy_axis_min[4], joy_axis_min[5], joy_axis_min[6]);
623 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_cen_str,
624 joy_axis_center[0], joy_axis_center[1], joy_axis_center[2], joy_axis_center[3],
625 joy_axis_center[4], joy_axis_center[5], joy_axis_center[6]);
627 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_max_str,
628 joy_axis_max[0], joy_axis_max[1], joy_axis_max[2], joy_axis_max[3],
629 joy_axis_max[4], joy_axis_max[5], joy_axis_max[6]);
634 CheckMovieAttributes();
640 #else // !defined(MACINTOSH)
649 #include <GestaltEqu.h>
651 #include <Processes.h>
652 #include <Resources.h>
655 #include "pa_enabl.h" // because some prefs rely on this fact
666 #include "prefs.h" // prefs file for configuration stuff -- from DeSalvo
668 #if defined(POLY_ACC)
669 #include "poly_acc.h"
673 static char rcsid[] = "$Id: config.c,v 1.10 2003-10-04 20:03:11 btb Exp $";
676 #define MAX_CTB_LEN 512
678 typedef struct preferences {
681 ubyte stereo_reverse;
683 ubyte oc; // object complexity
684 ubyte od; // object detail
685 ubyte wd; // wall detail
686 ubyte wrd; // wall render depth
687 ubyte da; // debris amount
688 ubyte sc; // sound channels
693 int joy_axis_center[4];
694 char lastplayer[CALLSIGN_LEN+1];
695 char lastmission[MISSION_NAME_LEN+1];
696 char ctb_config[MAX_CTB_LEN];
699 ubyte display_dialog;
700 ubyte change_resolution;
706 ubyte redbook_volume;
708 ubyte enable_input_sprockets;
711 char config_last_player[CALLSIGN_LEN+1] = "";
712 char config_last_mission[MISSION_NAME_LEN+1] = "";
713 char config_last_ctb_cfg[MAX_CTB_LEN] = "";
714 int config_last_ctb_tool;
715 ubyte Config_master_volume = 4;
716 ubyte Config_digi_volume = 8;
717 ubyte Config_midi_volume = 8;
718 ubyte Config_redbook_volume = 8;
719 ubyte Config_control_type = 0;
720 ubyte Config_channels_reversed = 0;
721 ubyte Config_joystick_sensitivity = 8;
723 int Config_vr_type = 0;
724 int Config_vr_resolution = 0;
725 int Config_vr_tracking = 0;
727 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
728 extern void digi_set_master_volume( int volume );
730 void set_custom_detail_vars(void);
732 static ubyte have_prefs = 0;
734 //¥ ------------------------------ Private Definitions
735 //¥ ------------------------------ Private Types
744 } PrefsInfo, *PrefsInfoPtr, **PrefsInfoHandle;
746 //¥ ------------------------------ Private Variables
748 static PrefsInfo prefsInfo;
749 static Boolean prefsInited = 0;
751 //¥ ------------------------------ Private Functions
753 static void Pstrcpy(StringPtr dst, StringPtr src);
754 static void Pstrcat(StringPtr dst, StringPtr src);
755 static Boolean FindPrefsFile(short *prefVRefNum, long *prefDirID);
757 //¥ -------------------- Pstrcpy
760 Pstrcpy(StringPtr dst, StringPtr src)
762 BlockMove(src, dst, (*src) + 1);
765 //¥ -------------------- Pstrcat
768 Pstrcat(StringPtr dst, StringPtr src)
770 BlockMove(src + 1, dst + (*dst) + 1, *src);
774 //¥ -------------------- FindPrefsFile
777 FindPrefsFile(short *prefVRefNum, long *prefDirID)
786 theErr = Gestalt(gestaltFindFolderAttr, &response);
787 if (theErr == noErr && ((response >> gestaltFindFolderPresent) & 1))
789 //¥ Find (or make) it the easy way...
790 theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, prefVRefNum, prefDirID);
795 StringPtr prefFolderName = "\pPreferences";
797 //¥ yeachh -- we have to do it all by hand!
798 theErr = SysEnvirons(1, &theSysEnv);
802 *prefVRefNum = theSysEnv.sysVRefNum;
804 //¥ Check whether Preferences folder already exists
805 infoPB.hFileInfo.ioCompletion = 0;
806 infoPB.hFileInfo.ioNamePtr = prefFolderName;
807 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
808 infoPB.hFileInfo.ioFDirIndex = 0;
809 infoPB.hFileInfo.ioDirID = 0;
811 theErr = PBGetCatInfo(&infoPB, 0);
814 *prefDirID = infoPB.hFileInfo.ioDirID;
816 else if (theErr == fnfErr) //¥ Preferences doesn't already exist
818 HParamBlockRec dirPB;
820 //¥ Create "Preferences" folder
821 dirPB.fileParam.ioCompletion = 0;
822 dirPB.fileParam.ioVRefNum = *prefVRefNum;
823 dirPB.fileParam.ioNamePtr = prefFolderName;
824 dirPB.fileParam.ioDirID = 0;
826 theErr = PBDirCreate(&dirPB, 0);
828 *prefDirID = dirPB.fileParam.ioDirID;
832 //¥ If we make it here OK, create Preferences file if necessary
835 infoPB.hFileInfo.ioCompletion = 0;
836 infoPB.hFileInfo.ioNamePtr = prefsInfo.fileName;
837 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
838 infoPB.hFileInfo.ioFDirIndex = 0;
839 infoPB.hFileInfo.ioDirID = *prefDirID;
841 theErr = PBGetCatInfo(&infoPB, 0);
842 if (theErr == fnfErr)
844 theErr = HCreate(*prefVRefNum, *prefDirID, prefsInfo.fileName, prefsInfo.creator, prefsInfo.fileType);
847 HCreateResFile(*prefVRefNum, *prefDirID, prefsInfo.fileName);
853 return (theErr == noErr);
856 //¥ -------------------- InitPrefsFile
858 #define UNKNOWN_TYPE 0x3f3f3f3f
861 InitPrefsFile(OSType creator)
864 PrefsInfoHandle piHdl;
866 if ((piHdl = (PrefsInfoHandle) GetResource('PRFI', 0)) == nil)
868 ProcessSerialNumber thePSN;
869 ProcessInfoRec thePIR;
871 StringPtr app_string;
874 GetCurrentProcess(&thePSN);
875 thePIR.processName = nil;
876 thePIR.processAppSpec = &appSpec;
878 //¥ Set default to 'ÇApplicationÈ Prefs', PREF 0
879 err = GetProcessInformation(&thePSN, &thePIR);
883 app_string = LMGetCurApName();
884 // Pstrcpy(prefsInfo.fileName, appSpec.name);
885 Pstrcpy(prefsInfo.fileName, app_string);
886 Pstrcat(prefsInfo.fileName, "\p Preferences");
888 //¥ Set creator to calling application's signature (should be able to
889 //¥ Determine this automatically, but unable to for some reason)
890 prefsInfo.creator = creator;
891 prefsInfo.fileType = 'pref';
892 prefsInfo.resType = 'pref';
897 //¥ Get Preferences file setup from PRFI 0
898 BlockMove(*piHdl, &prefsInfo, sizeof (prefsInfo));
899 ReleaseResource((Handle) piHdl);
901 if (prefsInfo.creator == UNKNOWN_TYPE)
902 prefsInfo.creator = creator;
908 //¥ -------------------- LoadPrefsFile
911 LoadPrefsFile(Handle prefsHdl)
913 short prefVRefNum, prefRefNum;
915 OSErr theErr = noErr;
917 Size prefSize, origSize;
920 return (nilHandleErr);
922 prefSize = GetHandleSize(prefsHdl);
924 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
927 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
928 if (prefRefNum == -1)
931 //¥ Not finding the resource is not an error -- caller will use default data
932 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
934 origSize = GetHandleSize(origHdl);
935 if (origSize > prefSize) //¥ Extend handle for extra stored data
936 SetHandleSize(prefsHdl, origSize);
938 BlockMove(*origHdl, *prefsHdl, origSize);
939 ReleaseResource(origHdl);
942 CloseResFile(prefRefNum);
950 //¥ -------------------- SavePrefsFile
953 SavePrefsFile(Handle prefHdl)
955 short prefVRefNum, prefRefNum;
957 Handle origHdl = nil;
958 Size origSize, prefSize;
959 OSErr theErr = noErr;
961 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
965 return (nilHandleErr);
967 prefSize = GetHandleSize(prefHdl);
969 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
970 if (prefRefNum == -1)
973 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
975 //¥ Overwrite existing preferences
976 origSize = GetHandleSize(origHdl);
977 if (prefSize > origSize)
978 SetHandleSize(origHdl, prefSize);
980 BlockMove(*prefHdl, *origHdl, prefSize);
981 ChangedResource(origHdl);
982 WriteResource(origHdl);
983 ReleaseResource(origHdl);
987 //¥ Store specified preferences for the first time
988 AddResource(prefHdl, prefsInfo.resType, prefsInfo.resID, "\p");
989 WriteResource(prefHdl);
990 DetachResource(prefHdl);
993 CloseResFile(prefRefNum);
1001 //¥ -------------------------------------------------------------------------------------------
1005 This module provides the ability to save and load a preferences file in the
1006 Preferences folder in the System Folder. An optional resource, PRFI 0,
1007 is used to provide specifications for the preferences file (creator, etc.).
1009 Three functions are provided:
1011 void InitPrefsFile(OSType creator)
1013 This function will initialize the preferences file, that is, it will create
1014 it in the appropriate place if it doesn't currently exist. It should be
1015 called with the creator code for the application. Note that the creator
1016 code specified in PRFI 0 (if any) will be used only if the creator code
1017 passed to this function is '????'. Without the PRFI 0 resource, the default
1020 File Name: "{Application} Prefs" (i.e., the name of the app plus " Prefs"
1021 Creator: the creator passed to InitPrefsFile
1023 Pref Resource Type: 'PREF'
1026 The PRFI 0 resource allows you to specify overrides for each of the above
1027 values. This is useful for development, since the application name might
1028 go through changes, but the preferences file name is held constant.
1030 OSErr LoadPrefsFile(Handle prefsHndl)
1032 This function will attempt to copy the data stored in the preferences
1033 file to the given handle (which must be pre-allocated). If the handle is too
1034 small, then it will be enlarged. If it is too large, it will not be resized.
1035 The data in the preferences file (normally in PREF 0) will then be copied
1036 into the handle. If the preferences file did not exist, the original data
1037 in the handle will not change.
1039 OSErr SavePrefsFile(Handle prefsHndl)
1041 This function will attempt to save the given handle to the preferences
1042 file. Its contents will completely replace the previous data (normally
1043 the PREF 0 resource).
1045 In typical use, you will use InitPrefsFile once, then allocate a handle large
1046 enough to contain your preferences data, and initialize it with default values.
1047 Throughout the course of your program, the handle will undergo modification as
1048 user preferences change. You can use SavePrefsFile anytime to update the
1049 preferences file, or wait until program exit to do so.
1053 int ReadConfigFile()
1057 Handle prefs_handle;
1061 if (!have_prefs) { // not initialized....get a handle to the preferences file
1062 InitPrefsFile('DCT2');
1066 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
1067 if (prefs_handle == NULL)
1070 prefs = (Preferences *)(*prefs_handle);
1071 err = LoadPrefsFile(prefs_handle);
1073 DisposeHandle(prefs_handle);
1078 for (i = 0; i < sizeof(Preferences); i++) {
1083 if ( i == sizeof(Preferences) )
1086 Config_digi_volume = prefs->digi_volume;
1087 Config_midi_volume = prefs->midi_volume;
1088 Config_master_volume = prefs->master_volume;
1089 Config_redbook_volume = prefs->redbook_volume;
1090 Config_channels_reversed = prefs->stereo_reverse;
1091 gr_palette_set_gamma( (int)(prefs->gamma_level) );
1093 Scanline_double = (int)prefs->pixel_double;
1095 Scanline_double = 0; // can't double with hardware acceleration
1097 Detail_level = prefs->detail_level;
1098 if (Detail_level == NUM_DETAIL_LEVELS-1) {
1099 Object_complexity = prefs->oc;
1100 Object_detail = prefs->od;
1101 Wall_detail = prefs->wd;
1102 Wall_render_depth = prefs->wrd;
1103 Debris_amount = prefs->da;
1104 SoundChannels = prefs->sc;
1105 set_custom_detail_vars();
1107 #ifdef PA_3DFX_VOODOO // Set to highest detail because you can't change em
1108 Object_complexity=Object_detail=Wall_detail=
1109 Wall_render_depth=Debris_amount=SoundChannels = NUM_DETAIL_LEVELS-1;
1110 Detail_level=NUM_DETAIL_LEVELS-1;
1111 set_custom_detail_vars();
1114 strncpy( config_last_player, prefs->lastplayer, CALLSIGN_LEN );
1115 p = strchr(config_last_player, '\n' );
1118 strncpy(config_last_mission, prefs->lastmission, MISSION_NAME_LEN);
1119 p = strchr(config_last_mission, '\n' );
1122 strcpy(config_last_ctb_cfg, prefs->ctb_config);
1124 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
1126 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
1128 joy_set_cal_vals( prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
1129 digi_set_volume( (Config_digi_volume*256)/8, (Config_midi_volume*256)/8 );
1130 digi_set_master_volume(Config_master_volume);
1132 gConfigInfo.mDoNotDisplayOptions = prefs->display_dialog;
1133 gConfigInfo.mUse11kSounds = prefs->sound_11k;
1134 gConfigInfo.mDisableSound = prefs->nosound;
1135 gConfigInfo.mDisableMIDIMusic = prefs->nomidi;
1136 gConfigInfo.mChangeResolution = prefs->change_resolution;
1137 gConfigInfo.mDoNotPlayMovies = prefs->no_movies;
1138 gConfigInfo.mGameMonitor = prefs->game_monitor;
1139 gConfigInfo.mAcceleration = prefs->enable_rave;
1140 gConfigInfo.mInputSprockets = prefs->enable_input_sprockets;
1142 DisposeHandle(prefs_handle);
1146 int WriteConfigFile()
1149 Handle prefs_handle;
1152 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
1153 if (prefs_handle == NULL)
1156 prefs = (Preferences *)(*prefs_handle);
1158 joy_get_cal_vals(prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
1159 prefs->digi_volume = Config_digi_volume;
1160 prefs->midi_volume = Config_midi_volume;
1161 prefs->stereo_reverse = Config_channels_reversed;
1162 prefs->detail_level = Detail_level;
1163 if (Detail_level == NUM_DETAIL_LEVELS-1) {
1164 prefs->oc = Object_complexity;
1165 prefs->od = Object_detail;
1166 prefs->wd = Wall_detail;
1167 prefs->wrd = Wall_render_depth;
1168 prefs->da = Debris_amount;
1169 prefs->sc = SoundChannels;
1171 prefs->gamma_level = (ubyte)gr_palette_get_gamma();
1174 prefs->pixel_double = (ubyte)Scanline_double; // hmm..don't write this out if doing hardware accel.
1176 strncpy( prefs->lastplayer, Players[Player_num].callsign, CALLSIGN_LEN );
1177 strncpy( prefs->lastmission, config_last_mission, MISSION_NAME_LEN );
1178 strcpy( prefs->ctb_config, config_last_ctb_cfg);
1179 prefs->ctb_tool = config_last_ctb_tool;
1180 prefs->master_volume = Config_master_volume;
1181 prefs->display_dialog = gConfigInfo.mDoNotDisplayOptions;
1182 prefs->change_resolution = gConfigInfo.mChangeResolution;
1183 prefs->nosound = gConfigInfo.mDisableSound;
1184 prefs->nomidi = gConfigInfo.mDisableMIDIMusic;
1185 prefs->sound_11k = gConfigInfo.mUse11kSounds;
1186 prefs->no_movies = gConfigInfo.mDoNotPlayMovies;
1187 prefs->game_monitor = gConfigInfo.mGameMonitor;
1188 prefs->redbook_volume = Config_redbook_volume;
1189 prefs->enable_rave = gConfigInfo.mAcceleration;
1190 prefs->enable_input_sprockets = gConfigInfo.mInputSprockets;
1192 err = SavePrefsFile(prefs_handle);
1193 DisposeHandle(prefs_handle);