2018-11-05 07:28:01 +00:00
|
|
|
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
|
|
|
|
// Ken Silverman's official web site: "http://www.advsys.net/ken"
|
|
|
|
// See the included license file "BUILDLIC.TXT" for license info.
|
|
|
|
//
|
|
|
|
// This file has been modified from Ken Silverman's original release
|
|
|
|
// by Jonathon Fowler (jf@jonof.id.au)
|
|
|
|
// by the EDuke32 team (development@voidpoint.com)
|
|
|
|
|
2016-06-21 00:33:30 +00:00
|
|
|
#pragma once
|
|
|
|
|
2008-12-02 10:44:39 +00:00
|
|
|
#ifndef ENGINE_PRIV_H
|
|
|
|
#define ENGINE_PRIV_H
|
|
|
|
|
2014-01-12 14:54:36 +00:00
|
|
|
#define MAXARTFILES_BASE 200
|
|
|
|
#define MAXARTFILES_TOTAL 220
|
2008-12-02 10:44:39 +00:00
|
|
|
#define MAXCLIPDIST 1024
|
|
|
|
|
2013-05-04 16:36:12 +00:00
|
|
|
// Uncomment to clear the screen before each top-level draw (classic only).
|
|
|
|
// FIXME: doesn't work with mirrors.
|
2011-05-17 21:48:13 +00:00
|
|
|
//#define ENGINE_CLEAR_SCREEN
|
2011-05-12 23:31:13 +00:00
|
|
|
|
2011-05-07 18:23:34 +00:00
|
|
|
#ifdef YAX_ENABLE
|
2011-05-12 23:31:13 +00:00
|
|
|
# define YAX_MAXDRAWS 8
|
2011-05-07 18:23:34 +00:00
|
|
|
#endif
|
|
|
|
|
2020-04-12 05:44:55 +00:00
|
|
|
extern intptr_t asm1, asm2;
|
2012-11-15 14:28:11 +00:00
|
|
|
extern int32_t globalx1, globaly2;
|
|
|
|
|
2014-11-28 08:14:00 +00:00
|
|
|
|
2019-10-12 20:49:46 +00:00
|
|
|
extern uint16_t sqrtable[4096], shlookup[4096+256],sqrtable_old[2048];
|
2016-06-21 00:33:30 +00:00
|
|
|
|
|
|
|
|
|
|
|
static inline int32_t nsqrtasm(uint32_t a)
|
|
|
|
{
|
|
|
|
// JBF 20030901: This was a damn lot simpler to reverse engineer than
|
|
|
|
// msqrtasm was. Really, it was just like simplifying an algebra equation.
|
|
|
|
uint16_t c;
|
|
|
|
|
|
|
|
if (a & 0xff000000) // test eax, 0xff000000 / jnz short over24
|
|
|
|
{
|
|
|
|
c = shlookup[(a >> 24) + 4096]; // mov ebx, eax
|
|
|
|
// over24: shr ebx, 24
|
|
|
|
// mov cx, word ptr shlookup[ebx*2+8192]
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
c = shlookup[a >> 12]; // mov ebx, eax
|
|
|
|
// shr ebx, 12
|
|
|
|
// mov cx, word ptr shlookup[ebx*2]
|
|
|
|
// jmp short under24
|
|
|
|
}
|
|
|
|
a >>= c&0xff; // under24: shr eax, cl
|
|
|
|
a = (a&0xffff0000)|(sqrtable[a]); // mov ax, word ptr sqrtable[eax*2]
|
|
|
|
a >>= ((c&0xff00) >> 8); // mov cl, ch
|
|
|
|
// shr eax, cl
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int32_t getclipmask(int32_t a, int32_t b, int32_t c, int32_t d)
|
|
|
|
{
|
|
|
|
// Ken did this
|
|
|
|
d = ((a<0)<<3) + ((b<0)<<2) + ((c<0)<<1) + (d<0);
|
2016-06-21 00:34:41 +00:00
|
|
|
return (((d<<4)^0xf0)|d);
|
2016-06-21 00:33:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-09-22 19:26:07 +00:00
|
|
|
inline int32_t ksqrtasm_old(int32_t n)
|
|
|
|
{
|
2020-06-13 00:07:27 +00:00
|
|
|
uint32_t shift = 0;
|
|
|
|
n = klabs((int32_t)n);
|
|
|
|
while (n >= 2048)
|
2019-09-22 19:26:07 +00:00
|
|
|
{
|
2020-06-13 00:07:27 +00:00
|
|
|
n >>= 2;
|
|
|
|
++shift;
|
2019-09-22 19:26:07 +00:00
|
|
|
}
|
2020-06-13 00:07:27 +00:00
|
|
|
uint32_t const s = sqrtable_old[n];
|
|
|
|
return (s << shift) >> 10;
|
2019-09-22 19:26:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
inline int32_t clip_nsqrtasm(int32_t n)
|
|
|
|
{
|
|
|
|
if (enginecompatibility_mode == ENGINECOMPATIBILITY_19950829)
|
|
|
|
return ksqrtasm_old(n);
|
|
|
|
return nsqrtasm(n);
|
|
|
|
}
|
|
|
|
|
2009-01-10 07:38:50 +00:00
|
|
|
extern int16_t thesector[MAXWALLSB], thewall[MAXWALLSB];
|
|
|
|
extern int16_t bunchfirst[MAXWALLSB], bunchlast[MAXWALLSB];
|
|
|
|
extern int16_t maskwall[MAXWALLSB], maskwallcnt;
|
2019-04-18 17:25:24 +00:00
|
|
|
extern tspriteptr_t tspriteptr[MAXSPRITESONSCREEN + 1];
|
2009-01-10 07:38:50 +00:00
|
|
|
extern int32_t xdimen, xdimenrecip, halfxdimen, xdimenscale, xdimscale, ydimen;
|
2014-11-28 08:14:00 +00:00
|
|
|
extern float fxdimen;
|
2009-01-10 07:38:50 +00:00
|
|
|
extern int32_t globalposx, globalposy, globalposz, globalhoriz;
|
2018-03-07 04:21:18 +00:00
|
|
|
extern fix16_t qglobalhoriz, qglobalang;
|
2014-10-25 03:32:26 +00:00
|
|
|
extern float fglobalposx, fglobalposy, fglobalposz;
|
2009-01-10 07:38:50 +00:00
|
|
|
extern int16_t globalang, globalcursectnum;
|
|
|
|
extern int32_t globalpal, cosglobalang, singlobalang;
|
|
|
|
extern int32_t cosviewingrangeglobalang, sinviewingrangeglobalang;
|
|
|
|
extern int32_t xyaspect;
|
|
|
|
extern int32_t globalshade;
|
|
|
|
extern int16_t globalpicnum;
|
2012-11-15 14:28:11 +00:00
|
|
|
|
2009-01-10 07:38:50 +00:00
|
|
|
extern int32_t globalorientation;
|
2008-12-02 10:44:39 +00:00
|
|
|
|
2011-10-02 22:38:09 +00:00
|
|
|
extern int16_t editstatus;
|
|
|
|
|
2009-01-10 07:38:50 +00:00
|
|
|
extern int16_t searchit;
|
|
|
|
extern int32_t searchx, searchy;
|
|
|
|
extern int16_t searchsector, searchwall, searchstat;
|
2011-03-17 23:37:38 +00:00
|
|
|
extern int16_t searchbottomwall, searchisbottom;
|
2008-12-02 10:44:39 +00:00
|
|
|
|
2019-06-25 18:35:05 +00:00
|
|
|
extern char inpreparemirror;
|
2008-12-02 10:44:39 +00:00
|
|
|
|
2014-04-21 17:00:54 +00:00
|
|
|
extern int16_t sectorborder[256];
|
2009-01-10 07:38:50 +00:00
|
|
|
extern int32_t qsetmode;
|
|
|
|
extern int32_t hitallsprites;
|
2008-12-02 10:44:39 +00:00
|
|
|
|
2009-01-10 07:38:50 +00:00
|
|
|
extern int32_t xb1[MAXWALLSB];
|
|
|
|
extern int32_t rx1[MAXWALLSB], ry1[MAXWALLSB];
|
2014-09-30 04:14:21 +00:00
|
|
|
extern int16_t bunchp2[MAXWALLSB];
|
2012-01-26 21:58:08 +00:00
|
|
|
extern int16_t numscans, numbunches;
|
2016-06-21 00:33:30 +00:00
|
|
|
extern int32_t rxi[8], ryi[8];
|
2008-12-02 10:44:39 +00:00
|
|
|
|
2016-06-21 00:33:30 +00:00
|
|
|
|
2010-06-07 09:03:16 +00:00
|
|
|
// int32_t wallmost(int16_t *mostbuf, int32_t w, int32_t sectnum, char dastat);
|
2009-01-10 07:38:50 +00:00
|
|
|
int32_t wallfront(int32_t l1, int32_t l2);
|
2013-02-10 16:24:11 +00:00
|
|
|
|
2019-04-18 17:24:10 +00:00
|
|
|
void set_globalang(fix16_t const ang);
|
2008-12-02 10:44:39 +00:00
|
|
|
|
2019-09-19 20:02:45 +00:00
|
|
|
int32_t animateoffs(int tilenum, int fakevar);
|
|
|
|
|
2019-04-18 17:25:24 +00:00
|
|
|
static FORCE_INLINE int32_t bad_tspr(tspriteptr_t tspr)
|
2013-04-29 19:24:19 +00:00
|
|
|
{
|
2013-05-01 17:42:07 +00:00
|
|
|
// NOTE: tspr->owner >= MAXSPRITES (could be model) has to be handled by
|
|
|
|
// caller.
|
|
|
|
return (tspr->owner < 0 || (unsigned)tspr->picnum >= MAXTILES);
|
2013-04-29 19:24:19 +00:00
|
|
|
}
|
|
|
|
|
2013-05-15 02:19:14 +00:00
|
|
|
//
|
|
|
|
// getpalookup (internal)
|
|
|
|
//
|
2017-02-25 08:15:53 +00:00
|
|
|
static FORCE_INLINE int32_t getpalookup(int32_t davis, int32_t dashade)
|
2013-05-15 02:19:14 +00:00
|
|
|
{
|
2019-09-19 20:02:45 +00:00
|
|
|
if (getpalookup_replace)
|
|
|
|
return getpalookup_replace(davis, dashade);
|
2016-06-21 00:34:41 +00:00
|
|
|
return min(max(dashade + (davis >> 8), 0), numshades - 1);
|
2013-05-15 02:19:14 +00:00
|
|
|
}
|
|
|
|
|
2017-02-25 08:15:53 +00:00
|
|
|
static FORCE_INLINE int32_t getpalookupsh(int32_t davis) { return getpalookup(davis, globalshade) << 8; }
|
2013-05-15 02:19:14 +00:00
|
|
|
|
2011-05-22 21:52:22 +00:00
|
|
|
////// yax'y stuff //////
|
|
|
|
#ifdef USE_OPENGL
|
|
|
|
extern void polymost_scansector(int32_t sectnum);
|
|
|
|
#endif
|
2018-04-12 21:04:00 +00:00
|
|
|
int32_t renderAddTsprite(int16_t z, int16_t sectnum);
|
2011-09-04 19:44:07 +00:00
|
|
|
#ifdef YAX_ENABLE
|
2019-03-19 17:07:53 +00:00
|
|
|
extern int32_t g_nodraw, scansector_retfast, scansector_collectsprites;
|
2011-09-15 17:02:12 +00:00
|
|
|
extern int32_t yax_globallev, yax_globalbunch;
|
Support for drawing 'island sectors' for TROR/classic (and with limited
functionality, Polymost).
The new feature can be enabled/disabled with the 'r_tror_nomaskpass' cvar.
The basic idea is that when drawing lower or upper levels, a first pass
is performed that ignores all red walls for which the TROR nextwall link
'towards' the viewer arrives at a red wall. Thus, in the worst case, there
can be up to twice as many rendering passes now (when it is discovered that
the no-mask-pass isn't different that what would be drawn with the ordinary
one, the latter is skipped, since we've already drawn all needed geometry).
Hovever, this kind of multi-pass splitting is only suitable for simple scenes,
like the upper subway in the TROR test map. In particular, multiple islands
shouldn't 'see' each other.
Two issues are worth mentioning: first, care needs to be taken for translucent
ceilings or floors, since drawing them twice isn't the same as drawing them
once. This is done for classic, but not for Polymost. Second, sprites (which
are always drawn _after_ the geometry for a given pass) are still clipped to
the geometry of the ordinary pass, resulting in their disappearance from
certain angles.
--
Additionaly, a change made it into this commit that fixes redundant collection
of sprites in TROR:classic/Polymost.
git-svn-id: https://svn.eduke32.com/eduke32@2024 1a8010ca-5511-0410-912e-c29ae57300e0
2011-09-15 17:04:14 +00:00
|
|
|
extern int32_t yax_globalcf, yax_nomaskpass, yax_nomaskdidit;
|
2019-07-19 01:49:19 +00:00
|
|
|
extern uint8_t haveymost[(YAX_MAXBUNCHES+7)>>3];
|
2019-04-18 17:24:43 +00:00
|
|
|
extern uint8_t yax_gotsector[(MAXSECTORS+7)>>3];
|
2019-03-19 17:07:53 +00:00
|
|
|
extern int32_t yax_polymostclearzbuffer;
|
Support for drawing 'island sectors' for TROR/classic (and with limited
functionality, Polymost).
The new feature can be enabled/disabled with the 'r_tror_nomaskpass' cvar.
The basic idea is that when drawing lower or upper levels, a first pass
is performed that ignores all red walls for which the TROR nextwall link
'towards' the viewer arrives at a red wall. Thus, in the worst case, there
can be up to twice as many rendering passes now (when it is discovered that
the no-mask-pass isn't different that what would be drawn with the ordinary
one, the latter is skipped, since we've already drawn all needed geometry).
Hovever, this kind of multi-pass splitting is only suitable for simple scenes,
like the upper subway in the TROR test map. In particular, multiple islands
shouldn't 'see' each other.
Two issues are worth mentioning: first, care needs to be taken for translucent
ceilings or floors, since drawing them twice isn't the same as drawing them
once. This is done for classic, but not for Polymost. Second, sprites (which
are always drawn _after_ the geometry for a given pass) are still clipped to
the geometry of the ordinary pass, resulting in their disappearance from
certain angles.
--
Additionaly, a change made it into this commit that fixes redundant collection
of sprites in TROR:classic/Polymost.
git-svn-id: https://svn.eduke32.com/eduke32@2024 1a8010ca-5511-0410-912e-c29ae57300e0
2011-09-15 17:04:14 +00:00
|
|
|
|
2017-02-25 08:15:53 +00:00
|
|
|
static FORCE_INLINE int32_t yax_isislandwall(int32_t line, int32_t cf) { return (yax_vnextsec(line, cf) >= 0); }
|
2011-09-04 19:44:07 +00:00
|
|
|
#endif
|
2011-05-22 21:52:22 +00:00
|
|
|
|
|
|
|
#ifdef YAX_DEBUG
|
|
|
|
extern char m32_debugstr[64][128];
|
|
|
|
extern int32_t m32_numdebuglines;
|
2020-01-25 09:56:30 +00:00
|
|
|
# define yaxdebug(fmt, ...) do { if (m32_numdebuglines<64) snprintf(m32_debugstr[m32_numdebuglines++], 128, fmt, ##__VA_ARGS__); } while (0)
|
2020-04-11 21:45:45 +00:00
|
|
|
# define yaxprintf(fmt, ...) do { Printf(fmt, ##__VA_ARGS__); } while (0)
|
2011-05-22 21:52:22 +00:00
|
|
|
#else
|
|
|
|
# define yaxdebug(fmt, ...)
|
|
|
|
# define yaxprintf(fmt, ...)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2008-12-02 10:44:39 +00:00
|
|
|
|
2017-02-25 08:15:53 +00:00
|
|
|
static FORCE_INLINE void setgotpic(int32_t tilenume)
|
2008-12-02 10:44:39 +00:00
|
|
|
{
|
2018-04-06 01:42:27 +00:00
|
|
|
gotpic[tilenume>>3] |= pow2char[tilenume&7];
|
2008-12-02 10:44:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-08-04 20:37:45 +00:00
|
|
|
// Get properties of parallaxed sky to draw.
|
2016-10-14 07:40:50 +00:00
|
|
|
// Returns: pointer to tile offset array. Sets-by-pointer the other three.
|
2017-11-29 07:29:48 +00:00
|
|
|
static FORCE_INLINE const int8_t *getpsky(int32_t picnum, int32_t *dapyscale, int32_t *dapskybits, int32_t *dapyoffs, int32_t *daptileyscale)
|
2013-08-04 20:37:45 +00:00
|
|
|
{
|
2015-05-27 08:47:34 +00:00
|
|
|
psky_t const * const psky = &multipsky[getpskyidx(picnum)];
|
2013-08-04 20:37:45 +00:00
|
|
|
|
2013-08-04 20:37:49 +00:00
|
|
|
if (dapskybits)
|
2015-05-27 08:47:34 +00:00
|
|
|
*dapskybits = (pskybits_override == -1 ? psky->lognumtiles : pskybits_override);
|
2013-08-04 20:37:45 +00:00
|
|
|
if (dapyscale)
|
2015-05-27 08:47:34 +00:00
|
|
|
*dapyscale = (parallaxyscale_override == 0 ? psky->horizfrac : parallaxyscale_override);
|
2016-10-14 07:40:50 +00:00
|
|
|
if (dapyoffs)
|
|
|
|
*dapyoffs = psky->yoffs + parallaxyoffs_override;
|
2017-11-29 07:29:48 +00:00
|
|
|
if (daptileyscale)
|
|
|
|
*daptileyscale = psky->yscale;
|
Clean up parallaxed sky functionality, part 2.
- Rename sky_t members: yscale -> horizfrac, bits -> lognumtiles.
- Add default sky (8 tiles, horizfrac=32768 (i.e. 1/2 the scene horiz), offsets
all zero) and CLOUDYOCEAN sky (8 tiles, horizfrac=65536, offsets all zero)
to multipsky[].
- Get rid of "psky_t g_psky", merely maintaining a g_pskyidx instead. Set it up
at map load time so as to keep the behavior of the legacy per-map psky:
the last sector index with a matching psky ceiling wins.
- In mapstate_t, save g_pskyidx too, not (former) pskybits and pskyoffs[].
- Make on-map-load global psky setup consistent for the game and editor by
factoring it out into common.c: G_SetupGlobalPsky().
- Remove a couple of useless initializations, add some static assertions.
This commit is more likely to introduce subtle differences in behavior.
Specifically, getpsky() now always returns the default sky properties instead of
the global sky ones (but with all-zero offsets) when no match for a suiting
multi-psky is found. This is only likely to affect the yscale/horizfrac of
non-multi-pskies when a global non-default multi-psky has been set up.
Bump BYTEVERSION again.
git-svn-id: https://svn.eduke32.com/eduke32@3976 1a8010ca-5511-0410-912e-c29ae57300e0
2013-08-04 20:37:48 +00:00
|
|
|
|
2015-05-27 08:47:34 +00:00
|
|
|
return psky->tileofs;
|
2013-08-04 20:37:45 +00:00
|
|
|
}
|
2014-10-25 03:32:26 +00:00
|
|
|
|
2017-02-25 08:15:53 +00:00
|
|
|
static FORCE_INLINE void set_globalpos(int32_t const x, int32_t const y, int32_t const z)
|
2014-10-25 03:32:26 +00:00
|
|
|
{
|
2019-06-25 11:30:22 +00:00
|
|
|
globalposx = x, fglobalposx = (float)x;
|
|
|
|
globalposy = y, fglobalposy = (float)y;
|
|
|
|
globalposz = z, fglobalposz = (float)z;
|
2014-10-25 03:32:26 +00:00
|
|
|
}
|
|
|
|
|
2019-06-25 11:30:22 +00:00
|
|
|
template <typename T> static FORCE_INLINE void tileUpdatePicnum(T * const tileptr, int const obj)
|
|
|
|
{
|
|
|
|
auto &tile = *tileptr;
|
|
|
|
|
2019-09-21 11:02:17 +00:00
|
|
|
if (picanm[tile].sf & PICANM_ANIMTYPE_MASK)
|
|
|
|
tile += animateoffs(tile, obj);
|
2019-06-25 11:30:22 +00:00
|
|
|
|
2019-10-16 18:39:59 +00:00
|
|
|
if (((obj & 16384) == 16384) && (globalorientation & CSTAT_WALL_ROTATE_90) && RotTile(tile).newtile != -1)
|
|
|
|
tile = RotTile(tile).newtile;
|
2019-06-25 11:30:22 +00:00
|
|
|
}
|
|
|
|
|
2019-12-26 06:27:48 +00:00
|
|
|
// x1, y1: in/out
|
|
|
|
// rest x/y: out
|
|
|
|
template <typename T>
|
|
|
|
static inline void get_wallspr_points(T const * const spr, int32_t *x1, int32_t *x2,
|
|
|
|
int32_t *y1, int32_t *y2)
|
|
|
|
{
|
|
|
|
//These lines get the 2 points of the rotated sprite
|
|
|
|
//Given: (x1, y1) starts out as the center point
|
|
|
|
|
|
|
|
const int32_t tilenum=spr->picnum, ang=spr->ang;
|
|
|
|
const int32_t xrepeat = spr->xrepeat;
|
2020-05-24 10:31:38 +00:00
|
|
|
int32_t xoff = tileLeftOffset(tilenum) + spr->xoffset;
|
2019-12-26 06:27:48 +00:00
|
|
|
int32_t k, l, dax, day;
|
|
|
|
|
|
|
|
if (spr->cstat&4)
|
|
|
|
xoff = -xoff;
|
|
|
|
|
|
|
|
dax = sintable[ang&2047]*xrepeat;
|
|
|
|
day = sintable[(ang+1536)&2047]*xrepeat;
|
|
|
|
|
|
|
|
l = tilesiz[tilenum].x;
|
|
|
|
k = (l>>1)+xoff;
|
|
|
|
|
|
|
|
*x1 -= mulscale16(dax,k);
|
|
|
|
*x2 = *x1 + mulscale16(dax,l);
|
|
|
|
|
|
|
|
*y1 -= mulscale16(day,k);
|
|
|
|
*y2 = *y1 + mulscale16(day,l);
|
|
|
|
}
|
|
|
|
|
|
|
|
// x1, y1: in/out
|
|
|
|
// rest x/y: out
|
|
|
|
template <typename T>
|
|
|
|
static inline void get_floorspr_points(T const * const spr, int32_t px, int32_t py,
|
|
|
|
int32_t *x1, int32_t *x2, int32_t *x3, int32_t *x4,
|
|
|
|
int32_t *y1, int32_t *y2, int32_t *y3, int32_t *y4)
|
|
|
|
{
|
|
|
|
const int32_t tilenum = spr->picnum;
|
|
|
|
const int32_t cosang = sintable[(spr->ang+512)&2047];
|
|
|
|
const int32_t sinang = sintable[spr->ang&2047];
|
|
|
|
|
|
|
|
vec2_t const span = { tilesiz[tilenum].x, tilesiz[tilenum].y};
|
|
|
|
vec2_t const repeat = { spr->xrepeat, spr->yrepeat };
|
|
|
|
|
2020-05-24 10:31:38 +00:00
|
|
|
vec2_t adjofs = { tileLeftOffset(tilenum) + spr->xoffset, tileTopOffset(tilenum) + spr->yoffset };
|
2019-12-26 06:27:48 +00:00
|
|
|
|
|
|
|
if (spr->cstat & 4)
|
|
|
|
adjofs.x = -adjofs.x;
|
|
|
|
|
|
|
|
if (spr->cstat & 8)
|
|
|
|
adjofs.y = -adjofs.y;
|
|
|
|
|
|
|
|
vec2_t const center = { ((span.x >> 1) + adjofs.x) * repeat.x, ((span.y >> 1) + adjofs.y) * repeat.y };
|
|
|
|
vec2_t const rspan = { span.x * repeat.x, span.y * repeat.y };
|
|
|
|
vec2_t const ofs = { -mulscale16(cosang, rspan.y), -mulscale16(sinang, rspan.y) };
|
|
|
|
|
|
|
|
*x1 += dmulscale16(sinang, center.x, cosang, center.y) - px;
|
|
|
|
*y1 += dmulscale16(sinang, center.y, -cosang, center.x) - py;
|
|
|
|
|
|
|
|
*x2 = *x1 - mulscale16(sinang, rspan.x);
|
|
|
|
*y2 = *y1 + mulscale16(cosang, rspan.x);
|
|
|
|
|
|
|
|
*x3 = *x2 + ofs.x, *x4 = *x1 + ofs.x;
|
|
|
|
*y3 = *y2 + ofs.y, *y4 = *y1 + ofs.y;
|
|
|
|
}
|
|
|
|
|
2008-12-02 10:44:39 +00:00
|
|
|
#endif /* ENGINE_PRIV_H */
|