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
95 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
97 void set_custom_detail_vars(void);
103 void CrystalLakeWriteMCP( ushort mc_addr, ubyte mc_data )
106 outp( CL_MC0, 0xE2 ); // Write password
107 outp( mc_addr, mc_data ); // Write data
111 ubyte CrystalLakeReadMCP( ushort mc_addr )
115 outp( CL_MC0, 0xE2 ); // Write password
116 value = inp( mc_addr ); // Read data
121 void CrystalLakeSetSB()
124 tmp = CrystalLakeReadMCP( CL_MC1 );
126 CrystalLakeWriteMCP( CL_MC1, tmp );
129 void CrystalLakeSetWSS()
132 tmp = CrystalLakeReadMCP( CL_MC1 );
134 CrystalLakeWriteMCP( CL_MC1, tmp );
137 //MovieHires might be changed by -nohighres, so save a "real" copy of it
139 int save_redbook_enabled;
142 void CheckMovieAttributes()
145 DWORD len, type, val;
148 lres = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Parallax\\Descent II\\1.1\\INSTALL",
150 if (lres == ERROR_SUCCESS) {
152 lres = RegQueryValueEx(hKey, "HIRES", NULL, &type, &val, &len);
153 if (lres == ERROR_SUCCESS) {
154 cvar_setint( &MovieHires, val );
155 logentry("HIRES=%d\n", val);
163 static int config_initialized;
165 static void config_init(void)
167 /* make sure our cvars are registered */
168 cvar_registervariable(&Config_digi_volume);
169 cvar_registervariable(&Config_midi_volume);
170 cvar_registervariable(&Redbook_enabled);
171 cvar_registervariable(&Config_redbook_volume);
172 cvar_registervariable(&Config_channels_reversed);
173 cvar_registervariable(&Config_gamma_level);
174 cvar_registervariable(&Config_detail_level);
175 cvar_registervariable(&Config_joystick_min);
176 cvar_registervariable(&Config_joystick_cen);
177 cvar_registervariable(&Config_joystick_max);
178 cvar_registervariable(&config_last_player);
179 cvar_registervariable(&config_last_mission);
180 cvar_registervariable(&Config_vr_type);
181 cvar_registervariable(&Config_vr_resolution);
182 cvar_registervariable(&Config_vr_tracking);
183 cvar_registervariable(&MovieHires);
185 config_initialized = 1;
189 void LoadConfigDefaults(void)
191 cmd_append("bind UP +lookdown; bind PAD8 +lookdown");
192 cmd_append("bind DOWN +lookup; bind PAD2 +lookup");
193 cmd_append("bind LEFT +left; bind PAD4 +left");
194 cmd_append("bind RIGHT +right; bind PAD6 +right");
196 cmd_append("bind LALT +strafe");
197 cmd_append("bind PAD1 +moveleft");
198 cmd_append("bind PAD3 +moveright");
199 cmd_append("bind PAD- +moveup");
200 cmd_append("bind PAD+ +movedown");
202 cmd_append("bind Q +bankleft; bind PAD7 +bankleft");
203 cmd_append("bind E +bankright; bind PAD9 +bankright");
205 cmd_append("bind , +cycle");
206 cmd_append("bind . +cycle2");
208 cmd_append("bind LCTRL +attack; bind RCTRL +attack");
209 cmd_append("bind SPC +attack2");
210 cmd_append("bind F +flare");
211 cmd_append("bind B +bomb");
213 cmd_append("bind R +rearview");
214 cmd_append("bind TAB +automap");
216 cmd_append("bind A +forward");
217 cmd_append("bind Z +back");
218 cmd_append("bind S +afterburner");
220 cmd_append("bind H +headlight");
221 cmd_append("bind T +nrgshield");
223 cmd_append("bind 1 weapon 1");
224 cmd_append("bind 2 weapon 2");
225 cmd_append("bind 3 weapon 3");
226 cmd_append("bind 4 weapon 4");
227 cmd_append("bind 5 weapon 5");
228 cmd_append("bind 6 weapon 6");
229 cmd_append("bind 7 weapon 7");
230 cmd_append("bind 8 weapon 8");
231 cmd_append("bind 9 weapon 9");
232 cmd_append("bind 0 weapon 0");
239 int joy_axis_center[7];
243 if (!config_initialized)
246 cvar_set_cvar( &config_last_player, "" );
248 joy_axis_min[0] = joy_axis_min[1] = joy_axis_min[2] = joy_axis_min[3] = 0;
249 joy_axis_max[0] = joy_axis_max[1] = joy_axis_max[2] = joy_axis_max[3] = 0;
250 joy_axis_center[0] = joy_axis_center[1] = joy_axis_center[2] = joy_axis_center[3] = 0;
252 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
255 cvar_setint(&digi_driver_board, 0);
256 cvar_setint(&digi_driver_port, 0);
257 cvar_setint(&digi_driver_irq, 0);
258 cvar_setint(&digi_driver_dma, 0);
259 cvar_setint(&digi_midi_type, 0);
260 cvar_setint(&digi_midi_port, 0);
263 cvar_setint( &Config_digi_volume, 8 );
264 cvar_setint( &Config_midi_volume, 8 );
265 cvar_setint( &Config_redbook_volume, 8 );
266 Config_control_type = 0;
267 cvar_setint( &Config_channels_reversed, 0);
269 //set these here in case no cfg file
270 SaveMovieHires = MovieHires.intval;
271 save_redbook_enabled = Redbook_enabled.intval;
273 if (cfexist("descent.cfg"))
274 cmd_append("exec descent.cfg");
276 LoadConfigDefaults();
280 /* TODO: allow cvars to define a callback that will carry out these initialization things on change. */
282 gr_palette_set_gamma( Config_gamma_level.intval );
284 Detail_level = strtol(Config_detail_level.string, NULL, 10);
285 if (Detail_level == NUM_DETAIL_LEVELS - 1) {
286 int count,dummy,oc,od,wd,wrd,da,sc;
288 count = sscanf (Config_detail_level.string, "%d,%d,%d,%d,%d,%d,%d\n",&dummy,&oc,&od,&wd,&wrd,&da,&sc);
291 Object_complexity = oc;
294 Wall_render_depth = wrd;
297 set_custom_detail_vars();
301 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] );
302 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] );
303 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] );
305 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
307 i = FindArg( "-volume" );
310 i = atoi( Args[i+1] );
312 if ( i > 100 ) i = 100;
313 cvar_setint( &Config_digi_volume, (i * 8) / 100 );
314 cvar_setint( &Config_midi_volume, (i * 8) / 100 );
315 cvar_setint( &Config_redbook_volume, (i * 8) / 100 );
318 if ( Config_digi_volume.intval > 8 ) cvar_setint( &Config_digi_volume, 8 );
319 if ( Config_midi_volume.intval > 8 ) cvar_setint( &Config_midi_volume, 8 );
320 if ( Config_redbook_volume.intval > 8 ) cvar_setint( &Config_redbook_volume, 8 );
322 digi_set_volume( (Config_digi_volume.intval * 32768) / 8, (Config_midi_volume.intval * 128) / 8 );
325 printf( "DigiDeviceID: 0x%x\n", digi_driver_board );
326 printf( "DigiPort: 0x%x\n", digi_driver_port.intval );
327 printf( "DigiIrq: 0x%x\n", digi_driver_irq.intval );
328 printf( "DigiDma: 0x%x\n", digi_driver_dma.intval );
329 printf( "MidiDeviceID: 0x%x\n", digi_midi_type.intval );
330 printf( "MidiPort: 0x%x\n", digi_midi_port.intval );
333 cvar_setint( &Config_midi_type, digi_midi_type );
334 cvar_setint( &Config_digi_type, digi_driver_board );
335 cvar_setint( &Config_digi_dma, digi_driver_dma );
339 if (digi_driver_board_16.intval > 0 && !FindArg("-no16bit") && digi_driver_board_16.intval != _GUS_16_ST) {
340 digi_driver_board = digi_driver_board_16.intval;
341 digi_driver_dma = digi_driver_dma_16.intval;
345 //Hack to make some cards look like others, such as
346 //the Crytal Lake look like Microsoft Sound System
347 if ( digi_driver_board == _CRYSTAL_LAKE_8_ST ) {
349 tmp = CrystalLakeReadMCP( CL_MC1 );
351 atexit( CrystalLakeSetSB ); // Restore to SB when done.
353 digi_driver_board = _MICROSOFT_8_ST;
354 } else if ( digi_driver_board == _CRYSTAL_LAKE_16_ST ) {
356 tmp = CrystalLakeReadMCP( CL_MC1 );
358 atexit( CrystalLakeSetSB ); // Restore to SB when done.
360 digi_driver_board = _MICROSOFT_16_ST;
361 } else if ( digi_driver_board == _AWE32_8_ST ) {
362 digi_driver_board = _SB16_8_ST;
363 } else if ( digi_driver_board == _AWE32_16_ST ) {
364 digi_driver_board = _SB16_16_ST;
366 digi_driver_board = digi_driver_board;
369 if (cfexist("descentw.cfg")) {
370 cmd_append("exec descentw.cfg");
373 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] );
374 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] );
375 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] );
382 int WriteConfigFile()
384 PHYSFS_file *outfile;
386 int joy_axis_center[7];
389 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
391 if (FindArg("-noredbook"))
392 cvar_setint( &Redbook_enabled, save_redbook_enabled );
394 cvar_setint( &Config_gamma_level, gr_palette_get_gamma() );
396 if (Detail_level == NUM_DETAIL_LEVELS-1)
397 cvar_set_cvarf( &Config_detail_level, "%d,%d,%d,%d,%d,%d,%d", Detail_level,
398 Object_complexity,Object_detail,Wall_detail,Wall_render_depth,Debris_amount,SoundChannels );
400 cvar_setint( &Config_detail_level, Detail_level );
402 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] );
403 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] );
404 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] );
406 cvar_set_cvar( &config_last_player, Players[Player_num].callsign );
408 cvar_setint( &MovieHires, SaveMovieHires );
410 outfile = PHYSFSX_openWriteBuffered("descent.cfg");
414 key_write_bindings(outfile);
415 PHYSFS_close(outfile);
417 if (FindArg("-nohires") || FindArg("-nohighres") || FindArg("-lowresmovies"))
418 cvar_setint( &MovieHires, 0 );
421 CheckMovieAttributes();
427 #else // !defined(MACINTOSH)
436 #include <GestaltEqu.h>
438 #include <Processes.h>
439 #include <Resources.h>
452 #include "prefs.h" // prefs file for configuration stuff -- from DeSalvo
454 #define MAX_CTB_LEN 512
456 typedef struct preferences {
459 ubyte stereo_reverse;
461 ubyte oc; // object complexity
462 ubyte od; // object detail
463 ubyte wd; // wall detail
464 ubyte wrd; // wall render depth
465 ubyte da; // debris amount
466 ubyte sc; // sound channels
471 int joy_axis_center[4];
472 char lastplayer[CALLSIGN_LEN+1];
473 char lastmission[MISSION_NAME_LEN+1];
474 char ctb_config[MAX_CTB_LEN];
477 ubyte display_dialog;
478 ubyte change_resolution;
484 ubyte redbook_volume;
486 ubyte enable_input_sprockets;
489 char config_last_player[CALLSIGN_LEN+1] = "";
490 char config_last_mission[MISSION_NAME_LEN+1] = "";
491 char config_last_ctb_cfg[MAX_CTB_LEN] = "";
492 int config_last_ctb_tool;
493 ubyte Config_master_volume = 4;
494 ubyte Config_digi_volume = 8;
495 ubyte Config_midi_volume = 8;
496 ubyte Config_redbook_volume = 8;
497 ubyte Config_control_type = 0;
498 ubyte Config_channels_reversed = 0;
499 ubyte Config_joystick_sensitivity = 8;
501 int Config_vr_type = 0;
502 int Config_vr_resolution = 0;
503 int Config_vr_tracking = 0;
505 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
506 extern void digi_set_master_volume( int volume );
508 void set_custom_detail_vars(void);
510 static ubyte have_prefs = 0;
512 //¥ ------------------------------ Private Definitions
513 //¥ ------------------------------ Private Types
522 } PrefsInfo, *PrefsInfoPtr, **PrefsInfoHandle;
524 //¥ ------------------------------ Private Variables
526 static PrefsInfo prefsInfo;
527 static Boolean prefsInited = 0;
529 //¥ ------------------------------ Private Functions
531 static void Pstrcpy(StringPtr dst, StringPtr src);
532 static void Pstrcat(StringPtr dst, StringPtr src);
533 static Boolean FindPrefsFile(short *prefVRefNum, long *prefDirID);
535 //¥ -------------------- Pstrcpy
538 Pstrcpy(StringPtr dst, StringPtr src)
540 BlockMove(src, dst, (*src) + 1);
543 //¥ -------------------- Pstrcat
546 Pstrcat(StringPtr dst, StringPtr src)
548 BlockMove(src + 1, dst + (*dst) + 1, *src);
552 //¥ -------------------- FindPrefsFile
555 FindPrefsFile(short *prefVRefNum, long *prefDirID)
564 theErr = Gestalt(gestaltFindFolderAttr, &response);
565 if (theErr == noErr && ((response >> gestaltFindFolderPresent) & 1))
567 //¥ Find (or make) it the easy way...
568 theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, prefVRefNum, prefDirID);
573 StringPtr prefFolderName = "\pPreferences";
575 //¥ yeachh -- we have to do it all by hand!
576 theErr = SysEnvirons(1, &theSysEnv);
580 *prefVRefNum = theSysEnv.sysVRefNum;
582 //¥ Check whether Preferences folder already exists
583 infoPB.hFileInfo.ioCompletion = 0;
584 infoPB.hFileInfo.ioNamePtr = prefFolderName;
585 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
586 infoPB.hFileInfo.ioFDirIndex = 0;
587 infoPB.hFileInfo.ioDirID = 0;
589 theErr = PBGetCatInfo(&infoPB, 0);
592 *prefDirID = infoPB.hFileInfo.ioDirID;
594 else if (theErr == fnfErr) //¥ Preferences doesn't already exist
596 HParamBlockRec dirPB;
598 //¥ Create "Preferences" folder
599 dirPB.fileParam.ioCompletion = 0;
600 dirPB.fileParam.ioVRefNum = *prefVRefNum;
601 dirPB.fileParam.ioNamePtr = prefFolderName;
602 dirPB.fileParam.ioDirID = 0;
604 theErr = PBDirCreate(&dirPB, 0);
606 *prefDirID = dirPB.fileParam.ioDirID;
610 //¥ If we make it here OK, create Preferences file if necessary
613 infoPB.hFileInfo.ioCompletion = 0;
614 infoPB.hFileInfo.ioNamePtr = prefsInfo.fileName;
615 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
616 infoPB.hFileInfo.ioFDirIndex = 0;
617 infoPB.hFileInfo.ioDirID = *prefDirID;
619 theErr = PBGetCatInfo(&infoPB, 0);
620 if (theErr == fnfErr)
622 theErr = HCreate(*prefVRefNum, *prefDirID, prefsInfo.fileName, prefsInfo.creator, prefsInfo.fileType);
625 HCreateResFile(*prefVRefNum, *prefDirID, prefsInfo.fileName);
631 return (theErr == noErr);
634 //¥ -------------------- InitPrefsFile
636 #define UNKNOWN_TYPE 0x3f3f3f3f
639 InitPrefsFile(OSType creator)
642 PrefsInfoHandle piHdl;
644 if ((piHdl = (PrefsInfoHandle) GetResource('PRFI', 0)) == nil)
646 ProcessSerialNumber thePSN;
647 ProcessInfoRec thePIR;
649 StringPtr app_string;
652 GetCurrentProcess(&thePSN);
653 thePIR.processName = nil;
654 thePIR.processAppSpec = &appSpec;
656 //¥ Set default to 'ÇApplicationÈ Prefs', PREF 0
657 err = GetProcessInformation(&thePSN, &thePIR);
661 app_string = LMGetCurApName();
662 // Pstrcpy(prefsInfo.fileName, appSpec.name);
663 Pstrcpy(prefsInfo.fileName, app_string);
664 Pstrcat(prefsInfo.fileName, "\p Preferences");
666 //¥ Set creator to calling application's signature (should be able to
667 //¥ Determine this automatically, but unable to for some reason)
668 prefsInfo.creator = creator;
669 prefsInfo.fileType = 'pref';
670 prefsInfo.resType = 'pref';
675 //¥ Get Preferences file setup from PRFI 0
676 BlockMove(*piHdl, &prefsInfo, sizeof (prefsInfo));
677 ReleaseResource((Handle) piHdl);
679 if (prefsInfo.creator == UNKNOWN_TYPE)
680 prefsInfo.creator = creator;
686 //¥ -------------------- LoadPrefsFile
689 LoadPrefsFile(Handle prefsHdl)
691 short prefVRefNum, prefRefNum;
693 OSErr theErr = noErr;
695 Size prefSize, origSize;
698 return (nilHandleErr);
700 prefSize = GetHandleSize(prefsHdl);
702 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
705 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
706 if (prefRefNum == -1)
709 //¥ Not finding the resource is not an error -- caller will use default data
710 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
712 origSize = GetHandleSize(origHdl);
713 if (origSize > prefSize) //¥ Extend handle for extra stored data
714 SetHandleSize(prefsHdl, origSize);
716 BlockMove(*origHdl, *prefsHdl, origSize);
717 ReleaseResource(origHdl);
720 CloseResFile(prefRefNum);
728 //¥ -------------------- SavePrefsFile
731 SavePrefsFile(Handle prefHdl)
733 short prefVRefNum, prefRefNum;
735 Handle origHdl = nil;
736 Size origSize, prefSize;
737 OSErr theErr = noErr;
739 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
743 return (nilHandleErr);
745 prefSize = GetHandleSize(prefHdl);
747 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
748 if (prefRefNum == -1)
751 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
753 //¥ Overwrite existing preferences
754 origSize = GetHandleSize(origHdl);
755 if (prefSize > origSize)
756 SetHandleSize(origHdl, prefSize);
758 BlockMove(*prefHdl, *origHdl, prefSize);
759 ChangedResource(origHdl);
760 WriteResource(origHdl);
761 ReleaseResource(origHdl);
765 //¥ Store specified preferences for the first time
766 AddResource(prefHdl, prefsInfo.resType, prefsInfo.resID, "\p");
767 WriteResource(prefHdl);
768 DetachResource(prefHdl);
771 CloseResFile(prefRefNum);
779 //¥ -------------------------------------------------------------------------------------------
783 This module provides the ability to save and load a preferences file in the
784 Preferences folder in the System Folder. An optional resource, PRFI 0,
785 is used to provide specifications for the preferences file (creator, etc.).
787 Three functions are provided:
789 void InitPrefsFile(OSType creator)
791 This function will initialize the preferences file, that is, it will create
792 it in the appropriate place if it doesn't currently exist. It should be
793 called with the creator code for the application. Note that the creator
794 code specified in PRFI 0 (if any) will be used only if the creator code
795 passed to this function is '????'. Without the PRFI 0 resource, the default
798 File Name: "{Application} Prefs" (i.e., the name of the app plus " Prefs"
799 Creator: the creator passed to InitPrefsFile
801 Pref Resource Type: 'PREF'
804 The PRFI 0 resource allows you to specify overrides for each of the above
805 values. This is useful for development, since the application name might
806 go through changes, but the preferences file name is held constant.
808 OSErr LoadPrefsFile(Handle prefsHndl)
810 This function will attempt to copy the data stored in the preferences
811 file to the given handle (which must be pre-allocated). If the handle is too
812 small, then it will be enlarged. If it is too large, it will not be resized.
813 The data in the preferences file (normally in PREF 0) will then be copied
814 into the handle. If the preferences file did not exist, the original data
815 in the handle will not change.
817 OSErr SavePrefsFile(Handle prefsHndl)
819 This function will attempt to save the given handle to the preferences
820 file. Its contents will completely replace the previous data (normally
821 the PREF 0 resource).
823 In typical use, you will use InitPrefsFile once, then allocate a handle large
824 enough to contain your preferences data, and initialize it with default values.
825 Throughout the course of your program, the handle will undergo modification as
826 user preferences change. You can use SavePrefsFile anytime to update the
827 preferences file, or wait until program exit to do so.
839 if (!have_prefs) { // not initialized....get a handle to the preferences file
840 InitPrefsFile('DCT2');
844 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
845 if (prefs_handle == NULL)
848 prefs = (Preferences *)(*prefs_handle);
849 err = LoadPrefsFile(prefs_handle);
851 DisposeHandle(prefs_handle);
856 for (i = 0; i < sizeof(Preferences); i++) {
861 if ( i == sizeof(Preferences) )
864 Config_digi_volume = prefs->digi_volume;
865 Config_midi_volume = prefs->midi_volume;
866 Config_master_volume = prefs->master_volume;
867 Config_redbook_volume = prefs->redbook_volume;
868 Config_channels_reversed = prefs->stereo_reverse;
869 gr_palette_set_gamma( (int)(prefs->gamma_level) );
871 Scanline_double = (int)prefs->pixel_double;
873 Scanline_double = 0; // can't double with hardware acceleration
875 Detail_level = prefs->detail_level;
876 if (Detail_level == NUM_DETAIL_LEVELS-1) {
877 Object_complexity = prefs->oc;
878 Object_detail = prefs->od;
879 Wall_detail = prefs->wd;
880 Wall_render_depth = prefs->wrd;
881 Debris_amount = prefs->da;
882 SoundChannels = prefs->sc;
883 set_custom_detail_vars();
886 strncpy( config_last_player, prefs->lastplayer, CALLSIGN_LEN );
887 p = strchr(config_last_player, '\n' );
890 strncpy(config_last_mission, prefs->lastmission, MISSION_NAME_LEN);
891 p = strchr(config_last_mission, '\n' );
894 strcpy(config_last_ctb_cfg, prefs->ctb_config);
896 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
898 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
900 joy_set_cal_vals( prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
901 digi_set_volume( (Config_digi_volume*256)/8, (Config_midi_volume*256)/8 );
902 digi_set_master_volume(Config_master_volume);
904 gConfigInfo.mDoNotDisplayOptions = prefs->display_dialog;
905 gConfigInfo.mUse11kSounds = prefs->sound_11k;
906 gConfigInfo.mDisableSound = prefs->nosound;
907 gConfigInfo.mDisableMIDIMusic = prefs->nomidi;
908 gConfigInfo.mChangeResolution = prefs->change_resolution;
909 gConfigInfo.mDoNotPlayMovies = prefs->no_movies;
910 gConfigInfo.mGameMonitor = prefs->game_monitor;
911 gConfigInfo.mAcceleration = prefs->enable_rave;
912 gConfigInfo.mInputSprockets = prefs->enable_input_sprockets;
914 DisposeHandle(prefs_handle);
918 int WriteConfigFile()
924 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
925 if (prefs_handle == NULL)
928 prefs = (Preferences *)(*prefs_handle);
930 joy_get_cal_vals(prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
931 prefs->digi_volume = Config_digi_volume;
932 prefs->midi_volume = Config_midi_volume;
933 prefs->stereo_reverse = Config_channels_reversed;
934 prefs->detail_level = Detail_level;
935 if (Detail_level == NUM_DETAIL_LEVELS-1) {
936 prefs->oc = Object_complexity;
937 prefs->od = Object_detail;
938 prefs->wd = Wall_detail;
939 prefs->wrd = Wall_render_depth;
940 prefs->da = Debris_amount;
941 prefs->sc = SoundChannels;
943 prefs->gamma_level = (ubyte)gr_palette_get_gamma();
946 prefs->pixel_double = (ubyte)Scanline_double; // hmm..don't write this out if doing hardware accel.
948 strncpy( prefs->lastplayer, Players[Player_num].callsign, CALLSIGN_LEN );
949 strncpy( prefs->lastmission, config_last_mission, MISSION_NAME_LEN );
950 strcpy( prefs->ctb_config, config_last_ctb_cfg);
951 prefs->ctb_tool = config_last_ctb_tool;
952 prefs->master_volume = Config_master_volume;
953 prefs->display_dialog = gConfigInfo.mDoNotDisplayOptions;
954 prefs->change_resolution = gConfigInfo.mChangeResolution;
955 prefs->nosound = gConfigInfo.mDisableSound;
956 prefs->nomidi = gConfigInfo.mDisableMIDIMusic;
957 prefs->sound_11k = gConfigInfo.mUse11kSounds;
958 prefs->no_movies = gConfigInfo.mDoNotPlayMovies;
959 prefs->game_monitor = gConfigInfo.mGameMonitor;
960 prefs->redbook_volume = Config_redbook_volume;
961 prefs->enable_rave = gConfigInfo.mAcceleration;
962 prefs->enable_input_sprockets = gConfigInfo.mInputSprockets;
964 err = SavePrefsFile(prefs_handle);
965 DisposeHandle(prefs_handle);