Wing Commander
Reconstructed Win32 source (1996)
Loading...
Searching...
No Matches
screen.c
Go to the documentation of this file.
1/**
2 * @file
3 * @ingroup graphics
4 * @brief Mission requests, viewport setup and packet-memory management.
5 *
6 * Address range 42efc0-42fa8f.
7 */
8#include <malloc.h>
9#include "wc1.h"
10
11
12/* Linker commons defined here; LINK orders them by identifier hash. */
13short anPitchGoal[16]; /* 0x0059d7a0 */
14signed char abShipNavPtIdx[16]; /* 0x0059d7c0 */
15signed char acTurnIntervalArray[16]; /* 0x0059d7d0 */
17signed char abShipTurnList[16]; /* 0x0059d860 */
18HazardField aHazardFields[8]; /* 0x0059d870 */
19short nFacingToTargetValue; /* 0x0059d920 */
23signed char cCurrentCockpitView; /* 0x0059dab0 */
25enum ShipManeuver aeShipManeuversTable[12]; /* 0x0059dcb0 */
26const short *apCannedSequenceList[12]; /* 0x0059dce0 */
28short asCapitalShipViewFramesTable[16]; /* 0x0059dd90 */
29signed char acObjCollisionGraceTicks[SPACE_OBJECT_COUNT]; /* 0x0059ddb0 */
31signed char acShipDestroyedWeaponCountArray[16]; /* 0x0059de30 */
32
33/* Function start: 0x42EFC0 */
35{
36 int objectiveType;
37 short objective;
38 short home;
39 short proximity;
40 short index;
41 short object;
42
43 objective = 0;
45 proximity = aMissionNavPoints[
47 objectiveType = aMissionObjectivesArray[objective].type;
48 for (; objectiveType != -1;
49 objective++,
50 objectiveType = aMissionObjectivesArray[objective].type) {
51 if (achieved(objective) == 0) {
52 index = (short)aMissionObjectivesArray[objective].index;
53 switch (objectiveType) {
54 case 0:
55 case 1:
56 case 3:
57 if (visited(objective) != 0)
58 flag_objective(objective, 2);
59 break;
60 case 2:
61 switch (aMissionShips[index].missionType) {
63 if (aMissionShips[index].state == 2) {
64 flag_objective(objective, 2);
65 if (aMissionShips[index].type ==
67 aMissionShips[index].type ==
69 affect_mission_score(0, 5, -1);
70 else
71 affect_mission_score(0, 9, -1);
72 }
73 break;
76 object = find_ship_index(index);
77 if (object != -1 && home != -1 &&
78 distance_from_object(object, home) < proximity)
79 aMissionShips[index].state = 1;
80 if (aMissionShips[index].state == 1 &&
81 sighted(objective) != 0) {
82 flag_objective(objective, 2);
83 if (aMissionShips[index].type ==
85 aMissionShips[index].type ==
87 affect_mission_score(0, 5, -1);
88 else
89 affect_mission_score(0, 9, -1);
90 }
91 break;
92 default:
93 if (aMissionShips[index].state == 0 &&
94 sighted(objective) != 0) {
95 flag_objective(objective, 2);
96 if (aMissionShips[index].type ==
98 aMissionShips[index].type ==
100 affect_mission_score(0, 5, -1);
101 else
102 affect_mission_score(0, 9, -1);
103 }
104 break;
105 }
106 break;
107 case 4:
108 if (aMissionShips[index].state == 3)
109 flag_objective(objective, 2);
110 break;
111 }
112 }
113 }
114}
115
116/* Function start: 0x42F1F0 */
117int too_busy(short ship)
118{
119 return aeShipMissionType[ship] == MISSION_TYPE_ROUT;
120}
121
122/* Function start: 0x42F210 */
123void reply(short ship, short accepted)
124{
125 if (accepted == 1) {
126 send_message(ship, 0);
127 return;
128 }
129 send_message(ship, 1);
130}
131
132/* Function start: 0x42F240 */
133int disobey_formation(short ship)
134{
135 switch (aiPilotLevel[ship]) {
136 case 10:
137 return any_enemy_tail(0);
138 case 11:
139 return report_kilrathi_rout(0);
140 }
141 return 0;
142}
143
144/* Function start: 0x42F270 */
145int bad_target(short ship, short target)
146{
147 if (target != ship &&
148 aeShipSide[target] != aeShipSide[ship] &&
149 too_busy(ship) == 0)
150 return 0;
151 return 1;
152}
153
154/* Function start: 0x42F2B0 */
155short can_land(void)
156{
157 short index;
158 short result;
159
160 result = 0;
161 if (any_enemy(0, 20000) == 0) {
162 if (evaluate_damage(0) < 50 || nPlayerKillTotal > 0 ||
163 anShipFuelsTable[0] < 1000)
164 result = 1;
165 for (index = 0; index < cMissionObjectiveCountValue; index++) {
166 if (aMissionObjectivesArray[index].type == 1)
167 continue;
168 if (achieved(index) != 0 ||
169 (visited(index) != 0 &&
170 aMissionObjectivesArray[index].type != 2))
171 result = 1;
172 }
173 }
174 return result;
175}
176
177/* Rout and engagement callees of the order routines below. */
178unsigned int triumph(short obj);
179void engage(short obj, short target, enum ShipObjective objective);
180
181/* Function start: 0x42F350 */
182short i_wanna_rout(short ship, int pilot)
183{
184 if (pilot <= 4)
185 return 1;
186 switch (pilot) {
187 case 6:
188 return any_enemy(ship, 5000) == 0;
189 case 7:
190 case 11:
191 return 0;
192 case 8:
193 return aeShipMissionType[ship] ==
195 case 9:
196 return (short)triumph(0);
197 case 10:
198 return any_enemy(0, 10000) == 0;
199 }
200 return 1;
201}
202
203/* Function start: 0x42F3F0 */
204void request(short requester, short ship, short command)
205{
206 signed char *requesterTarget;
207 short target;
208 short object;
209 short attacker;
210
211 requesterTarget = &acShipTargetTable[requester];
212
213 for (;;) {
214 target = (short)*requesterTarget;
215 switch (command) {
216 case 1:
217 allow_engage();
218 if (bad_target(ship, target) != 0) {
219 reply(ship, 0);
220 return;
221 }
222 engage(ship, target, OBJECTIVE_ENGAGE_ENEMY);
223 reply(ship, 1);
224 return;
225 case 2:
226 allow_engage();
227 attacker = -1;
228 for (object = 0; object < 10; object++) {
229 if (aeObjectClass[object] >=
231 aeSpecialManeuvers[object] !=
233 aeShipSide[ship] !=
234 aeShipSide[object] &&
235 acShipTargetTable[object] == requester) {
236 attacker = object;
237 break;
238 }
239 }
240 if (attacker == -1) {
241 command = 9;
242 continue;
243 }
244 engage(ship, attacker, OBJECTIVE_ENGAGE_ENEMY);
245 reply(ship, 1);
246 return;
247 case 3:
248 if (i_wanna_rout(ship, aiPilotLevel[ship]) != 0 &&
249 try2rout(ship) != 0) {
250 bEngageAllowed = 0;
251 reply(ship, 1);
252 return;
253 }
254 reply(ship, 0);
255 return;
256 case 4:
257 case 5:
258 case 6:
259 if (RandomBelow(100) < 70 ||
260 ((signed char)acShipRating[ship] >= 9 &&
261 (signed char)acShipRating[ship] <= 12))
262 send_message(ship, command - 2);
263 if (acShipTargetTable[ship] != requester &&
264 too_busy(ship) == 0) {
265 engage(ship, requester, OBJECTIVE_ENGAGE_ENEMY);
266 return;
267 }
268 break;
269 case 7:
270 allow_engage();
271 if (aeShipObjectiveList[ship] ==
274 reply(ship, 1);
275 return;
276 }
277 reply(ship, 0);
278 return;
279 case 8:
281 if (disobey_formation(ship) != 0) {
283 reply(ship, 0);
284 return;
285 }
286 nAutoEngageTimer = -150;
287 reply(ship, 1);
288 return;
289 case 9:
291 if (disobey_formation(ship) != 0) {
292 reply(ship, 0);
293 return;
294 }
296 nAutoEngageTimer = -150;
297 reply(ship, 1);
298 return;
299 case 10:
300 case 11:
301 bRadioSilence = 0;
302 reply(ship, 1);
303 bRadioSilence = command == 10;
304 return;
305 case 12:
307 if (can_land() != 0) {
309 send_message(ship, 8);
310 return;
311 }
312 send_message(ship, 9);
313 return;
314 }
315 return;
316 }
317}
318
319/* Function start: 0x42F730 */
320unsigned short __stdcall ShouldSuspendCursorForRect(const ShortRect *bounds)
321{
322 (void)bounds;
323 return 0;
324}
325
326/* Function start: 0x42F740 */
327unsigned short __stdcall InitializeDIBScreenViewport(
328 Viewport *viewport, unsigned short colour)
329{
330 short row;
331
332 (void)colour;
334 pAllocatedScreenViewport = viewport;
337 viewport->right = 319;
338 viewport->bottom = 199;
339 viewport->left = 0;
340 viewport->top = 0;
341 if (nVideoMode != 0x13) {
342 SystemDebugPrintf("== BAD alloc_screen == : type: '%d'\n",
343 (int)nVideoMode);
344 exit(1);
345 }
346 viewport->pixels = GetDIBPixelBuffer();
347 viewport->rowOffsets = awScreenRowOffsets;
348 for (row = 0; row < 202; row++)
349 awScreenRowOffsets[row] = row * 320;
350 return 1;
351}
352
353/* Function start: 0x42F7E0 */
354/* Initialises a 320x200 viewport record (0x13F == 319, 199) then validates it. */
355void __stdcall InitFullScreenViewport(Viewport *record, short arg)
356{
357 Viewport *viewport = record;
358
359 pFullScreenRecord = record;
360 viewport->left = 0;
361 viewport->right = 319;
362 viewport->bottom = 199;
363 viewport->top = 0;
364 AllocateViewport(viewport, arg, 0);
365}
366
367/* Function start: 0x42F810 */
368unsigned int __stdcall GetPacketSize(const char *filename, short section)
369{
370 PacketSectionHandle handle;
371 unsigned int size;
372
373 size = (unsigned int)-1;
374 if (OpenPacketSection(filename, section, &handle) != 0) {
375 switch (handle.compression) {
376 case 1:
377 ReadPacketSectionData(&handle, &size, 4);
378 if (nPacketError != 0)
379 size = (unsigned int)-1;
380 break;
381 case 2:
382 size = handle.dataSize;
383 break;
384 default:
385 size = handle.dataSize;
386 break;
387 }
388 CloseDataFileByHandle(&handle);
389 }
390 return size;
391}
392
393/* Function start: 0x42F890 */
395{
396 NearHeapBlock *block;
397 int descriptorAddress;
398 int freeBytes;
399
400 freeBytes = 0;
401 descriptorAddress =
403 for (; descriptorAddress >= nCurrentNearHeapFirstDescriptor;
404 descriptorAddress -= 8) {
405 block = DosNearPtrToFar(descriptorAddress);
406 if ((block->sizeAndFlags & 0x80000000) == 0)
407 freeBytes += block->sizeAndFlags & 0xfffff;
408 }
409 return freeBytes;
410}
411
412/* Function start: 0x42F8E0 */
413/* Nothing in the shipped executable calls this. It is the largest-block
414 * companion of GetFreeNearHeapBytes (the _memmax to its _memavl). */
416{
417 NearHeapBlock *block;
418 int descriptorAddress;
419 int largestBytes;
420
421 largestBytes = 0;
422 descriptorAddress =
424 for (; nCurrentNearHeapFirstDescriptor <= descriptorAddress;
425 descriptorAddress -= 8) {
426 block = DosNearPtrToFar(descriptorAddress);
427 if ((block->sizeAndFlags & 0x80000000) == 0 &&
428 largestBytes < (block->sizeAndFlags & 0xfffff))
429 largestBytes = block->sizeAndFlags & 0xfffff;
430 }
431 return largestBytes;
432}
433
434/* Repeated memory-service declarations: their placement reproduces this
435 * unit's compiler context. */
436void FrameStartHook(int mode);
437unsigned short IsSoundHardwarePresent(short device);
438void MessagePumpHook(int mode);
439void *PushMemoryStackFrame(void *memory, int offset);
440int IsPushedPacketHandle(void *handle);
441void *MapPacketHandleToBlock(void *handle);
442
443/* Function start: 0x42F930 */
444void FrameStartHook(int mode)
445{
447}
448
449/* Function start: 0x42F940 */
450unsigned short IsSoundHardwarePresent(short device)
451{
453 return 1;
454}
455
456/* Function start: 0x42F950 */
457void MessagePumpHook(int mode)
458{
460}
461
462/* Function start: 0x42F960 */
463void *PushMemoryStackFrame(void *memory, int offset)
464{
465 if (offset != 0) {
466 printf("push %p by %d\n", memory, offset);
467 if (nPacketHandleTotal == 0x1000)
468 exit_squadron("qq mem push overflow");
470 if (offset < 0)
472 (unsigned char *)memory - offset;
473 else
475 (unsigned char *)memory + offset;
476 }
477 return memory;
478}
479
480/* Function start: 0x42F9E0 */
481int IsPushedPacketHandle(void *handle)
482{
483 int index;
484 int pushed;
485
486 for (index = 0; index < nPacketHandleTotal; index++) {
487 if (apPacketHandlesList[index] == handle) {
488 if (aiPktHandleDeltas[index] < 0)
489 pushed = 1;
490 else
491 pushed = 0;
492 return pushed;
493 }
494 }
495 return 0;
496}
497
498/* Function start: 0x42FA20 */
499void *MapPacketHandleToBlock(void *handle)
500{
501 int count = nPacketHandleTotal;
502 int i;
503 void **entry;
504 int offset;
505
506 for (;;) {
507 i = 0;
508 nPacketHandleTotal = count;
509 if (count <= 0)
510 return handle;
511 entry = apPacketHandlesList;
512 while (*entry != handle) {
513 entry = entry + 1;
514 i = i + 1;
515 nPacketHandleTotal = count;
516 if (i >= count)
517 return handle;
518 }
519 offset = aiPktHandleDeltas[i];
520 if (offset < 0)
521 handle = (unsigned char *)handle + offset;
522 else
523 handle = (unsigned char *)handle - offset;
525 count = count - 1;
527 }
528}
void(__cdecl *pIxFree)(void *)
signed char acShipRating[16]
Definition joycal.c:25
signed char acShipDestroyedWeaponCountArray[16]
Definition screen.c:31
ScreenAllocation stCurrentScreenAlloc
Definition damage.c:53
MissionHeaderDisk stCurrentMissionHeader
Definition mission.c:57
enum Side aeShipSide[12]
Definition ending.c:22
enum ShipManeuver aeShipManeuversTable[12]
Definition screen.c:25
signed char abShipNavPtIdx[16]
Definition screen.c:14
int aiPilotLevel[12]
Definition video.c:16
short nVideoMode
Definition video.c:12
short anPitchGoal[16]
Definition screen.c:13
short anObjectRollRotationList[SPACE_OBJECT_COUNT]
Definition screen.c:16
int nPacketHandleTotal
Definition damage.c:49
short nPacketError
Definition mono.c:15
signed char cMissionObjectiveCountValue
Definition game.c:554
unsigned short awScreenRowOffsets[202]
Definition damage.c:52
int anShipFuelsTable[12]
Definition data.c:252
Viewport * pFullScreenRecord
Definition damage.c:51
signed char abShipTurnList[16]
Definition screen.c:17
short nFacingToTargetValue
Definition screen.c:19
enum ShipMissionType aeShipMissionType[12]
Definition game.c:550
enum ShipObjective aeShipObjectiveList[12]
Definition video.c:22
void * apPacketHandlesList[0x1000]
Definition damage.c:47
MissionNavPoint aMissionNavPoints[MISSION_NAV_POINT_COUNT]
Definition game.c:199
enum ObjectClass aeObjectClass[SPACE_OBJECT_COUNT]
Definition video.c:21
const short * apCannedSequenceList[12]
Definition screen.c:26
int aiPktHandleDeltas[0x1000]
Definition damage.c:48
short asObjectScreenYArray[SPACE_OBJECT_COUNT]
Definition screen.c:20
ScreenAllocation * pScreenAllocPtr
Definition install.c:12
signed char cCurrentCockpitView
Definition screen.c:23
short asCapitalShipViewFramesTable[16]
Definition screen.c:28
FixedVector aShipMissionSpotArray[10]
Definition screen.c:27
int nCurrentNearHeapFirstDescriptor
Definition nearheap.c:14
short asObjectScreenXList[SPACE_OBJECT_COUNT]
Definition screen.c:21
unsigned char bLandingAuthorized
Definition spc.c:14
int nNearHeapBase
Definition nearheap.c:13
MissionObjective aMissionObjectivesArray[MISSION_OBJECTIVE_COUNT]
Definition screen.c:24
Viewport * pAllocatedScreenViewport
Definition damage.c:50
int bEngageAllowed
Definition game.c:101
signed char acObjCollisionGraceTicks[SPACE_OBJECT_COUNT]
Definition screen.c:29
ObjectResourceSlot aObjectResourceSlotsArray[4]
Definition screen.c:30
signed char acTurnIntervalArray[16]
Definition screen.c:15
HazardField aHazardFields[8]
Definition screen.c:18
short nPlayerKillTotal
Definition logic.c:112
MissionShipRecord aMissionShips[MISSION_SHIP_STORAGE_COUNT]
Definition game.c:230
int nNearHeapSize
Definition nearheap.c:12
unsigned char bRadioSilence
Definition comm.c:14
signed char acShipTargetTable[16]
Definition joycal.c:30
short nAutoEngageTimer
Definition game.c:104
enum SpecialManeuver aeSpecialManeuvers[12]
Definition game.c:549
short asObjectAnimIndexes[SPACE_OBJECT_COUNT]
Definition screen.c:22
int GetLargestFreeNearHeapBlock(void)
Definition screen.c:415
short homeMissionShip
Definition wcdata.h:564
short entryNavPoint
Definition wcdata.h:563
short proximityRadius
Definition wcdata.h:860
signed char state
Definition wcdata.h:896
int sizeAndFlags
Definition wcdata.h:332
unsigned int dataSize
Definition wcdata.h:759
Viewport * viewport
Definition wc1base.h:300
unsigned char * pixels
Definition wc1base.h:74
short right
Definition wc1base.h:78
short bottom
Definition wc1base.h:79
unsigned short * rowOffsets
Definition wc1base.h:75
short left
Definition wc1base.h:76
short top
Definition wc1base.h:77
Umbrella header for the game core.
void SystemDebugPrintf(const char *fmt,...)
Definition pilot.cpp:182
unsigned short __stdcall InitializeDIBScreenViewport(Viewport *viewport, unsigned short colour)
Definition screen.c:327
int any_enemy_tail(short obj)
Definition logic.c:512
short __stdcall OpenPacketSection(const char *filename, short section, PacketSectionHandle *handle)
Definition view.c:371
void *__stdcall DosNearPtrToFar(unsigned int v)
Definition strdos.c:31
void __stdcall CloseDataFileByHandle(PacketSectionHandle *p)
Definition view.c:438
void TimerResetHook(void)
Definition eventmgr.c:669
unsigned int reset_objective(short ship, enum ShipObjective objective)
Definition logic.c:676
int IsPushedPacketHandle(void *handle)
Definition screen.c:481
void engage(short obj, short target, enum ShipObjective objective)
Definition logic.c:1306
short __stdcall ReadPacketSectionData(PacketSectionHandle *handle, void *destination, unsigned int length)
Definition killbrd.c:894
unsigned short __stdcall AllocateViewport(Viewport *viewport, short clearColour, short flags)
Definition view.c:758
unsigned int __stdcall GetPacketSize(const char *filename, short section)
Definition screen.c:368
void disallow_engage(void)
Definition brains.c:197
void * PushMemoryStackFrame(void *memory, int offset)
Definition screen.c:463
short evaluate_damage(short obj)
Definition logic.c:1366
short sighted(short objective)
Definition cockpt.c:1030
unsigned int triumph(short obj)
Definition logic.c:1328
unsigned short __stdcall ShouldSuspendCursorForRect(const ShortRect *bounds)
Definition screen.c:320
short distance_from_object(short obj, short other)
Definition geom.c:667
short visited(short objective)
Definition cockpt.c:1036
short achieved(short objective)
Definition cockpt.c:1042
int GetFreeNearHeapBytes(void)
Definition screen.c:394
int report_kilrathi_rout(int mode)
Definition logic.c:391
unsigned short IsSoundHardwarePresent(short device)
Definition screen.c:450
void cleanup_objectives(void)
Definition screen.c:34
unsigned char * GetDIBPixelBuffer(void)
Definition dib.c:727
void send_message(short obj, short message)
Definition cockpt.c:2489
unsigned int alter_objective(short ship, enum ShipObjective objective)
Definition logic.c:685
short i_wanna_rout(short ship, int pilot)
Definition screen.c:182
void * MapPacketHandleToBlock(void *handle)
Definition screen.c:499
short RandomBelow(short n)
Definition mathfp.c:29
int any_enemy(short obj, short range)
Definition logic.c:887
void __stdcall InitFullScreenViewport(Viewport *vp, short arg)
Definition screen.c:355
int too_busy(short ship)
Definition screen.c:117
int disobey_formation(short ship)
Definition screen.c:133
void exit_squadron(const char *msg)
Definition main.c:122
short try2rout(short obj)
Definition logic.c:464
void flag_objective(short objective, unsigned char flags)
Definition cockpt.c:1048
void allow_engage(void)
Definition brains.c:203
void TimerStopHook(void)
Definition eventmgr.c:687
void FrameStartHook(int mode)
Definition screen.c:444
unsigned int affect_mission_score(short pilot, int event, short amount)
Definition ship.c:1060
void MessagePumpHook(int mode)
Definition screen.c:457
void reply(short ship, short accepted)
Definition screen.c:123
int bad_target(short ship, short target)
Definition screen.c:145
void request(short requester, short ship, short command)
Definition screen.c:204
short find_ship_index(short missionShip)
Definition logic.c:439
short can_land(void)
Definition screen.c:155
unsigned short GetSoundHardwareFlag(void)
Definition eventmgr.c:642
@ MISSION_TYPE_WARP_ARRIVE
Definition wcdata.h:129
@ MISSION_TYPE_CANNED_SEQUENCE
Definition wcdata.h:130
@ MISSION_TYPE_GOTO_WARP
Definition wcdata.h:128
@ MISSION_TYPE_ROUT
Definition wcdata.h:127
@ MISSION_TYPE_COME_HOME
Definition wcdata.h:132
@ OBJECT_TYPE_DRAYMAN
Definition wcdata.h:61
@ OBJECT_TYPE_HORNET
Definition wcdata.h:55
ShipObjective
Definition wcdata.h:136
@ OBJECTIVE_ENGAGE_ENEMY
Definition wcdata.h:144
@ OBJECTIVE_HOLD_FORMATION
Definition wcdata.h:146
@ OBJECTIVE_BREAK_FORMATION
Definition wcdata.h:147
#define SPACE_OBJECT_COUNT
Definition wcdata.h:1004
@ SPECIAL_MANEUVER_UNKNOWN_9
Definition wcdata.h:268
ShipManeuver
Definition wcdata.h:206
#define MISSION_OBJECTIVE_COUNT
Definition wcdata.h:1014
@ OBJECT_CLASS_SHIP
Definition wcdata.h:50