Wing Commander II
Reconstructed Win32 source (1996)
Loading...
Searching...
No Matches
wipe.c
Go to the documentation of this file.
1/*
2 * Viewport wipe transitions.
3 *
4 * Retail object 0x448570-0x44ADDF (link order; see docs/ORDER.md).
5 */
6/* This unit owns the wipe storage declared in globals.h (as statics). */
7#define WIPE_C
8#include "game.h"
9
10#pragma function(sqrt)
11/* Function start: 0x448570 */
12signed char InitializeViewportWipe(Viewport *source,
13 Viewport *destination,
14 int wipeType, short duration,
15 short passFlags, void *workspace)
16{
17 int halfWidth;
18 int halfHeight;
19 short scanline;
20
24 g_19_stFadeToView = *destination;
27 g_17_nFadeType = wipeType;
28 g_3_nWipeRoundFlags = passFlags;
30 duration = 15;
31
32 switch (g_17_nFadeType) {
33 case 0:
34 case 1:
35 case 2:
36 case 3:
37 case 4:
38 case 5:
39 case 6:
40 case 7:
41 case 8:
42 case 9:
44 destination->right - destination->left + 1;
46 destination->bottom - destination->top + 1;
51 } else {
55 }
56 break;
57 }
58
59 switch (g_17_nFadeType) {
60 case 0:
71 g_nBlendMaximumStep = (short)(
72 g_5_nBlendHeight + 1 < duration
74 : duration);
76 break;
77 case 1:
88 g_nBlendMaximumStep = (short)(
89 g_15_nFadeWidth + 1 < duration
90 ? g_15_nFadeWidth + 1
91 : duration);
93 break;
94 case 2:
105 g_nBlendMaximumStep = (short)(
106 g_5_nBlendHeight + 1 < duration
107 ? g_5_nBlendHeight + 1
108 : duration);
110 break;
111 case 3:
122 g_nBlendMaximumStep = (short)(
123 g_15_nFadeWidth + 1 < duration
124 ? g_15_nFadeWidth + 1
125 : duration);
127 break;
128 case 4:
135 (short)(duration < 320 ? duration : 320);
138 break;
139 case 5:
148 (short)(duration < 320 ? duration : 320);
151 break;
152 case 6:
163 (short)(duration < 320 ? duration : 320);
166 break;
167 case 7:
176 (short)(duration < 320 ? duration : 320);
179 break;
180 case 8:
187 halfWidth = g_15_nFadeWidth;
188 halfHeight = g_5_nBlendHeight;
189 g_18_nWipeTotalStages = (short)(
190 sqrt((double)(halfHeight * halfHeight +
191 halfWidth * halfWidth)) /
192 2.0 + 1.0);
194 g_nBlendMaximumStep = (short)(
195 g_18_nWipeTotalStages + 2 < duration
197 : duration);
199 for (scanline = 0; scanline < 200; scanline++) {
200 g_11_pWipeFrontEdges[scanline] = -1;
201 g_9_pWipeRearEdges[scanline] = -1;
202 }
203 break;
204 case 9:
211 halfWidth = g_15_nFadeWidth;
212 halfHeight = g_5_nBlendHeight;
213 g_18_nWipeTotalStages = (short)(
214 sqrt((double)(halfHeight * halfHeight +
215 halfWidth * halfWidth)) /
216 2.0 + 1.0);
218 g_nBlendMaximumStep = (short)(
219 g_18_nWipeTotalStages + 1 < duration
221 : duration);
223 for (scanline = 0; scanline < g_nWipeRadialRowCount; scanline++) {
224 g_11_pWipeFrontEdges[scanline] = 300;
225 g_9_pWipeRearEdges[scanline] = 300;
226 }
227 break;
228 }
229
236 (void)workspace;
237 return 1;
238}
239
240/* Function start: 0x448D1A */
241void SetViewportHorizontalBounds(Viewport *viewport, int left, int right)
242{
243 viewport->left = (short)left;
244 viewport->right = (short)right;
245}
246
247/* Function start: 0x448D39 */
248void SetViewportVerticalBounds(Viewport *viewport, int top, int bottom)
249{
250 viewport->top = (short)top;
251 viewport->bottom = (short)bottom;
252}
253
254/* Function start: 0x448D58 */
255signed char AdvanceViewportWipe(void *workspace)
256{
257 short verticalCount;
258 short horizontalCount;
259 short *edgeSwap;
260
261 switch (g_17_nFadeType) {
262 case 0:
263 verticalCount = 0;
269 verticalCount++;
271 }
274 if ((g_3_nWipeRoundFlags & 1) != 0) {
279 verticalCount);
284 verticalCount);
288 } else {
291 0, 1, 0, verticalCount);
294 0, 1, 0, verticalCount);
300 0, -1, 0, 0);
303 0, -1, 0, 0);
304 }
305 break;
306 case 1:
307 horizontalCount = 0;
313 horizontalCount++;
315 }
318 if ((g_3_nWipeRoundFlags & 1) != 0) {
322 horizontalCount,
327 horizontalCount,
332 } else {
335 -horizontalCount, 0, -1, 0);
338 -horizontalCount, 0, -1, 0);
344 0, 0, 1, 0);
347 0, 0, 1, 0);
348 }
349 break;
350 case 2:
351 verticalCount = 0;
357 verticalCount++;
359 }
362 if ((g_3_nWipeRoundFlags & 1) != 0) {
365 g_1_stWipeScratchSourcePort.top - verticalCount,
370 verticalCount,
375 } else {
378 0, -verticalCount, 0, -1);
381 0, -verticalCount, 0, -1);
387 0, 0, 0, 1);
390 0, 0, 0, 1);
391 }
392 break;
393 case 3:
394 horizontalCount = 0;
400 horizontalCount++;
402 }
405 if ((g_3_nWipeRoundFlags & 1) != 0) {
410 horizontalCount);
415 horizontalCount);
419 } else {
422 1, 0, horizontalCount, 0);
425 1, 0, horizontalCount, 0);
431 -1, 0, 0, 0);
434 -1, 0, 0, 0);
435 }
436 break;
437 case 4:
438 verticalCount = 0;
439 horizontalCount = verticalCount;
445 horizontalCount++;
447 }
454 verticalCount++;
455 }
459 horizontalCount + g_2_nWipePreviousAcrossEdge;
461 verticalCount + g_105_nFadePreviousVerticalEdge;
462 if ((g_3_nWipeRoundFlags & 1) != 0) {
464 horizontalCount != 0) {
486 }
487 if (verticalCount != 0) {
509 }
510 } else {
530 }
531 break;
532 case 5:
533 verticalCount = 0;
534 horizontalCount = verticalCount;
540 horizontalCount++;
542 }
549 verticalCount++;
550 }
554 g_2_nWipePreviousAcrossEdge - horizontalCount;
556 verticalCount + g_105_nFadePreviousVerticalEdge;
557 if ((g_3_nWipeRoundFlags & 1) != 0) {
559 horizontalCount != 0) {
581 }
582 if (verticalCount != 0) {
604 }
605 } else {
625 }
626 break;
627 case 6:
628 verticalCount = 0;
629 horizontalCount = verticalCount;
635 horizontalCount++;
637 }
644 verticalCount++;
645 }
649 g_2_nWipePreviousAcrossEdge - horizontalCount;
651 g_105_nFadePreviousVerticalEdge - verticalCount;
652 if ((g_3_nWipeRoundFlags & 1) != 0) {
656 horizontalCount != 0) {
678 }
679 if (verticalCount != 0) {
701 }
702 } else {
722 }
723 break;
724 case 7:
725 verticalCount = 0;
726 horizontalCount = verticalCount;
732 horizontalCount++;
734 }
741 verticalCount++;
742 }
746 horizontalCount + g_2_nWipePreviousAcrossEdge;
748 g_105_nFadePreviousVerticalEdge - verticalCount;
749 if ((g_3_nWipeRoundFlags & 1) != 0) {
753 horizontalCount != 0) {
775 }
776 if (verticalCount != 0) {
798 }
799 } else {
819 }
820 break;
821 case 8:
828 }
838 if ((g_3_nWipeRoundFlags & 1) != 0) {
839 edgeSwap = g_9_pWipeRearEdges;
841 g_11_pWipeFrontEdges = edgeSwap;
842 }
843 break;
844 case 9:
851 }
862 if ((g_3_nWipeRoundFlags & 1) != 0) {
863 edgeSwap = g_9_pWipeRearEdges;
865 g_11_pWipeFrontEdges = edgeSwap;
866 }
867 break;
868 }
869
874 (void)workspace;
876 return 1;
877 else
878 return 0;
879}
880
881/* Function start: 0x449FAE */
882void OffsetViewportBounds(Viewport *viewport, int left,
883 int top, int right, int bottom)
884{
885 viewport->left += (short)left;
886 viewport->top += (short)top;
887 viewport->right += (short)right;
888 viewport->bottom += (short)bottom;
889}
890
891/* Function start: 0x44A009 */
892void SetViewportRectangleBounds(Viewport *viewport, int left, int top,
893 int right, int bottom)
894{
895 viewport->left = (short)left;
896 viewport->top = (short)top;
897 viewport->right = (short)right;
898 viewport->bottom = (short)bottom;
899}
900
901/* Function start: 0x44A03C */
902void FinishViewportWipe(void *workspace)
903{
904 short width;
905 short height;
906
907 /* "!flags & 1" binds as "(!flags) & 1"; retail tests it that way. */
908 if (!g_3_nWipeRoundFlags & 1) {
911 } else {
912 switch (g_17_nFadeType) {
913 case 0:
914 height = g_18_nWipeTotalStages -
924 height);
928 break;
929 case 1:
930 width = g_18_nWipeTotalStages -
943 break;
944 case 2:
945 height = g_18_nWipeTotalStages -
958 break;
959 case 3:
960 width = g_18_nWipeTotalStages -
973 break;
974 case 4:
1003 }
1025 break;
1026 case 5:
1053 }
1075 break;
1076 case 6:
1101 }
1123 break;
1124 case 7:
1151 }
1173 break;
1174 case 8:
1183 break;
1184 case 9:
1194 break;
1195 }
1196 }
1197 (void)workspace;
1198}
1199
1200/* Function start: 0x44A910 */
1201void GenerateWipeRadialEdges(short *edges, int radius)
1202{
1203 short y;
1204 short err;
1205 short lastY;
1206 short decision;
1207 short blankRow;
1208 short x;
1209
1210 x = 0;
1211 y = (short)radius;
1212 err = (short)((1 - radius) * 2);
1213 if (g_nWipeRadialRowCount > y)
1214 edges[y] = x;
1215 lastY = y;
1216
1217 while (y > 0) {
1218 if (err < 0) {
1219 decision = (short)((err + y) * 2 - 1);
1220 if (decision > 0) {
1221 x++;
1222 y--;
1223 err += 2 * (x - y + 1);
1224 } else {
1225 x++;
1226 err += x * 2 + 1;
1227 }
1228 } else if (err > 0) {
1229 decision = (short)((err - x) * 2 - 1);
1230 if (decision > 0) {
1231 y--;
1232 err += 1 - y * 2;
1233 } else {
1234 x++;
1235 y--;
1236 err += 2 * (x - y + 1);
1237 }
1238 } else {
1239 x++;
1240 y--;
1241 err += 2 * (x - y + 1);
1242 }
1243 if (lastY != y) {
1244 if (g_nWipeRadialRowCount > y)
1245 edges[y] = x;
1246 lastY = y;
1247 }
1248 }
1249
1250 if (radius == 0)
1251 edges[0] = -1;
1252 for (blankRow = (short)(radius + 1);
1253 g_nWipeRadialRowCount > blankRow;
1254 blankRow++) {
1255 edges[blankRow] = -1;
1256 }
1257}
1258
1259#pragma function(memcpy)
1260/* Function start: 0x44AAE5 */
1261void BlitWipeRadialBands(Viewport *source, Viewport *destination,
1262 short *trailingEdges, short *leadingEdges)
1263{
1264 short src_left_center;
1265 unsigned short *dst_row_offsets_lower;
1266 short radial_right_half_end;
1267 short half_source_width;
1268 short source_right_x;
1269 short dest_right_x;
1270 short wipe_row_count;
1271 short remaining_upper_rows;
1272 short wipe_width;
1273 int lead_width;
1274 short top_center_row;
1275 int bands_processed;
1276 short *wipe_trailing_edge;
1277 short *wipe_leading_widths;
1278 short wipe_left_half_extent;
1279 unsigned short *lower_src_row_offsets;
1280 short lower_center_offset;
1281 short band_width;
1282 short dst_midpoint_left;
1283 unsigned short *src_top_rows;
1284 unsigned short *destination_top_rows;
1285
1286 wipe_width = source->right - source->left + 1;
1287 half_source_width = (wipe_width + 1) >> 1;
1288 wipe_left_half_extent = half_source_width - 1;
1289 radial_right_half_end = wipe_left_half_extent;
1290 wipe_row_count = source->bottom - source->top + 1;
1291 remaining_upper_rows = (wipe_row_count + 1) >> 1;
1292 top_center_row = remaining_upper_rows - 1;
1293 lower_center_offset = wipe_row_count >> 1;
1294 src_left_center = source->left + wipe_left_half_extent;
1295 source_right_x = source->left + radial_right_half_end;
1296 src_top_rows = source->rowOffsets +
1297 (source->top + top_center_row);
1298 lower_src_row_offsets = source->rowOffsets +
1299 (source->top + lower_center_offset);
1300 dst_midpoint_left = destination->left + wipe_left_half_extent;
1301 dest_right_x = destination->left + radial_right_half_end;
1302 destination_top_rows = destination->rowOffsets +
1303 (destination->top + top_center_row);
1304 dst_row_offsets_lower = destination->rowOffsets +
1305 (destination->top + lower_center_offset);
1306 bands_processed = 0;
1307 wipe_leading_widths = leadingEdges;
1308 wipe_trailing_edge = trailingEdges;
1309
1310 while ((lead_width = *wipe_leading_widths) >= 0) {
1311 if (lead_width >= half_source_width)
1312 lead_width = half_source_width - 1;
1313 if (*wipe_trailing_edge < half_source_width) {
1314 band_width = (short)(lead_width - *wipe_trailing_edge);
1315 memmove(destination->pixels + dst_row_offsets_lower[bands_processed] +
1316 *wipe_trailing_edge + dest_right_x + 1,
1317 source->pixels + lower_src_row_offsets[bands_processed] +
1318 *wipe_trailing_edge + source_right_x + 1,
1319 band_width);
1320 memmove(destination->pixels +
1321 (dst_row_offsets_lower[bands_processed] + dst_midpoint_left -
1322 1 - *wipe_trailing_edge) - band_width,
1323 source->pixels +
1324 (lower_src_row_offsets[bands_processed] + src_left_center - 1 -
1325 *wipe_trailing_edge) - band_width,
1326 band_width);
1327 {
1328 memmove(destination->pixels + *(dst_row_offsets_lower - bands_processed - 1) +
1329 *wipe_trailing_edge + dest_right_x,
1330 source->pixels + *(lower_src_row_offsets - bands_processed - 1) +
1331 *wipe_trailing_edge + source_right_x,
1332 band_width);
1333 memmove(destination->pixels +
1334 (*(dst_row_offsets_lower - bands_processed - 1) +
1335 dst_midpoint_left - *wipe_trailing_edge) - band_width,
1336 source->pixels +
1337 (*(lower_src_row_offsets - bands_processed - 1) + src_left_center -
1338 *wipe_trailing_edge) - band_width,
1339 band_width);
1340 }
1341 }
1342 bands_processed++;
1343 wipe_leading_widths++;
1344 wipe_trailing_edge++;
1345 remaining_upper_rows--;
1346 if (remaining_upper_rows == 0)
1347 break;
1348 }
1349}
1350
1351/* Linker commons defined here. LINK lays a unit's commons out by the
1352 * identifiers' hash keys, so these spellings follow the original addresses. */
1353short g_nWipeRadialRowCount; /* 0x005d17b4 */
void(__cdecl *g_pIxFree)(void *)
void OffsetViewportBounds(Viewport *viewport, int left, int top, int right, int bottom)
Definition wipe.c:882
void SetViewportRectangleBounds(Viewport *viewport, int left, int top, int right, int bottom)
Definition wipe.c:892
void SetViewportHorizontalBounds(Viewport *viewport, int left, int right)
Definition wipe.c:241
signed char InitializeViewportWipe(Viewport *source, Viewport *destination, int wipeType, short duration, short passFlags, void *workspace)
Definition wipe.c:12
void GenerateWipeRadialEdges(short *edges, int radius)
Definition wipe.c:1201
signed char AdvanceViewportWipe(void *workspace)
Definition wipe.c:255
void BlitWipeRadialBands(Viewport *source, Viewport *destination, short *trailingEdges, short *leadingEdges)
Definition wipe.c:1261
void SetViewportVerticalBounds(Viewport *viewport, int top, int bottom)
Definition wipe.c:248
void CopyViewportContents(Viewport *source, Viewport *destination)
Definition gr.c:995
void FinishViewportWipe(void *workspace)
Definition wipe.c:902
Shared Win32 declarations, types and library interfaces.
WIPE_STATIC short g_nBlendMaximumStep
Definition globals.h:578
WIPE_STATIC int g_18_nBlendRadialStep
Definition globals.h:549
WIPE_STATIC short g_nWipeCurrentVerticalEdges
Definition globals.h:566
short g_nWipeRadialRowCount
Definition wipe.c:1353
WIPE_STATIC Viewport g_1_stWipeScratchSourcePort
Definition globals.h:579
WIPE_STATIC int g_5_nWipeAcrossThreshold
Definition globals.h:571
WIPE_STATIC short g_asWipeRadialTrailingEdges[200]
Definition globals.h:553
WIPE_STATIC short g_2_nWipePreviousAcrossEdge
Definition globals.h:567
WIPE_STATIC short g_3_asWipeRadialLeadingEdge[200]
Definition globals.h:552
WIPE_STATIC int g_18_nWipeAcrossStride
Definition globals.h:569
WIPE_STATIC short g_139_nDissolveProgress
Definition globals.h:557
WIPE_STATIC Viewport g_3_stDissolveSourceViewport
Definition globals.h:572
WIPE_STATIC short * g_9_pWipeRearEdges
Definition globals.h:559
WIPE_STATIC short g_105_nFadePreviousVerticalEdge
Definition globals.h:568
WIPE_STATIC short g_5_nWipeMinorExtent
Definition globals.h:554
WIPE_STATIC short * g_11_pWipeFrontEdges
Definition globals.h:558
WIPE_STATIC Viewport g_19_stFadeToView
Definition globals.h:564
WIPE_STATIC int g_11_nWipeRadialAccumulator
Definition globals.h:550
WIPE_STATIC int g_16_nRevealVerticalDelta
Definition globals.h:575
WIPE_STATIC int g_1_nFadeRadialThreshold
Definition globals.h:551
WIPE_STATIC short g_3_nFadeCurrentHorizontalEdge
Definition globals.h:565
WIPE_STATIC short g_5_nBlendHeight
Definition globals.h:563
WIPE_STATIC int g_17_nFadeType
Definition globals.h:561
WIPE_STATIC Viewport g_26_stWipeTempDestinationViewport
Definition globals.h:573
WIPE_STATIC short g_3_nWipeRoundFlags
Definition globals.h:574
WIPE_STATIC signed char g_bBlendWidthLessThanHeight
Definition globals.h:556
WIPE_STATIC short g_18_nWipeTotalStages
Definition globals.h:560
WIPE_STATIC int g_14_nBlendHorizontalTotal
Definition globals.h:570
WIPE_STATIC signed char g_1_bWipeWidthAtLeastHeight
Definition globals.h:555
WIPE_STATIC int g_108_nTransitionVertSum
Definition globals.h:576
WIPE_STATIC short g_15_nFadeWidth
Definition globals.h:562
WIPE_STATIC int g_nRevealVertThreshold
Definition globals.h:577
unsigned char * pixels
Definition game.h:150
short right
Definition game.h:154
short bottom
Definition game.h:155
unsigned short * rowOffsets
Definition game.h:151
short left
Definition game.h:152
short top
Definition game.h:153