Browse Source

Fix render order (#639)

pull/658/head
Anders Jenbo 6 years ago committed by GitHub
parent
commit
e4df9319b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 15
      Source/gendung.cpp
  2. 2
      Source/render.h
  3. 243
      Source/scrollrt.cpp

15
Source/gendung.cpp

@ -4,6 +4,9 @@ DEVILUTION_BEGIN_NAMESPACE
WORD level_frame_types[MAXTILES];
int themeCount;
/**
* List of transparent dPieces
*/
BOOLEAN nTransTable[2049];
//int dword_52D204;
int dMonster[MAXDUNX][MAXDUNY];
@ -21,6 +24,9 @@ BOOL setloadflag;
BYTE *pMegaTiles;
BYTE *pLevelPieces;
int gnDifficulty;
/**
* List of transparancy masks to use for dPieces
*/
char block_lvid[2049];
//char byte_5B78EB;
char dTransVal[MAXDUNX][MAXDUNY];
@ -28,17 +34,26 @@ BOOLEAN nTrapTable[2049];
BYTE leveltype;
BYTE currlevel;
BOOLEAN TransList[256];
/**
* List of path blocking dPieces
*/
BOOLEAN nSolidTable[2049];
ScrollStruct ScrollInfo;
BYTE *pDungeonCels;
THEME_LOC themeLoc[MAXTHEMES];
char dPlayer[MAXDUNX][MAXDUNY];
char dArch[MAXDUNX][MAXDUNY];
/**
* List of light blocking dPieces
*/
BOOLEAN nBlockTable[2049];
BYTE *pSpecialCels;
char dFlags[MAXDUNX][MAXDUNY];
char dItem[MAXDUNX][MAXDUNY];
BYTE setlvlnum;
/**
* List of missile blocking dPieces
*/
BOOLEAN nMissileTable[2049];
BYTE *pSetPiece;
char setlvltype;

2
Source/render.h

@ -2,8 +2,6 @@
#define __RENDER_H__
void RenderTile(BYTE *pBuff);
#define drawUpperScreen(p) RenderTile(p)
#define drawLowerScreen(p) RenderTile(p)
void world_draw_black_tile(int sx, int sy);
void trans_rect(int sx, int sy, int width, int height);

243
Source/scrollrt.cpp

@ -45,6 +45,8 @@ void (*DrawPlrProc)(int, int, int, int, int, BYTE *, int, int, int, int);
BYTE sgSaveBack[8192];
DWORD sgdwCursHgtOld;
bool dRendered[MAXDUNX][MAXDUNY];
/* data */
/* used in 1.00 debug */
@ -504,22 +506,20 @@ static void DrawObject(int x, int y, int ox, int oy, BOOL pre)
}
}
static void scrollrt_draw_dungeon(int sx, int sy, int dx, int dy, int eflag);
static void scrollrt_draw_dungeon(int sx, int sy, int dx, int dy);
/**
* @brief Render a row of tile
* @brief Render a cell
* @param x dPiece coordinate
* @param y dPiece coordinate
* @param sx Back buffer coordinate
* @param sy Back buffer coordinate
* @param eflag is it an even (0) or odd (1) row
*/
static void drawRow(int x, int y, int sx, int sy, int eflag)
static void drawCell(int x, int y, int sx, int sy)
{
BYTE *dst;
MICROS *pMap;
level_piece_id = dPiece[x][y];
light_table_index = dLight[x][y];
dst = &gpBuffer[sx + sy * BUFFER_WIDTH];
@ -529,41 +529,71 @@ static void drawRow(int x, int y, int sx, int sy, int eflag)
arch_draw_type = i == 0 ? 1 : 0;
level_cel_block = pMap->mt[2 * i];
if (level_cel_block != 0) {
drawUpperScreen(dst);
RenderTile(dst);
}
arch_draw_type = i == 0 ? 2 : 0;
level_cel_block = pMap->mt[2 * i + 1];
if (level_cel_block != 0) {
drawUpperScreen(dst + 32);
RenderTile(dst + 32);
}
dst -= BUFFER_WIDTH * 32;
}
scrollrt_draw_dungeon(x, y, sx, sy, eflag);
}
/**
* This variant checks for of screen element on the lower screen
* This function it self causes rendering issues since it will render on top of objects on the other side of walls
* @brief Re render tile to workaround sorting issues with players walking east/west
* @param y dPiece coordinate
* @brief Render grass and leafs
* @param x dPiece coordinate
* @param y dPiece coordinate
* @param sx Back buffer coordinate
* @param sy Back buffer coordinate
*/
static void scrollrt_draw_e_flag(int x, int y, int sx, int sy)
static void drawCellFoliage(int x, int y, int sx, int sy)
{
int lti_old, cta_old, lpi_old;
BYTE *dst;
MICROS *pMap;
lti_old = light_table_index;
cta_old = cel_transparency_active;
lpi_old = level_piece_id;
light_table_index = dLight[x][y];
dst = &gpBuffer[sx + sy * BUFFER_WIDTH];
dst -= BUFFER_WIDTH * 32;
pMap = &dpiece_defs_map_2[x][y];
cel_transparency_active = (BYTE)(nTransTable[level_piece_id] & TransList[dTransVal[x][y]]);
for (int i = 1; i<MicroTileLen>> 1; i++) {
arch_draw_type = 0;
level_cel_block = pMap->mt[2 * i];
if (level_cel_block != 0) {
RenderTile(dst);
}
level_cel_block = pMap->mt[2 * i + 1];
if (level_cel_block != 0) {
RenderTile(dst + 32);
}
dst -= BUFFER_WIDTH * 32;
}
}
drawRow(x, y, sx, sy, 0);
/**
* @brief Render a floor tiles
* @param x dPiece coordinate
* @param y dPiece coordinate
* @param sx Back buffer coordinate
* @param sy Back buffer coordinate
*/
static void drawFloor(int x, int y, int sx, int sy)
{
cel_transparency_active = 0;
light_table_index = dLight[x][y];
light_table_index = lti_old;
cel_transparency_active = cta_old;
level_piece_id = lpi_old;
BYTE *dst = &gpBuffer[sx + sy * BUFFER_WIDTH];
arch_draw_type = 1;
level_cel_block = dpiece_defs_map_2[x][y].mt[0];
if (level_cel_block != 0) {
RenderTile(dst);
}
arch_draw_type = 2;
level_cel_block = dpiece_defs_map_2[x][y].mt[1];
if (level_cel_block != 0) {
RenderTile(dst + 32);
}
}
/**
@ -601,9 +631,8 @@ static void DrawItem(int x, int y, int sx, int sy, BOOL pre)
* @param oy dPiece Y offset
* @param sx Back buffer coordinate
* @param sy Back buffer coordinate
* @param eflag Should the sorting workaround be applied
*/
static void DrawMonsterHelper(int x, int y, int oy, int sx, int sy, int eflag)
static void DrawMonsterHelper(int x, int y, int oy, int sx, int sy)
{
int mi, px, py;
MonsterStruct *pMonster;
@ -643,9 +672,6 @@ static void DrawMonsterHelper(int x, int y, int oy, int sx, int sy, int eflag)
Cl2DrawOutline(233, px, py, pMonster->_mAnimData, pMonster->_mAnimFrame, pMonster->MType->width);
}
DrawMonster(x, y, px, py, mi);
if (eflag && !pMonster->_meflag) {
scrollrt_draw_e_flag(x - 1, y + 1, sx - 64, sy);
}
}
/**
@ -655,9 +681,8 @@ static void DrawMonsterHelper(int x, int y, int oy, int sx, int sy, int eflag)
* @param oy dPiece Y offset
* @param sx Back buffer coordinate
* @param sy Back buffer coordinate
* @param eflag Should the sorting workaround be applied
*/
static void DrawPlayerHelper(int x, int y, int oy, int sx, int sy, int eflag)
static void DrawPlayerHelper(int x, int y, int oy, int sx, int sy)
{
int p = dPlayer[x][y + oy];
p = p > 0 ? p - 1 : -(p + 1);
@ -666,12 +691,6 @@ static void DrawPlayerHelper(int x, int y, int oy, int sx, int sy, int eflag)
int py = sy + pPlayer->_pyoff;
DrawPlayer(p, x, y + oy, px, py, pPlayer->_pAnimData, pPlayer->_pAnimFrame, pPlayer->_pAnimWidth);
if (eflag && pPlayer->_peflag != 0) {
if (pPlayer->_peflag == 2) {
scrollrt_draw_e_flag(x - 2, y + 1, sx - 96, sy - 16);
}
scrollrt_draw_e_flag(x - 1, y + 1, sx - 64, sy);
}
}
/**
@ -680,9 +699,8 @@ static void DrawPlayerHelper(int x, int y, int oy, int sx, int sy, int eflag)
* @param sy dPiece coordinate
* @param dx Back buffer coordinate
* @param dy Back buffer coordinate
* @param eflag Should the sorting workaround be applied
*/
static void scrollrt_draw_dungeon(int sx, int sy, int dx, int dy, int eflag)
static void scrollrt_draw_dungeon(int sx, int sy, int dx, int dy)
{
int mi, px, py, nCel, nMon, negMon, frames;
char bFlag, bDead, bObj, bItem, bPlr, bArch, bMap, negPlr, dd;
@ -691,9 +709,16 @@ static void scrollrt_draw_dungeon(int sx, int sy, int dx, int dy, int eflag)
assert((DWORD)sx < MAXDUNX);
assert((DWORD)sy < MAXDUNY);
if (dRendered[sx][sy])
return;
dRendered[sx][sy] = true;
light_table_index = dLight[sx][sy];
bFlag = dFlags[sx][sy];
bDead = dDead[sx][sy];
bArch = dArch[sx][sy];
bMap = dTransVal[sx][sy];
negMon = dMonster[sx][sy - 1];
@ -724,70 +749,138 @@ static void scrollrt_draw_dungeon(int sx, int sy, int dx, int dy, int eflag)
DrawItem(sx, sy, dx, dy, 1);
if (bFlag & BFLAG_PLAYERLR) {
assert((DWORD)(sy-1) < MAXDUNY);
DrawPlayerHelper(sx, sy, -1, dx, dy, eflag);
DrawPlayerHelper(sx, sy, -1, dx, dy);
}
if (bFlag & BFLAG_MONSTLR && negMon < 0) {
DrawMonsterHelper(sx, sy, -1, dx, dy, eflag);
DrawMonsterHelper(sx, sy, -1, dx, dy);
}
if (bFlag & BFLAG_DEAD_PLAYER) {
DrawDeadPlayer(sx, sy, dx, dy);
}
if (dPlayer[sx][sy] > 0) {
DrawPlayerHelper(sx, sy, 0, dx, dy, eflag);
DrawPlayerHelper(sx, sy, 0, dx, dy);
}
if (dMonster[sx][sy] > 0) {
DrawMonsterHelper(sx, sy, 0, dx, dy, eflag);
DrawMonsterHelper(sx, sy, 0, dx, dy);
}
DrawMissile(sx, sy, dx, dy, FALSE);
DrawObject(sx, sy, dx, dy, 0);
DrawItem(sx, sy, dx, dy, 0);
if (bArch != 0) {
cel_transparency_active = TransList[bMap];
if (leveltype != DTYPE_TOWN) {
if (leveltype != DTYPE_TOWN) {
bArch = dArch[sx][sy];
if (bArch != 0) {
cel_transparency_active = TransList[bMap];
CelClippedBlitLightTrans(&gpBuffer[dx + BUFFER_WIDTH * dy], pSpecialCels, bArch, 64);
} else {
#if 0 // Special tree rendering, disabled in 1.09
CelBlitFrame(&gpBuffer[dx + BUFFER_WIDTH * dy], pSpecialCels, bArch, 64);
#endif
}
} else {
if (sx - 2 >= 0 && sx - 2 < MAXDUNX && sy + 1 >= 0 && sy + 1 < MAXDUNY) {
bArch = dArch[sx - 2][sy + 1];
if (bArch != 0 && dx - 64 - 32 >= 0) {
CelBlitFrame(&gpBuffer[dx - 64 - 32 + BUFFER_WIDTH * (dy - 16)], pSpecialCels, bArch, 64);
}
}
}
}
/**
* @brief Render a row of tile
* @brief Render a row of floor tiles
* @param x dPiece coordinate
* @param y dPiece coordinate
* @param sx Back buffer coordinate
* @param sy Back buffer coordinate
* @param chunks tile width of row
* @param row current row being rendered
* @param blocks Number of rows
* @param chunks Tile in a row
*/
static void scrollrt_draw(int x, int y, int sx, int sy, int chunks, int row)
static void scrollrt_drawFloor(int x, int y, int sx, int sy, int blocks, int chunks)
{
assert(gpBuffer);
if (row & 1) {
x -= 1;
y += 1;
sx -= 32;
chunks += 1;
}
for (int j = 0; j < chunks; j++) {
if (y >= 0 && y < MAXDUNY && x >= 0 && x < MAXDUNX) {
level_piece_id = dPiece[x][y];
if (level_piece_id != 0) {
drawRow(x, y, sx, sy, 1);
for (int i = 0; i < (blocks << 1); i++) {
for (int j = 0; j < chunks ; j++) {
if (x >= 0 && x < MAXDUNX && y >= 0 && y < MAXDUNY) {
level_piece_id = dPiece[x][y];
if (level_piece_id != 0) {
if (!nSolidTable[level_piece_id])
drawFloor(x, y, sx, sy);
} else {
world_draw_black_tile(sx, sy);
}
} else {
world_draw_black_tile(sx, sy);
}
x++;
y--;
sx += 64;
}
// Return to start of row
x -= chunks;
y += chunks;
sx -= chunks * 64;
sy += 16;
// Jump to next row
if (i & 1) {
x++;
chunks--;
sx += 32;
} else {
world_draw_black_tile(sx, sy);
y++;
chunks++;
sx -= 32;
}
}
}
/**
* @brief Render a row of tile
* @param x dPiece coordinate
* @param y dPiece coordinate
* @param sx Back buffer coordinate
* @param sy Back buffer coordinate
* @param blocks Number of rows
* @param chunks Tile in a row
*/
static void scrollrt_draw(int x, int y, int sx, int sy, int blocks, int chunks)
{
assert(gpBuffer);
for (int i = 0; i < (blocks << 1); i++) {
for (int j = 0; j < chunks ; j++) {
if (x >= 0 && x < MAXDUNX && y >= 0 && y < MAXDUNY) {
level_piece_id = dPiece[x][y];
if (level_piece_id != 0) {
if (nSolidTable[level_piece_id]) {
// Avoid sprites poaking through walls
if (x + 2 >= 0 && x + 2 < MAXDUNX && y - 1 >= 0 && y - 1 < MAXDUNY && sx + 64 <= SCREEN_X + SCREEN_WIDTH)
scrollrt_draw_dungeon(x + 1, y - 1, sx + 64, sy);
drawCell(x, y, sx, sy);
} else {
drawCellFoliage(x, y, sx, sy);
}
scrollrt_draw_dungeon(x, y, sx, sy);
}
}
x++;
y--;
sx += 64;
}
// Return to start of row
x -= chunks;
y += chunks;
sx -= chunks * 64;
sy += 16;
// Jump to next row
if (i & 1) {
x++;
chunks--;
sx += 32;
} else {
y++;
chunks++;
sx -= 32;
}
x++;
y--;
sx += 64;
}
}
@ -893,14 +986,10 @@ static void DrawGame(int x, int y)
break;
}
for (i = 0; i < (blocks << 1); i++) {
scrollrt_draw(x, y, sx, sy, chunks, i);
sy += 16;
if (i & 1)
y++;
else
x++;
}
memset(dRendered, 0, sizeof(dRendered));
scrollrt_drawFloor(x, y, sx, sy, blocks, chunks);
scrollrt_draw(x, y, sx, sy, blocks, chunks);
gpBufStart = &gpBuffer[BUFFER_WIDTH * SCREEN_Y];
gpBufEnd = &gpBuffer[BUFFER_WIDTH * (SCREEN_HEIGHT + SCREEN_Y)];

Loading…
Cancel
Save