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/console.cpp14
-rw-r--r--src/game/client/components/console.h3
-rw-r--r--src/game/client/components/killmessages.cpp36
-rw-r--r--src/game/client/components/killmessages.h10
-rw-r--r--src/game/client/components/menus.cpp2
-rw-r--r--src/game/client/components/menus.h7
-rw-r--r--src/game/client/components/menus_demo.cpp82
7 files changed, 124 insertions, 30 deletions
diff --git a/src/game/client/components/console.cpp b/src/game/client/components/console.cpp
index 742b6b2d..b323ab48 100644
--- a/src/game/client/components/console.cpp
+++ b/src/game/client/components/console.cpp
@@ -34,9 +34,8 @@ enum
 	CONSOLE_CLOSING,
 };
 
-CGameConsole::CInstance::CInstance(CGameConsole *pGameConsole, int Type)
+CGameConsole::CInstance::CInstance(int Type)
 {
-	m_pGameConsole = pGameConsole;
 	// init ringbuffers
 	//history = ringbuf_init(history_data, sizeof(history_data), RINGBUF_FLAG_RECYCLE);
 	//backlog = ringbuf_init(backlog_data, sizeof(backlog_data), RINGBUF_FLAG_RECYCLE);
@@ -56,6 +55,11 @@ CGameConsole::CInstance::CInstance(CGameConsole *pGameConsole, int Type)
 	m_pCommand = 0x0;
 }
 
+void CGameConsole::CInstance::Init(CGameConsole *pGameConsole)
+{
+	m_pGameConsole = pGameConsole;
+};
+
 void CGameConsole::CInstance::ExecuteLine(const char *pLine)
 {
 	if(m_Type == 0)
@@ -198,7 +202,7 @@ void CGameConsole::CInstance::PrintLine(const char *pLine)
 }
 
 CGameConsole::CGameConsole()
-: m_LocalConsole(this, 0), m_RemoteConsole(this, 1)
+: m_LocalConsole(0), m_RemoteConsole(1)
 {
 	m_ConsoleType = 0;
 	m_ConsoleState = CONSOLE_CLOSED;
@@ -573,6 +577,10 @@ void CGameConsole::PrintLine(int Type, const char *pLine)
 
 void CGameConsole::OnConsoleInit()
 {
+	// init console instances
+	m_LocalConsole.Init(this);
+	m_RemoteConsole.Init(this);
+
 	m_pConsole = Kernel()->RequestInterface<IConsole>();
 	
 	//
diff --git a/src/game/client/components/console.h b/src/game/client/components/console.h
index b88c6349..d146307f 100644
--- a/src/game/client/components/console.h
+++ b/src/game/client/components/console.h
@@ -27,7 +27,8 @@ class CGameConsole : public CComponent
 		
 		IConsole::CCommandInfo *m_pCommand;
 
-		CInstance(CGameConsole *pGameConsole, int t);
+		CInstance(int t);
+		void Init(CGameConsole *pGameConsole);
 
 		void ExecuteLine(const char *pLine);
 		
diff --git a/src/game/client/components/killmessages.cpp b/src/game/client/components/killmessages.cpp
index d18dd965..a3dc3b9c 100644
--- a/src/game/client/components/killmessages.cpp
+++ b/src/game/client/components/killmessages.cpp
@@ -22,8 +22,14 @@ void CKillMessages::OnMessage(int MsgType, void *pRawMsg)
 		
 		// unpack messages
 		CKillMsg Kill;
-		Kill.m_Killer = pMsg->m_Killer;
-		Kill.m_Victim = pMsg->m_Victim;
+		Kill.m_VictimID = pMsg->m_Victim;
+		Kill.m_VictimTeam = m_pClient->m_aClients[Kill.m_VictimID].m_Team;
+		str_copy(Kill.m_aVictimName, m_pClient->m_aClients[Kill.m_VictimID].m_aName, sizeof(Kill.m_aVictimName));
+		Kill.m_VictimRenderInfo = m_pClient->m_aClients[Kill.m_VictimID].m_RenderInfo;
+		Kill.m_KillerID = pMsg->m_Killer;
+		Kill.m_KillerTeam = m_pClient->m_aClients[Kill.m_KillerID].m_Team;
+		str_copy(Kill.m_aKillerName, m_pClient->m_aClients[Kill.m_KillerID].m_aName, sizeof(Kill.m_aKillerName));
+		Kill.m_KillerRenderInfo = m_pClient->m_aClients[Kill.m_KillerID].m_RenderInfo;
 		Kill.m_Weapon = pMsg->m_Weapon;
 		Kill.m_ModeSpecial = pMsg->m_ModeSpecial;
 		Kill.m_Tick = Client()->GameTick();
@@ -51,14 +57,14 @@ void CKillMessages::OnRender()
 			continue;
 
 		float FontSize = 36.0f;
-		float KillerNameW = TextRender()->TextWidth(0, FontSize, m_pClient->m_aClients[m_aKillmsgs[r].m_Killer].m_aName, -1);
-		float VictimNameW = TextRender()->TextWidth(0, FontSize, m_pClient->m_aClients[m_aKillmsgs[r].m_Victim].m_aName, -1);
+		float KillerNameW = TextRender()->TextWidth(0, FontSize, m_aKillmsgs[r].m_aKillerName, -1);
+		float VictimNameW = TextRender()->TextWidth(0, FontSize, m_aKillmsgs[r].m_aVictimName, -1);
 
 		float x = StartX;
 
 		// render victim name
 		x -= VictimNameW;
-		TextRender()->Text(0, x, y, FontSize, m_pClient->m_aClients[m_aKillmsgs[r].m_Victim].m_aName, -1);
+		TextRender()->Text(0, x, y, FontSize, m_aKillmsgs[r].m_aVictimName, -1);
 
 		// render victim tee
 		x -= 24.0f;
@@ -71,8 +77,10 @@ void CKillMessages::OnRender()
 				Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
 				Graphics()->QuadsBegin();
 
-				if(m_pClient->m_aClients[m_aKillmsgs[r].m_Victim].m_Team == 0) RenderTools()->SelectSprite(SPRITE_FLAG_BLUE);
-				else RenderTools()->SelectSprite(SPRITE_FLAG_RED);
+				if(m_aKillmsgs[r].m_VictimTeam == 0)
+					RenderTools()->SelectSprite(SPRITE_FLAG_BLUE);
+				else
+					RenderTools()->SelectSprite(SPRITE_FLAG_RED);
 				
 				float Size = 56.0f;
 				IGraphics::CQuadItem QuadItem(x, y-16, Size/2, Size);
@@ -81,7 +89,7 @@ void CKillMessages::OnRender()
 			}
 		}
 		
-		RenderTools()->RenderTee(CAnimState::GetIdle(), &m_pClient->m_aClients[m_aKillmsgs[r].m_Victim].m_RenderInfo, EMOTE_PAIN, vec2(-1,0), vec2(x, y+28));
+		RenderTools()->RenderTee(CAnimState::GetIdle(), &m_aKillmsgs[r].m_VictimRenderInfo, EMOTE_PAIN, vec2(-1,0), vec2(x, y+28));
 		x -= 32.0f;
 		
 		// render weapon
@@ -96,7 +104,7 @@ void CKillMessages::OnRender()
 		}
 		x -= 52.0f;
 
-		if(m_aKillmsgs[r].m_Victim != m_aKillmsgs[r].m_Killer)
+		if(m_aKillmsgs[r].m_VictimID != m_aKillmsgs[r].m_KillerID)
 		{
 			if(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_FLAGS)
 			{
@@ -106,8 +114,10 @@ void CKillMessages::OnRender()
 					Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
 					Graphics()->QuadsBegin();
 
-					if(m_pClient->m_aClients[m_aKillmsgs[r].m_Killer].m_Team == 0) RenderTools()->SelectSprite(SPRITE_FLAG_BLUE, SPRITE_FLAG_FLIP_X);
-					else RenderTools()->SelectSprite(SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X);
+					if(m_aKillmsgs[r].m_KillerTeam == 0)
+						RenderTools()->SelectSprite(SPRITE_FLAG_BLUE, SPRITE_FLAG_FLIP_X);
+					else
+						RenderTools()->SelectSprite(SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X);
 					
 					float Size = 56.0f;
 					IGraphics::CQuadItem QuadItem(x-56, y-16, Size/2, Size);
@@ -118,12 +128,12 @@ void CKillMessages::OnRender()
 			
 			// render killer tee
 			x -= 24.0f;
-			RenderTools()->RenderTee(CAnimState::GetIdle(), &m_pClient->m_aClients[m_aKillmsgs[r].m_Killer].m_RenderInfo, EMOTE_ANGRY, vec2(1,0), vec2(x, y+28));
+			RenderTools()->RenderTee(CAnimState::GetIdle(), &m_aKillmsgs[r].m_KillerRenderInfo, EMOTE_ANGRY, vec2(1,0), vec2(x, y+28));
 			x -= 32.0f;
 
 			// render killer name
 			x -= KillerNameW;
-			TextRender()->Text(0, x, y, FontSize, m_pClient->m_aClients[m_aKillmsgs[r].m_Killer].m_aName, -1);
+			TextRender()->Text(0, x, y, FontSize, m_aKillmsgs[r].m_aKillerName, -1);
 		}
 
 		y += 44;
diff --git a/src/game/client/components/killmessages.h b/src/game/client/components/killmessages.h
index 720b10ae..b4954e22 100644
--- a/src/game/client/components/killmessages.h
+++ b/src/game/client/components/killmessages.h
@@ -9,8 +9,14 @@ public:
 	struct CKillMsg
 	{
 		int m_Weapon;
-		int m_Victim;
-		int m_Killer;
+		int m_VictimID;
+		int m_VictimTeam;
+		char m_aVictimName[64];
+		CTeeRenderInfo m_VictimRenderInfo;
+		int m_KillerID;
+		int m_KillerTeam;
+		char m_aKillerName[64];
+		CTeeRenderInfo m_KillerRenderInfo;
 		int m_ModeSpecial; // for CTF, if the guy is carrying a flag for example
 		int m_Tick;
 	};
diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp
index fc919409..76943620 100644
--- a/src/game/client/components/menus.cpp
+++ b/src/game/client/components/menus.cpp
@@ -94,6 +94,8 @@ CMenus::CMenus()
 	m_NumInputEvents = 0;
 	
 	m_LastInput = time_get();
+	
+	str_copy(m_aCurrentDemoFolder, "demos", sizeof(m_aCurrentDemoFolder));
 }
 
 vec4 CMenus::ButtonColorMul(const void *pID)
diff --git a/src/game/client/components/menus.h b/src/game/client/components/menus.h
index c09e6e96..229fce80 100644
--- a/src/game/client/components/menus.h
+++ b/src/game/client/components/menus.h
@@ -160,11 +160,14 @@ class CMenus : public CComponent
 	};
 	
 	sorted_array<CDemoItem> m_lDemos;
-		
+	char m_aCurrentDemoFolder[256];
+	
 	void DemolistPopulate();
 	static void DemolistCountCallback(const char *pName, int IsDir, void *pUser);
 	static void DemolistFetchCallback(const char *pName, int IsDir, void *pUser);
-
+	static void IsDirCallback(const char *pName, int IsDir, void *pUser);
+	void DemoSetParentDirectory();
+	
 	// found in menus.cpp
 	int Render();
 	//void render_background();
diff --git a/src/game/client/components/menus_demo.cpp b/src/game/client/components/menus_demo.cpp
index f3a6bc88..ec1ead8e 100644
--- a/src/game/client/components/menus_demo.cpp
+++ b/src/game/client/components/menus_demo.cpp
@@ -1,4 +1,5 @@
 
+#include <string.h>
 #include <base/math.h>
 
 
@@ -390,17 +391,32 @@ void CMenus::DemolistFetchCallback(const char *pName, int IsDir, void *pUser)
 	pInfo->m_pSelf->m_lDemos.add(Item);
 }
 
+void CMenus::IsDirCallback(const char *pName, int IsDir, void *pUser)
+{
+	*((bool *)pUser) = true;
+}
+
 void CMenus::DemolistPopulate()
 {
 	m_lDemos.clear();
 	
+	
+	if(strncmp(m_aCurrentDemoFolder, "demos", 256)) //add parent folder
+	{
+		CDemoItem Item;
+		str_copy(Item.m_aName, "..", sizeof(Item.m_aName));
+		str_copy(Item.m_aFilename, "..", sizeof(Item.m_aFilename));
+		m_lDemos.add(Item);
+	}
+	
+	
 	char aBuf[512];
-	str_format(aBuf, sizeof(aBuf), "%s/demos", Client()->UserDirectory());
-
+	str_format(aBuf, sizeof(aBuf), "%s/%s", Client()->UserDirectory(), m_aCurrentDemoFolder);
+	
 	FETCH_CALLBACKINFO Info = {this, aBuf, 0};
 	fs_listdir(aBuf, DemolistFetchCallback, &Info);
-	Info.m_pPrefix = "demos";
-	fs_listdir("demos", DemolistFetchCallback, &Info);
+	Info.m_pPrefix = m_aCurrentDemoFolder;
+	fs_listdir(m_aCurrentDemoFolder, DemolistFetchCallback, &Info);
 }
 
 
@@ -439,22 +455,70 @@ void CMenus::RenderDemoList(CUIRect MainView)
 	RefreshRect.VSplitRight(130.0f, &RefreshRect, &PlayRect);
 	PlayRect.VSplitRight(120.0f, 0x0, &PlayRect);
 	
+	
+	bool IsDir = false;
+	if(!strncmp(m_lDemos[s_SelectedItem].m_aName, "..", 256)) //parent folder
+		IsDir = true;
+	else
+		fs_listdir(m_lDemos[s_SelectedItem].m_aFilename, IsDirCallback, &IsDir);
+	
+	
 	static int s_RefreshButton = 0;
 	if(DoButton_Menu(&s_RefreshButton, Localize("Refresh"), 0, &RefreshRect))
 	{
 		DemolistPopulate();
 	}
-		
+	
 	static int s_PlayButton = 0;
-	if(DoButton_Menu(&s_PlayButton, Localize("Play"), 0, &PlayRect) || Activated)
+	char aTitleButton[8];
+	if(IsDir)
+		str_copy(aTitleButton, "Open", sizeof(aTitleButton));
+	else
+		str_copy(aTitleButton, "Play", sizeof(aTitleButton));
+	// /!\ TODO: Add "Open" in Localization /!\ 
+	if(DoButton_Menu(&s_PlayButton, Localize(aTitleButton), 0, &PlayRect) || Activated)
 	{		
 		if(s_SelectedItem >= 0 && s_SelectedItem < m_lDemos.size())
 		{
-			const char *pError = Client()->DemoPlayer_Play(m_lDemos[s_SelectedItem].m_aFilename);
-			if(pError)
-				PopupMessage(Localize("Error"), Localize(pError), Localize("Ok"));
+			if(!strncmp(m_lDemos[s_SelectedItem].m_aName, "..", 256))
+			{
+				DemoSetParentDirectory();
+				DemolistPopulate();
+				s_SelectedItem = 0;
+			}
+			else if(IsDir)
+			{
+				str_format(m_aCurrentDemoFolder, sizeof(m_aCurrentDemoFolder), "%s/%s", m_aCurrentDemoFolder, m_lDemos[s_SelectedItem].m_aName);
+				DemolistPopulate();
+				s_SelectedItem = 0;
+			}
+			else
+			{
+				const char *pError = Client()->DemoPlayer_Play(m_lDemos[s_SelectedItem].m_aFilename);
+				if(pError)
+					PopupMessage(Localize("Error"), pError, Localize("Ok"));
+			}
 		}
 	}
 	
 }
 
+
+
+void CMenus::DemoSetParentDirectory()
+{
+	int Stop = 0;
+	int i;
+	for(i = 0; i < 256; i++)
+	{
+		if(m_aCurrentDemoFolder[i] == '/')
+			Stop = i;
+	}
+	
+	//keeps chars which are before the last '/' and remove chars which are after
+	for(i = 0; i < 256; i++)
+	{
+		if(i >= Stop)
+			m_aCurrentDemoFolder[i] = NULL;
+	}
+}