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. */
|
2010-05-29 07:25:38 +00:00
|
|
|
#include <base/math.h>
|
2022-06-17 17:26:59 +00:00
|
|
|
|
2022-02-14 23:32:04 +00:00
|
|
|
#include <engine/graphics.h>
|
2022-06-17 17:26:59 +00:00
|
|
|
#include <engine/textrender.h>
|
|
|
|
|
|
|
|
#include <engine/shared/config.h>
|
2008-08-30 21:09:13 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
#include "render.h"
|
2008-01-12 17:09:00 +00:00
|
|
|
|
2010-09-30 21:31:19 +00:00
|
|
|
#include <game/generated/client_data.h>
|
2008-08-30 21:09:13 +00:00
|
|
|
|
2022-06-17 17:26:59 +00:00
|
|
|
#include <game/mapitems.h>
|
|
|
|
|
2022-05-18 16:00:05 +00:00
|
|
|
#include <chrono>
|
2022-06-17 17:26:59 +00:00
|
|
|
#include <cmath>
|
2022-05-18 16:00:05 +00:00
|
|
|
|
|
|
|
using namespace std::chrono_literals;
|
|
|
|
|
2022-07-01 04:42:36 +00:00
|
|
|
void CRenderTools::RenderEvalEnvelope(CEnvPoint *pPoints, int NumPoints, int Channels, std::chrono::nanoseconds TimeNanos, ColorRGBA &Result)
|
2008-01-17 23:09:49 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(NumPoints == 0)
|
2008-01-17 23:09:49 +00:00
|
|
|
{
|
2022-07-01 04:42:36 +00:00
|
|
|
Result = ColorRGBA();
|
2008-01-17 23:09:49 +00:00
|
|
|
return;
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(NumPoints == 1)
|
2008-01-17 23:09:49 +00:00
|
|
|
{
|
2022-07-01 04:42:36 +00:00
|
|
|
Result.r = fx2f(pPoints[0].m_aValues[0]);
|
|
|
|
Result.g = fx2f(pPoints[0].m_aValues[1]);
|
|
|
|
Result.b = fx2f(pPoints[0].m_aValues[2]);
|
|
|
|
Result.a = fx2f(pPoints[0].m_aValues[3]);
|
2008-01-17 23:09:49 +00:00
|
|
|
return;
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2022-05-18 16:00:05 +00:00
|
|
|
int64_t MaxPointTime = (int64_t)pPoints[NumPoints - 1].m_Time * std::chrono::nanoseconds(1ms).count();
|
2020-11-17 17:01:23 +00:00
|
|
|
if(MaxPointTime > 0) // TODO: remove this check when implementing a IO check for maps(in this case broken envelopes)
|
2022-05-22 14:04:50 +00:00
|
|
|
TimeNanos = std::chrono::nanoseconds(TimeNanos.count() % MaxPointTime);
|
2020-11-17 17:01:23 +00:00
|
|
|
else
|
2022-05-22 14:04:50 +00:00
|
|
|
TimeNanos = decltype(TimeNanos)::zero();
|
2020-10-04 00:30:36 +00:00
|
|
|
|
2022-05-22 14:04:50 +00:00
|
|
|
int TimeMillis = (int)(TimeNanos / std::chrono::nanoseconds(1ms).count()).count();
|
2020-09-26 19:41:58 +00:00
|
|
|
for(int i = 0; i < NumPoints - 1; i++)
|
2008-01-17 23:09:49 +00:00
|
|
|
{
|
2020-10-04 00:30:36 +00:00
|
|
|
if(TimeMillis >= pPoints[i].m_Time && TimeMillis <= pPoints[i + 1].m_Time)
|
2008-01-17 23:09:49 +00:00
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
float Delta = pPoints[i + 1].m_Time - pPoints[i].m_Time;
|
2022-05-22 14:04:50 +00:00
|
|
|
float a = (float)(((double)TimeNanos.count() / (double)std::chrono::nanoseconds(1ms).count()) - pPoints[i].m_Time) / Delta;
|
2008-01-17 23:09:49 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(pPoints[i].m_Curvetype == CURVETYPE_SMOOTH)
|
2020-09-26 19:41:58 +00:00
|
|
|
a = -2 * a * a * a + 3 * a * a; // second hermite basis
|
2010-05-29 07:25:38 +00:00
|
|
|
else if(pPoints[i].m_Curvetype == CURVETYPE_SLOW)
|
2020-09-26 19:41:58 +00:00
|
|
|
a = a * a * a;
|
2010-05-29 07:25:38 +00:00
|
|
|
else if(pPoints[i].m_Curvetype == CURVETYPE_FAST)
|
2008-01-17 23:09:49 +00:00
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
a = 1 - a;
|
|
|
|
a = 1 - a * a * a;
|
2008-01-17 23:09:49 +00:00
|
|
|
}
|
2020-09-26 19:41:58 +00:00
|
|
|
else if(pPoints[i].m_Curvetype == CURVETYPE_STEP)
|
2008-01-17 23:09:49 +00:00
|
|
|
a = 0;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// linear
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
for(int c = 0; c < Channels; c++)
|
2008-01-17 23:09:49 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
float v0 = fx2f(pPoints[i].m_aValues[c]);
|
2020-09-26 19:41:58 +00:00
|
|
|
float v1 = fx2f(pPoints[i + 1].m_aValues[c]);
|
2022-07-01 04:42:36 +00:00
|
|
|
Result[c] = v0 + (v1 - v0) * a;
|
2008-01-17 23:09:49 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2008-01-17 23:09:49 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2022-07-01 04:42:36 +00:00
|
|
|
Result.r = fx2f(pPoints[NumPoints - 1].m_aValues[0]);
|
|
|
|
Result.g = fx2f(pPoints[NumPoints - 1].m_aValues[1]);
|
|
|
|
Result.b = fx2f(pPoints[NumPoints - 1].m_aValues[2]);
|
|
|
|
Result.a = fx2f(pPoints[NumPoints - 1].m_aValues[3]);
|
2008-01-17 23:09:49 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
static void Rotate(CPoint *pCenter, CPoint *pPoint, float Rotation)
|
2008-01-12 17:09:00 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
int x = pPoint->x - pCenter->x;
|
|
|
|
int y = pPoint->y - pCenter->y;
|
|
|
|
pPoint->x = (int)(x * cosf(Rotation) - y * sinf(Rotation) + pCenter->x);
|
|
|
|
pPoint->y = (int)(x * sinf(Rotation) + y * cosf(Rotation) + pCenter->y);
|
2008-01-12 17:09:00 +00:00
|
|
|
}
|
|
|
|
|
2011-07-18 10:05:12 +00:00
|
|
|
void CRenderTools::RenderQuads(CQuad *pQuads, int NumQuads, int RenderFlags, ENVELOPE_EVAL pfnEval, void *pUser)
|
2008-01-12 17:09:00 +00:00
|
|
|
{
|
2014-05-01 15:44:35 +00:00
|
|
|
if(!g_Config.m_ClShowQuads || g_Config.m_ClOverlayEntities == 100)
|
2011-04-17 09:27:46 +00:00
|
|
|
return;
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
ForceRenderQuads(pQuads, NumQuads, RenderFlags, pfnEval, pUser, (100 - g_Config.m_ClOverlayEntities) / 100.0f);
|
2014-01-11 21:57:23 +00:00
|
|
|
}
|
|
|
|
|
2014-05-08 13:58:59 +00:00
|
|
|
void CRenderTools::ForceRenderQuads(CQuad *pQuads, int NumQuads, int RenderFlags, ENVELOPE_EVAL pfnEval, void *pUser, float Alpha)
|
2014-01-11 21:57:23 +00:00
|
|
|
{
|
2020-10-20 17:11:19 +00:00
|
|
|
Graphics()->TrianglesBegin();
|
2020-09-26 19:41:58 +00:00
|
|
|
float Conv = 1 / 255.0f;
|
2010-05-29 07:25:38 +00:00
|
|
|
for(int i = 0; i < NumQuads; i++)
|
2008-01-12 17:09:00 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CQuad *q = &pQuads[i];
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2022-07-01 04:42:36 +00:00
|
|
|
ColorRGBA Color(1.f, 1.f, 1.f, 1.f);
|
2010-05-29 07:25:38 +00:00
|
|
|
if(q->m_ColorEnv >= 0)
|
2008-03-29 11:44:03 +00:00
|
|
|
{
|
2022-07-01 04:42:36 +00:00
|
|
|
pfnEval(q->m_ColorEnvOffset, q->m_ColorEnv, Color, pUser);
|
2011-04-13 18:37:12 +00:00
|
|
|
}
|
|
|
|
|
2022-07-01 04:42:36 +00:00
|
|
|
if(Color.a <= 0)
|
2020-12-29 13:31:42 +00:00
|
|
|
continue;
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
bool Opaque = false;
|
2012-08-13 10:57:40 +00:00
|
|
|
/* TODO: Analyze quadtexture
|
2010-05-29 07:25:38 +00:00
|
|
|
if(a < 0.01f || (q->m_aColors[0].a < 0.01f && q->m_aColors[1].a < 0.01f && q->m_aColors[2].a < 0.01f && q->m_aColors[3].a < 0.01f))
|
|
|
|
Opaque = true;
|
2012-08-13 10:57:40 +00:00
|
|
|
*/
|
2020-09-26 19:41:58 +00:00
|
|
|
if(Opaque && !(RenderFlags & LAYERRENDERFLAG_OPAQUE))
|
2008-03-29 11:44:03 +00:00
|
|
|
continue;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(!Opaque && !(RenderFlags & LAYERRENDERFLAG_TRANSPARENT))
|
2008-03-29 11:44:03 +00:00
|
|
|
continue;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2009-10-27 14:38:53 +00:00
|
|
|
Graphics()->QuadsSetSubsetFree(
|
2010-05-29 07:25:38 +00:00
|
|
|
fx2f(q->m_aTexcoords[0].x), fx2f(q->m_aTexcoords[0].y),
|
|
|
|
fx2f(q->m_aTexcoords[1].x), fx2f(q->m_aTexcoords[1].y),
|
|
|
|
fx2f(q->m_aTexcoords[2].x), fx2f(q->m_aTexcoords[2].y),
|
2020-09-26 19:41:58 +00:00
|
|
|
fx2f(q->m_aTexcoords[3].x), fx2f(q->m_aTexcoords[3].y));
|
2008-01-12 17:09:00 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
float OffsetX = 0;
|
|
|
|
float OffsetY = 0;
|
|
|
|
float Rot = 0;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2008-01-12 17:09:00 +00:00
|
|
|
// TODO: fix this
|
2010-05-29 07:25:38 +00:00
|
|
|
if(q->m_PosEnv >= 0)
|
2008-01-12 17:09:00 +00:00
|
|
|
{
|
2022-07-01 04:42:36 +00:00
|
|
|
ColorRGBA Channels;
|
|
|
|
pfnEval(q->m_PosEnvOffset, q->m_PosEnv, Channels, pUser);
|
|
|
|
OffsetX = Channels.r;
|
|
|
|
OffsetY = Channels.g;
|
|
|
|
Rot = Channels.b / 360.0f * pi * 2;
|
2008-01-17 23:09:49 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
IGraphics::CColorVertex Array[4] = {
|
2022-07-01 04:42:36 +00:00
|
|
|
IGraphics::CColorVertex(0, q->m_aColors[0].r * Conv * Color.r, q->m_aColors[0].g * Conv * Color.g, q->m_aColors[0].b * Conv * Color.b, q->m_aColors[0].a * Conv * Color.a * Alpha),
|
|
|
|
IGraphics::CColorVertex(1, q->m_aColors[1].r * Conv * Color.r, q->m_aColors[1].g * Conv * Color.g, q->m_aColors[1].b * Conv * Color.b, q->m_aColors[1].a * Conv * Color.a * Alpha),
|
|
|
|
IGraphics::CColorVertex(2, q->m_aColors[2].r * Conv * Color.r, q->m_aColors[2].g * Conv * Color.g, q->m_aColors[2].b * Conv * Color.b, q->m_aColors[2].a * Conv * Color.a * Alpha),
|
|
|
|
IGraphics::CColorVertex(3, q->m_aColors[3].r * Conv * Color.r, q->m_aColors[3].g * Conv * Color.g, q->m_aColors[3].b * Conv * Color.b, q->m_aColors[3].a * Conv * Color.a * Alpha)};
|
2010-05-29 07:25:38 +00:00
|
|
|
Graphics()->SetColorVertex(Array, 4);
|
2008-01-12 17:09:00 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
CPoint *pPoints = q->m_aPoints;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(Rot != 0)
|
2008-01-12 17:09:00 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
static CPoint aRotated[4];
|
|
|
|
aRotated[0] = q->m_aPoints[0];
|
|
|
|
aRotated[1] = q->m_aPoints[1];
|
|
|
|
aRotated[2] = q->m_aPoints[2];
|
|
|
|
aRotated[3] = q->m_aPoints[3];
|
|
|
|
pPoints = aRotated;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
Rotate(&q->m_aPoints[4], &aRotated[0], Rot);
|
|
|
|
Rotate(&q->m_aPoints[4], &aRotated[1], Rot);
|
|
|
|
Rotate(&q->m_aPoints[4], &aRotated[2], Rot);
|
|
|
|
Rotate(&q->m_aPoints[4], &aRotated[3], Rot);
|
2008-01-12 17:09:00 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
IGraphics::CFreeformItem Freeform(
|
2020-09-26 19:41:58 +00:00
|
|
|
fx2f(pPoints[0].x) + OffsetX, fx2f(pPoints[0].y) + OffsetY,
|
|
|
|
fx2f(pPoints[1].x) + OffsetX, fx2f(pPoints[1].y) + OffsetY,
|
|
|
|
fx2f(pPoints[2].x) + OffsetX, fx2f(pPoints[2].y) + OffsetY,
|
|
|
|
fx2f(pPoints[3].x) + OffsetX, fx2f(pPoints[3].y) + OffsetY);
|
2010-05-29 07:25:38 +00:00
|
|
|
Graphics()->QuadsDrawFreeform(&Freeform, 1);
|
2008-01-12 17:09:00 +00:00
|
|
|
}
|
2020-10-20 17:11:19 +00:00
|
|
|
Graphics()->TrianglesEnd();
|
2008-01-12 17:09:00 +00:00
|
|
|
}
|
|
|
|
|
2017-03-16 15:37:40 +00:00
|
|
|
void CRenderTools::RenderTileRectangle(int RectX, int RectY, int RectW, int RectH,
|
2020-09-26 19:41:58 +00:00
|
|
|
unsigned char IndexIn, unsigned char IndexOut,
|
|
|
|
float Scale, ColorRGBA Color, int RenderFlags,
|
|
|
|
ENVELOPE_EVAL pfnEval, void *pUser, int ColorEnv, int ColorEnvOffset)
|
2017-03-15 11:06:13 +00:00
|
|
|
{
|
|
|
|
float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
|
|
|
|
Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1);
|
|
|
|
|
|
|
|
// calculate the final pixelsize for the tiles
|
2020-09-26 19:41:58 +00:00
|
|
|
float TilePixelSize = 1024 / 32.0f;
|
|
|
|
float FinalTileSize = Scale / (ScreenX1 - ScreenX0) * Graphics()->ScreenWidth();
|
|
|
|
float FinalTilesetScale = FinalTileSize / TilePixelSize;
|
2017-03-15 11:06:13 +00:00
|
|
|
|
2022-07-01 04:42:36 +00:00
|
|
|
ColorRGBA Channels(1.f, 1.f, 1.f, 1.f);
|
2017-03-15 11:06:13 +00:00
|
|
|
if(ColorEnv >= 0)
|
|
|
|
{
|
2022-07-01 04:42:36 +00:00
|
|
|
pfnEval(ColorEnvOffset, ColorEnv, Channels, pUser);
|
2017-03-15 11:06:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Graphics()->QuadsBegin();
|
2022-07-01 04:42:36 +00:00
|
|
|
Graphics()->SetColor(Color.r * Channels.r, Color.g * Channels.g, Color.b * Channels.b, Color.a * Channels.a);
|
2017-03-15 11:06:13 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
int StartY = (int)(ScreenY0 / Scale) - 1;
|
|
|
|
int StartX = (int)(ScreenX0 / Scale) - 1;
|
|
|
|
int EndY = (int)(ScreenY1 / Scale) + 1;
|
|
|
|
int EndX = (int)(ScreenX1 / Scale) + 1;
|
2017-03-15 11:06:13 +00:00
|
|
|
|
|
|
|
// adjust the texture shift according to mipmap level
|
|
|
|
float TexSize = 1024.0f;
|
2020-09-26 19:41:58 +00:00
|
|
|
float Frac = (1.25f / TexSize) * (1 / FinalTilesetScale);
|
|
|
|
float Nudge = (0.5f / TexSize) * (1 / FinalTilesetScale);
|
2017-03-15 11:06:13 +00:00
|
|
|
|
|
|
|
for(int y = StartY; y < EndY; y++)
|
2017-03-16 15:37:40 +00:00
|
|
|
{
|
2017-03-15 11:06:13 +00:00
|
|
|
for(int x = StartX; x < EndX; x++)
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
unsigned char Index = (x >= RectX && x < RectX + RectW && y >= RectY && y < RectY + RectH) ? IndexIn : IndexOut;
|
2017-03-15 11:06:13 +00:00
|
|
|
if(Index)
|
|
|
|
{
|
|
|
|
bool Render = false;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(RenderFlags & LAYERRENDERFLAG_TRANSPARENT)
|
2017-03-15 11:06:13 +00:00
|
|
|
Render = true;
|
|
|
|
|
|
|
|
if(Render)
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
int tx = Index % 16;
|
|
|
|
int ty = Index / 16;
|
|
|
|
int Px0 = tx * (1024 / 16);
|
|
|
|
int Py0 = ty * (1024 / 16);
|
|
|
|
int Px1 = Px0 + (1024 / 16) - 1;
|
|
|
|
int Py1 = Py0 + (1024 / 16) - 1;
|
|
|
|
|
|
|
|
float x0 = Nudge + Px0 / TexSize + Frac;
|
|
|
|
float y0 = Nudge + Py0 / TexSize + Frac;
|
|
|
|
float x1 = Nudge + Px1 / TexSize - Frac;
|
|
|
|
float y1 = Nudge + Py0 / TexSize + Frac;
|
|
|
|
float x2 = Nudge + Px1 / TexSize - Frac;
|
|
|
|
float y2 = Nudge + Py1 / TexSize - Frac;
|
|
|
|
float x3 = Nudge + Px0 / TexSize + Frac;
|
|
|
|
float y3 = Nudge + Py1 / TexSize - Frac;
|
2017-03-15 11:06:13 +00:00
|
|
|
|
|
|
|
Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3);
|
2020-09-26 19:41:58 +00:00
|
|
|
IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale);
|
2017-03-15 11:06:13 +00:00
|
|
|
Graphics()->QuadsDrawTL(&QuadItem, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-03-16 15:37:40 +00:00
|
|
|
}
|
2017-03-15 11:06:13 +00:00
|
|
|
|
|
|
|
Graphics()->QuadsEnd();
|
|
|
|
Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1);
|
|
|
|
}
|
|
|
|
|
2019-04-26 22:11:15 +00:00
|
|
|
void CRenderTools::RenderTilemap(CTile *pTiles, int w, int h, float Scale, ColorRGBA Color, int RenderFlags,
|
2020-09-21 03:57:54 +00:00
|
|
|
ENVELOPE_EVAL pfnEval, void *pUser, int ColorEnv, int ColorEnvOffset)
|
2008-01-12 17:09:00 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
|
|
|
|
Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1);
|
2008-01-12 17:09:00 +00:00
|
|
|
|
2011-04-13 18:37:12 +00:00
|
|
|
// calculate the final pixelsize for the tiles
|
2020-09-26 19:41:58 +00:00
|
|
|
float TilePixelSize = 1024 / 32.0f;
|
|
|
|
float FinalTileSize = Scale / (ScreenX1 - ScreenX0) * Graphics()->ScreenWidth();
|
|
|
|
float FinalTilesetScale = FinalTileSize / TilePixelSize;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2022-07-01 04:42:36 +00:00
|
|
|
ColorRGBA Channels(1.f, 1.f, 1.f, 1.f);
|
2011-07-18 10:05:12 +00:00
|
|
|
if(ColorEnv >= 0)
|
|
|
|
{
|
2022-07-01 04:42:36 +00:00
|
|
|
pfnEval(ColorEnvOffset, ColorEnv, Channels, pUser);
|
2011-07-18 10:05:12 +00:00
|
|
|
}
|
|
|
|
|
2020-09-21 03:57:54 +00:00
|
|
|
if(Graphics()->IsTileBufferingEnabled())
|
|
|
|
Graphics()->QuadsTex3DBegin();
|
|
|
|
else
|
|
|
|
Graphics()->QuadsBegin();
|
2022-07-01 04:42:36 +00:00
|
|
|
Graphics()->SetColor(Color.r * Channels.r, Color.g * Channels.g, Color.b * Channels.b, Color.a * Channels.a);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
int StartY = (int)(ScreenY0 / Scale) - 1;
|
|
|
|
int StartX = (int)(ScreenX0 / Scale) - 1;
|
|
|
|
int EndY = (int)(ScreenY1 / Scale) + 1;
|
|
|
|
int EndX = (int)(ScreenX1 / Scale) + 1;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2008-01-12 17:09:00 +00:00
|
|
|
// adjust the texture shift according to mipmap level
|
2010-05-29 07:25:38 +00:00
|
|
|
float TexSize = 1024.0f;
|
2020-09-26 19:41:58 +00:00
|
|
|
float Frac = (1.25f / TexSize) * (1 / FinalTilesetScale);
|
|
|
|
float Nudge = (0.5f / TexSize) * (1 / FinalTilesetScale);
|
2008-01-12 17:09:00 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
for(int y = StartY; y < EndY; y++)
|
2017-03-16 15:37:40 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
for(int x = StartX; x < EndX; x++)
|
2008-01-12 17:09:00 +00:00
|
|
|
{
|
|
|
|
int mx = x;
|
|
|
|
int my = y;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(RenderFlags & TILERENDERFLAG_EXTEND)
|
2008-01-13 11:15:32 +00:00
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx < 0)
|
2008-01-13 11:15:32 +00:00
|
|
|
mx = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx >= w)
|
|
|
|
mx = w - 1;
|
|
|
|
if(my < 0)
|
2008-01-13 11:15:32 +00:00
|
|
|
my = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(my >= h)
|
|
|
|
my = h - 1;
|
2008-01-13 11:15:32 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx < 0)
|
2008-01-13 11:15:32 +00:00
|
|
|
continue; // mx = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx >= w)
|
2008-01-13 11:15:32 +00:00
|
|
|
continue; // mx = w-1;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(my < 0)
|
2008-01-13 11:15:32 +00:00
|
|
|
continue; // my = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(my >= h)
|
2008-01-13 11:15:32 +00:00
|
|
|
continue; // my = h-1;
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
int c = mx + my * w;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
unsigned char Index = pTiles[c].m_Index;
|
|
|
|
if(Index)
|
2008-01-12 17:09:00 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
unsigned char Flags = pTiles[c].m_Flags;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
bool Render = false;
|
2022-07-01 04:42:36 +00:00
|
|
|
if(Flags & TILEFLAG_OPAQUE && Color.a * Channels.a > 254.0f / 255.0f)
|
2008-01-12 17:09:00 +00:00
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
if(RenderFlags & LAYERRENDERFLAG_OPAQUE)
|
2010-05-29 07:25:38 +00:00
|
|
|
Render = true;
|
2008-01-12 17:09:00 +00:00
|
|
|
}
|
2008-03-29 11:44:03 +00:00
|
|
|
else
|
2008-01-12 17:09:00 +00:00
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
if(RenderFlags & LAYERRENDERFLAG_TRANSPARENT)
|
2010-05-29 07:25:38 +00:00
|
|
|
Render = true;
|
2008-01-12 17:09:00 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(Render)
|
2008-03-29 11:44:03 +00:00
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
int tx = Index % 16;
|
|
|
|
int ty = Index / 16;
|
|
|
|
int Px0 = tx * (1024 / 16);
|
|
|
|
int Py0 = ty * (1024 / 16);
|
|
|
|
int Px1 = Px0 + (1024 / 16) - 1;
|
|
|
|
int Py1 = Py0 + (1024 / 16) - 1;
|
|
|
|
|
|
|
|
float x0 = Nudge + Px0 / TexSize + Frac;
|
|
|
|
float y0 = Nudge + Py0 / TexSize + Frac;
|
|
|
|
float x1 = Nudge + Px1 / TexSize - Frac;
|
|
|
|
float y1 = Nudge + Py0 / TexSize + Frac;
|
|
|
|
float x2 = Nudge + Px1 / TexSize - Frac;
|
|
|
|
float y2 = Nudge + Py1 / TexSize - Frac;
|
|
|
|
float x3 = Nudge + Px0 / TexSize + Frac;
|
|
|
|
float y3 = Nudge + Py1 / TexSize - Frac;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2020-09-21 03:57:54 +00:00
|
|
|
if(Graphics()->IsTileBufferingEnabled())
|
|
|
|
{
|
|
|
|
x0 = 0;
|
|
|
|
y0 = 0;
|
|
|
|
x1 = x0 + 1;
|
|
|
|
y1 = y0;
|
|
|
|
x2 = x0 + 1;
|
|
|
|
y2 = y0 + 1;
|
|
|
|
x3 = x0;
|
|
|
|
y3 = y0 + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(Flags & TILEFLAG_VFLIP)
|
2008-03-29 11:44:03 +00:00
|
|
|
{
|
2010-09-05 17:01:01 +00:00
|
|
|
x0 = x2;
|
|
|
|
x1 = x3;
|
|
|
|
x2 = x3;
|
|
|
|
x3 = x0;
|
2008-03-29 11:44:03 +00:00
|
|
|
}
|
2008-01-12 17:09:00 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(Flags & TILEFLAG_HFLIP)
|
2008-03-29 11:44:03 +00:00
|
|
|
{
|
2010-09-05 17:01:01 +00:00
|
|
|
y0 = y3;
|
|
|
|
y2 = y1;
|
|
|
|
y3 = y1;
|
|
|
|
y1 = y0;
|
2008-03-29 11:44:03 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(Flags & TILEFLAG_ROTATE)
|
2010-09-05 17:01:01 +00:00
|
|
|
{
|
|
|
|
float Tmp = x0;
|
|
|
|
x0 = x3;
|
|
|
|
x3 = x2;
|
|
|
|
x2 = x1;
|
2011-04-13 18:37:12 +00:00
|
|
|
x1 = Tmp;
|
2010-09-05 17:01:01 +00:00
|
|
|
Tmp = y0;
|
|
|
|
y0 = y3;
|
|
|
|
y3 = y2;
|
|
|
|
y2 = y1;
|
|
|
|
y1 = Tmp;
|
2015-07-09 00:08:14 +00:00
|
|
|
}
|
2010-09-05 17:01:01 +00:00
|
|
|
|
2020-09-21 03:57:54 +00:00
|
|
|
if(Graphics()->IsTileBufferingEnabled())
|
|
|
|
{
|
|
|
|
Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3, Index);
|
|
|
|
IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale);
|
|
|
|
Graphics()->QuadsTex3DDrawTL(&QuadItem, 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3);
|
|
|
|
IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale);
|
|
|
|
Graphics()->QuadsDrawTL(&QuadItem, 1);
|
|
|
|
}
|
2008-03-29 11:44:03 +00:00
|
|
|
}
|
2008-01-12 17:09:00 +00:00
|
|
|
}
|
2010-05-29 07:25:38 +00:00
|
|
|
x += pTiles[c].m_Skip;
|
2008-01-12 17:09:00 +00:00
|
|
|
}
|
2017-03-16 15:37:40 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2020-09-21 03:57:54 +00:00
|
|
|
if(Graphics()->IsTileBufferingEnabled())
|
|
|
|
Graphics()->QuadsTex3DEnd();
|
|
|
|
else
|
|
|
|
Graphics()->QuadsEnd();
|
2010-05-29 07:25:38 +00:00
|
|
|
Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1);
|
2008-01-12 17:09:00 +00:00
|
|
|
}
|
2010-09-30 21:31:19 +00:00
|
|
|
|
2014-05-01 18:15:53 +00:00
|
|
|
void CRenderTools::RenderTeleOverlay(CTeleTile *pTele, int w, int h, float Scale, float Alpha)
|
2010-09-30 21:31:19 +00:00
|
|
|
{
|
2015-11-07 19:17:41 +00:00
|
|
|
if(!g_Config.m_ClTextEntities)
|
2020-09-26 19:41:58 +00:00
|
|
|
return;
|
2015-09-28 04:04:57 +00:00
|
|
|
|
2010-09-30 21:31:19 +00:00
|
|
|
float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
|
|
|
|
Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1);
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
int StartY = (int)(ScreenY0 / Scale) - 1;
|
|
|
|
int StartX = (int)(ScreenX0 / Scale) - 1;
|
|
|
|
int EndY = (int)(ScreenY1 / Scale) + 1;
|
|
|
|
int EndX = (int)(ScreenX1 / Scale) + 1;
|
2014-11-16 10:09:37 +00:00
|
|
|
|
2016-04-30 15:59:58 +00:00
|
|
|
if(EndX - StartX > Graphics()->ScreenWidth() / g_Config.m_GfxTextOverlay || EndY - StartY > Graphics()->ScreenHeight() / g_Config.m_GfxTextOverlay)
|
2014-11-16 10:09:37 +00:00
|
|
|
return; // its useless to render text at this distance
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
float Size = g_Config.m_ClTextEntitiesSize / 100.f;
|
|
|
|
float ToCenterOffset = (1 - Size) / 2.f;
|
2019-05-06 12:19:10 +00:00
|
|
|
|
2010-09-30 21:31:19 +00:00
|
|
|
for(int y = StartY; y < EndY; y++)
|
|
|
|
for(int x = StartX; x < EndX; x++)
|
|
|
|
{
|
|
|
|
int mx = x;
|
|
|
|
int my = y;
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx < 0)
|
2010-09-30 21:31:19 +00:00
|
|
|
continue; // mx = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx >= w)
|
2010-09-30 21:31:19 +00:00
|
|
|
continue; // mx = w-1;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(my < 0)
|
2010-09-30 21:31:19 +00:00
|
|
|
continue; // my = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(my >= h)
|
2010-09-30 21:31:19 +00:00
|
|
|
continue; // my = h-1;
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
int c = mx + my * w;
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2010-09-30 21:31:19 +00:00
|
|
|
unsigned char Index = pTele[c].m_Number;
|
2014-11-16 15:42:01 +00:00
|
|
|
if(Index && pTele[c].m_Type != TILE_TELECHECKIN && pTele[c].m_Type != TILE_TELECHECKINEVIL)
|
2010-09-30 21:31:19 +00:00
|
|
|
{
|
|
|
|
char aBuf[16];
|
|
|
|
str_format(aBuf, sizeof(aBuf), "%d", Index);
|
2022-05-14 11:31:07 +00:00
|
|
|
TextRender()->TextColor(1.0f, 1.0f, 1.0f, Alpha);
|
|
|
|
TextRender()->Text(0, mx * Scale - 3.f, (my + ToCenterOffset) * Scale, Size * Scale, aBuf, -1.0f);
|
|
|
|
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
|
2010-09-30 21:31:19 +00:00
|
|
|
}
|
|
|
|
}
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2010-09-30 21:31:19 +00:00
|
|
|
Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1);
|
|
|
|
}
|
|
|
|
|
2014-05-01 18:15:53 +00:00
|
|
|
void CRenderTools::RenderSpeedupOverlay(CSpeedupTile *pSpeedup, int w, int h, float Scale, float Alpha)
|
2010-09-30 21:31:19 +00:00
|
|
|
{
|
|
|
|
float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
|
|
|
|
Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1);
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
int StartY = (int)(ScreenY0 / Scale) - 1;
|
|
|
|
int StartX = (int)(ScreenX0 / Scale) - 1;
|
|
|
|
int EndY = (int)(ScreenY1 / Scale) + 1;
|
|
|
|
int EndX = (int)(ScreenX1 / Scale) + 1;
|
2014-11-16 10:09:37 +00:00
|
|
|
|
2016-04-30 15:59:58 +00:00
|
|
|
if(EndX - StartX > Graphics()->ScreenWidth() / g_Config.m_GfxTextOverlay || EndY - StartY > Graphics()->ScreenHeight() / g_Config.m_GfxTextOverlay)
|
2014-11-16 10:09:37 +00:00
|
|
|
return; // its useless to render text at this distance
|
|
|
|
|
2019-05-06 12:19:10 +00:00
|
|
|
float Size = g_Config.m_ClTextEntitiesSize / 100.f;
|
2020-09-26 19:41:58 +00:00
|
|
|
float ToCenterOffset = (1 - Size) / 2.f;
|
2019-05-06 12:19:10 +00:00
|
|
|
|
2010-09-30 21:31:19 +00:00
|
|
|
for(int y = StartY; y < EndY; y++)
|
|
|
|
for(int x = StartX; x < EndX; x++)
|
|
|
|
{
|
|
|
|
int mx = x;
|
|
|
|
int my = y;
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx < 0)
|
2010-09-30 21:31:19 +00:00
|
|
|
continue; // mx = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx >= w)
|
2010-09-30 21:31:19 +00:00
|
|
|
continue; // mx = w-1;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(my < 0)
|
2010-09-30 21:31:19 +00:00
|
|
|
continue; // my = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(my >= h)
|
2010-09-30 21:31:19 +00:00
|
|
|
continue; // my = h-1;
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
int c = mx + my * w;
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2010-09-30 21:31:19 +00:00
|
|
|
int Force = (int)pSpeedup[c].m_Force;
|
|
|
|
int MaxSpeed = (int)pSpeedup[c].m_MaxSpeed;
|
|
|
|
if(Force)
|
2011-04-09 06:41:31 +00:00
|
|
|
{
|
2010-09-30 21:31:19 +00:00
|
|
|
// draw arrow
|
|
|
|
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_SPEEDUP_ARROW].m_Id);
|
|
|
|
Graphics()->QuadsBegin();
|
2014-05-01 18:15:53 +00:00
|
|
|
Graphics()->SetColor(255.0f, 255.0f, 255.0f, Alpha);
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2010-09-30 21:31:19 +00:00
|
|
|
SelectSprite(SPRITE_SPEEDUP_ARROW);
|
2020-09-26 19:41:58 +00:00
|
|
|
Graphics()->QuadsSetRotation(pSpeedup[c].m_Angle * (3.14159265f / 180.0f));
|
|
|
|
DrawSprite(mx * Scale + 16, my * Scale + 16, 35.0f);
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2010-09-30 21:31:19 +00:00
|
|
|
Graphics()->QuadsEnd();
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2015-09-28 04:04:57 +00:00
|
|
|
if(g_Config.m_ClTextEntities)
|
2010-09-30 21:31:19 +00:00
|
|
|
{
|
2015-09-28 04:04:57 +00:00
|
|
|
// draw force
|
|
|
|
char aBuf[16];
|
|
|
|
str_format(aBuf, sizeof(aBuf), "%d", Force);
|
2022-05-14 11:31:07 +00:00
|
|
|
TextRender()->TextColor(1.0f, 1.0f, 1.0f, Alpha);
|
|
|
|
TextRender()->Text(0, mx * Scale, (my + 0.5f + ToCenterOffset / 2) * Scale, Size * Scale / 2.f, aBuf, -1.0f);
|
|
|
|
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
|
2015-09-28 04:04:57 +00:00
|
|
|
if(MaxSpeed)
|
|
|
|
{
|
|
|
|
str_format(aBuf, sizeof(aBuf), "%d", MaxSpeed);
|
2022-05-14 11:31:07 +00:00
|
|
|
TextRender()->TextColor(1.0f, 1.0f, 1.0f, Alpha);
|
|
|
|
TextRender()->Text(0, mx * Scale, (my + ToCenterOffset / 2) * Scale, Size * Scale / 2.f, aBuf, -1.0f);
|
|
|
|
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
|
2015-09-28 04:04:57 +00:00
|
|
|
}
|
2010-09-30 21:31:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1);
|
|
|
|
}
|
|
|
|
|
2014-05-01 18:15:53 +00:00
|
|
|
void CRenderTools::RenderSwitchOverlay(CSwitchTile *pSwitch, int w, int h, float Scale, float Alpha)
|
2010-09-30 21:31:19 +00:00
|
|
|
{
|
2015-11-07 19:17:41 +00:00
|
|
|
if(!g_Config.m_ClTextEntities)
|
2020-09-26 19:41:58 +00:00
|
|
|
return;
|
2015-09-28 04:04:57 +00:00
|
|
|
|
2010-09-30 21:31:19 +00:00
|
|
|
float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
|
|
|
|
Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1);
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
int StartY = (int)(ScreenY0 / Scale) - 1;
|
|
|
|
int StartX = (int)(ScreenX0 / Scale) - 1;
|
|
|
|
int EndY = (int)(ScreenY1 / Scale) + 1;
|
|
|
|
int EndX = (int)(ScreenX1 / Scale) + 1;
|
2014-11-16 10:09:37 +00:00
|
|
|
|
2016-04-30 15:59:58 +00:00
|
|
|
if(EndX - StartX > Graphics()->ScreenWidth() / g_Config.m_GfxTextOverlay || EndY - StartY > Graphics()->ScreenHeight() / g_Config.m_GfxTextOverlay)
|
2014-11-16 10:09:37 +00:00
|
|
|
return; // its useless to render text at this distance
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
float Size = g_Config.m_ClTextEntitiesSize / 100.f;
|
|
|
|
float ToCenterOffset = (1 - Size) / 2.f;
|
2019-05-06 12:19:10 +00:00
|
|
|
|
2010-09-30 21:31:19 +00:00
|
|
|
for(int y = StartY; y < EndY; y++)
|
|
|
|
for(int x = StartX; x < EndX; x++)
|
|
|
|
{
|
|
|
|
int mx = x;
|
|
|
|
int my = y;
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx < 0)
|
2010-09-30 21:31:19 +00:00
|
|
|
continue; // mx = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx >= w)
|
2010-09-30 21:31:19 +00:00
|
|
|
continue; // mx = w-1;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(my < 0)
|
2010-09-30 21:31:19 +00:00
|
|
|
continue; // my = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(my >= h)
|
2010-09-30 21:31:19 +00:00
|
|
|
continue; // my = h-1;
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
int c = mx + my * w;
|
2010-09-30 21:31:19 +00:00
|
|
|
|
|
|
|
unsigned char Index = pSwitch[c].m_Number;
|
|
|
|
if(Index)
|
|
|
|
{
|
|
|
|
char aBuf[16];
|
|
|
|
str_format(aBuf, sizeof(aBuf), "%d", Index);
|
2022-05-14 11:31:07 +00:00
|
|
|
TextRender()->TextColor(1.0f, 1.0f, 1.0f, Alpha);
|
|
|
|
TextRender()->Text(0, mx * Scale, (my + ToCenterOffset / 2) * Scale, Size * Scale / 2.f, aBuf, -1.0f);
|
|
|
|
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
|
2010-11-22 20:43:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
unsigned char Delay = pSwitch[c].m_Delay;
|
|
|
|
if(Delay)
|
|
|
|
{
|
|
|
|
char aBuf[16];
|
|
|
|
str_format(aBuf, sizeof(aBuf), "%d", Delay);
|
2022-05-14 11:31:07 +00:00
|
|
|
TextRender()->TextColor(1.0f, 1.0f, 1.0f, Alpha);
|
|
|
|
TextRender()->Text(0, mx * Scale, (my + 0.5f + ToCenterOffset / 2) * Scale, Size * Scale / 2.f, aBuf, -1.0f);
|
|
|
|
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
|
2010-09-30 21:31:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1);
|
2011-03-16 12:48:16 +00:00
|
|
|
}
|
2011-04-19 14:32:42 +00:00
|
|
|
|
2014-05-01 18:15:53 +00:00
|
|
|
void CRenderTools::RenderTuneOverlay(CTuneTile *pTune, int w, int h, float Scale, float Alpha)
|
2014-03-12 22:42:51 +00:00
|
|
|
{
|
2015-11-07 19:17:41 +00:00
|
|
|
if(!g_Config.m_ClTextEntities)
|
2020-09-26 19:41:58 +00:00
|
|
|
return;
|
2015-09-28 04:04:57 +00:00
|
|
|
|
2014-03-12 22:42:51 +00:00
|
|
|
float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
|
|
|
|
Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1);
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
int StartY = (int)(ScreenY0 / Scale) - 1;
|
|
|
|
int StartX = (int)(ScreenX0 / Scale) - 1;
|
|
|
|
int EndY = (int)(ScreenY1 / Scale) + 1;
|
|
|
|
int EndX = (int)(ScreenX1 / Scale) + 1;
|
2014-11-16 10:09:37 +00:00
|
|
|
|
2016-04-30 15:59:58 +00:00
|
|
|
if(EndX - StartX > Graphics()->ScreenWidth() / g_Config.m_GfxTextOverlay || EndY - StartY > Graphics()->ScreenHeight() / g_Config.m_GfxTextOverlay)
|
2014-03-18 16:07:43 +00:00
|
|
|
return; // its useless to render text at this distance
|
2014-03-12 22:42:51 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
float Size = g_Config.m_ClTextEntitiesSize / 100.f;
|
2019-05-06 12:19:10 +00:00
|
|
|
|
2014-03-12 22:42:51 +00:00
|
|
|
for(int y = StartY; y < EndY; y++)
|
|
|
|
for(int x = StartX; x < EndX; x++)
|
|
|
|
{
|
|
|
|
int mx = x;
|
|
|
|
int my = y;
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx < 0)
|
2014-03-12 22:42:51 +00:00
|
|
|
continue; // mx = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx >= w)
|
2014-03-12 22:42:51 +00:00
|
|
|
continue; // mx = w-1;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(my < 0)
|
2014-03-12 22:42:51 +00:00
|
|
|
continue; // my = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(my >= h)
|
2014-03-12 22:42:51 +00:00
|
|
|
continue; // my = h-1;
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
int c = mx + my * w;
|
2014-03-12 22:42:51 +00:00
|
|
|
|
|
|
|
unsigned char Index = pTune[c].m_Number;
|
|
|
|
if(Index)
|
|
|
|
{
|
|
|
|
char aBuf[16];
|
|
|
|
str_format(aBuf, sizeof(aBuf), "%d", Index);
|
2022-05-14 11:31:07 +00:00
|
|
|
TextRender()->TextColor(1.0f, 1.0f, 1.0f, Alpha);
|
|
|
|
TextRender()->Text(0, mx * Scale + 11.f, my * Scale + 6.f, Size * Scale / 1.5f - 5.f, aBuf, -1.0f); // numbers shouldn't be too big and in the center of the tile
|
|
|
|
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
|
2014-03-12 22:42:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1);
|
|
|
|
}
|
|
|
|
|
2019-04-26 22:11:15 +00:00
|
|
|
void CRenderTools::RenderTelemap(CTeleTile *pTele, int w, int h, float Scale, ColorRGBA Color, int RenderFlags)
|
2011-04-19 14:32:42 +00:00
|
|
|
{
|
|
|
|
float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
|
|
|
|
Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1);
|
|
|
|
|
|
|
|
// calculate the final pixelsize for the tiles
|
2020-09-26 19:41:58 +00:00
|
|
|
float TilePixelSize = 1024 / 32.0f;
|
|
|
|
float FinalTileSize = Scale / (ScreenX1 - ScreenX0) * Graphics()->ScreenWidth();
|
|
|
|
float FinalTilesetScale = FinalTileSize / TilePixelSize;
|
2011-04-19 14:32:42 +00:00
|
|
|
|
|
|
|
Graphics()->QuadsBegin();
|
2019-04-26 22:11:15 +00:00
|
|
|
Graphics()->SetColor(Color);
|
2011-04-19 14:32:42 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
int StartY = (int)(ScreenY0 / Scale) - 1;
|
|
|
|
int StartX = (int)(ScreenX0 / Scale) - 1;
|
|
|
|
int EndY = (int)(ScreenY1 / Scale) + 1;
|
|
|
|
int EndX = (int)(ScreenX1 / Scale) + 1;
|
2011-04-19 14:32:42 +00:00
|
|
|
|
|
|
|
// adjust the texture shift according to mipmap level
|
|
|
|
float TexSize = 1024.0f;
|
2020-09-26 19:41:58 +00:00
|
|
|
float Frac = (1.25f / TexSize) * (1 / FinalTilesetScale);
|
|
|
|
float Nudge = (0.5f / TexSize) * (1 / FinalTilesetScale);
|
2011-04-19 14:32:42 +00:00
|
|
|
|
|
|
|
for(int y = StartY; y < EndY; y++)
|
|
|
|
for(int x = StartX; x < EndX; x++)
|
|
|
|
{
|
|
|
|
int mx = x;
|
|
|
|
int my = y;
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(RenderFlags & TILERENDERFLAG_EXTEND)
|
2011-04-19 14:32:42 +00:00
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx < 0)
|
2011-04-19 14:32:42 +00:00
|
|
|
mx = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx >= w)
|
|
|
|
mx = w - 1;
|
|
|
|
if(my < 0)
|
2011-04-19 14:32:42 +00:00
|
|
|
my = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(my >= h)
|
|
|
|
my = h - 1;
|
2011-04-19 14:32:42 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx < 0)
|
2011-04-19 14:32:42 +00:00
|
|
|
continue; // mx = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx >= w)
|
2011-04-19 14:32:42 +00:00
|
|
|
continue; // mx = w-1;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(my < 0)
|
2011-04-19 14:32:42 +00:00
|
|
|
continue; // my = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(my >= h)
|
2011-04-19 14:32:42 +00:00
|
|
|
continue; // my = h-1;
|
|
|
|
}
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
int c = mx + my * w;
|
2011-04-19 14:32:42 +00:00
|
|
|
|
|
|
|
unsigned char Index = pTele[c].m_Type;
|
|
|
|
if(Index)
|
|
|
|
{
|
|
|
|
bool Render = false;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(RenderFlags & LAYERRENDERFLAG_TRANSPARENT)
|
2011-04-19 14:32:42 +00:00
|
|
|
Render = true;
|
|
|
|
|
|
|
|
if(Render)
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
int tx = Index % 16;
|
|
|
|
int ty = Index / 16;
|
|
|
|
int Px0 = tx * (1024 / 16);
|
|
|
|
int Py0 = ty * (1024 / 16);
|
|
|
|
int Px1 = Px0 + (1024 / 16) - 1;
|
|
|
|
int Py1 = Py0 + (1024 / 16) - 1;
|
|
|
|
|
|
|
|
float x0 = Nudge + Px0 / TexSize + Frac;
|
|
|
|
float y0 = Nudge + Py0 / TexSize + Frac;
|
|
|
|
float x1 = Nudge + Px1 / TexSize - Frac;
|
|
|
|
float y1 = Nudge + Py0 / TexSize + Frac;
|
|
|
|
float x2 = Nudge + Px1 / TexSize - Frac;
|
|
|
|
float y2 = Nudge + Py1 / TexSize - Frac;
|
|
|
|
float x3 = Nudge + Px0 / TexSize + Frac;
|
|
|
|
float y3 = Nudge + Py1 / TexSize - Frac;
|
2011-04-19 14:32:42 +00:00
|
|
|
|
|
|
|
Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3);
|
2020-09-26 19:41:58 +00:00
|
|
|
IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale);
|
2011-04-19 14:32:42 +00:00
|
|
|
Graphics()->QuadsDrawTL(&QuadItem, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Graphics()->QuadsEnd();
|
|
|
|
Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1);
|
|
|
|
}
|
|
|
|
|
2019-04-26 22:11:15 +00:00
|
|
|
void CRenderTools::RenderSpeedupmap(CSpeedupTile *pSpeedupTile, int w, int h, float Scale, ColorRGBA Color, int RenderFlags)
|
2011-04-19 14:32:42 +00:00
|
|
|
{
|
|
|
|
//Graphics()->TextureSet(img_get(tmap->image));
|
|
|
|
float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
|
|
|
|
Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1);
|
|
|
|
//Graphics()->MapScreen(screen_x0-50, screen_y0-50, screen_x1+50, screen_y1+50);
|
|
|
|
|
|
|
|
// calculate the final pixelsize for the tiles
|
2020-09-26 19:41:58 +00:00
|
|
|
float TilePixelSize = 1024 / 32.0f;
|
|
|
|
float FinalTileSize = Scale / (ScreenX1 - ScreenX0) * Graphics()->ScreenWidth();
|
|
|
|
float FinalTilesetScale = FinalTileSize / TilePixelSize;
|
2011-04-19 14:32:42 +00:00
|
|
|
|
|
|
|
Graphics()->QuadsBegin();
|
2019-04-26 22:11:15 +00:00
|
|
|
Graphics()->SetColor(Color);
|
2011-04-19 14:32:42 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
int StartY = (int)(ScreenY0 / Scale) - 1;
|
|
|
|
int StartX = (int)(ScreenX0 / Scale) - 1;
|
|
|
|
int EndY = (int)(ScreenY1 / Scale) + 1;
|
|
|
|
int EndX = (int)(ScreenX1 / Scale) + 1;
|
2011-04-19 14:32:42 +00:00
|
|
|
|
|
|
|
// adjust the texture shift according to mipmap level
|
|
|
|
float TexSize = 1024.0f;
|
2020-09-26 19:41:58 +00:00
|
|
|
float Frac = (1.25f / TexSize) * (1 / FinalTilesetScale);
|
|
|
|
float Nudge = (0.5f / TexSize) * (1 / FinalTilesetScale);
|
2011-04-19 14:32:42 +00:00
|
|
|
|
|
|
|
for(int y = StartY; y < EndY; y++)
|
|
|
|
for(int x = StartX; x < EndX; x++)
|
|
|
|
{
|
|
|
|
int mx = x;
|
|
|
|
int my = y;
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(RenderFlags & TILERENDERFLAG_EXTEND)
|
2011-04-19 14:32:42 +00:00
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx < 0)
|
2011-04-19 14:32:42 +00:00
|
|
|
mx = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx >= w)
|
|
|
|
mx = w - 1;
|
|
|
|
if(my < 0)
|
2011-04-19 14:32:42 +00:00
|
|
|
my = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(my >= h)
|
|
|
|
my = h - 1;
|
2011-04-19 14:32:42 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx < 0)
|
2011-04-19 14:32:42 +00:00
|
|
|
continue; // mx = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx >= w)
|
2011-04-19 14:32:42 +00:00
|
|
|
continue; // mx = w-1;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(my < 0)
|
2011-04-19 14:32:42 +00:00
|
|
|
continue; // my = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(my >= h)
|
2011-04-19 14:32:42 +00:00
|
|
|
continue; // my = h-1;
|
|
|
|
}
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
int c = mx + my * w;
|
2011-04-19 14:32:42 +00:00
|
|
|
|
|
|
|
unsigned char Index = pSpeedupTile[c].m_Type;
|
|
|
|
if(Index)
|
|
|
|
{
|
|
|
|
bool Render = false;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(RenderFlags & LAYERRENDERFLAG_TRANSPARENT)
|
2011-04-19 14:32:42 +00:00
|
|
|
Render = true;
|
|
|
|
|
|
|
|
if(Render)
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
int tx = Index % 16;
|
|
|
|
int ty = Index / 16;
|
|
|
|
int Px0 = tx * (1024 / 16);
|
|
|
|
int Py0 = ty * (1024 / 16);
|
|
|
|
int Px1 = Px0 + (1024 / 16) - 1;
|
|
|
|
int Py1 = Py0 + (1024 / 16) - 1;
|
|
|
|
|
|
|
|
float x0 = Nudge + Px0 / TexSize + Frac;
|
|
|
|
float y0 = Nudge + Py0 / TexSize + Frac;
|
|
|
|
float x1 = Nudge + Px1 / TexSize - Frac;
|
|
|
|
float y1 = Nudge + Py0 / TexSize + Frac;
|
|
|
|
float x2 = Nudge + Px1 / TexSize - Frac;
|
|
|
|
float y2 = Nudge + Py1 / TexSize - Frac;
|
|
|
|
float x3 = Nudge + Px0 / TexSize + Frac;
|
|
|
|
float y3 = Nudge + Py1 / TexSize - Frac;
|
2011-04-19 14:32:42 +00:00
|
|
|
|
|
|
|
Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3);
|
2020-09-26 19:41:58 +00:00
|
|
|
IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale);
|
2011-04-19 14:32:42 +00:00
|
|
|
Graphics()->QuadsDrawTL(&QuadItem, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Graphics()->QuadsEnd();
|
|
|
|
Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1);
|
|
|
|
}
|
|
|
|
|
2019-04-26 22:11:15 +00:00
|
|
|
void CRenderTools::RenderSwitchmap(CSwitchTile *pSwitchTile, int w, int h, float Scale, ColorRGBA Color, int RenderFlags)
|
2011-04-19 14:32:42 +00:00
|
|
|
{
|
|
|
|
//Graphics()->TextureSet(img_get(tmap->image));
|
|
|
|
float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
|
|
|
|
Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1);
|
|
|
|
//Graphics()->MapScreen(screen_x0-50, screen_y0-50, screen_x1+50, screen_y1+50);
|
|
|
|
|
|
|
|
// calculate the final pixelsize for the tiles
|
2020-09-26 19:41:58 +00:00
|
|
|
float TilePixelSize = 1024 / 32.0f;
|
|
|
|
float FinalTileSize = Scale / (ScreenX1 - ScreenX0) * Graphics()->ScreenWidth();
|
|
|
|
float FinalTilesetScale = FinalTileSize / TilePixelSize;
|
2011-04-19 14:32:42 +00:00
|
|
|
|
|
|
|
Graphics()->QuadsBegin();
|
2019-04-26 22:11:15 +00:00
|
|
|
Graphics()->SetColor(Color);
|
2011-04-19 14:32:42 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
int StartY = (int)(ScreenY0 / Scale) - 1;
|
|
|
|
int StartX = (int)(ScreenX0 / Scale) - 1;
|
|
|
|
int EndY = (int)(ScreenY1 / Scale) + 1;
|
|
|
|
int EndX = (int)(ScreenX1 / Scale) + 1;
|
2011-04-19 14:32:42 +00:00
|
|
|
|
|
|
|
// adjust the texture shift according to mipmap level
|
|
|
|
float TexSize = 1024.0f;
|
2020-09-26 19:41:58 +00:00
|
|
|
float Frac = (1.25f / TexSize) * (1 / FinalTilesetScale);
|
|
|
|
float Nudge = (0.5f / TexSize) * (1 / FinalTilesetScale);
|
2011-04-19 14:32:42 +00:00
|
|
|
|
|
|
|
for(int y = StartY; y < EndY; y++)
|
|
|
|
for(int x = StartX; x < EndX; x++)
|
|
|
|
{
|
|
|
|
int mx = x;
|
|
|
|
int my = y;
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(RenderFlags & TILERENDERFLAG_EXTEND)
|
2011-04-19 14:32:42 +00:00
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx < 0)
|
2011-04-19 14:32:42 +00:00
|
|
|
mx = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx >= w)
|
|
|
|
mx = w - 1;
|
|
|
|
if(my < 0)
|
2011-04-19 14:32:42 +00:00
|
|
|
my = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(my >= h)
|
|
|
|
my = h - 1;
|
2011-04-19 14:32:42 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx < 0)
|
2011-04-19 14:32:42 +00:00
|
|
|
continue; // mx = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx >= w)
|
2011-04-19 14:32:42 +00:00
|
|
|
continue; // mx = w-1;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(my < 0)
|
2011-04-19 14:32:42 +00:00
|
|
|
continue; // my = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(my >= h)
|
2011-04-19 14:32:42 +00:00
|
|
|
continue; // my = h-1;
|
|
|
|
}
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
int c = mx + my * w;
|
2011-04-19 14:32:42 +00:00
|
|
|
|
|
|
|
unsigned char Index = pSwitchTile[c].m_Type;
|
|
|
|
if(Index)
|
|
|
|
{
|
2014-09-17 18:22:42 +00:00
|
|
|
if(Index == TILE_SWITCHTIMEDOPEN)
|
|
|
|
Index = 8;
|
|
|
|
|
2011-04-19 14:32:42 +00:00
|
|
|
unsigned char Flags = pSwitchTile[c].m_Flags;
|
|
|
|
|
|
|
|
bool Render = false;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(Flags & TILEFLAG_OPAQUE)
|
2011-04-19 14:32:42 +00:00
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
if(RenderFlags & LAYERRENDERFLAG_OPAQUE)
|
2011-04-19 14:32:42 +00:00
|
|
|
Render = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
if(RenderFlags & LAYERRENDERFLAG_TRANSPARENT)
|
2011-04-19 14:32:42 +00:00
|
|
|
Render = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(Render)
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
int tx = Index % 16;
|
|
|
|
int ty = Index / 16;
|
|
|
|
int Px0 = tx * (1024 / 16);
|
|
|
|
int Py0 = ty * (1024 / 16);
|
|
|
|
int Px1 = Px0 + (1024 / 16) - 1;
|
|
|
|
int Py1 = Py0 + (1024 / 16) - 1;
|
|
|
|
|
|
|
|
float x0 = Nudge + Px0 / TexSize + Frac;
|
|
|
|
float y0 = Nudge + Py0 / TexSize + Frac;
|
|
|
|
float x1 = Nudge + Px1 / TexSize - Frac;
|
|
|
|
float y1 = Nudge + Py0 / TexSize + Frac;
|
|
|
|
float x2 = Nudge + Px1 / TexSize - Frac;
|
|
|
|
float y2 = Nudge + Py1 / TexSize - Frac;
|
|
|
|
float x3 = Nudge + Px0 / TexSize + Frac;
|
|
|
|
float y3 = Nudge + Py1 / TexSize - Frac;
|
2011-04-19 14:32:42 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(Flags & TILEFLAG_VFLIP)
|
2011-04-19 14:32:42 +00:00
|
|
|
{
|
|
|
|
x0 = x2;
|
|
|
|
x1 = x3;
|
|
|
|
x2 = x3;
|
|
|
|
x3 = x0;
|
|
|
|
}
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(Flags & TILEFLAG_HFLIP)
|
2011-04-19 14:32:42 +00:00
|
|
|
{
|
|
|
|
y0 = y3;
|
|
|
|
y2 = y1;
|
|
|
|
y3 = y1;
|
|
|
|
y1 = y0;
|
|
|
|
}
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(Flags & TILEFLAG_ROTATE)
|
2011-04-19 14:32:42 +00:00
|
|
|
{
|
|
|
|
float Tmp = x0;
|
|
|
|
x0 = x3;
|
|
|
|
x3 = x2;
|
|
|
|
x2 = x1;
|
|
|
|
x1 = Tmp;
|
|
|
|
Tmp = y0;
|
|
|
|
y0 = y3;
|
|
|
|
y3 = y2;
|
|
|
|
y2 = y1;
|
|
|
|
y1 = Tmp;
|
2015-07-09 00:08:14 +00:00
|
|
|
}
|
2011-04-19 14:32:42 +00:00
|
|
|
|
|
|
|
Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3);
|
2020-09-26 19:41:58 +00:00
|
|
|
IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale);
|
2011-04-19 14:32:42 +00:00
|
|
|
Graphics()->QuadsDrawTL(&QuadItem, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Graphics()->QuadsEnd();
|
|
|
|
Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1);
|
|
|
|
}
|
2014-03-12 22:42:51 +00:00
|
|
|
|
2019-04-26 22:11:15 +00:00
|
|
|
void CRenderTools::RenderTunemap(CTuneTile *pTune, int w, int h, float Scale, ColorRGBA Color, int RenderFlags)
|
2014-03-12 22:42:51 +00:00
|
|
|
{
|
|
|
|
float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
|
|
|
|
Graphics()->GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1);
|
|
|
|
|
|
|
|
// calculate the final pixelsize for the tiles
|
2020-09-26 19:41:58 +00:00
|
|
|
float TilePixelSize = 1024 / 32.0f;
|
|
|
|
float FinalTileSize = Scale / (ScreenX1 - ScreenX0) * Graphics()->ScreenWidth();
|
|
|
|
float FinalTilesetScale = FinalTileSize / TilePixelSize;
|
2014-03-12 22:42:51 +00:00
|
|
|
|
|
|
|
Graphics()->QuadsBegin();
|
2019-04-26 22:11:15 +00:00
|
|
|
Graphics()->SetColor(Color);
|
2014-03-12 22:42:51 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
int StartY = (int)(ScreenY0 / Scale) - 1;
|
|
|
|
int StartX = (int)(ScreenX0 / Scale) - 1;
|
|
|
|
int EndY = (int)(ScreenY1 / Scale) + 1;
|
|
|
|
int EndX = (int)(ScreenX1 / Scale) + 1;
|
2014-03-12 22:42:51 +00:00
|
|
|
|
|
|
|
// adjust the texture shift according to mipmap level
|
|
|
|
float TexSize = 1024.0f;
|
2020-09-26 19:41:58 +00:00
|
|
|
float Frac = (1.25f / TexSize) * (1 / FinalTilesetScale);
|
|
|
|
float Nudge = (0.5f / TexSize) * (1 / FinalTilesetScale);
|
2014-03-12 22:42:51 +00:00
|
|
|
|
|
|
|
for(int y = StartY; y < EndY; y++)
|
|
|
|
for(int x = StartX; x < EndX; x++)
|
|
|
|
{
|
|
|
|
int mx = x;
|
|
|
|
int my = y;
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(RenderFlags & TILERENDERFLAG_EXTEND)
|
2014-03-12 22:42:51 +00:00
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx < 0)
|
2014-03-12 22:42:51 +00:00
|
|
|
mx = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx >= w)
|
|
|
|
mx = w - 1;
|
|
|
|
if(my < 0)
|
2014-03-12 22:42:51 +00:00
|
|
|
my = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(my >= h)
|
|
|
|
my = h - 1;
|
2014-03-12 22:42:51 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx < 0)
|
2014-03-12 22:42:51 +00:00
|
|
|
continue; // mx = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(mx >= w)
|
2014-03-12 22:42:51 +00:00
|
|
|
continue; // mx = w-1;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(my < 0)
|
2014-03-12 22:42:51 +00:00
|
|
|
continue; // my = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(my >= h)
|
2014-03-12 22:42:51 +00:00
|
|
|
continue; // my = h-1;
|
|
|
|
}
|
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
int c = mx + my * w;
|
2014-03-12 22:42:51 +00:00
|
|
|
|
|
|
|
unsigned char Index = pTune[c].m_Type;
|
|
|
|
if(Index)
|
|
|
|
{
|
|
|
|
bool Render = false;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(RenderFlags & LAYERRENDERFLAG_TRANSPARENT)
|
2014-03-12 22:42:51 +00:00
|
|
|
Render = true;
|
|
|
|
|
|
|
|
if(Render)
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
int tx = Index % 16;
|
|
|
|
int ty = Index / 16;
|
|
|
|
int Px0 = tx * (1024 / 16);
|
|
|
|
int Py0 = ty * (1024 / 16);
|
|
|
|
int Px1 = Px0 + (1024 / 16) - 1;
|
|
|
|
int Py1 = Py0 + (1024 / 16) - 1;
|
|
|
|
|
|
|
|
float x0 = Nudge + Px0 / TexSize + Frac;
|
|
|
|
float y0 = Nudge + Py0 / TexSize + Frac;
|
|
|
|
float x1 = Nudge + Px1 / TexSize - Frac;
|
|
|
|
float y1 = Nudge + Py0 / TexSize + Frac;
|
|
|
|
float x2 = Nudge + Px1 / TexSize - Frac;
|
|
|
|
float y2 = Nudge + Py1 / TexSize - Frac;
|
|
|
|
float x3 = Nudge + Px0 / TexSize + Frac;
|
|
|
|
float y3 = Nudge + Py1 / TexSize - Frac;
|
2014-03-12 22:42:51 +00:00
|
|
|
|
|
|
|
Graphics()->QuadsSetSubsetFree(x0, y0, x1, y1, x2, y2, x3, y3);
|
2020-09-26 19:41:58 +00:00
|
|
|
IGraphics::CQuadItem QuadItem(x * Scale, y * Scale, Scale, Scale);
|
2014-03-12 22:42:51 +00:00
|
|
|
Graphics()->QuadsDrawTL(&QuadItem, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Graphics()->QuadsEnd();
|
|
|
|
Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1);
|
|
|
|
}
|