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;
198 void LoadConfigDefaults(void)
200 cmd_append("bind UP +lookdown; bind PAD8 +lookdown");
201 cmd_append("bind DOWN +lookup; bind PAD2 +lookup");
202 cmd_append("bind LEFT +left; bind PAD4 +left");
203 cmd_append("bind RIGHT +right; bind PAD6 +right");
205 cmd_append("bind LALT +strafe");
206 cmd_append("bind PAD1 +moveleft");
207 cmd_append("bind PAD3 +moveright");
208 cmd_append("bind PAD- +moveup");
209 cmd_append("bind PAD+ +movedown");
211 cmd_append("bind Q +bankleft; bind PAD7 +bankleft");
212 cmd_append("bind E +bankright; bind PAD9 +bankright");
214 cmd_append("bind , +cycle");
215 cmd_append("bind . +cycle2");
217 cmd_append("bind LCTRL +attack; bind RCTRL +attack");
218 cmd_append("bind SPC +attack2");
219 cmd_append("bind F +flare");
220 cmd_append("bind B +bomb");
222 cmd_append("bind R +rearview");
223 cmd_append("bind TAB +automap");
225 cmd_append("bind A +forward");
226 cmd_append("bind Z +back");
227 cmd_append("bind S +afterburner");
229 cmd_append("bind H +headlight");
230 cmd_append("bind T +nrgshield");
237 int joy_axis_center[7];
241 if (!config_initialized)
244 cvar_set_cvar( &config_last_player, "" );
246 joy_axis_min[0] = joy_axis_min[1] = joy_axis_min[2] = joy_axis_min[3] = 0;
247 joy_axis_max[0] = joy_axis_max[1] = joy_axis_max[2] = joy_axis_max[3] = 0;
248 joy_axis_center[0] = joy_axis_center[1] = joy_axis_center[2] = joy_axis_center[3] = 0;
251 memset(&joy_axis_min[0], 0, sizeof(int)*7);
252 memset(&joy_axis_max[0], 0, sizeof(int)*7);
253 memset(&joy_axis_center[0], 0, sizeof(int)*7);
254 //@@ joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
256 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
260 cvar_setint(&digi_driver_board, 0);
261 cvar_setint(&digi_driver_port, 0);
262 cvar_setint(&digi_driver_irq, 0);
263 cvar_setint(&digi_driver_dma, 0);
264 cvar_setint(&digi_midi_type, 0);
265 cvar_setint(&digi_midi_port, 0);
268 cvar_setint( &Config_digi_volume, 8 );
269 cvar_setint( &Config_midi_volume, 8 );
270 cvar_setint( &Config_redbook_volume, 8 );
271 Config_control_type = 0;
272 cvar_setint( &Config_channels_reversed, 0);
274 //set these here in case no cfg file
275 SaveMovieHires = MovieHires.intval;
276 save_redbook_enabled = Redbook_enabled.intval;
278 if (cfexist("descent.cfg"))
279 cmd_append("exec descent.cfg");
281 LoadConfigDefaults();
285 /* TODO: allow cvars to define a callback that will carry out these initialization things on change. */
287 gr_palette_set_gamma( Config_gamma_level.intval );
289 Detail_level = strtol(Config_detail_level.string, NULL, 10);
290 if (Detail_level == NUM_DETAIL_LEVELS - 1) {
291 int count,dummy,oc,od,wd,wrd,da,sc;
293 count = sscanf (Config_detail_level.string, "%d,%d,%d,%d,%d,%d,%d\n",&dummy,&oc,&od,&wd,&wrd,&da,&sc);
296 Object_complexity = oc;
299 Wall_render_depth = wrd;
302 set_custom_detail_vars();
306 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] );
307 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] );
308 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] );
314 DOSJoySaveMin[i]=joy_axis_min[i];
315 DOSJoySaveCen[i]=joy_axis_center[i];
316 DOSJoySaveMax[i]=joy_axis_max[i];
319 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
322 i = FindArg( "-volume" );
325 i = atoi( Args[i+1] );
327 if ( i > 100 ) i = 100;
328 cvar_setint( &Config_digi_volume, (i * 8) / 100 );
329 cvar_setint( &Config_midi_volume, (i * 8) / 100 );
330 cvar_setint( &Config_redbook_volume, (i * 8) / 100 );
333 if ( Config_digi_volume.intval > 8 ) cvar_setint( &Config_digi_volume, 8 );
334 if ( Config_midi_volume.intval > 8 ) cvar_setint( &Config_midi_volume, 8 );
335 if ( Config_redbook_volume.intval > 8 ) cvar_setint( &Config_redbook_volume, 8 );
337 digi_set_volume( (Config_digi_volume.intval * 32768) / 8, (Config_midi_volume.intval * 128) / 8 );
340 printf( "DigiDeviceID: 0x%x\n", digi_driver_board );
341 printf( "DigiPort: 0x%x\n", digi_driver_port.intval );
342 printf( "DigiIrq: 0x%x\n", digi_driver_irq.intval );
343 printf( "DigiDma: 0x%x\n", digi_driver_dma.intval );
344 printf( "MidiDeviceID: 0x%x\n", digi_midi_type.intval );
345 printf( "MidiPort: 0x%x\n", digi_midi_port.intval );
348 cvar_setint( &Config_midi_type, digi_midi_type );
349 cvar_setint( &Config_digi_type, digi_driver_board );
350 cvar_setint( &Config_digi_dma, digi_driver_dma );
354 if (digi_driver_board_16.intval > 0 && !FindArg("-no16bit") && digi_driver_board_16.intval != _GUS_16_ST) {
355 digi_driver_board = digi_driver_board_16.intval;
356 digi_driver_dma = digi_driver_dma_16.intval;
360 //Hack to make some cards look like others, such as
361 //the Crytal Lake look like Microsoft Sound System
362 if ( digi_driver_board == _CRYSTAL_LAKE_8_ST ) {
364 tmp = CrystalLakeReadMCP( CL_MC1 );
366 atexit( CrystalLakeSetSB ); // Restore to SB when done.
368 digi_driver_board = _MICROSOFT_8_ST;
369 } else if ( digi_driver_board == _CRYSTAL_LAKE_16_ST ) {
371 tmp = CrystalLakeReadMCP( CL_MC1 );
373 atexit( CrystalLakeSetSB ); // Restore to SB when done.
375 digi_driver_board = _MICROSOFT_16_ST;
376 } else if ( digi_driver_board == _AWE32_8_ST ) {
377 digi_driver_board = _SB16_8_ST;
378 } else if ( digi_driver_board == _AWE32_16_ST ) {
379 digi_driver_board = _SB16_16_ST;
381 digi_driver_board = digi_driver_board;
384 if (cfexist("descentw.cfg")) {
385 cmd_append("exec descentw.cfg");
388 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] );
389 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] );
390 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] );
397 int WriteConfigFile()
399 PHYSFS_file *outfile;
401 int joy_axis_center[7];
404 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
409 joy_axis_min[i]=DOSJoySaveMin[i];
410 joy_axis_center[i]=DOSJoySaveCen[i];
411 joy_axis_max[i]=DOSJoySaveMax[i];
415 if (FindArg("-noredbook"))
416 cvar_setint( &Redbook_enabled, save_redbook_enabled );
418 cvar_setint( &Config_gamma_level, gr_palette_get_gamma() );
420 if (Detail_level == NUM_DETAIL_LEVELS-1)
421 cvar_set_cvarf( &Config_detail_level, "%d,%d,%d,%d,%d,%d,%d", Detail_level,
422 Object_complexity,Object_detail,Wall_detail,Wall_render_depth,Debris_amount,SoundChannels );
424 cvar_setint( &Config_detail_level, Detail_level );
426 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] );
427 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] );
428 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] );
430 cvar_set_cvar( &config_last_player, Players[Player_num].callsign );
432 cvar_setint( &MovieHires, SaveMovieHires );
434 outfile = PHYSFSX_openWriteBuffered("descent.cfg");
438 key_write_bindings(outfile);
439 PHYSFS_close(outfile);
441 if (FindArg("-nohires") || FindArg("-nohighres") || FindArg("-lowresmovies"))
442 cvar_setint( &MovieHires, 0 );
446 // Save Windows Config File
450 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
452 outfile = PHYSFSX_openWriteBuffered("descentw.cfg");
453 if (outfile == NULL) return 1;
455 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", Config_joystick_min.name,
456 joy_axis_min[0], joy_axis_min[1], joy_axis_min[2], joy_axis_min[3],
457 joy_axis_min[4], joy_axis_min[5], joy_axis_min[6]);
458 PHYSFSX_puts(outfile, str);
459 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", Config_joystick_cen.name,
460 joy_axis_center[0], joy_axis_center[1], joy_axis_center[2], joy_axis_center[3],
461 joy_axis_center[4], joy_axis_center[5], joy_axis_center[6]);
462 PHYSFSX_puts(outfile, str);
463 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", Config_joystick_max.name,
464 joy_axis_max[0], joy_axis_max[1], joy_axis_max[2], joy_axis_max[3],
465 joy_axis_max[4], joy_axis_max[5], joy_axis_max[6]);
466 PHYSFSX_puts(outfile, str);
470 CheckMovieAttributes();
476 #else // !defined(MACINTOSH)
485 #include <GestaltEqu.h>
487 #include <Processes.h>
488 #include <Resources.h>
501 #include "prefs.h" // prefs file for configuration stuff -- from DeSalvo
503 #define MAX_CTB_LEN 512
505 typedef struct preferences {
508 ubyte stereo_reverse;
510 ubyte oc; // object complexity
511 ubyte od; // object detail
512 ubyte wd; // wall detail
513 ubyte wrd; // wall render depth
514 ubyte da; // debris amount
515 ubyte sc; // sound channels
520 int joy_axis_center[4];
521 char lastplayer[CALLSIGN_LEN+1];
522 char lastmission[MISSION_NAME_LEN+1];
523 char ctb_config[MAX_CTB_LEN];
526 ubyte display_dialog;
527 ubyte change_resolution;
533 ubyte redbook_volume;
535 ubyte enable_input_sprockets;
538 char config_last_player[CALLSIGN_LEN+1] = "";
539 char config_last_mission[MISSION_NAME_LEN+1] = "";
540 char config_last_ctb_cfg[MAX_CTB_LEN] = "";
541 int config_last_ctb_tool;
542 ubyte Config_master_volume = 4;
543 ubyte Config_digi_volume = 8;
544 ubyte Config_midi_volume = 8;
545 ubyte Config_redbook_volume = 8;
546 ubyte Config_control_type = 0;
547 ubyte Config_channels_reversed = 0;
548 ubyte Config_joystick_sensitivity = 8;
550 int Config_vr_type = 0;
551 int Config_vr_resolution = 0;
552 int Config_vr_tracking = 0;
554 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
555 extern void digi_set_master_volume( int volume );
557 void set_custom_detail_vars(void);
559 static ubyte have_prefs = 0;
561 //¥ ------------------------------ Private Definitions
562 //¥ ------------------------------ Private Types
571 } PrefsInfo, *PrefsInfoPtr, **PrefsInfoHandle;
573 //¥ ------------------------------ Private Variables
575 static PrefsInfo prefsInfo;
576 static Boolean prefsInited = 0;
578 //¥ ------------------------------ Private Functions
580 static void Pstrcpy(StringPtr dst, StringPtr src);
581 static void Pstrcat(StringPtr dst, StringPtr src);
582 static Boolean FindPrefsFile(short *prefVRefNum, long *prefDirID);
584 //¥ -------------------- Pstrcpy
587 Pstrcpy(StringPtr dst, StringPtr src)
589 BlockMove(src, dst, (*src) + 1);
592 //¥ -------------------- Pstrcat
595 Pstrcat(StringPtr dst, StringPtr src)
597 BlockMove(src + 1, dst + (*dst) + 1, *src);
601 //¥ -------------------- FindPrefsFile
604 FindPrefsFile(short *prefVRefNum, long *prefDirID)
613 theErr = Gestalt(gestaltFindFolderAttr, &response);
614 if (theErr == noErr && ((response >> gestaltFindFolderPresent) & 1))
616 //¥ Find (or make) it the easy way...
617 theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, prefVRefNum, prefDirID);
622 StringPtr prefFolderName = "\pPreferences";
624 //¥ yeachh -- we have to do it all by hand!
625 theErr = SysEnvirons(1, &theSysEnv);
629 *prefVRefNum = theSysEnv.sysVRefNum;
631 //¥ Check whether Preferences folder already exists
632 infoPB.hFileInfo.ioCompletion = 0;
633 infoPB.hFileInfo.ioNamePtr = prefFolderName;
634 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
635 infoPB.hFileInfo.ioFDirIndex = 0;
636 infoPB.hFileInfo.ioDirID = 0;
638 theErr = PBGetCatInfo(&infoPB, 0);
641 *prefDirID = infoPB.hFileInfo.ioDirID;
643 else if (theErr == fnfErr) //¥ Preferences doesn't already exist
645 HParamBlockRec dirPB;
647 //¥ Create "Preferences" folder
648 dirPB.fileParam.ioCompletion = 0;
649 dirPB.fileParam.ioVRefNum = *prefVRefNum;
650 dirPB.fileParam.ioNamePtr = prefFolderName;
651 dirPB.fileParam.ioDirID = 0;
653 theErr = PBDirCreate(&dirPB, 0);
655 *prefDirID = dirPB.fileParam.ioDirID;
659 //¥ If we make it here OK, create Preferences file if necessary
662 infoPB.hFileInfo.ioCompletion = 0;
663 infoPB.hFileInfo.ioNamePtr = prefsInfo.fileName;
664 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
665 infoPB.hFileInfo.ioFDirIndex = 0;
666 infoPB.hFileInfo.ioDirID = *prefDirID;
668 theErr = PBGetCatInfo(&infoPB, 0);
669 if (theErr == fnfErr)
671 theErr = HCreate(*prefVRefNum, *prefDirID, prefsInfo.fileName, prefsInfo.creator, prefsInfo.fileType);
674 HCreateResFile(*prefVRefNum, *prefDirID, prefsInfo.fileName);
680 return (theErr == noErr);
683 //¥ -------------------- InitPrefsFile
685 #define UNKNOWN_TYPE 0x3f3f3f3f
688 InitPrefsFile(OSType creator)
691 PrefsInfoHandle piHdl;
693 if ((piHdl = (PrefsInfoHandle) GetResource('PRFI', 0)) == nil)
695 ProcessSerialNumber thePSN;
696 ProcessInfoRec thePIR;
698 StringPtr app_string;
701 GetCurrentProcess(&thePSN);
702 thePIR.processName = nil;
703 thePIR.processAppSpec = &appSpec;
705 //¥ Set default to 'ÇApplicationÈ Prefs', PREF 0
706 err = GetProcessInformation(&thePSN, &thePIR);
710 app_string = LMGetCurApName();
711 // Pstrcpy(prefsInfo.fileName, appSpec.name);
712 Pstrcpy(prefsInfo.fileName, app_string);
713 Pstrcat(prefsInfo.fileName, "\p Preferences");
715 //¥ Set creator to calling application's signature (should be able to
716 //¥ Determine this automatically, but unable to for some reason)
717 prefsInfo.creator = creator;
718 prefsInfo.fileType = 'pref';
719 prefsInfo.resType = 'pref';
724 //¥ Get Preferences file setup from PRFI 0
725 BlockMove(*piHdl, &prefsInfo, sizeof (prefsInfo));
726 ReleaseResource((Handle) piHdl);
728 if (prefsInfo.creator == UNKNOWN_TYPE)
729 prefsInfo.creator = creator;
735 //¥ -------------------- LoadPrefsFile
738 LoadPrefsFile(Handle prefsHdl)
740 short prefVRefNum, prefRefNum;
742 OSErr theErr = noErr;
744 Size prefSize, origSize;
747 return (nilHandleErr);
749 prefSize = GetHandleSize(prefsHdl);
751 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
754 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
755 if (prefRefNum == -1)
758 //¥ Not finding the resource is not an error -- caller will use default data
759 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
761 origSize = GetHandleSize(origHdl);
762 if (origSize > prefSize) //¥ Extend handle for extra stored data
763 SetHandleSize(prefsHdl, origSize);
765 BlockMove(*origHdl, *prefsHdl, origSize);
766 ReleaseResource(origHdl);
769 CloseResFile(prefRefNum);
777 //¥ -------------------- SavePrefsFile
780 SavePrefsFile(Handle prefHdl)
782 short prefVRefNum, prefRefNum;
784 Handle origHdl = nil;
785 Size origSize, prefSize;
786 OSErr theErr = noErr;
788 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
792 return (nilHandleErr);
794 prefSize = GetHandleSize(prefHdl);
796 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
797 if (prefRefNum == -1)
800 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
802 //¥ Overwrite existing preferences
803 origSize = GetHandleSize(origHdl);
804 if (prefSize > origSize)
805 SetHandleSize(origHdl, prefSize);
807 BlockMove(*prefHdl, *origHdl, prefSize);
808 ChangedResource(origHdl);
809 WriteResource(origHdl);
810 ReleaseResource(origHdl);
814 //¥ Store specified preferences for the first time
815 AddResource(prefHdl, prefsInfo.resType, prefsInfo.resID, "\p");
816 WriteResource(prefHdl);
817 DetachResource(prefHdl);
820 CloseResFile(prefRefNum);
828 //¥ -------------------------------------------------------------------------------------------
832 This module provides the ability to save and load a preferences file in the
833 Preferences folder in the System Folder. An optional resource, PRFI 0,
834 is used to provide specifications for the preferences file (creator, etc.).
836 Three functions are provided:
838 void InitPrefsFile(OSType creator)
840 This function will initialize the preferences file, that is, it will create
841 it in the appropriate place if it doesn't currently exist. It should be
842 called with the creator code for the application. Note that the creator
843 code specified in PRFI 0 (if any) will be used only if the creator code
844 passed to this function is '????'. Without the PRFI 0 resource, the default
847 File Name: "{Application} Prefs" (i.e., the name of the app plus " Prefs"
848 Creator: the creator passed to InitPrefsFile
850 Pref Resource Type: 'PREF'
853 The PRFI 0 resource allows you to specify overrides for each of the above
854 values. This is useful for development, since the application name might
855 go through changes, but the preferences file name is held constant.
857 OSErr LoadPrefsFile(Handle prefsHndl)
859 This function will attempt to copy the data stored in the preferences
860 file to the given handle (which must be pre-allocated). If the handle is too
861 small, then it will be enlarged. If it is too large, it will not be resized.
862 The data in the preferences file (normally in PREF 0) will then be copied
863 into the handle. If the preferences file did not exist, the original data
864 in the handle will not change.
866 OSErr SavePrefsFile(Handle prefsHndl)
868 This function will attempt to save the given handle to the preferences
869 file. Its contents will completely replace the previous data (normally
870 the PREF 0 resource).
872 In typical use, you will use InitPrefsFile once, then allocate a handle large
873 enough to contain your preferences data, and initialize it with default values.
874 Throughout the course of your program, the handle will undergo modification as
875 user preferences change. You can use SavePrefsFile anytime to update the
876 preferences file, or wait until program exit to do so.
888 if (!have_prefs) { // not initialized....get a handle to the preferences file
889 InitPrefsFile('DCT2');
893 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
894 if (prefs_handle == NULL)
897 prefs = (Preferences *)(*prefs_handle);
898 err = LoadPrefsFile(prefs_handle);
900 DisposeHandle(prefs_handle);
905 for (i = 0; i < sizeof(Preferences); i++) {
910 if ( i == sizeof(Preferences) )
913 Config_digi_volume = prefs->digi_volume;
914 Config_midi_volume = prefs->midi_volume;
915 Config_master_volume = prefs->master_volume;
916 Config_redbook_volume = prefs->redbook_volume;
917 Config_channels_reversed = prefs->stereo_reverse;
918 gr_palette_set_gamma( (int)(prefs->gamma_level) );
920 Scanline_double = (int)prefs->pixel_double;
922 Scanline_double = 0; // can't double with hardware acceleration
924 Detail_level = prefs->detail_level;
925 if (Detail_level == NUM_DETAIL_LEVELS-1) {
926 Object_complexity = prefs->oc;
927 Object_detail = prefs->od;
928 Wall_detail = prefs->wd;
929 Wall_render_depth = prefs->wrd;
930 Debris_amount = prefs->da;
931 SoundChannels = prefs->sc;
932 set_custom_detail_vars();
935 strncpy( config_last_player, prefs->lastplayer, CALLSIGN_LEN );
936 p = strchr(config_last_player, '\n' );
939 strncpy(config_last_mission, prefs->lastmission, MISSION_NAME_LEN);
940 p = strchr(config_last_mission, '\n' );
943 strcpy(config_last_ctb_cfg, prefs->ctb_config);
945 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
947 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
949 joy_set_cal_vals( prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
950 digi_set_volume( (Config_digi_volume*256)/8, (Config_midi_volume*256)/8 );
951 digi_set_master_volume(Config_master_volume);
953 gConfigInfo.mDoNotDisplayOptions = prefs->display_dialog;
954 gConfigInfo.mUse11kSounds = prefs->sound_11k;
955 gConfigInfo.mDisableSound = prefs->nosound;
956 gConfigInfo.mDisableMIDIMusic = prefs->nomidi;
957 gConfigInfo.mChangeResolution = prefs->change_resolution;
958 gConfigInfo.mDoNotPlayMovies = prefs->no_movies;
959 gConfigInfo.mGameMonitor = prefs->game_monitor;
960 gConfigInfo.mAcceleration = prefs->enable_rave;
961 gConfigInfo.mInputSprockets = prefs->enable_input_sprockets;
963 DisposeHandle(prefs_handle);
967 int WriteConfigFile()
973 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
974 if (prefs_handle == NULL)
977 prefs = (Preferences *)(*prefs_handle);
979 joy_get_cal_vals(prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
980 prefs->digi_volume = Config_digi_volume;
981 prefs->midi_volume = Config_midi_volume;
982 prefs->stereo_reverse = Config_channels_reversed;
983 prefs->detail_level = Detail_level;
984 if (Detail_level == NUM_DETAIL_LEVELS-1) {
985 prefs->oc = Object_complexity;
986 prefs->od = Object_detail;
987 prefs->wd = Wall_detail;
988 prefs->wrd = Wall_render_depth;
989 prefs->da = Debris_amount;
990 prefs->sc = SoundChannels;
992 prefs->gamma_level = (ubyte)gr_palette_get_gamma();
995 prefs->pixel_double = (ubyte)Scanline_double; // hmm..don't write this out if doing hardware accel.
997 strncpy( prefs->lastplayer, Players[Player_num].callsign, CALLSIGN_LEN );
998 strncpy( prefs->lastmission, config_last_mission, MISSION_NAME_LEN );
999 strcpy( prefs->ctb_config, config_last_ctb_cfg);
1000 prefs->ctb_tool = config_last_ctb_tool;
1001 prefs->master_volume = Config_master_volume;
1002 prefs->display_dialog = gConfigInfo.mDoNotDisplayOptions;
1003 prefs->change_resolution = gConfigInfo.mChangeResolution;
1004 prefs->nosound = gConfigInfo.mDisableSound;
1005 prefs->nomidi = gConfigInfo.mDisableMIDIMusic;
1006 prefs->sound_11k = gConfigInfo.mUse11kSounds;
1007 prefs->no_movies = gConfigInfo.mDoNotPlayMovies;
1008 prefs->game_monitor = gConfigInfo.mGameMonitor;
1009 prefs->redbook_volume = Config_redbook_volume;
1010 prefs->enable_rave = gConfigInfo.mAcceleration;
1011 prefs->enable_input_sprockets = gConfigInfo.mInputSprockets;
1013 err = SavePrefsFile(prefs_handle);
1014 DisposeHandle(prefs_handle);