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.
16 * contains routine(s) to read in the configuration file which contains
17 * game configuration stuff like detail level, sound card, etc
25 #ifndef MACINTOSH // I'm going to totally seperate these routines -- yeeech!!!!
26 // see end of file for macintosh equivs
29 #define WIN32_LEAN_AND_MEAN
59 ubyte Config_control_type = 0;
60 ubyte Config_joystick_sensitivity = 8;
64 cvar_t Config_digi_type = { "DigiDeviceID8", "0", 1 };
65 cvar_t digi_driver_board_16 = { "DigiDeviceID16", "0", 1 };
66 //cvar_t digi_driver_port = { "DigiPort", "0", 1 };
67 //cvar_t digi_driver_irq = { "DigiIrq", "0", 1 };
68 cvar_t Config_digi_dma = { "DigiDma8", "0", 1 };
69 cvar_t digi_driver_dma_16 = { "DigiDma16", "0", 1 };
70 cvar_t Config_midi_type = { "MidiDeviceID", "0", 1 };
71 //cvar_t digi_midi_port = { "MidiPort", "0", 1 };
73 cvar_t Config_digi_volume = { "DigiVolume", "8", 1 };
74 cvar_t Config_midi_volume = { "MidiVolume", "8", 1 };
75 cvar_t Config_redbook_volume = { "RedbookVolume", "8", 1 };
76 cvar_t Config_detail_level = { "DetailLevel", "4", 1 };
77 cvar_t Config_gamma_level = { "GammaLevel", "0", 1 };
78 cvar_t Config_channels_reversed = { "StereoReverse", "0", 1 };
79 cvar_t Config_joystick_min = { "JoystickMin", "0,0,0,0", 1 };
80 cvar_t Config_joystick_max = { "JoystickMax", "0,0,0,0", 1 };
81 cvar_t Config_joystick_cen = { "JoystickCen", "0,0,0,0", 1 };
82 cvar_t config_last_player = { "LastPlayer", "", 1 };
83 cvar_t config_last_mission = { "LastMission", "", 1 };
84 cvar_t Config_vr_type = { "VR_type", "0", 1 };
85 cvar_t Config_vr_resolution = { "VR_resolution", "0", 1 };
86 cvar_t Config_vr_tracking = { "VR_tracking", "0", 1 };
89 #define _CRYSTAL_LAKE_8_ST 0xe201
90 #define _CRYSTAL_LAKE_16_ST 0xe202
91 #define _AWE32_8_ST 0xe208
92 #define _AWE32_16_ST 0xe209
100 char win95_current_joyname[256];
104 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
106 void set_custom_detail_vars(void);
112 void CrystalLakeWriteMCP( ushort mc_addr, ubyte mc_data )
115 outp( CL_MC0, 0xE2 ); // Write password
116 outp( mc_addr, mc_data ); // Write data
120 ubyte CrystalLakeReadMCP( ushort mc_addr )
124 outp( CL_MC0, 0xE2 ); // Write password
125 value = inp( mc_addr ); // Read data
130 void CrystalLakeSetSB()
133 tmp = CrystalLakeReadMCP( CL_MC1 );
135 CrystalLakeWriteMCP( CL_MC1, tmp );
138 void CrystalLakeSetWSS()
141 tmp = CrystalLakeReadMCP( CL_MC1 );
143 CrystalLakeWriteMCP( CL_MC1, tmp );
146 //MovieHires might be changed by -nohighres, so save a "real" copy of it
148 int save_redbook_enabled;
151 void CheckMovieAttributes()
154 DWORD len, type, val;
157 lres = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Parallax\\Descent II\\1.1\\INSTALL",
159 if (lres == ERROR_SUCCESS) {
161 lres = RegQueryValueEx(hKey, "HIRES", NULL, &type, &val, &len);
162 if (lres == ERROR_SUCCESS) {
163 cvar_setint( &MovieHires, val );
164 logentry("HIRES=%d\n", val);
172 static int config_initialized;
174 static void config_init(void)
176 /* make sure our cvars are registered */
177 cvar_registervariable(&Config_digi_volume);
178 cvar_registervariable(&Config_midi_volume);
179 cvar_registervariable(&Redbook_enabled);
180 cvar_registervariable(&Config_redbook_volume);
181 cvar_registervariable(&Config_channels_reversed);
182 cvar_registervariable(&Config_gamma_level);
183 cvar_registervariable(&Config_detail_level);
184 cvar_registervariable(&Config_joystick_min);
185 cvar_registervariable(&Config_joystick_cen);
186 cvar_registervariable(&Config_joystick_max);
187 cvar_registervariable(&config_last_player);
188 cvar_registervariable(&config_last_mission);
189 cvar_registervariable(&Config_vr_type);
190 cvar_registervariable(&Config_vr_resolution);
191 cvar_registervariable(&Config_vr_tracking);
192 cvar_registervariable(&MovieHires);
194 config_initialized = 1;
201 int joy_axis_center[7];
205 if (!config_initialized)
208 cvar_set_cvar( &config_last_player, "" );
210 joy_axis_min[0] = joy_axis_min[1] = joy_axis_min[2] = joy_axis_min[3] = 0;
211 joy_axis_max[0] = joy_axis_max[1] = joy_axis_max[2] = joy_axis_max[3] = 0;
212 joy_axis_center[0] = joy_axis_center[1] = joy_axis_center[2] = joy_axis_center[3] = 0;
215 memset(&joy_axis_min[0], 0, sizeof(int)*7);
216 memset(&joy_axis_max[0], 0, sizeof(int)*7);
217 memset(&joy_axis_center[0], 0, sizeof(int)*7);
218 //@@ joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
220 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
224 cvar_setint(&digi_driver_board, 0);
225 cvar_setint(&digi_driver_port, 0);
226 cvar_setint(&digi_driver_irq, 0);
227 cvar_setint(&digi_driver_dma, 0);
228 cvar_setint(&digi_midi_type, 0);
229 cvar_setint(&digi_midi_port, 0);
232 cvar_setint( &Config_digi_volume, 8 );
233 cvar_setint( &Config_midi_volume, 8 );
234 cvar_setint( &Config_redbook_volume, 8 );
235 Config_control_type = 0;
236 cvar_setint( &Config_channels_reversed, 0);
238 //set these here in case no cfg file
239 SaveMovieHires = MovieHires.intval;
240 save_redbook_enabled = Redbook_enabled.intval;
242 cmd_append("exec descent.cfg");
245 /* TODO: allow cvars to define a callback that will carry out these initialization things on change. */
247 gr_palette_set_gamma( Config_gamma_level.intval );
249 Detail_level = strtol(Config_detail_level.string, NULL, 10);
250 if (Detail_level == NUM_DETAIL_LEVELS - 1) {
251 int count,dummy,oc,od,wd,wrd,da,sc;
253 count = sscanf (Config_detail_level.string, "%d,%d,%d,%d,%d,%d,%d\n",&dummy,&oc,&od,&wd,&wrd,&da,&sc);
256 Object_complexity = oc;
259 Wall_render_depth = wrd;
262 set_custom_detail_vars();
266 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] );
267 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] );
268 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] );
274 DOSJoySaveMin[i]=joy_axis_min[i];
275 DOSJoySaveCen[i]=joy_axis_center[i];
276 DOSJoySaveMax[i]=joy_axis_max[i];
279 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
282 i = FindArg( "-volume" );
285 i = atoi( Args[i+1] );
287 if ( i > 100 ) i = 100;
288 cvar_setint( &Config_digi_volume, (i * 8) / 100 );
289 cvar_setint( &Config_midi_volume, (i * 8) / 100 );
290 cvar_setint( &Config_redbook_volume, (i * 8) / 100 );
293 if ( Config_digi_volume.intval > 8 ) cvar_setint( &Config_digi_volume, 8 );
294 if ( Config_midi_volume.intval > 8 ) cvar_setint( &Config_midi_volume, 8 );
295 if ( Config_redbook_volume.intval > 8 ) cvar_setint( &Config_redbook_volume, 8 );
297 digi_set_volume( (Config_digi_volume.intval * 32768) / 8, (Config_midi_volume.intval * 128) / 8 );
300 printf( "DigiDeviceID: 0x%x\n", digi_driver_board );
301 printf( "DigiPort: 0x%x\n", digi_driver_port.intval );
302 printf( "DigiIrq: 0x%x\n", digi_driver_irq.intval );
303 printf( "DigiDma: 0x%x\n", digi_driver_dma.intval );
304 printf( "MidiDeviceID: 0x%x\n", digi_midi_type.intval );
305 printf( "MidiPort: 0x%x\n", digi_midi_port.intval );
308 cvar_setint( &Config_midi_type, digi_midi_type );
309 cvar_setint( &Config_digi_type, digi_driver_board );
310 cvar_setint( &Config_digi_dma, digi_driver_dma );
314 if (digi_driver_board_16.intval > 0 && !FindArg("-no16bit") && digi_driver_board_16.intval != _GUS_16_ST) {
315 digi_driver_board = digi_driver_board_16.intval;
316 digi_driver_dma = digi_driver_dma_16.intval;
320 //Hack to make some cards look like others, such as
321 //the Crytal Lake look like Microsoft Sound System
322 if ( digi_driver_board == _CRYSTAL_LAKE_8_ST ) {
324 tmp = CrystalLakeReadMCP( CL_MC1 );
326 atexit( CrystalLakeSetSB ); // Restore to SB when done.
328 digi_driver_board = _MICROSOFT_8_ST;
329 } else if ( digi_driver_board == _CRYSTAL_LAKE_16_ST ) {
331 tmp = CrystalLakeReadMCP( CL_MC1 );
333 atexit( CrystalLakeSetSB ); // Restore to SB when done.
335 digi_driver_board = _MICROSOFT_16_ST;
336 } else if ( digi_driver_board == _AWE32_8_ST ) {
337 digi_driver_board = _SB16_8_ST;
338 } else if ( digi_driver_board == _AWE32_16_ST ) {
339 digi_driver_board = _SB16_16_ST;
341 digi_driver_board = digi_driver_board;
344 if (cfexist("descentw.cfg")) {
345 cmd_append("exec descentw.cfg");
348 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] );
349 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] );
350 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] );
357 int WriteConfigFile()
359 PHYSFS_file *outfile;
361 int joy_axis_center[7];
364 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
369 joy_axis_min[i]=DOSJoySaveMin[i];
370 joy_axis_center[i]=DOSJoySaveCen[i];
371 joy_axis_max[i]=DOSJoySaveMax[i];
375 if (FindArg("-noredbook"))
376 cvar_setint( &Redbook_enabled, save_redbook_enabled );
378 cvar_setint( &Config_gamma_level, gr_palette_get_gamma() );
380 if (Detail_level == NUM_DETAIL_LEVELS-1)
381 cvar_set_cvarf( &Config_detail_level, "%d,%d,%d,%d,%d,%d,%d", Detail_level,
382 Object_complexity,Object_detail,Wall_detail,Wall_render_depth,Debris_amount,SoundChannels );
384 cvar_setint( &Config_detail_level, Detail_level );
386 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] );
387 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] );
388 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] );
390 cvar_set_cvar( &config_last_player, Players[Player_num].callsign );
392 if (FindArg("-nohires") || FindArg("-nohighres") || FindArg("-lowresmovies"))
393 cvar_setint( &MovieHires, SaveMovieHires );
395 outfile = PHYSFSX_openWriteBuffered("descent.cfg");
399 PHYSFS_close(outfile);
404 // Save Windows Config File
408 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
410 outfile = PHYSFSX_openWriteBuffered("descentw.cfg");
411 if (outfile == NULL) return 1;
413 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", Config_joystick_min.name,
414 joy_axis_min[0], joy_axis_min[1], joy_axis_min[2], joy_axis_min[3],
415 joy_axis_min[4], joy_axis_min[5], joy_axis_min[6]);
416 PHYSFSX_puts(outfile, str);
417 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", Config_joystick_cen.name,
418 joy_axis_center[0], joy_axis_center[1], joy_axis_center[2], joy_axis_center[3],
419 joy_axis_center[4], joy_axis_center[5], joy_axis_center[6]);
420 PHYSFSX_puts(outfile, str);
421 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", Config_joystick_max.name,
422 joy_axis_max[0], joy_axis_max[1], joy_axis_max[2], joy_axis_max[3],
423 joy_axis_max[4], joy_axis_max[5], joy_axis_max[6]);
424 PHYSFSX_puts(outfile, str);
428 CheckMovieAttributes();
434 #else // !defined(MACINTOSH)
443 #include <GestaltEqu.h>
445 #include <Processes.h>
446 #include <Resources.h>
459 #include "prefs.h" // prefs file for configuration stuff -- from DeSalvo
461 #define MAX_CTB_LEN 512
463 typedef struct preferences {
466 ubyte stereo_reverse;
468 ubyte oc; // object complexity
469 ubyte od; // object detail
470 ubyte wd; // wall detail
471 ubyte wrd; // wall render depth
472 ubyte da; // debris amount
473 ubyte sc; // sound channels
478 int joy_axis_center[4];
479 char lastplayer[CALLSIGN_LEN+1];
480 char lastmission[MISSION_NAME_LEN+1];
481 char ctb_config[MAX_CTB_LEN];
484 ubyte display_dialog;
485 ubyte change_resolution;
491 ubyte redbook_volume;
493 ubyte enable_input_sprockets;
496 char config_last_player[CALLSIGN_LEN+1] = "";
497 char config_last_mission[MISSION_NAME_LEN+1] = "";
498 char config_last_ctb_cfg[MAX_CTB_LEN] = "";
499 int config_last_ctb_tool;
500 ubyte Config_master_volume = 4;
501 ubyte Config_digi_volume = 8;
502 ubyte Config_midi_volume = 8;
503 ubyte Config_redbook_volume = 8;
504 ubyte Config_control_type = 0;
505 ubyte Config_channels_reversed = 0;
506 ubyte Config_joystick_sensitivity = 8;
508 int Config_vr_type = 0;
509 int Config_vr_resolution = 0;
510 int Config_vr_tracking = 0;
512 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
513 extern void digi_set_master_volume( int volume );
515 void set_custom_detail_vars(void);
517 static ubyte have_prefs = 0;
519 //¥ ------------------------------ Private Definitions
520 //¥ ------------------------------ Private Types
529 } PrefsInfo, *PrefsInfoPtr, **PrefsInfoHandle;
531 //¥ ------------------------------ Private Variables
533 static PrefsInfo prefsInfo;
534 static Boolean prefsInited = 0;
536 //¥ ------------------------------ Private Functions
538 static void Pstrcpy(StringPtr dst, StringPtr src);
539 static void Pstrcat(StringPtr dst, StringPtr src);
540 static Boolean FindPrefsFile(short *prefVRefNum, long *prefDirID);
542 //¥ -------------------- Pstrcpy
545 Pstrcpy(StringPtr dst, StringPtr src)
547 BlockMove(src, dst, (*src) + 1);
550 //¥ -------------------- Pstrcat
553 Pstrcat(StringPtr dst, StringPtr src)
555 BlockMove(src + 1, dst + (*dst) + 1, *src);
559 //¥ -------------------- FindPrefsFile
562 FindPrefsFile(short *prefVRefNum, long *prefDirID)
571 theErr = Gestalt(gestaltFindFolderAttr, &response);
572 if (theErr == noErr && ((response >> gestaltFindFolderPresent) & 1))
574 //¥ Find (or make) it the easy way...
575 theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, prefVRefNum, prefDirID);
580 StringPtr prefFolderName = "\pPreferences";
582 //¥ yeachh -- we have to do it all by hand!
583 theErr = SysEnvirons(1, &theSysEnv);
587 *prefVRefNum = theSysEnv.sysVRefNum;
589 //¥ Check whether Preferences folder already exists
590 infoPB.hFileInfo.ioCompletion = 0;
591 infoPB.hFileInfo.ioNamePtr = prefFolderName;
592 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
593 infoPB.hFileInfo.ioFDirIndex = 0;
594 infoPB.hFileInfo.ioDirID = 0;
596 theErr = PBGetCatInfo(&infoPB, 0);
599 *prefDirID = infoPB.hFileInfo.ioDirID;
601 else if (theErr == fnfErr) //¥ Preferences doesn't already exist
603 HParamBlockRec dirPB;
605 //¥ Create "Preferences" folder
606 dirPB.fileParam.ioCompletion = 0;
607 dirPB.fileParam.ioVRefNum = *prefVRefNum;
608 dirPB.fileParam.ioNamePtr = prefFolderName;
609 dirPB.fileParam.ioDirID = 0;
611 theErr = PBDirCreate(&dirPB, 0);
613 *prefDirID = dirPB.fileParam.ioDirID;
617 //¥ If we make it here OK, create Preferences file if necessary
620 infoPB.hFileInfo.ioCompletion = 0;
621 infoPB.hFileInfo.ioNamePtr = prefsInfo.fileName;
622 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
623 infoPB.hFileInfo.ioFDirIndex = 0;
624 infoPB.hFileInfo.ioDirID = *prefDirID;
626 theErr = PBGetCatInfo(&infoPB, 0);
627 if (theErr == fnfErr)
629 theErr = HCreate(*prefVRefNum, *prefDirID, prefsInfo.fileName, prefsInfo.creator, prefsInfo.fileType);
632 HCreateResFile(*prefVRefNum, *prefDirID, prefsInfo.fileName);
638 return (theErr == noErr);
641 //¥ -------------------- InitPrefsFile
643 #define UNKNOWN_TYPE 0x3f3f3f3f
646 InitPrefsFile(OSType creator)
649 PrefsInfoHandle piHdl;
651 if ((piHdl = (PrefsInfoHandle) GetResource('PRFI', 0)) == nil)
653 ProcessSerialNumber thePSN;
654 ProcessInfoRec thePIR;
656 StringPtr app_string;
659 GetCurrentProcess(&thePSN);
660 thePIR.processName = nil;
661 thePIR.processAppSpec = &appSpec;
663 //¥ Set default to 'ÇApplicationÈ Prefs', PREF 0
664 err = GetProcessInformation(&thePSN, &thePIR);
668 app_string = LMGetCurApName();
669 // Pstrcpy(prefsInfo.fileName, appSpec.name);
670 Pstrcpy(prefsInfo.fileName, app_string);
671 Pstrcat(prefsInfo.fileName, "\p Preferences");
673 //¥ Set creator to calling application's signature (should be able to
674 //¥ Determine this automatically, but unable to for some reason)
675 prefsInfo.creator = creator;
676 prefsInfo.fileType = 'pref';
677 prefsInfo.resType = 'pref';
682 //¥ Get Preferences file setup from PRFI 0
683 BlockMove(*piHdl, &prefsInfo, sizeof (prefsInfo));
684 ReleaseResource((Handle) piHdl);
686 if (prefsInfo.creator == UNKNOWN_TYPE)
687 prefsInfo.creator = creator;
693 //¥ -------------------- LoadPrefsFile
696 LoadPrefsFile(Handle prefsHdl)
698 short prefVRefNum, prefRefNum;
700 OSErr theErr = noErr;
702 Size prefSize, origSize;
705 return (nilHandleErr);
707 prefSize = GetHandleSize(prefsHdl);
709 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
712 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
713 if (prefRefNum == -1)
716 //¥ Not finding the resource is not an error -- caller will use default data
717 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
719 origSize = GetHandleSize(origHdl);
720 if (origSize > prefSize) //¥ Extend handle for extra stored data
721 SetHandleSize(prefsHdl, origSize);
723 BlockMove(*origHdl, *prefsHdl, origSize);
724 ReleaseResource(origHdl);
727 CloseResFile(prefRefNum);
735 //¥ -------------------- SavePrefsFile
738 SavePrefsFile(Handle prefHdl)
740 short prefVRefNum, prefRefNum;
742 Handle origHdl = nil;
743 Size origSize, prefSize;
744 OSErr theErr = noErr;
746 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
750 return (nilHandleErr);
752 prefSize = GetHandleSize(prefHdl);
754 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
755 if (prefRefNum == -1)
758 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
760 //¥ Overwrite existing preferences
761 origSize = GetHandleSize(origHdl);
762 if (prefSize > origSize)
763 SetHandleSize(origHdl, prefSize);
765 BlockMove(*prefHdl, *origHdl, prefSize);
766 ChangedResource(origHdl);
767 WriteResource(origHdl);
768 ReleaseResource(origHdl);
772 //¥ Store specified preferences for the first time
773 AddResource(prefHdl, prefsInfo.resType, prefsInfo.resID, "\p");
774 WriteResource(prefHdl);
775 DetachResource(prefHdl);
778 CloseResFile(prefRefNum);
786 //¥ -------------------------------------------------------------------------------------------
790 This module provides the ability to save and load a preferences file in the
791 Preferences folder in the System Folder. An optional resource, PRFI 0,
792 is used to provide specifications for the preferences file (creator, etc.).
794 Three functions are provided:
796 void InitPrefsFile(OSType creator)
798 This function will initialize the preferences file, that is, it will create
799 it in the appropriate place if it doesn't currently exist. It should be
800 called with the creator code for the application. Note that the creator
801 code specified in PRFI 0 (if any) will be used only if the creator code
802 passed to this function is '????'. Without the PRFI 0 resource, the default
805 File Name: "{Application} Prefs" (i.e., the name of the app plus " Prefs"
806 Creator: the creator passed to InitPrefsFile
808 Pref Resource Type: 'PREF'
811 The PRFI 0 resource allows you to specify overrides for each of the above
812 values. This is useful for development, since the application name might
813 go through changes, but the preferences file name is held constant.
815 OSErr LoadPrefsFile(Handle prefsHndl)
817 This function will attempt to copy the data stored in the preferences
818 file to the given handle (which must be pre-allocated). If the handle is too
819 small, then it will be enlarged. If it is too large, it will not be resized.
820 The data in the preferences file (normally in PREF 0) will then be copied
821 into the handle. If the preferences file did not exist, the original data
822 in the handle will not change.
824 OSErr SavePrefsFile(Handle prefsHndl)
826 This function will attempt to save the given handle to the preferences
827 file. Its contents will completely replace the previous data (normally
828 the PREF 0 resource).
830 In typical use, you will use InitPrefsFile once, then allocate a handle large
831 enough to contain your preferences data, and initialize it with default values.
832 Throughout the course of your program, the handle will undergo modification as
833 user preferences change. You can use SavePrefsFile anytime to update the
834 preferences file, or wait until program exit to do so.
846 if (!have_prefs) { // not initialized....get a handle to the preferences file
847 InitPrefsFile('DCT2');
851 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
852 if (prefs_handle == NULL)
855 prefs = (Preferences *)(*prefs_handle);
856 err = LoadPrefsFile(prefs_handle);
858 DisposeHandle(prefs_handle);
863 for (i = 0; i < sizeof(Preferences); i++) {
868 if ( i == sizeof(Preferences) )
871 Config_digi_volume = prefs->digi_volume;
872 Config_midi_volume = prefs->midi_volume;
873 Config_master_volume = prefs->master_volume;
874 Config_redbook_volume = prefs->redbook_volume;
875 Config_channels_reversed = prefs->stereo_reverse;
876 gr_palette_set_gamma( (int)(prefs->gamma_level) );
878 Scanline_double = (int)prefs->pixel_double;
880 Scanline_double = 0; // can't double with hardware acceleration
882 Detail_level = prefs->detail_level;
883 if (Detail_level == NUM_DETAIL_LEVELS-1) {
884 Object_complexity = prefs->oc;
885 Object_detail = prefs->od;
886 Wall_detail = prefs->wd;
887 Wall_render_depth = prefs->wrd;
888 Debris_amount = prefs->da;
889 SoundChannels = prefs->sc;
890 set_custom_detail_vars();
893 strncpy( config_last_player, prefs->lastplayer, CALLSIGN_LEN );
894 p = strchr(config_last_player, '\n' );
897 strncpy(config_last_mission, prefs->lastmission, MISSION_NAME_LEN);
898 p = strchr(config_last_mission, '\n' );
901 strcpy(config_last_ctb_cfg, prefs->ctb_config);
903 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
905 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
907 joy_set_cal_vals( prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
908 digi_set_volume( (Config_digi_volume*256)/8, (Config_midi_volume*256)/8 );
909 digi_set_master_volume(Config_master_volume);
911 gConfigInfo.mDoNotDisplayOptions = prefs->display_dialog;
912 gConfigInfo.mUse11kSounds = prefs->sound_11k;
913 gConfigInfo.mDisableSound = prefs->nosound;
914 gConfigInfo.mDisableMIDIMusic = prefs->nomidi;
915 gConfigInfo.mChangeResolution = prefs->change_resolution;
916 gConfigInfo.mDoNotPlayMovies = prefs->no_movies;
917 gConfigInfo.mGameMonitor = prefs->game_monitor;
918 gConfigInfo.mAcceleration = prefs->enable_rave;
919 gConfigInfo.mInputSprockets = prefs->enable_input_sprockets;
921 DisposeHandle(prefs_handle);
925 int WriteConfigFile()
931 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
932 if (prefs_handle == NULL)
935 prefs = (Preferences *)(*prefs_handle);
937 joy_get_cal_vals(prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
938 prefs->digi_volume = Config_digi_volume;
939 prefs->midi_volume = Config_midi_volume;
940 prefs->stereo_reverse = Config_channels_reversed;
941 prefs->detail_level = Detail_level;
942 if (Detail_level == NUM_DETAIL_LEVELS-1) {
943 prefs->oc = Object_complexity;
944 prefs->od = Object_detail;
945 prefs->wd = Wall_detail;
946 prefs->wrd = Wall_render_depth;
947 prefs->da = Debris_amount;
948 prefs->sc = SoundChannels;
950 prefs->gamma_level = (ubyte)gr_palette_get_gamma();
953 prefs->pixel_double = (ubyte)Scanline_double; // hmm..don't write this out if doing hardware accel.
955 strncpy( prefs->lastplayer, Players[Player_num].callsign, CALLSIGN_LEN );
956 strncpy( prefs->lastmission, config_last_mission, MISSION_NAME_LEN );
957 strcpy( prefs->ctb_config, config_last_ctb_cfg);
958 prefs->ctb_tool = config_last_ctb_tool;
959 prefs->master_volume = Config_master_volume;
960 prefs->display_dialog = gConfigInfo.mDoNotDisplayOptions;
961 prefs->change_resolution = gConfigInfo.mChangeResolution;
962 prefs->nosound = gConfigInfo.mDisableSound;
963 prefs->nomidi = gConfigInfo.mDisableMIDIMusic;
964 prefs->sound_11k = gConfigInfo.mUse11kSounds;
965 prefs->no_movies = gConfigInfo.mDoNotPlayMovies;
966 prefs->game_monitor = gConfigInfo.mGameMonitor;
967 prefs->redbook_volume = Config_redbook_volume;
968 prefs->enable_rave = gConfigInfo.mAcceleration;
969 prefs->enable_input_sprockets = gConfigInfo.mInputSprockets;
971 err = SavePrefsFile(prefs_handle);
972 DisposeHandle(prefs_handle);