1 /* $Id: config.c,v 1.17 2005-07-30 01:50:17 chris Exp $ */
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
17 * contains routine(s) to read in the configuration file which contains
18 * game configuration stuff like detail level, sound card, etc
26 #ifndef MACINTOSH // I'm going to totally seperate these routines -- yeeech!!!!
27 // see end of file for macintosh equivs
30 #define WIN32_LEAN_AND_MEAN
61 static char rcsid[] = "$Id: config.c,v 1.17 2005-07-30 01:50:17 chris Exp $";
64 ubyte Config_digi_volume = 8;
65 ubyte Config_midi_volume = 8;
66 ubyte Config_redbook_volume = 8;
67 ubyte Config_control_type = 0;
68 ubyte Config_channels_reversed = 0;
69 ubyte Config_joystick_sensitivity = 8;
72 static char *digi_dev8_str = "DigiDeviceID8";
73 static char *digi_dev16_str = "DigiDeviceID16";
74 static char *digi_port_str = "DigiPort";
75 static char *digi_irq_str = "DigiIrq";
76 static char *digi_dma8_str = "DigiDma8";
77 static char *digi_dma16_str = "DigiDma16";
78 static char *midi_dev_str = "MidiDeviceID";
79 static char *midi_port_str = "MidiPort";
81 #define _CRYSTAL_LAKE_8_ST 0xe201
82 #define _CRYSTAL_LAKE_16_ST 0xe202
83 #define _AWE32_8_ST 0xe208
84 #define _AWE32_16_ST 0xe209
86 static char *digi_volume_str = "DigiVolume";
87 static char *midi_volume_str = "MidiVolume";
88 static char *redbook_enabled_str = "RedbookEnabled";
89 static char *redbook_volume_str = "RedbookVolume";
90 static char *detail_level_str = "DetailLevel";
91 static char *gamma_level_str = "GammaLevel";
92 static char *stereo_rev_str = "StereoReverse";
93 static char *joystick_min_str = "JoystickMin";
94 static char *joystick_max_str = "JoystickMax";
95 static char *joystick_cen_str = "JoystickCen";
96 static char *last_player_str = "LastPlayer";
97 static char *last_mission_str = "LastMission";
98 static char *config_vr_type_str = "VR_type";
99 static char *config_vr_resolution_str = "VR_resolution";
100 static char *config_vr_tracking_str = "VR_tracking";
101 static char *movie_hires_str = "MovieHires";
103 char config_last_player[CALLSIGN_LEN+1] = "";
104 char config_last_mission[MISSION_NAME_LEN+1] = "";
106 int Config_digi_type = 0;
107 int Config_digi_dma = 0;
108 int Config_midi_type = 0;
111 int DOSJoySaveMin[4];
112 int DOSJoySaveCen[4];
113 int DOSJoySaveMax[4];
115 char win95_current_joyname[256];
120 int Config_vr_type = 0;
121 int Config_vr_resolution = 0;
122 int Config_vr_tracking = 0;
124 int digi_driver_board_16;
125 int digi_driver_dma_16;
127 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
129 void set_custom_detail_vars(void);
135 void CrystalLakeWriteMCP( ushort mc_addr, ubyte mc_data )
138 outp( CL_MC0, 0xE2 ); // Write password
139 outp( mc_addr, mc_data ); // Write data
143 ubyte CrystalLakeReadMCP( ushort mc_addr )
147 outp( CL_MC0, 0xE2 ); // Write password
148 value = inp( mc_addr ); // Read data
153 void CrystalLakeSetSB()
156 tmp = CrystalLakeReadMCP( CL_MC1 );
158 CrystalLakeWriteMCP( CL_MC1, tmp );
161 void CrystalLakeSetWSS()
164 tmp = CrystalLakeReadMCP( CL_MC1 );
166 CrystalLakeWriteMCP( CL_MC1, tmp );
169 //MovieHires might be changed by -nohighres, so save a "real" copy of it
171 int save_redbook_enabled;
174 void CheckMovieAttributes()
177 DWORD len, type, val;
180 lres = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Parallax\\Descent II\\1.1\\INSTALL",
182 if (lres == ERROR_SUCCESS) {
184 lres = RegQueryValueEx(hKey, "HIRES", NULL, &type, &val, &len);
185 if (lres == ERROR_SUCCESS) {
187 logentry("HIRES=%d\n", val);
199 char line[80], *token, *value, *ptr;
202 int joy_axis_center[7];
206 strcpy( config_last_player, "" );
208 joy_axis_min[0] = joy_axis_min[1] = joy_axis_min[2] = joy_axis_min[3] = 0;
209 joy_axis_max[0] = joy_axis_max[1] = joy_axis_max[2] = joy_axis_max[3] = 0;
210 joy_axis_center[0] = joy_axis_center[1] = joy_axis_center[2] = joy_axis_center[3] = 0;
213 memset(&joy_axis_min[0], 0, sizeof(int)*7);
214 memset(&joy_axis_max[0], 0, sizeof(int)*7);
215 memset(&joy_axis_center[0], 0, sizeof(int)*7);
216 //@@ joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
218 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
221 /*digi_driver_board = 0;
222 digi_driver_port = 0;
227 digi_midi_port = 0;*/
229 Config_digi_volume = 8;
230 Config_midi_volume = 8;
231 Config_redbook_volume = 8;
232 Config_control_type = 0;
233 Config_channels_reversed = 0;
235 //set these here in case no cfg file
236 SaveMovieHires = MovieHires;
237 save_redbook_enabled = Redbook_enabled;
239 infile = PHYSFSX_openReadBuffered("descent.cfg");
240 if (infile == NULL) {
241 WIN(CheckMovieAttributes());
244 while (!PHYSFS_eof(infile))
247 PHYSFSX_gets(infile, line);
249 while (isspace(*ptr))
252 token = strtok(ptr, "=");
253 value = strtok(NULL, "=");
256 /* if (!strcmp(token, digi_dev8_str))
257 digi_driver_board = strtol(value, NULL, 16);
258 else if (!strcmp(token, digi_dev16_str))
259 digi_driver_board_16 = strtol(value, NULL, 16);
260 else if (!strcmp(token, digi_port_str))
261 digi_driver_port = strtol(value, NULL, 16);
262 else if (!strcmp(token, digi_irq_str))
263 digi_driver_irq = strtol(value, NULL, 10);
264 else if (!strcmp(token, digi_dma8_str))
265 digi_driver_dma = strtol(value, NULL, 10);
266 else if (!strcmp(token, digi_dma16_str))
267 digi_driver_dma_16 = strtol(value, NULL, 10);
268 else*/ if (!strcmp(token, digi_volume_str))
269 Config_digi_volume = strtol(value, NULL, 10);
270 else/* if (!strcmp(token, midi_dev_str))
271 digi_midi_type = strtol(value, NULL, 16);
272 else if (!strcmp(token, midi_port_str))
273 digi_midi_port = strtol(value, NULL, 16);
274 else*/ if (!strcmp(token, midi_volume_str))
275 Config_midi_volume = strtol(value, NULL, 10);
276 else if (!strcmp(token, redbook_enabled_str))
277 Redbook_enabled = save_redbook_enabled = strtol(value, NULL, 10);
278 else if (!strcmp(token, redbook_volume_str))
279 Config_redbook_volume = strtol(value, NULL, 10);
280 else if (!strcmp(token, stereo_rev_str))
281 Config_channels_reversed = strtol(value, NULL, 10);
282 else if (!strcmp(token, gamma_level_str)) {
283 gamma = strtol(value, NULL, 10);
284 gr_palette_set_gamma( gamma );
286 else if (!strcmp(token, detail_level_str)) {
287 Detail_level = strtol(value, NULL, 10);
288 if (Detail_level == NUM_DETAIL_LEVELS-1) {
289 int count,dummy,oc,od,wd,wrd,da,sc;
291 count = sscanf (value, "%d,%d,%d,%d,%d,%d,%d\n",&dummy,&oc,&od,&wd,&wrd,&da,&sc);
294 Object_complexity = oc;
297 Wall_render_depth = wrd;
300 set_custom_detail_vars();
304 else if (!strcmp(token, joystick_min_str)) {
305 sscanf( value, "%d,%d,%d,%d", &joy_axis_min[0], &joy_axis_min[1], &joy_axis_min[2], &joy_axis_min[3] );
307 else if (!strcmp(token, joystick_max_str)) {
308 sscanf( value, "%d,%d,%d,%d", &joy_axis_max[0], &joy_axis_max[1], &joy_axis_max[2], &joy_axis_max[3] );
310 else if (!strcmp(token, joystick_cen_str)) {
311 sscanf( value, "%d,%d,%d,%d", &joy_axis_center[0], &joy_axis_center[1], &joy_axis_center[2], &joy_axis_center[3] );
313 else if (!strcmp(token, last_player_str)) {
315 strncpy( config_last_player, value, CALLSIGN_LEN );
316 p = strchr( config_last_player, '\n');
319 else if (!strcmp(token, last_mission_str)) {
321 strncpy( config_last_mission, value, MISSION_NAME_LEN );
322 p = strchr( config_last_mission, '\n');
324 } else if (!strcmp(token, config_vr_type_str)) {
325 Config_vr_type = strtol(value, NULL, 10);
326 } else if (!strcmp(token, config_vr_resolution_str)) {
327 Config_vr_resolution = strtol(value, NULL, 10);
328 } else if (!strcmp(token, config_vr_tracking_str)) {
329 Config_vr_tracking = strtol(value, NULL, 10);
330 } else if (!strcmp(token, movie_hires_str)) {
331 SaveMovieHires = MovieHires = strtol(value, NULL, 10);
336 PHYSFS_close(infile);
341 DOSJoySaveMin[i]=joy_axis_min[i];
342 DOSJoySaveCen[i]=joy_axis_center[i];
343 DOSJoySaveMax[i]=joy_axis_max[i];
346 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
349 i = FindArg( "-volume" );
352 i = atoi( Args[i+1] );
354 if ( i > 100 ) i = 100;
355 Config_digi_volume = (i*8)/100;
356 Config_midi_volume = (i*8)/100;
357 Config_redbook_volume = (i*8)/100;
360 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
361 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
362 if ( Config_redbook_volume > 8 ) Config_redbook_volume = 8;
364 digi_set_volume( (Config_digi_volume*32768)/8, (Config_midi_volume*128)/8 );
366 printf( "DigiDeviceID: 0x%x\n", digi_driver_board );
367 printf( "DigiPort: 0x%x\n", digi_driver_port );
368 printf( "DigiIrq: 0x%x\n", digi_driver_irq );
369 printf( "DigiDma: 0x%x\n", digi_driver_dma );
370 printf( "MidiDeviceID: 0x%x\n", digi_midi_type );
371 printf( "MidiPort: 0x%x\n", digi_midi_port );
375 /*Config_midi_type = digi_midi_type;
376 Config_digi_type = digi_driver_board;
377 Config_digi_dma = digi_driver_dma;*/
380 if (digi_driver_board_16 > 0 && !FindArg("-no16bit") && digi_driver_board_16 != _GUS_16_ST) {
381 digi_driver_board = digi_driver_board_16;
382 digi_driver_dma = digi_driver_dma_16;
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;
409 infile = PHYSFSX_openReadBuffered("descentw.cfg");
411 while (!PHYSFS_eof(infile))
414 PHYSFSX_gets(infile, line);
416 while (isspace(*ptr))
419 token = strtok(ptr, "=");
420 value = strtok(NULL, "=");
421 if (!strcmp(token, joystick_min_str)) {
422 sscanf( value, "%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] );
424 else if (!strcmp(token, joystick_max_str)) {
425 sscanf( value, "%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] );
427 else if (!strcmp(token, joystick_cen_str)) {
428 sscanf( value, "%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] );
432 PHYSFS_close(infile);
439 int WriteConfigFile()
444 int joy_axis_center[7];
446 ubyte gamma = gr_palette_get_gamma();
448 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
453 joy_axis_min[i]=DOSJoySaveMin[i];
454 joy_axis_center[i]=DOSJoySaveCen[i];
455 joy_axis_max[i]=DOSJoySaveMax[i];
459 infile = PHYSFSX_openWriteBuffered("descent.cfg");
460 if (infile == NULL) {
463 /*sprintf (str, "%s=0x%x\n", digi_dev8_str, Config_digi_type);
464 PHYSFSX_puts(infile, str);
465 sprintf (str, "%s=0x%x\n", digi_dev16_str, digi_driver_board_16);
466 PHYSFSX_puts(infile, str);
467 sprintf (str, "%s=0x%x\n", digi_port_str, digi_driver_port);
468 PHYSFSX_puts(infile, str);
469 sprintf (str, "%s=%d\n", digi_irq_str, digi_driver_irq);
470 PHYSFSX_puts(infile, str);
471 sprintf (str, "%s=%d\n", digi_dma8_str, Config_digi_dma);
472 PHYSFSX_puts(infile, str);
473 sprintf (str, "%s=%d\n", digi_dma16_str, digi_driver_dma_16);
474 PHYSFSX_puts(infile, str);*/
475 sprintf (str, "%s=%d\n", digi_volume_str, Config_digi_volume);
476 PHYSFSX_puts(infile, str);
477 /*sprintf (str, "%s=0x%x\n", midi_dev_str, Config_midi_type);
478 PHYSFSX_puts(infile, str);
479 sprintf (str, "%s=0x%x\n", midi_port_str, digi_midi_port);
480 PHYSFSX_puts(infile, str);*/
481 sprintf (str, "%s=%d\n", midi_volume_str, Config_midi_volume);
482 PHYSFSX_puts(infile, str);
483 sprintf (str, "%s=%d\n", redbook_enabled_str, FindArg("-noredbook")?save_redbook_enabled:Redbook_enabled);
484 PHYSFSX_puts(infile, str);
485 sprintf (str, "%s=%d\n", redbook_volume_str, Config_redbook_volume);
486 PHYSFSX_puts(infile, str);
487 sprintf (str, "%s=%d\n", stereo_rev_str, Config_channels_reversed);
488 PHYSFSX_puts(infile, str);
489 sprintf (str, "%s=%d\n", gamma_level_str, gamma);
490 PHYSFSX_puts(infile, str);
491 if (Detail_level == NUM_DETAIL_LEVELS-1)
492 sprintf (str, "%s=%d,%d,%d,%d,%d,%d,%d\n", detail_level_str, Detail_level,
493 Object_complexity,Object_detail,Wall_detail,Wall_render_depth,Debris_amount,SoundChannels);
495 sprintf (str, "%s=%d\n", detail_level_str, Detail_level);
496 PHYSFSX_puts(infile, str);
498 sprintf (str, "%s=%d,%d,%d,%d\n", joystick_min_str, joy_axis_min[0], joy_axis_min[1], joy_axis_min[2], joy_axis_min[3] );
499 PHYSFSX_puts(infile, str);
500 sprintf (str, "%s=%d,%d,%d,%d\n", joystick_cen_str, joy_axis_center[0], joy_axis_center[1], joy_axis_center[2], joy_axis_center[3] );
501 PHYSFSX_puts(infile, str);
502 sprintf (str, "%s=%d,%d,%d,%d\n", joystick_max_str, joy_axis_max[0], joy_axis_max[1], joy_axis_max[2], joy_axis_max[3] );
503 PHYSFSX_puts(infile, str);
505 sprintf (str, "%s=%s\n", last_player_str, Players[Player_num].callsign );
506 PHYSFSX_puts(infile, str);
507 sprintf (str, "%s=%s\n", last_mission_str, config_last_mission );
508 PHYSFSX_puts(infile, str);
509 sprintf (str, "%s=%d\n", config_vr_type_str, Config_vr_type );
510 PHYSFSX_puts(infile, str);
511 sprintf (str, "%s=%d\n", config_vr_resolution_str, Config_vr_resolution );
512 PHYSFSX_puts(infile, str);
513 sprintf (str, "%s=%d\n", config_vr_tracking_str, Config_vr_tracking );
514 PHYSFSX_puts(infile, str);
515 sprintf (str, "%s=%d\n", movie_hires_str, (FindArg("-nohires") || FindArg("-nohighres") || FindArg("-lowresmovies"))?SaveMovieHires:MovieHires);
516 PHYSFSX_puts(infile, str);
518 PHYSFS_close(infile);
522 // Save Windows Config File
526 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
528 infile = PHYSFSX_openWriteBuffered("descentw.cfg");
529 if (infile == NULL) return 1;
531 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_min_str,
532 joy_axis_min[0], joy_axis_min[1], joy_axis_min[2], joy_axis_min[3],
533 joy_axis_min[4], joy_axis_min[5], joy_axis_min[6]);
535 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_cen_str,
536 joy_axis_center[0], joy_axis_center[1], joy_axis_center[2], joy_axis_center[3],
537 joy_axis_center[4], joy_axis_center[5], joy_axis_center[6]);
539 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_max_str,
540 joy_axis_max[0], joy_axis_max[1], joy_axis_max[2], joy_axis_max[3],
541 joy_axis_max[4], joy_axis_max[5], joy_axis_max[6]);
546 CheckMovieAttributes();
552 #else // !defined(MACINTOSH)
561 #include <GestaltEqu.h>
563 #include <Processes.h>
564 #include <Resources.h>
577 #include "prefs.h" // prefs file for configuration stuff -- from DeSalvo
580 static char rcsid[] = "$Id: config.c,v 1.17 2005-07-30 01:50:17 chris Exp $";
583 #define MAX_CTB_LEN 512
585 typedef struct preferences {
588 ubyte stereo_reverse;
590 ubyte oc; // object complexity
591 ubyte od; // object detail
592 ubyte wd; // wall detail
593 ubyte wrd; // wall render depth
594 ubyte da; // debris amount
595 ubyte sc; // sound channels
600 int joy_axis_center[4];
601 char lastplayer[CALLSIGN_LEN+1];
602 char lastmission[MISSION_NAME_LEN+1];
603 char ctb_config[MAX_CTB_LEN];
606 ubyte display_dialog;
607 ubyte change_resolution;
613 ubyte redbook_volume;
615 ubyte enable_input_sprockets;
618 char config_last_player[CALLSIGN_LEN+1] = "";
619 char config_last_mission[MISSION_NAME_LEN+1] = "";
620 char config_last_ctb_cfg[MAX_CTB_LEN] = "";
621 int config_last_ctb_tool;
622 ubyte Config_master_volume = 4;
623 ubyte Config_digi_volume = 8;
624 ubyte Config_midi_volume = 8;
625 ubyte Config_redbook_volume = 8;
626 ubyte Config_control_type = 0;
627 ubyte Config_channels_reversed = 0;
628 ubyte Config_joystick_sensitivity = 8;
630 int Config_vr_type = 0;
631 int Config_vr_resolution = 0;
632 int Config_vr_tracking = 0;
634 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
635 extern void digi_set_master_volume( int volume );
637 void set_custom_detail_vars(void);
639 static ubyte have_prefs = 0;
641 //¥ ------------------------------ Private Definitions
642 //¥ ------------------------------ Private Types
651 } PrefsInfo, *PrefsInfoPtr, **PrefsInfoHandle;
653 //¥ ------------------------------ Private Variables
655 static PrefsInfo prefsInfo;
656 static Boolean prefsInited = 0;
658 //¥ ------------------------------ Private Functions
660 static void Pstrcpy(StringPtr dst, StringPtr src);
661 static void Pstrcat(StringPtr dst, StringPtr src);
662 static Boolean FindPrefsFile(short *prefVRefNum, long *prefDirID);
664 //¥ -------------------- Pstrcpy
667 Pstrcpy(StringPtr dst, StringPtr src)
669 BlockMove(src, dst, (*src) + 1);
672 //¥ -------------------- Pstrcat
675 Pstrcat(StringPtr dst, StringPtr src)
677 BlockMove(src + 1, dst + (*dst) + 1, *src);
681 //¥ -------------------- FindPrefsFile
684 FindPrefsFile(short *prefVRefNum, long *prefDirID)
693 theErr = Gestalt(gestaltFindFolderAttr, &response);
694 if (theErr == noErr && ((response >> gestaltFindFolderPresent) & 1))
696 //¥ Find (or make) it the easy way...
697 theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, prefVRefNum, prefDirID);
702 StringPtr prefFolderName = "\pPreferences";
704 //¥ yeachh -- we have to do it all by hand!
705 theErr = SysEnvirons(1, &theSysEnv);
709 *prefVRefNum = theSysEnv.sysVRefNum;
711 //¥ Check whether Preferences folder already exists
712 infoPB.hFileInfo.ioCompletion = 0;
713 infoPB.hFileInfo.ioNamePtr = prefFolderName;
714 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
715 infoPB.hFileInfo.ioFDirIndex = 0;
716 infoPB.hFileInfo.ioDirID = 0;
718 theErr = PBGetCatInfo(&infoPB, 0);
721 *prefDirID = infoPB.hFileInfo.ioDirID;
723 else if (theErr == fnfErr) //¥ Preferences doesn't already exist
725 HParamBlockRec dirPB;
727 //¥ Create "Preferences" folder
728 dirPB.fileParam.ioCompletion = 0;
729 dirPB.fileParam.ioVRefNum = *prefVRefNum;
730 dirPB.fileParam.ioNamePtr = prefFolderName;
731 dirPB.fileParam.ioDirID = 0;
733 theErr = PBDirCreate(&dirPB, 0);
735 *prefDirID = dirPB.fileParam.ioDirID;
739 //¥ If we make it here OK, create Preferences file if necessary
742 infoPB.hFileInfo.ioCompletion = 0;
743 infoPB.hFileInfo.ioNamePtr = prefsInfo.fileName;
744 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
745 infoPB.hFileInfo.ioFDirIndex = 0;
746 infoPB.hFileInfo.ioDirID = *prefDirID;
748 theErr = PBGetCatInfo(&infoPB, 0);
749 if (theErr == fnfErr)
751 theErr = HCreate(*prefVRefNum, *prefDirID, prefsInfo.fileName, prefsInfo.creator, prefsInfo.fileType);
754 HCreateResFile(*prefVRefNum, *prefDirID, prefsInfo.fileName);
760 return (theErr == noErr);
763 //¥ -------------------- InitPrefsFile
765 #define UNKNOWN_TYPE 0x3f3f3f3f
768 InitPrefsFile(OSType creator)
771 PrefsInfoHandle piHdl;
773 if ((piHdl = (PrefsInfoHandle) GetResource('PRFI', 0)) == nil)
775 ProcessSerialNumber thePSN;
776 ProcessInfoRec thePIR;
778 StringPtr app_string;
781 GetCurrentProcess(&thePSN);
782 thePIR.processName = nil;
783 thePIR.processAppSpec = &appSpec;
785 //¥ Set default to 'ÇApplicationÈ Prefs', PREF 0
786 err = GetProcessInformation(&thePSN, &thePIR);
790 app_string = LMGetCurApName();
791 // Pstrcpy(prefsInfo.fileName, appSpec.name);
792 Pstrcpy(prefsInfo.fileName, app_string);
793 Pstrcat(prefsInfo.fileName, "\p Preferences");
795 //¥ Set creator to calling application's signature (should be able to
796 //¥ Determine this automatically, but unable to for some reason)
797 prefsInfo.creator = creator;
798 prefsInfo.fileType = 'pref';
799 prefsInfo.resType = 'pref';
804 //¥ Get Preferences file setup from PRFI 0
805 BlockMove(*piHdl, &prefsInfo, sizeof (prefsInfo));
806 ReleaseResource((Handle) piHdl);
808 if (prefsInfo.creator == UNKNOWN_TYPE)
809 prefsInfo.creator = creator;
815 //¥ -------------------- LoadPrefsFile
818 LoadPrefsFile(Handle prefsHdl)
820 short prefVRefNum, prefRefNum;
822 OSErr theErr = noErr;
824 Size prefSize, origSize;
827 return (nilHandleErr);
829 prefSize = GetHandleSize(prefsHdl);
831 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
834 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
835 if (prefRefNum == -1)
838 //¥ Not finding the resource is not an error -- caller will use default data
839 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
841 origSize = GetHandleSize(origHdl);
842 if (origSize > prefSize) //¥ Extend handle for extra stored data
843 SetHandleSize(prefsHdl, origSize);
845 BlockMove(*origHdl, *prefsHdl, origSize);
846 ReleaseResource(origHdl);
849 CloseResFile(prefRefNum);
857 //¥ -------------------- SavePrefsFile
860 SavePrefsFile(Handle prefHdl)
862 short prefVRefNum, prefRefNum;
864 Handle origHdl = nil;
865 Size origSize, prefSize;
866 OSErr theErr = noErr;
868 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
872 return (nilHandleErr);
874 prefSize = GetHandleSize(prefHdl);
876 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
877 if (prefRefNum == -1)
880 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
882 //¥ Overwrite existing preferences
883 origSize = GetHandleSize(origHdl);
884 if (prefSize > origSize)
885 SetHandleSize(origHdl, prefSize);
887 BlockMove(*prefHdl, *origHdl, prefSize);
888 ChangedResource(origHdl);
889 WriteResource(origHdl);
890 ReleaseResource(origHdl);
894 //¥ Store specified preferences for the first time
895 AddResource(prefHdl, prefsInfo.resType, prefsInfo.resID, "\p");
896 WriteResource(prefHdl);
897 DetachResource(prefHdl);
900 CloseResFile(prefRefNum);
908 //¥ -------------------------------------------------------------------------------------------
912 This module provides the ability to save and load a preferences file in the
913 Preferences folder in the System Folder. An optional resource, PRFI 0,
914 is used to provide specifications for the preferences file (creator, etc.).
916 Three functions are provided:
918 void InitPrefsFile(OSType creator)
920 This function will initialize the preferences file, that is, it will create
921 it in the appropriate place if it doesn't currently exist. It should be
922 called with the creator code for the application. Note that the creator
923 code specified in PRFI 0 (if any) will be used only if the creator code
924 passed to this function is '????'. Without the PRFI 0 resource, the default
927 File Name: "{Application} Prefs" (i.e., the name of the app plus " Prefs"
928 Creator: the creator passed to InitPrefsFile
930 Pref Resource Type: 'PREF'
933 The PRFI 0 resource allows you to specify overrides for each of the above
934 values. This is useful for development, since the application name might
935 go through changes, but the preferences file name is held constant.
937 OSErr LoadPrefsFile(Handle prefsHndl)
939 This function will attempt to copy the data stored in the preferences
940 file to the given handle (which must be pre-allocated). If the handle is too
941 small, then it will be enlarged. If it is too large, it will not be resized.
942 The data in the preferences file (normally in PREF 0) will then be copied
943 into the handle. If the preferences file did not exist, the original data
944 in the handle will not change.
946 OSErr SavePrefsFile(Handle prefsHndl)
948 This function will attempt to save the given handle to the preferences
949 file. Its contents will completely replace the previous data (normally
950 the PREF 0 resource).
952 In typical use, you will use InitPrefsFile once, then allocate a handle large
953 enough to contain your preferences data, and initialize it with default values.
954 Throughout the course of your program, the handle will undergo modification as
955 user preferences change. You can use SavePrefsFile anytime to update the
956 preferences file, or wait until program exit to do so.
968 if (!have_prefs) { // not initialized....get a handle to the preferences file
969 InitPrefsFile('DCT2');
973 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
974 if (prefs_handle == NULL)
977 prefs = (Preferences *)(*prefs_handle);
978 err = LoadPrefsFile(prefs_handle);
980 DisposeHandle(prefs_handle);
985 for (i = 0; i < sizeof(Preferences); i++) {
990 if ( i == sizeof(Preferences) )
993 Config_digi_volume = prefs->digi_volume;
994 Config_midi_volume = prefs->midi_volume;
995 Config_master_volume = prefs->master_volume;
996 Config_redbook_volume = prefs->redbook_volume;
997 Config_channels_reversed = prefs->stereo_reverse;
998 gr_palette_set_gamma( (int)(prefs->gamma_level) );
1000 Scanline_double = (int)prefs->pixel_double;
1002 Scanline_double = 0; // can't double with hardware acceleration
1004 Detail_level = prefs->detail_level;
1005 if (Detail_level == NUM_DETAIL_LEVELS-1) {
1006 Object_complexity = prefs->oc;
1007 Object_detail = prefs->od;
1008 Wall_detail = prefs->wd;
1009 Wall_render_depth = prefs->wrd;
1010 Debris_amount = prefs->da;
1011 SoundChannels = prefs->sc;
1012 set_custom_detail_vars();
1015 strncpy( config_last_player, prefs->lastplayer, CALLSIGN_LEN );
1016 p = strchr(config_last_player, '\n' );
1019 strncpy(config_last_mission, prefs->lastmission, MISSION_NAME_LEN);
1020 p = strchr(config_last_mission, '\n' );
1023 strcpy(config_last_ctb_cfg, prefs->ctb_config);
1025 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
1027 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
1029 joy_set_cal_vals( prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
1030 digi_set_volume( (Config_digi_volume*256)/8, (Config_midi_volume*256)/8 );
1031 digi_set_master_volume(Config_master_volume);
1033 gConfigInfo.mDoNotDisplayOptions = prefs->display_dialog;
1034 gConfigInfo.mUse11kSounds = prefs->sound_11k;
1035 gConfigInfo.mDisableSound = prefs->nosound;
1036 gConfigInfo.mDisableMIDIMusic = prefs->nomidi;
1037 gConfigInfo.mChangeResolution = prefs->change_resolution;
1038 gConfigInfo.mDoNotPlayMovies = prefs->no_movies;
1039 gConfigInfo.mGameMonitor = prefs->game_monitor;
1040 gConfigInfo.mAcceleration = prefs->enable_rave;
1041 gConfigInfo.mInputSprockets = prefs->enable_input_sprockets;
1043 DisposeHandle(prefs_handle);
1047 int WriteConfigFile()
1050 Handle prefs_handle;
1053 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
1054 if (prefs_handle == NULL)
1057 prefs = (Preferences *)(*prefs_handle);
1059 joy_get_cal_vals(prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
1060 prefs->digi_volume = Config_digi_volume;
1061 prefs->midi_volume = Config_midi_volume;
1062 prefs->stereo_reverse = Config_channels_reversed;
1063 prefs->detail_level = Detail_level;
1064 if (Detail_level == NUM_DETAIL_LEVELS-1) {
1065 prefs->oc = Object_complexity;
1066 prefs->od = Object_detail;
1067 prefs->wd = Wall_detail;
1068 prefs->wrd = Wall_render_depth;
1069 prefs->da = Debris_amount;
1070 prefs->sc = SoundChannels;
1072 prefs->gamma_level = (ubyte)gr_palette_get_gamma();
1075 prefs->pixel_double = (ubyte)Scanline_double; // hmm..don't write this out if doing hardware accel.
1077 strncpy( prefs->lastplayer, Players[Player_num].callsign, CALLSIGN_LEN );
1078 strncpy( prefs->lastmission, config_last_mission, MISSION_NAME_LEN );
1079 strcpy( prefs->ctb_config, config_last_ctb_cfg);
1080 prefs->ctb_tool = config_last_ctb_tool;
1081 prefs->master_volume = Config_master_volume;
1082 prefs->display_dialog = gConfigInfo.mDoNotDisplayOptions;
1083 prefs->change_resolution = gConfigInfo.mChangeResolution;
1084 prefs->nosound = gConfigInfo.mDisableSound;
1085 prefs->nomidi = gConfigInfo.mDisableMIDIMusic;
1086 prefs->sound_11k = gConfigInfo.mUse11kSounds;
1087 prefs->no_movies = gConfigInfo.mDoNotPlayMovies;
1088 prefs->game_monitor = gConfigInfo.mGameMonitor;
1089 prefs->redbook_volume = Config_redbook_volume;
1090 prefs->enable_rave = gConfigInfo.mAcceleration;
1091 prefs->enable_input_sprockets = gConfigInfo.mInputSprockets;
1093 err = SavePrefsFile(prefs_handle);
1094 DisposeHandle(prefs_handle);