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 * contains routine(s) to read in the configuration file which contains
17 * game configuration stuff like detail level, sound card, etc
25 #ifndef MACINTOSH // I'm going to totally seperate these routines -- yeeech!!!!
26 // see end of file for macintosh equivs
29 #define WIN32_LEAN_AND_MEAN
59 ubyte Config_control_type = 0;
60 ubyte Config_joystick_sensitivity = 8;
64 cvar_t Config_digi_type = { "DigiDeviceID8", "0", 1 };
65 cvar_t digi_driver_board_16 = { "DigiDeviceID16", "0", 1 };
66 //cvar_t digi_driver_port = { "DigiPort", "0", 1 };
67 //cvar_t digi_driver_irq = { "DigiIrq", "0", 1 };
68 cvar_t Config_digi_dma = { "DigiDma8", "0", 1 };
69 cvar_t digi_driver_dma_16 = { "DigiDma16", "0", 1 };
70 cvar_t Config_midi_type = { "MidiDeviceID", "0", 1 };
71 //cvar_t digi_midi_port = { "MidiPort", "0", 1 };
73 cvar_t Config_digi_volume = { "DigiVolume", "8", 1 };
74 cvar_t Config_midi_volume = { "MidiVolume", "8", 1 };
75 cvar_t Config_redbook_volume = { "RedbookVolume", "8", 1 };
76 cvar_t Config_detail_level = { "DetailLevel", "4", 1 };
77 cvar_t Config_gamma_level = { "GammaLevel", "0", 1 };
78 cvar_t Config_channels_reversed = { "StereoReverse", "0", 1 };
79 cvar_t Config_joystick_min = { "JoystickMin", "0,0,0,0", 1 };
80 cvar_t Config_joystick_max = { "JoystickMax", "0,0,0,0", 1 };
81 cvar_t Config_joystick_cen = { "JoystickCen", "0,0,0,0", 1 };
82 cvar_t config_last_player = { "LastPlayer", "", 1 };
83 cvar_t config_last_mission = { "LastMission", "", 1 };
84 cvar_t Config_vr_type = { "VR_type", "0", 1 };
85 cvar_t Config_vr_resolution = { "VR_resolution", "0", 1 };
86 cvar_t Config_vr_tracking = { "VR_tracking", "0", 1 };
89 #define _CRYSTAL_LAKE_8_ST 0xe201
90 #define _CRYSTAL_LAKE_16_ST 0xe202
91 #define _AWE32_8_ST 0xe208
92 #define _AWE32_16_ST 0xe209
95 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
97 void set_custom_detail_vars(void);
103 void CrystalLakeWriteMCP( ushort mc_addr, ubyte mc_data )
106 outp( CL_MC0, 0xE2 ); // Write password
107 outp( mc_addr, mc_data ); // Write data
111 ubyte CrystalLakeReadMCP( ushort mc_addr )
115 outp( CL_MC0, 0xE2 ); // Write password
116 value = inp( mc_addr ); // Read data
121 void CrystalLakeSetSB()
124 tmp = CrystalLakeReadMCP( CL_MC1 );
126 CrystalLakeWriteMCP( CL_MC1, tmp );
129 void CrystalLakeSetWSS()
132 tmp = CrystalLakeReadMCP( CL_MC1 );
134 CrystalLakeWriteMCP( CL_MC1, tmp );
137 //MovieHires might be changed by -nohighres, so save a "real" copy of it
139 int save_redbook_enabled;
142 void CheckMovieAttributes()
145 DWORD len, type, val;
148 lres = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Parallax\\Descent II\\1.1\\INSTALL",
150 if (lres == ERROR_SUCCESS) {
152 lres = RegQueryValueEx(hKey, "HIRES", NULL, &type, &val, &len);
153 if (lres == ERROR_SUCCESS) {
154 cvar_setint( &MovieHires, val );
155 logentry("HIRES=%d\n", val);
163 static int config_initialized;
165 static void config_init(void)
167 /* make sure our cvars are registered */
168 cvar_registervariable(&Config_digi_volume);
169 cvar_registervariable(&Config_midi_volume);
170 cvar_registervariable(&Redbook_enabled);
171 cvar_registervariable(&Config_redbook_volume);
172 cvar_registervariable(&Config_channels_reversed);
173 cvar_registervariable(&Config_gamma_level);
174 cvar_registervariable(&Config_detail_level);
175 cvar_registervariable(&Config_joystick_min);
176 cvar_registervariable(&Config_joystick_cen);
177 cvar_registervariable(&Config_joystick_max);
178 cvar_registervariable(&config_last_player);
179 cvar_registervariable(&config_last_mission);
180 cvar_registervariable(&Config_vr_type);
181 cvar_registervariable(&Config_vr_resolution);
182 cvar_registervariable(&Config_vr_tracking);
183 cvar_registervariable(&MovieHires);
185 config_initialized = 1;
189 void LoadConfigDefaults(void)
191 cmd_append("bind UP +lookdown; bind PAD8 +lookdown");
192 cmd_append("bind DOWN +lookup; bind PAD2 +lookup");
193 cmd_append("bind LEFT +left; bind PAD4 +left");
194 cmd_append("bind RIGHT +right; bind PAD6 +right");
196 cmd_append("bind LALT +strafe");
197 cmd_append("bind PAD1 +moveleft");
198 cmd_append("bind PAD3 +moveright");
199 cmd_append("bind PAD- +moveup");
200 cmd_append("bind PAD+ +movedown");
202 cmd_append("bind Q +bankleft; bind PAD7 +bankleft");
203 cmd_append("bind E +bankright; bind PAD9 +bankright");
205 cmd_append("bind , +cycle");
206 cmd_append("bind . +cycle2");
208 cmd_append("bind LCTRL +attack; bind RCTRL +attack");
209 cmd_append("bind SPC +attack2");
210 cmd_append("bind F +flare");
211 cmd_append("bind B +bomb");
213 cmd_append("bind R +rearview");
214 cmd_append("bind TAB +automap");
216 cmd_append("bind A +forward");
217 cmd_append("bind Z +back");
218 cmd_append("bind S +afterburner");
220 cmd_append("bind H +headlight");
221 cmd_append("bind T +nrgshield");
223 cmd_append("bind J1B1 +attack");
224 cmd_append("bind J1B2 +attack2");
226 cmd_append("bind MB1 +attack");
227 cmd_append("bind MB2 +attack2");
229 cmd_append("bind 1 weapon 1");
230 cmd_append("bind 2 weapon 2");
231 cmd_append("bind 3 weapon 3");
232 cmd_append("bind 4 weapon 4");
233 cmd_append("bind 5 weapon 5");
234 cmd_append("bind 6 weapon 6");
235 cmd_append("bind 7 weapon 7");
236 cmd_append("bind 8 weapon 8");
237 cmd_append("bind 9 weapon 9");
238 cmd_append("bind 0 weapon 0");
245 int joy_axis_center[7];
249 if (!config_initialized)
252 cvar_set_cvar( &config_last_player, "" );
254 joy_axis_min[0] = joy_axis_min[1] = joy_axis_min[2] = joy_axis_min[3] = 0;
255 joy_axis_max[0] = joy_axis_max[1] = joy_axis_max[2] = joy_axis_max[3] = 0;
256 joy_axis_center[0] = joy_axis_center[1] = joy_axis_center[2] = joy_axis_center[3] = 0;
258 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
261 cvar_setint(&digi_driver_board, 0);
262 cvar_setint(&digi_driver_port, 0);
263 cvar_setint(&digi_driver_irq, 0);
264 cvar_setint(&digi_driver_dma, 0);
265 cvar_setint(&digi_midi_type, 0);
266 cvar_setint(&digi_midi_port, 0);
269 cvar_setint( &Config_digi_volume, 8 );
270 cvar_setint( &Config_midi_volume, 8 );
271 cvar_setint( &Config_redbook_volume, 8 );
272 Config_control_type = 0;
273 cvar_setint( &Config_channels_reversed, 0);
275 //set these here in case no cfg file
276 SaveMovieHires = MovieHires.intval;
277 save_redbook_enabled = Redbook_enabled.intval;
279 if (cfexist("descent.cfg"))
280 cmd_append("exec descent.cfg");
282 LoadConfigDefaults();
286 /* TODO: allow cvars to define a callback that will carry out these initialization things on change. */
288 gr_palette_set_gamma( Config_gamma_level.intval );
290 Detail_level = strtol(Config_detail_level.string, NULL, 10);
291 if (Detail_level == NUM_DETAIL_LEVELS - 1) {
292 int count,dummy,oc,od,wd,wrd,da,sc;
294 count = sscanf (Config_detail_level.string, "%d,%d,%d,%d,%d,%d,%d\n",&dummy,&oc,&od,&wd,&wrd,&da,&sc);
297 Object_complexity = oc;
300 Wall_render_depth = wrd;
303 set_custom_detail_vars();
307 sscanf( Config_joystick_min.string, "%d,%d,%d,%d", &joy_axis_min[0], &joy_axis_min[1], &joy_axis_min[2], &joy_axis_min[3] );
308 sscanf( Config_joystick_max.string, "%d,%d,%d,%d", &joy_axis_max[0], &joy_axis_max[1], &joy_axis_max[2], &joy_axis_max[3] );
309 sscanf( Config_joystick_cen.string, "%d,%d,%d,%d", &joy_axis_center[0], &joy_axis_center[1], &joy_axis_center[2], &joy_axis_center[3] );
311 joy_set_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
313 i = FindArg( "-volume" );
316 i = atoi( Args[i+1] );
318 if ( i > 100 ) i = 100;
319 cvar_setint( &Config_digi_volume, (i * 8) / 100 );
320 cvar_setint( &Config_midi_volume, (i * 8) / 100 );
321 cvar_setint( &Config_redbook_volume, (i * 8) / 100 );
324 if ( Config_digi_volume.intval > 8 ) cvar_setint( &Config_digi_volume, 8 );
325 if ( Config_midi_volume.intval > 8 ) cvar_setint( &Config_midi_volume, 8 );
326 if ( Config_redbook_volume.intval > 8 ) cvar_setint( &Config_redbook_volume, 8 );
328 digi_set_volume( (Config_digi_volume.intval * 32768) / 8, (Config_midi_volume.intval * 128) / 8 );
331 printf( "DigiDeviceID: 0x%x\n", digi_driver_board );
332 printf( "DigiPort: 0x%x\n", digi_driver_port.intval );
333 printf( "DigiIrq: 0x%x\n", digi_driver_irq.intval );
334 printf( "DigiDma: 0x%x\n", digi_driver_dma.intval );
335 printf( "MidiDeviceID: 0x%x\n", digi_midi_type.intval );
336 printf( "MidiPort: 0x%x\n", digi_midi_port.intval );
339 cvar_setint( &Config_midi_type, digi_midi_type );
340 cvar_setint( &Config_digi_type, digi_driver_board );
341 cvar_setint( &Config_digi_dma, digi_driver_dma );
345 if (digi_driver_board_16.intval > 0 && !FindArg("-no16bit") && digi_driver_board_16.intval != _GUS_16_ST) {
346 digi_driver_board = digi_driver_board_16.intval;
347 digi_driver_dma = digi_driver_dma_16.intval;
351 //Hack to make some cards look like others, such as
352 //the Crytal Lake look like Microsoft Sound System
353 if ( digi_driver_board == _CRYSTAL_LAKE_8_ST ) {
355 tmp = CrystalLakeReadMCP( CL_MC1 );
357 atexit( CrystalLakeSetSB ); // Restore to SB when done.
359 digi_driver_board = _MICROSOFT_8_ST;
360 } else if ( digi_driver_board == _CRYSTAL_LAKE_16_ST ) {
362 tmp = CrystalLakeReadMCP( CL_MC1 );
364 atexit( CrystalLakeSetSB ); // Restore to SB when done.
366 digi_driver_board = _MICROSOFT_16_ST;
367 } else if ( digi_driver_board == _AWE32_8_ST ) {
368 digi_driver_board = _SB16_8_ST;
369 } else if ( digi_driver_board == _AWE32_16_ST ) {
370 digi_driver_board = _SB16_16_ST;
372 digi_driver_board = digi_driver_board;
375 if (cfexist("descentw.cfg")) {
376 cmd_append("exec descentw.cfg");
379 sscanf( Config_joystick_min.string, "%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] );
380 sscanf( Config_joystick_max.string, "%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] );
381 sscanf( Config_joystick_cen.string, "%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] );
388 int WriteConfigFile()
390 PHYSFS_file *outfile;
392 int joy_axis_center[7];
395 joy_get_cal_vals(joy_axis_min, joy_axis_center, joy_axis_max);
397 if (FindArg("-noredbook"))
398 cvar_setint( &Redbook_enabled, save_redbook_enabled );
400 cvar_setint( &Config_gamma_level, gr_palette_get_gamma() );
402 if (Detail_level == NUM_DETAIL_LEVELS-1)
403 cvar_set_cvarf( &Config_detail_level, "%d,%d,%d,%d,%d,%d,%d", Detail_level,
404 Object_complexity,Object_detail,Wall_detail,Wall_render_depth,Debris_amount,SoundChannels );
406 cvar_setint( &Config_detail_level, Detail_level );
408 cvar_set_cvarf( &Config_joystick_min, "%d,%d,%d,%d", joy_axis_min[0], joy_axis_min[1], joy_axis_min[2], joy_axis_min[3] );
409 cvar_set_cvarf( &Config_joystick_cen, "%d,%d,%d,%d", joy_axis_center[0], joy_axis_center[1], joy_axis_center[2], joy_axis_center[3] );
410 cvar_set_cvarf( &Config_joystick_max, "%d,%d,%d,%d", joy_axis_max[0], joy_axis_max[1], joy_axis_max[2], joy_axis_max[3] );
412 cvar_set_cvar( &config_last_player, Players[Player_num].callsign );
414 cvar_setint( &MovieHires, SaveMovieHires );
416 outfile = PHYSFSX_openWriteBuffered("descent.cfg");
420 key_write_bindings(outfile);
421 PHYSFS_close(outfile);
423 if (FindArg("-nohires") || FindArg("-nohighres") || FindArg("-lowresmovies"))
424 cvar_setint( &MovieHires, 0 );
427 CheckMovieAttributes();
433 #else // !defined(MACINTOSH)
442 #include <GestaltEqu.h>
444 #include <Processes.h>
445 #include <Resources.h>
458 #include "prefs.h" // prefs file for configuration stuff -- from DeSalvo
460 #define MAX_CTB_LEN 512
462 typedef struct preferences {
465 ubyte stereo_reverse;
467 ubyte oc; // object complexity
468 ubyte od; // object detail
469 ubyte wd; // wall detail
470 ubyte wrd; // wall render depth
471 ubyte da; // debris amount
472 ubyte sc; // sound channels
477 int joy_axis_center[4];
478 char lastplayer[CALLSIGN_LEN+1];
479 char lastmission[MISSION_NAME_LEN+1];
480 char ctb_config[MAX_CTB_LEN];
483 ubyte display_dialog;
484 ubyte change_resolution;
490 ubyte redbook_volume;
492 ubyte enable_input_sprockets;
495 char config_last_player[CALLSIGN_LEN+1] = "";
496 char config_last_mission[MISSION_NAME_LEN+1] = "";
497 char config_last_ctb_cfg[MAX_CTB_LEN] = "";
498 int config_last_ctb_tool;
499 ubyte Config_master_volume = 4;
500 ubyte Config_digi_volume = 8;
501 ubyte Config_midi_volume = 8;
502 ubyte Config_redbook_volume = 8;
503 ubyte Config_control_type = 0;
504 ubyte Config_channels_reversed = 0;
505 ubyte Config_joystick_sensitivity = 8;
507 int Config_vr_type = 0;
508 int Config_vr_resolution = 0;
509 int Config_vr_tracking = 0;
511 extern sbyte Object_complexity, Object_detail, Wall_detail, Wall_render_depth, Debris_amount, SoundChannels;
512 extern void digi_set_master_volume( int volume );
514 void set_custom_detail_vars(void);
516 static ubyte have_prefs = 0;
518 //¥ ------------------------------ Private Definitions
519 //¥ ------------------------------ Private Types
528 } PrefsInfo, *PrefsInfoPtr, **PrefsInfoHandle;
530 //¥ ------------------------------ Private Variables
532 static PrefsInfo prefsInfo;
533 static Boolean prefsInited = 0;
535 //¥ ------------------------------ Private Functions
537 static void Pstrcpy(StringPtr dst, StringPtr src);
538 static void Pstrcat(StringPtr dst, StringPtr src);
539 static Boolean FindPrefsFile(short *prefVRefNum, long *prefDirID);
541 //¥ -------------------- Pstrcpy
544 Pstrcpy(StringPtr dst, StringPtr src)
546 BlockMove(src, dst, (*src) + 1);
549 //¥ -------------------- Pstrcat
552 Pstrcat(StringPtr dst, StringPtr src)
554 BlockMove(src + 1, dst + (*dst) + 1, *src);
558 //¥ -------------------- FindPrefsFile
561 FindPrefsFile(short *prefVRefNum, long *prefDirID)
570 theErr = Gestalt(gestaltFindFolderAttr, &response);
571 if (theErr == noErr && ((response >> gestaltFindFolderPresent) & 1))
573 //¥ Find (or make) it the easy way...
574 theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, prefVRefNum, prefDirID);
579 StringPtr prefFolderName = "\pPreferences";
581 //¥ yeachh -- we have to do it all by hand!
582 theErr = SysEnvirons(1, &theSysEnv);
586 *prefVRefNum = theSysEnv.sysVRefNum;
588 //¥ Check whether Preferences folder already exists
589 infoPB.hFileInfo.ioCompletion = 0;
590 infoPB.hFileInfo.ioNamePtr = prefFolderName;
591 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
592 infoPB.hFileInfo.ioFDirIndex = 0;
593 infoPB.hFileInfo.ioDirID = 0;
595 theErr = PBGetCatInfo(&infoPB, 0);
598 *prefDirID = infoPB.hFileInfo.ioDirID;
600 else if (theErr == fnfErr) //¥ Preferences doesn't already exist
602 HParamBlockRec dirPB;
604 //¥ Create "Preferences" folder
605 dirPB.fileParam.ioCompletion = 0;
606 dirPB.fileParam.ioVRefNum = *prefVRefNum;
607 dirPB.fileParam.ioNamePtr = prefFolderName;
608 dirPB.fileParam.ioDirID = 0;
610 theErr = PBDirCreate(&dirPB, 0);
612 *prefDirID = dirPB.fileParam.ioDirID;
616 //¥ If we make it here OK, create Preferences file if necessary
619 infoPB.hFileInfo.ioCompletion = 0;
620 infoPB.hFileInfo.ioNamePtr = prefsInfo.fileName;
621 infoPB.hFileInfo.ioVRefNum = *prefVRefNum;
622 infoPB.hFileInfo.ioFDirIndex = 0;
623 infoPB.hFileInfo.ioDirID = *prefDirID;
625 theErr = PBGetCatInfo(&infoPB, 0);
626 if (theErr == fnfErr)
628 theErr = HCreate(*prefVRefNum, *prefDirID, prefsInfo.fileName, prefsInfo.creator, prefsInfo.fileType);
631 HCreateResFile(*prefVRefNum, *prefDirID, prefsInfo.fileName);
637 return (theErr == noErr);
640 //¥ -------------------- InitPrefsFile
642 #define UNKNOWN_TYPE 0x3f3f3f3f
645 InitPrefsFile(OSType creator)
648 PrefsInfoHandle piHdl;
650 if ((piHdl = (PrefsInfoHandle) GetResource('PRFI', 0)) == nil)
652 ProcessSerialNumber thePSN;
653 ProcessInfoRec thePIR;
655 StringPtr app_string;
658 GetCurrentProcess(&thePSN);
659 thePIR.processName = nil;
660 thePIR.processAppSpec = &appSpec;
662 //¥ Set default to 'ÇApplicationÈ Prefs', PREF 0
663 err = GetProcessInformation(&thePSN, &thePIR);
667 app_string = LMGetCurApName();
668 // Pstrcpy(prefsInfo.fileName, appSpec.name);
669 Pstrcpy(prefsInfo.fileName, app_string);
670 Pstrcat(prefsInfo.fileName, "\p Preferences");
672 //¥ Set creator to calling application's signature (should be able to
673 //¥ Determine this automatically, but unable to for some reason)
674 prefsInfo.creator = creator;
675 prefsInfo.fileType = 'pref';
676 prefsInfo.resType = 'pref';
681 //¥ Get Preferences file setup from PRFI 0
682 BlockMove(*piHdl, &prefsInfo, sizeof (prefsInfo));
683 ReleaseResource((Handle) piHdl);
685 if (prefsInfo.creator == UNKNOWN_TYPE)
686 prefsInfo.creator = creator;
692 //¥ -------------------- LoadPrefsFile
695 LoadPrefsFile(Handle prefsHdl)
697 short prefVRefNum, prefRefNum;
699 OSErr theErr = noErr;
701 Size prefSize, origSize;
704 return (nilHandleErr);
706 prefSize = GetHandleSize(prefsHdl);
708 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
711 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
712 if (prefRefNum == -1)
715 //¥ Not finding the resource is not an error -- caller will use default data
716 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
718 origSize = GetHandleSize(origHdl);
719 if (origSize > prefSize) //¥ Extend handle for extra stored data
720 SetHandleSize(prefsHdl, origSize);
722 BlockMove(*origHdl, *prefsHdl, origSize);
723 ReleaseResource(origHdl);
726 CloseResFile(prefRefNum);
734 //¥ -------------------- SavePrefsFile
737 SavePrefsFile(Handle prefHdl)
739 short prefVRefNum, prefRefNum;
741 Handle origHdl = nil;
742 Size origSize, prefSize;
743 OSErr theErr = noErr;
745 if (! FindPrefsFile(&prefVRefNum, &prefDirID))
749 return (nilHandleErr);
751 prefSize = GetHandleSize(prefHdl);
753 prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsInfo.fileName, fsRdWrPerm);
754 if (prefRefNum == -1)
757 if ((origHdl = Get1Resource(prefsInfo.resType, prefsInfo.resID)) != nil)
759 //¥ Overwrite existing preferences
760 origSize = GetHandleSize(origHdl);
761 if (prefSize > origSize)
762 SetHandleSize(origHdl, prefSize);
764 BlockMove(*prefHdl, *origHdl, prefSize);
765 ChangedResource(origHdl);
766 WriteResource(origHdl);
767 ReleaseResource(origHdl);
771 //¥ Store specified preferences for the first time
772 AddResource(prefHdl, prefsInfo.resType, prefsInfo.resID, "\p");
773 WriteResource(prefHdl);
774 DetachResource(prefHdl);
777 CloseResFile(prefRefNum);
785 //¥ -------------------------------------------------------------------------------------------
789 This module provides the ability to save and load a preferences file in the
790 Preferences folder in the System Folder. An optional resource, PRFI 0,
791 is used to provide specifications for the preferences file (creator, etc.).
793 Three functions are provided:
795 void InitPrefsFile(OSType creator)
797 This function will initialize the preferences file, that is, it will create
798 it in the appropriate place if it doesn't currently exist. It should be
799 called with the creator code for the application. Note that the creator
800 code specified in PRFI 0 (if any) will be used only if the creator code
801 passed to this function is '????'. Without the PRFI 0 resource, the default
804 File Name: "{Application} Prefs" (i.e., the name of the app plus " Prefs"
805 Creator: the creator passed to InitPrefsFile
807 Pref Resource Type: 'PREF'
810 The PRFI 0 resource allows you to specify overrides for each of the above
811 values. This is useful for development, since the application name might
812 go through changes, but the preferences file name is held constant.
814 OSErr LoadPrefsFile(Handle prefsHndl)
816 This function will attempt to copy the data stored in the preferences
817 file to the given handle (which must be pre-allocated). If the handle is too
818 small, then it will be enlarged. If it is too large, it will not be resized.
819 The data in the preferences file (normally in PREF 0) will then be copied
820 into the handle. If the preferences file did not exist, the original data
821 in the handle will not change.
823 OSErr SavePrefsFile(Handle prefsHndl)
825 This function will attempt to save the given handle to the preferences
826 file. Its contents will completely replace the previous data (normally
827 the PREF 0 resource).
829 In typical use, you will use InitPrefsFile once, then allocate a handle large
830 enough to contain your preferences data, and initialize it with default values.
831 Throughout the course of your program, the handle will undergo modification as
832 user preferences change. You can use SavePrefsFile anytime to update the
833 preferences file, or wait until program exit to do so.
845 if (!have_prefs) { // not initialized....get a handle to the preferences file
846 InitPrefsFile('DCT2');
850 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
851 if (prefs_handle == NULL)
854 prefs = (Preferences *)(*prefs_handle);
855 err = LoadPrefsFile(prefs_handle);
857 DisposeHandle(prefs_handle);
862 for (i = 0; i < sizeof(Preferences); i++) {
867 if ( i == sizeof(Preferences) )
870 Config_digi_volume = prefs->digi_volume;
871 Config_midi_volume = prefs->midi_volume;
872 Config_master_volume = prefs->master_volume;
873 Config_redbook_volume = prefs->redbook_volume;
874 Config_channels_reversed = prefs->stereo_reverse;
875 gr_palette_set_gamma( (int)(prefs->gamma_level) );
877 Scanline_double = (int)prefs->pixel_double;
879 Scanline_double = 0; // can't double with hardware acceleration
881 Detail_level = prefs->detail_level;
882 if (Detail_level == NUM_DETAIL_LEVELS-1) {
883 Object_complexity = prefs->oc;
884 Object_detail = prefs->od;
885 Wall_detail = prefs->wd;
886 Wall_render_depth = prefs->wrd;
887 Debris_amount = prefs->da;
888 SoundChannels = prefs->sc;
889 set_custom_detail_vars();
892 strncpy( config_last_player, prefs->lastplayer, CALLSIGN_LEN );
893 p = strchr(config_last_player, '\n' );
896 strncpy(config_last_mission, prefs->lastmission, MISSION_NAME_LEN);
897 p = strchr(config_last_mission, '\n' );
900 strcpy(config_last_ctb_cfg, prefs->ctb_config);
902 if ( Config_digi_volume > 8 ) Config_digi_volume = 8;
904 if ( Config_midi_volume > 8 ) Config_midi_volume = 8;
906 joy_set_cal_vals( prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
907 digi_set_volume( (Config_digi_volume*256)/8, (Config_midi_volume*256)/8 );
908 digi_set_master_volume(Config_master_volume);
910 gConfigInfo.mDoNotDisplayOptions = prefs->display_dialog;
911 gConfigInfo.mUse11kSounds = prefs->sound_11k;
912 gConfigInfo.mDisableSound = prefs->nosound;
913 gConfigInfo.mDisableMIDIMusic = prefs->nomidi;
914 gConfigInfo.mChangeResolution = prefs->change_resolution;
915 gConfigInfo.mDoNotPlayMovies = prefs->no_movies;
916 gConfigInfo.mGameMonitor = prefs->game_monitor;
917 gConfigInfo.mAcceleration = prefs->enable_rave;
918 gConfigInfo.mInputSprockets = prefs->enable_input_sprockets;
920 DisposeHandle(prefs_handle);
924 int WriteConfigFile()
930 prefs_handle = NewHandleClear(sizeof(Preferences)); // new prefs handle
931 if (prefs_handle == NULL)
934 prefs = (Preferences *)(*prefs_handle);
936 joy_get_cal_vals(prefs->joy_axis_min, prefs->joy_axis_center, prefs->joy_axis_max);
937 prefs->digi_volume = Config_digi_volume;
938 prefs->midi_volume = Config_midi_volume;
939 prefs->stereo_reverse = Config_channels_reversed;
940 prefs->detail_level = Detail_level;
941 if (Detail_level == NUM_DETAIL_LEVELS-1) {
942 prefs->oc = Object_complexity;
943 prefs->od = Object_detail;
944 prefs->wd = Wall_detail;
945 prefs->wrd = Wall_render_depth;
946 prefs->da = Debris_amount;
947 prefs->sc = SoundChannels;
949 prefs->gamma_level = (ubyte)gr_palette_get_gamma();
952 prefs->pixel_double = (ubyte)Scanline_double; // hmm..don't write this out if doing hardware accel.
954 strncpy( prefs->lastplayer, Players[Player_num].callsign, CALLSIGN_LEN );
955 strncpy( prefs->lastmission, config_last_mission, MISSION_NAME_LEN );
956 strcpy( prefs->ctb_config, config_last_ctb_cfg);
957 prefs->ctb_tool = config_last_ctb_tool;
958 prefs->master_volume = Config_master_volume;
959 prefs->display_dialog = gConfigInfo.mDoNotDisplayOptions;
960 prefs->change_resolution = gConfigInfo.mChangeResolution;
961 prefs->nosound = gConfigInfo.mDisableSound;
962 prefs->nomidi = gConfigInfo.mDisableMIDIMusic;
963 prefs->sound_11k = gConfigInfo.mUse11kSounds;
964 prefs->no_movies = gConfigInfo.mDoNotPlayMovies;
965 prefs->game_monitor = gConfigInfo.mGameMonitor;
966 prefs->redbook_volume = Config_redbook_volume;
967 prefs->enable_rave = gConfigInfo.mAcceleration;
968 prefs->enable_input_sprockets = gConfigInfo.mInputSprockets;
970 err = SavePrefsFile(prefs_handle);
971 DisposeHandle(prefs_handle);