2987: Modulize skins, particles, emoticons and game r=def- a=Jupeyy

fixes #2203 

Puh, something i always wanted todo.
Need to error read, bcs alot of copy paste.

Modulizes all images, so that all images are mipmap indepedent, without texeloffset problems

I also added the ninja bar analyzer for #2921


Co-authored-by: Jupeyy <jupjopjap@gmail.com>
This commit is contained in:
bors[bot] 2020-10-09 15:20:48 +00:00 committed by GitHub
commit f93c8e4fdb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 1039 additions and 293 deletions

View file

@ -1397,6 +1397,8 @@ generate_source("src/game/generated/server_data.h" "server_content_header")
generate_source7("src/game/generated/protocol7.cpp" "network_source") generate_source7("src/game/generated/protocol7.cpp" "network_source")
generate_source7("src/game/generated/protocol7.h" "network_header") generate_source7("src/game/generated/protocol7.h" "network_header")
generate_source7("src/game/generated/client_data7.cpp" "client_content_source")
generate_source7("src/game/generated/client_data7.h" "client_content_header")
generate_maps("src/game/generated/protocolglue.h") generate_maps("src/game/generated/protocolglue.h")
@ -1756,6 +1758,7 @@ if(CLIENT)
render.cpp render.cpp
render.h render.h
render_map.cpp render_map.cpp
skin.h
ui.cpp ui.cpp
ui.h ui.h
) )
@ -1775,6 +1778,8 @@ if(CLIENT)
set(GAME_GENERATED_CLIENT set(GAME_GENERATED_CLIENT
src/game/generated/client_data.cpp src/game/generated/client_data.cpp
src/game/generated/client_data.h src/game/generated/client_data.h
src/game/generated/client_data7.cpp
src/game/generated/client_data7.h
) )
set(CLIENT_SRC ${ENGINE_CLIENT} ${PLATFORM_CLIENT} ${GAME_CLIENT} ${GAME_EDITOR} ${GAME_GENERATED_CLIENT}) set(CLIENT_SRC ${ENGINE_CLIENT} ${PLATFORM_CLIENT} ${GAME_CLIENT} ${GAME_EDITOR} ${GAME_GENERATED_CLIENT})

View file

@ -55,18 +55,19 @@ if "server_content_header" in sys.argv: gen_server_content_header = True
if "server_content_source" in sys.argv: gen_server_content_source = True if "server_content_source" in sys.argv: gen_server_content_source = True
if gen_client_content_header: if gen_client_content_header:
print("#ifndef CLIENT_CONTENT_HEADER") print("#ifndef CLIENT_CONTENT7_HEADER")
print("#define CLIENT_CONTENT_HEADER") print("#define CLIENT_CONTENT7_HEADER")
if gen_server_content_header: if gen_server_content_header:
print("#ifndef SERVER_CONTENT_HEADER") print("#ifndef SERVER_CONTENT7_HEADER")
print("#define SERVER_CONTENT_HEADER") print("#define SERVER_CONTENT7_HEADER")
if gen_client_content_header or gen_server_content_header: if gen_client_content_header or gen_server_content_header:
# print some includes # print some includes
print('#include <engine/graphics.h>') print('#include <engine/graphics.h>')
print('#include <engine/sound.h>') print('#include <engine/sound.h>')
print("namespace client_data7 {")
# emit the type declarations # emit the type declarations
contentlines = open("datasrc/content.py", "rb").readlines() contentlines = open("datasrc/content.py", "rb").readlines()
@ -88,11 +89,13 @@ if gen_client_content_header or gen_server_content_header:
if gen_client_content_source or gen_server_content_source: if gen_client_content_source or gen_server_content_source:
if gen_client_content_source: if gen_client_content_source:
print('#include "client_data.h"') print('#include "client_data7.h"')
if gen_server_content_source: if gen_server_content_source:
print('#include "server_data.h"') print('#include "server_data.h"')
print("namespace client_data7 {")
EmitDefinition(content.container, "datacontainer") EmitDefinition(content.container, "datacontainer")
print('CDataContainer *g_pData = &datacontainer;') print('CDataContainer *g_pData = &datacontainer;')
print("}")
# NETWORK # NETWORK
if gen_network_header: if gen_network_header:
@ -356,4 +359,5 @@ if gen_network_source:
print(l) print(l)
if gen_client_content_header or gen_server_content_header: if gen_client_content_header or gen_server_content_header:
print("}")
print("#endif") print("#endif")

View file

@ -173,7 +173,7 @@ class DataContainer(Struct):
self.sprites = Array(Sprite()) self.sprites = Array(Sprite())
self.animations = Array(Animation()) self.animations = Array(Animation())
self.weapons = Weapons() self.weapons = Weapons()
self.explosion = Explosion() #self.explosion = Explosion()
def FileList(format, num): def FileList(format, num):
return [format%(x+1) for x in range(0,num)] return [format%(x+1) for x in range(0,num)]

View file

@ -18,6 +18,8 @@
#include <engine/keys.h> #include <engine/keys.h>
#include <engine/shared/config.h> #include <engine/shared/config.h>
#include <engine/storage.h> #include <engine/storage.h>
#include <game/generated/client_data.h>
#include <game/generated/client_data7.h>
#include <game/localization.h> #include <game/localization.h>
#include <math.h> // cosf, sinf, log2f #include <math.h> // cosf, sinf, log2f
@ -102,7 +104,7 @@ void CGraphics_Threaded::FlushVerticesTex3D()
void CGraphics_Threaded::AddVertices(int Count) void CGraphics_Threaded::AddVertices(int Count)
{ {
m_NumVertices += Count; m_NumVertices += Count;
if((m_NumVertices + Count) >= MAX_VERTICES) if((m_NumVertices + Count) >= CCommandBuffer::MAX_VERTICES)
FlushVertices(); FlushVertices();
} }
@ -114,7 +116,7 @@ void CGraphics_Threaded::AddVertices(int Count, CCommandBuffer::SVertex *pVertic
void CGraphics_Threaded::AddVertices(int Count, CCommandBuffer::SVertexTex3DStream *pVertices) void CGraphics_Threaded::AddVertices(int Count, CCommandBuffer::SVertexTex3DStream *pVertices)
{ {
m_NumVertices += Count; m_NumVertices += Count;
if((m_NumVertices + Count) >= MAX_VERTICES) if((m_NumVertices + Count) >= CCommandBuffer::MAX_VERTICES)
FlushVerticesTex3D(); FlushVerticesTex3D();
} }
@ -273,6 +275,13 @@ int CGraphics_Threaded::UnloadTexture(CTextureHandle Index)
return 0; return 0;
} }
int CGraphics_Threaded::UnloadTextureNew(CTextureHandle &TextureHandle)
{
int Ret = UnloadTexture(TextureHandle);
TextureHandle = IGraphics::CTextureHandle();
return Ret;
}
static int ImageFormatToTexFormat(int Format) static int ImageFormatToTexFormat(int Format)
{ {
if(Format == CImageInfo::FORMAT_RGB) if(Format == CImageInfo::FORMAT_RGB)
@ -322,6 +331,74 @@ int CGraphics_Threaded::LoadTextureRawSub(CTextureHandle TextureID, int x, int y
return 0; return 0;
} }
IGraphics::CTextureHandle CGraphics_Threaded::LoadSpriteTextureImpl(CImageInfo &FromImageInfo, int x, int y, int w, int h)
{
int bpp = ImageFormatToPixelSize(FromImageInfo.m_Format);
m_SpriteHelper.resize(w * h * bpp);
CopyTextureFromTextureBufferSub(&m_SpriteHelper[0], w, h, (uint8_t *)FromImageInfo.m_pData, FromImageInfo.m_Width, FromImageInfo.m_Height, bpp, x, y, w, h);
IGraphics::CTextureHandle RetHandle = LoadTextureRaw(w, h, FromImageInfo.m_Format, &m_SpriteHelper[0], FromImageInfo.m_Format, 0);
return RetHandle;
}
IGraphics::CTextureHandle CGraphics_Threaded::LoadSpriteTexture(CImageInfo &FromImageInfo, CDataSprite *pSprite)
{
int imggx = FromImageInfo.m_Width / pSprite->m_pSet->m_Gridx;
int imggy = FromImageInfo.m_Height / pSprite->m_pSet->m_Gridy;
int x = pSprite->m_X * imggx;
int y = pSprite->m_Y * imggy;
int w = pSprite->m_W * imggx;
int h = pSprite->m_H * imggy;
return LoadSpriteTextureImpl(FromImageInfo, x, y, w, h);
}
IGraphics::CTextureHandle CGraphics_Threaded::LoadSpriteTexture(CImageInfo &FromImageInfo, client_data7::CDataSprite *pSprite)
{
int imggx = FromImageInfo.m_Width / pSprite->m_pSet->m_Gridx;
int imggy = FromImageInfo.m_Height / pSprite->m_pSet->m_Gridy;
int x = pSprite->m_X * imggx;
int y = pSprite->m_Y * imggy;
int w = pSprite->m_W * imggx;
int h = pSprite->m_H * imggy;
return LoadSpriteTextureImpl(FromImageInfo, x, y, w, h);
}
bool CGraphics_Threaded::IsImageSubFullyTransparent(CImageInfo &FromImageInfo, int x, int y, int w, int h)
{
if(FromImageInfo.m_Format == CImageInfo::FORMAT_ALPHA || FromImageInfo.m_Format == CImageInfo::FORMAT_RGBA)
{
uint8_t *pImgData = (uint8_t *)FromImageInfo.m_pData;
int bpp = ImageFormatToPixelSize(FromImageInfo.m_Format);
for(int iy = 0; iy < h; ++iy)
{
for(int ix = 0; ix < w; ++ix)
{
int RealOffset = (x + ix) * bpp + (y + iy) * bpp * FromImageInfo.m_Width;
if(pImgData[RealOffset + (bpp - 1)] > 0)
return false;
}
}
return true;
}
return false;
}
bool CGraphics_Threaded::IsSpriteTextureFullyTransparent(CImageInfo &FromImageInfo, client_data7::CDataSprite *pSprite)
{
int imggx = FromImageInfo.m_Width / pSprite->m_pSet->m_Gridx;
int imggy = FromImageInfo.m_Height / pSprite->m_pSet->m_Gridy;
int x = pSprite->m_X * imggx;
int y = pSprite->m_Y * imggy;
int w = pSprite->m_W * imggx;
int h = pSprite->m_H * imggy;
return IsImageSubFullyTransparent(FromImageInfo, x, y, w, h);
}
IGraphics::CTextureHandle CGraphics_Threaded::LoadTextureRaw(int Width, int Height, int Format, const void *pData, int StoreFormat, int Flags, const char *pTexName) IGraphics::CTextureHandle CGraphics_Threaded::LoadTextureRaw(int Width, int Height, int Format, const void *pData, int StoreFormat, int Flags, const char *pTexName)
{ {
// don't waste memory on texture if we are stress testing // don't waste memory on texture if we are stress testing
@ -488,6 +565,17 @@ void CGraphics_Threaded::CopyTextureBufferSub(uint8_t *pDestBuffer, uint8_t *pSo
} }
} }
void CGraphics_Threaded::CopyTextureFromTextureBufferSub(uint8_t *pDestBuffer, int DestWidth, int DestHeight, uint8_t *pSourceBuffer, int SrcWidth, int SrcHeight, int ColorChannelCount, int SrcSubOffsetX, int SrcSubOffsetY, int SrcSubCopyWidth, int SrcSubCopyHeight)
{
for(int Y = 0; Y < SrcSubCopyHeight; ++Y)
{
int SrcImgOffset = ((SrcSubOffsetY + Y) * SrcWidth * ColorChannelCount) + (SrcSubOffsetX * ColorChannelCount);
int DstImgOffset = (Y * DestWidth * ColorChannelCount);
int CopySize = SrcSubCopyWidth * ColorChannelCount;
mem_copy(&pDestBuffer[DstImgOffset], &pSourceBuffer[SrcImgOffset], CopySize);
}
}
void CGraphics_Threaded::KickCommandBuffer() void CGraphics_Threaded::KickCommandBuffer()
{ {
m_pBackend->RunBuffer(m_pCommandBuffer); m_pBackend->RunBuffer(m_pCommandBuffer);
@ -1183,7 +1271,7 @@ void CGraphics_Threaded::QuadContainerAddQuads(int ContainerIndex, CQuadItem *pA
{ {
SQuadContainer &Container = m_QuadContainers[ContainerIndex]; SQuadContainer &Container = m_QuadContainers[ContainerIndex];
if((int)Container.m_Quads.size() > Num + CCommandBuffer::MAX_VERTICES) if((int)Container.m_Quads.size() > Num + CCommandBuffer::CCommandBuffer::MAX_VERTICES)
return; return;
for(int i = 0; i < Num; ++i) for(int i = 0; i < Num; ++i)
@ -1228,7 +1316,7 @@ void CGraphics_Threaded::QuadContainerAddQuads(int ContainerIndex, CFreeformItem
{ {
SQuadContainer &Container = m_QuadContainers[ContainerIndex]; SQuadContainer &Container = m_QuadContainers[ContainerIndex];
if((int)Container.m_Quads.size() > Num + CCommandBuffer::MAX_VERTICES) if((int)Container.m_Quads.size() > Num + CCommandBuffer::CCommandBuffer::MAX_VERTICES)
return; return;
for(int i = 0; i < Num; ++i) for(int i = 0; i < Num; ++i)
@ -1301,6 +1389,8 @@ void CGraphics_Threaded::RenderQuadContainer(int ContainerIndex, int QuadOffset,
if(Container.m_QuadBufferContainerIndex == -1) if(Container.m_QuadBufferContainerIndex == -1)
return; return;
WrapClamp();
CCommandBuffer::SCommand_RenderQuadContainer Cmd; CCommandBuffer::SCommand_RenderQuadContainer Cmd;
Cmd.m_State = m_State; Cmd.m_State = m_State;
Cmd.m_DrawNum = (unsigned int)QuadDrawNum * 6; Cmd.m_DrawNum = (unsigned int)QuadDrawNum * 6;
@ -1342,9 +1432,11 @@ void CGraphics_Threaded::RenderQuadContainer(int ContainerIndex, int QuadOffset,
m_NumVertices += 4 * QuadDrawNum; m_NumVertices += 4 * QuadDrawNum;
} }
m_Drawing = DRAWING_QUADS; m_Drawing = DRAWING_QUADS;
WrapClamp();
FlushVertices(false); FlushVertices(false);
m_Drawing = 0; m_Drawing = 0;
} }
WrapNormal();
} }
void CGraphics_Threaded::RenderQuadContainerAsSprite(int ContainerIndex, int QuadOffset, float X, float Y, float ScaleX, float ScaleY) void CGraphics_Threaded::RenderQuadContainerAsSprite(int ContainerIndex, int QuadOffset, float X, float Y, float ScaleX, float ScaleY)
@ -1362,6 +1454,8 @@ void CGraphics_Threaded::RenderQuadContainerAsSprite(int ContainerIndex, int Qua
SQuadContainer::SQuad &Quad = Container.m_Quads[QuadOffset]; SQuadContainer::SQuad &Quad = Container.m_Quads[QuadOffset];
CCommandBuffer::SCommand_RenderQuadContainerAsSprite Cmd; CCommandBuffer::SCommand_RenderQuadContainerAsSprite Cmd;
WrapClamp();
float ScreenX0, ScreenY0, ScreenX1, ScreenY1; float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1); GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1);
MapScreen((ScreenX0 - X) / ScaleX, (ScreenY0 - Y) / ScaleY, (ScreenX1 - X) / ScaleX, (ScreenY1 - Y) / ScaleY); MapScreen((ScreenX0 - X) / ScaleX, (ScreenY0 - Y) / ScaleY, (ScreenX1 - X) / ScaleX, (ScreenY1 - Y) / ScaleY);
@ -1468,9 +1562,11 @@ void CGraphics_Threaded::RenderQuadContainerAsSprite(int ContainerIndex, int Qua
m_NumVertices += 4; m_NumVertices += 4;
} }
m_Drawing = DRAWING_QUADS; m_Drawing = DRAWING_QUADS;
WrapClamp();
FlushVertices(false); FlushVertices(false);
m_Drawing = 0; m_Drawing = 0;
} }
WrapNormal();
} }
void CGraphics_Threaded::RenderQuadContainerAsSpriteMultiple(int ContainerIndex, int QuadOffset, int DrawCount, SRenderSpriteInfo *pRenderInfo) void CGraphics_Threaded::RenderQuadContainerAsSpriteMultiple(int ContainerIndex, int QuadOffset, int DrawCount, SRenderSpriteInfo *pRenderInfo)
@ -1485,6 +1581,7 @@ void CGraphics_Threaded::RenderQuadContainerAsSpriteMultiple(int ContainerIndex,
if(Container.m_QuadBufferContainerIndex == -1) if(Container.m_QuadBufferContainerIndex == -1)
return; return;
WrapClamp();
SQuadContainer::SQuad &Quad = Container.m_Quads[0]; SQuadContainer::SQuad &Quad = Container.m_Quads[0];
CCommandBuffer::SCommand_RenderQuadContainerAsSpriteMultiple Cmd; CCommandBuffer::SCommand_RenderQuadContainerAsSpriteMultiple Cmd;
@ -1539,6 +1636,7 @@ void CGraphics_Threaded::RenderQuadContainerAsSpriteMultiple(int ContainerIndex,
} }
mem_copy(Cmd.m_pRenderInfo, pRenderInfo, sizeof(IGraphics::SRenderSpriteInfo) * DrawCount); mem_copy(Cmd.m_pRenderInfo, pRenderInfo, sizeof(IGraphics::SRenderSpriteInfo) * DrawCount);
WrapNormal();
} }
else else
{ {
@ -2094,9 +2192,9 @@ int CGraphics_Threaded::Init()
// init textures // init textures
m_FirstFreeTexture = 0; m_FirstFreeTexture = 0;
for(int i = 0; i < MAX_TEXTURES - 1; i++) for(int i = 0; i < CCommandBuffer::MAX_TEXTURES - 1; i++)
m_aTextureIndices[i] = i + 1; m_aTextureIndices[i] = i + 1;
m_aTextureIndices[MAX_TEXTURES - 1] = -1; m_aTextureIndices[CCommandBuffer::MAX_TEXTURES - 1] = -1;
m_FirstFreeVertexArrayInfo = -1; m_FirstFreeVertexArrayInfo = -1;
m_FirstFreeBufferObjectIndex = -1; m_FirstFreeBufferObjectIndex = -1;

View file

@ -58,7 +58,7 @@ public:
enum enum
{ {
MAX_TEXTURES = 1024 * 4, MAX_TEXTURES = 1024 * 32,
MAX_VERTICES = 32 * 1024, MAX_VERTICES = 32 * 1024,
}; };
@ -665,9 +665,6 @@ class CGraphics_Threaded : public IEngineGraphics
{ {
NUM_CMDBUFFERS = 2, NUM_CMDBUFFERS = 2,
MAX_VERTICES = 32 * 1024,
MAX_TEXTURES = 1024 * 4,
DRAWING_QUADS = 1, DRAWING_QUADS = 1,
DRAWING_LINES = 2 DRAWING_LINES = 2
}; };
@ -691,8 +688,8 @@ class CGraphics_Threaded : public IEngineGraphics
int m_CurIndex; int m_CurIndex;
CCommandBuffer::SVertex m_aVertices[MAX_VERTICES]; CCommandBuffer::SVertex m_aVertices[CCommandBuffer::MAX_VERTICES];
CCommandBuffer::SVertexTex3DStream m_aVerticesTex3D[MAX_VERTICES]; CCommandBuffer::SVertexTex3DStream m_aVerticesTex3D[CCommandBuffer::MAX_VERTICES];
int m_NumVertices; int m_NumVertices;
CCommandBuffer::SColor m_aColor[4]; CCommandBuffer::SColor m_aColor[4];
@ -707,10 +704,12 @@ class CGraphics_Threaded : public IEngineGraphics
CTextureHandle m_InvalidTexture; CTextureHandle m_InvalidTexture;
int m_aTextureIndices[MAX_TEXTURES]; int m_aTextureIndices[CCommandBuffer::MAX_TEXTURES];
int m_FirstFreeTexture; int m_FirstFreeTexture;
int m_TextureMemoryUsage; int m_TextureMemoryUsage;
std::vector<uint8_t> m_SpriteHelper;
std::vector<SWarning> m_Warnings; std::vector<SWarning> m_Warnings;
struct SVertexArrayInfo struct SVertexArrayInfo
@ -813,14 +812,23 @@ public:
void LinesDraw(const CLineItem *pArray, int Num) override; void LinesDraw(const CLineItem *pArray, int Num) override;
int UnloadTexture(IGraphics::CTextureHandle Index) override; int UnloadTexture(IGraphics::CTextureHandle Index) override;
int UnloadTextureNew(CTextureHandle &TextureHandle) override;
IGraphics::CTextureHandle LoadTextureRaw(int Width, int Height, int Format, const void *pData, int StoreFormat, int Flags, const char *pTexName = NULL) override; IGraphics::CTextureHandle LoadTextureRaw(int Width, int Height, int Format, const void *pData, int StoreFormat, int Flags, const char *pTexName = NULL) override;
int LoadTextureRawSub(IGraphics::CTextureHandle TextureID, int x, int y, int Width, int Height, int Format, const void *pData) override; int LoadTextureRawSub(IGraphics::CTextureHandle TextureID, int x, int y, int Width, int Height, int Format, const void *pData) override;
CTextureHandle LoadSpriteTextureImpl(CImageInfo &FromImageInfo, int x, int y, int w, int h);
CTextureHandle LoadSpriteTexture(CImageInfo &FromImageInfo, struct CDataSprite *pSprite) override;
CTextureHandle LoadSpriteTexture(CImageInfo &FromImageInfo, struct client_data7::CDataSprite *pSprite) override;
bool IsImageSubFullyTransparent(CImageInfo &FromImageInfo, int x, int y, int w, int h) override;
bool IsSpriteTextureFullyTransparent(CImageInfo &FromImageInfo, struct client_data7::CDataSprite *pSprite) override;
// simple uncompressed RGBA loaders // simple uncompressed RGBA loaders
IGraphics::CTextureHandle LoadTexture(const char *pFilename, int StorageType, int StoreFormat, int Flags) override; IGraphics::CTextureHandle LoadTexture(const char *pFilename, int StorageType, int StoreFormat, int Flags) override;
int LoadPNG(CImageInfo *pImg, const char *pFilename, int StorageType) override; int LoadPNG(CImageInfo *pImg, const char *pFilename, int StorageType) override;
void CopyTextureBufferSub(uint8_t *pDestBuffer, uint8_t *pSourceBuffer, int FullWidth, int FullHeight, int ColorChannelCount, int SubOffsetX, int SubOffsetY, int SubCopyWidth, int SubCopyHeight) override; void CopyTextureBufferSub(uint8_t *pDestBuffer, uint8_t *pSourceBuffer, int FullWidth, int FullHeight, int ColorChannelCount, int SubOffsetX, int SubOffsetY, int SubCopyWidth, int SubCopyHeight) override;
void CopyTextureFromTextureBufferSub(uint8_t *pDestBuffer, int DestWidth, int DestHeight, uint8_t *pSourceBuffer, int SrcWidth, int SrcHeight, int ColorChannelCount, int SrcSubOffsetX, int SrcSubOffsetY, int SrcSubCopyWidth, int SrcSubCopyHeight) override;
void ScreenshotDirect(); void ScreenshotDirect();

View file

@ -149,6 +149,10 @@ struct GL_SVertexTex3DStream
typedef void (*WINDOW_RESIZE_FUNC)(void *pUser); typedef void (*WINDOW_RESIZE_FUNC)(void *pUser);
namespace client_data7 {
struct CDataSprite;
}
class IGraphics : public IInterface class IGraphics : public IInterface
{ {
MACRO_INTERFACE("graphics", 0) MACRO_INTERFACE("graphics", 0)
@ -221,13 +225,23 @@ public:
// destination and source buffer require to have the same width and height // destination and source buffer require to have the same width and height
virtual void CopyTextureBufferSub(uint8_t *pDestBuffer, uint8_t *pSourceBuffer, int FullWidth, int FullHeight, int ColorChannelCount, int SubOffsetX, int SubOffsetY, int SubCopyWidth, int SubCopyHeight) = 0; virtual void CopyTextureBufferSub(uint8_t *pDestBuffer, uint8_t *pSourceBuffer, int FullWidth, int FullHeight, int ColorChannelCount, int SubOffsetX, int SubOffsetY, int SubCopyWidth, int SubCopyHeight) = 0;
// destination width must be equal to the subwidth of the source
virtual void CopyTextureFromTextureBufferSub(uint8_t *pDestBuffer, int DestWidth, int DestHeight, uint8_t *pSourceBuffer, int SrcWidth, int SrcHeight, int ColorChannelCount, int SrcSubOffsetX, int SrcSubOffsetY, int SrcSubCopyWidth, int SrcSubCopyHeight) = 0;
virtual int UnloadTexture(CTextureHandle Index) = 0; virtual int UnloadTexture(CTextureHandle Index) = 0;
virtual int UnloadTextureNew(CTextureHandle &TextureHandle) = 0;
virtual CTextureHandle LoadTextureRaw(int Width, int Height, int Format, const void *pData, int StoreFormat, int Flags, const char *pTexName = NULL) = 0; virtual CTextureHandle LoadTextureRaw(int Width, int Height, int Format, const void *pData, int StoreFormat, int Flags, const char *pTexName = NULL) = 0;
virtual int LoadTextureRawSub(CTextureHandle TextureID, int x, int y, int Width, int Height, int Format, const void *pData) = 0; virtual int LoadTextureRawSub(CTextureHandle TextureID, int x, int y, int Width, int Height, int Format, const void *pData) = 0;
virtual CTextureHandle LoadTexture(const char *pFilename, int StorageType, int StoreFormat, int Flags) = 0; virtual CTextureHandle LoadTexture(const char *pFilename, int StorageType, int StoreFormat, int Flags) = 0;
virtual void TextureSet(CTextureHandle Texture) = 0; virtual void TextureSet(CTextureHandle Texture) = 0;
void TextureClear() { TextureSet(CTextureHandle()); } void TextureClear() { TextureSet(CTextureHandle()); }
virtual CTextureHandle LoadSpriteTexture(CImageInfo &FromImageInfo, struct CDataSprite *pSprite) = 0;
virtual CTextureHandle LoadSpriteTexture(CImageInfo &FromImageInfo, struct client_data7::CDataSprite *pSprite) = 0;
virtual bool IsImageSubFullyTransparent(CImageInfo &FromImageInfo, int x, int y, int w, int h) = 0;
virtual bool IsSpriteTextureFullyTransparent(CImageInfo &FromImageInfo, struct client_data7::CDataSprite *pSprite) = 0;
virtual void FlushVertices(bool KeepVertices = false) = 0; virtual void FlushVertices(bool KeepVertices = false) = 0;
virtual void FlushTextVertices(int TextureSize, int TextTextureIndex, int TextOutlineTextureIndex, float *pOutlineTextColor) = 0; virtual void FlushTextVertices(int TextureSize, int TextTextureIndex, int TextOutlineTextureIndex, float *pOutlineTextColor) = 0;
virtual void FlushVerticesTex3D() = 0; virtual void FlushVerticesTex3D() = 0;

View file

@ -23,6 +23,12 @@ public:
SHAPE_RECTANGLE, SHAPE_RECTANGLE,
}; };
// unused
struct CSampleHandle
{
int m_SampleID;
};
struct CVoiceShapeCircle struct CVoiceShapeCircle
{ {
float m_Radius; float m_Radius;

View file

@ -47,7 +47,7 @@ void CDamageInd::Create(vec2 Pos, vec2 Dir)
void CDamageInd::OnRender() void CDamageInd::OnRender()
{ {
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteStars[0]);
static float s_LastLocalTime = LocalTime(); static float s_LastLocalTime = LocalTime();
for(int i = 0; i < m_NumItems;) for(int i = 0; i < m_NumItems;)
{ {
@ -89,8 +89,10 @@ void CDamageInd::OnInit()
Graphics()->SetColor(1.f, 1.f, 1.f, 1.f); Graphics()->SetColor(1.f, 1.f, 1.f, 1.f);
m_DmgIndQuadContainerIndex = Graphics()->CreateQuadContainer(); m_DmgIndQuadContainerIndex = Graphics()->CreateQuadContainer();
RenderTools()->SelectSprite(SPRITE_STAR1); float ScaleX, ScaleY;
RenderTools()->QuadContainerAddSprite(m_DmgIndQuadContainerIndex, 48.f); RenderTools()->GetSpriteScale(SPRITE_STAR1, ScaleX, ScaleY);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_DmgIndQuadContainerIndex, 48.f * ScaleX, 48.f * ScaleY);
} }
void CDamageInd::Reset() void CDamageInd::Reset()

View file

@ -170,9 +170,7 @@ void CEffects::PlayerDeath(vec2 Pos, int ClientID)
BloodColor = m_pClient->m_aClients[ClientID].m_RenderInfo.m_ColorBody; BloodColor = m_pClient->m_aClients[ClientID].m_RenderInfo.m_ColorBody;
else else
{ {
const CSkins::CSkin *s = m_pClient->m_pSkins->Get(m_pClient->m_aClients[ClientID].m_SkinID); BloodColor = m_pClient->m_aClients[ClientID].m_RenderInfo.m_BloodColor;
if(s)
BloodColor = s->m_BloodColor;
} }
} }

View file

@ -111,9 +111,7 @@ void CEmoticon::OnRender()
DrawCircle(Screen.w / 2, Screen.h / 2, 190.0f, 64); DrawCircle(Screen.w / 2, Screen.h / 2, 190.0f, 64);
Graphics()->QuadsEnd(); Graphics()->QuadsEnd();
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id); Graphics()->WrapClamp();
Graphics()->QuadsBegin();
for(int i = 0; i < NUM_EMOTICONS; i++) for(int i = 0; i < NUM_EMOTICONS; i++)
{ {
float Angle = 2 * pi * i / NUM_EMOTICONS; float Angle = 2 * pi * i / NUM_EMOTICONS;
@ -124,14 +122,17 @@ void CEmoticon::OnRender()
float Size = Selected ? 80.0f : 50.0f; float Size = Selected ? 80.0f : 50.0f;
Graphics()->TextureSet(GameClient()->m_EmoticonsSkin.m_SpriteEmoticons[i]);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
Graphics()->QuadsBegin();
float NudgeX = 150.0f * cosf(Angle); float NudgeX = 150.0f * cosf(Angle);
float NudgeY = 150.0f * sinf(Angle); float NudgeY = 150.0f * sinf(Angle);
RenderTools()->SelectSprite(SPRITE_OOP + i);
IGraphics::CQuadItem QuadItem(Screen.w / 2 + NudgeX, Screen.h / 2 + NudgeY, Size, Size); IGraphics::CQuadItem QuadItem(Screen.w / 2 + NudgeX, Screen.h / 2 + NudgeY, Size, Size);
Graphics()->QuadsDraw(&QuadItem, 1); Graphics()->QuadsDraw(&QuadItem, 1);
Graphics()->QuadsEnd();
} }
Graphics()->WrapNormal();
Graphics()->QuadsEnd();
if(GameClient()->m_GameInfo.m_AllowEyeWheel && g_Config.m_ClEyeWheel) if(GameClient()->m_GameInfo.m_AllowEyeWheel && g_Config.m_ClEyeWheel)
{ {
@ -143,8 +144,6 @@ void CEmoticon::OnRender()
CTeeRenderInfo *pTeeInfo = &m_pClient->m_aClients[m_pClient->m_LocalIDs[g_Config.m_ClDummy]].m_RenderInfo; CTeeRenderInfo *pTeeInfo = &m_pClient->m_aClients[m_pClient->m_LocalIDs[g_Config.m_ClDummy]].m_RenderInfo;
Graphics()->TextureSet(pTeeInfo->m_Texture);
for(int i = 0; i < NUM_EMOTES; i++) for(int i = 0; i < NUM_EMOTES; i++)
{ {
float Angle = 2 * pi * i / NUM_EMOTES; float Angle = 2 * pi * i / NUM_EMOTES;

View file

@ -352,16 +352,18 @@ void CGhost::InitRenderInfos(CGhostItem *pGhost)
CTeeRenderInfo *pRenderInfo = &pGhost->m_RenderInfo; CTeeRenderInfo *pRenderInfo = &pGhost->m_RenderInfo;
int SkinId = m_pClient->m_pSkins->Find(aSkinName); int SkinId = m_pClient->m_pSkins->Find(aSkinName);
const CSkin *pSkin = m_pClient->m_pSkins->Get(SkinId);
pRenderInfo->m_OriginalRenderSkin = pSkin->m_OriginalSkin;
pRenderInfo->m_ColorableRenderSkin = pSkin->m_ColorableSkin;
pRenderInfo->m_BloodColor = pSkin->m_BloodColor;
pRenderInfo->m_CustomColoredSkin = pGhost->m_Skin.m_UseCustomColor;
if(pGhost->m_Skin.m_UseCustomColor) if(pGhost->m_Skin.m_UseCustomColor)
{ {
pRenderInfo->m_Texture = m_pClient->m_pSkins->Get(SkinId)->m_ColorTexture;
pRenderInfo->m_ColorBody = color_cast<ColorRGBA>(ColorHSLA(pGhost->m_Skin.m_ColorBody)); pRenderInfo->m_ColorBody = color_cast<ColorRGBA>(ColorHSLA(pGhost->m_Skin.m_ColorBody));
pRenderInfo->m_ColorFeet = color_cast<ColorRGBA>(ColorHSLA(pGhost->m_Skin.m_ColorFeet)); pRenderInfo->m_ColorFeet = color_cast<ColorRGBA>(ColorHSLA(pGhost->m_Skin.m_ColorFeet));
} }
else else
{ {
pRenderInfo->m_Texture = m_pClient->m_pSkins->Get(SkinId)->m_OrgTexture;
pRenderInfo->m_ColorBody = ColorRGBA(1, 1, 1); pRenderInfo->m_ColorBody = ColorRGBA(1, 1, 1);
pRenderInfo->m_ColorFeet = ColorRGBA(1, 1, 1); pRenderInfo->m_ColorFeet = ColorRGBA(1, 1, 1);
} }
@ -624,3 +626,31 @@ int CGhost::GetLastRaceTick()
{ {
return m_LastRaceTick; return m_LastRaceTick;
} }
void CGhost::RefindSkin()
{
char aSkinName[64];
for(int i = 0; i < (int)(sizeof(m_aActiveGhosts) / sizeof(m_aActiveGhosts[0])); ++i)
{
IntsToStr(&m_aActiveGhosts[i].m_Skin.m_Skin0, 6, aSkinName);
if(aSkinName[0] != '\0')
{
CTeeRenderInfo *pRenderInfo = &m_aActiveGhosts[i].m_RenderInfo;
int SkinId = m_pClient->m_pSkins->Find(aSkinName);
const CSkin *pSkin = m_pClient->m_pSkins->Get(SkinId);
pRenderInfo->m_OriginalRenderSkin = pSkin->m_OriginalSkin;
pRenderInfo->m_ColorableRenderSkin = pSkin->m_ColorableSkin;
}
}
IntsToStr(&m_CurGhost.m_Skin.m_Skin0, 6, aSkinName);
if(aSkinName[0] != '\0')
{
CTeeRenderInfo *pRenderInfo = &m_CurGhost.m_RenderInfo;
int SkinId = m_pClient->m_pSkins->Find(aSkinName);
const CSkin *pSkin = m_pClient->m_pSkins->Get(SkinId);
pRenderInfo->m_OriginalRenderSkin = pSkin->m_OriginalSkin;
pRenderInfo->m_ColorableRenderSkin = pSkin->m_ColorableSkin;
}
}

View file

@ -168,6 +168,8 @@ public:
class IGhostRecorder *GhostRecorder() const { return m_pGhostRecorder; } class IGhostRecorder *GhostRecorder() const { return m_pGhostRecorder; }
int GetLastRaceTick(); int GetLastRaceTick();
void RefindSkin();
}; };
#endif #endif

View file

@ -87,14 +87,16 @@ void CHud::OnInit()
// all cursors // all cursors
for(int i = 0; i < NUM_WEAPONS; ++i) for(int i = 0; i < NUM_WEAPONS; ++i)
{ {
RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[i].m_pSpriteCursor); float ScaleX, ScaleY;
RenderTools()->QuadContainerAddSprite(m_HudQuadContainerIndex, 64.f); RenderTools()->GetSpriteScale(g_pData->m_Weapons.m_aId[i].m_pSpriteCursor, ScaleX, ScaleY);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_HudQuadContainerIndex, 64.f * ScaleX, 64.f * ScaleY);
} }
// the flags // the flags
RenderTools()->SelectSprite(SPRITE_FLAG_RED); Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_HudQuadContainerIndex, 0.f, 0.f, 8.f, 16.f); RenderTools()->QuadContainerAddSprite(m_HudQuadContainerIndex, 0.f, 0.f, 8.f, 16.f);
RenderTools()->SelectSprite(SPRITE_FLAG_BLUE); Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_HudQuadContainerIndex, 0.f, 0.f, 8.f, 16.f); RenderTools()->QuadContainerAddSprite(m_HudQuadContainerIndex, 0.f, 0.f, 8.f, 16.f);
} }
@ -257,7 +259,7 @@ void CHud::RenderScoreHud()
if(FlagCarrier[t] == FLAG_ATSTAND || (FlagCarrier[t] == FLAG_TAKEN && ((Client()->GameTick(g_Config.m_ClDummy) / BlinkTimer) & 1))) if(FlagCarrier[t] == FLAG_ATSTAND || (FlagCarrier[t] == FLAG_TAKEN && ((Client()->GameTick(g_Config.m_ClDummy) / BlinkTimer) & 1)))
{ {
// draw flag // draw flag
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); Graphics()->TextureSet(t == 0 ? GameClient()->m_GameSkin.m_SpriteFlagRed : GameClient()->m_GameSkin.m_SpriteFlagBlue);
int QuadOffset = NUM_WEAPONS * 10 + 40 + NUM_WEAPONS + t; int QuadOffset = NUM_WEAPONS * 10 + 40 + NUM_WEAPONS + t;
Graphics()->SetColor(1.f, 1.f, 1.f, 1.f); Graphics()->SetColor(1.f, 1.f, 1.f, 1.f);
Graphics()->RenderQuadContainerAsSprite(m_HudQuadContainerIndex, QuadOffset, Whole - ScoreWidthMax - ImageSize, StartY + 1.0f + t * 20); Graphics()->RenderQuadContainerAsSprite(m_HudQuadContainerIndex, QuadOffset, Whole - ScoreWidthMax - ImageSize, StartY + 1.0f + t * 20);
@ -659,10 +661,13 @@ void CHud::RenderCursor()
return; return;
MapscreenToGroup(m_pClient->m_pCamera->m_Center.x, m_pClient->m_pCamera->m_Center.y, Layers()->GameGroup()); MapscreenToGroup(m_pClient->m_pCamera->m_Center.x, m_pClient->m_pCamera->m_Center.y, Layers()->GameGroup());
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
int CurWeapon = m_pClient->m_Snap.m_pLocalCharacter->m_Weapon % NUM_WEAPONS;
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteWeaponCursors[CurWeapon]);
// render cursor // render cursor
int QuadOffset = NUM_WEAPONS * 10 + 40 + (m_pClient->m_Snap.m_pLocalCharacter->m_Weapon % NUM_WEAPONS); int QuadOffset = NUM_WEAPONS * 10 + 40 + (CurWeapon);
Graphics()->SetColor(1.f, 1.f, 1.f, 1.f); Graphics()->SetColor(1.f, 1.f, 1.f, 1.f);
Graphics()->RenderQuadContainerAsSprite(m_HudQuadContainerIndex, QuadOffset, m_pClient->m_pControls->m_TargetPos[g_Config.m_ClDummy].x, m_pClient->m_pControls->m_TargetPos[g_Config.m_ClDummy].y); Graphics()->RenderQuadContainerAsSprite(m_HudQuadContainerIndex, QuadOffset, m_pClient->m_pControls->m_TargetPos[g_Config.m_ClDummy].x, m_pClient->m_pControls->m_TargetPos[g_Config.m_ClDummy].y);
} }
@ -677,30 +682,30 @@ void CHud::PrepareHealthAmoQuads()
for(int i = 0; i < NUM_WEAPONS; ++i) for(int i = 0; i < NUM_WEAPONS; ++i)
{ {
RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[i % NUM_WEAPONS].m_pSpriteProj); Graphics()->QuadsSetSubset(0, 0, 1, 1);
for(int n = 0; n < 10; n++) for(int n = 0; n < 10; n++)
Array[n] = IGraphics::CQuadItem(x + n * 12, y + 24, 10, 10); Array[n] = IGraphics::CQuadItem(x + n * 12, y + 24, 10, 10);
Graphics()->QuadContainerAddQuads(m_HudQuadContainerIndex, Array, 10); Graphics()->QuadContainerAddQuads(m_HudQuadContainerIndex, Array, 10);
} }
// health // health
RenderTools()->SelectSprite(SPRITE_HEALTH_FULL); Graphics()->QuadsSetSubset(0, 0, 1, 1);
for(int i = 0; i < 10; ++i) for(int i = 0; i < 10; ++i)
Array[i] = IGraphics::CQuadItem(x + i * 12, y, 10, 10); Array[i] = IGraphics::CQuadItem(x + i * 12, y, 10, 10);
Graphics()->QuadContainerAddQuads(m_HudQuadContainerIndex, Array, 10); Graphics()->QuadContainerAddQuads(m_HudQuadContainerIndex, Array, 10);
RenderTools()->SelectSprite(SPRITE_HEALTH_EMPTY); Graphics()->QuadsSetSubset(0, 0, 1, 1);
for(int i = 0; i < 10; ++i) for(int i = 0; i < 10; ++i)
Array[i] = IGraphics::CQuadItem(x + i * 12, y, 10, 10); Array[i] = IGraphics::CQuadItem(x + i * 12, y, 10, 10);
Graphics()->QuadContainerAddQuads(m_HudQuadContainerIndex, Array, 10); Graphics()->QuadContainerAddQuads(m_HudQuadContainerIndex, Array, 10);
// armor meter // armor meter
RenderTools()->SelectSprite(SPRITE_ARMOR_FULL); Graphics()->QuadsSetSubset(0, 0, 1, 1);
for(int i = 0; i < 10; ++i) for(int i = 0; i < 10; ++i)
Array[i] = IGraphics::CQuadItem(x + i * 12, y + 12, 10, 10); Array[i] = IGraphics::CQuadItem(x + i * 12, y + 12, 10, 10);
Graphics()->QuadContainerAddQuads(m_HudQuadContainerIndex, Array, 10); Graphics()->QuadContainerAddQuads(m_HudQuadContainerIndex, Array, 10);
RenderTools()->SelectSprite(SPRITE_ARMOR_EMPTY); Graphics()->QuadsSetSubset(0, 0, 1, 1);
for(int i = 0; i < 10; ++i) for(int i = 0; i < 10; ++i)
Array[i] = IGraphics::CQuadItem(x + i * 12, y + 12, 10, 10); Array[i] = IGraphics::CQuadItem(x + i * 12, y + 12, 10, 10);
Graphics()->QuadContainerAddQuads(m_HudQuadContainerIndex, Array, 10); Graphics()->QuadContainerAddQuads(m_HudQuadContainerIndex, Array, 10);
@ -713,21 +718,34 @@ void CHud::RenderHealthAndAmmo(const CNetObj_Character *pCharacter)
// render ammo count // render ammo count
// render gui stuff // render gui stuff
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); int CurWeapon = pCharacter->m_Weapon % NUM_WEAPONS;
int QuadOffset = CurWeapon * 10;
int QuadOffset = pCharacter->m_Weapon % NUM_WEAPONS * 10; if(GameClient()->m_GameSkin.m_SpriteWeaponProjectiles[CurWeapon] != -1)
Graphics()->RenderQuadContainer(m_HudQuadContainerIndex, QuadOffset, minimum(pCharacter->m_AmmoCount, 10)); {
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteWeaponProjectiles[CurWeapon]);
Graphics()->RenderQuadContainer(m_HudQuadContainerIndex, QuadOffset, minimum(pCharacter->m_AmmoCount, 10));
}
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteHealthFull);
QuadOffset = NUM_WEAPONS * 10; QuadOffset = NUM_WEAPONS * 10;
Graphics()->RenderQuadContainer(m_HudQuadContainerIndex, QuadOffset, minimum(pCharacter->m_Health, 10)); Graphics()->RenderQuadContainer(m_HudQuadContainerIndex, QuadOffset, minimum(pCharacter->m_Health, 10));
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteHealthEmpty);
QuadOffset += 10 + minimum(pCharacter->m_Health, 10); QuadOffset += 10 + minimum(pCharacter->m_Health, 10);
if(minimum(pCharacter->m_Health, 10) < 10) if(minimum(pCharacter->m_Health, 10) < 10)
Graphics()->RenderQuadContainer(m_HudQuadContainerIndex, QuadOffset, 10 - minimum(pCharacter->m_Health, 10)); Graphics()->RenderQuadContainer(m_HudQuadContainerIndex, QuadOffset, 10 - minimum(pCharacter->m_Health, 10));
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteArmorFull);
QuadOffset = NUM_WEAPONS * 10 + 20; QuadOffset = NUM_WEAPONS * 10 + 20;
Graphics()->RenderQuadContainer(m_HudQuadContainerIndex, QuadOffset, minimum(pCharacter->m_Armor, 10)); Graphics()->RenderQuadContainer(m_HudQuadContainerIndex, QuadOffset, minimum(pCharacter->m_Armor, 10));
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteArmorEmpty);
QuadOffset += 10 + minimum(pCharacter->m_Armor, 10); QuadOffset += 10 + minimum(pCharacter->m_Armor, 10);
if(minimum(pCharacter->m_Armor, 10) < 10) if(minimum(pCharacter->m_Armor, 10) < 10)
Graphics()->RenderQuadContainer(m_HudQuadContainerIndex, QuadOffset, 10 - minimum(pCharacter->m_Armor, 10)); Graphics()->RenderQuadContainer(m_HudQuadContainerIndex, QuadOffset, 10 - minimum(pCharacter->m_Armor, 10));

View file

@ -4,6 +4,7 @@
#include <engine/graphics.h> #include <engine/graphics.h>
#include <engine/shared/config.h> #include <engine/shared/config.h>
#include <game/generated/client_data.h> #include <game/generated/client_data.h>
#include <game/generated/client_data7.h>
#include <game/generated/protocol.h> #include <game/generated/protocol.h>
#include <game/client/gameclient.h> #include <game/client/gameclient.h>
@ -76,52 +77,74 @@ void CItems::RenderProjectile(const CNetObj_Projectile *pCurrent, int ItemID)
Alpha = g_Config.m_ClShowOthersAlpha / 100.0f; Alpha = g_Config.m_ClShowOthersAlpha / 100.0f;
} }
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); int CurWeapon = clamp(pCurrent->m_Type, 0, NUM_WEAPONS - 1);
Graphics()->SetColor(1.f, 1.f, 1.f, Alpha);
int QuadOffset = 2 + 4 + NUM_WEAPONS + clamp(pCurrent->m_Type, 0, NUM_WEAPONS - 1); if(GameClient()->m_GameSkin.m_SpriteWeaponProjectiles[CurWeapon] != -1)
vec2 Vel = Pos - PrevPos;
//vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), Client()->IntraGameTick(g_Config.m_ClDummy));
// add particle for this projectile
if(pCurrent->m_Type == WEAPON_GRENADE)
{ {
m_pClient->m_pEffects->SmokeTrail(Pos, Vel * -1, Alpha); Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteWeaponProjectiles[CurWeapon]);
static float s_Time = 0.0f; Graphics()->SetColor(1.f, 1.f, 1.f, Alpha);
static float s_LastLocalTime = LocalTime();
if(Client()->State() == IClient::STATE_DEMOPLAYBACK) int QuadOffset = 2 + 8 + NUM_WEAPONS + CurWeapon;
vec2 Vel = Pos - PrevPos;
//vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), Client()->IntraGameTick(g_Config.m_ClDummy));
// add particle for this projectile
if(pCurrent->m_Type == WEAPON_GRENADE)
{ {
const IDemoPlayer::CInfo *pInfo = DemoPlayer()->BaseInfo(); m_pClient->m_pEffects->SmokeTrail(Pos, Vel * -1, Alpha);
if(!pInfo->m_Paused) static float s_Time = 0.0f;
s_Time += (LocalTime() - s_LastLocalTime) * pInfo->m_Speed; static float s_LastLocalTime = LocalTime();
if(Client()->State() == IClient::STATE_DEMOPLAYBACK)
{
const IDemoPlayer::CInfo *pInfo = DemoPlayer()->BaseInfo();
if(!pInfo->m_Paused)
s_Time += (LocalTime() - s_LastLocalTime) * pInfo->m_Speed;
}
else
{
if(m_pClient->m_Snap.m_pGameInfoObj && !(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags & GAMESTATEFLAG_PAUSED))
s_Time += LocalTime() - s_LastLocalTime;
}
Graphics()->QuadsSetRotation(s_Time * pi * 2 * 2 + ItemID);
s_LastLocalTime = LocalTime();
} }
else else
{ {
if(m_pClient->m_Snap.m_pGameInfoObj && !(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags & GAMESTATEFLAG_PAUSED)) m_pClient->m_pEffects->BulletTrail(Pos, Alpha);
s_Time += LocalTime() - s_LastLocalTime;
if(length(Vel) > 0.00001f)
Graphics()->QuadsSetRotation(GetAngle(Vel));
else
Graphics()->QuadsSetRotation(0);
} }
Graphics()->QuadsSetRotation(s_Time * pi * 2 * 2 + ItemID); Graphics()->RenderQuadContainerAsSprite(m_ItemsQuadContainerIndex, QuadOffset, Pos.x, Pos.y);
s_LastLocalTime = LocalTime();
} }
else
{
m_pClient->m_pEffects->BulletTrail(Pos, Alpha);
if(length(Vel) > 0.00001f)
Graphics()->QuadsSetRotation(GetAngle(Vel));
else
Graphics()->QuadsSetRotation(0);
}
Graphics()->RenderQuadContainerAsSprite(m_ItemsQuadContainerIndex, QuadOffset, Pos.x, Pos.y);
} }
void CItems::RenderPickup(const CNetObj_Pickup *pPrev, const CNetObj_Pickup *pCurrent, bool IsPredicted) void CItems::RenderPickup(const CNetObj_Pickup *pPrev, const CNetObj_Pickup *pCurrent, bool IsPredicted)
{ {
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); const int c[] = {
SPRITE_PICKUP_HEALTH,
SPRITE_PICKUP_ARMOR,
SPRITE_PICKUP_WEAPON,
SPRITE_PICKUP_NINJA};
int CurWeapon = clamp(pCurrent->m_Subtype, 0, NUM_WEAPONS - 1);
if(c[pCurrent->m_Type] == SPRITE_PICKUP_HEALTH)
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpritePickupHealth);
else if(c[pCurrent->m_Type] == SPRITE_PICKUP_ARMOR)
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpritePickupArmor);
else if(c[pCurrent->m_Type] == SPRITE_PICKUP_WEAPON)
{
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpritePickupWeapons[CurWeapon]);
}
else if(c[pCurrent->m_Type] == SPRITE_PICKUP_NINJA)
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpritePickupNinja);
Graphics()->QuadsSetRotation(0); Graphics()->QuadsSetRotation(0);
Graphics()->SetColor(1.f, 1.f, 1.f, 1.f); Graphics()->SetColor(1.f, 1.f, 1.f, 1.f);
@ -133,19 +156,15 @@ void CItems::RenderPickup(const CNetObj_Pickup *pPrev, const CNetObj_Pickup *pCu
if(pCurrent->m_Type == POWERUP_WEAPON) if(pCurrent->m_Type == POWERUP_WEAPON)
{ {
Angle = 0; //-pi/6;//-0.25f * pi * 2.0f; Angle = 0; //-pi/6;//-0.25f * pi * 2.0f;
QuadOffset += 4 + clamp(pCurrent->m_Subtype, 0, NUM_WEAPONS - 1); QuadOffset += 2 + CurWeapon;
} }
else else
{ {
const int c[] = {
SPRITE_PICKUP_HEALTH,
SPRITE_PICKUP_ARMOR,
SPRITE_PICKUP_WEAPON,
SPRITE_PICKUP_NINJA};
QuadOffset += pCurrent->m_Type; QuadOffset += pCurrent->m_Type;
if(c[pCurrent->m_Type] == SPRITE_PICKUP_NINJA) if(c[pCurrent->m_Type] == SPRITE_PICKUP_NINJA)
{ {
QuadOffset = 2 + 8 - 1; // ninja is the last weapon
m_pClient->m_pEffects->PowerupShine(Pos, vec2(96, 18)); m_pClient->m_pEffects->PowerupShine(Pos, vec2(96, 18));
Pos.x -= 10.0f; Pos.x -= 10.0f;
} }
@ -179,7 +198,10 @@ void CItems::RenderFlag(const CNetObj_Flag *pPrev, const CNetObj_Flag *pCurrent,
float Angle = 0.0f; float Angle = 0.0f;
float Size = 42.0f; float Size = 42.0f;
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); if(pCurrent->m_Team == TEAM_RED)
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagRed);
else
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagBlue);
Graphics()->QuadsSetRotation(0); Graphics()->QuadsSetRotation(0);
Graphics()->SetColor(1.f, 1.f, 1.f, 1.f); Graphics()->SetColor(1.f, 1.f, 1.f, 1.f);
int QuadOffset = 0; int QuadOffset = 0;
@ -260,9 +282,10 @@ void CItems::RenderLaser(const struct CNetObj_Laser *pCurrent, bool IsPredicted)
// render head // render head
{ {
int QuadOffset = 2 + 4 + NUM_WEAPONS * 2 + (Client()->GameTick(g_Config.m_ClDummy) % 3); int CurParticle = (Client()->GameTick(g_Config.m_ClDummy) % 3);
int QuadOffset = 2 + 8 + NUM_WEAPONS * 2 + CurParticle;
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_PARTICLES].m_Id); Graphics()->TextureSet(GameClient()->m_ParticlesSkin.m_SpriteParticleSplat[CurParticle]);
Graphics()->QuadsSetRotation(Client()->GameTick(g_Config.m_ClDummy)); Graphics()->QuadsSetRotation(Client()->GameTick(g_Config.m_ClDummy));
Graphics()->SetColor(OuterColor.r, OuterColor.g, OuterColor.b, 1.0f); Graphics()->SetColor(OuterColor.r, OuterColor.g, OuterColor.b, 1.0f);
Graphics()->RenderQuadContainerAsSprite(m_ItemsQuadContainerIndex, QuadOffset, Pos.x, Pos.y); Graphics()->RenderQuadContainerAsSprite(m_ItemsQuadContainerIndex, QuadOffset, Pos.x, Pos.y);
@ -394,38 +417,56 @@ void CItems::OnInit()
m_ItemsQuadContainerIndex = Graphics()->CreateQuadContainer(); m_ItemsQuadContainerIndex = Graphics()->CreateQuadContainer();
RenderTools()->SelectSprite(SPRITE_FLAG_RED); Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, -21.f, -42.f, 42.f, 84.f); RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, -21.f, -42.f, 42.f, 84.f);
RenderTools()->SelectSprite(SPRITE_FLAG_BLUE); Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, -21.f, -42.f, 42.f, 84.f); RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, -21.f, -42.f, 42.f, 84.f);
RenderTools()->SelectSprite(SPRITE_PICKUP_HEALTH); float ScaleX, ScaleY;
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 64.f); RenderTools()->GetSpriteScale(SPRITE_PICKUP_HEALTH, ScaleX, ScaleY);
RenderTools()->SelectSprite(SPRITE_PICKUP_ARMOR); Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 64.f); RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 64.f * ScaleX, 64.f * ScaleY);
RenderTools()->SelectSprite(SPRITE_PICKUP_WEAPON); RenderTools()->GetSpriteScale(SPRITE_PICKUP_ARMOR, ScaleX, ScaleY);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 64.f); Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->SelectSprite(SPRITE_PICKUP_NINJA); RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 64.f * ScaleX, 64.f * ScaleY);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 128.f); RenderTools()->GetSpriteScale(&client_data7::g_pData->m_aSprites[client_data7::SPRITE_PICKUP_HAMMER], ScaleX, ScaleY);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, client_data7::g_pData->m_Weapons.m_aId[WEAPON_HAMMER].m_VisualSize * ScaleX, client_data7::g_pData->m_Weapons.m_aId[WEAPON_HAMMER].m_VisualSize * ScaleY);
RenderTools()->GetSpriteScale(&client_data7::g_pData->m_aSprites[client_data7::SPRITE_PICKUP_GUN], ScaleX, ScaleY);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, client_data7::g_pData->m_Weapons.m_aId[WEAPON_GUN].m_VisualSize * ScaleX, client_data7::g_pData->m_Weapons.m_aId[WEAPON_GUN].m_VisualSize * ScaleY);
RenderTools()->GetSpriteScale(&client_data7::g_pData->m_aSprites[client_data7::SPRITE_PICKUP_SHOTGUN], ScaleX, ScaleY);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, client_data7::g_pData->m_Weapons.m_aId[WEAPON_SHOTGUN].m_VisualSize * ScaleX, client_data7::g_pData->m_Weapons.m_aId[WEAPON_SHOTGUN].m_VisualSize * ScaleY);
RenderTools()->GetSpriteScale(&client_data7::g_pData->m_aSprites[client_data7::SPRITE_PICKUP_GRENADE], ScaleX, ScaleY);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, client_data7::g_pData->m_Weapons.m_aId[WEAPON_GRENADE].m_VisualSize * ScaleX, client_data7::g_pData->m_Weapons.m_aId[WEAPON_GRENADE].m_VisualSize * ScaleY);
RenderTools()->GetSpriteScale(&client_data7::g_pData->m_aSprites[client_data7::SPRITE_PICKUP_LASER], ScaleX, ScaleY);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, client_data7::g_pData->m_Weapons.m_aId[WEAPON_LASER].m_VisualSize * ScaleX, client_data7::g_pData->m_Weapons.m_aId[WEAPON_LASER].m_VisualSize * ScaleY);
RenderTools()->GetSpriteScale(SPRITE_PICKUP_NINJA, ScaleX, ScaleY);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 128.f * ScaleX, 128.f * ScaleY);
for(int i = 0; i < NUM_WEAPONS; ++i) for(int i = 0; i < NUM_WEAPONS; ++i)
{ {
RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[i].m_pSpriteBody); RenderTools()->GetSpriteScale(g_pData->m_Weapons.m_aId[i].m_pSpriteBody, ScaleX, ScaleY);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, g_pData->m_Weapons.m_aId[i].m_VisualSize); Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, g_pData->m_Weapons.m_aId[i].m_VisualSize * ScaleX, g_pData->m_Weapons.m_aId[i].m_VisualSize * ScaleY);
} }
for(int i = 0; i < NUM_WEAPONS; ++i) for(int i = 0; i < NUM_WEAPONS; ++i)
{ {
RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[i].m_pSpriteProj); Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 32.f, false); RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 32.f);
} }
RenderTools()->SelectSprite(SPRITE_PART_SPLAT01); Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 24.f, false); RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 24.f);
RenderTools()->SelectSprite(SPRITE_PART_SPLAT02); Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 24.f, false); RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 24.f);
RenderTools()->SelectSprite(SPRITE_PART_SPLAT03); Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 24.f, false); RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 24.f);
} }
void CItems::AddExtraProjectile(CNetObj_Projectile *pProj) void CItems::AddExtraProjectile(CNetObj_Projectile *pProj)

View file

@ -44,20 +44,22 @@ void CKillMessages::OnInit()
Graphics()->SetColor(1.f, 1.f, 1.f, 1.f); Graphics()->SetColor(1.f, 1.f, 1.f, 1.f);
m_SpriteQuadContainerIndex = Graphics()->CreateQuadContainer(); m_SpriteQuadContainerIndex = Graphics()->CreateQuadContainer();
RenderTools()->SelectSprite(SPRITE_FLAG_RED); Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_SpriteQuadContainerIndex, 0.f, 0.f, 28.f, 56.f); RenderTools()->QuadContainerAddSprite(m_SpriteQuadContainerIndex, 0.f, 0.f, 28.f, 56.f);
RenderTools()->SelectSprite(SPRITE_FLAG_BLUE); Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_SpriteQuadContainerIndex, 0.f, 0.f, 28.f, 56.f); RenderTools()->QuadContainerAddSprite(m_SpriteQuadContainerIndex, 0.f, 0.f, 28.f, 56.f);
RenderTools()->SelectSprite(SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X); Graphics()->QuadsSetSubset(1, 0, 0, 1);
RenderTools()->QuadContainerAddSprite(m_SpriteQuadContainerIndex, 0.f, 0.f, 28.f, 56.f); RenderTools()->QuadContainerAddSprite(m_SpriteQuadContainerIndex, 0.f, 0.f, 28.f, 56.f);
RenderTools()->SelectSprite(SPRITE_FLAG_BLUE, SPRITE_FLAG_FLIP_X); Graphics()->QuadsSetSubset(1, 0, 0, 1);
RenderTools()->QuadContainerAddSprite(m_SpriteQuadContainerIndex, 0.f, 0.f, 28.f, 56.f); RenderTools()->QuadContainerAddSprite(m_SpriteQuadContainerIndex, 0.f, 0.f, 28.f, 56.f);
for(int i = 0; i < NUM_WEAPONS; ++i) for(int i = 0; i < NUM_WEAPONS; ++i)
{ {
RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[i].m_pSpriteBody); float ScaleX, ScaleY;
RenderTools()->QuadContainerAddSprite(m_SpriteQuadContainerIndex, 96.f); Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->GetSpriteScale(g_pData->m_Weapons.m_aId[i].m_pSpriteBody, ScaleX, ScaleY);
RenderTools()->QuadContainerAddSprite(m_SpriteQuadContainerIndex, 96.f * ScaleX, 96.f * ScaleY);
} }
} }
@ -178,11 +180,15 @@ void CKillMessages::OnRender()
{ {
if(m_aKillmsgs[r].m_ModeSpecial & 1) if(m_aKillmsgs[r].m_ModeSpecial & 1)
{ {
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
int QuadOffset = 0; int QuadOffset = 0;
if(m_aKillmsgs[r].m_VictimID == m_aKillmsgs[r].m_FlagCarrierBlue) if(m_aKillmsgs[r].m_VictimID == m_aKillmsgs[r].m_FlagCarrierBlue)
++QuadOffset; ++QuadOffset;
if(QuadOffset == 0)
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagRed);
else
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagBlue);
Graphics()->RenderQuadContainerAsSprite(m_SpriteQuadContainerIndex, QuadOffset, x, y - 16); Graphics()->RenderQuadContainerAsSprite(m_SpriteQuadContainerIndex, QuadOffset, x, y - 16);
} }
} }
@ -194,7 +200,7 @@ void CKillMessages::OnRender()
x -= 44.0f; x -= 44.0f;
if(m_aKillmsgs[r].m_Weapon >= 0) if(m_aKillmsgs[r].m_Weapon >= 0)
{ {
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteWeapons[m_aKillmsgs[r].m_Weapon]);
Graphics()->RenderQuadContainerAsSprite(m_SpriteQuadContainerIndex, 4 + m_aKillmsgs[r].m_Weapon, x, y + 28); Graphics()->RenderQuadContainerAsSprite(m_SpriteQuadContainerIndex, 4 + m_aKillmsgs[r].m_Weapon, x, y + 28);
} }
x -= 52.0f; x -= 52.0f;
@ -205,12 +211,15 @@ void CKillMessages::OnRender()
{ {
if(m_aKillmsgs[r].m_ModeSpecial & 2) if(m_aKillmsgs[r].m_ModeSpecial & 2)
{ {
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
int QuadOffset = 2; int QuadOffset = 2;
if(m_aKillmsgs[r].m_KillerID == m_aKillmsgs[r].m_FlagCarrierBlue) if(m_aKillmsgs[r].m_KillerID == m_aKillmsgs[r].m_FlagCarrierBlue)
++QuadOffset; ++QuadOffset;
if(QuadOffset == 2)
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagRed);
else
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagBlue);
Graphics()->RenderQuadContainerAsSprite(m_SpriteQuadContainerIndex, QuadOffset, x - 56, y - 16); Graphics()->RenderQuadContainerAsSprite(m_SpriteQuadContainerIndex, QuadOffset, x - 56, y - 16);
} }
} }

View file

@ -1127,13 +1127,14 @@ void CMenus::RenderGhost(CUIRect MainView)
{ {
if(pItem->Active()) if(pItem->Active())
{ {
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id); Graphics()->WrapClamp();
Graphics()->TextureSet(GameClient()->m_EmoticonsSkin.m_SpriteEmoticons[(SPRITE_OOP + 7) - SPRITE_OOP]);
Graphics()->QuadsBegin(); Graphics()->QuadsBegin();
RenderTools()->SelectSprite(SPRITE_OOP + 7);
IGraphics::CQuadItem QuadItem(Button.x + Button.w / 2, Button.y + Button.h / 2, 20.0f, 20.0f); IGraphics::CQuadItem QuadItem(Button.x + Button.w / 2, Button.y + Button.h / 2, 20.0f, 20.0f);
Graphics()->QuadsDraw(&QuadItem, 1); Graphics()->QuadsDraw(&QuadItem, 1);
Graphics()->QuadsEnd(); Graphics()->QuadsEnd();
Graphics()->WrapNormal();
} }
} }
else if(Id == COL_NAME) else if(Id == COL_NAME)

View file

@ -31,6 +31,8 @@
#include "menus.h" #include "menus.h"
#include "skins.h" #include "skins.h"
#include <utility>
CMenusKeyBinder CMenus::m_Binder; CMenusKeyBinder CMenus::m_Binder;
CMenusKeyBinder::CMenusKeyBinder() CMenusKeyBinder::CMenusKeyBinder()
@ -443,17 +445,18 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
} }
// skin info // skin info
const CSkins::CSkin *pOwnSkin = m_pClient->m_pSkins->Get(m_pClient->m_pSkins->Find(Skin));
CTeeRenderInfo OwnSkinInfo; CTeeRenderInfo OwnSkinInfo;
const CSkin *pSkin = m_pClient->m_pSkins->Get(m_pClient->m_pSkins->Find(Skin));
OwnSkinInfo.m_OriginalRenderSkin = pSkin->m_OriginalSkin;
OwnSkinInfo.m_ColorableRenderSkin = pSkin->m_ColorableSkin;
OwnSkinInfo.m_CustomColoredSkin = *UseCustomColor;
if(*UseCustomColor) if(*UseCustomColor)
{ {
OwnSkinInfo.m_Texture = pOwnSkin->m_ColorTexture;
OwnSkinInfo.m_ColorBody = color_cast<ColorRGBA>(ColorHSLA(*ColorBody).UnclampLighting()); OwnSkinInfo.m_ColorBody = color_cast<ColorRGBA>(ColorHSLA(*ColorBody).UnclampLighting());
OwnSkinInfo.m_ColorFeet = color_cast<ColorRGBA>(ColorHSLA(*ColorFeet).UnclampLighting()); OwnSkinInfo.m_ColorFeet = color_cast<ColorRGBA>(ColorHSLA(*ColorFeet).UnclampLighting());
} }
else else
{ {
OwnSkinInfo.m_Texture = pOwnSkin->m_OrgTexture;
OwnSkinInfo.m_ColorBody = ColorRGBA(1.0f, 1.0f, 1.0f); OwnSkinInfo.m_ColorBody = ColorRGBA(1.0f, 1.0f, 1.0f);
OwnSkinInfo.m_ColorFeet = ColorRGBA(1.0f, 1.0f, 1.0f); OwnSkinInfo.m_ColorFeet = ColorRGBA(1.0f, 1.0f, 1.0f);
} }
@ -579,7 +582,7 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
// skin selector // skin selector
MainView.HSplitTop(20.0f, 0, &MainView); MainView.HSplitTop(20.0f, 0, &MainView);
MainView.HSplitTop(230.0f, &SkinList, &MainView); MainView.HSplitTop(230.0f, &SkinList, &MainView);
static sorted_array<const CSkins::CSkin *> s_paSkinList; static sorted_array<const CSkin *> s_paSkinList;
static int s_SkinCount = 0; static int s_SkinCount = 0;
static float s_ScrollValue = 0.0f; static float s_ScrollValue = 0.0f;
if(s_InitSkinlist || m_pClient->m_pSkins->Num() != s_SkinCount) if(s_InitSkinlist || m_pClient->m_pSkins->Num() != s_SkinCount)
@ -587,7 +590,7 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
s_paSkinList.clear(); s_paSkinList.clear();
for(int i = 0; i < m_pClient->m_pSkins->Num(); ++i) for(int i = 0; i < m_pClient->m_pSkins->Num(); ++i)
{ {
const CSkins::CSkin *s = m_pClient->m_pSkins->Get(i); const CSkin *s = m_pClient->m_pSkins->Get(i);
// filter quick search // filter quick search
if(g_Config.m_ClSkinFilterString[0] != '\0' && !str_find_nocase(s->m_aName, g_Config.m_ClSkinFilterString)) if(g_Config.m_ClSkinFilterString[0] != '\0' && !str_find_nocase(s->m_aName, g_Config.m_ClSkinFilterString))
@ -611,7 +614,7 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
UiDoListboxStart(&s_InitSkinlist, &SkinList, 50.0f, Localize("Skins"), "", s_paSkinList.size(), 4, OldSelected, s_ScrollValue); UiDoListboxStart(&s_InitSkinlist, &SkinList, 50.0f, Localize("Skins"), "", s_paSkinList.size(), 4, OldSelected, s_ScrollValue);
for(int i = 0; i < s_paSkinList.size(); ++i) for(int i = 0; i < s_paSkinList.size(); ++i)
{ {
const CSkins::CSkin *s = s_paSkinList[i]; const CSkin *s = s_paSkinList[i];
if(s == 0) if(s == 0)
continue; continue;
@ -623,7 +626,10 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
if(Item.m_Visible) if(Item.m_Visible)
{ {
CTeeRenderInfo Info = OwnSkinInfo; CTeeRenderInfo Info = OwnSkinInfo;
Info.m_Texture = *UseCustomColor ? s->m_ColorTexture : s->m_OrgTexture; Info.m_CustomColoredSkin = *UseCustomColor;
Info.m_OriginalRenderSkin = s->m_OriginalSkin;
Info.m_ColorableRenderSkin = s->m_ColorableSkin;
Item.m_Rect.HSplitTop(5.0f, 0, &Item.m_Rect); // some margin from the top Item.m_Rect.HSplitTop(5.0f, 0, &Item.m_Rect); // some margin from the top
RenderTools()->RenderTee(CAnimState::GetIdle(), &Info, 0, vec2(1.0f, 0.0f), vec2(Item.m_Rect.x + 30, Item.m_Rect.y + Item.m_Rect.h / 2)); RenderTools()->RenderTee(CAnimState::GetIdle(), &Info, 0, vec2(1.0f, 0.0f), vec2(Item.m_Rect.x + 30, Item.m_Rect.y + Item.m_Rect.h / 2));
@ -707,6 +713,10 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
{ {
m_pClient->m_pSkins->Refresh(); m_pClient->m_pSkins->Refresh();
s_InitSkinlist = true; s_InitSkinlist = true;
if(Client()->State() >= IClient::STATE_ONLINE)
{
m_pClient->RefindSkins();
}
} }
TextRender()->SetRenderFlags(0); TextRender()->SetRenderFlags(0);
TextRender()->SetCurFont(NULL); TextRender()->SetCurFont(NULL);
@ -1910,11 +1920,10 @@ void CMenus::RenderSettingsHUD(CUIRect MainView)
// render head // render head
{ {
Graphics()->BlendNormal(); Graphics()->BlendNormal();
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_PARTICLES].m_Id); int SpriteIndex = time_get() % 3;
Graphics()->TextureSet(GameClient()->m_ParticlesSkin.m_SpriteParticleSplat[SpriteIndex]);
Graphics()->QuadsBegin(); Graphics()->QuadsBegin();
int Sprites[] = {SPRITE_PART_SPLAT01, SPRITE_PART_SPLAT02, SPRITE_PART_SPLAT03};
RenderTools()->SelectSprite(Sprites[time_get() % 3]);
Graphics()->QuadsSetRotation(time_get()); Graphics()->QuadsSetRotation(time_get());
Graphics()->SetColor(OuterColor.r, OuterColor.g, OuterColor.b, 1.0f); Graphics()->SetColor(OuterColor.r, OuterColor.g, OuterColor.b, 1.0f);
IGraphics::CQuadItem QuadItem(Pos.x, Pos.y, 24, 24); IGraphics::CQuadItem QuadItem(Pos.x, Pos.y, 24, 24);
@ -1925,10 +1934,11 @@ void CMenus::RenderSettingsHUD(CUIRect MainView)
Graphics()->QuadsEnd(); Graphics()->QuadsEnd();
} }
// draw laser weapon // draw laser weapon
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteWeaponLaser);
Graphics()->QuadsBegin(); Graphics()->QuadsBegin();
RenderTools()->SelectSprite(SPRITE_WEAPON_LASER_BODY); RenderTools()->SelectSprite(SPRITE_WEAPON_LASER_BODY);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->DrawSprite(Weapon.x, Weapon.y + Weapon.h / 2.0f, 60.0f); RenderTools()->DrawSprite(Weapon.x, Weapon.y + Weapon.h / 2.0f, 60.0f);
Graphics()->QuadsEnd(); Graphics()->QuadsEnd();

View file

@ -167,15 +167,13 @@ void CParticles::OnInit()
for(int i = 0; i <= (SPRITE_PART9 - SPRITE_PART_SLICE); ++i) for(int i = 0; i <= (SPRITE_PART9 - SPRITE_PART_SLICE); ++i)
{ {
RenderTools()->SelectSprite(i); Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ParticleQuadContainerIndex, 1.f, false); RenderTools()->QuadContainerAddSprite(m_ParticleQuadContainerIndex, 1.f);
} }
} }
void CParticles::RenderGroup(int Group) void CParticles::RenderGroup(int Group)
{ {
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_PARTICLES].m_Id);
// don't use the buffer methods here, else the old renderer gets many draw calls // don't use the buffer methods here, else the old renderer gets many draw calls
if(Graphics()->IsQuadContainerBufferingEnabled()) if(Graphics()->IsQuadContainerBufferingEnabled())
{ {
@ -214,6 +212,7 @@ void CParticles::RenderGroup(int Group)
if(LastColor[0] != m_aParticles[i].m_Color.r || LastColor[1] != m_aParticles[i].m_Color.g || LastColor[2] != m_aParticles[i].m_Color.b || LastColor[3] != m_aParticles[i].m_Color.a || LastQuadOffset != QuadOffset) if(LastColor[0] != m_aParticles[i].m_Color.r || LastColor[1] != m_aParticles[i].m_Color.g || LastColor[2] != m_aParticles[i].m_Color.b || LastColor[3] != m_aParticles[i].m_Color.a || LastQuadOffset != QuadOffset)
{ {
Graphics()->TextureSet(GameClient()->m_ParticlesSkin.m_SpriteParticles[LastQuadOffset - SPRITE_PART_SLICE]);
Graphics()->RenderQuadContainerAsSpriteMultiple(m_ParticleQuadContainerIndex, LastQuadOffset, CurParticleRenderCount, s_aParticleRenderInfo); Graphics()->RenderQuadContainerAsSpriteMultiple(m_ParticleQuadContainerIndex, LastQuadOffset, CurParticleRenderCount, s_aParticleRenderInfo);
CurParticleRenderCount = 0; CurParticleRenderCount = 0;
LastQuadOffset = QuadOffset; LastQuadOffset = QuadOffset;
@ -241,6 +240,7 @@ void CParticles::RenderGroup(int Group)
i = m_aParticles[i].m_NextPart; i = m_aParticles[i].m_NextPart;
} }
Graphics()->TextureSet(GameClient()->m_ParticlesSkin.m_SpriteParticles[LastQuadOffset - SPRITE_PART_SLICE]);
Graphics()->RenderQuadContainerAsSpriteMultiple(m_ParticleQuadContainerIndex, LastQuadOffset, CurParticleRenderCount, s_aParticleRenderInfo); Graphics()->RenderQuadContainerAsSpriteMultiple(m_ParticleQuadContainerIndex, LastQuadOffset, CurParticleRenderCount, s_aParticleRenderInfo);
} }
else else
@ -248,13 +248,12 @@ void CParticles::RenderGroup(int Group)
int i = m_aFirstPart[Group]; int i = m_aFirstPart[Group];
Graphics()->BlendNormal(); Graphics()->BlendNormal();
//gfx_blend_additive(); Graphics()->WrapClamp();
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_PARTICLES].m_Id);
Graphics()->QuadsBegin();
while(i != -1) while(i != -1)
{ {
RenderTools()->SelectSprite(m_aParticles[i].m_Spr); Graphics()->TextureSet(GameClient()->m_ParticlesSkin.m_SpriteParticles[m_aParticles[i].m_Spr - SPRITE_PART_SLICE]);
Graphics()->QuadsBegin();
float a = m_aParticles[i].m_Life / m_aParticles[i].m_LifeSpan; float a = m_aParticles[i].m_Life / m_aParticles[i].m_LifeSpan;
vec2 p = m_aParticles[i].m_Pos; vec2 p = m_aParticles[i].m_Pos;
float Size = mix(m_aParticles[i].m_StartSize, m_aParticles[i].m_EndSize, a); float Size = mix(m_aParticles[i].m_StartSize, m_aParticles[i].m_EndSize, a);
@ -271,8 +270,9 @@ void CParticles::RenderGroup(int Group)
Graphics()->QuadsDraw(&QuadItem, 1); Graphics()->QuadsDraw(&QuadItem, 1);
i = m_aParticles[i].m_NextPart; i = m_aParticles[i].m_NextPart;
Graphics()->QuadsEnd();
} }
Graphics()->QuadsEnd(); Graphics()->WrapNormal();
Graphics()->BlendNormal(); Graphics()->BlendNormal();
} }
} }

View file

@ -45,8 +45,8 @@ void CPlayers::RenderHand(CTeeRenderInfo *pInfo, vec2 CenterPos, vec2 Dir, float
HandPos += DirX * PostRotOffset.x; HandPos += DirX * PostRotOffset.x;
HandPos += DirY * PostRotOffset.y; HandPos += DirY * PostRotOffset.y;
//Graphics()->TextureSet(data->m_aImages[IMAGE_CHAR_DEFAULT].id); const CSkin::SSkinTextures *pSkinTextures = pInfo->m_CustomColoredSkin ? &pInfo->m_ColorableRenderSkin : &pInfo->m_OriginalRenderSkin;
Graphics()->TextureSet(pInfo->m_Texture);
Graphics()->SetColor(pInfo->m_ColorBody.r, pInfo->m_ColorBody.g, pInfo->m_ColorBody.b, Alpha); Graphics()->SetColor(pInfo->m_ColorBody.r, pInfo->m_ColorBody.g, pInfo->m_ColorBody.b, Alpha);
// two passes // two passes
@ -54,6 +54,7 @@ void CPlayers::RenderHand(CTeeRenderInfo *pInfo, vec2 CenterPos, vec2 Dir, float
{ {
int QuadOffset = NUM_WEAPONS * 2 + i; int QuadOffset = NUM_WEAPONS * 2 + i;
Graphics()->QuadsSetRotation(Angle); Graphics()->QuadsSetRotation(Angle);
Graphics()->TextureSet(i == 0 ? pSkinTextures->m_HandsOutline : pSkinTextures->m_Hands);
Graphics()->RenderQuadContainerAsSprite(m_WeaponEmoteQuadContainerIndex, QuadOffset, HandPos.x, HandPos.y); Graphics()->RenderQuadContainerAsSprite(m_WeaponEmoteQuadContainerIndex, QuadOffset, HandPos.x, HandPos.y);
} }
} }
@ -110,8 +111,6 @@ void CPlayers::RenderHook(
// draw hook // draw hook
if(Prev.m_HookState > 0 && Player.m_HookState > 0) if(Prev.m_HookState > 0 && Player.m_HookState > 0)
{ {
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f); Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
if(ClientID < 0) if(ClientID < 0)
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.5f); Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.5f);
@ -127,6 +126,7 @@ void CPlayers::RenderHook(
float d = distance(Pos, HookPos); float d = distance(Pos, HookPos);
vec2 Dir = normalize(Pos - HookPos); vec2 Dir = normalize(Pos - HookPos);
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteHookHead);
Graphics()->QuadsSetRotation(GetAngle(Dir) + pi); Graphics()->QuadsSetRotation(GetAngle(Dir) + pi);
// render head // render head
int QuadOffset = NUM_WEAPONS * 2 + 2; int QuadOffset = NUM_WEAPONS * 2 + 2;
@ -148,6 +148,7 @@ void CPlayers::RenderHook(
s_HookChainRenderInfo[HookChainCount].m_Rotation = GetAngle(Dir) + pi; s_HookChainRenderInfo[HookChainCount].m_Rotation = GetAngle(Dir) + pi;
++HookChainCount; ++HookChainCount;
} }
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteHookChain);
Graphics()->RenderQuadContainerAsSpriteMultiple(m_WeaponEmoteQuadContainerIndex, QuadOffset, HookChainCount, s_HookChainRenderInfo); Graphics()->RenderQuadContainerAsSpriteMultiple(m_WeaponEmoteQuadContainerIndex, QuadOffset, HookChainCount, s_HookChainRenderInfo);
Graphics()->QuadsSetRotation(0); Graphics()->QuadsSetRotation(0);
@ -356,7 +357,6 @@ void CPlayers::RenderPlayer(
Graphics()->LinesEnd(); Graphics()->LinesEnd();
} }
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f); Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
Graphics()->QuadsSetRotation(State.GetAttach()->m_Angle * pi * 2 + Angle); Graphics()->QuadsSetRotation(State.GetAttach()->m_Angle * pi * 2 + Angle);
@ -365,6 +365,7 @@ void CPlayers::RenderPlayer(
// normal weapons // normal weapons
int iw = clamp(Player.m_Weapon, 0, NUM_WEAPONS - 1); int iw = clamp(Player.m_Weapon, 0, NUM_WEAPONS - 1);
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteWeapons[iw]);
int QuadOffset = iw * 2 + (Direction.x < 0 ? 1 : 0); int QuadOffset = iw * 2 + (Direction.x < 0 ? 1 : 0);
Graphics()->SetColor(1.0f, 1.0f, 1.0f, Alpha); Graphics()->SetColor(1.0f, 1.0f, 1.0f, Alpha);
@ -442,6 +443,7 @@ void CPlayers::RenderPlayer(
p = Position; p = Position;
float OffsetX = g_pData->m_Weapons.m_aId[iw].m_Muzzleoffsetx; float OffsetX = g_pData->m_Weapons.m_aId[iw].m_Muzzleoffsetx;
p -= Dir * OffsetX; p -= Dir * OffsetX;
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteWeaponsMuzzles[iw][IteX]);
Graphics()->RenderQuadContainerAsSprite(m_WeaponSpriteMuzzleQuadContainerIndex[iw], QuadOffset, p.x, p.y); Graphics()->RenderQuadContainerAsSprite(m_WeaponSpriteMuzzleQuadContainerIndex[iw], QuadOffset, p.x, p.y);
} }
} }
@ -498,6 +500,7 @@ void CPlayers::RenderPlayer(
vec2 DirY(-Dir.y, Dir.x); vec2 DirY(-Dir.y, Dir.x);
vec2 MuzzlePos = p + Dir * g_pData->m_Weapons.m_aId[iw].m_Muzzleoffsetx + DirY * OffsetY; vec2 MuzzlePos = p + Dir * g_pData->m_Weapons.m_aId[iw].m_Muzzleoffsetx + DirY * OffsetY;
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteWeaponsMuzzles[iw][IteX]);
Graphics()->RenderQuadContainerAsSprite(m_WeaponSpriteMuzzleQuadContainerIndex[iw], QuadOffset, MuzzlePos.x, MuzzlePos.y); Graphics()->RenderQuadContainerAsSprite(m_WeaponSpriteMuzzleQuadContainerIndex[iw], QuadOffset, MuzzlePos.x, MuzzlePos.y);
} }
} }
@ -566,8 +569,9 @@ void CPlayers::RenderPlayer(
int QuadOffsetToEmoticon = NUM_WEAPONS * 2 + 2 + 2; int QuadOffsetToEmoticon = NUM_WEAPONS * 2 + 2 + 2;
if((Player.m_PlayerFlags & PLAYERFLAG_CHATTING) && !m_pClient->m_aClients[ClientID].m_Afk) if((Player.m_PlayerFlags & PLAYERFLAG_CHATTING) && !m_pClient->m_aClients[ClientID].m_Afk)
{ {
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id); int CurEmoticon = (SPRITE_DOTDOT - SPRITE_OOP);
int QuadOffset = QuadOffsetToEmoticon + (SPRITE_DOTDOT - SPRITE_OOP); Graphics()->TextureSet(GameClient()->m_EmoticonsSkin.m_SpriteEmoticons[CurEmoticon]);
int QuadOffset = QuadOffsetToEmoticon + CurEmoticon;
Graphics()->SetColor(1.0f, 1.0f, 1.0f, Alpha); Graphics()->SetColor(1.0f, 1.0f, 1.0f, Alpha);
Graphics()->RenderQuadContainerAsSprite(m_WeaponEmoteQuadContainerIndex, QuadOffset, Position.x + 24.f, Position.y - 40.f); Graphics()->RenderQuadContainerAsSprite(m_WeaponEmoteQuadContainerIndex, QuadOffset, Position.x + 24.f, Position.y - 40.f);
@ -580,8 +584,9 @@ void CPlayers::RenderPlayer(
if(g_Config.m_ClAfkEmote && m_pClient->m_aClients[ClientID].m_Afk && !(Client()->DummyConnected() && ClientID == m_pClient->m_LocalIDs[!g_Config.m_ClDummy])) if(g_Config.m_ClAfkEmote && m_pClient->m_aClients[ClientID].m_Afk && !(Client()->DummyConnected() && ClientID == m_pClient->m_LocalIDs[!g_Config.m_ClDummy]))
{ {
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id); int CurEmoticon = (SPRITE_ZZZ - SPRITE_OOP);
int QuadOffset = QuadOffsetToEmoticon + (SPRITE_ZZZ - SPRITE_OOP); Graphics()->TextureSet(GameClient()->m_EmoticonsSkin.m_SpriteEmoticons[CurEmoticon]);
int QuadOffset = QuadOffsetToEmoticon + CurEmoticon;
Graphics()->SetColor(1.0f, 1.0f, 1.0f, Alpha); Graphics()->SetColor(1.0f, 1.0f, 1.0f, Alpha);
Graphics()->RenderQuadContainerAsSprite(m_WeaponEmoteQuadContainerIndex, QuadOffset, Position.x + 24.f, Position.y - 40.f); Graphics()->RenderQuadContainerAsSprite(m_WeaponEmoteQuadContainerIndex, QuadOffset, Position.x + 24.f, Position.y - 40.f);
@ -591,8 +596,6 @@ void CPlayers::RenderPlayer(
if(g_Config.m_ClShowEmotes && !m_pClient->m_aClients[ClientID].m_EmoticonIgnore && m_pClient->m_aClients[ClientID].m_EmoticonStart != -1 && m_pClient->m_aClients[ClientID].m_EmoticonStart <= Client()->GameTick(g_Config.m_ClDummy) && m_pClient->m_aClients[ClientID].m_EmoticonStart + 2 * Client()->GameTickSpeed() > Client()->GameTick(g_Config.m_ClDummy)) if(g_Config.m_ClShowEmotes && !m_pClient->m_aClients[ClientID].m_EmoticonIgnore && m_pClient->m_aClients[ClientID].m_EmoticonStart != -1 && m_pClient->m_aClients[ClientID].m_EmoticonStart <= Client()->GameTick(g_Config.m_ClDummy) && m_pClient->m_aClients[ClientID].m_EmoticonStart + 2 * Client()->GameTickSpeed() > Client()->GameTick(g_Config.m_ClDummy))
{ {
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id);
int SinceStart = Client()->GameTick(g_Config.m_ClDummy) - m_pClient->m_aClients[ClientID].m_EmoticonStart; int SinceStart = Client()->GameTick(g_Config.m_ClDummy) - m_pClient->m_aClients[ClientID].m_EmoticonStart;
int FromEnd = m_pClient->m_aClients[ClientID].m_EmoticonStart + 2 * Client()->GameTickSpeed() - Client()->GameTick(g_Config.m_ClDummy); int FromEnd = m_pClient->m_aClients[ClientID].m_EmoticonStart + 2 * Client()->GameTickSpeed() - Client()->GameTick(g_Config.m_ClDummy);
@ -616,6 +619,7 @@ void CPlayers::RenderPlayer(
Graphics()->SetColor(1.0f, 1.0f, 1.0f, a * Alpha); Graphics()->SetColor(1.0f, 1.0f, 1.0f, a * Alpha);
// client_datas::emoticon is an offset from the first emoticon // client_datas::emoticon is an offset from the first emoticon
int QuadOffset = QuadOffsetToEmoticon + m_pClient->m_aClients[ClientID].m_Emoticon; int QuadOffset = QuadOffsetToEmoticon + m_pClient->m_aClients[ClientID].m_Emoticon;
Graphics()->TextureSet(GameClient()->m_EmoticonsSkin.m_SpriteEmoticons[m_pClient->m_aClients[ClientID].m_Emoticon]);
Graphics()->RenderQuadContainerAsSprite(m_WeaponEmoteQuadContainerIndex, QuadOffset, Position.x, Position.y - 23.f - 32.f * h, 1.f, (64.f * h) / 64.f); Graphics()->RenderQuadContainerAsSprite(m_WeaponEmoteQuadContainerIndex, QuadOffset, Position.x, Position.y - 23.f - 32.f * h, 1.f, (64.f * h) / 64.f);
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f); Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
@ -638,18 +642,25 @@ void CPlayers::OnRender()
int Skin = m_pClient->m_pSkins->Find("x_ninja"); int Skin = m_pClient->m_pSkins->Find("x_ninja");
if(Skin != -1) if(Skin != -1)
{ {
if(IsTeamplay) const CSkin *pSkin = m_pClient->m_pSkins->Get(Skin);
m_aRenderInfo[i].m_Texture = m_pClient->m_pSkins->Get(Skin)->m_ColorTexture; m_aRenderInfo[i].m_OriginalRenderSkin = pSkin->m_OriginalSkin;
else m_aRenderInfo[i].m_ColorableRenderSkin = pSkin->m_ColorableSkin;
m_aRenderInfo[i].m_BloodColor = pSkin->m_BloodColor;
m_aRenderInfo[i].m_CustomColoredSkin = IsTeamplay;
if(!IsTeamplay)
{ {
m_aRenderInfo[i].m_Texture = m_pClient->m_pSkins->Get(Skin)->m_OrgTexture;
m_aRenderInfo[i].m_ColorBody = ColorRGBA(1, 1, 1); m_aRenderInfo[i].m_ColorBody = ColorRGBA(1, 1, 1);
m_aRenderInfo[i].m_ColorFeet = ColorRGBA(1, 1, 1); m_aRenderInfo[i].m_ColorFeet = ColorRGBA(1, 1, 1);
} }
} }
} }
} }
m_RenderInfoSpec.m_Texture = m_pClient->m_pSkins->Get(m_pClient->m_pSkins->Find("x_spec"))->m_OrgTexture; int Skin = m_pClient->m_pSkins->Find("x_spec");
const CSkin *pSkin = m_pClient->m_pSkins->Get(Skin);
m_RenderInfoSpec.m_OriginalRenderSkin = pSkin->m_OriginalSkin;
m_RenderInfoSpec.m_ColorableRenderSkin = pSkin->m_ColorableSkin;
m_RenderInfoSpec.m_BloodColor = pSkin->m_BloodColor;
m_RenderInfoSpec.m_CustomColoredSkin = false;
m_RenderInfoSpec.m_Size = 64.0f; m_RenderInfoSpec.m_Size = 64.0f;
// render other players in three passes, first pass we render spectees, // render other players in three passes, first pass we render spectees,
@ -714,27 +725,30 @@ void CPlayers::OnInit()
for(int i = 0; i < NUM_WEAPONS; ++i) for(int i = 0; i < NUM_WEAPONS; ++i)
{ {
RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[i].m_pSpriteBody, 0); float ScaleX, ScaleY;
RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, g_pData->m_Weapons.m_aId[i].m_VisualSize); RenderTools()->GetSpriteScale(g_pData->m_Weapons.m_aId[i].m_pSpriteBody, ScaleX, ScaleY);
RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[i].m_pSpriteBody, SPRITE_FLAG_FLIP_Y); Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, g_pData->m_Weapons.m_aId[i].m_VisualSize); RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, g_pData->m_Weapons.m_aId[i].m_VisualSize * ScaleX, g_pData->m_Weapons.m_aId[i].m_VisualSize * ScaleY);
Graphics()->QuadsSetSubset(0, 1, 1, 0);
RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, g_pData->m_Weapons.m_aId[i].m_VisualSize * ScaleX, g_pData->m_Weapons.m_aId[i].m_VisualSize * ScaleY);
} }
float ScaleX, ScaleY;
// at the end the hand // at the end the hand
RenderTools()->SelectSprite(SPRITE_TEE_HAND_OUTLINE, 0, 0, 0); Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, 20.f, false); RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, 20.f);
RenderTools()->SelectSprite(SPRITE_TEE_HAND, 0, 0, 0); Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, 20.f, false); RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, 20.f);
RenderTools()->SelectSprite(SPRITE_HOOK_HEAD); Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, -12.f, -8.f, 24.f, 16.f); RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, -12.f, -8.f, 24.f, 16.f);
RenderTools()->SelectSprite(SPRITE_HOOK_CHAIN); Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, -12.f, -8.f, 24.f, 16.f); RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, -12.f, -8.f, 24.f, 16.f);
for(int i = 0; i < NUM_EMOTICONS; ++i) for(int i = 0; i < NUM_EMOTICONS; ++i)
{ {
RenderTools()->SelectSprite(SPRITE_OOP + i); Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, 64.f, false); RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, 64.f);
} }
for(int i = 0; i < NUM_WEAPONS; ++i) for(int i = 0; i < NUM_WEAPONS; ++i)
@ -744,21 +758,18 @@ void CPlayers::OnInit()
{ {
if(g_pData->m_Weapons.m_aId[i].m_aSpriteMuzzles[n]) if(g_pData->m_Weapons.m_aId[i].m_aSpriteMuzzles[n])
{ {
RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[i].m_aSpriteMuzzles[n], 0); RenderTools()->GetSpriteScale(g_pData->m_Weapons.m_aId[i].m_aSpriteMuzzles[n], ScaleX, ScaleY);
} }
if(WEAPON_NINJA == i) if(WEAPON_NINJA == i)
RenderTools()->QuadContainerAddSprite(m_WeaponSpriteMuzzleQuadContainerIndex[i], 160.f); RenderTools()->QuadContainerAddSprite(m_WeaponSpriteMuzzleQuadContainerIndex[i], 160.f * ScaleX, 160.f * ScaleY);
else else
RenderTools()->QuadContainerAddSprite(m_WeaponSpriteMuzzleQuadContainerIndex[i], g_pData->m_Weapons.m_aId[i].m_VisualSize); RenderTools()->QuadContainerAddSprite(m_WeaponSpriteMuzzleQuadContainerIndex[i], g_pData->m_Weapons.m_aId[i].m_VisualSize * ScaleX, g_pData->m_Weapons.m_aId[i].m_VisualSize * ScaleY);
if(g_pData->m_Weapons.m_aId[i].m_aSpriteMuzzles[n]) Graphics()->QuadsSetSubset(0, 1, 1, 0);
{
RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[i].m_aSpriteMuzzles[n], SPRITE_FLAG_FLIP_Y);
}
if(WEAPON_NINJA == i) if(WEAPON_NINJA == i)
RenderTools()->QuadContainerAddSprite(m_WeaponSpriteMuzzleQuadContainerIndex[i], 160.f); RenderTools()->QuadContainerAddSprite(m_WeaponSpriteMuzzleQuadContainerIndex[i], 160.f * ScaleX, 160.f * ScaleY);
else else
RenderTools()->QuadContainerAddSprite(m_WeaponSpriteMuzzleQuadContainerIndex[i], g_pData->m_Weapons.m_aId[i].m_VisualSize); RenderTools()->QuadContainerAddSprite(m_WeaponSpriteMuzzleQuadContainerIndex[i], g_pData->m_Weapons.m_aId[i].m_VisualSize * ScaleX, g_pData->m_Weapons.m_aId[i].m_VisualSize * ScaleY);
} }
} }

View file

@ -440,10 +440,13 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch
m_pClient->m_Snap.m_pGameDataObj && (m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierRed == pInfo->m_ClientID || m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierBlue == pInfo->m_ClientID)) m_pClient->m_Snap.m_pGameDataObj && (m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierRed == pInfo->m_ClientID || m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierBlue == pInfo->m_ClientID))
{ {
Graphics()->BlendNormal(); Graphics()->BlendNormal();
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); if(m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierBlue == pInfo->m_ClientID)
Graphics()->QuadsBegin(); Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagBlue);
else
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagRed);
RenderTools()->SelectSprite(m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierBlue == pInfo->m_ClientID ? SPRITE_FLAG_BLUE : SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X); Graphics()->QuadsBegin();
Graphics()->QuadsSetSubset(1, 0, 0, 1);
float Size = LineHeight; float Size = LineHeight;
IGraphics::CQuadItem QuadItem(TeeOffset + 0.0f, y - 5.0f - Spacing / 2.0f, Size / 2.0f, Size); IGraphics::CQuadItem QuadItem(TeeOffset + 0.0f, y - 5.0f - Spacing / 2.0f, Size / 2.0f, Size);

View file

@ -55,7 +55,7 @@ int CSkins::SkinScan(const char *pName, int IsDir, int DirType, void *pUser)
return pSelf->LoadSkin(aNameWithoutPng, aBuf, DirType); return pSelf->LoadSkin(aNameWithoutPng, aBuf, DirType);
} }
int CSkins::LoadSkin(const char *pName, const char *pPath, int DirType) int CSkins::LoadSkin(const char *pName, const char *pPath, int DirType, int *pGetSkinID)
{ {
char aBuf[512]; char aBuf[512];
CImageInfo Info; CImageInfo Info;
@ -68,7 +68,15 @@ int CSkins::LoadSkin(const char *pName, const char *pPath, int DirType)
CSkin Skin; CSkin Skin;
Skin.m_IsVanilla = IsVanillaSkin(pName); Skin.m_IsVanilla = IsVanillaSkin(pName);
Skin.m_OrgTexture = Graphics()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, Info.m_Format, 0); Skin.m_OriginalSkin.m_Body = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_BODY]);
Skin.m_OriginalSkin.m_BodyOutline = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_BODY_OUTLINE]);
Skin.m_OriginalSkin.m_Feet = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_FOOT]);
Skin.m_OriginalSkin.m_FeetOutline = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_FOOT_OUTLINE]);
Skin.m_OriginalSkin.m_Hands = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_HAND]);
Skin.m_OriginalSkin.m_HandsOutline = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_HAND_OUTLINE]);
for(int i = 0; i < 6; ++i)
Skin.m_OriginalSkin.m_Eyes[i] = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_EYE_NORMAL + i]);
int BodySize = 96; // body size int BodySize = 96; // body size
if(BodySize > Info.m_Height) if(BodySize > Info.m_Height)
@ -139,7 +147,16 @@ int CSkins::LoadSkin(const char *pName, const char *pPath, int DirType)
d[y * Pitch + x * 4 + 2] = v; d[y * Pitch + x * 4 + 2] = v;
} }
Skin.m_ColorTexture = Graphics()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, Info.m_Format, 0); Skin.m_ColorableSkin.m_Body = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_BODY]);
Skin.m_ColorableSkin.m_BodyOutline = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_BODY_OUTLINE]);
Skin.m_ColorableSkin.m_Feet = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_FOOT]);
Skin.m_ColorableSkin.m_FeetOutline = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_FOOT_OUTLINE]);
Skin.m_ColorableSkin.m_Hands = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_HAND]);
Skin.m_ColorableSkin.m_HandsOutline = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_HAND_OUTLINE]);
for(int i = 0; i < 6; ++i)
Skin.m_ColorableSkin.m_Eyes[i] = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_EYE_NORMAL + i]);
free(Info.m_pData); free(Info.m_pData);
// set skin data // set skin data
@ -151,6 +168,9 @@ int CSkins::LoadSkin(const char *pName, const char *pPath, int DirType)
} }
m_aSkins.add(Skin); m_aSkins.add(Skin);
if(pGetSkinID)
*pGetSkinID = m_aSkins.size() - 1;
return 0; return 0;
} }
@ -178,12 +198,23 @@ void CSkins::Refresh()
{ {
for(int i = 0; i < m_aSkins.size(); ++i) for(int i = 0; i < m_aSkins.size(); ++i)
{ {
if(m_aSkins[i].m_OrgTexture != -1) Graphics()->UnloadTextureNew(m_aSkins[i].m_OriginalSkin.m_Body);
Graphics()->UnloadTexture(m_aSkins[i].m_OrgTexture); Graphics()->UnloadTextureNew(m_aSkins[i].m_OriginalSkin.m_BodyOutline);
m_aSkins[i].m_OrgTexture = IGraphics::CTextureHandle(); Graphics()->UnloadTextureNew(m_aSkins[i].m_OriginalSkin.m_Feet);
if(m_aSkins[i].m_ColorTexture != -1) Graphics()->UnloadTextureNew(m_aSkins[i].m_OriginalSkin.m_FeetOutline);
Graphics()->UnloadTexture(m_aSkins[i].m_ColorTexture); Graphics()->UnloadTextureNew(m_aSkins[i].m_OriginalSkin.m_Hands);
m_aSkins[i].m_ColorTexture = IGraphics::CTextureHandle(); Graphics()->UnloadTextureNew(m_aSkins[i].m_OriginalSkin.m_HandsOutline);
for(int n = 0; n < 6; ++n)
Graphics()->UnloadTextureNew(m_aSkins[i].m_OriginalSkin.m_Eyes[n]);
Graphics()->UnloadTextureNew(m_aSkins[i].m_ColorableSkin.m_Body);
Graphics()->UnloadTextureNew(m_aSkins[i].m_ColorableSkin.m_BodyOutline);
Graphics()->UnloadTextureNew(m_aSkins[i].m_ColorableSkin.m_Feet);
Graphics()->UnloadTextureNew(m_aSkins[i].m_ColorableSkin.m_FeetOutline);
Graphics()->UnloadTextureNew(m_aSkins[i].m_ColorableSkin.m_Hands);
Graphics()->UnloadTextureNew(m_aSkins[i].m_ColorableSkin.m_HandsOutline);
for(int n = 0; n < 6; ++n)
Graphics()->UnloadTextureNew(m_aSkins[i].m_ColorableSkin.m_Eyes[n]);
} }
m_aSkins.clear(); m_aSkins.clear();
@ -205,7 +236,7 @@ int CSkins::Num()
return m_aSkins.size(); return m_aSkins.size();
} }
const CSkins::CSkin *CSkins::Get(int Index) const CSkin *CSkins::Get(int Index)
{ {
if(Index < 0) if(Index < 0)
{ {
@ -256,19 +287,20 @@ int CSkins::FindImpl(const char *pName)
auto d = ::find_binary(m_aDownloadSkins.all(), pName); auto d = ::find_binary(m_aDownloadSkins.all(), pName);
if(!d.empty()) if(!d.empty())
{ {
int SkinID = -1;
if(d.front().m_pTask && d.front().m_pTask->State() == HTTP_DONE) if(d.front().m_pTask && d.front().m_pTask->State() == HTTP_DONE)
{ {
char aPath[MAX_PATH_LENGTH]; char aPath[MAX_PATH_LENGTH];
str_format(aPath, sizeof(aPath), "downloadedskins/%s.png", d.front().m_aName); str_format(aPath, sizeof(aPath), "downloadedskins/%s.png", d.front().m_aName);
Storage()->RenameFile(d.front().m_aPath, aPath, IStorage::TYPE_SAVE); Storage()->RenameFile(d.front().m_aPath, aPath, IStorage::TYPE_SAVE);
LoadSkin(d.front().m_aName, aPath, IStorage::TYPE_SAVE); LoadSkin(d.front().m_aName, aPath, IStorage::TYPE_SAVE, &SkinID);
d.front().m_pTask = nullptr; d.front().m_pTask = nullptr;
} }
if(d.front().m_pTask && (d.front().m_pTask->State() == HTTP_ERROR || d.front().m_pTask->State() == HTTP_ABORTED)) if(d.front().m_pTask && (d.front().m_pTask->State() == HTTP_ERROR || d.front().m_pTask->State() == HTTP_ABORTED))
{ {
d.front().m_pTask = nullptr; d.front().m_pTask = nullptr;
} }
return -1; return SkinID;
} }
CDownloadSkin Skin; CDownloadSkin Skin;

View file

@ -7,25 +7,11 @@
#include <base/vmath.h> #include <base/vmath.h>
#include <engine/client/http.h> #include <engine/client/http.h>
#include <game/client/component.h> #include <game/client/component.h>
#include <game/client/skin.h>
class CSkins : public CComponent class CSkins : public CComponent
{ {
public: public:
// do this better and nicer
struct CSkin
{
bool m_IsVanilla;
IGraphics::CTextureHandle m_OrgTexture;
IGraphics::CTextureHandle m_ColorTexture;
char m_aName[24];
ColorRGBA m_BloodColor;
bool operator<(const CSkin &Other) const { return str_comp(m_aName, Other.m_aName) < 0; }
bool operator<(const char *pOther) const { return str_comp(m_aName, pOther) < 0; }
bool operator==(const char *pOther) const { return !str_comp(m_aName, pOther); }
};
struct CDownloadSkin struct CDownloadSkin
{ {
std::shared_ptr<CGetFile> m_pTask; std::shared_ptr<CGetFile> m_pTask;
@ -49,7 +35,7 @@ private:
sorted_array<CDownloadSkin> m_aDownloadSkins; sorted_array<CDownloadSkin> m_aDownloadSkins;
char m_EventSkinPrefix[24]; char m_EventSkinPrefix[24];
int LoadSkin(const char *pName, const char *pPath, int DirType); int LoadSkin(const char *pName, const char *pPath, int DirType, int *pGetSkinID = NULL);
int FindImpl(const char *pName); int FindImpl(const char *pName);
static int SkinScan(const char *pName, int IsDir, int DirType, void *pUser); static int SkinScan(const char *pName, int IsDir, int DirType, void *pUser);
}; };

View file

@ -395,10 +395,13 @@ void CSpectator::OnRender()
m_pClient->m_Snap.m_pGameDataObj && (m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierRed == m_pClient->m_Snap.m_paInfoByDDTeamName[i]->m_ClientID || m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierBlue == m_pClient->m_Snap.m_paInfoByDDTeamName[i]->m_ClientID)) m_pClient->m_Snap.m_pGameDataObj && (m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierRed == m_pClient->m_Snap.m_paInfoByDDTeamName[i]->m_ClientID || m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierBlue == m_pClient->m_Snap.m_paInfoByDDTeamName[i]->m_ClientID))
{ {
Graphics()->BlendNormal(); Graphics()->BlendNormal();
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); if(m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierBlue == m_pClient->m_Snap.m_paInfoByDDTeamName[i]->m_ClientID)
Graphics()->QuadsBegin(); Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagBlue);
else
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagRed);
RenderTools()->SelectSprite(m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierBlue == m_pClient->m_Snap.m_paInfoByDDTeamName[i]->m_ClientID ? SPRITE_FLAG_BLUE : SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X); Graphics()->QuadsBegin();
Graphics()->QuadsSetSubset(1, 0, 0, 1);
float Size = LineHeight; float Size = LineHeight;
IGraphics::CQuadItem QuadItem(Width / 2.0f + x - LineHeight / 5.0f, Height / 2.0f + y - LineHeight / 3.0f, Size / 2.0f, Size); IGraphics::CQuadItem QuadItem(Width / 2.0f + x - LineHeight / 5.0f, Height / 2.0f + y - LineHeight / 3.0f, Size / 2.0f, Size);

View file

@ -217,29 +217,31 @@ void CStatboard::RenderGlobalStats()
px += 85; px += 85;
} }
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
Graphics()->QuadsBegin();
px -= 40; px -= 40;
for(int i = 0; i < NUM_WEAPONS; i++) for(int i = 0; i < NUM_WEAPONS; i++)
{ {
if(!aDisplayWeapon[i]) if(!aDisplayWeapon[i])
continue; continue;
RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[i].m_pSpriteBody); float ScaleX, ScaleY;
RenderTools()->GetSpriteScale(g_pData->m_Weapons.m_aId[i].m_pSpriteBody, ScaleX, ScaleY);
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteWeapons[i]);
Graphics()->QuadsBegin();
if(i == 0) if(i == 0)
RenderTools()->DrawSprite(x + px, y + 10, g_pData->m_Weapons.m_aId[i].m_VisualSize * 0.8f); RenderTools()->DrawSprite(x + px, y + 10, g_pData->m_Weapons.m_aId[i].m_VisualSize * 0.8f * ScaleX, g_pData->m_Weapons.m_aId[i].m_VisualSize * 0.8f * ScaleY);
else else
RenderTools()->DrawSprite(x + px, y + 10, g_pData->m_Weapons.m_aId[i].m_VisualSize); RenderTools()->DrawSprite(x + px, y + 10, g_pData->m_Weapons.m_aId[i].m_VisualSize * ScaleX, g_pData->m_Weapons.m_aId[i].m_VisualSize * ScaleY);
px += 80; px += 80;
Graphics()->QuadsEnd();
} }
Graphics()->QuadsEnd();
if(GameWithFlags) if(GameWithFlags)
{ {
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagRed);
float ScaleX, ScaleY;
RenderTools()->GetSpriteScale(SPRITE_FLAG_RED, ScaleX, ScaleY);
Graphics()->QuadsBegin(); Graphics()->QuadsBegin();
Graphics()->QuadsSetRotation(0.78f); Graphics()->QuadsSetRotation(0.78f);
RenderTools()->SelectSprite(SPRITE_FLAG_RED); RenderTools()->DrawSprite(x + px, y + 15, 48 * ScaleX, 48 * ScaleY);
RenderTools()->DrawSprite(x + px, y + 15, 48);
Graphics()->QuadsEnd(); Graphics()->QuadsEnd();
} }
else else

View file

@ -18,6 +18,7 @@
#include <engine/updater.h> #include <engine/updater.h>
#include <game/generated/client_data.h> #include <game/generated/client_data.h>
#include <game/generated/client_data7.h>
#include <game/generated/protocol.h> #include <game/generated/protocol.h>
#include <base/math.h> #include <base/math.h>
@ -292,8 +293,8 @@ void CGameClient::OnInit()
// propagate pointers // propagate pointers
m_UI.SetGraphics(Graphics(), TextRender()); m_UI.SetGraphics(Graphics(), TextRender());
m_RenderTools.m_pGraphics = Graphics();
m_RenderTools.m_pUI = UI(); m_RenderTools.Init(Graphics(), UI(), this);
int64 Start = time_get(); int64 Start = time_get();
@ -322,6 +323,10 @@ void CGameClient::OnInit()
char aBuf[256]; char aBuf[256];
m_GameSkinLoaded = false;
m_ParticlesSkinLoaded = false;
m_EmoticonsSkinLoaded = false;
// setup load amount// load textures // setup load amount// load textures
for(int i = 0; i < g_pData->m_NumImages; i++) for(int i = 0; i < g_pData->m_NumImages; i++)
{ {
@ -1238,13 +1243,14 @@ void CGameClient::OnNewSnapshot()
pClient->m_SkinInfo.m_Size = 64; pClient->m_SkinInfo.m_Size = 64;
// find new skin // find new skin
pClient->m_SkinID = g_GameClient.m_pSkins->Find(pClient->m_aSkinName); const CSkin *pSkin = m_pSkins->Get(m_pSkins->Find(pClient->m_aSkinName));
pClient->m_SkinInfo.m_OriginalRenderSkin = pSkin->m_OriginalSkin;
pClient->m_SkinInfo.m_ColorableRenderSkin = pSkin->m_ColorableSkin;
pClient->m_SkinInfo.m_BloodColor = pSkin->m_BloodColor;
pClient->m_SkinInfo.m_CustomColoredSkin = pClient->m_UseCustomColor;
if(pClient->m_UseCustomColor) if(!pClient->m_UseCustomColor)
pClient->m_SkinInfo.m_Texture = g_GameClient.m_pSkins->Get(pClient->m_SkinID)->m_ColorTexture;
else
{ {
pClient->m_SkinInfo.m_Texture = g_GameClient.m_pSkins->Get(pClient->m_SkinID)->m_OrgTexture;
pClient->m_SkinInfo.m_ColorBody = ColorRGBA(1, 1, 1); pClient->m_SkinInfo.m_ColorBody = ColorRGBA(1, 1, 1);
pClient->m_SkinInfo.m_ColorFeet = ColorRGBA(1, 1, 1); pClient->m_SkinInfo.m_ColorFeet = ColorRGBA(1, 1, 1);
} }
@ -1923,7 +1929,7 @@ void CGameClient::CClientData::UpdateRenderInfo()
// force team colors // force team colors
if(g_GameClient.m_Snap.m_pGameInfoObj && g_GameClient.m_Snap.m_pGameInfoObj->m_GameFlags & GAMEFLAG_TEAMS) if(g_GameClient.m_Snap.m_pGameInfoObj && g_GameClient.m_Snap.m_pGameInfoObj->m_GameFlags & GAMEFLAG_TEAMS)
{ {
m_RenderInfo.m_Texture = g_GameClient.m_pSkins->Get(m_SkinID)->m_ColorTexture; m_RenderInfo.m_CustomColoredSkin = true;
const int TeamColors[2] = {65461, 10223541}; const int TeamColors[2] = {65461, 10223541};
if(m_Team >= TEAM_RED && m_Team <= TEAM_BLUE) if(m_Team >= TEAM_RED && m_Team <= TEAM_BLUE)
{ {
@ -1943,7 +1949,6 @@ void CGameClient::CClientData::Reset()
m_aName[0] = 0; m_aName[0] = 0;
m_aClan[0] = 0; m_aClan[0] = 0;
m_Country = -1; m_Country = -1;
m_SkinID = -1;
m_Team = 0; m_Team = 0;
m_Angle = 0; m_Angle = 0;
m_Emoticon = 0; m_Emoticon = 0;
@ -1957,7 +1962,10 @@ void CGameClient::CClientData::Reset()
m_Afk = false; m_Afk = false;
m_Paused = false; m_Paused = false;
m_Spec = false; m_Spec = false;
m_SkinInfo.m_Texture = g_GameClient.m_pSkins->Get(-1)->m_OrgTexture; m_SkinInfo.m_BloodColor = ColorRGBA(1, 1, 1);
m_SkinInfo.m_ColorableRenderSkin.Reset();
m_SkinInfo.m_OriginalRenderSkin.Reset();
m_SkinInfo.m_CustomColoredSkin = false;
m_SkinInfo.m_ColorBody = ColorRGBA(1, 1, 1); m_SkinInfo.m_ColorBody = ColorRGBA(1, 1, 1);
m_SkinInfo.m_ColorFeet = ColorRGBA(1, 1, 1); m_SkinInfo.m_ColorFeet = ColorRGBA(1, 1, 1);
@ -2514,10 +2522,99 @@ bool CGameClient::IsOtherTeam(int ClientID)
void CGameClient::LoadGameSkin(const char *pPath, bool AsDir) void CGameClient::LoadGameSkin(const char *pPath, bool AsDir)
{ {
if(g_pData->m_aImages[IMAGE_GAME].m_Id != -1) if(m_GameSkinLoaded)
{ {
Graphics()->UnloadTexture(g_pData->m_aImages[IMAGE_GAME].m_Id); Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteHealthFull);
g_pData->m_aImages[IMAGE_GAME].m_Id = IGraphics::CTextureHandle(); Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteHealthEmpty);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteArmorFull);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteArmorEmpty);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponHammerCursor);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponGunCursor);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponShotgunCursor);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponGrenadeCursor);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponNinjaCursor);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponLaserCursor);
for(int i = 0; i < 6; ++i)
{
m_GameSkin.m_SpriteWeaponCursors[i] = IGraphics::CTextureHandle();
}
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteHookChain);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteHookHead);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponHammer);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponGun);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponShotgun);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponGrenade);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponNinja);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponLaser);
for(int i = 0; i < 6; ++i)
{
m_GameSkin.m_SpriteWeapons[i] = IGraphics::CTextureHandle();
}
for(int i = 0; i < 9; ++i)
{
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteParticles[i]);
}
for(int i = 0; i < 3; ++i)
{
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteStars[i]);
}
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponGunProjectile);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponShotgunProjectile);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponGrenadeProjectile);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponHammerProjectile);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponNinjaProjectile);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponLaserProjectile);
for(int i = 0; i < 6; ++i)
{
m_GameSkin.m_SpriteWeaponProjectiles[i] = IGraphics::CTextureHandle();
}
for(int i = 0; i < 3; ++i)
{
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponGunMuzzles[i]);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponShotgunMuzzles[i]);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponNinjaMuzzles[i]);
for(int n = 0; n < 6; ++n)
{
m_GameSkin.m_SpriteWeaponsMuzzles[n][i] = IGraphics::CTextureHandle();
}
}
Graphics()->UnloadTextureNew(m_GameSkin.m_SpritePickupHealth);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpritePickupArmor);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpritePickupGrenade);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpritePickupShotgun);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpritePickupLaser);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpritePickupNinja);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpritePickupGun);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpritePickupHammer);
for(int i = 0; i < 6; ++i)
{
m_GameSkin.m_SpritePickupWeapons[i] = IGraphics::CTextureHandle();
}
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteFlagBlue);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteFlagRed);
if(m_GameSkin.IsSixup())
{
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteNinjaBarFullLeft);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteNinjaBarFull);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteNinjaBarEmpty);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteNinjaBarEmptyRight);
}
m_GameSkinLoaded = false;
} }
char aPath[MAX_PATH_LENGTH]; char aPath[MAX_PATH_LENGTH];
@ -2546,17 +2643,131 @@ void CGameClient::LoadGameSkin(const char *pPath, bool AsDir)
} }
else if(PngLoaded) else if(PngLoaded)
{ {
g_pData->m_aImages[IMAGE_GAME].m_Id = Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, ImgInfo.m_Format, 0, aPath); m_GameSkin.m_SpriteHealthFull = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_HEALTH_FULL]);
m_GameSkin.m_SpriteHealthEmpty = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_HEALTH_EMPTY]);
m_GameSkin.m_SpriteArmorFull = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_ARMOR_FULL]);
m_GameSkin.m_SpriteArmorEmpty = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_ARMOR_EMPTY]);
m_GameSkin.m_SpriteWeaponHammerCursor = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_HAMMER_CURSOR]);
m_GameSkin.m_SpriteWeaponGunCursor = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_GUN_CURSOR]);
m_GameSkin.m_SpriteWeaponShotgunCursor = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_SHOTGUN_CURSOR]);
m_GameSkin.m_SpriteWeaponGrenadeCursor = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_GRENADE_CURSOR]);
m_GameSkin.m_SpriteWeaponNinjaCursor = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_NINJA_CURSOR]);
m_GameSkin.m_SpriteWeaponLaserCursor = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_LASER_CURSOR]);
m_GameSkin.m_SpriteWeaponCursors[0] = m_GameSkin.m_SpriteWeaponHammerCursor;
m_GameSkin.m_SpriteWeaponCursors[1] = m_GameSkin.m_SpriteWeaponGunCursor;
m_GameSkin.m_SpriteWeaponCursors[2] = m_GameSkin.m_SpriteWeaponShotgunCursor;
m_GameSkin.m_SpriteWeaponCursors[3] = m_GameSkin.m_SpriteWeaponGrenadeCursor;
m_GameSkin.m_SpriteWeaponCursors[4] = m_GameSkin.m_SpriteWeaponLaserCursor;
m_GameSkin.m_SpriteWeaponCursors[5] = m_GameSkin.m_SpriteWeaponNinjaCursor;
// weapons and hook
m_GameSkin.m_SpriteHookChain = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_HOOK_CHAIN]);
m_GameSkin.m_SpriteHookHead = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_HOOK_HEAD]);
m_GameSkin.m_SpriteWeaponHammer = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_HAMMER_BODY]);
m_GameSkin.m_SpriteWeaponGun = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_GUN_BODY]);
m_GameSkin.m_SpriteWeaponShotgun = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_SHOTGUN_BODY]);
m_GameSkin.m_SpriteWeaponGrenade = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_GRENADE_BODY]);
m_GameSkin.m_SpriteWeaponNinja = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_NINJA_BODY]);
m_GameSkin.m_SpriteWeaponLaser = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_LASER_BODY]);
m_GameSkin.m_SpriteWeapons[0] = m_GameSkin.m_SpriteWeaponHammer;
m_GameSkin.m_SpriteWeapons[1] = m_GameSkin.m_SpriteWeaponGun;
m_GameSkin.m_SpriteWeapons[2] = m_GameSkin.m_SpriteWeaponShotgun;
m_GameSkin.m_SpriteWeapons[3] = m_GameSkin.m_SpriteWeaponGrenade;
m_GameSkin.m_SpriteWeapons[4] = m_GameSkin.m_SpriteWeaponLaser;
m_GameSkin.m_SpriteWeapons[5] = m_GameSkin.m_SpriteWeaponNinja;
// particles
for(int i = 0; i < 9; ++i)
{
m_GameSkin.m_SpriteParticles[i] = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PART1 + i]);
}
// stars
for(int i = 0; i < 3; ++i)
{
m_GameSkin.m_SpriteStars[i] = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_STAR1 + i]);
}
// projectiles
m_GameSkin.m_SpriteWeaponGunProjectile = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_GUN_PROJ]);
m_GameSkin.m_SpriteWeaponShotgunProjectile = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_SHOTGUN_PROJ]);
m_GameSkin.m_SpriteWeaponGrenadeProjectile = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_GRENADE_PROJ]);
// these weapons have no projectiles
m_GameSkin.m_SpriteWeaponHammerProjectile = IGraphics::CTextureHandle();
m_GameSkin.m_SpriteWeaponNinjaProjectile = IGraphics::CTextureHandle();
m_GameSkin.m_SpriteWeaponLaserProjectile = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_LASER_PROJ]);
m_GameSkin.m_SpriteWeaponProjectiles[0] = m_GameSkin.m_SpriteWeaponHammerProjectile;
m_GameSkin.m_SpriteWeaponProjectiles[1] = m_GameSkin.m_SpriteWeaponGunProjectile;
m_GameSkin.m_SpriteWeaponProjectiles[2] = m_GameSkin.m_SpriteWeaponShotgunProjectile;
m_GameSkin.m_SpriteWeaponProjectiles[3] = m_GameSkin.m_SpriteWeaponGrenadeProjectile;
m_GameSkin.m_SpriteWeaponProjectiles[4] = m_GameSkin.m_SpriteWeaponLaserProjectile;
m_GameSkin.m_SpriteWeaponProjectiles[5] = m_GameSkin.m_SpriteWeaponNinjaProjectile;
// muzzles
for(int i = 0; i < 3; ++i)
{
m_GameSkin.m_SpriteWeaponGunMuzzles[i] = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_GUN_MUZZLE1 + i]);
m_GameSkin.m_SpriteWeaponShotgunMuzzles[i] = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_SHOTGUN_MUZZLE1 + i]);
m_GameSkin.m_SpriteWeaponNinjaMuzzles[i] = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_NINJA_MUZZLE1 + i]);
m_GameSkin.m_SpriteWeaponsMuzzles[1][i] = m_GameSkin.m_SpriteWeaponGunMuzzles[i];
m_GameSkin.m_SpriteWeaponsMuzzles[2][i] = m_GameSkin.m_SpriteWeaponShotgunMuzzles[i];
m_GameSkin.m_SpriteWeaponsMuzzles[5][i] = m_GameSkin.m_SpriteWeaponNinjaMuzzles[i];
}
// pickups
m_GameSkin.m_SpritePickupHealth = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PICKUP_HEALTH]);
m_GameSkin.m_SpritePickupArmor = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PICKUP_ARMOR]);
m_GameSkin.m_SpritePickupGrenade = Graphics()->LoadSpriteTexture(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_PICKUP_GRENADE]);
m_GameSkin.m_SpritePickupShotgun = Graphics()->LoadSpriteTexture(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_PICKUP_SHOTGUN]);
m_GameSkin.m_SpritePickupLaser = Graphics()->LoadSpriteTexture(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_PICKUP_LASER]);
m_GameSkin.m_SpritePickupNinja = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PICKUP_NINJA]);
m_GameSkin.m_SpritePickupGun = Graphics()->LoadSpriteTexture(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_PICKUP_GUN]);
m_GameSkin.m_SpritePickupHammer = Graphics()->LoadSpriteTexture(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_PICKUP_HAMMER]);
m_GameSkin.m_SpritePickupWeapons[0] = m_GameSkin.m_SpritePickupHammer;
m_GameSkin.m_SpritePickupWeapons[1] = m_GameSkin.m_SpritePickupGun;
m_GameSkin.m_SpritePickupWeapons[2] = m_GameSkin.m_SpritePickupShotgun;
m_GameSkin.m_SpritePickupWeapons[3] = m_GameSkin.m_SpritePickupGrenade;
m_GameSkin.m_SpritePickupWeapons[4] = m_GameSkin.m_SpritePickupLaser;
m_GameSkin.m_SpritePickupWeapons[5] = m_GameSkin.m_SpritePickupNinja;
// flags
m_GameSkin.m_SpriteFlagBlue = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_FLAG_BLUE]);
m_GameSkin.m_SpriteFlagRed = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_FLAG_RED]);
// ninja bar (0.7)
if(!Graphics()->IsSpriteTextureFullyTransparent(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_NINJA_BAR_FULL_LEFT]) ||
!Graphics()->IsSpriteTextureFullyTransparent(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_NINJA_BAR_FULL]) ||
!Graphics()->IsSpriteTextureFullyTransparent(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_NINJA_BAR_EMPTY]) ||
!Graphics()->IsSpriteTextureFullyTransparent(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_NINJA_BAR_EMPTY_RIGHT]))
{
m_GameSkin.m_SpriteNinjaBarFullLeft = Graphics()->LoadSpriteTexture(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_NINJA_BAR_FULL_LEFT]);
m_GameSkin.m_SpriteNinjaBarFull = Graphics()->LoadSpriteTexture(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_NINJA_BAR_FULL]);
m_GameSkin.m_SpriteNinjaBarEmpty = Graphics()->LoadSpriteTexture(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_NINJA_BAR_EMPTY]);
m_GameSkin.m_SpriteNinjaBarEmptyRight = Graphics()->LoadSpriteTexture(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_NINJA_BAR_EMPTY_RIGHT]);
}
m_GameSkinLoaded = true;
free(ImgInfo.m_pData); free(ImgInfo.m_pData);
} }
} }
void CGameClient::LoadEmoticonsSkin(const char *pPath, bool AsDir) void CGameClient::LoadEmoticonsSkin(const char *pPath, bool AsDir)
{ {
if(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id != -1) if(m_EmoticonsSkinLoaded)
{ {
Graphics()->UnloadTexture(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id); for(int i = 0; i < 16; ++i)
g_pData->m_aImages[IMAGE_EMOTICONS].m_Id = IGraphics::CTextureHandle(); Graphics()->UnloadTextureNew(m_EmoticonsSkin.m_SpriteEmoticons[i]);
m_EmoticonsSkinLoaded = false;
} }
char aPath[MAX_PATH_LENGTH]; char aPath[MAX_PATH_LENGTH];
@ -2585,17 +2796,32 @@ void CGameClient::LoadEmoticonsSkin(const char *pPath, bool AsDir)
} }
else if(PngLoaded) else if(PngLoaded)
{ {
g_pData->m_aImages[IMAGE_EMOTICONS].m_Id = Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, ImgInfo.m_Format, 0, aPath); for(int i = 0; i < 16; ++i)
m_EmoticonsSkin.m_SpriteEmoticons[i] = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_OOP + i]);
m_EmoticonsSkinLoaded = true;
free(ImgInfo.m_pData); free(ImgInfo.m_pData);
} }
} }
void CGameClient::LoadParticlesSkin(const char *pPath, bool AsDir) void CGameClient::LoadParticlesSkin(const char *pPath, bool AsDir)
{ {
if(g_pData->m_aImages[IMAGE_PARTICLES].m_Id != -1) if(m_ParticlesSkinLoaded)
{ {
Graphics()->UnloadTexture(g_pData->m_aImages[IMAGE_PARTICLES].m_Id); Graphics()->UnloadTextureNew(m_ParticlesSkin.m_SpriteParticleSlice);
g_pData->m_aImages[IMAGE_PARTICLES].m_Id = IGraphics::CTextureHandle(); Graphics()->UnloadTextureNew(m_ParticlesSkin.m_SpriteParticleBall);
for(int i = 0; i < 3; ++i)
Graphics()->UnloadTextureNew(m_ParticlesSkin.m_SpriteParticleSplat[i]);
Graphics()->UnloadTextureNew(m_ParticlesSkin.m_SpriteParticleSmoke);
Graphics()->UnloadTextureNew(m_ParticlesSkin.m_SpriteParticleShell);
Graphics()->UnloadTextureNew(m_ParticlesSkin.m_SpriteParticleExpl);
Graphics()->UnloadTextureNew(m_ParticlesSkin.m_SpriteParticleAirJump);
Graphics()->UnloadTextureNew(m_ParticlesSkin.m_SpriteParticleHit);
for(int i = 0; i < (int)(sizeof(m_ParticlesSkin.m_SpriteParticles) / sizeof(m_ParticlesSkin.m_SpriteParticles[0])); ++i)
m_ParticlesSkin.m_SpriteParticles[i] = IGraphics::CTextureHandle();
m_ParticlesSkinLoaded = false;
} }
char aPath[MAX_PATH_LENGTH]; char aPath[MAX_PATH_LENGTH];
@ -2624,11 +2850,45 @@ void CGameClient::LoadParticlesSkin(const char *pPath, bool AsDir)
} }
else if(PngLoaded) else if(PngLoaded)
{ {
g_pData->m_aImages[IMAGE_PARTICLES].m_Id = Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, ImgInfo.m_Format, 0, aPath); m_ParticlesSkin.m_SpriteParticleSlice = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PART_SLICE]);
m_ParticlesSkin.m_SpriteParticleBall = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PART_BALL]);
for(int i = 0; i < 3; ++i)
m_ParticlesSkin.m_SpriteParticleSplat[i] = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PART_SPLAT01 + i]);
m_ParticlesSkin.m_SpriteParticleSmoke = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PART_SMOKE]);
m_ParticlesSkin.m_SpriteParticleShell = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PART_SHELL]);
m_ParticlesSkin.m_SpriteParticleExpl = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PART_EXPL01]);
m_ParticlesSkin.m_SpriteParticleAirJump = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PART_AIRJUMP]);
m_ParticlesSkin.m_SpriteParticleHit = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PART_HIT01]);
m_ParticlesSkin.m_SpriteParticles[0] = m_ParticlesSkin.m_SpriteParticleSlice;
m_ParticlesSkin.m_SpriteParticles[1] = m_ParticlesSkin.m_SpriteParticleBall;
for(int i = 0; i < 3; ++i)
m_ParticlesSkin.m_SpriteParticles[2 + i] = m_ParticlesSkin.m_SpriteParticleSplat[i];
m_ParticlesSkin.m_SpriteParticles[5] = m_ParticlesSkin.m_SpriteParticleSmoke;
m_ParticlesSkin.m_SpriteParticles[6] = m_ParticlesSkin.m_SpriteParticleShell;
m_ParticlesSkin.m_SpriteParticles[7] = m_ParticlesSkin.m_SpriteParticleExpl;
m_ParticlesSkin.m_SpriteParticles[8] = m_ParticlesSkin.m_SpriteParticleAirJump;
m_ParticlesSkin.m_SpriteParticles[9] = m_ParticlesSkin.m_SpriteParticleHit;
m_ParticlesSkinLoaded = true;
free(ImgInfo.m_pData); free(ImgInfo.m_pData);
} }
} }
void CGameClient::RefindSkins()
{
for(int i = 0; i < MAX_CLIENTS; ++i)
{
if(m_aClients[i].m_aSkinName[0] != '\0')
{
const CSkin *pSkin = m_pSkins->Get(m_pSkins->Find(m_aClients[i].m_aSkinName));
m_aClients[i].m_SkinInfo.m_OriginalRenderSkin = pSkin->m_OriginalSkin;
m_aClients[i].m_SkinInfo.m_ColorableRenderSkin = pSkin->m_ColorableSkin;
}
}
m_pGhost->RefindSkin();
}
void CGameClient::LoadMapSettings() void CGameClient::LoadMapSettings()
{ {
// Reset Tunezones // Reset Tunezones

View file

@ -247,7 +247,6 @@ public:
char m_aClan[MAX_CLAN_LENGTH]; char m_aClan[MAX_CLAN_LENGTH];
int m_Country; int m_Country;
char m_aSkinName[64]; char m_aSkinName[64];
int m_SkinID;
int m_SkinColor; int m_SkinColor;
int m_Team; int m_Team;
int m_Emoticon; int m_Emoticon;
@ -456,6 +455,116 @@ public:
void LoadEmoticonsSkin(const char *pPath, bool AsDir = false); void LoadEmoticonsSkin(const char *pPath, bool AsDir = false);
void LoadParticlesSkin(const char *pPath, bool AsDir = false); void LoadParticlesSkin(const char *pPath, bool AsDir = false);
void RefindSkins();
struct SClientGameSkin
{
// health armor hud
IGraphics::CTextureHandle m_SpriteHealthFull;
IGraphics::CTextureHandle m_SpriteHealthEmpty;
IGraphics::CTextureHandle m_SpriteArmorFull;
IGraphics::CTextureHandle m_SpriteArmorEmpty;
// cursors
IGraphics::CTextureHandle m_SpriteWeaponHammerCursor;
IGraphics::CTextureHandle m_SpriteWeaponGunCursor;
IGraphics::CTextureHandle m_SpriteWeaponShotgunCursor;
IGraphics::CTextureHandle m_SpriteWeaponGrenadeCursor;
IGraphics::CTextureHandle m_SpriteWeaponNinjaCursor;
IGraphics::CTextureHandle m_SpriteWeaponLaserCursor;
IGraphics::CTextureHandle m_SpriteWeaponCursors[6];
// weapons and hook
IGraphics::CTextureHandle m_SpriteHookChain;
IGraphics::CTextureHandle m_SpriteHookHead;
IGraphics::CTextureHandle m_SpriteWeaponHammer;
IGraphics::CTextureHandle m_SpriteWeaponGun;
IGraphics::CTextureHandle m_SpriteWeaponShotgun;
IGraphics::CTextureHandle m_SpriteWeaponGrenade;
IGraphics::CTextureHandle m_SpriteWeaponNinja;
IGraphics::CTextureHandle m_SpriteWeaponLaser;
IGraphics::CTextureHandle m_SpriteWeapons[6];
// particles
IGraphics::CTextureHandle m_SpriteParticles[9];
// stars
IGraphics::CTextureHandle m_SpriteStars[3];
// projectiles
IGraphics::CTextureHandle m_SpriteWeaponGunProjectile;
IGraphics::CTextureHandle m_SpriteWeaponShotgunProjectile;
IGraphics::CTextureHandle m_SpriteWeaponGrenadeProjectile;
IGraphics::CTextureHandle m_SpriteWeaponHammerProjectile;
IGraphics::CTextureHandle m_SpriteWeaponNinjaProjectile;
IGraphics::CTextureHandle m_SpriteWeaponLaserProjectile;
IGraphics::CTextureHandle m_SpriteWeaponProjectiles[6];
// muzzles
IGraphics::CTextureHandle m_SpriteWeaponGunMuzzles[3];
IGraphics::CTextureHandle m_SpriteWeaponShotgunMuzzles[3];
IGraphics::CTextureHandle m_SpriteWeaponNinjaMuzzles[3];
IGraphics::CTextureHandle m_SpriteWeaponsMuzzles[6][3];
// pickups
IGraphics::CTextureHandle m_SpritePickupHealth;
IGraphics::CTextureHandle m_SpritePickupArmor;
IGraphics::CTextureHandle m_SpritePickupGrenade;
IGraphics::CTextureHandle m_SpritePickupShotgun;
IGraphics::CTextureHandle m_SpritePickupLaser;
IGraphics::CTextureHandle m_SpritePickupNinja;
IGraphics::CTextureHandle m_SpritePickupGun;
IGraphics::CTextureHandle m_SpritePickupHammer;
IGraphics::CTextureHandle m_SpritePickupWeapons[6];
// flags
IGraphics::CTextureHandle m_SpriteFlagBlue;
IGraphics::CTextureHandle m_SpriteFlagRed;
// ninja bar (0.7)
IGraphics::CTextureHandle m_SpriteNinjaBarFullLeft;
IGraphics::CTextureHandle m_SpriteNinjaBarFull;
IGraphics::CTextureHandle m_SpriteNinjaBarEmpty;
IGraphics::CTextureHandle m_SpriteNinjaBarEmptyRight;
bool IsSixup()
{
return m_SpriteNinjaBarFullLeft != -1;
}
};
SClientGameSkin m_GameSkin;
bool m_GameSkinLoaded;
struct SClientParticlesSkin
{
IGraphics::CTextureHandle m_SpriteParticleSlice;
IGraphics::CTextureHandle m_SpriteParticleBall;
IGraphics::CTextureHandle m_SpriteParticleSplat[3];
IGraphics::CTextureHandle m_SpriteParticleSmoke;
IGraphics::CTextureHandle m_SpriteParticleShell;
IGraphics::CTextureHandle m_SpriteParticleExpl;
IGraphics::CTextureHandle m_SpriteParticleAirJump;
IGraphics::CTextureHandle m_SpriteParticleHit;
IGraphics::CTextureHandle m_SpriteParticles[10];
};
SClientParticlesSkin m_ParticlesSkin;
bool m_ParticlesSkinLoaded;
struct SClientEmoticonsSkin
{
IGraphics::CTextureHandle m_SpriteEmoticons[16];
};
SClientEmoticonsSkin m_EmoticonsSkin;
bool m_EmoticonsSkinLoaded;
private: private:
bool m_DDRaceMsgSent[2]; bool m_DDRaceMsgSent[2];
int m_ShowOthers[2]; int m_ShowOthers[2];

View file

@ -9,7 +9,10 @@
#include <engine/graphics.h> #include <engine/graphics.h>
#include <engine/map.h> #include <engine/map.h>
#include <engine/shared/config.h> #include <engine/shared/config.h>
#include <game/client/components/skins.h>
#include <game/client/gameclient.h>
#include <game/generated/client_data.h> #include <game/generated/client_data.h>
#include <game/generated/client_data7.h>
#include <game/generated/protocol.h> #include <game/generated/protocol.h>
#include <game/layers.h> #include <game/layers.h>
@ -36,32 +39,33 @@ static void layershot_end()
config.cl_layershot++; config.cl_layershot++;
}*/ }*/
void CRenderTools::Init(IGraphics *pGraphics, CUI *pUI) void CRenderTools::Init(IGraphics *pGraphics, CUI *pUI, CGameClient *pGameClient)
{ {
m_pGraphics = pGraphics; m_pGraphics = pGraphics;
m_pUI = pUI; m_pUI = pUI;
m_pGameClient = (CGameClient *)pGameClient;
m_TeeQuadContainerIndex = Graphics()->CreateQuadContainer(); m_TeeQuadContainerIndex = Graphics()->CreateQuadContainer();
Graphics()->SetColor(1.f, 1.f, 1.f, 1.f); Graphics()->SetColor(1.f, 1.f, 1.f, 1.f);
SelectSprite(SPRITE_TEE_BODY, 0, 0, 0); Graphics()->QuadsSetSubset(0, 0, 1, 1);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f, false); QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f);
SelectSprite(SPRITE_TEE_BODY_OUTLINE, 0, 0, 0); Graphics()->QuadsSetSubset(0, 0, 1, 1);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f, false); QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f);
SelectSprite(SPRITE_TEE_EYE_PAIN, 0, 0, 0); Graphics()->QuadsSetSubset(0, 0, 1, 1);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f * 0.4f, false); QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f * 0.4f);
SelectSprite(SPRITE_TEE_EYE_HAPPY, 0, 0, 0); Graphics()->QuadsSetSubset(0, 0, 1, 1);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f * 0.4f, false); QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f * 0.4f);
SelectSprite(SPRITE_TEE_EYE_SURPRISE, 0, 0, 0); Graphics()->QuadsSetSubset(0, 0, 1, 1);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f * 0.4f, false); QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f * 0.4f);
SelectSprite(SPRITE_TEE_EYE_ANGRY, 0, 0, 0); Graphics()->QuadsSetSubset(0, 0, 1, 1);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f * 0.4f, false); QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f * 0.4f);
SelectSprite(SPRITE_TEE_EYE_NORMAL, 0, 0, 0); Graphics()->QuadsSetSubset(0, 0, 1, 1);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f * 0.4f, false); QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f * 0.4f);
SelectSprite(SPRITE_TEE_FOOT_OUTLINE, 0, 0, 0); Graphics()->QuadsSetSubset(0, 0, 1, 1);
QuadContainerAddSprite(m_TeeQuadContainerIndex, -32.f, -16.f, 64.f, 32.f); QuadContainerAddSprite(m_TeeQuadContainerIndex, -32.f, -16.f, 64.f, 32.f);
SelectSprite(SPRITE_TEE_FOOT, 0, 0, 0); Graphics()->QuadsSetSubset(0, 0, 1, 1);
QuadContainerAddSprite(m_TeeQuadContainerIndex, -32.f, -16.f, 64.f, 32.f); QuadContainerAddSprite(m_TeeQuadContainerIndex, -32.f, -16.f, 64.f, 32.f);
} }
@ -108,38 +112,57 @@ void CRenderTools::SelectSprite(int Id, int Flags, int sx, int sy)
SelectSprite(&g_pData->m_aSprites[Id], Flags, sx, sy); SelectSprite(&g_pData->m_aSprites[Id], Flags, sx, sy);
} }
void CRenderTools::GetSpriteScale(client_data7::CDataSprite *pSprite, float &ScaleX, float &ScaleY)
{
int w = pSprite->m_W;
int h = pSprite->m_H;
float f = sqrtf(h * h + w * w);
ScaleX = w / f;
ScaleY = h / f;
}
void CRenderTools::GetSpriteScale(struct CDataSprite *pSprite, float &ScaleX, float &ScaleY)
{
int w = pSprite->m_W;
int h = pSprite->m_H;
float f = sqrtf(h * h + w * w);
ScaleX = w / f;
ScaleY = h / f;
}
void CRenderTools::GetSpriteScale(int id, float &ScaleX, float &ScaleY)
{
GetSpriteScale(&g_pData->m_aSprites[id], ScaleX, ScaleY);
}
void CRenderTools::DrawSprite(float x, float y, float Size) void CRenderTools::DrawSprite(float x, float y, float Size)
{ {
IGraphics::CQuadItem QuadItem(x, y, Size * gs_SpriteWScale, Size * gs_SpriteHScale); IGraphics::CQuadItem QuadItem(x, y, Size * gs_SpriteWScale, Size * gs_SpriteHScale);
Graphics()->QuadsDraw(&QuadItem, 1); Graphics()->QuadsDraw(&QuadItem, 1);
} }
void CRenderTools::QuadContainerAddSprite(int QuadContainerIndex, float x, float y, float Size, bool DoSpriteScale) void CRenderTools::DrawSprite(float x, float y, float ScaledWidth, float ScaledHeight)
{ {
if(DoSpriteScale) IGraphics::CQuadItem QuadItem(x, y, ScaledWidth, ScaledHeight);
{ Graphics()->QuadsDraw(&QuadItem, 1);
IGraphics::CQuadItem QuadItem(x, y, Size * gs_SpriteWScale, Size * gs_SpriteHScale);
Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1);
}
else
{
IGraphics::CQuadItem QuadItem(x, y, Size, Size);
Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1);
}
} }
void CRenderTools::QuadContainerAddSprite(int QuadContainerIndex, float Size, bool DoSpriteScale) void CRenderTools::QuadContainerAddSprite(int QuadContainerIndex, float x, float y, float Size)
{ {
if(DoSpriteScale) IGraphics::CQuadItem QuadItem(x, y, Size, Size);
{ Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1);
IGraphics::CQuadItem QuadItem(-(Size * gs_SpriteWScale) / 2.f, -(Size * gs_SpriteHScale) / 2.f, (Size * gs_SpriteWScale), (Size * gs_SpriteHScale)); }
Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1);
} void CRenderTools::QuadContainerAddSprite(int QuadContainerIndex, float Size)
else {
{ IGraphics::CQuadItem QuadItem(-(Size) / 2.f, -(Size) / 2.f, (Size), (Size));
IGraphics::CQuadItem QuadItem(-(Size) / 2.f, -(Size) / 2.f, (Size), (Size)); Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1);
Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1); }
}
void CRenderTools::QuadContainerAddSprite(int QuadContainerIndex, float Width, float Height)
{
IGraphics::CQuadItem QuadItem(-(Width) / 2.f, -(Height) / 2.f, (Width), (Height));
Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1);
} }
void CRenderTools::QuadContainerAddSprite(int QuadContainerIndex, float X, float Y, float Width, float Height) void CRenderTools::QuadContainerAddSprite(int QuadContainerIndex, float X, float Y, float Width, float Height)
@ -494,8 +517,7 @@ void CRenderTools::RenderTee(CAnimState *pAnim, CTeeRenderInfo *pInfo, int Emote
vec2 Direction = Dir; vec2 Direction = Dir;
vec2 Position = Pos; vec2 Position = Pos;
//Graphics()->TextureSet(data->images[IMAGE_CHAR_DEFAULT].id); const CSkin::SSkinTextures *pSkinTextures = pInfo->m_CustomColoredSkin ? &pInfo->m_ColorableRenderSkin : &pInfo->m_OriginalRenderSkin;
Graphics()->TextureSet(pInfo->m_Texture);
// first pass we draw the outline // first pass we draw the outline
// second pass we draw the filling // second pass we draw the filling
@ -515,6 +537,7 @@ void CRenderTools::RenderTee(CAnimState *pAnim, CTeeRenderInfo *pInfo, int Emote
Graphics()->SetColor(pInfo->m_ColorBody.r, pInfo->m_ColorBody.g, pInfo->m_ColorBody.b, Alpha); Graphics()->SetColor(pInfo->m_ColorBody.r, pInfo->m_ColorBody.g, pInfo->m_ColorBody.b, Alpha);
vec2 BodyPos = Position + vec2(pAnim->GetBody()->m_X, pAnim->GetBody()->m_Y) * AnimScale; vec2 BodyPos = Position + vec2(pAnim->GetBody()->m_X, pAnim->GetBody()->m_Y) * AnimScale;
float BodySize = g_Config.m_ClFatSkins ? BaseSize * 1.3f : BaseSize; float BodySize = g_Config.m_ClFatSkins ? BaseSize * 1.3f : BaseSize;
Graphics()->TextureSet(OutLine == 1 ? pSkinTextures->m_BodyOutline : pSkinTextures->m_Body);
Graphics()->RenderQuadContainerAsSprite(m_TeeQuadContainerIndex, OutLine, BodyPos.x, BodyPos.y, BodySize / 64.f, BodySize / 64.f); Graphics()->RenderQuadContainerAsSprite(m_TeeQuadContainerIndex, OutLine, BodyPos.x, BodyPos.y, BodySize / 64.f, BodySize / 64.f);
// draw eyes // draw eyes
@ -522,19 +545,24 @@ void CRenderTools::RenderTee(CAnimState *pAnim, CTeeRenderInfo *pInfo, int Emote
{ {
int QuadOffset = 2; int QuadOffset = 2;
int EyeQuadOffset = 0; int EyeQuadOffset = 0;
int TeeEye = 0;
switch(Emote) switch(Emote)
{ {
case EMOTE_PAIN: case EMOTE_PAIN:
EyeQuadOffset = 0; EyeQuadOffset = 0;
TeeEye = SPRITE_TEE_EYE_PAIN - SPRITE_TEE_EYE_NORMAL;
break; break;
case EMOTE_HAPPY: case EMOTE_HAPPY:
EyeQuadOffset = 1; EyeQuadOffset = 1;
TeeEye = SPRITE_TEE_EYE_HAPPY - SPRITE_TEE_EYE_NORMAL;
break; break;
case EMOTE_SURPRISE: case EMOTE_SURPRISE:
EyeQuadOffset = 2; EyeQuadOffset = 2;
TeeEye = SPRITE_TEE_EYE_SURPRISE - SPRITE_TEE_EYE_NORMAL;
break; break;
case EMOTE_ANGRY: case EMOTE_ANGRY:
EyeQuadOffset = 3; EyeQuadOffset = 3;
TeeEye = SPRITE_TEE_EYE_ANGRY - SPRITE_TEE_EYE_NORMAL;
break; break;
default: default:
EyeQuadOffset = 4; EyeQuadOffset = 4;
@ -546,6 +574,7 @@ void CRenderTools::RenderTee(CAnimState *pAnim, CTeeRenderInfo *pInfo, int Emote
float EyeSeparation = (0.075f - 0.010f * absolute(Direction.x)) * BaseSize; float EyeSeparation = (0.075f - 0.010f * absolute(Direction.x)) * BaseSize;
vec2 Offset = vec2(Direction.x * 0.125f, -0.05f + Direction.y * 0.10f) * BaseSize; vec2 Offset = vec2(Direction.x * 0.125f, -0.05f + Direction.y * 0.10f) * BaseSize;
Graphics()->TextureSet(pSkinTextures->m_Eyes[TeeEye]);
Graphics()->RenderQuadContainerAsSprite(m_TeeQuadContainerIndex, QuadOffset + EyeQuadOffset, BodyPos.x - EyeSeparation + Offset.x, BodyPos.y + Offset.y, EyeScale / (64.f * 0.4f), h / (64.f * 0.4f)); Graphics()->RenderQuadContainerAsSprite(m_TeeQuadContainerIndex, QuadOffset + EyeQuadOffset, BodyPos.x - EyeSeparation + Offset.x, BodyPos.y + Offset.y, EyeScale / (64.f * 0.4f), h / (64.f * 0.4f));
Graphics()->RenderQuadContainerAsSprite(m_TeeQuadContainerIndex, QuadOffset + EyeQuadOffset, BodyPos.x + EyeSeparation + Offset.x, BodyPos.y + Offset.y, -EyeScale / (64.f * 0.4f), h / (64.f * 0.4f)); Graphics()->RenderQuadContainerAsSprite(m_TeeQuadContainerIndex, QuadOffset + EyeQuadOffset, BodyPos.x + EyeSeparation + Offset.x, BodyPos.y + Offset.y, -EyeScale / (64.f * 0.4f), h / (64.f * 0.4f));
} }
@ -573,6 +602,7 @@ void CRenderTools::RenderTee(CAnimState *pAnim, CTeeRenderInfo *pInfo, int Emote
Graphics()->SetColor(pInfo->m_ColorFeet.r * cs, pInfo->m_ColorFeet.g * cs, pInfo->m_ColorFeet.b * cs, Alpha); Graphics()->SetColor(pInfo->m_ColorFeet.r * cs, pInfo->m_ColorFeet.g * cs, pInfo->m_ColorFeet.b * cs, Alpha);
Graphics()->TextureSet(OutLine == 1 ? pSkinTextures->m_FeetOutline : pSkinTextures->m_Feet);
Graphics()->RenderQuadContainerAsSprite(m_TeeQuadContainerIndex, QuadOffset, Position.x + pFoot->m_X * AnimScale, Position.y + pFoot->m_Y * AnimScale, w / 64.f, h / 32.f); Graphics()->RenderQuadContainerAsSprite(m_TeeQuadContainerIndex, QuadOffset, Position.x + pFoot->m_X * AnimScale, Position.y + pFoot->m_Y * AnimScale, w / 64.f, h / 32.f);
} }
} }

View file

@ -7,6 +7,7 @@
#include <base/color.h> #include <base/color.h>
#include <base/vmath.h> #include <base/vmath.h>
#include <engine/graphics.h> #include <engine/graphics.h>
#include <game/client/skin.h>
#include <game/mapitems.h> #include <game/mapitems.h>
class CTeeRenderInfo class CTeeRenderInfo
@ -20,7 +21,11 @@ public:
m_GotAirJump = 1; m_GotAirJump = 1;
}; };
IGraphics::CTextureHandle m_Texture; CSkin::SSkinTextures m_OriginalRenderSkin;
CSkin::SSkinTextures m_ColorableRenderSkin;
bool m_CustomColoredSkin;
ColorRGBA m_BloodColor;
ColorRGBA m_ColorBody; ColorRGBA m_ColorBody;
ColorRGBA m_ColorFeet; ColorRGBA m_ColorFeet;
float m_Size; float m_Size;
@ -48,20 +53,28 @@ class CRenderTools
public: public:
class IGraphics *m_pGraphics; class IGraphics *m_pGraphics;
class CUI *m_pUI; class CUI *m_pUI;
class CGameClient *m_pGameClient;
class IGraphics *Graphics() const { return m_pGraphics; } class IGraphics *Graphics() const { return m_pGraphics; }
class CUI *UI() const { return m_pUI; } class CUI *UI() const { return m_pUI; }
class CGameClient *GameClient() const { return m_pGameClient; }
void Init(class IGraphics *pGraphics, class CUI *pUI); void Init(class IGraphics *pGraphics, class CUI *pUI, class CGameClient *pGameClient);
//typedef struct SPRITE; //typedef struct SPRITE;
void SelectSprite(struct CDataSprite *pSprite, int Flags = 0, int sx = 0, int sy = 0); void SelectSprite(struct CDataSprite *pSprite, int Flags = 0, int sx = 0, int sy = 0);
void SelectSprite(int id, int Flags = 0, int sx = 0, int sy = 0); void SelectSprite(int id, int Flags = 0, int sx = 0, int sy = 0);
void GetSpriteScale(client_data7::CDataSprite *pSprite, float &ScaleX, float &ScaleY);
void GetSpriteScale(struct CDataSprite *pSprite, float &ScaleX, float &ScaleY);
void GetSpriteScale(int id, float &ScaleX, float &ScaleY);
void DrawSprite(float x, float y, float size); void DrawSprite(float x, float y, float size);
void QuadContainerAddSprite(int QuadContainerIndex, float x, float y, float size, bool DoSpriteScale = true); void DrawSprite(float x, float y, float ScaledWidth, float ScaledHeight);
void QuadContainerAddSprite(int QuadContainerIndex, float size, bool DoSpriteScale = true); void QuadContainerAddSprite(int QuadContainerIndex, float x, float y, float size);
void QuadContainerAddSprite(int QuadContainerIndex, float size);
void QuadContainerAddSprite(int QuadContainerIndex, float Width, float Height);
void QuadContainerAddSprite(int QuadContainerIndex, float X, float Y, float Width, float Height); void QuadContainerAddSprite(int QuadContainerIndex, float X, float Y, float Width, float Height);
// rects // rects

51
src/game/client/skin.h Normal file
View file

@ -0,0 +1,51 @@
#ifndef GAME_CLIENT_SKIN_H
#define GAME_CLIENT_SKIN_H
#include <base/color.h>
#include <base/tl/sorted_array.h>
#include <base/vmath.h>
#include <engine/graphics.h>
// do this better and nicer
struct CSkin
{
bool m_IsVanilla;
struct SSkinTextures
{
IGraphics::CTextureHandle m_Body;
IGraphics::CTextureHandle m_BodyOutline;
IGraphics::CTextureHandle m_Feet;
IGraphics::CTextureHandle m_FeetOutline;
IGraphics::CTextureHandle m_Hands;
IGraphics::CTextureHandle m_HandsOutline;
IGraphics::CTextureHandle m_Eyes[6];
void Reset()
{
m_Body = IGraphics::CTextureHandle();
m_BodyOutline = IGraphics::CTextureHandle();
m_Feet = IGraphics::CTextureHandle();
m_FeetOutline = IGraphics::CTextureHandle();
m_Hands = IGraphics::CTextureHandle();
m_HandsOutline = IGraphics::CTextureHandle();
for(int i = 0; i < 6; ++i)
m_Eyes[i] = IGraphics::CTextureHandle();
}
};
SSkinTextures m_OriginalSkin;
SSkinTextures m_ColorableSkin;
char m_aName[24];
ColorRGBA m_BloodColor;
bool operator<(const CSkin &Other) const { return str_comp(m_aName, Other.m_aName) < 0; }
bool operator<(const char *pOther) const { return str_comp(m_aName, pOther) < 0; }
bool operator==(const char *pOther) const { return !str_comp(m_aName, pOther); }
};
#endif

View file

@ -6417,7 +6417,8 @@ void CEditor::Init()
m_pTextRender = Kernel()->RequestInterface<ITextRender>(); m_pTextRender = Kernel()->RequestInterface<ITextRender>();
m_pStorage = Kernel()->RequestInterface<IStorage>(); m_pStorage = Kernel()->RequestInterface<IStorage>();
m_pSound = Kernel()->RequestInterface<ISound>(); m_pSound = Kernel()->RequestInterface<ISound>();
m_RenderTools.Init(m_pGraphics, &m_UI); CGameClient *pGameClient = (CGameClient *)Kernel()->RequestInterface<IGameClient>();
m_RenderTools.Init(m_pGraphics, &m_UI, pGameClient);
m_UI.SetGraphics(m_pGraphics, m_pTextRender); m_UI.SetGraphics(m_pGraphics, m_pTextRender);
m_Map.m_pEditor = this; m_Map.m_pEditor = this;