Skip to content

Commit

Permalink
update R_StudioGetSkin
Browse files Browse the repository at this point in the history
  • Loading branch information
hzqst committed Dec 23, 2023
1 parent 01020da commit e11439d
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 42 deletions.
3 changes: 2 additions & 1 deletion Plugins/Renderer/gl_hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4559,6 +4559,7 @@ void R_FillAddress(void)
Sig_FuncNotFound(GL_UnloadTexture);
}

#if 0//unused
if (1)
{
typedef struct
Expand Down Expand Up @@ -4635,7 +4636,7 @@ void R_FillAddress(void)
Sig_VarNotFound(DM_RemapSkin);
Sig_VarNotFound(r_remapindex);
}

#endif
if (1)
{
typedef struct
Expand Down
1 change: 1 addition & 0 deletions Plugins/Renderer/gl_rmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2313,6 +2313,7 @@ void R_NewMap(void)
R_NewMapWSurf();
R_NewMapLight();

R_StudioFlushAllSkins();
R_StudioReloadVBOCache();

//This is for GoldSrc
Expand Down
151 changes: 111 additions & 40 deletions Plugins/Renderer/gl_studio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
#include <sstream>
#include <algorithm>

std::unordered_map<studio_bone_handle, studio_bone_cache*, studio_bone_hasher> g_StudioBoneCacheManager;

std::unordered_map<program_state_t, studio_program_t> g_StudioProgramTable;

std::vector<studio_vbo_t*> g_StudioVBOCache;

std::unordered_map<int, studio_vbo_material_t*> g_StudioVBOMaterialCache;

#define MAX_STUDIO_BONE_CACHES 1024
std::unordered_map<int, studio_skin_cache_t *> g_StudioSkinCache;

std::unordered_map<studio_bone_handle, studio_bone_cache*, studio_bone_hasher> g_StudioBoneCacheManager;

std::unordered_map<program_state_t, studio_program_t> g_StudioProgramTable;

static studio_bone_cache g_StudioBoneCaches[MAX_STUDIO_BONE_CACHES];

Expand Down Expand Up @@ -59,10 +59,13 @@ dlight_t* (*locallight)[3] = NULL;
int* numlight = NULL;
int* r_topcolor = NULL;
int* r_bottomcolor = NULL;

#if 0//unused
player_model_t(*DM_PlayerState)[MAX_CLIENTS] = NULL;
skin_t (*DM_RemapSkin)[64][MAX_SKINS] = NULL;
skin_t* (*pDM_RemapSkin)[2528][MAX_SKINS] = NULL;
int* r_remapindex = NULL;
#endif

//Stats

Expand Down Expand Up @@ -1174,9 +1177,47 @@ bool R_IsRemapSkin(const char* texture, int* low, int* mid, int* high)
return false;
}

skin_t* R_StudioGetSkin(int keynum, int index)
void R_StudioFlushAllSkins()
{
for(auto &itor : g_StudioSkinCache)
{
delete itor.second;
}

g_StudioSkinCache.clear();
}

void R_StudioFlushSkins(int keynum)
{
#if 0
for (int index = 0; index < MAX_SKINS; index++)
{
if ((*pDM_RemapSkin)[keynum][index])
(*pDM_RemapSkin)[keynum][index]->model = NULL;
}
#endif

#if 1
auto& itor = g_StudioSkinCache.find(keynum);

if (itor != g_StudioSkinCache.end())
{
auto pSkinCache = itor->second;

if (pSkinCache)
{
for (int index = 0; index < MAX_SKINS; index++)
{
pSkinCache->skins[index].model = NULL;
}
}
}
#endif
}

skin_t* R_StudioGetSkin(int keynum, int index)
{
#if 0

if (index >= MAX_SKINS)
index = 0;
Expand All @@ -1194,9 +1235,45 @@ skin_t* R_StudioGetSkin(int keynum, int index)
}

return pskin;
#else
#endif

#if 0
return gPrivateFuncs.R_StudioGetSkin(keynum, index);
#endif

#if 1

if (index >= MAX_SKINS)
index = 0;

if (index < 0)
index = 0;

auto& itor = g_StudioSkinCache.find(keynum);

if (itor != g_StudioSkinCache.end())
{
return &itor->second->skins[index];
}
else
{
auto pSkinCache = new (std::nothrow) studio_skin_cache_t;

if (pSkinCache)
{
memset(pSkinCache, 0, sizeof(studio_skin_cache_t));

pSkinCache->skins[index].keynum = keynum;
pSkinCache->skins[index].topcolor = -1;
pSkinCache->skins[index].bottomcolor = -1;
g_StudioSkinCache[keynum] = pSkinCache;

return &pSkinCache->skins[index];
}
}

return NULL;
#endif
}

byte* R_StudioReloadSkin(model_t* pModel, int index, skin_t* pskin)
Expand Down Expand Up @@ -1277,15 +1354,6 @@ byte* R_StudioReloadSkin(model_t* pModel, int index, skin_t* pskin)
return pData->data;
}

void R_StudioFlushSkins(int keynum)
{
for (int index = 0; index < MAX_SKINS; index++)
{
if ((*pDM_RemapSkin)[keynum][index])
(*pDM_RemapSkin)[keynum][index]->model = NULL;
}
}

void PaletteHueReplace(byte* palette, int newHue, int start, int end) {
// Convert the new hue value to a range used in the algorithm
double targetHue = static_cast<double>(newHue) * 1.411764705882353;
Expand Down Expand Up @@ -1370,42 +1438,45 @@ void R_StudioSetupSkinEx(const studio_vbo_t* VBOData, studiohdr_t* ptexturehdr,
{
auto pskin = R_StudioGetSkin((*currententity)->index, index);

if (pskin->model != (*r_model) || pskin->topcolor != (*r_topcolor) && pskin->bottomcolor != (*r_bottomcolor))
if (pskin)
{
if (pskin->model)
R_StudioFlushSkins((*currententity)->index);
if (pskin->model != (*r_model) || pskin->topcolor != (*r_topcolor) || pskin->bottomcolor != (*r_bottomcolor))
{
if (pskin->model)
R_StudioFlushSkins((*currententity)->index);

auto pData = R_StudioReloadSkin((*r_model), index, pskin);
auto pTextureData = R_StudioReloadSkin((*r_model), index, pskin);

if (pData)
{
char fullname[1024] = {0};
snprintf(fullname, sizeof(fullname), "%s_%s_%d", ptexturehdr->name, ptexture[index].name, (*currententity)->index);
if (pTextureData)
{
char fullname[1024] = { 0 };
snprintf(fullname, sizeof(fullname), "%s_%s_%d", ptexturehdr->name, ptexture[index].name, (*currententity)->index);

byte* orig_palette = pData + (ptexture[index].height * ptexture[index].width);
byte* orig_palette = pTextureData + (ptexture[index].height * ptexture[index].width);

byte tmp_palette[768];
memcpy(tmp_palette, orig_palette, 768);
byte tmp_palette[768];
memcpy(tmp_palette, orig_palette, 768);

pskin->model = (*r_model);
pskin->bottomcolor = (*r_bottomcolor);
pskin->topcolor = (*r_topcolor);
pskin->model = (*r_model);
pskin->bottomcolor = (*r_bottomcolor);
pskin->topcolor = (*r_topcolor);

PaletteHueReplace(tmp_palette, pskin->topcolor, l, m);
PaletteHueReplace(tmp_palette, pskin->topcolor, l, m);

if (h != 0)
PaletteHueReplace(tmp_palette, pskin->bottomcolor, m, h);
if (h != 0)
PaletteHueReplace(tmp_palette, pskin->bottomcolor, m, h);

GL_UnloadTextureWithType(fullname, GLT_STUDIO, true);
GL_UnloadTextureWithType(fullname, GLT_STUDIO, true);

pskin->gl_index = GL_LoadTexture(fullname, GLT_STUDIO, pskin->width, pskin->height, pData, false, (ptexture[index].flags & STUDIO_NF_MASKED) ? TEX_TYPE_ALPHA : TEX_TYPE_NONE, tmp_palette);
pskin->gl_index = GL_LoadTexture(fullname, GLT_STUDIO, pskin->width, pskin->height, pTextureData, false, (ptexture[index].flags & STUDIO_NF_MASKED) ? TEX_TYPE_ALPHA : TEX_TYPE_NONE, tmp_palette);
}
}
}

if (pskin->gl_index != 0)
{
GL_Bind(pskin->gl_index);
return;
if (pskin->gl_index != 0)
{
GL_Bind(pskin->gl_index);
return;
}
}
}
}
Expand Down
40 changes: 39 additions & 1 deletion Plugins/Renderer/gl_studio.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include <set>
#include <unordered_map>

#define MAX_STUDIO_BONE_CACHES 1024

#define STUDIO_DIFFUSE_TEXTURE 0
#define STUDIO_REPLACE_TEXTURE 1
#define STUDIO_NORMAL_TEXTURE 2
Expand Down Expand Up @@ -182,6 +184,40 @@ typedef struct studio_vbo_s
bool bExternalFileLoaded;
}studio_vbo_t;

class studio_skin_handle
{
public:
studio_skin_handle(int keynum)
{
m_keynum = keynum;
}

bool operator == (const studio_skin_handle& a) const
{
return m_keynum == a.m_keynum;
}

int m_keynum;
int m_index;
};

class studio_skin_hasher
{
public:
std::size_t operator()(const studio_skin_handle& key) const
{
auto base = (std::size_t)(key.m_keynum << 8);

base += ((std::size_t)key.m_index);

return base;
}
};

typedef struct studio_skin_cache_s
{
skin_t skins[MAX_SKINS];
}studio_skin_cache_t;

class studio_bone_handle
{
Expand Down Expand Up @@ -289,11 +325,12 @@ extern dlight_t *(*locallight)[3];
extern int *numlight;
extern int* r_topcolor;
extern int* r_bottomcolor;
#if 0
extern player_model_t(*DM_PlayerState)[MAX_CLIENTS];
extern skin_t(*DM_RemapSkin)[64][MAX_SKINS];
extern skin_t* (*pDM_RemapSkin)[2528][MAX_SKINS];
extern int* r_remapindex;

#endif
extern model_t *cl_sprite_white;
extern model_t *cl_shellchrome;

Expand All @@ -308,6 +345,7 @@ void R_StudioBoneCaches_StartFrame();
studio_vbo_t *R_PrepareStudioVBO(studiohdr_t *studiohdr);
void R_StudioLoadExternalFile(model_t *mod, studiohdr_t *studiohdr, studio_vbo_t *VBOData);
void R_StudioReloadVBOCache(void);
void R_StudioFlushAllSkins();
void R_ShutdownStudio(void);
void R_InitStudio(void);
void R_SaveStudioProgramStates(void);
Expand Down

0 comments on commit e11439d

Please sign in to comment.