1 /* $Id: config.c,v 1.17 2005-07-30 01:50:17 chris 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
26 #ifndef MACINTOSH // I'm going to totally seperate these routines -- yeeech!!!!
27 // see end of file for macintosh equivs
30 #define WIN32_LEAN_AND_MEAN
61 static char rcsid[] = "$Id: config.c,v 1.17 2005-07-30 01:50:17 chris Exp $";
64 ubyte Config_control_type = 0;
65 ubyte Config_joystick_sensitivity = 8;
69 cvar_t Config_digi_type = { "DigiDeviceID8", "0", 1 };
70 cvar_t digi_driver_board_16 = { "DigiDeviceID16", "0", 1 };
71 //cvar_t digi_driver_port = { "DigiPort", "0", 1 };
72 //cvar_t digi_driver_irq = { "DigiIrq", "0", 1 };
73 cvar_t Config_digi_dma = { "DigiDma8", "0", 1 };
74 cvar_t digi_driver_dma_16 = { "DigiDma16", "0", 1 };
75 cvar_t Config_midi_type = { "MidiDeviceID", "0", 1 };
76 //cvar_t digi_midi_port = { "MidiPort", "0", 1 };
78 cvar_t Config_digi_volume = { "DigiVolume", "8", 1 };
79 cvar_t Config_midi_volume = { "MidiVolume", "8", 1 };
80 cvar_t Config_redbook_volume = { "RedbookVolume", "8", 1 };
81 cvar_t Config_detail_level = { "DetailLevel", "4", 1 };
82 cvar_t Config_gamma_level = { "GammaLevel", "0", 1 };
83 cvar_t Config_channels_reversed = { "StereoReverse", "0", 1 };
84 cvar_t Config_joystick_min = { "JoystickMin", "0,0,0,0", 1 };
85 cvar_t Config_joystick_max = { "JoystickMax", "0,0,0,0", 1 };
86 cvar_t Config_joystick_cen = { "JoystickCen", "0,0,0,0", 1 };
87 cvar_t config_last_player = { "LastPlayer", "", 1 };
88 cvar_t config_last_mission = { "LastMission", "", 1 };
89 cvar_t Config_vr_type = { "VR_type", "0", 1 };
90 cvar_t Config_vr_resolution = { "VR_resolution", "0", 1 };
91 cvar_t Config_vr_tracking = { "VR_tracking", "0", 1 };
94 #define _CRYSTAL_LAKE_8_ST 0xe201
95 #define _CRYSTAL_LAKE_16_ST 0xe202
96 #define _AWE32_8_ST 0xe208
97 #define _AWE32_16_ST 0xe209
101 int DOSJoySaveMin[4];
102 int DOSJoySaveCen[4];
103 int DOSJoySaveMax[4];
105 char win95_current_joyname[256];
109 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
111 void set_custom_detail_vars(void);
117 void CrystalLakeWriteMCP( ushort mc_addr, ubyte mc_data )
120 outp( CL_MC0, 0xE2 ); // Write password
121 outp( mc_addr, mc_data ); // Write data
125 ubyte CrystalLakeReadMCP( ushort mc_addr )
129 outp( CL_MC0, 0xE2 ); // Write password
130 value = inp( mc_addr ); // Read data
135 void CrystalLakeSetSB()
138 tmp = CrystalLakeReadMCP( CL_MC1 );
140 CrystalLakeWriteMCP( CL_MC1, tmp );
143 void CrystalLakeSetWSS()
146 tmp = CrystalLakeReadMCP( CL_MC1 );
148 CrystalLakeWriteMCP( CL_MC1, tmp );
151 //MovieHires might be changed by -nohighres, so save a "real" copy of it
153 int save_redbook_enabled;
156 void CheckMovieAttributes()
159 DWORD len, type, val;
162 lres = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Parallax\\Descent II\\1.1\\INSTALL",
164 if (lres == ERROR_SUCCESS) {
166 lres = RegQueryValueEx(hKey, "HIRES", NULL, &type, &val, &len);
167 if (lres == ERROR_SUCCESS) {
168 cvar_setint( &MovieHires, val );
169 logentry("HIRES=%d\n", val);
177 static int config_initialized;
179 static void config_init(void)
181 /* make sure our cvars are registered */
182 cvar_registervariable(&Config_digi_volume);
183 cvar_registervariable(&Config_midi_volume);
184 cvar_registervariable(&Redbook_enabled);
185 cvar_registervariable(&Config_redbook_volume);
186 cvar_registervariable(&Config_channels_reversed);
187 cvar_registervariable(&Config_gamma_level);
188 cvar_registervariable(&Config_detail_level);
189 cvar_registervariable(&Config_joystick_min);
190 cvar_registervariable(&Config_joystick_cen);
191 cvar_registervariable(&Config_joystick_max);
192 cvar_registervariable(&config_last_player);
193 cvar_registervariable(&config_last_mission);
194 cvar_registervariable(&Config_vr_type);
195 cvar_registervariable(&Config_vr_resolution);
196 cvar_registervariable(&Config_vr_tracking);
197 cvar_registervariable(&MovieHires);
199 config_initialized = 1;
206 int joy_axis_center[7];
210 if (!config_initialized)
213 cvar_set_cvar( &config_last_player, "" );
215 joy_axis_min[0] = joy_axis_min[1] = joy_axis_min[2] = joy_axis_min[3] = 0;
216 joy_axis_max[0] = joy_axis_max[1] = joy_axis_max[2] = joy_axis_max[3] = 0;
217 joy_axis_center[0] = joy_axis_center[1] = joy_axis_center[2] = joy_axis_center[3] = 0;
220 memset(&joy_axis_min[0], 0, sizeof(int)*7);
221 memset(&joy_axis_max[0], 0, sizeof(int)*7);
222 memset(&joy_axis_center[0], 0, sizeof(int)*7);
223 //@@ joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
225 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
229 cvar_setint(&digi_driver_board, 0);
230 cvar_setint(&digi_driver_port, 0);
231 cvar_setint(&digi_driver_irq, 0);
232 cvar_setint(&digi_driver_dma, 0);
233 cvar_setint(&digi_midi_type, 0);
234 cvar_setint(&digi_midi_port, 0);
237 cvar_setint( &Config_digi_volume, 8 );
238 cvar_setint( &Config_midi_volume, 8 );
239 cvar_setint( &Config_redbook_volume, 8 );
240 Config_control_type = 0;
241 cvar_setint( &Config_channels_reversed, 0);
243 //set these here in case no cfg file
244 SaveMovieHires = MovieHires.intval;
245 save_redbook_enabled = Redbook_enabled.intval;
247 cmd_append("exec descent.cfg");
250 /* TODO: allow cvars to define a callback that will carry out these initialization things on change. */
252 gr_palette_set_gamma( Config_gamma_level.intval );
254 Detail_level = strtol(Config_detail_level.string, NULL, 10);
255 if (Detail_level == NUM_DETAIL_LEVELS - 1) {
256 int count,dummy,oc,od,wd,wrd,da,sc;
258 count = sscanf (Config_detail_level.string, "%d,%d,%d,%d,%d,%d,%d\n",&dummy,&oc,&od,&wd,&wrd,&da,&sc);
261 Object_complexity = oc;
264 Wall_render_depth = wrd;
267 set_custom_detail_vars();
271 sscanf( Config_joystick_min.string, "%d,%d,%d,%d", &joy_axis_min[0], &joy_axis_min[1], &joy_axis_min[2], &joy_axis_min[3] );
272 sscanf( Config_joystick_max.string, "%d,%d,%d,%d", &joy_axis_max[0], &joy_axis_max[1], &joy_axis_max[2], &joy_axis_max[3] );
273 sscanf( Config_joystick_cen.string, "%d,%d,%d,%d", &joy_axis_center[0], &joy_axis_center[1], &joy_axis_center[2], &joy_axis_center[3] );
279 DOSJoySaveMin[i]=joy_axis_min[i];
280 DOSJoySaveCen[i]=joy_axis_center[i];
281 DOSJoySaveMax[i]=joy_axis_max[i];
284 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
287 i = FindArg( "-volume" );
290 i = atoi( Args[i+1] );
292 if ( i > 100 ) i = 100;
293 cvar_setint( &Config_digi_volume, (i * 8) / 100 );
294 cvar_setint( &Config_midi_volume, (i * 8) / 100 );
295 cvar_setint( &Config_redbook_volume, (i * 8) / 100 );
298 if ( Config_digi_volume.intval > 8 ) cvar_setint( &Config_digi_volume, 8 );
299 if ( Config_midi_volume.intval > 8 ) cvar_setint( &Config_midi_volume, 8 );
300 if ( Config_redbook_volume.intval > 8 ) cvar_setint( &Config_redbook_volume, 8 );
302 digi_set_volume( (Config_digi_volume.intval * 32768) / 8, (Config_midi_volume.intval * 128) / 8 );
305 printf( "DigiDeviceID: 0x%x\n", digi_driver_board );
306 printf( "DigiPort: 0x%x\n", digi_driver_port.intval );
307 printf( "DigiIrq: 0x%x\n", digi_driver_irq.intval );
308 printf( "DigiDma: 0x%x\n", digi_driver_dma.intval );
309 printf( "MidiDeviceID: 0x%x\n", digi_midi_type.intval );
310 printf( "MidiPort: 0x%x\n", digi_midi_port.intval );
313 cvar_setint( &Config_midi_type, digi_midi_type );
314 cvar_setint( &Config_digi_type, digi_driver_board );
315 cvar_setint( &Config_digi_dma, digi_driver_dma );
319 if (digi_driver_board_16.intval > 0 && !FindArg("-no16bit") && digi_driver_board_16.intval != _GUS_16_ST) {
320 digi_driver_board = digi_driver_board_16.intval;
321 digi_driver_dma = digi_driver_dma_16.intval;
325 //Hack to make some cards look like others, such as
326 //the Crytal Lake look like Microsoft Sound System
327 if ( digi_driver_board == _CRYSTAL_LAKE_8_ST ) {
329 tmp = CrystalLakeReadMCP( CL_MC1 );
331 atexit( CrystalLakeSetSB ); // Restore to SB when done.
333 digi_driver_board = _MICROSOFT_8_ST;
334 } else if ( digi_driver_board == _CRYSTAL_LAKE_16_ST ) {
336 tmp = CrystalLakeReadMCP( CL_MC1 );
338 atexit( CrystalLakeSetSB ); // Restore to SB when done.
340 digi_driver_board = _MICROSOFT_16_ST;
341 } else if ( digi_driver_board == _AWE32_8_ST ) {
342 digi_driver_board = _SB16_8_ST;
343 } else if ( digi_driver_board == _AWE32_16_ST ) {
344 digi_driver_board = _SB16_16_ST;
346 digi_driver_board = digi_driver_board;
349 if (cfexist("descentw.cfg")) {
350 cmd_append("exec descentw.cfg");
353 sscanf( Config_joystick_min.string, "%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] );
354 sscanf( Config_joystick_max.string, "%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] );
355 sscanf( Config_joystick_cen.string, "%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] );
362 int WriteConfigFile()
364 PHYSFS_file *outfile;
366 int joy_axis_center[7];
369 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
374 joy_axis_min[i]=DOSJoySaveMin[i];
375 joy_axis_center[i]=DOSJoySaveCen[i];
376 joy_axis_max[i]=DOSJoySaveMax[i];
380 if (FindArg("-noredbook"))
381 cvar_setint( &Redbook_enabled, save_redbook_enabled );
383 cvar_setint( &Config_gamma_level, gr_palette_get_gamma() );
385 if (Detail_level == NUM_DETAIL_LEVELS-1)
386 cvar_set_cvarf( &Config_detail_level, "%d,%d,%d,%d,%d,%d,%d", Detail_level,
387 Object_complexity,Object_detail,Wall_detail,Wall_render_depth,Debris_amount,SoundChannels );
389 cvar_setint( &Config_detail_level, Detail_level );
391 cvar_set_cvarf( &Config_joystick_min, "%d,%d,%d,%d", joy_axis_min[0], joy_axis_min[1], joy_axis_min[2], joy_axis_min[3] );
392 cvar_set_cvarf( &Config_joystick_cen, "%d,%d,%d,%d", joy_axis_center[0], joy_axis_center[1], joy_axis_center[2], joy_axis_center[3] );
393 cvar_set_cvarf( &Config_joystick_max, "%d,%d,%d,%d", joy_axis_max[0], joy_axis_max[1], joy_axis_max[2], joy_axis_max[3] );
395 cvar_set_cvar( &config_last_player, Players[Player_num].callsign );
397 if (FindArg("-nohires") || FindArg("-nohighres") || FindArg("-lowresmovies"))
398 cvar_setint( &MovieHires, SaveMovieHires );
400 outfile = PHYSFSX_openWriteBuffered("descent.cfg");
404 PHYSFS_close(outfile);
409 // Save Windows Config File
413 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
415 outfile = PHYSFSX_openWriteBuffered("descentw.cfg");
416 if (outfile == NULL) return 1;
418 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", Config_joystick_min.name,
419 joy_axis_min[0], joy_axis_min[1], joy_axis_min[2], joy_axis_min[3],
420 joy_axis_min[4], joy_axis_min[5], joy_axis_min[6]);
421 PHYSFSX_puts(outfile, str);
422 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", Config_joystick_cen.name,
423 joy_axis_center[0], joy_axis_center[1], joy_axis_center[2], joy_axis_center[3],
424 joy_axis_center[4], joy_axis_center[5], joy_axis_center[6]);
425 PHYSFSX_puts(outfile, str);
426 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", Config_joystick_max.name,
427 joy_axis_max[0], joy_axis_max[1], joy_axis_max[2], joy_axis_max[3],
428 joy_axis_max[4], joy_axis_max[5], joy_axis_max[6]);
429 PHYSFSX_puts(outfile, str);
433 CheckMovieAttributes();
439 #else // !defined(MACINTOSH)
448 #include <GestaltEqu.h>
450 #include <Processes.h>
451 #include <Resources.h>
464 #include "prefs.h" // prefs file for configuration stuff -- from DeSalvo
467 static char rcsid[] = "$Id: config.c,v 1.17 2005-07-30 01:50:17 chris Exp $";
470 #define MAX_CTB_LEN 512
472 typedef struct preferences {
475 ubyte stereo_reverse;
477 ubyte oc; // object complexity
478 ubyte od; // object detail
479 ubyte wd; // wall detail
480 ubyte wrd; // wall render depth
481 ubyte da; // debris amount
482 ubyte sc; // sound channels
487 int joy_axis_center[4];
488 char lastplayer[CALLSIGN_LEN+1];
489 char lastmission[MISSION_NAME_LEN+1];
490 char ctb_config[MAX_CTB_LEN];
493 ubyte display_dialog;
494 ubyte change_resolution;
500 ubyte redbook_volume;
502 ubyte enable_input_sprockets;
505 char config_last_player[CALLSIGN_LEN+1] = "";
506 char config_last_mission[MISSION_NAME_LEN+1] = "";
507 char config_last_ctb_cfg[MAX_CTB_LEN] = "";
508 int config_last_ctb_tool;
509 ubyte Config_master_volume = 4;
510 ubyte Config_digi_volume = 8;
511 ubyte Config_midi_volume = 8;
512 ubyte Config_redbook_volume = 8;
513 ubyte Config_control_type = 0;
514 ubyte Config_channels_reversed = 0;
515 ubyte Config_joystick_sensitivity = 8;
517 int Config_vr_type = 0;
518 int Config_vr_resolution = 0;
519 int Config_vr_tracking = 0;
521 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
522 extern void digi_set_master_volume( int volume );
524 void set_custom_detail_vars(void);
526 static ubyte have_prefs = 0;
528 //¥ ------------------------------ Private Definitions
529 //¥ ------------------------------ Private Types
538 } PrefsInfo, *PrefsInfoPtr, **PrefsInfoHandle;
540 //¥ ------------------------------ Private Variables
542 static PrefsInfo prefsInfo;
543 static Boolean prefsInited = 0;
545 //¥ ------------------------------ Private Functions
547 static void Pstrcpy(StringPtr dst, StringPtr src);
548 static void Pstrcat(StringPtr dst, StringPtr src);
549 static Boolean FindPrefsFile(short *prefVRefNum, long *prefDirID);
551 //¥ -------------------- Pstrcpy
554 Pstrcpy(StringPtr dst, StringPtr src)
556 BlockMove(src, dst, (*src) + 1);
559 //¥ -------------------- Pstrcat
562 Pstrcat(StringPtr dst, StringPtr src)
564 BlockMove(src + 1, dst + (*dst) + 1, *src);
568 //¥ -------------------- FindPrefsFile
571 FindPrefsFile(short *prefVRefNum, long *prefDirID)
580 theErr = Gestalt(gestaltFindFolderAttr, &response);
581 if (theErr == noErr && ((response >> gestaltFindFolderPresent) & 1))
583 //¥ Find (or make) it the easy way...
584 theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, prefVRefNum, prefDirID);
589 StringPtr prefFolderName = "\pPreferences";
591 //¥ yeachh -- we have to do it all by hand!
592 theErr = SysEnvirons(1, &theSysEnv);
596 *prefVRefNum = theSysEnv.sysVRefNum;
598 //¥ Check whether Preferences folder already exists
599 infoPB.hFileInfo.ioCompletion = 0;
600 infoPB.hFileInfo.ioNamePtr = prefFolderName;
601 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
602 infoPB.hFileInfo.ioFDirIndex = 0;
603 infoPB.hFileInfo.ioDirID = 0;
605 theErr = PBGetCatInfo(&infoPB, 0);
608 *prefDirID = infoPB.hFileInfo.ioDirID;
610 else if (theErr == fnfErr) //¥ Preferences doesn't already exist
612 HParamBlockRec dirPB;
614 //¥ Create "Preferences" folder
615 dirPB.fileParam.ioCompletion = 0;
616 dirPB.fileParam.ioVRefNum = *prefVRefNum;
617 dirPB.fileParam.ioNamePtr = prefFolderName;
618 dirPB.fileParam.ioDirID = 0;
620 theErr = PBDirCreate(&dirPB, 0);
622 *prefDirID = dirPB.fileParam.ioDirID;
626 //¥ If we make it here OK, create Preferences file if necessary
629 infoPB.hFileInfo.ioCompletion = 0;
630 infoPB.hFileInfo.ioNamePtr = prefsInfo.fileName;
631 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
632 infoPB.hFileInfo.ioFDirIndex = 0;
633 infoPB.hFileInfo.ioDirID = *prefDirID;
635 theErr = PBGetCatInfo(&infoPB, 0);
636 if (theErr == fnfErr)
638 theErr = HCreate(*prefVRefNum, *prefDirID, prefsInfo.fileName, prefsInfo.creator, prefsInfo.fileType);
641 HCreateResFile(*prefVRefNum, *prefDirID, prefsInfo.fileName);
647 return (theErr == noErr);
650 //¥ -------------------- InitPrefsFile
652 #define UNKNOWN_TYPE 0x3f3f3f3f
655 InitPrefsFile(OSType creator)
658 PrefsInfoHandle piHdl;
660 if ((piHdl = (PrefsInfoHandle) GetResource('PRFI', 0)) == nil)
662 ProcessSerialNumber thePSN;
663 ProcessInfoRec thePIR;
665 StringPtr app_string;
668 GetCurrentProcess(&thePSN);
669 thePIR.processName = nil;
670 thePIR.processAppSpec = &appSpec;
672 //¥ Set default to 'ÇApplicationÈ Prefs', PREF 0
673 err = GetProcessInformation(&thePSN, &thePIR);
677 app_string = LMGetCurApName();
678 // Pstrcpy(prefsInfo.fileName, appSpec.name);
679 Pstrcpy(prefsInfo.fileName, app_string);
680 Pstrcat(prefsInfo.fileName, "\p Preferences");
682 //¥ Set creator to calling application's signature (should be able to
683 //¥ Determine this automatically, but unable to for some reason)
684 prefsInfo.creator = creator;
685 prefsInfo.fileType = 'pref';
686 prefsInfo.resType = 'pref';
691 //¥ Get Preferences file setup from PRFI 0
692 BlockMove(*piHdl, &prefsInfo, sizeof (prefsInfo));
693 ReleaseResource((Handle) piHdl);
695 if (prefsInfo.creator == UNKNOWN_TYPE)
696 prefsInfo.creator = creator;
702 //¥ -------------------- LoadPrefsFile
705 LoadPrefsFile(Handle prefsHdl)
707 short prefVRefNum, prefRefNum;
709 OSErr theErr = noErr;
711 Size prefSize, origSize;
714 return (nilHandleErr);
716 prefSize = GetHandleSize(prefsHdl);
718 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
721 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
722 if (prefRefNum == -1)
725 //¥ Not finding the resource is not an error -- caller will use default data
726 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
728 origSize = GetHandleSize(origHdl);
729 if (origSize > prefSize) //¥ Extend handle for extra stored data
730 SetHandleSize(prefsHdl, origSize);
732 BlockMove(*origHdl, *prefsHdl, origSize);
733 ReleaseResource(origHdl);
736 CloseResFile(prefRefNum);
744 //¥ -------------------- SavePrefsFile
747 SavePrefsFile(Handle prefHdl)
749 short prefVRefNum, prefRefNum;
751 Handle origHdl = nil;
752 Size origSize, prefSize;
753 OSErr theErr = noErr;
755 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
759 return (nilHandleErr);
761 prefSize = GetHandleSize(prefHdl);
763 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
764 if (prefRefNum == -1)
767 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
769 //¥ Overwrite existing preferences
770 origSize = GetHandleSize(origHdl);
771 if (prefSize > origSize)
772 SetHandleSize(origHdl, prefSize);
774 BlockMove(*prefHdl, *origHdl, prefSize);
775 ChangedResource(origHdl);
776 WriteResource(origHdl);
777 ReleaseResource(origHdl);
781 //¥ Store specified preferences for the first time
782 AddResource(prefHdl, prefsInfo.resType, prefsInfo.resID, "\p");
783 WriteResource(prefHdl);
784 DetachResource(prefHdl);
787 CloseResFile(prefRefNum);
795 //¥ -------------------------------------------------------------------------------------------
799 This module provides the ability to save and load a preferences file in the
800 Preferences folder in the System Folder. An optional resource, PRFI 0,
801 is used to provide specifications for the preferences file (creator, etc.).
803 Three functions are provided:
805 void InitPrefsFile(OSType creator)
807 This function will initialize the preferences file, that is, it will create
808 it in the appropriate place if it doesn't currently exist. It should be
809 called with the creator code for the application. Note that the creator
810 code specified in PRFI 0 (if any) will be used only if the creator code
811 passed to this function is '????'. Without the PRFI 0 resource, the default
814 File Name: "{Application} Prefs" (i.e., the name of the app plus " Prefs"
815 Creator: the creator passed to InitPrefsFile
817 Pref Resource Type: 'PREF'
820 The PRFI 0 resource allows you to specify overrides for each of the above
821 values. This is useful for development, since the application name might
822 go through changes, but the preferences file name is held constant.
824 OSErr LoadPrefsFile(Handle prefsHndl)
826 This function will attempt to copy the data stored in the preferences
827 file to the given handle (which must be pre-allocated). If the handle is too
828 small, then it will be enlarged. If it is too large, it will not be resized.
829 The data in the preferences file (normally in PREF 0) will then be copied
830 into the handle. If the preferences file did not exist, the original data
831 in the handle will not change.
833 OSErr SavePrefsFile(Handle prefsHndl)
835 This function will attempt to save the given handle to the preferences
836 file. Its contents will completely replace the previous data (normally
837 the PREF 0 resource).
839 In typical use, you will use InitPrefsFile once, then allocate a handle large
840 enough to contain your preferences data, and initialize it with default values.
841 Throughout the course of your program, the handle will undergo modification as
842 user preferences change. You can use SavePrefsFile anytime to update the
843 preferences file, or wait until program exit to do so.
855 if (!have_prefs) { // not initialized....get a handle to the preferences file
856 InitPrefsFile('DCT2');
860 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
861 if (prefs_handle == NULL)
864 prefs = (Preferences *)(*prefs_handle);
865 err = LoadPrefsFile(prefs_handle);
867 DisposeHandle(prefs_handle);
872 for (i = 0; i < sizeof(Preferences); i++) {
877 if ( i == sizeof(Preferences) )
880 Config_digi_volume = prefs->digi_volume;
881 Config_midi_volume = prefs->midi_volume;
882 Config_master_volume = prefs->master_volume;
883 Config_redbook_volume = prefs->redbook_volume;
884 Config_channels_reversed = prefs->stereo_reverse;
885 gr_palette_set_gamma( (int)(prefs->gamma_level) );
887 Scanline_double = (int)prefs->pixel_double;
889 Scanline_double = 0; // can't double with hardware acceleration
891 Detail_level = prefs->detail_level;
892 if (Detail_level == NUM_DETAIL_LEVELS-1) {
893 Object_complexity = prefs->oc;
894 Object_detail = prefs->od;
895 Wall_detail = prefs->wd;
896 Wall_render_depth = prefs->wrd;
897 Debris_amount = prefs->da;
898 SoundChannels = prefs->sc;
899 set_custom_detail_vars();
902 strncpy( config_last_player, prefs->lastplayer, CALLSIGN_LEN );
903 p = strchr(config_last_player, '\n' );
906 strncpy(config_last_mission, prefs->lastmission, MISSION_NAME_LEN);
907 p = strchr(config_last_mission, '\n' );
910 strcpy(config_last_ctb_cfg, prefs->ctb_config);
912 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
914 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
916 joy_set_cal_vals( prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
917 digi_set_volume( (Config_digi_volume*256)/8, (Config_midi_volume*256)/8 );
918 digi_set_master_volume(Config_master_volume);
920 gConfigInfo.mDoNotDisplayOptions = prefs->display_dialog;
921 gConfigInfo.mUse11kSounds = prefs->sound_11k;
922 gConfigInfo.mDisableSound = prefs->nosound;
923 gConfigInfo.mDisableMIDIMusic = prefs->nomidi;
924 gConfigInfo.mChangeResolution = prefs->change_resolution;
925 gConfigInfo.mDoNotPlayMovies = prefs->no_movies;
926 gConfigInfo.mGameMonitor = prefs->game_monitor;
927 gConfigInfo.mAcceleration = prefs->enable_rave;
928 gConfigInfo.mInputSprockets = prefs->enable_input_sprockets;
930 DisposeHandle(prefs_handle);
934 int WriteConfigFile()
940 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
941 if (prefs_handle == NULL)
944 prefs = (Preferences *)(*prefs_handle);
946 joy_get_cal_vals(prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
947 prefs->digi_volume = Config_digi_volume;
948 prefs->midi_volume = Config_midi_volume;
949 prefs->stereo_reverse = Config_channels_reversed;
950 prefs->detail_level = Detail_level;
951 if (Detail_level == NUM_DETAIL_LEVELS-1) {
952 prefs->oc = Object_complexity;
953 prefs->od = Object_detail;
954 prefs->wd = Wall_detail;
955 prefs->wrd = Wall_render_depth;
956 prefs->da = Debris_amount;
957 prefs->sc = SoundChannels;
959 prefs->gamma_level = (ubyte)gr_palette_get_gamma();
962 prefs->pixel_double = (ubyte)Scanline_double; // hmm..don't write this out if doing hardware accel.
964 strncpy( prefs->lastplayer, Players[Player_num].callsign, CALLSIGN_LEN );
965 strncpy( prefs->lastmission, config_last_mission, MISSION_NAME_LEN );
966 strcpy( prefs->ctb_config, config_last_ctb_cfg);
967 prefs->ctb_tool = config_last_ctb_tool;
968 prefs->master_volume = Config_master_volume;
969 prefs->display_dialog = gConfigInfo.mDoNotDisplayOptions;
970 prefs->change_resolution = gConfigInfo.mChangeResolution;
971 prefs->nosound = gConfigInfo.mDisableSound;
972 prefs->nomidi = gConfigInfo.mDisableMIDIMusic;
973 prefs->sound_11k = gConfigInfo.mUse11kSounds;
974 prefs->no_movies = gConfigInfo.mDoNotPlayMovies;
975 prefs->game_monitor = gConfigInfo.mGameMonitor;
976 prefs->redbook_volume = Config_redbook_volume;
977 prefs->enable_rave = gConfigInfo.mAcceleration;
978 prefs->enable_input_sprockets = gConfigInfo.mInputSprockets;
980 err = SavePrefsFile(prefs_handle);
981 DisposeHandle(prefs_handle);