diff --git a/rehlds/build.gradle b/rehlds/build.gradle index b5cabf7..616c28e 100644 --- a/rehlds/build.gradle +++ b/rehlds/build.gradle @@ -184,11 +184,11 @@ void setupToolchain(NativeBinarySpec b) { } if (unitTestExecutable) { - cfg.singleDefines 'REHLDS_UNIT_TESTS' + cfg.singleDefines 'REHLDS_UNIT_TESTS', 'REHLDS_JIT' } if (rehldsFixes) { - cfg.singleDefines 'REHLDS_FIXES', 'REHLDS_CHECKS', 'HAVE_OPT_STRTOOLS' + cfg.singleDefines 'REHLDS_FIXES', 'REHLDS_JIT', 'REHLDS_CHECKS', 'HAVE_OPT_STRTOOLS' } ToolchainConfigUtils.apply(project, cfg, b) diff --git a/rehlds/engine/delta.cpp b/rehlds/engine/delta.cpp index 2df6d19..6f81baf 100644 --- a/rehlds/engine/delta.cpp +++ b/rehlds/engine/delta.cpp @@ -383,7 +383,7 @@ void EXT_FUNC DELTA_UnsetField(struct delta_s *pFields, const char *fieldname) void EXT_FUNC DELTA_SetFieldByIndex(struct delta_s *pFields, int fieldNumber) { -#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES) +#if (defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)) && defined REHLDS_JIT DELTAJit_SetFieldByIndex(pFields, fieldNumber); #else pFields->pdd[fieldNumber].flags |= FDT_MARK; @@ -392,7 +392,7 @@ void EXT_FUNC DELTA_SetFieldByIndex(struct delta_s *pFields, int fieldNumber) void EXT_FUNC DELTA_UnsetFieldByIndex(struct delta_s *pFields, int fieldNumber) { -#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES) +#if (defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)) && defined REHLDS_JIT DELTAJit_UnsetFieldByIndex(pFields, fieldNumber); #else pFields->pdd[fieldNumber].flags &= ~FDT_MARK; @@ -407,11 +407,14 @@ void DELTA_ClearFlags(delta_t *pFields) { pitem->flags = 0; } +#if defined REHLDS_FIXES && !defined REHLDS_JIT + pFields->originalMarkedFieldsMask.u64 = 0; +#endif } int DELTA_TestDelta(unsigned char *from, unsigned char *to, delta_t *pFields) { -#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES) +#if (defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)) && defined REHLDSJIT return DELTAJit_TestDelta(from, to, pFields); #else int i; @@ -562,6 +565,11 @@ void DELTA_MarkSendFields(unsigned char *from, unsigned char *to, delta_t *pFiel Con_Printf("%s: Bad field type %i\n", __func__, fieldType); break; } + +#if defined REHLDS_FIXES && !defined REHLDS_JIT + if (pTest->flags & FDT_MARK) + pFields->originalMarkedFieldsMask.u32[i >> 5] |= (1 << (i & 31)); +#endif } if (pFields->conditionalencode) pFields->conditionalencode(pFields, from, to); @@ -599,7 +607,7 @@ void DELTA_SetSendFlagBits(delta_t *pFields, int *bits, int *bytecount) qboolean DELTA_IsFieldMarked(delta_t* pFields, int fieldNumber) { -#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES) +#if (defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)) && defined REHLDS_JIT return DELTAJit_IsFieldMarked(pFields, fieldNumber); #else return pFields->pdd[fieldNumber].flags & FDT_MARK; @@ -725,7 +733,7 @@ qboolean DELTA_CheckDelta(unsigned char *from, unsigned char *to, delta_t *pFiel { qboolean sendfields; -#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES) +#if (defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)) && defined REHLDS_JIT sendfields = DELTAJit_Fields_Clear_Mark_Check(from, to, pFields, NULL); #else DELTA_ClearFlags(pFields); @@ -740,7 +748,7 @@ NOINLINE qboolean DELTA_WriteDelta(unsigned char *from, unsigned char *to, qbool { qboolean sendfields; -#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES) +#if (defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)) && defined REHLDS_JIT sendfields = DELTAJit_Fields_Clear_Mark_Check(from, to, pFields, NULL); #else // REHLDS_OPT_PEDANTIC || REHLDS_FIXES DELTA_ClearFlags(pFields); @@ -754,9 +762,57 @@ NOINLINE qboolean DELTA_WriteDelta(unsigned char *from, unsigned char *to, qbool #ifdef REHLDS_FIXES //Fix for https://github.com/dreamstalker/rehlds/issues/24 qboolean DELTA_WriteDeltaForceMask(unsigned char *from, unsigned char *to, qboolean force, delta_t *pFields, void(*callback)(void), void* pForceMask) { +#ifdef REHLDS_JIT qboolean sendfields = DELTAJit_Fields_Clear_Mark_Check(from, to, pFields, pForceMask); _DELTA_WriteDelta(from, to, force, pFields, callback, sendfields); return sendfields; +#else + DELTA_ClearFlags(pFields); + + // force fields + if (pForceMask) { + delta_description_t *pTest; + int i; + delta_marked_mask_t forceMask = *(delta_marked_mask_t *)pForceMask; + + for (i = 0, pTest = pFields->pdd; i < pFields->fieldCount; i++, pTest++) { + int mark = (forceMask.u32[i >> 5] & (1 << (i & 31))) ? FDT_MARK : 0; + pTest->flags |= mark; + } + } + + DELTA_MarkSendFields(from, to, pFields); + qboolean sendfields = DELTA_CountSendFields(pFields); + _DELTA_WriteDelta(from, to, force, pFields, callback, sendfields); + return sendfields; +#endif +} + +uint64 DELTA_GetOriginalMask(delta_t* pFields) +{ +#ifdef REHLDS_JIT + return DELTAJit_GetOriginalMask(pFields); +#else + return pFields->originalMarkedFieldsMask.u64; +#endif +} + +uint64 DELTA_GetMaskU64(delta_t* pFields) +{ +#ifdef REHLDS_JIT + return DELTAJit_GetMaskU64(pFields); +#else + delta_description_t *pTest; + int i; + delta_marked_mask_t mask = {}; + + for (i = 0, pTest = pFields->pdd; i < pFields->fieldCount; i++, pTest++) { + if (pTest->flags & FDT_MARK) + mask.u32[i >> 5] |= (1 << (i & 31)); + } + + return mask.u64; +#endif } #endif @@ -768,7 +824,7 @@ qboolean _DELTA_WriteDelta(unsigned char *from, unsigned char *to, qboolean forc if (sendfields || force) { -#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES) +#if (defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)) && defined REHLDS_JIT DELTAJit_SetSendFlagBits(pFields, bits, &bytecount); #else DELTA_SetSendFlagBits(pFields, bits, &bytecount); diff --git a/rehlds/engine/delta.h b/rehlds/engine/delta.h index 8562405..a9a0bcb 100644 --- a/rehlds/engine/delta.h +++ b/rehlds/engine/delta.h @@ -72,6 +72,12 @@ typedef struct delta_description_s class CDeltaJit; +union delta_marked_mask_t { + uint8 u8[8]; + uint32 u32[2]; + uint64 u64; +}; + typedef struct delta_s { int dynamic; @@ -80,8 +86,10 @@ typedef struct delta_s encoder_t conditionalencode; delta_description_t *pdd; -#ifdef REHLDS_FIXES +#if defined(REHLDS_JIT) CDeltaJit* jit; +#elif defined(REHLDS_FIXES) + delta_marked_mask_t originalMarkedFieldsMask; #endif } delta_t; @@ -136,6 +144,8 @@ qboolean DELTA_CheckDelta(unsigned char *from, unsigned char *to, delta_t *pFiel #ifdef REHLDS_FIXES //Fix for https://github.com/dreamstalker/rehlds/issues/24 qboolean DELTA_WriteDeltaForceMask(unsigned char *from, unsigned char *to, qboolean force, delta_t *pFields, void(*callback)(void), void* pForceMask); +uint64 DELTA_GetOriginalMask(delta_t* pFields); +uint64 DELTA_GetMaskU64(delta_t* pFields); #endif qboolean DELTA_WriteDelta(unsigned char *from, unsigned char *to, qboolean force, delta_t *pFields, void(*callback)(void)); diff --git a/rehlds/engine/delta_jit.cpp b/rehlds/engine/delta_jit.cpp index db0479f..544793f 100644 --- a/rehlds/engine/delta_jit.cpp +++ b/rehlds/engine/delta_jit.cpp @@ -29,6 +29,7 @@ #include "precompiled.h" #include "jitasm.h" +#ifdef REHLDS_JIT CDeltaJitRegistry g_DeltaJitRegistry; uint32 DELTAJIT_CreateMask(int startBit, int endBit) { @@ -686,11 +687,11 @@ void CDeltaJitRegistry::CreateAndRegisterDeltaJIT(delta_t* delta) { CDeltaClearMarkFieldsJIT* cleanMarkCheckFunc = new CDeltaClearMarkFieldsJIT(&data); cleanMarkCheckFunc->Assemble(); - cleanMarkCheckFunc->jitdesc = NULL; + cleanMarkCheckFunc->jitdesc = nullptr; CDeltaTestDeltaJIT* testDeltaFunc = new CDeltaTestDeltaJIT(&data); testDeltaFunc->Assemble(); - testDeltaFunc->jitdesc = NULL; + testDeltaFunc->jitdesc = nullptr; // align to 16 CDeltaJit* deltaJit = new CDeltaJit(delta, cleanMarkCheckFunc, testDeltaFunc); @@ -731,13 +732,13 @@ void DELTAJit_SetSendFlagBits(delta_t *pFields, int *bits, int *bytecount) { *bytecount = deltaJit->markedFieldsMaskSize; } -void DELTAJit_SetFieldByIndex(struct delta_s *pFields, int fieldNumber) +void DELTAJit_SetFieldByIndex(delta_t *pFields, int fieldNumber) { CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__func__, pFields); deltaJit->marked_fields_mask.u32[fieldNumber >> 5] |= (1 << (fieldNumber & 31)); } -void DELTAJit_UnsetFieldByIndex(struct delta_s *pFields, int fieldNumber) +void DELTAJit_UnsetFieldByIndex(delta_t *pFields, int fieldNumber) { CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__func__, pFields); deltaJit->marked_fields_mask.u32[fieldNumber >> 5] &= ~(1 << (fieldNumber & 31)); @@ -777,3 +778,4 @@ void CDeltaJitRegistry::Cleanup() { } #endif } +#endif diff --git a/rehlds/engine/delta_jit.h b/rehlds/engine/delta_jit.h index b0c6599..9e69417 100644 --- a/rehlds/engine/delta_jit.h +++ b/rehlds/engine/delta_jit.h @@ -30,6 +30,7 @@ #include "maintypes.h" +#ifdef REHLDS_JIT const int DELTAJIT_MAX_BLOCKS = 32; const int DELTAJIT_MAX_FIELDS = 56; @@ -87,23 +88,16 @@ public: void Cleanup(); }; -union delta_marked_mask_t { - uint8 u8[8]; - uint32 u32[2]; - uint64 u64; -}; - - extern CDeltaJitRegistry g_DeltaJitRegistry; extern int DELTAJit_Fields_Clear_Mark_Check(unsigned char *from, unsigned char *to, delta_t *pFields, void* pForceMarkMask); extern int DELTAJit_TestDelta(unsigned char *from, unsigned char *to, delta_t *pFields); extern void DELTAJit_SetSendFlagBits(delta_t *pFields, int *bits, int *bytecount); -extern void DELTAJit_SetFieldByIndex(struct delta_s *pFields, int fieldNumber); -extern void DELTAJit_UnsetFieldByIndex(struct delta_s *pFields, int fieldNumber); +extern void DELTAJit_SetFieldByIndex(delta_t *pFields, int fieldNumber); +extern void DELTAJit_UnsetFieldByIndex(delta_t *pFields, int fieldNumber); extern qboolean DELTAJit_IsFieldMarked(delta_t* pFields, int fieldNumber); /* Returns original mask, before it was changed by the conditional encoder */ extern uint64 DELTAJit_GetOriginalMask(delta_t* pFields); - extern uint64 DELTAJit_GetMaskU64(delta_t* pFields); +#endif diff --git a/rehlds/engine/sv_main.cpp b/rehlds/engine/sv_main.cpp index 085ad3f..dd380de 100644 --- a/rehlds/engine/sv_main.cpp +++ b/rehlds/engine/sv_main.cpp @@ -4435,8 +4435,8 @@ int SV_CreatePacketEntities_internal(sv_delta_t type, client_t *client, packet_e ); baselineToIdx = -1; - uint64 origMask = DELTAJit_GetOriginalMask(delta); - uint64 usedMask = DELTAJit_GetMaskU64(delta); + uint64 origMask = DELTA_GetOriginalMask(delta); + uint64 usedMask = DELTA_GetMaskU64(delta); uint64 diffMask = origMask ^ usedMask; //Remember changed fields that was marked in original mask, but unmarked by the conditional encoder @@ -7717,7 +7717,7 @@ void SV_RegisterDelta(char *name, char *loadfile) p->next = g_sv_delta; g_sv_delta = p; -#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES) +#if (defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)) && defined REHLDS_JIT g_DeltaJitRegistry.CreateAndRegisterDeltaJIT(pdesc); #endif } @@ -7763,7 +7763,7 @@ void SV_InitDeltas(void) Sys_Error("%s: No usercmd_t encoder on server!\n", __func__); #endif -#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES) +#if (defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)) && defined REHLDS_JIT g_DeltaJitRegistry.CreateAndRegisterDeltaJIT(&g_MetaDelta[0]); #endif } @@ -7966,7 +7966,9 @@ void SV_Init(void) void SV_Shutdown(void) { +#if (defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)) && defined REHLDS_JIT g_DeltaJitRegistry.Cleanup(); +#endif delta_info_t *p = g_sv_delta; while (p) { diff --git a/rehlds/unittests/delta_tests.cpp b/rehlds/unittests/delta_tests.cpp index ca608b0..e2c7407 100644 --- a/rehlds/unittests/delta_tests.cpp +++ b/rehlds/unittests/delta_tests.cpp @@ -63,10 +63,13 @@ NOINLINE void _FillTestDelta(delta_test_struct_t* data, unsigned char val) { NOINLINE qboolean _DoMarkFields(void* src, void* dst, delta_t* delta, bool useJit) { qboolean sendfields; +#ifdef REHLDS_JIT if (useJit) { DELTA_ClearFlags(delta); return DELTAJit_Fields_Clear_Mark_Check((unsigned char*)src, (unsigned char*)dst, delta, NULL); - } else { + } else +#endif + { DELTA_ClearFlags(delta); DELTA_MarkSendFields((unsigned char*)src, (unsigned char*)dst, delta); sendfields = DELTA_CountSendFields(delta); @@ -140,9 +143,12 @@ NOINLINE void _MarkAndEnsureCorrectResults(const char* action, delta_t* delta, v delta_marked_mask_t returnedMask; int returnedBytecount; +#ifdef REHLDS_JIT if (useJit) { DELTAJit_SetSendFlagBits(delta, (int*)returnedMask.u32, &returnedBytecount); - } else { + } else +#endif + { DELTA_SetSendFlagBits(delta, (int*)returnedMask.u32, &returnedBytecount); } @@ -159,10 +165,13 @@ NOINLINE void _MarkAndEnsureCorrectResults(const char* action, delta_t* delta, v NOINLINE void _GetBitmaskAndBytecount(delta_t* delta, int* bits, int* bytecount, int usejit) { +#ifdef REHLDS_JIT if (usejit) { DELTAJit_SetSendFlagBits(delta, bits, bytecount); } - else { + else +#endif + { DELTA_SetSendFlagBits(delta, bits, bytecount); } } @@ -209,8 +218,9 @@ NOINLINE delta_t* _CreateTestDeltaDesc() { dinfo->next = g_sv_delta; g_sv_delta = dinfo; +#ifdef REHLDS_JIT g_DeltaJitRegistry.CreateAndRegisterDeltaJIT(delta); - +#endif return delta; }; @@ -345,11 +355,8 @@ TEST(TestDelta_Test, Delta, 1000) { testdata[2].f_18 = 2.0; testdata[2].wb_20 = 2.0; strcpy(testdata[2].s_24, "TestDelta_Test" ); -#ifdef REHLDS_FIXES + result[2] = delta->pdd[10].significant_bits + delta->pdd[12].significant_bits + strlen(testdata[2].s_24) * 8 + 8 + (13 / 8 * 8 + 8); -#else - result[2] = delta->pdd[10].significant_bits + delta->pdd[12].significant_bits + (13 / 8 * 8 + 8); -#endif // change byte + int + float + short testdata[3].b_4D = 4;