summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristopher Schwarz <lakitu7@gmail.com>2009-10-12 19:17:00 +0000
committerTim Angus <tim@ngus.net>2013-01-03 00:16:48 +0000
commitcf8d239dbe92720a24e8968c0b00ec2d4eec060f (patch)
treef587fcdfcd80f8e6e9e3342dde57d2172f4c7ec6 /src
parent244808767a99cc237a477262420c43c126732088 (diff)
* (bug 4295) Add an option to view Tremulous news to the main menu
Diffstat (limited to 'src')
-rw-r--r--src/client/cl_main.c6
-rw-r--r--src/client/cl_ui.c51
-rw-r--r--src/client/client.h2
-rw-r--r--src/qcommon/q_shared.h1
-rw-r--r--src/ui/ui_local.h16
-rw-r--r--src/ui/ui_main.c78
-rw-r--r--src/ui/ui_public.h1
-rw-r--r--src/ui/ui_syscalls.asm1
-rw-r--r--src/ui/ui_syscalls.c5
9 files changed, 159 insertions, 2 deletions
diff --git a/src/client/cl_main.c b/src/client/cl_main.c
index 09c42e63..0aafa529 100644
--- a/src/client/cl_main.c
+++ b/src/client/cl_main.c
@@ -1869,11 +1869,13 @@ void CL_DownloadsComplete( void ) {
CL_cURL_Shutdown();
if( clc.cURLDisconnected ) {
if(clc.downloadRestart) {
- FS_Restart(clc.checksumFeed);
+ if( !clc.activeCURLNotGameRelated )
+ FS_Restart(clc.checksumFeed);
clc.downloadRestart = qfalse;
}
clc.cURLDisconnected = qfalse;
- CL_Reconnect_f();
+ if( !clc.activeCURLNotGameRelated )
+ CL_Reconnect_f();
return;
}
}
diff --git a/src/client/cl_ui.c b/src/client/cl_ui.c
index 4c1ff9ed..caf55ef0 100644
--- a/src/client/cl_ui.c
+++ b/src/client/cl_ui.c
@@ -81,6 +81,52 @@ void LAN_SaveServersToCache( void ) {
FS_FCloseFile(fileOut);
}
+/*
+====================
+GetNews
+====================
+*/
+qboolean GetNews( qboolean begin )
+{
+#ifdef USE_CURL
+ qboolean finished = qfalse;
+ fileHandle_t fileIn;
+ int readSize;
+
+ if( begin ) { // if not already using curl, start the download
+ if( !clc.downloadCURLM ) {
+ if(!CL_cURL_Init()) {
+ Cvar_Set( "cl_newsString", "^1Error: Could not load cURL library" );
+ return qtrue;
+ }
+ clc.activeCURLNotGameRelated = qtrue;
+ CL_cURL_BeginDownload("news.dat",
+ "http://tremulous.net/clientnews.txt");
+ return qfalse;
+ }
+ }
+
+ if ( !clc.downloadCURLM && FS_SV_FOpenFileRead("news.dat", &fileIn)) {
+ readSize = FS_Read(clc.newsString, sizeof( clc.newsString ), fileIn);
+ FS_FCloseFile(fileIn);
+ clc.newsString[ readSize ] = '\0';
+ if( readSize > 0 ) {
+ finished = qtrue;
+ clc.cURLUsed = qfalse;
+ CL_cURL_Shutdown();
+ clc.activeCURLNotGameRelated = qfalse;
+ }
+ }
+ if( !finished )
+ strcpy( clc.newsString, "Retrieving..." );
+#else
+ Cvar_Set( "cl_newsString",
+ "^1You must compile your client with CURL support to use this feature" );
+ return qtrue;
+#endif
+ Cvar_Set( "cl_newsString", clc.newsString );
+ return finished;
+}
/*
====================
@@ -907,6 +953,9 @@ intptr_t CL_UISystemCalls( intptr_t *args ) {
case UI_LAN_SERVERSTATUS:
return LAN_GetServerStatus( VMA(1), VMA(2), args[3] );
+ case UI_GETNEWS:
+ return GetNews( args[1] );
+
case UI_LAN_COMPARESERVERS:
return LAN_CompareServers( args[1], args[2], args[3], args[4], args[5] );
@@ -1059,6 +1108,8 @@ void CL_InitUI( void ) {
// reset any CVAR_CHEAT cvars registered by ui
if ( !clc.demoplaying && !cl_connectedToCheatServer )
Cvar_SetCheatState();
+
+ clc.newsString[ 0 ] = '\0';
}
/*
diff --git a/src/client/client.h b/src/client/client.h
index 206d5dd9..a6d61950 100644
--- a/src/client/client.h
+++ b/src/client/client.h
@@ -204,6 +204,7 @@ typedef struct {
char downloadURL[MAX_OSPATH];
CURL *downloadCURL;
CURLM *downloadCURLM;
+ qboolean activeCURLNotGameRelated;
#endif /* USE_CURL */
int sv_allowDownload;
char sv_dlURL[MAX_CVAR_VALUE_STRING];
@@ -213,6 +214,7 @@ typedef struct {
int downloadSize; // how many bytes we got
char downloadList[MAX_INFO_STRING]; // list of paks we need to download
qboolean downloadRestart; // if true, we need to do another FS_Restart because we downloaded a pak
+ char newsString[ MAX_NEWS_STRING ];
// demo information
char demoName[MAX_QPATH];
diff --git a/src/qcommon/q_shared.h b/src/qcommon/q_shared.h
index 34f3e471..59c5b91d 100644
--- a/src/qcommon/q_shared.h
+++ b/src/qcommon/q_shared.h
@@ -204,6 +204,7 @@ typedef int clipHandle_t;
#define BIG_INFO_KEY 8192
#define BIG_INFO_VALUE 8192
+#define MAX_NEWS_STRING 10000
#define MAX_QPATH 64 // max length of a quake game pathname
#ifdef PATH_MAX
diff --git a/src/ui/ui_local.h b/src/ui/ui_local.h
index 241cb6d8..1f7ecf40 100644
--- a/src/ui/ui_local.h
+++ b/src/ui/ui_local.h
@@ -41,6 +41,7 @@ int UI_AdjustTimeByGame( int time );
void UI_ClearScores( void );
void UI_LoadArenas( void );
void UI_ServerInfo( void );
+void UI_UpdateNews( qboolean );
void UI_RegisterCvars( void );
void UI_UpdateCvars( void );
@@ -53,6 +54,8 @@ void UI_DrawConnectScreen( qboolean overlay );
#define MAX_DISPLAY_SERVERS 2048
#define MAX_SERVERSTATUS_LINES 128
#define MAX_SERVERSTATUS_TEXT 1024
+#define MAX_NEWS_LINES 50
+#define MAX_NEWS_LINEWIDTH 85
#define MAX_FOUNDPLAYER_SERVERS 16
#define MAX_MODS 64
#define MAX_DEMOS 256
@@ -148,6 +151,15 @@ serverStatusInfo_t;
typedef struct
{
+ char text[MAX_NEWS_LINES][MAX_NEWS_LINEWIDTH];
+ int numLines;
+ qboolean refreshActive;
+ int refreshtime;
+}
+newsInfo_t;
+
+typedef struct
+{
const char *modName;
const char *modDescr;
}
@@ -262,6 +274,9 @@ typedef struct
serverStatus_t serverStatus;
+ // for showing the game news window
+ newsInfo_t newsInfo;
+
// for the showing the status of a server
char serverStatusAddress[MAX_ADDRESSLENGTH];
serverStatusInfo_t serverStatusInfo;
@@ -365,6 +380,7 @@ int trap_LAN_AddServer( int source, const char *name, const char *addr );
void trap_LAN_RemoveServer( int source, const char *addr );
void trap_LAN_ResetPings( int n );
int trap_LAN_ServerStatus( const char *serverAddress, char *serverStatus, int maxLen );
+qboolean trap_GetNews( qboolean force );
int trap_LAN_CompareServers( int source, int sortKey, int sortDir, int s1, int s2 );
int trap_MemoryRemaining( void );
void trap_R_RegisterFont( const char *pFontname, int pointSize, fontInfo_t *font );
diff --git a/src/ui/ui_main.c b/src/ui/ui_main.c
index 3eb63c5d..ab96fa3e 100644
--- a/src/ui/ui_main.c
+++ b/src/ui/ui_main.c
@@ -1138,6 +1138,8 @@ void UI_Refresh( int realtime )
UI_BuildServerStatus( qfalse );
// refresh find player list
UI_BuildFindPlayerList( qfalse );
+ // refresh news
+ UI_UpdateNews( qfalse );
}
// draw cursor
@@ -2856,6 +2858,8 @@ static void UI_RunMenuScript( char **args )
}
else if( Q_stricmp( name, "loadServerInfo" ) == 0 )
UI_ServerInfo();
+ else if( Q_stricmp( name, "getNews" ) == 0 )
+ UI_UpdateNews( qtrue );
else if( Q_stricmp( name, "saveControls" ) == 0 )
Controls_SetConfig( qtrue );
else if( Q_stricmp( name, "loadControls" ) == 0 )
@@ -3356,6 +3360,8 @@ static int UI_FeederCount( float feederID )
return uiInfo.serverStatus.numFeaturedServers;
else if( feederID == FEEDER_SERVERSTATUS )
return uiInfo.serverStatusInfo.numLines;
+ else if( feederID == FEEDER_NEWS )
+ return uiInfo.newsInfo.numLines;
else if( feederID == FEEDER_FINDPLAYER )
return uiInfo.numFoundPlayerServers;
else if( feederID == FEEDER_PLAYER_LIST )
@@ -3524,6 +3530,13 @@ static const char *UI_FeederItemText( float feederID, int index, int column, qha
return uiInfo.serverStatusInfo.lines[index][column];
}
}
+ else if( feederID == FEEDER_NEWS )
+ {
+ if( index >= 0 && index < uiInfo.newsInfo.numLines )
+ {
+ return uiInfo.newsInfo.text[index];
+ }
+ }
else if( feederID == FEEDER_FINDPLAYER )
{
if( index >= 0 && index < uiInfo.numFoundPlayerServers )
@@ -4473,3 +4486,68 @@ void UI_UpdateCvars( void )
for( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ )
trap_Cvar_Update( cv->vmCvar );
}
+
+/*
+=================
+UI_UpdateNews
+=================
+*/
+void UI_UpdateNews( qboolean begin )
+{
+ char newsString[ MAX_NEWS_STRING ];
+ const char *c;
+ const char *wrapped;
+ int line = 0;
+ int linePos = 0;
+ qboolean finished;
+
+ if( begin && !uiInfo.newsInfo.refreshActive ) {
+ uiInfo.newsInfo.refreshtime = uiInfo.uiDC.realTime + 10000;
+ uiInfo.newsInfo.refreshActive = qtrue;
+ }
+ else if( !uiInfo.newsInfo.refreshActive ) // do nothing
+ return;
+ else if( uiInfo.uiDC.realTime > uiInfo.newsInfo.refreshtime ) {
+ strcpy( uiInfo.newsInfo.text[ 0 ],
+ "^1Error: Timed out while contacting the server.");
+ uiInfo.newsInfo.numLines = 1;
+ return;
+ }
+
+ // start the news fetching
+ finished = trap_GetNews( begin );
+
+ // parse what comes back. Parse newlines and otherwise chop when necessary
+ trap_Cvar_VariableStringBuffer( "cl_newsString", newsString,
+ sizeof( newsString ) );
+
+ wrapped = Item_Text_Wrap( newsString, .25, 300 );
+
+ for( c = wrapped; *c != '\0'; ++c ) {
+ if( linePos == (MAX_NEWS_LINEWIDTH - 1) || *c == '\n' ) {
+ uiInfo.newsInfo.text[ line ][ linePos ] = '\0';
+
+ if( line == ( MAX_NEWS_LINES - 1 ) )
+ break;
+
+ linePos = 0;
+ line++;
+
+ if( *c != '\n' ) {
+ uiInfo.newsInfo.text[ line ][ linePos ] = *c;
+ linePos++;
+ }
+ } else if( isprint( *c ) ) {
+ uiInfo.newsInfo.text[ line ][ linePos ] = *c;
+ linePos++;
+ }
+ }
+
+ uiInfo.newsInfo.text[ line ] [linePos ] = '\0';
+ uiInfo.newsInfo.numLines = line + 1;
+
+ if( finished )
+ uiInfo.newsInfo.refreshActive = qfalse;
+
+}
+
diff --git a/src/ui/ui_public.h b/src/ui/ui_public.h
index 26c6fbd4..bcaf3d5c 100644
--- a/src/ui/ui_public.h
+++ b/src/ui/ui_public.h
@@ -126,6 +126,7 @@ typedef enum
UI_PARSE_FREE_SOURCE,
UI_PARSE_READ_TOKEN,
UI_PARSE_SOURCE_FILE_AND_LINE,
+ UI_GETNEWS,
UI_MEMSET = 100,
UI_MEMCPY,
diff --git a/src/ui/ui_syscalls.asm b/src/ui/ui_syscalls.asm
index fb37c736..0880d419 100644
--- a/src/ui/ui_syscalls.asm
+++ b/src/ui/ui_syscalls.asm
@@ -86,6 +86,7 @@ equ trap_Parse_LoadSource -82
equ trap_Parse_FreeSource -83
equ trap_Parse_ReadToken -84
equ trap_Parse_SourceFileAndLine -85
+equ trap_GetNews -86
equ memset -101
diff --git a/src/ui/ui_syscalls.c b/src/ui/ui_syscalls.c
index f1d252cd..29938149 100644
--- a/src/ui/ui_syscalls.c
+++ b/src/ui/ui_syscalls.c
@@ -322,6 +322,11 @@ int trap_LAN_ServerStatus( const char *serverAddress, char *serverStatus, int ma
return syscall( UI_LAN_SERVERSTATUS, serverAddress, serverStatus, maxLen );
}
+qboolean trap_GetNews( qboolean force )
+{
+ return syscall( UI_GETNEWS, force );
+}
+
void trap_LAN_SaveCachedServers( void )
{
syscall( UI_LAN_SAVECACHEDSERVERS );