From 45e770f07eb04222f2b11fb6e2994805813f8a93 Mon Sep 17 00:00:00 2001 From: ThirteenAG Date: Sat, 25 Nov 2023 18:49:07 +0800 Subject: [PATCH] vcs ps2 p2dfx fix --- .../PLUGINS/GTAVCS.PCSX2F.Project2DFX.ini | 2 - source/GTAVCS.PCSX2F.Project2DFX/lodl.c | 279 ++++++++++++++++++ source/GTAVCS.PCSX2F.Project2DFX/lodl.h | 7 + source/GTAVCS.PCSX2F.Project2DFX/main.c | 43 ++- 4 files changed, 317 insertions(+), 14 deletions(-) diff --git a/data/GTAVCS.PCSX2F.Project2DFX/PLUGINS/GTAVCS.PCSX2F.Project2DFX.ini b/data/GTAVCS.PCSX2F.Project2DFX/PLUGINS/GTAVCS.PCSX2F.Project2DFX.ini index 2ab16ffa2..f9f3f9c76 100644 --- a/data/GTAVCS.PCSX2F.Project2DFX/PLUGINS/GTAVCS.PCSX2F.Project2DFX.ini +++ b/data/GTAVCS.PCSX2F.Project2DFX/PLUGINS/GTAVCS.PCSX2F.Project2DFX.ini @@ -1,8 +1,6 @@ [PROJECT2DFX] ; Set to 1 to enable RenderLodLights = 1 -; Default value is 56 -CoronaLimit = 1000 ; Makes lod lights bigger or smaller CoronaRadiusMultiplier = 1.0 ; Affects performance, for better results decrease this value diff --git a/source/GTAVCS.PCSX2F.Project2DFX/lodl.c b/source/GTAVCS.PCSX2F.Project2DFX/lodl.c index 1cd7261d4..2f90f3b27 100644 --- a/source/GTAVCS.PCSX2F.Project2DFX/lodl.c +++ b/source/GTAVCS.PCSX2F.Project2DFX/lodl.c @@ -11,6 +11,11 @@ float SolveEqSys(float a, float b, float c, float d, float value) float fCoronaFarClip = 500.0f; float fCoronaRadiusMultiplier = 1.0f; void(*CCoronas__RegisterCoronaINT)(unsigned int id, unsigned char r, unsigned char g, unsigned char b, unsigned char a, void* pos, unsigned char coronaType, unsigned char flareType, unsigned char reflection, unsigned char LOScheck, unsigned char drawStreak, unsigned char flag4, unsigned char flag5); +void (*CSprite__FlushSpriteBuffer)(); +void (*CCoronas__Render)(); +void (*RslRenderStateSet)(int, int); +int (*CSprite__CalcScreenCoors)(CVector* in, CVector* out, float* outW, float* outH, uint8_t farClip); +void (*CSprite__RenderBufferedOneXLUSprite)(); CVector* pCamPos; uintptr_t CurrentTimeHoursOffset; uintptr_t CurrentTimeMinutesOffset; @@ -4162,4 +4167,278 @@ void RegisterLODLights() } } } +} + +void RenderLODLightsBuffered() +{ + if (GetIsTimeInRange(19, 7)) + { + unsigned char bAlpha = 0; + float fRadius = 0.0f; + unsigned int nTime = CurrentTimeHours() * 60 + CurrentTimeMinutes(); + unsigned int curMin = CurrentTimeMinutes(); + + if (nTime >= 19 * 60) + bAlpha = (unsigned char)SolveEqSys((float)(19 * 60), 30.0f, (float)(24 * 60), 255.0f, (float)nTime); // {(19*60)a + y = 30, (24*60)a + y = 255} + else if (nTime < 3 * 60) + bAlpha = 255; + else + bAlpha = (unsigned char)SolveEqSys((float)(7 * 60), 30.0f, (float)(3 * 60), 255.0f, (float)nTime); // {(7*60)a + y = 30, (3*60)a + y = 255} + + for (size_t i = 0; i < sizeof(aLodLights) / sizeof(aLodLights[0]); i++) + { + //if ((aLodLights[i].z >= -15.0f) && (aLodLights[i].z <= 1030.0f)) + { + CVector* pCamPos = (CVector*)GetCamPos(); + float fDistSqr = (pCamPos->x - aLodLights[i].x) * (pCamPos->x - aLodLights[i].x) + (pCamPos->y - aLodLights[i].y) * (pCamPos->y - aLodLights[i].y) + (pCamPos->z - aLodLights[i].z) * (pCamPos->z - aLodLights[i].z); + float fCoronaDist = aLodLights[i].fThisCoronaFarClip / 3.0f; + + if ((fDistSqr > fCoronaDist * fCoronaDist && fDistSqr < fCoronaFarClip * fCoronaFarClip) || aLodLights[i].nNoDistance) + { + float fUnkDist1 = 0.125f; + float fUnkDist2 = 0.125f; + + float min_radius_distance = fCoronaDist; + float min_radius_value = 0.0f; + float max_radius_distance = aLodLights[i].fThisCoronaFarClip; + float max_radius_value = 3.5f; + + if (aLodLights[i].nNoDistance) + fRadius = 3.5f; + else + fRadius = SolveEqSys(min_radius_distance, min_radius_value, max_radius_distance, max_radius_value, 1.0f / Q_rsqrt(fDistSqr)); + + if (fRadius > 3.5f) + fRadius = 3.5f; + + void* pos = &aLodLights[i]; + unsigned char alpha = (bAlpha * (aLodLights[i].a / 255.0f)); + float radius = (fRadius * aLodLights[i].fCustomSizeMult * fCoronaRadiusMultiplier); + + if (!IsSphereVisible(radius * 1.2f, (CVector*)pos)) + continue; + + if (aLodLights[i].fCustomSizeMult != 0.45f) + { + if (!aLodLights[i].nCoronaShowMode) + { + //CCoronas__RegisterCorona(&aLodLights[i], aLodLights[i].r, aLodLights[i].g, aLodLights[i].b, alpha, pos, 0, 0, radius, fCoronaFarClip, fUnkDist1, fUnkDist2, 1, 0, 0, 0, 0); + + CVector ScreenPos, WorldPos; + float SZ, SZX, SZY; + WorldPos.x = aLodLights[i].x; + WorldPos.y = aLodLights[i].y; + WorldPos.z = aLodLights[i].z; + SZ = radius; + + if (CSprite__CalcScreenCoors(&WorldPos, &ScreenPos, &SZX, &SZY, 1)) + { + int a0 = aLodLights[i].r; + int a1 = aLodLights[i].g; + int a2 = aLodLights[i].b; + int a3 = alpha; + int a4 = alpha; + float f12 = ScreenPos.x; + float f13 = ScreenPos.y; + float f14 = ScreenPos.z; + float f15 = SZX * SZ; + float f16 = SZY * SZ; + float f17 = 1.0f / ScreenPos.z; + + asm volatile ("lw $v0, %[x]" ::[x] "m" (a0)); + asm volatile ("move $a0, $v0"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (a1)); + asm volatile ("move $a1, $v0"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (a2)); + asm volatile ("move $a2, $v0"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (a3)); + asm volatile ("move $a3, $v0"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (a4)); + asm volatile ("move $a4, $v0"); + + asm volatile ("lw $v0, %[x]" ::[x] "m" (f12)); + asm volatile ("mtc1 $v0, $f12"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (f13)); + asm volatile ("mtc1 $v0, $f13"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (f14)); + asm volatile ("mtc1 $v0, $f14"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (f15)); + asm volatile ("mtc1 $v0, $f15"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (f16)); + asm volatile ("mtc1 $v0, $f16"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (f17)); + asm volatile ("mtc1 $v0, $f17"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (CSprite__RenderBufferedOneXLUSprite)); + asm volatile ("jalr $v0"); + } + + + } + else + { + static float blinking = 1.0f; + static volatile float blinking_a = 1.0f; + static volatile float blinking_b = 1.0f; + static volatile float blinking_c = 1.0f; + if (IsBlinkingNeeded(aLodLights[i].nCoronaShowMode)) + blinking -= CTimer__ms_fTimeStep() / 1000.0f; + else + blinking += CTimer__ms_fTimeStep() / 1000.0f; + + (blinking > 1.0f) ? blinking = 1.0f : (blinking < 0.0f) ? blinking = 0.0f : 0.0f; + + //CCoronas__RegisterCorona(&aLodLights[i], aLodLights[i].r, aLodLights[i].g, aLodLights[i].b, blinking * alpha, pos, 0, 0, radius, fCoronaFarClip, fUnkDist1, fUnkDist2, 1, 0, 0, 0, 0); + + CVector ScreenPos, WorldPos; + float SZ, SZX, SZY; + WorldPos.x = aLodLights[i].x; + WorldPos.y = aLodLights[i].y; + WorldPos.z = aLodLights[i].z; + SZ = radius; + + if (CSprite__CalcScreenCoors(&WorldPos, &ScreenPos, &SZX, &SZY, 1)) + { + int a0 = aLodLights[i].r; + int a1 = aLodLights[i].g; + int a2 = aLodLights[i].b; + int a3 = 255; + int a4 = blinking * alpha; + float f12 = ScreenPos.x; + float f13 = ScreenPos.y; + float f14 = ScreenPos.z; + float f15 = SZX * SZ; + float f16 = SZY * SZ; + float f17 = 1.0f / ScreenPos.z; + + asm volatile ("lw $v0, %[x]" ::[x] "m" (a0)); + asm volatile ("move $a0, $v0"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (a1)); + asm volatile ("move $a1, $v0"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (a2)); + asm volatile ("move $a2, $v0"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (a3)); + asm volatile ("move $a3, $v0"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (a4)); + asm volatile ("move $a4, $v0"); + + asm volatile ("lw $v0, %[x]" ::[x] "m" (f12)); + asm volatile ("mtc1 $v0, $f12"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (f13)); + asm volatile ("mtc1 $v0, $f13"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (f14)); + asm volatile ("mtc1 $v0, $f14"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (f15)); + asm volatile ("mtc1 $v0, $f15"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (f16)); + asm volatile ("mtc1 $v0, $f16"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (f17)); + asm volatile ("mtc1 $v0, $f17"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (CSprite__RenderBufferedOneXLUSprite)); + asm volatile ("jalr $v0"); + } + } + } + else + { + int bNeedsToDrawCorona = 0; + if ((aLodLights[i].r >= 250 && aLodLights[i].g >= 100 && aLodLights[i].b <= 100) && ((curMin == 9 || curMin == 19 || curMin == 29 || curMin == 39 || curMin == 49 || curMin == 59))) //yellow + { + //CCoronas__RegisterCorona(&aLodLights[i], aLodLights[i].r, aLodLights[i].g, aLodLights[i].b, alpha, pos, 0, 0, radius, fCoronaFarClip, fUnkDist1, fUnkDist2, 1, 0, 0, 0, 0); + bNeedsToDrawCorona = 1; + } + else + { + //if ((abs(aLodLights[i].fHeading) >= (3.1415f / 6.0f) && abs(aLodLights[i].fHeading) <= (5.0f * 3.1415f / 6.0f))) + if (abs(aLodLights[i].fHeading) > (3.1415f / 2.0f)) + { + if ((aLodLights[i].r >= 250 && aLodLights[i].g < 100 && aLodLights[i].b == 0) && (((curMin >= 0 && curMin < 9) || (curMin >= 20 && curMin < 29) || (curMin >= 40 && curMin < 49)))) //red + { + CCoronas__RegisterCorona(&aLodLights[i], aLodLights[i].r, aLodLights[i].g, aLodLights[i].b, alpha, pos, 0, 0, radius, fCoronaFarClip, fUnkDist1, fUnkDist2, 1, 0, 0, 0, 0); + bNeedsToDrawCorona = 1; + } + else + { + if ((aLodLights[i].r == 0 && aLodLights[i].g >= 250 && aLodLights[i].b == 0) && (((curMin > 9 && curMin < 19) || (curMin > 29 && curMin < 39) || (curMin > 49 && curMin < 59)))) //green + { + CCoronas__RegisterCorona(&aLodLights[i], aLodLights[i].r, aLodLights[i].g, aLodLights[i].b, alpha, pos, 0, 0, radius, fCoronaFarClip, fUnkDist1, fUnkDist2, 1, 0, 0, 0, 0); + bNeedsToDrawCorona = 1; + } + } + } + else + { + if ((aLodLights[i].r == 0 && aLodLights[i].g >= 250 && aLodLights[i].b == 0) && (((curMin >= 0 && curMin < 9) || (curMin >= 20 && curMin < 29) || (curMin >= 40 && curMin < 49)))) //red + { + CCoronas__RegisterCorona(&aLodLights[i], aLodLights[i].r, aLodLights[i].g, aLodLights[i].b, alpha, pos, 0, 0, radius, fCoronaFarClip, fUnkDist1, fUnkDist2, 1, 0, 0, 0, 0); + bNeedsToDrawCorona = 1; + } + else + { + if ((aLodLights[i].r >= 250 && aLodLights[i].g < 100 && aLodLights[i].b == 0) && (((curMin > 9 && curMin < 19) || (curMin > 29 && curMin < 39) || (curMin > 49 && curMin < 59)))) //green + { + CCoronas__RegisterCorona(&aLodLights[i], aLodLights[i].r, aLodLights[i].g, aLodLights[i].b, alpha, pos, 0, 0, radius, fCoronaFarClip, fUnkDist1, fUnkDist2, 1, 0, 0, 0, 0); + bNeedsToDrawCorona = 1; + } + } + } + } + + if (bNeedsToDrawCorona) + { + CVector ScreenPos, WorldPos; + float SZ, SZX, SZY; + WorldPos.x = aLodLights[i].x; + WorldPos.y = aLodLights[i].y; + WorldPos.z = aLodLights[i].z; + SZ = radius; + + if (CSprite__CalcScreenCoors(&WorldPos, &ScreenPos, &SZX, &SZY, 1)) + { + int a0 = aLodLights[i].r; + int a1 = aLodLights[i].g; + int a2 = aLodLights[i].b; + int a3 = 255; + int a4 = alpha; + float f12 = ScreenPos.x; + float f13 = ScreenPos.y; + float f14 = ScreenPos.z; + float f15 = SZX * SZ; + float f16 = SZY * SZ; + float f17 = 1.0f / ScreenPos.z; + + asm volatile ("lw $v0, %[x]" ::[x] "m" (a0)); + asm volatile ("move $a0, $v0"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (a1)); + asm volatile ("move $a1, $v0"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (a2)); + asm volatile ("move $a2, $v0"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (a3)); + asm volatile ("move $a3, $v0"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (a4)); + asm volatile ("move $a4, $v0"); + + asm volatile ("lw $v0, %[x]" ::[x] "m" (f12)); + asm volatile ("mtc1 $v0, $f12"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (f13)); + asm volatile ("mtc1 $v0, $f13"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (f14)); + asm volatile ("mtc1 $v0, $f14"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (f15)); + asm volatile ("mtc1 $v0, $f15"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (f16)); + asm volatile ("mtc1 $v0, $f16"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (f17)); + asm volatile ("mtc1 $v0, $f17"); + asm volatile ("lw $v0, %[x]" ::[x] "m" (CSprite__RenderBufferedOneXLUSprite)); + asm volatile ("jalr $v0"); + } + } + } + } + } + if (i % 96 == 0) + CSprite__FlushSpriteBuffer(); + } + CSprite__FlushSpriteBuffer(); + } } \ No newline at end of file diff --git a/source/GTAVCS.PCSX2F.Project2DFX/lodl.h b/source/GTAVCS.PCSX2F.Project2DFX/lodl.h index eb88b99e2..3ea312120 100644 --- a/source/GTAVCS.PCSX2F.Project2DFX/lodl.h +++ b/source/GTAVCS.PCSX2F.Project2DFX/lodl.h @@ -55,6 +55,11 @@ extern uintptr_t CurrentTimeHoursOffset; extern uintptr_t CurrentTimeMinutesOffset; extern uintptr_t CTimer__m_snTimeInMillisecondsPauseModeOffset; extern uintptr_t CTimer__ms_fTimeStepOffset; +extern void (*CSprite__FlushSpriteBuffer)(); +extern void (*CCoronas__Render)(); +extern void (*RslRenderStateSet)(int, int); +extern int (*CSprite__CalcScreenCoors)(CVector* in, CVector* out, float* outW, float* outH, uint8_t farClip); +extern void (*CSprite__RenderBufferedOneXLUSprite)(); void IncreaseCoronasLimit(size_t CoronaLimit); char CurrentTimeHours(); @@ -65,4 +70,6 @@ char GetIsTimeInRange(int hourA, int hourB); CVector* GetCamPos(); int IsBlinkingNeeded(int BlinkType); void RegisterLODLights(); +void RenderLODLightsBuffered(); +int IsSphereVisible(float radius, CVector* center); #endif diff --git a/source/GTAVCS.PCSX2F.Project2DFX/main.c b/source/GTAVCS.PCSX2F.Project2DFX/main.c index 8ca388762..39524113d 100644 --- a/source/GTAVCS.PCSX2F.Project2DFX/main.c +++ b/source/GTAVCS.PCSX2F.Project2DFX/main.c @@ -47,9 +47,7 @@ float randf(float min, float max) float* CWeather__Foggyness; float* CWeather__CloudCoverage; -void (*CSprite__FlushSpriteBuffer)(); -int (*CSprite__CalcScreenCoors)(CVector* in, CVector* out, float* outW, float* outH, uint8_t farClip); -void (*CSprite__RenderBufferedOneXLUSprite)(); +int** gpCoronaTexture; void CSprite__FlushSpriteBufferHook() { CSprite__FlushSpriteBuffer(); @@ -144,6 +142,19 @@ void CSprite__FlushSpriteBufferHook() } } +void CCoronas__RenderHook() +{ + CCoronas__Render(); + + RslRenderStateSet(6, 0); + RslRenderStateSet(10, 1); + RslRenderStateSet(8, 2); + RslRenderStateSet(9, 2); + RslRenderStateSet(4, 1); + RslRenderStateSet(1, *gpCoronaTexture[0]); + RenderLODLightsBuffered(); +} + uintptr_t GetAbsoluteAddress(uintptr_t at, int32_t offs_hi, int32_t offs_lo) { return (uintptr_t)((uint32_t)(*(uint16_t*)(at + offs_hi)) << 16) + *(int16_t*)(at + offs_lo); @@ -160,6 +171,15 @@ void init() int SkyGfx = inireader.ReadInteger("PROJECT2DFX", "SkyGfx", 0); + uintptr_t ptr_39FC48 = pattern.get(0, "70 00 02 3C 10 00 B0 FF", -4); + CSprite__CalcScreenCoors = (int(*)(CVector*, CVector*, float*, float*, uint8_t))ptr_39FC48; + uintptr_t ptr_39FF48 = pattern.get(0, "80 68 10 46 ? ? ? ? 40 60 0F 46 80 3F 01 3C 00 00 81 44 01 63 0F 46 20 00 A0 AF 41 6B 10 46 68 00 B5 FF", -0); + CSprite__RenderBufferedOneXLUSprite = (void(*)())ptr_39FF48; + uintptr_t ptr_18D450 = pattern.get(0, "00 00 00 00 48 00 03 3C 01 00 04 24 ? ? ? ? ? ? ? ? 00 00 45 8C", -4); + CSprite__FlushSpriteBuffer = (void(*)())injector.GetBranchDestination(ptr_18D450); + uintptr_t ptr_27C464 = pattern.get(0, "90 00 B4 E7 00 3F 01 3C", -4); + RslRenderStateSet = (void(*)(int, int))injector.GetBranchDestination(ptr_27C464); + if (RenderLodLights) { uintptr_t ptr_27DD10 = pattern.get(0, "FF 00 4A 31 ? ? ? ? ? ? ? ? ? ? ? ? 80 50 0A 00 ? ? ? ? 21 50 42 01", 0); @@ -174,12 +194,17 @@ void init() CTimer__m_snTimeInMillisecondsPauseModeOffset = GetAbsoluteAddress(ptr_1085AC, 0, 4); uintptr_t ptr_132678 = pattern.get(0, "02 08 00 46 82 08 02 46 42 08 03 46 00 21 00 46", 0); CTimer__ms_fTimeStepOffset = GetAbsoluteAddress(ptr_132678, -20, -8); + uintptr_t ptr_244B10 = pattern.get(0, "48 00 03 3C 01 00 04 24 ? ? ? ? ? ? ? ? 00 00 45 8C 04 00 04 24", -0); + gpCoronaTexture = (int**)GetAbsoluteAddress(ptr_244B10, 0, 8); - IncreaseCoronasLimit(CoronaLimit); + // disabled because introduces bugs with script objects + //IncreaseCoronasLimit(CoronaLimit); // Coronas Render - uintptr_t ptr_21ED38 = pattern.get(0, "00 00 00 00 48 00 02 3C 48 7A 43 8C", -4); - injector.MakeJAL(ptr_21ED38, (intptr_t)RegisterLODLights); + //uintptr_t ptr_21ED38 = pattern.get(0, "00 00 00 00 48 00 02 3C 48 7A 43 8C", -4); + //injector.MakeJAL(ptr_21ED38, (intptr_t)RegisterLODLights); + uintptr_t ptr_21F268 = pattern.get(11, "00 00 00 00 ? ? ? ? 2D 20 40 02 23 10 22 02 2B 10 02 02 ? ? ? ? 00 00 B0 DF", -4); + CCoronas__Render = (void(*)())injector.MakeJAL(ptr_21F268, (uintptr_t)CCoronas__RenderHook); // Heli Height Limit uintptr_t ptr_3EA644 = pattern.get(1, "A0 42 01 3C 00 00 81 44 00 00 00 00", 0); // count = 3 @@ -202,11 +227,6 @@ void init() uintptr_t ptr_408058 = pattern.get(0, "49 00 08 3C 01 00 03 3C", -0); base__Random = (int(*)())ptr_408058; - uintptr_t ptr_39FC48 = pattern.get(0, "70 00 02 3C 10 00 B0 FF", -4); - CSprite__CalcScreenCoors = (int(*)(CVector*, CVector*, float*, float*, uint8_t))ptr_39FC48; - uintptr_t ptr_39FF48 = pattern.get(0, "80 68 10 46 ? ? ? ? 40 60 0F 46 80 3F 01 3C 00 00 81 44 01 63 0F 46 20 00 A0 AF 41 6B 10 46 68 00 B5 FF", -0); - CSprite__RenderBufferedOneXLUSprite = (void(*)())ptr_39FF48; - for (int side = 0; side < STAR_SKYBOX_SIDES; ++side) { for (int i = 0; i < AMOUNT_OF_STARS; ++i) @@ -223,7 +243,6 @@ void init() } } - uintptr_t ptr_18D450 = pattern.get(0, "00 00 00 00 48 00 03 3C 01 00 04 24 ? ? ? ? ? ? ? ? 00 00 45 8C", -4); CSprite__FlushSpriteBuffer = (void(*)())injector.MakeJAL(ptr_18D450, (uintptr_t)CSprite__FlushSpriteBufferHook); } }