1 /* $Id: config.c,v 1.12 2004-08-29 17:57:23 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.12 2004-08-29 17:57:23 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, "=");
252 /* if (!strcmp(token, digi_dev8_str))
253 digi_driver_board = strtol(value, NULL, 16);
254 else if (!strcmp(token, digi_dev16_str))
255 digi_driver_board_16 = strtol(value, NULL, 16);
256 else if (!strcmp(token, digi_port_str))
257 digi_driver_port = strtol(value, NULL, 16);
258 else if (!strcmp(token, digi_irq_str))
259 digi_driver_irq = strtol(value, NULL, 10);
260 else if (!strcmp(token, digi_dma8_str))
261 digi_driver_dma = strtol(value, NULL, 10);
262 else if (!strcmp(token, digi_dma16_str))
263 digi_driver_dma_16 = strtol(value, NULL, 10);
264 else*/ if (!strcmp(token, digi_volume_str))
265 Config_digi_volume = strtol(value, NULL, 10);
266 else/* if (!strcmp(token, midi_dev_str))
267 digi_midi_type = strtol(value, NULL, 16);
268 else if (!strcmp(token, midi_port_str))
269 digi_midi_port = strtol(value, NULL, 16);
270 else*/ if (!strcmp(token, midi_volume_str))
271 Config_midi_volume = strtol(value, NULL, 10);
272 else if (!strcmp(token, redbook_enabled_str))
273 Redbook_enabled = save_redbook_enabled = strtol(value, NULL, 10);
274 else if (!strcmp(token, redbook_volume_str))
275 Config_redbook_volume = strtol(value, NULL, 10);
276 else if (!strcmp(token, stereo_rev_str))
277 Config_channels_reversed = strtol(value, NULL, 10);
278 else if (!strcmp(token, gamma_level_str)) {
279 gamma = strtol(value, NULL, 10);
280 gr_palette_set_gamma( gamma );
282 else if (!strcmp(token, detail_level_str)) {
283 Detail_level = strtol(value, NULL, 10);
284 if (Detail_level == NUM_DETAIL_LEVELS-1) {
285 int count,dummy,oc,od,wd,wrd,da,sc;
287 count = sscanf (value, "%d,%d,%d,%d,%d,%d,%d\n",&dummy,&oc,&od,&wd,&wrd,&da,&sc);
290 Object_complexity = oc;
293 Wall_render_depth = wrd;
296 set_custom_detail_vars();
298 #ifdef PA_3DFX_VOODOO // Set to highest detail because you can't change em
299 Object_complexity=Object_detail=Wall_detail=
300 Wall_render_depth=Debris_amount=SoundChannels = NUM_DETAIL_LEVELS-1;
301 Detail_level=NUM_DETAIL_LEVELS-1;
302 set_custom_detail_vars();
306 else if (!strcmp(token, joystick_min_str)) {
307 sscanf( value, "%d,%d,%d,%d", &joy_axis_min[0], &joy_axis_min[1], &joy_axis_min[2], &joy_axis_min[3] );
309 else if (!strcmp(token, joystick_max_str)) {
310 sscanf( value, "%d,%d,%d,%d", &joy_axis_max[0], &joy_axis_max[1], &joy_axis_max[2], &joy_axis_max[3] );
312 else if (!strcmp(token, joystick_cen_str)) {
313 sscanf( value, "%d,%d,%d,%d", &joy_axis_center[0], &joy_axis_center[1], &joy_axis_center[2], &joy_axis_center[3] );
315 else if (!strcmp(token, last_player_str)) {
317 strncpy( config_last_player, value, CALLSIGN_LEN );
318 p = strchr( config_last_player, '\n');
321 else if (!strcmp(token, last_mission_str)) {
323 strncpy( config_last_mission, value, MISSION_NAME_LEN );
324 p = strchr( config_last_mission, '\n');
326 } else if (!strcmp(token, config_vr_type_str)) {
327 Config_vr_type = strtol(value, NULL, 10);
328 } else if (!strcmp(token, config_vr_resolution_str)) {
329 Config_vr_resolution = strtol(value, NULL, 10);
330 } else if (!strcmp(token, config_vr_tracking_str)) {
331 Config_vr_tracking = strtol(value, NULL, 10);
332 } else if (!strcmp(token, movie_hires_str)) {
333 SaveMovieHires = MovieHires = strtol(value, NULL, 10);
343 DOSJoySaveMin[i]=joy_axis_min[i];
344 DOSJoySaveCen[i]=joy_axis_center[i];
345 DOSJoySaveMax[i]=joy_axis_max[i];
348 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
351 i = FindArg( "-volume" );
354 i = atoi( Args[i+1] );
356 if ( i > 100 ) i = 100;
357 Config_digi_volume = (i*8)/100;
358 Config_midi_volume = (i*8)/100;
359 Config_redbook_volume = (i*8)/100;
362 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
363 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
364 if ( Config_redbook_volume > 8 ) Config_redbook_volume = 8;
366 digi_set_volume( (Config_digi_volume*32768)/8, (Config_midi_volume*128)/8 );
368 printf( "DigiDeviceID: 0x%x\n", digi_driver_board );
369 printf( "DigiPort: 0x%x\n", digi_driver_port );
370 printf( "DigiIrq: 0x%x\n", digi_driver_irq );
371 printf( "DigiDma: 0x%x\n", digi_driver_dma );
372 printf( "MidiDeviceID: 0x%x\n", digi_midi_type );
373 printf( "MidiPort: 0x%x\n", digi_midi_port );
377 /*Config_midi_type = digi_midi_type;
378 Config_digi_type = digi_driver_board;
379 Config_digi_dma = digi_driver_dma;*/
382 if (digi_driver_board_16 > 0 && !FindArg("-no16bit") && digi_driver_board_16 != _GUS_16_ST) {
383 digi_driver_board = digi_driver_board_16;
384 digi_driver_dma = digi_driver_dma_16;
388 //Hack to make some cards look like others, such as
389 //the Crytal Lake look like Microsoft Sound System
390 if ( digi_driver_board == _CRYSTAL_LAKE_8_ST ) {
392 tmp = CrystalLakeReadMCP( CL_MC1 );
394 atexit( CrystalLakeSetSB ); // Restore to SB when done.
396 digi_driver_board = _MICROSOFT_8_ST;
397 } else if ( digi_driver_board == _CRYSTAL_LAKE_16_ST ) {
399 tmp = CrystalLakeReadMCP( CL_MC1 );
401 atexit( CrystalLakeSetSB ); // Restore to SB when done.
403 digi_driver_board = _MICROSOFT_16_ST;
404 } else if ( digi_driver_board == _AWE32_8_ST ) {
405 digi_driver_board = _SB16_8_ST;
406 } else if ( digi_driver_board == _AWE32_16_ST ) {
407 digi_driver_board = _SB16_16_ST;
409 digi_driver_board = digi_driver_board;
411 infile = cfopen("descentw.cfg", "rt");
413 while (!cfeof(infile))
416 cfgets(line, 80, infile);
418 while (isspace(*ptr))
421 token = strtok(ptr, "=");
422 value = strtok(NULL, "=");
423 if (!strcmp(token, joystick_min_str)) {
424 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] );
426 else if (!strcmp(token, joystick_max_str)) {
427 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] );
429 else if (!strcmp(token, joystick_cen_str)) {
430 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] );
441 int WriteConfigFile()
446 int joy_axis_center[7];
448 ubyte gamma = gr_palette_get_gamma();
450 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
455 joy_axis_min[i]=DOSJoySaveMin[i];
456 joy_axis_center[i]=DOSJoySaveCen[i];
457 joy_axis_max[i]=DOSJoySaveMax[i];
461 infile = cfopen("descent.cfg", "wt");
462 if (infile == NULL) {
465 /*sprintf (str, "%s=0x%x\n", digi_dev8_str, Config_digi_type);
467 sprintf (str, "%s=0x%x\n", digi_dev16_str, digi_driver_board_16);
469 sprintf (str, "%s=0x%x\n", digi_port_str, digi_driver_port);
471 sprintf (str, "%s=%d\n", digi_irq_str, digi_driver_irq);
473 sprintf (str, "%s=%d\n", digi_dma8_str, Config_digi_dma);
475 sprintf (str, "%s=%d\n", digi_dma16_str, digi_driver_dma_16);
476 cfputs(str, infile);*/
477 sprintf (str, "%s=%d\n", digi_volume_str, Config_digi_volume);
479 /*sprintf (str, "%s=0x%x\n", midi_dev_str, Config_midi_type);
481 sprintf (str, "%s=0x%x\n", midi_port_str, digi_midi_port);
482 cfputs(str, infile);*/
483 sprintf (str, "%s=%d\n", midi_volume_str, Config_midi_volume);
485 sprintf (str, "%s=%d\n", redbook_enabled_str, FindArg("-noredbook")?save_redbook_enabled:Redbook_enabled);
487 sprintf (str, "%s=%d\n", redbook_volume_str, Config_redbook_volume);
489 sprintf (str, "%s=%d\n", stereo_rev_str, Config_channels_reversed);
491 sprintf (str, "%s=%d\n", gamma_level_str, gamma);
493 if (Detail_level == NUM_DETAIL_LEVELS-1)
494 sprintf (str, "%s=%d,%d,%d,%d,%d,%d,%d\n", detail_level_str, Detail_level,
495 Object_complexity,Object_detail,Wall_detail,Wall_render_depth,Debris_amount,SoundChannels);
497 sprintf (str, "%s=%d\n", detail_level_str, Detail_level);
500 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] );
502 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] );
504 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] );
507 sprintf (str, "%s=%s\n", last_player_str, Players[Player_num].callsign );
509 sprintf (str, "%s=%s\n", last_mission_str, config_last_mission );
511 sprintf (str, "%s=%d\n", config_vr_type_str, Config_vr_type );
513 sprintf (str, "%s=%d\n", config_vr_resolution_str, Config_vr_resolution );
515 sprintf (str, "%s=%d\n", config_vr_tracking_str, Config_vr_tracking );
517 sprintf (str, "%s=%d\n", movie_hires_str, (FindArg("-nohires") || FindArg("-nohighres") || FindArg("-lowresmovies"))?SaveMovieHires:MovieHires);
524 // Save Windows Config File
528 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
530 infile = cfopen("descentw.cfg", "wt");
531 if (infile == NULL) return 1;
533 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_min_str,
534 joy_axis_min[0], joy_axis_min[1], joy_axis_min[2], joy_axis_min[3],
535 joy_axis_min[4], joy_axis_min[5], joy_axis_min[6]);
537 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_cen_str,
538 joy_axis_center[0], joy_axis_center[1], joy_axis_center[2], joy_axis_center[3],
539 joy_axis_center[4], joy_axis_center[5], joy_axis_center[6]);
541 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_max_str,
542 joy_axis_max[0], joy_axis_max[1], joy_axis_max[2], joy_axis_max[3],
543 joy_axis_max[4], joy_axis_max[5], joy_axis_max[6]);
548 CheckMovieAttributes();
554 #else // !defined(MACINTOSH)
563 #include <GestaltEqu.h>
565 #include <Processes.h>
566 #include <Resources.h>
569 #include "pa_enabl.h" // because some prefs rely on this fact
580 #include "prefs.h" // prefs file for configuration stuff -- from DeSalvo
582 #if defined(POLY_ACC)
583 #include "poly_acc.h"
587 static char rcsid[] = "$Id: config.c,v 1.12 2004-08-29 17:57:23 schaffner Exp $";
590 #define MAX_CTB_LEN 512
592 typedef struct preferences {
595 ubyte stereo_reverse;
597 ubyte oc; // object complexity
598 ubyte od; // object detail
599 ubyte wd; // wall detail
600 ubyte wrd; // wall render depth
601 ubyte da; // debris amount
602 ubyte sc; // sound channels
607 int joy_axis_center[4];
608 char lastplayer[CALLSIGN_LEN+1];
609 char lastmission[MISSION_NAME_LEN+1];
610 char ctb_config[MAX_CTB_LEN];
613 ubyte display_dialog;
614 ubyte change_resolution;
620 ubyte redbook_volume;
622 ubyte enable_input_sprockets;
625 char config_last_player[CALLSIGN_LEN+1] = "";
626 char config_last_mission[MISSION_NAME_LEN+1] = "";
627 char config_last_ctb_cfg[MAX_CTB_LEN] = "";
628 int config_last_ctb_tool;
629 ubyte Config_master_volume = 4;
630 ubyte Config_digi_volume = 8;
631 ubyte Config_midi_volume = 8;
632 ubyte Config_redbook_volume = 8;
633 ubyte Config_control_type = 0;
634 ubyte Config_channels_reversed = 0;
635 ubyte Config_joystick_sensitivity = 8;
637 int Config_vr_type = 0;
638 int Config_vr_resolution = 0;
639 int Config_vr_tracking = 0;
641 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
642 extern void digi_set_master_volume( int volume );
644 void set_custom_detail_vars(void);
646 static ubyte have_prefs = 0;
648 //¥ ------------------------------ Private Definitions
649 //¥ ------------------------------ Private Types
658 } PrefsInfo, *PrefsInfoPtr, **PrefsInfoHandle;
660 //¥ ------------------------------ Private Variables
662 static PrefsInfo prefsInfo;
663 static Boolean prefsInited = 0;
665 //¥ ------------------------------ Private Functions
667 static void Pstrcpy(StringPtr dst, StringPtr src);
668 static void Pstrcat(StringPtr dst, StringPtr src);
669 static Boolean FindPrefsFile(short *prefVRefNum, long *prefDirID);
671 //¥ -------------------- Pstrcpy
674 Pstrcpy(StringPtr dst, StringPtr src)
676 BlockMove(src, dst, (*src) + 1);
679 //¥ -------------------- Pstrcat
682 Pstrcat(StringPtr dst, StringPtr src)
684 BlockMove(src + 1, dst + (*dst) + 1, *src);
688 //¥ -------------------- FindPrefsFile
691 FindPrefsFile(short *prefVRefNum, long *prefDirID)
700 theErr = Gestalt(gestaltFindFolderAttr, &response);
701 if (theErr == noErr && ((response >> gestaltFindFolderPresent) & 1))
703 //¥ Find (or make) it the easy way...
704 theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, prefVRefNum, prefDirID);
709 StringPtr prefFolderName = "\pPreferences";
711 //¥ yeachh -- we have to do it all by hand!
712 theErr = SysEnvirons(1, &theSysEnv);
716 *prefVRefNum = theSysEnv.sysVRefNum;
718 //¥ Check whether Preferences folder already exists
719 infoPB.hFileInfo.ioCompletion = 0;
720 infoPB.hFileInfo.ioNamePtr = prefFolderName;
721 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
722 infoPB.hFileInfo.ioFDirIndex = 0;
723 infoPB.hFileInfo.ioDirID = 0;
725 theErr = PBGetCatInfo(&infoPB, 0);
728 *prefDirID = infoPB.hFileInfo.ioDirID;
730 else if (theErr == fnfErr) //¥ Preferences doesn't already exist
732 HParamBlockRec dirPB;
734 //¥ Create "Preferences" folder
735 dirPB.fileParam.ioCompletion = 0;
736 dirPB.fileParam.ioVRefNum = *prefVRefNum;
737 dirPB.fileParam.ioNamePtr = prefFolderName;
738 dirPB.fileParam.ioDirID = 0;
740 theErr = PBDirCreate(&dirPB, 0);
742 *prefDirID = dirPB.fileParam.ioDirID;
746 //¥ If we make it here OK, create Preferences file if necessary
749 infoPB.hFileInfo.ioCompletion = 0;
750 infoPB.hFileInfo.ioNamePtr = prefsInfo.fileName;
751 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
752 infoPB.hFileInfo.ioFDirIndex = 0;
753 infoPB.hFileInfo.ioDirID = *prefDirID;
755 theErr = PBGetCatInfo(&infoPB, 0);
756 if (theErr == fnfErr)
758 theErr = HCreate(*prefVRefNum, *prefDirID, prefsInfo.fileName, prefsInfo.creator, prefsInfo.fileType);
761 HCreateResFile(*prefVRefNum, *prefDirID, prefsInfo.fileName);
767 return (theErr == noErr);
770 //¥ -------------------- InitPrefsFile
772 #define UNKNOWN_TYPE 0x3f3f3f3f
775 InitPrefsFile(OSType creator)
778 PrefsInfoHandle piHdl;
780 if ((piHdl = (PrefsInfoHandle) GetResource('PRFI', 0)) == nil)
782 ProcessSerialNumber thePSN;
783 ProcessInfoRec thePIR;
785 StringPtr app_string;
788 GetCurrentProcess(&thePSN);
789 thePIR.processName = nil;
790 thePIR.processAppSpec = &appSpec;
792 //¥ Set default to 'ÇApplicationÈ Prefs', PREF 0
793 err = GetProcessInformation(&thePSN, &thePIR);
797 app_string = LMGetCurApName();
798 // Pstrcpy(prefsInfo.fileName, appSpec.name);
799 Pstrcpy(prefsInfo.fileName, app_string);
800 Pstrcat(prefsInfo.fileName, "\p Preferences");
802 //¥ Set creator to calling application's signature (should be able to
803 //¥ Determine this automatically, but unable to for some reason)
804 prefsInfo.creator = creator;
805 prefsInfo.fileType = 'pref';
806 prefsInfo.resType = 'pref';
811 //¥ Get Preferences file setup from PRFI 0
812 BlockMove(*piHdl, &prefsInfo, sizeof (prefsInfo));
813 ReleaseResource((Handle) piHdl);
815 if (prefsInfo.creator == UNKNOWN_TYPE)
816 prefsInfo.creator = creator;
822 //¥ -------------------- LoadPrefsFile
825 LoadPrefsFile(Handle prefsHdl)
827 short prefVRefNum, prefRefNum;
829 OSErr theErr = noErr;
831 Size prefSize, origSize;
834 return (nilHandleErr);
836 prefSize = GetHandleSize(prefsHdl);
838 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
841 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
842 if (prefRefNum == -1)
845 //¥ Not finding the resource is not an error -- caller will use default data
846 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
848 origSize = GetHandleSize(origHdl);
849 if (origSize > prefSize) //¥ Extend handle for extra stored data
850 SetHandleSize(prefsHdl, origSize);
852 BlockMove(*origHdl, *prefsHdl, origSize);
853 ReleaseResource(origHdl);
856 CloseResFile(prefRefNum);
864 //¥ -------------------- SavePrefsFile
867 SavePrefsFile(Handle prefHdl)
869 short prefVRefNum, prefRefNum;
871 Handle origHdl = nil;
872 Size origSize, prefSize;
873 OSErr theErr = noErr;
875 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
879 return (nilHandleErr);
881 prefSize = GetHandleSize(prefHdl);
883 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
884 if (prefRefNum == -1)
887 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
889 //¥ Overwrite existing preferences
890 origSize = GetHandleSize(origHdl);
891 if (prefSize > origSize)
892 SetHandleSize(origHdl, prefSize);
894 BlockMove(*prefHdl, *origHdl, prefSize);
895 ChangedResource(origHdl);
896 WriteResource(origHdl);
897 ReleaseResource(origHdl);
901 //¥ Store specified preferences for the first time
902 AddResource(prefHdl, prefsInfo.resType, prefsInfo.resID, "\p");
903 WriteResource(prefHdl);
904 DetachResource(prefHdl);
907 CloseResFile(prefRefNum);
915 //¥ -------------------------------------------------------------------------------------------
919 This module provides the ability to save and load a preferences file in the
920 Preferences folder in the System Folder. An optional resource, PRFI 0,
921 is used to provide specifications for the preferences file (creator, etc.).
923 Three functions are provided:
925 void InitPrefsFile(OSType creator)
927 This function will initialize the preferences file, that is, it will create
928 it in the appropriate place if it doesn't currently exist. It should be
929 called with the creator code for the application. Note that the creator
930 code specified in PRFI 0 (if any) will be used only if the creator code
931 passed to this function is '????'. Without the PRFI 0 resource, the default
934 File Name: "{Application} Prefs" (i.e., the name of the app plus " Prefs"
935 Creator: the creator passed to InitPrefsFile
937 Pref Resource Type: 'PREF'
940 The PRFI 0 resource allows you to specify overrides for each of the above
941 values. This is useful for development, since the application name might
942 go through changes, but the preferences file name is held constant.
944 OSErr LoadPrefsFile(Handle prefsHndl)
946 This function will attempt to copy the data stored in the preferences
947 file to the given handle (which must be pre-allocated). If the handle is too
948 small, then it will be enlarged. If it is too large, it will not be resized.
949 The data in the preferences file (normally in PREF 0) will then be copied
950 into the handle. If the preferences file did not exist, the original data
951 in the handle will not change.
953 OSErr SavePrefsFile(Handle prefsHndl)
955 This function will attempt to save the given handle to the preferences
956 file. Its contents will completely replace the previous data (normally
957 the PREF 0 resource).
959 In typical use, you will use InitPrefsFile once, then allocate a handle large
960 enough to contain your preferences data, and initialize it with default values.
961 Throughout the course of your program, the handle will undergo modification as
962 user preferences change. You can use SavePrefsFile anytime to update the
963 preferences file, or wait until program exit to do so.
975 if (!have_prefs) { // not initialized....get a handle to the preferences file
976 InitPrefsFile('DCT2');
980 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
981 if (prefs_handle == NULL)
984 prefs = (Preferences *)(*prefs_handle);
985 err = LoadPrefsFile(prefs_handle);
987 DisposeHandle(prefs_handle);
992 for (i = 0; i < sizeof(Preferences); i++) {
997 if ( i == sizeof(Preferences) )
1000 Config_digi_volume = prefs->digi_volume;
1001 Config_midi_volume = prefs->midi_volume;
1002 Config_master_volume = prefs->master_volume;
1003 Config_redbook_volume = prefs->redbook_volume;
1004 Config_channels_reversed = prefs->stereo_reverse;
1005 gr_palette_set_gamma( (int)(prefs->gamma_level) );
1007 Scanline_double = (int)prefs->pixel_double;
1009 Scanline_double = 0; // can't double with hardware acceleration
1011 Detail_level = prefs->detail_level;
1012 if (Detail_level == NUM_DETAIL_LEVELS-1) {
1013 Object_complexity = prefs->oc;
1014 Object_detail = prefs->od;
1015 Wall_detail = prefs->wd;
1016 Wall_render_depth = prefs->wrd;
1017 Debris_amount = prefs->da;
1018 SoundChannels = prefs->sc;
1019 set_custom_detail_vars();
1021 #ifdef PA_3DFX_VOODOO // Set to highest detail because you can't change em
1022 Object_complexity=Object_detail=Wall_detail=
1023 Wall_render_depth=Debris_amount=SoundChannels = NUM_DETAIL_LEVELS-1;
1024 Detail_level=NUM_DETAIL_LEVELS-1;
1025 set_custom_detail_vars();
1028 strncpy( config_last_player, prefs->lastplayer, CALLSIGN_LEN );
1029 p = strchr(config_last_player, '\n' );
1032 strncpy(config_last_mission, prefs->lastmission, MISSION_NAME_LEN);
1033 p = strchr(config_last_mission, '\n' );
1036 strcpy(config_last_ctb_cfg, prefs->ctb_config);
1038 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
1040 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
1042 joy_set_cal_vals( prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
1043 digi_set_volume( (Config_digi_volume*256)/8, (Config_midi_volume*256)/8 );
1044 digi_set_master_volume(Config_master_volume);
1046 gConfigInfo.mDoNotDisplayOptions = prefs->display_dialog;
1047 gConfigInfo.mUse11kSounds = prefs->sound_11k;
1048 gConfigInfo.mDisableSound = prefs->nosound;
1049 gConfigInfo.mDisableMIDIMusic = prefs->nomidi;
1050 gConfigInfo.mChangeResolution = prefs->change_resolution;
1051 gConfigInfo.mDoNotPlayMovies = prefs->no_movies;
1052 gConfigInfo.mGameMonitor = prefs->game_monitor;
1053 gConfigInfo.mAcceleration = prefs->enable_rave;
1054 gConfigInfo.mInputSprockets = prefs->enable_input_sprockets;
1056 DisposeHandle(prefs_handle);
1060 int WriteConfigFile()
1063 Handle prefs_handle;
1066 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
1067 if (prefs_handle == NULL)
1070 prefs = (Preferences *)(*prefs_handle);
1072 joy_get_cal_vals(prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
1073 prefs->digi_volume = Config_digi_volume;
1074 prefs->midi_volume = Config_midi_volume;
1075 prefs->stereo_reverse = Config_channels_reversed;
1076 prefs->detail_level = Detail_level;
1077 if (Detail_level == NUM_DETAIL_LEVELS-1) {
1078 prefs->oc = Object_complexity;
1079 prefs->od = Object_detail;
1080 prefs->wd = Wall_detail;
1081 prefs->wrd = Wall_render_depth;
1082 prefs->da = Debris_amount;
1083 prefs->sc = SoundChannels;
1085 prefs->gamma_level = (ubyte)gr_palette_get_gamma();
1088 prefs->pixel_double = (ubyte)Scanline_double; // hmm..don't write this out if doing hardware accel.
1090 strncpy( prefs->lastplayer, Players[Player_num].callsign, CALLSIGN_LEN );
1091 strncpy( prefs->lastmission, config_last_mission, MISSION_NAME_LEN );
1092 strcpy( prefs->ctb_config, config_last_ctb_cfg);
1093 prefs->ctb_tool = config_last_ctb_tool;
1094 prefs->master_volume = Config_master_volume;
1095 prefs->display_dialog = gConfigInfo.mDoNotDisplayOptions;
1096 prefs->change_resolution = gConfigInfo.mChangeResolution;
1097 prefs->nosound = gConfigInfo.mDisableSound;
1098 prefs->nomidi = gConfigInfo.mDisableMIDIMusic;
1099 prefs->sound_11k = gConfigInfo.mUse11kSounds;
1100 prefs->no_movies = gConfigInfo.mDoNotPlayMovies;
1101 prefs->game_monitor = gConfigInfo.mGameMonitor;
1102 prefs->redbook_volume = Config_redbook_volume;
1103 prefs->enable_rave = gConfigInfo.mAcceleration;
1104 prefs->enable_input_sprockets = gConfigInfo.mInputSprockets;
1106 err = SavePrefsFile(prefs_handle);
1107 DisposeHandle(prefs_handle);