Wing Commander
Reconstructed Win32 source (1996)
Loading...
Searching...
No Matches
debug.cpp
Go to the documentation of this file.
1/**
2 * @file
3 * @ingroup shell
4 * @brief The Win32 developer overlay console.
5 *
6 * Address range 41c760-41d0bf. The new and delete call sites, the implicit
7 * ECX object parameter and the callee-cleanup member arguments show that
8 * this isolated utility was compiled as C++, although the surrounding game
9 * sources are C.
10 */
11#include <malloc.h>
12#include <locale.h>
13#include "wc1.h"
14#include <stdarg.h>
15#include <signal.h>
16
17int nDebugOverlayConsoleCount = 0; /* 0x00469644 */
18DWORD dwDebugOverlayKey = 0; /* 0x00469648 */
19DWORD dwDebugOverlayKeyLatch = 0; /* 0x0046964c */
20HHOOK hDebugKeyboardHook = 0; /* 0x00469650 */
21
22/* Function start: 0x41C760 */
23DebugOverlayConsole::DebugOverlayConsole(HINSTANCE module,
24 HWND targetWindow,
25 int columnCount,
26 int rowCount,
27 int waitMode)
28{
29 TEXTMETRICA metrics;
30 HDC deviceContext;
31
32 busyWait = waitMode;
34 window = targetWindow;
35 columns = columnCount;
36 cursorRow = 0;
37 rows = rowCount;
38 cursorColumn = 0;
39 textBuffer = (char *)malloc(rows * columns);
40 dirtyLines = (unsigned char *)malloc(rows);
41 memset(textBuffer, ' ', rows * columns);
42 memset(dirtyLines, 1, rows);
43
44 deviceContext = GetDC(window);
45 SelectObject(deviceContext,
46 CreateFontA(10, 10, 0, 0, 400, 0, 0, 0, 0, 2, 0, 0,
47 0x30, "Courier"));
49 textColor = 0xffffff;
50 backgroundMode = OPAQUE;
51 GetTextMetricsA(deviceContext, &metrics);
52 SetTextColor(deviceContext, 0xffffff);
53 SetBkColor(deviceContext, 0);
54 ReleaseDC(window, deviceContext);
55 characterWidth = metrics.tmMaxCharWidth;
56 characterHeight = metrics.tmHeight;
57
58 if (hDebugKeyboardHook == 0) {
60 SetWindowsHookExA(WH_KEYBOARD, (HOOKPROC)DebugKeyboardHookProc,
61 module, 0);
62 }
63 reverseVideo = 0;
64 HANDLE (WINAPI *createMutex)(LPSECURITY_ATTRIBUTES attributes,
65 BOOL initialOwner, LPCSTR name) = CreateMutexA;
66
67 mutex = createMutex(0, FALSE, 0);
68 spinnerIndex = 0;
70 spinnerCharacters = (char *)malloc(5);
71 strcpy(spinnerCharacters, "-\\|/");
72}
73
74/* Function start: 0x41C910 */
75DebugOverlayConsole::~DebugOverlayConsole()
76{
79 UnhookWindowsHookEx(hDebugKeyboardHook);
80 free(textBuffer);
81 free(dirtyLines);
83}
84
85/* Function start: 0x41C960 */
86extern "C" DWORD WINAPI DebugOverlayWorkerProc(void *parameter)
87{
88 DebugOverlayConsole *console;
89 /* Retail compares against this stack slot before its first assignment. */
90 int timer;
91 DWORD waitResult;
92 HDC deviceContext;
93 char *spinnerText;
94
95 console = (DebugOverlayConsole *)parameter;
96 for (;;) {
97 if (console->animationState == 2) {
98 ExitThread(0);
99 return 0;
100 }
101 if ((int)timeGetTime() > timer + 500) {
102 waitResult = WaitForSingleObject(console->mutex, 500);
103 if (waitResult == WAIT_FAILED) {
104 ExitThread(1);
105 } else if (waitResult == WAIT_TIMEOUT) {
106 continue;
107 }
108 if (console->animationState != 0) {
109 deviceContext = GetDC(console->window);
110 spinnerText = console->spinnerCharacters;
111 TextOutA(deviceContext,
112 console->characterWidth * console->cursorColumn,
113 console->characterHeight * console->cursorRow,
114 spinnerText + console->spinnerIndex,
115 1);
116 console->spinnerIndex++;
117 if ((int)strlen(console->spinnerCharacters) ==
118 console->spinnerIndex) {
119 console->spinnerIndex = 0;
120 }
121 ReleaseDC(console->window, deviceContext);
122 }
123 ReleaseMutex(console->mutex);
124 timer = timeGetTime();
125 }
126 }
127}
128
129/* Function start: 0x41CA60 */
130extern "C" LRESULT CALLBACK DebugKeyboardHookProc(int code, WPARAM key,
131 LPARAM flags)
132{
133 if (code < 0)
134 return CallNextHookEx(hDebugKeyboardHook,
135 code, key, flags);
136 if ((flags & 0x40000000) != 0) {
137 dwDebugOverlayKey = key;
139 }
140 return CallNextHookEx(hDebugKeyboardHook,
141 code, key, flags);
142}
143
144/* Function start: 0x41CAB0 */
146 const char *format, ...)
147{
148 int index;
149 int length;
150 signed char character;
151
152 if (format != 0) {
153 vsprintf(console->formatBuffer, format, (char *)(&format + 1));
154 } else {
155 strcpy(console->formatBuffer, "\n");
156 }
157 length = strlen(console->formatBuffer);
158 index = 0;
159 while (index < length) {
160 console->dirtyLines[console->cursorRow] = 1;
161 character = console->formatBuffer[index];
162 if (character >= ' ' && character <= '~') {
163 console->textBuffer[console->cursorRow * console->columns +
164 console->cursorColumn] = character;
165 console->cursorColumn++;
166 if (console->cursorColumn == console->columns) {
167 console->cursorColumn = 0;
168 console->cursorRow++;
169 if (console->cursorRow == console->rows)
170 console->Scroll();
171 }
172 } else {
173 switch (character) {
174 case '\a':
175 Beep(0, 0);
176 break;
177 case '\b':
178 console->cursorColumn--;
179 if (console->cursorColumn < 0) {
180 console->cursorColumn = 0;
181 console->cursorRow--;
182 if (console->cursorRow < 0)
183 console->cursorRow = 0;
184 }
185 console->textBuffer[
186 console->cursorRow * console->columns +
187 console->cursorColumn] = ' ';
188 break;
189 case '\n':
190 case '\r':
191 console->cursorColumn = 0;
192 console->cursorRow++;
193 if (console->cursorRow == console->rows)
194 console->Scroll();
195 break;
196 }
197 }
198 index++;
199 }
200 console->DrawPendingLines();
201}
202
203/* Function start: 0x41CC00 */
204void DebugOverlayConsole::Clear(void)
205{
206 cursorRow = 0;
207 cursorColumn = 0;
208 memset(textBuffer, ' ', rows * columns);
209 memset(dirtyLines, 1, rows);
210}
211
212/* Function start: 0x41CC50 */
213void DebugOverlayConsole::Scroll(void)
214{
215 memmove(textBuffer, textBuffer + columns, (rows - 1) * columns);
216 cursorRow = rows - 1;
217 memset(textBuffer + cursorRow * columns, ' ', columns);
218 memset(dirtyLines, 1, rows);
219}
220
221/* Function start: 0x41CCC0 */
222void DebugOverlayConsole::DrawPendingLines(void)
223{
224 int row;
225 HDC deviceContext;
226
227 deviceContext = GetDC(window);
228 row = 0;
229 while (row < rows) {
230 BOOL (WINAPI *drawText)(HDC, int, int, LPCSTR, int) = TextOutA;
231
232 if (dirtyLines[row] != 0) {
233 drawText(deviceContext, 0, characterHeight * row,
234 textBuffer + row * columns, columns);
235 }
236 row++;
237 }
238 ReleaseDC(window, deviceContext);
239 memset(dirtyLines, 0, rows);
240}
241
242/* Function start: 0x41CD40 */
243char DebugOverlayConsole::WaitForKey(void)
244{
245 RECT clip;
246 MSG message;
247 HANDLE process;
248 int (WINAPI *showCursor)(BOOL);
249 BOOL (WINAPI *setPriorityClass)(HANDLE, DWORD);
250 int minimized;
251 int complete;
252
253 minimized = 0;
254 complete = 0;
255 if (busyWait == 0) {
256 while (dwDebugOverlayKey == 0) {
257 showCursor = ShowCursor;
258 setPriorityClass = SetPriorityClass;
259 while (complete == 0) {
260 if (minimized != 0) {
261 if (GetMessageA(&message, 0, 0, 0) != 0) {
262 TranslateMessage(&message);
263 DispatchMessageA(&message);
264 complete = 1;
265 } else {
267 }
268 if (IsIconic(hMainWindow) == 0)
269 minimized = 0;
270 if (minimized == 0) {
271 clip.left = 0;
272 clip.top = 0;
273 clip.right = 320;
274 clip.bottom = 200;
275 ClipCursor(&clip);
276 showCursor(0);
277 process = GetCurrentProcess();
278 setPriorityClass(process, HIGH_PRIORITY_CLASS);
279 SetActiveWindow(hMainWindow);
280 SetForegroundWindow(hMainWindow);
281 DIBreInstall();
282 DIBslam();
283 DIBslamReal();
284 }
285 } else {
286 if (PeekMessageA(&message, 0, 0, 0, PM_NOREMOVE) != 0) {
287 if (GetMessageA(&message, 0, 0, 0) != 0) {
288 TranslateMessage(&message);
289 DispatchMessageA(&message);
290 complete = 0;
291 } else {
293 complete = 0;
294 }
295 } else {
296 complete = 1;
297 }
298 }
299 if (IsIconic(hMainWindow) != 0) {
300 if (minimized == 0) {
301 ClipCursor(0);
302 showCursor(1);
303 process = GetCurrentProcess();
304 setPriorityClass(process, 0x40);
305 }
306 minimized = 1;
307 }
308 if (minimized != 0)
309 complete = 0;
310 }
311 }
312 } else {
313 while (dwDebugOverlayKey == 0)
314 ;
315 }
316 {
317 char key = (char)dwDebugOverlayKey;
318
320 return key;
321 }
322}
323
324/* Function start: 0x41CF00 */
325void DebugOverlayConsole::EnableReverseVideo(void)
326{
327 HDC deviceContext;
328
329 if (reverseVideo == 0) {
330 deviceContext = GetDC(window);
331 SetBkColor(deviceContext, textColor);
332 SetTextColor(deviceContext, backgroundColor);
333 reverseVideo = 1;
334 ReleaseDC(window, deviceContext);
335 }
336}
337
338/* Function start: 0x41CF50 */
339void DebugOverlayConsole::DisableReverseVideo(void)
340{
341 HDC deviceContext;
342
343 if (reverseVideo != 0) {
344 deviceContext = GetDC(window);
345 SetTextColor(deviceContext, textColor);
346 SetBkColor(deviceContext, backgroundColor);
347 reverseVideo = 0;
348 ReleaseDC(window, deviceContext);
349 }
350}
351
352/* Function start: 0x41CFA0 */
353void DebugOverlayConsole::SetOverlayTextColor(int red, int green, int blue)
354{
355 HDC deviceContext;
356
357 deviceContext = GetDC(window);
358 textColor = red + (blue * 0x100 + green) * 0x100;
359 SetTextColor(deviceContext, textColor);
360 ReleaseDC(window, deviceContext);
361}
362
363/* Function start: 0x41CFF0 */
364void DebugOverlayConsole::SetOverlayBackgroundColor(int red, int green,
365 int blue)
366{
367 HDC deviceContext;
368
369 deviceContext = GetDC(window);
370 backgroundColor = red + (blue * 0x100 + green) * 0x100;
371 SetBkColor(deviceContext, backgroundColor);
372 ReleaseDC(window, deviceContext);
373}
374
375/* Function start: 0x41D040 */
376void DebugOverlayConsole::SetTransparentBackground(void)
377{
378 HDC deviceContext;
379
380 backgroundMode = TRANSPARENT;
381 deviceContext = GetDC(window);
382 SetBkMode(deviceContext, backgroundMode);
383 ReleaseDC(window, deviceContext);
384}
385
386/* Function start: 0x41D080 */
387void DebugOverlayConsole::SetOpaqueBackground(void)
388{
389 HDC deviceContext;
390
391 backgroundMode = OPAQUE;
392 deviceContext = GetDC(window);
393 SetBkMode(deviceContext, backgroundMode);
394 ReleaseDC(window, deviceContext);
395}
int nDebugOverlayConsoleCount
Definition debug.cpp:17
HHOOK hDebugKeyboardHook
Definition debug.cpp:20
HWND hMainWindow
Definition winsys.c:49
DWORD dwDebugOverlayKey
Definition debug.cpp:18
DWORD dwDebugOverlayKeyLatch
Definition debug.cpp:19
COLORREF backgroundColor
Definition wc1base.h:361
char formatBuffer[0x400]
Definition wc1base.h:353
unsigned char * dirtyLines
Definition wc1base.h:355
char * spinnerCharacters
Definition wc1base.h:371
COLORREF textColor
Definition wc1base.h:360
Umbrella header for the game core.
void DIBslam(void)
Definition dib.c:513
void ShutdownGameWindow(void)
Definition winmain.c:638
void DIBslamReal(void)
Definition dib.c:519
void DIBreInstall(void)
Definition dib.c:224
DWORD WINAPI DebugOverlayWorkerProc(void *parameter)
Definition debug.cpp:86
LRESULT CALLBACK DebugKeyboardHookProc(int code, WPARAM key, LPARAM flags)
Definition debug.cpp:130
void DebugOverlayPrintf(DebugOverlayConsole *console, const char *format,...)
Definition debug.cpp:145