Example #1
0
BOOL C4ComponentHost::LoadEx(const char *szName, C4Group &hGroup,
                             const char *szFilename, const char *szLanguage) {
  // Load from a group set containing the provided group and
  // alternative groups for cross-loading from a language pack
  C4GroupSet hGroups;
  hGroups.RegisterGroup(
      hGroup, false, 1000,
      C4GSCnt_Component);  // Provided group gets highest priority
  hGroups.RegisterGroups(Languages.GetPackGroups(pConfig->AtExeRelativePath(
                             hGroup.GetFullName().getData())),
                         C4GSCnt_Language);
  // Load from group set
  return Load(szName, hGroups, szFilename, szLanguage);
}
Example #2
0
C4GroupSet C4Language::GetPackGroups(C4Group & hGroup)
{
	// Build a group set containing the provided group and
	// alternative groups for cross-loading from a language pack
	char strRelativePath[_MAX_PATH + 1];
	char strTargetLocation[_MAX_PATH + 1];
	char strPackPath[_MAX_PATH + 1];
	char strPackGroupLocation[_MAX_PATH + 1];
	char strAdvance[_MAX_PATH + 1];

	// Store wanted target location
	SCopy(Config.AtRelativePath(hGroup.GetFullName().getData()), strRelativePath, _MAX_PATH);
	SCopy(strRelativePath, strTargetLocation, _MAX_PATH);

	// Adjust location by scenario origin
	if (Game.C4S.Head.Origin.getLength() && SEqualNoCase(GetExtension(Game.C4S.Head.Origin.getData()), "ocs"))
	{
		const char *szScenarioRelativePath = GetRelativePathS(strRelativePath, Config.AtRelativePath(Game.ScenarioFilename));
		if (szScenarioRelativePath != strRelativePath)
		{
			// this is a path within the scenario! Change to origin.
			size_t iRestPathLen = SLen(szScenarioRelativePath);
			if (Game.C4S.Head.Origin.getLength() + 1 + iRestPathLen <= _MAX_PATH)
			{
				SCopy(Game.C4S.Head.Origin.getData(), strTargetLocation);
				if (iRestPathLen)
				{
					SAppendChar(DirectorySeparator, strTargetLocation);
					SAppend(szScenarioRelativePath, strTargetLocation);
				}
			}
		}
	}

	// Process all language packs (and their respective pack groups)
	C4Group *pPack, *pPackGroup;
	for (int iPack = 0; (pPack = Packs.GetGroup(iPack)) && (pPackGroup = PackGroups.GetGroup(iPack)); iPack++)
	{
		// Get current pack group position within pack
		SCopy(pPack->GetFullName().getData(), strPackPath, _MAX_PATH);
		GetRelativePath(pPackGroup->GetFullName().getData(), strPackPath, strPackGroupLocation);

		// Pack group is at correct position within pack: continue with next pack
		if (SEqualNoCase(strPackGroupLocation, strTargetLocation))
			continue;

		// Try to backtrack until we can reach the target location as a relative child
		while ( strPackGroupLocation[0]
		        && !GetRelativePath(strTargetLocation, strPackGroupLocation, strAdvance)
		        && pPackGroup->OpenMother() )
		{
			// Update pack group location
			GetRelativePath(pPackGroup->GetFullName().getData(), strPackPath, strPackGroupLocation);
		}

		// We can reach the target location as a relative child
		if (strPackGroupLocation[0] && GetRelativePath(strTargetLocation, strPackGroupLocation, strAdvance))
		{
			// Advance pack group to relative child
			pPackGroup->OpenChild(strAdvance);
		}

		// Cannot reach by advancing: need to close and reopen (rewinding group file)
		else
		{
			// Close pack group (if it is open at all)
			pPackGroup->Close();
			// Reopen pack group to relative position in language pack if possible
			pPackGroup->OpenAsChild(pPack, strTargetLocation);
		}

	}

	// Store new target location
	SCopy(strTargetLocation, PackGroupLocation, _MAX_FNAME);

	C4GroupSet r;
	// Provided group gets highest priority
	r.RegisterGroup(hGroup, false, 1000, C4GSCnt_Component);
	// register currently open pack groups
	r.RegisterGroups(PackGroups, C4GSCnt_Language);
	return r;
}