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);
199 cvar_registervariable(&Network_message_macro[0]);
200 cvar_registervariable(&Network_message_macro[1]);
201 cvar_registervariable(&Network_message_macro[2]);
202 cvar_registervariable(&Network_message_macro[3]);
204 config_initialized = 1;
208 void LoadConfigDefaults(void)
210 cmd_append("bind UP +lookdown; bind PAD8 +lookdown");
211 cmd_append("bind DOWN +lookup; bind PAD2 +lookup");
212 cmd_append("bind LEFT +left; bind PAD4 +left");
213 cmd_append("bind RIGHT +right; bind PAD6 +right");
215 cmd_append("bind LALT +strafe");
216 cmd_append("bind PAD1 +moveleft");
217 cmd_append("bind PAD3 +moveright");
218 cmd_append("bind PAD- +moveup");
219 cmd_append("bind PAD+ +movedown");
221 cmd_append("bind Q +bankleft; bind PAD7 +bankleft");
222 cmd_append("bind E +bankright; bind PAD9 +bankright");
224 cmd_append("bind , +cycle");
225 cmd_append("bind . +cycle2");
227 cmd_append("bind LCTRL +attack; bind RCTRL +attack");
228 cmd_append("bind SPC +attack2");
229 cmd_append("bind F +flare");
230 cmd_append("bind B +bomb");
232 cmd_append("bind R +rearview");
233 cmd_append("bind TAB +automap");
235 cmd_append("bind A +forward");
236 cmd_append("bind Z +back");
237 cmd_append("bind S +afterburner");
239 cmd_append("bind H +headlight");
240 cmd_append("bind T +nrgshield");
242 cmd_append("bind J1B1 +attack");
243 cmd_append("bind J1B2 +attack2");
245 cmd_append("bind MB1 +attack");
246 cmd_append("bind MB2 +attack2");
248 cmd_append("bind 1 weapon 1");
249 cmd_append("bind 2 weapon 2");
250 cmd_append("bind 3 weapon 3");
251 cmd_append("bind 4 weapon 4");
252 cmd_append("bind 5 weapon 5");
253 cmd_append("bind 6 weapon 6");
254 cmd_append("bind 7 weapon 7");
255 cmd_append("bind 8 weapon 8");
256 cmd_append("bind 9 weapon 9");
257 cmd_append("bind 0 weapon 0");
264 int joy_axis_center[7];
268 if (!config_initialized)
271 cvar_set_cvar( &config_last_player, "" );
273 joy_axis_min[0] = joy_axis_min[1] = joy_axis_min[2] = joy_axis_min[3] = 0;
274 joy_axis_max[0] = joy_axis_max[1] = joy_axis_max[2] = joy_axis_max[3] = 0;
275 joy_axis_center[0] = joy_axis_center[1] = joy_axis_center[2] = joy_axis_center[3] = 0;
277 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
280 cvar_setint(&digi_driver_board, 0);
281 cvar_setint(&digi_driver_port, 0);
282 cvar_setint(&digi_driver_irq, 0);
283 cvar_setint(&digi_driver_dma, 0);
284 cvar_setint(&digi_midi_type, 0);
285 cvar_setint(&digi_midi_port, 0);
288 cvar_setint( &Config_digi_volume, 8 );
289 cvar_setint( &Config_midi_volume, 8 );
290 cvar_setint( &Config_redbook_volume, 8 );
291 cvar_setint( &Config_control_type, CONTROL_NONE );
292 cvar_setint( &Config_channels_reversed, 0);
293 cvar_setint( &Config_joystick_sensitivity, 8 );
295 //set these here in case no cfg file
296 SaveMovieHires = MovieHires.intval;
297 save_redbook_enabled = Redbook_enabled.intval;
299 InitWeaponOrdering(); // setup default weapon priorities
300 cvar_set_cvarf(&Config_primary_order, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
301 PrimaryOrder[0], PrimaryOrder[1], PrimaryOrder[2], PrimaryOrder[3],
302 PrimaryOrder[4], PrimaryOrder[5], PrimaryOrder[6], PrimaryOrder[7],
303 PrimaryOrder[8], PrimaryOrder[9], PrimaryOrder[10]);
304 cvar_set_cvarf(&Config_secondary_order, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
305 SecondaryOrder[0], SecondaryOrder[1], SecondaryOrder[2], SecondaryOrder[3],
306 SecondaryOrder[4], SecondaryOrder[5], SecondaryOrder[6], SecondaryOrder[7],
307 SecondaryOrder[8], SecondaryOrder[9], SecondaryOrder[10]);
309 cvar_setint( &Cockpit_3d_view[0], CV_NONE );
310 cvar_setint( &Cockpit_3d_view[1], CV_NONE );
312 cvar_setint( &Config_lifetime_kills, 0 );
313 cvar_setint( &Config_lifetime_killed, 0 );
314 cvar_setint( &Config_lifetime_checksum, 0 );
316 // Default taunt macros
318 cvar_set_cvar(&Network_message_macro[0], "Why can't we all just get along?");
319 cvar_set_cvar(&Network_message_macro[1], "Hey, I got a present for ya");
320 cvar_set_cvar(&Network_message_macro[2], "I got a hankerin' for a spankerin'");
321 cvar_set_cvar(&Network_message_macro[3], "This one's headed for Uranus");
324 if (cfexist("descent.cfg"))
325 cmd_append("exec descent.cfg");
327 LoadConfigDefaults();
331 /* TODO: allow cvars to define a callback that will carry out these initialization things on change. */
333 gr_palette_set_gamma( Config_gamma_level.intval );
335 Detail_level = strtol(Config_detail_level.string, NULL, 10);
336 if (Detail_level == NUM_DETAIL_LEVELS - 1) {
337 int count,dummy,oc,od,wd,wrd,da,sc;
339 count = sscanf (Config_detail_level.string, "%d,%d,%d,%d,%d,%d,%d\n",&dummy,&oc,&od,&wd,&wrd,&da,&sc);
342 Object_complexity = oc;
345 Wall_render_depth = wrd;
348 set_custom_detail_vars();
352 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] );
353 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] );
354 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] );
356 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
358 i = FindArg( "-volume" );
361 i = atoi( Args[i+1] );
363 if ( i > 100 ) i = 100;
364 cvar_setint( &Config_digi_volume, (i * 8) / 100 );
365 cvar_setint( &Config_midi_volume, (i * 8) / 100 );
366 cvar_setint( &Config_redbook_volume, (i * 8) / 100 );
369 if ( Config_digi_volume.intval > 8 ) cvar_setint( &Config_digi_volume, 8 );
370 if ( Config_midi_volume.intval > 8 ) cvar_setint( &Config_midi_volume, 8 );
371 if ( Config_redbook_volume.intval > 8 ) cvar_setint( &Config_redbook_volume, 8 );
373 digi_set_volume( (Config_digi_volume.intval * 32768) / 8, (Config_midi_volume.intval * 128) / 8 );
377 strncpy(guidebot_name, real_guidebot_name.string, GUIDEBOT_NAME_LEN);
378 guidebot_name[GUIDEBOT_NAME_LEN] = 0;
380 sscanf(Config_primary_order.string, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
381 (int *)&PrimaryOrder[0], (int *)&PrimaryOrder[1], (int *)&PrimaryOrder[2], (int *)&PrimaryOrder[3],
382 (int *)&PrimaryOrder[4], (int *)&PrimaryOrder[5], (int *)&PrimaryOrder[6], (int *)&PrimaryOrder[7],
383 (int *)&PrimaryOrder[8], (int *)&PrimaryOrder[9], (int *)&PrimaryOrder[10]);
384 sscanf(Config_secondary_order.string, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
385 (int *)&SecondaryOrder[0], (int *)&SecondaryOrder[1], (int *)&SecondaryOrder[2], (int *)&SecondaryOrder[3],
386 (int *)&SecondaryOrder[4], (int *)&SecondaryOrder[5], (int *)&SecondaryOrder[6], (int *)&SecondaryOrder[7],
387 (int *)&SecondaryOrder[8], (int *)&SecondaryOrder[9], (int *)&SecondaryOrder[10]);
390 Netlife_kills = Config_lifetime_kills.intval;
391 Netlife_killed = Config_lifetime_killed.intval;
393 con_printf(CON_DEBUG, "Reading: lifetime checksum is %d\n", Config_lifetime_checksum.intval);
394 if (Config_lifetime_checksum.intval != get_lifetime_checksum(Netlife_kills, Netlife_killed)) {
395 Netlife_kills = Netlife_killed = 0;
396 Warning("Shame on me\nTrying to cheat eh?");
401 printf( "DigiDeviceID: 0x%x\n", digi_driver_board );
402 printf( "DigiPort: 0x%x\n", digi_driver_port.intval );
403 printf( "DigiIrq: 0x%x\n", digi_driver_irq.intval );
404 printf( "DigiDma: 0x%x\n", digi_driver_dma.intval );
405 printf( "MidiDeviceID: 0x%x\n", digi_midi_type.intval );
406 printf( "MidiPort: 0x%x\n", digi_midi_port.intval );
409 cvar_setint( &Config_midi_type, digi_midi_type );
410 cvar_setint( &Config_digi_type, digi_driver_board );
411 cvar_setint( &Config_digi_dma, digi_driver_dma );
415 if (digi_driver_board_16.intval > 0 && !FindArg("-no16bit") && digi_driver_board_16.intval != _GUS_16_ST) {
416 digi_driver_board = digi_driver_board_16.intval;
417 digi_driver_dma = digi_driver_dma_16.intval;
421 //Hack to make some cards look like others, such as
422 //the Crytal Lake look like Microsoft Sound System
423 if ( digi_driver_board == _CRYSTAL_LAKE_8_ST ) {
425 tmp = CrystalLakeReadMCP( CL_MC1 );
427 atexit( CrystalLakeSetSB ); // Restore to SB when done.
429 digi_driver_board = _MICROSOFT_8_ST;
430 } else if ( digi_driver_board == _CRYSTAL_LAKE_16_ST ) {
432 tmp = CrystalLakeReadMCP( CL_MC1 );
434 atexit( CrystalLakeSetSB ); // Restore to SB when done.
436 digi_driver_board = _MICROSOFT_16_ST;
437 } else if ( digi_driver_board == _AWE32_8_ST ) {
438 digi_driver_board = _SB16_8_ST;
439 } else if ( digi_driver_board == _AWE32_16_ST ) {
440 digi_driver_board = _SB16_16_ST;
442 digi_driver_board = digi_driver_board;
445 if (cfexist("descentw.cfg")) {
446 cmd_append("exec descentw.cfg");
449 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] );
450 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] );
451 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] );
458 int WriteConfigFile()
460 PHYSFS_file *outfile;
462 int joy_axis_center[7];
465 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
467 if (FindArg("-noredbook"))
468 cvar_setint( &Redbook_enabled, save_redbook_enabled );
470 cvar_setint( &Config_gamma_level, gr_palette_get_gamma() );
472 if (Detail_level == NUM_DETAIL_LEVELS-1)
473 cvar_set_cvarf( &Config_detail_level, "%d,%d,%d,%d,%d,%d,%d", Detail_level,
474 Object_complexity,Object_detail,Wall_detail,Wall_render_depth,Debris_amount,SoundChannels );
476 cvar_setint( &Config_detail_level, Detail_level );
478 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] );
479 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] );
480 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] );
482 cvar_set_cvar( &config_last_player, Players[Player_num].callsign );
484 cvar_setint( &MovieHires, SaveMovieHires );
486 cvar_set_cvarf(&Config_primary_order, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
487 PrimaryOrder[0], PrimaryOrder[1], PrimaryOrder[2], PrimaryOrder[3],
488 PrimaryOrder[4], PrimaryOrder[5], PrimaryOrder[6], PrimaryOrder[7],
489 PrimaryOrder[8], PrimaryOrder[9], PrimaryOrder[10]);
490 cvar_set_cvarf(&Config_secondary_order, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
491 SecondaryOrder[0], SecondaryOrder[1], SecondaryOrder[2], SecondaryOrder[3],
492 SecondaryOrder[4], SecondaryOrder[5], SecondaryOrder[6], SecondaryOrder[7],
493 SecondaryOrder[8], SecondaryOrder[9], SecondaryOrder[10]);
496 cvar_setint(&Config_lifetime_kills, Netlife_kills);
497 cvar_setint(&Config_lifetime_killed, Netlife_killed);
498 cvar_setint(&Config_lifetime_checksum, get_lifetime_checksum(Netlife_kills, Netlife_killed));
499 con_printf(CON_DEBUG, "Writing: Lifetime checksum is %d\n", Config_lifetime_checksum.intval);
502 outfile = PHYSFSX_openWriteBuffered("descent.cfg");
506 key_write_bindings(outfile);
507 PHYSFS_close(outfile);
509 if (FindArg("-nohires") || FindArg("-nohighres") || FindArg("-lowresmovies"))
510 cvar_setint( &MovieHires, 0 );
513 CheckMovieAttributes();
519 #else // !defined(MACINTOSH)
528 #include <GestaltEqu.h>
530 #include <Processes.h>
531 #include <Resources.h>
544 #include "prefs.h" // prefs file for configuration stuff -- from DeSalvo
546 #define MAX_CTB_LEN 512
548 typedef struct preferences {
551 ubyte stereo_reverse;
553 ubyte oc; // object complexity
554 ubyte od; // object detail
555 ubyte wd; // wall detail
556 ubyte wrd; // wall render depth
557 ubyte da; // debris amount
558 ubyte sc; // sound channels
563 int joy_axis_center[4];
564 char lastplayer[CALLSIGN_LEN+1];
565 char lastmission[MISSION_NAME_LEN+1];
566 char ctb_config[MAX_CTB_LEN];
569 ubyte display_dialog;
570 ubyte change_resolution;
576 ubyte redbook_volume;
578 ubyte enable_input_sprockets;
581 char config_last_player[CALLSIGN_LEN+1] = "";
582 char config_last_mission[MISSION_NAME_LEN+1] = "";
583 char config_last_ctb_cfg[MAX_CTB_LEN] = "";
584 int config_last_ctb_tool;
585 ubyte Config_master_volume = 4;
586 ubyte Config_digi_volume = 8;
587 ubyte Config_midi_volume = 8;
588 ubyte Config_redbook_volume = 8;
589 ubyte Config_control_type = 0;
590 ubyte Config_channels_reversed = 0;
591 ubyte Config_joystick_sensitivity = 8;
593 int Config_vr_type = 0;
594 int Config_vr_resolution = 0;
595 int Config_vr_tracking = 0;
597 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
598 extern void digi_set_master_volume( int volume );
600 void set_custom_detail_vars(void);
602 static ubyte have_prefs = 0;
604 //¥ ------------------------------ Private Definitions
605 //¥ ------------------------------ Private Types
614 } PrefsInfo, *PrefsInfoPtr, **PrefsInfoHandle;
616 //¥ ------------------------------ Private Variables
618 static PrefsInfo prefsInfo;
619 static Boolean prefsInited = 0;
621 //¥ ------------------------------ Private Functions
623 static void Pstrcpy(StringPtr dst, StringPtr src);
624 static void Pstrcat(StringPtr dst, StringPtr src);
625 static Boolean FindPrefsFile(short *prefVRefNum, long *prefDirID);
627 //¥ -------------------- Pstrcpy
630 Pstrcpy(StringPtr dst, StringPtr src)
632 BlockMove(src, dst, (*src) + 1);
635 //¥ -------------------- Pstrcat
638 Pstrcat(StringPtr dst, StringPtr src)
640 BlockMove(src + 1, dst + (*dst) + 1, *src);
644 //¥ -------------------- FindPrefsFile
647 FindPrefsFile(short *prefVRefNum, long *prefDirID)
656 theErr = Gestalt(gestaltFindFolderAttr, &response);
657 if (theErr == noErr && ((response >> gestaltFindFolderPresent) & 1))
659 //¥ Find (or make) it the easy way...
660 theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, prefVRefNum, prefDirID);
665 StringPtr prefFolderName = "\pPreferences";
667 //¥ yeachh -- we have to do it all by hand!
668 theErr = SysEnvirons(1, &theSysEnv);
672 *prefVRefNum = theSysEnv.sysVRefNum;
674 //¥ Check whether Preferences folder already exists
675 infoPB.hFileInfo.ioCompletion = 0;
676 infoPB.hFileInfo.ioNamePtr = prefFolderName;
677 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
678 infoPB.hFileInfo.ioFDirIndex = 0;
679 infoPB.hFileInfo.ioDirID = 0;
681 theErr = PBGetCatInfo(&infoPB, 0);
684 *prefDirID = infoPB.hFileInfo.ioDirID;
686 else if (theErr == fnfErr) //¥ Preferences doesn't already exist
688 HParamBlockRec dirPB;
690 //¥ Create "Preferences" folder
691 dirPB.fileParam.ioCompletion = 0;
692 dirPB.fileParam.ioVRefNum = *prefVRefNum;
693 dirPB.fileParam.ioNamePtr = prefFolderName;
694 dirPB.fileParam.ioDirID = 0;
696 theErr = PBDirCreate(&dirPB, 0);
698 *prefDirID = dirPB.fileParam.ioDirID;
702 //¥ If we make it here OK, create Preferences file if necessary
705 infoPB.hFileInfo.ioCompletion = 0;
706 infoPB.hFileInfo.ioNamePtr = prefsInfo.fileName;
707 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
708 infoPB.hFileInfo.ioFDirIndex = 0;
709 infoPB.hFileInfo.ioDirID = *prefDirID;
711 theErr = PBGetCatInfo(&infoPB, 0);
712 if (theErr == fnfErr)
714 theErr = HCreate(*prefVRefNum, *prefDirID, prefsInfo.fileName, prefsInfo.creator, prefsInfo.fileType);
717 HCreateResFile(*prefVRefNum, *prefDirID, prefsInfo.fileName);
723 return (theErr == noErr);
726 //¥ -------------------- InitPrefsFile
728 #define UNKNOWN_TYPE 0x3f3f3f3f
731 InitPrefsFile(OSType creator)
734 PrefsInfoHandle piHdl;
736 if ((piHdl = (PrefsInfoHandle) GetResource('PRFI', 0)) == nil)
738 ProcessSerialNumber thePSN;
739 ProcessInfoRec thePIR;
741 StringPtr app_string;
744 GetCurrentProcess(&thePSN);
745 thePIR.processName = nil;
746 thePIR.processAppSpec = &appSpec;
748 //¥ Set default to 'ÇApplicationÈ Prefs', PREF 0
749 err = GetProcessInformation(&thePSN, &thePIR);
753 app_string = LMGetCurApName();
754 // Pstrcpy(prefsInfo.fileName, appSpec.name);
755 Pstrcpy(prefsInfo.fileName, app_string);
756 Pstrcat(prefsInfo.fileName, "\p Preferences");
758 //¥ Set creator to calling application's signature (should be able to
759 //¥ Determine this automatically, but unable to for some reason)
760 prefsInfo.creator = creator;
761 prefsInfo.fileType = 'pref';
762 prefsInfo.resType = 'pref';
767 //¥ Get Preferences file setup from PRFI 0
768 BlockMove(*piHdl, &prefsInfo, sizeof (prefsInfo));
769 ReleaseResource((Handle) piHdl);
771 if (prefsInfo.creator == UNKNOWN_TYPE)
772 prefsInfo.creator = creator;
778 //¥ -------------------- LoadPrefsFile
781 LoadPrefsFile(Handle prefsHdl)
783 short prefVRefNum, prefRefNum;
785 OSErr theErr = noErr;
787 Size prefSize, origSize;
790 return (nilHandleErr);
792 prefSize = GetHandleSize(prefsHdl);
794 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
797 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
798 if (prefRefNum == -1)
801 //¥ Not finding the resource is not an error -- caller will use default data
802 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
804 origSize = GetHandleSize(origHdl);
805 if (origSize > prefSize) //¥ Extend handle for extra stored data
806 SetHandleSize(prefsHdl, origSize);
808 BlockMove(*origHdl, *prefsHdl, origSize);
809 ReleaseResource(origHdl);
812 CloseResFile(prefRefNum);
820 //¥ -------------------- SavePrefsFile
823 SavePrefsFile(Handle prefHdl)
825 short prefVRefNum, prefRefNum;
827 Handle origHdl = nil;
828 Size origSize, prefSize;
829 OSErr theErr = noErr;
831 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
835 return (nilHandleErr);
837 prefSize = GetHandleSize(prefHdl);
839 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
840 if (prefRefNum == -1)
843 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
845 //¥ Overwrite existing preferences
846 origSize = GetHandleSize(origHdl);
847 if (prefSize > origSize)
848 SetHandleSize(origHdl, prefSize);
850 BlockMove(*prefHdl, *origHdl, prefSize);
851 ChangedResource(origHdl);
852 WriteResource(origHdl);
853 ReleaseResource(origHdl);
857 //¥ Store specified preferences for the first time
858 AddResource(prefHdl, prefsInfo.resType, prefsInfo.resID, "\p");
859 WriteResource(prefHdl);
860 DetachResource(prefHdl);
863 CloseResFile(prefRefNum);
871 //¥ -------------------------------------------------------------------------------------------
875 This module provides the ability to save and load a preferences file in the
876 Preferences folder in the System Folder. An optional resource, PRFI 0,
877 is used to provide specifications for the preferences file (creator, etc.).
879 Three functions are provided:
881 void InitPrefsFile(OSType creator)
883 This function will initialize the preferences file, that is, it will create
884 it in the appropriate place if it doesn't currently exist. It should be
885 called with the creator code for the application. Note that the creator
886 code specified in PRFI 0 (if any) will be used only if the creator code
887 passed to this function is '????'. Without the PRFI 0 resource, the default
890 File Name: "{Application} Prefs" (i.e., the name of the app plus " Prefs"
891 Creator: the creator passed to InitPrefsFile
893 Pref Resource Type: 'PREF'
896 The PRFI 0 resource allows you to specify overrides for each of the above
897 values. This is useful for development, since the application name might
898 go through changes, but the preferences file name is held constant.
900 OSErr LoadPrefsFile(Handle prefsHndl)
902 This function will attempt to copy the data stored in the preferences
903 file to the given handle (which must be pre-allocated). If the handle is too
904 small, then it will be enlarged. If it is too large, it will not be resized.
905 The data in the preferences file (normally in PREF 0) will then be copied
906 into the handle. If the preferences file did not exist, the original data
907 in the handle will not change.
909 OSErr SavePrefsFile(Handle prefsHndl)
911 This function will attempt to save the given handle to the preferences
912 file. Its contents will completely replace the previous data (normally
913 the PREF 0 resource).
915 In typical use, you will use InitPrefsFile once, then allocate a handle large
916 enough to contain your preferences data, and initialize it with default values.
917 Throughout the course of your program, the handle will undergo modification as
918 user preferences change. You can use SavePrefsFile anytime to update the
919 preferences file, or wait until program exit to do so.
931 if (!have_prefs) { // not initialized....get a handle to the preferences file
932 InitPrefsFile('DCT2');
936 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
937 if (prefs_handle == NULL)
940 prefs = (Preferences *)(*prefs_handle);
941 err = LoadPrefsFile(prefs_handle);
943 DisposeHandle(prefs_handle);
948 for (i = 0; i < sizeof(Preferences); i++) {
953 if ( i == sizeof(Preferences) )
956 Config_digi_volume = prefs->digi_volume;
957 Config_midi_volume = prefs->midi_volume;
958 Config_master_volume = prefs->master_volume;
959 Config_redbook_volume = prefs->redbook_volume;
960 Config_channels_reversed = prefs->stereo_reverse;
961 gr_palette_set_gamma( (int)(prefs->gamma_level) );
963 Scanline_double = (int)prefs->pixel_double;
965 Scanline_double = 0; // can't double with hardware acceleration
967 Detail_level = prefs->detail_level;
968 if (Detail_level == NUM_DETAIL_LEVELS-1) {
969 Object_complexity = prefs->oc;
970 Object_detail = prefs->od;
971 Wall_detail = prefs->wd;
972 Wall_render_depth = prefs->wrd;
973 Debris_amount = prefs->da;
974 SoundChannels = prefs->sc;
975 set_custom_detail_vars();
978 strncpy( config_last_player, prefs->lastplayer, CALLSIGN_LEN );
979 p = strchr(config_last_player, '\n' );
982 strncpy(config_last_mission, prefs->lastmission, MISSION_NAME_LEN);
983 p = strchr(config_last_mission, '\n' );
986 strcpy(config_last_ctb_cfg, prefs->ctb_config);
988 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
990 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
992 joy_set_cal_vals( prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
993 digi_set_volume( (Config_digi_volume*256)/8, (Config_midi_volume*256)/8 );
994 digi_set_master_volume(Config_master_volume);
996 gConfigInfo.mDoNotDisplayOptions = prefs->display_dialog;
997 gConfigInfo.mUse11kSounds = prefs->sound_11k;
998 gConfigInfo.mDisableSound = prefs->nosound;
999 gConfigInfo.mDisableMIDIMusic = prefs->nomidi;
1000 gConfigInfo.mChangeResolution = prefs->change_resolution;
1001 gConfigInfo.mDoNotPlayMovies = prefs->no_movies;
1002 gConfigInfo.mGameMonitor = prefs->game_monitor;
1003 gConfigInfo.mAcceleration = prefs->enable_rave;
1004 gConfigInfo.mInputSprockets = prefs->enable_input_sprockets;
1006 DisposeHandle(prefs_handle);
1010 int WriteConfigFile()
1013 Handle prefs_handle;
1016 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
1017 if (prefs_handle == NULL)
1020 prefs = (Preferences *)(*prefs_handle);
1022 joy_get_cal_vals(prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
1023 prefs->digi_volume = Config_digi_volume;
1024 prefs->midi_volume = Config_midi_volume;
1025 prefs->stereo_reverse = Config_channels_reversed;
1026 prefs->detail_level = Detail_level;
1027 if (Detail_level == NUM_DETAIL_LEVELS-1) {
1028 prefs->oc = Object_complexity;
1029 prefs->od = Object_detail;
1030 prefs->wd = Wall_detail;
1031 prefs->wrd = Wall_render_depth;
1032 prefs->da = Debris_amount;
1033 prefs->sc = SoundChannels;
1035 prefs->gamma_level = (ubyte)gr_palette_get_gamma();
1038 prefs->pixel_double = (ubyte)Scanline_double; // hmm..don't write this out if doing hardware accel.
1040 strncpy( prefs->lastplayer, Players[Player_num].callsign, CALLSIGN_LEN );
1041 strncpy( prefs->lastmission, config_last_mission, MISSION_NAME_LEN );
1042 strcpy( prefs->ctb_config, config_last_ctb_cfg);
1043 prefs->ctb_tool = config_last_ctb_tool;
1044 prefs->master_volume = Config_master_volume;
1045 prefs->display_dialog = gConfigInfo.mDoNotDisplayOptions;
1046 prefs->change_resolution = gConfigInfo.mChangeResolution;
1047 prefs->nosound = gConfigInfo.mDisableSound;
1048 prefs->nomidi = gConfigInfo.mDisableMIDIMusic;
1049 prefs->sound_11k = gConfigInfo.mUse11kSounds;
1050 prefs->no_movies = gConfigInfo.mDoNotPlayMovies;
1051 prefs->game_monitor = gConfigInfo.mGameMonitor;
1052 prefs->redbook_volume = Config_redbook_volume;
1053 prefs->enable_rave = gConfigInfo.mAcceleration;
1054 prefs->enable_input_sprockets = gConfigInfo.mInputSprockets;
1056 err = SavePrefsFile(prefs_handle);
1057 DisposeHandle(prefs_handle);