C4Network2ClientListBox::ClientListItem::ClientListItem(class C4Network2ClientListBox *pForDlg, int iClientID) // ctor : ListItem(pForDlg, iClientID), pStatusIcon(nullptr), pName(nullptr), pPing(nullptr), pActivateBtn(nullptr), pKickBtn(nullptr), last_sound_time(0) { // get associated client const C4Client *pClient = GetClient(); // get size int iIconSize = ::GraphicsResource.TextFont.GetLineHeight(); if (pForDlg->IsStartup()) iIconSize *= 2; int iWidth = pForDlg->GetItemWidth(); int iVerticalIndent = 2; SetBounds(C4Rect(0, 0, iWidth, iIconSize+2*iVerticalIndent)); C4GUI::ComponentAligner ca(GetContainedClientRect(), 0,iVerticalIndent); // create subcomponents bool fIsHost = pClient && pClient->isHost(); pStatusIcon = new C4GUI::Icon(ca.GetFromLeft(iIconSize), fIsHost ? C4GUI::Ico_Host : C4GUI::Ico_Client); StdStrBuf sNameLabel; if (pClient) { if (pForDlg->IsStartup()) sNameLabel.Ref(pClient->getName()); else sNameLabel.Format("%s:%s", pClient->getName(), pClient->getNick()); } else { sNameLabel.Ref("???"); } pName = new C4GUI::Label(sNameLabel.getData(), iIconSize + IconLabelSpacing,iVerticalIndent, ALeft); int iPingRightPos = GetBounds().Wdt - IconLabelSpacing; if (::Network.isHost()) iPingRightPos -= 48; if (::Network.isHost() && pClient && !pClient->isHost()) { // activate/deactivate and kick btns for clients at host if (!pForDlg->IsStartup()) { pActivateBtn = new C4GUI::CallbackButtonEx<C4Network2ClientListBox::ClientListItem, C4GUI::IconButton>(C4GUI::Ico_Active, GetToprightCornerRect(std::max(iIconSize, 16),std::max(iIconSize, 16),2,1,1), 0, this, &ClientListItem::OnButtonActivate); fShownActive = true; } pKickBtn = new C4GUI::CallbackButtonEx<C4Network2ClientListBox::ClientListItem, C4GUI::IconButton>(C4GUI::Ico_Kick, GetToprightCornerRect(std::max(iIconSize, 16),std::max(iIconSize, 16),2,1,0), 0, this, &ClientListItem::OnButtonKick); pKickBtn->SetToolTip(LoadResStrNoAmp("IDS_NET_KICKCLIENT")); } if (!pForDlg->IsStartup()) if (pClient && !pClient->isLocal()) { // wait time pPing = new C4GUI::Label("???", iPingRightPos, iVerticalIndent, ARight); pPing->SetToolTip(LoadResStr("IDS_DESC_CONTROLWAITTIME")); } // add components AddElement(pStatusIcon); AddElement(pName); if (pPing) AddElement(pPing); if (pActivateBtn) AddElement(pActivateBtn); if (pKickBtn) AddElement(pKickBtn); // add to listbox (will eventually get moved) pForDlg->AddElement(this); // first-time update Update(); }
void C4DownloadDlg::OnIdle() { // continue query process if (!HTTPClient.Execute()) { // query aborted Close(false); return; } if (!HTTPClient.isBusy()) { // download done or aborted Close(HTTPClient.isSuccess()); return; } StdStrBuf sStatus; int32_t iProgress = -1; StdStrBuf sSize(""); // download in progress: Update status if (!HTTPClient.isConnected()) { // still connecting sStatus.Ref(LoadResStr("IDS_DL_STATUSCONNECTING")); } else { // header received? size_t iSize = HTTPClient.getTotalSize(); if (!iSize) { // file size unknown: No header received. sStatus.Ref(LoadResStr("IDS_PRC_CONNECTED")); } else { // file size known: Download in progress sStatus.Ref(LoadResStr("IDS_CTL_DL_PROGRESS")); if (iSize <= 1024) sSize.Format(" (%ld Bytes)", (long)iSize); else if (iSize <= 1024*1024) sSize.Format(" (%ld KB)", (long)(iSize/1024)); else sSize.Format(" (%ld MB)", (long)(iSize/1024/1024)); iProgress = int64_t(100) * HTTPClient.getDownloadedSize() / iSize; } } const char *szStatusString = LoadResStr("IDS_PRC_DOWNLOADINGFILE"); SetStatus(FormatString(szStatusString, GetFilename(HTTPClient.getRequest())).getData(), iProgress ); }
// Helper for IRC command parameter parsing StdStrBuf ircExtractPar(const char **ppPar) { // No parameter left? if(!ppPar || !*ppPar || !**ppPar) return StdStrBuf(""); // Last parameter? StdStrBuf Result; if(**ppPar == ':') { // Reference everything after the double-colon Result.Ref(*ppPar + 1); *ppPar = NULL; } else { // Copy until next space (or end of string) Result.CopyUntil(*ppPar, ' '); // Go over parameters *ppPar += Result.getLength(); if(**ppPar == ' ') (*ppPar)++; else *ppPar = NULL; } // Done return Result; }
void C4ValueMapData::CompileFunc(StdCompiler *pComp, C4ValueNumbers * numbers) { bool deserializing = pComp->isDeserializer(); C4ValueMapNames *pOldNames = pNames; if (deserializing) Reset(); // Compile item count int32_t iValueCnt; if (!deserializing) iValueCnt = pNames ? pNames->iSize : 0; pComp->Value(mkDefaultAdapt(iValueCnt, 0)); // nuthing 2do for no items if (!iValueCnt) return; // Separator (';') pComp->Separator(StdCompiler::SEP_SEP2); // Data char **ppNames = !deserializing ? pNames->pNames : new char * [iValueCnt]; if (deserializing) for (int32_t i = 0; i < iValueCnt; i++) ppNames[i] = nullptr; C4Value *pValues = !deserializing ? pData : new C4Value [iValueCnt]; // Compile try { for (int32_t i = 0; i < iValueCnt; i++) { // Separate if (i) pComp->Separator(); // Name StdStrBuf Name; if (!deserializing) Name.Ref(ppNames[i]); pComp->Value(mkParAdapt(Name, StdCompiler::RCT_Idtf)); if (deserializing) ppNames[i] = Name.GrabPointer(); // Separator ('=') pComp->Separator(StdCompiler::SEP_SET); // Value pComp->Value(mkParAdapt(pValues[i], numbers)); } } catch (...) { // make sure no mem is leaked on compiler error in name list if (deserializing) { for (int32_t i = 0; i < iValueCnt; i++) if (ppNames[i]) free(ppNames[i]); delete [] ppNames; delete [] pValues; } throw; } // Set if (deserializing) { // Set CreateTempNameList(); pNames->SetNameArray(const_cast<const char **>(ppNames), iValueCnt); for (int32_t i = 0; i < iValueCnt; i++) free(ppNames[i]); delete [] ppNames; delete [] pData; pData = pValues; // Assign old name list if (pOldNames) SetNameList(pOldNames); } }
C4FileSelDlg::DefaultListItem::DefaultListItem(const char *szFilename, bool fTruncateExtension, bool fCheckbox, bool fGrayed, C4GUI::Icons eIcon) : C4FileSelDlg::ListItem(szFilename), pLbl(NULL), pCheck(NULL), pKeyCheck(NULL), fGrayed(fGrayed) { StdStrBuf sLabel; if (szFilename) sLabel.Ref(::GetFilename(szFilename)); else sLabel.Ref(LoadResStr("IDS_CTL_NONE")); if (szFilename && fTruncateExtension) { sLabel.Copy(); char *szFilename = sLabel.GrabPointer(); RemoveExtension(szFilename); sLabel.Take(szFilename); } rcBounds.Hgt = C4GUI::GetRes()->TextFont.GetLineHeight(); UpdateSize(); C4GUI::ComponentAligner caMain(GetContainedClientRect(), 0, 0); int32_t iHeight = caMain.GetInnerHeight(); if (fCheckbox) { pCheck = new C4GUI::CheckBox(caMain.GetFromLeft(iHeight), NULL, false); if (fGrayed) pCheck->SetEnabled(false); AddElement(pCheck); pKeyCheck = new C4KeyBinding( C4KeyCodeEx(K_SPACE), "FileSelToggleFileActive", KEYSCOPE_Gui, new C4GUI::ControlKeyCB<ListItem>(*this, &ListItem::UserToggleCheck), C4CustomKey::PRIO_Ctrl); } C4GUI::Icon *pIco = new C4GUI::Icon(caMain.GetFromLeft(iHeight), eIcon); AddElement(pIco); pLbl = new C4GUI::Label( sLabel.getData(), caMain.GetAll(), ALeft, fGrayed ? C4GUI_CheckboxDisabledFontClr : C4GUI_CheckboxFontClr); AddElement(pLbl); }
bool C4Network2IRCClient::Send(const char *szCommand, const char *szParameters) { if(!fConnected) { SetError("not connected"); return false; } // Create message StdStrBuf Msg; if(szParameters) Msg.Format("%s %s", szCommand, szParameters); else Msg.Ref(szCommand); // Send return C4NetIOTCP::Send(C4NetIOPacket(Msg.getData(), Msg.getLength(), false, PeerAddr)); }
StdStrBuf GetDbgRecPktData(C4RecordChunkType eType, const StdBuf &RawData) { StdStrBuf r; switch (eType) { case RCT_AulFunc: r.Ref(reinterpret_cast<const char *>(RawData.getData()), RawData.getSize() - 1); break; default: for (int i = 0; i < RawData.getSize(); ++i) r.AppendFormat("%02x ", (uint32_t)((uint8_t *)RawData.getData())[i]); break; } return r; }
bool ShaderLog(const char *szMessage) { // security if (!C4ShaderLogFile) return false; if (!Application.AssertMainThread()) return false; if (!szMessage) return false; // output into shader log file #ifdef HAVE_ICONV StdStrBuf Line = Languages.IconvSystem(szMessage); #else StdStrBuf Line; Line.Ref(szMessage); #endif fputs(Line.getData(), C4ShaderLogFile); fputs("\n", C4ShaderLogFile); fflush(C4ShaderLogFile); return true; }
StdStrBuf C4RankSystem::GetRankName(int iRank, bool fReturnLastIfOver) { if (iRank<0) return StdStrBuf(); // if a new-style ranklist is loaded, seek there if (pszRankNames) { if (iRankNum<=0) return StdStrBuf(); // overflow check if (iRank>=iRankNum*(iRankExtNum+1)) { // rank undefined: Fallback to last rank if (!fReturnLastIfOver) return StdStrBuf(); iRank = iRankNum*(iRankExtNum+1)-1; } StdStrBuf sResult; if (iRank >= iRankNum) { // extended rank composed of two parts int iExtension = iRank / iRankNum - 1; iRank = iRank % iRankNum; sResult.Format(pszRankExtensions[iExtension], pszRankNames[iRank]); } else { // simple rank sResult.Ref(pszRankNames[iRank]); } return sResult; } #ifdef _WIN32 // old-style registry fallback while (iRank>=0) { char keyname[30]; StdCopyStrBuf rankname; sprintf(keyname,"Rank%03d",iRank+1); rankname = GetRegistryString(Register,keyname); if (!rankname.isNull()) return rankname; if (!fReturnLastIfOver) return StdStrBuf(); --iRank; } #endif return StdStrBuf(); }
C4PortraitSelDlg::ListItem::ListItem(const char *szFilename) : C4FileSelDlg::ListItem(szFilename), fError(false), fLoaded(false) { CStdFont *pUseFont = &(C4GUI::GetRes()->MiniFont); // determine label text StdStrBuf sDisplayLabel; if (szFilename) { sDisplayLabel.Copy(::GetFilename(szFilename)); ::RemoveExtension(&sDisplayLabel); } else { sDisplayLabel.Ref(LoadResStr("IDS_MSG_NOPORTRAIT")); } // insert linebreaks into label text int32_t iLineHgt = Max<int32_t>( pUseFont->BreakMessage(sDisplayLabel.getData(), ImagePreviewSize - 6, &sFilenameLabelText, false), 1); // set size SetBounds(C4Rect(0, 0, ImagePreviewSize, ImagePreviewSize + iLineHgt)); }
C4StartupNetDlg::C4StartupNetDlg() : C4StartupDlg(LoadResStr("IDS_DLG_NETSTART")) { // ctor // key bindings C4CustomKey::CodeList keys; keys.emplace_back(K_BACK); keys.emplace_back(K_LEFT); pKeyBack = new C4KeyBinding(keys, "StartupNetBack", KEYSCOPE_Gui, new C4GUI::DlgKeyCB<C4StartupNetDlg>(*this, &C4StartupNetDlg::KeyBack), C4CustomKey::PRIO_Dlg); pKeyRefresh = new C4KeyBinding(C4KeyCodeEx(K_F5), "StartupNetReload", KEYSCOPE_Gui, new C4GUI::DlgKeyCB<C4StartupNetDlg>(*this, &C4StartupNetDlg::KeyRefresh), C4CustomKey::PRIO_CtrlOverride); // screen calculations UpdateSize(); int32_t iIconSize = C4GUI_IconExWdt; int32_t iButtonWidth,iCaptionFontHgt, iSideSize = std::max<int32_t>(GetBounds().Wdt/6, iIconSize); int32_t iButtonHeight = C4GUI_ButtonHgt, iButtonIndent = GetBounds().Wdt/40; ::GraphicsResource.CaptionFont.GetTextExtent("<< BACK", iButtonWidth, iCaptionFontHgt, true); iButtonWidth *= 3; C4GUI::ComponentAligner caMain(GetClientRect(), 0,0, true); C4GUI::ComponentAligner caButtonArea(caMain.GetFromBottom(caMain.GetHeight()/7),0,0); int32_t iButtonAreaWdt = caButtonArea.GetWidth()*7/8; iButtonWidth = std::min<int32_t>(iButtonWidth, (iButtonAreaWdt - 8 * iButtonIndent)/4); iButtonIndent = (iButtonAreaWdt - 4 * iButtonWidth) / 8; C4GUI::ComponentAligner caButtons(caButtonArea.GetCentered(iButtonAreaWdt, iButtonHeight),iButtonIndent,0); C4GUI::ComponentAligner caLeftBtnArea(caMain.GetFromLeft(iSideSize), std::min<int32_t>(caMain.GetWidth()/20, (iSideSize-C4GUI_IconExWdt)/2), caMain.GetHeight()/40); C4GUI::ComponentAligner caConfigArea(caMain.GetFromRight(iSideSize), std::min<int32_t>(caMain.GetWidth()/20, (iSideSize-C4GUI_IconExWdt)/2), caMain.GetHeight()/40); // left button area: Switch between chat and game list if (C4ChatDlg::IsChatEnabled()) { btnGameList = new C4GUI::CallbackButton<C4StartupNetDlg, C4GUI::IconButton>(C4GUI::Ico_Ex_GameList, caLeftBtnArea.GetFromTop(iIconSize, iIconSize), '\0', &C4StartupNetDlg::OnBtnGameList); btnGameList->SetToolTip(LoadResStr("IDS_DESC_SHOWSAVAILABLENETWORKGAME")); btnGameList->SetText(LoadResStr("IDS_BTN_GAMES")); AddElement(btnGameList); btnChat = new C4GUI::CallbackButton<C4StartupNetDlg, C4GUI::IconButton>(C4GUI::Ico_Ex_Chat, caLeftBtnArea.GetFromTop(iIconSize, iIconSize), '\0', &C4StartupNetDlg::OnBtnChat); btnChat->SetToolTip(LoadResStr("IDS_DESC_CONNECTSTOANIRCCHATSERVER")); btnChat->SetText(LoadResStr("IDS_BTN_CHAT")); AddElement(btnChat); } else btnChat = nullptr; // main area: Tabular to switch between game list and chat pMainTabular = new C4GUI::Tabular(caMain.GetAll(), C4GUI::Tabular::tbNone); pMainTabular->SetDrawDecoration(false); pMainTabular->SetSheetMargin(0); AddElement(pMainTabular); // main area: game selection sheet C4GUI::Tabular::Sheet *pSheetGameList = pMainTabular->AddSheet(nullptr); C4GUI::ComponentAligner caGameList(pSheetGameList->GetContainedClientRect(), 0,0, false); C4GUI::WoodenLabel *pGameListLbl; int32_t iCaptHgt = C4GUI::WoodenLabel::GetDefaultHeight(&::GraphicsResource.TextFont); pGameListLbl = new C4GUI::WoodenLabel(LoadResStr("IDS_NET_GAMELIST"), caGameList.GetFromTop(iCaptHgt), C4GUI_Caption2FontClr, &::GraphicsResource.TextFont, ALeft); // search field C4GUI::WoodenLabel *pSearchLbl; const char *szSearchLblText = LoadResStr("IDS_NET_MSSEARCH"); int32_t iSearchWdt=100, iSearchHgt; ::GraphicsResource.TextFont.GetTextExtent(szSearchLblText, iSearchWdt, iSearchHgt, true); C4GUI::ComponentAligner caSearch(caGameList.GetFromTop(iSearchHgt), 0,0); pSearchLbl = new C4GUI::WoodenLabel(szSearchLblText, caSearch.GetFromLeft(iSearchWdt+10), C4GUI_Caption2FontClr, &::GraphicsResource.TextFont); const char *szSearchTip = LoadResStr("IDS_NET_MSSEARCH_DESC"); pSearchLbl->SetToolTip(szSearchTip); pSheetGameList->AddElement(pSearchLbl); pSearchFieldEdt = new C4GUI::CallbackEdit<C4StartupNetDlg>(caSearch.GetAll(), this, &C4StartupNetDlg::OnSearchFieldEnter); pSearchFieldEdt->SetToolTip(szSearchTip); pSheetGameList->AddElement(pSearchFieldEdt); pSheetGameList->AddElement(pGameListLbl); pGameSelList = new C4GUI::ListBox(caGameList.GetFromTop(caGameList.GetHeight() - iCaptHgt)); pGameSelList->SetDecoration(true, nullptr, true, true); pGameSelList->UpdateElementPositions(); pGameSelList->SetSelectionDblClickFn(new C4GUI::CallbackHandler<C4StartupNetDlg>(this, &C4StartupNetDlg::OnSelDblClick)); pGameSelList->SetSelectionChangeCallbackFn(new C4GUI::CallbackHandler<C4StartupNetDlg>(this, &C4StartupNetDlg::OnSelChange)); pSheetGameList->AddElement(pGameSelList); C4GUI::ComponentAligner caIP(caGameList.GetAll(), 0,0); C4GUI::WoodenLabel *pIPLbl; const char *szIPLblText = LoadResStr("IDS_NET_IP"); int32_t iIPWdt=100, Q; ::GraphicsResource.TextFont.GetTextExtent(szIPLblText, iIPWdt, Q, true); pIPLbl = new C4GUI::WoodenLabel(szIPLblText, caIP.GetFromLeft(iIPWdt+10), C4GUI_Caption2FontClr, &::GraphicsResource.TextFont); const char *szIPTip = LoadResStr("IDS_NET_IP_DESC"); pIPLbl->SetToolTip(szIPTip); pSheetGameList->AddElement(pIPLbl); pJoinAddressEdt = new C4GUI::CallbackEdit<C4StartupNetDlg>(caIP.GetAll(), this, &C4StartupNetDlg::OnJoinAddressEnter); pJoinAddressEdt->SetToolTip(szIPTip); pSheetGameList->AddElement(pJoinAddressEdt); // main area: chat sheet if (C4ChatDlg::IsChatEnabled()) { C4GUI::Tabular::Sheet *pSheetChat = pMainTabular->AddSheet(nullptr); C4GUI::ComponentAligner caChat(pSheetChat->GetContainedClientRect(), 0,0, false); pSheetChat->AddElement(pChatTitleLabel = new C4GUI::WoodenLabel("", caChat.GetFromTop(iCaptHgt), C4GUI_Caption2FontClr, &::GraphicsResource.TextFont, ALeft, false)); C4GUI::GroupBox *pChatGroup = new C4GUI::GroupBox(caChat.GetAll()); pChatGroup->SetColors(0u, C4GUI_CaptionFontClr, C4GUI_StandardBGColor); pChatGroup->SetMargin(2); pSheetChat->AddElement(pChatGroup); pChatCtrl = new C4ChatControl(&Application.IRCClient); pChatCtrl->SetBounds(pChatGroup->GetContainedClientRect()); pChatCtrl->SetTitleChangeCB(new C4GUI::InputCallback<C4StartupNetDlg>(this, &C4StartupNetDlg::OnChatTitleChange)); StdStrBuf sCurrTitle; sCurrTitle.Ref(pChatCtrl->GetTitle()); OnChatTitleChange(sCurrTitle); pChatGroup->AddElement(pChatCtrl); } // config area btnInternet = new C4GUI::CallbackButton<C4StartupNetDlg, C4GUI::IconButton>(Config.Network.MasterServerSignUp ? C4GUI::Ico_Ex_InternetOn : C4GUI::Ico_Ex_InternetOff, caConfigArea.GetFromTop(iIconSize, iIconSize), '\0', &C4StartupNetDlg::OnBtnInternet); btnInternet->SetToolTip(LoadResStr("IDS_DLGTIP_SEARCHINTERNETGAME")); btnInternet->SetText(LoadResStr("IDS_CTL_INETSERVER")); AddElement(btnInternet); btnRecord = new C4GUI::CallbackButton<C4StartupNetDlg, C4GUI::IconButton>(Game.Record ? C4GUI::Ico_Ex_RecordOn : C4GUI::Ico_Ex_RecordOff, caConfigArea.GetFromTop(iIconSize, iIconSize), '\0', &C4StartupNetDlg::OnBtnRecord); btnRecord->SetToolTip(LoadResStr("IDS_DLGTIP_RECORD")); btnRecord->SetText(LoadResStr("IDS_CTL_RECORD")); AddElement(btnRecord); #ifdef WITH_AUTOMATIC_UPDATE btnUpdate = new C4GUI::CallbackButton<C4StartupNetDlg, C4GUI::IconButton>(C4GUI::Ico_Ex_Update, caConfigArea.GetFromTop(iIconSize, iIconSize), '\0', &C4StartupNetDlg::OnBtnUpdate); btnUpdate->SetVisibility(false); // update only available if masterserver notifies it btnUpdate->SetToolTip(LoadResStr("IDS_DLGTIP_UPDATE")); btnUpdate->SetText(LoadResStr("IDS_CTL_UPDATE")); AddElement(btnUpdate); #endif // button area C4GUI::CallbackButton<C4StartupNetDlg> *btn; AddElement(btn = new C4GUI::CallbackButton<C4StartupNetDlg>(LoadResStr("IDS_BTN_BACK"), caButtons.GetFromLeft(iButtonWidth), &C4StartupNetDlg::OnBackBtn)); btn->SetToolTip(LoadResStr("IDS_DLGTIP_BACKMAIN")); AddElement(btnRefresh = new C4GUI::CallbackButton<C4StartupNetDlg>(LoadResStr("IDS_BTN_RELOAD"), caButtons.GetFromLeft(iButtonWidth), &C4StartupNetDlg::OnRefreshBtn)); btnRefresh->SetToolTip(LoadResStr("IDS_NET_RELOAD_DESC")); AddElement(btnJoin = new C4GUI::CallbackButton<C4StartupNetDlg>(LoadResStr("IDS_NET_JOINGAME_BTN"), caButtons.GetFromLeft(iButtonWidth), &C4StartupNetDlg::OnJoinGameBtn)); btnJoin->SetToolTip(LoadResStr("IDS_NET_JOINGAME_DESC")); AddElement(btn = new C4GUI::CallbackButton<C4StartupNetDlg>(LoadResStr("IDS_NET_NEWGAME"), caButtons.GetFromLeft(iButtonWidth), &C4StartupNetDlg::OnCreateGameBtn)); btn->SetToolTip(LoadResStr("IDS_NET_NEWGAME_DESC")); // initial dlg mode UpdateDlgMode(); // initial focus SetFocus(GetDlgModeFocusControl(), false); // initialize discovery DiscoverClient.Init(Config.Network.PortDiscovery); DiscoverClient.StartDiscovery(); iGameDiscoverInterval = C4NetGameDiscoveryInterval; // register timer Application.Add(this); // register as receiver of reference notifies Application.InteractiveThread.SetCallback(Ev_HTTP_Response, this); }
bool C4LandscapeRenderGL::InitMaterialTexture(C4TextureMap *pTexs) { // Populate our map with all needed textures MaterialTextureMap.push_back(StdCopyStrBuf("")); AddTexturesFromMap(pTexs); // Determine depth to use iMaterialTextureDepth = 2*MaterialTextureMap.size(); int32_t iNormalDepth = iMaterialTextureDepth / 2; // Find the largest texture C4Texture *pTex; C4Surface *pRefSfc = NULL; for(int iTexIx = 0; (pTex = pTexs->GetTexture(pTexs->GetTexture(iTexIx))); iTexIx++) if(C4Surface *pSfc = pTex->Surface32) if (!pRefSfc || pRefSfc->Wdt < pSfc->Wdt || pRefSfc->Hgt < pSfc->Hgt) pRefSfc = pSfc; if(!pRefSfc) return false; // Get size for our textures. We might be limited by hardware int iTexWdt = pRefSfc->Wdt, iTexHgt = pRefSfc->Hgt; GLint iMaxTexSize, iMaxTexLayers; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &iMaxTexSize); glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &iMaxTexLayers); if (iTexWdt > iMaxTexSize || iTexHgt > iMaxTexSize) { iTexWdt = std::min(iTexWdt, iMaxTexSize); iTexHgt = std::min(iTexHgt, iMaxTexSize); LogF(" gl: Material textures too large, GPU only supports %dx%d! Cropping might occur!", iMaxTexSize, iMaxTexSize); } if(iMaterialTextureDepth >= iMaxTexLayers) { LogF(" gl: Too many material textures! GPU only supports 3D texture depth of %d!", iMaxTexSize); return false; } iMaterialWidth = iTexWdt; iMaterialHeight = iTexHgt; // Compose together data of all textures const int iTexSize = iTexWdt * iTexHgt * C4Draw::COLOR_DEPTH_BYTES; const int iSize = iTexSize * iMaterialTextureDepth; BYTE *pData = new BYTE [iSize]; for(int i = 0; i < iMaterialTextureDepth; i++) { BYTE *p = pData + i * iTexSize; // Get texture at position StdStrBuf Texture; bool fNormal = i >= iNormalDepth; if(i < int32_t(MaterialTextureMap.size())) Texture.Ref(MaterialTextureMap[i]); else if(fNormal && i < iNormalDepth + int32_t(MaterialTextureMap.size())) Texture.Format("%s_NRM", MaterialTextureMap[i-iNormalDepth].getData()); // Try to find the texture C4Texture *pTex; C4Surface *pSurface; if((pTex = pTexs->GetTexture(Texture.getData())) && (pSurface = pTex->Surface32)) { #ifdef DEBUG_SOLID_COLOR_TEXTURES // Just write a solid color that depends on the texture index DWORD *texdata = reinterpret_cast<DWORD *>(p); for (int y = 0; y < iTexHgt; ++y) for (int x = 0; x < iTexWdt; ++x) *texdata++ = RGBA((iTex & 48), (iTex & 3) * 16, (i & 12) * 4, 255); continue; #else // Size recheck. It's fine if this texture's size is a divisor // of the maximum texture size, because then we can just tile // the smaller texture. if(pSurface->Wdt != iTexWdt || pSurface->Hgt != iTexHgt) if (iTexWdt % pSurface->Wdt != 0 || iTexHgt % pSurface->Hgt != 0) LogF(" gl: texture %s size mismatch (%dx%d vs %dx%d)!", Texture.getData(), pSurface->Wdt, pSurface->Hgt, iTexWdt, iTexHgt); // Copy bytes DWORD *texdata = reinterpret_cast<DWORD *>(p); pSurface->Lock(); for (int y = 0; y < iTexHgt; ++y) for (int x = 0; x < iTexWdt; ++x) *texdata++ = pSurface->GetPixDw(x % pSurface->Wdt, y % pSurface->Hgt, false); pSurface->Unlock(); continue; #endif } // Seperator texture? if(SEqual(Texture.getData(), SEPERATOR_TEXTURE)) { // Make some ugly stripes DWORD *texdata = reinterpret_cast<DWORD *>(p); for (int y = 0; y < iTexHgt; ++y) for (int x = 0; x < iTexWdt; ++x) *texdata++ = ((x + y) % 32 < 16 ? RGBA(255, 0, 0, 255) : RGBA(0, 255, 255, 255)); continue; } // If we didn't "continue" yet, we haven't written the texture yet. // Make color texture transparent, and normal texture flat. if (fNormal) { DWORD *texdata = reinterpret_cast<DWORD *>(p); for (int y = 0; y < iTexHgt; ++y) for (int x = 0; x < iTexWdt; ++x) *texdata++ = RGBA(127, 127, 255, 255); } else memset(p, 0, iTexSize); } // Clear error error(s?) while(glGetError()) {} // Alloc 1D matmap texture glGenTextures(1, &matMapTexture); // Alloc 2D texture array glGenTextures(1, &hMaterialTexture); // Generate textures int iSizeSum = 0; // Select texture glBindTexture(GL_TEXTURE_2D_ARRAY, hMaterialTexture); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // We fully expect to tile these glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); // Make it happen! glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, iTexWdt, iTexHgt, iMaterialTextureDepth, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pData); glGenerateMipmap(GL_TEXTURE_2D_ARRAY); // Statistics iSizeSum += iTexWdt * iTexHgt * iMaterialTextureDepth * C4Draw::COLOR_DEPTH_BYTES; // Dispose of data delete [] pData; // Check whether we were successful if(int err = glGetError()) { LogF(" gl: Could not load textures (error %d)", err); return false; } // Announce the good news LogF(" gl: Texturing uses %d slots at %dx%d (%d MB total)", static_cast<int>(MaterialTextureMap.size()), iMaterialWidth, iMaterialHeight, iSizeSum / 1000000); return true; }
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; }
bool C4MainMenu::DoRefillInternal(bool &rfRefilled) { // Variables C4FacetSurface fctSymbol; C4Player *pPlayer; C4IDList ListItems; C4Facet fctTarget; bool fWasEmpty = !GetItemCount(); // Refill switch (Identification) { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case C4MN_Hostility: { // Clear items ClearItems(); // Refill player if (!(pPlayer = ::Players.Get(Player))) return false; // Refill items C4Player *pPlr; int32_t iIndex; for (iIndex=0; (pPlr = ::Players.GetByIndex(iIndex)); iIndex++) // Ignore player self and invisible if (pPlr != pPlayer) if (!pPlr->IsInvisible()) { // Symbol fctSymbol.Create(C4SymbolSize,C4SymbolSize); pPlayer->DrawHostility(fctSymbol,iIndex); // Message StdStrBuf sMsg; bool isFriendly = pPlayer->Hostility.find(pPlr) == pPlayer->Hostility.end(); if (isFriendly) sMsg.Format(LoadResStr("IDS_MENU_ATTACK"),pPlr->GetName()); else sMsg.Format(LoadResStr("IDS_MENU_NOATTACK"),pPlr->GetName()); // Command char szCommand[1000]; sprintf(szCommand,"SetHostility:%i",pPlr->Number); // Info caption char szInfoCaption[C4MaxTitle+1],szFriendly[50],szNot[30]=""; SCopy(LoadResStr(isFriendly ? "IDS_MENU_ATTACKHOSTILE" : "IDS_MENU_ATTACKFRIENDLY"),szFriendly); if (!isFriendly) SCopy(LoadResStr("IDS_MENU_ATTACKNOT"),szNot); sprintf(szInfoCaption,LoadResStr("IDS_MENU_ATTACKINFO"),pPlr->GetName(),szFriendly,szNot); if (iIndex==pPlayer->Number) SCopy(LoadResStr("IDS_MENU_ATTACKSELF"),szInfoCaption); // Add item Add(sMsg.getData(),fctSymbol,szCommand,C4MN_Item_NoCount,NULL,szInfoCaption); fctSymbol.Default(); } break; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case C4MN_TeamSelection: case C4MN_TeamSwitch: { // Clear items ClearItems(); // add all teams as menu items // 2do: Icon C4Team *pTeam; int32_t i=0; bool fAddNewTeam=Game.Teams.IsAutoGenerateTeams(); for (;;) { pTeam = Game.Teams.GetTeamByIndex(i); if (pTeam) { // next regular team ++i; // do not add a new team if an empty team exists if (!pTeam->GetPlayerCount()) fAddNewTeam = false; } else if (fAddNewTeam) { // join new team fAddNewTeam = false; } else { // all teams done break; } // create team symbol: Icon spec if specified; otherwise flag for empty and crew for nonempty team fctSymbol.Create(C4SymbolSize,C4SymbolSize); const char *szIconSpec = pTeam ? pTeam->GetIconSpec() : NULL; bool fHasIcon = false; if (szIconSpec && *szIconSpec) { fHasIcon = Game.DrawTextSpecImage(fctSymbol, szIconSpec, NULL, pTeam->GetColor()); } if (!fHasIcon) { if (pTeam && pTeam->GetPlayerCount()) ::GraphicsResource.fctCrewClr.DrawClr(fctSymbol, true, pTeam->GetColor()); else C4GUI::Icon::GetIconFacet(C4GUI::Ico_Team).Draw(fctSymbol, true); } StdStrBuf sTeamName; if (pTeam) { sTeamName.Take(pTeam->GetNameWithParticipants()); } else sTeamName.Ref(LoadResStr("IDS_PRC_NEWTEAM")); const char *szOperation = (Identification == C4MN_TeamSwitch) ? "TeamSwitch" : "TeamSel"; Add(sTeamName.getData(), fctSymbol,FormatString("%s:%d", szOperation, pTeam ? pTeam->GetID() : TEAMID_New).getData(), C4MN_Item_NoCount,NULL,FormatString(LoadResStr("IDS_MSG_JOINTEAM"), sTeamName.getData()).getData(), C4ID(pTeam ? pTeam->GetID() : 0)); fctSymbol.Default(); } break; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case C4MN_Observer: // observer menu { // Clear items ClearItems(); // Check validity C4Viewport *pVP = ::Viewports.GetViewport(NO_OWNER); if (!pVP) return false; int32_t iInitialSelection = 0; // Add free view AddRefSym(LoadResStr("IDS_MSG_FREEVIEW"), C4GUI::Icon::GetIconFacet(C4GUI::Ico_Star), "Observe:Free", C4MN_Item_NoCount, NULL, LoadResStr("IDS_MSG_FREELYSCROLLAROUNDTHEMAP")); // Add players C4Player *pPlr; int32_t iIndex; for (iIndex=0; (pPlr = ::Players.GetByIndex(iIndex)); iIndex++) { // Ignore invisible if (!pPlr->IsInvisible()) { // Symbol fctSymbol.Create(C4SymbolSize,C4SymbolSize); ::GraphicsResource.fctPlayerClr.DrawClr(fctSymbol, true, pPlr->ColorDw); // Message StdStrBuf sMsg; DWORD dwClr = pPlr->ColorDw; sMsg.Format("<c %x>%s</c>", (unsigned int)C4GUI::MakeColorReadableOnBlack(dwClr), pPlr->GetName()); // Command StdStrBuf sCommand; sCommand.Format("Observe:%d", (int)pPlr->Number); // Info caption StdStrBuf sInfo; sInfo.Format(LoadResStr("IDS_TEXT_FOLLOWVIEWOFPLAYER"), pPlr->GetName()); // Add item Add(sMsg.getData(),fctSymbol,sCommand.getData(),C4MN_Item_NoCount,NULL,sInfo.getData()); fctSymbol.Default(); // check if this is the currently selected player if (pVP->GetPlayer() == pPlr->Number) iInitialSelection = GetItemCount()-1; } // Initial selection on followed player if (fWasEmpty) SetSelection(iInitialSelection, false, true); } } break; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - default: // No internal refill needed return true; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - } // Successfull internal refill rfRefilled = true; return true; }