Browse Source

Pre render Micro tiles

surface-to-cel
Anders Jenbo 4 years ago
parent
commit
bdfd3a24a5
  1. 2
      Source/diablo.cpp
  2. 38
      Source/gendung.cpp
  3. 5
      Source/gendung.h
  4. 37
      Source/scrollrt.cpp

2
Source/diablo.cpp

@ -2084,8 +2084,8 @@ void LoadGameLevel(bool firstflag, lvl_entry lvldir)
SetRndSeed(glSeedTbl[currlevel]); SetRndSeed(glSeedTbl[currlevel]);
IncProgress(); IncProgress();
MakeLightTable(); MakeLightTable();
SetDungeonMicros();
LoadLvlGFX(); LoadLvlGFX();
SetDungeonMicros();
IncProgress(); IncProgress();
if (firstflag) { if (firstflag) {

38
Source/gendung.cpp

@ -13,10 +13,13 @@
#include "drlg_l4.h" #include "drlg_l4.h"
#include "engine/load_file.hpp" #include "engine/load_file.hpp"
#include "engine/random.hpp" #include "engine/random.hpp"
#include "engine/render/dun_render.hpp"
#include "init.h" #include "init.h"
#include "lighting.h" #include "lighting.h"
#include "options.h" #include "options.h"
#include "town.h" #include "town.h"
#include "utils/sdl_compat.h"
#include "utils/surface_to_cel.hpp"
namespace devilution { namespace devilution {
@ -30,6 +33,7 @@ std::optional<OwnedCelSprite> pSpecialCels;
std::unique_ptr<MegaTile[]> pMegaTiles; std::unique_ptr<MegaTile[]> pMegaTiles;
std::unique_ptr<byte[]> pDungeonCels; std::unique_ptr<byte[]> pDungeonCels;
std::array<TileProperties, MAXTILES> SOLData; std::array<TileProperties, MAXTILES> SOLData;
std::vector<OwnedCelSpriteWithFrameHeight> MicroTiles;
Point dminPosition; Point dminPosition;
Point dmaxPosition; Point dmaxPosition;
dungeon_type leveltype; dungeon_type leveltype;
@ -43,7 +47,6 @@ int MicroTileLen;
char TransVal; char TransVal;
bool TransList[256]; bool TransList[256];
uint16_t dPiece[MAXDUNX][MAXDUNY]; uint16_t dPiece[MAXDUNX][MAXDUNY];
MICROS DPieceMicros[MAXTILES];
int8_t dTransVal[MAXDUNX][MAXDUNY]; int8_t dTransVal[MAXDUNX][MAXDUNY];
char dLight[MAXDUNX][MAXDUNY]; char dLight[MAXDUNX][MAXDUNY];
char dPreLight[MAXDUNX][MAXDUNY]; char dPreLight[MAXDUNX][MAXDUNY];
@ -478,7 +481,7 @@ void LoadLevelSOLData()
void SetDungeonMicros() void SetDungeonMicros()
{ {
MicroTileLen = 10; MicroTileLen = 10;
size_t blocks = 10; int blocks = 10;
if (leveltype == DTYPE_TOWN) { if (leveltype == DTYPE_TOWN) {
MicroTileLen = 16; MicroTileLen = 16;
@ -491,12 +494,37 @@ void SetDungeonMicros()
size_t tileCount; size_t tileCount;
std::unique_ptr<uint16_t[]> levelPieces = LoadMinData(tileCount); std::unique_ptr<uint16_t[]> levelPieces = LoadMinData(tileCount);
for (size_t i = 0; i < tileCount / blocks; i++) { LightTableIndex = 0;
arch_draw_type = 0;
cel_foliage_active = false;
cel_transparency_active = false;
MicroTiles.clear();
SDLSurfaceUniquePtr microTile = SDLWrap::CreateRGBSurfaceWithFormat(0, TILE_WIDTH, TILE_HEIGHT * blocks / 2, 8, SDL_PIXELFORMAT_INDEX8);
for (int i = 0; i < tileCount / blocks; i++) {
int frameStartY = 0;
Point targetBufferPosition { 0, 0 };
SDL_FillRect(microTile.get(), nullptr, 225);
uint16_t *pieces = &levelPieces[blocks * i]; uint16_t *pieces = &levelPieces[blocks * i];
for (size_t block = 0; block < blocks; block++) { for (int block = 0; block < blocks; block += 2) {
DPieceMicros[i].mt[block] = SDL_SwapLE16(pieces[blocks - 2 + (block & 1) - (block & 0xE)]); level_cel_block = SDL_SwapLE16(pieces[block]);
if (level_cel_block != 0) {
RenderTile(Surface { microTile.get() }, targetBufferPosition + Displacement { 0, TILE_HEIGHT - 1 });
if (frameStartY == 0)
frameStartY = targetBufferPosition.y;
}
level_cel_block = SDL_SwapLE16(pieces[block + 1]);
if (level_cel_block != 0) {
RenderTile(Surface { microTile.get() }, targetBufferPosition + Displacement { TILE_WIDTH / 2, TILE_HEIGHT - 1 });
if (frameStartY == 0)
frameStartY = targetBufferPosition.y;
}
targetBufferPosition.y += TILE_HEIGHT;
} }
Surface next { microTile.get() };
MicroTiles.emplace_back(SurfaceToCel(next.subregion(0, frameStartY, TILE_WIDTH, TILE_HEIGHT * blocks / 2 - frameStartY), 1, true, 225));
} }
pDungeonCels = nullptr;
} }
void DRLG_InitTrans() void DRLG_InitTrans()

5
Source/gendung.h

@ -7,6 +7,7 @@
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
#include <vector>
#include "engine.h" #include "engine.h"
#include "engine/cel_sprite.hpp" #include "engine/cel_sprite.hpp"
@ -15,6 +16,7 @@
#include "scrollrt.h" #include "scrollrt.h"
#include "utils/attributes.h" #include "utils/attributes.h"
#include "utils/enum_traits.h" #include "utils/enum_traits.h"
#include "utils/static_vector.hpp"
#include "utils/stdcompat/optional.hpp" #include "utils/stdcompat/optional.hpp"
namespace devilution { namespace devilution {
@ -155,6 +157,7 @@ extern std::unique_ptr<byte[]> pDungeonCels;
* List tile properties * List tile properties
*/ */
extern DVL_API_FOR_TEST std::array<TileProperties, MAXTILES> SOLData; extern DVL_API_FOR_TEST std::array<TileProperties, MAXTILES> SOLData;
extern std::vector<OwnedCelSpriteWithFrameHeight> MicroTiles;
/** Specifies the minimum X,Y-coordinates of the map. */ /** Specifies the minimum X,Y-coordinates of the map. */
extern Point dminPosition; extern Point dminPosition;
/** Specifies the maximum X,Y-coordinates of the map. */ /** Specifies the maximum X,Y-coordinates of the map. */
@ -177,8 +180,6 @@ extern char TransVal;
extern bool TransList[256]; extern bool TransList[256];
/** Contains the piece IDs of each tile on the map. */ /** Contains the piece IDs of each tile on the map. */
extern DVL_API_FOR_TEST uint16_t dPiece[MAXDUNX][MAXDUNY]; extern DVL_API_FOR_TEST uint16_t dPiece[MAXDUNX][MAXDUNY];
/** Map of micros that comprises a full tile for any given dungeon piece. */
extern MICROS DPieceMicros[MAXTILES];
/** Specifies the transparency at each coordinate of the map. */ /** Specifies the transparency at each coordinate of the map. */
extern DVL_API_FOR_TEST int8_t dTransVal[MAXDUNX][MAXDUNY]; extern DVL_API_FOR_TEST int8_t dTransVal[MAXDUNX][MAXDUNY];
extern char dLight[MAXDUNX][MAXDUNY]; extern char dLight[MAXDUNX][MAXDUNY];

37
Source/scrollrt.cpp

@ -654,24 +654,11 @@ static void DrawDungeon(const Surface & /*out*/, Point /*tilePosition*/, Point /
*/ */
void DrawCell(const Surface &out, Point tilePosition, Point targetBufferPosition) void DrawCell(const Surface &out, Point tilePosition, Point targetBufferPosition)
{ {
level_piece_id = dPiece[tilePosition.x][tilePosition.y]; int tileId = dPiece[tilePosition.x][tilePosition.y];
MICROS *pMap = &DPieceMicros[level_piece_id]; cel_transparency_active = TileHasAny(tileId, TileProperties::Transparent) && TransList[dTransVal[tilePosition.x][tilePosition.y]];
cel_transparency_active = TileHasAny(level_piece_id, TileProperties::Transparent) && TransList[dTransVal[tilePosition.x][tilePosition.y]]; bool foliage = !TileHasAny(tileId, TileProperties::Solid);
cel_foliage_active = !TileHasAny(level_piece_id, TileProperties::Solid); // TODO apply foliage and transparancy masks
for (int i = 0; i < (MicroTileLen / 2); i++) { CelClippedBlitLightTransTo(out, targetBufferPosition, MicroTiles[tileId].sprite, 0);
level_cel_block = pMap->mt[2 * i];
if (level_cel_block != 0) {
arch_draw_type = i == 0 ? 1 : 0;
RenderTile(out, targetBufferPosition);
}
level_cel_block = pMap->mt[2 * i + 1];
if (level_cel_block != 0) {
arch_draw_type = i == 0 ? 2 : 0;
RenderTile(out, targetBufferPosition + Displacement { TILE_WIDTH / 2, 0 });
}
targetBufferPosition.y -= TILE_HEIGHT;
}
cel_foliage_active = false;
} }
/** /**
@ -682,20 +669,10 @@ void DrawCell(const Surface &out, Point tilePosition, Point targetBufferPosition
*/ */
void DrawFloor(const Surface &out, Point tilePosition, Point targetBufferPosition) void DrawFloor(const Surface &out, Point tilePosition, Point targetBufferPosition)
{ {
cel_transparency_active = false;
LightTableIndex = dLight[tilePosition.x][tilePosition.y]; LightTableIndex = dLight[tilePosition.x][tilePosition.y];
arch_draw_type = 1; // Left
int pn = dPiece[tilePosition.x][tilePosition.y]; int pn = dPiece[tilePosition.x][tilePosition.y];
level_cel_block = DPieceMicros[pn].mt[0]; // TODO Clip/mask to floor tile
if (level_cel_block != 0) { CelClippedDrawLightTo(out, targetBufferPosition, MicroTiles[pn].sprite, 0);
RenderTile(out, targetBufferPosition);
}
arch_draw_type = 2; // Right
level_cel_block = DPieceMicros[pn].mt[1];
if (level_cel_block != 0) {
RenderTile(out, targetBufferPosition + Displacement { TILE_WIDTH / 2, 0 });
}
} }
/** /**

Loading…
Cancel
Save