Wing Commander
Reconstructed Win32 source (1996)
Loading...
Searching...
No Matches
mono.c
Go to the documentation of this file.
1/**
2 * @file
3 * @ingroup shell
4 * @brief Data-file wrappers, scaled interstitial text, canned sequences and
5 * the MONODEBG.VXD developer console.
6 *
7 * Address range 403500-403e4f. MonoDebug_install and MonoDebug_print anchor
8 * the final block; the Mac auto unit starts at visit_the_cinema (403e50).
9 */
10#include "wc1.h"
11#include <sys/stat.h>
12#include <sys/utime.h>
13#include <share.h>
14
15short nPacketError = 0; /* 0x00465460 */
16/* File-error buffers. CL places these and the console statics by
17 * identifier hash, so their spellings reproduce the original order. */
18static char szDataFileReadError[0x40]; /* 0x00475d20 */
19static char szDataCreateError[0x40]; /* 0x00475d60 */
20static char szWriteDataError[0x40]; /* 0x00475da0 */
21static char szSeekDataError[0x40]; /* 0x00475de0 */
22/* Function start: 0x403500 */
23void __stdcall CloseDataFile(unsigned short fd)
24{
25 nPacketError = (short)_close(fd & 0xffff);
26}
27
28/* Function start: 0x403520 */
29short __stdcall WriteDataFileAtOffset(unsigned short fd, int offset,
30 unsigned int length, const void *data)
31{
32 nPacketError = 0;
33 if (_lseek(fd, offset, SEEK_SET) == -1) {
34 sprintf(szWriteDataError, "!lseek %d\n", offset);
35 nPacketError = (short)errno;
36 return 0;
37 }
38 if (_write(fd, data, length) == -1) {
39 sprintf(szWriteDataError, "!write %d\n", offset);
40 nPacketError = (short)errno;
41 return 0;
42 }
43 return 1;
44}
45
46/* Function start: 0x4035C0 */
47short __stdcall CreateDataFile(const char *path)
48{
49 unsigned short fd;
50
51 fd = (unsigned short)_open(path, 0x8101, 0x180);
52 if ((unsigned int)fd == (unsigned int)-1) {
53 sprintf(szDataCreateError, "!_open '%s'\n", path);
54 nPacketError = (short)errno;
55 return 0;
56 }
57 return (short)fd;
58}
59
60/* Function start: 0x403610 */
61int __stdcall ReadDataFileAtOffset(unsigned short fd, int offset,
62 unsigned int length, void *data)
63{
64 nPacketError = 0;
65 if (_lseek(fd, offset, SEEK_SET) == -1) {
66 sprintf(szDataFileReadError, "!lseek %d\n", offset);
67 nPacketError = (short)errno;
68 return 0;
69 }
70 if (_read(fd, data, length) == -1) {
71 sprintf(szDataFileReadError, "!lseek %d\n", offset);
72 nPacketError = (short)errno;
73 return 0;
74 }
75 return 1;
76}
77
78/* Function start: 0x4036B0 */
79int __stdcall SeekDataFile(unsigned short fd, int offset,
80 unsigned int origin)
81{
82 int position;
83
84 position = _lseek(fd, offset, origin & 0xffff);
85 if (position == -1) {
86 sprintf(szSeekDataError, "!lseek %d\n", offset);
87 nPacketError = (short)errno;
88 }
89 return position;
90}
91
92/* Function start: 0x403710 */
93int MeasureScaledIntroTextWidth(const char *text, short scale)
94{
95 ShortRect bounds;
96 short width = 0;
97
98 for (;;) {
99 char c = *text++;
100
101 if (c == 0)
102 break;
103
104 if (c >= 'A' && c <= 'z') {
105 c -= 'A';
106
108 pIntroFont, (short)c, 0,
109 scale, 0, &bounds);
110 width = (short)(width + bounds.right + 1);
111 width = (short)(width + ((int)scale * 2 >> 8));
112 } else if (c == ' ') {
113 width = (short)(width + ((int)scale * 6 >> 8));
114 } else if (c == '\n') {
115 break;
116 }
117 }
118 return width;
119}
120
121/* Function start: 0x4037A0 */
122int DrawCenteredScaledIntroText(const char *text, short centreX,
123 short baselineY, short scale)
124{
125 ShortRect bounds;
126 short x;
127 short y;
128 char c;
129
130 x = (short)(centreX - MeasureScaledIntroTextWidth(text, scale) / 2);
131 y = (short)(baselineY - ((int)scale * 16 >> 9));
132 for (;;) {
133 c = *text++;
134
135 if (c == 0)
136 break;
137
138 if (c >= 'A' && c <= 'z') {
139 c -= 'A';
140
142 pIntroFont, (short)c, 0,
143 scale, 0);
145 pIntroFont, (short)c, 0,
146 scale, 0, &bounds);
147 x = (short)(x + bounds.right + 1);
148 x = (short)(x + ((int)scale * 2 >> 8));
149 } else if (c == ' ') {
150 x = (short)(x + ((int)scale * 6 >> 8));
151 } else if (c == '\n') {
152 break;
153 }
154 }
155 return 0;
156}
157
158/* Function start: 0x403890 */
159short GetLineLength(const char *text)
160{
161 short width;
162 char c;
163
164 width = 0;
165 for (;;) {
166 c = *text;
167 text++;
168 if (c == 0)
169 break;
170 if (c >= 'A' && c <= 'z') {
171 c = (char)(c - 'A');
172 width = width + GetShapeFrameExtent(
173 0, 0, pIntroFont, c, 2);
174 width = width + 2;
175 } else if (c == '.') {
176 width = width + GetShapeFrameExtent(
177 0, 0, pIntroFont, 58, 2);
178 width = width + 2;
179 } else if (c == ',') {
180 width = width + GetShapeFrameExtent(
181 0, 0, pIntroFont, 59, 2);
182 width = width + 2;
183 } else if (c == ' ') {
184 width = width + 6;
185 } else if (c == '\n') {
186 break;
187 }
188 }
189 return width;
190}
191
192/* print_subtitle declares its glyph blitter (gr.c) locally. */
193void DrawSpriteDefault(Viewport *viewport, short x, short y,
194 struct Shape *shape, short frame);
195
196/* Function start: 0x403920 */
197int print_subtitle(Viewport *viewport, short colour, const char *text)
198{
199 char c;
200 const char *scan;
201 short lines;
202 short y;
203 short x;
204
205 lines = 1;
206 scan = text;
207 while ((c = *scan++) != 0) {
208 if (c == '\n')
209 lines++;
210 }
211 lines = (short)(lines * 16);
212 y = (short)((128 - lines) / 2);
213 x = GetLineLength(text);
214 x = (short)((320 - x) >> 1);
215 scan = text;
216 while ((c = *scan++) != 0) {
217 if (c >= 'A' && c <= 'z') {
218 DrawSpriteDefault(viewport, x, y, pIntroFont, (char)(c - 'A'));
219 x = x + GetShapeFrameExtent(
220 0, 0, pIntroFont, (char)(c - 'A'), 2);
221 x = x + 2;
222 } else if (c == ' ') {
223 x = x + 6;
224 } else if (c == '.') {
225 DrawSpriteDefault(viewport, x, y, pIntroFont, 58);
226 x = x + GetShapeFrameExtent(
227 0, 0, pIntroFont, 58, 2);
228 x = x + 2;
229 } else if (c == ',') {
230 DrawSpriteDefault(viewport, x, y, pIntroFont, 59);
231 x = x + GetShapeFrameExtent(
232 0, 0, pIntroFont, 59, 2);
233 x = x + 2;
234 } else if (c == '\n') {
235 y = y + 16;
236 x = GetLineLength(scan);
237 x = (short)((320 - x) >> 1);
238 }
239 }
240 if (viewport->pixels == stScreenView.pixels)
241 DIBslam();
242 return 0;
243}
244
245/* Function start: 0x403A80 */
247{
248 const short *command;
249
250 command = apCannedSequenceList[obj];
251 asCannedCommands[obj] = *command++;
252 switch (asCannedCommands[obj]) {
253 case 0:
254 asActionCounts[obj] = *command++;
255 break;
256 case 1:
257 anYawTarget[obj] = *command++;
258 anPitchGoal[obj] = *command++;
259 anRollGoal[obj] = *command++;
260 anShipSpeed[obj] = (int)*command++ << 8;
261 break;
262 case 2:
263 explode(-1, obj);
264 break;
265 case 3:
267 break;
268 case 4:
269 aeSpecialManeuvers[obj] =
271 break;
272 }
273 apCannedSequenceList[obj] = command;
274 return 0;
275}
276
277/* Function start: 0x403B70 */
278unsigned int update_canned_sequence(short obj)
279{
280 switch (asCannedCommands[obj]) {
281 case 0:
282 asActionCounts[obj]--;
283 if (asActionCounts[obj] == 0)
285 break;
286 case 1:
287 if (anYawTarget[obj] == 0 &&
288 anPitchGoal[obj] == 0 &&
289 anRollGoal[obj] == 0) {
290 /* A chained comparison: the speed window test compares the
291 0/1 result of the first test with the upper bound. */
292 if ((anShipSpeed[obj] - 0x400 <
294 anShipSpeed[obj] + 0x400)
296 }
297 break;
298 case 3:
299 case 4:
301 break;
302 }
303 return 0;
304}
305
306/* Function start: 0x403C40 */
307void __stdcall SplitGameClockTicks(unsigned char *parts)
308{
309 int ticks = (int)GetGameClockTicks();
310
311 parts[0] = (unsigned char)(ticks % 60);
312 ticks = ticks / 60;
313 parts[1] = (unsigned char)(ticks % 60);
314 ticks = ticks / 60;
315 parts[2] = (unsigned char)(ticks % 60);
316 ticks = ticks / 60;
317 parts[3] = (unsigned char)(ticks % 24);
318}
319
320/* Nothing in the shipped executable references this buffer. */
321static unsigned char abUnusedMonoBuffer[0x50]; /* 0x00475e20 */
322static int bMonoDebugAvailable; /* 0x00475e70 */
323static HANDLE hMonoDebugDriver; /* 0x00475e74 */
324
325/* Linker commons defined here; LINK orders them by identifier hash. */
326int nHostMouseMessageY; /* 0x005a8994 */
327int bHostPrimaryMouseButton; /* 0x005a8998 */
328int bHostSecondaryMouseButton; /* 0x005a899c */
329
330/* Function start: 0x403C90 */
332{
333 unsigned int version;
334
336 CreateFileA("\\\\.\\MONODEBG.VXD", 0, 0, 0, CREATE_ALWAYS,
337 FILE_FLAG_DELETE_ON_CLOSE, 0);
338 if (hMonoDebugDriver == INVALID_HANDLE_VALUE)
339 return;
340
341 if (!DeviceIoControl(hMonoDebugDriver, 1, 0, 0,
342 &version, sizeof(version), 0, 0)) {
343 CloseHandle(hMonoDebugDriver);
344 return;
345 }
346 if (version != 0x20004) {
347 CloseHandle(hMonoDebugDriver);
348 exit_squadron("MonoDebug__install expecting version");
349 return;
350 }
351 if (!DeviceIoControl(hMonoDebugDriver, 2, 0, 0,
352 0, 0, 0, 0)) {
353 CloseHandle(hMonoDebugDriver);
354 exit_squadron("MonoDebug__install init failed");
355 return;
356 }
358}
359
360/* Function start: 0x403D60 */
362{
363 if (bMonoDebugAvailable != 0) {
364 CloseHandle(hMonoDebugDriver);
366 }
367}
368
369/* Function start: 0x403D80 */
370/* Nothing in the shipped executable calls this. It sends control code 3 to
371 MONODEBG.VXD (install uses 1 and 2, print uses 9); what code 3 asks the
372 driver to do is unknown. */
374{
375 if (bMonoDebugAvailable != 0) {
376 if (!DeviceIoControl(hMonoDebugDriver, 3, 0, 0, 0, 0, 0, 0))
378 }
379}
380
381/* Function start: 0x403DB0 */
382void SoundDebugPrintf(const char *fmt, ...)
383{
384 va_list arguments;
385
386 va_start(arguments, fmt);
387 vsprintf(szSoundDebugMsg, fmt, arguments);
388 va_end(arguments);
390}
391
392/* Function start: 0x403DE0 */
393void MonoDebug_print(const char *text)
394{
395 if (bMonoDebugAvailable != 0) {
396 if (!DeviceIoControl(hMonoDebugDriver, 9,
397 (void *)text, 0xfa0, 0, 0, 0, 0)) {
398 exit_squadron("MonoDebug::print failed (buffer possibly on stack?!)");
400 }
401 }
402}
403
404/* Function start: 0x403E30 */
405void ReadPerformanceCounter(LARGE_INTEGER *p)
406{
407 QueryPerformanceCounter(p);
408}
409
410/* Function start: 0x403E40 */
411char *__stdcall ResetStringBuilder(TextContext *context)
412{
413 char *text = context->text;
414
415 context->textCursor = text;
416 *text = 0;
417 return text;
418}
short anRollGoal[16]
Definition ending.c:21
short anPitchGoal[16]
Definition screen.c:13
short nPacketError
Definition mono.c:15
const short * apCannedSequenceList[12]
Definition screen.c:26
short asCannedCommands[16]
Definition comm.c:59
FixedVector aShipVelocity[SPACE_OBJECT_COUNT]
Definition smart.c:21
int anShipSpeed[64]
Definition data.c:248
Viewport stScreenView
Definition launch.c:50
Viewport stSpaceBufferViewport
Definition timer.c:13
int nHostMouseMessageY
Definition mono.c:326
int bHostPrimaryMouseButton
Definition mono.c:327
char szSoundDebugMsg[512]
Definition eject.c:28
int bHostSecondaryMouseButton
Definition mono.c:328
short anYawTarget[16]
Definition smart.c:22
enum SpecialManeuver aeSpecialManeuvers[12]
Definition game.c:549
short asActionCounts[10]
Definition dib.c:103
struct Shape * pIntroFont
Definition eject.c:29
static HANDLE hMonoDebugDriver
Definition mono.c:323
void SendMonoDebugCommand3(void)
Definition mono.c:373
static char szWriteDataError[0x40]
Definition mono.c:20
static int bMonoDebugAvailable
Definition mono.c:322
static char szDataCreateError[0x40]
Definition mono.c:19
static unsigned char abUnusedMonoBuffer[0x50]
Definition mono.c:321
static char szDataFileReadError[0x40]
Definition mono.c:18
static char szSeekDataError[0x40]
Definition mono.c:21
short right
Definition wcdata.h:442
char * text
Definition wc1base.h:242
char * textCursor
Definition wc1base.h:243
unsigned char * pixels
Definition wc1base.h:74
Umbrella header for the game core.
void SoundDebugPrintf(const char *fmt,...)
Definition mono.c:382
short GetTransformedShapeBounds(Viewport *viewport, short x, short y, struct Shape *shape, short frame, short angle, short scale, short flip, ShortRect *bounds)
Definition gr.c:1196
void DIBslam(void)
Definition dib.c:513
int advance_canned_sequence(short obj)
Definition mono.c:246
int __stdcall SeekDataFile(unsigned short fd, int offset, unsigned int origin)
Definition mono.c:79
long Vector_magnitude(const FixedVector *vector)
Definition mathfp.c:132
void DrawSpriteScaled(Viewport *viewport, short x, short y, struct Shape *shape, short frame, short angle, short scale, short flip)
Definition gr.c:1176
short __stdcall GetShapeFrameExtent(short x, short y, struct Shape *shape, short frame, short extent)
Definition cutscene.c:187
void MonoDebug_print(const char *text)
Definition mono.c:393
void DrawSpriteDefault(Viewport *viewport, short x, short y, struct Shape *shape, short frame)
Definition gr.c:660
int __stdcall ReadDataFileAtOffset(unsigned short fd, int offset, unsigned int length, void *data)
Definition mono.c:61
void MonoDebug_remove(void)
Definition mono.c:361
void __stdcall CloseDataFile(unsigned short fd)
Definition mono.c:23
int fire_fixed_projectile_weapon(short obj)
Definition ship.c:1935
void ReadPerformanceCounter(LARGE_INTEGER *p)
Definition mono.c:405
int explode(short attacker, short victim)
Definition ship.c:1340
void MonoDebug_install(void)
Definition mono.c:331
int print_subtitle(Viewport *viewport, short colour, const char *text)
Definition mono.c:197
unsigned int update_canned_sequence(short obj)
Definition mono.c:278
void __stdcall SplitGameClockTicks(unsigned char *parts)
Definition mono.c:307
short __stdcall CreateDataFile(const char *path)
Definition mono.c:47
void exit_squadron(const char *msg)
Definition main.c:122
int DrawCenteredScaledIntroText(const char *text, short centreX, short baselineY, short scale)
Definition mono.c:122
int MeasureScaledIntroTextWidth(const char *text, short scale)
Definition mono.c:93
unsigned int GetGameClockTicks(void)
Definition winsys.c:129
short __stdcall WriteDataFileAtOffset(unsigned short fd, int offset, unsigned int length, const void *data)
Definition mono.c:29
short GetLineLength(const char *text)
Definition mono.c:159
char *__stdcall ResetStringBuilder(TextContext *context)
Definition mono.c:411
@ SPECIAL_MANEUVER_AFTERBURNER
Definition wcdata.h:260