1 /* $Id: config.c,v 1.14 2004-12-01 12:48:13 btb 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
62 static char rcsid[] = "$Id: config.c,v 1.14 2004-12-01 12:48:13 btb Exp $";
65 ubyte Config_digi_volume = 8;
66 ubyte Config_midi_volume = 8;
67 ubyte Config_redbook_volume = 8;
68 ubyte Config_control_type = 0;
69 ubyte Config_channels_reversed = 0;
70 ubyte Config_joystick_sensitivity = 8;
73 static char *digi_dev8_str = "DigiDeviceID8";
74 static char *digi_dev16_str = "DigiDeviceID16";
75 static char *digi_port_str = "DigiPort";
76 static char *digi_irq_str = "DigiIrq";
77 static char *digi_dma8_str = "DigiDma8";
78 static char *digi_dma16_str = "DigiDma16";
79 static char *midi_dev_str = "MidiDeviceID";
80 static char *midi_port_str = "MidiPort";
82 #define _CRYSTAL_LAKE_8_ST 0xe201
83 #define _CRYSTAL_LAKE_16_ST 0xe202
84 #define _AWE32_8_ST 0xe208
85 #define _AWE32_16_ST 0xe209
87 static char *digi_volume_str = "DigiVolume";
88 static char *midi_volume_str = "MidiVolume";
89 static char *redbook_enabled_str = "RedbookEnabled";
90 static char *redbook_volume_str = "RedbookVolume";
91 static char *detail_level_str = "DetailLevel";
92 static char *gamma_level_str = "GammaLevel";
93 static char *stereo_rev_str = "StereoReverse";
94 static char *joystick_min_str = "JoystickMin";
95 static char *joystick_max_str = "JoystickMax";
96 static char *joystick_cen_str = "JoystickCen";
97 static char *last_player_str = "LastPlayer";
98 static char *last_mission_str = "LastMission";
99 static char *config_vr_type_str = "VR_type";
100 static char *config_vr_resolution_str = "VR_resolution";
101 static char *config_vr_tracking_str = "VR_tracking";
102 static char *movie_hires_str = "MovieHires";
104 char config_last_player[CALLSIGN_LEN+1] = "";
105 char config_last_mission[MISSION_NAME_LEN+1] = "";
107 int Config_digi_type = 0;
108 int Config_digi_dma = 0;
109 int Config_midi_type = 0;
112 int DOSJoySaveMin[4];
113 int DOSJoySaveCen[4];
114 int DOSJoySaveMax[4];
116 char win95_current_joyname[256];
121 int Config_vr_type = 0;
122 int Config_vr_resolution = 0;
123 int Config_vr_tracking = 0;
125 int digi_driver_board_16;
126 int digi_driver_dma_16;
128 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
130 void set_custom_detail_vars(void);
136 void CrystalLakeWriteMCP( ushort mc_addr, ubyte mc_data )
139 outp( CL_MC0, 0xE2 ); // Write password
140 outp( mc_addr, mc_data ); // Write data
144 ubyte CrystalLakeReadMCP( ushort mc_addr )
148 outp( CL_MC0, 0xE2 ); // Write password
149 value = inp( mc_addr ); // Read data
154 void CrystalLakeSetSB()
157 tmp = CrystalLakeReadMCP( CL_MC1 );
159 CrystalLakeWriteMCP( CL_MC1, tmp );
162 void CrystalLakeSetWSS()
165 tmp = CrystalLakeReadMCP( CL_MC1 );
167 CrystalLakeWriteMCP( CL_MC1, tmp );
170 //MovieHires might be changed by -nohighres, so save a "real" copy of it
172 int save_redbook_enabled;
175 void CheckMovieAttributes()
178 DWORD len, type, val;
181 lres = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Parallax\\Descent II\\1.1\\INSTALL",
183 if (lres == ERROR_SUCCESS) {
185 lres = RegQueryValueEx(hKey, "HIRES", NULL, &type, &val, &len);
186 if (lres == ERROR_SUCCESS) {
188 logentry("HIRES=%d\n", val);
200 char line[80], *token, *value, *ptr;
203 int joy_axis_center[7];
207 strcpy( config_last_player, "" );
209 joy_axis_min[0] = joy_axis_min[1] = joy_axis_min[2] = joy_axis_min[3] = 0;
210 joy_axis_max[0] = joy_axis_max[1] = joy_axis_max[2] = joy_axis_max[3] = 0;
211 joy_axis_center[0] = joy_axis_center[1] = joy_axis_center[2] = joy_axis_center[3] = 0;
214 memset(&joy_axis_min[0], 0, sizeof(int)*7);
215 memset(&joy_axis_max[0], 0, sizeof(int)*7);
216 memset(&joy_axis_center[0], 0, sizeof(int)*7);
217 //@@ joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
219 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
222 /*digi_driver_board = 0;
223 digi_driver_port = 0;
228 digi_midi_port = 0;*/
230 Config_digi_volume = 8;
231 Config_midi_volume = 8;
232 Config_redbook_volume = 8;
233 Config_control_type = 0;
234 Config_channels_reversed = 0;
236 //set these here in case no cfg file
237 SaveMovieHires = MovieHires;
238 save_redbook_enabled = Redbook_enabled;
240 infile = PHYSFS_openRead("descent.cfg");
241 if (infile == NULL) {
242 WIN(CheckMovieAttributes());
245 while (!PHYSFS_eof(infile))
248 PHYSFSX_gets(infile, line);
250 while (isspace(*ptr))
253 token = strtok(ptr, "=");
254 value = strtok(NULL, "=");
257 /* if (!strcmp(token, digi_dev8_str))
258 digi_driver_board = strtol(value, NULL, 16);
259 else if (!strcmp(token, digi_dev16_str))
260 digi_driver_board_16 = strtol(value, NULL, 16);
261 else if (!strcmp(token, digi_port_str))
262 digi_driver_port = strtol(value, NULL, 16);
263 else if (!strcmp(token, digi_irq_str))
264 digi_driver_irq = strtol(value, NULL, 10);
265 else if (!strcmp(token, digi_dma8_str))
266 digi_driver_dma = strtol(value, NULL, 10);
267 else if (!strcmp(token, digi_dma16_str))
268 digi_driver_dma_16 = strtol(value, NULL, 10);
269 else*/ if (!strcmp(token, digi_volume_str))
270 Config_digi_volume = strtol(value, NULL, 10);
271 else/* if (!strcmp(token, midi_dev_str))
272 digi_midi_type = strtol(value, NULL, 16);
273 else if (!strcmp(token, midi_port_str))
274 digi_midi_port = strtol(value, NULL, 16);
275 else*/ if (!strcmp(token, midi_volume_str))
276 Config_midi_volume = strtol(value, NULL, 10);
277 else if (!strcmp(token, redbook_enabled_str))
278 Redbook_enabled = save_redbook_enabled = strtol(value, NULL, 10);
279 else if (!strcmp(token, redbook_volume_str))
280 Config_redbook_volume = strtol(value, NULL, 10);
281 else if (!strcmp(token, stereo_rev_str))
282 Config_channels_reversed = strtol(value, NULL, 10);
283 else if (!strcmp(token, gamma_level_str)) {
284 gamma = strtol(value, NULL, 10);
285 gr_palette_set_gamma( gamma );
287 else if (!strcmp(token, detail_level_str)) {
288 Detail_level = strtol(value, NULL, 10);
289 if (Detail_level == NUM_DETAIL_LEVELS-1) {
290 int count,dummy,oc,od,wd,wrd,da,sc;
292 count = sscanf (value, "%d,%d,%d,%d,%d,%d,%d\n",&dummy,&oc,&od,&wd,&wrd,&da,&sc);
295 Object_complexity = oc;
298 Wall_render_depth = wrd;
301 set_custom_detail_vars();
303 #ifdef PA_3DFX_VOODOO // Set to highest detail because you can't change em
304 Object_complexity=Object_detail=Wall_detail=
305 Wall_render_depth=Debris_amount=SoundChannels = NUM_DETAIL_LEVELS-1;
306 Detail_level=NUM_DETAIL_LEVELS-1;
307 set_custom_detail_vars();
311 else if (!strcmp(token, joystick_min_str)) {
312 sscanf( value, "%d,%d,%d,%d", &joy_axis_min[0], &joy_axis_min[1], &joy_axis_min[2], &joy_axis_min[3] );
314 else if (!strcmp(token, joystick_max_str)) {
315 sscanf( value, "%d,%d,%d,%d", &joy_axis_max[0], &joy_axis_max[1], &joy_axis_max[2], &joy_axis_max[3] );
317 else if (!strcmp(token, joystick_cen_str)) {
318 sscanf( value, "%d,%d,%d,%d", &joy_axis_center[0], &joy_axis_center[1], &joy_axis_center[2], &joy_axis_center[3] );
320 else if (!strcmp(token, last_player_str)) {
322 strncpy( config_last_player, value, CALLSIGN_LEN );
323 p = strchr( config_last_player, '\n');
326 else if (!strcmp(token, last_mission_str)) {
328 strncpy( config_last_mission, value, MISSION_NAME_LEN );
329 p = strchr( config_last_mission, '\n');
331 } else if (!strcmp(token, config_vr_type_str)) {
332 Config_vr_type = strtol(value, NULL, 10);
333 } else if (!strcmp(token, config_vr_resolution_str)) {
334 Config_vr_resolution = strtol(value, NULL, 10);
335 } else if (!strcmp(token, config_vr_tracking_str)) {
336 Config_vr_tracking = strtol(value, NULL, 10);
337 } else if (!strcmp(token, movie_hires_str)) {
338 SaveMovieHires = MovieHires = strtol(value, NULL, 10);
343 PHYSFS_close(infile);
348 DOSJoySaveMin[i]=joy_axis_min[i];
349 DOSJoySaveCen[i]=joy_axis_center[i];
350 DOSJoySaveMax[i]=joy_axis_max[i];
353 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
356 i = FindArg( "-volume" );
359 i = atoi( Args[i+1] );
361 if ( i > 100 ) i = 100;
362 Config_digi_volume = (i*8)/100;
363 Config_midi_volume = (i*8)/100;
364 Config_redbook_volume = (i*8)/100;
367 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
368 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
369 if ( Config_redbook_volume > 8 ) Config_redbook_volume = 8;
371 digi_set_volume( (Config_digi_volume*32768)/8, (Config_midi_volume*128)/8 );
373 printf( "DigiDeviceID: 0x%x\n", digi_driver_board );
374 printf( "DigiPort: 0x%x\n", digi_driver_port );
375 printf( "DigiIrq: 0x%x\n", digi_driver_irq );
376 printf( "DigiDma: 0x%x\n", digi_driver_dma );
377 printf( "MidiDeviceID: 0x%x\n", digi_midi_type );
378 printf( "MidiPort: 0x%x\n", digi_midi_port );
382 /*Config_midi_type = digi_midi_type;
383 Config_digi_type = digi_driver_board;
384 Config_digi_dma = digi_driver_dma;*/
387 if (digi_driver_board_16 > 0 && !FindArg("-no16bit") && digi_driver_board_16 != _GUS_16_ST) {
388 digi_driver_board = digi_driver_board_16;
389 digi_driver_dma = digi_driver_dma_16;
393 //Hack to make some cards look like others, such as
394 //the Crytal Lake look like Microsoft Sound System
395 if ( digi_driver_board == _CRYSTAL_LAKE_8_ST ) {
397 tmp = CrystalLakeReadMCP( CL_MC1 );
399 atexit( CrystalLakeSetSB ); // Restore to SB when done.
401 digi_driver_board = _MICROSOFT_8_ST;
402 } else if ( digi_driver_board == _CRYSTAL_LAKE_16_ST ) {
404 tmp = CrystalLakeReadMCP( CL_MC1 );
406 atexit( CrystalLakeSetSB ); // Restore to SB when done.
408 digi_driver_board = _MICROSOFT_16_ST;
409 } else if ( digi_driver_board == _AWE32_8_ST ) {
410 digi_driver_board = _SB16_8_ST;
411 } else if ( digi_driver_board == _AWE32_16_ST ) {
412 digi_driver_board = _SB16_16_ST;
414 digi_driver_board = digi_driver_board;
416 infile = PHYSFS_openRead("descentw.cfg");
418 while (!PHYSFS_eof(infile))
421 PHYSFSX_gets(infile, line);
423 while (isspace(*ptr))
426 token = strtok(ptr, "=");
427 value = strtok(NULL, "=");
428 if (!strcmp(token, joystick_min_str)) {
429 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] );
431 else if (!strcmp(token, joystick_max_str)) {
432 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] );
434 else if (!strcmp(token, joystick_cen_str)) {
435 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] );
439 PHYSFS_close(infile);
446 int WriteConfigFile()
451 int joy_axis_center[7];
453 ubyte gamma = gr_palette_get_gamma();
455 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
460 joy_axis_min[i]=DOSJoySaveMin[i];
461 joy_axis_center[i]=DOSJoySaveCen[i];
462 joy_axis_max[i]=DOSJoySaveMax[i];
466 infile = PHYSFS_openWrite("descent.cfg");
467 if (infile == NULL) {
470 /*sprintf (str, "%s=0x%x\n", digi_dev8_str, Config_digi_type);
471 PHYSFSX_puts(infile, str);
472 sprintf (str, "%s=0x%x\n", digi_dev16_str, digi_driver_board_16);
473 PHYSFSX_puts(infile, str);
474 sprintf (str, "%s=0x%x\n", digi_port_str, digi_driver_port);
475 PHYSFSX_puts(infile, str);
476 sprintf (str, "%s=%d\n", digi_irq_str, digi_driver_irq);
477 PHYSFSX_puts(infile, str);
478 sprintf (str, "%s=%d\n", digi_dma8_str, Config_digi_dma);
479 PHYSFSX_puts(infile, str);
480 sprintf (str, "%s=%d\n", digi_dma16_str, digi_driver_dma_16);
481 PHYSFSX_puts(infile, str);*/
482 sprintf (str, "%s=%d\n", digi_volume_str, Config_digi_volume);
483 PHYSFSX_puts(infile, str);
484 /*sprintf (str, "%s=0x%x\n", midi_dev_str, Config_midi_type);
485 PHYSFSX_puts(infile, str);
486 sprintf (str, "%s=0x%x\n", midi_port_str, digi_midi_port);
487 PHYSFSX_puts(infile, str);*/
488 sprintf (str, "%s=%d\n", midi_volume_str, Config_midi_volume);
489 PHYSFSX_puts(infile, str);
490 sprintf (str, "%s=%d\n", redbook_enabled_str, FindArg("-noredbook")?save_redbook_enabled:Redbook_enabled);
491 PHYSFSX_puts(infile, str);
492 sprintf (str, "%s=%d\n", redbook_volume_str, Config_redbook_volume);
493 PHYSFSX_puts(infile, str);
494 sprintf (str, "%s=%d\n", stereo_rev_str, Config_channels_reversed);
495 PHYSFSX_puts(infile, str);
496 sprintf (str, "%s=%d\n", gamma_level_str, gamma);
497 PHYSFSX_puts(infile, str);
498 if (Detail_level == NUM_DETAIL_LEVELS-1)
499 sprintf (str, "%s=%d,%d,%d,%d,%d,%d,%d\n", detail_level_str, Detail_level,
500 Object_complexity,Object_detail,Wall_detail,Wall_render_depth,Debris_amount,SoundChannels);
502 sprintf (str, "%s=%d\n", detail_level_str, Detail_level);
503 PHYSFSX_puts(infile, str);
505 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] );
506 PHYSFSX_puts(infile, str);
507 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] );
508 PHYSFSX_puts(infile, str);
509 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] );
510 PHYSFSX_puts(infile, str);
512 sprintf (str, "%s=%s\n", last_player_str, Players[Player_num].callsign );
513 PHYSFSX_puts(infile, str);
514 sprintf (str, "%s=%s\n", last_mission_str, config_last_mission );
515 PHYSFSX_puts(infile, str);
516 sprintf (str, "%s=%d\n", config_vr_type_str, Config_vr_type );
517 PHYSFSX_puts(infile, str);
518 sprintf (str, "%s=%d\n", config_vr_resolution_str, Config_vr_resolution );
519 PHYSFSX_puts(infile, str);
520 sprintf (str, "%s=%d\n", config_vr_tracking_str, Config_vr_tracking );
521 PHYSFSX_puts(infile, str);
522 sprintf (str, "%s=%d\n", movie_hires_str, (FindArg("-nohires") || FindArg("-nohighres") || FindArg("-lowresmovies"))?SaveMovieHires:MovieHires);
523 PHYSFSX_puts(infile, str);
525 PHYSFS_close(infile);
529 // Save Windows Config File
533 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
535 infile = cfopen("descentw.cfg", "wt");
536 if (infile == NULL) return 1;
538 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_min_str,
539 joy_axis_min[0], joy_axis_min[1], joy_axis_min[2], joy_axis_min[3],
540 joy_axis_min[4], joy_axis_min[5], joy_axis_min[6]);
542 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_cen_str,
543 joy_axis_center[0], joy_axis_center[1], joy_axis_center[2], joy_axis_center[3],
544 joy_axis_center[4], joy_axis_center[5], joy_axis_center[6]);
546 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_max_str,
547 joy_axis_max[0], joy_axis_max[1], joy_axis_max[2], joy_axis_max[3],
548 joy_axis_max[4], joy_axis_max[5], joy_axis_max[6]);
553 CheckMovieAttributes();
559 #else // !defined(MACINTOSH)
568 #include <GestaltEqu.h>
570 #include <Processes.h>
571 #include <Resources.h>
574 #include "pa_enabl.h" // because some prefs rely on this fact
585 #include "prefs.h" // prefs file for configuration stuff -- from DeSalvo
587 #if defined(POLY_ACC)
588 #include "poly_acc.h"
592 static char rcsid[] = "$Id: config.c,v 1.14 2004-12-01 12:48:13 btb Exp $";
595 #define MAX_CTB_LEN 512
597 typedef struct preferences {
600 ubyte stereo_reverse;
602 ubyte oc; // object complexity
603 ubyte od; // object detail
604 ubyte wd; // wall detail
605 ubyte wrd; // wall render depth
606 ubyte da; // debris amount
607 ubyte sc; // sound channels
612 int joy_axis_center[4];
613 char lastplayer[CALLSIGN_LEN+1];
614 char lastmission[MISSION_NAME_LEN+1];
615 char ctb_config[MAX_CTB_LEN];
618 ubyte display_dialog;
619 ubyte change_resolution;
625 ubyte redbook_volume;
627 ubyte enable_input_sprockets;
630 char config_last_player[CALLSIGN_LEN+1] = "";
631 char config_last_mission[MISSION_NAME_LEN+1] = "";
632 char config_last_ctb_cfg[MAX_CTB_LEN] = "";
633 int config_last_ctb_tool;
634 ubyte Config_master_volume = 4;
635 ubyte Config_digi_volume = 8;
636 ubyte Config_midi_volume = 8;
637 ubyte Config_redbook_volume = 8;
638 ubyte Config_control_type = 0;
639 ubyte Config_channels_reversed = 0;
640 ubyte Config_joystick_sensitivity = 8;
642 int Config_vr_type = 0;
643 int Config_vr_resolution = 0;
644 int Config_vr_tracking = 0;
646 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
647 extern void digi_set_master_volume( int volume );
649 void set_custom_detail_vars(void);
651 static ubyte have_prefs = 0;
653 //¥ ------------------------------ Private Definitions
654 //¥ ------------------------------ Private Types
663 } PrefsInfo, *PrefsInfoPtr, **PrefsInfoHandle;
665 //¥ ------------------------------ Private Variables
667 static PrefsInfo prefsInfo;
668 static Boolean prefsInited = 0;
670 //¥ ------------------------------ Private Functions
672 static void Pstrcpy(StringPtr dst, StringPtr src);
673 static void Pstrcat(StringPtr dst, StringPtr src);
674 static Boolean FindPrefsFile(short *prefVRefNum, long *prefDirID);
676 //¥ -------------------- Pstrcpy
679 Pstrcpy(StringPtr dst, StringPtr src)
681 BlockMove(src, dst, (*src) + 1);
684 //¥ -------------------- Pstrcat
687 Pstrcat(StringPtr dst, StringPtr src)
689 BlockMove(src + 1, dst + (*dst) + 1, *src);
693 //¥ -------------------- FindPrefsFile
696 FindPrefsFile(short *prefVRefNum, long *prefDirID)
705 theErr = Gestalt(gestaltFindFolderAttr, &response);
706 if (theErr == noErr && ((response >> gestaltFindFolderPresent) & 1))
708 //¥ Find (or make) it the easy way...
709 theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, prefVRefNum, prefDirID);
714 StringPtr prefFolderName = "\pPreferences";
716 //¥ yeachh -- we have to do it all by hand!
717 theErr = SysEnvirons(1, &theSysEnv);
721 *prefVRefNum = theSysEnv.sysVRefNum;
723 //¥ Check whether Preferences folder already exists
724 infoPB.hFileInfo.ioCompletion = 0;
725 infoPB.hFileInfo.ioNamePtr = prefFolderName;
726 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
727 infoPB.hFileInfo.ioFDirIndex = 0;
728 infoPB.hFileInfo.ioDirID = 0;
730 theErr = PBGetCatInfo(&infoPB, 0);
733 *prefDirID = infoPB.hFileInfo.ioDirID;
735 else if (theErr == fnfErr) //¥ Preferences doesn't already exist
737 HParamBlockRec dirPB;
739 //¥ Create "Preferences" folder
740 dirPB.fileParam.ioCompletion = 0;
741 dirPB.fileParam.ioVRefNum = *prefVRefNum;
742 dirPB.fileParam.ioNamePtr = prefFolderName;
743 dirPB.fileParam.ioDirID = 0;
745 theErr = PBDirCreate(&dirPB, 0);
747 *prefDirID = dirPB.fileParam.ioDirID;
751 //¥ If we make it here OK, create Preferences file if necessary
754 infoPB.hFileInfo.ioCompletion = 0;
755 infoPB.hFileInfo.ioNamePtr = prefsInfo.fileName;
756 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
757 infoPB.hFileInfo.ioFDirIndex = 0;
758 infoPB.hFileInfo.ioDirID = *prefDirID;
760 theErr = PBGetCatInfo(&infoPB, 0);
761 if (theErr == fnfErr)
763 theErr = HCreate(*prefVRefNum, *prefDirID, prefsInfo.fileName, prefsInfo.creator, prefsInfo.fileType);
766 HCreateResFile(*prefVRefNum, *prefDirID, prefsInfo.fileName);
772 return (theErr == noErr);
775 //¥ -------------------- InitPrefsFile
777 #define UNKNOWN_TYPE 0x3f3f3f3f
780 InitPrefsFile(OSType creator)
783 PrefsInfoHandle piHdl;
785 if ((piHdl = (PrefsInfoHandle) GetResource('PRFI', 0)) == nil)
787 ProcessSerialNumber thePSN;
788 ProcessInfoRec thePIR;
790 StringPtr app_string;
793 GetCurrentProcess(&thePSN);
794 thePIR.processName = nil;
795 thePIR.processAppSpec = &appSpec;
797 //¥ Set default to 'ÇApplicationÈ Prefs', PREF 0
798 err = GetProcessInformation(&thePSN, &thePIR);
802 app_string = LMGetCurApName();
803 // Pstrcpy(prefsInfo.fileName, appSpec.name);
804 Pstrcpy(prefsInfo.fileName, app_string);
805 Pstrcat(prefsInfo.fileName, "\p Preferences");
807 //¥ Set creator to calling application's signature (should be able to
808 //¥ Determine this automatically, but unable to for some reason)
809 prefsInfo.creator = creator;
810 prefsInfo.fileType = 'pref';
811 prefsInfo.resType = 'pref';
816 //¥ Get Preferences file setup from PRFI 0
817 BlockMove(*piHdl, &prefsInfo, sizeof (prefsInfo));
818 ReleaseResource((Handle) piHdl);
820 if (prefsInfo.creator == UNKNOWN_TYPE)
821 prefsInfo.creator = creator;
827 //¥ -------------------- LoadPrefsFile
830 LoadPrefsFile(Handle prefsHdl)
832 short prefVRefNum, prefRefNum;
834 OSErr theErr = noErr;
836 Size prefSize, origSize;
839 return (nilHandleErr);
841 prefSize = GetHandleSize(prefsHdl);
843 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
846 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
847 if (prefRefNum == -1)
850 //¥ Not finding the resource is not an error -- caller will use default data
851 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
853 origSize = GetHandleSize(origHdl);
854 if (origSize > prefSize) //¥ Extend handle for extra stored data
855 SetHandleSize(prefsHdl, origSize);
857 BlockMove(*origHdl, *prefsHdl, origSize);
858 ReleaseResource(origHdl);
861 CloseResFile(prefRefNum);
869 //¥ -------------------- SavePrefsFile
872 SavePrefsFile(Handle prefHdl)
874 short prefVRefNum, prefRefNum;
876 Handle origHdl = nil;
877 Size origSize, prefSize;
878 OSErr theErr = noErr;
880 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
884 return (nilHandleErr);
886 prefSize = GetHandleSize(prefHdl);
888 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
889 if (prefRefNum == -1)
892 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
894 //¥ Overwrite existing preferences
895 origSize = GetHandleSize(origHdl);
896 if (prefSize > origSize)
897 SetHandleSize(origHdl, prefSize);
899 BlockMove(*prefHdl, *origHdl, prefSize);
900 ChangedResource(origHdl);
901 WriteResource(origHdl);
902 ReleaseResource(origHdl);
906 //¥ Store specified preferences for the first time
907 AddResource(prefHdl, prefsInfo.resType, prefsInfo.resID, "\p");
908 WriteResource(prefHdl);
909 DetachResource(prefHdl);
912 CloseResFile(prefRefNum);
920 //¥ -------------------------------------------------------------------------------------------
924 This module provides the ability to save and load a preferences file in the
925 Preferences folder in the System Folder. An optional resource, PRFI 0,
926 is used to provide specifications for the preferences file (creator, etc.).
928 Three functions are provided:
930 void InitPrefsFile(OSType creator)
932 This function will initialize the preferences file, that is, it will create
933 it in the appropriate place if it doesn't currently exist. It should be
934 called with the creator code for the application. Note that the creator
935 code specified in PRFI 0 (if any) will be used only if the creator code
936 passed to this function is '????'. Without the PRFI 0 resource, the default
939 File Name: "{Application} Prefs" (i.e., the name of the app plus " Prefs"
940 Creator: the creator passed to InitPrefsFile
942 Pref Resource Type: 'PREF'
945 The PRFI 0 resource allows you to specify overrides for each of the above
946 values. This is useful for development, since the application name might
947 go through changes, but the preferences file name is held constant.
949 OSErr LoadPrefsFile(Handle prefsHndl)
951 This function will attempt to copy the data stored in the preferences
952 file to the given handle (which must be pre-allocated). If the handle is too
953 small, then it will be enlarged. If it is too large, it will not be resized.
954 The data in the preferences file (normally in PREF 0) will then be copied
955 into the handle. If the preferences file did not exist, the original data
956 in the handle will not change.
958 OSErr SavePrefsFile(Handle prefsHndl)
960 This function will attempt to save the given handle to the preferences
961 file. Its contents will completely replace the previous data (normally
962 the PREF 0 resource).
964 In typical use, you will use InitPrefsFile once, then allocate a handle large
965 enough to contain your preferences data, and initialize it with default values.
966 Throughout the course of your program, the handle will undergo modification as
967 user preferences change. You can use SavePrefsFile anytime to update the
968 preferences file, or wait until program exit to do so.
980 if (!have_prefs) { // not initialized....get a handle to the preferences file
981 InitPrefsFile('DCT2');
985 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
986 if (prefs_handle == NULL)
989 prefs = (Preferences *)(*prefs_handle);
990 err = LoadPrefsFile(prefs_handle);
992 DisposeHandle(prefs_handle);
997 for (i = 0; i < sizeof(Preferences); i++) {
1002 if ( i == sizeof(Preferences) )
1005 Config_digi_volume = prefs->digi_volume;
1006 Config_midi_volume = prefs->midi_volume;
1007 Config_master_volume = prefs->master_volume;
1008 Config_redbook_volume = prefs->redbook_volume;
1009 Config_channels_reversed = prefs->stereo_reverse;
1010 gr_palette_set_gamma( (int)(prefs->gamma_level) );
1012 Scanline_double = (int)prefs->pixel_double;
1014 Scanline_double = 0; // can't double with hardware acceleration
1016 Detail_level = prefs->detail_level;
1017 if (Detail_level == NUM_DETAIL_LEVELS-1) {
1018 Object_complexity = prefs->oc;
1019 Object_detail = prefs->od;
1020 Wall_detail = prefs->wd;
1021 Wall_render_depth = prefs->wrd;
1022 Debris_amount = prefs->da;
1023 SoundChannels = prefs->sc;
1024 set_custom_detail_vars();
1026 #ifdef PA_3DFX_VOODOO // Set to highest detail because you can't change em
1027 Object_complexity=Object_detail=Wall_detail=
1028 Wall_render_depth=Debris_amount=SoundChannels = NUM_DETAIL_LEVELS-1;
1029 Detail_level=NUM_DETAIL_LEVELS-1;
1030 set_custom_detail_vars();
1033 strncpy( config_last_player, prefs->lastplayer, CALLSIGN_LEN );
1034 p = strchr(config_last_player, '\n' );
1037 strncpy(config_last_mission, prefs->lastmission, MISSION_NAME_LEN);
1038 p = strchr(config_last_mission, '\n' );
1041 strcpy(config_last_ctb_cfg, prefs->ctb_config);
1043 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
1045 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
1047 joy_set_cal_vals( prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
1048 digi_set_volume( (Config_digi_volume*256)/8, (Config_midi_volume*256)/8 );
1049 digi_set_master_volume(Config_master_volume);
1051 gConfigInfo.mDoNotDisplayOptions = prefs->display_dialog;
1052 gConfigInfo.mUse11kSounds = prefs->sound_11k;
1053 gConfigInfo.mDisableSound = prefs->nosound;
1054 gConfigInfo.mDisableMIDIMusic = prefs->nomidi;
1055 gConfigInfo.mChangeResolution = prefs->change_resolution;
1056 gConfigInfo.mDoNotPlayMovies = prefs->no_movies;
1057 gConfigInfo.mGameMonitor = prefs->game_monitor;
1058 gConfigInfo.mAcceleration = prefs->enable_rave;
1059 gConfigInfo.mInputSprockets = prefs->enable_input_sprockets;
1061 DisposeHandle(prefs_handle);
1065 int WriteConfigFile()
1068 Handle prefs_handle;
1071 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
1072 if (prefs_handle == NULL)
1075 prefs = (Preferences *)(*prefs_handle);
1077 joy_get_cal_vals(prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
1078 prefs->digi_volume = Config_digi_volume;
1079 prefs->midi_volume = Config_midi_volume;
1080 prefs->stereo_reverse = Config_channels_reversed;
1081 prefs->detail_level = Detail_level;
1082 if (Detail_level == NUM_DETAIL_LEVELS-1) {
1083 prefs->oc = Object_complexity;
1084 prefs->od = Object_detail;
1085 prefs->wd = Wall_detail;
1086 prefs->wrd = Wall_render_depth;
1087 prefs->da = Debris_amount;
1088 prefs->sc = SoundChannels;
1090 prefs->gamma_level = (ubyte)gr_palette_get_gamma();
1093 prefs->pixel_double = (ubyte)Scanline_double; // hmm..don't write this out if doing hardware accel.
1095 strncpy( prefs->lastplayer, Players[Player_num].callsign, CALLSIGN_LEN );
1096 strncpy( prefs->lastmission, config_last_mission, MISSION_NAME_LEN );
1097 strcpy( prefs->ctb_config, config_last_ctb_cfg);
1098 prefs->ctb_tool = config_last_ctb_tool;
1099 prefs->master_volume = Config_master_volume;
1100 prefs->display_dialog = gConfigInfo.mDoNotDisplayOptions;
1101 prefs->change_resolution = gConfigInfo.mChangeResolution;
1102 prefs->nosound = gConfigInfo.mDisableSound;
1103 prefs->nomidi = gConfigInfo.mDisableMIDIMusic;
1104 prefs->sound_11k = gConfigInfo.mUse11kSounds;
1105 prefs->no_movies = gConfigInfo.mDoNotPlayMovies;
1106 prefs->game_monitor = gConfigInfo.mGameMonitor;
1107 prefs->redbook_volume = Config_redbook_volume;
1108 prefs->enable_rave = gConfigInfo.mAcceleration;
1109 prefs->enable_input_sprockets = gConfigInfo.mInputSprockets;
1111 err = SavePrefsFile(prefs_handle);
1112 DisposeHandle(prefs_handle);