summaryrefslogtreecommitdiff
path: root/3dc/MORPH.C
diff options
context:
space:
mode:
authorRebellion Developments <rebellion@nomail>2000-03-16 11:25:00 +0100
committerPatryk Obara <dreamer.tan@gmail.com>2019-08-19 05:45:17 +0200
commit218ca90543758a20ac326e444ca0643174ca7384 (patch)
tree16bfe3e5307f9f515489000f28728224291a0e3b /3dc/MORPH.C
Import Aliens vs Predator - Gold (Build 116)
Source code release, imported from: https://www.gamefront.com/games/aliens-vs-predator-3/file/avp-gold-complete-source-code All text files were converted to Unix format.
Diffstat (limited to '3dc/MORPH.C')
-rw-r--r--3dc/MORPH.C322
1 files changed, 322 insertions, 0 deletions
diff --git a/3dc/MORPH.C b/3dc/MORPH.C
new file mode 100644
index 0000000..d868a50
--- /dev/null
+++ b/3dc/MORPH.C
@@ -0,0 +1,322 @@
+#include "3dc.h"
+
+#include "inline.h"
+
+
+/*
+ externs for commonly used global variables and arrays
+*/
+
+ extern MORPHDISPLAY MorphDisplay;
+ extern int NormalFrameTime;
+
+
+/*
+
+ Global Variables
+
+*/
+
+
+
+
+
+/*
+
+ Update Morphing Animation Control Block
+
+*/
+
+void UpdateMorphing(MORPHCTRL *mcptr)
+
+{
+
+ MORPHHEADER *mhdr = mcptr->ObMorphHeader;
+ int UpdateRate;
+
+
+ /*textprint("UpdateMorphing\n");*/
+
+
+ if(mcptr->ObMorphFlags & mph_flag_play) {
+
+ /* How fast? */
+
+ if(mcptr->ObMorphSpeed == ONE_FIXED) {
+
+ UpdateRate = NormalFrameTime;
+
+ }
+
+ else {
+
+ UpdateRate = MUL_FIXED(NormalFrameTime, mcptr->ObMorphSpeed);
+
+ }
+
+
+ /* Update the current frame */
+
+ if(mcptr->ObMorphFlags & mph_flag_reverse) {
+
+ mcptr->ObMorphCurrFrame -= UpdateRate;
+
+ if(mcptr->ObMorphCurrFrame < 0) {
+
+ if(mcptr->ObMorphFlags & mph_flag_noloop) {
+
+ mcptr->ObMorphCurrFrame = 0;
+
+ /* The sequence has finished and we are at the start */
+
+ mcptr->ObMorphFlags |= (mph_flag_finished | mph_flag_start);
+
+ }
+
+ else {
+
+ mcptr->ObMorphCurrFrame += mhdr->mph_maxframes;
+
+ /* The sequence has looped and we are back at the end */
+
+ mcptr->ObMorphFlags |= (mph_flag_looped | mph_flag_end);
+
+ }
+
+ }
+
+ }
+
+ else {
+
+ mcptr->ObMorphCurrFrame += UpdateRate;
+
+ if(mcptr->ObMorphCurrFrame >= mhdr->mph_maxframes) {
+
+ if(mcptr->ObMorphFlags & mph_flag_noloop) {
+
+ /* The sequence has finished and we are at the end */
+
+ mcptr->ObMorphFlags |= (mph_flag_finished | mph_flag_end);
+
+ mcptr->ObMorphCurrFrame = mhdr->mph_maxframes - 1;
+
+ }
+
+ else {
+
+ mcptr->ObMorphCurrFrame -= mhdr->mph_maxframes;
+
+ /* The sequence has looped and we are back at the start */
+
+ mcptr->ObMorphFlags |= (mph_flag_looped | mph_flag_start);
+
+ }
+
+ }
+
+ }
+
+ }
+
+}
+
+
+
+/*
+
+ Update the Morphing Animation for this object
+
+*/
+
+void UpdateMorphingDptr(DISPLAYBLOCK *dptr)
+
+{
+
+ SHAPEHEADER *sptr1;
+ SHAPEHEADER *sptr2;
+
+
+ /* Update object radius and extents */
+
+ GetMorphDisplay(&MorphDisplay, dptr);
+
+ sptr1 = MorphDisplay.md_sptr1;
+ sptr2 = MorphDisplay.md_sptr2;
+
+ #if 0
+ textprint("sptr1->shaperadius = %d\n", sptr1->shaperadius);
+ textprint("sptr2->shaperadius = %d\n", sptr2->shaperadius);
+ #endif
+
+
+ /* Radius */
+
+ if(sptr1->shaperadius == sptr2->shaperadius) {
+
+ dptr->ObRadius = sptr1->shaperadius;
+
+ }
+
+ else {
+
+ dptr->ObRadius = WideMul2NarrowDiv(sptr1->shaperadius,
+ MorphDisplay.md_one_minus_lerp,
+ sptr2->shaperadius,
+ MorphDisplay.md_lerp, ONE_FIXED);
+
+ }
+
+
+ /* X Extent */
+
+ if(sptr1->shapemaxx == sptr2->shapemaxx) {
+
+ dptr->ObMaxX = sptr1->shapemaxx;
+
+ }
+
+ else {
+
+ dptr->ObMaxX = WideMul2NarrowDiv(sptr1->shapemaxx,
+ MorphDisplay.md_one_minus_lerp,
+ sptr2->shapemaxx,
+ MorphDisplay.md_lerp, ONE_FIXED);
+
+ }
+
+ if(sptr1->shapeminx == sptr2->shapeminx) {
+
+ dptr->ObMinX = sptr1->shapeminx;
+
+ }
+
+ else {
+
+ dptr->ObMinX = WideMul2NarrowDiv(sptr1->shapeminx,
+ MorphDisplay.md_one_minus_lerp,
+ sptr2->shapeminx,
+ MorphDisplay.md_lerp, ONE_FIXED);
+
+ }
+
+
+ /* Y Extent */
+
+ if(sptr1->shapemaxy == sptr2->shapemaxy) {
+
+ dptr->ObMaxY = sptr1->shapemaxy;
+
+ }
+
+ else {
+
+ dptr->ObMaxY = WideMul2NarrowDiv(sptr1->shapemaxy,
+ MorphDisplay.md_one_minus_lerp,
+ sptr2->shapemaxy,
+ MorphDisplay.md_lerp, ONE_FIXED);
+
+ }
+
+ if(sptr1->shapeminy == sptr2->shapeminy) {
+
+ dptr->ObMinY = sptr1->shapeminy;
+
+ }
+
+ else {
+
+ dptr->ObMinY = WideMul2NarrowDiv(sptr1->shapeminy,
+ MorphDisplay.md_one_minus_lerp,
+ sptr2->shapeminy,
+ MorphDisplay.md_lerp, ONE_FIXED);
+
+ }
+
+
+ /* Z Extent */
+
+ if(sptr1->shapemaxz == sptr2->shapemaxz) {
+
+ dptr->ObMaxZ = sptr1->shapemaxz;
+
+ }
+
+ else {
+
+ dptr->ObMaxZ = WideMul2NarrowDiv(sptr1->shapemaxz,
+ MorphDisplay.md_one_minus_lerp,
+ sptr2->shapemaxz,
+ MorphDisplay.md_lerp, ONE_FIXED);
+
+ }
+
+ if(sptr1->shapeminz == sptr2->shapeminz) {
+
+ dptr->ObMinZ = sptr1->shapeminz;
+
+ }
+
+ else {
+
+ dptr->ObMinZ = WideMul2NarrowDiv(sptr1->shapeminz,
+ MorphDisplay.md_one_minus_lerp,
+ sptr2->shapeminz,
+ MorphDisplay.md_lerp, ONE_FIXED);
+
+ }
+
+ #if 0
+ textprint("dptr->ObRadius = %d\n", dptr->ObRadius);
+ #endif
+
+}
+
+
+
+/*
+
+ Using the current frame, calculate the lerp values and find out which two
+ shapes to interpolate between.
+
+ Write this information back to a MORPHDISPLAY structure.
+
+*/
+
+void GetMorphDisplay(MORPHDISPLAY *md, DISPLAYBLOCK *dptr)
+
+{
+
+ MORPHFRAME *mdata;
+ MORPHCTRL *mc = dptr->ObMorphCtrl;
+ MORPHHEADER *mhdr = mc->ObMorphHeader;
+
+
+ md->md_lerp = mc->ObMorphCurrFrame & 0xffff;
+ md->md_one_minus_lerp = ONE_FIXED - md->md_lerp;
+
+ mdata = mhdr->mph_frames;
+ mdata = &mdata[mc->ObMorphCurrFrame >> 16];
+
+ md->md_shape1 = mdata->mf_shape1;
+ md->md_shape2 = mdata->mf_shape2;
+
+ md->md_sptr1 = GetShapeData(md->md_shape1);
+ md->md_sptr2 = GetShapeData(md->md_shape2);
+
+}
+
+
+void CopyMorphCtrl(MORPHCTRL *src, MORPHCTRL *dst)
+
+{
+
+ dst->ObMorphCurrFrame = src->ObMorphCurrFrame;
+ dst->ObMorphFlags = src->ObMorphFlags;
+ dst->ObMorphSpeed = src->ObMorphSpeed;
+ dst->ObMorphHeader = src->ObMorphHeader;
+
+}
+
+
+ \ No newline at end of file