aboutsummaryrefslogtreecommitdiff
path: root/src/lprintf.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lprintf.c')
-rw-r--r--src/lprintf.c382
1 files changed, 382 insertions, 0 deletions
diff --git a/src/lprintf.c b/src/lprintf.c
new file mode 100644
index 0000000..0951cf3
--- /dev/null
+++ b/src/lprintf.c
@@ -0,0 +1,382 @@
1/* Emacs style mode select -*- C++ -*-
2 *-----------------------------------------------------------------------------
3 *
4 *
5 * PrBoom: a Doom port merged with LxDoom and LSDLDoom
6 * based on BOOM, a modified and improved DOOM engine
7 * Copyright (C) 1999 by
8 * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
9 * Copyright (C) 1999-2000 by
10 * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
11 * Copyright 2005, 2006 by
12 * Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 * 02111-1307, USA.
28 *
29 * DESCRIPTION:
30 * Provides a logical console output routine that allows what is
31 * output to console normally and when output is redirected to
32 * be controlled..
33 *
34 *-----------------------------------------------------------------------------*/
35
36#ifdef HAVE_CONFIG_H
37#include "config.h"
38#endif
39#ifdef _WIN32
40#define WIN32_LEAN_AND_MEAN
41#include <windows.h>
42#endif
43#ifdef _MSC_VER
44#include <io.h>
45#endif
46#include <stdio.h>
47#include <stdlib.h>
48#include <stdarg.h>
49#ifdef HAVE_UNISTD_H
50#include <unistd.h>
51#endif
52#include "doomtype.h"
53#include "lprintf.h"
54#include "i_main.h"
55#include "m_argv.h"
56
57int cons_error_mask = -1-LO_INFO; /* all but LO_INFO when redir'd */
58int cons_output_mask = -1; /* all output enabled */
59
60/* cphipps - enlarged message buffer and made non-static
61 * We still have to be careful here, this function can be called after exit
62 */
63#define MAX_MESSAGE_SIZE 2048
64
65#ifdef _WIN32
66// Variables for the console
67HWND con_hWnd=0;
68HFONT OemFont;
69LONG OemWidth, OemHeight;
70int ConWidth,ConHeight;
71char szConName[] = "PrBoomConWinClass";
72char Lines[(80+2)*25+1];
73char *Last = NULL;
74boolean console_inited=FALSE;
75static boolean should_exit = 0;
76
77static CALLBACK ConWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
78{
79 PAINTSTRUCT paint;
80 HDC dc;
81
82 switch (iMsg) {
83 case WM_KEYDOWN:
84 if (wParam == VK_ESCAPE)
85 should_exit = 1;
86 break;
87 case WM_CLOSE:
88 return 1;
89 break;
90 case WM_PAINT:
91 if (dc = BeginPaint (con_hWnd, &paint))
92 {
93 if (Last)
94 {
95 char *row;
96 int line, last;
97
98 line = paint.rcPaint.top / OemHeight;
99 last = paint.rcPaint.bottom / OemHeight;
100 for (row = Lines + (line*(80+2)); line < last; line++)
101 {
102 if (row[1]>0)
103 TextOut (dc, 0, line * OemHeight, &row[2], row[1]);
104 row += 80 + 2;
105 }
106 }
107 EndPaint (con_hWnd, &paint);
108 }
109 return 0;
110 break;
111 default:
112 break;
113 }
114 return(DefWindowProc(hwnd,iMsg,wParam,lParam));
115}
116
117static void I_PrintStr (int xp, const char *cp, int count, BOOL scroll) {
118 RECT rect;
119 HDC conDC;
120
121 if ((!con_hWnd) || (!console_inited))
122 return;
123 if (count)
124 {
125 conDC=GetDC(con_hWnd);
126 TextOut (conDC, xp * OemWidth, ConHeight - OemHeight, cp, count);
127 ReleaseDC(con_hWnd,conDC);
128 }
129 if (scroll) {
130 rect.left = 0;
131 rect.top = 0;
132 rect.right = ConWidth;
133 rect.bottom = ConHeight;
134 ScrollWindowEx (con_hWnd, 0, -OemHeight, NULL, &rect, NULL, NULL, SW_ERASE|SW_INVALIDATE);
135 UpdateWindow (con_hWnd);
136 }
137}
138
139static int I_ConPrintString (const char *outline)
140{
141 const char *cp, *newcp;
142 static int xp = 0;
143 int newxp;
144 BOOL scroll;
145
146 if (!console_inited)
147 return 0;
148 cp = outline;
149 while (*cp) {
150 for (newcp = cp, newxp = xp;
151 *newcp != '\n' && *newcp != '\0' && newxp < 80;
152 newcp++) {
153 if (*newcp == '\x08') {
154 newxp--;
155 break;
156 }
157 else if (*newcp == '\t') {
158 newxp = ((newxp + 8) / 8) * 8;
159 break;
160 }
161 else
162 newxp++;
163 }
164
165 if (*cp) {
166 const char *poop;
167 int x;
168
169 for (x = xp, poop = cp; poop < newcp; poop++, x++) {
170 Last[x+2] = ((*poop) < 32) ? 32 : (*poop);
171 }
172
173 if (*newcp == '\t')
174 for (x = xp; x < newxp; x++)
175 Last[x+2] = ' ';
176
177 if (Last[1] < xp + (newcp - cp))
178 Last[1] = xp + (newcp - cp);
179
180 if (*newcp == '\n' || xp == 80) {
181 if (*newcp != '\n') {
182 Last[0] = 1;
183 }
184 memmove (Lines, Lines + (80 + 2), (80 + 2) * (25 - 1));
185 Last[0] = 0;
186 Last[1] = 0;
187 newxp = 0;
188 scroll = TRUE;
189 } else {
190 scroll = FALSE;
191 }
192 I_PrintStr (xp, cp, newcp - cp, scroll);
193
194 xp = newxp;
195
196 if ((*newcp == '\n') || (*newcp == '\x08') || (*newcp == '\t'))
197 cp = newcp + 1;
198 else
199 cp = newcp;
200 }
201 }
202
203 return strlen (outline);
204}
205
206void I_ConTextAttr(unsigned char a)
207{
208 int r,g,b,col;
209 HDC conDC;
210
211 if (!console_inited)
212 return;
213 conDC=GetDC(con_hWnd);
214 r=0; g=0; b=0;
215 if (a & FOREGROUND_INTENSITY) col=255;
216 else col=128;
217 if (a & FOREGROUND_RED) r=col;
218 if (a & FOREGROUND_GREEN) g=col;
219 if (a & FOREGROUND_BLUE) b=col;
220 SetTextColor(conDC, PALETTERGB(r,g,b));
221 r=0; g=0; b=0;
222 if (a & BACKGROUND_INTENSITY) col=255;
223 else col=128;
224 if (a & BACKGROUND_RED) r=col;
225 if (a & BACKGROUND_GREEN) g=col;
226 if (a & BACKGROUND_BLUE) b=col;
227 SetBkColor(conDC, PALETTERGB(r,g,b));
228 ReleaseDC(con_hWnd,conDC);
229}
230
231void I_UpdateConsole(void)
232{
233 MSG msg;
234
235 UpdateWindow(con_hWnd);
236 while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) > 0)
237 {
238 TranslateMessage(&msg);
239 DispatchMessage(&msg);
240 }
241 if (should_exit)
242 exit(0);
243}
244
245static void Init_Console(void)
246{
247 memset(Lines,0,25*(80+2)+1);
248 Last = Lines + (25 - 1) * (80 + 2);
249 console_inited=TRUE;
250}
251
252int Init_ConsoleWin(void)
253{
254 HDC conDC;
255 WNDCLASS wndclass;
256 TEXTMETRIC metrics;
257 RECT cRect;
258 int width,height;
259 int scr_width,scr_height;
260 HINSTANCE hInstance;
261 char titlebuffer[2048];
262
263 if (con_hWnd)
264 return TRUE;
265 hInstance = GetModuleHandle(NULL);
266 Init_Console();
267 /* Register the frame class */
268 wndclass.style = CS_OWNDC;
269 wndclass.lpfnWndProc = (WNDPROC)ConWndProc;
270 wndclass.cbClsExtra = 0;
271 wndclass.cbWndExtra = 0;
272 wndclass.hInstance = hInstance;
273 wndclass.hIcon = LoadIcon (hInstance, IDI_WINLOGO);
274 wndclass.hCursor = LoadCursor (NULL,IDC_ARROW);
275 wndclass.hbrBackground = (HBRUSH)GetStockObject (BLACK_BRUSH);
276 wndclass.lpszMenuName = szConName;
277 wndclass.lpszClassName = szConName;
278
279 if (!RegisterClass(&wndclass))
280 return FALSE;
281
282 width=100;
283 height=100;
284 strcpy(titlebuffer,PACKAGE);
285 strcat(titlebuffer," ");
286 strcat(titlebuffer,VERSION);
287 strcat(titlebuffer," console");
288 con_hWnd = CreateWindow(szConName, titlebuffer,
289 WS_CAPTION | WS_POPUP,
290 0, 0, width, height,
291 NULL, NULL, hInstance, NULL);
292 conDC=GetDC(con_hWnd);
293 OemFont = GetStockObject(OEM_FIXED_FONT);
294 SelectObject(conDC, OemFont);
295 GetTextMetrics(conDC, &metrics);
296 OemWidth = metrics.tmAveCharWidth;
297 OemHeight = metrics.tmHeight;
298 GetClientRect(con_hWnd, &cRect);
299 width += (OemWidth * 80) - cRect.right;
300 height += (OemHeight * 25) - cRect.bottom;
301 // proff 11/09/98: Added code for centering console
302 scr_width = GetSystemMetrics(SM_CXFULLSCREEN);
303 scr_height = GetSystemMetrics(SM_CYFULLSCREEN);
304 MoveWindow(con_hWnd, (scr_width-width)/2, (scr_height-height)/2, width, height, TRUE);
305 GetClientRect(con_hWnd, &cRect);
306 ConWidth = cRect.right;
307 ConHeight = cRect.bottom;
308 SetTextColor(conDC, RGB(192,192,192));
309 SetBkColor(conDC, RGB(0,0,0));
310 SetBkMode(conDC, OPAQUE);
311 ReleaseDC(con_hWnd,conDC);
312 ShowWindow(con_hWnd, SW_SHOW);
313 UpdateWindow(con_hWnd);
314 return TRUE;
315}
316
317void Done_ConsoleWin(void)
318{
319 if (con_hWnd)
320 DestroyWindow(con_hWnd);
321 UnregisterClass(szConName,GetModuleHandle(NULL));
322 con_hWnd=0;
323}
324#endif
325
326int lprintf(OutputLevels pri, const char *s, ...)
327{
328 int r=0;
329 char msg[MAX_MESSAGE_SIZE];
330 int lvl=pri;
331
332 va_list v;
333 va_start(v,s);
334#ifdef HAVE_VSNPRINTF
335 vsnprintf(msg,sizeof(msg),s,v); /* print message in buffer */
336#else
337 vsprintf(msg,s,v);
338#endif
339 va_end(v);
340
341 if (lvl&cons_output_mask) /* mask output as specified */
342 {
343 r=fprintf(stdout,"%s",msg);
344#ifdef _WIN32
345 I_ConPrintString(msg);
346#endif
347 }
348 if (!isatty(1) && lvl&cons_error_mask) /* if stdout redirected */
349 r=fprintf(stderr,"%s",msg); /* select output at console */
350
351 return r;
352}
353
354/*
355 * I_Error
356 *
357 * cphipps - moved out of i_* headers, to minimise source files that depend on
358 * the low-level headers. All this does is print the error, then call the
359 * low-level safe exit function.
360 * killough 3/20/98: add const
361 */
362
363void I_Error(const char *error, ...)
364{
365 char errmsg[MAX_MESSAGE_SIZE];
366 va_list argptr;
367 va_start(argptr,error);
368#ifdef HAVE_VSNPRINTF
369 vsnprintf(errmsg,sizeof(errmsg),error,argptr);
370#else
371 vsprintf(errmsg,error,argptr);
372#endif
373 va_end(argptr);
374 lprintf(LO_ERROR, "%s\n", errmsg);
375#ifdef _MSC_VER
376 if (!M_CheckParm ("-nodraw")) {
377 //Init_ConsoleWin();
378 MessageBox(con_hWnd,errmsg,"PrBoom",MB_OK | MB_TASKMODAL | MB_TOPMOST);
379 }
380#endif
381 I_SafeExit(-1);
382}