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>
2016-04-29 16:17:06 +00:00
# include <engine/serverbrowser.h>
2020-09-26 19:41:58 +00:00
# include <engine/storage.h>
2017-09-12 18:15:37 +00:00
# include <engine/textrender.h>
2020-09-26 19:41:58 +00:00
# include <game/client/component.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
2020-09-26 19:41:58 +00:00
CMapImages : : CMapImages ( ) :
CMapImages ( 100 )
2019-05-06 12:19:10 +00:00
{
}
2020-09-26 19:41:58 +00:00
CMapImages : : CMapImages ( int TextureSize )
2008-09-01 05:54:00 +00:00
{
2010-05-29 07:25:38 +00:00
m_Count = 0 ;
2019-05-06 12:19:10 +00:00
m_TextureScale = TextureSize ;
2020-09-08 13:11:32 +00:00
mem_zero ( m_EntitiesIsLoaded , sizeof ( m_EntitiesIsLoaded ) ) ;
2020-08-19 05:05:51 +00:00
m_SpeedupArrowIsLoaded = false ;
2020-08-23 06:25:21 +00:00
mem_zero ( m_aTextureUsedByTileOrQuadLayerFlag , sizeof ( m_aTextureUsedByTileOrQuadLayerFlag ) ) ;
2020-09-26 07:37:35 +00:00
str_copy ( m_aEntitiesPath , " editor/entities_clear " , sizeof ( m_aEntitiesPath ) ) ;
static_assert ( sizeof ( gs_aModEntitiesNames ) / sizeof ( gs_aModEntitiesNames [ 0 ] ) = = MAP_IMAGE_MOD_TYPE_COUNT , " Mod name string count is not equal to mod type count " ) ;
2017-09-12 18:15:37 +00:00
}
2017-09-13 18:33:58 +00:00
void CMapImages : : OnInit ( )
{
2019-05-06 12:19:10 +00:00
InitOverlayTextures ( ) ;
2020-09-26 07:37:35 +00:00
if ( str_comp ( g_Config . m_ClAssetsEntites , " default " ) = = 0 )
str_copy ( m_aEntitiesPath , " editor/entities_clear " , sizeof ( m_aEntitiesPath ) ) ;
else
{
str_format ( m_aEntitiesPath , sizeof ( m_aEntitiesPath ) , " assets/entities/%s " , g_Config . m_ClAssetsEntites ) ;
}
2008-09-01 05:54:00 +00:00
}
2020-08-26 13:06:51 +00:00
void CMapImages : : OnMapLoadImpl ( class CLayers * pLayers , IMap * pMap )
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 ] ) ;
2012-08-12 10:41:50 +00:00
m_aTextures [ i ] = IGraphics : : CTextureHandle ( ) ;
2020-08-23 06:25:21 +00:00
m_aTextureUsedByTileOrQuadLayerFlag [ i ] = 0 ;
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 ) ;
2011-04-13 18:37:12 +00:00
2020-09-19 18:52:28 +00:00
m_Count = clamp ( m_Count , 0 , 64 ) ;
2020-08-19 05:05:51 +00:00
for ( int g = 0 ; g < pLayers - > NumGroups ( ) ; g + + )
2015-08-25 00:11:04 +00:00
{
2020-08-19 05:05:51 +00:00
CMapItemGroup * pGroup = pLayers - > GetGroup ( g ) ;
if ( ! pGroup )
2015-08-25 00:11:04 +00:00
{
2020-08-19 05:05:51 +00:00
continue ;
2015-08-25 00:11:04 +00:00
}
2020-08-19 05:05:51 +00:00
for ( int l = 0 ; l < pGroup - > m_NumLayers ; l + + )
2015-08-25 00:11:04 +00:00
{
2020-09-26 19:41:58 +00:00
CMapItemLayer * pLayer = pLayers - > GetLayer ( pGroup - > m_StartLayer + l ) ;
2020-08-19 05:05:51 +00:00
if ( pLayer - > m_Type = = LAYERTYPE_TILES )
{
CMapItemLayerTilemap * pTLayer = ( CMapItemLayerTilemap * ) pLayer ;
if ( pTLayer - > m_Image ! = - 1 & & pTLayer - > m_Image < ( int ) ( sizeof ( m_aTextures ) / sizeof ( m_aTextures [ 0 ] ) ) )
{
2020-09-10 22:42:42 +00:00
m_aTextureUsedByTileOrQuadLayerFlag [ pTLayer - > m_Image ] | = 1 ;
2020-08-23 06:25:21 +00:00
}
}
else if ( pLayer - > m_Type = = LAYERTYPE_QUADS )
{
CMapItemLayerQuads * pQLayer = ( CMapItemLayerQuads * ) pLayer ;
if ( pQLayer - > m_Image ! = - 1 & & pQLayer - > m_Image < ( int ) ( sizeof ( m_aTextures ) / sizeof ( m_aTextures [ 0 ] ) ) )
{
2020-09-10 22:42:42 +00:00
m_aTextureUsedByTileOrQuadLayerFlag [ pQLayer - > m_Image ] | = 2 ;
2020-08-19 05:05:51 +00:00
}
}
2015-08-25 00:11:04 +00:00
}
}
2020-08-19 05:05:51 +00:00
int TextureLoadFlag = Graphics ( ) - > HasTextureArrays ( ) ? IGraphics : : TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics : : TEXLOAD_TO_3D_TEXTURE ;
2015-08-25 00:11:04 +00:00
// 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
{
2020-08-23 06:25:21 +00:00
int LoadFlag = ( ( ( m_aTextureUsedByTileOrQuadLayerFlag [ i ] & 1 ) ! = 0 ) ? TextureLoadFlag : 0 ) | ( ( ( m_aTextureUsedByTileOrQuadLayerFlag [ i ] & 2 ) ! = 0 ) ? 0 : ( Graphics ( ) - > IsTileBufferingEnabled ( ) ? IGraphics : : TEXLOAD_NO_2D_TEXTURE : 0 ) ) ;
2020-09-26 19:41:58 +00:00
CMapItemImage * pImg = ( CMapItemImage * ) pMap - > GetItem ( Start + i , 0 , 0 ) ;
2010-05-29 07:25:38 +00:00
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 ) ;
2020-08-23 06:25:21 +00:00
m_aTextures [ i ] = Graphics ( ) - > LoadTexture ( Buf , IStorage : : TYPE_ALL , CImageInfo : : FORMAT_AUTO , LoadFlag ) ;
2008-09-01 05:54:00 +00:00
}
else
{
2010-05-29 07:25:38 +00:00
void * pData = pMap - > GetData ( pImg - > m_ImageData ) ;
2020-08-29 10:49:45 +00:00
char * pName = ( char * ) pMap - > GetData ( pImg - > m_ImageName ) ;
char aTexName [ 128 ] ;
str_format ( aTexName , sizeof ( aTexName ) , " %s %s " , " embedded: " , pName ) ;
m_aTextures [ i ] = Graphics ( ) - > LoadTextureRaw ( pImg - > m_Width , pImg - > m_Height , CImageInfo : : FORMAT_RGBA , pData , CImageInfo : : FORMAT_RGBA , LoadFlag , aTexName ) ;
2010-05-29 07:25:38 +00:00
pMap - > UnloadData ( pImg - > m_ImageData ) ;
2008-09-01 05:54:00 +00:00
}
}
}
2020-08-26 13:06:51 +00:00
void CMapImages : : OnMapLoad ( )
{
IMap * pMap = Kernel ( ) - > RequestInterface < IMap > ( ) ;
CLayers * pLayers = m_pClient - > Layers ( ) ;
OnMapLoadImpl ( pLayers , pMap ) ;
}
void CMapImages : : LoadBackground ( class CLayers * pLayers , class IMap * pMap )
2020-08-19 05:05:51 +00:00
{
2020-08-26 13:06:51 +00:00
OnMapLoadImpl ( pLayers , pMap ) ;
2020-08-19 05:05:51 +00:00
}
2020-09-22 00:01:22 +00:00
bool CMapImages : : HasFrontLayer ( EMapImageModType ModType )
2020-09-08 13:11:32 +00:00
{
2020-09-22 00:01:22 +00:00
return ModType = = MAP_IMAGE_MOD_TYPE_DDNET | | ModType = = MAP_IMAGE_MOD_TYPE_DDRACE ;
2020-09-08 13:11:32 +00:00
}
2020-09-22 00:01:22 +00:00
bool CMapImages : : HasSpeedupLayer ( EMapImageModType ModType )
2020-09-08 13:11:32 +00:00
{
2020-09-22 00:01:22 +00:00
return ModType = = MAP_IMAGE_MOD_TYPE_DDNET | | ModType = = MAP_IMAGE_MOD_TYPE_DDRACE ;
2020-09-08 13:11:32 +00:00
}
2020-09-22 00:01:22 +00:00
bool CMapImages : : HasSwitchLayer ( EMapImageModType ModType )
2020-09-08 13:11:32 +00:00
{
2020-09-22 00:01:22 +00:00
return ModType = = MAP_IMAGE_MOD_TYPE_DDNET | | ModType = = MAP_IMAGE_MOD_TYPE_DDRACE ;
2020-09-08 13:11:32 +00:00
}
2020-09-22 00:01:22 +00:00
bool CMapImages : : HasTeleLayer ( EMapImageModType ModType )
2020-09-08 13:11:32 +00:00
{
2020-09-22 00:01:22 +00:00
return ModType = = MAP_IMAGE_MOD_TYPE_DDNET | | ModType = = MAP_IMAGE_MOD_TYPE_DDRACE ;
2020-09-08 13:11:32 +00:00
}
2020-09-22 00:01:22 +00:00
bool CMapImages : : HasTuneLayer ( EMapImageModType ModType )
2020-09-08 13:11:32 +00:00
{
2020-09-22 00:01:22 +00:00
return ModType = = MAP_IMAGE_MOD_TYPE_DDNET | | ModType = = MAP_IMAGE_MOD_TYPE_DDRACE ;
2020-09-08 13:11:32 +00:00
}
IGraphics : : CTextureHandle CMapImages : : GetEntities ( EMapImageEntityLayerType EntityLayerType )
2011-03-16 12:48:16 +00:00
{
2020-09-19 12:43:47 +00:00
EMapImageModType EntitiesModType = MAP_IMAGE_MOD_TYPE_DDNET ;
2020-09-08 13:11:32 +00:00
bool EntitesAreMasked = ! GameClient ( ) - > m_GameInfo . m_DontMaskEntities ;
2020-12-21 15:45:19 +00:00
if ( GameClient ( ) - > m_GameInfo . m_EntitiesFDDrace )
EntitiesModType = MAP_IMAGE_MOD_TYPE_FDDRACE ;
else if ( GameClient ( ) - > m_GameInfo . m_EntitiesDDNet )
2020-09-08 13:11:32 +00:00
EntitiesModType = MAP_IMAGE_MOD_TYPE_DDNET ;
2020-09-19 12:43:47 +00:00
else if ( GameClient ( ) - > m_GameInfo . m_EntitiesDDRace )
2020-09-08 13:11:32 +00:00
EntitiesModType = MAP_IMAGE_MOD_TYPE_DDRACE ;
2019-06-03 19:52:14 +00:00
else if ( GameClient ( ) - > m_GameInfo . m_EntitiesRace )
2020-09-08 13:11:32 +00:00
EntitiesModType = MAP_IMAGE_MOD_TYPE_RACE ;
2020-09-10 22:42:42 +00:00
else if ( GameClient ( ) - > m_GameInfo . m_EntitiesBW )
2020-09-08 13:11:32 +00:00
EntitiesModType = MAP_IMAGE_MOD_TYPE_BLOCKWORLDS ;
2019-06-03 19:52:14 +00:00
else if ( GameClient ( ) - > m_GameInfo . m_EntitiesFNG )
2020-09-08 13:11:32 +00:00
EntitiesModType = MAP_IMAGE_MOD_TYPE_FNG ;
2019-06-03 19:52:14 +00:00
else if ( GameClient ( ) - > m_GameInfo . m_EntitiesVanilla )
2020-09-08 13:11:32 +00:00
EntitiesModType = MAP_IMAGE_MOD_TYPE_VANILLA ;
2019-06-03 19:52:14 +00:00
2020-09-22 00:01:22 +00:00
if ( ! m_EntitiesIsLoaded [ ( EntitiesModType * 2 ) + ( int ) EntitesAreMasked ] )
2011-03-16 12:48:16 +00:00
{
2020-09-22 00:01:22 +00:00
m_EntitiesIsLoaded [ ( EntitiesModType * 2 ) + ( int ) EntitesAreMasked ] = true ;
2020-09-10 22:42:42 +00:00
2020-09-19 12:43:47 +00:00
// any mod that does not mask, will get all layers unmasked
bool WasUnknwon = ! EntitesAreMasked ;
2020-09-08 13:11:32 +00:00
2019-06-03 19:52:14 +00:00
char aPath [ 64 ] ;
2020-09-26 07:37:35 +00:00
str_format ( aPath , sizeof ( aPath ) , " %s/%s.png " , m_aEntitiesPath , gs_aModEntitiesNames [ EntitiesModType ] ) ;
2019-06-03 19:52:14 +00:00
2020-09-22 00:01:22 +00:00
bool GameTypeHasFrontLayer = HasFrontLayer ( EntitiesModType ) | | WasUnknwon ;
bool GameTypeHasSpeedupLayer = HasSpeedupLayer ( EntitiesModType ) | | WasUnknwon ;
bool GameTypeHasSwitchLayer = HasSwitchLayer ( EntitiesModType ) | | WasUnknwon ;
bool GameTypeHasTeleLayer = HasTeleLayer ( EntitiesModType ) | | WasUnknwon ;
bool GameTypeHasTuneLayer = HasTuneLayer ( EntitiesModType ) | | WasUnknwon ;
2020-09-08 13:11:32 +00:00
2020-08-19 05:05:51 +00:00
int TextureLoadFlag = Graphics ( ) - > HasTextureArrays ( ) ? IGraphics : : TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics : : TEXLOAD_TO_3D_TEXTURE ;
2020-09-08 13:11:32 +00:00
CImageInfo ImgInfo ;
2020-09-26 07:37:35 +00:00
bool ImagePNGLoaded = false ;
if ( Graphics ( ) - > LoadPNG ( & ImgInfo , aPath , IStorage : : TYPE_ALL ) )
ImagePNGLoaded = true ;
else
{
bool TryDefault = true ;
// try as single ddnet replacement
if ( EntitiesModType = = MAP_IMAGE_MOD_TYPE_DDNET )
{
str_format ( aPath , sizeof ( aPath ) , " %s.png " , m_aEntitiesPath ) ;
if ( Graphics ( ) - > LoadPNG ( & ImgInfo , aPath , IStorage : : TYPE_ALL ) )
{
ImagePNGLoaded = true ;
TryDefault = false ;
}
}
if ( ! ImagePNGLoaded & & TryDefault )
{
// try default
str_format ( aPath , sizeof ( aPath ) , " editor/entities_clear/%s.png " , gs_aModEntitiesNames [ EntitiesModType ] ) ;
if ( Graphics ( ) - > LoadPNG ( & ImgInfo , aPath , IStorage : : TYPE_ALL ) )
{
ImagePNGLoaded = true ;
}
}
}
if ( ImagePNGLoaded & & ImgInfo . m_Width > 0 & & ImgInfo . m_Height > 0 )
2020-09-08 13:11:32 +00:00
{
2020-10-12 14:07:29 +00:00
int ColorChannelCount = 4 ;
2020-09-08 13:11:32 +00:00
if ( ImgInfo . m_Format = = CImageInfo : : FORMAT_ALPHA )
ColorChannelCount = 1 ;
else if ( ImgInfo . m_Format = = CImageInfo : : FORMAT_RGB )
ColorChannelCount = 3 ;
else if ( ImgInfo . m_Format = = CImageInfo : : FORMAT_RGBA )
ColorChannelCount = 4 ;
2020-09-10 22:42:42 +00:00
int BuildImageSize = ColorChannelCount * ImgInfo . m_Width * ImgInfo . m_Height ;
uint8_t * pTmpImgData = ( uint8_t * ) ImgInfo . m_pData ;
uint8_t * pBuildImgData = ( uint8_t * ) malloc ( BuildImageSize ) ;
2020-09-08 13:11:32 +00:00
// build game layer
2020-09-10 22:42:42 +00:00
for ( int n = 0 ; n < MAP_IMAGE_ENTITY_LAYER_TYPE_COUNT ; + + n )
2020-09-08 13:11:32 +00:00
{
bool BuildThisLayer = true ;
2020-09-10 22:42:42 +00:00
if ( n = = MAP_IMAGE_ENTITY_LAYER_TYPE_FRONT & & ! GameTypeHasFrontLayer )
2020-09-08 13:11:32 +00:00
BuildThisLayer = false ;
2020-09-10 22:42:42 +00:00
else if ( n = = MAP_IMAGE_ENTITY_LAYER_TYPE_SPEEDUP & & ! GameTypeHasSpeedupLayer )
2020-09-08 13:11:32 +00:00
BuildThisLayer = false ;
2020-09-10 22:42:42 +00:00
else if ( n = = MAP_IMAGE_ENTITY_LAYER_TYPE_SWITCH & & ! GameTypeHasSwitchLayer )
2020-09-08 13:11:32 +00:00
BuildThisLayer = false ;
2020-09-10 22:42:42 +00:00
else if ( n = = MAP_IMAGE_ENTITY_LAYER_TYPE_TELE & & ! GameTypeHasTeleLayer )
2020-09-08 13:11:32 +00:00
BuildThisLayer = false ;
2020-09-10 22:42:42 +00:00
else if ( n = = MAP_IMAGE_ENTITY_LAYER_TYPE_TUNE & & ! GameTypeHasTuneLayer )
2020-09-08 13:11:32 +00:00
BuildThisLayer = false ;
2020-09-22 00:01:22 +00:00
dbg_assert ( m_EntitiesTextures [ ( EntitiesModType * 2 ) + ( int ) EntitesAreMasked ] [ n ] = = - 1 , " entities texture already loaded when it should not be " ) ;
2020-09-08 13:11:32 +00:00
if ( BuildThisLayer )
{
// set everything transparent
mem_zero ( pBuildImgData , BuildImageSize ) ;
2020-09-10 22:42:42 +00:00
for ( int i = 0 ; i < 256 ; + + i )
2020-09-08 13:11:32 +00:00
{
bool ValidTile = i ! = 0 ;
2020-09-10 22:42:42 +00:00
int TileIndex = i ;
2020-09-19 12:43:47 +00:00
if ( EntitesAreMasked )
2020-09-08 13:11:32 +00:00
{
2020-09-19 12:43:47 +00:00
if ( EntitiesModType = = MAP_IMAGE_MOD_TYPE_DDNET | | EntitiesModType = = MAP_IMAGE_MOD_TYPE_DDRACE )
2020-09-08 13:11:32 +00:00
{
2020-09-19 12:43:47 +00:00
if ( EntitiesModType = = MAP_IMAGE_MOD_TYPE_DDNET | | TileIndex ! = TILE_BOOST )
2020-09-08 13:11:32 +00:00
{
2020-09-19 12:43:47 +00:00
if ( n = = MAP_IMAGE_ENTITY_LAYER_TYPE_GAME & & ! IsValidGameTile ( ( int ) TileIndex ) )
ValidTile = false ;
else if ( n = = MAP_IMAGE_ENTITY_LAYER_TYPE_FRONT & & ! IsValidFrontTile ( ( int ) TileIndex ) )
ValidTile = false ;
else if ( n = = MAP_IMAGE_ENTITY_LAYER_TYPE_SPEEDUP & & ! IsValidSpeedupTile ( ( int ) TileIndex ) )
2020-09-08 13:11:32 +00:00
ValidTile = false ;
2020-09-19 12:43:47 +00:00
else if ( n = = MAP_IMAGE_ENTITY_LAYER_TYPE_SWITCH )
2020-09-08 13:11:32 +00:00
{
2020-09-19 12:43:47 +00:00
if ( ! IsValidSwitchTile ( ( int ) TileIndex ) )
ValidTile = false ;
2020-09-10 22:42:42 +00:00
}
2020-09-19 12:43:47 +00:00
else if ( n = = MAP_IMAGE_ENTITY_LAYER_TYPE_TELE & & ! IsValidTeleTile ( ( int ) TileIndex ) )
ValidTile = false ;
else if ( n = = MAP_IMAGE_ENTITY_LAYER_TYPE_TUNE & & ! IsValidTuneTile ( ( int ) TileIndex ) )
ValidTile = false ;
2020-09-08 13:11:32 +00:00
}
}
2020-09-19 12:43:47 +00:00
else if ( ( EntitiesModType = = MAP_IMAGE_MOD_TYPE_RACE ) & & IsCreditsTile ( ( int ) TileIndex ) )
{
ValidTile = false ;
}
else if ( ( EntitiesModType = = MAP_IMAGE_MOD_TYPE_FNG ) & & IsCreditsTile ( ( int ) TileIndex ) )
{
ValidTile = false ;
}
else if ( ( EntitiesModType = = MAP_IMAGE_MOD_TYPE_VANILLA ) & & IsCreditsTile ( ( int ) TileIndex ) )
{
ValidTile = false ;
}
/*else if((EntitiesModType == MAP_IMAGE_MOD_TYPE_RACE_BLOCKWORLD) && ...)
{
ValidTile = false ;
} */
2020-09-08 13:11:32 +00:00
}
2020-09-19 12:43:47 +00:00
if ( EntitiesModType = = MAP_IMAGE_MOD_TYPE_DDNET | | EntitiesModType = = MAP_IMAGE_MOD_TYPE_DDRACE )
2020-09-08 13:11:32 +00:00
{
2020-09-19 12:43:47 +00:00
if ( n = = MAP_IMAGE_ENTITY_LAYER_TYPE_SWITCH & & TileIndex = = TILE_SWITCHTIMEDOPEN )
TileIndex = 8 ;
2020-09-08 13:11:32 +00:00
}
2020-09-10 22:42:42 +00:00
int X = TileIndex % 16 ;
int Y = TileIndex / 16 ;
2020-09-08 13:11:32 +00:00
2020-09-10 22:42:42 +00:00
int CopyWidth = ImgInfo . m_Width / 16 ;
int CopyHeight = ImgInfo . m_Height / 16 ;
2020-09-08 13:11:32 +00:00
if ( ValidTile )
{
2020-09-10 22:42:42 +00:00
Graphics ( ) - > CopyTextureBufferSub ( pBuildImgData , pTmpImgData , ImgInfo . m_Width , ImgInfo . m_Height , ColorChannelCount , X * CopyWidth , Y * CopyHeight , CopyWidth , CopyHeight ) ;
2020-09-08 13:11:32 +00:00
}
}
2020-09-22 00:01:22 +00:00
m_EntitiesTextures [ ( EntitiesModType * 2 ) + ( int ) EntitesAreMasked ] [ n ] = Graphics ( ) - > LoadTextureRaw ( ImgInfo . m_Width , ImgInfo . m_Height , ImgInfo . m_Format , pBuildImgData , ImgInfo . m_Format , TextureLoadFlag , aPath ) ;
2020-09-08 13:11:32 +00:00
}
else
{
if ( m_TransparentTexture = = - 1 )
{
// set everything transparent
mem_zero ( pBuildImgData , BuildImageSize ) ;
m_TransparentTexture = Graphics ( ) - > LoadTextureRaw ( ImgInfo . m_Width , ImgInfo . m_Height , ImgInfo . m_Format , pBuildImgData , ImgInfo . m_Format , TextureLoadFlag , aPath ) ;
}
2020-09-22 00:01:22 +00:00
m_EntitiesTextures [ ( EntitiesModType * 2 ) + ( int ) EntitesAreMasked ] [ n ] = m_TransparentTexture ;
2020-09-10 22:42:42 +00:00
}
2020-09-08 13:11:32 +00:00
}
free ( pBuildImgData ) ;
2020-11-25 12:05:53 +00:00
Graphics ( ) - > FreePNG ( & ImgInfo ) ;
2020-09-08 13:11:32 +00:00
}
2011-03-16 12:48:16 +00:00
}
2020-09-08 13:11:32 +00:00
2020-09-22 00:01:22 +00:00
return m_EntitiesTextures [ ( EntitiesModType * 2 ) + ( int ) EntitesAreMasked ] [ EntityLayerType ] ;
2011-03-16 12:48:16 +00:00
}
2017-09-12 18:15:37 +00:00
2020-08-19 05:05:51 +00:00
IGraphics : : CTextureHandle CMapImages : : GetSpeedupArrow ( )
{
if ( ! m_SpeedupArrowIsLoaded )
{
2020-08-23 06:25:21 +00:00
int TextureLoadFlag = ( Graphics ( ) - > HasTextureArrays ( ) ? IGraphics : : TEXLOAD_TO_2D_ARRAY_TEXTURE_SINGLE_LAYER : IGraphics : : TEXLOAD_TO_3D_TEXTURE_SINGLE_LAYER ) | IGraphics : : TEXLOAD_NO_2D_TEXTURE ;
2020-08-19 05:05:51 +00:00
m_SpeedupArrowTexture = Graphics ( ) - > LoadTexture ( g_pData - > m_aImages [ IMAGE_SPEEDUP_ARROW ] . m_pFilename , IStorage : : TYPE_ALL , CImageInfo : : FORMAT_AUTO , TextureLoadFlag ) ;
m_SpeedupArrowIsLoaded = true ;
}
return m_SpeedupArrowTexture ;
}
2012-08-12 10:41:50 +00:00
IGraphics : : CTextureHandle CMapImages : : GetOverlayBottom ( )
2017-09-13 18:33:58 +00:00
{
2017-09-12 18:15:37 +00:00
return m_OverlayBottomTexture ;
}
2012-08-12 10:41:50 +00:00
IGraphics : : CTextureHandle CMapImages : : GetOverlayTop ( )
2017-09-13 18:33:58 +00:00
{
2017-09-12 18:15:37 +00:00
return m_OverlayTopTexture ;
}
2012-08-12 10:41:50 +00:00
IGraphics : : CTextureHandle CMapImages : : GetOverlayCenter ( )
2017-09-13 18:33:58 +00:00
{
2017-09-12 18:15:37 +00:00
return m_OverlayCenterTexture ;
}
2019-05-06 12:19:10 +00:00
2020-09-26 07:37:35 +00:00
void CMapImages : : ChangeEntitiesPath ( const char * pPath )
{
if ( str_comp ( pPath , " default " ) = = 0 )
str_copy ( m_aEntitiesPath , " editor/entities_clear " , sizeof ( m_aEntitiesPath ) ) ;
else
{
str_format ( m_aEntitiesPath , sizeof ( m_aEntitiesPath ) , " assets/entities/%s " , pPath ) ;
}
for ( int i = 0 ; i < MAP_IMAGE_MOD_TYPE_COUNT * 2 ; + + i )
{
if ( m_EntitiesIsLoaded [ i ] )
{
for ( int n = 0 ; n < MAP_IMAGE_ENTITY_LAYER_TYPE_COUNT ; + + n )
{
if ( m_EntitiesTextures [ i ] [ n ] ! = - 1 )
Graphics ( ) - > UnloadTexture ( m_EntitiesTextures [ i ] [ n ] ) ;
m_EntitiesTextures [ i ] [ n ] = IGraphics : : CTextureHandle ( ) ;
}
m_EntitiesIsLoaded [ i ] = false ;
}
}
}
2019-05-06 12:19:10 +00:00
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 ) ;
2020-09-01 07:13:47 +00:00
m_OverlayBottomTexture = IGraphics : : CTextureHandle ( ) ;
m_OverlayTopTexture = IGraphics : : CTextureHandle ( ) ;
m_OverlayCenterTexture = IGraphics : : CTextureHandle ( ) ;
2019-05-06 12:19:10 +00:00
InitOverlayTextures ( ) ;
}
}
int CMapImages : : GetTextureScale ( )
{
return m_TextureScale ;
}
2020-08-26 13:56:23 +00:00
IGraphics : : CTextureHandle CMapImages : : UploadEntityLayerText ( int TextureSize , int MaxWidth , int YOffset )
2020-09-26 19:41:58 +00:00
{
2020-08-22 06:09:10 +00:00
void * pMem = calloc ( 1024 * 1024 * 4 , 1 ) ;
2019-05-06 12:19:10 +00:00
2020-08-26 13:56:23 +00:00
UpdateEntityLayerText ( pMem , 4 , 1024 , 1024 , TextureSize , MaxWidth , YOffset , 0 ) ;
UpdateEntityLayerText ( pMem , 4 , 1024 , 1024 , TextureSize , MaxWidth , YOffset , 1 ) ;
UpdateEntityLayerText ( pMem , 4 , 1024 , 1024 , TextureSize , MaxWidth , YOffset , 2 , 255 ) ;
2020-08-19 05:05:51 +00:00
2020-08-23 06:25:21 +00:00
int TextureLoadFlag = ( Graphics ( ) - > HasTextureArrays ( ) ? IGraphics : : TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics : : TEXLOAD_TO_3D_TEXTURE ) | IGraphics : : TEXLOAD_NO_2D_TEXTURE ;
2020-08-22 06:09:10 +00:00
IGraphics : : CTextureHandle Texture = Graphics ( ) - > LoadTextureRaw ( 1024 , 1024 , CImageInfo : : FORMAT_RGBA , pMem , CImageInfo : : FORMAT_RGBA , TextureLoadFlag ) ;
2020-08-19 05:05:51 +00:00
free ( pMem ) ;
2019-08-17 00:42:54 +00:00
2012-08-12 10:41:50 +00:00
return Texture ;
2019-08-17 00:42:54 +00:00
}
2020-09-26 19:41:58 +00:00
void CMapImages : : UpdateEntityLayerText ( void * pTexBuffer , int ImageColorChannelCount , int TexWidth , int TexHeight , int TextureSize , int MaxWidth , int YOffset , int NumbersPower , int MaxNumber )
2019-08-17 00:42:54 +00:00
{
2019-05-06 12:19:10 +00:00
char aBuf [ 4 ] ;
2020-09-26 19:41:58 +00:00
int DigitsCount = NumbersPower + 1 ;
2019-05-06 12:19:10 +00:00
2019-08-17 00:42:54 +00:00
int CurrentNumber = pow ( 10 , NumbersPower ) ;
2020-09-14 14:39:05 +00:00
if ( MaxNumber = = - 1 )
MaxNumber = CurrentNumber * 10 - 1 ;
2019-08-17 00:42:54 +00:00
str_format ( aBuf , 4 , " %d " , CurrentNumber ) ;
2020-09-14 14:39:05 +00:00
2020-08-26 13:56:23 +00:00
int CurrentNumberSuitableFontSize = TextRender ( ) - > AdjustFontSize ( aBuf , DigitsCount , TextureSize , MaxWidth ) ;
2020-09-14 14:39:05 +00:00
int UniversalSuitableFontSize = CurrentNumberSuitableFontSize * 0.92f ; // should be smoothed enough to fit any digits combination
2019-05-11 15:59:47 +00:00
2020-09-14 14:39:05 +00:00
YOffset + = ( ( TextureSize - UniversalSuitableFontSize ) / 2 ) ;
2019-05-06 12:19:10 +00:00
2020-09-26 19:41:58 +00:00
for ( ; CurrentNumber < = MaxNumber ; + + CurrentNumber )
2019-05-06 12:19:10 +00:00
{
2019-08-17 00:42:54 +00:00
str_format ( aBuf , 4 , " %d " , CurrentNumber ) ;
2019-05-06 12:19:10 +00:00
2020-09-26 19:41:58 +00:00
float x = ( CurrentNumber % 16 ) * 64 ;
float y = ( CurrentNumber / 16 ) * 64 ;
2019-05-06 12:19:10 +00:00
2020-09-14 14:39:05 +00:00
int ApproximateTextWidth = TextRender ( ) - > CalculateTextWidth ( aBuf , DigitsCount , 0 , UniversalSuitableFontSize ) ;
int XOffSet = ( MaxWidth - clamp ( ApproximateTextWidth , 0 , MaxWidth ) ) / 2 ;
TextRender ( ) - > UploadEntityLayerText ( pTexBuffer , ImageColorChannelCount , TexWidth , TexHeight , ( TexWidth / 16 ) - XOffSet , ( TexHeight / 16 ) - YOffset , aBuf , DigitsCount , x + XOffSet , y + YOffset , UniversalSuitableFontSize ) ;
2019-08-17 00:42:54 +00:00
}
2019-05-06 12:19:10 +00:00
}
void CMapImages : : InitOverlayTextures ( )
{
2020-09-26 19:41:58 +00:00
int TextureSize = 64 * m_TextureScale / 100 ;
2020-10-19 12:18:23 +00:00
TextureSize = clamp ( TextureSize , 2 , 64 ) ;
2020-09-26 19:41:58 +00:00
int TextureToVerticalCenterOffset = ( 64 - TextureSize ) / 2 ; // should be used to move texture to the center of 64 pixels area
2019-05-06 12:19:10 +00:00
if ( m_OverlayBottomTexture = = - 1 )
{
2020-09-26 19:41:58 +00:00
m_OverlayBottomTexture = UploadEntityLayerText ( TextureSize / 2 , 64 , 32 + TextureToVerticalCenterOffset / 2 ) ;
2019-05-06 12:19:10 +00:00
}
if ( m_OverlayTopTexture = = - 1 )
{
2020-09-26 19:41:58 +00:00
m_OverlayTopTexture = UploadEntityLayerText ( TextureSize / 2 , 64 , TextureToVerticalCenterOffset / 2 ) ;
2019-05-06 12:19:10 +00:00
}
if ( m_OverlayCenterTexture = = - 1 )
{
2020-08-26 13:56:23 +00:00
m_OverlayCenterTexture = UploadEntityLayerText ( TextureSize , 64 , TextureToVerticalCenterOffset ) ;
2019-05-06 12:19:10 +00:00
}
}