1 /* $Id: config.c,v 1.13 2004-10-14 16:30:56 schaffner 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
59 static char rcsid[] = "$Id: config.c,v 1.13 2004-10-14 16:30:56 schaffner Exp $";
62 ubyte Config_digi_volume = 8;
63 ubyte Config_midi_volume = 8;
64 ubyte Config_redbook_volume = 8;
65 ubyte Config_control_type = 0;
66 ubyte Config_channels_reversed = 0;
67 ubyte Config_joystick_sensitivity = 8;
70 static char *digi_dev8_str = "DigiDeviceID8";
71 static char *digi_dev16_str = "DigiDeviceID16";
72 static char *digi_port_str = "DigiPort";
73 static char *digi_irq_str = "DigiIrq";
74 static char *digi_dma8_str = "DigiDma8";
75 static char *digi_dma16_str = "DigiDma16";
76 static char *midi_dev_str = "MidiDeviceID";
77 static char *midi_port_str = "MidiPort";
79 #define _CRYSTAL_LAKE_8_ST 0xe201
80 #define _CRYSTAL_LAKE_16_ST 0xe202
81 #define _AWE32_8_ST 0xe208
82 #define _AWE32_16_ST 0xe209
84 static char *digi_volume_str = "DigiVolume";
85 static char *midi_volume_str = "MidiVolume";
86 static char *redbook_enabled_str = "RedbookEnabled";
87 static char *redbook_volume_str = "RedbookVolume";
88 static char *detail_level_str = "DetailLevel";
89 static char *gamma_level_str = "GammaLevel";
90 static char *stereo_rev_str = "StereoReverse";
91 static char *joystick_min_str = "JoystickMin";
92 static char *joystick_max_str = "JoystickMax";
93 static char *joystick_cen_str = "JoystickCen";
94 static char *last_player_str = "LastPlayer";
95 static char *last_mission_str = "LastMission";
96 static char *config_vr_type_str = "VR_type";
97 static char *config_vr_resolution_str = "VR_resolution";
98 static char *config_vr_tracking_str = "VR_tracking";
99 static char *movie_hires_str = "MovieHires";
101 char config_last_player[CALLSIGN_LEN+1] = "";
102 char config_last_mission[MISSION_NAME_LEN+1] = "";
104 int Config_digi_type = 0;
105 int Config_digi_dma = 0;
106 int Config_midi_type = 0;
109 int DOSJoySaveMin[4];
110 int DOSJoySaveCen[4];
111 int DOSJoySaveMax[4];
113 char win95_current_joyname[256];
118 int Config_vr_type = 0;
119 int Config_vr_resolution = 0;
120 int Config_vr_tracking = 0;
122 int digi_driver_board_16;
123 int digi_driver_dma_16;
125 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
127 void set_custom_detail_vars(void);
133 void CrystalLakeWriteMCP( ushort mc_addr, ubyte mc_data )
136 outp( CL_MC0, 0xE2 ); // Write password
137 outp( mc_addr, mc_data ); // Write data
141 ubyte CrystalLakeReadMCP( ushort mc_addr )
145 outp( CL_MC0, 0xE2 ); // Write password
146 value = inp( mc_addr ); // Read data
151 void CrystalLakeSetSB()
154 tmp = CrystalLakeReadMCP( CL_MC1 );
156 CrystalLakeWriteMCP( CL_MC1, tmp );
159 void CrystalLakeSetWSS()
162 tmp = CrystalLakeReadMCP( CL_MC1 );
164 CrystalLakeWriteMCP( CL_MC1, tmp );
167 //MovieHires might be changed by -nohighres, so save a "real" copy of it
169 int save_redbook_enabled;
172 void CheckMovieAttributes()
175 DWORD len, type, val;
178 lres = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Parallax\\Descent II\\1.1\\INSTALL",
180 if (lres == ERROR_SUCCESS) {
182 lres = RegQueryValueEx(hKey, "HIRES", NULL, &type, &val, &len);
183 if (lres == ERROR_SUCCESS) {
185 logentry("HIRES=%d\n", val);
197 char line[80], *token, *value, *ptr;
200 int joy_axis_center[7];
204 strcpy( config_last_player, "" );
206 joy_axis_min[0] = joy_axis_min[1] = joy_axis_min[2] = joy_axis_min[3] = 0;
207 joy_axis_max[0] = joy_axis_max[1] = joy_axis_max[2] = joy_axis_max[3] = 0;
208 joy_axis_center[0] = joy_axis_center[1] = joy_axis_center[2] = joy_axis_center[3] = 0;
211 memset(&joy_axis_min[0], 0, sizeof(int)*7);
212 memset(&joy_axis_max[0], 0, sizeof(int)*7);
213 memset(&joy_axis_center[0], 0, sizeof(int)*7);
214 //@@ joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
216 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
219 /*digi_driver_board = 0;
220 digi_driver_port = 0;
225 digi_midi_port = 0;*/
227 Config_digi_volume = 8;
228 Config_midi_volume = 8;
229 Config_redbook_volume = 8;
230 Config_control_type = 0;
231 Config_channels_reversed = 0;
233 //set these here in case no cfg file
234 SaveMovieHires = MovieHires;
235 save_redbook_enabled = Redbook_enabled;
237 infile = cfopen("descent.cfg", "rt");
238 if (infile == NULL) {
239 WIN(CheckMovieAttributes());
242 while (!cfeof(infile))
245 cfgets(line, 80, infile);
247 while (isspace(*ptr))
250 token = strtok(ptr, "=");
251 value = strtok(NULL, "=");
254 /* if (!strcmp(token, digi_dev8_str))
255 digi_driver_board = strtol(value, NULL, 16);
256 else if (!strcmp(token, digi_dev16_str))
257 digi_driver_board_16 = strtol(value, NULL, 16);
258 else if (!strcmp(token, digi_port_str))
259 digi_driver_port = strtol(value, NULL, 16);
260 else if (!strcmp(token, digi_irq_str))
261 digi_driver_irq = strtol(value, NULL, 10);
262 else if (!strcmp(token, digi_dma8_str))
263 digi_driver_dma = strtol(value, NULL, 10);
264 else if (!strcmp(token, digi_dma16_str))
265 digi_driver_dma_16 = strtol(value, NULL, 10);
266 else*/ if (!strcmp(token, digi_volume_str))
267 Config_digi_volume = strtol(value, NULL, 10);
268 else/* if (!strcmp(token, midi_dev_str))
269 digi_midi_type = strtol(value, NULL, 16);
270 else if (!strcmp(token, midi_port_str))
271 digi_midi_port = strtol(value, NULL, 16);
272 else*/ if (!strcmp(token, midi_volume_str))
273 Config_midi_volume = strtol(value, NULL, 10);
274 else if (!strcmp(token, redbook_enabled_str))
275 Redbook_enabled = save_redbook_enabled = strtol(value, NULL, 10);
276 else if (!strcmp(token, redbook_volume_str))
277 Config_redbook_volume = strtol(value, NULL, 10);
278 else if (!strcmp(token, stereo_rev_str))
279 Config_channels_reversed = strtol(value, NULL, 10);
280 else if (!strcmp(token, gamma_level_str)) {
281 gamma = strtol(value, NULL, 10);
282 gr_palette_set_gamma( gamma );
284 else if (!strcmp(token, detail_level_str)) {
285 Detail_level = strtol(value, NULL, 10);
286 if (Detail_level == NUM_DETAIL_LEVELS-1) {
287 int count,dummy,oc,od,wd,wrd,da,sc;
289 count = sscanf (value, "%d,%d,%d,%d,%d,%d,%d\n",&dummy,&oc,&od,&wd,&wrd,&da,&sc);
292 Object_complexity = oc;
295 Wall_render_depth = wrd;
298 set_custom_detail_vars();
300 #ifdef PA_3DFX_VOODOO // Set to highest detail because you can't change em
301 Object_complexity=Object_detail=Wall_detail=
302 Wall_render_depth=Debris_amount=SoundChannels = NUM_DETAIL_LEVELS-1;
303 Detail_level=NUM_DETAIL_LEVELS-1;
304 set_custom_detail_vars();
308 else if (!strcmp(token, joystick_min_str)) {
309 sscanf( value, "%d,%d,%d,%d", &joy_axis_min[0], &joy_axis_min[1], &joy_axis_min[2], &joy_axis_min[3] );
311 else if (!strcmp(token, joystick_max_str)) {
312 sscanf( value, "%d,%d,%d,%d", &joy_axis_max[0], &joy_axis_max[1], &joy_axis_max[2], &joy_axis_max[3] );
314 else if (!strcmp(token, joystick_cen_str)) {
315 sscanf( value, "%d,%d,%d,%d", &joy_axis_center[0], &joy_axis_center[1], &joy_axis_center[2], &joy_axis_center[3] );
317 else if (!strcmp(token, last_player_str)) {
319 strncpy( config_last_player, value, CALLSIGN_LEN );
320 p = strchr( config_last_player, '\n');
323 else if (!strcmp(token, last_mission_str)) {
325 strncpy( config_last_mission, value, MISSION_NAME_LEN );
326 p = strchr( config_last_mission, '\n');
328 } else if (!strcmp(token, config_vr_type_str)) {
329 Config_vr_type = strtol(value, NULL, 10);
330 } else if (!strcmp(token, config_vr_resolution_str)) {
331 Config_vr_resolution = strtol(value, NULL, 10);
332 } else if (!strcmp(token, config_vr_tracking_str)) {
333 Config_vr_tracking = strtol(value, NULL, 10);
334 } else if (!strcmp(token, movie_hires_str)) {
335 SaveMovieHires = MovieHires = strtol(value, NULL, 10);
345 DOSJoySaveMin[i]=joy_axis_min[i];
346 DOSJoySaveCen[i]=joy_axis_center[i];
347 DOSJoySaveMax[i]=joy_axis_max[i];
350 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
353 i = FindArg( "-volume" );
356 i = atoi( Args[i+1] );
358 if ( i > 100 ) i = 100;
359 Config_digi_volume = (i*8)/100;
360 Config_midi_volume = (i*8)/100;
361 Config_redbook_volume = (i*8)/100;
364 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
365 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
366 if ( Config_redbook_volume > 8 ) Config_redbook_volume = 8;
368 digi_set_volume( (Config_digi_volume*32768)/8, (Config_midi_volume*128)/8 );
370 printf( "DigiDeviceID: 0x%x\n", digi_driver_board );
371 printf( "DigiPort: 0x%x\n", digi_driver_port );
372 printf( "DigiIrq: 0x%x\n", digi_driver_irq );
373 printf( "DigiDma: 0x%x\n", digi_driver_dma );
374 printf( "MidiDeviceID: 0x%x\n", digi_midi_type );
375 printf( "MidiPort: 0x%x\n", digi_midi_port );
379 /*Config_midi_type = digi_midi_type;
380 Config_digi_type = digi_driver_board;
381 Config_digi_dma = digi_driver_dma;*/
384 if (digi_driver_board_16 > 0 && !FindArg("-no16bit") && digi_driver_board_16 != _GUS_16_ST) {
385 digi_driver_board = digi_driver_board_16;
386 digi_driver_dma = digi_driver_dma_16;
390 //Hack to make some cards look like others, such as
391 //the Crytal Lake look like Microsoft Sound System
392 if ( digi_driver_board == _CRYSTAL_LAKE_8_ST ) {
394 tmp = CrystalLakeReadMCP( CL_MC1 );
396 atexit( CrystalLakeSetSB ); // Restore to SB when done.
398 digi_driver_board = _MICROSOFT_8_ST;
399 } else if ( digi_driver_board == _CRYSTAL_LAKE_16_ST ) {
401 tmp = CrystalLakeReadMCP( CL_MC1 );
403 atexit( CrystalLakeSetSB ); // Restore to SB when done.
405 digi_driver_board = _MICROSOFT_16_ST;
406 } else if ( digi_driver_board == _AWE32_8_ST ) {
407 digi_driver_board = _SB16_8_ST;
408 } else if ( digi_driver_board == _AWE32_16_ST ) {
409 digi_driver_board = _SB16_16_ST;
411 digi_driver_board = digi_driver_board;
413 infile = cfopen("descentw.cfg", "rt");
415 while (!cfeof(infile))
418 cfgets(line, 80, infile);
420 while (isspace(*ptr))
423 token = strtok(ptr, "=");
424 value = strtok(NULL, "=");
425 if (!strcmp(token, joystick_min_str)) {
426 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] );
428 else if (!strcmp(token, joystick_max_str)) {
429 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] );
431 else if (!strcmp(token, joystick_cen_str)) {
432 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] );
443 int WriteConfigFile()
448 int joy_axis_center[7];
450 ubyte gamma = gr_palette_get_gamma();
452 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
457 joy_axis_min[i]=DOSJoySaveMin[i];
458 joy_axis_center[i]=DOSJoySaveCen[i];
459 joy_axis_max[i]=DOSJoySaveMax[i];
463 infile = cfopen("descent.cfg", "wt");
464 if (infile == NULL) {
467 /*sprintf (str, "%s=0x%x\n", digi_dev8_str, Config_digi_type);
469 sprintf (str, "%s=0x%x\n", digi_dev16_str, digi_driver_board_16);
471 sprintf (str, "%s=0x%x\n", digi_port_str, digi_driver_port);
473 sprintf (str, "%s=%d\n", digi_irq_str, digi_driver_irq);
475 sprintf (str, "%s=%d\n", digi_dma8_str, Config_digi_dma);
477 sprintf (str, "%s=%d\n", digi_dma16_str, digi_driver_dma_16);
478 cfputs(str, infile);*/
479 sprintf (str, "%s=%d\n", digi_volume_str, Config_digi_volume);
481 /*sprintf (str, "%s=0x%x\n", midi_dev_str, Config_midi_type);
483 sprintf (str, "%s=0x%x\n", midi_port_str, digi_midi_port);
484 cfputs(str, infile);*/
485 sprintf (str, "%s=%d\n", midi_volume_str, Config_midi_volume);
487 sprintf (str, "%s=%d\n", redbook_enabled_str, FindArg("-noredbook")?save_redbook_enabled:Redbook_enabled);
489 sprintf (str, "%s=%d\n", redbook_volume_str, Config_redbook_volume);
491 sprintf (str, "%s=%d\n", stereo_rev_str, Config_channels_reversed);
493 sprintf (str, "%s=%d\n", gamma_level_str, gamma);
495 if (Detail_level == NUM_DETAIL_LEVELS-1)
496 sprintf (str, "%s=%d,%d,%d,%d,%d,%d,%d\n", detail_level_str, Detail_level,
497 Object_complexity,Object_detail,Wall_detail,Wall_render_depth,Debris_amount,SoundChannels);
499 sprintf (str, "%s=%d\n", detail_level_str, Detail_level);
502 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] );
504 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] );
506 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] );
509 sprintf (str, "%s=%s\n", last_player_str, Players[Player_num].callsign );
511 sprintf (str, "%s=%s\n", last_mission_str, config_last_mission );
513 sprintf (str, "%s=%d\n", config_vr_type_str, Config_vr_type );
515 sprintf (str, "%s=%d\n", config_vr_resolution_str, Config_vr_resolution );
517 sprintf (str, "%s=%d\n", config_vr_tracking_str, Config_vr_tracking );
519 sprintf (str, "%s=%d\n", movie_hires_str, (FindArg("-nohires") || FindArg("-nohighres") || FindArg("-lowresmovies"))?SaveMovieHires:MovieHires);
526 // Save Windows Config File
530 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
532 infile = cfopen("descentw.cfg", "wt");
533 if (infile == NULL) return 1;
535 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_min_str,
536 joy_axis_min[0], joy_axis_min[1], joy_axis_min[2], joy_axis_min[3],
537 joy_axis_min[4], joy_axis_min[5], joy_axis_min[6]);
539 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_cen_str,
540 joy_axis_center[0], joy_axis_center[1], joy_axis_center[2], joy_axis_center[3],
541 joy_axis_center[4], joy_axis_center[5], joy_axis_center[6]);
543 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_max_str,
544 joy_axis_max[0], joy_axis_max[1], joy_axis_max[2], joy_axis_max[3],
545 joy_axis_max[4], joy_axis_max[5], joy_axis_max[6]);
550 CheckMovieAttributes();
556 #else // !defined(MACINTOSH)
565 #include <GestaltEqu.h>
567 #include <Processes.h>
568 #include <Resources.h>
571 #include "pa_enabl.h" // because some prefs rely on this fact
582 #include "prefs.h" // prefs file for configuration stuff -- from DeSalvo
584 #if defined(POLY_ACC)
585 #include "poly_acc.h"
589 static char rcsid[] = "$Id: config.c,v 1.13 2004-10-14 16:30:56 schaffner Exp $";
592 #define MAX_CTB_LEN 512
594 typedef struct preferences {
597 ubyte stereo_reverse;
599 ubyte oc; // object complexity
600 ubyte od; // object detail
601 ubyte wd; // wall detail
602 ubyte wrd; // wall render depth
603 ubyte da; // debris amount
604 ubyte sc; // sound channels
609 int joy_axis_center[4];
610 char lastplayer[CALLSIGN_LEN+1];
611 char lastmission[MISSION_NAME_LEN+1];
612 char ctb_config[MAX_CTB_LEN];
615 ubyte display_dialog;
616 ubyte change_resolution;
622 ubyte redbook_volume;
624 ubyte enable_input_sprockets;
627 char config_last_player[CALLSIGN_LEN+1] = "";
628 char config_last_mission[MISSION_NAME_LEN+1] = "";
629 char config_last_ctb_cfg[MAX_CTB_LEN] = "";
630 int config_last_ctb_tool;
631 ubyte Config_master_volume = 4;
632 ubyte Config_digi_volume = 8;
633 ubyte Config_midi_volume = 8;
634 ubyte Config_redbook_volume = 8;
635 ubyte Config_control_type = 0;
636 ubyte Config_channels_reversed = 0;
637 ubyte Config_joystick_sensitivity = 8;
639 int Config_vr_type = 0;
640 int Config_vr_resolution = 0;
641 int Config_vr_tracking = 0;
643 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
644 extern void digi_set_master_volume( int volume );
646 void set_custom_detail_vars(void);
648 static ubyte have_prefs = 0;
650 //¥ ------------------------------ Private Definitions
651 //¥ ------------------------------ Private Types
660 } PrefsInfo, *PrefsInfoPtr, **PrefsInfoHandle;
662 //¥ ------------------------------ Private Variables
664 static PrefsInfo prefsInfo;
665 static Boolean prefsInited = 0;
667 //¥ ------------------------------ Private Functions
669 static void Pstrcpy(StringPtr dst, StringPtr src);
670 static void Pstrcat(StringPtr dst, StringPtr src);
671 static Boolean FindPrefsFile(short *prefVRefNum, long *prefDirID);
673 //¥ -------------------- Pstrcpy
676 Pstrcpy(StringPtr dst, StringPtr src)
678 BlockMove(src, dst, (*src) + 1);
681 //¥ -------------------- Pstrcat
684 Pstrcat(StringPtr dst, StringPtr src)
686 BlockMove(src + 1, dst + (*dst) + 1, *src);
690 //¥ -------------------- FindPrefsFile
693 FindPrefsFile(short *prefVRefNum, long *prefDirID)
702 theErr = Gestalt(gestaltFindFolderAttr, &response);
703 if (theErr == noErr && ((response >> gestaltFindFolderPresent) & 1))
705 //¥ Find (or make) it the easy way...
706 theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, prefVRefNum, prefDirID);
711 StringPtr prefFolderName = "\pPreferences";
713 //¥ yeachh -- we have to do it all by hand!
714 theErr = SysEnvirons(1, &theSysEnv);
718 *prefVRefNum = theSysEnv.sysVRefNum;
720 //¥ Check whether Preferences folder already exists
721 infoPB.hFileInfo.ioCompletion = 0;
722 infoPB.hFileInfo.ioNamePtr = prefFolderName;
723 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
724 infoPB.hFileInfo.ioFDirIndex = 0;
725 infoPB.hFileInfo.ioDirID = 0;
727 theErr = PBGetCatInfo(&infoPB, 0);
730 *prefDirID = infoPB.hFileInfo.ioDirID;
732 else if (theErr == fnfErr) //¥ Preferences doesn't already exist
734 HParamBlockRec dirPB;
736 //¥ Create "Preferences" folder
737 dirPB.fileParam.ioCompletion = 0;
738 dirPB.fileParam.ioVRefNum = *prefVRefNum;
739 dirPB.fileParam.ioNamePtr = prefFolderName;
740 dirPB.fileParam.ioDirID = 0;
742 theErr = PBDirCreate(&dirPB, 0);
744 *prefDirID = dirPB.fileParam.ioDirID;
748 //¥ If we make it here OK, create Preferences file if necessary
751 infoPB.hFileInfo.ioCompletion = 0;
752 infoPB.hFileInfo.ioNamePtr = prefsInfo.fileName;
753 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
754 infoPB.hFileInfo.ioFDirIndex = 0;
755 infoPB.hFileInfo.ioDirID = *prefDirID;
757 theErr = PBGetCatInfo(&infoPB, 0);
758 if (theErr == fnfErr)
760 theErr = HCreate(*prefVRefNum, *prefDirID, prefsInfo.fileName, prefsInfo.creator, prefsInfo.fileType);
763 HCreateResFile(*prefVRefNum, *prefDirID, prefsInfo.fileName);
769 return (theErr == noErr);
772 //¥ -------------------- InitPrefsFile
774 #define UNKNOWN_TYPE 0x3f3f3f3f
777 InitPrefsFile(OSType creator)
780 PrefsInfoHandle piHdl;
782 if ((piHdl = (PrefsInfoHandle) GetResource('PRFI', 0)) == nil)
784 ProcessSerialNumber thePSN;
785 ProcessInfoRec thePIR;
787 StringPtr app_string;
790 GetCurrentProcess(&thePSN);
791 thePIR.processName = nil;
792 thePIR.processAppSpec = &appSpec;
794 //¥ Set default to 'ÇApplicationÈ Prefs', PREF 0
795 err = GetProcessInformation(&thePSN, &thePIR);
799 app_string = LMGetCurApName();
800 // Pstrcpy(prefsInfo.fileName, appSpec.name);
801 Pstrcpy(prefsInfo.fileName, app_string);
802 Pstrcat(prefsInfo.fileName, "\p Preferences");
804 //¥ Set creator to calling application's signature (should be able to
805 //¥ Determine this automatically, but unable to for some reason)
806 prefsInfo.creator = creator;
807 prefsInfo.fileType = 'pref';
808 prefsInfo.resType = 'pref';
813 //¥ Get Preferences file setup from PRFI 0
814 BlockMove(*piHdl, &prefsInfo, sizeof (prefsInfo));
815 ReleaseResource((Handle) piHdl);
817 if (prefsInfo.creator == UNKNOWN_TYPE)
818 prefsInfo.creator = creator;
824 //¥ -------------------- LoadPrefsFile
827 LoadPrefsFile(Handle prefsHdl)
829 short prefVRefNum, prefRefNum;
831 OSErr theErr = noErr;
833 Size prefSize, origSize;
836 return (nilHandleErr);
838 prefSize = GetHandleSize(prefsHdl);
840 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
843 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
844 if (prefRefNum == -1)
847 //¥ Not finding the resource is not an error -- caller will use default data
848 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
850 origSize = GetHandleSize(origHdl);
851 if (origSize > prefSize) //¥ Extend handle for extra stored data
852 SetHandleSize(prefsHdl, origSize);
854 BlockMove(*origHdl, *prefsHdl, origSize);
855 ReleaseResource(origHdl);
858 CloseResFile(prefRefNum);
866 //¥ -------------------- SavePrefsFile
869 SavePrefsFile(Handle prefHdl)
871 short prefVRefNum, prefRefNum;
873 Handle origHdl = nil;
874 Size origSize, prefSize;
875 OSErr theErr = noErr;
877 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
881 return (nilHandleErr);
883 prefSize = GetHandleSize(prefHdl);
885 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
886 if (prefRefNum == -1)
889 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
891 //¥ Overwrite existing preferences
892 origSize = GetHandleSize(origHdl);
893 if (prefSize > origSize)
894 SetHandleSize(origHdl, prefSize);
896 BlockMove(*prefHdl, *origHdl, prefSize);
897 ChangedResource(origHdl);
898 WriteResource(origHdl);
899 ReleaseResource(origHdl);
903 //¥ Store specified preferences for the first time
904 AddResource(prefHdl, prefsInfo.resType, prefsInfo.resID, "\p");
905 WriteResource(prefHdl);
906 DetachResource(prefHdl);
909 CloseResFile(prefRefNum);
917 //¥ -------------------------------------------------------------------------------------------
921 This module provides the ability to save and load a preferences file in the
922 Preferences folder in the System Folder. An optional resource, PRFI 0,
923 is used to provide specifications for the preferences file (creator, etc.).
925 Three functions are provided:
927 void InitPrefsFile(OSType creator)
929 This function will initialize the preferences file, that is, it will create
930 it in the appropriate place if it doesn't currently exist. It should be
931 called with the creator code for the application. Note that the creator
932 code specified in PRFI 0 (if any) will be used only if the creator code
933 passed to this function is '????'. Without the PRFI 0 resource, the default
936 File Name: "{Application} Prefs" (i.e., the name of the app plus " Prefs"
937 Creator: the creator passed to InitPrefsFile
939 Pref Resource Type: 'PREF'
942 The PRFI 0 resource allows you to specify overrides for each of the above
943 values. This is useful for development, since the application name might
944 go through changes, but the preferences file name is held constant.
946 OSErr LoadPrefsFile(Handle prefsHndl)
948 This function will attempt to copy the data stored in the preferences
949 file to the given handle (which must be pre-allocated). If the handle is too
950 small, then it will be enlarged. If it is too large, it will not be resized.
951 The data in the preferences file (normally in PREF 0) will then be copied
952 into the handle. If the preferences file did not exist, the original data
953 in the handle will not change.
955 OSErr SavePrefsFile(Handle prefsHndl)
957 This function will attempt to save the given handle to the preferences
958 file. Its contents will completely replace the previous data (normally
959 the PREF 0 resource).
961 In typical use, you will use InitPrefsFile once, then allocate a handle large
962 enough to contain your preferences data, and initialize it with default values.
963 Throughout the course of your program, the handle will undergo modification as
964 user preferences change. You can use SavePrefsFile anytime to update the
965 preferences file, or wait until program exit to do so.
977 if (!have_prefs) { // not initialized....get a handle to the preferences file
978 InitPrefsFile('DCT2');
982 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
983 if (prefs_handle == NULL)
986 prefs = (Preferences *)(*prefs_handle);
987 err = LoadPrefsFile(prefs_handle);
989 DisposeHandle(prefs_handle);
994 for (i = 0; i < sizeof(Preferences); i++) {
999 if ( i == sizeof(Preferences) )
1002 Config_digi_volume = prefs->digi_volume;
1003 Config_midi_volume = prefs->midi_volume;
1004 Config_master_volume = prefs->master_volume;
1005 Config_redbook_volume = prefs->redbook_volume;
1006 Config_channels_reversed = prefs->stereo_reverse;
1007 gr_palette_set_gamma( (int)(prefs->gamma_level) );
1009 Scanline_double = (int)prefs->pixel_double;
1011 Scanline_double = 0; // can't double with hardware acceleration
1013 Detail_level = prefs->detail_level;
1014 if (Detail_level == NUM_DETAIL_LEVELS-1) {
1015 Object_complexity = prefs->oc;
1016 Object_detail = prefs->od;
1017 Wall_detail = prefs->wd;
1018 Wall_render_depth = prefs->wrd;
1019 Debris_amount = prefs->da;
1020 SoundChannels = prefs->sc;
1021 set_custom_detail_vars();
1023 #ifdef PA_3DFX_VOODOO // Set to highest detail because you can't change em
1024 Object_complexity=Object_detail=Wall_detail=
1025 Wall_render_depth=Debris_amount=SoundChannels = NUM_DETAIL_LEVELS-1;
1026 Detail_level=NUM_DETAIL_LEVELS-1;
1027 set_custom_detail_vars();
1030 strncpy( config_last_player, prefs->lastplayer, CALLSIGN_LEN );
1031 p = strchr(config_last_player, '\n' );
1034 strncpy(config_last_mission, prefs->lastmission, MISSION_NAME_LEN);
1035 p = strchr(config_last_mission, '\n' );
1038 strcpy(config_last_ctb_cfg, prefs->ctb_config);
1040 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
1042 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
1044 joy_set_cal_vals( prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
1045 digi_set_volume( (Config_digi_volume*256)/8, (Config_midi_volume*256)/8 );
1046 digi_set_master_volume(Config_master_volume);
1048 gConfigInfo.mDoNotDisplayOptions = prefs->display_dialog;
1049 gConfigInfo.mUse11kSounds = prefs->sound_11k;
1050 gConfigInfo.mDisableSound = prefs->nosound;
1051 gConfigInfo.mDisableMIDIMusic = prefs->nomidi;
1052 gConfigInfo.mChangeResolution = prefs->change_resolution;
1053 gConfigInfo.mDoNotPlayMovies = prefs->no_movies;
1054 gConfigInfo.mGameMonitor = prefs->game_monitor;
1055 gConfigInfo.mAcceleration = prefs->enable_rave;
1056 gConfigInfo.mInputSprockets = prefs->enable_input_sprockets;
1058 DisposeHandle(prefs_handle);
1062 int WriteConfigFile()
1065 Handle prefs_handle;
1068 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
1069 if (prefs_handle == NULL)
1072 prefs = (Preferences *)(*prefs_handle);
1074 joy_get_cal_vals(prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
1075 prefs->digi_volume = Config_digi_volume;
1076 prefs->midi_volume = Config_midi_volume;
1077 prefs->stereo_reverse = Config_channels_reversed;
1078 prefs->detail_level = Detail_level;
1079 if (Detail_level == NUM_DETAIL_LEVELS-1) {
1080 prefs->oc = Object_complexity;
1081 prefs->od = Object_detail;
1082 prefs->wd = Wall_detail;
1083 prefs->wrd = Wall_render_depth;
1084 prefs->da = Debris_amount;
1085 prefs->sc = SoundChannels;
1087 prefs->gamma_level = (ubyte)gr_palette_get_gamma();
1090 prefs->pixel_double = (ubyte)Scanline_double; // hmm..don't write this out if doing hardware accel.
1092 strncpy( prefs->lastplayer, Players[Player_num].callsign, CALLSIGN_LEN );
1093 strncpy( prefs->lastmission, config_last_mission, MISSION_NAME_LEN );
1094 strcpy( prefs->ctb_config, config_last_ctb_cfg);
1095 prefs->ctb_tool = config_last_ctb_tool;
1096 prefs->master_volume = Config_master_volume;
1097 prefs->display_dialog = gConfigInfo.mDoNotDisplayOptions;
1098 prefs->change_resolution = gConfigInfo.mChangeResolution;
1099 prefs->nosound = gConfigInfo.mDisableSound;
1100 prefs->nomidi = gConfigInfo.mDisableMIDIMusic;
1101 prefs->sound_11k = gConfigInfo.mUse11kSounds;
1102 prefs->no_movies = gConfigInfo.mDoNotPlayMovies;
1103 prefs->game_monitor = gConfigInfo.mGameMonitor;
1104 prefs->redbook_volume = Config_redbook_volume;
1105 prefs->enable_rave = gConfigInfo.mAcceleration;
1106 prefs->enable_input_sprockets = gConfigInfo.mInputSprockets;
1108 err = SavePrefsFile(prefs_handle);
1109 DisposeHandle(prefs_handle);