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, out, secondChunk );
125
126 readPos = ( readPos + outSize ) % MAX_LOG;
127
128 return outSize;
129 }
130