char *GetResStr(const char *id, const char *strTable)
{
	const char *pos;
	// Default
	sprintf(strResult, "[Undefined:%s]", id);
	// Compose identifier with operator
	char idExt[256 + 1 + 1]; SCopy(id, idExt, 256); SAppendChar('=', idExt);
	// String table present and id not empty
	if (strTable && id && id[0])
		// Search for identifier with operator
		if ((pos = SSearch(strTable, idExt)))
			// Get string until end of line
			SCopyUntil(pos, strResult, "\r\n", ResStrMaxLen);
	// Compile line feeds ("\n" -> 0D0A)
	pos = strResult;
	while ((pos = SSearch(pos, "\\n")))
		{ ((char*)pos)[-2] = 0x0D; ((char*)pos)[-1] = 0x0A; }
#ifdef _DEBUG
#ifdef _MSC_VER
	if (SEqual2(strResult, "[Undefined:"))
		if (!SEqual(id, "IDS_LANG_CHARSET"))
			{
			/* __asm int 3 */
			}
#endif
#endif
	// Return string
	return strResult;
}
void C4MusicSystem::LoadMoreMusic()
{
	StdStrBuf MoreMusicFile;
	// load MoreMusic.txt
	if (!MoreMusicFile.LoadFromFile(Config.AtUserDataPath(C4CFN_MoreMusic))) return;
	// read contents
	char *pPos = MoreMusicFile.getMData();
	while (pPos && *pPos)
	{
		// get line
		char szLine[1024 + 1];
		SCopyUntil(pPos, szLine, '\n', 1024);
		pPos = strchr(pPos, '\n'); if (pPos) pPos++;
		// remove leading whitespace
		char *pLine = szLine;
		while (*pLine == ' ' || *pLine == '\t' || *pLine == '\r') pLine++;
		// and whitespace at end
		char *p = pLine + strlen(pLine) - 1;
		while (*p == ' ' || *p == '\t' || *p == '\r') { *p = 0; --p; }
		// comment?
		if (*pLine == '#')
		{
			// might be a "directive"
			if (SEqual(pLine, "#clear"))
				ClearSongs();
			continue;
		}
		// try to load file(s)
		LoadDir(pLine);
	}
}
bool C4GameSave::SaveDesc(C4Group &hToGroup)
{
	// Unfortunately, there's no way to prealloc the buffer in an appropriate size
	StdStrBuf sBuffer;

	// Header
	sBuffer.AppendFormat("{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1031{\\fonttbl {\\f0\\fnil\\fcharset%d Times New Roman;}}", 0 /*FIXME: a number for UTF-8 here*/);
	sBuffer.Append(LineFeed);

	// Scenario title
	sBuffer.AppendFormat("\\uc1\\pard\\ulnone\\b\\f0\\fs20 %s\\par",Game.ScenarioTitle.getData());
	sBuffer.Append(LineFeed "\\b0\\fs16\\par" LineFeed);

	// OK; each specializations has its own desc format
	WriteDesc(sBuffer);

	// End of file
	sBuffer.Append(LineFeed "}" LineFeed);

	// Generate Filename
	StdStrBuf sFilename; char szLang[3];
	SCopyUntil(Config.General.Language, szLang, ',', 2);
	sFilename.Format(C4CFN_ScenarioDesc,szLang);

	// Save to file
	return !!hToGroup.Add(sFilename.getData(),sBuffer,false,true);
}
void C4GraphicsOverlay::Read(const char **ppInput)
{
	// deprecated
	assert(false && "C4GraphicsOverlay::Read: deprecated");
#if 0
	const char *szReadFrom = *ppInput;
	// defaults
	eMode = MODE_None; pSourceGfx = NULL; *Action=0; dwBlitMode = 0; iPhase = 0; iID=0;
	// read ID
	SCopyUntil(szReadFrom, OSTR, ',', C4MaxName);
	szReadFrom += strlen(OSTR); if (*szReadFrom) ++szReadFrom;
	sscanf(OSTR, "%i", &iID);
	// read C4ID::Gfxname
	int32_t iLineLength = SLen(szReadFrom);
	// not C4ID::Name?
	if (iLineLength < 6 || szReadFrom[4]!=':' || szReadFrom[5]!=':')
	{
		DebugLog("C4Compiler error: Malformed graphics overlay definition!");
		return;
	}
	// get ID
	char id[5]; SCopy(szReadFrom, id, 4); szReadFrom += 6;
	C4Def *pSrcDef = ::Definitions.ID2Def(C4Id(id)); // defaults to NULL for unloaded def
	if (pSrcDef)
	{
		char GfxName[C4MaxName+1];
		SCopyUntil(szReadFrom, GfxName, ',', C4MaxName);
		szReadFrom += strlen(GfxName); if (*szReadFrom) ++szReadFrom;
		// get graphics - "C4ID::" leads to *szLine == NULL, and thus the default graphic of pSrcDef!
		pSourceGfx = pSrcDef->Graphics.Get(GfxName);
	}
	// read mode
	DWORD dwRead;
	SCopyUntil(szReadFrom, OSTR, ',', C4MaxName);
	szReadFrom += strlen(OSTR); if (*szReadFrom) ++szReadFrom;
	sscanf(OSTR, "%i", &dwRead); eMode = (Mode) dwRead;
	// read action
	SCopyUntil(szReadFrom, Action, ',', C4MaxName);
	szReadFrom += strlen(Action); if (*szReadFrom) ++szReadFrom;
	// read blit mode
	SCopyUntil(szReadFrom, OSTR, ',', C4MaxName);
	szReadFrom += strlen(OSTR); if (*szReadFrom) ++szReadFrom;
	sscanf(OSTR, "%i", &dwBlitMode);
	// read phase
	SCopyUntil(szReadFrom, OSTR, ',', C4MaxName);
	szReadFrom += strlen(OSTR); if (*szReadFrom) ++szReadFrom;
	sscanf(OSTR, "%i", &iPhase);
	// read transform
	if (*szReadFrom) ++szReadFrom; // '('
	int32_t iScanCnt = sscanf(szReadFrom, "%f,%f,%f,%f,%f,%f,%d",
	                          &Transform.mat[0], &Transform.mat[1], &Transform.mat[2],
	                          &Transform.mat[3], &Transform.mat[4], &Transform.mat[5], &Transform.FlipDir);
	if (iScanCnt != 7) { DebugLog("C4Compiler: malformed C4CV_Transform"); }
	iScanCnt = SCharPos(')', szReadFrom); if (iScanCnt>=0) szReadFrom += iScanCnt+1;
	// assign ptr immediately after read overlay
	*ppInput = szReadFrom;
	// update used facet according to read data
	UpdateFacet();
#endif
}
Exemple #5
0
bool C4GameSave::SaveDesc(C4Group &hToGroup)
{
	// Unfortunately, there's no way to prealloc the buffer in an appropriate size
	StdStrBuf sBuffer;

	// Scenario title
	sBuffer.Append(Game.ScenarioTitle.getData());
	sBuffer.Append("\n\n");

	// OK; each specializations has its own desc format
	WriteDesc(sBuffer);

	// Generate Filename
	StdStrBuf sFilename; char szLang[3];
	SCopyUntil(Config.General.Language, szLang, ',', 2);
	sFilename.Format(C4CFN_ScenarioDesc,szLang);

	// Save to file
	return !!hToGroup.Add(sFilename.getData(),sBuffer,false,true);
}
Exemple #6
0
bool C4MessageInput::ProcessCommand(const char *szCommand) {
  C4GameLobby::MainDlg *pLobby = Game.Network.GetLobby();
  // command
  char szCmdName[C4MaxName + 1];
  SCopyUntil(szCommand + 1, szCmdName, ' ', C4MaxName);
  // parameter
  const char *pCmdPar = SSearch(szCommand, " ");
  if (!pCmdPar) pCmdPar = "";

  // dev-scripts
  if (SEqual(szCmdName, "help")) {
    LogF(LoadResStr("IDS_TEXT_COMMANDSAVAILABLEDURINGGA"));
    LogF("/private [player] [message] - %s",
         LoadResStr("IDS_MSG_SENDAPRIVATEMESSAGETOTHES"));
    LogF("/team [message] - %s",
         LoadResStr("IDS_MSG_SENDAPRIVATEMESSAGETOYOUR"));
    LogF("/me [action] - %s", LoadResStr("IDS_TEXT_PERFORMANACTIONINYOURNAME"));
    LogF("/sound [sound] - %s",
         LoadResStr("IDS_TEXT_PLAYASOUNDFROMTHEGLOBALSO"));
    LogF("/kick [client] - %s", LoadResStr("IDS_TEXT_KICKTHESPECIFIEDCLIENT"));
    LogF("/observer [client] - %s",
         LoadResStr("IDS_TEXT_SETTHESPECIFIEDCLIENTTOOB"));
    LogF("/fast [x] - %s", LoadResStr("IDS_TEXT_SETTOFASTMODESKIPPINGXFRA"));
    LogF("/slow - %s", LoadResStr("IDS_TEXT_SETTONORMALSPEEDMODE"));
    LogF("/chart - %s", LoadResStr("IDS_TEXT_DISPLAYNETWORKSTATISTICS"));
    LogF("/nodebug - %s", LoadResStr("IDS_TEXT_PREVENTDEBUGMODEINTHISROU"));
    LogF("/set comment [comment] - %s",
         LoadResStr("IDS_TEXT_SETANEWNETWORKCOMMENT"));
    LogF("/set password [password] - %s",
         LoadResStr("IDS_TEXT_SETANEWNETWORKPASSWORD"));
    LogF("/set faircrew [on/off] - %s",
         LoadResStr("IDS_TEXT_ENABLEORDISABLEFAIRCREW"));
    LogF("/set maxplayer [4] - %s",
         LoadResStr("IDS_TEXT_SETANEWMAXIMUMNUMBEROFPLA"));
    LogF("/script [script] - %s", LoadResStr("IDS_TEXT_EXECUTEASCRIPTCOMMAND"));
    LogF("/clear - %s", LoadResStr("IDS_MSG_CLEARTHEMESSAGEBOARD"));
    return TRUE;
  }
  // dev-scripts
  if (SEqual(szCmdName, "script")) {
    if (!Game.IsRunning) return FALSE;
    if (!Game.DebugMode) return FALSE;
    if (!Game.Network.isEnabled() &&
        !SEqual(Game.ScenarioFile.GetMaker(), Config.General.Name) &&
        Game.ScenarioFile.GetStatus() != GRPF_Folder)
      return FALSE;
    if (Game.Network.isEnabled() && !Game.Network.isHost()) return FALSE;

    Game.Control.DoInput(
        CID_Script,
        new C4ControlScript(pCmdPar, C4ControlScript::SCOPE_Console, false),
        CDT_Decide);
    return TRUE;
  }
  // set runtimte properties
  if (SEqual(szCmdName, "set")) {
    if (SEqual2(pCmdPar, "maxplayer ")) {
      if (Game.Control.isCtrlHost()) {
        if (atoi(pCmdPar + 10) == 0 && !SEqual(pCmdPar + 10, "0")) {
          Log("Syntax: /set maxplayer count");
          return FALSE;
        }
        Game.Control.DoInput(
            CID_Set, new C4ControlSet(C4CVT_MaxPlayer, atoi(pCmdPar + 10)),
            CDT_Decide);
        return TRUE;
      }
    }
    if (SEqual2(pCmdPar, "comment ") || SEqual(pCmdPar, "comment")) {
      if (!Game.Network.isEnabled() || !Game.Network.isHost()) return FALSE;
      // Set in configuration, update reference
      Config.Network.Comment.CopyValidated(pCmdPar[7] ? (pCmdPar + 8) : "");
      Game.Network.InvalidateReference();
      Log(LoadResStr("IDS_NET_COMMENTCHANGED"));
      return TRUE;
    }
    if (SEqual2(pCmdPar, "password ") || SEqual(pCmdPar, "password")) {
      if (!Game.Network.isEnabled() || !Game.Network.isHost()) return FALSE;
      Game.Network.SetPassword(pCmdPar[8] ? (pCmdPar + 9) : NULL);
      if (pLobby) pLobby->UpdatePassword();
      return TRUE;
    }
    if (SEqual2(pCmdPar, "faircrew ")) {
      if (!Game.Control.isCtrlHost() || Game.Parameters.isLeague())
        return FALSE;
      C4ControlSet *pSet = NULL;
      if (SEqual(pCmdPar + 9, "on"))
        pSet =
            new C4ControlSet(C4CVT_FairCrew, Config.General.FairCrewStrength);
      else if (SEqual(pCmdPar + 9, "off"))
        pSet = new C4ControlSet(C4CVT_FairCrew, -1);
      else if (isdigit((unsigned char)pCmdPar[9]))
        pSet = new C4ControlSet(C4CVT_FairCrew, atoi(pCmdPar + 9));
      else
        return FALSE;
      Game.Control.DoInput(CID_Set, pSet, CDT_Decide);
      return TRUE;
    }
    // unknown property
    return FALSE;
  }
  // get szen from network folder - not in lobby; use res tab there
  if (SEqual(szCmdName, "netgetscen")) {
    if (Game.Network.isEnabled() && !Game.Network.isHost() && !pLobby) {
      const C4Network2ResCore *pResCoreScen =
          Game.Parameters.Scenario.getResCore();
      if (pResCoreScen) {
        C4Network2Res::Ref pScenario =
            Game.Network.ResList.getRefRes(pResCoreScen->getID());
        if (pScenario)
          if (C4Group_CopyItem(
                  pScenario->getFile(),
                  Config.AtExePath(GetFilename(Game.ScenarioFilename)))) {
            LogF(LoadResStr("IDS_MSG_CMD_NETGETSCEN_SAVED"),
                 Config.AtExePath(GetFilename(Game.ScenarioFilename)));
            return TRUE;
          }
      }
    }
    return FALSE;
  }
  // clear message board
  if (SEqual(szCmdName, "clear")) {
    // lobby
    if (pLobby) {
      pLobby->ClearLog();
    }
    // fullscreen
    else if (Game.GraphicsSystem.MessageBoard.Active)
      Game.GraphicsSystem.MessageBoard.ClearLog();
    else {
      // EM mode
      Console.ClearLog();
    }
    return TRUE;
  }
  // kick client
  if (SEqual(szCmdName, "kick")) {
    if (Game.Network.isEnabled() && Game.Network.isHost()) {
      // find client
      C4Client *pClient = Game.Clients.getClientByName(pCmdPar);
      if (!pClient) {
        LogF(LoadResStr("IDS_MSG_CMD_NOCLIENT"), pCmdPar);
        return FALSE;
      }
      // league: Kick needs voting
      if (Game.Parameters.isLeague() &&
          Game.Players.GetAtClient(pClient->getID()))
        Game.Network.Vote(VT_Kick, true, pClient->getID());
      else
        // add control
        Game.Clients.CtrlRemove(pClient,
                                LoadResStr("IDS_MSG_KICKFROMMSGBOARD"));
    }
    return TRUE;
  }
  // set fast mode
  if (SEqual(szCmdName, "fast")) {
    if (!Game.IsRunning) return FALSE;
    if (Game.Parameters.isLeague()) {
      Log(LoadResStr("IDS_LOG_COMMANDNOTALLOWEDINLEAGUE"));
      return FALSE;
    }
    int32_t iFS;
    if ((iFS = atoi(pCmdPar)) == 0) return FALSE;
    // set frameskip and fullspeed flag
    Game.FrameSkip = BoundBy<int32_t>(iFS, 1, 500);
    Game.FullSpeed = TRUE;
    // start calculation immediatly
    Application.NextTick(false);
    return TRUE;
  }
  // reset fast mode
  if (SEqual(szCmdName, "slow")) {
    if (!Game.IsRunning) return FALSE;
    Game.FullSpeed = FALSE;
    Game.FrameSkip = 1;
    return TRUE;
  }

  if (SEqual(szCmdName, "nodebug")) {
    if (!Game.IsRunning) return FALSE;
    Game.Control.DoInput(CID_Set, new C4ControlSet(C4CVT_AllowDebug, false),
                         CDT_Decide);
    return TRUE;
  }

  if (SEqual(szCmdName, "msgboard")) {
    if (!Game.IsRunning) return FALSE;
    // get line cnt
    int32_t iLineCnt = BoundBy(atoi(pCmdPar), 0, 20);
    if (iLineCnt == 0)
      Game.GraphicsSystem.MessageBoard.ChangeMode(2);
    else if (iLineCnt == 1)
      Game.GraphicsSystem.MessageBoard.ChangeMode(0);
    else {
      Game.GraphicsSystem.MessageBoard.iLines = iLineCnt;
      Game.GraphicsSystem.MessageBoard.ChangeMode(1);
    }
    return TRUE;
  }

  // kick/activate/deactivate/observer
  if (SEqual(szCmdName, "activate") || SEqual(szCmdName, "deactivate") ||
      SEqual(szCmdName, "observer")) {
    if (!Game.Network.isEnabled() || !Game.Network.isHost()) {
      Log(LoadResStr("IDS_MSG_CMD_HOSTONLY"));
      return FALSE;
    }
    // search for client
    C4Client *pClient = Game.Clients.getClientByName(pCmdPar);
    if (!pClient) {
      LogF(LoadResStr("IDS_MSG_CMD_NOCLIENT"), pCmdPar);
      return FALSE;
    }
    // what to do?
    C4ControlClientUpdate *pCtrl = NULL;
    if (szCmdName[0] == 'a')  // activate
      pCtrl = new C4ControlClientUpdate(pClient->getID(), CUT_Activate, true);
    else if (szCmdName[0] == 'd' && !Game.Parameters.isLeague())  // deactivate
      pCtrl = new C4ControlClientUpdate(pClient->getID(), CUT_Activate, false);
    else if (szCmdName[0] == 'o' && !Game.Parameters.isLeague())  // observer
      pCtrl = new C4ControlClientUpdate(pClient->getID(), CUT_SetObserver);
    // perform it
    if (pCtrl)
      Game.Control.DoInput(CID_ClientUpdate, pCtrl, CDT_Sync);
    else
      Log(LoadResStr("IDS_LOG_COMMANDNOTALLOWEDINLEAGUE"));
    return TRUE;
  }

  // control mode
  if (SEqual(szCmdName, "centralctrl") || SEqual(szCmdName, "decentralctrl") ||
      SEqual(szCmdName, "asyncctrl")) {
    if (!Game.Network.isEnabled() || !Game.Network.isHost()) {
      Log(LoadResStr("IDS_MSG_CMD_HOSTONLY"));
      return FALSE;
    }
    if (Game.Parameters.isLeague() && *szCmdName == 'a') {
      Log(LoadResStr("IDS_LOG_COMMANDNOTALLOWEDINLEAGUE"));
      return FALSE;
    }
    Game.Network.SetCtrlMode(
        *szCmdName == 'c' ? CNM_Central : *szCmdName == 'd' ? CNM_Decentral
                                                            : CNM_Async);
    return TRUE;
  }

  // show chart
  if (Game.IsRunning)
    if (SEqual(szCmdName, "chart")) return Game.ToggleChart();

  // custom command
  C4MessageBoardCommand *pCmd;
  if (Game.IsRunning)
    if (pCmd = GetCommand(szCmdName)) {
      StdStrBuf Script, CmdScript;
      // replace %player% by calling player number
      if (SSearch(pCmd->Script, "%player%")) {
        int32_t iLocalPlr = NO_OWNER;
        C4Player *pLocalPlr = Game.Players.GetLocalByIndex(0);
        if (pLocalPlr) iLocalPlr = pLocalPlr->Number;
        StdStrBuf sLocalPlr;
        sLocalPlr.Format("%d", iLocalPlr);
        CmdScript.Copy(pCmd->Script);
        CmdScript.Replace("%player%", sLocalPlr.getData());
      } else {
        CmdScript.Ref(pCmd->Script);
      }
      // insert parameters
      if (SSearch(CmdScript.getData(), "%d")) {
        // make sure it's a number by converting
        Script.Format(CmdScript.getData(), (int)atoi(pCmdPar));
      } else if (SSearch(CmdScript.getData(), "%s")) {
        // Unrestricted parameters?
        // That's kind of a security risk as it will allow anyone to execute
        // code
        switch (pCmd->eRestriction) {
          case C4MessageBoardCommand::C4MSGCMDR_Escaped: {
            // escape strings
            StdStrBuf Par;
            Par.Copy(pCmdPar);
            Par.EscapeString();
            // compose script
            Script.Format(CmdScript.getData(), Par.getData());
          } break;

          case C4MessageBoardCommand::C4MSGCMDR_Plain:
            // unescaped
            Script.Format(CmdScript.getData(), pCmdPar);
            break;

          case C4MessageBoardCommand::C4MSGCMDR_Identifier: {
            // only allow identifier-characters
            StdStrBuf Par;
            while (IsIdentifier(*pCmdPar) || isspace((unsigned char)*pCmdPar))
              Par.AppendChar(*pCmdPar++);
            // compose script
            Script.Format(CmdScript.getData(), Par.getData());
          } break;
        }
      } else
        Script = CmdScript.getData();
      // add script
      Game.Control.DoInput(CID_Script, new C4ControlScript(Script.getData()),
                           CDT_Decide);
      // ok
      return TRUE;
    }

  // unknown command
  StdStrBuf sErr;
  sErr.Format(LoadResStr("IDS_ERR_UNKNOWNCMD"), szCmdName);
  if (pLobby)
    pLobby->OnError(sErr.getData());
  else
    Log(sErr.getData());
  return FALSE;
}
Exemple #7
0
bool C4MessageInput::ProcessInput(const char *szText) {
  // helper variables
  C4ControlMessageType eMsgType;
  const char *szMsg = NULL;
  int32_t iToPlayer = -1;

  // Starts with '^', "team:" or "/team ": Team message
  if (szText[0] == '^' || SEqual2NoCase(szText, "team:") ||
      SEqual2NoCase(szText, "/team ")) {
    if (!Game.Teams.IsTeamVisible()) {
      // team not known; can't send!
      Log(LoadResStr("IDS_MSG_CANTSENDTEAMMESSAGETEAMSN"));
      return FALSE;
    } else {
      eMsgType = C4CMT_Team;
      szMsg = szText[0] == '^' ? szText + 1 : szText[0] == '/' ? szText + 6
                                                               : szText + 5;
    }
  }
  // Starts with "/private ": Private message (running game only)
  else if (Game.IsRunning && SEqual2NoCase(szText, "/private ")) {
    // get target name
    char szTargetPlr[C4MaxName + 1];
    SCopyUntil(szText + 9, szTargetPlr, ' ', C4MaxName);
    // search player
    C4Player *pToPlr = Game.Players.GetByName(szTargetPlr);
    if (!pToPlr) return FALSE;
    // set
    eMsgType = C4CMT_Private;
    iToPlayer = pToPlr->Number;
    szMsg = szText + 10 + SLen(szTargetPlr);
    if (szMsg > szText + SLen(szText)) return FALSE;
  }
  // Starts with "/me ": Me-Message
  else if (SEqual2NoCase(szText, "/me ")) {
    eMsgType = C4CMT_Me;
    szMsg = szText + 4;
  }
  // Starts with "/sound ": Sound-Message
  else if (SEqual2NoCase(szText, "/sound ")) {
    eMsgType = C4CMT_Sound;
    szMsg = szText + 7;
  }
  // Starts with "/alert": Taskbar flash (message optional)
  else if (SEqual2NoCase(szText, "/alert ") || SEqualNoCase(szText, "/alert")) {
    eMsgType = C4CMT_Alert;
    szMsg = szText + 6;
    if (*szMsg) ++szMsg;
  }
  // Starts with '"': Let the clonk say it
  else if (Game.IsRunning && szText[0] == '"') {
    eMsgType = C4CMT_Say;
    // Append '"', if neccessary
    SCopy(szText, OSTR, 400);
    char *pEnd = OSTR + SLen(OSTR) - 1;
    if (*pEnd != '"') {
      *++pEnd = '"';
      *++pEnd = 0;
    }
    szMsg = OSTR;
  }
  // Starts with '/': Command
  else if (szText[0] == '/')
    return ProcessCommand(szText);
  // Regular message
  else {
    eMsgType = C4CMT_Normal;
    szMsg = szText;
  }

  // message?
  if (szMsg) {
    char szMessage[C4MaxMessage + 1];
    // go over whitespaces, check empty message
    while (IsWhiteSpace(*szMsg)) szMsg++;
    if (!*szMsg) {
      if (eMsgType != C4CMT_Alert) return TRUE;
      *szMessage = '\0';
    } else {
      // trim right
      const char *szEnd = szMsg + SLen(szMsg) - 1;
      while (IsWhiteSpace(*szEnd) && szEnd >= szMsg) szEnd--;
      // Say: Strip quotation marks in cinematic film mode
      if (Game.C4S.Head.Film == C4SFilm_Cinematic) {
        if (eMsgType == C4CMT_Say) {
          ++szMsg;
          szEnd--;
        }
      }
      // get message
      SCopy(szMsg, szMessage,
            Min<unsigned long>(C4MaxMessage, szEnd - szMsg + 1));
    }
    // get sending player (if any)
    C4Player *pPlr = Game.IsRunning ? Game.Players.GetLocalByIndex(0) : NULL;
    // send
    Game.Control.DoInput(
        CID_Message, new C4ControlMessage(eMsgType, szMessage,
                                          pPlr ? pPlr->Number : -1, iToPlayer),
        CDT_Private);
  }

  return TRUE;
}
Exemple #8
0
bool C4Application::DoInit() {
  assert(AppState == C4AS_None);
  // Config overwrite by parameter
  StdStrBuf sConfigFilename;
  char szParameter[_MAX_PATH + 1];
  for (int32_t iPar = 0;
       SGetParameter(GetCommandLine(), iPar, szParameter, _MAX_PATH); iPar++)
    if (SEqual2NoCase(szParameter, "/config:"))
      sConfigFilename.Copy(szParameter + 8);
  // Config check
  Config.Init();
  Config.Load(true, sConfigFilename.getData());
  Config.Save();
  // sometimes, the configuration can become corrupted due to loading errors or
  // w/e
  // check this and reset defaults if necessary
  if (Config.IsCorrupted()) {
    if (sConfigFilename) {
      // custom config corrupted: Fail
      Log("Warning: Custom configuration corrupted - program abort!\n");
      return false;
    } else {
      // default config corrupted: Restore default
      Log("Warning: Configuration corrupted - restoring default!\n");
      Config.Default();
      Config.Save();
      Config.Load();
    }
  }
  MMTimer = Config.General.MMTimer != 0;
  // Init C4Group
  C4Group_SetMaker(Config.General.Name);
  C4Group_SetProcessCallback(&ProcessCallback);
  C4Group_SetTempPath(Config.General.TempPath);
  C4Group_SetSortList(C4CFN_FLS);

  // Open log
  if (!OpenLog()) return false;

  // init system group
  if (!SystemGroup.Open(C4CFN_System)) {
    // Error opening system group - no LogFatal, because it needs language
    // table.
    // This will *not* use the FatalErrors stack, but this will cause the game
    // to instantly halt, anyway.
    Log("Error opening system group file (System.c4g)!");
    return false;
  }

  // Language override by parameter
  const char *pLanguage;
  if (pLanguage = SSearchNoCase(GetCommandLine(), "/Language:"))
    SCopyUntil(pLanguage, Config.General.LanguageEx, ' ', CFG_MaxString);

  // Init external language packs
  Languages.Init();
  // Load language string table
  if (!Languages.LoadLanguage(Config.General.LanguageEx))
    // No language table was loaded - bad luck...
    if (!IsResStrTableLoaded())
      Log("WARNING: No language string table loaded!");

  // Set unregistered user name
  C4Group_SetMaker(LoadResStr("IDS_PRC_UNREGUSER"));

  // Parse command line
  Game.ParseCommandLine(GetCommandLine());

#ifdef WIN32
  // Windows: handle incoming updates directly, even before starting up the gui
  //          because updates will be applied in the console anyway.
  if (Application.IncomingUpdate)
    if (C4UpdateDlg::ApplyUpdate(Application.IncomingUpdate.getData(), false,
                                 NULL))
      return true;
#endif

  // activate
  Active = TRUE;

  // Init carrier window
  if (isFullScreen) {
    if (!(pWindow = FullScreen.Init(this))) {
      Clear();
      return false;
    }
  } else {
    if (!(pWindow = Console.Init(this))) {
      Clear();
      return false;
    }
  }

  // init timers (needs window)
  if (!InitTimer()) {
    LogFatal(LoadResStr("IDS_ERR_TIMER"));
    Clear();
    return false;
  }

  // Engine header message
  Log(C4ENGINEINFOLONG);
  LogF("Version: %s %s", C4VERSION, C4_OS);

#if defined(USE_DIRECTX) && defined(_WIN32)
  // DDraw emulation warning
  DWORD DDrawEmulationState;
  if (GetRegistryDWord(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\DirectDraw",
                       "EmulationOnly", &DDrawEmulationState))
    if (DDrawEmulationState)
      Log("WARNING: DDraw Software emulation is activated!");
#endif
  // Initialize D3D/OpenGL
  DDraw = DDrawInit(this, isFullScreen, FALSE, Config.Graphics.BitDepth,
                    Config.Graphics.Engine, Config.Graphics.Monitor);
  if (!DDraw) {
    LogFatal(LoadResStr("IDS_ERR_DDRAW"));
    Clear();
    return false;
  }

#if defined(_WIN32) && !defined(USE_CONSOLE)
  // Register clonk file classes - notice: under Vista this will only work if we
  // have administrator rights
  char szModule[_MAX_PATH + 1];
  GetModuleFileName(NULL, szModule, _MAX_PATH);
  SetC4FileClasses(szModule);
#endif

  // Initialize gamepad
  if (!pGamePadControl && Config.General.GamepadEnabled)
    pGamePadControl = new C4GamePadControl();

  AppState = C4AS_PreInit;

  return true;
}
Exemple #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;
	}