Esempio n. 1
0
C4SoundEffect *C4SoundSystem::GetEffect(const char *szSndName) {
  C4SoundEffect *pSfx;
  char szName[C4MaxSoundName + 4 + 1];
  int32_t iNumber;
  // Evaluate sound name
  SCopy(szSndName, szName, C4MaxSoundName);
  // Default extension
  DefaultExtension(szName, "wav");
  // Convert old style '*' wildcard to correct '?' wildcard
  // For sound effects, '*' is supposed to match single digits only
  SReplaceChar(szName, '*', '?');
  // Sound with a wildcard: determine number of available matches
  if (SCharCount('?', szName)) {
    // Search global sound file
    if (!(iNumber = SoundFile.EntryCount(szName)))
      // Search scenario local files
      if (!(iNumber = Game.ScenarioFile.EntryCount(szName)))
        // Search bank loaded sounds
        if (!(iNumber = EffectInBank(szName)))
          // None found: failure
          return NULL;
    // Insert index to name
    iNumber = BoundBy(1 + SafeRandom(iNumber), 1, 9);
    SReplaceChar(szName, '?', '0' + iNumber);
  }
  // Find requested sound effect in bank
  for (pSfx = FirstSound; pSfx; pSfx = pSfx->Next)
    if (SEqualNoCase(szName, pSfx->Name)) break;
  // Sound not in bank, try add
  if (!pSfx)
    if (!(pSfx = AddEffect(szName))) return NULL;
  return pSfx;
}
Esempio n. 2
0
void C4Language::LoadInfos(C4Group &hGroup)
{
	char strEntry[_MAX_FNAME + 1];
	char *strTable;
	// Look for language string tables
	hGroup.ResetSearch();
	while (hGroup.FindNextEntry(C4CFN_Language, strEntry))
		// For now, we will only load info on the first string table found for a given
		// language code as there is currently no handling for selecting different string tables
		// of the same code - the system always loads the first string table found for a given code
		if (!FindInfo(GetFilenameOnly(strEntry) + SLen(GetFilenameOnly(strEntry)) - 2))
			// Load language string table
			if (hGroup.LoadEntry(strEntry, &strTable, 0, 1))
			{
				// New language info
				C4LanguageInfo *pInfo = new C4LanguageInfo;
				// Get language code by entry name
				SCopy(GetFilenameOnly(strEntry) + SLen(GetFilenameOnly(strEntry)) - 2, pInfo->Code, 2);
				SCapitalize(pInfo->Code);
				// Get language name, info, fallback from table
				CopyResStr("IDS_LANG_NAME", strTable, pInfo->Name);
				CopyResStr("IDS_LANG_INFO", strTable, pInfo->Info);
				CopyResStr("IDS_LANG_FALLBACK", strTable, pInfo->Fallback);
				// Safety: pipe character is not allowed in any language info string
				SReplaceChar(pInfo->Name, '|', ' ');
				SReplaceChar(pInfo->Info, '|', ' ');
				SReplaceChar(pInfo->Fallback, '|', ' ');
				// Delete table
				delete [] strTable;
				// Add info to list
				pInfo->Next = Infos;
				Infos = pInfo;
			}
}
Esempio n. 3
0
int32_t C4TextureMap::LoadTextures(C4Group &hGroup, C4Group* OverloadFile)
  {
  int32_t texnum=0;

#ifdef C4ENGINE

	// overload: load from other file
	if (OverloadFile) texnum+=LoadTextures(*OverloadFile);

  char texname[256+1];
	C4Surface *ctex;
  size_t binlen;
	// newgfx: load PNG-textures first
  hGroup.ResetSearch();
  while (hGroup.AccessNextEntry(C4CFN_PNGFiles,&binlen,texname))		
		{
		// check if it already exists in the map
    SReplaceChar(texname,'.',0);
		if (GetTexture(texname)) continue;
		SAppend(".png", texname);
		// load
    if (ctex=GroupReadSurfacePNG(hGroup))
      {
      SReplaceChar(texname,'.',0);
      if (AddTexture(texname,ctex)) texnum++;
      else delete ctex;
      }
		}
	// Load all bitmap files from group
	hGroup.ResetSearch();
	CSurface8 *ctex8;
	while (hGroup.AccessNextEntry(C4CFN_BitmapFiles,&binlen,texname))		
		{
		// check if it already exists in the map
		SReplaceChar(texname,'.',0);
		if (GetTexture(texname)) continue;
		SAppend(".bmp", texname);
		if (ctex8=GroupReadSurface8(hGroup))
			{
			ctex8->AllowColor(0,2,TRUE);
			SReplaceChar(texname,'.',0);
			if (AddTexture(texname,ctex8)) texnum++;
			else delete ctex;
			}
		}

#endif

	return texnum;
	}
Esempio n. 4
0
void C4Application::QuitGame() {
  // reinit desired? Do restart
  if (UseStartupDialog || NextMission) {
    // backup last start params
    bool fWasNetworkActive = Game.NetworkActive;
    // stop game
    Game.Clear();
    Game.Default();
    AppState = C4AS_PreInit;
    // if a next mission is desired, set to start it
    if (NextMission) {
      SCopy(NextMission.getData(), Game.ScenarioFilename, _MAX_PATH);
      SReplaceChar(
          Game.ScenarioFilename, '\\',
          DirSep[0]);  // linux/mac: make sure we are using forward slashes
#ifdef NETWORK
      Game.fLobby = Game.NetworkActive = fWasNetworkActive;
#endif
      Game.fObserve = false;
      Game.Record = !!Config.General.Record;
      NextMission.Clear();
    }
  } else {
    Quit();
  }
}
Esempio n. 5
0
int32_t C4TextureMap::LoadMap(C4Group &hGroup, const char *szEntryName, BOOL *pOverloadMaterials, BOOL *pOverloadTextures)
  {
  char *bpMap;
  char szLine[100+1];
  int32_t cnt, iIndex, iTextures = 0;
  // Load text file into memory
  if (!hGroup.LoadEntry(szEntryName,&bpMap,NULL,1)) return 0;
  // Scan text buffer lines       
  for (cnt=0; SCopySegment(bpMap,cnt,szLine,0x0A,100); cnt++)
    if ( (szLine[0]!='#') && (SCharCount('=',szLine)==1) )
      {
      SReplaceChar(szLine,0x0D,0x00);
			if (Inside<int32_t>( iIndex = strtol(szLine,NULL,10), 0, C4M_MaxTexIndex-1 ))
				{
				const char *szMapping = szLine+SCharPos('=',szLine)+1;
				StdStrBuf Material, Texture;
				Material.CopyUntil(szMapping, '-'); Texture.Copy(SSearch(szMapping, "-"));
				if (AddEntry(iIndex, Material.getData(), Texture.getData()))
					iTextures++;
				}
      }
		else
			{
			if (SEqual2(szLine, "OverloadMaterials")) { fOverloadMaterials = TRUE; if(pOverloadMaterials) *pOverloadMaterials = TRUE; }
			if (SEqual2(szLine, "OverloadTextures")) { fOverloadTextures = TRUE;  if(pOverloadTextures) *pOverloadTextures = TRUE; }
			}
  // Delete buffer, return entry count
  delete [] bpMap;
	fEntriesAdded=false;
  return iTextures;
  }
Esempio n. 6
0
void C4ObjectInfoCore::Default(C4ID n_id, 
															 C4DefList *pDefs, 
															 const char *cpNames)
  {
	
	// Def
	C4Def *pDef=NULL;
	if (pDefs) pDef = pDefs->ID2Def(n_id);
	
	// Defaults
	id=n_id;
  Participation=1; 
  Rank=0;
	Experience=0;
	Rounds=0;
	DeathCount=0;
	Birthday=0;
	TotalPlayingTime=0;	
	SCopy("Clonk",Name,C4MaxName);
	SCopy("Clonk",TypeName,C4MaxName);
	sRankName.Copy("Clonk");
	sNextRankName.Clear();
	NextRankExp=0;
	DeathMessage[0]='\0';
	*PortraitFile=0;
	Age=0;
	ExtraData.Reset();

	// Type
	if (pDef) SCopy(pDef->GetName(),TypeName,C4MaxName);

	// Name
	if (cpNames) 
		{
		// Name file reference
		if (SSearchNoCase(cpNames,C4CFN_Names))
			SCopy(GetAName(cpNames),Name,C4MaxName);
		// Name list 
		else
			{
			SCopySegment(cpNames,Random(SCharCount(0x0A,cpNames)),Name,0x0A,C4MaxName+1);
			SClearFrontBack(Name);
			SReplaceChar(Name,0x0D,0x00);
			}
		if (!Name[0]) SCopy("Clonk",Name,C4MaxName);
		}

#ifdef C4ENGINE
	if (pDefs) UpdateCustomRanks(pDefs);
#endif
  
	// Physical
	Physical.Default();
	if (pDef) Physical = pDef->Physical;
	Physical.PromotionUpdate(Rank);

	// Old format
  
	} 
Esempio n. 7
0
C4MenuItem::C4MenuItem(C4Menu *pMenu, int32_t iIndex, const char *szCaption,
                       const char *szCommand, int32_t iCount, C4Object *pObject, const char *szInfoCaption,
                       C4ID idID, const char *szCommand2, bool fOwnValue, int32_t iValue, int32_t iStyle, bool fIsSelectable)
		: C4GUI::Element(), Count(iCount), id(idID), Object(pObject), pSymbolObj(NULL), pSymbolGraphics(NULL), dwSymbolClr(0u),
		fOwnValue(fOwnValue), iValue(iValue), fSelected(false), iStyle(iStyle), pMenu(pMenu),
		iIndex(iIndex), IsSelectable(fIsSelectable), TextDisplayProgress(-1)
{
	*Caption=*Command=*Command2=*InfoCaption=0;
	Symbol.Default();
	SCopy(szCaption,Caption,C4MaxTitle);
	SCopy(szCommand,Command,_MAX_FNAME+30);
	SCopy(szCommand2,Command2,_MAX_FNAME+30);
	SCopy(szInfoCaption,InfoCaption,C4MaxTitle);
	// some info caption corrections
	SReplaceChar(InfoCaption, 10, ' '); SReplaceChar(InfoCaption, 13, '|');
	SetToolTip(InfoCaption);
}
void C4Application::SetNextMission(const char *szMissionFilename)
{
	// set next mission if any is desired
	if (szMissionFilename)
	{
		NextMission.Copy(szMissionFilename);
		// scenarios tend to use the wrong slash
		SReplaceChar(NextMission.getMData(), AltDirectorySeparator, DirectorySeparator);
	}
	else
		NextMission.Clear();
}
Esempio n. 9
0
C4SoundInstance *C4SoundSystem::FindInstance(const char *szSndName,
                                             C4Object *pObj) {
  char szName[C4MaxSoundName + 4 + 1];
  // Evaluate sound name (see GetEffect)
  SCopy(szSndName, szName, C4MaxSoundName);
  DefaultExtension(szName, "wav");
  SReplaceChar(szName, '*', '?');
  // Find an effect with a matching instance
  for (C4SoundEffect *csfx = FirstSound; csfx; csfx = csfx->Next)
    if (WildcardMatch(szName, csfx->Name)) {
      C4SoundInstance *pInst = csfx->GetInstance(pObj);
      if (pInst) return pInst;
    }
  return NULL;
}
Esempio n. 10
0
void C4ObjectInfoCore::Default(C4ID n_id,
                               C4DefList *pDefs,
                               const char *cpNames)
{

	// Def
	C4Def *pDef=NULL;
	if (pDefs) pDef = pDefs->ID2Def(n_id);

	// Defaults
	id=n_id;
	Participation=1;
	Rank=0;
	Experience=0;
	Rounds=0;
	DeathCount=0;
	Birthday=0;
	TotalPlayingTime=0;
	SCopy("Clonk",Name,C4MaxName);
	SCopy("Clonk",TypeName,C4MaxName);
	sRankName.Copy("Clonk");
	sNextRankName.Clear();
	NextRankExp=0;
	DeathMessage[0]='\0';
	Age=0;
	ExtraData.Reset();

	// Type
	if (pDef) SCopy(pDef->GetName(),TypeName,C4MaxName);

	// Name
	if (cpNames)
	{
		SCopySegment(cpNames,Random(SCharCount(0x0A,cpNames)),Name,0x0A,C4MaxName+1);
		SClearFrontBack(Name);
		SReplaceChar(Name,0x0D,0x00);
		if (!Name[0]) SCopy("Clonk",Name,C4MaxName);
	}

	if (pDefs) UpdateCustomRanks(pDefs);
}
Esempio n. 11
0
BOOL C4ComponentHost::Load(const char *szName, C4GroupSet &hGroupSet,
                           const char *szFilename, const char *szLanguage) {
  // Clear any old stuff
  Clear();
  // Store name & filename
  SCopy(szName, Name);
  SCopy(szFilename, Filename);
  // Load component - try all segmented filenames
  char strEntry[_MAX_FNAME + 1], strEntryWithLanguage[_MAX_FNAME + 1];
  for (int iFilename = 0;
       SCopySegment(Filename, iFilename, strEntry, '|', _MAX_FNAME);
       iFilename++) {
    // Try to insert all language codes provided into the filename
    char strCode[3] = "";
    for (int iLang = 0;
         SCopySegment(szLanguage ? szLanguage : "", iLang, strCode, ',', 2);
         iLang++) {
      // Insert language code
      sprintf(strEntryWithLanguage, strEntry, strCode);
      if (hGroupSet.LoadEntryString(strEntryWithLanguage, Data)) {
        if (pConfig->General.fUTF8) Data.EnsureUnicode();
        // Store actual filename
        C4Group *pGroup = hGroupSet.FindEntry(strEntryWithLanguage);
        pGroup->FindEntry(strEntryWithLanguage, Filename);
        CopyFilePathFromGroup(*pGroup);
        // Got it
        return TRUE;
      }
      // Couldn't insert language code anyway - no point in trying other
      // languages
      if (!SSearch(strEntry, "%s")) break;
    }
  }
  // Truncate any additional segments from stored filename
  SReplaceChar(Filename, '|', 0);
  // skip full path (unknown)
  FilePath[0] = 0;
  // Not loaded
  return FALSE;
}
Esempio n. 12
0
void C4Application::ParseCommandLine(int argc, char * argv[])
{

	StdStrBuf CmdLine("Command line:");
	for(int i = 0; i < argc; ++i) {
		CmdLine.Append(" ");
		CmdLine.Append(argv[i]);
	}
	Log(CmdLine.getData());

	ClearCommandLine();
	Game.NetworkActive = false;
	isEditor = 2;
	int c;
	while (1)
	{

		static struct option long_options[] =
		{
			// option, w/ argument?, set directly, set to...
			{"editor", no_argument, &isEditor, 1},
			{"fullscreen", no_argument, &isEditor, 0},
			{"debugwait", no_argument, &Game.DebugWait, 1},
			{"update", no_argument, &CheckForUpdates, 1},
			{"noruntimejoin", no_argument, &Config.Network.NoRuntimeJoin, 1},
			{"runtimejoin", no_argument, &Config.Network.NoRuntimeJoin, 0},
			{"noleague", no_argument, &Config.Network.LeagueServerSignUp, 0},
			{"league", no_argument, &Config.Network.LeagueServerSignUp, 1},
			{"nosignup", no_argument, &Config.Network.MasterServerSignUp, 0},
			{"signup", no_argument, &Config.Network.MasterServerSignUp, 1},
			
			{"debugrecread", required_argument, 0, 'K'},
			{"debugrecwrite", required_argument, 0, 'w'},

			{"client", required_argument, 0, 'c'},
			{"host", no_argument, 0, 'h'},
			{"debughost", required_argument, 0, 'H'},
			{"debugpass", required_argument, 0, 'P'},
			{"debug", required_argument, 0, 'D'},
			{"data", required_argument, 0, 'd'},
			{"startup", required_argument, 0, 's'},
			{"stream", required_argument, 0, 'e'},
			{"recdump", required_argument, 0, 'R'},
			{"comment", required_argument, 0, 'm'},
			{"pass", required_argument, 0, 'p'},
			{"udpport", required_argument, 0, 'u'},
			{"tcpport", required_argument, 0, 't'},
			{"join", required_argument, 0, 'j'},
			{"language", required_argument, 0, 'L'},
			{"scenpar", required_argument, 0, 'S'},

			{"observe", no_argument, 0, 'o'},
			{"nonetwork", no_argument, 0, 'N'},
			{"network", no_argument, 0, 'n'},
			{"record", no_argument, 0, 'r'},

			{"lobby", required_argument, 0, 'l'},

			{"debug-opengl", no_argument, &Config.Graphics.DebugOpenGL, 1},
			{0, 0, 0, 0}
		};
		int option_index = 0;
		c = getopt_long (argc, argv, "abc:d:f:",
			long_options, &option_index);
     		// no more options
		if (c == -1)
			break;
		switch (c)
		{
		case 0:
			// Signup
			if (SEqualNoCase(long_options[option_index].name, "signup"))
			{
				Game.NetworkActive = true;
			}
			// League
			if (SEqualNoCase(long_options[option_index].name, "league"))
			{
				Game.NetworkActive = true;
				Config.Network.MasterServerSignUp = true;
			}
			break;
		// Lobby
		case 'l':
			Game.fLobby = true;
			// lobby timeout specified? (e.g. --lobby=120)
			if (optarg)
			{
				Game.iLobbyTimeout = atoi(optarg);
				if (Game.iLobbyTimeout < 0) Game.iLobbyTimeout = 0;
			}
			break;
		case 'o': Game.fObserve = true; break;
		// Direct join
		case 'j':
			Game.NetworkActive = true;
			SCopy(optarg, Game.DirectJoinAddress, _MAX_PATH);
			break;
		case 'K':
			if (optarg && optarg[0])
			{
				LogF("Reading from DebugRec file '%s'", optarg);
				SCopy(optarg, Config.General.DebugRecExternalFile, _MAX_PATH);
			}
			else
				Log("Reading DebugRec from CtrlRec file in scenario record");
			Config.General.DebugRec = 1;
			Config.General.DebugRecWrite = 0;
			break;
		case 'w':
			if (optarg && optarg[0])
			{
				LogF("Writing to DebugRec file '%s'", optarg);
				SCopy(optarg, Config.General.DebugRecExternalFile, _MAX_PATH);
			}
			else
				Log("Writing DebugRec to CtrlRec file in scenario record");
			Config.General.DebugRec = 1;
			Config.General.DebugRecWrite = 1;
			break;
		case 'r': Game.Record = true; break;
		case 'n': Game.NetworkActive = true; break;
		case 'N': Game.NetworkActive = false; break;
		// Language override by parameter
		case 'L': SCopy(optarg, Config.General.LanguageEx, CFG_MaxString);
		// port overrides
		case 't': Config.Network.PortTCP = atoi(optarg); break;
		case 'u': Config.Network.PortUDP = atoi(optarg); break;
		// network game password
		case 'p': Network.SetPassword(optarg); break;
		// network game comment
		case 'm': Config.Network.Comment.CopyValidated(optarg); break;
		// record dump
		case 'R': Game.RecordDumpFile.Copy(optarg); break;
		// record stream
		case 'e': Game.RecordStream.Copy(optarg); break;
		// startup start screen
		case 's': C4Startup::SetStartScreen(optarg); break;
		// additional read-only data path
		case 'd': Reloc.AddPath(optarg); break;
		// debug options
		case 'D': Game.DebugPort = atoi(optarg); break;
		case 'P': Game.DebugPassword = optarg; break;
		case 'H': Game.DebugHost = optarg; break;
		// set custom scenario parameter by command line
		case 'S':
			{
			StdStrBuf sopt, soptval; sopt.Copy(optarg);
			int32_t val=1;
			if (sopt.SplitAtChar('=', &soptval)) val=atoi(soptval.getData());
			Game.StartupScenarioParameters.SetValue(sopt.getData(), val, false);
			}
			break;
		// debug configs
		case 'h':
			Game.NetworkActive = true;
			Game.fLobby = true;
			Config.Network.PortTCP = 11112;
			Config.Network.PortUDP = 11113;
			Config.Network.MasterServerSignUp = Config.Network.LeagueServerSignUp = false;
			break;
		case 'c':
			Game.NetworkActive = true;
			SCopy("localhost", Game.DirectJoinAddress, _MAX_PATH);
			Game.fLobby = true;
			Config.Network.PortTCP = 11112 + 2*(atoi(optarg)+1);
			Config.Network.PortUDP = 11113 + 2*(atoi(optarg)+1);
			break;
		case '?': /* getopt_long already printed an error message. */ break;
		default: assert(!"unexpected getopt_long return value");
		}
	}
	if (!Config.Network.MasterServerSignUp)
		Config.Network.LeagueServerSignUp = false;
	if (Game.fObserve || Game.fLobby)
		Game.NetworkActive = true;

	while (optind < argc)
	{
		char * szParameter = argv[optind++];
		{ // Strip trailing / that result from tab-completing unpacked c4groups
			int iLen = SLen(szParameter);
			if (iLen > 5 && szParameter[iLen-1] == '/' && szParameter[iLen-5] == '.' && szParameter[iLen-4] == 'o' && szParameter[iLen-3] == 'c')
			{
				szParameter[iLen-1] = '\0';
			}
		}
		// Scenario file
		if (SEqualNoCase(GetExtension(szParameter),"ocs"))
		{
			if(IsGlobalPath(szParameter))
				Game.SetScenarioFilename(szParameter);
			else
				Game.SetScenarioFilename((std::string(GetWorkingDirectory()) + DirSep + szParameter).c_str());

			continue;
		}
		if (SEqualNoCase(GetFilename(szParameter),"scenario.txt"))
		{
			Game.SetScenarioFilename(szParameter);
			continue;
		}
		// Player file
		if (SEqualNoCase(GetExtension(szParameter),"ocp"))
		{
			if(IsGlobalPath(szParameter))
				SAddModule(Game.PlayerFilenames, szParameter);
			else
				SAddModule(Game.PlayerFilenames, (std::string(GetWorkingDirectory()) + DirSep + szParameter).c_str());

			continue;
		}
		// Definition file
		if (SEqualNoCase(GetExtension(szParameter),"ocd"))
		{
			SAddModule(Game.DefinitionFilenames,szParameter);
			continue;
		}
		// Key file
		if (SEqualNoCase(GetExtension(szParameter),"c4k"))
		{
			Application.IncomingKeyfile.Copy(szParameter);
			continue;
		}
		// Update file
		if (SEqualNoCase(GetExtension(szParameter),"ocu"))
		{
			Application.IncomingUpdate.Copy(szParameter);
			continue;
		}
		// record stream
		if (SEqualNoCase(GetExtension(szParameter),"c4r"))
		{
			Game.RecordStream.Copy(szParameter);
		}
		// Direct join by URL
		if (SEqual2NoCase(szParameter, "clonk:"))
		{
			// Store address
			SCopy(szParameter + 6, Game.DirectJoinAddress, _MAX_PATH);
			SClearFrontBack(Game.DirectJoinAddress, '/');
			// Special case: if the target address is "update" then this is used for update initiation by url
			if (SEqualNoCase(Game.DirectJoinAddress, "update"))
			{
				Application.CheckForUpdates = true;
				Game.DirectJoinAddress[0] = 0;
				continue;
			}
			// Self-enable network
			Game.NetworkActive = true;
			continue;
		}
	}

#ifdef _WIN32
	// Clean up some forward/backward slach confusion since many internal OC file functions cannot handle both
	SReplaceChar(Game.ScenarioFilename, AltDirectorySeparator, DirectorySeparator);
	SReplaceChar(Game.PlayerFilenames, AltDirectorySeparator, DirectorySeparator);
	SReplaceChar(Game.DefinitionFilenames, AltDirectorySeparator, DirectorySeparator);
	Application.IncomingKeyfile.ReplaceChar(AltDirectorySeparator, DirectorySeparator);
	Application.IncomingUpdate.ReplaceChar(AltDirectorySeparator, DirectorySeparator);
	Game.RecordStream.ReplaceChar(AltDirectorySeparator, DirectorySeparator);
#endif

	// Default to editor if scenario given, player mode otherwise
	if (isEditor == 2)
		isEditor = !!*Game.ScenarioFilename && !Config.General.OpenScenarioInGameMode;

	// record?
	Game.Record = Game.Record || (Config.Network.LeagueServerSignUp && Game.NetworkActive);

	// startup dialog required?
	QuitAfterGame = !isEditor && Game.HasScenario();
}
Esempio n. 13
0
BOOL C4ComponentHost::LoadAppend(const char *szName, C4Group &hGroup,
                                 const char *szFilename,
                                 const char *szLanguage) {
  Clear();

  // Store name & filename
  SCopy(szName, Name);
  SCopy(szFilename, Filename);

  // Load component (segmented filename)
  char str1[_MAX_FNAME + 1], str2[_MAX_FNAME + 1];
  int iFileCnt = 0, iFileSizeSum = 0;
  int cseg, clseg;
  for (cseg = 0; SCopySegment(Filename, cseg, str1, '|', _MAX_FNAME); cseg++) {
    char szLang[3] = "";
    for (clseg = 0;
         SCopySegment(szLanguage ? szLanguage : "", clseg, szLang, ',', 2);
         clseg++) {
      sprintf(str2, str1, szLang);
      // Check existance
      size_t iFileSize;
      if (hGroup.FindEntry(str2, NULL, &iFileSize)) {
        iFileCnt++;
        iFileSizeSum += 1 + iFileSize;
        break;
      }
      if (!SSearch(str1, "%s")) break;
    }
  }

  // No matching files found?
  if (!iFileCnt) return FALSE;

  // Allocate memory
  Data.SetLength(iFileSizeSum);

  // Search files to read contents
  char *pPos = Data.getMData();
  *pPos = 0;
  for (cseg = 0; SCopySegment(Filename, cseg, str1, '|', _MAX_FNAME); cseg++) {
    char szLang[3] = "";
    for (clseg = 0;
         SCopySegment(szLanguage ? szLanguage : "", clseg, szLang, ',', 2);
         clseg++) {
      sprintf(str2, str1, szLang);
      // Load data
      char *pTemp;
      if (hGroup.LoadEntry(str2, &pTemp, NULL, 1)) {
        *pPos++ = '\n';
        SCopy(pTemp, pPos, Data.getPtr(Data.getLength()) - pPos);
        pPos += SLen(pPos);
        delete[] pTemp;
        break;
      }
      delete[] pTemp;
      if (!SSearch(str1, "%s")) break;
    }
  }

  SReplaceChar(Filename, '|', 0);
  CopyFilePathFromGroup(hGroup);
  return !!iFileCnt;
}
Esempio n. 14
0
bool C4Sky::Init(bool fSavegame)
{
	int32_t skylistn;

	// reset scrolling pos+speed
	// not in savegame, because it will have been loaded from game data there
	if (!fSavegame)
	{
		x=y=xdir=ydir=0; ParX=ParY=10; ParallaxMode=0;
	}

	// Check for sky bitmap in scenario file
	Surface = new C4Surface();
	bool loaded = !!Surface->LoadAny(Game.ScenarioFile,C4CFN_Sky,true,true, C4SF_Tileable | C4SF_MipMap);

	// Else, evaluate scenario core landscape sky default list
	if (!loaded)
	{
		// Scan list sections
		SReplaceChar(Game.C4S.Landscape.SkyDef,',',';'); // modifying the C4S here...!
		skylistn=SCharCount(';',Game.C4S.Landscape.SkyDef)+1;
		char str[402];
		SCopySegment(Game.C4S.Landscape.SkyDef,SeededRandom(Game.RandomSeed,skylistn),str,';');
		SClearFrontBack(str);
		// Sky tile specified, try load
		if (*str && !SEqual(str,"Default"))
		{
			// Check for sky tile in scenario file
			loaded = !!Surface->LoadAny(Game.ScenarioFile,str,true,true, C4SF_Tileable | C4SF_MipMap);
			if (!loaded)
			{
				loaded = !!Surface->LoadAny(::GraphicsResource.Files, str, true, false, C4SF_Tileable | C4SF_MipMap);
			}
		}
	}

	if (loaded)
	{
		// surface loaded, store first color index
		FadeClr1=FadeClr2=0xffffffff;

		// set parallax scroll mode
		switch (Game.C4S.Landscape.SkyScrollMode)
		{
		case 0: // default: no scrolling
			break;
		case 1: // go with the wind in xdir, and do some parallax scrolling in ydir
			ParallaxMode=C4SkyPM_Wind;
			ParY=20;
			break;
		case 2: // parallax in both directions
			ParX=ParY=20;
			break;
		}

	}


	// Else, try creating default Surface
	if (!loaded)
	{
		SetFadePalette(Game.C4S.Landscape.SkyDefFade);
		delete Surface;
		Surface = 0;
	}

	// Load sky shaders: regular sprite shaders with OC_SKY define
	const char* const SkyDefines[] = { "OC_SKY", NULL };
	if (!pDraw->PrepareSpriteShader(Shader, "Sky", Surface ? C4SSC_BASE : 0, &::GraphicsResource.Files, SkyDefines, NULL))
		return false;
	if (!pDraw->PrepareSpriteShader(ShaderLight, "SkyLight", (Surface ? C4SSC_BASE : 0) | C4SSC_LIGHT, &::GraphicsResource.Files, SkyDefines, NULL))
		return false;

	// no sky - using fade in newgfx
	if (!Surface)
		return true;

	// Store size
	if (Surface)
	{
		int iWdt,iHgt;
		if (Surface->GetSurfaceSize(iWdt, iHgt))
		{
			Width = iWdt; Height = iHgt;
		}
	}

	// Success
	return true;
}