about summary refs log tree commit diff
path: root/src/game/client
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/client')
-rw-r--r--src/game/client/components/countryflags.cpp105
-rw-r--r--src/game/client/components/countryflags.h31
-rw-r--r--src/game/client/gameclient.cpp13
-rw-r--r--src/game/client/gameclient.h1
4 files changed, 150 insertions, 0 deletions
diff --git a/src/game/client/components/countryflags.cpp b/src/game/client/components/countryflags.cpp
new file mode 100644
index 00000000..fd6e31d1
--- /dev/null
+++ b/src/game/client/components/countryflags.cpp
@@ -0,0 +1,105 @@
+/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
+/* If you are missing that file, acquire a complete release at teeworlds.com.                */
+#include <base/math.h>
+#include <base/system.h>
+
+#include <engine/console.h>
+#include <engine/graphics.h>
+#include <engine/storage.h>
+#include <engine/shared/linereader.h>
+
+#include "countryflags.h"
+
+
+void CCountryFlags::LoadCountryflagsIndexfile()
+{
+	IOHANDLE File = Storage()->OpenFile("countryflags/index.txt", IOFLAG_READ, IStorage::TYPE_ALL);
+	if(!File)
+	{
+		Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "countryflags", "couldn't open index file");
+		return;
+	}
+	
+	char aOrigin[128];
+	CLineReader LineReader;
+	LineReader.Init(File);
+	char *pLine;
+	while((pLine = LineReader.Get()))
+	{
+		if(!str_length(pLine) || pLine[0] == '#') // skip empty lines and comments
+			continue;
+		
+		str_copy(aOrigin, pLine, sizeof(aOrigin));
+		char *pReplacement = LineReader.Get();
+		if(!pReplacement)
+		{
+			Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "countryflags", "unexpected end of index file");
+			break;
+		}
+		
+		if(pReplacement[0] != '=' || pReplacement[1] != '=' || pReplacement[2] != ' ')
+		{
+			char aBuf[128];
+			str_format(aBuf, sizeof(aBuf), "malform replacement for index '%s'", aOrigin);
+			Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "countryflags", aBuf);
+			continue;
+		}
+		
+		// load the graphic file
+		char aBuf[128];
+		str_format(aBuf, sizeof(aBuf), "countryflags/%s.png", aOrigin);
+		CImageInfo Info;
+		if(!Graphics()->LoadPNG(&Info, aBuf, IStorage::TYPE_ALL))
+		{
+			char aMsg[128];
+			str_format(aMsg, sizeof(aMsg), "failed to load '%s'", aBuf);
+			Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "countryflags", aMsg);
+			continue;
+		}
+
+		// add entry
+		CCountryFlag CountryFlag;
+		CountryFlag.m_CountryCode = str_toint(pReplacement);
+		CountryFlag.m_Texture = Graphics()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, Info.m_Format, 0);
+		mem_free(Info.m_pData);
+		str_format(aBuf, sizeof(aBuf), "loaded country flag '%s'", aOrigin);
+		Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "countryflags", aBuf);
+		m_aCountryFlags.add(CountryFlag);
+	}
+	io_close(File);
+}
+
+void CCountryFlags::OnInit()
+{
+	// load country flags
+	m_aCountryFlags.clear();
+	LoadCountryflagsIndexfile();
+	if(!m_aCountryFlags.size())
+	{
+		Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "countryflags", "failed to load country flags. folder='countryflags/'");
+		CCountryFlag DummyEntry;
+		DummyEntry.m_CountryCode = -1;
+		DummyEntry.m_Texture = -1;
+		m_aCountryFlags.add(DummyEntry);
+	}
+}
+
+int CCountryFlags::Num() const
+{
+	return m_aCountryFlags.size();
+}
+
+const CCountryFlags::CCountryFlag *CCountryFlags::Get(int Index) const
+{
+	return &m_aCountryFlags[Index%m_aCountryFlags.size()];
+}
+
+int CCountryFlags::Find(int CountryCode) const
+{
+	for(int i = 0; i < m_aCountryFlags.size(); ++i)
+	{
+		if(m_aCountryFlags[i].m_CountryCode == CountryCode)
+			return i;
+	}
+	return -1;
+}
diff --git a/src/game/client/components/countryflags.h b/src/game/client/components/countryflags.h
new file mode 100644
index 00000000..b0960661
--- /dev/null
+++ b/src/game/client/components/countryflags.h
@@ -0,0 +1,31 @@
+/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
+/* If you are missing that file, acquire a complete release at teeworlds.com.                */
+#ifndef GAME_CLIENT_COMPONENTS_COUNTRYFLAGS_H
+#define GAME_CLIENT_COMPONENTS_COUNTRYFLAGS_H
+#include <base/vmath.h>
+#include <base/tl/sorted_array.h>
+#include <game/client/component.h>
+
+class CCountryFlags : public CComponent
+{
+public:
+	struct CCountryFlag
+	{
+		int m_CountryCode;
+		int m_Texture;
+		
+		bool operator<(const CCountryFlag &Other) { return m_CountryCode < Other.m_CountryCode; }
+	};
+	
+	void OnInit();
+	
+	int Num() const;
+	const CCountryFlag *Get(int Index) const;
+	int Find(int CountryCode) const;
+	
+private:
+	sorted_array<CCountryFlag> m_aCountryFlags;
+
+	void LoadCountryflagsIndexfile();
+};
+#endif
diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp
index b6e89a7b..15786110 100644
--- a/src/game/client/gameclient.cpp
+++ b/src/game/client/gameclient.cpp
@@ -26,6 +26,7 @@
 #include "components/chat.h"
 #include "components/console.h"
 #include "components/controls.h"
+#include "components/countryflags.h"
 #include "components/damageind.h"
 #include "components/debughud.h"
 #include "components/effects.h"
@@ -60,6 +61,7 @@ static CBinds gs_Binds;
 static CParticles gs_Particles;
 static CMenus gs_Menus;
 static CSkins gs_Skins;
+static CCountryFlags gs_CountryFlags;
 static CFlow gs_Flow;
 static CHud gs_Hud;
 static CDebugHud gs_DebugHud;
@@ -107,6 +109,7 @@ void CGameClient::OnConsoleInit()
 	m_pParticles = &::gs_Particles;
 	m_pMenus = &::gs_Menus;
 	m_pSkins = &::gs_Skins;
+	m_pCountryFlags = &::gs_CountryFlags;
 	m_pChat = &::gs_Chat;
 	m_pFlow = &::gs_Flow;
 	m_pCamera = &::gs_Camera;
@@ -121,6 +124,7 @@ void CGameClient::OnConsoleInit()
 	
 	// make a list of all the systems, make sure to add them in the corrent render order
 	m_All.Add(m_pSkins);
+	m_All.Add(m_pCountryFlags);
 	m_All.Add(m_pMapimages);
 	m_All.Add(m_pEffects); // doesn't render anything, just updates effects
 	m_All.Add(m_pParticles);
@@ -697,6 +701,15 @@ void CGameClient::OnNewSnapshot()
 				m_aClients[ClientID].m_UseCustomColor = pInfo->m_UseCustomColor;
 				m_aClients[ClientID].m_ColorBody = pInfo->m_ColorBody;
 				m_aClients[ClientID].m_ColorFeet = pInfo->m_ColorFeet;
+
+				// find country flag
+				m_aClients[ClientID].m_Country = g_GameClient.m_pCountryFlags->Find(m_aClients[ClientID].m_Country);
+				if(m_aClients[ClientID].m_Country < 0)
+				{
+					m_aClients[ClientID].m_Country = g_GameClient.m_pCountryFlags->Find(-1);
+					if(m_aClients[ClientID].m_Country < 0)
+						m_aClients[ClientID].m_Country = 0;
+				}
 				
 				// prepare the info
 				if(m_aClients[ClientID].m_aSkinName[0] == 'x' || m_aClients[ClientID].m_aSkinName[1] == '_')
diff --git a/src/game/client/gameclient.h b/src/game/client/gameclient.h
index a3092514..26c839a3 100644
--- a/src/game/client/gameclient.h
+++ b/src/game/client/gameclient.h
@@ -219,6 +219,7 @@ public:
 	class CParticles *m_pParticles;
 	class CMenus *m_pMenus;
 	class CSkins *m_pSkins;
+	class CCountryFlags *m_pCountryFlags;
 	class CFlow *m_pFlow;
 	class CChat *m_pChat;
 	class CDamageInd *m_pDamageind;