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
60 cvar_t Config_digi_type = { "DigiDeviceID8", "0", 1 };
61 cvar_t digi_driver_board_16 = { "DigiDeviceID16", "0", 1 };
62 //cvar_t digi_driver_port = { "DigiPort", "0", 1 };
63 //cvar_t digi_driver_irq = { "DigiIrq", "0", 1 };
64 cvar_t Config_digi_dma = { "DigiDma8", "0", 1 };
65 cvar_t digi_driver_dma_16 = { "DigiDma16", "0", 1 };
66 cvar_t Config_midi_type = { "MidiDeviceID", "0", 1 };
67 //cvar_t digi_midi_port = { "MidiPort", "0", 1 };
69 cvar_t Config_digi_volume = { "DigiVolume", "8", 1 };
70 cvar_t Config_midi_volume = { "MidiVolume", "8", 1 };
71 cvar_t Config_redbook_volume = { "RedbookVolume", "8", 1 };
72 cvar_t Config_detail_level = { "DetailLevel", "4", 1 };
73 cvar_t Config_gamma_level = { "GammaLevel", "0", 1 };
74 cvar_t Config_control_type = { "ControlType", "0", 1 };
75 cvar_t Config_channels_reversed = { "StereoReverse", "0", 1 };
76 cvar_t Config_joystick_sensitivity = { "JoystickSensitivity", "8", 1 };
77 cvar_t Config_joystick_min = { "JoystickMin", "0,0,0,0", 1 };
78 cvar_t Config_joystick_max = { "JoystickMax", "0,0,0,0", 1 };
79 cvar_t Config_joystick_cen = { "JoystickCen", "0,0,0,0", 1 };
80 cvar_t config_last_player = { "LastPlayer", "", 1 };
81 cvar_t config_last_mission = { "LastMission", "", 1 };
82 cvar_t Config_vr_type = { "VR_type", "0", 1 };
83 cvar_t Config_vr_resolution = { "VR_resolution", "0", 1 };
84 cvar_t Config_vr_tracking = { "VR_tracking", "0", 1 };
87 #define _CRYSTAL_LAKE_8_ST 0xe201
88 #define _CRYSTAL_LAKE_16_ST 0xe202
89 #define _AWE32_8_ST 0xe208
90 #define _AWE32_16_ST 0xe209
93 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
95 void set_custom_detail_vars(void);
101 void CrystalLakeWriteMCP( ushort mc_addr, ubyte mc_data )
104 outp( CL_MC0, 0xE2 ); // Write password
105 outp( mc_addr, mc_data ); // Write data
109 ubyte CrystalLakeReadMCP( ushort mc_addr )
113 outp( CL_MC0, 0xE2 ); // Write password
114 value = inp( mc_addr ); // Read data
119 void CrystalLakeSetSB()
122 tmp = CrystalLakeReadMCP( CL_MC1 );
124 CrystalLakeWriteMCP( CL_MC1, tmp );
127 void CrystalLakeSetWSS()
130 tmp = CrystalLakeReadMCP( CL_MC1 );
132 CrystalLakeWriteMCP( CL_MC1, tmp );
135 //MovieHires might be changed by -nohighres, so save a "real" copy of it
137 int save_redbook_enabled;
140 void CheckMovieAttributes()
143 DWORD len, type, val;
146 lres = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Parallax\\Descent II\\1.1\\INSTALL",
148 if (lres == ERROR_SUCCESS) {
150 lres = RegQueryValueEx(hKey, "HIRES", NULL, &type, &val, &len);
151 if (lres == ERROR_SUCCESS) {
152 cvar_setint( &MovieHires, val );
153 logentry("HIRES=%d\n", val);
161 static int config_initialized;
163 static void config_init(void)
165 /* make sure our cvars are registered */
166 cvar_registervariable(&Config_digi_volume);
167 cvar_registervariable(&Config_midi_volume);
168 cvar_registervariable(&Redbook_enabled);
169 cvar_registervariable(&Config_redbook_volume);
170 cvar_registervariable(&Config_channels_reversed);
171 cvar_registervariable(&Config_gamma_level);
172 cvar_registervariable(&Config_detail_level);
173 cvar_registervariable(&Config_control_type);
174 cvar_registervariable(&Config_joystick_sensitivity);
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);
184 cvar_registervariable(&real_guidebot_name);
186 config_initialized = 1;
190 void LoadConfigDefaults(void)
192 cmd_append("bind UP +lookdown; bind PAD8 +lookdown");
193 cmd_append("bind DOWN +lookup; bind PAD2 +lookup");
194 cmd_append("bind LEFT +left; bind PAD4 +left");
195 cmd_append("bind RIGHT +right; bind PAD6 +right");
197 cmd_append("bind LALT +strafe");
198 cmd_append("bind PAD1 +moveleft");
199 cmd_append("bind PAD3 +moveright");
200 cmd_append("bind PAD- +moveup");
201 cmd_append("bind PAD+ +movedown");
203 cmd_append("bind Q +bankleft; bind PAD7 +bankleft");
204 cmd_append("bind E +bankright; bind PAD9 +bankright");
206 cmd_append("bind , +cycle");
207 cmd_append("bind . +cycle2");
209 cmd_append("bind LCTRL +attack; bind RCTRL +attack");
210 cmd_append("bind SPC +attack2");
211 cmd_append("bind F +flare");
212 cmd_append("bind B +bomb");
214 cmd_append("bind R +rearview");
215 cmd_append("bind TAB +automap");
217 cmd_append("bind A +forward");
218 cmd_append("bind Z +back");
219 cmd_append("bind S +afterburner");
221 cmd_append("bind H +headlight");
222 cmd_append("bind T +nrgshield");
224 cmd_append("bind J1B1 +attack");
225 cmd_append("bind J1B2 +attack2");
227 cmd_append("bind MB1 +attack");
228 cmd_append("bind MB2 +attack2");
230 cmd_append("bind 1 weapon 1");
231 cmd_append("bind 2 weapon 2");
232 cmd_append("bind 3 weapon 3");
233 cmd_append("bind 4 weapon 4");
234 cmd_append("bind 5 weapon 5");
235 cmd_append("bind 6 weapon 6");
236 cmd_append("bind 7 weapon 7");
237 cmd_append("bind 8 weapon 8");
238 cmd_append("bind 9 weapon 9");
239 cmd_append("bind 0 weapon 0");
246 int joy_axis_center[7];
250 if (!config_initialized)
253 cvar_set_cvar( &config_last_player, "" );
255 joy_axis_min[0] = joy_axis_min[1] = joy_axis_min[2] = joy_axis_min[3] = 0;
256 joy_axis_max[0] = joy_axis_max[1] = joy_axis_max[2] = joy_axis_max[3] = 0;
257 joy_axis_center[0] = joy_axis_center[1] = joy_axis_center[2] = joy_axis_center[3] = 0;
259 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
262 cvar_setint(&digi_driver_board, 0);
263 cvar_setint(&digi_driver_port, 0);
264 cvar_setint(&digi_driver_irq, 0);
265 cvar_setint(&digi_driver_dma, 0);
266 cvar_setint(&digi_midi_type, 0);
267 cvar_setint(&digi_midi_port, 0);
270 cvar_setint( &Config_digi_volume, 8 );
271 cvar_setint( &Config_midi_volume, 8 );
272 cvar_setint( &Config_redbook_volume, 8 );
273 cvar_setint( &Config_control_type, CONTROL_NONE );
274 cvar_setint( &Config_channels_reversed, 0);
275 cvar_setint( &Config_joystick_sensitivity, 8 );
277 //set these here in case no cfg file
278 SaveMovieHires = MovieHires.intval;
279 save_redbook_enabled = Redbook_enabled.intval;
281 if (cfexist("descent.cfg"))
282 cmd_append("exec descent.cfg");
284 LoadConfigDefaults();
288 /* TODO: allow cvars to define a callback that will carry out these initialization things on change. */
290 gr_palette_set_gamma( Config_gamma_level.intval );
292 Detail_level = strtol(Config_detail_level.string, NULL, 10);
293 if (Detail_level == NUM_DETAIL_LEVELS - 1) {
294 int count,dummy,oc,od,wd,wrd,da,sc;
296 count = sscanf (Config_detail_level.string, "%d,%d,%d,%d,%d,%d,%d\n",&dummy,&oc,&od,&wd,&wrd,&da,&sc);
299 Object_complexity = oc;
302 Wall_render_depth = wrd;
305 set_custom_detail_vars();
309 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] );
310 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] );
311 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] );
313 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
315 i = FindArg( "-volume" );
318 i = atoi( Args[i+1] );
320 if ( i > 100 ) i = 100;
321 cvar_setint( &Config_digi_volume, (i * 8) / 100 );
322 cvar_setint( &Config_midi_volume, (i * 8) / 100 );
323 cvar_setint( &Config_redbook_volume, (i * 8) / 100 );
326 if ( Config_digi_volume.intval > 8 ) cvar_setint( &Config_digi_volume, 8 );
327 if ( Config_midi_volume.intval > 8 ) cvar_setint( &Config_midi_volume, 8 );
328 if ( Config_redbook_volume.intval > 8 ) cvar_setint( &Config_redbook_volume, 8 );
330 digi_set_volume( (Config_digi_volume.intval * 32768) / 8, (Config_midi_volume.intval * 128) / 8 );
334 strncpy(guidebot_name, real_guidebot_name.string, GUIDEBOT_NAME_LEN);
335 guidebot_name[GUIDEBOT_NAME_LEN] = 0;
338 printf( "DigiDeviceID: 0x%x\n", digi_driver_board );
339 printf( "DigiPort: 0x%x\n", digi_driver_port.intval );
340 printf( "DigiIrq: 0x%x\n", digi_driver_irq.intval );
341 printf( "DigiDma: 0x%x\n", digi_driver_dma.intval );
342 printf( "MidiDeviceID: 0x%x\n", digi_midi_type.intval );
343 printf( "MidiPort: 0x%x\n", digi_midi_port.intval );
346 cvar_setint( &Config_midi_type, digi_midi_type );
347 cvar_setint( &Config_digi_type, digi_driver_board );
348 cvar_setint( &Config_digi_dma, digi_driver_dma );
352 if (digi_driver_board_16.intval > 0 && !FindArg("-no16bit") && digi_driver_board_16.intval != _GUS_16_ST) {
353 digi_driver_board = digi_driver_board_16.intval;
354 digi_driver_dma = digi_driver_dma_16.intval;
358 //Hack to make some cards look like others, such as
359 //the Crytal Lake look like Microsoft Sound System
360 if ( digi_driver_board == _CRYSTAL_LAKE_8_ST ) {
362 tmp = CrystalLakeReadMCP( CL_MC1 );
364 atexit( CrystalLakeSetSB ); // Restore to SB when done.
366 digi_driver_board = _MICROSOFT_8_ST;
367 } else if ( digi_driver_board == _CRYSTAL_LAKE_16_ST ) {
369 tmp = CrystalLakeReadMCP( CL_MC1 );
371 atexit( CrystalLakeSetSB ); // Restore to SB when done.
373 digi_driver_board = _MICROSOFT_16_ST;
374 } else if ( digi_driver_board == _AWE32_8_ST ) {
375 digi_driver_board = _SB16_8_ST;
376 } else if ( digi_driver_board == _AWE32_16_ST ) {
377 digi_driver_board = _SB16_16_ST;
379 digi_driver_board = digi_driver_board;
382 if (cfexist("descentw.cfg")) {
383 cmd_append("exec descentw.cfg");
386 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] );
387 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] );
388 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] );
395 int WriteConfigFile()
397 PHYSFS_file *outfile;
399 int joy_axis_center[7];
402 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
404 if (FindArg("-noredbook"))
405 cvar_setint( &Redbook_enabled, save_redbook_enabled );
407 cvar_setint( &Config_gamma_level, gr_palette_get_gamma() );
409 if (Detail_level == NUM_DETAIL_LEVELS-1)
410 cvar_set_cvarf( &Config_detail_level, "%d,%d,%d,%d,%d,%d,%d", Detail_level,
411 Object_complexity,Object_detail,Wall_detail,Wall_render_depth,Debris_amount,SoundChannels );
413 cvar_setint( &Config_detail_level, Detail_level );
415 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] );
416 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] );
417 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] );
419 cvar_set_cvar( &config_last_player, Players[Player_num].callsign );
421 cvar_setint( &MovieHires, SaveMovieHires );
423 outfile = PHYSFSX_openWriteBuffered("descent.cfg");
427 key_write_bindings(outfile);
428 PHYSFS_close(outfile);
430 if (FindArg("-nohires") || FindArg("-nohighres") || FindArg("-lowresmovies"))
431 cvar_setint( &MovieHires, 0 );
434 CheckMovieAttributes();
440 #else // !defined(MACINTOSH)
449 #include <GestaltEqu.h>
451 #include <Processes.h>
452 #include <Resources.h>
465 #include "prefs.h" // prefs file for configuration stuff -- from DeSalvo
467 #define MAX_CTB_LEN 512
469 typedef struct preferences {
472 ubyte stereo_reverse;
474 ubyte oc; // object complexity
475 ubyte od; // object detail
476 ubyte wd; // wall detail
477 ubyte wrd; // wall render depth
478 ubyte da; // debris amount
479 ubyte sc; // sound channels
484 int joy_axis_center[4];
485 char lastplayer[CALLSIGN_LEN+1];
486 char lastmission[MISSION_NAME_LEN+1];
487 char ctb_config[MAX_CTB_LEN];
490 ubyte display_dialog;
491 ubyte change_resolution;
497 ubyte redbook_volume;
499 ubyte enable_input_sprockets;
502 char config_last_player[CALLSIGN_LEN+1] = "";
503 char config_last_mission[MISSION_NAME_LEN+1] = "";
504 char config_last_ctb_cfg[MAX_CTB_LEN] = "";
505 int config_last_ctb_tool;
506 ubyte Config_master_volume = 4;
507 ubyte Config_digi_volume = 8;
508 ubyte Config_midi_volume = 8;
509 ubyte Config_redbook_volume = 8;
510 ubyte Config_control_type = 0;
511 ubyte Config_channels_reversed = 0;
512 ubyte Config_joystick_sensitivity = 8;
514 int Config_vr_type = 0;
515 int Config_vr_resolution = 0;
516 int Config_vr_tracking = 0;
518 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
519 extern void digi_set_master_volume( int volume );
521 void set_custom_detail_vars(void);
523 static ubyte have_prefs = 0;
525 //¥ ------------------------------ Private Definitions
526 //¥ ------------------------------ Private Types
535 } PrefsInfo, *PrefsInfoPtr, **PrefsInfoHandle;
537 //¥ ------------------------------ Private Variables
539 static PrefsInfo prefsInfo;
540 static Boolean prefsInited = 0;
542 //¥ ------------------------------ Private Functions
544 static void Pstrcpy(StringPtr dst, StringPtr src);
545 static void Pstrcat(StringPtr dst, StringPtr src);
546 static Boolean FindPrefsFile(short *prefVRefNum, long *prefDirID);
548 //¥ -------------------- Pstrcpy
551 Pstrcpy(StringPtr dst, StringPtr src)
553 BlockMove(src, dst, (*src) + 1);
556 //¥ -------------------- Pstrcat
559 Pstrcat(StringPtr dst, StringPtr src)
561 BlockMove(src + 1, dst + (*dst) + 1, *src);
565 //¥ -------------------- FindPrefsFile
568 FindPrefsFile(short *prefVRefNum, long *prefDirID)
577 theErr = Gestalt(gestaltFindFolderAttr, &response);
578 if (theErr == noErr && ((response >> gestaltFindFolderPresent) & 1))
580 //¥ Find (or make) it the easy way...
581 theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, prefVRefNum, prefDirID);
586 StringPtr prefFolderName = "\pPreferences";
588 //¥ yeachh -- we have to do it all by hand!
589 theErr = SysEnvirons(1, &theSysEnv);
593 *prefVRefNum = theSysEnv.sysVRefNum;
595 //¥ Check whether Preferences folder already exists
596 infoPB.hFileInfo.ioCompletion = 0;
597 infoPB.hFileInfo.ioNamePtr = prefFolderName;
598 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
599 infoPB.hFileInfo.ioFDirIndex = 0;
600 infoPB.hFileInfo.ioDirID = 0;
602 theErr = PBGetCatInfo(&infoPB, 0);
605 *prefDirID = infoPB.hFileInfo.ioDirID;
607 else if (theErr == fnfErr) //¥ Preferences doesn't already exist
609 HParamBlockRec dirPB;
611 //¥ Create "Preferences" folder
612 dirPB.fileParam.ioCompletion = 0;
613 dirPB.fileParam.ioVRefNum = *prefVRefNum;
614 dirPB.fileParam.ioNamePtr = prefFolderName;
615 dirPB.fileParam.ioDirID = 0;
617 theErr = PBDirCreate(&dirPB, 0);
619 *prefDirID = dirPB.fileParam.ioDirID;
623 //¥ If we make it here OK, create Preferences file if necessary
626 infoPB.hFileInfo.ioCompletion = 0;
627 infoPB.hFileInfo.ioNamePtr = prefsInfo.fileName;
628 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
629 infoPB.hFileInfo.ioFDirIndex = 0;
630 infoPB.hFileInfo.ioDirID = *prefDirID;
632 theErr = PBGetCatInfo(&infoPB, 0);
633 if (theErr == fnfErr)
635 theErr = HCreate(*prefVRefNum, *prefDirID, prefsInfo.fileName, prefsInfo.creator, prefsInfo.fileType);
638 HCreateResFile(*prefVRefNum, *prefDirID, prefsInfo.fileName);
644 return (theErr == noErr);
647 //¥ -------------------- InitPrefsFile
649 #define UNKNOWN_TYPE 0x3f3f3f3f
652 InitPrefsFile(OSType creator)
655 PrefsInfoHandle piHdl;
657 if ((piHdl = (PrefsInfoHandle) GetResource('PRFI', 0)) == nil)
659 ProcessSerialNumber thePSN;
660 ProcessInfoRec thePIR;
662 StringPtr app_string;
665 GetCurrentProcess(&thePSN);
666 thePIR.processName = nil;
667 thePIR.processAppSpec = &appSpec;
669 //¥ Set default to 'ÇApplicationÈ Prefs', PREF 0
670 err = GetProcessInformation(&thePSN, &thePIR);
674 app_string = LMGetCurApName();
675 // Pstrcpy(prefsInfo.fileName, appSpec.name);
676 Pstrcpy(prefsInfo.fileName, app_string);
677 Pstrcat(prefsInfo.fileName, "\p Preferences");
679 //¥ Set creator to calling application's signature (should be able to
680 //¥ Determine this automatically, but unable to for some reason)
681 prefsInfo.creator = creator;
682 prefsInfo.fileType = 'pref';
683 prefsInfo.resType = 'pref';
688 //¥ Get Preferences file setup from PRFI 0
689 BlockMove(*piHdl, &prefsInfo, sizeof (prefsInfo));
690 ReleaseResource((Handle) piHdl);
692 if (prefsInfo.creator == UNKNOWN_TYPE)
693 prefsInfo.creator = creator;
699 //¥ -------------------- LoadPrefsFile
702 LoadPrefsFile(Handle prefsHdl)
704 short prefVRefNum, prefRefNum;
706 OSErr theErr = noErr;
708 Size prefSize, origSize;
711 return (nilHandleErr);
713 prefSize = GetHandleSize(prefsHdl);
715 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
718 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
719 if (prefRefNum == -1)
722 //¥ Not finding the resource is not an error -- caller will use default data
723 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
725 origSize = GetHandleSize(origHdl);
726 if (origSize > prefSize) //¥ Extend handle for extra stored data
727 SetHandleSize(prefsHdl, origSize);
729 BlockMove(*origHdl, *prefsHdl, origSize);
730 ReleaseResource(origHdl);
733 CloseResFile(prefRefNum);
741 //¥ -------------------- SavePrefsFile
744 SavePrefsFile(Handle prefHdl)
746 short prefVRefNum, prefRefNum;
748 Handle origHdl = nil;
749 Size origSize, prefSize;
750 OSErr theErr = noErr;
752 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
756 return (nilHandleErr);
758 prefSize = GetHandleSize(prefHdl);
760 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
761 if (prefRefNum == -1)
764 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
766 //¥ Overwrite existing preferences
767 origSize = GetHandleSize(origHdl);
768 if (prefSize > origSize)
769 SetHandleSize(origHdl, prefSize);
771 BlockMove(*prefHdl, *origHdl, prefSize);
772 ChangedResource(origHdl);
773 WriteResource(origHdl);
774 ReleaseResource(origHdl);
778 //¥ Store specified preferences for the first time
779 AddResource(prefHdl, prefsInfo.resType, prefsInfo.resID, "\p");
780 WriteResource(prefHdl);
781 DetachResource(prefHdl);
784 CloseResFile(prefRefNum);
792 //¥ -------------------------------------------------------------------------------------------
796 This module provides the ability to save and load a preferences file in the
797 Preferences folder in the System Folder. An optional resource, PRFI 0,
798 is used to provide specifications for the preferences file (creator, etc.).
800 Three functions are provided:
802 void InitPrefsFile(OSType creator)
804 This function will initialize the preferences file, that is, it will create
805 it in the appropriate place if it doesn't currently exist. It should be
806 called with the creator code for the application. Note that the creator
807 code specified in PRFI 0 (if any) will be used only if the creator code
808 passed to this function is '????'. Without the PRFI 0 resource, the default
811 File Name: "{Application} Prefs" (i.e., the name of the app plus " Prefs"
812 Creator: the creator passed to InitPrefsFile
814 Pref Resource Type: 'PREF'
817 The PRFI 0 resource allows you to specify overrides for each of the above
818 values. This is useful for development, since the application name might
819 go through changes, but the preferences file name is held constant.
821 OSErr LoadPrefsFile(Handle prefsHndl)
823 This function will attempt to copy the data stored in the preferences
824 file to the given handle (which must be pre-allocated). If the handle is too
825 small, then it will be enlarged. If it is too large, it will not be resized.
826 The data in the preferences file (normally in PREF 0) will then be copied
827 into the handle. If the preferences file did not exist, the original data
828 in the handle will not change.
830 OSErr SavePrefsFile(Handle prefsHndl)
832 This function will attempt to save the given handle to the preferences
833 file. Its contents will completely replace the previous data (normally
834 the PREF 0 resource).
836 In typical use, you will use InitPrefsFile once, then allocate a handle large
837 enough to contain your preferences data, and initialize it with default values.
838 Throughout the course of your program, the handle will undergo modification as
839 user preferences change. You can use SavePrefsFile anytime to update the
840 preferences file, or wait until program exit to do so.
852 if (!have_prefs) { // not initialized....get a handle to the preferences file
853 InitPrefsFile('DCT2');
857 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
858 if (prefs_handle == NULL)
861 prefs = (Preferences *)(*prefs_handle);
862 err = LoadPrefsFile(prefs_handle);
864 DisposeHandle(prefs_handle);
869 for (i = 0; i < sizeof(Preferences); i++) {
874 if ( i == sizeof(Preferences) )
877 Config_digi_volume = prefs->digi_volume;
878 Config_midi_volume = prefs->midi_volume;
879 Config_master_volume = prefs->master_volume;
880 Config_redbook_volume = prefs->redbook_volume;
881 Config_channels_reversed = prefs->stereo_reverse;
882 gr_palette_set_gamma( (int)(prefs->gamma_level) );
884 Scanline_double = (int)prefs->pixel_double;
886 Scanline_double = 0; // can't double with hardware acceleration
888 Detail_level = prefs->detail_level;
889 if (Detail_level == NUM_DETAIL_LEVELS-1) {
890 Object_complexity = prefs->oc;
891 Object_detail = prefs->od;
892 Wall_detail = prefs->wd;
893 Wall_render_depth = prefs->wrd;
894 Debris_amount = prefs->da;
895 SoundChannels = prefs->sc;
896 set_custom_detail_vars();
899 strncpy( config_last_player, prefs->lastplayer, CALLSIGN_LEN );
900 p = strchr(config_last_player, '\n' );
903 strncpy(config_last_mission, prefs->lastmission, MISSION_NAME_LEN);
904 p = strchr(config_last_mission, '\n' );
907 strcpy(config_last_ctb_cfg, prefs->ctb_config);
909 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
911 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
913 joy_set_cal_vals( prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
914 digi_set_volume( (Config_digi_volume*256)/8, (Config_midi_volume*256)/8 );
915 digi_set_master_volume(Config_master_volume);
917 gConfigInfo.mDoNotDisplayOptions = prefs->display_dialog;
918 gConfigInfo.mUse11kSounds = prefs->sound_11k;
919 gConfigInfo.mDisableSound = prefs->nosound;
920 gConfigInfo.mDisableMIDIMusic = prefs->nomidi;
921 gConfigInfo.mChangeResolution = prefs->change_resolution;
922 gConfigInfo.mDoNotPlayMovies = prefs->no_movies;
923 gConfigInfo.mGameMonitor = prefs->game_monitor;
924 gConfigInfo.mAcceleration = prefs->enable_rave;
925 gConfigInfo.mInputSprockets = prefs->enable_input_sprockets;
927 DisposeHandle(prefs_handle);
931 int WriteConfigFile()
937 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
938 if (prefs_handle == NULL)
941 prefs = (Preferences *)(*prefs_handle);
943 joy_get_cal_vals(prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
944 prefs->digi_volume = Config_digi_volume;
945 prefs->midi_volume = Config_midi_volume;
946 prefs->stereo_reverse = Config_channels_reversed;
947 prefs->detail_level = Detail_level;
948 if (Detail_level == NUM_DETAIL_LEVELS-1) {
949 prefs->oc = Object_complexity;
950 prefs->od = Object_detail;
951 prefs->wd = Wall_detail;
952 prefs->wrd = Wall_render_depth;
953 prefs->da = Debris_amount;
954 prefs->sc = SoundChannels;
956 prefs->gamma_level = (ubyte)gr_palette_get_gamma();
959 prefs->pixel_double = (ubyte)Scanline_double; // hmm..don't write this out if doing hardware accel.
961 strncpy( prefs->lastplayer, Players[Player_num].callsign, CALLSIGN_LEN );
962 strncpy( prefs->lastmission, config_last_mission, MISSION_NAME_LEN );
963 strcpy( prefs->ctb_config, config_last_ctb_cfg);
964 prefs->ctb_tool = config_last_ctb_tool;
965 prefs->master_volume = Config_master_volume;
966 prefs->display_dialog = gConfigInfo.mDoNotDisplayOptions;
967 prefs->change_resolution = gConfigInfo.mChangeResolution;
968 prefs->nosound = gConfigInfo.mDisableSound;
969 prefs->nomidi = gConfigInfo.mDisableMIDIMusic;
970 prefs->sound_11k = gConfigInfo.mUse11kSounds;
971 prefs->no_movies = gConfigInfo.mDoNotPlayMovies;
972 prefs->game_monitor = gConfigInfo.mGameMonitor;
973 prefs->redbook_volume = Config_redbook_volume;
974 prefs->enable_rave = gConfigInfo.mAcceleration;
975 prefs->enable_input_sprockets = gConfigInfo.mInputSprockets;
977 err = SavePrefsFile(prefs_handle);
978 DisposeHandle(prefs_handle);