2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
16 #ifndef MACINTOSH // I'm going to totally seperate these routines -- yeeech!!!!
17 // see end of file for macintosh equivs
20 #define WIN32_LEAN_AND_MEAN
49 static char rcsid[] = "$Id: config.c,v 1.2 2001-01-24 04:29:45 bradleyb Exp $";
52 ubyte Config_digi_volume = 8;
53 ubyte Config_midi_volume = 8;
54 ubyte Config_redbook_volume = 8;
55 ubyte Config_control_type = 0;
56 ubyte Config_channels_reversed = 0;
57 ubyte Config_joystick_sensitivity = 8;
60 static char *digi_dev8_str = "DigiDeviceID8";
61 static char *digi_dev16_str = "DigiDeviceID16";
62 static char *digi_port_str = "DigiPort";
63 static char *digi_irq_str = "DigiIrq";
64 static char *digi_dma8_str = "DigiDma8";
65 static char *digi_dma16_str = "DigiDma16";
66 static char *midi_dev_str = "MidiDeviceID";
67 static char *midi_port_str = "MidiPort";
69 #define _CRYSTAL_LAKE_8_ST 0xe201
70 #define _CRYSTAL_LAKE_16_ST 0xe202
71 #define _AWE32_8_ST 0xe208
72 #define _AWE32_16_ST 0xe209
74 static char *digi_volume_str = "DigiVolume";
75 static char *midi_volume_str = "MidiVolume";
76 static char *redbook_enabled_str = "RedbookEnabled";
77 static char *redbook_volume_str = "RedbookVolume";
78 static char *detail_level_str = "DetailLevel";
79 static char *gamma_level_str = "GammaLevel";
80 static char *stereo_rev_str = "StereoReverse";
81 static char *joystick_min_str = "JoystickMin";
82 static char *joystick_max_str = "JoystickMax";
83 static char *joystick_cen_str = "JoystickCen";
84 static char *last_player_str = "LastPlayer";
85 static char *last_mission_str = "LastMission";
86 static char *config_vr_type_str = "VR_type";
87 static char *config_vr_resolution_str = "VR_resolution";
88 static char *config_vr_tracking_str = "VR_tracking";
89 static char *movie_hires_str = "MovieHires";
91 char config_last_player[CALLSIGN_LEN+1] = "";
92 char config_last_mission[MISSION_NAME_LEN+1] = "";
94 int Config_digi_type = 0;
95 int Config_digi_dma = 0;
96 int Config_midi_type = 0;
100 int DOSJoySaveCen[4];
101 int DOSJoySaveMax[4];
103 char win95_current_joyname[256];
108 int Config_vr_type = 0;
109 int Config_vr_resolution = 0;
110 int Config_vr_tracking = 0;
112 int digi_driver_board_16;
113 int digi_driver_dma_16;
115 extern byte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
117 void set_custom_detail_vars(void);
123 void CrystalLakeWriteMCP( ushort mc_addr, ubyte mc_data )
126 outp( CL_MC0, 0xE2 ); // Write password
127 outp( mc_addr, mc_data ); // Write data
131 ubyte CrystalLakeReadMCP( ushort mc_addr )
135 outp( CL_MC0, 0xE2 ); // Write password
136 value = inp( mc_addr ); // Read data
141 void CrystalLakeSetSB()
144 tmp = CrystalLakeReadMCP( CL_MC1 );
146 CrystalLakeWriteMCP( CL_MC1, tmp );
149 void CrystalLakeSetWSS()
152 tmp = CrystalLakeReadMCP( CL_MC1 );
154 CrystalLakeWriteMCP( CL_MC1, tmp );
157 //MovieHires might be changed by -nohighres, so save a "real" copy of it
159 int save_redbook_enabled;
162 void CheckMovieAttributes()
165 DWORD len, type, val;
168 lres = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Parallax\\Descent II\\1.1\\INSTALL",
170 if (lres == ERROR_SUCCESS) {
172 lres = RegQueryValueEx(hKey, "HIRES", NULL, &type, &val, &len);
173 if (lres == ERROR_SUCCESS) {
175 logentry("HIRES=%d\n", val);
187 char line[80], *token, *value, *ptr;
190 int joy_axis_center[7];
194 strcpy( config_last_player, "" );
196 joy_axis_min[0] = joy_axis_min[1] = joy_axis_min[2] = joy_axis_min[3] = 0;
197 joy_axis_max[0] = joy_axis_max[1] = joy_axis_max[2] = joy_axis_max[3] = 0;
198 joy_axis_center[0] = joy_axis_center[1] = joy_axis_center[2] = joy_axis_center[3] = 0;
201 memset(&joy_axis_min[0], 0, sizeof(int)*7);
202 memset(&joy_axis_max[0], 0, sizeof(int)*7);
203 memset(&joy_axis_center[0], 0, sizeof(int)*7);
204 //@@ joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
206 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
209 /*digi_driver_board = 0;
210 digi_driver_port = 0;
215 digi_midi_port = 0;*/
217 Config_digi_volume = 8;
218 Config_midi_volume = 8;
219 Config_redbook_volume = 8;
220 Config_control_type = 0;
221 Config_channels_reversed = 0;
223 //set these here in case no cfg file
224 SaveMovieHires = MovieHires;
225 save_redbook_enabled = Redbook_enabled;
227 infile = fopen("descent.cfg", "rt");
228 if (infile == NULL) {
229 WIN(CheckMovieAttributes());
232 while (!feof(infile)) {
234 fgets(line, 80, infile);
236 while (isspace(*ptr))
239 token = strtok(ptr, "=");
240 value = strtok(NULL, "=");
241 if (value[strlen(value)-1] == '\n')
242 value[strlen(value)-1] = 0;
243 /* if (!strcmp(token, digi_dev8_str))
244 digi_driver_board = strtol(value, NULL, 16);
245 else if (!strcmp(token, digi_dev16_str))
246 digi_driver_board_16 = strtol(value, NULL, 16);
247 else if (!strcmp(token, digi_port_str))
248 digi_driver_port = strtol(value, NULL, 16);
249 else if (!strcmp(token, digi_irq_str))
250 digi_driver_irq = strtol(value, NULL, 10);
251 else if (!strcmp(token, digi_dma8_str))
252 digi_driver_dma = strtol(value, NULL, 10);
253 else if (!strcmp(token, digi_dma16_str))
254 digi_driver_dma_16 = strtol(value, NULL, 10);
255 else*/ if (!strcmp(token, digi_volume_str))
256 Config_digi_volume = strtol(value, NULL, 10);
257 else/* if (!strcmp(token, midi_dev_str))
258 digi_midi_type = strtol(value, NULL, 16);
259 else if (!strcmp(token, midi_port_str))
260 digi_midi_port = strtol(value, NULL, 16);
261 else*/ if (!strcmp(token, midi_volume_str))
262 Config_midi_volume = strtol(value, NULL, 10);
263 else if (!strcmp(token, redbook_enabled_str))
264 Redbook_enabled = save_redbook_enabled = strtol(value, NULL, 10);
265 else if (!strcmp(token, redbook_volume_str))
266 Config_redbook_volume = strtol(value, NULL, 10);
267 else if (!strcmp(token, stereo_rev_str))
268 Config_channels_reversed = strtol(value, NULL, 10);
269 else if (!strcmp(token, gamma_level_str)) {
270 gamma = strtol(value, NULL, 10);
271 gr_palette_set_gamma( gamma );
273 else if (!strcmp(token, detail_level_str)) {
274 Detail_level = strtol(value, NULL, 10);
275 if (Detail_level == NUM_DETAIL_LEVELS-1) {
276 int count,dummy,oc,od,wd,wrd,da,sc;
278 count = sscanf (value, "%d,%d,%d,%d,%d,%d,%d\n",&dummy,&oc,&od,&wd,&wrd,&da,&sc);
281 Object_complexity = oc;
284 Wall_render_depth = wrd;
287 set_custom_detail_vars();
289 #ifdef PA_3DFX_VOODOO // Set to highest detail because you can't change em
290 Object_complexity=Object_detail=Wall_detail=
291 Wall_render_depth=Debris_amount=SoundChannels = NUM_DETAIL_LEVELS-1;
292 Detail_level=NUM_DETAIL_LEVELS-1;
293 set_custom_detail_vars();
297 else if (!strcmp(token, joystick_min_str)) {
298 sscanf( value, "%d,%d,%d,%d", &joy_axis_min[0], &joy_axis_min[1], &joy_axis_min[2], &joy_axis_min[3] );
300 else if (!strcmp(token, joystick_max_str)) {
301 sscanf( value, "%d,%d,%d,%d", &joy_axis_max[0], &joy_axis_max[1], &joy_axis_max[2], &joy_axis_max[3] );
303 else if (!strcmp(token, joystick_cen_str)) {
304 sscanf( value, "%d,%d,%d,%d", &joy_axis_center[0], &joy_axis_center[1], &joy_axis_center[2], &joy_axis_center[3] );
306 else if (!strcmp(token, last_player_str)) {
308 strncpy( config_last_player, value, CALLSIGN_LEN );
309 p = strchr( config_last_player, '\n');
312 else if (!strcmp(token, last_mission_str)) {
314 strncpy( config_last_mission, value, MISSION_NAME_LEN );
315 p = strchr( config_last_mission, '\n');
317 } else if (!strcmp(token, config_vr_type_str)) {
318 Config_vr_type = strtol(value, NULL, 10);
319 } else if (!strcmp(token, config_vr_resolution_str)) {
320 Config_vr_resolution = strtol(value, NULL, 10);
321 } else if (!strcmp(token, config_vr_tracking_str)) {
322 Config_vr_tracking = strtol(value, NULL, 10);
323 } else if (!strcmp(token, movie_hires_str)) {
324 SaveMovieHires = MovieHires = strtol(value, NULL, 10);
334 DOSJoySaveMin[i]=joy_axis_min[i];
335 DOSJoySaveCen[i]=joy_axis_center[i];
336 DOSJoySaveMax[i]=joy_axis_max[i];
339 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
342 i = FindArg( "-volume" );
345 i = atoi( Args[i+1] );
347 if ( i > 100 ) i = 100;
348 Config_digi_volume = (i*8)/100;
349 Config_midi_volume = (i*8)/100;
350 Config_redbook_volume = (i*8)/100;
353 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
354 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
355 if ( Config_redbook_volume > 8 ) Config_redbook_volume = 8;
357 digi_set_volume( (Config_digi_volume*32768)/8, (Config_midi_volume*128)/8 );
359 printf( "DigiDeviceID: 0x%x\n", digi_driver_board );
360 printf( "DigiPort: 0x%x\n", digi_driver_port );
361 printf( "DigiIrq: 0x%x\n", digi_driver_irq );
362 printf( "DigiDma: 0x%x\n", digi_driver_dma );
363 printf( "MidiDeviceID: 0x%x\n", digi_midi_type );
364 printf( "MidiPort: 0x%x\n", digi_midi_port );
368 /*Config_midi_type = digi_midi_type;
369 Config_digi_type = digi_driver_board;
370 Config_digi_dma = digi_driver_dma;*/
372 #if !defined WINDOWS && !defined __ENV_LINUX__ && !defined __ENV_DJGPP__
373 if (digi_driver_board_16 > 0 && !FindArg("-no16bit") && digi_driver_board_16 != _GUS_16_ST) {
374 digi_driver_board = digi_driver_board_16;
375 digi_driver_dma = digi_driver_dma_16;
379 //Hack to make some cards look like others, such as
380 //the Crytal Lake look like Microsoft Sound System
381 if ( digi_driver_board == _CRYSTAL_LAKE_8_ST ) {
383 tmp = CrystalLakeReadMCP( CL_MC1 );
385 atexit( CrystalLakeSetSB ); // Restore to SB when done.
387 digi_driver_board = _MICROSOFT_8_ST;
388 } else if ( digi_driver_board == _CRYSTAL_LAKE_16_ST ) {
390 tmp = CrystalLakeReadMCP( CL_MC1 );
392 atexit( CrystalLakeSetSB ); // Restore to SB when done.
394 digi_driver_board = _MICROSOFT_16_ST;
395 } else if ( digi_driver_board == _AWE32_8_ST ) {
396 digi_driver_board = _SB16_8_ST;
397 } else if ( digi_driver_board == _AWE32_16_ST ) {
398 digi_driver_board = _SB16_16_ST;
400 digi_driver_board = digi_driver_board;
402 infile = fopen("descentw.cfg", "rt");
404 while (!feof(infile)) {
406 fgets(line, 80, infile);
408 while (isspace(*ptr))
411 token = strtok(ptr, "=");
412 value = strtok(NULL, "=");
413 if (value[strlen(value)-1] == '\n')
414 value[strlen(value)-1] = 0;
415 if (!strcmp(token, joystick_min_str)) {
416 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] );
418 else if (!strcmp(token, joystick_max_str)) {
419 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] );
421 else if (!strcmp(token, joystick_cen_str)) {
422 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] );
433 int WriteConfigFile()
438 int joy_axis_center[7];
440 ubyte gamma = gr_palette_get_gamma();
442 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
447 joy_axis_min[i]=DOSJoySaveMin[i];
448 joy_axis_center[i]=DOSJoySaveCen[i];
449 joy_axis_max[i]=DOSJoySaveMax[i];
453 infile = fopen("descent.cfg", "wt");
454 if (infile == NULL) {
457 /*sprintf (str, "%s=0x%x\n", digi_dev8_str, Config_digi_type);
459 sprintf (str, "%s=0x%x\n", digi_dev16_str, digi_driver_board_16);
461 sprintf (str, "%s=0x%x\n", digi_port_str, digi_driver_port);
463 sprintf (str, "%s=%d\n", digi_irq_str, digi_driver_irq);
465 sprintf (str, "%s=%d\n", digi_dma8_str, Config_digi_dma);
467 sprintf (str, "%s=%d\n", digi_dma16_str, digi_driver_dma_16);
468 fputs(str, infile);*/
469 sprintf (str, "%s=%d\n", digi_volume_str, Config_digi_volume);
471 /*sprintf (str, "%s=0x%x\n", midi_dev_str, Config_midi_type);
473 sprintf (str, "%s=0x%x\n", midi_port_str, digi_midi_port);
474 fputs(str, infile);*/
475 sprintf (str, "%s=%d\n", midi_volume_str, Config_midi_volume);
477 sprintf (str, "%s=%d\n", redbook_enabled_str, FindArg("-noredbook")?save_redbook_enabled:Redbook_enabled);
479 sprintf (str, "%s=%d\n", redbook_volume_str, Config_redbook_volume);
481 sprintf (str, "%s=%d\n", stereo_rev_str, Config_channels_reversed);
483 sprintf (str, "%s=%d\n", gamma_level_str, gamma);
485 if (Detail_level == NUM_DETAIL_LEVELS-1)
486 sprintf (str, "%s=%d,%d,%d,%d,%d,%d,%d\n", detail_level_str, Detail_level,
487 Object_complexity,Object_detail,Wall_detail,Wall_render_depth,Debris_amount,SoundChannels);
489 sprintf (str, "%s=%d\n", detail_level_str, Detail_level);
492 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] );
494 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] );
496 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] );
499 sprintf (str, "%s=%s\n", last_player_str, Players[Player_num].callsign );
501 sprintf (str, "%s=%s\n", last_mission_str, config_last_mission );
503 sprintf (str, "%s=%d\n", config_vr_type_str, Config_vr_type );
505 sprintf (str, "%s=%d\n", config_vr_resolution_str, Config_vr_resolution );
507 sprintf (str, "%s=%d\n", config_vr_tracking_str, Config_vr_tracking );
509 sprintf (str, "%s=%d\n", movie_hires_str, SaveMovieHires );
516 // Save Windows Config File
520 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
522 infile = fopen("descentw.cfg", "wt");
523 if (infile == NULL) return 1;
525 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_min_str,
526 joy_axis_min[0], joy_axis_min[1], joy_axis_min[2], joy_axis_min[3],
527 joy_axis_min[4], joy_axis_min[5], joy_axis_min[6]);
529 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_cen_str,
530 joy_axis_center[0], joy_axis_center[1], joy_axis_center[2], joy_axis_center[3],
531 joy_axis_center[4], joy_axis_center[5], joy_axis_center[6]);
533 sprintf(str, "%s=%d,%d,%d,%d,%d,%d,%d\n", joystick_max_str,
534 joy_axis_max[0], joy_axis_max[1], joy_axis_max[2], joy_axis_max[3],
535 joy_axis_max[4], joy_axis_max[5], joy_axis_max[6]);
540 CheckMovieAttributes();
546 #else // !defined(MACINTOSH)
555 #include <GestaltEqu.h>
557 #include <Processes.h>
558 #include <Resources.h>
561 #include "pa_enabl.h" // because some prefs rely on this fact
572 #include "prefs.h" // prefs file for configuration stuff -- from DeSalvo
574 #if defined(POLY_ACC)
575 #include "poly_acc.h"
579 static char rcsid[] = "$Id: config.c,v 1.2 2001-01-24 04:29:45 bradleyb Exp $";
582 #define MAX_CTB_LEN 512
584 typedef struct preferences {
587 ubyte stereo_reverse;
589 ubyte oc; // object complexity
590 ubyte od; // object detail
591 ubyte wd; // wall detail
592 ubyte wrd; // wall render depth
593 ubyte da; // debris amount
594 ubyte sc; // sound channels
599 int joy_axis_center[4];
600 char lastplayer[CALLSIGN_LEN+1];
601 char lastmission[MISSION_NAME_LEN+1];
602 char ctb_config[MAX_CTB_LEN];
605 ubyte display_dialog;
606 ubyte change_resolution;
612 ubyte redbook_volume;
614 ubyte enable_input_sprockets;
617 char config_last_player[CALLSIGN_LEN+1] = "";
618 char config_last_mission[MISSION_NAME_LEN+1] = "";
619 char config_last_ctb_cfg[MAX_CTB_LEN] = "";
620 int config_last_ctb_tool;
621 ubyte Config_master_volume = 4;
622 ubyte Config_digi_volume = 8;
623 ubyte Config_midi_volume = 8;
624 ubyte Config_redbook_volume = 8;
625 ubyte Config_control_type = 0;
626 ubyte Config_channels_reversed = 0;
627 ubyte Config_joystick_sensitivity = 8;
629 int Config_vr_type = 0;
630 int Config_vr_resolution = 0;
631 int Config_vr_tracking = 0;
633 extern byte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
634 extern void digi_set_master_volume( int volume );
636 void set_custom_detail_vars(void);
638 static ubyte have_prefs = 0;
640 //¥ ------------------------------ Private Definitions
641 //¥ ------------------------------ Private Types
650 } PrefsInfo, *PrefsInfoPtr, **PrefsInfoHandle;
652 //¥ ------------------------------ Private Variables
654 static PrefsInfo prefsInfo;
655 static Boolean prefsInited = 0;
657 //¥ ------------------------------ Private Functions
659 static void Pstrcpy(StringPtr dst, StringPtr src);
660 static void Pstrcat(StringPtr dst, StringPtr src);
661 static Boolean FindPrefsFile(short *prefVRefNum, long *prefDirID);
663 //¥ -------------------- Pstrcpy
666 Pstrcpy(StringPtr dst, StringPtr src)
668 BlockMove(src, dst, (*src) + 1);
671 //¥ -------------------- Pstrcat
674 Pstrcat(StringPtr dst, StringPtr src)
676 BlockMove(src + 1, dst + (*dst) + 1, *src);
680 //¥ -------------------- FindPrefsFile
683 FindPrefsFile(short *prefVRefNum, long *prefDirID)
692 theErr = Gestalt(gestaltFindFolderAttr, &response);
693 if (theErr == noErr && ((response >> gestaltFindFolderPresent) & 1))
695 //¥ Find (or make) it the easy way...
696 theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, prefVRefNum, prefDirID);
701 StringPtr prefFolderName = "\pPreferences";
703 //¥ yeachh -- we have to do it all by hand!
704 theErr = SysEnvirons(1, &theSysEnv);
708 *prefVRefNum = theSysEnv.sysVRefNum;
710 //¥ Check whether Preferences folder already exists
711 infoPB.hFileInfo.ioCompletion = 0;
712 infoPB.hFileInfo.ioNamePtr = prefFolderName;
713 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
714 infoPB.hFileInfo.ioFDirIndex = 0;
715 infoPB.hFileInfo.ioDirID = 0;
717 theErr = PBGetCatInfo(&infoPB, 0);
720 *prefDirID = infoPB.hFileInfo.ioDirID;
722 else if (theErr == fnfErr) //¥ Preferences doesn't already exist
724 HParamBlockRec dirPB;
726 //¥ Create "Preferences" folder
727 dirPB.fileParam.ioCompletion = 0;
728 dirPB.fileParam.ioVRefNum = *prefVRefNum;
729 dirPB.fileParam.ioNamePtr = prefFolderName;
730 dirPB.fileParam.ioDirID = 0;
732 theErr = PBDirCreate(&dirPB, 0);
734 *prefDirID = dirPB.fileParam.ioDirID;
738 //¥ If we make it here OK, create Preferences file if necessary
741 infoPB.hFileInfo.ioCompletion = 0;
742 infoPB.hFileInfo.ioNamePtr = prefsInfo.fileName;
743 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
744 infoPB.hFileInfo.ioFDirIndex = 0;
745 infoPB.hFileInfo.ioDirID = *prefDirID;
747 theErr = PBGetCatInfo(&infoPB, 0);
748 if (theErr == fnfErr)
750 theErr = HCreate(*prefVRefNum, *prefDirID, prefsInfo.fileName, prefsInfo.creator, prefsInfo.fileType);
753 HCreateResFile(*prefVRefNum, *prefDirID, prefsInfo.fileName);
759 return (theErr == noErr);
762 //¥ -------------------- InitPrefsFile
764 #define UNKNOWN_TYPE 0x3f3f3f3f
767 InitPrefsFile(OSType creator)
770 PrefsInfoHandle piHdl;
772 if ((piHdl = (PrefsInfoHandle) GetResource('PRFI', 0)) == nil)
774 ProcessSerialNumber thePSN;
775 ProcessInfoRec thePIR;
777 StringPtr app_string;
780 GetCurrentProcess(&thePSN);
781 thePIR.processName = nil;
782 thePIR.processAppSpec = &appSpec;
784 //¥ Set default to 'ÇApplicationÈ Prefs', PREF 0
785 err = GetProcessInformation(&thePSN, &thePIR);
789 app_string = LMGetCurApName();
790 // Pstrcpy(prefsInfo.fileName, appSpec.name);
791 Pstrcpy(prefsInfo.fileName, app_string);
792 Pstrcat(prefsInfo.fileName, "\p Preferences");
794 //¥ Set creator to calling application's signature (should be able to
795 //¥ Determine this automatically, but unable to for some reason)
796 prefsInfo.creator = creator;
797 prefsInfo.fileType = 'pref';
798 prefsInfo.resType = 'pref';
803 //¥ Get Preferences file setup from PRFI 0
804 BlockMove(*piHdl, &prefsInfo, sizeof (prefsInfo));
805 ReleaseResource((Handle) piHdl);
807 if (prefsInfo.creator == UNKNOWN_TYPE)
808 prefsInfo.creator = creator;
814 //¥ -------------------- LoadPrefsFile
817 LoadPrefsFile(Handle prefsHdl)
819 short prefVRefNum, prefRefNum;
821 OSErr theErr = noErr;
823 Size prefSize, origSize;
826 return (nilHandleErr);
828 prefSize = GetHandleSize(prefsHdl);
830 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
833 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
834 if (prefRefNum == -1)
837 //¥ Not finding the resource is not an error -- caller will use default data
838 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
840 origSize = GetHandleSize(origHdl);
841 if (origSize > prefSize) //¥ Extend handle for extra stored data
842 SetHandleSize(prefsHdl, origSize);
844 BlockMove(*origHdl, *prefsHdl, origSize);
845 ReleaseResource(origHdl);
848 CloseResFile(prefRefNum);
856 //¥ -------------------- SavePrefsFile
859 SavePrefsFile(Handle prefHdl)
861 short prefVRefNum, prefRefNum;
863 Handle origHdl = nil;
864 Size origSize, prefSize;
865 OSErr theErr = noErr;
867 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
871 return (nilHandleErr);
873 prefSize = GetHandleSize(prefHdl);
875 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
876 if (prefRefNum == -1)
879 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
881 //¥ Overwrite existing preferences
882 origSize = GetHandleSize(origHdl);
883 if (prefSize > origSize)
884 SetHandleSize(origHdl, prefSize);
886 BlockMove(*prefHdl, *origHdl, prefSize);
887 ChangedResource(origHdl);
888 WriteResource(origHdl);
889 ReleaseResource(origHdl);
893 //¥ Store specified preferences for the first time
894 AddResource(prefHdl, prefsInfo.resType, prefsInfo.resID, "\p");
895 WriteResource(prefHdl);
896 DetachResource(prefHdl);
899 CloseResFile(prefRefNum);
907 //¥ -------------------------------------------------------------------------------------------
911 This module provides the ability to save and load a preferences file in the
912 Preferences folder in the System Folder. An optional resource, PRFI 0,
913 is used to provide specifications for the preferences file (creator, etc.).
915 Three functions are provided:
917 void InitPrefsFile(OSType creator)
919 This function will initialize the preferences file, that is, it will create
920 it in the appropriate place if it doesn't currently exist. It should be
921 called with the creator code for the application. Note that the creator
922 code specified in PRFI 0 (if any) will be used only if the creator code
923 passed to this function is '????'. Without the PRFI 0 resource, the default
926 File Name: "{Application} Prefs" (i.e., the name of the app plus " Prefs"
927 Creator: the creator passed to InitPrefsFile
929 Pref Resource Type: 'PREF'
932 The PRFI 0 resource allows you to specify overrides for each of the above
933 values. This is useful for development, since the application name might
934 go through changes, but the preferences file name is held constant.
936 OSErr LoadPrefsFile(Handle prefsHndl)
938 This function will attempt to copy the data stored in the preferences
939 file to the given handle (which must be pre-allocated). If the handle is too
940 small, then it will be enlarged. If it is too large, it will not be resized.
941 The data in the preferences file (normally in PREF 0) will then be copied
942 into the handle. If the preferences file did not exist, the original data
943 in the handle will not change.
945 OSErr SavePrefsFile(Handle prefsHndl)
947 This function will attempt to save the given handle to the preferences
948 file. Its contents will completely replace the previous data (normally
949 the PREF 0 resource).
951 In typical use, you will use InitPrefsFile once, then allocate a handle large
952 enough to contain your preferences data, and initialize it with default values.
953 Throughout the course of your program, the handle will undergo modification as
954 user preferences change. You can use SavePrefsFile anytime to update the
955 preferences file, or wait until program exit to do so.
967 if (!have_prefs) { // not initialized....get a handle to the preferences file
968 InitPrefsFile('DCT2');
972 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
973 if (prefs_handle == NULL)
976 prefs = (Preferences *)(*prefs_handle);
977 err = LoadPrefsFile(prefs_handle);
979 DisposeHandle(prefs_handle);
984 for (i = 0; i < sizeof(Preferences); i++) {
989 if ( i == sizeof(Preferences) )
992 Config_digi_volume = prefs->digi_volume;
993 Config_midi_volume = prefs->midi_volume;
994 Config_master_volume = prefs->master_volume;
995 Config_redbook_volume = prefs->redbook_volume;
996 Config_channels_reversed = prefs->stereo_reverse;
997 gr_palette_set_gamma( (int)(prefs->gamma_level) );
999 Scanline_double = (int)prefs->pixel_double;
1001 Scanline_double = 0; // can't double with hardware acceleration
1003 Detail_level = prefs->detail_level;
1004 if (Detail_level == NUM_DETAIL_LEVELS-1) {
1005 Object_complexity = prefs->oc;
1006 Object_detail = prefs->od;
1007 Wall_detail = prefs->wd;
1008 Wall_render_depth = prefs->wrd;
1009 Debris_amount = prefs->da;
1010 SoundChannels = prefs->sc;
1011 set_custom_detail_vars();
1013 #ifdef PA_3DFX_VOODOO // Set to highest detail because you can't change em
1014 Object_complexity=Object_detail=Wall_detail=
1015 Wall_render_depth=Debris_amount=SoundChannels = NUM_DETAIL_LEVELS-1;
1016 Detail_level=NUM_DETAIL_LEVELS-1;
1017 set_custom_detail_vars();
1020 strncpy( config_last_player, prefs->lastplayer, CALLSIGN_LEN );
1021 p = strchr(config_last_player, '\n' );
1024 strncpy(config_last_mission, prefs->lastmission, MISSION_NAME_LEN);
1025 p = strchr(config_last_mission, '\n' );
1028 strcpy(config_last_ctb_cfg, prefs->ctb_config);
1030 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
1032 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
1034 joy_set_cal_vals( prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
1035 digi_set_volume( (Config_digi_volume*256)/8, (Config_midi_volume*256)/8 );
1036 digi_set_master_volume(Config_master_volume);
1038 gConfigInfo.mDoNotDisplayOptions = prefs->display_dialog;
1039 gConfigInfo.mUse11kSounds = prefs->sound_11k;
1040 gConfigInfo.mDisableSound = prefs->nosound;
1041 gConfigInfo.mDisableMIDIMusic = prefs->nomidi;
1042 gConfigInfo.mChangeResolution = prefs->change_resolution;
1043 gConfigInfo.mDoNotPlayMovies = prefs->no_movies;
1044 gConfigInfo.mGameMonitor = prefs->game_monitor;
1045 gConfigInfo.mAcceleration = prefs->enable_rave;
1046 gConfigInfo.mInputSprockets = prefs->enable_input_sprockets;
1048 DisposeHandle(prefs_handle);
1052 int WriteConfigFile()
1055 Handle prefs_handle;
1058 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
1059 if (prefs_handle == NULL)
1062 prefs = (Preferences *)(*prefs_handle);
1064 joy_get_cal_vals(prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
1065 prefs->digi_volume = Config_digi_volume;
1066 prefs->midi_volume = Config_midi_volume;
1067 prefs->stereo_reverse = Config_channels_reversed;
1068 prefs->detail_level = Detail_level;
1069 if (Detail_level == NUM_DETAIL_LEVELS-1) {
1070 prefs->oc = Object_complexity;
1071 prefs->od = Object_detail;
1072 prefs->wd = Wall_detail;
1073 prefs->wrd = Wall_render_depth;
1074 prefs->da = Debris_amount;
1075 prefs->sc = SoundChannels;
1077 prefs->gamma_level = (ubyte)gr_palette_get_gamma();
1080 prefs->pixel_double = (ubyte)Scanline_double; // hmm..don't write this out if doing hardware accel.
1082 strncpy( prefs->lastplayer, Players[Player_num].callsign, CALLSIGN_LEN );
1083 strncpy( prefs->lastmission, config_last_mission, MISSION_NAME_LEN );
1084 strcpy( prefs->ctb_config, config_last_ctb_cfg);
1085 prefs->ctb_tool = config_last_ctb_tool;
1086 prefs->master_volume = Config_master_volume;
1087 prefs->display_dialog = gConfigInfo.mDoNotDisplayOptions;
1088 prefs->change_resolution = gConfigInfo.mChangeResolution;
1089 prefs->nosound = gConfigInfo.mDisableSound;
1090 prefs->nomidi = gConfigInfo.mDisableMIDIMusic;
1091 prefs->sound_11k = gConfigInfo.mUse11kSounds;
1092 prefs->no_movies = gConfigInfo.mDoNotPlayMovies;
1093 prefs->game_monitor = gConfigInfo.mGameMonitor;
1094 prefs->redbook_volume = Config_redbook_volume;
1095 prefs->enable_rave = gConfigInfo.mAcceleration;
1096 prefs->enable_input_sprockets = gConfigInfo.mInputSprockets;
1098 err = SavePrefsFile(prefs_handle);
1099 DisposeHandle(prefs_handle);