mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-24 10:40:46 +00:00
- render camera textures with the hardware renderer.
This removes the last active use case for the software renderer and allows rendering the camera views at a higher resolution. For Shadow Warrior this necessitated a split of JS_DrawMirrors, because it processed cameras and mirrors in the same loop which cannot be done with the hardware renderer.
This commit is contained in:
parent
8f3cc0b5af
commit
621a9338e5
17 changed files with 320 additions and 324 deletions
|
@ -838,8 +838,6 @@ int32_t qloadkvx(int32_t voxindex, const char *filename);
|
|||
void vox_undefine(int32_t const);
|
||||
void vox_deinit();
|
||||
|
||||
void squarerotatetile(int16_t tilenume);
|
||||
|
||||
int32_t videoSetGameMode(char davidoption, int32_t daupscaledxdim, int32_t daupscaledydim, int32_t dabpp, int32_t daupscalefactor);
|
||||
void videoNextPage(void);
|
||||
void videoSetCorrectedAspect();
|
||||
|
@ -849,7 +847,7 @@ inline void renderFlushPerms(void) {}
|
|||
|
||||
void plotpixel(int32_t x, int32_t y, char col);
|
||||
void renderSetTarget(int16_t tilenume, int32_t xsiz, int32_t ysiz);
|
||||
void renderRestoreTarget(void);
|
||||
void renderRestoreTarget();
|
||||
void renderPrepareMirror(int32_t dax, int32_t day, int32_t daz, fix16_t daang, fix16_t dahoriz, int16_t dawall,
|
||||
int32_t *tposx, int32_t *tposy, fix16_t *tang);
|
||||
void renderCompleteMirror(void);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#define engine_c_
|
||||
|
||||
#include "gl_load.h"
|
||||
#include "a.h"
|
||||
#include "baselayer.h"
|
||||
#include "build.h"
|
||||
|
@ -36,6 +37,7 @@
|
|||
# include "polymost.h"
|
||||
#include "v_video.h"
|
||||
#include "../../glbackend/glbackend.h"
|
||||
#include "gl_renderer.h"
|
||||
#endif
|
||||
|
||||
//////////
|
||||
|
@ -1323,14 +1325,6 @@ static int32_t mirrorsx1, mirrorsy1, mirrorsx2, mirrorsy2;
|
|||
|
||||
#define MAXSETVIEW 4
|
||||
|
||||
static int32_t setviewcnt = 0; // interface layers use this now
|
||||
static intptr_t bakframeplace[MAXSETVIEW];
|
||||
static int32_t bakxsiz[MAXSETVIEW], bakysiz[MAXSETVIEW];
|
||||
static vec2_t bakwindowxy1[MAXSETVIEW], bakwindowxy2[MAXSETVIEW];
|
||||
#ifdef USE_OPENGL
|
||||
static int32_t bakrendmode;
|
||||
#endif
|
||||
static int32_t baktile;
|
||||
|
||||
#ifdef GAMENAME
|
||||
char apptitle[256] = GAMENAME;
|
||||
|
@ -10087,44 +10081,35 @@ void videoClearScreen(int32_t dacol)
|
|||
|
||||
//MUST USE RESTOREFORDRAWROOMS AFTER DRAWING
|
||||
|
||||
static int32_t setviewcnt = 0; // interface layers use this now
|
||||
static int32_t bakxsiz, bakysiz;
|
||||
static vec2_t bakwindowxy1, bakwindowxy2;
|
||||
|
||||
//
|
||||
// setviewtotile
|
||||
//
|
||||
void renderSetTarget(int16_t tilenume, int32_t xsiz, int32_t ysiz)
|
||||
{
|
||||
if (setviewcnt >= MAXSETVIEW-1)
|
||||
if (setviewcnt > 0)
|
||||
return;
|
||||
if (xsiz <= 0 ||
|
||||
ysiz <= 0)
|
||||
return;
|
||||
|
||||
OpenGLRenderer::GLRenderer->StartOffscreen();
|
||||
OpenGLRenderer::GLRenderer->BindToFrameBuffer(TileFiles.tiles[tilenume]);
|
||||
|
||||
//DRAWROOMS TO TILE BACKUP&SET CODE
|
||||
TileFiles.tileCreate(tilenume, xsiz, ysiz);
|
||||
bakxsiz[setviewcnt] = xdim; bakysiz[setviewcnt] = ydim;
|
||||
bakframeplace[setviewcnt] = frameplace; frameplace = (intptr_t)tilePtr(tilenume);
|
||||
bakwindowxy1[setviewcnt] = windowxy1;
|
||||
bakwindowxy2[setviewcnt] = windowxy2;
|
||||
bakxsiz = xdim; bakysiz = ydim;
|
||||
bakwindowxy1 = windowxy1;
|
||||
bakwindowxy2 = windowxy2;
|
||||
|
||||
if (setviewcnt == 0)
|
||||
{
|
||||
#ifdef USE_OPENGL
|
||||
bakrendmode = rendmode;
|
||||
#endif
|
||||
baktile = tilenume;
|
||||
}
|
||||
|
||||
#ifdef USE_OPENGL
|
||||
rendmode = REND_CLASSIC;
|
||||
#endif
|
||||
|
||||
copybufbyte(&startumost[windowxy1.x],&bakumost[windowxy1.x],(windowxy2.x-windowxy1.x+1)*sizeof(bakumost[0]));
|
||||
copybufbyte(&startdmost[windowxy1.x],&bakdmost[windowxy1.x],(windowxy2.x-windowxy1.x+1)*sizeof(bakdmost[0]));
|
||||
setviewcnt++;
|
||||
|
||||
offscreenrendering = 1;
|
||||
xdim = ysiz;
|
||||
ydim = xsiz;
|
||||
videoSetViewableArea(0,0,ysiz-1,xsiz-1);
|
||||
xdim = ysiz*4;
|
||||
ydim = xsiz*4;
|
||||
videoSetViewableArea(0,0,ysiz*4-1,xsiz*4-1);
|
||||
renderSetAspect(65536,65536);
|
||||
|
||||
calc_ylookup(ysiz, xsiz);
|
||||
|
@ -10134,73 +10119,26 @@ void renderSetTarget(int16_t tilenume, int32_t xsiz, int32_t ysiz)
|
|||
//
|
||||
// setviewback
|
||||
//
|
||||
void renderRestoreTarget(void)
|
||||
void renderRestoreTarget()
|
||||
{
|
||||
if (setviewcnt <= 0) return;
|
||||
setviewcnt--;
|
||||
|
||||
offscreenrendering = (setviewcnt>0);
|
||||
#ifdef USE_OPENGL
|
||||
if (setviewcnt == 0)
|
||||
{
|
||||
rendmode = bakrendmode;
|
||||
tileInvalidate(baktile,-1,-1);
|
||||
}
|
||||
#endif
|
||||
OpenGLRenderer::GLRenderer->EndOffscreen();
|
||||
|
||||
xdim = bakxsiz[setviewcnt];
|
||||
ydim = bakysiz[setviewcnt];
|
||||
videoSetViewableArea(bakwindowxy1[setviewcnt].x,bakwindowxy1[setviewcnt].y,
|
||||
bakwindowxy2[setviewcnt].x,bakwindowxy2[setviewcnt].y);
|
||||
copybufbyte(&bakumost[windowxy1.x],&startumost[windowxy1.x],(windowxy2.x-windowxy1.x+1)*sizeof(startumost[0]));
|
||||
copybufbyte(&bakdmost[windowxy1.x],&startdmost[windowxy1.x],(windowxy2.x-windowxy1.x+1)*sizeof(startdmost[0]));
|
||||
frameplace = bakframeplace[setviewcnt];
|
||||
xdim = bakxsiz;
|
||||
ydim = bakysiz;
|
||||
videoSetViewableArea(bakwindowxy1.x,bakwindowxy1.y,
|
||||
bakwindowxy2.x,bakwindowxy2.y);
|
||||
|
||||
calc_ylookup((setviewcnt == 0) ? bytesperline : bakxsiz[setviewcnt],
|
||||
bakysiz[setviewcnt]);
|
||||
calc_ylookup((setviewcnt == 0) ? bytesperline : bakxsiz,
|
||||
bakysiz);
|
||||
|
||||
modechange=1;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// squarerotatetile
|
||||
//
|
||||
void squarerotatetile(int16_t tilenume)
|
||||
{
|
||||
int const siz = tilesiz[tilenume].x;
|
||||
|
||||
if (siz != tilesiz[tilenume].y)
|
||||
return;
|
||||
|
||||
uint8_t *ptr1, *ptr2;
|
||||
auto p = tileData(tilenume);
|
||||
if (!p) return; // safety precaution, this may only be called on writable tiles for camera textures.
|
||||
|
||||
for (bssize_t i=siz-1, j; i>=3; i-=4)
|
||||
{
|
||||
ptr2 = ptr1 = (p+i*(siz+1));
|
||||
swapchar(--ptr1, (ptr2 -= siz));
|
||||
for (j=(i>>1)-1; j>=0; --j)
|
||||
swapchar2((ptr1 -= 2), (ptr2 -= (siz<<1)), siz);
|
||||
|
||||
ptr2 = ptr1 = (p+(i-1)*(siz+1));
|
||||
for (j=((i-1)>>1)-1; j>=0; --j)
|
||||
swapchar2((ptr1 -= 2), (ptr2 -= (siz<<1)), siz);
|
||||
|
||||
ptr2 = ptr1 = (p+(i-2)*(siz+1));
|
||||
swapchar(--ptr1, (ptr2 -= siz));
|
||||
|
||||
for (j=((i-2)>>1)-1; j>=0; --j)
|
||||
swapchar2((ptr1 -= 2), (ptr2 -= (siz<<1)), siz);
|
||||
|
||||
ptr2 = ptr1 = (p+(i-3)*(siz+1));
|
||||
|
||||
for (j=((i-3)>>1)-1; j>=0; --j)
|
||||
swapchar2((ptr1 -= 2), (ptr2 -= (siz<<1)), siz);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// preparemirror
|
||||
//
|
||||
|
|
|
@ -541,10 +541,20 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32
|
|||
{
|
||||
float const r = 1.f / dd[i];
|
||||
|
||||
if (TileFiles.tiles[globalpicnum]->GetUseType() == FTexture::Canvas)
|
||||
{
|
||||
//update texcoords, canvas textures are upside down!
|
||||
vt->SetTexCoord(
|
||||
uu[i] * r * scale.x - usub,
|
||||
1.f - (vv[i] * r * scale.y - vsub));
|
||||
}
|
||||
else
|
||||
{
|
||||
//update texcoords
|
||||
vt->SetTexCoord(
|
||||
uu[i] * r * scale.x - usub,
|
||||
vv[i] * r * scale.y - vsub);
|
||||
}
|
||||
|
||||
//update verts
|
||||
vt->SetVertex(
|
||||
|
|
|
@ -177,9 +177,11 @@ void FGLRenderer::BindToFrameBuffer(FTexture *mat)
|
|||
if (BaseLayer == nullptr)
|
||||
{
|
||||
// must create the hardware texture first
|
||||
BaseLayer->CreateTexture(mat->GetWidth(), mat->GetHeight(), FHardwareTexture::TrueColor, false);
|
||||
BaseLayer = new FHardwareTexture();
|
||||
BaseLayer->CreateTexture(mat->GetWidth()*4, mat->GetHeight()*4, FHardwareTexture::TrueColor, false);
|
||||
mat->SetHardwareTexture(0, BaseLayer);
|
||||
}
|
||||
BaseLayer->BindToFrameBuffer(mat->GetWidth(), mat->GetHeight());
|
||||
BaseLayer->BindToFrameBuffer(mat->GetWidth()*4, mat->GetHeight()*4);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
|
@ -254,6 +254,11 @@ void BuildTiles::ClearTextureCache(bool artonly)
|
|||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// InvalidateTile
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void BuildTiles::InvalidateTile(int num)
|
||||
{
|
||||
|
@ -271,6 +276,21 @@ void BuildTiles::InvalidateTile(int num)
|
|||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// MakeCanvas
|
||||
//
|
||||
// Turns texture into a canvas (i.e. camera texture)
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void BuildTiles::MakeCanvas(int tilenum, int width, int height)
|
||||
{
|
||||
auto canvas = ValidateCustomTile(tilenum, FTexture::Canvas);
|
||||
canvas->Size.x = width;
|
||||
canvas->Size.y = height;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// LoadArtFile
|
||||
|
@ -388,6 +408,10 @@ FTexture* BuildTiles::ValidateCustomTile(int tilenum, int type)
|
|||
// todo: invalidate hardware textures for tile.
|
||||
replacement = new FRestorableTile(tile);
|
||||
}
|
||||
else if (type == FTexture::Canvas)
|
||||
{
|
||||
replacement = new FCanvasTexture("camera", 0, 0);
|
||||
}
|
||||
else return nullptr;
|
||||
AddTile(tilenum, replacement);
|
||||
return replacement;
|
||||
|
@ -683,7 +707,6 @@ int BuildTiles::tileCreateRotated(int tileNum)
|
|||
auto src = buffer.Data();
|
||||
auto dst = dbuffer.Data();
|
||||
|
||||
// the engine has a squarerotatetile() we could call, but it mirrors at the same time
|
||||
auto siz = tex->GetSize();
|
||||
for (int x = 0; x < siz.x; ++x)
|
||||
{
|
||||
|
|
|
@ -201,6 +201,7 @@ public:
|
|||
Art, // from an ART file, readonly
|
||||
Writable, // A writable texture
|
||||
Restorable, // a writable copy of something else
|
||||
Canvas, // camera texture
|
||||
User // A texture with user-provided image content
|
||||
};
|
||||
|
||||
|
@ -311,6 +312,33 @@ protected:
|
|||
friend struct BuildTiles;
|
||||
};
|
||||
|
||||
class FCanvasTexture : public FTexture
|
||||
{
|
||||
public:
|
||||
FCanvasTexture(const char* name, int width, int height)
|
||||
{
|
||||
Name = name;
|
||||
Size.x = width;
|
||||
Size.y = height;
|
||||
|
||||
bMasked = false;
|
||||
bTranslucent = false;
|
||||
//bNoExpand = true;
|
||||
useType = FTexture::Canvas;
|
||||
}
|
||||
|
||||
void NeedUpdate() { bNeedsUpdate = true; }
|
||||
void SetUpdated(bool rendertype) { bNeedsUpdate = false; bFirstUpdate = false; bLastUpdateType = rendertype; }
|
||||
|
||||
protected:
|
||||
|
||||
bool bLastUpdateType = false;
|
||||
bool bNeedsUpdate = true;
|
||||
public:
|
||||
bool bFirstUpdate = true;
|
||||
|
||||
friend struct FCanvasTextureInfo;
|
||||
};
|
||||
class FTileTexture : public FTexture
|
||||
{
|
||||
public:
|
||||
|
@ -551,6 +579,7 @@ struct BuildTiles
|
|||
int tileCreateRotated(int owner);
|
||||
void ClearTextureCache(bool artonly = false);
|
||||
void InvalidateTile(int num);
|
||||
void MakeCanvas(int tilenum, int width, int height);
|
||||
};
|
||||
|
||||
int tileGetCRC32(int tileNum);
|
||||
|
|
|
@ -3547,8 +3547,7 @@ void G_DoSpriteAnimations(int32_t ourx, int32_t oury, int32_t ourz, int32_t oura
|
|||
case VIEWSCREEN__STATIC:
|
||||
case VIEWSCREEN2__STATIC:
|
||||
{
|
||||
int const viewscrShift = G_GetViewscreenSizeShift(t);
|
||||
int const viewscrTile = TILE_VIEWSCR-viewscrShift;
|
||||
int const viewscrTile = TILE_VIEWSCR;
|
||||
|
||||
if (g_curViewscreen >= 0 && actor[OW(i)].t_data[0] == 1)
|
||||
{
|
||||
|
@ -3559,25 +3558,7 @@ void G_DoSpriteAnimations(int32_t ourx, int32_t oury, int32_t ourz, int32_t oura
|
|||
}
|
||||
else if (g_curViewscreen == i && display_mirror != 3 && tileData(viewscrTile))
|
||||
{
|
||||
// this exposes a sprite sorting issue which needs to be debugged further...
|
||||
#if 0
|
||||
if (spritesortcnt < maxspritesonscreen)
|
||||
{
|
||||
auto const newt = &tsprite[spritesortcnt++];
|
||||
|
||||
*newt = *t;
|
||||
|
||||
newt->cstat |= 2|512;
|
||||
newt->x += (sintable[(newt->ang+512)&2047]>>12);
|
||||
newt->y += (sintable[newt->ang&2047]>>12);
|
||||
updatesector(newt->x, newt->y, &newt->sectnum);
|
||||
}
|
||||
#endif
|
||||
t->picnum = viewscrTile;
|
||||
#if VIEWSCREENFACTOR > 0
|
||||
t->xrepeat >>= viewscrShift;
|
||||
t->yrepeat >>= viewscrShift;
|
||||
#endif
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
@ -43,8 +43,6 @@ BEGIN_DUKE_NS
|
|||
// Compile game-side legacy Room over Room code?
|
||||
#define LEGACY_ROR 1
|
||||
|
||||
# define VIEWSCREENFACTOR 2
|
||||
|
||||
enum GametypeFlags_t {
|
||||
GAMETYPE_COOP = 0x00000001,
|
||||
GAMETYPE_WEAPSTAY = 0x00000002,
|
||||
|
@ -437,32 +435,6 @@ static inline int G_GetMusicIdx(const char *str)
|
|||
#endif
|
||||
|
||||
|
||||
#ifndef ONLY_USERDEFS
|
||||
|
||||
template <typename T>
|
||||
static inline int G_GetViewscreenSizeShift(T const * spr)
|
||||
{
|
||||
#if VIEWSCREENFACTOR == 0
|
||||
UNREFERENCED_PARAMETER(spr);
|
||||
return VIEWSCREENFACTOR;
|
||||
#else
|
||||
static CONSTEXPR int const mask = (1<<VIEWSCREENFACTOR)-1;
|
||||
const int rem = (spr->xrepeat & mask) | (spr->yrepeat & mask);
|
||||
|
||||
for (int i=0; i < VIEWSCREENFACTOR; i++)
|
||||
if (rem & (1<<i))
|
||||
return i;
|
||||
|
||||
return VIEWSCREENFACTOR;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined game_c_ || !defined DISABLE_INLINING
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
END_DUKE_NS
|
||||
|
||||
#endif
|
||||
|
|
|
@ -414,8 +414,6 @@ static void G_SetupCamTile(int spriteNum, int tileNum, int smoothRatio)
|
|||
|
||||
finishTileSetup:
|
||||
renderRestoreTarget();
|
||||
squarerotatetile(tileNum);
|
||||
tileInvalidate(tileNum, -1, 255);
|
||||
}
|
||||
|
||||
void G_AnimateCamSprite(int smoothRatio)
|
||||
|
@ -438,11 +436,8 @@ void G_AnimateCamSprite(int smoothRatio)
|
|||
|
||||
if (OW(spriteNum) >= 0 && dist(&sprite[pPlayer->i], &sprite[spriteNum]) < VIEWSCREEN_ACTIVE_DISTANCE)
|
||||
{
|
||||
int const viewscrShift = G_GetViewscreenSizeShift((uspriteptr_t)&sprite[spriteNum]);
|
||||
int const viewscrTile = TILE_VIEWSCR - viewscrShift;
|
||||
|
||||
if (tileData(viewscrTile) ==nullptr)
|
||||
TileFiles.tileCreate(viewscrTile, tilesiz[PN(spriteNum)].x << viewscrShift, tilesiz[PN(spriteNum)].y << viewscrShift);
|
||||
int const viewscrTile = TILE_VIEWSCR;
|
||||
TileFiles.MakeCanvas(viewscrTile, tilesiz[PN(spriteNum)].x, tilesiz[PN(spriteNum)].y);
|
||||
|
||||
G_SetupCamTile(OW(spriteNum), viewscrTile, smoothRatio);
|
||||
#ifdef POLYMER
|
||||
|
|
|
@ -134,11 +134,13 @@ FHardwareTexture* GLInstance::LoadTexture(FTexture* tex, int textype, int palid)
|
|||
auto phwtex = tex->GetHardwareTexture(palid);
|
||||
if (phwtex) return *phwtex;
|
||||
|
||||
FHardwareTexture *hwtex;
|
||||
FHardwareTexture *hwtex = nullptr;
|
||||
if (textype == TT_INDEXED)
|
||||
hwtex = CreateIndexedTexture(tex);
|
||||
else
|
||||
else if (tex->GetUseType() != FTexture::Canvas)
|
||||
hwtex = CreateTrueColorTexture(tex, textype == TT_HICREPLACE? -1 : palid, textype == TT_BRIGHTMAP, textype == TT_BRIGHTMAP);
|
||||
else
|
||||
hwtex = nullptr;
|
||||
|
||||
if (hwtex) tex->SetHardwareTexture(palid, hwtex);
|
||||
return hwtex;
|
||||
|
@ -169,8 +171,9 @@ bool GLInstance::SetTextureInternal(int picnum, FTexture* tex, int palette, int
|
|||
|
||||
auto& h = hictinting[palette];
|
||||
bool applytint = false;
|
||||
// Canvas textures must be treated like hightile replacements in the following code.
|
||||
auto rep = (hw_hightile && !(h.f & HICTINT_ALWAYSUSEART)) ? tex->FindReplacement(palette) : nullptr;
|
||||
if (rep)
|
||||
if (rep || tex->GetUseType() == FTexture::Canvas)
|
||||
{
|
||||
if (usepalette != 0)
|
||||
{
|
||||
|
@ -180,9 +183,12 @@ bool GLInstance::SetTextureInternal(int picnum, FTexture* tex, int palette, int
|
|||
GLInterface.SetBasepalTint(hh.tint);
|
||||
}
|
||||
|
||||
if (rep)
|
||||
{
|
||||
tex = rep->faces[0];
|
||||
}
|
||||
if (!rep || rep->palnum != palette || (h.f & HICTINT_APPLYOVERALTPAL)) applytint = true;
|
||||
TextureType = TT_HICREPLACE;
|
||||
if (rep->palnum != palette || (h.f & HICTINT_APPLYOVERALTPAL)) applytint = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1262,22 +1262,6 @@ void G_DrawRooms(int32_t playerNum, int32_t smoothRatio)
|
|||
renderDrawMasks();
|
||||
#endif
|
||||
screen->FinishScene();
|
||||
|
||||
if (g_screenCapture)
|
||||
{
|
||||
g_screenCapture = 0;
|
||||
|
||||
tileInvalidate(TILE_SAVESHOT, 0, 255);
|
||||
|
||||
//if (videoGetRenderMode() == REND_CLASSIC)
|
||||
{
|
||||
renderRestoreTarget();
|
||||
}
|
||||
#ifdef USE_OPENGL
|
||||
//else
|
||||
// G_ReadGLFrame();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
G_RestoreInterpolations();
|
||||
|
@ -4808,8 +4792,7 @@ default_case1:
|
|||
case VIEWSCREEN2__STATIC:
|
||||
{
|
||||
if (RR) goto default_case2;
|
||||
int const viewscrShift = G_GetViewscreenSizeShift(t);
|
||||
int const viewscrTile = TILE_VIEWSCR-viewscrShift;
|
||||
int const viewscrTile = TILE_VIEWSCR;
|
||||
|
||||
if (g_curViewscreen >= 0 && actor[OW(i)].t_data[0] == 1)
|
||||
{
|
||||
|
@ -4818,27 +4801,11 @@ default_case1:
|
|||
t->xrepeat += 10;
|
||||
t->yrepeat += 9;
|
||||
}
|
||||
else if (g_curViewscreen == i && display_mirror != 3 && tileData(viewscrTile))
|
||||
else if (g_curViewscreen == i && display_mirror != 3)
|
||||
{
|
||||
// this exposes a sprite sorting issue which needs to be debugged further...
|
||||
#if 0
|
||||
if (spritesortcnt < maxspritesonscreen)
|
||||
{
|
||||
auto const newt = &tsprite[spritesortcnt++];
|
||||
|
||||
*newt = *t;
|
||||
|
||||
newt->cstat |= 2|512;
|
||||
newt->x += (sintable[(newt->ang+512)&2047]>>12);
|
||||
newt->y += (sintable[newt->ang&2047]>>12);
|
||||
updatesector(newt->x, newt->y, &newt->sectnum);
|
||||
}
|
||||
#endif
|
||||
t->picnum = viewscrTile;
|
||||
#if VIEWSCREENFACTOR > 0
|
||||
t->xrepeat >>= viewscrShift;
|
||||
t->yrepeat >>= viewscrShift;
|
||||
#endif
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
@ -40,8 +40,6 @@ BEGIN_RR_NS
|
|||
// Compile game-side legacy Room over Room code?
|
||||
#define LEGACY_ROR 1
|
||||
|
||||
# define VIEWSCREENFACTOR 2
|
||||
|
||||
enum GametypeFlags_t {
|
||||
GAMETYPE_COOP = 0x00000001,
|
||||
GAMETYPE_WEAPSTAY = 0x00000002,
|
||||
|
@ -426,24 +424,6 @@ static inline int G_GetMusicIdx(const char *str)
|
|||
|
||||
extern void G_PrintCurrentMusic(void);
|
||||
|
||||
template <typename T>
|
||||
static inline int G_GetViewscreenSizeShift(T const *tspr)
|
||||
{
|
||||
#if VIEWSCREENFACTOR == 0
|
||||
UNREFERENCED_PARAMETER(tspr);
|
||||
return VIEWSCREENFACTOR;
|
||||
#else
|
||||
static const int mask = (1<<VIEWSCREENFACTOR)-1;
|
||||
const int rem = (tspr->xrepeat & mask) | (tspr->yrepeat & mask);
|
||||
|
||||
for (bssize_t i=0; i < VIEWSCREENFACTOR; i++)
|
||||
if (rem & (1<<i))
|
||||
return i;
|
||||
|
||||
return VIEWSCREENFACTOR;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -245,7 +245,6 @@ G_EXTERN input_t inputfifo[MOVEFIFOSIZ][MAXPLAYERS];
|
|||
|
||||
G_EXTERN int32_t g_noEnemies;
|
||||
G_EXTERN int32_t g_restorePalette;
|
||||
G_EXTERN int32_t g_screenCapture;
|
||||
G_EXTERN uint32_t everyothertime;
|
||||
G_EXTERN uint32_t g_moveThingsCount;
|
||||
G_EXTERN double g_gameUpdateTime;
|
||||
|
|
|
@ -519,8 +519,6 @@ static void G_SetupCamTile(int spriteNum, int tileNum, int smoothRatio)
|
|||
screen->FinishScene();
|
||||
|
||||
renderRestoreTarget();
|
||||
squarerotatetile(tileNum);
|
||||
tileInvalidate(tileNum, -1, 255);
|
||||
}
|
||||
|
||||
void G_AnimateCamSprite(int smoothRatio)
|
||||
|
@ -543,11 +541,8 @@ void G_AnimateCamSprite(int smoothRatio)
|
|||
|
||||
if (OW(spriteNum) >= 0 && dist(&sprite[pPlayer->i], &sprite[spriteNum]) < VIEWSCREEN_ACTIVE_DISTANCE)
|
||||
{
|
||||
int const viewscrShift = G_GetViewscreenSizeShift((const uspritetype *)&sprite[spriteNum]);
|
||||
int const viewscrTile = TILE_VIEWSCR - viewscrShift;
|
||||
|
||||
if (tileData(viewscrTile) == nullptr)
|
||||
TileFiles.tileCreate(viewscrTile, tilesiz[PN(spriteNum)].x << viewscrShift, tilesiz[PN(spriteNum)].y << viewscrShift);
|
||||
int const viewscrTile = TILE_VIEWSCR;
|
||||
TileFiles.MakeCanvas(viewscrTile, tilesiz[PN(spriteNum)].x, tilesiz[PN(spriteNum)].y);
|
||||
|
||||
G_SetupCamTile(OW(spriteNum), viewscrTile, smoothRatio);
|
||||
#ifdef POLYMER
|
||||
|
|
|
@ -2114,6 +2114,12 @@ drawscreen(PLAYERp pp)
|
|||
if (FAF_DebugView)
|
||||
videoClearViewableArea(255L);
|
||||
|
||||
if (dimensionmode != 6)// && !ScreenSavePic)
|
||||
{
|
||||
// Cameras must be done before the main loop.
|
||||
JS_DrawCameras(pp, tx, ty, tz, tang, thoriz);
|
||||
}
|
||||
|
||||
screen->BeginScene();
|
||||
OverlapDraw = TRUE;
|
||||
DrawOverlapRoom(tx, ty, tz, tang, thoriz, tsectnum);
|
||||
|
|
|
@ -57,8 +57,6 @@ short mirrorcnt; //, floormirrorcnt;
|
|||
//short floormirrorsector[MAXMIRRORS];
|
||||
SWBOOL mirrorinview;
|
||||
|
||||
SWBOOL MirrorMoveSkip16 = 0;
|
||||
|
||||
// Voxel stuff
|
||||
//SWBOOL bVoxelsOn = TRUE; // Turn voxels on by default
|
||||
SWBOOL bSpinBobVoxels = FALSE; // Do twizzly stuff to voxels, but
|
||||
|
@ -464,7 +462,7 @@ void JS_InitMirrors(void)
|
|||
void drawroomstotile(int daposx, int daposy, int daposz,
|
||||
short daang, int dahoriz, short dacursectnum, short tilenume)
|
||||
{
|
||||
TileFiles.tileCreate(tilenume, tilesiz[tilenume].x, tilesiz[tilenume].y);
|
||||
TileFiles.MakeCanvas(tilenume, tilesiz[tilenume].x, tilesiz[tilenume].y);
|
||||
|
||||
renderSetTarget(tilenume, tilesiz[tilenume].x, tilesiz[tilenume].y);
|
||||
screen->BeginScene();
|
||||
|
@ -475,10 +473,6 @@ void drawroomstotile(int daposx, int daposy, int daposz,
|
|||
screen->FinishScene();
|
||||
|
||||
renderRestoreTarget();
|
||||
|
||||
squarerotatetile(tilenume);
|
||||
|
||||
tileInvalidate(tilenume, -1, -1);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -527,8 +521,10 @@ int camloopcnt = 0; // Timer to cycle through player
|
|||
// views
|
||||
short camplayerview = 1; // Don't show yourself!
|
||||
|
||||
void
|
||||
JS_DrawMirrors(PLAYERp pp, int tx, int ty, int tz, short tpang, int tphoriz)
|
||||
// Hack job alert!
|
||||
// Mirrors and cameras are maintained in the same data structure, but for hardware rendering they cannot be interleaved.
|
||||
// So this function replicates JS_DrawMirrors to only process the camera textures but not change any global state.
|
||||
void JS_DrawCameras(PLAYERp pp, int tx, int ty, int tz, short tpang, int tphoriz)
|
||||
{
|
||||
int j, cnt;
|
||||
int dist;
|
||||
|
@ -540,8 +536,6 @@ JS_DrawMirrors(PLAYERp pp, int tx, int ty, int tz, short tpang, int tphoriz)
|
|||
// drift!
|
||||
SWBOOL bIsWallMirror = FALSE;
|
||||
|
||||
MirrorMoveSkip16 = (MirrorMoveSkip16 + 1) & 15;
|
||||
|
||||
camloopcnt += (int32_t)(totalclock - ototalclock);
|
||||
if (camloopcnt > (60 * 5)) // 5 seconds per player view
|
||||
{
|
||||
|
@ -551,6 +545,190 @@ JS_DrawMirrors(PLAYERp pp, int tx, int ty, int tz, short tpang, int tphoriz)
|
|||
camplayerview = 1;
|
||||
}
|
||||
|
||||
// WARNING! Assuming (MIRRORLABEL&31) = 0 and MAXMIRRORS = 64 <-- JBF: wrong
|
||||
longptr = (int*)&gotpic[MIRRORLABEL >> 3];
|
||||
if (longptr && (longptr[0] || longptr[1]))
|
||||
{
|
||||
for (cnt = MAXMIRRORS - 1; cnt >= 0; cnt--)
|
||||
{
|
||||
if (!mirror[cnt].ismagic) continue; // these are definitely not camera textures.
|
||||
|
||||
//if (TEST_GOTPIC(cnt + MIRRORLABEL) || TEST_GOTPIC(cnt + CAMSPRITE))
|
||||
if (TEST_GOTPIC(cnt + MIRRORLABEL) || ((unsigned)mirror[cnt].campic < MAXTILES && TEST_GOTPIC(mirror[cnt].campic)))
|
||||
{
|
||||
// Do not change any global state here!
|
||||
bIsWallMirror = (TEST_GOTPIC(cnt + MIRRORLABEL));
|
||||
dist = 0x7fffffff;
|
||||
|
||||
if (bIsWallMirror)
|
||||
{
|
||||
j = klabs(wall[mirror[cnt].mirrorwall].x - tx);
|
||||
j += klabs(wall[mirror[cnt].mirrorwall].y - ty);
|
||||
if (j < dist)
|
||||
dist = j;
|
||||
}
|
||||
else
|
||||
{
|
||||
SPRITEp tp;
|
||||
|
||||
tp = &sprite[mirror[cnt].camsprite];
|
||||
|
||||
j = klabs(tp->x - tx);
|
||||
j += klabs(tp->y - ty);
|
||||
if (j < dist)
|
||||
dist = j;
|
||||
}
|
||||
|
||||
|
||||
SPRITEp sp = NULL;
|
||||
int camhoriz;
|
||||
short w;
|
||||
int dx, dy, dz, tdx, tdy, tdz, midx, midy;
|
||||
|
||||
|
||||
ASSERT(mirror[cnt].camera != -1);
|
||||
|
||||
sp = &sprite[mirror[cnt].camera];
|
||||
|
||||
ASSERT(sp);
|
||||
|
||||
// Calculate the angle of the mirror wall
|
||||
w = mirror[cnt].mirrorwall;
|
||||
|
||||
// Get wall midpoint for offset in mirror view
|
||||
midx = (wall[w].x + wall[wall[w].point2].x) / 2;
|
||||
midy = (wall[w].y + wall[wall[w].point2].y) / 2;
|
||||
|
||||
// Finish finding offsets
|
||||
tdx = klabs(midx - tx);
|
||||
tdy = klabs(midy - ty);
|
||||
|
||||
if (midx >= tx)
|
||||
dx = sp->x - tdx;
|
||||
else
|
||||
dx = sp->x + tdx;
|
||||
|
||||
if (midy >= ty)
|
||||
dy = sp->y - tdy;
|
||||
else
|
||||
dy = sp->y + tdy;
|
||||
|
||||
tdz = klabs(tz - sp->z);
|
||||
if (tz >= sp->z)
|
||||
dz = sp->z + tdz;
|
||||
else
|
||||
dz = sp->z - tdz;
|
||||
|
||||
|
||||
// Is it a TV cam or a teleporter that shows destination?
|
||||
// TRUE = It's a TV cam
|
||||
mirror[cnt].mstate = m_normal;
|
||||
if (TEST_BOOL1(sp))
|
||||
mirror[cnt].mstate = m_viewon;
|
||||
|
||||
// Show teleport destination
|
||||
// NOTE: Adding MAXSECTORS lets you draw a room, even if
|
||||
// you are outside of it!
|
||||
if (mirror[cnt].mstate == m_viewon)
|
||||
{
|
||||
SWBOOL DoCam = FALSE;
|
||||
|
||||
if (mirror[cnt].campic == -1)
|
||||
{
|
||||
Printf("Missing campic for mirror %d. Map Coordinates: x = %d, y = %d\n", cnt, midx, midy);
|
||||
return;
|
||||
}
|
||||
|
||||
// BOOL2 = Oscilate camera
|
||||
if (TEST_BOOL2(sp) && MoveSkip2 == 0)
|
||||
{
|
||||
if (TEST_BOOL3(sp)) // If true add increment to
|
||||
// angle else subtract
|
||||
{
|
||||
// Store current angle in TAG5
|
||||
SP_TAG5(sp) = NORM_ANGLE((SP_TAG5(sp) + 4));
|
||||
|
||||
// TAG6 = Turn radius
|
||||
if (klabs(GetDeltaAngle(SP_TAG5(sp), sp->ang)) >= SP_TAG6(sp))
|
||||
{
|
||||
RESET_BOOL3(sp); // Reverse turn
|
||||
// direction.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Store current angle in TAG5
|
||||
SP_TAG5(sp) = NORM_ANGLE((SP_TAG5(sp) - 4));
|
||||
|
||||
// TAG6 = Turn radius
|
||||
if (klabs(GetDeltaAngle(SP_TAG5(sp), sp->ang)) >= SP_TAG6(sp))
|
||||
{
|
||||
SET_BOOL3(sp); // Reverse turn
|
||||
// direction.
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!TEST_BOOL2(sp))
|
||||
{
|
||||
SP_TAG5(sp) = sp->ang; // Copy sprite angle to
|
||||
// tag5
|
||||
}
|
||||
|
||||
// See if there is a horizon value. 0 defaults to
|
||||
// 100!
|
||||
if (SP_TAG7(sp) != 0)
|
||||
{
|
||||
camhoriz = SP_TAG7(sp);
|
||||
if (camhoriz > PLAYER_HORIZ_MAX)
|
||||
camhoriz = PLAYER_HORIZ_MAX;
|
||||
else if (camhoriz < PLAYER_HORIZ_MIN)
|
||||
camhoriz = PLAYER_HORIZ_MIN;
|
||||
}
|
||||
else
|
||||
camhoriz = 100; // Default
|
||||
|
||||
// If player is dead still then update at MoveSkip4
|
||||
// rate.
|
||||
if (pp->posx == pp->oposx && pp->posy == pp->oposy && pp->posz == pp->oposz)
|
||||
DoCam = TRUE;
|
||||
|
||||
|
||||
// Set up the tile for drawing
|
||||
TileFiles.MakeCanvas(mirror[cnt].campic, 128, 128);
|
||||
|
||||
{
|
||||
if (dist < MAXCAMDIST)
|
||||
{
|
||||
PLAYERp cp = Player + camplayerview;
|
||||
|
||||
if (TEST_BOOL11(sp) && numplayers > 1)
|
||||
{
|
||||
drawroomstotile(cp->posx, cp->posy, cp->posz, cp->pang, cp->horiz, cp->cursectnum, mirror[cnt].campic);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawroomstotile(sp->x, sp->y, sp->z, SP_TAG5(sp), camhoriz, sp->sectnum, mirror[cnt].campic);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JS_DrawMirrors(PLAYERp pp, int tx, int ty, int tz, short tpang, int tphoriz)
|
||||
{
|
||||
int j, cnt;
|
||||
int dist;
|
||||
int tposx, tposy; // Camera
|
||||
int *longptr;
|
||||
fix16_t tang;
|
||||
|
||||
// int tx, ty, tz, tpang; // Interpolate so mirror doesn't
|
||||
// drift!
|
||||
SWBOOL bIsWallMirror = FALSE;
|
||||
|
||||
// WARNING! Assuming (MIRRORLABEL&31) = 0 and MAXMIRRORS = 64 <-- JBF: wrong
|
||||
longptr = (int *)&gotpic[MIRRORLABEL >> 3];
|
||||
if (longptr && (longptr[0] || longptr[1]))
|
||||
|
@ -678,90 +856,6 @@ JS_DrawMirrors(PLAYERp pp, int tx, int ty, int tz, short tpang, int tphoriz)
|
|||
analyzesprites(dx, dy, dz, FALSE);
|
||||
renderDrawMasks();
|
||||
}
|
||||
else
|
||||
{
|
||||
SWBOOL DoCam = FALSE;
|
||||
|
||||
if (mirror[cnt].campic == -1)
|
||||
{
|
||||
Printf("Missing campic for mirror %d. Map Coordinates: x = %d, y = %d\n", cnt,midx,midy);
|
||||
return;
|
||||
}
|
||||
|
||||
// BOOL2 = Oscilate camera
|
||||
if (TEST_BOOL2(sp) && MoveSkip2 == 0)
|
||||
{
|
||||
if (TEST_BOOL3(sp)) // If true add increment to
|
||||
// angle else subtract
|
||||
{
|
||||
// Store current angle in TAG5
|
||||
SP_TAG5(sp) = NORM_ANGLE((SP_TAG5(sp) + 4));
|
||||
|
||||
// TAG6 = Turn radius
|
||||
if (klabs(GetDeltaAngle(SP_TAG5(sp), sp->ang)) >= SP_TAG6(sp))
|
||||
{
|
||||
RESET_BOOL3(sp); // Reverse turn
|
||||
// direction.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Store current angle in TAG5
|
||||
SP_TAG5(sp) = NORM_ANGLE((SP_TAG5(sp) - 4));
|
||||
|
||||
// TAG6 = Turn radius
|
||||
if (klabs(GetDeltaAngle(SP_TAG5(sp), sp->ang)) >= SP_TAG6(sp))
|
||||
{
|
||||
SET_BOOL3(sp); // Reverse turn
|
||||
// direction.
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!TEST_BOOL2(sp))
|
||||
{
|
||||
SP_TAG5(sp) = sp->ang; // Copy sprite angle to
|
||||
// tag5
|
||||
}
|
||||
|
||||
// See if there is a horizon value. 0 defaults to
|
||||
// 100!
|
||||
if (SP_TAG7(sp) != 0)
|
||||
{
|
||||
camhoriz = SP_TAG7(sp);
|
||||
if (camhoriz > PLAYER_HORIZ_MAX)
|
||||
camhoriz = PLAYER_HORIZ_MAX;
|
||||
else if (camhoriz < PLAYER_HORIZ_MIN)
|
||||
camhoriz = PLAYER_HORIZ_MIN;
|
||||
}
|
||||
else
|
||||
camhoriz = 100; // Default
|
||||
|
||||
// If player is dead still then update at MoveSkip4
|
||||
// rate.
|
||||
if (pp->posx == pp->oposx && pp->posy == pp->oposy && pp->posz == pp->oposz)
|
||||
DoCam = TRUE;
|
||||
|
||||
|
||||
// Set up the tile for drawing
|
||||
TileFiles.tileCreate(mirror[cnt].campic, 128, 128);
|
||||
|
||||
if (MirrorMoveSkip16 == 0 || (DoCam && (MoveSkip4 == 0)))
|
||||
{
|
||||
if (dist < MAXCAMDIST)
|
||||
{
|
||||
PLAYERp cp = Player + camplayerview;
|
||||
|
||||
if (TEST_BOOL11(sp) && numplayers > 1)
|
||||
{
|
||||
drawroomstotile(cp->posx, cp->posy, cp->posz, cp->pang, cp->horiz, cp->cursectnum, mirror[cnt].campic);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawroomstotile(sp->x, sp->y, sp->z, SP_TAG5(sp), camhoriz, sp->sectnum, mirror[cnt].campic);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -71,6 +71,7 @@ extern SWBOOL mirrorinview;
|
|||
extern short NormalVisibility;
|
||||
|
||||
void JAnalyzeSprites(tspriteptr_t tspr);
|
||||
void JS_DrawCameras(PLAYERp pp, int tx, int ty, int tz, short tpang, int tphoriz);
|
||||
void JS_DrawMirrors(PLAYERp pp,int tx,int ty,int tz,short tpang,int tphoriz);
|
||||
void JS_InitMirrors(void);
|
||||
void JS_InitLockouts(void);
|
||||
|
|
Loading…
Reference in a new issue