Wing Commander
Reconstructed Win32 source (1996)
Loading...
Searching...
No Matches
ending.c
Go to the documentation of this file.
1/**
2 * @file
3 * @ingroup campaign
4 * @brief Campaign victory, retreat and ending scenes.
5 *
6 * Address range 42fa90-43070f. The tagged-allocation helpers at its start
7 * stay in this unit provisionally.
8 */
9#include "wc1.h"
10#include <sys/types.h>
11
12/* The ending passes the series byte as a word. */
13unsigned int init_3Space_objects(short);
14
15/* 0x0046ad88 */
16static unsigned char abTaggedAllocationPrefix[8] = {
17 'j', 'e', 'f', 'f', 0, 0, 0, 0
18};
19/* Linker commons defined here; LINK orders them by identifier hash. */
20signed char acShipStressList[16]; /* 0x0059d620 */
21short anRollGoal[16]; /* 0x0059d630 */
22enum Side aeShipSide[12]; /* 0x0059d650 */
23signed char acShipAiCooldowns[16]; /* 0x0059d680 */
25signed char acLastCollisionObjects[SPACE_OBJECT_COUNT]; /* 0x0059d6a0 */
26short aasShipMaximumShieldTable[10][2]; /* 0x0059d6e0 */
27short asObjectCollisionRadius[64]; /* 0x0059d710 */
28signed char acShipPointingModeList[16]; /* 0x0059d790 */
29
30/* Function start: 0x42FA90 */
31void *AllocateTaggedMemory(int size, unsigned short flags)
32{
33 struct TaggedAllocationHeader *memory;
34 unsigned short tagged;
35
36 tagged = flags & 0x40;
37 if (tagged != 0)
38 size += sizeof(struct TaggedAllocationHeader);
39 memory = AllocateGuardedMemory(size);
40 if (tagged != 0) {
41 memcpy(&memory->signature, abTaggedAllocationPrefix,
43 memory = PushMemoryStackFrame(
44 memory, -(int)sizeof(struct TaggedAllocationHeader));
45 }
46 return memory;
47}
48
49/* Function start: 0x42FAE0 */
50void ReleasePacketHandle(void *handle)
51{
52 void **reference;
53 int group;
54 int i;
55
56 reference = (void **)aapPacketReferences;
57 for (group = 0; group < 4; group++) {
58 for (i = 0; i < 0x25; i++) {
59 if (*reference == handle)
60 *reference = 0;
61 reference++;
62 }
63 }
65}
66
67/* Function start: 0x42FB20 */
68/* Tail-jump thunk to 0x004362E0, not a constant return -- Ghidra followed the
69 * jump and folded the callee's body into the display. The optimized compiler
70 * emits the tail jump from this forwarding return. */
71unsigned int GetFixedOneMillionThunk(short memoryType)
72{
73 (void)memoryType;
74 return GetFixedOneMillion();
75}
76
77/* Function start: 0x42FB30 */
78unsigned int GetFixedOneMillionThunkAlt(short memoryType)
79{
80 (void)memoryType;
81 return GetFixedOneMillionAlt();
82}
83
84/* Function start: 0x42FB40 */
85void CreateCannedSceneObject(short *object, short yaw, short unusedPitch,
86 short distance, struct Shape *shape,
87 short frame, short type, short scale)
88{
89 (void)unusedPitch;
90 *object = find_vacant_3d_object();
91 if (*object != -1) {
93 init_ijk(63);
94 alter_yaw(yaw, 63);
96 (int)distance << 8,
97 &aShipPositionsArray[*object]);
98 asObjectViewFrames[*object] = frame;
99 asObjScreenAngles[*object] = type;
100 aeObjectTypeList[*object] =
101 (enum ObjectType)asObjScreenAngles[*object];
102 asObjScreenScalesArray[*object] = scale;
103 apObjShapeArray[*object] = shape;
104 }
105}
106
107/* 0x0046ad90 */
108static const char *apszCampaignVictoryText[4] = {
109 "Destroying the remains of the Kilrathi naval power in the sector...",
110 "The Tiger's Claw closes in for the kill...",
111 "And the last Kilrathi planet in the sector falls!",
112 0
113};
114/* 0x0046ada0 */
115static const char *pszTigerClawEscapeOpening =
116 "Fleeing from the overwelming Kilrathi forces in the sector...";
117/* 0x0046ada4 */
118static const char *pszTigerClawEscapeJump =
119 "The Tiger's Claw manages to jump out. Barely.";
120/* 0x0046ada8 */
121static const char *pszTigerClawEscapeClosing =
122 "There'll be other sectors, other battles...";
123/* 0x0046adb0 */
125 { -55, 42, 0 }, { -68, 46, 0 },
126 { 60, 42, 16 }, { 73, 46, 16 }
127};
128static const char *pszTheEnd = "The End"; /* 0x0046adc8 */
129static const char *pszForNow = "For Now..."; /* 0x0046adcc */
130
131/* Function start: 0x42FC00 */
133{
134 short slot;
135 CampaignVictoryProjectile projectiles[16];
136 struct Shape *planetShape;
137 struct Shape *projectileShape;
138 const ShortVector *origin;
139 short planetObject;
140 short spawnCountdown;
141 short vacant[2];
142 short vacantCount;
143 short textIndex;
144 CampaignVictoryProjectile *projectile;
145 short frame;
146 short elapsed;
147 short animationFrame;
148 int planetScale;
149 int verticalOffset;
150 int planetDepth;
151 int projectedY;
152
154 spacetrack(0x21, 2, 1);
160 planetShape =
162 projectileShape =
164 CreateCannedSceneObject(&planetObject, -4, 0, 30000,
165 planetShape, 0, 0, 0x50);
168 {
169 short initializationCount;
170
171 initializationCount = 16;
172 projectile = projectiles;
173 do {
174 projectile->scale = -1;
175 projectile++;
176 initializationCount--;
177 } while (initializationCount != 0);
178 }
179
180 planetDepth = -1500;
181 frame = 0;
183 verticalOffset = -70000;
185 do {
186 switch (frame) {
187 case 0:
188 textIndex = 0;
189 break;
190 case 100:
191 textIndex = 1;
192 break;
193 case 180:
194 textIndex = 2;
195 break;
196 default:
197 textIndex = -1;
198 break;
199 }
200 if (textIndex != -1) {
205 "%X%Y%s%P", 0, 160,
206 apszCampaignVictoryText[textIndex]);
207 }
208
210 if (Draw_3Space_Frame() != 0) {
211 if (frame > 90)
212 asObjScreenScalesArray[planetObject]++;
213 if (asObjectCollisionRadius[61] < planetDepth) {
214 slot = 0;
215 projectile = projectiles;
216 do {
217 if (projectile->scale != -1 &&
219 projectile->depth) {
220 projectile->screenX =
221 (short)(projectile->x / projectile->depth);
222 projectile->screenY =
223 (short)(projectile->y / projectile->depth);
224 projectile->scale = 0x10000L / projectile->depth;
225 if (projectile->scale < 16) {
226 projectile->scale = -1;
227 } else {
230 (short)(projectile->screenX +
232 (short)(projectile->screenY +
234 projectileShape, 1, 0,
235 (short)projectile->scale,
236 projectile->flip);
237 projectile->depth += 100;
238 projectile->y += 4000;
239 }
240 }
241 projectile++;
242 slot++;
243 } while (slot < 16);
244
245 if (frame < 170 && --spawnCountdown < 1) {
246 projectile = projectiles;
247 vacantCount = 0;
248 slot = 0;
249 do {
250 if (projectile->scale == -1) {
251 vacant[vacantCount] = slot;
252 vacantCount++;
253 if (vacantCount == 2)
254 break;
255 }
256 slot++;
257 projectile++;
258 } while (slot < 16);
259
260 if (vacantCount > 1) {
261 origin =
264 projectile = &projectiles[vacant[0]];
265 projectile->depth = planetDepth;
266 projectile->x =
267 ((origin->x * planetScale) >> 8) * planetDepth;
268 projectile->y =
269 ((origin->y * planetScale) >> 8) *
270 projectile->depth + verticalOffset;
271 projectile->scale = 0x100;
272 projectile->flip = origin->z;
273 projectile->depth += 40;
274
275 projectile = &projectiles[vacant[1]];
276 projectile->depth = planetDepth;
277 projectile->x =
278 (((origin->x - 4) * planetScale) >> 8) *
279 planetDepth;
280 projectile->y =
281 ((origin->y * planetScale) >> 8) *
282 projectile->depth + verticalOffset;
283 projectile->scale = 0x100;
284 projectile->flip = origin->z;
285 projectile->depth += 40;
286 }
287 spawnCountdown = 8;
288 }
289
290 planetScale = 0x40000L / planetDepth;
291 projectedY = verticalOffset / planetDepth;
294 (short)(nCurrentViewCenterPosY + projectedY),
295 projectileShape, 0, 0, (short)planetScale, 0);
296 verticalOffset += 200;
297 }
300 DIBslam();
301 DIBslamReal();
302 }
303 planetDepth += 15;
304 if (bEscapePressedFlag == 1)
305 break;
306 DIBslam();
307 DIBslamReal();
308 frame++;
309 } while (frame < 250);
310
311 ReleasePacketHandle(projectileShape);
312 ReleasePacketHandle(planetShape);
315 free_3Space();
316 if (bEscapePressedFlag != 1) {
317 planetShape =
320 animationFrame = 1;
322 DrawSpriteDefault(&stScreenView, 0, 0, planetShape, 0);
323 WaitForSceneAdvance(14, 0);
324 elapsed = 0;
325 do {
327 DrawSpriteDefault(&stScreenView, 0, 0, planetShape,
328 animationFrame++);
329 if (animationFrame > 17)
330 animationFrame = 12;
331 while ((short)IsFrameTickElapsed() == 0) {
332 if (bEscapePressedFlag != 0 || CheckEscaped() != 0) {
333 elapsed = 1000;
334 break;
335 }
336 }
337 elapsed++;
338 DIBslam();
339 DIBslamReal();
340 } while (elapsed < 40);
341 ReleasePacketHandle(planetShape);
343 cBlackColour, 1);
346 DIBslam();
347 DIBslamReal();
349 }
350
354 bScriptedView = 0;
358 cBlackColour, 1);
361 DIBslam();
362 DIBslamReal();
364 return 0;
365}
366
367/* Function start: 0x430150 */
368unsigned int ShowTigerClawEscapeScene(void)
369{
370 struct Shape *escapeShape;
371 FixedVector jumpOffset;
372 short approachStep;
373 short frame;
374 short effect;
375 int verticalOffset;
376 int depth;
377 int scale;
378 int projectedY;
379
380 approachStep = 15;
382 spacetrack(0x22, 2, 1);
388 escapeShape =
390 if (aObjectTypeData[
391 OBJECT_TYPE_HYPERSPACE_JUMP_FLASH].shapeSet == 0) {
394 FetchDiskPacketRetrying(3, 14, 0);
395 }
402 "%X%Y%s%P", 0, 160,
404 depth = -1000;
405 verticalOffset = -70000;
408 frame = 0;
409 do {
411 if (Draw_3Space_Frame() != 0) {
412 if (asObjectCollisionRadius[61] < depth &&
413 frame < 198) {
414 scale = 0x40000L / depth;
415 projectedY = verticalOffset / depth;
418 (short)(nCurrentViewCenterPosY + projectedY),
419 escapeShape, 0, 0, (short)scale, 0);
420 }
423 }
424 if (asObjectCollisionRadius[61] < depth)
425 verticalOffset += 400;
426 depth += approachStep;
427 if (frame > 170)
428 approachStep = (short)(approachStep + 10);
429
430 switch (frame) {
431 case 150:
436 "%X%Y%s%P", 0, 160,
438 break;
439 case 190:
440 effect = find_vacant_3d_object();
441 if (effect != -1) {
442 set_objects_data(effect,
444 -1);
446 0x271000, &jumpOffset);
447 awObjectScales[effect] =
448 (short)(awObjectScales[effect] << 2);
449 zero_vector(&aShipVelocity[effect]);
451 &jumpOffset,
452 &aShipPositionsArray[effect]);
453 }
454 break;
455 case 198:
458 bViewportDirty = 1;
459 break;
460 case 210:
465 "%X%Y%s%P", 0, 160,
467 break;
468 }
469 if (bEscapePressedFlag == 1)
470 break;
471 frame++;
472 DIBslam();
473 DIBslamReal();
474 } while (frame < 260);
475
480 ReleasePacketHandle(escapeShape);
483 free_3Space();
488 bScriptedView = 0;
491 return 0;
492}
493
494/* Function start: 0x4304F0 */
495unsigned int ShowTheEndScreen(short enableFireworks)
496{
497 short activeFireworks;
498 short frame;
499 short slot;
500
501 activeFireworks = 0;
504 spacetrack(0x17, 2, 1);
506 ViewMedals();
512 FetchDiskPacketRetrying(9, 0x11, 0);
513 pIntroFont =
518 frame = 0;
520 do {
522 if (enableFireworks != 0 && activeFireworks != 0 &&
523 (RandomBelowOrEqual(100) < 40 || frame > 280)) {
524 for (slot = 0; slot < 30; slot++) {
525 if (aFireworksList[slot].frame == -1) {
526 aFireworksList[slot].frame = 0;
527 aFireworksList[slot].x =
529 aFireworksList[slot].y =
532 break;
533 }
534 }
535 }
536 activeFireworks = TheEndFireWorks(&stSceneBuffer, 30);
537 if (frame < 160) {
539 pszTheEnd);
540 } else if (frame > 190) {
541 StopMusic((short)(320 - frame));
543 pszForNow);
544 }
545 frame++;
547 DIBslam();
548 DIBslamReal();
549 } while (frame < 320);
550
556 return 0;
557}
void(__cdecl *pIxFree)(void *)
static const char * pszTigerClawEscapeClosing
Definition ending.c:121
static const char * pszForNow
Definition ending.c:129
static const char * pszTheEnd
Definition ending.c:128
static unsigned char abTaggedAllocationPrefix[8]
Definition ending.c:16
static ShortVector aCampaignVictoryProjectileOrigins[4]
Definition ending.c:124
static const char * pszTigerClawEscapeJump
Definition ending.c:118
static const char * apszCampaignVictoryText[4]
Definition ending.c:108
static const char * pszTigerClawEscapeOpening
Definition ending.c:115
unsigned char bEscapePressedFlag
Definition mathfp.c:24
short asObjScreenScalesArray[SPACE_OBJECT_COUNT]
Definition dib.c:105
enum Side aeShipSide[12]
Definition ending.c:22
short anRollGoal[16]
Definition ending.c:21
signed char acShipStressList[16]
Definition ending.c:20
short asObjScreenAngles[SPACE_OBJECT_COUNT]
Definition joycal.c:26
ObjectTypeData aObjectTypeData[OBJECT_TYPE_COUNT]
Definition objdata.c:86
short aasShipMaximumShieldTable[10][2]
Definition ending.c:26
unsigned char cBlackColour
Definition init.c:12
unsigned char cViewportClearColour
Definition init.c:13
int bViewportDirty
Definition main.c:27
TextContext stCurrentConvTxtCtx
Definition targ.c:15
short nFrameSkipCounter
Definition main.c:23
enum ObjectClass aeObjectClass[SPACE_OBJECT_COUNT]
Definition video.c:21
signed char acShipPointingModeList[16]
Definition ending.c:28
Viewport stCurrentConvTextViewport
Definition timer.c:17
Viewport stSceneBuffer
Definition select.c:17
FixedVector aShipVelocity[SPACE_OBJECT_COUNT]
Definition smart.c:21
int bScriptedView
Definition view.c:14
unsigned int bIntroSceneResourcesActive
Definition logic.c:87
short asObjectCollisionRadius[64]
Definition ending.c:27
short nCurrentViewCenterPosX
Definition eventmgr.c:25
struct Shape * pFireworkShape
Definition install.c:19
short nScriptedViewObject
Definition view.c:13
Viewport stScreenView
Definition launch.c:50
void * aapPacketReferences[4][0x25]
Definition mission.c:17
short asCampaignVictoryViewScript[24]
Definition game.c:140
Viewport stSpaceBufferViewport
Definition timer.c:13
int nCannedSceneMode
Definition main.c:21
CampaignState stCampaignState
Definition dib.c:107
unsigned short awObjectScales[SPACE_OBJECT_COUNT]
Definition music.c:86
struct Shape * apObjShapeArray[SPACE_OBJECT_COUNT]
Definition comm.c:48
enum ObjectType aeObjectTypeList[SPACE_OBJECT_COUNT]
Definition data.c:255
signed char acLastCollisionObjects[SPACE_OBJECT_COUNT]
Definition ending.c:25
short asObjectViewFrames[SPACE_OBJECT_COUNT]
Definition video.c:23
Viewport stModalSrcViewport
Definition select.c:14
FireworkState aFireworksList[30]
Definition install.c:18
FixedVector aShipPositionsArray[SPACE_OBJECT_COUNT]
Definition game.c:556
FixedVector aShipFwdVec[64]
Definition smart.c:17
short nCurrentViewCenterPosY
Definition eventmgr.c:26
FixedVector vCollisionDelta
Definition ending.c:24
struct Shape * pIntroFont
Definition eject.c:29
signed char acShipAiCooldowns[16]
Definition ending.c:23
short asTigerClawEscapeViewScript[12]
Definition game.c:173
signed char currentSeries
Definition wcdata.h:715
short variant
Definition wcdata.h:341
short frame
Definition wcdata.h:338
struct Shape * shapeSet
Definition wcdata.h:393
short z
Definition wcdata.h:435
short x
Definition wcdata.h:433
short y
Definition wcdata.h:434
unsigned int signature
Definition wc1base.h:330
short right
Definition wc1base.h:78
short bottom
Definition wc1base.h:79
Umbrella header for the game core.
unsigned int RefreshMemoryStatusOverlay(void)
Definition main.c:467
void * AllocateTaggedMemory(int size, unsigned short flags)
Definition ending.c:31
unsigned int InitializeConversationText(void)
Definition main.c:448
void FormatTextBufferFromStart(const char *format,...)
Definition cockpt.c:211
void DIBslam(void)
Definition dib.c:513
int set_up_action_sphere(short navPoint)
Definition mission.c:519
unsigned int free_3Space(void)
Definition logic.c:1975
unsigned int InitializeFireworks(void)
Definition view.c:186
unsigned int GetFixedOneMillion(void)
Definition eventmgr.c:692
unsigned int Draw_3Space_Frame(void)
Definition main.c:1832
void * PushMemoryStackFrame(void *memory, int offset)
Definition screen.c:463
void * FetchDiskPacketRetrying(short logicalFile, short section, short flags)
Definition disk.c:126
void AddFixedVectors(const FixedVector *left, const FixedVector *right, FixedVector *sum)
Definition geom.c:296
void set_objects_data(short obj, enum ObjectType type, short owner)
Definition ship.c:173
void DrawSpriteScaled(Viewport *viewport, short x, short y, struct Shape *shape, short frame, short angle, short scale, short flip)
Definition gr.c:1176
unsigned int spacetrack(int track, int mode, short enabled)
Definition music.c:411
void get_player_input(void)
Definition main.c:575
void * AllocateGuardedMemory(unsigned int size)
Definition winmain.c:1054
unsigned int GetFixedOneMillionThunkAlt(short memoryType)
Definition ending.c:78
void DrawSpriteDefault(Viewport *viewport, short x, short y, struct Shape *shape, short frame)
Definition gr.c:660
void init_ijk(short obj)
Definition geom.c:568
int IsFrameTickElapsed(void)
Definition eventmgr.c:629
void RestoreGamePalette(void)
Definition winmain.c:76
void StopMusicUnlessSuppressed(void)
Definition music.c:419
unsigned int ViewMedals(void)
Definition screens.c:220
unsigned int GetFixedOneMillionAlt(void)
Definition eventmgr.c:698
void DIBslamReal(void)
Definition dib.c:519
unsigned int clear_view_buffer(void)
Definition main.c:414
void CreateCannedSceneObject(short *object, short yaw, short unusedPitch, short distance, struct Shape *shape, short frame, short type, short scale)
Definition ending.c:85
void FreeGuardedAllocation(void *memory)
Definition winmain.c:1147
unsigned int PreloadMusicTrackHook(short track)
Definition logic.c:2044
void __stdcall SetEventManagerPump(void(*pump)(void))
Definition strdos.c:126
void __stdcall SetTextContext(TextContext *context)
Definition mathfp.c:152
int free_all_slots(void)
Definition mission.c:397
void WaitForSceneAdvance(short duration, short unused)
Definition disk.c:509
void initialize_scripted_view(const short *script)
Definition view.c:175
unsigned int init_3Space_objects()
void alter_yaw(short angle, short obj)
Definition geom.c:627
void WaitForVerticalBlankThunk(void)
Definition mathfp.c:158
void __stdcall SetFrameTimerPeriodDirect(short p)
Definition eventmgr.c:617
unsigned int ShowTigerClawEscapeScene(void)
Definition ending.c:368
void __stdcall FadeViewportPaletteToColour(Viewport *viewport, unsigned short colour, short enabled)
Definition main.c:2213
int print_subtitle(Viewport *viewport, short colour, const char *text)
Definition mono.c:197
void ScaleFixedVector(const FixedVector *vector, int scale, FixedVector *result)
Definition geom.c:322
short TheEndFireWorks(Viewport *viewport, short count)
Definition view.c:198
void zero_vector(FixedVector *vector)
Definition geom.c:280
unsigned int ReleaseMusicTrackHook(short track)
Definition logic.c:2051
unsigned int ResetScreenClipToFullHeight(void)
Definition main.c:439
void __stdcall PanToScreen(Viewport *source, Viewport *destination)
Definition screens.c:1571
void * MapPacketHandleToBlock(void *handle)
Definition screen.c:499
void ClearViewport(Viewport *viewport, short colour)
Definition gr.c:963
short find_vacant_3d_object(void)
Definition geom.c:987
void StopMusic(short unused)
Definition music.c:114
unsigned int GetFixedOneMillionThunk(short memoryType)
Definition ending.c:71
unsigned int Update_3Space(void)
Definition main.c:476
unsigned int ShowTheEndScreen(short enableFireworks)
Definition ending.c:495
void ReleasePacketHandle(void *handle)
Definition ending.c:50
short CheckEscaped(void)
Definition disk.c:442
unsigned int ReleaseTextFont(short fontIndex)
Definition disk.c:222
short __stdcall RandomInRange(short lo, short hi)
Definition mathfp.c:49
short RandomBelowOrEqual(short n)
Definition mathfp.c:59
unsigned int InitializeConversationViewport(void)
Definition main.c:422
unsigned int dump_buffer_to_screen(void)
Definition main.c:383
unsigned int ShowCampaignVictorySequence(void)
Definition ending.c:132
ObjectType
Definition wcdata.h:54
@ OBJECT_TYPE_HYPERSPACE_JUMP_FLASH
Definition wcdata.h:112
Side
Definition wcdata.h:173
#define SPACE_OBJECT_COUNT
Definition wcdata.h:1004
@ OBJECT_CLASS_PLANET
Definition wcdata.h:41