ddnet/src/game/client/components/mapimages.cpp

232 lines
6.5 KiB
C++
Raw Normal View History

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 <engine/graphics.h>
#include <engine/map.h>
2010-10-06 21:07:35 +00:00
#include <engine/storage.h>
#include <engine/serverbrowser.h>
2010-05-29 07:25:38 +00:00
#include <game/client/component.h>
#include <engine/textrender.h>
2010-05-29 07:25:38 +00:00
#include <game/mapitems.h>
2008-09-01 05:54:00 +00:00
2010-05-29 07:25:38 +00:00
#include "mapimages.h"
2008-09-01 05:54:00 +00:00
CMapImages::CMapImages() : CMapImages(100)
{
}
CMapImages::CMapImages(int TextureSize)
2008-09-01 05:54:00 +00:00
{
2010-05-29 07:25:38 +00:00
m_Count = 0;
m_TextureScale = TextureSize;
m_EntitiesIsLoaded = false;
}
2017-09-13 18:33:58 +00:00
void CMapImages::OnInit()
{
InitOverlayTextures();
2008-09-01 05:54:00 +00:00
}
2010-05-29 07:25:38 +00:00
void CMapImages::OnMapLoad()
2008-09-01 05:54:00 +00:00
{
2010-05-29 07:25:38 +00:00
IMap *pMap = Kernel()->RequestInterface<IMap>();
2008-09-01 05:54:00 +00:00
// unload all textures
2010-05-29 07:25:38 +00:00
for(int i = 0; i < m_Count; i++)
2008-09-01 05:54:00 +00:00
{
2010-05-29 07:25:38 +00:00
Graphics()->UnloadTexture(m_aTextures[i]);
m_aTextures[i] = IGraphics::CTextureHandle();
2008-09-01 05:54:00 +00:00
}
2010-05-29 07:25:38 +00:00
m_Count = 0;
2008-09-01 05:54:00 +00:00
2010-05-29 07:25:38 +00:00
int Start;
pMap->GetType(MAPITEMTYPE_IMAGE, &Start, &m_Count);
2008-09-01 05:54:00 +00:00
// load new textures
2015-08-25 00:11:04 +00:00
for(int i = 0; i < m_Count; i++)
{
CMapItemImage *pImg = (CMapItemImage *)pMap->GetItem(Start+i, 0, 0);
if(pImg->m_External)
{
char Buf[256];
char *pName = (char *)pMap->GetData(pImg->m_ImageName);
str_format(Buf, sizeof(Buf), "mapres/%s.png", pName);
m_aTextures[i] = Graphics()->LoadTexture(Buf, IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
}
else
{
void *pData = pMap->GetData(pImg->m_ImageData);
m_aTextures[i] = Graphics()->LoadTextureRaw(pImg->m_Width, pImg->m_Height, CImageInfo::FORMAT_RGBA, pData, CImageInfo::FORMAT_RGBA, 0);
pMap->UnloadData(pImg->m_ImageData);
}
}
}
void CMapImages::LoadBackground(class IMap *pMap)
{
// unload all textures
for(int i = 0; i < m_Count; i++)
{
Graphics()->UnloadTexture(m_aTextures[i]);
m_aTextures[i] = IGraphics::CTextureHandle();
2015-08-25 00:11:04 +00:00
}
m_Count = 0;
int Start;
pMap->GetType(MAPITEMTYPE_IMAGE, &Start, &m_Count);
// load new textures
2010-05-29 07:25:38 +00:00
for(int i = 0; i < m_Count; i++)
2008-09-01 05:54:00 +00:00
{
2010-05-29 07:25:38 +00:00
CMapItemImage *pImg = (CMapItemImage *)pMap->GetItem(Start+i, 0, 0);
if(pImg->m_External)
2008-09-01 05:54:00 +00:00
{
2010-05-29 07:25:38 +00:00
char Buf[256];
char *pName = (char *)pMap->GetData(pImg->m_ImageName);
str_format(Buf, sizeof(Buf), "mapres/%s.png", pName);
2010-10-06 21:07:35 +00:00
m_aTextures[i] = Graphics()->LoadTexture(Buf, IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
2008-09-01 05:54:00 +00:00
}
else
{
2010-05-29 07:25:38 +00:00
void *pData = pMap->GetData(pImg->m_ImageData);
m_aTextures[i] = Graphics()->LoadTextureRaw(pImg->m_Width, pImg->m_Height, CImageInfo::FORMAT_RGBA, pData, CImageInfo::FORMAT_RGBA, 0);
pMap->UnloadData(pImg->m_ImageData);
2008-09-01 05:54:00 +00:00
}
}
}
IGraphics::CTextureHandle CMapImages::GetEntities()
2011-03-16 12:48:16 +00:00
{
// DDNet default to prevent delay in seeing entities
const char *pEntities = "ddnet";
if(GameClient()->m_GameInfo.m_EntitiesDDNet)
pEntities = "ddnet";
else if(GameClient()->m_GameInfo.m_EntitiesDDRace)
pEntities = "ddrace";
else if(GameClient()->m_GameInfo.m_EntitiesRace)
pEntities = "race";
else if(GameClient()->m_GameInfo.m_EntitiesFNG)
pEntities = "fng";
else if(GameClient()->m_GameInfo.m_EntitiesVanilla)
pEntities = "vanilla";
if(!m_EntitiesIsLoaded || m_pEntitiesGameType != pEntities)
2011-03-16 12:48:16 +00:00
{
char aPath[64];
str_format(aPath, sizeof(aPath), "editor/entities_clear/%s.png", pEntities);
2017-03-02 08:27:03 +00:00
if(m_EntitiesTextures >= 0)
Graphics()->UnloadTexture(m_EntitiesTextures);
m_EntitiesTextures = Graphics()->LoadTexture(aPath, IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
m_EntitiesIsLoaded = true;
m_pEntitiesGameType = pEntities;
2011-03-16 12:48:16 +00:00
}
return m_EntitiesTextures;
}
IGraphics::CTextureHandle CMapImages::GetOverlayBottom()
2017-09-13 18:33:58 +00:00
{
return m_OverlayBottomTexture;
}
IGraphics::CTextureHandle CMapImages::GetOverlayTop()
2017-09-13 18:33:58 +00:00
{
return m_OverlayTopTexture;
}
IGraphics::CTextureHandle CMapImages::GetOverlayCenter()
2017-09-13 18:33:58 +00:00
{
return m_OverlayCenterTexture;
}
void CMapImages::SetTextureScale(int Scale)
{
if(m_TextureScale == Scale)
return;
m_TextureScale = Scale;
if(Graphics() && m_OverlayCenterTexture != -1) // check if component was initialized
{
// reinitialize component
Graphics()->UnloadTexture(m_OverlayBottomTexture);
Graphics()->UnloadTexture(m_OverlayTopTexture);
Graphics()->UnloadTexture(m_OverlayCenterTexture);
InitOverlayTextures();
}
}
int CMapImages::GetTextureScale()
{
return m_TextureScale;
}
IGraphics::CTextureHandle CMapImages::UploadEntityLayerText(int TextureSize, int YOffset)
{
void *pMem = calloc(1024 * 1024, 1);
IGraphics::CTextureHandle Texture = Graphics()->LoadTextureRaw(1024, 1024, CImageInfo::FORMAT_ALPHA, pMem, CImageInfo::FORMAT_ALPHA, IGraphics::TEXLOAD_NOMIPMAPS);
free(pMem);
UpdateEntityLayerText(Texture, TextureSize, YOffset, 0);
UpdateEntityLayerText(Texture, TextureSize, YOffset, 1);
UpdateEntityLayerText(Texture, TextureSize, YOffset, 2, 255);
return Texture;
}
void CMapImages::UpdateEntityLayerText(IGraphics::CTextureHandle Texture, int TextureSize, int YOffset, int NumbersPower, int MaxNumber)
{
char aBuf[4];
int DigitsCount = NumbersPower+1;
int CurrentNumber = pow(10, NumbersPower);
if (MaxNumber == -1)
MaxNumber = CurrentNumber*10-1;
str_format(aBuf, 4, "%d", CurrentNumber);
int CurrentNumberSuitableFontSize = TextRender()->AdjustFontSize(aBuf, DigitsCount, TextureSize);
int UniversalSuitableFontSize = CurrentNumberSuitableFontSize*0.9; // should be smoothed enough to fit any digits combination
2019-05-11 15:59:47 +00:00
if (UniversalSuitableFontSize < 1)
2019-05-11 15:59:47 +00:00
{
dbg_msg("pFont", "texture with id '%d' will not be loaded. Reason - font is too small", (int)Texture);
2019-05-11 15:59:47 +00:00
}
int ApproximateTextWidth = TextRender()->CalculateTextWidth(aBuf, DigitsCount, 0, UniversalSuitableFontSize);
int XOffSet = (64-ApproximateTextWidth)/2;
YOffset += ((TextureSize - UniversalSuitableFontSize)/2);
for (; CurrentNumber <= MaxNumber; ++CurrentNumber)
{
str_format(aBuf, 4, "%d", CurrentNumber);
float x = (CurrentNumber%16)*64;
float y = (CurrentNumber/16)*64;
TextRender()->UploadEntityLayerText(Texture, aBuf, DigitsCount, x+XOffSet, y+YOffset, UniversalSuitableFontSize);
}
}
void CMapImages::InitOverlayTextures()
{
int TextureSize = 64*m_TextureScale/100;
int TextureToVerticalCenterOffset = (64-TextureSize)/2; // should be used to move texture to the center of 64 pixels area
if(m_OverlayBottomTexture == -1)
{
m_OverlayBottomTexture = UploadEntityLayerText(TextureSize/2, 32+TextureToVerticalCenterOffset/2);
}
if(m_OverlayTopTexture == -1)
{
m_OverlayTopTexture = UploadEntityLayerText(TextureSize/2, TextureToVerticalCenterOffset/2);
}
if(m_OverlayCenterTexture == -1)
{
m_OverlayCenterTexture = UploadEntityLayerText(TextureSize, TextureToVerticalCenterOffset);
}
}