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.
18 #ifndef MACINTOSH // I'm going to totally seperate these routines -- yeeech!!!!
19 // see end of file for macintosh equivs
22 #define WIN32_LEAN_AND_MEAN
51 static char rcsid[] = "$Id: config.c,v 1.6 2003-03-22 04:04:47 btb Exp $";
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;
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";
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
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";
93 char config_last_player[CALLSIGN_LEN+1] = "";
94 char config_last_mission[MISSION_NAME_LEN+1] = "";
96 int Config_digi_type = 0;
97 int Config_digi_dma = 0;
98 int Config_midi_type = 0;
101 int DOSJoySaveMin[4];
102 int DOSJoySaveCen[4];
103 int DOSJoySaveMax[4];
105 char win95_current_joyname[256];
110 int Config_vr_type = 0;
111 int Config_vr_resolution = 0;
112 int Config_vr_tracking = 0;
114 int digi_driver_board_16;
115 int digi_driver_dma_16;
117 extern byte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
119 void set_custom_detail_vars(void);
125 void CrystalLakeWriteMCP( ushort mc_addr, ubyte mc_data )
128 outp( CL_MC0, 0xE2 ); // Write password
129 outp( mc_addr, mc_data ); // Write data
133 ubyte CrystalLakeReadMCP( ushort mc_addr )
137 outp( CL_MC0, 0xE2 ); // Write password
138 value = inp( mc_addr ); // Read data
143 void CrystalLakeSetSB()
146 tmp = CrystalLakeReadMCP( CL_MC1 );
148 CrystalLakeWriteMCP( CL_MC1, tmp );
151 void CrystalLakeSetWSS()
154 tmp = CrystalLakeReadMCP( CL_MC1 );
156 CrystalLakeWriteMCP( CL_MC1, tmp );
159 //MovieHires might be changed by -nohighres, so save a "real" copy of it
161 int save_redbook_enabled;
164 void CheckMovieAttributes()
167 DWORD len, type, val;
170 lres = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Parallax\\Descent II\\1.1\\INSTALL",
172 if (lres == ERROR_SUCCESS) {
174 lres = RegQueryValueEx(hKey, "HIRES", NULL, &type, &val, &len);
175 if (lres == ERROR_SUCCESS) {
177 logentry("HIRES=%d\n", val);
189 char line[80], *token, *value, *ptr;
192 int joy_axis_center[7];
196 strcpy( config_last_player, "" );
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;
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);
208 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
211 /*digi_driver_board = 0;
212 digi_driver_port = 0;
217 digi_midi_port = 0;*/
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;
225 //set these here in case no cfg file
226 SaveMovieHires = MovieHires;
227 save_redbook_enabled = Redbook_enabled;
229 infile = fopen("descent.cfg", "rt");
230 if (infile == NULL) {
231 WIN(CheckMovieAttributes());
234 while (!feof(infile)) {
236 fgets(line, 80, infile);
238 while (isspace(*ptr))
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 );
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;
280 count = sscanf (value, "%d,%d,%d,%d,%d,%d,%d\n",&dummy,&oc,&od,&wd,&wrd,&da,&sc);
283 Object_complexity = oc;
286 Wall_render_depth = wrd;
289 set_custom_detail_vars();
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();
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] );
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] );
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] );
308 else if (!strcmp(token, last_player_str)) {
310 strncpy( config_last_player, value, CALLSIGN_LEN );
311 p = strchr( config_last_player, '\n');
314 else if (!strcmp(token, last_mission_str)) {
316 strncpy( config_last_mission, value, MISSION_NAME_LEN );
317 p = strchr( config_last_mission, '\n');
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);
336 DOSJoySaveMin[i]=joy_axis_min[i];
337 DOSJoySaveCen[i]=joy_axis_center[i];
338 DOSJoySaveMax[i]=joy_axis_max[i];
341 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
344 i = FindArg( "-volume" );
347 i = atoi( Args[i+1] );
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;
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;
359 digi_set_volume( (Config_digi_volume*32768)/8, (Config_midi_volume*128)/8 );
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 );
370 /*Config_midi_type = digi_midi_type;
371 Config_digi_type = digi_driver_board;
372 Config_digi_dma = digi_driver_dma;*/
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;
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 ) {
385 tmp = CrystalLakeReadMCP( CL_MC1 );
387 atexit( CrystalLakeSetSB ); // Restore to SB when done.
389 digi_driver_board = _MICROSOFT_8_ST;
390 } else if ( digi_driver_board == _CRYSTAL_LAKE_16_ST ) {
392 tmp = CrystalLakeReadMCP( CL_MC1 );
394 atexit( CrystalLakeSetSB ); // Restore to SB when done.
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;
402 digi_driver_board = digi_driver_board;
404 infile = fopen("descentw.cfg", "rt");
406 while (!feof(infile)) {
408 fgets(line, 80, infile);
410 while (isspace(*ptr))
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] );
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] );
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] );
435 int WriteConfigFile()
440 int joy_axis_center[7];
442 ubyte gamma = gr_palette_get_gamma();
444 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
449 joy_axis_min[i]=DOSJoySaveMin[i];
450 joy_axis_center[i]=DOSJoySaveCen[i];
451 joy_axis_max[i]=DOSJoySaveMax[i];
455 infile = fopen("descent.cfg", "wt");
456 if (infile == NULL) {
459 /*sprintf (str, "%s=0x%x\n", digi_dev8_str, Config_digi_type);
461 sprintf (str, "%s=0x%x\n", digi_dev16_str, digi_driver_board_16);
463 sprintf (str, "%s=0x%x\n", digi_port_str, digi_driver_port);
465 sprintf (str, "%s=%d\n", digi_irq_str, digi_driver_irq);
467 sprintf (str, "%s=%d\n", digi_dma8_str, Config_digi_dma);
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);
473 /*sprintf (str, "%s=0x%x\n", midi_dev_str, Config_midi_type);
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);
479 sprintf (str, "%s=%d\n", redbook_enabled_str, FindArg("-noredbook")?save_redbook_enabled:Redbook_enabled);
481 sprintf (str, "%s=%d\n", redbook_volume_str, Config_redbook_volume);
483 sprintf (str, "%s=%d\n", stereo_rev_str, Config_channels_reversed);
485 sprintf (str, "%s=%d\n", gamma_level_str, gamma);
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);
491 sprintf (str, "%s=%d\n", detail_level_str, Detail_level);
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] );
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] );
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] );
501 sprintf (str, "%s=%s\n", last_player_str, Players[Player_num].callsign );
503 sprintf (str, "%s=%s\n", last_mission_str, config_last_mission );
505 sprintf (str, "%s=%d\n", config_vr_type_str, Config_vr_type );
507 sprintf (str, "%s=%d\n", config_vr_resolution_str, Config_vr_resolution );
509 sprintf (str, "%s=%d\n", config_vr_tracking_str, Config_vr_tracking );
511 sprintf (str, "%s=%d\n", movie_hires_str, (FindArg("-nohires") || FindArg("-nohighres") || FindArg("-lowresmovies"))?SaveMovieHires:MovieHires);
518 // Save Windows Config File
522 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
524 infile = fopen("descentw.cfg", "wt");
525 if (infile == NULL) return 1;
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]);
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]);
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]);
542 CheckMovieAttributes();
548 #else // !defined(MACINTOSH)
557 #include <GestaltEqu.h>
559 #include <Processes.h>
560 #include <Resources.h>
563 #include "pa_enabl.h" // because some prefs rely on this fact
574 #include "prefs.h" // prefs file for configuration stuff -- from DeSalvo
576 #if defined(POLY_ACC)
577 #include "poly_acc.h"
581 static char rcsid[] = "$Id: config.c,v 1.6 2003-03-22 04:04:47 btb Exp $";
584 #define MAX_CTB_LEN 512
586 typedef struct preferences {
589 ubyte stereo_reverse;
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
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];
607 ubyte display_dialog;
608 ubyte change_resolution;
614 ubyte redbook_volume;
616 ubyte enable_input_sprockets;
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;
631 int Config_vr_type = 0;
632 int Config_vr_resolution = 0;
633 int Config_vr_tracking = 0;
635 extern byte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
636 extern void digi_set_master_volume( int volume );
638 void set_custom_detail_vars(void);
640 static ubyte have_prefs = 0;
642 //¥ ------------------------------ Private Definitions
643 //¥ ------------------------------ Private Types
652 } PrefsInfo, *PrefsInfoPtr, **PrefsInfoHandle;
654 //¥ ------------------------------ Private Variables
656 static PrefsInfo prefsInfo;
657 static Boolean prefsInited = 0;
659 //¥ ------------------------------ Private Functions
661 static void Pstrcpy(StringPtr dst, StringPtr src);
662 static void Pstrcat(StringPtr dst, StringPtr src);
663 static Boolean FindPrefsFile(short *prefVRefNum, long *prefDirID);
665 //¥ -------------------- Pstrcpy
668 Pstrcpy(StringPtr dst, StringPtr src)
670 BlockMove(src, dst, (*src) + 1);
673 //¥ -------------------- Pstrcat
676 Pstrcat(StringPtr dst, StringPtr src)
678 BlockMove(src + 1, dst + (*dst) + 1, *src);
682 //¥ -------------------- FindPrefsFile
685 FindPrefsFile(short *prefVRefNum, long *prefDirID)
694 theErr = Gestalt(gestaltFindFolderAttr, &response);
695 if (theErr == noErr && ((response >> gestaltFindFolderPresent) & 1))
697 //¥ Find (or make) it the easy way...
698 theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, prefVRefNum, prefDirID);
703 StringPtr prefFolderName = "\pPreferences";
705 //¥ yeachh -- we have to do it all by hand!
706 theErr = SysEnvirons(1, &theSysEnv);
710 *prefVRefNum = theSysEnv.sysVRefNum;
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;
719 theErr = PBGetCatInfo(&infoPB, 0);
722 *prefDirID = infoPB.hFileInfo.ioDirID;
724 else if (theErr == fnfErr) //¥ Preferences doesn't already exist
726 HParamBlockRec dirPB;
728 //¥ Create "Preferences" folder
729 dirPB.fileParam.ioCompletion = 0;
730 dirPB.fileParam.ioVRefNum = *prefVRefNum;
731 dirPB.fileParam.ioNamePtr = prefFolderName;
732 dirPB.fileParam.ioDirID = 0;
734 theErr = PBDirCreate(&dirPB, 0);
736 *prefDirID = dirPB.fileParam.ioDirID;
740 //¥ If we make it here OK, create Preferences file if necessary
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;
749 theErr = PBGetCatInfo(&infoPB, 0);
750 if (theErr == fnfErr)
752 theErr = HCreate(*prefVRefNum, *prefDirID, prefsInfo.fileName, prefsInfo.creator, prefsInfo.fileType);
755 HCreateResFile(*prefVRefNum, *prefDirID, prefsInfo.fileName);
761 return (theErr == noErr);
764 //¥ -------------------- InitPrefsFile
766 #define UNKNOWN_TYPE 0x3f3f3f3f
769 InitPrefsFile(OSType creator)
772 PrefsInfoHandle piHdl;
774 if ((piHdl = (PrefsInfoHandle) GetResource('PRFI', 0)) == nil)
776 ProcessSerialNumber thePSN;
777 ProcessInfoRec thePIR;
779 StringPtr app_string;
782 GetCurrentProcess(&thePSN);
783 thePIR.processName = nil;
784 thePIR.processAppSpec = &appSpec;
786 //¥ Set default to 'ÇApplicationÈ Prefs', PREF 0
787 err = GetProcessInformation(&thePSN, &thePIR);
791 app_string = LMGetCurApName();
792 // Pstrcpy(prefsInfo.fileName, appSpec.name);
793 Pstrcpy(prefsInfo.fileName, app_string);
794 Pstrcat(prefsInfo.fileName, "\p Preferences");
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';
805 //¥ Get Preferences file setup from PRFI 0
806 BlockMove(*piHdl, &prefsInfo, sizeof (prefsInfo));
807 ReleaseResource((Handle) piHdl);
809 if (prefsInfo.creator == UNKNOWN_TYPE)
810 prefsInfo.creator = creator;
816 //¥ -------------------- LoadPrefsFile
819 LoadPrefsFile(Handle prefsHdl)
821 short prefVRefNum, prefRefNum;
823 OSErr theErr = noErr;
825 Size prefSize, origSize;
828 return (nilHandleErr);
830 prefSize = GetHandleSize(prefsHdl);
832 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
835 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
836 if (prefRefNum == -1)
839 //¥ Not finding the resource is not an error -- caller will use default data
840 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
842 origSize = GetHandleSize(origHdl);
843 if (origSize > prefSize) //¥ Extend handle for extra stored data
844 SetHandleSize(prefsHdl, origSize);
846 BlockMove(*origHdl, *prefsHdl, origSize);
847 ReleaseResource(origHdl);
850 CloseResFile(prefRefNum);
858 //¥ -------------------- SavePrefsFile
861 SavePrefsFile(Handle prefHdl)
863 short prefVRefNum, prefRefNum;
865 Handle origHdl = nil;
866 Size origSize, prefSize;
867 OSErr theErr = noErr;
869 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
873 return (nilHandleErr);
875 prefSize = GetHandleSize(prefHdl);
877 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
878 if (prefRefNum == -1)
881 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
883 //¥ Overwrite existing preferences
884 origSize = GetHandleSize(origHdl);
885 if (prefSize > origSize)
886 SetHandleSize(origHdl, prefSize);
888 BlockMove(*prefHdl, *origHdl, prefSize);
889 ChangedResource(origHdl);
890 WriteResource(origHdl);
891 ReleaseResource(origHdl);
895 //¥ Store specified preferences for the first time
896 AddResource(prefHdl, prefsInfo.resType, prefsInfo.resID, "\p");
897 WriteResource(prefHdl);
898 DetachResource(prefHdl);
901 CloseResFile(prefRefNum);
909 //¥ -------------------------------------------------------------------------------------------
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.).
917 Three functions are provided:
919 void InitPrefsFile(OSType creator)
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
928 File Name: "{Application} Prefs" (i.e., the name of the app plus " Prefs"
929 Creator: the creator passed to InitPrefsFile
931 Pref Resource Type: 'PREF'
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.
938 OSErr LoadPrefsFile(Handle prefsHndl)
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.
947 OSErr SavePrefsFile(Handle prefsHndl)
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).
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.
969 if (!have_prefs) { // not initialized....get a handle to the preferences file
970 InitPrefsFile('DCT2');
974 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
975 if (prefs_handle == NULL)
978 prefs = (Preferences *)(*prefs_handle);
979 err = LoadPrefsFile(prefs_handle);
981 DisposeHandle(prefs_handle);
986 for (i = 0; i < sizeof(Preferences); i++) {
991 if ( i == sizeof(Preferences) )
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) );
1001 Scanline_double = (int)prefs->pixel_double;
1003 Scanline_double = 0; // can't double with hardware acceleration
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();
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();
1022 strncpy( config_last_player, prefs->lastplayer, CALLSIGN_LEN );
1023 p = strchr(config_last_player, '\n' );
1026 strncpy(config_last_mission, prefs->lastmission, MISSION_NAME_LEN);
1027 p = strchr(config_last_mission, '\n' );
1030 strcpy(config_last_ctb_cfg, prefs->ctb_config);
1032 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
1034 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
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);
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;
1050 DisposeHandle(prefs_handle);
1054 int WriteConfigFile()
1057 Handle prefs_handle;
1060 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
1061 if (prefs_handle == NULL)
1064 prefs = (Preferences *)(*prefs_handle);
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;
1079 prefs->gamma_level = (ubyte)gr_palette_get_gamma();
1082 prefs->pixel_double = (ubyte)Scanline_double; // hmm..don't write this out if doing hardware accel.
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;
1100 err = SavePrefsFile(prefs_handle);
1101 DisposeHandle(prefs_handle);