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); 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); 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; t->cstat |= 2;
if ( screenpeek == myconnectindex && numplayers >= 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->y = omyy + mulscale16((int)(myy - omyy), smoothratio);
t->z = omyz + mulscale16((int)(myz - omyz), smoothratio) + (40 << 8); 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->ang = omyang + mulscale16((int)(((myang + 1024 - omyang) & 2047) - 1024), smoothratio);
t->sectnum = mycursectnum; 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->x = omyx + mulscale16((int)(myx - omyx), smoothratio);
t->y = omyy + mulscale16((int)(myy - omyy), smoothratio); t->y = omyy + mulscale16((int)(myy - omyy), smoothratio);
t->z = omyz + mulscale16((int)(myz - omyz), smoothratio) + (40 << 8); 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->ang = omyang + mulscale16((int)(((myang + 1024 - omyang) & 2047) - 1024), smoothratio);
t->sectnum = mycursectnum; t->sectnum = mycursectnum;
} }

View file

@ -306,6 +306,8 @@ void displayrest(int smoothratio)
{ {
cposx = omyx + mulscale16(myx - omyx, smoothratio); cposx = omyx + mulscale16(myx - omyx, smoothratio);
cposy = omyy + mulscale16(myy - omyy, 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); cang = fix16_to_int(omyang) + mulscale16((fix16_to_int(myang + F16(1024) - omyang) & 2047) - 1024, smoothratio);
} }
else else

View file

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

View file

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

View file

@ -58,7 +58,7 @@ static int tempsectorz[MAXSECTORS];
static int tempsectorpicnum[MAXSECTORS]; static int tempsectorpicnum[MAXSECTORS];
//short tempcursectnum; //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 i, j = 0, k = 0;
int floor1, floor2 = 0, ok = 0, fofmode = 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; offx = x - sprite[i].x;
offy = y - sprite[i].y; offy = y - sprite[i].y;
i = floor2; 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(); renderDrawMasks();
for (j = 0; j < MAXSPRITES; j++) // restore ceiling or floor 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; int i, tag;
if (!isRR()) tag = 40; 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) 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) 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; int j = g_visibility;
g_visibility = (j >> 1) + (j >> 2); 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; display_mirror = 1;
fi.animatesprites(tposx, tposy, tang, smoothratio); 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; short gs, tgsect, nextspr, geosect, geoid = 0;
int spr; int spr;
drawrooms(cposx, cposy, cposz, cang, choriz, sect); renderDrawRoomsQ16(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), sect);
fi.animatesprites(cposx, cposy, cang, smoothratio); fi.animatesprites(cposx, cposy, cang.asbuild(), smoothratio);
renderDrawMasks(); renderDrawMasks();
for (gs = 0; gs < geocnt; gs++) 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]; cposx -= geox[geoid];
cposy -= geoy[geoid]; cposy -= geoy[geoid];
drawrooms(cposx, cposy, cposz, cang, choriz, sect); renderDrawRoomsQ16(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), sect);
cposx += geox[geoid]; cposx += geox[geoid];
cposy += geoy[geoid]; cposy += geoy[geoid];
for (gs = 0; gs < geocnt; gs++) 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; spr = nextspr;
} }
} }
fi.animatesprites(cposx, cposy, cang, smoothratio); fi.animatesprites(cposx, cposy, cang.asbuild(), smoothratio);
renderDrawMasks(); renderDrawMasks();
for (gs = 0; gs < geocnt; gs++) 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]; cposx -= geox2[geoid];
cposy -= geoy2[geoid]; cposy -= geoy2[geoid];
drawrooms(cposx, cposy, cposz, cang, choriz, sect); renderDrawRoomsQ16(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), sect);
cposx += geox2[geoid]; cposx += geox2[geoid];
cposy += geoy2[geoid]; cposy += geoy2[geoid];
for (gs = 0; gs < geocnt; gs++) 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; spr = nextspr;
} }
} }
fi.animatesprites(cposx, cposy, cang, smoothratio); fi.animatesprites(cposx, cposy, cang.asbuild(), smoothratio);
renderDrawMasks(); renderDrawMasks();
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -469,7 +466,9 @@ static void geometryEffect(int cposx, int cposy, int cposz, int cang, int choriz
void displayrooms(int snum, int smoothratio) void displayrooms(int snum, int smoothratio)
{ {
int cposx, cposy, cposz, fz, cz; int cposx, cposy, cposz, fz, cz;
short sect, cang, choriz; short sect;
binangle cang;
fixedhoriz choriz;
struct player_struct* p; struct player_struct* p;
int tiltcs = 0; // JBF 20030807 int tiltcs = 0; // JBF 20030807
@ -514,12 +513,13 @@ void displayrooms(int snum, int smoothratio)
if (s->yvel < 0) s->yvel = -100; if (s->yvel < 0) s->yvel = -100;
else if (s->yvel > 199) s->yvel = 300; 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); auto bh = buildhoriz(s->yvel);
renderMirror(s->x, s->y, s->z, cang, s->yvel, smoothratio); se40code(s->x, s->y, s->z, cang, bh, smoothratio);
drawrooms(s->x, s->y, s->z - (4 << 8), cang, s->yvel, s->sectnum); renderMirror(s->x, s->y, s->z, cang, bh, smoothratio);
fi.animatesprites(s->x, s->y, cang, 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(); renderDrawMasks();
} }
else else
@ -553,13 +553,15 @@ void displayrooms(int snum, int smoothratio)
cposz = omyz + mulscale16((int)(myz - omyz), smoothratio); cposz = omyz + mulscale16((int)(myz - omyz), smoothratio);
if (synchronized_input) if (synchronized_input)
{ {
cang = omyang + mulscale16((int)(((myang + 1024 - omyang) & 2047) - 1024), smoothratio); cang.interpolate(q16ang(oq16myang), q16ang(q16myang), smoothratio);
choriz = omyhoriz + omyhorizoff + mulscale16((int)(myhoriz + myhorizoff - omyhoriz - omyhorizoff), smoothratio); fix16_t osum = (oq16myhoriz + oq16myhorizoff);
fix16_t sum = (q16myhoriz + q16myhorizoff);
choriz = q16horiz(osum + mulscale16(sum - osum, smoothratio));
} }
else else
{ {
cang = myang; cang = q16ang(q16myang);
choriz = (myhoriz + myhorizoff); choriz = q16horiz(q16myhoriz + q16myhorizoff);
} }
sect = mycursectnum; sect = mycursectnum;
} }
@ -571,23 +573,24 @@ void displayrooms(int snum, int smoothratio)
if (synchronized_input /*|| smoothcamera*/) if (synchronized_input /*|| smoothcamera*/)
{ {
// Original code for when the values are passed through the sync struct // 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); cang.interpolate(q16ang(p->oq16ang), q16ang(p->q16ang), smoothratio);
int ohorz = (p->oq16horiz + p->oq16horizoff) >> FRACBITS; fix16_t osum = (p->oq16horiz + p->oq16horizoff);
choriz = ohorz + mulscale16((int)(p->gethorizsum() - ohorz), smoothratio); fix16_t sum = (p->q16horiz + p->q16horizoff);
choriz = q16horiz(osum + mulscale16(sum - osum, smoothratio));
} }
else else
{ {
// This is for real time updating of the view direction. // This is for real time updating of the view direction.
cang = p->getang(); cang = q16ang(p->q16ang);
choriz = p->gethorizsum(); choriz = q16horiz(p->q16horiz + p->q16horizoff);
} }
} }
cang += p->getlookang(); cang += q16ang(p->q16look_ang);
if (p->newowner >= 0) if (p->newowner >= 0)
{ {
cang = p->getang() + p->getlookang(); cang = q16ang(p->q16ang + p->q16look_ang);
choriz = p->gethorizsum(); choriz = q16horiz(p->q16horiz + p->q16horizoff);
cposx = p->posx; cposx = p->posx;
cposy = p->posy; cposy = p->posy;
cposz = p->posz; 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); 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; cz = hittype[p->i].ceilingz;
fz = hittype[p->i].floorz; fz = hittype[p->i].floorz;
@ -606,13 +609,13 @@ void displayrooms(int snum, int smoothratio)
if (earthquaketime > 0 && p->on_ground == 1) if (earthquaketime > 0 && p->on_ground == 1)
{ {
cposz += 256 - (((earthquaketime) & 1) << 9); 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 (sprite[p->i].pal == 1) cposz -= (18 << 8);
if (p->newowner >= 0) if (p->newowner >= 0)
choriz = 100 + sprite[p->newowner].shade; choriz = buildhoriz(100 + sprite[p->newowner].shade);
else if (p->spritebridge == 0) else if (p->spritebridge == 0)
{ {
@ -627,7 +630,7 @@ void displayrooms(int snum, int smoothratio)
if (cposz > fz - (4 << 8)) cposz = fz - (4 << 8); 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) if (isRR() && sector[sect].lotag == 848)
{ {
@ -637,8 +640,8 @@ void displayrooms(int snum, int smoothratio)
{ {
se40code(cposx, cposy, cposz, cang, choriz, smoothratio); se40code(cposx, cposy, cposz, cang, choriz, smoothratio);
renderMirror(cposx, cposy, cposz, cang, choriz, smoothratio); renderMirror(cposx, cposy, cposz, cang, choriz, smoothratio);
drawrooms(cposx, cposy, cposz, cang, choriz, sect); renderDrawRoomsQ16(cposx, cposy, cposz, cang.asq16(), choriz.asq16(), sect);
fi.animatesprites(cposx, cposy, cang, smoothratio); fi.animatesprites(cposx, cposy, cang.asbuild(), smoothratio);
renderDrawMasks(); renderDrawMasks();
} }
} }