From 5984717e30d6073dc8b9c3c41ac11535208360a6 Mon Sep 17 00:00:00 2001 From: Aleksey Komarov Date: Sun, 22 May 2022 18:54:42 +0300 Subject: [PATCH] [linux] fix build CTechnique --- src/libs/renderer/src/technique.cpp | 391 ++++++++++++++++++---------- src/libs/renderer/src/technique.h | 21 +- 2 files changed, 273 insertions(+), 139 deletions(-) diff --git a/src/libs/renderer/src/technique.cpp b/src/libs/renderer/src/technique.cpp index 6dc36d83a..25da581f8 100644 --- a/src/libs/renderer/src/technique.cpp +++ b/src/libs/renderer/src/technique.cpp @@ -1,9 +1,18 @@ -#include "Technique.h" -#include "../Common_h/defines.h" -#include +#ifndef _WIN32 // Effects +#include "technique.h" +#include "core.h" +#include "defines.h" +#include "inlines.h" -#define SHA_DIR "modules\\Techniques" -#define SHA_EXT ".sha" +#define USE_FX // Will load techniques from fx files + +#ifdef USE_FX +#define SHA_DIR "resource\\techniques" +#define SHA_EXT "*.fx" +#else +#define SHA_DIR "resource\\techniques-sha" +#define SHA_EXT "*.sha" +#endif #define PASS_OK 0 #define PASS_ERROR 1 @@ -90,10 +99,11 @@ // common defines #define SAVED_STATES_ADD 128 -char *SkipToken(char *str, char *cmp) +char *SkipToken(char *str, const char *cmp) { int flag; - char *str1, *cmp1; + char *str1; + const char *cmp1; if (str == nullptr || cmp == nullptr) return nullptr; @@ -139,10 +149,11 @@ char *SkipToken(char *str, char *cmp) return nullptr; } -char *FindToken(char *str, char *cmp) +char *FindToken(char *str, const char *cmp) { int flag; - char *str1, *cmp1; + char *str1; + const char *cmp1; if (str == nullptr || cmp == nullptr) return nullptr; @@ -185,14 +196,14 @@ char *FindToken(char *str, char *cmp) } // Get token before symbol skip -char *GetTokenWhile(char *src, char *dst, char *skip) +char *GetTokenWhile(char *src, char *dst, const char *skip) { if (!src || !dst || !skip) return nullptr; dst[0] = 0; char *dst1 = dst; - long lensrc = strlen(src); - long dstlen = 0; + int32_t lensrc = strlen(src); + int32_t dstlen = 0; while (lensrc && src[0] == ' ') { src++; @@ -225,9 +236,9 @@ typedef struct SRSPARAM *pParam; uint32_t dwParamNum; bool bUse; - long dwUseSubCode; + int32_t dwUseSubCode; uint32_t SrsType; - char *cName; + const char *cName; D3DRENDERSTATETYPE State; } SRS; @@ -236,9 +247,9 @@ typedef struct SRSPARAM *pParam; uint32_t dwParamNum; bool bUse; - long dwUseSubCode; + int32_t dwUseSubCode; uint32_t SrsType; - char *cName; + const char *cName; D3DTEXTURESTAGESTATETYPE State; } STSS; @@ -247,9 +258,9 @@ typedef struct SRSPARAM *pParam; uint32_t dwParamNum; bool bUse; - long dwUseSubCode; + int32_t dwUseSubCode; uint32_t SrsType; - char *cName; + const char *cName; D3DSAMPLERSTATETYPE State; } SAMP; @@ -384,8 +395,13 @@ SRS RenderStates[] = { {DEFSIZE(0), SRS_FLOAT, "FogEnd", D3DRS_FOGEND}, {DEFSIZE(0), SRS_FLOAT, "FogDensity", D3DRS_FOGDENSITY}, {DEFSIZE(MYTRUEFALSE), SRS_DWORD, "EdgeAntialias", D3DRS_ANTIALIASEDLINEENABLE}, +#ifdef USE_FX + {DEFSIZE(0), SRS_DWORD, "DepthBias", D3DRS_DEPTHBIAS}, + {DEFSIZE(0), SRS_DWORD, "SlopeScaleDepthBias", D3DRS_SLOPESCALEDEPTHBIAS}, +#else {DEFSIZE(0), SRS_DWORD, "Zbias", D3DRS_DEPTHBIAS}, {DEFSIZE(0), SRS_DWORD, "SSZbias", D3DRS_SLOPESCALEDEPTHBIAS}, +#endif {DEFSIZE(MYTRUEFALSE), SRS_DWORD, "RangeFogEnable", D3DRS_RANGEFOGENABLE}, {DEFSIZE(MYTRUEFALSE), SRS_DWORD, "StencilEnable", D3DRS_STENCILENABLE}, {DEFSIZE(MYD3DSTENCILOP), SRS_DWORD, "StencilFail", D3DRS_STENCILFAIL}, @@ -678,16 +694,16 @@ void ClearComment(char *pStr) // search comment and delete all symbols after if (!pStr || !pStr[0]) return; - long iLen = strlen(pStr); + int32_t iLen = strlen(pStr); char *pSkip1 = FindToken(pStr, COMMENT1); - long iStart1 = iLen, iStart2 = iLen; + int32_t iStart1 = iLen, iStart2 = iLen; if (pSkip1) iStart1 = (pSkip1 - pStr) - strlen(COMMENT1); char *pSkip2 = FindToken(pStr, COMMENT2); if (pSkip2) iStart2 = (pSkip2 - pStr) - strlen(COMMENT2); - long iStart = (iStart2 > iStart1) ? iStart1 : iStart2; - for (long i = iStart; i < iLen; i++) + int32_t iStart = (iStart2 > iStart1) ? iStart1 : iStart2; + for (int32_t i = iStart; i < iLen; i++) pStr[i] = 0; } @@ -752,9 +768,9 @@ uint32_t CTechnique::GetSRSIndex(char *pStr) { uint32_t dwNumParam = sizeof(RenderStates) / sizeof(STSS); for (uint32_t i = 0; i < dwNumParam; i++) - if (_stricmp(pStr, RenderStates[i].cName) == 0) + if (storm::iEquals(pStr, RenderStates[i].cName)) return i; - api->Trace("ERROR: SetRenderState: unknown parameter type <%s> in <%s> file, technique <%s>", pStr, + core.Trace("ERROR: SetRenderState: unknown parameter type <%s> in <%s> file, technique <%s>", pStr, sCurrentFileName, sCurrentBlockName); // THROW; return INVALID_SRS_INDEX; @@ -764,7 +780,7 @@ uint32_t CTechnique::GetSTSSIndex(char *pStr) { uint32_t dwNumParam = sizeof(TexturesStageStates) / sizeof(STSS); for (uint32_t i = 0; i < dwNumParam; i++) - if (_stricmp(pStr, TexturesStageStates[i].cName) == 0) + if (storm::iEquals(pStr, TexturesStageStates[i].cName)) return i; // api->Trace("ERROR: SetTextureStageState: unknown parameter type <%s> in <%s> file, technique // <%s>",pStr,sCurrentFileName,sCurrentBlockName); THROW; @@ -775,7 +791,7 @@ uint32_t CTechnique::GetSAMPIndex(char *pStr) { uint32_t dwNumParam = sizeof(SampleStates) / sizeof(SAMP); for (uint32_t i = 0; i < dwNumParam; i++) - if (_stricmp(pStr, SampleStates[i].cName) == 0) + if (storm::iEquals(pStr, SampleStates[i].cName)) return i; // api->Trace("ERROR: SetSamplerState: unknown parameter type <%s> in <%s> file, technique <%s>", pStr, // sCurrentFileName, sCurrentBlockName); THROW; @@ -785,10 +801,10 @@ uint32_t CTechnique::GetSAMPIndex(char *pStr) uint32_t CTechnique::GetIndex(char *pStr, SRSPARAM *pParam, uint32_t dwNumParam, bool bCanBeNumber) { for (uint32_t i = 0; i < dwNumParam; i++) - if (_stricmp(pStr, pParam[i].cName) == 0) + if (storm::iEquals(pStr, pParam[i].cName)) return i; if (!bCanBeNumber) - api->Trace("ERROR: Unknown parameter type <%s> in <%s> file, technique <%s>", pStr, sCurrentFileName, + core.Trace("ERROR: Unknown parameter type <%s> in <%s> file, technique <%s>", pStr, sCurrentFileName, sCurrentBlockName); // THROW; return INVALID_INDEX; @@ -816,7 +832,7 @@ uint32_t CTechnique::GetCode(char *pStr, SRSPARAM *pParam, uint32_t dwNumParam, } else { - api->Trace("ERROR: unknown parameter type <%s> in <%s> file, technique <%s>", pStr, sCurrentFileName, + core.Trace("ERROR: unknown parameter type <%s> in <%s> file, technique <%s>", pStr, sCurrentFileName, sCurrentBlockName); return 0; } @@ -826,13 +842,13 @@ uint32_t CTechnique::AddShader(char *pShaderName) { // find exist shader or create empty new for (uint32_t i = 0; i < dwNumShaders; i++) - if (_stricmp(pShaders[i].pName, pShaderName) == 0) + if (storm::iEquals(pShaders[i].pName, pShaderName)) return i; - pShaders = (shader_t *)RESIZE(pShaders, sizeof(shader_t) * (dwNumShaders + 1)); + pShaders = (shader_t *)realloc(pShaders, sizeof(shader_t) * (dwNumShaders + 1)); shader_t *pS = &pShaders[dwNumShaders]; ZERO(pShaders[dwNumShaders]); const auto len = strlen(pShaderName) + 1; - pS->pName = NEW char[len]; + pS->pName = new char[len]; memcpy(pS->pName, pShaderName, len); pS->dwHashName = hash_string(pShaderName); pS->pVertexDecl = nullptr; @@ -847,8 +863,8 @@ uint32_t CTechnique::ProcessPass(char *pFile, uint32_t dwSize, char **pStr) block_t *pB = &pBlocks[dwNumBlocks]; technique_t *pTechniques = &pB->pTechniques[pB->dwNumTechniques]; - pTechniques->pPasses = (pass_t *)RESIZE(pTechniques->pPasses, sizeof(pass_t) * (pTechniques->dwNumPasses + 1)); - PZERO(&pTechniques->pPasses[pTechniques->dwNumPasses], sizeof pass_t); + pTechniques->pPasses = (pass_t *)realloc(pTechniques->pPasses, sizeof(pass_t) * (pTechniques->dwNumPasses + 1)); + PZERO(&pTechniques->pPasses[pTechniques->dwNumPasses], sizeof(pass_t)); uint32_t *pPass = pPassStorage; uint32_t *pPassBegin = pPass; @@ -861,14 +877,28 @@ uint32_t CTechnique::ProcessPass(char *pFile, uint32_t dwSize, char **pStr) (*pStr)++; \ continue; \ } - *pStr = _strlwr(*pStr); + tolwr(*pStr); ClearComment(*pStr); if (isEndBracket(*pStr)) + { +#ifdef USE_FX // fx files has no "Render." and "Restore." strings + *pPass++ = CODE_RENDER; + *pPass++ = SUBCODE_RENDER_DRAW; + + *pPass++ = CODE_RESTORE; + *pPass++ = SUBCODE_RESTORE_STATES; + // clear STSS and SRS bUse + ClearSRS_STSS_bUse(); +#endif break; // end of pass + } // check right side of expression for [in] parameters bool bIn = false; uint32_t dwInParamIndex = 0; +#ifdef false // current sha files has no params. Last usage was in + // ENGINE/modules/techniques/weather/shaders/SeaFoam.sha. Removed here: + // https://github.com/storm-devs/thunderstorm-engine/commit/f290ca08ff33d3f86fcdf6aef26b0e20e36ab54c if (pTemp = SkipToken(*pStr, INPARAM_CHECK)) // STSS or SetTexture { GetTokenWhile(pTemp, &temp[0], ">"); @@ -876,6 +906,7 @@ uint32_t CTechnique::ProcessPass(char *pFile, uint32_t dwSize, char **pStr) dwInParamIndex = GetIndex(temp, pParams, dwNumParams, false); dwAdditionalFlags |= FLAGS_CODE_IN_PARAM; } +#endif // check for additional flags such as "no restore states" and other dwAdditionalFlags |= FLAGS_CODE_RESTORE; @@ -885,6 +916,7 @@ uint32_t CTechnique::ProcessPass(char *pFile, uint32_t dwSize, char **pStr) dwAdditionalFlags &= (~FLAGS_CODE_RESTORE); } +#ifndef USE_FX // fx files has no "Restore." strings // restore states check if (pTemp = SkipToken(*pStr, RESTORE_STATES_CHECK)) { @@ -894,10 +926,11 @@ uint32_t CTechnique::ProcessPass(char *pFile, uint32_t dwSize, char **pStr) ClearSRS_STSS_bUse(); SKIP3; } +#endif if (isPixelShaderConst(*pStr)) { if (!bIn) - __debugbreak(); + psnip_trap(); uint32_t dwIndex = 0; *pPass++ = CODE_SPSCONST | dwAdditionalFlags; GetTokenWhile(SkipToken(*pStr, "["), &temp[0], "]"); @@ -955,7 +988,7 @@ uint32_t CTechnique::ProcessPass(char *pFile, uint32_t dwSize, char **pStr) if (TexturesStageStates[dwIndex].bUse && TexturesStageStates[dwIndex].dwUseSubCode & (1 << dwTextureIndex) && dwAdditionalFlags & FLAGS_CODE_RESTORE) - api->Trace("WARN: STSS: dup restore param type <%s[%d]> in <%s> file, technique <%s>", temp, + core.Trace("WARN: STSS: dup restore param type <%s[%d]> in <%s> file, technique <%s>", temp, dwTextureIndex, sCurrentFileName, sCurrentBlockName); if (dwAdditionalFlags & FLAGS_CODE_RESTORE) { @@ -983,7 +1016,7 @@ uint32_t CTechnique::ProcessPass(char *pFile, uint32_t dwSize, char **pStr) { if (SampleStates[dwIndex].bUse && SampleStates[dwIndex].dwUseSubCode & (1 << dwTextureIndex) && dwAdditionalFlags & FLAGS_CODE_RESTORE) - api->Trace("WARN: SAMP: dup restore param type <%s[%d]> in <%s> file, technique <%s>", temp, + core.Trace("WARN: SAMP: dup restore param type <%s[%d]> in <%s> file, technique <%s>", temp, dwTextureIndex, sCurrentFileName, sCurrentBlockName); if (dwAdditionalFlags & FLAGS_CODE_RESTORE) { @@ -1003,7 +1036,7 @@ uint32_t CTechnique::ProcessPass(char *pFile, uint32_t dwSize, char **pStr) } } else - api->Trace("ERROR: unknown parameter type <%s> in <%s> file, technique <%s>", pStr, + core.Trace("ERROR: unknown parameter type <%s> in <%s> file, technique <%s>", pStr, sCurrentFileName, sCurrentBlockName); } SKIP3; @@ -1013,8 +1046,21 @@ uint32_t CTechnique::ProcessPass(char *pFile, uint32_t dwSize, char **pStr) if (SkipToken(*pStr, PIXEL_SHADER)) { *pPass++ = CODE_SPS; +#ifdef USE_FX + pTemp = SkipToken(*pStr, "="); + GetShaderBinPath(pTemp, CODE_SPS, temp); + + auto i = AddShader(temp); + shader_t *pS = &pShaders[i]; + if (pS->dwShaderType == 0) + { + pS->dwShaderType = CODE_SPS; + ProcessShaderBin(pS, temp, CODE_SPS); + } +#else GetTokenWhile(SkipToken(*pStr, "\""), temp, "\""); auto i = AddShader(temp); +#endif *pPass++ = i; SKIP3; } @@ -1022,12 +1068,26 @@ uint32_t CTechnique::ProcessPass(char *pFile, uint32_t dwSize, char **pStr) if (SkipToken(*pStr, VERTEX_SHADER)) { *pPass++ = CODE_SVS; +#ifdef USE_FX + pTemp = SkipToken(*pStr, "="); + GetShaderBinPath(pTemp, CODE_SVS, temp); + + auto i = AddShader(temp); + shader_t *pS = &pShaders[i]; + if (pS->dwShaderType == 0) + { + pS->dwShaderType = CODE_SVS; + ProcessShaderBin(pS, temp, CODE_SVS); + } +#else GetTokenWhile(SkipToken(*pStr, "\""), temp, "\""); auto i = AddShader(temp); +#endif *pPass++ = i; SKIP3; } +#ifndef USE_FX // fx files has no "Render." strings // RENDER if (SkipToken(*pStr, RENDER_CHECK)) { @@ -1035,7 +1095,9 @@ uint32_t CTechnique::ProcessPass(char *pFile, uint32_t dwSize, char **pStr) *pPass++ = SUBCODE_RENDER_DRAW; SKIP3; } +#endif +#ifdef false // current sha files has no "transform." strings // transform if (SkipToken(*pStr, TRANSFORM_CHECK)) { @@ -1046,7 +1108,7 @@ uint32_t CTechnique::ProcessPass(char *pFile, uint32_t dwSize, char **pStr) { // maybe world0-world256 if (nullptr == (pTemp = SkipToken(*pStr, WORLD_TRANSFORM_CHECK))) - THROW("transform. error!"); + throw std::runtime_error("transform. error!"); sscanf(pTemp, "%lu", &dwCode); dwCode = (uint32_t)D3DTS_WORLDMATRIX(dwCode); } @@ -1055,6 +1117,7 @@ uint32_t CTechnique::ProcessPass(char *pFile, uint32_t dwSize, char **pStr) *pPass++ = dwInParamIndex; SKIP3; } +#endif // SetRenderState if (SkipToken(*pStr, "=")) @@ -1064,7 +1127,7 @@ uint32_t CTechnique::ProcessPass(char *pFile, uint32_t dwSize, char **pStr) uint32_t dwSRSIndex = GetSRSIndex(temp); Assert(dwSRSIndex != INVALID_SRS_INDEX); if (RenderStates[dwSRSIndex].bUse && dwAdditionalFlags & FLAGS_CODE_RESTORE) - api->Trace("WARN: SRS: dup restore param type <%s> in <%s> file, technique <%s>", temp, + core.Trace("WARN: SRS: dup restore param type <%s> in <%s> file, technique <%s>", temp, sCurrentFileName, sCurrentBlockName); if (dwAdditionalFlags & FLAGS_CODE_RESTORE) RenderStates[dwSRSIndex].bUse = true; @@ -1089,7 +1152,7 @@ uint32_t CTechnique::ProcessPass(char *pFile, uint32_t dwSize, char **pStr) } uint32_t dwSizePass = pPass - pPassBegin; - pPassBegin = NEW uint32_t[dwSizePass]; //(uint32_t*)RESIZE(pPassBegin,dwSizePass*sizeof(uint32_t)); + pPassBegin = new uint32_t[dwSizePass]; //(uint32_t*)RESIZE(pPassBegin,dwSizePass*sizeof(uint32_t)); memcpy(pPassBegin, pPassStorage, dwSizePass * sizeof(uint32_t)); pTechniques->pPasses[pTechniques->dwNumPasses].dwSize = dwSizePass; pTechniques->pPasses[pTechniques->dwNumPasses].isValidate = true; @@ -1102,8 +1165,8 @@ uint32_t CTechnique::ProcessPass(char *pFile, uint32_t dwSize, char **pStr) uint32_t CTechnique::ProcessTechnique(char *pFile, uint32_t dwSize, char **pStr) { block_t *pB = &pBlocks[dwNumBlocks]; - pB->pTechniques = (technique_t *)RESIZE(pB->pTechniques, sizeof(technique_t) * (pB->dwNumTechniques + 1)); - PZERO(&pB->pTechniques[pB->dwNumTechniques], sizeof technique_t); + pB->pTechniques = (technique_t *)realloc(pB->pTechniques, sizeof(technique_t) * (pB->dwNumTechniques + 1)); + PZERO(&pB->pTechniques[pB->dwNumTechniques], sizeof(technique_t)); // clear STSS and SRS bUse ClearSRS_STSS_bUse(); // search for pass and '}' @@ -1114,7 +1177,7 @@ uint32_t CTechnique::ProcessTechnique(char *pFile, uint32_t dwSize, char **pStr) (*pStr)++; \ continue; \ } - *pStr = _strlwr(*pStr); + tolwr(*pStr); ClearComment(*pStr); // if (isComment(*pStr)) SKIP2; if (isEndBracket(*pStr)) @@ -1137,7 +1200,7 @@ uint32_t CTechnique::ProcessTechnique(char *pFile, uint32_t dwSize, char **pStr) void AddDeclElement(shader_t *pS) { pS->dwDeclSize++; - pS->pDecl = (D3DVERTEXELEMENT9 *)RESIZE(pS->pDecl, sizeof(D3DVERTEXELEMENT9) * pS->dwDeclSize); + pS->pDecl = (D3DVERTEXELEMENT9 *)realloc(pS->pDecl, sizeof(D3DVERTEXELEMENT9) * pS->dwDeclSize); pS->pDecl[pS->dwDeclSize - 1].Method = D3DDECLMETHOD_DEFAULT; } @@ -1151,11 +1214,11 @@ uint32_t CTechnique::ProcessVertexDeclaration(shader_t *pS, char *pFile, uint32_ uint32_t dwTemp; ; uint32_t dwStream = 0, dwOffset = 0; - uint32_t dwIndexes[_countof(MYDECLUSAGE)] = {0}; + uint32_t dwIndexes[std::size(MYDECLUSAGE)] = {0}; while (nullptr != (*pStr = GetString(pFile, dwSize, *pStr))) { - *pStr = _strlwr(*pStr); + tolwr(*pStr); ClearComment(*pStr); if (isEndBracket(*pStr)) break; // end of declaration @@ -1166,7 +1229,7 @@ uint32_t CTechnique::ProcessVertexDeclaration(shader_t *pS, char *pFile, uint32_ } if (SkipToken(*pStr, VDECL_FLOAT_CHECK)) { - sscanf(SkipToken(*pStr, "["), "%lu", &dwTemp); + sscanf(SkipToken(*pStr, "["), "%u", &dwTemp); switch (dwTemp) { case 1: @@ -1190,7 +1253,7 @@ uint32_t CTechnique::ProcessVertexDeclaration(shader_t *pS, char *pFile, uint32_ // Usage dwTemp = ~0; - for (int i = 0; i < _countof(MYDECLUSAGE); i++) + for (int i = 0; i < std::size(MYDECLUSAGE); i++) { if (SkipToken(*pStr, MYDECLUSAGE[i].cName)) { @@ -1221,7 +1284,7 @@ uint32_t CTechnique::ProcessVertexDeclaration(shader_t *pS, char *pFile, uint32_ HRESULT hr = pRS->CreateVertexDeclaration(pS->pDecl, &pS->pVertexDecl); if (hr != S_OK) - api->Trace("ERROR: invalid shader declaration <%s>", pS->pName); + core.Trace("ERROR: invalid shader declaration <%s>", pS->pName); return 0; } @@ -1271,7 +1334,7 @@ char *CTechnique::Preprocessor(char *pBuffer, uint32_t &dwSize) while (nullptr != (pStr = GetString(pBuffer, dwBufSize, pStr))) { - // pStr = _strlwr(pStr); + // tolwr(pStr); ClearComment(pStr); if (isDefine(pStr)) { @@ -1281,16 +1344,16 @@ char *CTechnique::Preprocessor(char *pBuffer, uint32_t &dwSize) if (dwMaxDefineElements != dwNewSize) { dwMaxDefineElements = dwNewSize; - pDefines = (define_t *)RESIZE(pDefines, sizeof(define_t) * dwMaxDefineElements); + pDefines = (define_t *)realloc(pDefines, sizeof(define_t) * dwMaxDefineElements); } auto len = strlen(sName) + 1; - pDefines[dwNumDefines].pName = NEW char[len]; + pDefines[dwNumDefines].pName = new char[len]; memcpy(pDefines[dwNumDefines].pName, sName, len); pDefines[dwNumDefines].dwNameLen = len - 1; len = strlen(sValue) + 1; - pDefines[dwNumDefines].pValue = NEW char[len]; + pDefines[dwNumDefines].pValue = new char[len]; memcpy(pDefines[dwNumDefines].pValue, sValue, len); dwNumDefines++; @@ -1307,7 +1370,7 @@ char *CTechnique::Preprocessor(char *pBuffer, uint32_t &dwSize) { // find define for (i = 0; i < dwNumDefines; i++) - if (dwTempLen == pDefines[i].dwNameLen && _stricmp(pDefines[i].pName, sToken) == 0) + if (dwTempLen == pDefines[i].dwNameLen && storm::iEquals(pDefines[i].pName, sToken)) { if (pDefines[i].pValue) strcpy_s(sToken, pDefines[i].pValue); @@ -1320,7 +1383,7 @@ char *CTechnique::Preprocessor(char *pBuffer, uint32_t &dwSize) if (dwNewSize > dwMaxProgramElements) { dwMaxProgramElements = dwNewSize; - pProgram = (char *)RESIZE(pProgram, dwMaxProgramElements); + pProgram = (char *)realloc(pProgram, dwMaxProgramElements); } strcpy_s(&pProgram[dwProgramSize], dwNewSize - dwProgramSize, sToken); dwProgramSize += dwTempLen; @@ -1359,7 +1422,7 @@ uint32_t CTechnique::ProcessShaderAsm(shader_t *pS, char *pFile, uint32_t dwSize char *pBuffer = nullptr; while (nullptr != (*pStr = GetString(pFile, dwSize, *pStr))) { - //*pStr = _strlwr(*pStr); + // tolwr(*pStr); ClearComment(*pStr); if (isBeginBracket(*pStr)) TOTAL_SKIP; @@ -1376,21 +1439,22 @@ uint32_t CTechnique::ProcessShaderAsm(shader_t *pS, char *pFile, uint32_t dwSize sprintf_s(sIncFileName, "%s\\%s", sCurrentDir, sName); if (!fio->LoadFile(sIncFileName, &pTempBuffer, &dwFileSize)) { - api->Trace("ERROR: in file %s, file not found : %s", sCurrentFileName, sIncFileName); + core.Trace("ERROR: in file %s, file not found : %s", sCurrentFileName, sIncFileName); TOTAL_SKIP; } pTempBuffer[dwFileSize - 1] = 0x0; pTemp = pTempBuffer; } - long iLen = strlen(pTemp) - 1; - pBuffer = (char *)RESIZE(pBuffer, dwTotalLen + iLen + 4); + int32_t iLen = strlen(pTemp) - 1; + pBuffer = (char *)realloc(pBuffer, dwTotalLen + iLen + 4); strcpy_s(&pBuffer[dwTotalLen], iLen + 4, pTemp); strcpy_s(&pBuffer[dwTotalLen + iLen + 1], 3, "\r\n"); dwTotalLen += iLen + 2; STORM_DELETE(pTempBuffer); TOTAL_SKIP; } +#ifdef _WIN32 // replace D3DXAssembleShader with D3DCompile or similar #ifndef _XBOX ID3DXBuffer *CompiledShader = nullptr, *ErrorShader = nullptr; #else @@ -1418,10 +1482,10 @@ uint32_t CTechnique::ProcessShaderAsm(shader_t *pS, char *pFile, uint32_t dwSize if (D3D_OK != hr && ErrorShader) { const auto len = ErrorShader->GetBufferSize() + 1; - char *pErrStr = NEW char[len]; + char *pErrStr = new char[len]; strncpy_s(pErrStr, len, (char *)ErrorShader->GetBufferPointer(), ErrorShader->GetBufferSize()); pErrStr[ErrorShader->GetBufferSize()] = 0; - api->Trace("ERROR: in compile shader %s\nerror:\n%s", pS->pName, pErrStr); + core.Trace("ERROR: in compile shader %s\nerror:\n%s", pS->pName, pErrStr); RELEASE(CompiledShader); RELEASE(ErrorShader); STORM_DELETE(pBuffer); @@ -1440,6 +1504,51 @@ uint32_t CTechnique::ProcessShaderAsm(shader_t *pS, char *pFile, uint32_t dwSize RELEASE(CompiledShader); RELEASE(ErrorShader); +#endif + STORM_DELETE(pBuffer); + return 0; +} + +void CTechnique::GetShaderBinPath(char *pShaderStr, uint32_t dwShaderType, char *dest) +{ + // dest will contain path to shader file "currentFilename_shaderName.vso" (or .pso) in folder of sCurrentFileName + char sShaderName[256]; + if (pShaderStr[strlen(pShaderStr)-2] == '(' && pShaderStr[strlen(pShaderStr)-1] == ')') + { + // for pShaderStr like "compile vs_1_0 main()" + GetTokenWhile(SkipToken(SkipToken(pShaderStr, " "), " "), sShaderName, "("); + } + else + { + strcpy_s(sShaderName, pShaderStr); + } + + GetTokenWhile(sCurrentFileName, dest, "."); + sprintf(dest + strlen(dest), "_%s", sShaderName); + if (dwShaderType == CODE_SVS) + sprintf(dest + strlen(dest), ".vso"); + else + sprintf(dest + strlen(dest), ".pso"); +} + +uint32_t CTechnique::ProcessShaderBin(shader_t *pS, char *pFile, uint32_t dwShaderType) +{ + char *pBuffer = nullptr; + if (!fio->LoadFile(pFile, &pBuffer, nullptr)) + { + core.Trace("ERROR: in file %s, file not found : %s", sCurrentFileName, pFile); + return 0; + } + + HRESULT hr; + if (dwShaderType == CODE_SVS) + hr = pRS->CreateVertexShader((uint32_t *)pBuffer, &pS->pVertexShader); + else + hr = pRS->CreatePixelShader((uint32_t *)pBuffer, &pS->pPixelShader); + + if (hr != D3D_OK) + core.Trace("ERROR: can't create shader from %s\nfrom file: %s", pS->pName, pFile); + STORM_DELETE(pBuffer); return 0; } @@ -1458,7 +1567,7 @@ uint32_t CTechnique::ProcessVertexShader(char *pFile, uint32_t dwSize, char **pS while (nullptr != (*pStr = GetString(pFile, dwSize, *pStr))) { - *pStr = _strlwr(*pStr); + tolwr(*pStr); ClearComment(*pStr); if (isEndBracket(*pStr)) break; // end of vertex shader @@ -1486,7 +1595,7 @@ uint32_t CTechnique::ProcessPixelShader(char *pFile, uint32_t dwSize, char **pSt while (nullptr != (*pStr = GetString(pFile, dwSize, *pStr))) { - *pStr = _strlwr(*pStr); + tolwr(*pStr); ClearComment(*pStr); if (isEndBracket(*pStr)) break; // end of vertex shader @@ -1501,33 +1610,42 @@ uint32_t CTechnique::ProcessPixelShader(char *pFile, uint32_t dwSize, char **pSt uint32_t CTechnique::ProcessBlock(char *pFile, uint32_t dwSize, char **pStr) { uint32_t i; - char temp[1024], pTempParamStr[1024]; + char temp[1024]; +#ifndef USE_FX // fx files has no parameters + char pTempParamStr[1024]; +#endif // resize - pBlocks = (block_t *)RESIZE(pBlocks, sizeof(block_t) * (dwNumBlocks + 1)); + pBlocks = (block_t *)realloc(pBlocks, sizeof(block_t) * (dwNumBlocks + 1)); block_t *pB = &pBlocks[dwNumBlocks]; - PZERO(pB, sizeof block_t); + PZERO(pB, sizeof(block_t)); dwNumParams = 0; // get name this block +#ifdef USE_FX + char *pName = SkipToken(*pStr, TECHNIQUE); +#else char *pName = SkipToken(*pStr, BLOCK); +#endif strcpy_s(sCurrentBlockName, pName); GetTokenWhile(pName, &temp[0], "("); pB->dwHashBlockName = hash_string(temp); const auto len = strlen(temp) + 1; - pB->pBlockName = NEW char[len]; + pB->pBlockName = new char[len]; memcpy(pB->pBlockName, temp, len); for (i = 0; i < dwNumBlocks; i++) - if (pBlocks[i].dwHashBlockName == pB->dwHashBlockName && (_stricmp(pBlocks[i].pBlockName, pB->pBlockName) == 0)) + if (pBlocks[i].dwHashBlockName == pB->dwHashBlockName && + (storm::iEquals(pBlocks[i].pBlockName, pB->pBlockName))) { - api->Trace("ERROR: Techniques: Find duplicate technique name: %s", pB->pBlockName); + core.Trace("ERROR: Techniques: Find duplicate technique name: %s", pB->pBlockName); break; } htBlocks[pB->pBlockName] = dwNumBlocks; // get parameters +#ifndef USE_FX // fx files has no parameters pTempParamStr[0] = 0; GetTokenWhile(SkipToken(*pStr, "("), &pTempParamStr[0], ")"); char *pParamStr = &pTempParamStr[0]; @@ -1537,18 +1655,27 @@ uint32_t CTechnique::ProcessBlock(char *pFile, uint32_t dwSize, char **pStr) pParamStr = GetTokenWhile(pParamStr, &temp[0], " "); if (!pParamStr[0]) break; - pParams = (SRSPARAM *)RESIZE(pParams, sizeof(SRSPARAM) * (dwNumParams + 1)); - pB->pParams = (uint32_t *)RESIZE(pB->pParams, sizeof(uint32_t) * (dwNumParams + 1)); + pParams = (SRSPARAM *)realloc(pParams, sizeof(SRSPARAM) * (dwNumParams + 1)); + pB->pParams = (uint32_t *)realloc(pB->pParams, sizeof(uint32_t) * (dwNumParams + 1)); pParams[dwNumParams].dwCode = GetCode(&temp[0], PARAM_TYPES, sizeof(PARAM_TYPES) / sizeof(SRSPARAM)); pB->pParams[dwNumParams] = pParams[dwNumParams].dwCode; // get parameter name pParamStr = GetTokenWhile(pParamStr, &temp[0], ","); const auto len = strlen(temp) + 1; - pParams[dwNumParams].cName = NEW char[len]; + pParams[dwNumParams].cName = new char[len]; strcpy_s(pParams[dwNumParams].cName, len, temp); dwNumParams++; pB->dwNumParams++; } +#endif + +#ifdef USE_FX + // HACK: remove after drop sha files support + // For all lines except the first one, we need to get the previous line + // in order to get correct line when entering the loop + if (pFile != *pStr) + (*pStr)--; +#endif // search for technique and '}' while (nullptr != (*pStr = GetString(pFile, dwSize, *pStr))) @@ -1558,13 +1685,22 @@ uint32_t CTechnique::ProcessBlock(char *pFile, uint32_t dwSize, char **pStr) (*pStr)++; \ continue; \ } - *pStr = _strlwr(*pStr); + tolwr(*pStr); ClearComment(*pStr); // if (isComment(*pStr)) SKIP1; if (isEndBracket(*pStr)) break; // end of block if (isTechnique(*pStr)) + { ProcessTechnique(pFile, dwSize, pStr); +#ifdef USE_FX + // HACK: remove after drop sha files support + // fx files don't have "block" => it has 1 less level. Entry into ProcessBlock occurred + // by "technique" and the exit from it should use SKIP1 for keepeng "{" + (*pStr)--; + continue; +#endif + } SKIP1; } @@ -1606,15 +1742,15 @@ void CTechnique::DecodeFiles(char *sub_dir) { uint64_t dwRDTSC; RDTSC_B(dwRDTSC); - pPassStorage = NEW uint32_t[16384]; + pPassStorage = new uint32_t[16384]; InnerDecodeFiles(sub_dir); STORM_DELETE(pPassStorage); RDTSC_E(dwRDTSC); - api->Trace("Techniques: %d shaders compiled.", dwNumShaders); - api->Trace("Techniques: %d techniques compiled.", dwNumBlocks); - api->Trace("Techniques: compiled by %d ticks.", dwRDTSC); + core.Trace("Techniques: %d shaders compiled.", dwNumShaders); + core.Trace("Techniques: %d techniques compiled.", dwNumBlocks); + core.Trace("Techniques: compiled by %d ticks.", dwRDTSC); // some optimize for (uint32_t i = 0; i < dwNumBlocks; i++) @@ -1623,50 +1759,27 @@ void CTechnique::DecodeFiles(char *sub_dir) void CTechnique::InnerDecodeFiles(char *sub_dir) { - char file_mask[256]; - WIN32_FIND_DATA wfd; - - sprintf_s(sCurrentDir, "%s%s", SHA_DIR, (sub_dir) ? sub_dir : ""); - sprintf_s(file_mask, "%s\\*.*", sCurrentDir); + sprintf(sCurrentDir, "%s%s", SHA_DIR, (sub_dir) ? sub_dir : ""); - HANDLE hFile = fio->_FindFirstFile(file_mask, &wfd); - if (hFile != INVALID_HANDLE_VALUE) + const auto vFilenames = fio->_GetPathsOrFilenamesByMask(sCurrentDir, SHA_EXT, true, false, true, true); + for (std::string path : vFilenames) { - do - { - if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - { - if (wfd.cFileName[0] == '.') - continue; - sprintf_s(file_mask, "%s\\%s", (sub_dir) ? sub_dir : "", wfd.cFileName); - InnerDecodeFiles(file_mask); - } - else - { - if (SkipToken(wfd.cFileName, SHA_EXT)) - { - sprintf_s(file_mask, "%s\\%s", (sub_dir) ? sub_dir : "", wfd.cFileName); - DecodeFile(file_mask); - } - } - } while (fio->_FindNextFile(hFile, &wfd)); - - fio->_FindClose(hFile); + DecodeFile(path); } } -bool CTechnique::DecodeFile(char *sname) +bool CTechnique::DecodeFile(std::string sname) { char fname[256]; - sprintf_s(fname, "%s%s", SHA_DIR, sname); - strcpy_s(sCurrentFileName, sname); - HANDLE hFile = fio->_CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING); - uint32_t dwSize = fio->_GetFileSize(hFile, nullptr); + sprintf(fname, "%s", sname.c_str()); + strcpy(sCurrentFileName, fname); + auto fileS = fio->_CreateFile(fname, std::ios::binary | std::ios::in); + auto dwSize = fio->_GetFileSize(fname); Assert(dwSize != 0); - char *pFile = NEW char[dwSize]; - fio->_ReadFile(hFile, pFile, dwSize, nullptr); - fio->_CloseHandle(hFile); + char *pFile = new char[dwSize]; + fio->_ReadFile(fileS, pFile, dwSize); + fio->_CloseFile(fileS); // change 0xd and 0xa to 0x0 for (uint32_t i = 0; i < dwSize; i++) @@ -1688,7 +1801,7 @@ bool CTechnique::DecodeFile(char *sname) pStr++; \ continue; \ } - pStr = _strlwr(pStr); + tolwr(pStr); ClearComment(pStr); // if (isComment(pStr)) SKIP; if (isPixelShader(pStr)) @@ -1703,7 +1816,11 @@ bool CTechnique::DecodeFile(char *sname) if (dwRes == SHADER_ERROR) return false; } +#ifdef USE_FX + if (isTechnique(pStr)) // fx files has no blocks +#else if (isBlock(pStr)) +#endif { uint32_t dwRes = ProcessBlock(pFile, dwSize, &pStr); if (dwRes == BLOCK_ERROR) @@ -1727,8 +1844,8 @@ bool CTechnique::ExecutePassStart() return false; dwCurBlock = it->second; // for (uint32_t i=0;idwNumTechniques == 0) @@ -1771,7 +1888,7 @@ uint32_t CTechnique::GetPassParameter(uint32_t dwParam, uint32_t dwFlags) if (dwFlags & FLAGS_CODE_IN_PARAM) { if (dwParam >= dwCurNumParams) - THROW("Technique: Exceeded parameter numbers!"); + throw std::runtime_error("Technique: Exceeded parameter numbers!"); return pCurParams[dwParam]; } @@ -1870,16 +1987,17 @@ bool CTechnique::ExecutePass(bool bStart) case CODE_TEXTURE: // SetTexture( { uint32_t dwTextureIndex = *pPass++; - long iTextureIndex = (long)*pPass++; + int32_t iTextureIndex = (int32_t)*pPass++; if (iTextureIndex >= 0) - iTextureIndex = (long)GetPassParameter(*pPass++, dwSubCode); + iTextureIndex = (int32_t)GetPassParameter(*pPass++, dwSubCode); pRS->TextureSet(dwTextureIndex, iTextureIndex); } break; case CODE_TRANSFORM: // SetTransform( { D3DTRANSFORMSTATETYPE TransformType = (D3DTRANSFORMSTATETYPE)*pPass++; - pRS->SetTransform(TransformType, (D3DMATRIX *)GetPassParameter(*pPass++, dwSubCode)); + throw std::runtime_error("conversion from uint32_t to D3DMATRIX*"); + // pRS->SetTransform(TransformType,(D3DMATRIX*)GetPassParameter(*pPass++,dwSubCode)); } break; case CODE_RENDER: // Render functions @@ -1927,8 +2045,9 @@ bool CTechnique::ExecutePass(bool bStart) break; case CODE_SPSCONST: { uint32_t dwShaderConstIndex = *pPass++; - pRS->SetPixelShaderConstantF(dwShaderConstIndex, (const float *)GetPassParameter(*pPass++, dwSubCode), - 1); //~!~ + throw std::runtime_error("conversion from uint32_t to const float *"); + // pRS->SetPixelShaderConstantF(dwShaderConstIndex, (const float*)GetPassParameter(*pPass++, dwSubCode), 1); + //~!~ } break; case CODE_SVSCONST: { @@ -1937,6 +2056,7 @@ bool CTechnique::ExecutePass(bool bStart) switch (dwCode) { case SUBCODE_SVSCONST_WORLDVIEWPROJ: { +#ifdef _WIN32 // replace D3DXMATRIX D3DXMATRIX matTemp, matWorldViewProj; D3DXMATRIX matWorld; @@ -1952,6 +2072,9 @@ bool CTechnique::ExecutePass(bool bStart) // Projection to clip space D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj); pRS->SetVertexShaderConstantF(dwShaderConstIndex, &matWorldViewProj(0, 0), 4); +#else + throw std::runtime_error("replace D3DXMATRIX in technique.cpp"); +#endif } break; } @@ -1981,7 +2104,8 @@ void inline CTechnique::AddState2Restore2(uint32_t dwState, uint32_t dw1) // add new memory if need if ((dwCurSavedStatesPos + 2) >= dwCurMaxSavedSize / sizeof(pSavedStates[0])) { - pSavedStates = (uint32_t *)RESIZE(pSavedStates, dwCurMaxSavedSize + SAVED_STATES_ADD * sizeof(pSavedStates[0])); + pSavedStates = + (uint32_t *)realloc(pSavedStates, dwCurMaxSavedSize + SAVED_STATES_ADD * sizeof(pSavedStates[0])); dwCurMaxSavedSize += SAVED_STATES_ADD; } @@ -1995,7 +2119,8 @@ void inline CTechnique::AddState2Restore3(uint32_t dwState, uint32_t dw1, uint32 // add new memory if need if ((dwCurSavedStatesPos + 3) >= dwCurMaxSavedSize / sizeof(pSavedStates[0])) { - pSavedStates = (uint32_t *)RESIZE(pSavedStates, dwCurMaxSavedSize + SAVED_STATES_ADD * sizeof(pSavedStates[0])); + pSavedStates = + (uint32_t *)realloc(pSavedStates, dwCurMaxSavedSize + SAVED_STATES_ADD * sizeof(pSavedStates[0])); dwCurMaxSavedSize += SAVED_STATES_ADD; } @@ -2010,7 +2135,8 @@ void inline CTechnique::AddState2Restore(uint32_t dwState) // add new memory if need if (dwCurSavedStatesPos >= dwCurMaxSavedSize / sizeof(pSavedStates[0])) { - pSavedStates = (uint32_t *)RESIZE(pSavedStates, dwCurMaxSavedSize + SAVED_STATES_ADD * sizeof(pSavedStates[0])); + pSavedStates = + (uint32_t *)realloc(pSavedStates, dwCurMaxSavedSize + SAVED_STATES_ADD * sizeof(pSavedStates[0])); dwCurMaxSavedSize += SAVED_STATES_ADD; } @@ -2059,11 +2185,13 @@ void CTechnique::RestoreSavedStates() break; case CODE_SPS: dwValue = pSavedStates[dwTempSavedStatesPos++]; - pRS->SetPixelShader((IDirect3DPixelShader9 *)dwValue); + throw std::runtime_error("conversion from uint32_t to IDirect3DPixelShader9 *"); + // pRS->SetPixelShader((IDirect3DPixelShader9*)dwValue); break; case CODE_SVS: dwValue = pSavedStates[dwTempSavedStatesPos++]; - pRS->SetVertexShader((IDirect3DVertexShader9 *)dwValue); + throw std::runtime_error("conversion from uint32_t to IDirect3DPixelShader9 *"); + // pRS->SetVertexShader((IDirect3DVertexShader9*)dwValue); break; } } @@ -2077,7 +2205,7 @@ void CTechnique::SetCurrentBlock(const char *name, uint32_t _dwNumParams, void * { strcpy_s(sCurrentBlockName, name); - _strlwr(sCurrentBlockName); + tolwr(sCurrentBlockName); // dwHashCode = hash_string(sCurrentBlockName); dwCurNumParams = _dwNumParams; @@ -2085,7 +2213,7 @@ void CTechnique::SetCurrentBlock(const char *name, uint32_t _dwNumParams, void * { while (dwCurNumParams > dwCurParamsMax) dwCurParamsMax += 10; - pCurParams = (uint32_t *)RESIZE(pCurParams, sizeof(uint32_t) * dwCurParamsMax); + pCurParams = (uint32_t *)realloc(pCurParams, sizeof(uint32_t) * dwCurParamsMax); } for (uint32_t i = 0; i < _dwNumParams; i++) @@ -2093,6 +2221,7 @@ void CTechnique::SetCurrentBlock(const char *name, uint32_t _dwNumParams, void * } else { - api->Trace("ERROR: SetCurrentBlock: unknown technique <%s> first character is <%s> ", name, name[0]); + core.Trace("ERROR: SetCurrentBlock: unknown technique <%s> first character is <%s> ", name, name[0]); } } +#endif // _WIN32 diff --git a/src/libs/renderer/src/technique.h b/src/libs/renderer/src/technique.h index 9588c939a..4ea63940c 100644 --- a/src/libs/renderer/src/technique.h +++ b/src/libs/renderer/src/technique.h @@ -1,15 +1,18 @@ -#ifndef TECHNIQUE_HPP -#define TECHNIQUE_HPP +#ifndef _WIN32 // Effects +#pragma once -#include "../Common_h/dx9render.h" -#include "../Common_h/vmodule_api.h" -#include -#include +#include "dx9render.h" struct SRSPARAM { char *cName; uint32_t dwCode; + + SRSPARAM(const char *cName, uint32_t dwCode) + { + this->cName = strdup(cName); + this->dwCode = dwCode; + } }; struct pass_t @@ -122,6 +125,8 @@ class CTechnique uint32_t ProcessPixelShader(char *pFile, uint32_t dwSize, char **pStr); uint32_t ProcessShaderAsm(shader_t *pS, char *pFile, uint32_t dwSize, char **pStr, uint32_t dwShaderType, bool HLSL = false); + void GetShaderBinPath(char *pShaderStr, uint32_t dwShaderType, char *dest); + uint32_t ProcessShaderBin(shader_t *pS, char *pFile, uint32_t dwShaderType); uint32_t AddShader(char *pShaderName); char *Preprocessor(char *pBuffer, uint32_t &dwSize); @@ -151,7 +156,7 @@ class CTechnique public: void SetCurrentBlock(const char *name, uint32_t _dwNumParams, void *pParams); - bool DecodeFile(char *sname); + bool DecodeFile(std::string sname); void DecodeFiles(char *sub_dir = nullptr); bool ExecutePassStart(); @@ -162,4 +167,4 @@ class CTechnique ~CTechnique(); }; -#endif \ No newline at end of file +#endif // _WIN32