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.7 2003-06-16 06:57:34 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 = cfopen("descent.cfg", "rt");
230 if (infile == NULL) {
231 WIN(CheckMovieAttributes());
234 while (!cfeof(infile))
237 cfgets(line, 80, infile);
239 while (isspace(*ptr))
242 token = strtok(ptr, "=");
243 value = strtok(NULL, "=");
244 if (value[strlen(value)-1] == '\n')
245 value[strlen(value)-1] = 0;
246 /* if (!strcmp(token, digi_dev8_str))
247 digi_driver_board = strtol(value, NULL, 16);
248 else if (!strcmp(token, digi_dev16_str))
249 digi_driver_board_16 = strtol(value, NULL, 16);
250 else if (!strcmp(token, digi_port_str))
251 digi_driver_port = strtol(value, NULL, 16);
252 else if (!strcmp(token, digi_irq_str))
253 digi_driver_irq = strtol(value, NULL, 10);
254 else if (!strcmp(token, digi_dma8_str))
255 digi_driver_dma = strtol(value, NULL, 10);
256 else if (!strcmp(token, digi_dma16_str))
257 digi_driver_dma_16 = strtol(value, NULL, 10);
258 else*/ if (!strcmp(token, digi_volume_str))
259 Config_digi_volume = strtol(value, NULL, 10);
260 else/* if (!strcmp(token, midi_dev_str))
261 digi_midi_type = strtol(value, NULL, 16);
262 else if (!strcmp(token, midi_port_str))
263 digi_midi_port = strtol(value, NULL, 16);
264 else*/ if (!strcmp(token, midi_volume_str))
265 Config_midi_volume = strtol(value, NULL, 10);
266 else if (!strcmp(token, redbook_enabled_str))
267 Redbook_enabled = save_redbook_enabled = strtol(value, NULL, 10);
268 else if (!strcmp(token, redbook_volume_str))
269 Config_redbook_volume = strtol(value, NULL, 10);
270 else if (!strcmp(token, stereo_rev_str))
271 Config_channels_reversed = strtol(value, NULL, 10);
272 else if (!strcmp(token, gamma_level_str)) {
273 gamma = strtol(value, NULL, 10);
274 gr_palette_set_gamma( gamma );
276 else if (!strcmp(token, detail_level_str)) {
277 Detail_level = strtol(value, NULL, 10);
278 if (Detail_level == NUM_DETAIL_LEVELS-1) {
279 int count,dummy,oc,od,wd,wrd,da,sc;
281 count = sscanf (value, "%d,%d,%d,%d,%d,%d,%d\n",&dummy,&oc,&od,&wd,&wrd,&da,&sc);
284 Object_complexity = oc;
287 Wall_render_depth = wrd;
290 set_custom_detail_vars();
292 #ifdef PA_3DFX_VOODOO // Set to highest detail because you can't change em
293 Object_complexity=Object_detail=Wall_detail=
294 Wall_render_depth=Debris_amount=SoundChannels = NUM_DETAIL_LEVELS-1;
295 Detail_level=NUM_DETAIL_LEVELS-1;
296 set_custom_detail_vars();
300 else if (!strcmp(token, joystick_min_str)) {
301 sscanf( value, "%d,%d,%d,%d", &joy_axis_min[0], &joy_axis_min[1], &joy_axis_min[2], &joy_axis_min[3] );
303 else if (!strcmp(token, joystick_max_str)) {
304 sscanf( value, "%d,%d,%d,%d", &joy_axis_max[0], &joy_axis_max[1], &joy_axis_max[2], &joy_axis_max[3] );
306 else if (!strcmp(token, joystick_cen_str)) {
307 sscanf( value, "%d,%d,%d,%d", &joy_axis_center[0], &joy_axis_center[1], &joy_axis_center[2], &joy_axis_center[3] );
309 else if (!strcmp(token, last_player_str)) {
311 strncpy( config_last_player, value, CALLSIGN_LEN );
312 p = strchr( config_last_player, '\n');
315 else if (!strcmp(token, last_mission_str)) {
317 strncpy( config_last_mission, value, MISSION_NAME_LEN );
318 p = strchr( config_last_mission, '\n');
320 } else if (!strcmp(token, config_vr_type_str)) {
321 Config_vr_type = strtol(value, NULL, 10);
322 } else if (!strcmp(token, config_vr_resolution_str)) {
323 Config_vr_resolution = strtol(value, NULL, 10);
324 } else if (!strcmp(token, config_vr_tracking_str)) {
325 Config_vr_tracking = strtol(value, NULL, 10);
326 } else if (!strcmp(token, movie_hires_str)) {
327 SaveMovieHires = MovieHires = strtol(value, NULL, 10);
337 DOSJoySaveMin[i]=joy_axis_min[i];
338 DOSJoySaveCen[i]=joy_axis_center[i];
339 DOSJoySaveMax[i]=joy_axis_max[i];
342 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
345 i = FindArg( "-volume" );
348 i = atoi( Args[i+1] );
350 if ( i > 100 ) i = 100;
351 Config_digi_volume = (i*8)/100;
352 Config_midi_volume = (i*8)/100;
353 Config_redbook_volume = (i*8)/100;
356 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
357 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
358 if ( Config_redbook_volume > 8 ) Config_redbook_volume = 8;
360 digi_set_volume( (Config_digi_volume*32768)/8, (Config_midi_volume*128)/8 );
362 printf( "DigiDeviceID: 0x%x\n", digi_driver_board );
363 printf( "DigiPort: 0x%x\n", digi_driver_port );
364 printf( "DigiIrq: 0x%x\n", digi_driver_irq );
365 printf( "DigiDma: 0x%x\n", digi_driver_dma );
366 printf( "MidiDeviceID: 0x%x\n", digi_midi_type );
367 printf( "MidiPort: 0x%x\n", digi_midi_port );
371 /*Config_midi_type = digi_midi_type;
372 Config_digi_type = digi_driver_board;
373 Config_digi_dma = digi_driver_dma;*/
376 if (digi_driver_board_16 > 0 && !FindArg("-no16bit") && digi_driver_board_16 != _GUS_16_ST) {
377 digi_driver_board = digi_driver_board_16;
378 digi_driver_dma = digi_driver_dma_16;
382 //Hack to make some cards look like others, such as
383 //the Crytal Lake look like Microsoft Sound System
384 if ( digi_driver_board == _CRYSTAL_LAKE_8_ST ) {
386 tmp = CrystalLakeReadMCP( CL_MC1 );
388 atexit( CrystalLakeSetSB ); // Restore to SB when done.
390 digi_driver_board = _MICROSOFT_8_ST;
391 } else if ( digi_driver_board == _CRYSTAL_LAKE_16_ST ) {
393 tmp = CrystalLakeReadMCP( CL_MC1 );
395 atexit( CrystalLakeSetSB ); // Restore to SB when done.
397 digi_driver_board = _MICROSOFT_16_ST;
398 } else if ( digi_driver_board == _AWE32_8_ST ) {
399 digi_driver_board = _SB16_8_ST;
400 } else if ( digi_driver_board == _AWE32_16_ST ) {
401 digi_driver_board = _SB16_16_ST;
403 digi_driver_board = digi_driver_board;
405 infile = cfopen("descentw.cfg", "rt");
407 while (!cfeof(infile))
410 cfgets(line, 80, infile);
412 while (isspace(*ptr))
415 token = strtok(ptr, "=");
416 value = strtok(NULL, "=");
417 if (value[strlen(value)-1] == '\n')
418 value[strlen(value)-1] = 0;
419 if (!strcmp(token, joystick_min_str)) {
420 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] );
422 else if (!strcmp(token, joystick_max_str)) {
423 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] );
425 else if (!strcmp(token, joystick_cen_str)) {
426 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] );
437 int WriteConfigFile()
442 int joy_axis_center[7];
444 ubyte gamma = gr_palette_get_gamma();
446 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
451 joy_axis_min[i]=DOSJoySaveMin[i];
452 joy_axis_center[i]=DOSJoySaveCen[i];
453 joy_axis_max[i]=DOSJoySaveMax[i];
457 infile = cfopen("descent.cfg", "wt");
458 if (infile == NULL) {
461 /*sprintf (str, "%s=0x%x\n", digi_dev8_str, Config_digi_type);
463 sprintf (str, "%s=0x%x\n", digi_dev16_str, digi_driver_board_16);
465 sprintf (str, "%s=0x%x\n", digi_port_str, digi_driver_port);
467 sprintf (str, "%s=%d\n", digi_irq_str, digi_driver_irq);
469 sprintf (str, "%s=%d\n", digi_dma8_str, Config_digi_dma);
471 sprintf (str, "%s=%d\n", digi_dma16_str, digi_driver_dma_16);
472 cfputs(str, infile);*/
473 sprintf (str, "%s=%d\n", digi_volume_str, Config_digi_volume);
475 /*sprintf (str, "%s=0x%x\n", midi_dev_str, Config_midi_type);
477 sprintf (str, "%s=0x%x\n", midi_port_str, digi_midi_port);
478 cfputs(str, infile);*/
479 sprintf (str, "%s=%d\n", midi_volume_str, Config_midi_volume);
481 sprintf (str, "%s=%d\n", redbook_enabled_str, FindArg("-noredbook")?save_redbook_enabled:Redbook_enabled);
483 sprintf (str, "%s=%d\n", redbook_volume_str, Config_redbook_volume);
485 sprintf (str, "%s=%d\n", stereo_rev_str, Config_channels_reversed);
487 sprintf (str, "%s=%d\n", gamma_level_str, gamma);
489 if (Detail_level == NUM_DETAIL_LEVELS-1)
490 sprintf (str, "%s=%d,%d,%d,%d,%d,%d,%d\n", detail_level_str, Detail_level,
491 Object_complexity,Object_detail,Wall_detail,Wall_render_depth,Debris_amount,SoundChannels);
493 sprintf (str, "%s=%d\n", detail_level_str, Detail_level);
496 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] );
498 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] );
500 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] );
503 sprintf (str, "%s=%s\n", last_player_str, Players[Player_num].callsign );
505 sprintf (str, "%s=%s\n", last_mission_str, config_last_mission );
507 sprintf (str, "%s=%d\n", config_vr_type_str, Config_vr_type );
509 sprintf (str, "%s=%d\n", config_vr_resolution_str, Config_vr_resolution );
511 sprintf (str, "%s=%d\n", config_vr_tracking_str, Config_vr_tracking );
513 sprintf (str, "%s=%d\n", movie_hires_str, (FindArg("-nohires") || FindArg("-nohighres") || FindArg("-lowresmovies"))?SaveMovieHires:MovieHires);
520 // Save Windows Config File
524 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
526 infile = cfopen("descentw.cfg", "wt");
527 if (infile == NULL) return 1;
529 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_min_str,
530 joy_axis_min[0], joy_axis_min[1], joy_axis_min[2], joy_axis_min[3],
531 joy_axis_min[4], joy_axis_min[5], joy_axis_min[6]);
533 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_cen_str,
534 joy_axis_center[0], joy_axis_center[1], joy_axis_center[2], joy_axis_center[3],
535 joy_axis_center[4], joy_axis_center[5], joy_axis_center[6]);
537 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_max_str,
538 joy_axis_max[0], joy_axis_max[1], joy_axis_max[2], joy_axis_max[3],
539 joy_axis_max[4], joy_axis_max[5], joy_axis_max[6]);
544 CheckMovieAttributes();
550 #else // !defined(MACINTOSH)
559 #include <GestaltEqu.h>
561 #include <Processes.h>
562 #include <Resources.h>
565 #include "pa_enabl.h" // because some prefs rely on this fact
576 #include "prefs.h" // prefs file for configuration stuff -- from DeSalvo
578 #if defined(POLY_ACC)
579 #include "poly_acc.h"
583 static char rcsid[] = "$Id: config.c,v 1.7 2003-06-16 06:57:34 btb Exp $";
586 #define MAX_CTB_LEN 512
588 typedef struct preferences {
591 ubyte stereo_reverse;
593 ubyte oc; // object complexity
594 ubyte od; // object detail
595 ubyte wd; // wall detail
596 ubyte wrd; // wall render depth
597 ubyte da; // debris amount
598 ubyte sc; // sound channels
603 int joy_axis_center[4];
604 char lastplayer[CALLSIGN_LEN+1];
605 char lastmission[MISSION_NAME_LEN+1];
606 char ctb_config[MAX_CTB_LEN];
609 ubyte display_dialog;
610 ubyte change_resolution;
616 ubyte redbook_volume;
618 ubyte enable_input_sprockets;
621 char config_last_player[CALLSIGN_LEN+1] = "";
622 char config_last_mission[MISSION_NAME_LEN+1] = "";
623 char config_last_ctb_cfg[MAX_CTB_LEN] = "";
624 int config_last_ctb_tool;
625 ubyte Config_master_volume = 4;
626 ubyte Config_digi_volume = 8;
627 ubyte Config_midi_volume = 8;
628 ubyte Config_redbook_volume = 8;
629 ubyte Config_control_type = 0;
630 ubyte Config_channels_reversed = 0;
631 ubyte Config_joystick_sensitivity = 8;
633 int Config_vr_type = 0;
634 int Config_vr_resolution = 0;
635 int Config_vr_tracking = 0;
637 extern byte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
638 extern void digi_set_master_volume( int volume );
640 void set_custom_detail_vars(void);
642 static ubyte have_prefs = 0;
644 //¥ ------------------------------ Private Definitions
645 //¥ ------------------------------ Private Types
654 } PrefsInfo, *PrefsInfoPtr, **PrefsInfoHandle;
656 //¥ ------------------------------ Private Variables
658 static PrefsInfo prefsInfo;
659 static Boolean prefsInited = 0;
661 //¥ ------------------------------ Private Functions
663 static void Pstrcpy(StringPtr dst, StringPtr src);
664 static void Pstrcat(StringPtr dst, StringPtr src);
665 static Boolean FindPrefsFile(short *prefVRefNum, long *prefDirID);
667 //¥ -------------------- Pstrcpy
670 Pstrcpy(StringPtr dst, StringPtr src)
672 BlockMove(src, dst, (*src) + 1);
675 //¥ -------------------- Pstrcat
678 Pstrcat(StringPtr dst, StringPtr src)
680 BlockMove(src + 1, dst + (*dst) + 1, *src);
684 //¥ -------------------- FindPrefsFile
687 FindPrefsFile(short *prefVRefNum, long *prefDirID)
696 theErr = Gestalt(gestaltFindFolderAttr, &response);
697 if (theErr == noErr && ((response >> gestaltFindFolderPresent) & 1))
699 //¥ Find (or make) it the easy way...
700 theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, prefVRefNum, prefDirID);
705 StringPtr prefFolderName = "\pPreferences";
707 //¥ yeachh -- we have to do it all by hand!
708 theErr = SysEnvirons(1, &theSysEnv);
712 *prefVRefNum = theSysEnv.sysVRefNum;
714 //¥ Check whether Preferences folder already exists
715 infoPB.hFileInfo.ioCompletion = 0;
716 infoPB.hFileInfo.ioNamePtr = prefFolderName;
717 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
718 infoPB.hFileInfo.ioFDirIndex = 0;
719 infoPB.hFileInfo.ioDirID = 0;
721 theErr = PBGetCatInfo(&infoPB, 0);
724 *prefDirID = infoPB.hFileInfo.ioDirID;
726 else if (theErr == fnfErr) //¥ Preferences doesn't already exist
728 HParamBlockRec dirPB;
730 //¥ Create "Preferences" folder
731 dirPB.fileParam.ioCompletion = 0;
732 dirPB.fileParam.ioVRefNum = *prefVRefNum;
733 dirPB.fileParam.ioNamePtr = prefFolderName;
734 dirPB.fileParam.ioDirID = 0;
736 theErr = PBDirCreate(&dirPB, 0);
738 *prefDirID = dirPB.fileParam.ioDirID;
742 //¥ If we make it here OK, create Preferences file if necessary
745 infoPB.hFileInfo.ioCompletion = 0;
746 infoPB.hFileInfo.ioNamePtr = prefsInfo.fileName;
747 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
748 infoPB.hFileInfo.ioFDirIndex = 0;
749 infoPB.hFileInfo.ioDirID = *prefDirID;
751 theErr = PBGetCatInfo(&infoPB, 0);
752 if (theErr == fnfErr)
754 theErr = HCreate(*prefVRefNum, *prefDirID, prefsInfo.fileName, prefsInfo.creator, prefsInfo.fileType);
757 HCreateResFile(*prefVRefNum, *prefDirID, prefsInfo.fileName);
763 return (theErr == noErr);
766 //¥ -------------------- InitPrefsFile
768 #define UNKNOWN_TYPE 0x3f3f3f3f
771 InitPrefsFile(OSType creator)
774 PrefsInfoHandle piHdl;
776 if ((piHdl = (PrefsInfoHandle) GetResource('PRFI', 0)) == nil)
778 ProcessSerialNumber thePSN;
779 ProcessInfoRec thePIR;
781 StringPtr app_string;
784 GetCurrentProcess(&thePSN);
785 thePIR.processName = nil;
786 thePIR.processAppSpec = &appSpec;
788 //¥ Set default to 'ÇApplicationÈ Prefs', PREF 0
789 err = GetProcessInformation(&thePSN, &thePIR);
793 app_string = LMGetCurApName();
794 // Pstrcpy(prefsInfo.fileName, appSpec.name);
795 Pstrcpy(prefsInfo.fileName, app_string);
796 Pstrcat(prefsInfo.fileName, "\p Preferences");
798 //¥ Set creator to calling application's signature (should be able to
799 //¥ Determine this automatically, but unable to for some reason)
800 prefsInfo.creator = creator;
801 prefsInfo.fileType = 'pref';
802 prefsInfo.resType = 'pref';
807 //¥ Get Preferences file setup from PRFI 0
808 BlockMove(*piHdl, &prefsInfo, sizeof (prefsInfo));
809 ReleaseResource((Handle) piHdl);
811 if (prefsInfo.creator == UNKNOWN_TYPE)
812 prefsInfo.creator = creator;
818 //¥ -------------------- LoadPrefsFile
821 LoadPrefsFile(Handle prefsHdl)
823 short prefVRefNum, prefRefNum;
825 OSErr theErr = noErr;
827 Size prefSize, origSize;
830 return (nilHandleErr);
832 prefSize = GetHandleSize(prefsHdl);
834 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
837 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
838 if (prefRefNum == -1)
841 //¥ Not finding the resource is not an error -- caller will use default data
842 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
844 origSize = GetHandleSize(origHdl);
845 if (origSize > prefSize) //¥ Extend handle for extra stored data
846 SetHandleSize(prefsHdl, origSize);
848 BlockMove(*origHdl, *prefsHdl, origSize);
849 ReleaseResource(origHdl);
852 CloseResFile(prefRefNum);
860 //¥ -------------------- SavePrefsFile
863 SavePrefsFile(Handle prefHdl)
865 short prefVRefNum, prefRefNum;
867 Handle origHdl = nil;
868 Size origSize, prefSize;
869 OSErr theErr = noErr;
871 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
875 return (nilHandleErr);
877 prefSize = GetHandleSize(prefHdl);
879 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
880 if (prefRefNum == -1)
883 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
885 //¥ Overwrite existing preferences
886 origSize = GetHandleSize(origHdl);
887 if (prefSize > origSize)
888 SetHandleSize(origHdl, prefSize);
890 BlockMove(*prefHdl, *origHdl, prefSize);
891 ChangedResource(origHdl);
892 WriteResource(origHdl);
893 ReleaseResource(origHdl);
897 //¥ Store specified preferences for the first time
898 AddResource(prefHdl, prefsInfo.resType, prefsInfo.resID, "\p");
899 WriteResource(prefHdl);
900 DetachResource(prefHdl);
903 CloseResFile(prefRefNum);
911 //¥ -------------------------------------------------------------------------------------------
915 This module provides the ability to save and load a preferences file in the
916 Preferences folder in the System Folder. An optional resource, PRFI 0,
917 is used to provide specifications for the preferences file (creator, etc.).
919 Three functions are provided:
921 void InitPrefsFile(OSType creator)
923 This function will initialize the preferences file, that is, it will create
924 it in the appropriate place if it doesn't currently exist. It should be
925 called with the creator code for the application. Note that the creator
926 code specified in PRFI 0 (if any) will be used only if the creator code
927 passed to this function is '????'. Without the PRFI 0 resource, the default
930 File Name: "{Application} Prefs" (i.e., the name of the app plus " Prefs"
931 Creator: the creator passed to InitPrefsFile
933 Pref Resource Type: 'PREF'
936 The PRFI 0 resource allows you to specify overrides for each of the above
937 values. This is useful for development, since the application name might
938 go through changes, but the preferences file name is held constant.
940 OSErr LoadPrefsFile(Handle prefsHndl)
942 This function will attempt to copy the data stored in the preferences
943 file to the given handle (which must be pre-allocated). If the handle is too
944 small, then it will be enlarged. If it is too large, it will not be resized.
945 The data in the preferences file (normally in PREF 0) will then be copied
946 into the handle. If the preferences file did not exist, the original data
947 in the handle will not change.
949 OSErr SavePrefsFile(Handle prefsHndl)
951 This function will attempt to save the given handle to the preferences
952 file. Its contents will completely replace the previous data (normally
953 the PREF 0 resource).
955 In typical use, you will use InitPrefsFile once, then allocate a handle large
956 enough to contain your preferences data, and initialize it with default values.
957 Throughout the course of your program, the handle will undergo modification as
958 user preferences change. You can use SavePrefsFile anytime to update the
959 preferences file, or wait until program exit to do so.
971 if (!have_prefs) { // not initialized....get a handle to the preferences file
972 InitPrefsFile('DCT2');
976 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
977 if (prefs_handle == NULL)
980 prefs = (Preferences *)(*prefs_handle);
981 err = LoadPrefsFile(prefs_handle);
983 DisposeHandle(prefs_handle);
988 for (i = 0; i < sizeof(Preferences); i++) {
993 if ( i == sizeof(Preferences) )
996 Config_digi_volume = prefs->digi_volume;
997 Config_midi_volume = prefs->midi_volume;
998 Config_master_volume = prefs->master_volume;
999 Config_redbook_volume = prefs->redbook_volume;
1000 Config_channels_reversed = prefs->stereo_reverse;
1001 gr_palette_set_gamma( (int)(prefs->gamma_level) );
1003 Scanline_double = (int)prefs->pixel_double;
1005 Scanline_double = 0; // can't double with hardware acceleration
1007 Detail_level = prefs->detail_level;
1008 if (Detail_level == NUM_DETAIL_LEVELS-1) {
1009 Object_complexity = prefs->oc;
1010 Object_detail = prefs->od;
1011 Wall_detail = prefs->wd;
1012 Wall_render_depth = prefs->wrd;
1013 Debris_amount = prefs->da;
1014 SoundChannels = prefs->sc;
1015 set_custom_detail_vars();
1017 #ifdef PA_3DFX_VOODOO // Set to highest detail because you can't change em
1018 Object_complexity=Object_detail=Wall_detail=
1019 Wall_render_depth=Debris_amount=SoundChannels = NUM_DETAIL_LEVELS-1;
1020 Detail_level=NUM_DETAIL_LEVELS-1;
1021 set_custom_detail_vars();
1024 strncpy( config_last_player, prefs->lastplayer, CALLSIGN_LEN );
1025 p = strchr(config_last_player, '\n' );
1028 strncpy(config_last_mission, prefs->lastmission, MISSION_NAME_LEN);
1029 p = strchr(config_last_mission, '\n' );
1032 strcpy(config_last_ctb_cfg, prefs->ctb_config);
1034 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
1036 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
1038 joy_set_cal_vals( prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
1039 digi_set_volume( (Config_digi_volume*256)/8, (Config_midi_volume*256)/8 );
1040 digi_set_master_volume(Config_master_volume);
1042 gConfigInfo.mDoNotDisplayOptions = prefs->display_dialog;
1043 gConfigInfo.mUse11kSounds = prefs->sound_11k;
1044 gConfigInfo.mDisableSound = prefs->nosound;
1045 gConfigInfo.mDisableMIDIMusic = prefs->nomidi;
1046 gConfigInfo.mChangeResolution = prefs->change_resolution;
1047 gConfigInfo.mDoNotPlayMovies = prefs->no_movies;
1048 gConfigInfo.mGameMonitor = prefs->game_monitor;
1049 gConfigInfo.mAcceleration = prefs->enable_rave;
1050 gConfigInfo.mInputSprockets = prefs->enable_input_sprockets;
1052 DisposeHandle(prefs_handle);
1056 int WriteConfigFile()
1059 Handle prefs_handle;
1062 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
1063 if (prefs_handle == NULL)
1066 prefs = (Preferences *)(*prefs_handle);
1068 joy_get_cal_vals(prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
1069 prefs->digi_volume = Config_digi_volume;
1070 prefs->midi_volume = Config_midi_volume;
1071 prefs->stereo_reverse = Config_channels_reversed;
1072 prefs->detail_level = Detail_level;
1073 if (Detail_level == NUM_DETAIL_LEVELS-1) {
1074 prefs->oc = Object_complexity;
1075 prefs->od = Object_detail;
1076 prefs->wd = Wall_detail;
1077 prefs->wrd = Wall_render_depth;
1078 prefs->da = Debris_amount;
1079 prefs->sc = SoundChannels;
1081 prefs->gamma_level = (ubyte)gr_palette_get_gamma();
1084 prefs->pixel_double = (ubyte)Scanline_double; // hmm..don't write this out if doing hardware accel.
1086 strncpy( prefs->lastplayer, Players[Player_num].callsign, CALLSIGN_LEN );
1087 strncpy( prefs->lastmission, config_last_mission, MISSION_NAME_LEN );
1088 strcpy( prefs->ctb_config, config_last_ctb_cfg);
1089 prefs->ctb_tool = config_last_ctb_tool;
1090 prefs->master_volume = Config_master_volume;
1091 prefs->display_dialog = gConfigInfo.mDoNotDisplayOptions;
1092 prefs->change_resolution = gConfigInfo.mChangeResolution;
1093 prefs->nosound = gConfigInfo.mDisableSound;
1094 prefs->nomidi = gConfigInfo.mDisableMIDIMusic;
1095 prefs->sound_11k = gConfigInfo.mUse11kSounds;
1096 prefs->no_movies = gConfigInfo.mDoNotPlayMovies;
1097 prefs->game_monitor = gConfigInfo.mGameMonitor;
1098 prefs->redbook_volume = Config_redbook_volume;
1099 prefs->enable_rave = gConfigInfo.mAcceleration;
1100 prefs->enable_input_sprockets = gConfigInfo.mInputSprockets;
1102 err = SavePrefsFile(prefs_handle);
1103 DisposeHandle(prefs_handle);