Example #1
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;
			}
}
Example #2
0
void C4StartupMainDlg::UpdateParticipants() {
  // First validate all participants (files must exist)
  StdStrBuf strPlayers, strPlayer;
  strPlayer.SetLength(1024 + 1);
  strPlayers.Copy(Config.General.Participants);
  *Config.General.Participants = 0;
  for (int i = 0; SCopySegment(strPlayers.getData(), i, strPlayer.getMData(),
                               ';', 1024, true);
       i++) {
    const char *szPlayer = strPlayer.getData();
    if (!szPlayer || !*szPlayer) continue;
    if (!FileExists(szPlayer)) continue;
    if (!SEqualNoCase(GetExtension(szPlayer), "c4p"))
      continue;  // additional sanity check to clear strange exe-path-only
                 // entries in player list?
    SAddModule(Config.General.Participants, szPlayer);
  }
  // Draw selected players - we are currently displaying the players stored in
  // Config.General.Participants.
  // Existence of the player files is not validated and player filenames are
  // displayed directly
  // (names are not loaded from the player core).
  strPlayers.Format(LoadResStr("IDS_DESC_PLRS"));
  if (!Config.General.Participants[0])
    strPlayers.Append(LoadResStr("IDS_DLG_NOPLAYERSSELECTED"));
  else
    for (int i = 0; SCopySegment(Config.General.Participants, i,
                                 strPlayer.getMData(), ';', 1024, true);
         i++) {
      if (i > 0) strPlayers.Append(", ");
      strPlayers.Append(C4Language::IconvClonk(
                            GetFilenameOnly(strPlayer.getData())).getData());
    }
  pParticipantsLbl->SetText(strPlayers.getData());
}
Example #3
0
void C4StartupMainDlg::UpdateParticipants()
{
	// First validate all participants (files must exist)
	std::string strPlayers(Config.General.Participants);
	std::vector<char> strPlayer(1025);
	*Config.General.Participants=0;
	for (int i = 0; SCopySegment(strPlayers.c_str(), i, &strPlayer[0], ';', strPlayer.size() - 1, true); i++)
	{
		const char *szPlayer = &strPlayer[0];
		std::string strPlayerFile(Config.General.UserDataPath);
		strPlayerFile.append(szPlayer);
		if (!szPlayer || !*szPlayer) continue;
		if (!FileExists(strPlayerFile.c_str())) continue;
		if (!SEqualNoCase(GetExtension(szPlayer), "ocp")) continue; // additional sanity check to clear strange exe-path-only entries in player list?
		SAddModule(Config.General.Participants, szPlayer);
	}
	// Draw selected players - we are currently displaying the players stored in Config.General.Participants.
	// Existence of the player files is not validated and player filenames are displayed directly
	// (names are not loaded from the player core).
	strPlayers = LoadResStr("IDS_DESC_PLRS");
	if (!Config.General.Participants[0])
		strPlayers.append(LoadResStr("IDS_DLG_NOPLAYERSSELECTED"));
	else
		for (int i = 0; SCopySegment(Config.General.Participants, i, &strPlayer[0], ';', 1024, true); i++)
		{
			if (i > 0) strPlayers.append(", ");
			strPlayers.append(GetFilenameOnly(&strPlayer[0]));
		}
	pParticipantsLbl->SetText(strPlayers.c_str());
}
Example #4
0
C4GUI::ContextMenu *C4StartupMainDlg::OnPlayerSelContextRemove(C4GUI::Element *pBtn, int32_t iX, int32_t iY)
{
	C4GUI::ContextMenu *pCtx = new C4GUI::ContextMenu();
	char szPlayer[1024+1];
	for (int i = 0; SCopySegment(Config.General.Participants, i, szPlayer, ';', 1024, true); i++)
		if (*szPlayer)
			pCtx->AddItem(GetFilenameOnly(szPlayer), "Remove this player from participation list", C4GUI::Ico_Player, new C4GUI::CBMenuHandlerEx<C4StartupMainDlg, int>(this, &C4StartupMainDlg::OnPlayerSelContextRemovePlr, i), nullptr);
	return pCtx;
}
Example #5
0
void C4GameSaveSavegame::AdjustCore(C4Scenario &rC4S)
{
	// Determine save game index from trailing number in group file name
	int iSaveGameIndex = GetTrailingNumber(GetFilenameOnly(pSaveGroup->GetFullName().getData()));
	// Looks like a decent index: set numbered icon
	if (Inside(iSaveGameIndex, 1, 10))
		rC4S.Head.Icon = 2 + (iSaveGameIndex - 1);
	// Else: set normal script icon
	else
		rC4S.Head.Icon = 29;
}
Example #6
0
bool C4VectorFont::Init(C4Group &hGrp, const char *szFilename, C4Config &rCfg)
	{
	// name by file
	Name.Copy(GetFilenameOnly(szFilename));
#if defined(_WIN32) && !defined(HAVE_FREETYPE)
	// check whether group is directory or packed
	if (!hGrp.IsPacked())
		{
		// it's open: use the file directly
		SCopy(hGrp.GetFullName().getData(), FileName, _MAX_PATH);
		AppendBackslash(FileName);
		SAppend(szFilename, FileName);
		if (!FileExists(FileName)) { *FileName=0; return false; }
		fIsTempFile = false;
		}
	else
		{
		// it's packed: extract to temp path
		SCopy(rCfg.AtTempPath(szFilename), FileName, _MAX_PATH);
		// make sure the filename is not in use, in case multiple instances of the engine are run
		if (FileExists(FileName))
			{
			RemoveExtension(FileName);
			StdStrBuf sNewFilename;
			for (int i=0; i<1000; ++i)
				{
				sNewFilename.Format("%s%x", FileName, (int)rand());
				if (*GetExtension(szFilename))
					{
					sNewFilename.AppendChar('.');
					sNewFilename.Append(GetExtension(szFilename));
					}
				if (!FileExists(sNewFilename.getData())) break;
				}
			SCopy(sNewFilename.getData(), FileName, _MAX_PATH);
			}
		if (!hGrp.ExtractEntry(szFilename, FileName)) { *FileName=0; return false; }
		fIsTempFile = true;
		}
	// add the font resource
	//if (!AddFontResourceEx(FileName, FR_PRIVATE, NULL)) requires win2k
	if (!AddFontResource(FileName))
		{
		if (fIsTempFile) EraseFile(FileName);
		*FileName='\0';
		return false;
		}
#else
	if (!hGrp.LoadEntry(szFilename, Data)) return false;
#endif
	// success
	return true;
	}
Example #7
0
C4GUI::ContextMenu *C4StartupMainDlg::OnPlayerSelContextAdd(C4GUI::Element *pBtn, int32_t iX, int32_t iY)
{
	C4GUI::ContextMenu *pCtx = new C4GUI::ContextMenu();
	const char *szFn;
	StdStrBuf sSearchPath(Config.General.UserDataPath);
//  sSearchPath.Format("%s%s", (const char *) Config.General.ExePath, (const char *) Config.General.PlayerPath);
	for (DirectoryIterator i(sSearchPath.getData()); (szFn=*i); i++)
	{
		szFn = Config.AtRelativePath(szFn);
		if (*GetFilename(szFn) == '.') continue;
		if (!WildcardMatch(C4CFN_PlayerFiles, GetFilename(szFn))) continue;
		if (!SIsModule(Config.General.Participants, szFn, nullptr, false))
			pCtx->AddItem(GetFilenameOnly(szFn), "Let this player join in next game", C4GUI::Ico_Player,
			              new C4GUI::CBMenuHandlerEx<C4StartupMainDlg, StdCopyStrBuf>(this, &C4StartupMainDlg::OnPlayerSelContextAddPlr, StdCopyStrBuf(szFn)), nullptr);
	}
	return pCtx;
}
Example #8
0
LinkedList *GetMatchingFiles (const char * const pattern, const bool full_path_flag)
{
	LinkedList *list_p = AllocateLinkedList (FreeStringListNode);

	if (list_p)
		{
			char *filename_p = GetFilenameOnly (pattern);

			if (filename_p)
				{
					char *path_p = GetPathOnly (pattern);

					if (path_p)
						{
							DIR *dir_p = opendir (path_p);

							if (dir_p)
								{
									struct dirent entry;
									struct dirent *entry_p = &entry;

									while ((entry_p = readdir (dir_p)) != NULL)
										{
											if ((fnmatch (filename_p, entry_p -> d_name, 0)) == 0)
												{
													StringListNode *node_p = NULL;

													if (full_path_flag)
														{
															char *full_filename_s = MakeFilename (path_p, entry_p -> d_name);

															if (full_filename_s)
																{
																	node_p = AllocateStringListNode (full_filename_s, MF_SHALLOW_COPY);
																}
														}
													else
														{
															node_p = AllocateStringListNode (entry_p -> d_name, MF_DEEP_COPY);
														}

													if (node_p)
														{
															LinkedListAddTail (list_p, (ListItem *) node_p);
														}
												}
										}

									closedir (dir_p);
								}

							FreeMemory (path_p);
						}

					FreeMemory (filename_p);
				}


			if (list_p -> ll_size > 0)
				{
					return list_p;
				}
			else
				{
					FreeLinkedList (list_p);
				}
		}

	return NULL;
}
Example #9
0
bool C4FontLoader::InitFont(CStdFont &rFont, const char *szFontName, FontType eType, int32_t iSize, C4GroupSet *pGfxGroups, bool fDoShadow)
	{
	// safety
	if (!szFontName || !*szFontName)
		{
		LogFatal(LoadResStr("IDS_ERR_INITFONTS"));
		return false;
		}
	// get font to load
	// pFontDefs may be NULL if no fonts are loaded; but then iFontDefCount is zero as well
	// the function must not be aborted, because a standard windows font may be loaded
	std::vector<C4FontDef>::iterator pFontDefC = FontDefs.begin(), pFontDef = FontDefs.end();
	while (pFontDefC != FontDefs.end())
		{
		// check font
		if (pFontDefC->Name == szFontName)
			{
			int32_t iSizeDiff = Abs(pFontDefC->iSize - iSize);
			// better match than last font?
			if (pFontDef == FontDefs.end() || Abs(pFontDef->iSize - iSize) >= iSizeDiff)
				pFontDef = pFontDefC;
			}
		// check next one
		++pFontDefC;
		}
	// if def has not been found, use the def as font name
	// determine font def string
	const char *szFontString = szFontName;
	// special: Fonts without shadow are always newly rendered
	if (!fDoShadow) { pFontDef=FontDefs.end(); }
	if (pFontDef!=FontDefs.end()) switch (eType)
		{
		case C4FT_Log:      szFontString = pFontDef->LogFont.getData(); break;
		case C4FT_MainSmall:szFontString = pFontDef->SmallFont.getData(); break;
		case C4FT_Main:     szFontString = pFontDef->Font.getData(); break;
		case C4FT_Caption:  szFontString = pFontDef->CaptionFont.getData(); break;
		case C4FT_Title:    szFontString = pFontDef->TitleFont.getData(); break;
		default: LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; // invalid call
		}
	// font not assigned?
	if (!*szFontString)
		{
		// invalid call or spec
		LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false;
		}
	// get font name
	char FontFaceName[C4MaxName+1], FontParam[C4MaxName+1];
	SCopyUntil(szFontString, FontFaceName, ',', C4MaxName);
	// is it an image file?
	const char *szExt = GetExtension(FontFaceName);
	if (SEqualNoCase(szExt, "png") || SEqualNoCase(szExt, "bmp"))
		{
		// image file name: load bitmap font from image file
		// if no graphics group is given, do not load yet
		if (!pGfxGroups)
			{
			LogFatal(LoadResStr("IDS_ERR_INITFONTS"));
			return false;
			}
		// indent given?	
		int32_t iIndent = 0;
		if (SCopySegment(szFontString, 1, FontParam, ',', C4MaxName))
			sscanf(FontParam, "%i", &iIndent);
		// load font face from gfx group
		int32_t iGrpId;
		C4Group *pGrp = pGfxGroups->FindEntry(FontFaceName, NULL, &iGrpId);
		if (!pGrp)
			{
			LogFatal(LoadResStr("IDS_ERR_INITFONTS"));
			return false;
			}
		// check if it's already loaded from that group with that parameters
		if (!rFont.IsSameAsID(FontFaceName, iGrpId, iIndent))
			{
			// it's not; so (re-)load it now!
			if (rFont.IsInitialized())
				{
				// reloading
				rFont.Clear();
				LogF(LoadResStr("IDS_PRC_UPDATEFONT"), FontFaceName, iIndent, 0);
				}
			C4Surface sfc;
			if (!sfc.Load(*pGrp, FontFaceName))
				{
				LogFatal(LoadResStr("IDS_ERR_INITFONTS"));
				return false;
				}
			// init font from face
			try 
				{
				rFont.Init(GetFilenameOnly(FontFaceName), &sfc, iIndent);
				}
			catch (std::runtime_error & e)
				{
				LogFatal(e.what());
				LogFatal(LoadResStr("IDS_ERR_INITFONTS"));
				return false;
				}
			rFont.id = iGrpId;
			}
		}
	else
		{
		int32_t iDefFontSize; DWORD dwDefWeight=FW_NORMAL;
#if defined(_WIN32) && !defined(HAVE_FREETYPE)
		switch (eType)
			{
			case C4FT_Log:     iDefFontSize = 8; break;
			case C4FT_MainSmall:iDefFontSize = iSize+1; break;
			case C4FT_Main:    iDefFontSize = iSize+4; break;
			case C4FT_Caption: iDefFontSize = iSize+6; dwDefWeight = FW_BOLD; break;
			case C4FT_Title:   iDefFontSize = iSize*3; break;
			default: LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; // invalid call
			}
#else
		switch (eType)
			{
			case C4FT_Log:     iDefFontSize = iSize*12/14; break;
			case C4FT_MainSmall:iDefFontSize = iSize*13/14; break;
			case C4FT_Main:    iDefFontSize = iSize; break;
			case C4FT_Caption: iDefFontSize = iSize*16/14; /*dwDefWeight = FW_MEDIUM;*/ break;
			case C4FT_Title:   iDefFontSize = iSize*22/14; /*dwDefWeight = FW_MEDIUM;*/ break;
			default: LogFatal(LoadResStr("IDS_ERR_INITFONTS")); return false; // invalid call
			}
#endif
		// regular font name: let WinGDI or Freetype draw a font with the given parameters
		// font size given?	
		if (SCopySegment(szFontString, 1, FontParam, ',', C4MaxName))
			sscanf(FontParam, "%i", &iDefFontSize);
		// font weight given?
		if (SCopySegment(szFontString, 2, FontParam, ',', C4MaxName))
			sscanf(FontParam, "%i", &dwDefWeight);
		// check if it's already loaded from that group with that parameters
		if (!rFont.IsSameAs(FontFaceName, iDefFontSize, dwDefWeight))
			{
			// it's not; so (re-)load it now!
			if (rFont.IsInitialized())
				{
				// reloading
				rFont.Clear();
				LogF(LoadResStr("IDS_PRC_UPDATEFONT"), FontFaceName, iDefFontSize, dwDefWeight);
				}
			// init with given font name
			try 
				{
				// check if one of the internally listed fonts should be used
				C4VectorFont * pFont = pVectorFonts;
				while (pFont)
					{
					if (SEqual(pFont->Name.getData(), FontFaceName))
						{
						if (InitFont(rFont, pFont, iDefFontSize, dwDefWeight, fDoShadow)) break;
						}
					pFont = pFont->pNext;
					}
				// no internal font matching? Then create one using the given face/filename (using a system font)
				if (!pFont)
					{
					pFont = new C4VectorFont();
					if (pFont->Init(FontFaceName, iDefFontSize, dwDefWeight, Config.General.LanguageCharset))
						{
						AddVectorFont(pFont);
						if (!InitFont(rFont, pFont, iDefFontSize, dwDefWeight, fDoShadow))
						  throw std::runtime_error(FormatString("Error initializing font %s", FontFaceName).getData());
						}
					else
						{
						delete pFont;
						// no match for font face found
						throw std::runtime_error(FormatString("Font face %s undefined", FontFaceName).getData());
						}
					}
				}
			catch (std::runtime_error & e)
				{
				LogFatal(e.what());
				LogFatal(LoadResStr("IDS_ERR_INITFONTS"));
				return false;
				}
			rFont.id = 0;
			}
		}
	// done, success
	return true;
	}
Example #10
0
BOOL C4Record::Start(bool fInitial) {
  // no double record
  if (fRecording) return FALSE;

  // create demos folder
  if (!Config.General.CreateSaveFolder(Config.General.SaveDemoFolder.getData(),
                                       LoadResStr("IDS_GAME_RECORDSTITLE")))
    return FALSE;

  // various infos
  StdStrBuf sDemoFolder;
  sDemoFolder.Ref(Config.General.SaveDemoFolder);
  char sScenName[_MAX_FNAME + 1];
  SCopy(GetFilenameOnly(Game.Parameters.Scenario.getFile()), sScenName,
        _MAX_FNAME);

  // remove trailing numbers from scenario name (e.g. from savegames) - could we
  // perhaps use C4S.Head.Origin instead...?
  char *pScenNameEnd = sScenName + SLen(sScenName);
  while (Inside<char>(*--pScenNameEnd, '0', '9'))
    if (pScenNameEnd == sScenName) break;
  pScenNameEnd[1] = 0;

  // determine index (by total number of records)
  Index = 1;
  for (DirectoryIterator i(Config.General.SaveDemoFolder.getData()); *i; ++i)
    if (WildcardMatch(C4CFN_ScenarioFiles, *i)) Index++;

  // compose record filename
  sFilename.Format("%s" DirSep "%03i-%s.c4s", sDemoFolder.getData(), Index,
                   sScenName);

  // log
  StdStrBuf sLog;
  sLog.Format(LoadResStr("IDS_PRC_RECORDINGTO"), sFilename.getData());
  if (Game.FrameCounter) sLog.AppendFormat(" (Frame %d)", Game.FrameCounter);
  Log(sLog.getData());

  // save game - this also saves player info list
  C4GameSaveRecord saveRec(fInitial, Index, Game.Parameters.isLeague());
  if (!saveRec.Save(sFilename.getData())) return FALSE;
  saveRec.Close();

  // unpack group, if neccessary
  if (!DirectoryExists(sFilename.getData()) &&
      !C4Group_UnpackDirectory(sFilename.getData()))
    return FALSE;

  // open control record file
  char szCtrlRecFilename[_MAX_PATH + 1 + _MAX_FNAME];
  sprintf(szCtrlRecFilename, "%s" DirSep C4CFN_CtrlRec, sFilename.getData());
  if (!CtrlRec.Create(szCtrlRecFilename)) return FALSE;

  // open record group
  if (!RecordGrp.Open(sFilename.getData())) return FALSE;

  // record go
  fStreaming = false;
  fRecording = true;
  iLastFrame = 0;
  return TRUE;
}
Example #11
0
bool C4MainMenu::ActivateSavegame(int32_t iPlayer)
{
	// Check if saving is possible
	if (!Game.CanQuickSave()) return false;

	// Menu symbol/init
	char DirPath[_MAX_PATH+1];
	char ScenName[_MAX_PATH+1]; *ScenName=0;

	InitRefSym(GfxR->fctMenu.GetPhase(0), LoadResStr("IDS_MENU_CPSAVEGAME"), iPlayer);
	SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom);
	SetPermanent(true);

	// target file name mask
	// get folder & filename to store in
	// some magic is needed to ensure savegames are stored properly into their folders
	SCopy(GetFilename(Game.ScenarioFilename), DirPath);
	if (DirPath[strlen(DirPath) - 1] == '\\') DirPath[strlen(DirPath) - 1] = 0;
	RemoveExtension(DirPath);
	if (LooksLikeInteger(DirPath))
	{
		// ScenTitle.ocf\%d.ocs-names (old-style savegames)
		// get owning folder
		if (Game.pParentGroup)
		{
			// owning folder determines filename
			SCopy(GetFilenameOnly(Game.pParentGroup->GetName()), ScenName);
		}
		else
		{
			// no owning folder known: too bad
			// make a vague guess based on the scenario title
			SCopy(GetFilenameOnly(Game.ScenarioFilename), ScenName);
		}
	}
	else
	{
		// DirPath is a valid filename for now...
		SCopy(DirPath, ScenName);
		// but remove trailing numbers to adjust new-style savegames
		char *pScenNameEnd = ScenName+SLen(ScenName);
		while (Inside<char>(*--pScenNameEnd, '0', '9'))
			if (pScenNameEnd == ScenName)
			{
				// should not happen: digit-only-filenames should have been caught earlier
				SCopy("dbg_error!", ScenName);
				pScenNameEnd = ScenName+SLen(ScenName)-1;
			}
		pScenNameEnd[1]=0;
	}

	// New Style 2007:
	// * scenarios are saved into ScenName.ocf/ScenName123.ocs to keep umlauts out of filenames
	// * language titles are stored in folders as title component
	StdStrBuf strFilename, strTitle;
	strFilename.Format("%s.ocf%c%s%%d.ocs", ScenName, DirectorySeparator, ScenName);
	strTitle = Game.ScenarioTitle;

	// Create menu items
	StdStrBuf strFilenameIndexed, strCommand, strCaption, strSavePath;
	for (int32_t i = 1; i <= 10; i++)
	{
		// Index filename
		strFilenameIndexed.Format(strFilename.getData(), i);
		// Compose commmand
		strCommand.Format("Save:Game:%s:%s", strFilenameIndexed.getData(), strTitle.getData()); // Notice: the language title might contain ':' and thus confuse the segment list - but C4Menu::MenuCommand will try to handle this...
		// Check free slot
		strSavePath.Format("%s%c%s", Config.AtUserDataPath(C4CFN_Savegames), DirectorySeparator, strFilenameIndexed.getData());
		bool fFree = !C4Group_IsGroup(strSavePath.getData());
		// Item caption
		strCaption = LoadResStr("IDS_MENU_CPSAVEGAME");
		// add menu item
		AddRefSym(strCaption.getData(), GfxR->fctMenu.GetPhase(i - 1, fFree ? 2 : 1), strCommand.getData(), C4MN_Item_NoCount, NULL, LoadResStr("IDS_MENU_CPSAVEGAMEINFO"));
	}

	// Go back to options menu on close
	SetCloseCommand("ActivateMenu:Main");

	return true;
}