2010-11-20 10:37:14 +00:00
|
|
|
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
|
|
|
|
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
2020-09-26 19:41:58 +00:00
|
|
|
#include <engine/demo.h>
|
2010-05-29 07:25:38 +00:00
|
|
|
#include <engine/graphics.h>
|
2010-09-07 00:06:11 +00:00
|
|
|
#include <engine/keys.h>
|
|
|
|
#include <engine/serverbrowser.h>
|
2010-05-29 07:25:38 +00:00
|
|
|
#include <engine/shared/config.h>
|
2010-09-07 00:06:11 +00:00
|
|
|
#include <engine/storage.h>
|
2009-10-27 14:38:53 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
#include <game/client/gameclient.h>
|
2010-05-29 07:25:38 +00:00
|
|
|
#include <game/client/render.h>
|
2022-06-17 17:26:59 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
#include <game/layers.h>
|
2022-06-17 17:26:59 +00:00
|
|
|
#include <game/mapitems.h>
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
#include <game/client/components/camera.h>
|
|
|
|
#include <game/client/components/mapimages.h>
|
2022-06-23 17:59:38 +00:00
|
|
|
#include <game/localization.h>
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
#include "maplayers.h"
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2022-05-18 16:00:05 +00:00
|
|
|
#include <chrono>
|
|
|
|
|
|
|
|
using namespace std::chrono_literals;
|
|
|
|
|
2020-09-18 16:45:42 +00:00
|
|
|
CMapLayers::CMapLayers(int t, bool OnlineOnly)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Type = t;
|
|
|
|
m_pLayers = 0;
|
2011-12-04 13:04:12 +00:00
|
|
|
m_CurrentLocalTick = 0;
|
|
|
|
m_LastLocalTick = 0;
|
|
|
|
m_EnvelopeUpdate = false;
|
2020-09-18 16:45:42 +00:00
|
|
|
m_OnlineOnly = OnlineOnly;
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CMapLayers::OnInit()
|
|
|
|
{
|
|
|
|
m_pLayers = Layers();
|
2021-07-12 09:43:56 +00:00
|
|
|
m_pImages = &m_pClient->m_MapImages;
|
2010-05-29 07:25:38 +00:00
|
|
|
}
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2020-09-18 16:45:42 +00:00
|
|
|
CCamera *CMapLayers::GetCurCamera()
|
|
|
|
{
|
2021-07-12 09:43:56 +00:00
|
|
|
return &m_pClient->m_Camera;
|
2020-09-18 16:45:42 +00:00
|
|
|
}
|
|
|
|
|
2011-12-04 13:04:12 +00:00
|
|
|
void CMapLayers::EnvelopeUpdate()
|
|
|
|
{
|
|
|
|
if(Client()->State() == IClient::STATE_DEMOPLAYBACK)
|
|
|
|
{
|
|
|
|
const IDemoPlayer::CInfo *pInfo = DemoPlayer()->BaseInfo();
|
|
|
|
m_CurrentLocalTick = pInfo->m_CurrentTick;
|
|
|
|
m_LastLocalTick = pInfo->m_CurrentTick;
|
|
|
|
m_EnvelopeUpdate = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-01 04:42:36 +00:00
|
|
|
void CMapLayers::EnvelopeEval(int TimeOffsetMillis, int Env, ColorRGBA &Channels, void *pUser)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CMapLayers *pThis = (CMapLayers *)pUser;
|
2022-07-01 04:42:36 +00:00
|
|
|
Channels = ColorRGBA();
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2010-06-09 16:24:38 +00:00
|
|
|
CEnvPoint *pPoints = 0;
|
2008-08-27 15:48:50 +00:00
|
|
|
|
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
int Start, Num;
|
|
|
|
pThis->m_pLayers->Map()->GetType(MAPITEMTYPE_ENVPOINTS, &Start, &Num);
|
|
|
|
if(Num)
|
|
|
|
pPoints = (CEnvPoint *)pThis->m_pLayers->Map()->GetItem(Start, 0, 0);
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
int Start, Num;
|
|
|
|
pThis->m_pLayers->Map()->GetType(MAPITEMTYPE_ENVELOPE, &Start, &Num);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(Env >= Num)
|
2008-08-27 15:48:50 +00:00
|
|
|
return;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
CMapItemEnvelope *pItem = (CMapItemEnvelope *)pThis->m_pLayers->Map()->GetItem(Start + Env, 0, 0);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2022-05-22 14:04:50 +00:00
|
|
|
const auto TickToNanoSeconds = std::chrono::nanoseconds(1s) / (int64_t)pThis->Client()->GameTickSpeed();
|
2020-10-04 00:30:36 +00:00
|
|
|
|
2022-05-22 14:04:50 +00:00
|
|
|
static std::chrono::nanoseconds s_Time{0};
|
2022-06-13 16:07:29 +00:00
|
|
|
static auto s_LastLocalTime = time_get_nanoseconds();
|
2010-10-19 11:37:36 +00:00
|
|
|
if(pThis->Client()->State() == IClient::STATE_DEMOPLAYBACK)
|
|
|
|
{
|
|
|
|
const IDemoPlayer::CInfo *pInfo = pThis->DemoPlayer()->BaseInfo();
|
2015-07-09 00:08:14 +00:00
|
|
|
|
2011-12-04 13:04:12 +00:00
|
|
|
if(!pInfo->m_Paused || pThis->m_EnvelopeUpdate)
|
2011-12-01 17:36:51 +00:00
|
|
|
{
|
2011-12-04 13:04:12 +00:00
|
|
|
if(pThis->m_CurrentLocalTick != pInfo->m_CurrentTick)
|
2011-12-01 17:36:51 +00:00
|
|
|
{
|
2011-12-04 13:04:12 +00:00
|
|
|
pThis->m_LastLocalTick = pThis->m_CurrentLocalTick;
|
|
|
|
pThis->m_CurrentLocalTick = pInfo->m_CurrentTick;
|
2011-12-01 17:36:51 +00:00
|
|
|
}
|
2019-10-14 11:11:29 +00:00
|
|
|
if(pItem->m_Version < 2 || pItem->m_Synchronized)
|
|
|
|
{
|
Fix null pointer access in maplayers when the snapshot has no game info
```
src/game/client/components/maplayers.cpp:98:112: runtime error: member access within null pointer of type 'const struct CNetObj_GameInfo'
#0 0x55d84eea9e1e in CMapLayers::EnvelopeEval(int, int, ColorRGBA&, void*) src/game/client/components/maplayers.cpp:98
#1 0x55d84f518082 in CRenderTools::ForceRenderQuads(CQuad*, int, int, void (*)(int, int, ColorRGBA&, void*), void*, float) src/game/client/render_map.cpp:112
#2 0x55d84f517ac7 in CRenderTools::RenderQuads(CQuad*, int, int, void (*)(int, int, ColorRGBA&, void*), void*) src/game/client/render_map.cpp:98
#3 0x55d84eee10b0 in CMapLayers::OnRender() src/game/client/components/maplayers.cpp:1839
#4 0x55d84f34b915 in CGameClient::OnRender() src/game/client/gameclient.cpp:640
#5 0x55d84e8d44c2 in CClient::Render() src/engine/client/client.cpp:1222
#6 0x55d84e92d1a0 in CClient::Run() src/engine/client/client.cpp:3370
#7 0x55d84e99964f in main src/engine/client/client.cpp:4761
```
2022-07-21 13:28:31 +00:00
|
|
|
if(pThis->m_pClient->m_Snap.m_pGameInfoObj)
|
|
|
|
{
|
|
|
|
// get the lerp of the current tick and prev
|
|
|
|
int MinTick = pThis->Client()->PrevGameTick(g_Config.m_ClDummy) - pThis->m_pClient->m_Snap.m_pGameInfoObj->m_RoundStartTick;
|
|
|
|
int CurTick = pThis->Client()->GameTick(g_Config.m_ClDummy) - pThis->m_pClient->m_Snap.m_pGameInfoObj->m_RoundStartTick;
|
|
|
|
s_Time = std::chrono::nanoseconds((int64_t)(mix<double>(
|
|
|
|
0,
|
|
|
|
(CurTick - MinTick),
|
|
|
|
(double)pThis->Client()->IntraGameTick(g_Config.m_ClDummy)) *
|
|
|
|
TickToNanoSeconds.count())) +
|
|
|
|
MinTick * TickToNanoSeconds;
|
|
|
|
}
|
2019-10-14 11:11:29 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-10-04 00:30:36 +00:00
|
|
|
int MinTick = pThis->m_LastLocalTick;
|
2022-05-22 14:04:50 +00:00
|
|
|
s_Time = std::chrono::nanoseconds((int64_t)(mix<double>(0,
|
|
|
|
pThis->m_CurrentLocalTick - MinTick,
|
|
|
|
(double)pThis->Client()->IntraGameTick(g_Config.m_ClDummy)) *
|
|
|
|
TickToNanoSeconds.count())) +
|
|
|
|
MinTick * TickToNanoSeconds;
|
2019-10-14 11:11:29 +00:00
|
|
|
}
|
2011-12-01 17:36:51 +00:00
|
|
|
}
|
2022-07-01 04:42:36 +00:00
|
|
|
CRenderTools::RenderEvalEnvelope(pPoints + pItem->m_StartPoint, pItem->m_NumPoints, 4, s_Time + (int64_t)TimeOffsetMillis * std::chrono::nanoseconds(1ms), Channels);
|
2010-10-19 11:37:36 +00:00
|
|
|
}
|
2019-10-14 11:11:29 +00:00
|
|
|
else
|
2011-04-17 20:07:59 +00:00
|
|
|
{
|
2020-09-18 16:45:42 +00:00
|
|
|
if(pThis->m_OnlineOnly && (pItem->m_Version < 2 || pItem->m_Synchronized))
|
2011-12-04 13:34:27 +00:00
|
|
|
{
|
2020-10-03 18:52:40 +00:00
|
|
|
if(pThis->m_pClient->m_Snap.m_pGameInfoObj) // && !(pThis->m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_PAUSED))
|
2012-01-09 23:49:31 +00:00
|
|
|
{
|
2020-10-04 00:30:36 +00:00
|
|
|
// get the lerp of the current tick and prev
|
2020-12-29 02:08:28 +00:00
|
|
|
int MinTick = pThis->Client()->PrevGameTick(g_Config.m_ClDummy) - pThis->m_pClient->m_Snap.m_pGameInfoObj->m_RoundStartTick;
|
|
|
|
int CurTick = pThis->Client()->GameTick(g_Config.m_ClDummy) - pThis->m_pClient->m_Snap.m_pGameInfoObj->m_RoundStartTick;
|
2022-05-22 14:04:50 +00:00
|
|
|
s_Time = std::chrono::nanoseconds((int64_t)(mix<double>(
|
|
|
|
0,
|
|
|
|
(CurTick - MinTick),
|
|
|
|
(double)pThis->Client()->IntraGameTick(g_Config.m_ClDummy)) *
|
|
|
|
TickToNanoSeconds.count())) +
|
|
|
|
MinTick * TickToNanoSeconds;
|
2012-01-09 23:49:31 +00:00
|
|
|
}
|
2011-12-04 13:34:27 +00:00
|
|
|
}
|
2020-10-03 18:52:40 +00:00
|
|
|
else
|
2020-09-18 16:45:42 +00:00
|
|
|
{
|
2022-06-13 16:07:29 +00:00
|
|
|
auto CurTime = time_get_nanoseconds();
|
2020-10-04 00:30:36 +00:00
|
|
|
s_Time += CurTime - s_LastLocalTime;
|
|
|
|
s_LastLocalTime = CurTime;
|
2020-09-18 16:45:42 +00:00
|
|
|
}
|
2022-07-01 04:42:36 +00:00
|
|
|
CRenderTools::RenderEvalEnvelope(pPoints + pItem->m_StartPoint, pItem->m_NumPoints, 4, s_Time + std::chrono::nanoseconds(std::chrono::milliseconds(TimeOffsetMillis)), Channels);
|
2011-04-17 20:07:59 +00:00
|
|
|
}
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
void FillTmpTileSpeedup(SGraphicTile *pTmpTile, SGraphicTileTexureCoords *pTmpTex, bool As3DTextureCoord, unsigned char Flags, unsigned char Index, int x, int y, int Scale, CMapItemGroup *pGroup, short AngleRotate)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
|
|
|
if(pTmpTex)
|
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
unsigned char x0 = 0;
|
|
|
|
unsigned char y0 = 0;
|
2020-08-29 10:10:38 +00:00
|
|
|
unsigned char x1 = x0 + 1;
|
|
|
|
unsigned char y1 = y0;
|
|
|
|
unsigned char x2 = x0 + 1;
|
|
|
|
unsigned char y2 = y0 + 1;
|
|
|
|
unsigned char x3 = x0;
|
|
|
|
unsigned char y3 = y0 + 1;
|
|
|
|
|
|
|
|
pTmpTex->m_TexCoordTopLeft.x = x0;
|
|
|
|
pTmpTex->m_TexCoordTopLeft.y = y0;
|
|
|
|
pTmpTex->m_TexCoordBottomLeft.x = x3;
|
|
|
|
pTmpTex->m_TexCoordBottomLeft.y = y3;
|
|
|
|
pTmpTex->m_TexCoordTopRight.x = x1;
|
|
|
|
pTmpTex->m_TexCoordTopRight.y = y1;
|
|
|
|
pTmpTex->m_TexCoordBottomRight.x = x2;
|
|
|
|
pTmpTex->m_TexCoordBottomRight.y = y2;
|
|
|
|
|
|
|
|
if(As3DTextureCoord)
|
|
|
|
{
|
|
|
|
pTmpTex->m_TexCoordTopLeft.z = ((float)Index + 0.5f) / 256.f;
|
|
|
|
pTmpTex->m_TexCoordBottomLeft.z = ((float)Index + 0.5f) / 256.f;
|
|
|
|
pTmpTex->m_TexCoordTopRight.z = ((float)Index + 0.5f) / 256.f;
|
|
|
|
pTmpTex->m_TexCoordBottomRight.z = ((float)Index + 0.5f) / 256.f;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pTmpTex->m_TexCoordTopLeft.z = Index;
|
|
|
|
pTmpTex->m_TexCoordBottomLeft.z = Index;
|
|
|
|
pTmpTex->m_TexCoordTopRight.z = Index;
|
|
|
|
pTmpTex->m_TexCoordBottomRight.z = Index;
|
|
|
|
}
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-12 18:22:18 +00:00
|
|
|
//same as in rotate from Graphics()
|
2022-06-10 09:30:57 +00:00
|
|
|
float Angle = (float)AngleRotate * (pi / 180.0f);
|
2017-09-12 18:22:18 +00:00
|
|
|
float c = cosf(Angle);
|
|
|
|
float s = sinf(Angle);
|
|
|
|
float xR, yR;
|
|
|
|
int i;
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-12 18:22:18 +00:00
|
|
|
int ScaleSmaller = 2;
|
2020-09-26 19:41:58 +00:00
|
|
|
pTmpTile->m_TopLeft.x = x * Scale + ScaleSmaller;
|
|
|
|
pTmpTile->m_TopLeft.y = y * Scale + ScaleSmaller;
|
|
|
|
pTmpTile->m_BottomLeft.x = x * Scale + ScaleSmaller;
|
|
|
|
pTmpTile->m_BottomLeft.y = y * Scale + Scale - ScaleSmaller;
|
|
|
|
pTmpTile->m_TopRight.x = x * Scale + Scale - ScaleSmaller;
|
|
|
|
pTmpTile->m_TopRight.y = y * Scale + ScaleSmaller;
|
|
|
|
pTmpTile->m_BottomRight.x = x * Scale + Scale - ScaleSmaller;
|
|
|
|
pTmpTile->m_BottomRight.y = y * Scale + Scale - ScaleSmaller;
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
float *pTmpTileVertices = (float *)pTmpTile;
|
2017-09-12 18:22:18 +00:00
|
|
|
|
|
|
|
vec2 Center;
|
2020-09-26 19:41:58 +00:00
|
|
|
Center.x = pTmpTile->m_TopLeft.x + (Scale - ScaleSmaller) / 2.f;
|
|
|
|
Center.y = pTmpTile->m_TopLeft.y + (Scale - ScaleSmaller) / 2.f;
|
2018-03-13 20:57:46 +00:00
|
|
|
|
|
|
|
for(i = 0; i < 4; i++)
|
2017-09-12 18:22:18 +00:00
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
xR = pTmpTileVertices[i * 2] - Center.x;
|
|
|
|
yR = pTmpTileVertices[i * 2 + 1] - Center.y;
|
|
|
|
pTmpTileVertices[i * 2] = xR * c - yR * s + Center.x;
|
|
|
|
pTmpTileVertices[i * 2 + 1] = xR * s + yR * c + Center.y;
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
void FillTmpTile(SGraphicTile *pTmpTile, SGraphicTileTexureCoords *pTmpTex, bool As3DTextureCoord, unsigned char Flags, unsigned char Index, int x, int y, int Scale, CMapItemGroup *pGroup)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
|
|
|
if(pTmpTex)
|
|
|
|
{
|
2020-08-29 10:10:38 +00:00
|
|
|
unsigned char x0 = 0;
|
|
|
|
unsigned char y0 = 0;
|
|
|
|
unsigned char x1 = x0 + 1;
|
|
|
|
unsigned char y1 = y0;
|
|
|
|
unsigned char x2 = x0 + 1;
|
|
|
|
unsigned char y2 = y0 + 1;
|
|
|
|
unsigned char x3 = x0;
|
|
|
|
unsigned char y3 = y0 + 1;
|
2017-09-12 18:22:18 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(Flags & TILEFLAG_VFLIP)
|
2017-09-12 18:22:18 +00:00
|
|
|
{
|
|
|
|
x0 = x2;
|
|
|
|
x1 = x3;
|
|
|
|
x2 = x3;
|
|
|
|
x3 = x0;
|
|
|
|
}
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(Flags & TILEFLAG_HFLIP)
|
2017-09-12 18:22:18 +00:00
|
|
|
{
|
|
|
|
y0 = y3;
|
|
|
|
y2 = y1;
|
|
|
|
y3 = y1;
|
|
|
|
y1 = y0;
|
|
|
|
}
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(Flags & TILEFLAG_ROTATE)
|
2017-09-12 18:22:18 +00:00
|
|
|
{
|
|
|
|
unsigned char Tmp = x0;
|
|
|
|
x0 = x3;
|
|
|
|
x3 = x2;
|
|
|
|
x2 = x1;
|
|
|
|
x1 = Tmp;
|
|
|
|
Tmp = y0;
|
|
|
|
y0 = y3;
|
|
|
|
y3 = y2;
|
|
|
|
y2 = y1;
|
|
|
|
y1 = Tmp;
|
2020-08-22 06:09:10 +00:00
|
|
|
}
|
2020-08-26 18:01:32 +00:00
|
|
|
|
2020-08-29 10:10:38 +00:00
|
|
|
pTmpTex->m_TexCoordTopLeft.x = x0;
|
|
|
|
pTmpTex->m_TexCoordTopLeft.y = y0;
|
|
|
|
pTmpTex->m_TexCoordBottomLeft.x = x3;
|
|
|
|
pTmpTex->m_TexCoordBottomLeft.y = y3;
|
|
|
|
pTmpTex->m_TexCoordTopRight.x = x1;
|
|
|
|
pTmpTex->m_TexCoordTopRight.y = y1;
|
|
|
|
pTmpTex->m_TexCoordBottomRight.x = x2;
|
|
|
|
pTmpTex->m_TexCoordBottomRight.y = y2;
|
|
|
|
|
|
|
|
if(As3DTextureCoord)
|
|
|
|
{
|
|
|
|
pTmpTex->m_TexCoordTopLeft.z = ((float)Index + 0.5f) / 256.f;
|
|
|
|
pTmpTex->m_TexCoordBottomLeft.z = ((float)Index + 0.5f) / 256.f;
|
|
|
|
pTmpTex->m_TexCoordTopRight.z = ((float)Index + 0.5f) / 256.f;
|
|
|
|
pTmpTex->m_TexCoordBottomRight.z = ((float)Index + 0.5f) / 256.f;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pTmpTex->m_TexCoordTopLeft.z = Index;
|
|
|
|
pTmpTex->m_TexCoordBottomLeft.z = Index;
|
|
|
|
pTmpTex->m_TexCoordTopRight.z = Index;
|
|
|
|
pTmpTex->m_TexCoordBottomRight.z = Index;
|
|
|
|
}
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
pTmpTile->m_TopLeft.x = x * Scale;
|
|
|
|
pTmpTile->m_TopLeft.y = y * Scale;
|
|
|
|
pTmpTile->m_BottomLeft.x = x * Scale;
|
|
|
|
pTmpTile->m_BottomLeft.y = y * Scale + Scale;
|
|
|
|
pTmpTile->m_TopRight.x = x * Scale + Scale;
|
|
|
|
pTmpTile->m_TopRight.y = y * Scale;
|
|
|
|
pTmpTile->m_BottomRight.x = x * Scale + Scale;
|
|
|
|
pTmpTile->m_BottomRight.y = y * Scale + Scale;
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
|
|
|
|
2019-03-26 18:15:24 +00:00
|
|
|
bool CMapLayers::STileLayerVisuals::Init(unsigned int Width, unsigned int Height)
|
2017-09-27 10:20:23 +00:00
|
|
|
{
|
|
|
|
m_Width = Width;
|
|
|
|
m_Height = Height;
|
2022-05-25 15:55:21 +00:00
|
|
|
if(Width == 0 || Height == 0)
|
2018-03-13 20:57:46 +00:00
|
|
|
return false;
|
2022-05-25 15:55:21 +00:00
|
|
|
if constexpr(sizeof(unsigned int) >= sizeof(ptrdiff_t))
|
|
|
|
if(Width >= std::numeric_limits<std::ptrdiff_t>::max() || Height >= std::numeric_limits<std::ptrdiff_t>::max())
|
|
|
|
return false;
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2022-03-24 18:30:26 +00:00
|
|
|
m_pTilesOfLayer = new CMapLayers::STileLayerVisuals::STileVisual[Height * Width];
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-27 12:52:06 +00:00
|
|
|
if(Width > 2)
|
|
|
|
{
|
2022-03-24 18:30:26 +00:00
|
|
|
m_pBorderTop = new CMapLayers::STileLayerVisuals::STileVisual[Width - 2];
|
|
|
|
m_pBorderBottom = new CMapLayers::STileLayerVisuals::STileVisual[Width - 2];
|
2017-09-27 10:20:23 +00:00
|
|
|
}
|
2017-09-27 12:52:06 +00:00
|
|
|
if(Height > 2)
|
|
|
|
{
|
2022-03-24 18:30:26 +00:00
|
|
|
m_pBorderLeft = new CMapLayers::STileLayerVisuals::STileVisual[Height - 2];
|
|
|
|
m_pBorderRight = new CMapLayers::STileLayerVisuals::STileVisual[Height - 2];
|
2017-09-27 10:20:23 +00:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-03-26 18:15:24 +00:00
|
|
|
CMapLayers::STileLayerVisuals::~STileLayerVisuals()
|
2017-09-27 10:20:23 +00:00
|
|
|
{
|
2022-03-24 18:30:26 +00:00
|
|
|
delete[] m_pTilesOfLayer;
|
|
|
|
delete[] m_pBorderTop;
|
|
|
|
delete[] m_pBorderBottom;
|
|
|
|
delete[] m_pBorderLeft;
|
|
|
|
delete[] m_pBorderRight;
|
|
|
|
|
|
|
|
m_pTilesOfLayer = NULL;
|
|
|
|
m_pBorderTop = NULL;
|
|
|
|
m_pBorderBottom = NULL;
|
|
|
|
m_pBorderLeft = NULL;
|
|
|
|
m_pBorderRight = NULL;
|
2017-09-27 10:20:23 +00:00
|
|
|
}
|
|
|
|
|
2022-06-15 17:34:41 +00:00
|
|
|
bool AddTile(std::vector<SGraphicTile> &vTmpTiles, std::vector<SGraphicTileTexureCoords> &vTmpTileTexCoords, bool As3DTextureCoord, unsigned char Index, unsigned char Flags, int x, int y, CMapItemGroup *pGroup, bool DoTextureCoords, bool FillSpeedup = false, int AngleRotate = -1)
|
2017-09-27 10:20:23 +00:00
|
|
|
{
|
|
|
|
if(Index)
|
|
|
|
{
|
2022-06-15 17:34:41 +00:00
|
|
|
vTmpTiles.emplace_back();
|
|
|
|
SGraphicTile &Tile = vTmpTiles.back();
|
2020-09-26 19:41:58 +00:00
|
|
|
SGraphicTileTexureCoords *pTileTex = NULL;
|
2017-09-27 10:20:23 +00:00
|
|
|
if(DoTextureCoords)
|
|
|
|
{
|
2022-06-15 17:34:41 +00:00
|
|
|
vTmpTileTexCoords.emplace_back();
|
|
|
|
SGraphicTileTexureCoords &TileTex = vTmpTileTexCoords.back();
|
2017-09-27 10:20:23 +00:00
|
|
|
pTileTex = &TileTex;
|
|
|
|
}
|
2018-03-13 20:57:46 +00:00
|
|
|
if(FillSpeedup)
|
2020-08-29 10:10:38 +00:00
|
|
|
FillTmpTileSpeedup(&Tile, pTileTex, As3DTextureCoord, Flags, 0, x, y, 32.f, pGroup, AngleRotate);
|
2018-03-13 20:57:46 +00:00
|
|
|
else
|
2020-08-29 10:10:38 +00:00
|
|
|
FillTmpTile(&Tile, pTileTex, As3DTextureCoord, Flags, Index, x, y, 32.f, pGroup);
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-27 10:20:23 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-03-13 20:57:46 +00:00
|
|
|
struct STmpQuadVertexTextured
|
|
|
|
{
|
|
|
|
float m_X, m_Y, m_CenterX, m_CenterY;
|
2020-08-26 18:01:32 +00:00
|
|
|
unsigned char m_R, m_G, m_B, m_A;
|
2020-08-29 10:10:38 +00:00
|
|
|
float m_U, m_V;
|
2018-03-13 20:57:46 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct STmpQuadVertex
|
|
|
|
{
|
|
|
|
float m_X, m_Y, m_CenterX, m_CenterY;
|
|
|
|
unsigned char m_R, m_G, m_B, m_A;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct STmpQuad
|
|
|
|
{
|
|
|
|
STmpQuadVertex m_aVertices[4];
|
|
|
|
};
|
|
|
|
|
|
|
|
struct STmpQuadTextured
|
|
|
|
{
|
|
|
|
STmpQuadVertexTextured m_aVertices[4];
|
|
|
|
};
|
|
|
|
|
|
|
|
void mem_copy_special(void *pDest, void *pSource, size_t Size, size_t Count, size_t Steps)
|
|
|
|
{
|
|
|
|
size_t CurStep = 0;
|
|
|
|
for(size_t i = 0; i < Count; ++i)
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
mem_copy(((char *)pDest) + CurStep + i * Size, ((char *)pSource) + i * Size, Size);
|
2018-03-13 20:57:46 +00:00
|
|
|
CurStep += Steps;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-30 21:57:03 +00:00
|
|
|
CMapLayers::~CMapLayers()
|
|
|
|
{
|
|
|
|
//clear everything and destroy all buffers
|
2022-06-11 19:38:18 +00:00
|
|
|
if(!m_vpTileLayerVisuals.empty())
|
2020-09-30 21:57:03 +00:00
|
|
|
{
|
2022-06-11 19:38:18 +00:00
|
|
|
int s = m_vpTileLayerVisuals.size();
|
2020-09-30 21:57:03 +00:00
|
|
|
for(int i = 0; i < s; ++i)
|
|
|
|
{
|
2022-06-11 19:38:18 +00:00
|
|
|
delete m_vpTileLayerVisuals[i];
|
2020-09-30 21:57:03 +00:00
|
|
|
}
|
|
|
|
}
|
2022-06-11 19:38:18 +00:00
|
|
|
if(!m_vpQuadLayerVisuals.empty())
|
2020-09-30 21:57:03 +00:00
|
|
|
{
|
2022-06-11 19:38:18 +00:00
|
|
|
int s = m_vpQuadLayerVisuals.size();
|
2020-09-30 21:57:03 +00:00
|
|
|
for(int i = 0; i < s; ++i)
|
|
|
|
{
|
2022-06-11 19:38:18 +00:00
|
|
|
delete m_vpQuadLayerVisuals[i];
|
2020-09-30 21:57:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-12 18:22:18 +00:00
|
|
|
void CMapLayers::OnMapLoad()
|
|
|
|
{
|
2020-08-29 10:10:38 +00:00
|
|
|
if(!Graphics()->IsTileBufferingEnabled() && !Graphics()->IsQuadBufferingEnabled())
|
2018-03-13 20:57:46 +00:00
|
|
|
return;
|
2022-06-23 17:59:38 +00:00
|
|
|
|
|
|
|
const char *pConnectCaption = GameClient()->DemoPlayer()->IsPlaying() ? Localize("Preparing demo playback") : Localize("Connected");
|
|
|
|
const char *pLoadMapContent = Localize("Uploading map data to GPU");
|
|
|
|
|
|
|
|
auto CurTime = time_get_nanoseconds();
|
|
|
|
auto &&RenderLoading = [&]() {
|
|
|
|
if(CanRenderMenuBackground())
|
|
|
|
GameClient()->m_Menus.RenderLoading(pConnectCaption, pLoadMapContent, 0, false);
|
|
|
|
else if(time_get_nanoseconds() - CurTime > 500ms)
|
|
|
|
GameClient()->m_Menus.RenderLoading(pConnectCaption, pLoadMapContent, 0, false, false);
|
|
|
|
};
|
|
|
|
|
2017-09-12 18:22:18 +00:00
|
|
|
//clear everything and destroy all buffers
|
2022-06-11 19:38:18 +00:00
|
|
|
if(!m_vpTileLayerVisuals.empty())
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2022-06-11 19:38:18 +00:00
|
|
|
int s = m_vpTileLayerVisuals.size();
|
2017-09-13 18:33:58 +00:00
|
|
|
for(int i = 0; i < s; ++i)
|
|
|
|
{
|
2022-06-11 19:38:18 +00:00
|
|
|
Graphics()->DeleteBufferContainer(m_vpTileLayerVisuals[i]->m_BufferContainerIndex, true);
|
|
|
|
delete m_vpTileLayerVisuals[i];
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2022-06-11 19:38:18 +00:00
|
|
|
m_vpTileLayerVisuals.clear();
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2022-06-11 19:38:18 +00:00
|
|
|
if(!m_vpQuadLayerVisuals.empty())
|
2018-03-13 20:57:46 +00:00
|
|
|
{
|
2022-06-11 19:38:18 +00:00
|
|
|
int s = m_vpQuadLayerVisuals.size();
|
2018-03-13 20:57:46 +00:00
|
|
|
for(int i = 0; i < s; ++i)
|
|
|
|
{
|
2022-06-11 19:38:18 +00:00
|
|
|
Graphics()->DeleteBufferContainer(m_vpQuadLayerVisuals[i]->m_BufferContainerIndex, true);
|
|
|
|
delete m_vpQuadLayerVisuals[i];
|
2018-03-13 20:57:46 +00:00
|
|
|
}
|
2022-06-11 19:38:18 +00:00
|
|
|
m_vpQuadLayerVisuals.clear();
|
2022-06-23 17:59:38 +00:00
|
|
|
|
|
|
|
RenderLoading();
|
2018-03-13 20:57:46 +00:00
|
|
|
}
|
|
|
|
|
2017-09-12 18:22:18 +00:00
|
|
|
bool PassedGameLayer = false;
|
2019-03-26 18:15:24 +00:00
|
|
|
//prepare all visuals for all tile layers
|
2022-06-15 17:34:41 +00:00
|
|
|
std::vector<SGraphicTile> vtmpTiles;
|
|
|
|
std::vector<SGraphicTileTexureCoords> vtmpTileTexCoords;
|
|
|
|
std::vector<SGraphicTile> vtmpBorderTopTiles;
|
|
|
|
std::vector<SGraphicTileTexureCoords> vtmpBorderTopTilesTexCoords;
|
|
|
|
std::vector<SGraphicTile> vtmpBorderLeftTiles;
|
|
|
|
std::vector<SGraphicTileTexureCoords> vtmpBorderLeftTilesTexCoords;
|
|
|
|
std::vector<SGraphicTile> vtmpBorderRightTiles;
|
|
|
|
std::vector<SGraphicTileTexureCoords> vtmpBorderRightTilesTexCoords;
|
|
|
|
std::vector<SGraphicTile> vtmpBorderBottomTiles;
|
|
|
|
std::vector<SGraphicTileTexureCoords> vtmpBorderBottomTilesTexCoords;
|
|
|
|
std::vector<SGraphicTile> vtmpBorderCorners;
|
|
|
|
std::vector<SGraphicTileTexureCoords> vtmpBorderCornersTexCoords;
|
|
|
|
|
|
|
|
std::vector<STmpQuad> vtmpQuads;
|
|
|
|
std::vector<STmpQuadTextured> vtmpQuadsTextured;
|
2018-03-13 20:57:46 +00:00
|
|
|
|
2020-08-29 10:10:38 +00:00
|
|
|
bool As3DTextureCoords = !Graphics()->HasTextureArrays();
|
|
|
|
|
2017-09-12 18:22:18 +00:00
|
|
|
for(int g = 0; g < m_pLayers->NumGroups(); g++)
|
|
|
|
{
|
|
|
|
CMapItemGroup *pGroup = m_pLayers->GetGroup(g);
|
|
|
|
if(!pGroup)
|
|
|
|
{
|
|
|
|
dbg_msg("maplayers", "error group was null, group number = %d, total groups = %d", g, m_pLayers->NumGroups());
|
|
|
|
dbg_msg("maplayers", "this is here to prevent a crash but the source of this is unknown, please report this for it to get fixed");
|
|
|
|
dbg_msg("maplayers", "we need mapname and crc and the map that caused this if possible, and anymore info you think is relevant");
|
|
|
|
continue;
|
|
|
|
}
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-12 18:22:18 +00:00
|
|
|
for(int l = 0; l < pGroup->m_NumLayers; l++)
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
CMapItemLayer *pLayer = m_pLayers->GetLayer(pGroup->m_StartLayer + l);
|
2017-09-12 18:22:18 +00:00
|
|
|
bool IsFrontLayer = false;
|
|
|
|
bool IsSwitchLayer = false;
|
|
|
|
bool IsTeleLayer = false;
|
|
|
|
bool IsSpeedupLayer = false;
|
|
|
|
bool IsTuneLayer = false;
|
|
|
|
bool IsGameLayer = false;
|
|
|
|
bool IsEntityLayer = false;
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(pLayer == (CMapItemLayer *)m_pLayers->GameLayer())
|
2017-09-12 18:22:18 +00:00
|
|
|
{
|
|
|
|
IsGameLayer = true;
|
|
|
|
IsEntityLayer = true;
|
|
|
|
PassedGameLayer = true;
|
|
|
|
}
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(pLayer == (CMapItemLayer *)m_pLayers->FrontLayer())
|
2017-09-12 18:22:18 +00:00
|
|
|
IsEntityLayer = IsFrontLayer = true;
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(pLayer == (CMapItemLayer *)m_pLayers->SwitchLayer())
|
2017-09-12 18:22:18 +00:00
|
|
|
IsEntityLayer = IsSwitchLayer = true;
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(pLayer == (CMapItemLayer *)m_pLayers->TeleLayer())
|
2017-09-12 18:22:18 +00:00
|
|
|
IsEntityLayer = IsTeleLayer = true;
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(pLayer == (CMapItemLayer *)m_pLayers->SpeedupLayer())
|
2017-09-12 18:22:18 +00:00
|
|
|
IsEntityLayer = IsSpeedupLayer = true;
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(pLayer == (CMapItemLayer *)m_pLayers->TuneLayer())
|
2017-09-12 18:22:18 +00:00
|
|
|
IsEntityLayer = IsTuneLayer = true;
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-12 18:22:18 +00:00
|
|
|
if(m_Type <= TYPE_BACKGROUND_FORCE)
|
|
|
|
{
|
|
|
|
if(PassedGameLayer)
|
|
|
|
return;
|
|
|
|
}
|
2018-01-16 08:35:28 +00:00
|
|
|
else if(m_Type == TYPE_FOREGROUND)
|
|
|
|
{
|
|
|
|
if(!PassedGameLayer)
|
|
|
|
continue;
|
|
|
|
}
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2020-08-29 10:10:38 +00:00
|
|
|
if(pLayer->m_Type == LAYERTYPE_TILES && Graphics()->IsTileBufferingEnabled())
|
2019-03-26 18:15:24 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
bool DoTextureCoords = false;
|
|
|
|
CMapItemLayerTilemap *pTMap = (CMapItemLayerTilemap *)pLayer;
|
|
|
|
if(pTMap->m_Image == -1)
|
|
|
|
{
|
|
|
|
if(IsEntityLayer)
|
|
|
|
DoTextureCoords = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
DoTextureCoords = true;
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-12 18:22:18 +00:00
|
|
|
int DataIndex = 0;
|
2017-09-27 12:52:06 +00:00
|
|
|
unsigned int TileSize = 0;
|
2017-09-12 18:22:18 +00:00
|
|
|
int OverlayCount = 0;
|
2018-01-16 08:35:28 +00:00
|
|
|
if(IsFrontLayer)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
DataIndex = pTMap->m_Front;
|
|
|
|
TileSize = sizeof(CTile);
|
|
|
|
}
|
2018-01-16 08:35:28 +00:00
|
|
|
else if(IsSwitchLayer)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
DataIndex = pTMap->m_Switch;
|
|
|
|
TileSize = sizeof(CSwitchTile);
|
|
|
|
OverlayCount = 2;
|
|
|
|
}
|
2018-01-16 08:35:28 +00:00
|
|
|
else if(IsTeleLayer)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
DataIndex = pTMap->m_Tele;
|
|
|
|
TileSize = sizeof(CTeleTile);
|
|
|
|
OverlayCount = 1;
|
|
|
|
}
|
2018-01-16 08:35:28 +00:00
|
|
|
else if(IsSpeedupLayer)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
DataIndex = pTMap->m_Speedup;
|
|
|
|
TileSize = sizeof(CSpeedupTile);
|
|
|
|
OverlayCount = 2;
|
|
|
|
}
|
2018-01-16 08:35:28 +00:00
|
|
|
else if(IsTuneLayer)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
DataIndex = pTMap->m_Tune;
|
|
|
|
TileSize = sizeof(CTuneTile);
|
|
|
|
}
|
2017-09-13 18:33:58 +00:00
|
|
|
else
|
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
DataIndex = pTMap->m_Data;
|
|
|
|
TileSize = sizeof(CTile);
|
|
|
|
}
|
|
|
|
unsigned int Size = m_pLayers->Map()->GetDataSize(DataIndex);
|
2020-09-26 19:41:58 +00:00
|
|
|
void *pTiles = m_pLayers->Map()->GetData(DataIndex);
|
2017-09-12 18:22:18 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(Size >= pTMap->m_Width * pTMap->m_Height * TileSize)
|
2017-09-12 18:22:18 +00:00
|
|
|
{
|
|
|
|
int CurOverlay = 0;
|
2017-09-13 18:33:58 +00:00
|
|
|
while(CurOverlay < OverlayCount + 1)
|
|
|
|
{
|
2018-02-04 15:00:47 +00:00
|
|
|
// We can later just count the tile layers to get the idx in the vector
|
2022-06-11 19:38:18 +00:00
|
|
|
m_vpTileLayerVisuals.push_back(new STileLayerVisuals());
|
|
|
|
STileLayerVisuals &Visuals = *m_vpTileLayerVisuals.back();
|
2018-03-13 20:57:46 +00:00
|
|
|
if(!Visuals.Init(pTMap->m_Width, pTMap->m_Height))
|
|
|
|
{
|
|
|
|
++CurOverlay;
|
|
|
|
continue;
|
|
|
|
}
|
2017-09-12 18:22:18 +00:00
|
|
|
Visuals.m_IsTextured = DoTextureCoords;
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2022-06-15 17:34:41 +00:00
|
|
|
vtmpTiles.clear();
|
|
|
|
vtmpTileTexCoords.clear();
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2022-06-15 17:34:41 +00:00
|
|
|
vtmpBorderTopTiles.clear();
|
|
|
|
vtmpBorderLeftTiles.clear();
|
|
|
|
vtmpBorderRightTiles.clear();
|
|
|
|
vtmpBorderBottomTiles.clear();
|
|
|
|
vtmpBorderCorners.clear();
|
|
|
|
vtmpBorderTopTilesTexCoords.clear();
|
|
|
|
vtmpBorderLeftTilesTexCoords.clear();
|
|
|
|
vtmpBorderRightTilesTexCoords.clear();
|
|
|
|
vtmpBorderBottomTilesTexCoords.clear();
|
|
|
|
vtmpBorderCornersTexCoords.clear();
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(!DoTextureCoords)
|
|
|
|
{
|
2022-06-15 17:34:41 +00:00
|
|
|
vtmpTiles.reserve((size_t)pTMap->m_Width * pTMap->m_Height);
|
|
|
|
vtmpBorderTopTiles.reserve((size_t)pTMap->m_Width);
|
|
|
|
vtmpBorderBottomTiles.reserve((size_t)pTMap->m_Width);
|
|
|
|
vtmpBorderLeftTiles.reserve((size_t)pTMap->m_Height);
|
|
|
|
vtmpBorderRightTiles.reserve((size_t)pTMap->m_Height);
|
|
|
|
vtmpBorderCorners.reserve((size_t)4);
|
2020-08-29 10:10:38 +00:00
|
|
|
}
|
2020-09-26 19:41:58 +00:00
|
|
|
else
|
|
|
|
{
|
2022-06-15 17:34:41 +00:00
|
|
|
vtmpTileTexCoords.reserve((size_t)pTMap->m_Width * pTMap->m_Height);
|
|
|
|
vtmpBorderTopTilesTexCoords.reserve((size_t)pTMap->m_Width);
|
|
|
|
vtmpBorderBottomTilesTexCoords.reserve((size_t)pTMap->m_Width);
|
|
|
|
vtmpBorderLeftTilesTexCoords.reserve((size_t)pTMap->m_Height);
|
|
|
|
vtmpBorderRightTilesTexCoords.reserve((size_t)pTMap->m_Height);
|
|
|
|
vtmpBorderCornersTexCoords.reserve((size_t)4);
|
2020-08-29 10:10:38 +00:00
|
|
|
}
|
|
|
|
|
2017-09-12 18:22:18 +00:00
|
|
|
int x = 0;
|
|
|
|
int y = 0;
|
2017-09-27 10:20:23 +00:00
|
|
|
for(y = 0; y < pTMap->m_Height; ++y)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-27 10:20:23 +00:00
|
|
|
for(x = 0; x < pTMap->m_Width; ++x)
|
2017-09-12 18:22:18 +00:00
|
|
|
{
|
2017-09-27 10:20:23 +00:00
|
|
|
unsigned char Index = 0;
|
|
|
|
unsigned char Flags = 0;
|
|
|
|
int AngleRotate = -1;
|
|
|
|
if(IsEntityLayer)
|
2019-03-26 18:15:24 +00:00
|
|
|
{
|
2017-09-27 10:20:23 +00:00
|
|
|
if(IsGameLayer)
|
2019-03-26 18:15:24 +00:00
|
|
|
{
|
2020-09-10 22:42:42 +00:00
|
|
|
Index = ((CTile *)pTiles)[y * pTMap->m_Width + x].m_Index;
|
|
|
|
Flags = ((CTile *)pTiles)[y * pTMap->m_Width + x].m_Flags;
|
2017-09-27 10:20:23 +00:00
|
|
|
}
|
|
|
|
if(IsFrontLayer)
|
2019-03-26 18:15:24 +00:00
|
|
|
{
|
2020-09-10 22:42:42 +00:00
|
|
|
Index = ((CTile *)pTiles)[y * pTMap->m_Width + x].m_Index;
|
|
|
|
Flags = ((CTile *)pTiles)[y * pTMap->m_Width + x].m_Flags;
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2017-09-27 10:20:23 +00:00
|
|
|
if(IsSwitchLayer)
|
2017-09-12 18:22:18 +00:00
|
|
|
{
|
2017-09-27 10:20:23 +00:00
|
|
|
Flags = 0;
|
2020-09-10 22:42:42 +00:00
|
|
|
Index = ((CSwitchTile *)pTiles)[y * pTMap->m_Width + x].m_Type;
|
2020-09-08 13:11:32 +00:00
|
|
|
if(CurOverlay == 0)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
Flags = ((CSwitchTile *)pTiles)[y * pTMap->m_Width + x].m_Flags;
|
|
|
|
if(Index == TILE_SWITCHTIMEDOPEN)
|
|
|
|
Index = 8;
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2017-10-25 13:42:06 +00:00
|
|
|
else if(CurOverlay == 1)
|
2020-09-26 19:41:58 +00:00
|
|
|
Index = ((CSwitchTile *)pTiles)[y * pTMap->m_Width + x].m_Number;
|
2017-10-25 13:42:06 +00:00
|
|
|
else if(CurOverlay == 2)
|
2020-09-26 19:41:58 +00:00
|
|
|
Index = ((CSwitchTile *)pTiles)[y * pTMap->m_Width + x].m_Delay;
|
2017-09-27 10:20:23 +00:00
|
|
|
}
|
|
|
|
if(IsTeleLayer)
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
Index = ((CTeleTile *)pTiles)[y * pTMap->m_Width + x].m_Type;
|
2017-09-27 10:20:23 +00:00
|
|
|
Flags = 0;
|
2020-09-08 13:11:32 +00:00
|
|
|
if(CurOverlay == 1)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-27 10:20:23 +00:00
|
|
|
if(Index != TILE_TELECHECKIN && Index != TILE_TELECHECKINEVIL)
|
2020-09-26 19:41:58 +00:00
|
|
|
Index = ((CTeleTile *)pTiles)[y * pTMap->m_Width + x].m_Number;
|
|
|
|
else
|
|
|
|
Index = 0;
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
|
|
|
}
|
2017-09-27 10:20:23 +00:00
|
|
|
if(IsSpeedupLayer)
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
Index = ((CSpeedupTile *)pTiles)[y * pTMap->m_Width + x].m_Type;
|
2017-09-27 10:20:23 +00:00
|
|
|
Flags = 0;
|
2020-09-10 22:42:42 +00:00
|
|
|
AngleRotate = ((CSpeedupTile *)pTiles)[y * pTMap->m_Width + x].m_Angle;
|
|
|
|
if(((CSpeedupTile *)pTiles)[y * pTMap->m_Width + x].m_Force == 0)
|
2017-10-25 13:42:06 +00:00
|
|
|
Index = 0;
|
|
|
|
else if(CurOverlay == 1)
|
2020-09-26 19:41:58 +00:00
|
|
|
Index = ((CSpeedupTile *)pTiles)[y * pTMap->m_Width + x].m_Force;
|
2017-10-25 13:42:06 +00:00
|
|
|
else if(CurOverlay == 2)
|
2020-09-26 19:41:58 +00:00
|
|
|
Index = ((CSpeedupTile *)pTiles)[y * pTMap->m_Width + x].m_MaxSpeed;
|
2017-09-27 10:20:23 +00:00
|
|
|
}
|
|
|
|
if(IsTuneLayer)
|
2019-03-26 18:15:24 +00:00
|
|
|
{
|
2020-09-10 22:42:42 +00:00
|
|
|
Index = ((CTuneTile *)pTiles)[y * pTMap->m_Width + x].m_Type;
|
2017-09-27 10:20:23 +00:00
|
|
|
Flags = 0;
|
|
|
|
}
|
2020-09-26 19:41:58 +00:00
|
|
|
}
|
|
|
|
else
|
2017-09-27 10:20:23 +00:00
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
Index = ((CTile *)pTiles)[y * pTMap->m_Width + x].m_Index;
|
|
|
|
Flags = ((CTile *)pTiles)[y * pTMap->m_Width + x].m_Flags;
|
2017-09-27 10:20:23 +00:00
|
|
|
}
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-27 10:20:23 +00:00
|
|
|
//the amount of tiles handled before this tile
|
2022-06-15 17:34:41 +00:00
|
|
|
int TilesHandledCount = vtmpTiles.size();
|
2022-03-24 18:30:26 +00:00
|
|
|
Visuals.m_pTilesOfLayer[y * pTMap->m_Width + x].SetIndexBufferByteOffset((offset_ptr32)(TilesHandledCount * 6 * sizeof(unsigned int)));
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-10-27 22:52:54 +00:00
|
|
|
bool AddAsSpeedup = false;
|
2018-01-16 08:35:28 +00:00
|
|
|
if(IsSpeedupLayer && CurOverlay == 0)
|
2017-10-27 22:52:54 +00:00
|
|
|
AddAsSpeedup = true;
|
|
|
|
|
2022-06-15 17:34:41 +00:00
|
|
|
if(AddTile(vtmpTiles, vtmpTileTexCoords, As3DTextureCoords, Index, Flags, x, y, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate))
|
2022-03-24 18:30:26 +00:00
|
|
|
Visuals.m_pTilesOfLayer[y * pTMap->m_Width + x].Draw(true);
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-27 10:20:23 +00:00
|
|
|
//do the border tiles
|
|
|
|
if(x == 0)
|
|
|
|
{
|
|
|
|
if(y == 0)
|
|
|
|
{
|
2022-06-15 17:34:41 +00:00
|
|
|
Visuals.m_BorderTopLeft.SetIndexBufferByteOffset((offset_ptr32)(vtmpBorderCorners.size() * 6 * sizeof(unsigned int)));
|
|
|
|
if(AddTile(vtmpBorderCorners, vtmpBorderCornersTexCoords, As3DTextureCoords, Index, Flags, x, y, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate))
|
2018-01-16 08:35:28 +00:00
|
|
|
Visuals.m_BorderTopLeft.Draw(true);
|
2018-03-13 20:57:46 +00:00
|
|
|
}
|
|
|
|
else if(y == pTMap->m_Height - 1)
|
2017-09-27 10:20:23 +00:00
|
|
|
{
|
2022-06-15 17:34:41 +00:00
|
|
|
Visuals.m_BorderBottomLeft.SetIndexBufferByteOffset((offset_ptr32)(vtmpBorderCorners.size() * 6 * sizeof(unsigned int)));
|
|
|
|
if(AddTile(vtmpBorderCorners, vtmpBorderCornersTexCoords, As3DTextureCoords, Index, Flags, x, y, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate))
|
2018-01-16 08:35:28 +00:00
|
|
|
Visuals.m_BorderBottomLeft.Draw(true);
|
2018-03-13 20:57:46 +00:00
|
|
|
}
|
2019-03-26 18:15:24 +00:00
|
|
|
else
|
2017-09-27 10:20:23 +00:00
|
|
|
{
|
2022-06-15 17:34:41 +00:00
|
|
|
Visuals.m_pBorderLeft[y - 1].SetIndexBufferByteOffset((offset_ptr32)(vtmpBorderLeftTiles.size() * 6 * sizeof(unsigned int)));
|
|
|
|
if(AddTile(vtmpBorderLeftTiles, vtmpBorderLeftTilesTexCoords, As3DTextureCoords, Index, Flags, x, y, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate))
|
2022-03-24 18:30:26 +00:00
|
|
|
Visuals.m_pBorderLeft[y - 1].Draw(true);
|
2017-09-27 10:20:23 +00:00
|
|
|
}
|
2018-03-13 20:57:46 +00:00
|
|
|
}
|
|
|
|
else if(x == pTMap->m_Width - 1)
|
2017-09-27 10:20:23 +00:00
|
|
|
{
|
|
|
|
if(y == 0)
|
|
|
|
{
|
2022-06-15 17:34:41 +00:00
|
|
|
Visuals.m_BorderTopRight.SetIndexBufferByteOffset((offset_ptr32)(vtmpBorderCorners.size() * 6 * sizeof(unsigned int)));
|
|
|
|
if(AddTile(vtmpBorderCorners, vtmpBorderCornersTexCoords, As3DTextureCoords, Index, Flags, x, y, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate))
|
2018-01-16 08:35:28 +00:00
|
|
|
Visuals.m_BorderTopRight.Draw(true);
|
2018-03-13 20:57:46 +00:00
|
|
|
}
|
|
|
|
else if(y == pTMap->m_Height - 1)
|
2017-09-27 10:20:23 +00:00
|
|
|
{
|
2022-06-15 17:34:41 +00:00
|
|
|
Visuals.m_BorderBottomRight.SetIndexBufferByteOffset((offset_ptr32)(vtmpBorderCorners.size() * 6 * sizeof(unsigned int)));
|
|
|
|
if(AddTile(vtmpBorderCorners, vtmpBorderCornersTexCoords, As3DTextureCoords, Index, Flags, x, y, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate))
|
2018-01-16 08:35:28 +00:00
|
|
|
Visuals.m_BorderBottomRight.Draw(true);
|
2018-03-13 20:57:46 +00:00
|
|
|
}
|
|
|
|
else
|
2017-09-27 10:20:23 +00:00
|
|
|
{
|
2022-06-15 17:34:41 +00:00
|
|
|
Visuals.m_pBorderRight[y - 1].SetIndexBufferByteOffset((offset_ptr32)(vtmpBorderRightTiles.size() * 6 * sizeof(unsigned int)));
|
|
|
|
if(AddTile(vtmpBorderRightTiles, vtmpBorderRightTilesTexCoords, As3DTextureCoords, Index, Flags, x, y, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate))
|
2022-03-24 18:30:26 +00:00
|
|
|
Visuals.m_pBorderRight[y - 1].Draw(true);
|
2017-09-27 10:20:23 +00:00
|
|
|
}
|
2018-03-13 20:57:46 +00:00
|
|
|
}
|
|
|
|
else if(y == 0)
|
2017-09-27 10:20:23 +00:00
|
|
|
{
|
|
|
|
if(x > 0 && x < pTMap->m_Width - 1)
|
|
|
|
{
|
2022-06-15 17:34:41 +00:00
|
|
|
Visuals.m_pBorderTop[x - 1].SetIndexBufferByteOffset((offset_ptr32)(vtmpBorderTopTiles.size() * 6 * sizeof(unsigned int)));
|
|
|
|
if(AddTile(vtmpBorderTopTiles, vtmpBorderTopTilesTexCoords, As3DTextureCoords, Index, Flags, x, y, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate))
|
2022-03-24 18:30:26 +00:00
|
|
|
Visuals.m_pBorderTop[x - 1].Draw(true);
|
2017-09-27 10:20:23 +00:00
|
|
|
}
|
2018-03-13 20:57:46 +00:00
|
|
|
}
|
|
|
|
else if(y == pTMap->m_Height - 1)
|
2017-09-27 10:20:23 +00:00
|
|
|
{
|
|
|
|
if(x > 0 && x < pTMap->m_Width - 1)
|
|
|
|
{
|
2022-06-15 17:34:41 +00:00
|
|
|
Visuals.m_pBorderBottom[x - 1].SetIndexBufferByteOffset((offset_ptr32)(vtmpBorderBottomTiles.size() * 6 * sizeof(unsigned int)));
|
|
|
|
if(AddTile(vtmpBorderBottomTiles, vtmpBorderBottomTilesTexCoords, As3DTextureCoords, Index, Flags, x, y, pGroup, DoTextureCoords, AddAsSpeedup, AngleRotate))
|
2022-03-24 18:30:26 +00:00
|
|
|
Visuals.m_pBorderBottom[x - 1].Draw(true);
|
2017-09-27 10:20:23 +00:00
|
|
|
}
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-12 18:22:18 +00:00
|
|
|
//append one kill tile to the gamelayer
|
2017-09-13 18:33:58 +00:00
|
|
|
if(IsGameLayer)
|
|
|
|
{
|
2022-06-15 17:34:41 +00:00
|
|
|
Visuals.m_BorderKillTile.SetIndexBufferByteOffset((offset_ptr32)(vtmpTiles.size() * 6 * sizeof(unsigned int)));
|
|
|
|
if(AddTile(vtmpTiles, vtmpTileTexCoords, As3DTextureCoords, TILE_DEATH, 0, 0, 0, pGroup, DoTextureCoords))
|
2018-01-16 08:35:28 +00:00
|
|
|
Visuals.m_BorderKillTile.Draw(true);
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-27 10:20:23 +00:00
|
|
|
//add the border corners, then the borders and fix their byte offsets
|
2022-06-15 17:34:41 +00:00
|
|
|
int TilesHandledCount = vtmpTiles.size();
|
2020-09-26 19:41:58 +00:00
|
|
|
Visuals.m_BorderTopLeft.AddIndexBufferByteOffset(TilesHandledCount * 6 * sizeof(unsigned int));
|
|
|
|
Visuals.m_BorderTopRight.AddIndexBufferByteOffset(TilesHandledCount * 6 * sizeof(unsigned int));
|
|
|
|
Visuals.m_BorderBottomLeft.AddIndexBufferByteOffset(TilesHandledCount * 6 * sizeof(unsigned int));
|
|
|
|
Visuals.m_BorderBottomRight.AddIndexBufferByteOffset(TilesHandledCount * 6 * sizeof(unsigned int));
|
2017-09-27 10:20:23 +00:00
|
|
|
//add the Corners to the tiles
|
2022-06-15 17:34:41 +00:00
|
|
|
vtmpTiles.insert(vtmpTiles.end(), vtmpBorderCorners.begin(), vtmpBorderCorners.end());
|
|
|
|
vtmpTileTexCoords.insert(vtmpTileTexCoords.end(), vtmpBorderCornersTexCoords.begin(), vtmpBorderCornersTexCoords.end());
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-27 10:20:23 +00:00
|
|
|
//now the borders
|
2022-06-15 17:34:41 +00:00
|
|
|
TilesHandledCount = vtmpTiles.size();
|
2017-09-27 10:20:23 +00:00
|
|
|
if(pTMap->m_Width > 2)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
for(int i = 0; i < pTMap->m_Width - 2; ++i)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2022-03-24 18:30:26 +00:00
|
|
|
Visuals.m_pBorderTop[i].AddIndexBufferByteOffset(TilesHandledCount * 6 * sizeof(unsigned int));
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
|
|
|
}
|
2022-06-15 17:34:41 +00:00
|
|
|
vtmpTiles.insert(vtmpTiles.end(), vtmpBorderTopTiles.begin(), vtmpBorderTopTiles.end());
|
|
|
|
vtmpTileTexCoords.insert(vtmpTileTexCoords.end(), vtmpBorderTopTilesTexCoords.begin(), vtmpBorderTopTilesTexCoords.end());
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2022-06-15 17:34:41 +00:00
|
|
|
TilesHandledCount = vtmpTiles.size();
|
2017-09-27 10:20:23 +00:00
|
|
|
if(pTMap->m_Width > 2)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
for(int i = 0; i < pTMap->m_Width - 2; ++i)
|
2017-09-27 10:20:23 +00:00
|
|
|
{
|
2022-03-24 18:30:26 +00:00
|
|
|
Visuals.m_pBorderBottom[i].AddIndexBufferByteOffset(TilesHandledCount * 6 * sizeof(unsigned int));
|
2017-09-27 10:20:23 +00:00
|
|
|
}
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2022-06-15 17:34:41 +00:00
|
|
|
vtmpTiles.insert(vtmpTiles.end(), vtmpBorderBottomTiles.begin(), vtmpBorderBottomTiles.end());
|
|
|
|
vtmpTileTexCoords.insert(vtmpTileTexCoords.end(), vtmpBorderBottomTilesTexCoords.begin(), vtmpBorderBottomTilesTexCoords.end());
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2022-06-15 17:34:41 +00:00
|
|
|
TilesHandledCount = vtmpTiles.size();
|
2017-09-27 10:20:23 +00:00
|
|
|
if(pTMap->m_Height > 2)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
for(int i = 0; i < pTMap->m_Height - 2; ++i)
|
2017-09-27 10:20:23 +00:00
|
|
|
{
|
2022-03-24 18:30:26 +00:00
|
|
|
Visuals.m_pBorderLeft[i].AddIndexBufferByteOffset(TilesHandledCount * 6 * sizeof(unsigned int));
|
2017-09-27 10:20:23 +00:00
|
|
|
}
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2022-06-15 17:34:41 +00:00
|
|
|
vtmpTiles.insert(vtmpTiles.end(), vtmpBorderLeftTiles.begin(), vtmpBorderLeftTiles.end());
|
|
|
|
vtmpTileTexCoords.insert(vtmpTileTexCoords.end(), vtmpBorderLeftTilesTexCoords.begin(), vtmpBorderLeftTilesTexCoords.end());
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2022-06-15 17:34:41 +00:00
|
|
|
TilesHandledCount = vtmpTiles.size();
|
2017-09-27 10:20:23 +00:00
|
|
|
if(pTMap->m_Height > 2)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
for(int i = 0; i < pTMap->m_Height - 2; ++i)
|
2017-09-27 10:20:23 +00:00
|
|
|
{
|
2022-03-24 18:30:26 +00:00
|
|
|
Visuals.m_pBorderRight[i].AddIndexBufferByteOffset(TilesHandledCount * 6 * sizeof(unsigned int));
|
2017-09-27 10:20:23 +00:00
|
|
|
}
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2022-06-15 17:34:41 +00:00
|
|
|
vtmpTiles.insert(vtmpTiles.end(), vtmpBorderRightTiles.begin(), vtmpBorderRightTiles.end());
|
|
|
|
vtmpTileTexCoords.insert(vtmpTileTexCoords.end(), vtmpBorderRightTilesTexCoords.begin(), vtmpBorderRightTilesTexCoords.end());
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-12 18:22:18 +00:00
|
|
|
//setup params
|
2022-07-10 19:22:50 +00:00
|
|
|
float *pTmpTiles = vtmpTiles.empty() ? NULL : (float *)vtmpTiles.data();
|
|
|
|
unsigned char *pTmpTileTexCoords = vtmpTileTexCoords.empty() ? NULL : (unsigned char *)vtmpTileTexCoords.data();
|
2018-03-13 20:57:46 +00:00
|
|
|
|
2020-08-29 10:10:38 +00:00
|
|
|
Visuals.m_BufferContainerIndex = -1;
|
2022-06-15 17:34:41 +00:00
|
|
|
size_t UploadDataSize = vtmpTileTexCoords.size() * sizeof(SGraphicTileTexureCoords) + vtmpTiles.size() * sizeof(SGraphicTile);
|
2020-08-29 10:10:38 +00:00
|
|
|
if(UploadDataSize > 0)
|
2020-08-26 18:01:32 +00:00
|
|
|
{
|
2020-10-13 17:33:02 +00:00
|
|
|
char *pUploadData = (char *)malloc(sizeof(char) * UploadDataSize);
|
2018-03-13 20:57:46 +00:00
|
|
|
|
2022-06-15 17:34:41 +00:00
|
|
|
mem_copy_special(pUploadData, pTmpTiles, sizeof(vec2), vtmpTiles.size() * 4, (DoTextureCoords ? sizeof(vec3) : 0));
|
2020-08-29 10:10:38 +00:00
|
|
|
if(DoTextureCoords)
|
|
|
|
{
|
2022-06-15 17:34:41 +00:00
|
|
|
mem_copy_special(pUploadData + sizeof(vec2), pTmpTileTexCoords, sizeof(vec3), vtmpTiles.size() * 4, (DoTextureCoords ? (sizeof(vec2)) : 0));
|
2020-08-29 10:10:38 +00:00
|
|
|
}
|
2020-08-22 06:09:10 +00:00
|
|
|
|
2020-08-29 10:10:38 +00:00
|
|
|
// first create the buffer object
|
2022-03-20 17:03:25 +00:00
|
|
|
int BufferObjectIndex = Graphics()->CreateBufferObject(UploadDataSize, pUploadData, 0, true);
|
2020-08-29 10:10:38 +00:00
|
|
|
|
|
|
|
// then create the buffer container
|
|
|
|
SBufferContainerInfo ContainerInfo;
|
|
|
|
ContainerInfo.m_Stride = (DoTextureCoords ? (sizeof(float) * 2 + sizeof(vec3)) : 0);
|
2022-03-20 17:04:00 +00:00
|
|
|
ContainerInfo.m_VertBufferBindingIndex = BufferObjectIndex;
|
2022-06-11 19:38:18 +00:00
|
|
|
ContainerInfo.m_vAttributes.emplace_back();
|
|
|
|
SBufferContainerInfo::SAttribute *pAttr = &ContainerInfo.m_vAttributes.back();
|
2020-08-22 06:09:10 +00:00
|
|
|
pAttr->m_DataTypeCount = 2;
|
2020-08-29 10:10:38 +00:00
|
|
|
pAttr->m_Type = GRAPHICS_TYPE_FLOAT;
|
2018-03-13 20:57:46 +00:00
|
|
|
pAttr->m_Normalized = false;
|
2020-08-29 10:10:38 +00:00
|
|
|
pAttr->m_pOffset = 0;
|
2018-03-13 20:57:46 +00:00
|
|
|
pAttr->m_FuncType = 0;
|
2020-08-29 10:10:38 +00:00
|
|
|
if(DoTextureCoords)
|
|
|
|
{
|
2022-06-11 19:38:18 +00:00
|
|
|
ContainerInfo.m_vAttributes.emplace_back();
|
|
|
|
pAttr = &ContainerInfo.m_vAttributes.back();
|
2020-08-29 10:10:38 +00:00
|
|
|
pAttr->m_DataTypeCount = 3;
|
|
|
|
pAttr->m_Type = GRAPHICS_TYPE_FLOAT;
|
|
|
|
pAttr->m_Normalized = false;
|
2020-09-26 19:41:58 +00:00
|
|
|
pAttr->m_pOffset = (void *)(sizeof(vec2));
|
2020-08-29 10:10:38 +00:00
|
|
|
pAttr->m_FuncType = 0;
|
|
|
|
}
|
2018-03-13 20:57:46 +00:00
|
|
|
|
2020-08-29 10:10:38 +00:00
|
|
|
Visuals.m_BufferContainerIndex = Graphics()->CreateBufferContainer(&ContainerInfo);
|
|
|
|
// and finally inform the backend how many indices are required
|
2022-06-15 17:34:41 +00:00
|
|
|
Graphics()->IndicesNumRequiredNotify(vtmpTiles.size() * 6);
|
2022-06-23 17:59:38 +00:00
|
|
|
|
|
|
|
RenderLoading();
|
2020-08-22 06:09:10 +00:00
|
|
|
}
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-12 18:22:18 +00:00
|
|
|
++CurOverlay;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-08-29 10:10:38 +00:00
|
|
|
else if(pLayer->m_Type == LAYERTYPE_QUADS && Graphics()->IsQuadBufferingEnabled())
|
2018-03-13 20:57:46 +00:00
|
|
|
{
|
|
|
|
CMapItemLayerQuads *pQLayer = (CMapItemLayerQuads *)pLayer;
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2022-06-11 19:38:18 +00:00
|
|
|
m_vpQuadLayerVisuals.push_back(new SQuadLayerVisuals());
|
|
|
|
SQuadLayerVisuals *pQLayerVisuals = m_vpQuadLayerVisuals.back();
|
2018-03-13 20:57:46 +00:00
|
|
|
|
2022-01-22 16:34:23 +00:00
|
|
|
bool Textured = (pQLayer->m_Image != -1);
|
2018-03-13 20:57:46 +00:00
|
|
|
|
2022-06-15 17:34:41 +00:00
|
|
|
vtmpQuads.clear();
|
|
|
|
vtmpQuadsTextured.clear();
|
2018-03-13 20:57:46 +00:00
|
|
|
|
|
|
|
if(Textured)
|
2022-06-15 17:34:41 +00:00
|
|
|
vtmpQuadsTextured.resize(pQLayer->m_NumQuads);
|
2018-03-13 20:57:46 +00:00
|
|
|
else
|
2022-06-15 17:34:41 +00:00
|
|
|
vtmpQuads.resize(pQLayer->m_NumQuads);
|
2018-03-13 20:57:46 +00:00
|
|
|
|
|
|
|
CQuad *pQuads = (CQuad *)m_pLayers->Map()->GetDataSwapped(pQLayer->m_Data);
|
|
|
|
for(int i = 0; i < pQLayer->m_NumQuads; ++i)
|
|
|
|
{
|
2022-06-30 22:36:32 +00:00
|
|
|
CQuad *pQuad = &pQuads[i];
|
2018-03-13 20:57:46 +00:00
|
|
|
for(int j = 0; j < 4; ++j)
|
|
|
|
{
|
|
|
|
int QuadIDX = j;
|
|
|
|
if(j == 2)
|
|
|
|
QuadIDX = 3;
|
|
|
|
else if(j == 3)
|
|
|
|
QuadIDX = 2;
|
|
|
|
if(!Textured)
|
|
|
|
{
|
2018-07-10 09:29:02 +00:00
|
|
|
// ignore the conversion for the position coordinates
|
2022-06-30 22:36:32 +00:00
|
|
|
vtmpQuads[i].m_aVertices[j].m_X = (pQuad->m_aPoints[QuadIDX].x);
|
|
|
|
vtmpQuads[i].m_aVertices[j].m_Y = (pQuad->m_aPoints[QuadIDX].y);
|
|
|
|
vtmpQuads[i].m_aVertices[j].m_CenterX = (pQuad->m_aPoints[4].x);
|
|
|
|
vtmpQuads[i].m_aVertices[j].m_CenterY = (pQuad->m_aPoints[4].y);
|
|
|
|
vtmpQuads[i].m_aVertices[j].m_R = (unsigned char)pQuad->m_aColors[QuadIDX].r;
|
|
|
|
vtmpQuads[i].m_aVertices[j].m_G = (unsigned char)pQuad->m_aColors[QuadIDX].g;
|
|
|
|
vtmpQuads[i].m_aVertices[j].m_B = (unsigned char)pQuad->m_aColors[QuadIDX].b;
|
|
|
|
vtmpQuads[i].m_aVertices[j].m_A = (unsigned char)pQuad->m_aColors[QuadIDX].a;
|
2018-03-13 20:57:46 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-07-10 09:29:02 +00:00
|
|
|
// ignore the conversion for the position coordinates
|
2022-06-30 22:36:32 +00:00
|
|
|
vtmpQuadsTextured[i].m_aVertices[j].m_X = (pQuad->m_aPoints[QuadIDX].x);
|
|
|
|
vtmpQuadsTextured[i].m_aVertices[j].m_Y = (pQuad->m_aPoints[QuadIDX].y);
|
|
|
|
vtmpQuadsTextured[i].m_aVertices[j].m_CenterX = (pQuad->m_aPoints[4].x);
|
|
|
|
vtmpQuadsTextured[i].m_aVertices[j].m_CenterY = (pQuad->m_aPoints[4].y);
|
|
|
|
vtmpQuadsTextured[i].m_aVertices[j].m_U = fx2f(pQuad->m_aTexcoords[QuadIDX].x);
|
|
|
|
vtmpQuadsTextured[i].m_aVertices[j].m_V = fx2f(pQuad->m_aTexcoords[QuadIDX].y);
|
|
|
|
vtmpQuadsTextured[i].m_aVertices[j].m_R = (unsigned char)pQuad->m_aColors[QuadIDX].r;
|
|
|
|
vtmpQuadsTextured[i].m_aVertices[j].m_G = (unsigned char)pQuad->m_aColors[QuadIDX].g;
|
|
|
|
vtmpQuadsTextured[i].m_aVertices[j].m_B = (unsigned char)pQuad->m_aColors[QuadIDX].b;
|
|
|
|
vtmpQuadsTextured[i].m_aVertices[j].m_A = (unsigned char)pQuad->m_aColors[QuadIDX].a;
|
2018-03-13 20:57:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t UploadDataSize = 0;
|
|
|
|
if(Textured)
|
2022-06-15 17:34:41 +00:00
|
|
|
UploadDataSize = vtmpQuadsTextured.size() * sizeof(STmpQuadTextured);
|
2018-03-13 20:57:46 +00:00
|
|
|
else
|
2022-06-15 17:34:41 +00:00
|
|
|
UploadDataSize = vtmpQuads.size() * sizeof(STmpQuad);
|
2018-03-13 20:57:46 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(UploadDataSize > 0)
|
|
|
|
{
|
|
|
|
void *pUploadData = NULL;
|
2018-03-13 20:57:46 +00:00
|
|
|
if(Textured)
|
2022-07-10 19:22:50 +00:00
|
|
|
pUploadData = vtmpQuadsTextured.data();
|
2018-03-13 20:57:46 +00:00
|
|
|
else
|
2022-07-10 19:22:50 +00:00
|
|
|
pUploadData = vtmpQuads.data();
|
2018-03-13 20:57:46 +00:00
|
|
|
// create the buffer object
|
2022-03-20 17:03:25 +00:00
|
|
|
int BufferObjectIndex = Graphics()->CreateBufferObject(UploadDataSize, pUploadData, 0);
|
2018-03-13 20:57:46 +00:00
|
|
|
// then create the buffer container
|
|
|
|
SBufferContainerInfo ContainerInfo;
|
|
|
|
ContainerInfo.m_Stride = (Textured ? (sizeof(STmpQuadTextured) / 4) : (sizeof(STmpQuad) / 4));
|
2022-03-20 17:04:00 +00:00
|
|
|
ContainerInfo.m_VertBufferBindingIndex = BufferObjectIndex;
|
2022-06-11 19:38:18 +00:00
|
|
|
ContainerInfo.m_vAttributes.emplace_back();
|
|
|
|
SBufferContainerInfo::SAttribute *pAttr = &ContainerInfo.m_vAttributes.back();
|
2018-03-13 20:57:46 +00:00
|
|
|
pAttr->m_DataTypeCount = 4;
|
|
|
|
pAttr->m_Type = GRAPHICS_TYPE_FLOAT;
|
|
|
|
pAttr->m_Normalized = false;
|
|
|
|
pAttr->m_pOffset = 0;
|
|
|
|
pAttr->m_FuncType = 0;
|
2022-06-11 19:38:18 +00:00
|
|
|
ContainerInfo.m_vAttributes.emplace_back();
|
|
|
|
pAttr = &ContainerInfo.m_vAttributes.back();
|
2020-08-29 10:10:38 +00:00
|
|
|
pAttr->m_DataTypeCount = 4;
|
|
|
|
pAttr->m_Type = GRAPHICS_TYPE_UNSIGNED_BYTE;
|
|
|
|
pAttr->m_Normalized = true;
|
2020-09-26 19:41:58 +00:00
|
|
|
pAttr->m_pOffset = (void *)(sizeof(float) * 4);
|
2020-08-29 10:10:38 +00:00
|
|
|
pAttr->m_FuncType = 0;
|
2018-03-13 20:57:46 +00:00
|
|
|
if(Textured)
|
|
|
|
{
|
2022-06-11 19:38:18 +00:00
|
|
|
ContainerInfo.m_vAttributes.emplace_back();
|
|
|
|
pAttr = &ContainerInfo.m_vAttributes.back();
|
2018-03-13 20:57:46 +00:00
|
|
|
pAttr->m_DataTypeCount = 2;
|
|
|
|
pAttr->m_Type = GRAPHICS_TYPE_FLOAT;
|
|
|
|
pAttr->m_Normalized = false;
|
2020-09-26 19:41:58 +00:00
|
|
|
pAttr->m_pOffset = (void *)(sizeof(float) * 4 + sizeof(unsigned char) * 4);
|
2018-03-13 20:57:46 +00:00
|
|
|
pAttr->m_FuncType = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
pQLayerVisuals->m_BufferContainerIndex = Graphics()->CreateBufferContainer(&ContainerInfo);
|
|
|
|
// and finally inform the backend how many indices are required
|
|
|
|
Graphics()->IndicesNumRequiredNotify(pQLayer->m_NumQuads * 6);
|
2022-06-23 17:59:38 +00:00
|
|
|
|
|
|
|
RenderLoading();
|
2018-03-13 20:57:46 +00:00
|
|
|
}
|
|
|
|
}
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-01 04:42:36 +00:00
|
|
|
void CMapLayers::RenderTileLayer(int LayerIndex, ColorRGBA &Color, CMapItemLayerTilemap *pTileLayer, CMapItemGroup *pGroup)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2022-06-11 19:38:18 +00:00
|
|
|
STileLayerVisuals &Visuals = *m_vpTileLayerVisuals[LayerIndex];
|
2018-03-13 20:57:46 +00:00
|
|
|
if(Visuals.m_BufferContainerIndex == -1)
|
|
|
|
return; //no visuals were created
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-12 18:22:18 +00:00
|
|
|
float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
|
|
|
|
Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1);
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2022-07-01 04:42:36 +00:00
|
|
|
ColorRGBA Channels(1.f, 1.f, 1.f, 1.f);
|
2017-09-12 18:22:18 +00:00
|
|
|
if(pTileLayer->m_ColorEnv >= 0)
|
|
|
|
{
|
2022-07-01 04:42:36 +00:00
|
|
|
EnvelopeEval(pTileLayer->m_ColorEnvOffset, pTileLayer->m_ColorEnv, Channels, this);
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-12 18:22:18 +00:00
|
|
|
int BorderX0, BorderY0, BorderX1, BorderY1;
|
|
|
|
bool DrawBorder = false;
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
int Y0 = BorderY0 = (int)floorf((ScreenY0) / 32);
|
|
|
|
int X0 = BorderX0 = (int)floorf((ScreenX0) / 32);
|
|
|
|
int Y1 = BorderY1 = (int)floorf((ScreenY1) / 32);
|
|
|
|
int X1 = BorderX1 = (int)floorf((ScreenX1) / 32);
|
2019-03-26 18:15:24 +00:00
|
|
|
|
|
|
|
if(X0 <= 0)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
X0 = 0;
|
|
|
|
DrawBorder = true;
|
|
|
|
}
|
2018-08-02 16:26:12 +00:00
|
|
|
if(Y0 <= 0)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
Y0 = 0;
|
|
|
|
DrawBorder = true;
|
|
|
|
}
|
2018-08-02 16:26:12 +00:00
|
|
|
if(X1 >= pTileLayer->m_Width - 1)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
X1 = pTileLayer->m_Width - 1;
|
|
|
|
DrawBorder = true;
|
|
|
|
}
|
2018-08-02 16:26:12 +00:00
|
|
|
if(Y1 >= pTileLayer->m_Height - 1)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
Y1 = pTileLayer->m_Height - 1;
|
|
|
|
DrawBorder = true;
|
|
|
|
}
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-12 21:16:01 +00:00
|
|
|
bool DrawLayer = true;
|
2018-03-13 20:57:46 +00:00
|
|
|
if(X1 < 0)
|
|
|
|
DrawLayer = false;
|
|
|
|
if(Y1 < 0)
|
|
|
|
DrawLayer = false;
|
|
|
|
if(X0 >= pTileLayer->m_Width)
|
|
|
|
DrawLayer = false;
|
|
|
|
if(Y0 >= pTileLayer->m_Height)
|
|
|
|
DrawLayer = false;
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-13 18:33:58 +00:00
|
|
|
if(DrawLayer)
|
|
|
|
{
|
2017-09-12 21:16:01 +00:00
|
|
|
//create the indice buffers we want to draw -- reuse them
|
2022-06-15 17:34:41 +00:00
|
|
|
static std::vector<char *> s_vpIndexOffsets;
|
|
|
|
static std::vector<unsigned int> s_vDrawCounts;
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2022-06-15 17:34:41 +00:00
|
|
|
s_vpIndexOffsets.clear();
|
|
|
|
s_vDrawCounts.clear();
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-27 10:20:23 +00:00
|
|
|
unsigned long long Reserve = absolute(Y1 - Y0) + 1;
|
2022-06-15 17:34:41 +00:00
|
|
|
s_vpIndexOffsets.reserve(Reserve);
|
|
|
|
s_vDrawCounts.reserve(Reserve);
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-27 10:20:23 +00:00
|
|
|
for(int y = Y0; y <= Y1; ++y)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2019-03-26 18:15:24 +00:00
|
|
|
if(X0 > X1)
|
2018-01-16 08:35:28 +00:00
|
|
|
continue;
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2022-03-24 18:30:26 +00:00
|
|
|
dbg_assert(Visuals.m_pTilesOfLayer[y * pTileLayer->m_Width + X1].IndexBufferByteOffset() >= Visuals.m_pTilesOfLayer[y * pTileLayer->m_Width + X0].IndexBufferByteOffset(), "Tile count wrong.");
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2022-03-24 18:30:26 +00:00
|
|
|
unsigned int NumVertices = ((Visuals.m_pTilesOfLayer[y * pTileLayer->m_Width + X1].IndexBufferByteOffset() - Visuals.m_pTilesOfLayer[y * pTileLayer->m_Width + X0].IndexBufferByteOffset()) / sizeof(unsigned int)) + (Visuals.m_pTilesOfLayer[y * pTileLayer->m_Width + X1].DoDraw() ? 6lu : 0lu);
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-27 12:52:06 +00:00
|
|
|
if(NumVertices)
|
|
|
|
{
|
2022-06-15 17:34:41 +00:00
|
|
|
s_vpIndexOffsets.push_back((offset_ptr_size)Visuals.m_pTilesOfLayer[y * pTileLayer->m_Width + X0].IndexBufferByteOffset());
|
|
|
|
s_vDrawCounts.push_back(NumVertices);
|
2017-09-12 21:16:01 +00:00
|
|
|
}
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2022-07-01 04:42:36 +00:00
|
|
|
Color.x *= Channels.r;
|
|
|
|
Color.y *= Channels.g;
|
|
|
|
Color.z *= Channels.b;
|
|
|
|
Color.w *= Channels.a;
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2022-06-15 17:34:41 +00:00
|
|
|
int DrawCount = s_vpIndexOffsets.size();
|
2017-09-27 12:52:06 +00:00
|
|
|
if(DrawCount != 0)
|
|
|
|
{
|
2022-07-10 19:22:50 +00:00
|
|
|
Graphics()->RenderTileLayer(Visuals.m_BufferContainerIndex, Color, s_vpIndexOffsets.data(), s_vDrawCounts.data(), DrawCount);
|
2017-09-27 10:20:23 +00:00
|
|
|
}
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2018-08-02 16:26:12 +00:00
|
|
|
if(DrawBorder)
|
2022-07-01 04:42:36 +00:00
|
|
|
RenderTileBorder(LayerIndex, Color, pTileLayer, pGroup, BorderX0, BorderY0, BorderX1, BorderY1, (int)(-floorf((-ScreenX1) / 32.f)) - BorderX0, (int)(-floorf((-ScreenY1) / 32.f)) - BorderY0);
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
|
|
|
|
2022-07-01 04:42:36 +00:00
|
|
|
void CMapLayers::RenderTileBorderCornerTiles(int WidthOffsetToOrigin, int HeightOffsetToOrigin, int TileCountWidth, int TileCountHeight, int BufferContainerIndex, const ColorRGBA &Color, offset_ptr_size IndexBufferOffset, const vec2 &Offset, const vec2 &Dir)
|
2018-10-29 21:09:11 +00:00
|
|
|
{
|
|
|
|
// if border is still in range of the original corner, it doesn't needs to be redrawn
|
|
|
|
bool CornerVisible = (WidthOffsetToOrigin - 1 < TileCountWidth) && (HeightOffsetToOrigin - 1 < TileCountHeight);
|
2018-10-29 07:44:55 +00:00
|
|
|
|
2019-04-26 19:36:49 +00:00
|
|
|
int CountX = minimum(WidthOffsetToOrigin, TileCountWidth);
|
|
|
|
int CountY = minimum(HeightOffsetToOrigin, TileCountHeight);
|
2018-10-29 07:44:55 +00:00
|
|
|
|
2018-10-29 21:09:11 +00:00
|
|
|
int Count = (CountX * CountY) - (CornerVisible ? 1 : 0); // Don't draw the corner again
|
2018-10-29 07:44:55 +00:00
|
|
|
|
2022-07-01 04:42:36 +00:00
|
|
|
Graphics()->RenderBorderTiles(BufferContainerIndex, Color, IndexBufferOffset, Offset, Dir, CountX, Count);
|
2018-10-29 07:44:55 +00:00
|
|
|
}
|
|
|
|
|
2022-07-01 04:42:36 +00:00
|
|
|
void CMapLayers::RenderTileBorder(int LayerIndex, const ColorRGBA &Color, CMapItemLayerTilemap *pTileLayer, CMapItemGroup *pGroup, int BorderX0, int BorderY0, int BorderX1, int BorderY1, int ScreenWidthTileCount, int ScreenHeightTileCount)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2022-06-11 19:38:18 +00:00
|
|
|
STileLayerVisuals &Visuals = *m_vpTileLayerVisuals[LayerIndex];
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-12 18:22:18 +00:00
|
|
|
int Y0 = BorderY0;
|
|
|
|
int X0 = BorderX0;
|
|
|
|
int Y1 = BorderY1;
|
|
|
|
int X1 = BorderX1;
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2018-08-02 16:26:12 +00:00
|
|
|
int CountWidth = ScreenWidthTileCount;
|
|
|
|
int CountHeight = ScreenHeightTileCount;
|
|
|
|
|
2018-03-13 20:57:46 +00:00
|
|
|
if(X0 < 1)
|
|
|
|
X0 = 1;
|
|
|
|
if(Y0 < 1)
|
|
|
|
Y0 = 1;
|
|
|
|
if(X1 >= pTileLayer->m_Width - 1)
|
|
|
|
X1 = pTileLayer->m_Width - 2;
|
|
|
|
if(Y1 >= pTileLayer->m_Height - 1)
|
|
|
|
Y1 = pTileLayer->m_Height - 2;
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2018-08-02 16:26:12 +00:00
|
|
|
if(BorderX0 <= 0)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2018-02-04 15:00:47 +00:00
|
|
|
// Draw corners on left side
|
2018-08-02 16:26:12 +00:00
|
|
|
if(BorderY0 <= 0)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2018-01-16 08:35:28 +00:00
|
|
|
if(Visuals.m_BorderTopLeft.DoDraw())
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
vec2 Offset;
|
|
|
|
Offset.x = BorderX0 * 32.f;
|
|
|
|
Offset.y = BorderY0 * 32.f;
|
|
|
|
vec2 Dir;
|
|
|
|
Dir.x = 32.f;
|
|
|
|
Dir.y = 32.f;
|
|
|
|
|
2022-07-01 04:42:36 +00:00
|
|
|
RenderTileBorderCornerTiles(absolute(BorderX0) + 1, absolute(BorderY0) + 1, CountWidth, CountHeight, Visuals.m_BufferContainerIndex, Color, (offset_ptr_size)Visuals.m_BorderTopLeft.IndexBufferByteOffset(), Offset, Dir);
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
|
|
|
}
|
2018-08-02 16:26:12 +00:00
|
|
|
if(BorderY1 >= pTileLayer->m_Height - 1)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2018-01-16 08:35:28 +00:00
|
|
|
if(Visuals.m_BorderBottomLeft.DoDraw())
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
vec2 Offset;
|
|
|
|
Offset.x = BorderX0 * 32.f;
|
2018-08-02 16:26:12 +00:00
|
|
|
Offset.y = (BorderY1 - (pTileLayer->m_Height - 1)) * 32.f;
|
2017-09-12 18:22:18 +00:00
|
|
|
vec2 Dir;
|
|
|
|
Dir.x = 32.f;
|
|
|
|
Dir.y = -32.f;
|
|
|
|
|
2022-07-01 04:42:36 +00:00
|
|
|
RenderTileBorderCornerTiles(absolute(BorderX0) + 1, (BorderY1 - (pTileLayer->m_Height - 1)) + 1, CountWidth, CountHeight, Visuals.m_BufferContainerIndex, Color, (offset_ptr_size)Visuals.m_BorderBottomLeft.IndexBufferByteOffset(), Offset, Dir);
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
|
|
|
}
|
2018-08-02 16:26:12 +00:00
|
|
|
}
|
|
|
|
if(BorderX0 < 0)
|
|
|
|
{
|
2018-02-04 15:00:47 +00:00
|
|
|
// Draw left border
|
2017-09-13 18:33:58 +00:00
|
|
|
if(Y0 < pTileLayer->m_Height - 1 && Y1 > 0)
|
|
|
|
{
|
2022-03-24 18:30:26 +00:00
|
|
|
unsigned int DrawNum = ((Visuals.m_pBorderLeft[Y1 - 1].IndexBufferByteOffset() - Visuals.m_pBorderLeft[Y0 - 1].IndexBufferByteOffset()) / sizeof(unsigned int)) + (Visuals.m_pBorderLeft[Y1 - 1].DoDraw() ? 6lu : 0lu);
|
|
|
|
offset_ptr_size pOffset = (offset_ptr_size)Visuals.m_pBorderLeft[Y0 - 1].IndexBufferByteOffset();
|
2018-08-02 16:26:12 +00:00
|
|
|
vec2 Offset;
|
|
|
|
Offset.x = 32.f * BorderX0;
|
|
|
|
Offset.y = 0.f;
|
2017-09-12 18:22:18 +00:00
|
|
|
vec2 Dir;
|
2018-08-02 16:26:12 +00:00
|
|
|
Dir.x = 32.f;
|
2017-09-12 18:22:18 +00:00
|
|
|
Dir.y = 0.f;
|
2022-07-01 04:42:36 +00:00
|
|
|
Graphics()->RenderBorderTileLines(Visuals.m_BufferContainerIndex, Color, pOffset, Offset, Dir, DrawNum, minimum(absolute(BorderX0), CountWidth));
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
|
|
|
}
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2018-08-02 16:26:12 +00:00
|
|
|
if(BorderX1 >= pTileLayer->m_Width - 1)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2018-02-04 15:00:47 +00:00
|
|
|
// Draw corners on right side
|
2018-08-02 16:26:12 +00:00
|
|
|
if(BorderY0 <= 0)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2018-01-16 08:35:28 +00:00
|
|
|
if(Visuals.m_BorderTopRight.DoDraw())
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
vec2 Offset;
|
2018-08-02 16:26:12 +00:00
|
|
|
Offset.x = (BorderX1 - (pTileLayer->m_Width - 1)) * 32.f;
|
2017-09-12 18:22:18 +00:00
|
|
|
Offset.y = BorderY0 * 32.f;
|
|
|
|
vec2 Dir;
|
|
|
|
Dir.x = -32.f;
|
|
|
|
Dir.y = 32.f;
|
|
|
|
|
2022-07-01 04:42:36 +00:00
|
|
|
RenderTileBorderCornerTiles((BorderX1 - (pTileLayer->m_Width - 1)) + 1, absolute(BorderY0) + 1, CountWidth, CountHeight, Visuals.m_BufferContainerIndex, Color, (offset_ptr_size)Visuals.m_BorderTopRight.IndexBufferByteOffset(), Offset, Dir);
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
|
|
|
}
|
2018-08-02 16:26:12 +00:00
|
|
|
if(BorderY1 >= pTileLayer->m_Height - 1)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2018-01-16 08:35:28 +00:00
|
|
|
if(Visuals.m_BorderBottomRight.DoDraw())
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
vec2 Offset;
|
2018-08-02 16:26:12 +00:00
|
|
|
Offset.x = (BorderX1 - (pTileLayer->m_Width - 1)) * 32.f;
|
|
|
|
Offset.y = (BorderY1 - (pTileLayer->m_Height - 1)) * 32.f;
|
2017-09-12 18:22:18 +00:00
|
|
|
vec2 Dir;
|
|
|
|
Dir.x = -32.f;
|
|
|
|
Dir.y = -32.f;
|
|
|
|
|
2022-07-01 04:42:36 +00:00
|
|
|
RenderTileBorderCornerTiles((BorderX1 - (pTileLayer->m_Width - 1)) + 1, (BorderY1 - (pTileLayer->m_Height - 1)) + 1, CountWidth, CountHeight, Visuals.m_BufferContainerIndex, Color, (offset_ptr_size)Visuals.m_BorderBottomRight.IndexBufferByteOffset(), Offset, Dir);
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2018-08-02 16:26:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if(BorderX1 > pTileLayer->m_Width - 1)
|
|
|
|
{
|
2018-02-04 15:00:47 +00:00
|
|
|
// Draw right border
|
2017-09-13 18:33:58 +00:00
|
|
|
if(Y0 < pTileLayer->m_Height - 1 && Y1 > 0)
|
|
|
|
{
|
2022-03-24 18:30:26 +00:00
|
|
|
unsigned int DrawNum = ((Visuals.m_pBorderRight[Y1 - 1].IndexBufferByteOffset() - Visuals.m_pBorderRight[Y0 - 1].IndexBufferByteOffset()) / sizeof(unsigned int)) + (Visuals.m_pBorderRight[Y1 - 1].DoDraw() ? 6lu : 0lu);
|
|
|
|
offset_ptr_size pOffset = (offset_ptr_size)Visuals.m_pBorderRight[Y0 - 1].IndexBufferByteOffset();
|
2018-08-02 16:26:12 +00:00
|
|
|
vec2 Offset;
|
|
|
|
Offset.x = 32.f * (BorderX1 - (pTileLayer->m_Width - 1));
|
|
|
|
Offset.y = 0.f;
|
2017-09-12 18:22:18 +00:00
|
|
|
vec2 Dir;
|
2018-08-02 16:26:12 +00:00
|
|
|
Dir.x = -32.f;
|
2017-09-12 18:22:18 +00:00
|
|
|
Dir.y = 0.f;
|
2022-07-01 04:42:36 +00:00
|
|
|
Graphics()->RenderBorderTileLines(Visuals.m_BufferContainerIndex, Color, pOffset, Offset, Dir, DrawNum, minimum((BorderX1 - (pTileLayer->m_Width - 1)), CountWidth));
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
|
|
|
}
|
2017-09-13 18:33:58 +00:00
|
|
|
if(BorderY0 < 0)
|
|
|
|
{
|
2018-02-04 15:00:47 +00:00
|
|
|
// Draw top border
|
2017-09-13 18:33:58 +00:00
|
|
|
if(X0 < pTileLayer->m_Width - 1 && X1 > 0)
|
2019-03-26 18:15:24 +00:00
|
|
|
{
|
2022-03-24 18:30:26 +00:00
|
|
|
unsigned int DrawNum = ((Visuals.m_pBorderTop[X1 - 1].IndexBufferByteOffset() - Visuals.m_pBorderTop[X0 - 1].IndexBufferByteOffset()) / sizeof(unsigned int)) + (Visuals.m_pBorderTop[X1 - 1].DoDraw() ? 6lu : 0lu);
|
|
|
|
offset_ptr_size pOffset = (offset_ptr_size)Visuals.m_pBorderTop[X0 - 1].IndexBufferByteOffset();
|
2018-08-02 16:26:12 +00:00
|
|
|
vec2 Offset;
|
|
|
|
Offset.x = 0.f;
|
|
|
|
Offset.y = 32.f * BorderY0;
|
2017-09-12 18:22:18 +00:00
|
|
|
vec2 Dir;
|
|
|
|
Dir.x = 0.f;
|
2018-08-02 16:26:12 +00:00
|
|
|
Dir.y = 32.f;
|
2022-07-01 04:42:36 +00:00
|
|
|
Graphics()->RenderBorderTileLines(Visuals.m_BufferContainerIndex, Color, pOffset, Offset, Dir, DrawNum, minimum(absolute(BorderY0), CountHeight));
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
|
|
|
}
|
2017-09-13 18:33:58 +00:00
|
|
|
if(BorderY1 >= pTileLayer->m_Height)
|
|
|
|
{
|
2018-02-04 15:00:47 +00:00
|
|
|
// Draw bottom border
|
2017-09-13 18:33:58 +00:00
|
|
|
if(X0 < pTileLayer->m_Width - 1 && X1 > 0)
|
|
|
|
{
|
2022-03-24 18:30:26 +00:00
|
|
|
unsigned int DrawNum = ((Visuals.m_pBorderBottom[X1 - 1].IndexBufferByteOffset() - Visuals.m_pBorderBottom[X0 - 1].IndexBufferByteOffset()) / sizeof(unsigned int)) + (Visuals.m_pBorderBottom[X1 - 1].DoDraw() ? 6lu : 0lu);
|
|
|
|
offset_ptr_size pOffset = (offset_ptr_size)Visuals.m_pBorderBottom[X0 - 1].IndexBufferByteOffset();
|
2018-08-02 16:26:12 +00:00
|
|
|
vec2 Offset;
|
|
|
|
Offset.x = 0.f;
|
|
|
|
Offset.y = 32.f * (BorderY1 - (pTileLayer->m_Height - 1));
|
2017-09-12 18:22:18 +00:00
|
|
|
vec2 Dir;
|
|
|
|
Dir.x = 0.f;
|
2018-08-02 16:26:12 +00:00
|
|
|
Dir.y = -32.f;
|
2022-07-01 04:42:36 +00:00
|
|
|
Graphics()->RenderBorderTileLines(Visuals.m_BufferContainerIndex, Color, pOffset, Offset, Dir, DrawNum, minimum((BorderY1 - (pTileLayer->m_Height - 1)), CountHeight));
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-01 04:42:36 +00:00
|
|
|
void CMapLayers::RenderKillTileBorder(int LayerIndex, const ColorRGBA &Color, CMapItemLayerTilemap *pTileLayer, CMapItemGroup *pGroup)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2022-06-11 19:38:18 +00:00
|
|
|
STileLayerVisuals &Visuals = *m_vpTileLayerVisuals[LayerIndex];
|
2020-09-26 19:41:58 +00:00
|
|
|
if(Visuals.m_BufferContainerIndex == -1)
|
|
|
|
return; //no visuals were created
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-12 18:22:18 +00:00
|
|
|
float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
|
|
|
|
Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1);
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-12 18:22:18 +00:00
|
|
|
bool DrawBorder = false;
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
int BorderY0 = (int)(ScreenY0 / 32) - 1;
|
|
|
|
int BorderX0 = (int)(ScreenX0 / 32) - 1;
|
|
|
|
int BorderY1 = (int)(ScreenY1 / 32) + 1;
|
|
|
|
int BorderX1 = (int)(ScreenX1 / 32) + 1;
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2018-03-13 20:57:46 +00:00
|
|
|
if(BorderX0 < -201)
|
|
|
|
DrawBorder = true;
|
|
|
|
if(BorderY0 < -201)
|
|
|
|
DrawBorder = true;
|
|
|
|
if(BorderX1 >= pTileLayer->m_Width + 201)
|
|
|
|
DrawBorder = true;
|
|
|
|
if(BorderY1 >= pTileLayer->m_Height + 201)
|
|
|
|
DrawBorder = true;
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2018-03-13 20:57:46 +00:00
|
|
|
if(!DrawBorder)
|
|
|
|
return;
|
|
|
|
if(!Visuals.m_BorderKillTile.DoDraw())
|
|
|
|
return;
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2018-03-13 20:57:46 +00:00
|
|
|
if(BorderX0 < -300)
|
|
|
|
BorderX0 = -300;
|
|
|
|
if(BorderY0 < -300)
|
|
|
|
BorderY0 = -300;
|
|
|
|
if(BorderX1 >= pTileLayer->m_Width + 300)
|
|
|
|
BorderX1 = pTileLayer->m_Width + 299;
|
|
|
|
if(BorderY1 >= pTileLayer->m_Height + 300)
|
2019-03-26 18:15:24 +00:00
|
|
|
BorderY1 = pTileLayer->m_Height + 299;
|
|
|
|
|
2018-03-13 20:57:46 +00:00
|
|
|
if(BorderX1 < -300)
|
|
|
|
BorderX1 = -300;
|
|
|
|
if(BorderY1 < -300)
|
|
|
|
BorderY1 = -300;
|
|
|
|
if(BorderX0 >= pTileLayer->m_Width + 300)
|
|
|
|
BorderX0 = pTileLayer->m_Width + 299;
|
|
|
|
if(BorderY0 >= pTileLayer->m_Height + 300)
|
2019-03-26 18:15:24 +00:00
|
|
|
BorderY0 = pTileLayer->m_Height + 299;
|
|
|
|
|
2018-02-04 15:00:47 +00:00
|
|
|
// Draw left kill tile border
|
2017-09-13 18:33:58 +00:00
|
|
|
if(BorderX0 < -201)
|
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
vec2 Offset;
|
|
|
|
Offset.x = BorderX0 * 32.f;
|
|
|
|
Offset.y = BorderY0 * 32.f;
|
|
|
|
vec2 Dir;
|
|
|
|
Dir.x = 32.f;
|
|
|
|
Dir.y = 32.f;
|
|
|
|
|
2017-09-27 10:20:23 +00:00
|
|
|
int Count = (absolute(BorderX0) - 201) * (BorderY1 - BorderY0);
|
2017-09-12 18:22:18 +00:00
|
|
|
|
2022-07-01 04:42:36 +00:00
|
|
|
Graphics()->RenderBorderTiles(Visuals.m_BufferContainerIndex, Color, (offset_ptr_size)Visuals.m_BorderKillTile.IndexBufferByteOffset(), Offset, Dir, (absolute(BorderX0) - 201), Count);
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2018-02-04 15:00:47 +00:00
|
|
|
// Draw top kill tile border
|
2017-09-13 18:33:58 +00:00
|
|
|
if(BorderY0 < -201)
|
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
vec2 Offset;
|
|
|
|
int OffX0 = (BorderX0 < -201 ? -201 : BorderX0);
|
|
|
|
int OffX1 = (BorderX1 >= pTileLayer->m_Width + 201 ? pTileLayer->m_Width + 201 : BorderX1);
|
2020-09-06 21:58:54 +00:00
|
|
|
OffX0 = clamp(OffX0, -201, (int)pTileLayer->m_Width + 201);
|
|
|
|
OffX1 = clamp(OffX1, -201, (int)pTileLayer->m_Width + 201);
|
2017-09-12 18:22:18 +00:00
|
|
|
Offset.x = OffX0 * 32.f;
|
|
|
|
Offset.y = BorderY0 * 32.f;
|
|
|
|
vec2 Dir;
|
|
|
|
Dir.x = 32.f;
|
|
|
|
Dir.y = 32.f;
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
int Count = (OffX1 - OffX0) * (absolute(BorderY0) - 201);
|
2017-09-12 18:22:18 +00:00
|
|
|
|
2022-07-01 04:42:36 +00:00
|
|
|
Graphics()->RenderBorderTiles(Visuals.m_BufferContainerIndex, Color, (offset_ptr_size)Visuals.m_BorderKillTile.IndexBufferByteOffset(), Offset, Dir, (OffX1 - OffX0), Count);
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2017-09-13 18:33:58 +00:00
|
|
|
if(BorderX1 >= pTileLayer->m_Width + 201)
|
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
vec2 Offset;
|
|
|
|
Offset.x = (pTileLayer->m_Width + 201) * 32.f;
|
|
|
|
Offset.y = BorderY0 * 32.f;
|
|
|
|
vec2 Dir;
|
|
|
|
Dir.x = 32.f;
|
|
|
|
Dir.y = 32.f;
|
|
|
|
|
2017-09-27 10:20:23 +00:00
|
|
|
int Count = (BorderX1 - (pTileLayer->m_Width + 201)) * (BorderY1 - BorderY0);
|
2017-09-12 18:22:18 +00:00
|
|
|
|
2022-07-01 04:42:36 +00:00
|
|
|
Graphics()->RenderBorderTiles(Visuals.m_BufferContainerIndex, Color, (offset_ptr_size)Visuals.m_BorderKillTile.IndexBufferByteOffset(), Offset, Dir, (BorderX1 - (pTileLayer->m_Width + 201)), Count);
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2017-09-13 18:33:58 +00:00
|
|
|
if(BorderY1 >= pTileLayer->m_Height + 201)
|
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
vec2 Offset;
|
|
|
|
int OffX0 = (BorderX0 < -201 ? -201 : BorderX0);
|
|
|
|
int OffX1 = (BorderX1 >= pTileLayer->m_Width + 201 ? pTileLayer->m_Width + 201 : BorderX1);
|
2020-09-06 21:58:54 +00:00
|
|
|
OffX0 = clamp(OffX0, -201, (int)pTileLayer->m_Width + 201);
|
|
|
|
OffX1 = clamp(OffX1, -201, (int)pTileLayer->m_Width + 201);
|
2017-09-12 18:22:18 +00:00
|
|
|
Offset.x = OffX0 * 32.f;
|
|
|
|
Offset.y = (pTileLayer->m_Height + 201) * 32.f;
|
|
|
|
vec2 Dir;
|
|
|
|
Dir.x = 32.f;
|
|
|
|
Dir.y = 32.f;
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
int Count = (OffX1 - OffX0) * (BorderY1 - (pTileLayer->m_Height + 201));
|
2017-09-12 18:22:18 +00:00
|
|
|
|
2022-07-01 04:42:36 +00:00
|
|
|
Graphics()->RenderBorderTiles(Visuals.m_BufferContainerIndex, Color, (offset_ptr_size)Visuals.m_BorderKillTile.IndexBufferByteOffset(), Offset, Dir, (OffX1 - OffX0), Count);
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
void CMapLayers::RenderQuadLayer(int LayerIndex, CMapItemLayerQuads *pQuadLayer, CMapItemGroup *pGroup, bool Force)
|
2018-03-13 20:57:46 +00:00
|
|
|
{
|
2022-06-11 19:38:18 +00:00
|
|
|
SQuadLayerVisuals &Visuals = *m_vpQuadLayerVisuals[LayerIndex];
|
2018-03-13 20:57:46 +00:00
|
|
|
if(Visuals.m_BufferContainerIndex == -1)
|
|
|
|
return; //no visuals were created
|
|
|
|
|
|
|
|
if(!Force && (!g_Config.m_ClShowQuads || g_Config.m_ClOverlayEntities == 100))
|
|
|
|
return;
|
|
|
|
|
|
|
|
CQuad *pQuads = (CQuad *)m_pLayers->Map()->GetDataSwapped(pQuadLayer->m_Data);
|
|
|
|
|
2022-06-15 17:34:41 +00:00
|
|
|
static std::vector<SQuadRenderInfo> s_vQuadRenderInfo;
|
2018-03-13 20:57:46 +00:00
|
|
|
|
2022-06-15 17:34:41 +00:00
|
|
|
s_vQuadRenderInfo.resize(pQuadLayer->m_NumQuads);
|
2020-12-29 13:31:42 +00:00
|
|
|
size_t QuadsRenderCount = 0;
|
|
|
|
size_t CurQuadOffset = 0;
|
2018-03-13 20:57:46 +00:00
|
|
|
for(int i = 0; i < pQuadLayer->m_NumQuads; ++i)
|
|
|
|
{
|
2022-06-30 22:36:32 +00:00
|
|
|
CQuad *pQuad = &pQuads[i];
|
2018-03-13 20:57:46 +00:00
|
|
|
|
2022-07-01 04:42:36 +00:00
|
|
|
ColorRGBA Color(1.f, 1.f, 1.f, 1.f);
|
2022-06-30 22:36:32 +00:00
|
|
|
if(pQuad->m_ColorEnv >= 0)
|
2018-03-13 20:57:46 +00:00
|
|
|
{
|
2022-06-30 22:36:32 +00:00
|
|
|
EnvelopeEval(pQuad->m_ColorEnvOffset, pQuad->m_ColorEnv, Color, this);
|
2018-03-13 20:57:46 +00:00
|
|
|
}
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2018-03-13 20:57:46 +00:00
|
|
|
float OffsetX = 0;
|
|
|
|
float OffsetY = 0;
|
|
|
|
float Rot = 0;
|
|
|
|
|
2022-06-30 22:36:32 +00:00
|
|
|
if(pQuad->m_PosEnv >= 0)
|
2018-03-13 20:57:46 +00:00
|
|
|
{
|
2022-07-01 04:42:36 +00:00
|
|
|
ColorRGBA Channels;
|
2022-06-30 22:36:32 +00:00
|
|
|
EnvelopeEval(pQuad->m_PosEnvOffset, pQuad->m_PosEnv, Channels, this);
|
2022-07-01 04:42:36 +00:00
|
|
|
OffsetX = Channels.r;
|
|
|
|
OffsetY = Channels.g;
|
|
|
|
Rot = Channels.b / 180.0f * pi;
|
2018-03-13 20:57:46 +00:00
|
|
|
}
|
|
|
|
|
2022-08-09 15:44:09 +00:00
|
|
|
const bool IsFullyTransparent = Color.a <= 0;
|
|
|
|
bool NeedsFlush = QuadsRenderCount == gs_GraphicsMaxQuadsRenderCount || IsFullyTransparent;
|
2022-03-20 17:04:00 +00:00
|
|
|
|
|
|
|
if(NeedsFlush)
|
|
|
|
{
|
|
|
|
// render quads of the current offset directly(cancel batching)
|
2022-07-10 19:22:50 +00:00
|
|
|
Graphics()->RenderQuadLayer(Visuals.m_BufferContainerIndex, s_vQuadRenderInfo.data(), QuadsRenderCount, CurQuadOffset);
|
2022-03-20 17:04:00 +00:00
|
|
|
QuadsRenderCount = 0;
|
2022-04-29 13:48:01 +00:00
|
|
|
CurQuadOffset = i;
|
2022-08-09 15:44:09 +00:00
|
|
|
if(IsFullyTransparent)
|
2022-04-29 13:48:01 +00:00
|
|
|
{
|
|
|
|
// since this quad is ignored, the offset is the next quad
|
|
|
|
++CurQuadOffset;
|
|
|
|
}
|
2022-03-20 17:04:00 +00:00
|
|
|
}
|
|
|
|
|
2022-08-09 15:44:09 +00:00
|
|
|
if(!IsFullyTransparent)
|
2020-12-29 13:31:42 +00:00
|
|
|
{
|
2022-06-15 17:34:41 +00:00
|
|
|
SQuadRenderInfo &QInfo = s_vQuadRenderInfo[QuadsRenderCount++];
|
2022-07-01 04:42:36 +00:00
|
|
|
QInfo.m_Color = Color;
|
2022-07-01 02:23:22 +00:00
|
|
|
QInfo.m_Offsets.x = OffsetX;
|
|
|
|
QInfo.m_Offsets.y = OffsetY;
|
2020-12-29 13:31:42 +00:00
|
|
|
QInfo.m_Rotation = Rot;
|
|
|
|
}
|
2018-03-13 20:57:46 +00:00
|
|
|
}
|
2022-07-10 19:22:50 +00:00
|
|
|
Graphics()->RenderQuadLayer(Visuals.m_BufferContainerIndex, s_vQuadRenderInfo.data(), QuadsRenderCount, CurQuadOffset);
|
2018-03-13 20:57:46 +00:00
|
|
|
}
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
void CMapLayers::LayersOfGroupCount(CMapItemGroup *pGroup, int &TileLayerCount, int &QuadLayerCount, bool &PassedGameLayer)
|
2019-03-26 18:15:24 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
int TileLayerCounter = 0;
|
2018-03-13 20:57:46 +00:00
|
|
|
int QuadLayerCounter = 0;
|
2017-09-12 18:22:18 +00:00
|
|
|
for(int l = 0; l < pGroup->m_NumLayers; l++)
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
CMapItemLayer *pLayer = m_pLayers->GetLayer(pGroup->m_StartLayer + l);
|
2017-09-12 18:22:18 +00:00
|
|
|
bool IsFrontLayer = false;
|
|
|
|
bool IsSwitchLayer = false;
|
|
|
|
bool IsTeleLayer = false;
|
|
|
|
bool IsSpeedupLayer = false;
|
|
|
|
bool IsTuneLayer = false;
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(pLayer == (CMapItemLayer *)m_pLayers->GameLayer())
|
2017-09-12 18:22:18 +00:00
|
|
|
{
|
|
|
|
PassedGameLayer = true;
|
|
|
|
}
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(pLayer == (CMapItemLayer *)m_pLayers->FrontLayer())
|
2017-09-27 13:01:38 +00:00
|
|
|
IsFrontLayer = true;
|
2017-09-12 18:22:18 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(pLayer == (CMapItemLayer *)m_pLayers->SwitchLayer())
|
2017-09-27 13:01:38 +00:00
|
|
|
IsSwitchLayer = true;
|
2017-09-12 18:22:18 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(pLayer == (CMapItemLayer *)m_pLayers->TeleLayer())
|
2017-09-27 13:01:38 +00:00
|
|
|
IsTeleLayer = true;
|
2017-09-12 18:22:18 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(pLayer == (CMapItemLayer *)m_pLayers->SpeedupLayer())
|
2017-09-27 13:01:38 +00:00
|
|
|
IsSpeedupLayer = true;
|
2017-09-12 18:22:18 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(pLayer == (CMapItemLayer *)m_pLayers->TuneLayer())
|
2017-09-27 13:01:38 +00:00
|
|
|
IsTuneLayer = true;
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2018-01-16 08:35:28 +00:00
|
|
|
if(m_Type <= TYPE_BACKGROUND_FORCE)
|
2017-09-12 18:22:18 +00:00
|
|
|
{
|
|
|
|
if(PassedGameLayer)
|
2018-03-13 20:57:46 +00:00
|
|
|
break;
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2018-01-16 08:35:28 +00:00
|
|
|
else if(m_Type == TYPE_FOREGROUND)
|
|
|
|
{
|
|
|
|
if(!PassedGameLayer)
|
|
|
|
continue;
|
|
|
|
}
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-12 18:22:18 +00:00
|
|
|
if(pLayer->m_Type == LAYERTYPE_TILES)
|
|
|
|
{
|
|
|
|
CMapItemLayerTilemap *pTMap = (CMapItemLayerTilemap *)pLayer;
|
|
|
|
int DataIndex = 0;
|
2017-09-27 12:52:06 +00:00
|
|
|
unsigned int TileSize = 0;
|
2017-09-12 18:22:18 +00:00
|
|
|
int TileLayerAndOverlayCount = 0;
|
2018-01-16 08:35:28 +00:00
|
|
|
if(IsFrontLayer)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
DataIndex = pTMap->m_Front;
|
|
|
|
TileSize = sizeof(CTile);
|
|
|
|
TileLayerAndOverlayCount = 1;
|
|
|
|
}
|
2019-03-26 18:15:24 +00:00
|
|
|
else if(IsSwitchLayer)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
DataIndex = pTMap->m_Switch;
|
|
|
|
TileSize = sizeof(CSwitchTile);
|
|
|
|
TileLayerAndOverlayCount = 3;
|
|
|
|
}
|
2019-03-26 18:15:24 +00:00
|
|
|
else if(IsTeleLayer)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
DataIndex = pTMap->m_Tele;
|
|
|
|
TileSize = sizeof(CTeleTile);
|
|
|
|
TileLayerAndOverlayCount = 2;
|
|
|
|
}
|
2019-03-26 18:15:24 +00:00
|
|
|
else if(IsSpeedupLayer)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
DataIndex = pTMap->m_Speedup;
|
|
|
|
TileSize = sizeof(CSpeedupTile);
|
|
|
|
TileLayerAndOverlayCount = 3;
|
|
|
|
}
|
2019-03-26 18:15:24 +00:00
|
|
|
else if(IsTuneLayer)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
DataIndex = pTMap->m_Tune;
|
|
|
|
TileSize = sizeof(CTuneTile);
|
|
|
|
TileLayerAndOverlayCount = 1;
|
|
|
|
}
|
2019-03-26 18:15:24 +00:00
|
|
|
else
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
DataIndex = pTMap->m_Data;
|
|
|
|
TileSize = sizeof(CTile);
|
|
|
|
TileLayerAndOverlayCount = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int Size = m_pLayers->Map()->GetDataSize(DataIndex);
|
2020-09-26 19:41:58 +00:00
|
|
|
if(Size >= pTMap->m_Width * pTMap->m_Height * TileSize)
|
2017-09-12 18:22:18 +00:00
|
|
|
{
|
|
|
|
TileLayerCounter += TileLayerAndOverlayCount;
|
|
|
|
}
|
|
|
|
}
|
2018-03-13 20:57:46 +00:00
|
|
|
else if(pLayer->m_Type == LAYERTYPE_QUADS)
|
|
|
|
{
|
|
|
|
++QuadLayerCounter;
|
|
|
|
}
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2018-03-13 20:57:46 +00:00
|
|
|
|
|
|
|
TileLayerCount += TileLayerCounter;
|
|
|
|
QuadLayerCount += QuadLayerCounter;
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CMapLayers::OnRender()
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2020-09-18 16:45:42 +00:00
|
|
|
if(m_OnlineOnly && Client()->State() != IClient::STATE_ONLINE && Client()->State() != IClient::STATE_DEMOPLAYBACK)
|
2008-08-30 09:16:29 +00:00
|
|
|
return;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
CUIRect Screen;
|
|
|
|
Graphics()->GetScreen(&Screen.x, &Screen.y, &Screen.w, &Screen.h);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2020-09-18 16:45:42 +00:00
|
|
|
vec2 Center = GetCurCamera()->m_Center;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
bool PassedGameLayer = false;
|
2017-09-12 18:22:18 +00:00
|
|
|
int TileLayerCounter = 0;
|
2018-03-13 20:57:46 +00:00
|
|
|
int QuadLayerCounter = 0;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
for(int g = 0; g < m_pLayers->NumGroups(); g++)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CMapItemGroup *pGroup = m_pLayers->GetGroup(g);
|
2022-08-10 01:51:03 +00:00
|
|
|
CMapItemGroupEx *pGroupEx = m_pLayers->GetGroupEx(g);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-02-17 09:24:11 +00:00
|
|
|
if(!pGroup)
|
|
|
|
{
|
2016-05-02 19:35:32 +00:00
|
|
|
dbg_msg("maplayers", "error group was null, group number = %d, total groups = %d", g, m_pLayers->NumGroups());
|
|
|
|
dbg_msg("maplayers", "this is here to prevent a crash but the source of this is unknown, please report this for it to get fixed");
|
|
|
|
dbg_msg("maplayers", "we need mapname and crc and the map that caused this if possible, and anymore info you think is relevant");
|
2011-02-17 09:24:11 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2020-09-18 16:45:42 +00:00
|
|
|
if((!g_Config.m_GfxNoclip || m_Type == TYPE_FULL_DESIGN) && pGroup->m_Version >= 2 && pGroup->m_UseClipping)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
|
|
|
// set clipping
|
2022-06-30 22:36:32 +00:00
|
|
|
float aPoints[4];
|
2022-08-10 01:51:03 +00:00
|
|
|
RenderTools()->MapScreenToGroup(Center.x, Center.y, m_pLayers->GameGroup(), m_pLayers->GameGroupEx(), GetCurCamera()->m_Zoom);
|
2022-06-30 22:36:32 +00:00
|
|
|
Graphics()->GetScreen(&aPoints[0], &aPoints[1], &aPoints[2], &aPoints[3]);
|
|
|
|
float x0 = (pGroup->m_ClipX - aPoints[0]) / (aPoints[2] - aPoints[0]);
|
|
|
|
float y0 = (pGroup->m_ClipY - aPoints[1]) / (aPoints[3] - aPoints[1]);
|
|
|
|
float x1 = ((pGroup->m_ClipX + pGroup->m_ClipW) - aPoints[0]) / (aPoints[2] - aPoints[0]);
|
|
|
|
float y1 = ((pGroup->m_ClipY + pGroup->m_ClipH) - aPoints[1]) / (aPoints[3] - aPoints[1]);
|
2017-02-21 16:10:08 +00:00
|
|
|
|
2018-01-16 08:35:28 +00:00
|
|
|
if(x1 < 0.0f || x0 > 1.0f || y1 < 0.0f || y0 > 1.0f)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
//check tile layer count of this group
|
2018-03-13 20:57:46 +00:00
|
|
|
LayersOfGroupCount(pGroup, TileLayerCounter, QuadLayerCounter, PassedGameLayer);
|
2017-01-05 09:24:52 +00:00
|
|
|
continue;
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
Graphics()->ClipEnable((int)(x0 * Graphics()->ScreenWidth()), (int)(y0 * Graphics()->ScreenHeight()),
|
|
|
|
(int)((x1 - x0) * Graphics()->ScreenWidth()), (int)((y1 - y0) * Graphics()->ScreenHeight()));
|
2011-04-13 18:37:12 +00:00
|
|
|
}
|
|
|
|
|
2022-08-10 01:51:03 +00:00
|
|
|
RenderTools()->MapScreenToGroup(Center.x, Center.y, pGroup, pGroupEx, GetCurCamera()->m_Zoom);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
for(int l = 0; l < pGroup->m_NumLayers; l++)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
CMapItemLayer *pLayer = m_pLayers->GetLayer(pGroup->m_StartLayer + l);
|
2010-05-29 07:25:38 +00:00
|
|
|
bool Render = false;
|
|
|
|
bool IsGameLayer = false;
|
2011-03-16 17:48:16 +00:00
|
|
|
bool IsFrontLayer = false;
|
|
|
|
bool IsSwitchLayer = false;
|
|
|
|
bool IsTeleLayer = false;
|
|
|
|
bool IsSpeedupLayer = false;
|
2014-07-26 10:33:25 +00:00
|
|
|
bool IsTuneLayer = false;
|
2017-09-12 18:22:18 +00:00
|
|
|
bool IsEntityLayer = false;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(pLayer == (CMapItemLayer *)m_pLayers->GameLayer())
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
IsEntityLayer = IsGameLayer = true;
|
2015-10-05 10:51:19 +00:00
|
|
|
PassedGameLayer = true;
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(pLayer == (CMapItemLayer *)m_pLayers->FrontLayer())
|
2017-09-12 18:22:18 +00:00
|
|
|
IsEntityLayer = IsFrontLayer = true;
|
2011-03-16 17:48:16 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(pLayer == (CMapItemLayer *)m_pLayers->SwitchLayer())
|
2017-09-12 18:22:18 +00:00
|
|
|
IsEntityLayer = IsSwitchLayer = true;
|
2011-03-16 17:48:16 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(pLayer == (CMapItemLayer *)m_pLayers->TeleLayer())
|
2017-09-12 18:22:18 +00:00
|
|
|
IsEntityLayer = IsTeleLayer = true;
|
2011-03-16 17:48:16 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(pLayer == (CMapItemLayer *)m_pLayers->SpeedupLayer())
|
2017-09-12 18:22:18 +00:00
|
|
|
IsEntityLayer = IsSpeedupLayer = true;
|
2014-03-23 16:44:02 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(pLayer == (CMapItemLayer *)m_pLayers->TuneLayer())
|
2017-09-12 18:22:18 +00:00
|
|
|
IsEntityLayer = IsTuneLayer = true;
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_Type == -1)
|
|
|
|
Render = true;
|
2017-09-12 18:22:18 +00:00
|
|
|
else if(m_Type <= TYPE_BACKGROUND_FORCE)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(PassedGameLayer)
|
2008-08-27 15:48:50 +00:00
|
|
|
return;
|
2010-05-29 07:25:38 +00:00
|
|
|
Render = true;
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-13 18:33:58 +00:00
|
|
|
if(m_Type == TYPE_BACKGROUND_FORCE)
|
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
if(pLayer->m_Type == LAYERTYPE_TILES && !g_Config.m_ClBackgroundShowTilesLayers)
|
|
|
|
continue;
|
|
|
|
}
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
2020-09-18 16:45:42 +00:00
|
|
|
else if(m_Type == TYPE_FOREGROUND)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(PassedGameLayer && !IsGameLayer)
|
|
|
|
Render = true;
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
2020-09-18 16:45:42 +00:00
|
|
|
else if(m_Type == TYPE_FULL_DESIGN)
|
|
|
|
{
|
|
|
|
if(!IsGameLayer)
|
|
|
|
Render = true;
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2021-12-18 11:23:20 +00:00
|
|
|
if(Render && pLayer->m_Type == LAYERTYPE_TILES && Input()->ModifierIsPressed() && (Input()->KeyIsPressed(KEY_LSHIFT) || Input()->KeyIsPressed(KEY_RSHIFT)) && Input()->KeyPress(KEY_KP_0))
|
2010-05-29 07:25:38 +00:00
|
|
|
{
|
|
|
|
CMapItemLayerTilemap *pTMap = (CMapItemLayerTilemap *)pLayer;
|
|
|
|
CTile *pTiles = (CTile *)m_pLayers->Map()->GetData(pTMap->m_Data);
|
2010-09-07 00:06:11 +00:00
|
|
|
CServerInfo CurrentServerInfo;
|
|
|
|
Client()->GetServerInfo(&CurrentServerInfo);
|
2021-09-13 08:06:34 +00:00
|
|
|
char aFilename[IO_MAX_PATH_LENGTH];
|
2010-09-07 00:06:11 +00:00
|
|
|
str_format(aFilename, sizeof(aFilename), "dumps/tilelayer_dump_%s-%d-%d-%dx%d.txt", CurrentServerInfo.m_aMap, g, l, pTMap->m_Width, pTMap->m_Height);
|
2010-10-06 21:07:35 +00:00
|
|
|
IOHANDLE File = Storage()->OpenFile(aFilename, IOFLAG_WRITE, IStorage::TYPE_SAVE);
|
2010-09-07 00:06:11 +00:00
|
|
|
if(File)
|
2010-05-29 07:25:38 +00:00
|
|
|
{
|
2010-09-07 00:06:11 +00:00
|
|
|
for(int y = 0; y < pTMap->m_Height; y++)
|
|
|
|
{
|
|
|
|
for(int x = 0; x < pTMap->m_Width; x++)
|
2020-09-26 19:41:58 +00:00
|
|
|
io_write(File, &(pTiles[y * pTMap->m_Width + x].m_Index), sizeof(pTiles[y * pTMap->m_Width + x].m_Index));
|
2011-12-29 22:36:53 +00:00
|
|
|
io_write_newline(File);
|
2010-09-07 00:06:11 +00:00
|
|
|
}
|
|
|
|
io_close(File);
|
2010-05-29 07:25:38 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
}
|
|
|
|
|
2018-01-16 08:35:28 +00:00
|
|
|
if((Render || IsGameLayer) && pLayer->m_Type == LAYERTYPE_TILES)
|
2017-09-12 18:22:18 +00:00
|
|
|
{
|
|
|
|
CMapItemLayerTilemap *pTMap = (CMapItemLayerTilemap *)pLayer;
|
|
|
|
int DataIndex = 0;
|
2017-09-27 12:52:06 +00:00
|
|
|
unsigned int TileSize = 0;
|
2017-09-12 18:22:18 +00:00
|
|
|
int TileLayerAndOverlayCount = 0;
|
2018-01-16 08:35:28 +00:00
|
|
|
if(IsFrontLayer)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
DataIndex = pTMap->m_Front;
|
|
|
|
TileSize = sizeof(CTile);
|
|
|
|
TileLayerAndOverlayCount = 1;
|
|
|
|
}
|
2018-01-16 08:35:28 +00:00
|
|
|
else if(IsSwitchLayer)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
DataIndex = pTMap->m_Switch;
|
|
|
|
TileSize = sizeof(CSwitchTile);
|
|
|
|
TileLayerAndOverlayCount = 3;
|
|
|
|
}
|
2018-01-16 08:35:28 +00:00
|
|
|
else if(IsTeleLayer)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
DataIndex = pTMap->m_Tele;
|
|
|
|
TileSize = sizeof(CTeleTile);
|
|
|
|
TileLayerAndOverlayCount = 2;
|
|
|
|
}
|
2018-01-16 08:35:28 +00:00
|
|
|
else if(IsSpeedupLayer)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
DataIndex = pTMap->m_Speedup;
|
|
|
|
TileSize = sizeof(CSpeedupTile);
|
|
|
|
TileLayerAndOverlayCount = 3;
|
|
|
|
}
|
2018-01-16 08:35:28 +00:00
|
|
|
else if(IsTuneLayer)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
DataIndex = pTMap->m_Tune;
|
|
|
|
TileSize = sizeof(CTuneTile);
|
|
|
|
TileLayerAndOverlayCount = 1;
|
|
|
|
}
|
2017-09-13 18:33:58 +00:00
|
|
|
else
|
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
DataIndex = pTMap->m_Data;
|
|
|
|
TileSize = sizeof(CTile);
|
|
|
|
TileLayerAndOverlayCount = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int Size = m_pLayers->Map()->GetDataSize(DataIndex);
|
2020-09-26 19:41:58 +00:00
|
|
|
if(Size >= pTMap->m_Width * pTMap->m_Height * TileSize)
|
2017-09-12 18:22:18 +00:00
|
|
|
{
|
|
|
|
TileLayerCounter += TileLayerAndOverlayCount;
|
|
|
|
}
|
|
|
|
}
|
2018-03-13 20:57:46 +00:00
|
|
|
else if(Render && pLayer->m_Type == LAYERTYPE_QUADS)
|
|
|
|
{
|
|
|
|
++QuadLayerCounter;
|
|
|
|
}
|
2017-09-12 18:22:18 +00:00
|
|
|
|
|
|
|
// skip rendering if detail layers if not wanted, or is entity layer and we are a background map
|
2020-09-18 16:45:42 +00:00
|
|
|
if((pLayer->m_Flags & LAYERFLAG_DETAIL && (!g_Config.m_GfxHighDetail && !(m_Type == TYPE_FULL_DESIGN)) && !IsGameLayer) || (m_Type == TYPE_BACKGROUND_FORCE && IsEntityLayer) || (m_Type == TYPE_FULL_DESIGN && IsEntityLayer))
|
2017-09-12 18:22:18 +00:00
|
|
|
continue;
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2020-09-18 16:45:42 +00:00
|
|
|
int EntityOverlayVal = g_Config.m_ClOverlayEntities;
|
|
|
|
if(m_Type == TYPE_FULL_DESIGN)
|
|
|
|
EntityOverlayVal = 0;
|
|
|
|
|
|
|
|
if((Render && EntityOverlayVal < 100 && !IsGameLayer && !IsFrontLayer && !IsSwitchLayer && !IsTeleLayer && !IsSpeedupLayer && !IsTuneLayer) || (EntityOverlayVal && IsGameLayer) || (m_Type == TYPE_BACKGROUND_FORCE))
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(pLayer->m_Type == LAYERTYPE_TILES)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CMapItemLayerTilemap *pTMap = (CMapItemLayerTilemap *)pLayer;
|
|
|
|
if(pTMap->m_Image == -1)
|
2011-03-16 12:48:16 +00:00
|
|
|
{
|
2014-05-01 15:44:35 +00:00
|
|
|
if(!IsGameLayer)
|
2012-08-12 10:41:50 +00:00
|
|
|
Graphics()->TextureClear();
|
2011-03-16 12:48:16 +00:00
|
|
|
else
|
2020-09-08 13:11:32 +00:00
|
|
|
Graphics()->TextureSet(m_pImages->GetEntities(MAP_IMAGE_ENTITY_LAYER_TYPE_GAME));
|
2011-03-16 12:48:16 +00:00
|
|
|
}
|
2008-08-27 15:48:50 +00:00
|
|
|
else
|
2017-09-12 18:22:18 +00:00
|
|
|
Graphics()->TextureSet(m_pImages->Get(pTMap->m_Image));
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
CTile *pTiles = (CTile *)m_pLayers->Map()->GetData(pTMap->m_Data);
|
2017-08-30 06:36:17 +00:00
|
|
|
unsigned int Size = m_pLayers->Map()->GetDataSize(pTMap->m_Data);
|
2014-02-10 18:19:49 +00:00
|
|
|
|
2020-10-05 17:03:14 +00:00
|
|
|
if(Size >= (size_t)pTMap->m_Width * pTMap->m_Height * sizeof(CTile))
|
2014-02-10 18:19:49 +00:00
|
|
|
{
|
2020-09-18 16:45:42 +00:00
|
|
|
ColorRGBA Color = ColorRGBA(pTMap->m_Color.r / 255.0f, pTMap->m_Color.g / 255.0f, pTMap->m_Color.b / 255.0f, pTMap->m_Color.a / 255.0f);
|
|
|
|
if(IsGameLayer && EntityOverlayVal)
|
|
|
|
Color = ColorRGBA(pTMap->m_Color.r / 255.0f, pTMap->m_Color.g / 255.0f, pTMap->m_Color.b / 255.0f, pTMap->m_Color.a / 255.0f * EntityOverlayVal / 100.0f);
|
|
|
|
else if(!IsGameLayer && EntityOverlayVal && !(m_Type == TYPE_BACKGROUND_FORCE))
|
|
|
|
Color = ColorRGBA(pTMap->m_Color.r / 255.0f, pTMap->m_Color.g / 255.0f, pTMap->m_Color.b / 255.0f, pTMap->m_Color.a / 255.0f * (100 - EntityOverlayVal) / 100.0f);
|
2020-08-29 10:10:38 +00:00
|
|
|
if(!Graphics()->IsTileBufferingEnabled())
|
2018-03-13 20:57:46 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
Graphics()->BlendNone();
|
2020-09-26 19:41:58 +00:00
|
|
|
RenderTools()->RenderTilemap(pTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND | LAYERRENDERFLAG_OPAQUE,
|
|
|
|
EnvelopeEval, this, pTMap->m_ColorEnv, pTMap->m_ColorEnvOffset);
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-12 18:22:18 +00:00
|
|
|
Graphics()->BlendNormal();
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-09-12 18:22:18 +00:00
|
|
|
// draw kill tiles outside the entity clipping rectangle
|
|
|
|
if(IsGameLayer)
|
2019-03-26 18:15:24 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
// slow blinking to hint that it's not a part of the map
|
2020-09-26 19:41:58 +00:00
|
|
|
double Seconds = time_get() / (double)time_freq();
|
2022-03-23 18:34:51 +00:00
|
|
|
ColorRGBA ColorHint = ColorRGBA(1.0f, 1.0f, 1.0f, 0.3 + 0.7 * (1 + sin(2 * (double)pi * Seconds / 3)) / 2);
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
RenderTools()->RenderTileRectangle(-201, -201, pTMap->m_Width + 402, pTMap->m_Height + 402,
|
|
|
|
0, TILE_DEATH, // display air inside, death outside
|
|
|
|
32.0f, Color.v4() * ColorHint.v4(), TILERENDERFLAG_EXTEND | LAYERRENDERFLAG_TRANSPARENT,
|
|
|
|
EnvelopeEval, this, pTMap->m_ColorEnv, pTMap->m_ColorEnvOffset);
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
RenderTools()->RenderTilemap(pTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND | LAYERRENDERFLAG_TRANSPARENT,
|
|
|
|
EnvelopeEval, this, pTMap->m_ColorEnv, pTMap->m_ColorEnvOffset);
|
2020-08-29 10:10:38 +00:00
|
|
|
}
|
|
|
|
else
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
Graphics()->BlendNormal();
|
|
|
|
// draw kill tiles outside the entity clipping rectangle
|
2018-01-16 08:35:28 +00:00
|
|
|
if(IsGameLayer)
|
2017-09-12 18:22:18 +00:00
|
|
|
{
|
|
|
|
// slow blinking to hint that it's not a part of the map
|
|
|
|
double Seconds = time_get() / (double)time_freq();
|
2022-03-23 18:34:51 +00:00
|
|
|
ColorRGBA ColorHint = ColorRGBA(1.0f, 1.0f, 1.0f, 0.3 + 0.7 * (1.0 + sin(2 * (double)pi * Seconds / 3)) / 2);
|
2017-09-12 18:22:18 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
ColorRGBA ColorKill(Color.x * ColorHint.x, Color.y * ColorHint.y, Color.z * ColorHint.z, Color.w * ColorHint.w);
|
2022-07-01 04:42:36 +00:00
|
|
|
RenderKillTileBorder(TileLayerCounter - 1, ColorKill, pTMap, pGroup);
|
2019-03-26 18:15:24 +00:00
|
|
|
}
|
2022-07-01 04:42:36 +00:00
|
|
|
RenderTileLayer(TileLayerCounter - 1, Color, pTMap, pGroup);
|
2017-03-15 11:06:13 +00:00
|
|
|
}
|
2014-02-10 18:19:49 +00:00
|
|
|
}
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
2010-05-29 07:25:38 +00:00
|
|
|
else if(pLayer->m_Type == LAYERTYPE_QUADS)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CMapItemLayerQuads *pQLayer = (CMapItemLayerQuads *)pLayer;
|
|
|
|
if(pQLayer->m_Image == -1)
|
2012-08-12 10:41:50 +00:00
|
|
|
Graphics()->TextureClear();
|
2008-08-27 15:48:50 +00:00
|
|
|
else
|
2017-09-12 18:22:18 +00:00
|
|
|
Graphics()->TextureSet(m_pImages->Get(pQLayer->m_Image));
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
CQuad *pQuads = (CQuad *)m_pLayers->Map()->GetDataSwapped(pQLayer->m_Data);
|
2020-09-18 16:45:42 +00:00
|
|
|
if(m_Type == TYPE_BACKGROUND_FORCE || m_Type == TYPE_FULL_DESIGN)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2020-09-18 16:45:42 +00:00
|
|
|
if(g_Config.m_ClShowQuads || m_Type == TYPE_FULL_DESIGN)
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2020-08-29 10:10:38 +00:00
|
|
|
if(!Graphics()->IsQuadBufferingEnabled())
|
2018-03-13 20:57:46 +00:00
|
|
|
{
|
|
|
|
//Graphics()->BlendNone();
|
|
|
|
//RenderTools()->ForceRenderQuads(pQuads, pQLayer->m_NumQuads, LAYERRENDERFLAG_OPAQUE, EnvelopeEval, this, 1.f);
|
|
|
|
Graphics()->BlendNormal();
|
|
|
|
RenderTools()->ForceRenderQuads(pQuads, pQLayer->m_NumQuads, LAYERRENDERFLAG_TRANSPARENT, EnvelopeEval, this, 1.f);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
RenderQuadLayer(QuadLayerCounter - 1, pQLayer, pGroup, true);
|
2018-03-13 20:57:46 +00:00
|
|
|
}
|
2019-03-26 18:15:24 +00:00
|
|
|
}
|
2020-09-18 16:45:42 +00:00
|
|
|
}
|
|
|
|
else
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2020-08-29 10:10:38 +00:00
|
|
|
if(!Graphics()->IsQuadBufferingEnabled())
|
2018-03-13 20:57:46 +00:00
|
|
|
{
|
|
|
|
//Graphics()->BlendNone();
|
|
|
|
//RenderTools()->RenderQuads(pQuads, pQLayer->m_NumQuads, LAYERRENDERFLAG_OPAQUE, EnvelopeEval, this);
|
|
|
|
Graphics()->BlendNormal();
|
|
|
|
RenderTools()->RenderQuads(pQuads, pQLayer->m_NumQuads, LAYERRENDERFLAG_TRANSPARENT, EnvelopeEval, this);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
RenderQuadLayer(QuadLayerCounter - 1, pQLayer, pGroup, false);
|
2018-03-13 20:57:46 +00:00
|
|
|
}
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
|
|
|
}
|
2020-09-18 16:45:42 +00:00
|
|
|
else if(Render && EntityOverlayVal && IsFrontLayer)
|
2011-04-19 14:32:42 +00:00
|
|
|
{
|
|
|
|
CMapItemLayerTilemap *pTMap = (CMapItemLayerTilemap *)pLayer;
|
2020-09-08 13:11:32 +00:00
|
|
|
Graphics()->TextureSet(m_pImages->GetEntities(MAP_IMAGE_ENTITY_LAYER_TYPE_FRONT));
|
2011-04-19 14:32:42 +00:00
|
|
|
|
|
|
|
CTile *pFrontTiles = (CTile *)m_pLayers->Map()->GetData(pTMap->m_Front);
|
2017-08-30 06:36:17 +00:00
|
|
|
unsigned int Size = m_pLayers->Map()->GetDataSize(pTMap->m_Front);
|
2014-02-10 18:19:49 +00:00
|
|
|
|
2020-10-05 17:03:14 +00:00
|
|
|
if(Size >= (size_t)pTMap->m_Width * pTMap->m_Height * sizeof(CTile))
|
2014-02-10 18:19:49 +00:00
|
|
|
{
|
2020-09-18 16:45:42 +00:00
|
|
|
ColorRGBA Color = ColorRGBA(pTMap->m_Color.r / 255.0f, pTMap->m_Color.g / 255.0f, pTMap->m_Color.b / 255.0f, pTMap->m_Color.a / 255.0f * EntityOverlayVal / 100.0f);
|
2020-08-29 10:10:38 +00:00
|
|
|
if(!Graphics()->IsTileBufferingEnabled())
|
2019-03-26 18:15:24 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
Graphics()->BlendNone();
|
2020-09-26 19:41:58 +00:00
|
|
|
RenderTools()->RenderTilemap(pFrontTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND | LAYERRENDERFLAG_OPAQUE,
|
|
|
|
EnvelopeEval, this, pTMap->m_ColorEnv, pTMap->m_ColorEnvOffset);
|
2017-09-12 18:22:18 +00:00
|
|
|
Graphics()->BlendNormal();
|
2020-09-26 19:41:58 +00:00
|
|
|
RenderTools()->RenderTilemap(pFrontTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND | LAYERRENDERFLAG_TRANSPARENT,
|
|
|
|
EnvelopeEval, this, pTMap->m_ColorEnv, pTMap->m_ColorEnvOffset);
|
2019-03-26 18:15:24 +00:00
|
|
|
}
|
2017-09-27 12:52:06 +00:00
|
|
|
else
|
|
|
|
{
|
2019-03-26 18:15:24 +00:00
|
|
|
Graphics()->BlendNormal();
|
2022-07-01 04:42:36 +00:00
|
|
|
RenderTileLayer(TileLayerCounter - 1, Color, pTMap, pGroup);
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2014-02-10 18:19:49 +00:00
|
|
|
}
|
2011-04-19 14:32:42 +00:00
|
|
|
}
|
2020-09-18 16:45:42 +00:00
|
|
|
else if(Render && EntityOverlayVal && IsSwitchLayer)
|
2011-04-19 14:32:42 +00:00
|
|
|
{
|
|
|
|
CMapItemLayerTilemap *pTMap = (CMapItemLayerTilemap *)pLayer;
|
2020-09-08 13:11:32 +00:00
|
|
|
Graphics()->TextureSet(m_pImages->GetEntities(MAP_IMAGE_ENTITY_LAYER_TYPE_SWITCH));
|
2011-04-19 14:32:42 +00:00
|
|
|
|
|
|
|
CSwitchTile *pSwitchTiles = (CSwitchTile *)m_pLayers->Map()->GetData(pTMap->m_Switch);
|
2017-08-30 06:36:17 +00:00
|
|
|
unsigned int Size = m_pLayers->Map()->GetDataSize(pTMap->m_Switch);
|
2014-02-10 18:19:49 +00:00
|
|
|
|
2020-10-05 17:03:14 +00:00
|
|
|
if(Size >= (size_t)pTMap->m_Width * pTMap->m_Height * sizeof(CSwitchTile))
|
2014-02-10 18:19:49 +00:00
|
|
|
{
|
2020-09-18 16:45:42 +00:00
|
|
|
ColorRGBA Color = ColorRGBA(pTMap->m_Color.r / 255.0f, pTMap->m_Color.g / 255.0f, pTMap->m_Color.b / 255.0f, pTMap->m_Color.a / 255.0f * EntityOverlayVal / 100.0f);
|
2020-08-29 10:10:38 +00:00
|
|
|
if(!Graphics()->IsTileBufferingEnabled())
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
Graphics()->BlendNone();
|
2020-09-26 19:41:58 +00:00
|
|
|
RenderTools()->RenderSwitchmap(pSwitchTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND | LAYERRENDERFLAG_OPAQUE);
|
2017-09-12 18:22:18 +00:00
|
|
|
Graphics()->BlendNormal();
|
2020-09-18 16:45:42 +00:00
|
|
|
RenderTools()->RenderSwitchmap(pSwitchTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND | LAYERRENDERFLAG_TRANSPARENT);
|
|
|
|
RenderTools()->RenderSwitchOverlay(pSwitchTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, EntityOverlayVal / 100.0f);
|
2019-03-26 18:15:24 +00:00
|
|
|
}
|
2017-09-27 12:52:06 +00:00
|
|
|
else
|
|
|
|
{
|
2019-03-26 18:15:24 +00:00
|
|
|
Graphics()->BlendNormal();
|
2022-07-01 04:42:36 +00:00
|
|
|
RenderTileLayer(TileLayerCounter - 3, Color, pTMap, pGroup);
|
2017-09-27 10:20:23 +00:00
|
|
|
if(g_Config.m_ClTextEntities)
|
|
|
|
{
|
|
|
|
Graphics()->TextureSet(m_pImages->GetOverlayBottom());
|
2022-07-01 04:42:36 +00:00
|
|
|
RenderTileLayer(TileLayerCounter - 2, Color, pTMap, pGroup);
|
2017-09-27 10:20:23 +00:00
|
|
|
Graphics()->TextureSet(m_pImages->GetOverlayTop());
|
2022-07-01 04:42:36 +00:00
|
|
|
RenderTileLayer(TileLayerCounter - 1, Color, pTMap, pGroup);
|
2017-09-27 10:20:23 +00:00
|
|
|
}
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2014-02-10 18:19:49 +00:00
|
|
|
}
|
2011-04-19 14:32:42 +00:00
|
|
|
}
|
2020-09-18 16:45:42 +00:00
|
|
|
else if(Render && EntityOverlayVal && IsTeleLayer)
|
2011-04-19 14:32:42 +00:00
|
|
|
{
|
|
|
|
CMapItemLayerTilemap *pTMap = (CMapItemLayerTilemap *)pLayer;
|
2020-09-08 13:11:32 +00:00
|
|
|
Graphics()->TextureSet(m_pImages->GetEntities(MAP_IMAGE_ENTITY_LAYER_TYPE_TELE));
|
2011-04-19 14:32:42 +00:00
|
|
|
|
|
|
|
CTeleTile *pTeleTiles = (CTeleTile *)m_pLayers->Map()->GetData(pTMap->m_Tele);
|
2017-08-30 06:36:17 +00:00
|
|
|
unsigned int Size = m_pLayers->Map()->GetDataSize(pTMap->m_Tele);
|
2014-02-10 18:19:49 +00:00
|
|
|
|
2020-10-05 17:03:14 +00:00
|
|
|
if(Size >= (size_t)pTMap->m_Width * pTMap->m_Height * sizeof(CTeleTile))
|
2014-02-10 18:19:49 +00:00
|
|
|
{
|
2020-09-18 16:45:42 +00:00
|
|
|
ColorRGBA Color = ColorRGBA(pTMap->m_Color.r / 255.0f, pTMap->m_Color.g / 255.0f, pTMap->m_Color.b / 255.0f, pTMap->m_Color.a / 255.0f * EntityOverlayVal / 100.0f);
|
2020-08-29 10:10:38 +00:00
|
|
|
if(!Graphics()->IsTileBufferingEnabled())
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
Graphics()->BlendNone();
|
2020-09-26 19:41:58 +00:00
|
|
|
RenderTools()->RenderTelemap(pTeleTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND | LAYERRENDERFLAG_OPAQUE);
|
2017-09-12 18:22:18 +00:00
|
|
|
Graphics()->BlendNormal();
|
2020-09-18 16:45:42 +00:00
|
|
|
RenderTools()->RenderTelemap(pTeleTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND | LAYERRENDERFLAG_TRANSPARENT);
|
|
|
|
RenderTools()->RenderTeleOverlay(pTeleTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, EntityOverlayVal / 100.0f);
|
2017-09-27 12:52:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
Graphics()->BlendNormal();
|
2022-07-01 04:42:36 +00:00
|
|
|
RenderTileLayer(TileLayerCounter - 2, Color, pTMap, pGroup);
|
2017-09-27 10:20:23 +00:00
|
|
|
if(g_Config.m_ClTextEntities)
|
|
|
|
{
|
|
|
|
Graphics()->TextureSet(m_pImages->GetOverlayCenter());
|
2022-07-01 04:42:36 +00:00
|
|
|
RenderTileLayer(TileLayerCounter - 1, Color, pTMap, pGroup);
|
2017-09-27 10:20:23 +00:00
|
|
|
}
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2014-02-10 18:19:49 +00:00
|
|
|
}
|
2011-04-19 14:32:42 +00:00
|
|
|
}
|
2020-09-18 16:45:42 +00:00
|
|
|
else if(Render && EntityOverlayVal && IsSpeedupLayer)
|
2011-04-19 14:32:42 +00:00
|
|
|
{
|
|
|
|
CMapItemLayerTilemap *pTMap = (CMapItemLayerTilemap *)pLayer;
|
2020-09-08 13:11:32 +00:00
|
|
|
Graphics()->TextureSet(m_pImages->GetEntities(MAP_IMAGE_ENTITY_LAYER_TYPE_SPEEDUP));
|
2011-04-19 14:32:42 +00:00
|
|
|
|
|
|
|
CSpeedupTile *pSpeedupTiles = (CSpeedupTile *)m_pLayers->Map()->GetData(pTMap->m_Speedup);
|
2017-08-30 06:36:17 +00:00
|
|
|
unsigned int Size = m_pLayers->Map()->GetDataSize(pTMap->m_Speedup);
|
2014-02-10 18:19:49 +00:00
|
|
|
|
2020-10-05 17:03:14 +00:00
|
|
|
if(Size >= (size_t)pTMap->m_Width * pTMap->m_Height * sizeof(CSpeedupTile))
|
2014-02-10 18:19:49 +00:00
|
|
|
{
|
2020-09-18 16:45:42 +00:00
|
|
|
ColorRGBA Color = ColorRGBA(pTMap->m_Color.r / 255.0f, pTMap->m_Color.g / 255.0f, pTMap->m_Color.b / 255.0f, pTMap->m_Color.a / 255.0f * EntityOverlayVal / 100.0f);
|
2020-08-29 10:10:38 +00:00
|
|
|
if(!Graphics()->IsTileBufferingEnabled())
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
Graphics()->BlendNone();
|
2020-09-26 19:41:58 +00:00
|
|
|
RenderTools()->RenderSpeedupmap(pSpeedupTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND | LAYERRENDERFLAG_OPAQUE);
|
2017-09-12 18:22:18 +00:00
|
|
|
Graphics()->BlendNormal();
|
2020-09-18 16:45:42 +00:00
|
|
|
RenderTools()->RenderSpeedupmap(pSpeedupTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND | LAYERRENDERFLAG_TRANSPARENT);
|
|
|
|
RenderTools()->RenderSpeedupOverlay(pSpeedupTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, EntityOverlayVal / 100.0f);
|
2019-03-26 18:15:24 +00:00
|
|
|
}
|
2017-09-27 12:52:06 +00:00
|
|
|
else
|
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
Graphics()->BlendNormal();
|
2019-03-26 18:15:24 +00:00
|
|
|
|
2017-10-10 10:08:36 +00:00
|
|
|
// draw arrow -- clamp to the edge of the arrow image
|
|
|
|
Graphics()->WrapClamp();
|
2020-08-29 10:10:38 +00:00
|
|
|
Graphics()->TextureSet(m_pImages->GetSpeedupArrow());
|
2022-07-01 04:42:36 +00:00
|
|
|
RenderTileLayer(TileLayerCounter - 3, Color, pTMap, pGroup);
|
2017-10-10 10:08:36 +00:00
|
|
|
Graphics()->WrapNormal();
|
2017-09-27 10:20:23 +00:00
|
|
|
if(g_Config.m_ClTextEntities)
|
|
|
|
{
|
|
|
|
Graphics()->TextureSet(m_pImages->GetOverlayBottom());
|
2022-07-01 04:42:36 +00:00
|
|
|
RenderTileLayer(TileLayerCounter - 2, Color, pTMap, pGroup);
|
2017-09-27 10:20:23 +00:00
|
|
|
Graphics()->TextureSet(m_pImages->GetOverlayTop());
|
2022-07-01 04:42:36 +00:00
|
|
|
RenderTileLayer(TileLayerCounter - 1, Color, pTMap, pGroup);
|
2017-09-27 10:20:23 +00:00
|
|
|
}
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2014-02-10 18:19:49 +00:00
|
|
|
}
|
2011-04-19 14:32:42 +00:00
|
|
|
}
|
2020-09-18 16:45:42 +00:00
|
|
|
else if(Render && EntityOverlayVal && IsTuneLayer)
|
2014-03-12 23:11:25 +00:00
|
|
|
{
|
|
|
|
CMapItemLayerTilemap *pTMap = (CMapItemLayerTilemap *)pLayer;
|
2020-09-08 13:11:32 +00:00
|
|
|
Graphics()->TextureSet(m_pImages->GetEntities(MAP_IMAGE_ENTITY_LAYER_TYPE_TUNE));
|
2014-03-12 23:11:25 +00:00
|
|
|
|
|
|
|
CTuneTile *pTuneTiles = (CTuneTile *)m_pLayers->Map()->GetData(pTMap->m_Tune);
|
2017-08-30 06:36:17 +00:00
|
|
|
unsigned int Size = m_pLayers->Map()->GetDataSize(pTMap->m_Tune);
|
2014-03-12 23:11:25 +00:00
|
|
|
|
2020-10-05 17:03:14 +00:00
|
|
|
if(Size >= (size_t)pTMap->m_Width * pTMap->m_Height * sizeof(CTuneTile))
|
2014-03-12 23:11:25 +00:00
|
|
|
{
|
2020-09-18 16:45:42 +00:00
|
|
|
ColorRGBA Color = ColorRGBA(pTMap->m_Color.r / 255.0f, pTMap->m_Color.g / 255.0f, pTMap->m_Color.b / 255.0f, pTMap->m_Color.a / 255.0f * EntityOverlayVal / 100.0f);
|
2020-08-29 10:10:38 +00:00
|
|
|
if(!Graphics()->IsTileBufferingEnabled())
|
2017-09-13 18:33:58 +00:00
|
|
|
{
|
2017-09-12 18:22:18 +00:00
|
|
|
Graphics()->BlendNone();
|
2020-09-26 19:41:58 +00:00
|
|
|
RenderTools()->RenderTunemap(pTuneTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND | LAYERRENDERFLAG_OPAQUE);
|
2017-09-12 18:22:18 +00:00
|
|
|
Graphics()->BlendNormal();
|
2020-09-18 16:45:42 +00:00
|
|
|
RenderTools()->RenderTunemap(pTuneTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, Color, TILERENDERFLAG_EXTEND | LAYERRENDERFLAG_TRANSPARENT);
|
|
|
|
//RenderTools()->RenderTuneOverlay(pTuneTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, EntityOverlayVal/100.0f);
|
2019-03-26 18:15:24 +00:00
|
|
|
}
|
2017-09-27 12:52:06 +00:00
|
|
|
else
|
|
|
|
{
|
2019-03-26 18:15:24 +00:00
|
|
|
Graphics()->BlendNormal();
|
2022-07-01 04:42:36 +00:00
|
|
|
RenderTileLayer(TileLayerCounter - 1, Color, pTMap, pGroup);
|
2017-09-12 18:22:18 +00:00
|
|
|
}
|
2014-03-12 23:11:25 +00:00
|
|
|
}
|
|
|
|
}
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
2020-09-18 16:45:42 +00:00
|
|
|
if(!g_Config.m_GfxNoclip || m_Type == TYPE_FULL_DESIGN)
|
2009-10-27 14:38:53 +00:00
|
|
|
Graphics()->ClipDisable();
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2020-09-18 16:45:42 +00:00
|
|
|
if(!g_Config.m_GfxNoclip || m_Type == TYPE_FULL_DESIGN)
|
2009-10-27 14:38:53 +00:00
|
|
|
Graphics()->ClipDisable();
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2009-01-12 14:43:39 +00:00
|
|
|
// reset the screen like it was before
|
2010-05-29 07:25:38 +00:00
|
|
|
Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h);
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|