Example #1
0
static int ReadLevelInfo (CFile& cf)
{
if (gameTopFileInfo.fileinfoVersion >= 31) { //load mine filename
	// read newline-terminated string, not sure what version this changed.
	cf.GetS (gameData.missions.szCurrentLevel, sizeof (gameData.missions.szCurrentLevel));

	if (gameData.missions.szCurrentLevel [strlen (gameData.missions.szCurrentLevel) - 1] == '\n')
		gameData.missions.szCurrentLevel [strlen (gameData.missions.szCurrentLevel) - 1] = 0;
}
else if (gameTopFileInfo.fileinfoVersion >= 14) { //load mine filename
	// read null-terminated string
	char *p = gameData.missions.szCurrentLevel;
	//must do read one char at a time, since no cf.GetS()
	do {
		*p = cf.GetC ();
		} while (*p++);
}
else
	gameData.missions.szCurrentLevel [0] = 0;
if (gameTopFileInfo.fileinfoVersion >= 19) {	//load pof names
	nSavePOFNames = cf.ReadShort ();
	if ((nSavePOFNames != 0x614d) && (nSavePOFNames != 0x5547)) { // "Ma"de w/DMB beta/"GU"ILE
		if (nSavePOFNames >= MAX_POLYGON_MODELS)
			return -1;
		cf.Read (szSavePOFNames, nSavePOFNames, SHORT_FILENAME_LEN);
		}
	}
return 0;
}
Example #2
0
// ----------------------------------------------------------------------------
//loads a level (.LVL) file from disk
//returns 0 if success, else error code
int LoadLevelData (char * pszFilename, int nLevel)
{
	CFile cf;
	char	filename [128];
	int	sig, nMineDataOffset, nGameDataOffset;
	int	nError;

SetDataVersion (-1);
gameData.segs.bHaveSlideSegs = 0;
if (gameData.app.nGameMode & GM_NETWORK) {
	gameData.multiplayer.maxPowerupsAllowed.Clear (0);
	gameData.multiplayer.powerupsInMine.Clear (0);
	}
#if DBG
Level_being_loaded = pszFilename;
#endif

gameStates.render.nMeshQuality = gameOpts->render.nMeshQuality;

for (;;) {
	strcpy (filename, pszFilename);
	if (!cf.Open (filename, "", "rb", gameStates.app.bD1Mission))
		return 1;

	strcpy(gameData.segs.szLevelFilename, filename);

	//	#ifdef NEWDEMO
	//	if (gameData.demo.nState == ND_STATE_RECORDING)
	//		NDRecordStartDemo();
	//	#endif

	sig = cf.ReadInt ();
	gameData.segs.nLevelVersion = cf.ReadInt ();
	gameStates.app.bD2XLevel = (gameData.segs.nLevelVersion >= 10);
	#if TRACE
	console.printf (CON_DBG, "gameData.segs.nLevelVersion = %d\n", gameData.segs.nLevelVersion);
	#endif
	nMineDataOffset = cf.ReadInt ();
	nGameDataOffset = cf.ReadInt ();

	Assert(sig == MAKE_SIG('P','L','V','L'));
	if (gameData.segs.nLevelVersion >= 8) {    //read dummy data
		cf.ReadInt ();
		cf.ReadShort ();
		cf.ReadByte ();
	}

	if (gameData.segs.nLevelVersion < 5)
		cf.ReadInt ();       //was hostagetext_offset

	if (gameData.segs.nLevelVersion > 1) {
		cf.GetS (szCurrentLevelPalette, sizeof (szCurrentLevelPalette));
		if (szCurrentLevelPalette [strlen(szCurrentLevelPalette) - 1] == '\n')
			szCurrentLevelPalette [strlen(szCurrentLevelPalette) - 1] = 0;
	}
	if ((gameData.segs.nLevelVersion <= 1) || (szCurrentLevelPalette [0] == 0)) // descent 1 level
		strcpy (szCurrentLevelPalette, DEFAULT_LEVEL_PALETTE); //D1_PALETTE

	if (gameData.segs.nLevelVersion >= 3)
		gameStates.app.nBaseCtrlCenExplTime = cf.ReadInt ();
	else
		gameStates.app.nBaseCtrlCenExplTime = DEFAULT_CONTROL_CENTER_EXPLOSION_TIME;

	if (gameData.segs.nLevelVersion >= 4)
		gameData.reactor.nStrength = cf.ReadInt ();
	else
		gameData.reactor.nStrength = -1;  //use old defaults

	if (gameData.segs.nLevelVersion >= 7) {
	#if TRACE
		console.printf (CON_DBG, "   loading dynamic lights ...\n");
	#endif
		if (0 > ReadVariableLights (cf)) {
			cf.Close ();
			return 5;
			}
		}	

	if (gameData.segs.nLevelVersion < 6) {
		gameData.segs.secret.nReturnSegment = 0;
		gameData.segs.secret.returnOrient = CFixMatrix::IDENTITY;
		}
	else {
		gameData.segs.secret.nReturnSegment = cf.ReadInt ();
		for (int i = 0; i < 9; i++)
			gameData.segs.secret.returnOrient [i] = cf.ReadInt ();
		}

	//NOTE LINK TO ABOVE!!
	cf.Seek (nGameDataOffset, SEEK_SET);
	nError = LoadMineDataCompiled (cf, 1);
	cf.Seek (nMineDataOffset, SEEK_SET);
	nError = LoadMineSegmentsCompiled (cf);
	if (nError == -1) {   //error!!
		cf.Close ();
		return 2;
		}
	cf.Seek (nGameDataOffset, SEEK_SET);
	gameData.objs.lists.Init ();
	nError = LoadMineDataCompiled (cf, 0);
	if (nError == -1) {   //error!!
		cf.Close ();
		return 3;
		}
	cf.Close ();
	networkData.nSegmentCheckSum = CalcSegmentCheckSum ();
	if (meshBuilder.Build (nLevel))
		break;
	if (gameStates.render.nMeshQuality <= 0)
		return 6;
	gameStates.render.nMeshQuality--;
	}
gameStates.render.nMeshQuality = gameOpts->render.nMeshQuality;
#if 0
if (!(gameData.render.lights.Create () &&
		gameData.render.color.Create () &&
		gameData.render.shadows.Create ()))
	return 7;
#endif	
if (!gameData.render.mine.Create ())
	return 4;
lightManager.Setup (nLevel); //moved to loadgame.cpp::LoadLevel()

SetAmbientSoundFlags ();
return 0;
}
Example #3
0
//if filename passed is NULL, show Normal credits
void ShowCredits(char *credits_filename)
{
	int			i, j, l, bDone;
	CFile			cf;
	char			buffer [NUM_LINES_HIRES][80];
	grsBitmap	bmBackdrop;
	int			nPcxError;
	unsigned int	nLine = 0;
	unsigned int	nXlLine = 0;
	fix			xTimeout, xDelay = X2I (2800 * 1000);
	int			nFirstLineOffs, nExtraInc = 0;
	int			bBinary = 0;
	char			*pszTemp;
	char			filename [32];
	int			xOffs, yOffs;
	box			dirtyBox [NUM_LINES_HIRES];
	gsrCanvas	*creditsOffscreenBuf = NULL;
	gsrCanvas	*saveCanv = grdCurCanv;

	// Clear out all tex buffer lines.
memset (buffer, 0, sizeof (buffer));
memset (dirtyBox, 0, sizeof (dirtyBox));

sprintf(filename, "%s", CREDITS_FILE);
bBinary = 0;
if (credits_filename) {
	strcpy(filename,credits_filename);
	bBinary = 1;
	}
if (!cf.Open (filename, gameFolders.szDataDir, "rb", 0)) {
	char nfile [32];

	if (credits_filename)
		return;		//ok to not find special filename

	if ((pszTemp = strchr (filename, '.')))
		*pszTemp = '\0';
	sprintf (nfile, "%s.txb", filename);
	if (!cf.Open (nfile, gameFolders.szDataDir, "rb", 0))
		Error("Missing CREDITS.TEX and CREDITS.TXB &cf\n");
	bBinary = 1;
	}
SetScreenMode(SCREEN_MENU);
xOffs = (grdCurCanv->cvBitmap.bmProps.w - 640) / 2;
yOffs = (grdCurCanv->cvBitmap.bmProps.h - 480) / 2;
if (xOffs < 0)
	xOffs = 0;
if (yOffs < 0)
	yOffs = 0;
creditsPalette = GrUsePaletteTable("credits.256", NULL);
GrPaletteStepLoad (NULL);
header_font = GrInitFont(gameStates.menus.bHires ? (char *) "font1-1h.fnt" : (char *) "font1-1.fnt");
title_font = GrInitFont(gameStates.menus.bHires ? (char *) "font2-3h.fnt" : (char *) "font2-3.fnt");
names_font = GrInitFont(gameStates.menus.bHires ? (char *) "font2-2h.fnt" : (char *) "font2-2.fnt");
bmBackdrop.bmTexBuf = NULL;
bmBackdrop.bmPalette = NULL;

//MWA  Made bmBackdrop bitmap linear since it should always be.  the current canvas may not
//MWA  be linear, so we can't rely on grdCurCanv->cvBitmap->bmProps.nType.

nPcxError = PCXReadBitmap ((char *) CREDITS_BACKGROUND_FILENAME, &bmBackdrop, BM_LINEAR, 0);
if (nPcxError != PCX_ERROR_NONE) {
	cf.Close();
	return;
	}
SongsPlaySong(SONG_CREDITS, 1);
GrRemapBitmapGood(&bmBackdrop, NULL, -1, -1);

if (!gameOpts->menus.nStyle) {
	GrSetCurrentCanvas(NULL);
	GrBitmap(xOffs,yOffs,&bmBackdrop);
	if ((grdCurCanv->cvBitmap.bmProps.w > 640) || (grdCurCanv->cvBitmap.bmProps.h > 480)) {
		GrSetColorRGBi (RGBA_PAL (0,0,32));
		GrUBox(xOffs,yOffs,xOffs+bmBackdrop.bmProps.w+1,yOffs+bmBackdrop.bmProps.h+1);
		}
	}
GrPaletteFadeIn(NULL, 32, 0);

//	Create a new offscreen buffer for the credits screen
//MWA  Let's be a little smarter about this and check the VR_offscreen buffer
//MWA  for size to determine if we can use that buffer.  If the game size
//MWA  matches what we need, then lets save memory.

if (gameStates.menus.bHires && !gameOpts->menus.nStyle && gameStates.render.vr.buffers.offscreen->cv_w == 640)
	creditsOffscreenBuf = gameStates.render.vr.buffers.offscreen;
else if (gameStates.menus.bHires)
	creditsOffscreenBuf = GrCreateCanvas(640,480);
else
	creditsOffscreenBuf = GrCreateCanvas(320,200);
if (!creditsOffscreenBuf)
	Error("Not enough memory to allocate Credits Buffer.");
creditsOffscreenBuf->cvBitmap.bmPalette = grdCurCanv->cvBitmap.bmPalette;
if (gameOpts->menus.nStyle)
	creditsOffscreenBuf->cvBitmap.bmProps.flags |= BM_FLAG_TRANSPARENT;
KeyFlush ();

bDone = 0;
nFirstLineOffs = 0;

xTimeout = SDL_GetTicks () + xDelay;
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
gameStates.menus.nInMenu = 1;
while (1) {
	int k;

	do {
		nLine = (nLine + 1) % NUM_LINES;
get_line:;
		if (cf.GetS (buffer [nLine], 80)) {
			char *p = buffer [nLine];
			if (bBinary)				// is this a binary tbl &cf
				for (i = (int) strlen (buffer [nLine]); i > 0; i--, p++)
					*p = EncodeRotateLeft ((char) (EncodeRotateLeft (*p) ^ BITMAP_TBL_XOR));
			p = buffer [nLine];
			if (*p == ';')
				goto get_line;
			if (*p == '%') {
				if (p [1] == ALLOWED_CHAR)
					strcpy (p, p + 2);
				else
					goto get_line;
				}
			if ((p = strchr (buffer [nLine], '\n')))
				*p = '\0';
			} 
		else if (nXlLine < NUM_XL_LINES) {
			strcpy (buffer [nLine], xlCredits [nXlLine++]);
			}
		else {
			//fseek(&cf, 0, SEEK_SET);
			buffer [nLine][0] = 0;
			bDone++;
			}
		} while (nExtraInc--);
	nExtraInc = 0;

	//PrintLog ("%s\n", buffer [nLine]);
	for (i = 0; i < ROW_SPACING; i += gameStates.menus.bHires + 1) {
		int y;

		if (gameOpts->menus.nStyle) {
			GrSetCurrentCanvas (NULL);
			ShowFullscreenImage (&bmBackdrop);
	//			GrUpdate (0);
	#if 0
			if ((grdCurCanv->cvBitmap.bmProps.w > 640) || (grdCurCanv->cvBitmap.bmProps.h > 480)) {
				GrSetColorRGBi (RGBA_PAL (0,0,32));
				GrUBox (xOffs, yOffs, xOffs + bmBackdrop. bmProps.w + 1, yOffs + bmBackdrop.bmProps.h + 1);
				}
	#endif
			}
		y = nFirstLineOffs - i;
		GrSetCurrentCanvas (creditsOffscreenBuf);
		if (gameOpts->menus.nStyle)
			GrClearCanvas (0);	
		else
			GrBitmap (0, 0, &bmBackdrop);
		for (j = 0; j < NUM_LINES; j++)	{
			char *s;

			l = (nLine + j + 1) %  NUM_LINES;
			s = buffer [l];
			if (s[0] == '!') 
				s++;
			else if (s[0] == '$') {
				grdCurCanv->cvFont = header_font;
				s++;
				} 
			else if (s[0] == '*') {
				grdCurCanv->cvFont = title_font;
				s++;
				} 
			else
				grdCurCanv->cvFont = names_font;
			grBitBltFadeTable = (gameStates.menus.bHires ? fadeValues_hires : fadeValues);
			pszTemp = strchr (s, '\t');
			if (pszTemp) {	//	Wacky Credits thing
				int w, h, aw, w2, x1, x2;
				*pszTemp = 0;
				GrGetStringSize(s, &w, &h, &aw);
				x1 = ((gameStates.menus.bHires?320:160)-w)/2;
				cr_gr_printf (x1 , y, s);
				GrGetStringSize (pszTemp + 1, &w2, &h, &aw);
				x2 = (gameStates.menus.bHires ? 320 : 160) + (((gameStates.menus.bHires ? 320 : 160) - w2) / 2);
				cr_gr_printf(x2, y, &pszTemp[1]);
				dirtyBox [j].left = ((gameStates.menus.bHires?320:160)-w)/2;
				dirtyBox [j].top = y;
				dirtyBox [j].width =(x2+w2)-x1;
				dirtyBox [j].height = h;
				*pszTemp = '\t';
				} 
			else {
			// Wacky Fast Credits thing
				int w, h, aw;

				GrGetStringSize (s, &w, &h, &aw);
				dirtyBox [j].width = w;
        		dirtyBox [j].height = h;
        		dirtyBox [j].top = y;
        		dirtyBox [j].left = ((gameStates.menus.bHires?640:320) - w) / 2;
				cr_gr_printf (0x8000, y, s);
				}
			grBitBltFadeTable = NULL;
			if (buffer[l][0] == '!')
				y += ROW_SPACING / 2;
			else
				y += ROW_SPACING;
			}

		if (gameOpts->menus.nStyle) 
			GrSetCurrentCanvas (NULL);

		{	// Wacky Fast Credits Thing
		box	*newBox;
		grsBitmap *tempBmP;

		for (j = 0; j < NUM_LINES; j++) {
			newBox = dirtyBox + j;
			tempBmP = &creditsOffscreenBuf->cvBitmap;

			GrBmBitBlt (newBox->width + 1, newBox->height +4,
							newBox->left + xOffs, newBox->top + yOffs, 
							newBox->left, newBox->top,
							tempBmP, &grdCurScreen->scCanvas.cvBitmap);
			}
		}
	GrUpdate (0);
#if 1
	{
	int t = xTimeout - SDL_GetTicks ();
	if (t > 0)
		G3_SLEEP (t);
	xTimeout = SDL_GetTicks () + xDelay;
	}
#endif
	//see if redbook song needs to be restarted
	SongsCheckRedbookRepeat();
	k = KeyInKey ();
#if DBG
	if (k == KEY_BACKSP) {
		Int3();
		k = 0;
		}
#endif

	if ((k == KEY_PRINT_SCREEN) || (k == KEY_ALTED+KEY_F9)) {
		gameStates.app.bSaveScreenshot = 1;
		SaveScreenShot (NULL, 0);
		k = 0;
		}
	else if (k == KEY_PADPLUS)
		xDelay /= 2;
	else if (k == KEY_PADMINUS) {
		if (xDelay)
			xDelay *= 2;
		else
			xDelay = 1;
		}
	else if ((k == KEY_ESC) || (bDone > NUM_LINES)) {
		GrCloseFont (header_font);
		GrCloseFont (title_font);
		GrCloseFont (names_font);
		GrPaletteFadeOut (NULL, 32, 0);
		GrUsePaletteTable (D2_DEFAULT_PALETTE, NULL);
		D2_FREE (bmBackdrop.bmTexBuf);
		cf.Close ();
		GrSetCurrentCanvas (saveCanv);
		SongsPlaySong (SONG_TITLE, 1);

		if (creditsOffscreenBuf != gameStates.render.vr.buffers.offscreen)
			GrFreeCanvas (creditsOffscreenBuf);
		glDisable (GL_BLEND);
		gameStates.menus.nInMenu = 0;
		return;
		}
	}

	if (buffer [(nLine + 1) %  NUM_LINES][0] == '!') {
		nFirstLineOffs -= ROW_SPACING - ROW_SPACING / 2;
		if (nFirstLineOffs <= -ROW_SPACING) {
			nFirstLineOffs += ROW_SPACING;
			nExtraInc++;
			}
		}
	}
}
Example #4
0
int ReadConfigFile (void)
{
	CFile			cf;
	char			line [80], *token, *value, *ptr;
	ubyte			gamma;
	tJoyAxisCal	cal [7];
	int			i;

strcpy (gameConfig.szLastPlayer, "");
memset (cal, 0, sizeof (cal));
JoySetCalVals (cal, sizeofa (cal));
gameConfig.nDigiVolume = 8;
gameConfig.nMidiVolume = 8;
gameConfig.nRedbookVolume = 8;
gameConfig.nControlType = 0;
gameConfig.bReverseChannels = 0;

//set these here in case no cfg file
bHiresMoviesSave = gameOpts->movies.bHires;
bRedbookEnabledSave = redbook.Enabled ();

if (!cf.Open ("descent.cfg", gameFolders.szConfigDir, "rt", 0))
	return 1;
while (!cf.EoF ()) {
	memset (line, 0, 80);
	cf.GetS (line, 80);
	ptr = line;
	while (::isspace (*ptr))
		ptr++;
	if (*ptr != '\0') {
		token = strtok (ptr, "=");
		value = strtok (NULL, "=");
		if (!(value && token)) {
			PrintLog ("configuration file (descent.cfg) looks messed up.\n");
			continue;
			}
		if (value [strlen (value) - 1] == '\n')
			value [strlen (value) - 1] = 0;
		if (!strcmp (token, pszDigiVolume))
			gameConfig.nDigiVolume = (ubyte) strtol (value, NULL, 10);
		else if (!strcmp (token, pszMidiVolume))
			gameConfig.nMidiVolume = (ubyte) strtol (value, NULL, 10);
		else if (!strcmp (token, pszRedbookEnabled))
			redbook.Enable (bRedbookEnabledSave = strtol (value, NULL, 10));
		else if (!strcmp (token, pszRedbookVolume))
			gameConfig.nRedbookVolume = (ubyte) strtol (value, NULL, 10);
		else if (!strcmp (token, pszStereoRev))
			gameConfig.bReverseChannels = (ubyte) strtol (value, NULL, 10);
		else if (!strcmp (token, pszGammaLevel)) {
			gamma = (ubyte) strtol (value, NULL, 10);
			paletteManager.SetGamma (gamma);
			}
		else if (!strcmp (token, pszDetailLevel)) {
			gameStates.app.nDetailLevel = strtol (value, NULL, 10);
			if (gameStates.app.nDetailLevel == NUM_DETAIL_LEVELS-1) {
				int count,dummy,oc,od,wd,wrd,da,sc;
				count = sscanf (value, "%d,%d,%d,%d,%d,%d,%d\n", &dummy, &oc, &od, &wd, &wrd, &da, &sc);
				if (count == 7) {
					gameStates.render.detail.nObjectComplexity = oc;
					gameStates.render.detail.nObjectDetail = od;
					gameStates.render.detail.nWallDetail = wd;
					gameStates.render.detail.nWallRenderDepth = wrd;
					gameStates.render.detail.nDebrisAmount = da;
					gameStates.sound.nSoundChannels = sc;
					InitCustomDetails ();
					}
				}
			}
		else if (!strcmp (token, pszJoystickMin))
			sscanf (value, "%d,%d,%d,%d", &cal [0].nMin, &cal [1].nMin, &cal [2].nMin, &cal [3].nMin);
		else if (!strcmp (token, pszJoystickMax))
			sscanf (value, "%d,%d,%d,%d", &cal [0].nMax, &cal [1].nMax, &cal [2].nMax, &cal [3].nMax);
		else if (!strcmp (token, pszJoystickCen))
			sscanf (value, "%d,%d,%d,%d", &cal [0].nCenter, &cal [1].nCenter, &cal [2].nCenter, &cal [3].nCenter);
		else if (!strcmp (token, pszLastPlayer)) {
			char * p;
			strncpy (gameConfig.szLastPlayer, value, CALLSIGN_LEN);
			p = strchr (gameConfig.szLastPlayer, '\n');
			if (p) *p = 0;
		}
		else if (!strcmp (token, pszLastMission)) {
			int j = MsnHasGameVer (value) ? 4 : 0;
			strncpy (gameConfig.szLastMission, value + j, MISSION_NAME_LEN);
			char *p = strchr (gameConfig.szLastMission, '\n');
			if (p)
				*p = 0;
			}
		else if (!strcmp (token, pszVrType))
			gameConfig.vrType = strtol (value, NULL, 10);
		else if (!strcmp (token, pszVrResolution))
			gameConfig.vrResolution = strtol (value, NULL, 10);
		else if (!strcmp (token, pszVrTracking))
			gameConfig.vrTracking = strtol (value, NULL, 10);
		else if (!strcmp (token, pszD2XVersion))
			gameConfig.nVersion = strtoul (value, NULL, 10);
		else if (!strcmp (token, pszHiresMovies) && gameStates.app.bNostalgia)
			bHiresMoviesSave = gameOpts->movies.bHires = strtol (value, NULL, 10);
	}
}
cf.Close ();

i = FindArg ("-volume");
if (i > 0) {
	i = atoi (pszArgList [i + 1]);
	if (i < 0)
		i = 0;
	else if (i > 100)
		i = 100;
	gameConfig.nDigiVolume =
	gameConfig.nMidiVolume =
	gameConfig.nRedbookVolume = (i * 8) / 100;
	}

if (gameConfig.nDigiVolume > 8)
	gameConfig.nDigiVolume = 8;
if (gameConfig.nMidiVolume > 8)
	gameConfig.nMidiVolume = 8;
if (gameConfig.nRedbookVolume > 8)
	gameConfig.nRedbookVolume = 8;
audio.SetVolumes ((gameConfig.nDigiVolume * 32768) / 8, (gameConfig.nMidiVolume * 128) / 8);
if (cf.Open ("descentw.cfg", gameFolders.szConfigDir, "rt", 0)) {
	while (!cf.EoF ()) {
		memset (line, 0, 80);
		cf.GetS (line, 80);
		ptr = line;
		while (::isspace(*ptr))
			ptr++;
		if (*ptr != '\0') {
			token = strtok(ptr, "=");
			value = strtok(NULL, "=");
			if (!(value  && token)) {
				PrintLog ("configuration file (descentw.cfg) looks messed up.\n");
				continue;
				}
			if (value [strlen(value)-1] == '\n')
				value [strlen(value)-1] = 0;
			if (!strcmp (token, pszJoystickMin))
				sscanf (value, "%d,%d,%d,%d,%d,%d,%d",
						  &cal [0].nMin, &cal [1].nMin, &cal [2].nMin, &cal [3].nMin, &cal [4].nMin, &cal [5].nMin, &cal [6].nMin);
			else if (!strcmp (token, pszJoystickMax))
				sscanf (value, "%d,%d,%d,%d,%d,%d,%d",
						  &cal [0].nMax, &cal [1].nMax, &cal [2].nMax, &cal [3].nMax, &cal [4].nMax, &cal [5].nMax, &cal [6].nMax);
			else if (!strcmp (token, pszJoystickCen))
				sscanf (value, "%d,%d,%d,%d,%d,%d,%d",
						  &cal [0].nCenter, &cal [1].nCenter, &cal [2].nCenter, &cal [3].nCenter, &cal [4].nCenter, &cal [5].nCenter, &cal [6].nCenter);
			}
		}
	cf.Close ();
	}
JoySetCalVals (cal, sizeofa (cal));
return 0;
}