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 };
85 cvar_t Config_primary_order = { "PrimaryOrder", "", 1 };
86 cvar_t Config_secondary_order = { "SecondaryOrder", "", 1 };
89 #define _CRYSTAL_LAKE_8_ST 0xe201
90 #define _CRYSTAL_LAKE_16_ST 0xe202
91 #define _AWE32_8_ST 0xe208
92 #define _AWE32_16_ST 0xe209
95 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
97 void set_custom_detail_vars(void);
103 void CrystalLakeWriteMCP( ushort mc_addr, ubyte mc_data )
106 outp( CL_MC0, 0xE2 ); // Write password
107 outp( mc_addr, mc_data ); // Write data
111 ubyte CrystalLakeReadMCP( ushort mc_addr )
115 outp( CL_MC0, 0xE2 ); // Write password
116 value = inp( mc_addr ); // Read data
121 void CrystalLakeSetSB()
124 tmp = CrystalLakeReadMCP( CL_MC1 );
126 CrystalLakeWriteMCP( CL_MC1, tmp );
129 void CrystalLakeSetWSS()
132 tmp = CrystalLakeReadMCP( CL_MC1 );
134 CrystalLakeWriteMCP( CL_MC1, tmp );
137 //MovieHires might be changed by -nohighres, so save a "real" copy of it
139 int save_redbook_enabled;
142 void CheckMovieAttributes()
145 DWORD len, type, val;
148 lres = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Parallax\\Descent II\\1.1\\INSTALL",
150 if (lres == ERROR_SUCCESS) {
152 lres = RegQueryValueEx(hKey, "HIRES", NULL, &type, &val, &len);
153 if (lres == ERROR_SUCCESS) {
154 cvar_setint( &MovieHires, val );
155 logentry("HIRES=%d\n", val);
163 static int config_initialized;
165 static void config_init(void)
167 /* make sure our cvars are registered */
168 cvar_registervariable(&Config_digi_volume);
169 cvar_registervariable(&Config_midi_volume);
170 cvar_registervariable(&Redbook_enabled);
171 cvar_registervariable(&Config_redbook_volume);
172 cvar_registervariable(&Config_channels_reversed);
173 cvar_registervariable(&Config_gamma_level);
174 cvar_registervariable(&Config_detail_level);
175 cvar_registervariable(&Config_control_type);
176 cvar_registervariable(&Config_joystick_sensitivity);
177 cvar_registervariable(&Config_joystick_min);
178 cvar_registervariable(&Config_joystick_cen);
179 cvar_registervariable(&Config_joystick_max);
180 cvar_registervariable(&config_last_player);
181 cvar_registervariable(&config_last_mission);
182 cvar_registervariable(&Config_vr_type);
183 cvar_registervariable(&Config_vr_resolution);
184 cvar_registervariable(&Config_vr_tracking);
185 cvar_registervariable(&MovieHires);
186 cvar_registervariable(&real_guidebot_name);
187 cvar_registervariable(&Config_primary_order);
188 cvar_registervariable(&Config_secondary_order);
189 cvar_registervariable(&Cockpit_3d_view[0]);
190 cvar_registervariable(&Cockpit_3d_view[1]);
192 config_initialized = 1;
196 void LoadConfigDefaults(void)
198 cmd_append("bind UP +lookdown; bind PAD8 +lookdown");
199 cmd_append("bind DOWN +lookup; bind PAD2 +lookup");
200 cmd_append("bind LEFT +left; bind PAD4 +left");
201 cmd_append("bind RIGHT +right; bind PAD6 +right");
203 cmd_append("bind LALT +strafe");
204 cmd_append("bind PAD1 +moveleft");
205 cmd_append("bind PAD3 +moveright");
206 cmd_append("bind PAD- +moveup");
207 cmd_append("bind PAD+ +movedown");
209 cmd_append("bind Q +bankleft; bind PAD7 +bankleft");
210 cmd_append("bind E +bankright; bind PAD9 +bankright");
212 cmd_append("bind , +cycle");
213 cmd_append("bind . +cycle2");
215 cmd_append("bind LCTRL +attack; bind RCTRL +attack");
216 cmd_append("bind SPC +attack2");
217 cmd_append("bind F +flare");
218 cmd_append("bind B +bomb");
220 cmd_append("bind R +rearview");
221 cmd_append("bind TAB +automap");
223 cmd_append("bind A +forward");
224 cmd_append("bind Z +back");
225 cmd_append("bind S +afterburner");
227 cmd_append("bind H +headlight");
228 cmd_append("bind T +nrgshield");
230 cmd_append("bind J1B1 +attack");
231 cmd_append("bind J1B2 +attack2");
233 cmd_append("bind MB1 +attack");
234 cmd_append("bind MB2 +attack2");
236 cmd_append("bind 1 weapon 1");
237 cmd_append("bind 2 weapon 2");
238 cmd_append("bind 3 weapon 3");
239 cmd_append("bind 4 weapon 4");
240 cmd_append("bind 5 weapon 5");
241 cmd_append("bind 6 weapon 6");
242 cmd_append("bind 7 weapon 7");
243 cmd_append("bind 8 weapon 8");
244 cmd_append("bind 9 weapon 9");
245 cmd_append("bind 0 weapon 0");
252 int joy_axis_center[7];
256 if (!config_initialized)
259 cvar_set_cvar( &config_last_player, "" );
261 joy_axis_min[0] = joy_axis_min[1] = joy_axis_min[2] = joy_axis_min[3] = 0;
262 joy_axis_max[0] = joy_axis_max[1] = joy_axis_max[2] = joy_axis_max[3] = 0;
263 joy_axis_center[0] = joy_axis_center[1] = joy_axis_center[2] = joy_axis_center[3] = 0;
265 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
268 cvar_setint(&digi_driver_board, 0);
269 cvar_setint(&digi_driver_port, 0);
270 cvar_setint(&digi_driver_irq, 0);
271 cvar_setint(&digi_driver_dma, 0);
272 cvar_setint(&digi_midi_type, 0);
273 cvar_setint(&digi_midi_port, 0);
276 cvar_setint( &Config_digi_volume, 8 );
277 cvar_setint( &Config_midi_volume, 8 );
278 cvar_setint( &Config_redbook_volume, 8 );
279 cvar_setint( &Config_control_type, CONTROL_NONE );
280 cvar_setint( &Config_channels_reversed, 0);
281 cvar_setint( &Config_joystick_sensitivity, 8 );
283 //set these here in case no cfg file
284 SaveMovieHires = MovieHires.intval;
285 save_redbook_enabled = Redbook_enabled.intval;
287 InitWeaponOrdering(); // setup default weapon priorities
288 cvar_set_cvarf(&Config_primary_order, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
289 PrimaryOrder[0], PrimaryOrder[1], PrimaryOrder[2], PrimaryOrder[3],
290 PrimaryOrder[4], PrimaryOrder[5], PrimaryOrder[6], PrimaryOrder[7],
291 PrimaryOrder[8], PrimaryOrder[9], PrimaryOrder[10]);
292 cvar_set_cvarf(&Config_secondary_order, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
293 SecondaryOrder[0], SecondaryOrder[1], SecondaryOrder[2], SecondaryOrder[3],
294 SecondaryOrder[4], SecondaryOrder[5], SecondaryOrder[6], SecondaryOrder[7],
295 SecondaryOrder[8], SecondaryOrder[9], SecondaryOrder[10]);
297 cvar_setint( &Cockpit_3d_view[0], CV_NONE );
298 cvar_setint( &Cockpit_3d_view[1], CV_NONE );
300 if (cfexist("descent.cfg"))
301 cmd_append("exec descent.cfg");
303 LoadConfigDefaults();
307 /* TODO: allow cvars to define a callback that will carry out these initialization things on change. */
309 gr_palette_set_gamma( Config_gamma_level.intval );
311 Detail_level = strtol(Config_detail_level.string, NULL, 10);
312 if (Detail_level == NUM_DETAIL_LEVELS - 1) {
313 int count,dummy,oc,od,wd,wrd,da,sc;
315 count = sscanf (Config_detail_level.string, "%d,%d,%d,%d,%d,%d,%d\n",&dummy,&oc,&od,&wd,&wrd,&da,&sc);
318 Object_complexity = oc;
321 Wall_render_depth = wrd;
324 set_custom_detail_vars();
328 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] );
329 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] );
330 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] );
332 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
334 i = FindArg( "-volume" );
337 i = atoi( Args[i+1] );
339 if ( i > 100 ) i = 100;
340 cvar_setint( &Config_digi_volume, (i * 8) / 100 );
341 cvar_setint( &Config_midi_volume, (i * 8) / 100 );
342 cvar_setint( &Config_redbook_volume, (i * 8) / 100 );
345 if ( Config_digi_volume.intval > 8 ) cvar_setint( &Config_digi_volume, 8 );
346 if ( Config_midi_volume.intval > 8 ) cvar_setint( &Config_midi_volume, 8 );
347 if ( Config_redbook_volume.intval > 8 ) cvar_setint( &Config_redbook_volume, 8 );
349 digi_set_volume( (Config_digi_volume.intval * 32768) / 8, (Config_midi_volume.intval * 128) / 8 );
353 strncpy(guidebot_name, real_guidebot_name.string, GUIDEBOT_NAME_LEN);
354 guidebot_name[GUIDEBOT_NAME_LEN] = 0;
356 sscanf(Config_primary_order.string, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
357 (int *)&PrimaryOrder[0], (int *)&PrimaryOrder[1], (int *)&PrimaryOrder[2], (int *)&PrimaryOrder[3],
358 (int *)&PrimaryOrder[4], (int *)&PrimaryOrder[5], (int *)&PrimaryOrder[6], (int *)&PrimaryOrder[7],
359 (int *)&PrimaryOrder[8], (int *)&PrimaryOrder[9], (int *)&PrimaryOrder[10]);
360 sscanf(Config_secondary_order.string, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
361 (int *)&SecondaryOrder[0], (int *)&SecondaryOrder[1], (int *)&SecondaryOrder[2], (int *)&SecondaryOrder[3],
362 (int *)&SecondaryOrder[4], (int *)&SecondaryOrder[5], (int *)&SecondaryOrder[6], (int *)&SecondaryOrder[7],
363 (int *)&SecondaryOrder[8], (int *)&SecondaryOrder[9], (int *)&SecondaryOrder[10]);
366 printf( "DigiDeviceID: 0x%x\n", digi_driver_board );
367 printf( "DigiPort: 0x%x\n", digi_driver_port.intval );
368 printf( "DigiIrq: 0x%x\n", digi_driver_irq.intval );
369 printf( "DigiDma: 0x%x\n", digi_driver_dma.intval );
370 printf( "MidiDeviceID: 0x%x\n", digi_midi_type.intval );
371 printf( "MidiPort: 0x%x\n", digi_midi_port.intval );
374 cvar_setint( &Config_midi_type, digi_midi_type );
375 cvar_setint( &Config_digi_type, digi_driver_board );
376 cvar_setint( &Config_digi_dma, digi_driver_dma );
380 if (digi_driver_board_16.intval > 0 && !FindArg("-no16bit") && digi_driver_board_16.intval != _GUS_16_ST) {
381 digi_driver_board = digi_driver_board_16.intval;
382 digi_driver_dma = digi_driver_dma_16.intval;
386 //Hack to make some cards look like others, such as
387 //the Crytal Lake look like Microsoft Sound System
388 if ( digi_driver_board == _CRYSTAL_LAKE_8_ST ) {
390 tmp = CrystalLakeReadMCP( CL_MC1 );
392 atexit( CrystalLakeSetSB ); // Restore to SB when done.
394 digi_driver_board = _MICROSOFT_8_ST;
395 } else if ( digi_driver_board == _CRYSTAL_LAKE_16_ST ) {
397 tmp = CrystalLakeReadMCP( CL_MC1 );
399 atexit( CrystalLakeSetSB ); // Restore to SB when done.
401 digi_driver_board = _MICROSOFT_16_ST;
402 } else if ( digi_driver_board == _AWE32_8_ST ) {
403 digi_driver_board = _SB16_8_ST;
404 } else if ( digi_driver_board == _AWE32_16_ST ) {
405 digi_driver_board = _SB16_16_ST;
407 digi_driver_board = digi_driver_board;
410 if (cfexist("descentw.cfg")) {
411 cmd_append("exec descentw.cfg");
414 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] );
415 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] );
416 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] );
423 int WriteConfigFile()
425 PHYSFS_file *outfile;
427 int joy_axis_center[7];
430 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
432 if (FindArg("-noredbook"))
433 cvar_setint( &Redbook_enabled, save_redbook_enabled );
435 cvar_setint( &Config_gamma_level, gr_palette_get_gamma() );
437 if (Detail_level == NUM_DETAIL_LEVELS-1)
438 cvar_set_cvarf( &Config_detail_level, "%d,%d,%d,%d,%d,%d,%d", Detail_level,
439 Object_complexity,Object_detail,Wall_detail,Wall_render_depth,Debris_amount,SoundChannels );
441 cvar_setint( &Config_detail_level, Detail_level );
443 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] );
444 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] );
445 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] );
447 cvar_set_cvar( &config_last_player, Players[Player_num].callsign );
449 cvar_setint( &MovieHires, SaveMovieHires );
451 cvar_set_cvarf(&Config_primary_order, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
452 PrimaryOrder[0], PrimaryOrder[1], PrimaryOrder[2], PrimaryOrder[3],
453 PrimaryOrder[4], PrimaryOrder[5], PrimaryOrder[6], PrimaryOrder[7],
454 PrimaryOrder[8], PrimaryOrder[9], PrimaryOrder[10]);
455 cvar_set_cvarf(&Config_secondary_order, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
456 SecondaryOrder[0], SecondaryOrder[1], SecondaryOrder[2], SecondaryOrder[3],
457 SecondaryOrder[4], SecondaryOrder[5], SecondaryOrder[6], SecondaryOrder[7],
458 SecondaryOrder[8], SecondaryOrder[9], SecondaryOrder[10]);
460 outfile = PHYSFSX_openWriteBuffered("descent.cfg");
464 key_write_bindings(outfile);
465 PHYSFS_close(outfile);
467 if (FindArg("-nohires") || FindArg("-nohighres") || FindArg("-lowresmovies"))
468 cvar_setint( &MovieHires, 0 );
471 CheckMovieAttributes();
477 #else // !defined(MACINTOSH)
486 #include <GestaltEqu.h>
488 #include <Processes.h>
489 #include <Resources.h>
502 #include "prefs.h" // prefs file for configuration stuff -- from DeSalvo
504 #define MAX_CTB_LEN 512
506 typedef struct preferences {
509 ubyte stereo_reverse;
511 ubyte oc; // object complexity
512 ubyte od; // object detail
513 ubyte wd; // wall detail
514 ubyte wrd; // wall render depth
515 ubyte da; // debris amount
516 ubyte sc; // sound channels
521 int joy_axis_center[4];
522 char lastplayer[CALLSIGN_LEN+1];
523 char lastmission[MISSION_NAME_LEN+1];
524 char ctb_config[MAX_CTB_LEN];
527 ubyte display_dialog;
528 ubyte change_resolution;
534 ubyte redbook_volume;
536 ubyte enable_input_sprockets;
539 char config_last_player[CALLSIGN_LEN+1] = "";
540 char config_last_mission[MISSION_NAME_LEN+1] = "";
541 char config_last_ctb_cfg[MAX_CTB_LEN] = "";
542 int config_last_ctb_tool;
543 ubyte Config_master_volume = 4;
544 ubyte Config_digi_volume = 8;
545 ubyte Config_midi_volume = 8;
546 ubyte Config_redbook_volume = 8;
547 ubyte Config_control_type = 0;
548 ubyte Config_channels_reversed = 0;
549 ubyte Config_joystick_sensitivity = 8;
551 int Config_vr_type = 0;
552 int Config_vr_resolution = 0;
553 int Config_vr_tracking = 0;
555 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
556 extern void digi_set_master_volume( int volume );
558 void set_custom_detail_vars(void);
560 static ubyte have_prefs = 0;
562 //¥ ------------------------------ Private Definitions
563 //¥ ------------------------------ Private Types
572 } PrefsInfo, *PrefsInfoPtr, **PrefsInfoHandle;
574 //¥ ------------------------------ Private Variables
576 static PrefsInfo prefsInfo;
577 static Boolean prefsInited = 0;
579 //¥ ------------------------------ Private Functions
581 static void Pstrcpy(StringPtr dst, StringPtr src);
582 static void Pstrcat(StringPtr dst, StringPtr src);
583 static Boolean FindPrefsFile(short *prefVRefNum, long *prefDirID);
585 //¥ -------------------- Pstrcpy
588 Pstrcpy(StringPtr dst, StringPtr src)
590 BlockMove(src, dst, (*src) + 1);
593 //¥ -------------------- Pstrcat
596 Pstrcat(StringPtr dst, StringPtr src)
598 BlockMove(src + 1, dst + (*dst) + 1, *src);
602 //¥ -------------------- FindPrefsFile
605 FindPrefsFile(short *prefVRefNum, long *prefDirID)
614 theErr = Gestalt(gestaltFindFolderAttr, &response);
615 if (theErr == noErr && ((response >> gestaltFindFolderPresent) & 1))
617 //¥ Find (or make) it the easy way...
618 theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, prefVRefNum, prefDirID);
623 StringPtr prefFolderName = "\pPreferences";
625 //¥ yeachh -- we have to do it all by hand!
626 theErr = SysEnvirons(1, &theSysEnv);
630 *prefVRefNum = theSysEnv.sysVRefNum;
632 //¥ Check whether Preferences folder already exists
633 infoPB.hFileInfo.ioCompletion = 0;
634 infoPB.hFileInfo.ioNamePtr = prefFolderName;
635 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
636 infoPB.hFileInfo.ioFDirIndex = 0;
637 infoPB.hFileInfo.ioDirID = 0;
639 theErr = PBGetCatInfo(&infoPB, 0);
642 *prefDirID = infoPB.hFileInfo.ioDirID;
644 else if (theErr == fnfErr) //¥ Preferences doesn't already exist
646 HParamBlockRec dirPB;
648 //¥ Create "Preferences" folder
649 dirPB.fileParam.ioCompletion = 0;
650 dirPB.fileParam.ioVRefNum = *prefVRefNum;
651 dirPB.fileParam.ioNamePtr = prefFolderName;
652 dirPB.fileParam.ioDirID = 0;
654 theErr = PBDirCreate(&dirPB, 0);
656 *prefDirID = dirPB.fileParam.ioDirID;
660 //¥ If we make it here OK, create Preferences file if necessary
663 infoPB.hFileInfo.ioCompletion = 0;
664 infoPB.hFileInfo.ioNamePtr = prefsInfo.fileName;
665 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
666 infoPB.hFileInfo.ioFDirIndex = 0;
667 infoPB.hFileInfo.ioDirID = *prefDirID;
669 theErr = PBGetCatInfo(&infoPB, 0);
670 if (theErr == fnfErr)
672 theErr = HCreate(*prefVRefNum, *prefDirID, prefsInfo.fileName, prefsInfo.creator, prefsInfo.fileType);
675 HCreateResFile(*prefVRefNum, *prefDirID, prefsInfo.fileName);
681 return (theErr == noErr);
684 //¥ -------------------- InitPrefsFile
686 #define UNKNOWN_TYPE 0x3f3f3f3f
689 InitPrefsFile(OSType creator)
692 PrefsInfoHandle piHdl;
694 if ((piHdl = (PrefsInfoHandle) GetResource('PRFI', 0)) == nil)
696 ProcessSerialNumber thePSN;
697 ProcessInfoRec thePIR;
699 StringPtr app_string;
702 GetCurrentProcess(&thePSN);
703 thePIR.processName = nil;
704 thePIR.processAppSpec = &appSpec;
706 //¥ Set default to 'ÇApplicationÈ Prefs', PREF 0
707 err = GetProcessInformation(&thePSN, &thePIR);
711 app_string = LMGetCurApName();
712 // Pstrcpy(prefsInfo.fileName, appSpec.name);
713 Pstrcpy(prefsInfo.fileName, app_string);
714 Pstrcat(prefsInfo.fileName, "\p Preferences");
716 //¥ Set creator to calling application's signature (should be able to
717 //¥ Determine this automatically, but unable to for some reason)
718 prefsInfo.creator = creator;
719 prefsInfo.fileType = 'pref';
720 prefsInfo.resType = 'pref';
725 //¥ Get Preferences file setup from PRFI 0
726 BlockMove(*piHdl, &prefsInfo, sizeof (prefsInfo));
727 ReleaseResource((Handle) piHdl);
729 if (prefsInfo.creator == UNKNOWN_TYPE)
730 prefsInfo.creator = creator;
736 //¥ -------------------- LoadPrefsFile
739 LoadPrefsFile(Handle prefsHdl)
741 short prefVRefNum, prefRefNum;
743 OSErr theErr = noErr;
745 Size prefSize, origSize;
748 return (nilHandleErr);
750 prefSize = GetHandleSize(prefsHdl);
752 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
755 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
756 if (prefRefNum == -1)
759 //¥ Not finding the resource is not an error -- caller will use default data
760 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
762 origSize = GetHandleSize(origHdl);
763 if (origSize > prefSize) //¥ Extend handle for extra stored data
764 SetHandleSize(prefsHdl, origSize);
766 BlockMove(*origHdl, *prefsHdl, origSize);
767 ReleaseResource(origHdl);
770 CloseResFile(prefRefNum);
778 //¥ -------------------- SavePrefsFile
781 SavePrefsFile(Handle prefHdl)
783 short prefVRefNum, prefRefNum;
785 Handle origHdl = nil;
786 Size origSize, prefSize;
787 OSErr theErr = noErr;
789 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
793 return (nilHandleErr);
795 prefSize = GetHandleSize(prefHdl);
797 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
798 if (prefRefNum == -1)
801 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
803 //¥ Overwrite existing preferences
804 origSize = GetHandleSize(origHdl);
805 if (prefSize > origSize)
806 SetHandleSize(origHdl, prefSize);
808 BlockMove(*prefHdl, *origHdl, prefSize);
809 ChangedResource(origHdl);
810 WriteResource(origHdl);
811 ReleaseResource(origHdl);
815 //¥ Store specified preferences for the first time
816 AddResource(prefHdl, prefsInfo.resType, prefsInfo.resID, "\p");
817 WriteResource(prefHdl);
818 DetachResource(prefHdl);
821 CloseResFile(prefRefNum);
829 //¥ -------------------------------------------------------------------------------------------
833 This module provides the ability to save and load a preferences file in the
834 Preferences folder in the System Folder. An optional resource, PRFI 0,
835 is used to provide specifications for the preferences file (creator, etc.).
837 Three functions are provided:
839 void InitPrefsFile(OSType creator)
841 This function will initialize the preferences file, that is, it will create
842 it in the appropriate place if it doesn't currently exist. It should be
843 called with the creator code for the application. Note that the creator
844 code specified in PRFI 0 (if any) will be used only if the creator code
845 passed to this function is '????'. Without the PRFI 0 resource, the default
848 File Name: "{Application} Prefs" (i.e., the name of the app plus " Prefs"
849 Creator: the creator passed to InitPrefsFile
851 Pref Resource Type: 'PREF'
854 The PRFI 0 resource allows you to specify overrides for each of the above
855 values. This is useful for development, since the application name might
856 go through changes, but the preferences file name is held constant.
858 OSErr LoadPrefsFile(Handle prefsHndl)
860 This function will attempt to copy the data stored in the preferences
861 file to the given handle (which must be pre-allocated). If the handle is too
862 small, then it will be enlarged. If it is too large, it will not be resized.
863 The data in the preferences file (normally in PREF 0) will then be copied
864 into the handle. If the preferences file did not exist, the original data
865 in the handle will not change.
867 OSErr SavePrefsFile(Handle prefsHndl)
869 This function will attempt to save the given handle to the preferences
870 file. Its contents will completely replace the previous data (normally
871 the PREF 0 resource).
873 In typical use, you will use InitPrefsFile once, then allocate a handle large
874 enough to contain your preferences data, and initialize it with default values.
875 Throughout the course of your program, the handle will undergo modification as
876 user preferences change. You can use SavePrefsFile anytime to update the
877 preferences file, or wait until program exit to do so.
889 if (!have_prefs) { // not initialized....get a handle to the preferences file
890 InitPrefsFile('DCT2');
894 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
895 if (prefs_handle == NULL)
898 prefs = (Preferences *)(*prefs_handle);
899 err = LoadPrefsFile(prefs_handle);
901 DisposeHandle(prefs_handle);
906 for (i = 0; i < sizeof(Preferences); i++) {
911 if ( i == sizeof(Preferences) )
914 Config_digi_volume = prefs->digi_volume;
915 Config_midi_volume = prefs->midi_volume;
916 Config_master_volume = prefs->master_volume;
917 Config_redbook_volume = prefs->redbook_volume;
918 Config_channels_reversed = prefs->stereo_reverse;
919 gr_palette_set_gamma( (int)(prefs->gamma_level) );
921 Scanline_double = (int)prefs->pixel_double;
923 Scanline_double = 0; // can't double with hardware acceleration
925 Detail_level = prefs->detail_level;
926 if (Detail_level == NUM_DETAIL_LEVELS-1) {
927 Object_complexity = prefs->oc;
928 Object_detail = prefs->od;
929 Wall_detail = prefs->wd;
930 Wall_render_depth = prefs->wrd;
931 Debris_amount = prefs->da;
932 SoundChannels = prefs->sc;
933 set_custom_detail_vars();
936 strncpy( config_last_player, prefs->lastplayer, CALLSIGN_LEN );
937 p = strchr(config_last_player, '\n' );
940 strncpy(config_last_mission, prefs->lastmission, MISSION_NAME_LEN);
941 p = strchr(config_last_mission, '\n' );
944 strcpy(config_last_ctb_cfg, prefs->ctb_config);
946 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
948 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
950 joy_set_cal_vals( prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
951 digi_set_volume( (Config_digi_volume*256)/8, (Config_midi_volume*256)/8 );
952 digi_set_master_volume(Config_master_volume);
954 gConfigInfo.mDoNotDisplayOptions = prefs->display_dialog;
955 gConfigInfo.mUse11kSounds = prefs->sound_11k;
956 gConfigInfo.mDisableSound = prefs->nosound;
957 gConfigInfo.mDisableMIDIMusic = prefs->nomidi;
958 gConfigInfo.mChangeResolution = prefs->change_resolution;
959 gConfigInfo.mDoNotPlayMovies = prefs->no_movies;
960 gConfigInfo.mGameMonitor = prefs->game_monitor;
961 gConfigInfo.mAcceleration = prefs->enable_rave;
962 gConfigInfo.mInputSprockets = prefs->enable_input_sprockets;
964 DisposeHandle(prefs_handle);
968 int WriteConfigFile()
974 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
975 if (prefs_handle == NULL)
978 prefs = (Preferences *)(*prefs_handle);
980 joy_get_cal_vals(prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
981 prefs->digi_volume = Config_digi_volume;
982 prefs->midi_volume = Config_midi_volume;
983 prefs->stereo_reverse = Config_channels_reversed;
984 prefs->detail_level = Detail_level;
985 if (Detail_level == NUM_DETAIL_LEVELS-1) {
986 prefs->oc = Object_complexity;
987 prefs->od = Object_detail;
988 prefs->wd = Wall_detail;
989 prefs->wrd = Wall_render_depth;
990 prefs->da = Debris_amount;
991 prefs->sc = SoundChannels;
993 prefs->gamma_level = (ubyte)gr_palette_get_gamma();
996 prefs->pixel_double = (ubyte)Scanline_double; // hmm..don't write this out if doing hardware accel.
998 strncpy( prefs->lastplayer, Players[Player_num].callsign, CALLSIGN_LEN );
999 strncpy( prefs->lastmission, config_last_mission, MISSION_NAME_LEN );
1000 strcpy( prefs->ctb_config, config_last_ctb_cfg);
1001 prefs->ctb_tool = config_last_ctb_tool;
1002 prefs->master_volume = Config_master_volume;
1003 prefs->display_dialog = gConfigInfo.mDoNotDisplayOptions;
1004 prefs->change_resolution = gConfigInfo.mChangeResolution;
1005 prefs->nosound = gConfigInfo.mDisableSound;
1006 prefs->nomidi = gConfigInfo.mDisableMIDIMusic;
1007 prefs->sound_11k = gConfigInfo.mUse11kSounds;
1008 prefs->no_movies = gConfigInfo.mDoNotPlayMovies;
1009 prefs->game_monitor = gConfigInfo.mGameMonitor;
1010 prefs->redbook_volume = Config_redbook_volume;
1011 prefs->enable_rave = gConfigInfo.mAcceleration;
1012 prefs->enable_input_sprockets = gConfigInfo.mInputSprockets;
1014 err = SavePrefsFile(prefs_handle);
1015 DisposeHandle(prefs_handle);