1 /*
2 ===========================================================================
3 Copyright (C) 1999-2005 Id Software, Inc.
4 
5 This file is part of Quake III Arena source code.
6 
7 Quake III Arena source code is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the License,
10 or (at your option) any later version.
11 
12 Quake III Arena source code is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Quake III Arena source code; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 ===========================================================================
21 */
22 
23 #include "../qcommon/q_shared.h"
24 #include "../qcommon/qcommon.h"
25 #include "sys_local.h"
26 
27 #define MAX_LOG 32768
28 
29 static char          consoleLog[ MAX_LOG ];
30 static unsigned int  writePos = 0;
31 static unsigned int  readPos = 0;
32 
33 /*
34 ==================
35 CON_LogSize
36 ==================
37 */
CON_LogSize(void)38 unsigned int CON_LogSize( void )
39 {
40 	if( readPos <= writePos )
41 		return writePos - readPos;
42 	else
43 		return writePos + MAX_LOG - readPos;
44 }
45 
46 /*
47 ==================
48 CON_LogFree
49 ==================
50 */
CON_LogFree(void)51 static unsigned int CON_LogFree( void )
52 {
53 	return MAX_LOG - CON_LogSize( ) - 1;
54 }
55 
56 /*
57 ==================
58 CON_LogWrite
59 ==================
60 */
CON_LogWrite(const char * in)61 unsigned int CON_LogWrite( const char *in )
62 {
63 	unsigned int length = strlen( in );
64 	unsigned int firstChunk;
65 	unsigned int secondChunk;
66 
67 	while( CON_LogFree( ) < length && CON_LogSize( ) > 0 )
68 	{
69 		// Free enough space
70 		while( consoleLog[ readPos ] != '\n' && CON_LogSize( ) > 1 )
71 			readPos = ( readPos + 1 ) % MAX_LOG;
72 
73 		// Skip past the '\n'
74 		readPos = ( readPos + 1 ) % MAX_LOG;
75 	}
76 
77 	if( CON_LogFree( ) < length )
78 		return 0;
79 
80 	if( writePos + length > MAX_LOG )
81 	{
82 		firstChunk  = MAX_LOG - writePos;
83 		secondChunk = length - firstChunk;
84 	}
85 	else
86 	{
87 		firstChunk  = length;
88 		secondChunk = 0;
89 	}
90 
91 	Com_Memcpy( consoleLog + writePos, in, firstChunk );
92 	Com_Memcpy( consoleLog, in + firstChunk, secondChunk );
93 
94 	writePos = ( writePos + length ) % MAX_LOG;
95 
96 	return length;
97 }
98 
99 /*
100 ==================
101 CON_LogRead
102 ==================
103 */
CON_LogRead(char * out,unsigned int outSize)104 unsigned int CON_LogRead( char *out, unsigned int outSize )
105 {
106 	unsigned int firstChunk;
107 	unsigned int secondChunk;
108 
109 	if( CON_LogSize( ) < outSize )
110 		outSize = CON_LogSize( );
111 
112 	if( readPos + outSize > MAX_LOG )
113 	{
114 		firstChunk  = MAX_LOG - readPos;
115 		secondChunk = outSize - firstChunk;
116 	}
117 	else
118 	{
119 		firstChunk  = outSize;
120 		secondChunk = 0;
121 	}
122 
123 	Com_Memcpy( out, consoleLog + readPos, firstChunk );
124 	Com_Memcpy( out + firstChunk, consoleLog, secondChunk );
125 
126 	readPos = ( readPos + outSize ) % MAX_LOG;
127 
128 	return outSize;
129 }
130