From bdfd3a24a575355215a20797271dbac852475846 Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Mon, 20 Jun 2022 04:10:59 +0200 Subject: [PATCH] Pre render Micro tiles --- Source/diablo.cpp | 2 +- Source/gendung.cpp | 38 +++++++++++++++++++++++++++++++++----- Source/gendung.h | 5 +++-- Source/scrollrt.cpp | 37 +++++++------------------------------ 4 files changed, 44 insertions(+), 38 deletions(-) diff --git a/Source/diablo.cpp b/Source/diablo.cpp index ad22947fb..ab211cc84 100644 --- a/Source/diablo.cpp +++ b/Source/diablo.cpp @@ -2084,8 +2084,8 @@ void LoadGameLevel(bool firstflag, lvl_entry lvldir) SetRndSeed(glSeedTbl[currlevel]); IncProgress(); MakeLightTable(); - SetDungeonMicros(); LoadLvlGFX(); + SetDungeonMicros(); IncProgress(); if (firstflag) { diff --git a/Source/gendung.cpp b/Source/gendung.cpp index 5972d72ad..8a6c85682 100644 --- a/Source/gendung.cpp +++ b/Source/gendung.cpp @@ -13,10 +13,13 @@ #include "drlg_l4.h" #include "engine/load_file.hpp" #include "engine/random.hpp" +#include "engine/render/dun_render.hpp" #include "init.h" #include "lighting.h" #include "options.h" #include "town.h" +#include "utils/sdl_compat.h" +#include "utils/surface_to_cel.hpp" namespace devilution { @@ -30,6 +33,7 @@ std::optional pSpecialCels; std::unique_ptr pMegaTiles; std::unique_ptr pDungeonCels; std::array SOLData; +std::vector MicroTiles; Point dminPosition; Point dmaxPosition; dungeon_type leveltype; @@ -43,7 +47,6 @@ int MicroTileLen; char TransVal; bool TransList[256]; uint16_t dPiece[MAXDUNX][MAXDUNY]; -MICROS DPieceMicros[MAXTILES]; int8_t dTransVal[MAXDUNX][MAXDUNY]; char dLight[MAXDUNX][MAXDUNY]; char dPreLight[MAXDUNX][MAXDUNY]; @@ -478,7 +481,7 @@ void LoadLevelSOLData() void SetDungeonMicros() { MicroTileLen = 10; - size_t blocks = 10; + int blocks = 10; if (leveltype == DTYPE_TOWN) { MicroTileLen = 16; @@ -491,12 +494,37 @@ void SetDungeonMicros() size_t tileCount; std::unique_ptr 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]; - for (size_t block = 0; block < blocks; block++) { - DPieceMicros[i].mt[block] = SDL_SwapLE16(pieces[blocks - 2 + (block & 1) - (block & 0xE)]); + for (int block = 0; block < blocks; block += 2) { + 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() diff --git a/Source/gendung.h b/Source/gendung.h index 81a3ff448..531b3ddce 100644 --- a/Source/gendung.h +++ b/Source/gendung.h @@ -7,6 +7,7 @@ #include #include +#include #include "engine.h" #include "engine/cel_sprite.hpp" @@ -15,6 +16,7 @@ #include "scrollrt.h" #include "utils/attributes.h" #include "utils/enum_traits.h" +#include "utils/static_vector.hpp" #include "utils/stdcompat/optional.hpp" namespace devilution { @@ -155,6 +157,7 @@ extern std::unique_ptr pDungeonCels; * List tile properties */ extern DVL_API_FOR_TEST std::array SOLData; +extern std::vector MicroTiles; /** Specifies the minimum X,Y-coordinates of the map. */ extern Point dminPosition; /** Specifies the maximum X,Y-coordinates of the map. */ @@ -177,8 +180,6 @@ extern char TransVal; extern bool TransList[256]; /** Contains the piece IDs of each tile on the map. */ 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. */ extern DVL_API_FOR_TEST int8_t dTransVal[MAXDUNX][MAXDUNY]; extern char dLight[MAXDUNX][MAXDUNY]; diff --git a/Source/scrollrt.cpp b/Source/scrollrt.cpp index 3ce1c6acc..fa92376f7 100644 --- a/Source/scrollrt.cpp +++ b/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) { - level_piece_id = dPiece[tilePosition.x][tilePosition.y]; - MICROS *pMap = &DPieceMicros[level_piece_id]; - cel_transparency_active = TileHasAny(level_piece_id, TileProperties::Transparent) && TransList[dTransVal[tilePosition.x][tilePosition.y]]; - cel_foliage_active = !TileHasAny(level_piece_id, TileProperties::Solid); - for (int i = 0; i < (MicroTileLen / 2); i++) { - 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; + int tileId = dPiece[tilePosition.x][tilePosition.y]; + cel_transparency_active = TileHasAny(tileId, TileProperties::Transparent) && TransList[dTransVal[tilePosition.x][tilePosition.y]]; + bool foliage = !TileHasAny(tileId, TileProperties::Solid); + // TODO apply foliage and transparancy masks + CelClippedBlitLightTransTo(out, targetBufferPosition, MicroTiles[tileId].sprite, 0); } /** @@ -682,20 +669,10 @@ void DrawCell(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]; - - arch_draw_type = 1; // Left int pn = dPiece[tilePosition.x][tilePosition.y]; - level_cel_block = DPieceMicros[pn].mt[0]; - if (level_cel_block != 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 }); - } + // TODO Clip/mask to floor tile + CelClippedDrawLightTo(out, targetBufferPosition, MicroTiles[pn].sprite, 0); } /**