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 cvar_setint( &MovieHires, SaveMovieHires );
394 outfile = PHYSFSX_openWriteBuffered("descent.cfg");
398 key_write_bindings(outfile);
399 PHYSFS_close(outfile);
401 if (FindArg("-nohires") || FindArg("-nohighres") || FindArg("-lowresmovies"))
402 cvar_setint( &MovieHires, 0 );
406 // Save Windows Config File
410 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
412 outfile = PHYSFSX_openWriteBuffered("descentw.cfg");
413 if (outfile == NULL) return 1;
415 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", Config_joystick_min.name,
416 joy_axis_min[0], joy_axis_min[1], joy_axis_min[2], joy_axis_min[3],
417 joy_axis_min[4], joy_axis_min[5], joy_axis_min[6]);
418 PHYSFSX_puts(outfile, str);
419 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", Config_joystick_cen.name,
420 joy_axis_center[0], joy_axis_center[1], joy_axis_center[2], joy_axis_center[3],
421 joy_axis_center[4], joy_axis_center[5], joy_axis_center[6]);
422 PHYSFSX_puts(outfile, str);
423 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", Config_joystick_max.name,
424 joy_axis_max[0], joy_axis_max[1], joy_axis_max[2], joy_axis_max[3],
425 joy_axis_max[4], joy_axis_max[5], joy_axis_max[6]);
426 PHYSFSX_puts(outfile, str);
430 CheckMovieAttributes();
436 #else // !defined(MACINTOSH)
445 #include <GestaltEqu.h>
447 #include <Processes.h>
448 #include <Resources.h>
461 #include "prefs.h" // prefs file for configuration stuff -- from DeSalvo
463 #define MAX_CTB_LEN 512
465 typedef struct preferences {
468 ubyte stereo_reverse;
470 ubyte oc; // object complexity
471 ubyte od; // object detail
472 ubyte wd; // wall detail
473 ubyte wrd; // wall render depth
474 ubyte da; // debris amount
475 ubyte sc; // sound channels
480 int joy_axis_center[4];
481 char lastplayer[CALLSIGN_LEN+1];
482 char lastmission[MISSION_NAME_LEN+1];
483 char ctb_config[MAX_CTB_LEN];
486 ubyte display_dialog;
487 ubyte change_resolution;
493 ubyte redbook_volume;
495 ubyte enable_input_sprockets;
498 char config_last_player[CALLSIGN_LEN+1] = "";
499 char config_last_mission[MISSION_NAME_LEN+1] = "";
500 char config_last_ctb_cfg[MAX_CTB_LEN] = "";
501 int config_last_ctb_tool;
502 ubyte Config_master_volume = 4;
503 ubyte Config_digi_volume = 8;
504 ubyte Config_midi_volume = 8;
505 ubyte Config_redbook_volume = 8;
506 ubyte Config_control_type = 0;
507 ubyte Config_channels_reversed = 0;
508 ubyte Config_joystick_sensitivity = 8;
510 int Config_vr_type = 0;
511 int Config_vr_resolution = 0;
512 int Config_vr_tracking = 0;
514 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
515 extern void digi_set_master_volume( int volume );
517 void set_custom_detail_vars(void);
519 static ubyte have_prefs = 0;
521 //¥ ------------------------------ Private Definitions
522 //¥ ------------------------------ Private Types
531 } PrefsInfo, *PrefsInfoPtr, **PrefsInfoHandle;
533 //¥ ------------------------------ Private Variables
535 static PrefsInfo prefsInfo;
536 static Boolean prefsInited = 0;
538 //¥ ------------------------------ Private Functions
540 static void Pstrcpy(StringPtr dst, StringPtr src);
541 static void Pstrcat(StringPtr dst, StringPtr src);
542 static Boolean FindPrefsFile(short *prefVRefNum, long *prefDirID);
544 //¥ -------------------- Pstrcpy
547 Pstrcpy(StringPtr dst, StringPtr src)
549 BlockMove(src, dst, (*src) + 1);
552 //¥ -------------------- Pstrcat
555 Pstrcat(StringPtr dst, StringPtr src)
557 BlockMove(src + 1, dst + (*dst) + 1, *src);
561 //¥ -------------------- FindPrefsFile
564 FindPrefsFile(short *prefVRefNum, long *prefDirID)
573 theErr = Gestalt(gestaltFindFolderAttr, &response);
574 if (theErr == noErr && ((response >> gestaltFindFolderPresent) & 1))
576 //¥ Find (or make) it the easy way...
577 theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, prefVRefNum, prefDirID);
582 StringPtr prefFolderName = "\pPreferences";
584 //¥ yeachh -- we have to do it all by hand!
585 theErr = SysEnvirons(1, &theSysEnv);
589 *prefVRefNum = theSysEnv.sysVRefNum;
591 //¥ Check whether Preferences folder already exists
592 infoPB.hFileInfo.ioCompletion = 0;
593 infoPB.hFileInfo.ioNamePtr = prefFolderName;
594 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
595 infoPB.hFileInfo.ioFDirIndex = 0;
596 infoPB.hFileInfo.ioDirID = 0;
598 theErr = PBGetCatInfo(&infoPB, 0);
601 *prefDirID = infoPB.hFileInfo.ioDirID;
603 else if (theErr == fnfErr) //¥ Preferences doesn't already exist
605 HParamBlockRec dirPB;
607 //¥ Create "Preferences" folder
608 dirPB.fileParam.ioCompletion = 0;
609 dirPB.fileParam.ioVRefNum = *prefVRefNum;
610 dirPB.fileParam.ioNamePtr = prefFolderName;
611 dirPB.fileParam.ioDirID = 0;
613 theErr = PBDirCreate(&dirPB, 0);
615 *prefDirID = dirPB.fileParam.ioDirID;
619 //¥ If we make it here OK, create Preferences file if necessary
622 infoPB.hFileInfo.ioCompletion = 0;
623 infoPB.hFileInfo.ioNamePtr = prefsInfo.fileName;
624 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
625 infoPB.hFileInfo.ioFDirIndex = 0;
626 infoPB.hFileInfo.ioDirID = *prefDirID;
628 theErr = PBGetCatInfo(&infoPB, 0);
629 if (theErr == fnfErr)
631 theErr = HCreate(*prefVRefNum, *prefDirID, prefsInfo.fileName, prefsInfo.creator, prefsInfo.fileType);
634 HCreateResFile(*prefVRefNum, *prefDirID, prefsInfo.fileName);
640 return (theErr == noErr);
643 //¥ -------------------- InitPrefsFile
645 #define UNKNOWN_TYPE 0x3f3f3f3f
648 InitPrefsFile(OSType creator)
651 PrefsInfoHandle piHdl;
653 if ((piHdl = (PrefsInfoHandle) GetResource('PRFI', 0)) == nil)
655 ProcessSerialNumber thePSN;
656 ProcessInfoRec thePIR;
658 StringPtr app_string;
661 GetCurrentProcess(&thePSN);
662 thePIR.processName = nil;
663 thePIR.processAppSpec = &appSpec;
665 //¥ Set default to 'ÇApplicationÈ Prefs', PREF 0
666 err = GetProcessInformation(&thePSN, &thePIR);
670 app_string = LMGetCurApName();
671 // Pstrcpy(prefsInfo.fileName, appSpec.name);
672 Pstrcpy(prefsInfo.fileName, app_string);
673 Pstrcat(prefsInfo.fileName, "\p Preferences");
675 //¥ Set creator to calling application's signature (should be able to
676 //¥ Determine this automatically, but unable to for some reason)
677 prefsInfo.creator = creator;
678 prefsInfo.fileType = 'pref';
679 prefsInfo.resType = 'pref';
684 //¥ Get Preferences file setup from PRFI 0
685 BlockMove(*piHdl, &prefsInfo, sizeof (prefsInfo));
686 ReleaseResource((Handle) piHdl);
688 if (prefsInfo.creator == UNKNOWN_TYPE)
689 prefsInfo.creator = creator;
695 //¥ -------------------- LoadPrefsFile
698 LoadPrefsFile(Handle prefsHdl)
700 short prefVRefNum, prefRefNum;
702 OSErr theErr = noErr;
704 Size prefSize, origSize;
707 return (nilHandleErr);
709 prefSize = GetHandleSize(prefsHdl);
711 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
714 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
715 if (prefRefNum == -1)
718 //¥ Not finding the resource is not an error -- caller will use default data
719 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
721 origSize = GetHandleSize(origHdl);
722 if (origSize > prefSize) //¥ Extend handle for extra stored data
723 SetHandleSize(prefsHdl, origSize);
725 BlockMove(*origHdl, *prefsHdl, origSize);
726 ReleaseResource(origHdl);
729 CloseResFile(prefRefNum);
737 //¥ -------------------- SavePrefsFile
740 SavePrefsFile(Handle prefHdl)
742 short prefVRefNum, prefRefNum;
744 Handle origHdl = nil;
745 Size origSize, prefSize;
746 OSErr theErr = noErr;
748 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
752 return (nilHandleErr);
754 prefSize = GetHandleSize(prefHdl);
756 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
757 if (prefRefNum == -1)
760 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
762 //¥ Overwrite existing preferences
763 origSize = GetHandleSize(origHdl);
764 if (prefSize > origSize)
765 SetHandleSize(origHdl, prefSize);
767 BlockMove(*prefHdl, *origHdl, prefSize);
768 ChangedResource(origHdl);
769 WriteResource(origHdl);
770 ReleaseResource(origHdl);
774 //¥ Store specified preferences for the first time
775 AddResource(prefHdl, prefsInfo.resType, prefsInfo.resID, "\p");
776 WriteResource(prefHdl);
777 DetachResource(prefHdl);
780 CloseResFile(prefRefNum);
788 //¥ -------------------------------------------------------------------------------------------
792 This module provides the ability to save and load a preferences file in the
793 Preferences folder in the System Folder. An optional resource, PRFI 0,
794 is used to provide specifications for the preferences file (creator, etc.).
796 Three functions are provided:
798 void InitPrefsFile(OSType creator)
800 This function will initialize the preferences file, that is, it will create
801 it in the appropriate place if it doesn't currently exist. It should be
802 called with the creator code for the application. Note that the creator
803 code specified in PRFI 0 (if any) will be used only if the creator code
804 passed to this function is '????'. Without the PRFI 0 resource, the default
807 File Name: "{Application} Prefs" (i.e., the name of the app plus " Prefs"
808 Creator: the creator passed to InitPrefsFile
810 Pref Resource Type: 'PREF'
813 The PRFI 0 resource allows you to specify overrides for each of the above
814 values. This is useful for development, since the application name might
815 go through changes, but the preferences file name is held constant.
817 OSErr LoadPrefsFile(Handle prefsHndl)
819 This function will attempt to copy the data stored in the preferences
820 file to the given handle (which must be pre-allocated). If the handle is too
821 small, then it will be enlarged. If it is too large, it will not be resized.
822 The data in the preferences file (normally in PREF 0) will then be copied
823 into the handle. If the preferences file did not exist, the original data
824 in the handle will not change.
826 OSErr SavePrefsFile(Handle prefsHndl)
828 This function will attempt to save the given handle to the preferences
829 file. Its contents will completely replace the previous data (normally
830 the PREF 0 resource).
832 In typical use, you will use InitPrefsFile once, then allocate a handle large
833 enough to contain your preferences data, and initialize it with default values.
834 Throughout the course of your program, the handle will undergo modification as
835 user preferences change. You can use SavePrefsFile anytime to update the
836 preferences file, or wait until program exit to do so.
848 if (!have_prefs) { // not initialized....get a handle to the preferences file
849 InitPrefsFile('DCT2');
853 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
854 if (prefs_handle == NULL)
857 prefs = (Preferences *)(*prefs_handle);
858 err = LoadPrefsFile(prefs_handle);
860 DisposeHandle(prefs_handle);
865 for (i = 0; i < sizeof(Preferences); i++) {
870 if ( i == sizeof(Preferences) )
873 Config_digi_volume = prefs->digi_volume;
874 Config_midi_volume = prefs->midi_volume;
875 Config_master_volume = prefs->master_volume;
876 Config_redbook_volume = prefs->redbook_volume;
877 Config_channels_reversed = prefs->stereo_reverse;
878 gr_palette_set_gamma( (int)(prefs->gamma_level) );
880 Scanline_double = (int)prefs->pixel_double;
882 Scanline_double = 0; // can't double with hardware acceleration
884 Detail_level = prefs->detail_level;
885 if (Detail_level == NUM_DETAIL_LEVELS-1) {
886 Object_complexity = prefs->oc;
887 Object_detail = prefs->od;
888 Wall_detail = prefs->wd;
889 Wall_render_depth = prefs->wrd;
890 Debris_amount = prefs->da;
891 SoundChannels = prefs->sc;
892 set_custom_detail_vars();
895 strncpy( config_last_player, prefs->lastplayer, CALLSIGN_LEN );
896 p = strchr(config_last_player, '\n' );
899 strncpy(config_last_mission, prefs->lastmission, MISSION_NAME_LEN);
900 p = strchr(config_last_mission, '\n' );
903 strcpy(config_last_ctb_cfg, prefs->ctb_config);
905 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
907 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
909 joy_set_cal_vals( prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
910 digi_set_volume( (Config_digi_volume*256)/8, (Config_midi_volume*256)/8 );
911 digi_set_master_volume(Config_master_volume);
913 gConfigInfo.mDoNotDisplayOptions = prefs->display_dialog;
914 gConfigInfo.mUse11kSounds = prefs->sound_11k;
915 gConfigInfo.mDisableSound = prefs->nosound;
916 gConfigInfo.mDisableMIDIMusic = prefs->nomidi;
917 gConfigInfo.mChangeResolution = prefs->change_resolution;
918 gConfigInfo.mDoNotPlayMovies = prefs->no_movies;
919 gConfigInfo.mGameMonitor = prefs->game_monitor;
920 gConfigInfo.mAcceleration = prefs->enable_rave;
921 gConfigInfo.mInputSprockets = prefs->enable_input_sprockets;
923 DisposeHandle(prefs_handle);
927 int WriteConfigFile()
933 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
934 if (prefs_handle == NULL)
937 prefs = (Preferences *)(*prefs_handle);
939 joy_get_cal_vals(prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
940 prefs->digi_volume = Config_digi_volume;
941 prefs->midi_volume = Config_midi_volume;
942 prefs->stereo_reverse = Config_channels_reversed;
943 prefs->detail_level = Detail_level;
944 if (Detail_level == NUM_DETAIL_LEVELS-1) {
945 prefs->oc = Object_complexity;
946 prefs->od = Object_detail;
947 prefs->wd = Wall_detail;
948 prefs->wrd = Wall_render_depth;
949 prefs->da = Debris_amount;
950 prefs->sc = SoundChannels;
952 prefs->gamma_level = (ubyte)gr_palette_get_gamma();
955 prefs->pixel_double = (ubyte)Scanline_double; // hmm..don't write this out if doing hardware accel.
957 strncpy( prefs->lastplayer, Players[Player_num].callsign, CALLSIGN_LEN );
958 strncpy( prefs->lastmission, config_last_mission, MISSION_NAME_LEN );
959 strcpy( prefs->ctb_config, config_last_ctb_cfg);
960 prefs->ctb_tool = config_last_ctb_tool;
961 prefs->master_volume = Config_master_volume;
962 prefs->display_dialog = gConfigInfo.mDoNotDisplayOptions;
963 prefs->change_resolution = gConfigInfo.mChangeResolution;
964 prefs->nosound = gConfigInfo.mDisableSound;
965 prefs->nomidi = gConfigInfo.mDisableMIDIMusic;
966 prefs->sound_11k = gConfigInfo.mUse11kSounds;
967 prefs->no_movies = gConfigInfo.mDoNotPlayMovies;
968 prefs->game_monitor = gConfigInfo.mGameMonitor;
969 prefs->redbook_volume = Config_redbook_volume;
970 prefs->enable_rave = gConfigInfo.mAcceleration;
971 prefs->enable_input_sprockets = gConfigInfo.mInputSprockets;
973 err = SavePrefsFile(prefs_handle);
974 DisposeHandle(prefs_handle);