Use type safe angle and horizon classes for the render interface

These need to be robust and not allow implicit conversions.
This commit is contained in:
Christoph Oelckers 2020-07-23 17:01:37 +02:00
parent 9742bc72aa
commit 945dbc9f7e
7 changed files with 82 additions and 64 deletions

View file

@ -95,6 +95,14 @@ public:
return binangle(value - other.value);
}
void interpolate(binangle a1, binangle a2, fix16_t smoothratio)
{
// Calculate in floating point to reduce the error caused by overflows which are to be expected here and then downconvert using a method that is safe to overflow.
// We do not want fixed point multiplications here to trash the result.
double smooth = smoothratio / 65536.f;
value = xs_CRoundToUInt(double(a1.asbam()) + smooth * (double(a2.asbam()) - double(a1.asbam())));
}
};
@ -170,7 +178,6 @@ public:
{
return fixedhoriz(value - other.value);
}
};

View file

@ -322,9 +322,11 @@ void animatesprites_d(int x,int y,int a,int smoothratio)
t->cstat |= 2;
if ( screenpeek == myconnectindex && numplayers >= 2 )
{
t->x = omyx + mulscale16((int)( myx - omyx), smoothratio);
t->x = omyx + mulscale16((int)(myx - omyx), smoothratio);
t->y = omyy + mulscale16((int)(myy - omyy), smoothratio);
t->z = omyz + mulscale16((int)(myz - omyz), smoothratio) + (40 << 8);
int omyang = fix16_to_int(oq16myang);
int myang = fix16_to_int(q16myang);
t->ang = omyang + mulscale16((int)(((myang + 1024 - omyang) & 2047) - 1024), smoothratio);
t->sectnum = mycursectnum;
}
@ -742,4 +744,4 @@ void animatesprites_d(int x,int y,int a,int smoothratio)
}
END_DUKE_NS
END_DUKE_NS

View file

@ -374,6 +374,8 @@ void animatesprites_r(int x,int y,int a,int smoothratio)
t->x = omyx + mulscale16((int)(myx - omyx), smoothratio);
t->y = omyy + mulscale16((int)(myy - omyy), smoothratio);
t->z = omyz + mulscale16((int)(myz - omyz), smoothratio) + (40 << 8);
int omyang = fix16_to_int(oq16myang);
int myang = fix16_to_int(q16myang);
t->ang = omyang + mulscale16((int)(((myang + 1024 - omyang) & 2047) - 1024), smoothratio);
t->sectnum = mycursectnum;
}

View file

@ -306,6 +306,8 @@ void displayrest(int smoothratio)
{
cposx = omyx + mulscale16(myx - omyx, smoothratio);
cposy = omyy + mulscale16(myy - omyy, smoothratio);
int omyang = fix16_to_int(oq16myang);
int myang = fix16_to_int(q16myang);
cang = fix16_to_int(omyang) + mulscale16((fix16_to_int(myang + F16(1024) - omyang) & 2047) - 1024, smoothratio);
}
else

View file

@ -39,8 +39,9 @@ BEGIN_DUKE_NS
int myx, omyx, myxvel, myy, omyy, myyvel, myz, omyz, myzvel;
short myhoriz, omyhoriz, myhorizoff, omyhorizoff, globalskillsound;
short myang, omyang, mycursectnum, myjumpingcounter;
short globalskillsound;
fix16_t q16myang, oq16myang, q16myhoriz, oq16myhoriz, q16myhorizoff, oq16myhorizoff;
short mycursectnum, myjumpingcounter;
char myjumpingtoggle, myonground, myhardlanding,myreturntocenter;
int fakemovefifoplc;
int myxbak[MOVEFIFOSIZ], myybak[MOVEFIFOSIZ], myzbak[MOVEFIFOSIZ];
@ -50,20 +51,20 @@ short myangbak[MOVEFIFOSIZ];
void resetmys()
{
myx = omyx = ps[myconnectindex].posx;
myy = omyy = ps[myconnectindex].posy;
myz = omyz = ps[myconnectindex].posz;
myxvel = myyvel = myzvel = 0;
myang = omyang = ps[myconnectindex].getang();
myhoriz = omyhoriz = ps[myconnectindex].gethoriz();
myhorizoff = omyhorizoff = ps[myconnectindex].gethorizof();
mycursectnum = ps[myconnectindex].cursectnum;
myjumpingcounter = ps[myconnectindex].jumping_counter;
myjumpingtoggle = ps[myconnectindex].jumping_toggle;
myonground = ps[myconnectindex].on_ground;
myhardlanding = ps[myconnectindex].hard_landing;
myreturntocenter = ps[myconnectindex].return_to_center;
}
myx = omyx = ps[myconnectindex].posx;
myy = omyy = ps[myconnectindex].posy;
myz = omyz = ps[myconnectindex].posz;
myxvel = myyvel = myzvel = 0;
q16myang = oq16myang = ps[myconnectindex].q16ang;
q16myhoriz = oq16myhoriz = ps[myconnectindex].q16horiz;
q16myhorizoff = oq16myhorizoff = ps[myconnectindex].q16horizoff;
mycursectnum = ps[myconnectindex].cursectnum;
myjumpingcounter = ps[myconnectindex].jumping_counter;
myjumpingtoggle = ps[myconnectindex].jumping_toggle;
myonground = ps[myconnectindex].on_ground;
myhardlanding = ps[myconnectindex].hard_landing;
myreturntocenter = ps[myconnectindex].return_to_center;
}
#if 0 // todo: fix this when networking works again
void fakedomovethingscorrect(void)

View file

@ -3,8 +3,9 @@
BEGIN_DUKE_NS
extern int myx, omyx, myxvel, myy, omyy, myyvel, myz, omyz, myzvel;
extern short myhoriz, omyhoriz, myhorizoff, omyhorizoff, globalskillsound;
extern short myang, omyang, mycursectnum, myjumpingcounter;
extern short globalskillsound;
extern short mycursectnum, myjumpingcounter;
extern fix16_t q16myang, oq16myang, q16myhoriz, oq16myhoriz, q16myhorizoff, oq16myhorizoff;
extern char myjumpingtoggle, myonground, myhardlanding,myreturntocenter;
extern int fakemovefifoplc;
extern int myxbak[MOVEFIFOSIZ], myybak[MOVEFIFOSIZ], myzbak[MOVEFIFOSIZ];

View file

@ -58,7 +58,7 @@ static int tempsectorz[MAXSECTORS];
static int tempsectorpicnum[MAXSECTORS];
//short tempcursectnum;
void SE40_Draw(int tag, int spnum, int x, int y, int z, int a, int h, int smoothratio)
void SE40_Draw(int tag, int spnum, int x, int y, int z, binangle a, fixedhoriz h, int smoothratio)
{
int i, j = 0, k = 0;
int floor1, floor2 = 0, ok = 0, fofmode = 0;
@ -135,13 +135,9 @@ void SE40_Draw(int tag, int spnum, int x, int y, int z, int a, int h, int smooth
offx = x - sprite[i].x;
offy = y - sprite[i].y;
i = floor2;
#if 0
drawrooms(offx + sprite[i].x, offy + sprite[i].y, z, a, h, sprite[i].sectnum);
#else
renderDrawRoomsQ16(sprite[i].x + offx, sprite[i].y + offy, z, a, h, sprite[i].sectnum);
#endif
fi.animatesprites(offx + sprite[i].x, offy + sprite[i].y, fix16_to_int(a), smoothratio);
renderDrawRoomsQ16(sprite[i].x + offx, sprite[i].y + offy, z, a.asq16(), h.asq16(), sprite[i].sectnum);
fi.animatesprites(offx + sprite[i].x, offy + sprite[i].y, a.asbuild(), smoothratio);
renderDrawMasks();
for (j = 0; j < MAXSPRITES; j++) // restore ceiling or floor
@ -173,7 +169,7 @@ void SE40_Draw(int tag, int spnum, int x, int y, int z, int a, int h, int smooth
//
//---------------------------------------------------------------------------
void se40code(int x, int y, int z, int a, int h, int smoothratio)
void se40code(int x, int y, int z, binangle a, fixedhoriz h, int smoothratio)
{
int i, tag;
if (!isRR()) tag = 40;
@ -208,7 +204,7 @@ void se40code(int x, int y, int z, int a, int h, int smoothratio)
//
//---------------------------------------------------------------------------
void renderMirror(int cposx, int cposy, int cposz, int cang, int choriz, int smoothratio)
void renderMirror(int cposx, int cposy, int cposz, binangle cang, fixedhoriz choriz, int smoothratio)
{
if ((gotpic[TILE_MIRROR >> 3] & (1 << (TILE_MIRROR & 7))) > 0)
{
@ -221,14 +217,15 @@ void renderMirror(int cposx, int cposy, int cposz, int cang, int choriz, int smo
if (wall[mirrorwall[i]].overpicnum == TILE_MIRROR)
{
int tposx, tposy, tang;
int tposx, tposy;
fix16_t tang;
renderPrepareMirror(cposx, cposy, cposz, cang << FRACBITS, choriz<<FRACBITS, mirrorwall[i], &tposx, &tposy, &tang);
renderPrepareMirror(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), mirrorwall[i], &tposx, &tposy, &tang);
int j = g_visibility;
g_visibility = (j >> 1) + (j >> 2);
renderDrawRoomsQ16(tposx, tposy, cposz, tang, choriz << FRACBITS, mirrorsector[i] + MAXSECTORS);
renderDrawRoomsQ16(tposx, tposy, cposz, tang, choriz.asq16(), mirrorsector[i] + MAXSECTORS);
display_mirror = 1;
fi.animatesprites(tposx, tposy, tang, smoothratio);
@ -380,12 +377,12 @@ void setdrugmode(player_struct *p, int oyrepeat)
//
//---------------------------------------------------------------------------
static void geometryEffect(int cposx, int cposy, int cposz, int cang, int choriz, int sect, int smoothratio)
static void geometryEffect(int cposx, int cposy, int cposz, binangle cang, fixedhoriz choriz, int sect, int smoothratio)
{
short gs, tgsect, nextspr, geosect, geoid = 0;
int spr;
drawrooms(cposx, cposy, cposz, cang, choriz, sect);
fi.animatesprites(cposx, cposy, cang, smoothratio);
renderDrawRoomsQ16(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), sect);
fi.animatesprites(cposx, cposy, cang.asbuild(), smoothratio);
renderDrawMasks();
for (gs = 0; gs < geocnt; gs++)
{
@ -406,7 +403,7 @@ static void geometryEffect(int cposx, int cposy, int cposz, int cang, int choriz
}
cposx -= geox[geoid];
cposy -= geoy[geoid];
drawrooms(cposx, cposy, cposz, cang, choriz, sect);
renderDrawRoomsQ16(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), sect);
cposx += geox[geoid];
cposy += geoy[geoid];
for (gs = 0; gs < geocnt; gs++)
@ -421,7 +418,7 @@ static void geometryEffect(int cposx, int cposy, int cposz, int cang, int choriz
spr = nextspr;
}
}
fi.animatesprites(cposx, cposy, cang, smoothratio);
fi.animatesprites(cposx, cposy, cang.asbuild(), smoothratio);
renderDrawMasks();
for (gs = 0; gs < geocnt; gs++)
{
@ -442,7 +439,7 @@ static void geometryEffect(int cposx, int cposy, int cposz, int cang, int choriz
}
cposx -= geox2[geoid];
cposy -= geoy2[geoid];
drawrooms(cposx, cposy, cposz, cang, choriz, sect);
renderDrawRoomsQ16(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), sect);
cposx += geox2[geoid];
cposy += geoy2[geoid];
for (gs = 0; gs < geocnt; gs++)
@ -457,7 +454,7 @@ static void geometryEffect(int cposx, int cposy, int cposz, int cang, int choriz
spr = nextspr;
}
}
fi.animatesprites(cposx, cposy, cang, smoothratio);
fi.animatesprites(cposx, cposy, cang.asbuild(), smoothratio);
renderDrawMasks();
}
//---------------------------------------------------------------------------
@ -469,7 +466,9 @@ static void geometryEffect(int cposx, int cposy, int cposz, int cang, int choriz
void displayrooms(int snum, int smoothratio)
{
int cposx, cposy, cposz, fz, cz;
short sect, cang, choriz;
short sect;
binangle cang;
fixedhoriz choriz;
struct player_struct* p;
int tiltcs = 0; // JBF 20030807
@ -514,12 +513,13 @@ void displayrooms(int snum, int smoothratio)
if (s->yvel < 0) s->yvel = -100;
else if (s->yvel > 199) s->yvel = 300;
cang = hittype[ud.camerasprite].tempang + mulscale16((int)(((s->ang + 1024 - hittype[ud.camerasprite].tempang) & 2047) - 1024), smoothratio);
cang = buildang(hittype[ud.camerasprite].tempang + mulscale16((int)(((s->ang + 1024 - hittype[ud.camerasprite].tempang) & 2047) - 1024), smoothratio));
se40code(s->x, s->y, s->z, cang, s->yvel, smoothratio);
renderMirror(s->x, s->y, s->z, cang, s->yvel, smoothratio);
drawrooms(s->x, s->y, s->z - (4 << 8), cang, s->yvel, s->sectnum);
fi.animatesprites(s->x, s->y, cang, smoothratio);
auto bh = buildhoriz(s->yvel);
se40code(s->x, s->y, s->z, cang, bh, smoothratio);
renderMirror(s->x, s->y, s->z, cang, bh, smoothratio);
renderDrawRoomsQ16(s->x, s->y, s->z - (4 << 8), cang.asq16(), bh.asq16(), s->sectnum);
fi.animatesprites(s->x, s->y, cang.asbuild(), smoothratio);
renderDrawMasks();
}
else
@ -553,13 +553,15 @@ void displayrooms(int snum, int smoothratio)
cposz = omyz + mulscale16((int)(myz - omyz), smoothratio);
if (synchronized_input)
{
cang = omyang + mulscale16((int)(((myang + 1024 - omyang) & 2047) - 1024), smoothratio);
choriz = omyhoriz + omyhorizoff + mulscale16((int)(myhoriz + myhorizoff - omyhoriz - omyhorizoff), smoothratio);
cang.interpolate(q16ang(oq16myang), q16ang(q16myang), smoothratio);
fix16_t osum = (oq16myhoriz + oq16myhorizoff);
fix16_t sum = (q16myhoriz + q16myhorizoff);
choriz = q16horiz(osum + mulscale16(sum - osum, smoothratio));
}
else
{
cang = myang;
choriz = (myhoriz + myhorizoff);
cang = q16ang(q16myang);
choriz = q16horiz(q16myhoriz + q16myhorizoff);
}
sect = mycursectnum;
}
@ -571,23 +573,24 @@ void displayrooms(int snum, int smoothratio)
if (synchronized_input /*|| smoothcamera*/)
{
// Original code for when the values are passed through the sync struct
cang = p->getoang() + mulscale16((int)(((p->getang() + 1024 - p->getoang()) & 2047) - 1024), smoothratio);
int ohorz = (p->oq16horiz + p->oq16horizoff) >> FRACBITS;
choriz = ohorz + mulscale16((int)(p->gethorizsum() - ohorz), smoothratio);
cang.interpolate(q16ang(p->oq16ang), q16ang(p->q16ang), smoothratio);
fix16_t osum = (p->oq16horiz + p->oq16horizoff);
fix16_t sum = (p->q16horiz + p->q16horizoff);
choriz = q16horiz(osum + mulscale16(sum - osum, smoothratio));
}
else
{
// This is for real time updating of the view direction.
cang = p->getang();
choriz = p->gethorizsum();
cang = q16ang(p->q16ang);
choriz = q16horiz(p->q16horiz + p->q16horizoff);
}
}
cang += p->getlookang();
cang += q16ang(p->q16look_ang);
if (p->newowner >= 0)
{
cang = p->getang() + p->getlookang();
choriz = p->gethorizsum();
cang = q16ang(p->q16ang + p->q16look_ang);
choriz = q16horiz(p->q16horiz + p->q16horizoff);
cposx = p->posx;
cposy = p->posy;
cposz = p->posz;
@ -598,7 +601,7 @@ void displayrooms(int snum, int smoothratio)
{
if (cl_viewbob) cposz += p->opyoff + mulscale16((int)(p->pyoff - p->opyoff), smoothratio);
}
else view(p, &cposx, &cposy, &cposz, &sect, cang, choriz);
else view(p, &cposx, &cposy, &cposz, &sect, cang.asbuild(), choriz.asbuild());
cz = hittype[p->i].ceilingz;
fz = hittype[p->i].floorz;
@ -606,13 +609,13 @@ void displayrooms(int snum, int smoothratio)
if (earthquaketime > 0 && p->on_ground == 1)
{
cposz += 256 - (((earthquaketime) & 1) << 9);
cang += (2 - ((earthquaketime) & 2)) << 2;
cang += buildang((2 - ((earthquaketime) & 2)) << 2);
}
if (sprite[p->i].pal == 1) cposz -= (18 << 8);
if (p->newowner >= 0)
choriz = 100 + sprite[p->newowner].shade;
choriz = buildhoriz(100 + sprite[p->newowner].shade);
else if (p->spritebridge == 0)
{
@ -627,7 +630,7 @@ void displayrooms(int snum, int smoothratio)
if (cposz > fz - (4 << 8)) cposz = fz - (4 << 8);
}
choriz = clamp(choriz, HORIZ_MIN, HORIZ_MAX);
choriz = clamp(choriz, buildhoriz(HORIZ_MIN), buildhoriz(HORIZ_MAX));
if (isRR() && sector[sect].lotag == 848)
{
@ -637,8 +640,8 @@ void displayrooms(int snum, int smoothratio)
{
se40code(cposx, cposy, cposz, cang, choriz, smoothratio);
renderMirror(cposx, cposy, cposz, cang, choriz, smoothratio);
drawrooms(cposx, cposy, cposz, cang, choriz, sect);
fi.animatesprites(cposx, cposy, cang, smoothratio);
renderDrawRoomsQ16(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), sect);
fi.animatesprites(cposx, cposy, cang.asbuild(), smoothratio);
renderDrawMasks();
}
}