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]);
IncProgress();
MakeLightTable();
SetDungeonMicros();
LoadLvlGFX();
SetDungeonMicros();
IncProgress();
if (firstflag) {

38
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<OwnedCelSprite> pSpecialCels;
std::unique_ptr<MegaTile[]> pMegaTiles;
std::unique_ptr<byte[]> pDungeonCels;
std::array<TileProperties, MAXTILES> SOLData;
std::vector<OwnedCelSpriteWithFrameHeight> 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<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];
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()

5
Source/gendung.h

@ -7,6 +7,7 @@
#include <cstdint>
#include <memory>
#include <vector>
#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<byte[]> pDungeonCels;
* List tile properties
*/
extern DVL_API_FOR_TEST std::array<TileProperties, MAXTILES> SOLData;
extern std::vector<OwnedCelSpriteWithFrameHeight> 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];

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)
{
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);
}
/**

Loading…
Cancel
Save