00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef CONSOLE_H
00023 #define CONSOLE_H
00024
00025 #include "istring.h"
00026 #include <map>
00027 #include <vector>
00028 #include <cstdarg>
00029
00030
00031
00032
00033 #define CON_TEXTSIZE 32768
00034 #define CON_PUTCHAR_SIZE 256
00035 #define CON_NUM_TIMES 4
00036
00037
00038 #define CON_STDOUT 0x01
00039 #define CON_STDERR 0x02
00040
00041 class ODataSource;
00042 class RenderSurface;
00043 struct FixedWidthFont;
00044
00045 enum MsgMask {
00046
00047 MM_NONE=0x00,
00048
00049
00050 MM_INFO=0x01,
00051
00052
00053
00054
00055 MM_MINOR_WARN=0x02,
00056
00057 MM_MAJOR_WARN=0x04,
00058
00059 MM_MINOR_ERR=0x08,
00060
00061
00062
00063
00064
00065 MM_MAJOR_ERR=0x10,
00066
00067
00068
00069
00070
00071 MM_TERMINAL_ERR=0x20,
00072
00073 MM_ALL=0x3F
00074
00075
00076
00077
00078
00079
00080
00081 };
00082
00083 class Console
00084 {
00085 char text[CON_TEXTSIZE];
00086 sint32 current;
00087 sint32 x;
00088 sint32 display;
00089
00090 sint32 linewidth;
00091 sint32 totallines;
00092
00093 sint32 vislines;
00094
00095 bool wordwrap;
00096 bool cr;
00097
00098 sint32 putchar_count;
00099 char putchar_buf[CON_PUTCHAR_SIZE];
00100
00101 uint32 std_output_enabled;
00102
00103
00104 ODataSource *stdout_redir;
00105 ODataSource *stderr_redir;
00106
00107
00108 FixedWidthFont *confont;
00109
00110 void (*auto_paint)(void);
00111
00112 MsgMask msgMask;
00113
00114
00115 uint32 framenum;
00116 uint32 times[CON_NUM_TIMES];
00117
00118 public:
00119 enum SpecialChars
00120 {
00121 Tab = '\t',
00122 Backspace = '\b',
00123 Enter = '\n'
00124 };
00125
00126
00127 Console();
00128 ~Console();
00129
00130
00131 void Clear();
00132
00133
00134 void Dump (const char *name);
00135
00136
00137 void CheckResize (int scrwidth);
00138
00139
00140 void DrawConsole (RenderSurface *surf, int height);
00141
00142
00143 void DrawConsoleNotify (RenderSurface *surf);
00144
00145
00146 void SetConFont(FixedWidthFont *cf) { confont = cf; }
00147
00148
00149 FixedWidthFont *GetConFont() { return confont; }
00150
00151
00152 void SetAutoPaint(void (*func)(void)) { auto_paint = func; }
00153
00154
00155 void ScrollConsole(sint32 lines);
00156
00157
00158 void RedirectOutputStream(uint32 mask, ODataSource *ds)
00159 {
00160 if (mask & CON_STDOUT) stdout_redir = ds;
00161 if (mask & CON_STDERR) stderr_redir = ds;
00162 }
00163
00164
00165 void setOutputEnabled(uint32 mask)
00166 {
00167 std_output_enabled |= mask;
00168 }
00169
00170
00171 void unsetOutputEnabled(uint32 mask)
00172 {
00173 std_output_enabled &= ~mask;
00174 }
00175
00176
00177 uint32 getOutputEnabled()
00178 {
00179 return std_output_enabled;
00180 }
00181
00182
00183 void setMsgMask(const MsgMask mm)
00184 {
00185 msgMask = mm;
00186 }
00187
00188 void setFrameNum(uint32 f)
00189 {
00190 framenum = f;
00191 }
00192
00193
00194
00195
00196
00197
00198 void Print(const char *txt);
00199 void Print(const MsgMask mm, const char *txt);
00200
00201
00202 sint32 Printf(const char *fmt, ...);
00203 sint32 Printf(const MsgMask mm, const char *fmt, ...);
00204
00205
00206 int vPrintf (const char *fmt, va_list);
00207
00208
00209 void Putchar (int c);
00210
00211
00212 void PrintRaw (const char *txt, int n);
00213
00214
00215
00216
00217
00218
00219
00220 void Print_err(const char *txt);
00221 void Print_err(const MsgMask mm, const char *txt);
00222
00223
00224 sint32 Printf_err(const char *fmt, ...);
00225 sint32 Printf_err(const MsgMask mm, const char *fmt, ...);
00226
00227
00228 int vPrintf_err (const char *fmt, va_list);
00229
00230
00231 void Putchar_err (int c);
00232
00233
00234 void PrintRaw_err (const char *txt, int n);
00235
00236
00237
00238 void EnableWordWrap() { wordwrap = true; }
00239 void DisableWordWrap() { wordwrap = false; }
00240
00241
00242
00243
00244
00245 typedef Pentagram::istring ArgsType;
00246 typedef std::vector<ArgsType> ArgvType;
00247 typedef void (*Function)(const ArgvType &argv);
00248
00252 void AddConsoleCommand(const ArgsType &command, Console::Function function);
00253
00256 void RemoveConsoleCommand(Console::Function function);
00257
00260 void ExecuteConsoleCommand(const Console::ArgsType &args);
00261
00264 void ExecuteConsoleCommand(const Console::ArgvType &argv);
00265
00267 void ExecuteCommandBuffer();
00268
00271 void ScrollCommandHistory(int num);
00272
00274 void ClearCommandBuffer();
00275
00281 void AddCharacterToCommandBuffer(int ch);
00282
00285 void DeleteCommandBufferChars(int num);
00286
00289 void MoveCommandCursor(int num);
00290
00292 void ToggleCommandInsert() { commandInsert = !commandInsert; }
00293
00295 static void ConCmd_CmdList(const Console::ArgvType &argv);
00296
00298 static void ConCmd_CmdHistory(const Console::ArgvType &argv);
00299
00300 private:
00301
00302
00303 void PrintInternal (const char *txt);
00304
00305
00306 void PrintRawInternal (const char *txt, int n);
00307
00308
00309 void PutcharInternal (int c);
00310
00311
00312 void Linefeed ();
00313
00314
00315 void PrintPutchar();
00316
00317
00318 ArgsType commandBuffer;
00319 int commandCursorPos;
00320 bool commandInsert;
00321 std::vector<ArgsType> commandHistory;
00322 int commandHistoryPos;
00323 std::map<ArgsType,Function> ConsoleCommands;
00324
00325 };
00326
00327
00328 extern Console con;
00329
00330
00331
00332
00333
00334 #include <ostream>
00335
00336
00337
00338
00339 template<class _E, class _Tr = std::char_traits<_E> >
00340 class console_streambuf : public std::basic_streambuf<_E, _Tr>
00341 {
00342 public:
00343 console_streambuf() : std::basic_streambuf<_E, _Tr>() { }
00344 virtual ~console_streambuf() { }
00345 typedef typename _Tr::int_type int_type;
00346 typedef typename _Tr::char_type char_type;
00347
00348 protected:
00349
00350
00351 virtual int_type overflow(int_type c = _Tr::eof())
00352 {
00353 if (!_Tr::eq_int_type(_Tr::eof(), c)) con.Putchar(_Tr::to_char_type(c));
00354 return (_Tr::not_eof(c));
00355 }
00356
00357
00358 virtual int sync()
00359 {
00360 return 0;
00361 }
00362 };
00363
00364
00365
00366
00367 template<class _E, class _Tr = std::char_traits<_E> >
00368 class console_ostream : public std::basic_ostream<_E, _Tr>
00369 {
00370
00371 console_streambuf<_E, _Tr> _Fb;
00372
00373
00374 public:
00375 console_ostream() : std::basic_ostream<_E, _Tr>(&_Fb), _Fb() {}
00376 console_ostream(console_streambuf<_E, _Tr> *Fb) : std::basic_ostream<_E, _Tr>(Fb) {}
00377 virtual ~console_ostream() { }
00378
00379 #if defined(MACOSX) && defined(__GNUC__)
00380
00381 int __attribute__ ((noinline)) printf (const char *fmt, ...)
00382 #else
00383 int printf (const char *fmt, ...)
00384 #endif
00385 {
00386 va_list argptr;
00387 va_start (argptr,fmt);
00388 int ret = con.vPrintf(fmt, argptr);
00389 va_end (argptr);
00390 return ret;
00391 }
00392 };
00393
00394
00395
00396
00397 #ifndef SAFE_CONSOLE_STREAMS
00398 extern console_ostream<char> pout;
00399 extern console_ostream<char> *ppout;
00400 #else
00401 #define pout (*ppout)
00402 extern console_ostream<char> *ppout;
00403 #endif
00404
00405
00406
00407
00408 template<class _E, class _Tr = std::char_traits<_E> >
00409 class console_err_streambuf : public std::basic_streambuf<_E, _Tr>
00410 {
00411 public:
00412 console_err_streambuf() : std::basic_streambuf<_E, _Tr>() { }
00413 virtual ~console_err_streambuf() { }
00414 typedef typename _Tr::int_type int_type;
00415 typedef typename _Tr::char_type char_type;
00416
00417 protected:
00418
00419
00420 virtual int_type overflow(int_type c = _Tr::eof())
00421 {
00422 if (!_Tr::eq_int_type(_Tr::eof(), c)) con.Putchar_err(_Tr::to_char_type(c));
00423 return (_Tr::not_eof(c));
00424 }
00425
00426
00427 virtual int sync()
00428 {
00429 return 0;
00430 }
00431 };
00432
00433
00434
00435
00436 template<class _E, class _Tr = std::char_traits<_E> >
00437 class console_err_ostream : public std::basic_ostream<_E, _Tr>
00438 {
00439
00440 console_err_streambuf<_E, _Tr> _Fb;
00441
00442
00443 public:
00444 console_err_ostream() : std::basic_ostream<_E, _Tr>(&_Fb), _Fb() {}
00445 console_err_ostream(console_err_streambuf<_E, _Tr> *Fb) : std::basic_ostream<_E, _Tr>(Fb) {}
00446 virtual ~console_err_ostream() { }
00447
00448 #if defined(MACOSX) && defined(__GNUC__)
00449
00450 int __attribute__ ((noinline)) printf (const char *fmt, ...)
00451 #else
00452 int printf (const char *fmt, ...)
00453 #endif
00454 {
00455 va_list argptr;
00456 va_start (argptr,fmt);
00457 int ret = con.vPrintf_err(fmt, argptr);
00458 va_end (argptr);
00459 return ret;
00460 }
00461
00462 };
00463
00464
00465
00466
00467 #ifndef SAFE_CONSOLE_STREAMS
00468 extern console_err_ostream<char> perr;
00469 extern console_err_ostream<char> *pperr;
00470 #else
00471 #define perr (*pperr)
00472 extern console_err_ostream<char> *pperr;
00473 #endif
00474
00475 #endif // CONSOLE_H