1 /* $Id: config.c,v 1.9 2003-10-04 03:28:47 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.9 2003-10-04 03:28:47 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 if (cfgets(line, 80, infile) == EOF)
330 while (isspace(*ptr))
333 token = strtok(ptr, "=");
334 value = strtok(NULL, "=");
335 if (value[strlen(value)-1] == '\n')
336 value[strlen(value)-1] = 0;
337 /* if (!strcmp(token, digi_dev8_str))
338 digi_driver_board = strtol(value, NULL, 16);
339 else if (!strcmp(token, digi_dev16_str))
340 digi_driver_board_16 = strtol(value, NULL, 16);
341 else if (!strcmp(token, digi_port_str))
342 digi_driver_port = strtol(value, NULL, 16);
343 else if (!strcmp(token, digi_irq_str))
344 digi_driver_irq = strtol(value, NULL, 10);
345 else if (!strcmp(token, digi_dma8_str))
346 digi_driver_dma = strtol(value, NULL, 10);
347 else if (!strcmp(token, digi_dma16_str))
348 digi_driver_dma_16 = strtol(value, NULL, 10);
349 else*/ if (!strcmp(token, digi_volume_str))
350 Config_digi_volume = strtol(value, NULL, 10);
351 else/* if (!strcmp(token, midi_dev_str))
352 digi_midi_type = strtol(value, NULL, 16);
353 else if (!strcmp(token, midi_port_str))
354 digi_midi_port = strtol(value, NULL, 16);
355 else*/ if (!strcmp(token, midi_volume_str))
356 Config_midi_volume = strtol(value, NULL, 10);
357 else if (!strcmp(token, redbook_enabled_str))
358 Redbook_enabled = save_redbook_enabled = strtol(value, NULL, 10);
359 else if (!strcmp(token, redbook_volume_str))
360 Config_redbook_volume = strtol(value, NULL, 10);
361 else if (!strcmp(token, stereo_rev_str))
362 Config_channels_reversed = strtol(value, NULL, 10);
363 else if (!strcmp(token, gamma_level_str)) {
364 gamma = strtol(value, NULL, 10);
365 gr_palette_set_gamma( gamma );
367 else if (!strcmp(token, detail_level_str)) {
368 Detail_level = strtol(value, NULL, 10);
369 if (Detail_level == NUM_DETAIL_LEVELS-1) {
370 int count,dummy,oc,od,wd,wrd,da,sc;
372 count = sscanf (value, "%d,%d,%d,%d,%d,%d,%d\n",&dummy,&oc,&od,&wd,&wrd,&da,&sc);
375 Object_complexity = oc;
378 Wall_render_depth = wrd;
381 set_custom_detail_vars();
383 #ifdef PA_3DFX_VOODOO // Set to highest detail because you can't change em
384 Object_complexity=Object_detail=Wall_detail=
385 Wall_render_depth=Debris_amount=SoundChannels = NUM_DETAIL_LEVELS-1;
386 Detail_level=NUM_DETAIL_LEVELS-1;
387 set_custom_detail_vars();
391 else if (!strcmp(token, joystick_min_str)) {
392 sscanf( value, "%d,%d,%d,%d", &joy_axis_min[0], &joy_axis_min[1], &joy_axis_min[2], &joy_axis_min[3] );
394 else if (!strcmp(token, joystick_max_str)) {
395 sscanf( value, "%d,%d,%d,%d", &joy_axis_max[0], &joy_axis_max[1], &joy_axis_max[2], &joy_axis_max[3] );
397 else if (!strcmp(token, joystick_cen_str)) {
398 sscanf( value, "%d,%d,%d,%d", &joy_axis_center[0], &joy_axis_center[1], &joy_axis_center[2], &joy_axis_center[3] );
400 else if (!strcmp(token, last_player_str)) {
402 strncpy( config_last_player, value, CALLSIGN_LEN );
403 p = strchr( config_last_player, '\n');
406 else if (!strcmp(token, last_mission_str)) {
408 strncpy( config_last_mission, value, MISSION_NAME_LEN );
409 p = strchr( config_last_mission, '\n');
411 } else if (!strcmp(token, config_vr_type_str)) {
412 Config_vr_type = strtol(value, NULL, 10);
413 } else if (!strcmp(token, config_vr_resolution_str)) {
414 Config_vr_resolution = strtol(value, NULL, 10);
415 } else if (!strcmp(token, config_vr_tracking_str)) {
416 Config_vr_tracking = strtol(value, NULL, 10);
417 } else if (!strcmp(token, movie_hires_str)) {
418 SaveMovieHires = MovieHires = strtol(value, NULL, 10);
428 DOSJoySaveMin[i]=joy_axis_min[i];
429 DOSJoySaveCen[i]=joy_axis_center[i];
430 DOSJoySaveMax[i]=joy_axis_max[i];
433 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
436 i = FindArg( "-volume" );
439 i = atoi( Args[i+1] );
441 if ( i > 100 ) i = 100;
442 Config_digi_volume = (i*8)/100;
443 Config_midi_volume = (i*8)/100;
444 Config_redbook_volume = (i*8)/100;
447 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
448 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
449 if ( Config_redbook_volume > 8 ) Config_redbook_volume = 8;
451 digi_set_volume( (Config_digi_volume*32768)/8, (Config_midi_volume*128)/8 );
453 printf( "DigiDeviceID: 0x%x\n", digi_driver_board );
454 printf( "DigiPort: 0x%x\n", digi_driver_port );
455 printf( "DigiIrq: 0x%x\n", digi_driver_irq );
456 printf( "DigiDma: 0x%x\n", digi_driver_dma );
457 printf( "MidiDeviceID: 0x%x\n", digi_midi_type );
458 printf( "MidiPort: 0x%x\n", digi_midi_port );
462 /*Config_midi_type = digi_midi_type;
463 Config_digi_type = digi_driver_board;
464 Config_digi_dma = digi_driver_dma;*/
467 if (digi_driver_board_16 > 0 && !FindArg("-no16bit") && digi_driver_board_16 != _GUS_16_ST) {
468 digi_driver_board = digi_driver_board_16;
469 digi_driver_dma = digi_driver_dma_16;
473 //Hack to make some cards look like others, such as
474 //the Crytal Lake look like Microsoft Sound System
475 if ( digi_driver_board == _CRYSTAL_LAKE_8_ST ) {
477 tmp = CrystalLakeReadMCP( CL_MC1 );
479 atexit( CrystalLakeSetSB ); // Restore to SB when done.
481 digi_driver_board = _MICROSOFT_8_ST;
482 } else if ( digi_driver_board == _CRYSTAL_LAKE_16_ST ) {
484 tmp = CrystalLakeReadMCP( CL_MC1 );
486 atexit( CrystalLakeSetSB ); // Restore to SB when done.
488 digi_driver_board = _MICROSOFT_16_ST;
489 } else if ( digi_driver_board == _AWE32_8_ST ) {
490 digi_driver_board = _SB16_8_ST;
491 } else if ( digi_driver_board == _AWE32_16_ST ) {
492 digi_driver_board = _SB16_16_ST;
494 digi_driver_board = digi_driver_board;
496 infile = cfopen("descentw.cfg", "rt");
498 while (!cfeof(infile))
501 if (cfgets(line, 80, infile) == EOF)
504 while (isspace(*ptr))
507 token = strtok(ptr, "=");
508 value = strtok(NULL, "=");
509 if (value[strlen(value)-1] == '\n')
510 value[strlen(value)-1] = 0;
511 if (!strcmp(token, joystick_min_str)) {
512 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] );
514 else if (!strcmp(token, joystick_max_str)) {
515 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] );
517 else if (!strcmp(token, joystick_cen_str)) {
518 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] );
529 int WriteConfigFile()
534 int joy_axis_center[7];
536 ubyte gamma = gr_palette_get_gamma();
538 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
543 joy_axis_min[i]=DOSJoySaveMin[i];
544 joy_axis_center[i]=DOSJoySaveCen[i];
545 joy_axis_max[i]=DOSJoySaveMax[i];
549 infile = cfopen("descent.cfg", "wt");
550 if (infile == NULL) {
553 /*sprintf (str, "%s=0x%x\n", digi_dev8_str, Config_digi_type);
555 sprintf (str, "%s=0x%x\n", digi_dev16_str, digi_driver_board_16);
557 sprintf (str, "%s=0x%x\n", digi_port_str, digi_driver_port);
559 sprintf (str, "%s=%d\n", digi_irq_str, digi_driver_irq);
561 sprintf (str, "%s=%d\n", digi_dma8_str, Config_digi_dma);
563 sprintf (str, "%s=%d\n", digi_dma16_str, digi_driver_dma_16);
564 cfputs(str, infile);*/
565 sprintf (str, "%s=%d\n", digi_volume_str, Config_digi_volume);
567 /*sprintf (str, "%s=0x%x\n", midi_dev_str, Config_midi_type);
569 sprintf (str, "%s=0x%x\n", midi_port_str, digi_midi_port);
570 cfputs(str, infile);*/
571 sprintf (str, "%s=%d\n", midi_volume_str, Config_midi_volume);
573 sprintf (str, "%s=%d\n", redbook_enabled_str, FindArg("-noredbook")?save_redbook_enabled:Redbook_enabled);
575 sprintf (str, "%s=%d\n", redbook_volume_str, Config_redbook_volume);
577 sprintf (str, "%s=%d\n", stereo_rev_str, Config_channels_reversed);
579 sprintf (str, "%s=%d\n", gamma_level_str, gamma);
581 if (Detail_level == NUM_DETAIL_LEVELS-1)
582 sprintf (str, "%s=%d,%d,%d,%d,%d,%d,%d\n", detail_level_str, Detail_level,
583 Object_complexity,Object_detail,Wall_detail,Wall_render_depth,Debris_amount,SoundChannels);
585 sprintf (str, "%s=%d\n", detail_level_str, Detail_level);
588 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] );
590 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] );
592 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] );
595 sprintf (str, "%s=%s\n", last_player_str, Players[Player_num].callsign );
597 sprintf (str, "%s=%s\n", last_mission_str, config_last_mission );
599 sprintf (str, "%s=%d\n", config_vr_type_str, Config_vr_type );
601 sprintf (str, "%s=%d\n", config_vr_resolution_str, Config_vr_resolution );
603 sprintf (str, "%s=%d\n", config_vr_tracking_str, Config_vr_tracking );
605 sprintf (str, "%s=%d\n", movie_hires_str, (FindArg("-nohires") || FindArg("-nohighres") || FindArg("-lowresmovies"))?SaveMovieHires:MovieHires);
612 // Save Windows Config File
616 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
618 infile = cfopen("descentw.cfg", "wt");
619 if (infile == NULL) return 1;
621 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_min_str,
622 joy_axis_min[0], joy_axis_min[1], joy_axis_min[2], joy_axis_min[3],
623 joy_axis_min[4], joy_axis_min[5], joy_axis_min[6]);
625 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_cen_str,
626 joy_axis_center[0], joy_axis_center[1], joy_axis_center[2], joy_axis_center[3],
627 joy_axis_center[4], joy_axis_center[5], joy_axis_center[6]);
629 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_max_str,
630 joy_axis_max[0], joy_axis_max[1], joy_axis_max[2], joy_axis_max[3],
631 joy_axis_max[4], joy_axis_max[5], joy_axis_max[6]);
636 CheckMovieAttributes();
642 #else // !defined(MACINTOSH)
651 #include <GestaltEqu.h>
653 #include <Processes.h>
654 #include <Resources.h>
657 #include "pa_enabl.h" // because some prefs rely on this fact
668 #include "prefs.h" // prefs file for configuration stuff -- from DeSalvo
670 #if defined(POLY_ACC)
671 #include "poly_acc.h"
675 static char rcsid[] = "$Id: config.c,v 1.9 2003-10-04 03:28:47 btb Exp $";
678 #define MAX_CTB_LEN 512
680 typedef struct preferences {
683 ubyte stereo_reverse;
685 ubyte oc; // object complexity
686 ubyte od; // object detail
687 ubyte wd; // wall detail
688 ubyte wrd; // wall render depth
689 ubyte da; // debris amount
690 ubyte sc; // sound channels
695 int joy_axis_center[4];
696 char lastplayer[CALLSIGN_LEN+1];
697 char lastmission[MISSION_NAME_LEN+1];
698 char ctb_config[MAX_CTB_LEN];
701 ubyte display_dialog;
702 ubyte change_resolution;
708 ubyte redbook_volume;
710 ubyte enable_input_sprockets;
713 char config_last_player[CALLSIGN_LEN+1] = "";
714 char config_last_mission[MISSION_NAME_LEN+1] = "";
715 char config_last_ctb_cfg[MAX_CTB_LEN] = "";
716 int config_last_ctb_tool;
717 ubyte Config_master_volume = 4;
718 ubyte Config_digi_volume = 8;
719 ubyte Config_midi_volume = 8;
720 ubyte Config_redbook_volume = 8;
721 ubyte Config_control_type = 0;
722 ubyte Config_channels_reversed = 0;
723 ubyte Config_joystick_sensitivity = 8;
725 int Config_vr_type = 0;
726 int Config_vr_resolution = 0;
727 int Config_vr_tracking = 0;
729 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
730 extern void digi_set_master_volume( int volume );
732 void set_custom_detail_vars(void);
734 static ubyte have_prefs = 0;
736 //¥ ------------------------------ Private Definitions
737 //¥ ------------------------------ Private Types
746 } PrefsInfo, *PrefsInfoPtr, **PrefsInfoHandle;
748 //¥ ------------------------------ Private Variables
750 static PrefsInfo prefsInfo;
751 static Boolean prefsInited = 0;
753 //¥ ------------------------------ Private Functions
755 static void Pstrcpy(StringPtr dst, StringPtr src);
756 static void Pstrcat(StringPtr dst, StringPtr src);
757 static Boolean FindPrefsFile(short *prefVRefNum, long *prefDirID);
759 //¥ -------------------- Pstrcpy
762 Pstrcpy(StringPtr dst, StringPtr src)
764 BlockMove(src, dst, (*src) + 1);
767 //¥ -------------------- Pstrcat
770 Pstrcat(StringPtr dst, StringPtr src)
772 BlockMove(src + 1, dst + (*dst) + 1, *src);
776 //¥ -------------------- FindPrefsFile
779 FindPrefsFile(short *prefVRefNum, long *prefDirID)
788 theErr = Gestalt(gestaltFindFolderAttr, &response);
789 if (theErr == noErr && ((response >> gestaltFindFolderPresent) & 1))
791 //¥ Find (or make) it the easy way...
792 theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, prefVRefNum, prefDirID);
797 StringPtr prefFolderName = "\pPreferences";
799 //¥ yeachh -- we have to do it all by hand!
800 theErr = SysEnvirons(1, &theSysEnv);
804 *prefVRefNum = theSysEnv.sysVRefNum;
806 //¥ Check whether Preferences folder already exists
807 infoPB.hFileInfo.ioCompletion = 0;
808 infoPB.hFileInfo.ioNamePtr = prefFolderName;
809 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
810 infoPB.hFileInfo.ioFDirIndex = 0;
811 infoPB.hFileInfo.ioDirID = 0;
813 theErr = PBGetCatInfo(&infoPB, 0);
816 *prefDirID = infoPB.hFileInfo.ioDirID;
818 else if (theErr == fnfErr) //¥ Preferences doesn't already exist
820 HParamBlockRec dirPB;
822 //¥ Create "Preferences" folder
823 dirPB.fileParam.ioCompletion = 0;
824 dirPB.fileParam.ioVRefNum = *prefVRefNum;
825 dirPB.fileParam.ioNamePtr = prefFolderName;
826 dirPB.fileParam.ioDirID = 0;
828 theErr = PBDirCreate(&dirPB, 0);
830 *prefDirID = dirPB.fileParam.ioDirID;
834 //¥ If we make it here OK, create Preferences file if necessary
837 infoPB.hFileInfo.ioCompletion = 0;
838 infoPB.hFileInfo.ioNamePtr = prefsInfo.fileName;
839 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
840 infoPB.hFileInfo.ioFDirIndex = 0;
841 infoPB.hFileInfo.ioDirID = *prefDirID;
843 theErr = PBGetCatInfo(&infoPB, 0);
844 if (theErr == fnfErr)
846 theErr = HCreate(*prefVRefNum, *prefDirID, prefsInfo.fileName, prefsInfo.creator, prefsInfo.fileType);
849 HCreateResFile(*prefVRefNum, *prefDirID, prefsInfo.fileName);
855 return (theErr == noErr);
858 //¥ -------------------- InitPrefsFile
860 #define UNKNOWN_TYPE 0x3f3f3f3f
863 InitPrefsFile(OSType creator)
866 PrefsInfoHandle piHdl;
868 if ((piHdl = (PrefsInfoHandle) GetResource('PRFI', 0)) == nil)
870 ProcessSerialNumber thePSN;
871 ProcessInfoRec thePIR;
873 StringPtr app_string;
876 GetCurrentProcess(&thePSN);
877 thePIR.processName = nil;
878 thePIR.processAppSpec = &appSpec;
880 //¥ Set default to 'ÇApplicationÈ Prefs', PREF 0
881 err = GetProcessInformation(&thePSN, &thePIR);
885 app_string = LMGetCurApName();
886 // Pstrcpy(prefsInfo.fileName, appSpec.name);
887 Pstrcpy(prefsInfo.fileName, app_string);
888 Pstrcat(prefsInfo.fileName, "\p Preferences");
890 //¥ Set creator to calling application's signature (should be able to
891 //¥ Determine this automatically, but unable to for some reason)
892 prefsInfo.creator = creator;
893 prefsInfo.fileType = 'pref';
894 prefsInfo.resType = 'pref';
899 //¥ Get Preferences file setup from PRFI 0
900 BlockMove(*piHdl, &prefsInfo, sizeof (prefsInfo));
901 ReleaseResource((Handle) piHdl);
903 if (prefsInfo.creator == UNKNOWN_TYPE)
904 prefsInfo.creator = creator;
910 //¥ -------------------- LoadPrefsFile
913 LoadPrefsFile(Handle prefsHdl)
915 short prefVRefNum, prefRefNum;
917 OSErr theErr = noErr;
919 Size prefSize, origSize;
922 return (nilHandleErr);
924 prefSize = GetHandleSize(prefsHdl);
926 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
929 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
930 if (prefRefNum == -1)
933 //¥ Not finding the resource is not an error -- caller will use default data
934 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
936 origSize = GetHandleSize(origHdl);
937 if (origSize > prefSize) //¥ Extend handle for extra stored data
938 SetHandleSize(prefsHdl, origSize);
940 BlockMove(*origHdl, *prefsHdl, origSize);
941 ReleaseResource(origHdl);
944 CloseResFile(prefRefNum);
952 //¥ -------------------- SavePrefsFile
955 SavePrefsFile(Handle prefHdl)
957 short prefVRefNum, prefRefNum;
959 Handle origHdl = nil;
960 Size origSize, prefSize;
961 OSErr theErr = noErr;
963 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
967 return (nilHandleErr);
969 prefSize = GetHandleSize(prefHdl);
971 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
972 if (prefRefNum == -1)
975 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
977 //¥ Overwrite existing preferences
978 origSize = GetHandleSize(origHdl);
979 if (prefSize > origSize)
980 SetHandleSize(origHdl, prefSize);
982 BlockMove(*prefHdl, *origHdl, prefSize);
983 ChangedResource(origHdl);
984 WriteResource(origHdl);
985 ReleaseResource(origHdl);
989 //¥ Store specified preferences for the first time
990 AddResource(prefHdl, prefsInfo.resType, prefsInfo.resID, "\p");
991 WriteResource(prefHdl);
992 DetachResource(prefHdl);
995 CloseResFile(prefRefNum);
1003 //¥ -------------------------------------------------------------------------------------------
1007 This module provides the ability to save and load a preferences file in the
1008 Preferences folder in the System Folder. An optional resource, PRFI 0,
1009 is used to provide specifications for the preferences file (creator, etc.).
1011 Three functions are provided:
1013 void InitPrefsFile(OSType creator)
1015 This function will initialize the preferences file, that is, it will create
1016 it in the appropriate place if it doesn't currently exist. It should be
1017 called with the creator code for the application. Note that the creator
1018 code specified in PRFI 0 (if any) will be used only if the creator code
1019 passed to this function is '????'. Without the PRFI 0 resource, the default
1022 File Name: "{Application} Prefs" (i.e., the name of the app plus " Prefs"
1023 Creator: the creator passed to InitPrefsFile
1025 Pref Resource Type: 'PREF'
1028 The PRFI 0 resource allows you to specify overrides for each of the above
1029 values. This is useful for development, since the application name might
1030 go through changes, but the preferences file name is held constant.
1032 OSErr LoadPrefsFile(Handle prefsHndl)
1034 This function will attempt to copy the data stored in the preferences
1035 file to the given handle (which must be pre-allocated). If the handle is too
1036 small, then it will be enlarged. If it is too large, it will not be resized.
1037 The data in the preferences file (normally in PREF 0) will then be copied
1038 into the handle. If the preferences file did not exist, the original data
1039 in the handle will not change.
1041 OSErr SavePrefsFile(Handle prefsHndl)
1043 This function will attempt to save the given handle to the preferences
1044 file. Its contents will completely replace the previous data (normally
1045 the PREF 0 resource).
1047 In typical use, you will use InitPrefsFile once, then allocate a handle large
1048 enough to contain your preferences data, and initialize it with default values.
1049 Throughout the course of your program, the handle will undergo modification as
1050 user preferences change. You can use SavePrefsFile anytime to update the
1051 preferences file, or wait until program exit to do so.
1055 int ReadConfigFile()
1059 Handle prefs_handle;
1063 if (!have_prefs) { // not initialized....get a handle to the preferences file
1064 InitPrefsFile('DCT2');
1068 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
1069 if (prefs_handle == NULL)
1072 prefs = (Preferences *)(*prefs_handle);
1073 err = LoadPrefsFile(prefs_handle);
1075 DisposeHandle(prefs_handle);
1080 for (i = 0; i < sizeof(Preferences); i++) {
1085 if ( i == sizeof(Preferences) )
1088 Config_digi_volume = prefs->digi_volume;
1089 Config_midi_volume = prefs->midi_volume;
1090 Config_master_volume = prefs->master_volume;
1091 Config_redbook_volume = prefs->redbook_volume;
1092 Config_channels_reversed = prefs->stereo_reverse;
1093 gr_palette_set_gamma( (int)(prefs->gamma_level) );
1095 Scanline_double = (int)prefs->pixel_double;
1097 Scanline_double = 0; // can't double with hardware acceleration
1099 Detail_level = prefs->detail_level;
1100 if (Detail_level == NUM_DETAIL_LEVELS-1) {
1101 Object_complexity = prefs->oc;
1102 Object_detail = prefs->od;
1103 Wall_detail = prefs->wd;
1104 Wall_render_depth = prefs->wrd;
1105 Debris_amount = prefs->da;
1106 SoundChannels = prefs->sc;
1107 set_custom_detail_vars();
1109 #ifdef PA_3DFX_VOODOO // Set to highest detail because you can't change em
1110 Object_complexity=Object_detail=Wall_detail=
1111 Wall_render_depth=Debris_amount=SoundChannels = NUM_DETAIL_LEVELS-1;
1112 Detail_level=NUM_DETAIL_LEVELS-1;
1113 set_custom_detail_vars();
1116 strncpy( config_last_player, prefs->lastplayer, CALLSIGN_LEN );
1117 p = strchr(config_last_player, '\n' );
1120 strncpy(config_last_mission, prefs->lastmission, MISSION_NAME_LEN);
1121 p = strchr(config_last_mission, '\n' );
1124 strcpy(config_last_ctb_cfg, prefs->ctb_config);
1126 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
1128 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
1130 joy_set_cal_vals( prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
1131 digi_set_volume( (Config_digi_volume*256)/8, (Config_midi_volume*256)/8 );
1132 digi_set_master_volume(Config_master_volume);
1134 gConfigInfo.mDoNotDisplayOptions = prefs->display_dialog;
1135 gConfigInfo.mUse11kSounds = prefs->sound_11k;
1136 gConfigInfo.mDisableSound = prefs->nosound;
1137 gConfigInfo.mDisableMIDIMusic = prefs->nomidi;
1138 gConfigInfo.mChangeResolution = prefs->change_resolution;
1139 gConfigInfo.mDoNotPlayMovies = prefs->no_movies;
1140 gConfigInfo.mGameMonitor = prefs->game_monitor;
1141 gConfigInfo.mAcceleration = prefs->enable_rave;
1142 gConfigInfo.mInputSprockets = prefs->enable_input_sprockets;
1144 DisposeHandle(prefs_handle);
1148 int WriteConfigFile()
1151 Handle prefs_handle;
1154 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
1155 if (prefs_handle == NULL)
1158 prefs = (Preferences *)(*prefs_handle);
1160 joy_get_cal_vals(prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
1161 prefs->digi_volume = Config_digi_volume;
1162 prefs->midi_volume = Config_midi_volume;
1163 prefs->stereo_reverse = Config_channels_reversed;
1164 prefs->detail_level = Detail_level;
1165 if (Detail_level == NUM_DETAIL_LEVELS-1) {
1166 prefs->oc = Object_complexity;
1167 prefs->od = Object_detail;
1168 prefs->wd = Wall_detail;
1169 prefs->wrd = Wall_render_depth;
1170 prefs->da = Debris_amount;
1171 prefs->sc = SoundChannels;
1173 prefs->gamma_level = (ubyte)gr_palette_get_gamma();
1176 prefs->pixel_double = (ubyte)Scanline_double; // hmm..don't write this out if doing hardware accel.
1178 strncpy( prefs->lastplayer, Players[Player_num].callsign, CALLSIGN_LEN );
1179 strncpy( prefs->lastmission, config_last_mission, MISSION_NAME_LEN );
1180 strcpy( prefs->ctb_config, config_last_ctb_cfg);
1181 prefs->ctb_tool = config_last_ctb_tool;
1182 prefs->master_volume = Config_master_volume;
1183 prefs->display_dialog = gConfigInfo.mDoNotDisplayOptions;
1184 prefs->change_resolution = gConfigInfo.mChangeResolution;
1185 prefs->nosound = gConfigInfo.mDisableSound;
1186 prefs->nomidi = gConfigInfo.mDisableMIDIMusic;
1187 prefs->sound_11k = gConfigInfo.mUse11kSounds;
1188 prefs->no_movies = gConfigInfo.mDoNotPlayMovies;
1189 prefs->game_monitor = gConfigInfo.mGameMonitor;
1190 prefs->redbook_volume = Config_redbook_volume;
1191 prefs->enable_rave = gConfigInfo.mAcceleration;
1192 prefs->enable_input_sprockets = gConfigInfo.mInputSprockets;
1194 err = SavePrefsFile(prefs_handle);
1195 DisposeHandle(prefs_handle);