Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
rendertext.cpp
Go to the documentation of this file.
1 //rendertext.cpp: based on Don's gl_text.cpp
2 //Based on Aardarples rendertext
3 #include "config.h"
4 #include "command.h"
5 
6 #include "vegastrike.h"
7 #include "cg_global.h"
8 #ifdef HAVE_SDL
9 #include "SDL/SDL.h"
10 #endif
11 #include "gfx/hud.h"
12 #include "gldrv/winsys.h"
13 #include <sstream>
14 #include <string>
15 #include <vector>
16 
17 using std::vector;
18 using std::string;
19 using std::ostringstream;
20 using std::cout;
21 using std::endl;
22 
23 //****************
24 //Console Rendering System by Rogue
25 //2005-08-a-few-days
26 //
27 //****************
28 
29 #ifdef HAVE_SDL
30 static SDL_mutex * _rtextSDLMutex()
31 {
32  static SDL_mutex *rv = SDL_CreateMutex();
33  return rv;
34 }
35 #endif
36 
37 //Render Text (Console) Constructor {{{
39 {
40 #ifdef HAVE_SDL
41  //Initialize shared mutex
42  //(creation is always single-threaded, since no aliases are possible yet)
43  _rtextSDLMutex();
44 #endif
45 
46  ndraw = 15;
47  WORDWRAP = 85;
48  conskip = 0;
49  saycommand( "" );
50 }
52 //Set the text width, not used .. yet{{{
53 int RText::text_width( char *str )
54 {
55  return 0;
56 }
57 //Should be unused defines {{{
58 #define VIRTW 2400
59 #define VIRTH 1800
60 #define PIXELTAB (VIRTW/12)
61 #define FONTH 64
62 //Draw text, used by the console, should be private, use conoutf to print to the console {{{
63 void RText::draw_text( std::string &str, float left, float top, int gl_num )
64 {
65  int x = float_to_int( left );
66  int y = float_to_int( top );
67 
68  std::string::iterator iter = str.begin();
69  GFXColor foreground( 1, 1, 1, 1 );
70  GFXColor background( 0.05f, 0.05f, 0.2f, 0.5f );
71  TextPlane newTextPlane( foreground, background );
72  newTextPlane.SetPos( x, y );
73  newTextPlane.SetCharSize( .8, .12 );
74  newTextPlane.Draw( str );
75 }
76 //render the console, only call if bool console == true {{{
77 void RText::renderconsole() //render buffer
78 {
79  int nd = 0;
80  vector< string >refs;
81  bool breaker = false;
82  for (vector< cline >::iterator iter = conlines.begin(); iter < conlines.end(); iter++) {
83  if (nd < ndraw)
84  refs.push_back( ( *(iter) ).cref );
85  else iter = conlines.end();
86  nd++;
87  }
88  size_t j = 0;
89  float x = -1;
90  float y = -0.5;
91  string workIt;
92  workIt.append( "\n" );
93  bool breakout = true;
94  vector< string >::iterator iter = refs.end();
95  if ( iter == refs.begin() ) breakout = false;
96  for (; breakout;) {
97  iter--;
98  if ( iter == refs.begin() ) breakout = false;
99  workIt.append( ( *(iter) ) );
100  workIt.append( "\n" );
101  }
102  y = 1;
103  ostringstream drawCommand;
104  string shorter;
105  shorter.append( getcurcommand() );
106  while (shorter.size() > 80)
107  shorter.erase( shorter.begin() );
108  //erase the front of the current command while it's larger than 80
109  //charactors, as to not draw off the screen
110  drawCommand<<workIt<<"#FF1100> "<<"#FF1100"<<shorter<<"#00000";
111  string Acdraw; //passing .str() straight to draw_text produces an
112  //error with gcc 4, because it's constant I believe
113  Acdraw.append( drawCommand.str() );
114  draw_text( Acdraw, x, y, 2 );
115 }
116 //append a line to the console, optional "highlight" method , untested {{{
117 void RText::conline( string &sf, bool highlight ) //add a line to the console buffer
118 {
119  {
120  size_t search = 0;
121  size_t lastsearch = 0;
122  for (; ( search = sf.find( "/r" ) ) != string::npos;) {
123  sf.replace( lastsearch, search-lastsearch, "" );
124  lastsearch = search;
125  }
126  }
127  cline cl;
128  int lastmillis = 0;
129  cl.outtime = lastmillis; //for how long to keep line on screen
130  if (highlight) {
131  //show line in a different colour, for chat etc.
132  cl.cref.append( "\f" );
133  cl.cref.append( sf );
134  } else {
135  cl.cref.append( sf );
136  }
137  conlines.insert( conlines.begin(), cl );
138 }
139 //print a line to the console, broken at \n's {{{
140 void RText::conoutf( char *in )
141 {
142  string foobar( in );
143  conoutf( foobar );
144 }
145 
146 void RText::conoutf( string &s, int a, int b, int c )
147 {
148 #ifdef HAVE_SDL
149  //NOTE: first call must be single-threaded!
150  SDL_mutex *mymutex = _rtextSDLMutex();
151  SDL_LockMutex( mymutex );
152 #endif
153  cout<<s<<endl;
154  string::size_type fries = s.size();
155  string customer;
156  for (string::size_type burger = 0; burger < fries; burger++) {
157  if (s[burger] == '\n' || burger == fries-1) {
158  if (burger == fries-1)
159  if (s[fries-1] != '\n' && s[fries-1] != '\r')
160  customer += s[burger];
161  conline( customer, 1 );
162  customer.erase();
163  } else if ( customer.size() >= static_cast<size_t>(WORDWRAP) ) {
164  customer += s[burger];
165  string fliptheburger;
166  while (customer[customer.size()-1] != ' ') {
167  fliptheburger += customer[customer.size()-1];
168  string::iterator oldfloormeat = customer.end();
169  oldfloormeat--;
170  customer.erase( oldfloormeat );
171  }
172  conline( customer, 1 );
173  customer.erase();
174  {
175  string spatchula;
176  for (int salt = fliptheburger.size()-1; salt >= 0; salt--)
177  spatchula += fliptheburger[salt];
178  fliptheburger.erase();
179  fliptheburger.append( spatchula );
180  }
181  customer.append( fliptheburger );
182  } else if (s[burger] != '\r') {
183  customer += s[burger]; //get fat
184  }
185  }
186 #ifdef HAVE_SDL
187  SDL_UnlockMutex( mymutex );
188 #endif
189 }
190 //same as above, but I think it works better {{{
191 void RText::conoutn( string &s, int a, int b, int c )
192 {
193  size_t x = s.find( "\n" );
194  size_t xlast = 0;
195  if (x >= string::npos)
196  conoutf( s );
197  string::iterator iter = s.end();
198  if ( iter != s.begin() ) {
199  iter--;
200  if (strcmp( &( *(iter) ), "\n" ) != 0) s.append( "\n" );
201  ;
202  }
203  while (x < string::npos) {
204  string part;
205  part.append( s.substr( xlast, x-xlast ) );
206  xlast = x+1;
207  x = s.find( "\n", x+1 );
208  conoutf( part, a, b, c );
209  }
210 }
211 //saycommand(char *), should "say" something, will be useful only with network enabled {{{
212 //does nothing now
213 void RText::saycommand( const char *init ) // DELETE unused
214 {
215 }
216 //Console Keyboard Input {{{
217 void RText::ConsoleKeyboardI( int code, bool isdown )
218 {
219  if (isdown) {
220  switch (code)
221  {
222 //pop teh back of commandbuf
223  case WSK_BACKSPACE:
224  {
225  string::iterator iter = commandbuf.begin();
226  if ( iter < commandbuf.end() ) {
227  iter = commandbuf.end();
228  iter--;
229  commandbuf.erase( iter );
230  }
231  break;
232  }
233  case WSK_LEFT:
234 //this should move a put pointer for commandbuf
235 //right should move it the other way.
236  break;
237 
238  case WSK_RETURN:
239  if (commandbuf[0]) {
240  vector< string >::iterator iter = vhistory.end();
241  bool noSize = false;
242  if ( iter <= vhistory.begin() && iter >= vhistory.end() ) noSize = true;
243  if (!noSize) {
244  iter--;
245  if (commandbuf.compare( ( *(iter) ) ) != 0 && !noSize) {
246 //store what was typed into a vector for a command history
247 //to scroll up and down through what was typed
248 //This "feature" isn't finished
249  vhistory.push_back( commandbuf ); //cap this?
250  }
251  } else if (noSize) {
252  vhistory.push_back( commandbuf );
253  }
254  //commands beginning with / are executed
255  //in localPlayer.cpp just before this is called
256  }
257  if (commandbuf.size() > 0) {
258 //print what was typed - Now done in the command processor
259 //clear the buffer
260  commandbuf.erase();
261  }
262  break;
263  default:
264 //add it to the command buffer
265  if (code > 0 && code < 256) {
266  unsigned char k = (unsigned char) code;
267  commandbuf += k;
268  }
269  break;
270  }
271  }
272 }
273 //}}}
274 //get the current command buffer, to execute at enter {{{
276 {
277  return commandbuf;
278 }
279 //footer, leave at bottom
280 /*
281  * Local variables:
282  * tab-width: 4
283  * c-basic-offset: 4
284  * End:
285  * vim600: sw=4 ts=4 fdm=marker
286  * vim<600: sw=4 ts=4
287  */
288