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
61 cvar_t Config_digi_type = { "DigiDeviceID8", "0", 1 };
62 cvar_t digi_driver_board_16 = { "DigiDeviceID16", "0", 1 };
63 //cvar_t digi_driver_port = { "DigiPort", "0", 1 };
64 //cvar_t digi_driver_irq = { "DigiIrq", "0", 1 };
65 cvar_t Config_digi_dma = { "DigiDma8", "0", 1 };
66 cvar_t digi_driver_dma_16 = { "DigiDma16", "0", 1 };
67 cvar_t Config_midi_type = { "MidiDeviceID", "0", 1 };
68 //cvar_t digi_midi_port = { "MidiPort", "0", 1 };
70 cvar_t Config_digi_volume = { "DigiVolume", "8", 1 };
71 cvar_t Config_midi_volume = { "MidiVolume", "8", 1 };
72 cvar_t Config_redbook_volume = { "RedbookVolume", "8", 1 };
73 cvar_t Config_detail_level = { "DetailLevel", "4", 1 };
74 cvar_t Config_gamma_level = { "GammaLevel", "0", 1 };
75 cvar_t Config_control_type = { "ControlType", "0", 1 };
76 cvar_t Config_channels_reversed = { "StereoReverse", "0", 1 };
77 cvar_t Config_joystick_sensitivity = { "JoystickSensitivity", "8", 1 };
78 cvar_t Config_joystick_min = { "JoystickMin", "0,0,0,0", 1 };
79 cvar_t Config_joystick_max = { "JoystickMax", "0,0,0,0", 1 };
80 cvar_t Config_joystick_cen = { "JoystickCen", "0,0,0,0", 1 };
81 cvar_t config_last_player = { "LastPlayer", "", 1 };
82 cvar_t config_last_mission = { "LastMission", "", 1 };
83 cvar_t Config_vr_type = { "VR_type", "0", 1 };
84 cvar_t Config_vr_resolution = { "VR_resolution", "0", 1 };
85 cvar_t Config_vr_tracking = { "VR_tracking", "0", 1 };
86 cvar_t Config_primary_order = { "PrimaryOrder", "", 1 };
87 cvar_t Config_secondary_order = { "SecondaryOrder", "", 1 };
88 cvar_t Config_lifetime_kills = { "LifetimeKills", "0", 1 };
89 cvar_t Config_lifetime_killed = { "LifetimeKilled", "0", 1 };
90 cvar_t Config_lifetime_checksum = { "LifetimeChecksum", "0", 1 };
93 #define _CRYSTAL_LAKE_8_ST 0xe201
94 #define _CRYSTAL_LAKE_16_ST 0xe202
95 #define _AWE32_8_ST 0xe208
96 #define _AWE32_16_ST 0xe209
99 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
101 void set_custom_detail_vars(void);
102 int get_lifetime_checksum(int a, int b);
108 void CrystalLakeWriteMCP( ushort mc_addr, ubyte mc_data )
111 outp( CL_MC0, 0xE2 ); // Write password
112 outp( mc_addr, mc_data ); // Write data
116 ubyte CrystalLakeReadMCP( ushort mc_addr )
120 outp( CL_MC0, 0xE2 ); // Write password
121 value = inp( mc_addr ); // Read data
126 void CrystalLakeSetSB()
129 tmp = CrystalLakeReadMCP( CL_MC1 );
131 CrystalLakeWriteMCP( CL_MC1, tmp );
134 void CrystalLakeSetWSS()
137 tmp = CrystalLakeReadMCP( CL_MC1 );
139 CrystalLakeWriteMCP( CL_MC1, tmp );
142 //MovieHires might be changed by -nohighres, so save a "real" copy of it
144 int save_redbook_enabled;
147 void CheckMovieAttributes()
150 DWORD len, type, val;
153 lres = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Parallax\\Descent II\\1.1\\INSTALL",
155 if (lres == ERROR_SUCCESS) {
157 lres = RegQueryValueEx(hKey, "HIRES", NULL, &type, &val, &len);
158 if (lres == ERROR_SUCCESS) {
159 cvar_setint( &MovieHires, val );
160 logentry("HIRES=%d\n", val);
168 static int config_initialized;
170 static void config_init(void)
172 /* make sure our cvars are registered */
173 cvar_registervariable(&Config_digi_volume);
174 cvar_registervariable(&Config_midi_volume);
175 cvar_registervariable(&Redbook_enabled);
176 cvar_registervariable(&Config_redbook_volume);
177 cvar_registervariable(&Config_channels_reversed);
178 cvar_registervariable(&Config_gamma_level);
179 cvar_registervariable(&Config_detail_level);
180 cvar_registervariable(&Config_control_type);
181 cvar_registervariable(&Config_joystick_sensitivity);
182 cvar_registervariable(&Config_joystick_min);
183 cvar_registervariable(&Config_joystick_cen);
184 cvar_registervariable(&Config_joystick_max);
185 cvar_registervariable(&config_last_player);
186 cvar_registervariable(&config_last_mission);
187 cvar_registervariable(&Config_vr_type);
188 cvar_registervariable(&Config_vr_resolution);
189 cvar_registervariable(&Config_vr_tracking);
190 cvar_registervariable(&MovieHires);
191 cvar_registervariable(&real_guidebot_name);
192 cvar_registervariable(&Config_primary_order);
193 cvar_registervariable(&Config_secondary_order);
194 cvar_registervariable(&Cockpit_3d_view[0]);
195 cvar_registervariable(&Cockpit_3d_view[1]);
196 cvar_registervariable(&Config_lifetime_kills);
197 cvar_registervariable(&Config_lifetime_killed);
198 cvar_registervariable(&Config_lifetime_checksum);
200 config_initialized = 1;
204 void LoadConfigDefaults(void)
206 cmd_append("bind UP +lookdown; bind PAD8 +lookdown");
207 cmd_append("bind DOWN +lookup; bind PAD2 +lookup");
208 cmd_append("bind LEFT +left; bind PAD4 +left");
209 cmd_append("bind RIGHT +right; bind PAD6 +right");
211 cmd_append("bind LALT +strafe");
212 cmd_append("bind PAD1 +moveleft");
213 cmd_append("bind PAD3 +moveright");
214 cmd_append("bind PAD- +moveup");
215 cmd_append("bind PAD+ +movedown");
217 cmd_append("bind Q +bankleft; bind PAD7 +bankleft");
218 cmd_append("bind E +bankright; bind PAD9 +bankright");
220 cmd_append("bind , +cycle");
221 cmd_append("bind . +cycle2");
223 cmd_append("bind LCTRL +attack; bind RCTRL +attack");
224 cmd_append("bind SPC +attack2");
225 cmd_append("bind F +flare");
226 cmd_append("bind B +bomb");
228 cmd_append("bind R +rearview");
229 cmd_append("bind TAB +automap");
231 cmd_append("bind A +forward");
232 cmd_append("bind Z +back");
233 cmd_append("bind S +afterburner");
235 cmd_append("bind H +headlight");
236 cmd_append("bind T +nrgshield");
238 cmd_append("bind J1B1 +attack");
239 cmd_append("bind J1B2 +attack2");
241 cmd_append("bind MB1 +attack");
242 cmd_append("bind MB2 +attack2");
244 cmd_append("bind 1 weapon 1");
245 cmd_append("bind 2 weapon 2");
246 cmd_append("bind 3 weapon 3");
247 cmd_append("bind 4 weapon 4");
248 cmd_append("bind 5 weapon 5");
249 cmd_append("bind 6 weapon 6");
250 cmd_append("bind 7 weapon 7");
251 cmd_append("bind 8 weapon 8");
252 cmd_append("bind 9 weapon 9");
253 cmd_append("bind 0 weapon 0");
260 int joy_axis_center[7];
264 if (!config_initialized)
267 cvar_set_cvar( &config_last_player, "" );
269 joy_axis_min[0] = joy_axis_min[1] = joy_axis_min[2] = joy_axis_min[3] = 0;
270 joy_axis_max[0] = joy_axis_max[1] = joy_axis_max[2] = joy_axis_max[3] = 0;
271 joy_axis_center[0] = joy_axis_center[1] = joy_axis_center[2] = joy_axis_center[3] = 0;
273 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
276 cvar_setint(&digi_driver_board, 0);
277 cvar_setint(&digi_driver_port, 0);
278 cvar_setint(&digi_driver_irq, 0);
279 cvar_setint(&digi_driver_dma, 0);
280 cvar_setint(&digi_midi_type, 0);
281 cvar_setint(&digi_midi_port, 0);
284 cvar_setint( &Config_digi_volume, 8 );
285 cvar_setint( &Config_midi_volume, 8 );
286 cvar_setint( &Config_redbook_volume, 8 );
287 cvar_setint( &Config_control_type, CONTROL_NONE );
288 cvar_setint( &Config_channels_reversed, 0);
289 cvar_setint( &Config_joystick_sensitivity, 8 );
291 //set these here in case no cfg file
292 SaveMovieHires = MovieHires.intval;
293 save_redbook_enabled = Redbook_enabled.intval;
295 InitWeaponOrdering(); // setup default weapon priorities
296 cvar_set_cvarf(&Config_primary_order, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
297 PrimaryOrder[0], PrimaryOrder[1], PrimaryOrder[2], PrimaryOrder[3],
298 PrimaryOrder[4], PrimaryOrder[5], PrimaryOrder[6], PrimaryOrder[7],
299 PrimaryOrder[8], PrimaryOrder[9], PrimaryOrder[10]);
300 cvar_set_cvarf(&Config_secondary_order, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
301 SecondaryOrder[0], SecondaryOrder[1], SecondaryOrder[2], SecondaryOrder[3],
302 SecondaryOrder[4], SecondaryOrder[5], SecondaryOrder[6], SecondaryOrder[7],
303 SecondaryOrder[8], SecondaryOrder[9], SecondaryOrder[10]);
305 cvar_setint( &Cockpit_3d_view[0], CV_NONE );
306 cvar_setint( &Cockpit_3d_view[1], CV_NONE );
308 cvar_setint( &Config_lifetime_kills, 0 );
309 cvar_setint( &Config_lifetime_killed, 0 );
310 cvar_setint( &Config_lifetime_checksum, 0 );
312 if (cfexist("descent.cfg"))
313 cmd_append("exec descent.cfg");
315 LoadConfigDefaults();
319 /* TODO: allow cvars to define a callback that will carry out these initialization things on change. */
321 gr_palette_set_gamma( Config_gamma_level.intval );
323 Detail_level = strtol(Config_detail_level.string, NULL, 10);
324 if (Detail_level == NUM_DETAIL_LEVELS - 1) {
325 int count,dummy,oc,od,wd,wrd,da,sc;
327 count = sscanf (Config_detail_level.string, "%d,%d,%d,%d,%d,%d,%d\n",&dummy,&oc,&od,&wd,&wrd,&da,&sc);
330 Object_complexity = oc;
333 Wall_render_depth = wrd;
336 set_custom_detail_vars();
340 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] );
341 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] );
342 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] );
344 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
346 i = FindArg( "-volume" );
349 i = atoi( Args[i+1] );
351 if ( i > 100 ) i = 100;
352 cvar_setint( &Config_digi_volume, (i * 8) / 100 );
353 cvar_setint( &Config_midi_volume, (i * 8) / 100 );
354 cvar_setint( &Config_redbook_volume, (i * 8) / 100 );
357 if ( Config_digi_volume.intval > 8 ) cvar_setint( &Config_digi_volume, 8 );
358 if ( Config_midi_volume.intval > 8 ) cvar_setint( &Config_midi_volume, 8 );
359 if ( Config_redbook_volume.intval > 8 ) cvar_setint( &Config_redbook_volume, 8 );
361 digi_set_volume( (Config_digi_volume.intval * 32768) / 8, (Config_midi_volume.intval * 128) / 8 );
365 strncpy(guidebot_name, real_guidebot_name.string, GUIDEBOT_NAME_LEN);
366 guidebot_name[GUIDEBOT_NAME_LEN] = 0;
368 sscanf(Config_primary_order.string, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
369 (int *)&PrimaryOrder[0], (int *)&PrimaryOrder[1], (int *)&PrimaryOrder[2], (int *)&PrimaryOrder[3],
370 (int *)&PrimaryOrder[4], (int *)&PrimaryOrder[5], (int *)&PrimaryOrder[6], (int *)&PrimaryOrder[7],
371 (int *)&PrimaryOrder[8], (int *)&PrimaryOrder[9], (int *)&PrimaryOrder[10]);
372 sscanf(Config_secondary_order.string, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
373 (int *)&SecondaryOrder[0], (int *)&SecondaryOrder[1], (int *)&SecondaryOrder[2], (int *)&SecondaryOrder[3],
374 (int *)&SecondaryOrder[4], (int *)&SecondaryOrder[5], (int *)&SecondaryOrder[6], (int *)&SecondaryOrder[7],
375 (int *)&SecondaryOrder[8], (int *)&SecondaryOrder[9], (int *)&SecondaryOrder[10]);
378 Netlife_kills = Config_lifetime_kills.intval;
379 Netlife_killed = Config_lifetime_killed.intval;
381 con_printf(CON_DEBUG, "Reading: lifetime checksum is %d\n", Config_lifetime_checksum.intval);
382 if (Config_lifetime_checksum.intval != get_lifetime_checksum(Netlife_kills, Netlife_killed)) {
383 Netlife_kills = Netlife_killed = 0;
384 Warning("Shame on me\nTrying to cheat eh?");
389 printf( "DigiDeviceID: 0x%x\n", digi_driver_board );
390 printf( "DigiPort: 0x%x\n", digi_driver_port.intval );
391 printf( "DigiIrq: 0x%x\n", digi_driver_irq.intval );
392 printf( "DigiDma: 0x%x\n", digi_driver_dma.intval );
393 printf( "MidiDeviceID: 0x%x\n", digi_midi_type.intval );
394 printf( "MidiPort: 0x%x\n", digi_midi_port.intval );
397 cvar_setint( &Config_midi_type, digi_midi_type );
398 cvar_setint( &Config_digi_type, digi_driver_board );
399 cvar_setint( &Config_digi_dma, digi_driver_dma );
403 if (digi_driver_board_16.intval > 0 && !FindArg("-no16bit") && digi_driver_board_16.intval != _GUS_16_ST) {
404 digi_driver_board = digi_driver_board_16.intval;
405 digi_driver_dma = digi_driver_dma_16.intval;
409 //Hack to make some cards look like others, such as
410 //the Crytal Lake look like Microsoft Sound System
411 if ( digi_driver_board == _CRYSTAL_LAKE_8_ST ) {
413 tmp = CrystalLakeReadMCP( CL_MC1 );
415 atexit( CrystalLakeSetSB ); // Restore to SB when done.
417 digi_driver_board = _MICROSOFT_8_ST;
418 } else if ( digi_driver_board == _CRYSTAL_LAKE_16_ST ) {
420 tmp = CrystalLakeReadMCP( CL_MC1 );
422 atexit( CrystalLakeSetSB ); // Restore to SB when done.
424 digi_driver_board = _MICROSOFT_16_ST;
425 } else if ( digi_driver_board == _AWE32_8_ST ) {
426 digi_driver_board = _SB16_8_ST;
427 } else if ( digi_driver_board == _AWE32_16_ST ) {
428 digi_driver_board = _SB16_16_ST;
430 digi_driver_board = digi_driver_board;
433 if (cfexist("descentw.cfg")) {
434 cmd_append("exec descentw.cfg");
437 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] );
438 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] );
439 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] );
446 int WriteConfigFile()
448 PHYSFS_file *outfile;
450 int joy_axis_center[7];
453 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
455 if (FindArg("-noredbook"))
456 cvar_setint( &Redbook_enabled, save_redbook_enabled );
458 cvar_setint( &Config_gamma_level, gr_palette_get_gamma() );
460 if (Detail_level == NUM_DETAIL_LEVELS-1)
461 cvar_set_cvarf( &Config_detail_level, "%d,%d,%d,%d,%d,%d,%d", Detail_level,
462 Object_complexity,Object_detail,Wall_detail,Wall_render_depth,Debris_amount,SoundChannels );
464 cvar_setint( &Config_detail_level, Detail_level );
466 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] );
467 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] );
468 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] );
470 cvar_set_cvar( &config_last_player, Players[Player_num].callsign );
472 cvar_setint( &MovieHires, SaveMovieHires );
474 cvar_set_cvarf(&Config_primary_order, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
475 PrimaryOrder[0], PrimaryOrder[1], PrimaryOrder[2], PrimaryOrder[3],
476 PrimaryOrder[4], PrimaryOrder[5], PrimaryOrder[6], PrimaryOrder[7],
477 PrimaryOrder[8], PrimaryOrder[9], PrimaryOrder[10]);
478 cvar_set_cvarf(&Config_secondary_order, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
479 SecondaryOrder[0], SecondaryOrder[1], SecondaryOrder[2], SecondaryOrder[3],
480 SecondaryOrder[4], SecondaryOrder[5], SecondaryOrder[6], SecondaryOrder[7],
481 SecondaryOrder[8], SecondaryOrder[9], SecondaryOrder[10]);
484 cvar_setint(&Config_lifetime_kills, Netlife_kills);
485 cvar_setint(&Config_lifetime_killed, Netlife_killed);
486 cvar_setint(&Config_lifetime_checksum, get_lifetime_checksum(Netlife_kills, Netlife_killed));
487 con_printf(CON_DEBUG, "Writing: Lifetime checksum is %d\n", Config_lifetime_checksum.intval);
490 outfile = PHYSFSX_openWriteBuffered("descent.cfg");
494 key_write_bindings(outfile);
495 PHYSFS_close(outfile);
497 if (FindArg("-nohires") || FindArg("-nohighres") || FindArg("-lowresmovies"))
498 cvar_setint( &MovieHires, 0 );
501 CheckMovieAttributes();
507 #else // !defined(MACINTOSH)
516 #include <GestaltEqu.h>
518 #include <Processes.h>
519 #include <Resources.h>
532 #include "prefs.h" // prefs file for configuration stuff -- from DeSalvo
534 #define MAX_CTB_LEN 512
536 typedef struct preferences {
539 ubyte stereo_reverse;
541 ubyte oc; // object complexity
542 ubyte od; // object detail
543 ubyte wd; // wall detail
544 ubyte wrd; // wall render depth
545 ubyte da; // debris amount
546 ubyte sc; // sound channels
551 int joy_axis_center[4];
552 char lastplayer[CALLSIGN_LEN+1];
553 char lastmission[MISSION_NAME_LEN+1];
554 char ctb_config[MAX_CTB_LEN];
557 ubyte display_dialog;
558 ubyte change_resolution;
564 ubyte redbook_volume;
566 ubyte enable_input_sprockets;
569 char config_last_player[CALLSIGN_LEN+1] = "";
570 char config_last_mission[MISSION_NAME_LEN+1] = "";
571 char config_last_ctb_cfg[MAX_CTB_LEN] = "";
572 int config_last_ctb_tool;
573 ubyte Config_master_volume = 4;
574 ubyte Config_digi_volume = 8;
575 ubyte Config_midi_volume = 8;
576 ubyte Config_redbook_volume = 8;
577 ubyte Config_control_type = 0;
578 ubyte Config_channels_reversed = 0;
579 ubyte Config_joystick_sensitivity = 8;
581 int Config_vr_type = 0;
582 int Config_vr_resolution = 0;
583 int Config_vr_tracking = 0;
585 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
586 extern void digi_set_master_volume( int volume );
588 void set_custom_detail_vars(void);
590 static ubyte have_prefs = 0;
592 //¥ ------------------------------ Private Definitions
593 //¥ ------------------------------ Private Types
602 } PrefsInfo, *PrefsInfoPtr, **PrefsInfoHandle;
604 //¥ ------------------------------ Private Variables
606 static PrefsInfo prefsInfo;
607 static Boolean prefsInited = 0;
609 //¥ ------------------------------ Private Functions
611 static void Pstrcpy(StringPtr dst, StringPtr src);
612 static void Pstrcat(StringPtr dst, StringPtr src);
613 static Boolean FindPrefsFile(short *prefVRefNum, long *prefDirID);
615 //¥ -------------------- Pstrcpy
618 Pstrcpy(StringPtr dst, StringPtr src)
620 BlockMove(src, dst, (*src) + 1);
623 //¥ -------------------- Pstrcat
626 Pstrcat(StringPtr dst, StringPtr src)
628 BlockMove(src + 1, dst + (*dst) + 1, *src);
632 //¥ -------------------- FindPrefsFile
635 FindPrefsFile(short *prefVRefNum, long *prefDirID)
644 theErr = Gestalt(gestaltFindFolderAttr, &response);
645 if (theErr == noErr && ((response >> gestaltFindFolderPresent) & 1))
647 //¥ Find (or make) it the easy way...
648 theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, prefVRefNum, prefDirID);
653 StringPtr prefFolderName = "\pPreferences";
655 //¥ yeachh -- we have to do it all by hand!
656 theErr = SysEnvirons(1, &theSysEnv);
660 *prefVRefNum = theSysEnv.sysVRefNum;
662 //¥ Check whether Preferences folder already exists
663 infoPB.hFileInfo.ioCompletion = 0;
664 infoPB.hFileInfo.ioNamePtr = prefFolderName;
665 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
666 infoPB.hFileInfo.ioFDirIndex = 0;
667 infoPB.hFileInfo.ioDirID = 0;
669 theErr = PBGetCatInfo(&infoPB, 0);
672 *prefDirID = infoPB.hFileInfo.ioDirID;
674 else if (theErr == fnfErr) //¥ Preferences doesn't already exist
676 HParamBlockRec dirPB;
678 //¥ Create "Preferences" folder
679 dirPB.fileParam.ioCompletion = 0;
680 dirPB.fileParam.ioVRefNum = *prefVRefNum;
681 dirPB.fileParam.ioNamePtr = prefFolderName;
682 dirPB.fileParam.ioDirID = 0;
684 theErr = PBDirCreate(&dirPB, 0);
686 *prefDirID = dirPB.fileParam.ioDirID;
690 //¥ If we make it here OK, create Preferences file if necessary
693 infoPB.hFileInfo.ioCompletion = 0;
694 infoPB.hFileInfo.ioNamePtr = prefsInfo.fileName;
695 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
696 infoPB.hFileInfo.ioFDirIndex = 0;
697 infoPB.hFileInfo.ioDirID = *prefDirID;
699 theErr = PBGetCatInfo(&infoPB, 0);
700 if (theErr == fnfErr)
702 theErr = HCreate(*prefVRefNum, *prefDirID, prefsInfo.fileName, prefsInfo.creator, prefsInfo.fileType);
705 HCreateResFile(*prefVRefNum, *prefDirID, prefsInfo.fileName);
711 return (theErr == noErr);
714 //¥ -------------------- InitPrefsFile
716 #define UNKNOWN_TYPE 0x3f3f3f3f
719 InitPrefsFile(OSType creator)
722 PrefsInfoHandle piHdl;
724 if ((piHdl = (PrefsInfoHandle) GetResource('PRFI', 0)) == nil)
726 ProcessSerialNumber thePSN;
727 ProcessInfoRec thePIR;
729 StringPtr app_string;
732 GetCurrentProcess(&thePSN);
733 thePIR.processName = nil;
734 thePIR.processAppSpec = &appSpec;
736 //¥ Set default to 'ÇApplicationÈ Prefs', PREF 0
737 err = GetProcessInformation(&thePSN, &thePIR);
741 app_string = LMGetCurApName();
742 // Pstrcpy(prefsInfo.fileName, appSpec.name);
743 Pstrcpy(prefsInfo.fileName, app_string);
744 Pstrcat(prefsInfo.fileName, "\p Preferences");
746 //¥ Set creator to calling application's signature (should be able to
747 //¥ Determine this automatically, but unable to for some reason)
748 prefsInfo.creator = creator;
749 prefsInfo.fileType = 'pref';
750 prefsInfo.resType = 'pref';
755 //¥ Get Preferences file setup from PRFI 0
756 BlockMove(*piHdl, &prefsInfo, sizeof (prefsInfo));
757 ReleaseResource((Handle) piHdl);
759 if (prefsInfo.creator == UNKNOWN_TYPE)
760 prefsInfo.creator = creator;
766 //¥ -------------------- LoadPrefsFile
769 LoadPrefsFile(Handle prefsHdl)
771 short prefVRefNum, prefRefNum;
773 OSErr theErr = noErr;
775 Size prefSize, origSize;
778 return (nilHandleErr);
780 prefSize = GetHandleSize(prefsHdl);
782 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
785 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
786 if (prefRefNum == -1)
789 //¥ Not finding the resource is not an error -- caller will use default data
790 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
792 origSize = GetHandleSize(origHdl);
793 if (origSize > prefSize) //¥ Extend handle for extra stored data
794 SetHandleSize(prefsHdl, origSize);
796 BlockMove(*origHdl, *prefsHdl, origSize);
797 ReleaseResource(origHdl);
800 CloseResFile(prefRefNum);
808 //¥ -------------------- SavePrefsFile
811 SavePrefsFile(Handle prefHdl)
813 short prefVRefNum, prefRefNum;
815 Handle origHdl = nil;
816 Size origSize, prefSize;
817 OSErr theErr = noErr;
819 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
823 return (nilHandleErr);
825 prefSize = GetHandleSize(prefHdl);
827 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
828 if (prefRefNum == -1)
831 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
833 //¥ Overwrite existing preferences
834 origSize = GetHandleSize(origHdl);
835 if (prefSize > origSize)
836 SetHandleSize(origHdl, prefSize);
838 BlockMove(*prefHdl, *origHdl, prefSize);
839 ChangedResource(origHdl);
840 WriteResource(origHdl);
841 ReleaseResource(origHdl);
845 //¥ Store specified preferences for the first time
846 AddResource(prefHdl, prefsInfo.resType, prefsInfo.resID, "\p");
847 WriteResource(prefHdl);
848 DetachResource(prefHdl);
851 CloseResFile(prefRefNum);
859 //¥ -------------------------------------------------------------------------------------------
863 This module provides the ability to save and load a preferences file in the
864 Preferences folder in the System Folder. An optional resource, PRFI 0,
865 is used to provide specifications for the preferences file (creator, etc.).
867 Three functions are provided:
869 void InitPrefsFile(OSType creator)
871 This function will initialize the preferences file, that is, it will create
872 it in the appropriate place if it doesn't currently exist. It should be
873 called with the creator code for the application. Note that the creator
874 code specified in PRFI 0 (if any) will be used only if the creator code
875 passed to this function is '????'. Without the PRFI 0 resource, the default
878 File Name: "{Application} Prefs" (i.e., the name of the app plus " Prefs"
879 Creator: the creator passed to InitPrefsFile
881 Pref Resource Type: 'PREF'
884 The PRFI 0 resource allows you to specify overrides for each of the above
885 values. This is useful for development, since the application name might
886 go through changes, but the preferences file name is held constant.
888 OSErr LoadPrefsFile(Handle prefsHndl)
890 This function will attempt to copy the data stored in the preferences
891 file to the given handle (which must be pre-allocated). If the handle is too
892 small, then it will be enlarged. If it is too large, it will not be resized.
893 The data in the preferences file (normally in PREF 0) will then be copied
894 into the handle. If the preferences file did not exist, the original data
895 in the handle will not change.
897 OSErr SavePrefsFile(Handle prefsHndl)
899 This function will attempt to save the given handle to the preferences
900 file. Its contents will completely replace the previous data (normally
901 the PREF 0 resource).
903 In typical use, you will use InitPrefsFile once, then allocate a handle large
904 enough to contain your preferences data, and initialize it with default values.
905 Throughout the course of your program, the handle will undergo modification as
906 user preferences change. You can use SavePrefsFile anytime to update the
907 preferences file, or wait until program exit to do so.
919 if (!have_prefs) { // not initialized....get a handle to the preferences file
920 InitPrefsFile('DCT2');
924 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
925 if (prefs_handle == NULL)
928 prefs = (Preferences *)(*prefs_handle);
929 err = LoadPrefsFile(prefs_handle);
931 DisposeHandle(prefs_handle);
936 for (i = 0; i < sizeof(Preferences); i++) {
941 if ( i == sizeof(Preferences) )
944 Config_digi_volume = prefs->digi_volume;
945 Config_midi_volume = prefs->midi_volume;
946 Config_master_volume = prefs->master_volume;
947 Config_redbook_volume = prefs->redbook_volume;
948 Config_channels_reversed = prefs->stereo_reverse;
949 gr_palette_set_gamma( (int)(prefs->gamma_level) );
951 Scanline_double = (int)prefs->pixel_double;
953 Scanline_double = 0; // can't double with hardware acceleration
955 Detail_level = prefs->detail_level;
956 if (Detail_level == NUM_DETAIL_LEVELS-1) {
957 Object_complexity = prefs->oc;
958 Object_detail = prefs->od;
959 Wall_detail = prefs->wd;
960 Wall_render_depth = prefs->wrd;
961 Debris_amount = prefs->da;
962 SoundChannels = prefs->sc;
963 set_custom_detail_vars();
966 strncpy( config_last_player, prefs->lastplayer, CALLSIGN_LEN );
967 p = strchr(config_last_player, '\n' );
970 strncpy(config_last_mission, prefs->lastmission, MISSION_NAME_LEN);
971 p = strchr(config_last_mission, '\n' );
974 strcpy(config_last_ctb_cfg, prefs->ctb_config);
976 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
978 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
980 joy_set_cal_vals( prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
981 digi_set_volume( (Config_digi_volume*256)/8, (Config_midi_volume*256)/8 );
982 digi_set_master_volume(Config_master_volume);
984 gConfigInfo.mDoNotDisplayOptions = prefs->display_dialog;
985 gConfigInfo.mUse11kSounds = prefs->sound_11k;
986 gConfigInfo.mDisableSound = prefs->nosound;
987 gConfigInfo.mDisableMIDIMusic = prefs->nomidi;
988 gConfigInfo.mChangeResolution = prefs->change_resolution;
989 gConfigInfo.mDoNotPlayMovies = prefs->no_movies;
990 gConfigInfo.mGameMonitor = prefs->game_monitor;
991 gConfigInfo.mAcceleration = prefs->enable_rave;
992 gConfigInfo.mInputSprockets = prefs->enable_input_sprockets;
994 DisposeHandle(prefs_handle);
998 int WriteConfigFile()
1001 Handle prefs_handle;
1004 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
1005 if (prefs_handle == NULL)
1008 prefs = (Preferences *)(*prefs_handle);
1010 joy_get_cal_vals(prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
1011 prefs->digi_volume = Config_digi_volume;
1012 prefs->midi_volume = Config_midi_volume;
1013 prefs->stereo_reverse = Config_channels_reversed;
1014 prefs->detail_level = Detail_level;
1015 if (Detail_level == NUM_DETAIL_LEVELS-1) {
1016 prefs->oc = Object_complexity;
1017 prefs->od = Object_detail;
1018 prefs->wd = Wall_detail;
1019 prefs->wrd = Wall_render_depth;
1020 prefs->da = Debris_amount;
1021 prefs->sc = SoundChannels;
1023 prefs->gamma_level = (ubyte)gr_palette_get_gamma();
1026 prefs->pixel_double = (ubyte)Scanline_double; // hmm..don't write this out if doing hardware accel.
1028 strncpy( prefs->lastplayer, Players[Player_num].callsign, CALLSIGN_LEN );
1029 strncpy( prefs->lastmission, config_last_mission, MISSION_NAME_LEN );
1030 strcpy( prefs->ctb_config, config_last_ctb_cfg);
1031 prefs->ctb_tool = config_last_ctb_tool;
1032 prefs->master_volume = Config_master_volume;
1033 prefs->display_dialog = gConfigInfo.mDoNotDisplayOptions;
1034 prefs->change_resolution = gConfigInfo.mChangeResolution;
1035 prefs->nosound = gConfigInfo.mDisableSound;
1036 prefs->nomidi = gConfigInfo.mDisableMIDIMusic;
1037 prefs->sound_11k = gConfigInfo.mUse11kSounds;
1038 prefs->no_movies = gConfigInfo.mDoNotPlayMovies;
1039 prefs->game_monitor = gConfigInfo.mGameMonitor;
1040 prefs->redbook_volume = Config_redbook_volume;
1041 prefs->enable_rave = gConfigInfo.mAcceleration;
1042 prefs->enable_input_sprockets = gConfigInfo.mInputSprockets;
1044 err = SavePrefsFile(prefs_handle);
1045 DisposeHandle(prefs_handle);