bool			
UnitSpriteGroup::GetImageFileName(MBCHAR * name, char *format,...)
{
   	va_list          v_args;
	char			 fname[512];
	
	
    va_start(v_args, format);    
    vsprintf(name,format,v_args);
    va_end( v_args );            

	
	sprintf(fname,"%s.%s",name,"TGA");

	if (c3files_PathIsValid(fname))
	{	
		strcpy(name,fname);
		return true;
	}

	
	sprintf(fname,"%s.%s",name,"TIF");

	if (c3files_PathIsValid(fname))
	{	
		strcpy(name,fname);
		return true;
	}

	return false;
}
bool
SpriteEditWindow::FileExists(char *name)
{
	if (name==NULL)
		return false;

	MBCHAR spritePath[_MAX_PATH];
	MBCHAR fullPath[_MAX_PATH];
	g_civPaths->GetSpecificPath(C3DIR_SPRITES, spritePath, FALSE);
	sprintf(fullPath, "%s%s%s", spritePath, FILE_SEP, name);

	return c3files_PathIsValid(fullPath);
}
/// @todo Repair major memory leaks when returning FALSE
sint32 UnitSpriteGroup::Parse(uint16 id, GROUPTYPE type)
{
	MBCHAR			scriptName[k_MAX_NAME_LENGTH];

	MBCHAR			*facedImageNames[k_NUM_FACINGS][k_MAX_NAMES];
	MBCHAR			*facedShadowNames[k_NUM_FACINGS][k_MAX_NAMES];

	MBCHAR			*imageNames[k_MAX_NAMES];
	MBCHAR			*shadowNames[k_MAX_NAMES];

	size_t			i;
    size_t          j;

	char			prefixStr[80];

	
	for (j=0; j<k_NUM_FACINGS; j++) 
	{
		for (i=0; i<k_MAX_NAMES; i++) 
		{
			facedImageNames[j][i] =  new MBCHAR[2 * k_MAX_NAME_LENGTH];
			facedShadowNames[j][i] = new MBCHAR[2 * k_MAX_NAME_LENGTH];
		}
	}

	for (i=0; i<k_MAX_NAMES; i++) 
	{
		imageNames[i] =  new MBCHAR[2 * k_MAX_NAME_LENGTH];
		shadowNames[i] = new MBCHAR[2 * k_MAX_NAME_LENGTH];
	}

	sprintf(prefixStr, ".%s%d%s", FILE_SEP, id, FILE_SEP);

	if (type == GROUPTYPE_UNIT)
	{
		sprintf(scriptName, "GU%.3d.txt", id);

		
		if (!c3files_PathIsValid(scriptName))
			sprintf(scriptName, "GU%.2d.txt", id);
	}
	else 
		sprintf(scriptName, "GC%.3d.txt", id);

	printf("Processing '%s'\n", scriptName);

	Token	* theToken = new Token(scriptName, C3DIR_SPRITES); 
	Assert(theToken); 
	if (!theToken) return FALSE; 
	
	sint32 tmp; 

	if (!token_ParseKeywordNext(theToken, TOKEN_UNIT_SPRITE)) return FALSE; 

	if (!token_ParseAnOpenBraceNext(theToken)) return FALSE; 

	if (!token_ParseValNext(theToken, TOKEN_UNIT_SPRITE_MOVE, tmp)) return FALSE;    
	
	if (tmp) 
	{
		Assert(type == GROUPTYPE_UNIT);
		
		if (type != GROUPTYPE_UNIT) 
		{
			printf("\n Illegal unit action (Move) for a city sprite.\n");
			return FALSE;
		}

		
		FacedSprite *moveSprite = new FacedSprite;
		
		
		moveSprite->ParseFromTokens(theToken);

		printf(" [Move");
		for (j=0; j<k_NUM_FACINGS; j++) 
		{
			for (size_t k = 0; k < moveSprite->GetNumFrames(); ++k) 
			{
				if (!GetImageFileName(facedShadowNames[j][k],"%sGU%#.3dMS%d.%d", prefixStr,  id, j+1, k+moveSprite->GetFirstFrame()))
					GetImageFileName(facedShadowNames[j][k] ,"%sGU%#.2dMS%d.%d", prefixStr,  id, j+1, k+moveSprite->GetFirstFrame());
				
				if (!GetImageFileName(facedImageNames[j][k], "%sGU%#.3dMA%d.%d", prefixStr, id,  j+1, k+moveSprite->GetFirstFrame()))
					GetImageFileName(facedImageNames[j][k] , "%sGU%#.2dMA%d.%d", prefixStr, id,  j+1, k+moveSprite->GetFirstFrame());
			}
		}

		
		moveSprite->Import(moveSprite->GetNumFrames(), facedImageNames, facedShadowNames);

		delete m_sprites[UNITACTION_MOVE];
		m_sprites[UNITACTION_MOVE] = moveSprite;
		printf("]\n");

		Anim *moveAnim = new Anim;

		moveAnim->ParseFromTokens(theToken);
		delete m_anims[UNITACTION_MOVE];
		m_anims[UNITACTION_MOVE] = moveAnim;
	}

	if (!token_ParseValNext(theToken, TOKEN_UNIT_SPRITE_ATTACK, tmp)) return FALSE;    
	if (tmp) 
	{
		Assert(type == GROUPTYPE_UNIT);
		
		if (type != GROUPTYPE_UNIT) 
		{
			printf("\n Illegal unit action (Attack) for a city sprite.\n");
			return FALSE;
		}
		
		if (!token_ParseValNext(theToken, TOKEN_UNIT_SPRITE_ATTACK_IS_DIRECTIONAL, tmp)) return FALSE;
		if (tmp) 
			m_hasDirectional = TRUE;
		else 
			m_hasDirectional = FALSE;

		
		FacedSprite *attackSprite = new FacedSprite;
		
		
		attackSprite->ParseFromTokens(theToken);

		printf(" [Attack");
		for (j=0; j<k_NUM_FACINGS; j++) 
		{
			for(i=0; i<attackSprite->GetNumFrames(); i++) 
			{
				if (!GetImageFileName(facedShadowNames[j][i],"%sGU%#.3dAS%d.%d", prefixStr, id, j+1, i+attackSprite->GetFirstFrame()))
					GetImageFileName (facedShadowNames[j][i],"%sGU%#.2dAS%d.%d", prefixStr, id, j+1, i+attackSprite->GetFirstFrame());
				
				if (!GetImageFileName(facedImageNames [j][i],"%sGU%#.3dAA%d.%d", prefixStr, id, j+1, i+attackSprite->GetFirstFrame()))
					GetImageFileName (facedImageNames [j][i],"%sGU%#.2dAA%d.%d", prefixStr, id, j+1, i+attackSprite->GetFirstFrame());
			}
		}

		
		attackSprite->Import(attackSprite->GetNumFrames(), facedImageNames, facedShadowNames);

		delete m_sprites[UNITACTION_ATTACK];
		m_sprites[UNITACTION_ATTACK] = attackSprite;
		printf("]\n");

		Anim *attackAnim = new Anim;

		attackAnim->ParseFromTokens(theToken);
		delete m_anims[UNITACTION_ATTACK];
		m_anims[UNITACTION_ATTACK] = attackAnim;
	}

	if (!token_ParseValNext(theToken, TOKEN_UNIT_SPRITE_IDLE, tmp)) return FALSE;    
	if (tmp) 
	{
		Sprite *idleSprite = new Sprite;
		idleSprite->ParseFromTokens(theToken);

		if (type == GROUPTYPE_UNIT) 
		{
			printf(" [Idle");
		  
			for (size_t n = 0; n < idleSprite->GetNumFrames(); ++n) 
			{
				if (!GetImageFileName(imageNames[n] ,"%sGU%#.3dIA%d.%d", prefixStr, id, 4, n + idleSprite->GetFirstFrame()))
					GetImageFileName (imageNames[n] ,"%sGU%#.2dIA%d.%d", prefixStr, id, 4, n + idleSprite->GetFirstFrame());
				if (!GetImageFileName(shadowNames[n],"%sGU%#.3dIS%d.%d", prefixStr, id, 4, n + idleSprite->GetFirstFrame()))
					GetImageFileName (shadowNames[n],"%sGU%#.2dIS%d.%d", prefixStr, id, 4, n + idleSprite->GetFirstFrame());
			}
		} 
		else if (type == GROUPTYPE_CITY) 
		{
			printf(" [City");

			for (size_t n = 0; n < idleSprite->GetNumFrames(); ++n) 
			{
				GetImageFileName(shadowNames[n], "%sGC%#.3dS.%d", prefixStr, id, n + idleSprite->GetFirstFrame());
				GetImageFileName(imageNames[n] , "%sGC%#.3dA.%d", prefixStr, id, n + idleSprite->GetFirstFrame());
			}
		} 
		else 
		{
			Assert(FALSE);
		}

		idleSprite->Import(idleSprite->GetNumFrames(), imageNames, shadowNames);
		delete m_sprites[UNITACTION_IDLE];
		m_sprites[UNITACTION_IDLE] = idleSprite;
		printf("]\n");

		Anim *idleAnim = new Anim;

		idleAnim->ParseFromTokens(theToken);
		delete m_anims[UNITACTION_IDLE];
		m_anims[UNITACTION_IDLE] = idleAnim;
	}

	if (!token_ParseValNext(theToken, TOKEN_UNIT_SPRITE_VICTORY, tmp)) return FALSE;    
	if (tmp) 
	{
		Assert(type == GROUPTYPE_UNIT);
		
		if (type != GROUPTYPE_UNIT) 
		{
			printf("\n Illegal unit action (Victory) for a city sprite.\n");
			return FALSE;
		}

		Sprite *victorySprite = new Sprite;

		if (!token_ParseValNext(theToken, TOKEN_UNIT_SPRITE_IS_DEATH, tmp)) return FALSE;
		SetHasDeath(0 != tmp);

		victorySprite->ParseFromTokens(theToken);

		printf(" [Victory");
		for(size_t n = 0; n < victorySprite->GetNumFrames(); ++n) 
		{			
			if (!GetImageFileName(shadowNames[n],"%sGU%#.3dVS%d.%d", prefixStr, id, 4, n + victorySprite->GetFirstFrame()))
				GetImageFileName (shadowNames[n],"%sGU%#.2dVS%d.%d", prefixStr, id, 4, n + victorySprite->GetFirstFrame());
			if (!GetImageFileName(imageNames[n], "%sGU%#.3dVA%d.%d", prefixStr, id, 4, n + victorySprite->GetFirstFrame()))
				GetImageFileName (imageNames[n], "%sGU%#.2dVA%d.%d", prefixStr, id, 4, n + victorySprite->GetFirstFrame());
		}

		victorySprite->Import(victorySprite->GetNumFrames(), imageNames, shadowNames);
		delete m_sprites[UNITACTION_VICTORY];
		m_sprites[UNITACTION_VICTORY] = victorySprite;
		printf("]\n");

		Anim *victoryAnim = new Anim;

		victoryAnim->ParseFromTokens(theToken);
		delete m_anims[UNITACTION_VICTORY];
		m_anims[UNITACTION_VICTORY] = victoryAnim;
	}

	if (!token_ParseValNext(theToken, TOKEN_UNIT_SPRITE_WORK, tmp)) return FALSE;    
	if (tmp) 
	{
		Assert(type == GROUPTYPE_UNIT);
		if (type != GROUPTYPE_UNIT) 
		{
			printf("\n Illegal unit action (Work) for a city sprite.\n");
			return FALSE;
		}

		
		FacedSprite *workSprite = new FacedSprite;
		
		
		workSprite->ParseFromTokens(theToken);

		printf(" [Work/A2");
		for (j=0; j<k_NUM_FACINGS; j++) 
		{
			for(size_t n = 0; n < workSprite->GetNumFrames(); ++n) 
			{
				if (!GetImageFileName(facedShadowNames[j][n],"%sGU%#.3dWS%d.%d", prefixStr, id, j+1, n+workSprite->GetFirstFrame()))
					GetImageFileName (facedShadowNames[j][n],"%sGU%#.2dWS%d.%d", prefixStr, id, j+1, n+workSprite->GetFirstFrame());
				if (!GetImageFileName(facedImageNames[j][n] ,"%sGU%#.3dWA%d.%d", prefixStr, id, j+1, n+workSprite->GetFirstFrame()))
					GetImageFileName (facedImageNames[j][n] ,"%sGU%#.2dWA%d.%d", prefixStr, id, j+1, n+workSprite->GetFirstFrame());
			}
		}


		
		workSprite->Import(workSprite->GetNumFrames(), facedImageNames, facedShadowNames);

		delete m_sprites[UNITACTION_WORK];
		m_sprites[UNITACTION_WORK] = workSprite;
		printf("]\n");

		Anim *workAnim = new Anim;
		workAnim->ParseFromTokens(theToken);
		delete m_anims[UNITACTION_WORK];
		m_anims[UNITACTION_WORK] = workAnim;
	}

	if (!token_ParseValNext(theToken, TOKEN_UNIT_SPRITE_FIREPOINTS, tmp)) return FALSE;    
	
	if (tmp) 
	{
		
	

		for (sint32 j=0; j<tmp; j++) {
			if (!token_ParseAnOpenBraceNext(theToken)) return FALSE;
			for (i=0; i<k_NUM_FACINGS; i++) {
			    token_ParsePoint(theToken);
			}
			if (!token_ParseAnCloseBraceNext(theToken)) return FALSE;
		}
	}

	if (!token_ParseValNext(theToken, TOKEN_UNIT_SPRITE_FIREPOINTS_WORK, tmp)) return FALSE;    
	if (tmp) {
		
		m_numFirePointsWork = (uint16)tmp;

		for (sint32 j=0; j<tmp; j++) {
			if (!token_ParseAnOpenBraceNext(theToken)) return FALSE;
			for (i=0; i<k_NUM_FACINGS; i++) {
			   token_ParsePoint(theToken);
			}
			if (!token_ParseAnCloseBraceNext(theToken)) return FALSE;
		}
	}


	if (!token_ParseValNext(theToken, TOKEN_UNIT_SPRITE_MOVEOFFSETS, tmp)) return FALSE;    
	if (tmp) {
		if (!token_ParseAnOpenBraceNext(theToken)) return FALSE;
		for (i=0; i<k_NUM_FACINGS; i++) {
			m_moveOffsets[i] = token_ParsePoint(theToken);
		}
		if (!token_ParseAnCloseBraceNext(theToken)) return FALSE;
	}

	if (!token_ParseValNext(theToken, TOKEN_UNIT_SPRITE_SHIELDPOINTS, tmp)) return FALSE;    
	if (tmp) {
		
		if (!token_ParseAnOpenBraceNext(theToken)) return FALSE;

		if (!token_ParseKeywordNext(theToken, TOKEN_UNIT_SPRITE_SHIELDPOINTS_MOVE)) return FALSE;    
		if (tmp) {
			for (i=0; i<k_NUM_FACINGS; i++) {
				m_shieldPoints[UNITACTION_MOVE][i] = token_ParsePoint(theToken);
			}
		}
		if (!token_ParseKeywordNext(theToken, TOKEN_UNIT_SPRITE_SHIELDPOINTS_ATTACK)) return FALSE;    
		if (tmp) {
			for (i=0; i<k_NUM_FACINGS; i++) {
				m_shieldPoints[UNITACTION_ATTACK][i] = token_ParsePoint(theToken);
			}
		}
		if (!token_ParseKeywordNext(theToken, TOKEN_UNIT_SPRITE_SHIELDPOINTS_IDLE)) return FALSE;    
		if (tmp) {
			for (i=0; i<k_NUM_FACINGS; i++) {
				m_shieldPoints[UNITACTION_IDLE][i] = token_ParsePoint(theToken);
			}
		}
		if (!token_ParseKeywordNext(theToken, TOKEN_UNIT_SPRITE_SHIELDPOINTS_VICTORY)) return FALSE;    
		if (tmp) {
			for (i=0; i<k_NUM_FACINGS; i++) {
				m_shieldPoints[UNITACTION_VICTORY][i] = token_ParsePoint(theToken);
			}
		}
		if (!token_ParseKeywordNext(theToken, TOKEN_UNIT_SPRITE_SHIELDPOINTS_WORK)) return FALSE;    
		if (tmp) {
			for (i=0; i<k_NUM_FACINGS; i++) {
				m_shieldPoints[UNITACTION_WORK][i] = token_ParsePoint(theToken);
			}
		}
		
		if (!token_ParseAnCloseBraceNext(theToken)) return FALSE;
	}

	

	

	delete theToken;

	for (j=0; j<k_NUM_FACINGS; j++) 
    {
		for (i=0; i<k_MAX_NAMES; i++) 
		{
			delete [] facedImageNames[j][i];
			delete [] facedShadowNames[j][i];
		}
	}

	for (i = 0; i < k_MAX_NAMES; i++) 
    {
		delete [] imageNames[i];
		delete [] shadowNames[i];
	}

	return TRUE;
}
Beispiel #4
0
MBCHAR *CivPaths::FindFile(C3DIR dir, const MBCHAR *filename, MBCHAR *path,
                           bool silent, bool check_prjfile, bool checkScenario)
{
	MBCHAR			fullPath[_MAX_PATH];	

	
	Assert(path != NULL);

	
	Assert(dir < C3DIR_MAX);

	
	Assert(filename != NULL);

	
	if (dir == C3DIR_DIRECT) {
		strcpy(path, filename);

		
		return path;
	}

	
	if(checkScenario){
		if (m_curScenarioPath) {
		
			sprintf(fullPath, "%s%s%s%s%s%s%s", m_curScenarioPath, FILE_SEP, m_localizedPath, FILE_SEP, m_assetPaths[dir], FILE_SEP, filename);
			if (c3files_PathIsValid(fullPath)) {
	
				strcpy(path, fullPath);
				return path;
			}
			sprintf(fullPath, "%s%s%s%s%s%s%s", m_curScenarioPath, FILE_SEP, m_defaultPath, FILE_SEP, m_assetPaths[dir], FILE_SEP, filename);

			if (c3files_PathIsValid(fullPath)) {
			
				strcpy(path, fullPath);
				return path;
			}
		}

		if (m_curScenarioPackPath) {
		
			sprintf(fullPath, "%s%s%s%s%s%s%s", m_curScenarioPackPath, FILE_SEP, m_localizedPath, FILE_SEP, m_assetPaths[dir], FILE_SEP, filename);
			if (c3files_PathIsValid(fullPath)) {

				strcpy(path, fullPath);
				return path;
			}
			sprintf(fullPath, "%s%s%s%s%s%s%s", m_curScenarioPackPath, FILE_SEP, m_defaultPath, FILE_SEP, m_assetPaths[dir], FILE_SEP, filename);
		
			if (c3files_PathIsValid(fullPath)) {
			
				strcpy(path, fullPath);
				return path;
			}
		}
	}

    // The extra data paths take priority over the regular one.
	for 
	(
		std::vector<MBCHAR const *>::iterator	p	= m_extraDataPaths.begin();
		p != m_extraDataPaths.end();
		++p
	)
	{
		MBCHAR const *	l_dataPath	= *p;
		if (MakeAssetPath(fullPath, m_hdPath, l_dataPath, m_localizedPath, m_assetPaths[dir], filename) ||
			MakeAssetPath(fullPath, m_hdPath, l_dataPath, m_defaultPath,   m_assetPaths[dir], filename)
		   ) 
		{
			strcpy(path, fullPath);
			return path;
		}
	}

	// When not found in the new data, try the original directories
	if (MakeAssetPath(fullPath, m_hdPath, m_dataPath, m_localizedPath, m_assetPaths[dir], filename)) {
		
		strcpy(path, fullPath);
		return path;
	}

	
	if (MakeAssetPath(fullPath, m_hdPath, m_dataPath, m_defaultPath, m_assetPaths[dir], filename)) {
		
		strcpy(path, fullPath);
		return path;
	}

	

	// The CD will only have the original content
	if (MakeAssetPath(fullPath, m_cdPath, m_dataPath, m_localizedPath, m_assetPaths[dir], filename)) {
		
		strcpy(path, fullPath);
		return path;
	}

	
	if (MakeAssetPath(fullPath, m_cdPath, m_dataPath, m_defaultPath, m_assetPaths[dir], filename)) {
		
		strcpy(path, fullPath);
		return path;
	}
    
	
    if (check_prjfile && 
        ((dir == C3DIR_PATTERNS) || 
			(dir == C3DIR_PICTURES))) {
        
		uint32 len = strlen(filename);

        if (len > 3) {
			
			
            strcpy(fullPath, filename);
            fullPath[len-3] = 'r';
            fullPath[len-2] = 'i';
            fullPath[len-1] = 'm';

			
            if (g_ImageMapPF && g_ImageMapPF->exists(fullPath)) {
				
                strcpy(path, filename);
                return path;
            }                
        }
    }

	
    if (!silent)
        c3errors_ErrorDialog("Paths", "'%s' not found in asset tree.", filename);

	return NULL;
}
void loadsavescreen_SaveSCENGame(void)
{
	SaveInfo		*saveInfo = g_loadsaveWindow->GetSaveInfoToSave();

	Assert( saveInfo != NULL );
	if ( !saveInfo ) return;

	if (!g_loadsaveWindow->GetGameName(saveInfo->gameName)) return;
	if (!g_loadsaveWindow->GetSaveName(saveInfo->fileName)) return;
	if (!g_loadsaveWindow->GetNote(saveInfo->note)) return;

	if (strlen(saveInfo->gameName) == 0) {
		// Empty game name in the save info, copy it over from the game info
		if (g_loadsaveWindow->GetGameInfo() != NULL) {
			strcpy(saveInfo->gameName, g_loadsaveWindow->GetGameInfo()->name);
		} else {
			g_loadsaveWindow->BuildDefaultSaveName(NULL, saveInfo->gameName);
			saveInfo->gameName[SAVE_LEADER_NAME_SIZE] = '\0';
		}
	}

	// Create a default gamesetup.
	nf_GameSetup gs;

	// Must save which tribes were used.
	sint32 j = 0;
	for ( sint32 i = 0; i < k_NS_MAX_PLAYERS; i++ )
	{
		if ( g_player[ i ] )
		{
			TribeSlot ts;

			// These fields don't matter for the savedtribeslots.
			ts.isAI = 0;
			ts.key  = 0;

			// This is the only important field.
			// +1 because netshell treats zero as "none" w/ barbarians == 1.
			ts.tribe = g_player[ i ]->m_civilisation->GetCivilisation() + 1;

			ts.isFemale = g_player[i]->m_civilisation->GetGender() == GENDER_FEMALE;

			// We don't want to store the barbarians.  The netshell skips them.
			if ( 1 < ts.tribe )
				gs.GetSavedTribeSlots()[ j++ ] = ts;
		}
	}

	saveInfo->gameSetup = gs;

	MBCHAR	path[_MAX_PATH];

	if (!g_civPaths->GetSavePath(C3SAVEDIR_SCEN, path)) return;

	MBCHAR	fullPath[_MAX_PATH];
	sprintf(fullPath, "%s%s%s", path, FILE_SEP, saveInfo->gameName);

	// Verify that this directory exists, and if it doesn't, create it
	if (!c3files_PathIsValid(fullPath)) {
		if (!c3files_CreateDirectory(fullPath)) {
			Assert(FALSE);
			// FIXME
			// unable to create the directory for the game, should report
			// to the user, here
			return;
		}
	}

	// Full path, including the save file's filename
	sprintf(saveInfo->pathName, "%s%s%s", fullPath, FILE_SEP, saveInfo->fileName);

	// Build a power graph from the UI
	g_loadsaveWindow->GetPowerGraph(saveInfo);
	g_loadsaveWindow->GetRadarMap(saveInfo);

	// SAM021899 changed to make a save request
	allocated::reassign(g_savedGameRequest, new SaveInfo(saveInfo));

//	GameFile::SaveGame(saveInfo->pathName, saveInfo);
}
void loadsavescreen_SaveMPGame(void)
{
	SaveInfo		*saveInfo = g_loadsaveWindow->GetSaveInfoToSave();

	Assert( saveInfo != NULL );
	if ( !saveInfo ) return;

	if (!g_loadsaveWindow->GetGameName(saveInfo->gameName)) return;
	if (!g_loadsaveWindow->GetSaveName(saveInfo->fileName)) return;
	if (!g_loadsaveWindow->GetNote(saveInfo->note)) return;

	// SAM050399
	saveInfo->isScenario = g_isScenario;

	if (strlen(saveInfo->gameName) == 0) {
		// Empty game name in the save info, copy it over from the game info
		if (g_loadsaveWindow->GetGameInfo() != NULL) {
			strcpy(saveInfo->gameName, g_loadsaveWindow->GetGameInfo()->name);
		} else {
			g_loadsaveWindow->BuildDefaultSaveName(NULL, saveInfo->gameName);
			saveInfo->gameName[SAVE_LEADER_NAME_SIZE] = '\0';
		}
	}

	saveInfo->gameSetup = g_gamesetup;

	memcpy(
		saveInfo->gameSetup.GetSavedTribeSlots(),
		saveInfo->gameSetup.GetTribeSlots(),
		k_NS_MAX_PLAYERS * sizeof( TribeSlot ) );
	memset(
		saveInfo->gameSetup.GetTribeSlots(),
		0,
		k_NS_MAX_PLAYERS * sizeof( TribeSlot ) );

	MBCHAR	path[_MAX_PATH];
	if (!g_civPaths->GetSavePath(C3SAVEDIR_MP, path)) return;

	MBCHAR	fullPath[_MAX_PATH];
	sprintf(fullPath, "%s%s%s", path, FILE_SEP, saveInfo->gameName);

	// Verify that this directory exists, and if it doesn't, create it
	if (!c3files_PathIsValid(fullPath)) {
		if (!c3files_CreateDirectory(fullPath)) {
			Assert(FALSE);
			// FIXME
			// unable to create the directory for the game, should report
			// to the user, here
			return;
		}
	}

	// Full path, including the save file's filename
	sprintf(saveInfo->pathName, "%s%s%s", fullPath, FILE_SEP, saveInfo->fileName);

	// Build a power graph from the UI
	g_loadsaveWindow->GetPowerGraph(saveInfo);
	g_loadsaveWindow->GetRadarMap(saveInfo);

	// SAM021899 changed to make a save request
	allocated::reassign(g_savedGameRequest, new SaveInfo(saveInfo));

//	GameFile::SaveGame(saveInfo->pathName, saveInfo);

}
void loadsavescreen_SaveGame(MBCHAR *usePath, MBCHAR *useName)
{

	SaveInfo		*saveInfo = g_loadsaveWindow->GetSaveInfoToSave();

	Assert( saveInfo != NULL );
	if ( !saveInfo ) return;

	if (!g_loadsaveWindow->GetGameName(saveInfo->gameName)) return;
	if (!g_loadsaveWindow->GetSaveName(saveInfo->fileName)) return;
	if (!g_loadsaveWindow->GetNote(saveInfo->note)) return;

	saveInfo->isScenario = g_isScenario;

	if (strlen(saveInfo->gameName) == 0) {

		if (g_loadsaveWindow->GetGameInfo() != NULL) {
			strcpy(saveInfo->gameName, g_loadsaveWindow->GetGameInfo()->name);
		} else {
			g_loadsaveWindow->BuildDefaultSaveName(NULL, saveInfo->gameName);
			saveInfo->gameName[SAVE_LEADER_NAME_SIZE] = '\0';
		}
	}

	nf_GameSetup gs;

	sint32 j = 0;
	uint32 i;
	for(i = 0; i < k_MAX_PLAYERS; i++)
	{
		if ( g_player[ i ] )
		{
			TribeSlot ts;

			ts.key = 0;

#if you_want_ai_civs_from_singleplayer_saved_game_showing_up_in_netshell
			ts.isAI = g_player[ i ]->IsRobot();
#else
			ts.isAI = 0;
#endif


			ts.tribe = g_player[ i ]->m_civilisation->GetCivilisation() + 1;

			ts.isFemale = (g_player[i]->m_civilisation->GetGender() == GENDER_FEMALE);


			if ( 1 < ts.tribe )
			{

				if ( j >= k_NS_MAX_PLAYERS ) break;

				gs.GetSavedTribeSlots()[ j++ ] = ts;
			}
		}
	}
	saveInfo->gameSetup = gs;

	MBCHAR	path[_MAX_PATH];
	MBCHAR	fullPath[_MAX_PATH];

	if(usePath) {
		strcpy(path, usePath);
	} else {
		if (!g_civPaths->GetSavePath(C3SAVEDIR_GAME, path)) return;
	}

	if(!useName) {

		char *testchars="\\*\"/:|?<>";
		bool charschanged=false;
		for(i=0; i<strlen(saveInfo->gameName); i++)
		{
			if(strchr(testchars,saveInfo->gameName[i]))
			{
				saveInfo->gameName[i]='#';
				charschanged=true;
			}
		}
		if(charschanged)
		{
			MessageBoxDialog::Information("str_ldl_InvalidCharsFixed", "InfoInvalidCharsFixed");
		}

		sprintf(fullPath, "%s%s%s", path, FILE_SEP, saveInfo->gameName);

		// Verify that this directory exists, and if it doesn't, create it
		if (!c3files_PathIsValid(fullPath)) {
			if (!c3files_CreateDirectory(fullPath)) {
				Assert(FALSE);
				// FIXME
				// unable to create the directory for the game, should report
				// to the user, here
				return;
			}
		}

		// Check for invalid characters in filename.
		bool charschanged2=false;
		for(i=0; i<strlen(saveInfo->fileName); i++)
		{
			if(strchr(testchars,saveInfo->fileName[i]))
			{
				saveInfo->fileName[i]='#';
				charschanged2=true;
			}
		}
		if(charschanged2 && !charschanged)
		{
			MessageBoxDialog::Information("str_ldl_InvalidCharsFixed", "InfoInvalidCharsFixed");
		}

		// Full path, including the save file's filename
		sprintf(saveInfo->pathName, "%s%s%s", fullPath, FILE_SEP, saveInfo->fileName);
	} else {
		sprintf(fullPath, "%s", path);
		strcpy(saveInfo->fileName, useName);
		sprintf(saveInfo->pathName, "%s%s%s", fullPath, FILE_SEP, useName);
	}

	// Build a power graph from the UI
	g_loadsaveWindow->GetPowerGraph(saveInfo);
	g_loadsaveWindow->GetRadarMap(saveInfo);

	// SAM021899 changed to make a save request
	allocated::reassign(g_savedGameRequest, new SaveInfo(saveInfo));

//	GameFile::SaveGame(saveInfo->pathName, saveInfo);
}