diff --git a/source/build/include/build.h b/source/build/include/build.h index b138a106a..432a020c8 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -329,10 +329,11 @@ typedef struct { uint32_t mdanimtims; int16_t mdanimcur; int16_t angoff, pitch, roll; - vec3_t offset; + vec3_t pivot_offset, position_offset; uint8_t flags; uint8_t xpanning, ypanning; uint8_t filler; + uint32_t filler2; float alpha; // NOTE: keep 'tspr' on an 8-byte boundary: tspriteptr_t tspr; diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 1fe231be2..567128913 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -6108,13 +6108,17 @@ draw_as_face_sprite: } } + x = tspr->x + spriteext[spritenum].position_offset.x; + y = tspr->y + spriteext[spritenum].position_offset.y; + z = tspr->z + spriteext[spritenum].position_offset.z; + i = (int32_t)tspr->ang+1536; i += spriteext[spritenum].angoff; const int32_t ceilingz = (sec->ceilingstat&3) == 0 ? sec->ceilingz : INT32_MIN; const int32_t floorz = (sec->floorstat&3) == 0 ? sec->floorz : INT32_MAX; - classicDrawVoxel(tspr->x,tspr->y,tspr->z,i,daxrepeat,(int32_t)tspr->yrepeat,vtilenum, + classicDrawVoxel(x,y,z,i,daxrepeat,(int32_t)tspr->yrepeat,vtilenum, tspr->shade,tspr->pal,lwall.Data(),swall.Data(),tspr->cstat,(tspr->cstat&48)!=48,floorz,ceilingz); } diff --git a/source/build/src/mdsprite.cpp b/source/build/src/mdsprite.cpp index 4ff6a24b8..b9abbd106 100644 --- a/source/build/src/mdsprite.cpp +++ b/source/build/src/mdsprite.cpp @@ -1428,8 +1428,8 @@ void md3_vox_calcmat_common(tspriteptr_t tspr, const vec3f_t *a0, float f, float float g; float k0, k1, k2, k3, k4, k5, k6, k7; - k0 = ((float)(tspr->x-globalposx))*f*(1.f/1024.f); - k1 = ((float)(tspr->y-globalposy))*f*(1.f/1024.f); + k0 = ((float)(tspr->x+spriteext[tspr->owner].position_offset.x-globalposx))*f*(1.f/1024.f); + k1 = ((float)(tspr->y+spriteext[tspr->owner].position_offset.y-globalposy))*f*(1.f/1024.f); f = gcosang2*gshang/gvrcorrection; g = gsinang2*gshang/gvrcorrection; k4 = (float)sintable[(tspr->ang+spriteext[tspr->owner].angoff+1024)&2047] * (1.f/16384.f); @@ -1521,7 +1521,7 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr) a0.z = m->zadd * m->scale; // Parkar: Moved up to be able to use k0 for the y-flipping code - k0 = (float)tspr->z; + k0 = (float)tspr->z+spriteext[tspr->owner].position_offset.z; if ((globalorientation&128) && !((globalorientation&48)==32)) k0 += (float)(sizyrep<<1); @@ -1544,7 +1544,7 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr) m0.z *= f; m1.z *= f; a0.z *= f; // floor aligned - k1 = (float)tspr->y; + k1 = (float)tspr->y+spriteext[tspr->owner].position_offset.y; if ((globalorientation&48)==32) { m0.z = -m0.z; m1.z = -m1.z; a0.z = -a0.z; @@ -1557,7 +1557,7 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr) // calculations below again, but are needed for the base offsets. f = (65536.f*512.f)/(fxdimen*fviewingrange); g = 32.f/(fxdimen*gxyaspect); - m0.y *= f; m1.y *= f; a0.y = (((float)(tspr->x-globalposx))* (1.f/1024.f) + a0.y)*f; + m0.y *= f; m1.y *= f; a0.y = (((float)(tspr->x+spriteext[tspr->owner].position_offset.x-globalposx))* (1.f/1024.f) + a0.y)*f; m0.x *=-f; m1.x *=-f; a0.x = ((k1 -fglobalposy) * -(1.f/1024.f) + a0.x)*-f; m0.z *= g; m1.z *= g; a0.z = ((k0 -fglobalposz) * -(1.f/16384.f) + a0.z)*g; @@ -1623,14 +1623,14 @@ static int32_t polymost_md3draw(md3model_t *m, tspriteptr_t tspr) float f = 1.f/(fxdimen * fviewingrange) * (256.f/(65536.f*128.f)) * (m0.x+m1.x); Bmemset(&a0, 0, sizeof(a0)); - if (sext->offset.x) - a0.x = (float) sext->offset.x * f; + if (sext->pivot_offset.x) + a0.x = (float) sext->pivot_offset.x * f; - if (sext->offset.y) // Compare with SCREEN_FACTORS above - a0.y = (float) sext->offset.y * f; + if (sext->pivot_offset.y) // Compare with SCREEN_FACTORS above + a0.y = (float) sext->pivot_offset.y * f; - if ((sext->offset.z) && !(tspr->clipdist & TSPR_FLAGS_MDHACK)) // Compare with SCREEN_FACTORS above - a0.z = (float)sext->offset.z / (gxyaspect * fxdimen * (65536.f/128.f) * (m0.z+m1.z)); + if ((sext->pivot_offset.z) && !(tspr->clipdist & TSPR_FLAGS_MDHACK)) // Compare with SCREEN_FACTORS above + a0.z = (float)sext->pivot_offset.z / (gxyaspect * fxdimen * (65536.f/128.f) * (m0.z+m1.z)); k0 = (float)sintable[(sext->pitch+512)&2047] * (1.f/16384.f); k1 = (float)sintable[sext->pitch&2047] * (1.f/16384.f); diff --git a/source/build/src/mhk.cpp b/source/build/src/mhk.cpp index 0ac922632..7d8224aae 100644 --- a/source/build/src/mhk.cpp +++ b/source/build/src/mhk.cpp @@ -46,9 +46,12 @@ int32_t engineLoadMHK(const char *filename) T_NOANIM, T_PITCH, T_ROLL, - T_MDXOFF, - T_MDYOFF, - T_MDZOFF, + T_PIVOTXOFF, + T_PIVOTYOFF, + T_PIVOTZOFF, + T_POSITIONXOFF, + T_POSITIONYOFF, + T_POSITIONZOFF, T_AWAY1, T_AWAY2, T_LIGHT, @@ -67,9 +70,21 @@ int32_t engineLoadMHK(const char *filename) { "nomdanim", T_NOANIM }, { "pitch", T_PITCH }, { "roll", T_ROLL }, - { "mdxoff", T_MDXOFF }, - { "mdyoff", T_MDYOFF }, - { "mdzoff", T_MDZOFF }, + { "mdxoff", T_PIVOTXOFF }, + { "mdyoff", T_PIVOTYOFF }, + { "mdzoff", T_PIVOTZOFF }, + { "pivxoff", T_PIVOTXOFF }, + { "pivyoff", T_PIVOTYOFF }, + { "pivzoff", T_PIVOTZOFF }, + { "pivotxoff", T_PIVOTXOFF }, + { "pivotyoff", T_PIVOTYOFF }, + { "pivotzoff", T_PIVOTZOFF }, + { "posxoff", T_POSITIONXOFF }, + { "posyoff", T_POSITIONYOFF }, + { "poszoff", T_POSITIONZOFF }, + { "positionxoff", T_POSITIONXOFF }, + { "positionyoff", T_POSITIONYOFF }, + { "positionzoff", T_POSITIONZOFF }, { "away1", T_AWAY1 }, { "away2", T_AWAY2 }, { "light", T_LIGHT }, @@ -197,7 +212,7 @@ int32_t engineLoadMHK(const char *filename) spriteext[whichsprite].roll = (int16_t) roll; } break; - case T_MDXOFF: // mdxoff + case T_PIVOTXOFF: // pivxoff { int32_t i; if (scriptfile_getnumber(script, &i)) break; @@ -205,14 +220,14 @@ int32_t engineLoadMHK(const char *filename) if (whichsprite < 0) { // no sprite directive preceeding - initprintf("Ignoring mdxoff directive because of absent/invalid sprite number on line %s:%d\n", + initprintf("Ignoring mdxoff/pivxoff directive because of absent/invalid sprite number on line %s:%d\n", script->filename, scriptfile_getlinum(script, cmdtokptr)); break; } - spriteext[whichsprite].offset.x = i; + spriteext[whichsprite].pivot_offset.x = i; } break; - case T_MDYOFF: // mdyoff + case T_PIVOTYOFF: // pivyoff { int32_t i; if (scriptfile_getnumber(script, &i)) break; @@ -220,14 +235,14 @@ int32_t engineLoadMHK(const char *filename) if (whichsprite < 0) { // no sprite directive preceeding - initprintf("Ignoring mdyoff directive because of absent/invalid sprite number on line %s:%d\n", + initprintf("Ignoring mdyoff/pivyoff directive because of absent/invalid sprite number on line %s:%d\n", script->filename, scriptfile_getlinum(script, cmdtokptr)); break; } - spriteext[whichsprite].offset.y = i; + spriteext[whichsprite].pivot_offset.y = i; } break; - case T_MDZOFF: // mdzoff + case T_PIVOTZOFF: // pivzoff { int32_t i; if (scriptfile_getnumber(script, &i)) break; @@ -235,11 +250,56 @@ int32_t engineLoadMHK(const char *filename) if (whichsprite < 0) { // no sprite directive preceeding - initprintf("Ignoring mdzoff directive because of absent/invalid sprite number on line %s:%d\n", + initprintf("Ignoring mdzoff/pivzoff directive because of absent/invalid sprite number on line %s:%d\n", script->filename, scriptfile_getlinum(script, cmdtokptr)); break; } - spriteext[whichsprite].offset.z = i; + spriteext[whichsprite].pivot_offset.z = i; + } + break; + case T_POSITIONXOFF: // posxoff + { + int32_t i; + if (scriptfile_getnumber(script, &i)) break; + + if (whichsprite < 0) + { + // no sprite directive preceeding + initprintf("Ignoring posxoff directive because of absent/invalid sprite number on line %s:%d\n", + script->filename, scriptfile_getlinum(script, cmdtokptr)); + break; + } + spriteext[whichsprite].position_offset.x = i; + } + break; + case T_POSITIONYOFF: // posyoff + { + int32_t i; + if (scriptfile_getnumber(script, &i)) break; + + if (whichsprite < 0) + { + // no sprite directive preceeding + initprintf("Ignoring posyoff directive because of absent/invalid sprite number on line %s:%d\n", + script->filename, scriptfile_getlinum(script, cmdtokptr)); + break; + } + spriteext[whichsprite].position_offset.y = i; + } + break; + case T_POSITIONZOFF: // poszoff + { + int32_t i; + if (scriptfile_getnumber(script, &i)) break; + + if (whichsprite < 0) + { + // no sprite directive preceeding + initprintf("Ignoring poszoff directive because of absent/invalid sprite number on line %s:%d\n", + script->filename, scriptfile_getlinum(script, cmdtokptr)); + break; + } + spriteext[whichsprite].position_offset.z = i; } break; case T_AWAY1: // away1 diff --git a/source/build/src/voxmodel.cpp b/source/build/src/voxmodel.cpp index af5789e13..ffdc8c280 100644 --- a/source/build/src/voxmodel.cpp +++ b/source/build/src/voxmodel.cpp @@ -1035,7 +1035,7 @@ int32_t polymost_voxdraw(voxmodel_t *m, tspriteptr_t const tspr) f = (float) tspr->yrepeat * k0; m0.z *= f; a0.z *= f; - k0 = (float) tspr->z; + k0 = (float) (tspr->z+spriteext[tspr->owner].position_offset.z); f = ((globalorientation&8) && (sprite[tspr->owner].cstat&48)!=0) ? -4.f : 4.f; k0 -= (tspr->yoffset*tspr->yrepeat)*f*m->bscale; zoff = m->siz.z*.5f; @@ -1053,8 +1053,8 @@ int32_t polymost_voxdraw(voxmodel_t *m, tspriteptr_t const tspr) int const shadowHack = !!(tspr->clipdist & TSPR_FLAGS_MDHACK); - m0.y *= f; a0.y = (((float)(tspr->x-globalposx)) * (1.f/1024.f) + a0.y) * f; - m0.x *=-f; a0.x = (((float)(tspr->y-globalposy)) * -(1.f/1024.f) + a0.x) * -f; + m0.y *= f; a0.y = (((float)(tspr->x+spriteext[tspr->owner].position_offset.x-globalposx)) * (1.f/1024.f) + a0.y) * f; + m0.x *=-f; a0.x = (((float)(tspr->y+spriteext[tspr->owner].position_offset.y-globalposy)) * -(1.f/1024.f) + a0.x) * -f; m0.z *= g; a0.z = (((float)(k0 -globalposz - shadowHack)) * -(1.f/16384.f) + a0.z) * g; float mat[16]; diff --git a/source/duke3d/src/actors.h b/source/duke3d/src/actors.h index 94a2340bc..312aa01b5 100644 --- a/source/duke3d/src/actors.h +++ b/source/duke3d/src/actors.h @@ -315,9 +315,13 @@ typedef struct netactor_s ext_pitch, ext_roll, - ext_offset_x, - ext_offset_y, - ext_offset_z, + ext_pivot_offset_x, + ext_pivot_offset_y, + ext_pivot_offset_z, + + ext_position_offset_x, + ext_position_offset_y, + ext_position_offset_z, ext_flags, ext_xpanning, diff --git a/source/duke3d/src/gamedef.h b/source/duke3d/src/gamedef.h index f46bc8df0..912cbaafa 100644 --- a/source/duke3d/src/gamedef.h +++ b/source/duke3d/src/gamedef.h @@ -737,9 +737,12 @@ enum ActorLabel_t ACTOR_ANGOFF = ACTOR_SPRITEEXT_BEGIN, ACTOR_PITCH, ACTOR_ROLL, - ACTOR_MDXOFF, - ACTOR_MDYOFF, - ACTOR_MDZOFF, + ACTOR_PIVOTXOFF, + ACTOR_PIVOTYOFF, + ACTOR_PIVOTZOFF, + ACTOR_POSITIONXOFF, + ACTOR_POSITIONYOFF, + ACTOR_POSITIONZOFF, ACTOR_MDFLAGS, ACTOR_XPANNING, ACTOR_YPANNING, diff --git a/source/duke3d/src/gamestructures.cpp b/source/duke3d/src/gamestructures.cpp index 8a4713b98..41a267a33 100644 --- a/source/duke3d/src/gamestructures.cpp +++ b/source/duke3d/src/gamestructures.cpp @@ -305,9 +305,12 @@ const memberlabel_t ActorLabels[]= LABEL_SETUP(spriteext, pitch, ACTOR_PITCH), LABEL_SETUP(spriteext, roll, ACTOR_ROLL), - LABEL_SETUP_UNMATCHED(spriteext, offset.x, "mdxoff", ACTOR_MDXOFF), - LABEL_SETUP_UNMATCHED(spriteext, offset.y, "mdyoff", ACTOR_MDYOFF), - LABEL_SETUP_UNMATCHED(spriteext, offset.z, "mdzoff", ACTOR_MDZOFF), + LABEL_SETUP_UNMATCHED(spriteext, pivot_offset.x, "mdxoff", ACTOR_PIVOTXOFF), + LABEL_SETUP_UNMATCHED(spriteext, pivot_offset.y, "mdyoff", ACTOR_PIVOTYOFF), + LABEL_SETUP_UNMATCHED(spriteext, pivot_offset.z, "mdzoff", ACTOR_PIVOTZOFF), + LABEL_SETUP_UNMATCHED(spriteext, position_offset.x, "posxoff", ACTOR_POSITIONXOFF), + LABEL_SETUP_UNMATCHED(spriteext, position_offset.y, "posyoff", ACTOR_POSITIONYOFF), + LABEL_SETUP_UNMATCHED(spriteext, position_offset.z, "poszoff", ACTOR_POSITIONZOFF), LABEL_SETUP_UNMATCHED(spriteext, flags, "mdflags", ACTOR_MDFLAGS), LABEL_SETUP(spriteext, xpanning, ACTOR_XPANNING), diff --git a/source/duke3d/src/network.cpp b/source/duke3d/src/network.cpp index 69cd7c6fc..13b90b70d 100644 --- a/source/duke3d/src/network.cpp +++ b/source/duke3d/src/network.cpp @@ -402,9 +402,13 @@ static netField_t ActorFields[] = { ACTF(ext_pitch), 16 }, { ACTF(ext_roll), 16 }, - { ACTF(ext_offset_x), 32 }, - { ACTF(ext_offset_y), 32 }, - { ACTF(ext_offset_z), 32 }, + { ACTF(ext_pivot_offset_x), 32 }, + { ACTF(ext_pivot_offset_y), 32 }, + { ACTF(ext_pivot_offset_z), 32 }, + + { ACTF(ext_position_offset_x), 32 }, + { ACTF(ext_position_offset_y), 32 }, + { ACTF(ext_position_offset_z), 32 }, { ACTF(ext_flags), 8 }, { ACTF(ext_xpanning), 8 }, @@ -1020,9 +1024,13 @@ static void Net_CopySpriteExtFromNet(const netactor_t* netActor, spriteext_t* ga gameSprExt->pitch = netActor->ext_pitch; gameSprExt->roll = netActor->ext_roll; - gameSprExt->offset.x = netActor->ext_offset_x; - gameSprExt->offset.y = netActor->ext_offset_y; - gameSprExt->offset.z = netActor->ext_offset_z; + gameSprExt->pivot_offset.x = netActor->ext_pivot_offset_x; + gameSprExt->pivot_offset.y = netActor->ext_pivot_offset_y; + gameSprExt->pivot_offset.z = netActor->ext_pivot_offset_z; + + gameSprExt->position_offset.x = netActor->ext_position_offset_x; + gameSprExt->position_offset.y = netActor->ext_position_offset_y; + gameSprExt->position_offset.z = netActor->ext_position_offset_z; gameSprExt->flags = netActor->ext_flags; gameSprExt->xpanning = netActor->ext_xpanning; @@ -1375,9 +1383,13 @@ static void Net_CopySpriteExtToNet(const spriteext_t* gameSpriteExt, netactor_t* netActor->ext_pitch = gameSpriteExt->pitch; netActor->ext_roll = gameSpriteExt->roll; - netActor->ext_offset_x = gameSpriteExt->offset.x; - netActor->ext_offset_y = gameSpriteExt->offset.y; - netActor->ext_offset_z = gameSpriteExt->offset.z; + netActor->ext_pivot_offset_x = gameSpriteExt->pivot_offset.x; + netActor->ext_pivot_offset_y = gameSpriteExt->pivot_offset.y; + netActor->ext_pivot_offset_z = gameSpriteExt->pivot_offset.z; + + netActor->ext_position_offset_x = gameSpriteExt->position_offset.x; + netActor->ext_position_offset_y = gameSpriteExt->position_offset.y; + netActor->ext_position_offset_z = gameSpriteExt->position_offset.z; netActor->ext_flags = gameSpriteExt->flags; netActor->ext_xpanning = gameSpriteExt->xpanning;