mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-07-20 00:01:47 +00:00
Fix Android arm64 crashes and improve GLES/Input stability
- Fixed 64-bit pointer truncation in CUtlMemoryAligned affecting shadows and meshes. - Resolved heap corruption in GameUI and GamepadUI music systems (mismatched new[]/delete). - Fixed out-of-bounds touch input crashes by mapping 64-bit SDL finger IDs. - Lowered OpenGL requirement to 3.0 on Android and added fallbacks for GLES 3.2+ functions. - Fixed GamepadUI text wrapping and lifecycle crashes.
This commit is contained in:
parent
8420c329c6
commit
067036f6e9
@ -450,7 +450,7 @@ void CTouchControls::CreateAtlasTexture()
|
||||
int atlasSize = 0;
|
||||
|
||||
stbrp_rect *rects = (stbrp_rect*)malloc(textureList.Count()*sizeof(stbrp_rect));
|
||||
memset(rects, 0, sizeof(stbrp_node)*textureList.Count());
|
||||
memset(rects, 0, sizeof(stbrp_rect)*textureList.Count());
|
||||
|
||||
if( touchTextureID )
|
||||
vgui::surface()->DeleteTextureByID( touchTextureID );
|
||||
|
||||
@ -156,7 +156,7 @@ bool GamepadUIBasePanel::StartBackgroundMusic( float flVolume )
|
||||
GamepadUI::GetInstance().GetEngineClient()->ClientCmd_Unrestricted( found );
|
||||
}
|
||||
|
||||
fileNames.PurgeAndDeleteElements();
|
||||
fileNames.PurgeAndDeleteElementsArray();
|
||||
|
||||
return m_nBackgroundMusicGUID != 0;
|
||||
}
|
||||
|
||||
@ -93,6 +93,10 @@ void GamepadUI::Shutdown()
|
||||
if ( m_pBasePanel )
|
||||
m_pBasePanel->DeletePanel();
|
||||
|
||||
if ( m_pAnimationController )
|
||||
delete m_pAnimationController;
|
||||
m_pAnimationController = NULL;
|
||||
|
||||
#ifdef HL2_RETAIL // not necessary on SDK2013 (Madi)
|
||||
m_SteamAPIContext.Clear();
|
||||
#endif
|
||||
@ -116,8 +120,10 @@ void GamepadUI::OnLevelInitializePreEntity()
|
||||
|
||||
void GamepadUI::OnLevelInitializePostEntity()
|
||||
{
|
||||
m_pBasePanel->OnMenuStateChanged();
|
||||
GetMainMenu()->OnMenuStateChanged();
|
||||
if ( m_pBasePanel )
|
||||
m_pBasePanel->OnMenuStateChanged();
|
||||
if ( GetMainMenu() )
|
||||
GetMainMenu()->OnMenuStateChanged();
|
||||
}
|
||||
|
||||
void GamepadUI::OnLevelShutdown()
|
||||
@ -128,12 +134,17 @@ void GamepadUI::OnLevelShutdown()
|
||||
m_pAnimationController->RunAllAnimationsToCompletion();
|
||||
}
|
||||
|
||||
m_pBasePanel->OnMenuStateChanged();
|
||||
GetMainMenu()->OnMenuStateChanged();
|
||||
if ( m_pBasePanel )
|
||||
m_pBasePanel->OnMenuStateChanged();
|
||||
if ( GetMainMenu() )
|
||||
GetMainMenu()->OnMenuStateChanged();
|
||||
}
|
||||
|
||||
void GamepadUI::VidInit()
|
||||
{
|
||||
if ( !m_pBasePanel )
|
||||
return;
|
||||
|
||||
int w, h;
|
||||
vgui::surface()->GetScreenSize( w, h );
|
||||
|
||||
|
||||
@ -35,6 +35,9 @@ const char *COM_GetModDirectory()
|
||||
|
||||
int DrawPrintWrappedText(vgui::HFont font, int pX, int pY, const wchar_t* pszText, int nLength, int nMaxWidth, bool bDraw)
|
||||
{
|
||||
if ( !pszText || nLength <= 0 || nMaxWidth <= 0 )
|
||||
return 0;
|
||||
|
||||
float x = 0.0f;
|
||||
int extraY = 0;
|
||||
const int nFontTall = vgui::surface()->GetFontTall(font);
|
||||
@ -42,53 +45,68 @@ int DrawPrintWrappedText(vgui::HFont font, int pX, int pY, const wchar_t* pszTex
|
||||
const wchar_t* wszLastSpace = NULL;
|
||||
const wchar_t* wszEnd = pszText + nLength;
|
||||
|
||||
for (const wchar_t* wsz = pszText; *wsz; wsz++)
|
||||
for (const wchar_t* wsz = pszText; wsz < wszEnd; wsz++)
|
||||
{
|
||||
wchar_t ch = *wsz;
|
||||
|
||||
if (ch == L' ' || ch == L'\n')
|
||||
wszLastSpace = wsz;
|
||||
|
||||
#if USE_GETKERNEDCHARWIDTH
|
||||
wchar_t chBefore = 0;
|
||||
wchar_t chAfter = 0;
|
||||
if (wsz > pszText)
|
||||
chBefore = wsz[-1];
|
||||
chAfter = wsz[1];
|
||||
float flWide = 0.0f, flabcA = 0.0f;
|
||||
vgui::surface()->GetKernedCharWidth(font, ch, chBefore, chAfter, flWide, flabcA);
|
||||
if (ch == L' ')
|
||||
x = ceil(x);
|
||||
|
||||
surface()->DrawSetTextPos(x + px, y + py);
|
||||
surface()->DrawUnicodeChar(ch);
|
||||
x += floor(flWide + 0.6);
|
||||
#else
|
||||
x += vgui::surface()->GetCharacterWidth(font, ch);
|
||||
#endif
|
||||
|
||||
if (x >= nMaxWidth || ch == L'\n')
|
||||
{
|
||||
const wchar_t* wszNewStart = wszLastSpace ? wszLastSpace : wsz;
|
||||
const wchar_t* wszBreak;
|
||||
const wchar_t* wszNextStart;
|
||||
|
||||
if ( ch == L'\n' )
|
||||
{
|
||||
wszBreak = wsz;
|
||||
wszNextStart = wsz + 1;
|
||||
}
|
||||
else if ( wszLastSpace )
|
||||
{
|
||||
wszBreak = wszLastSpace;
|
||||
wszNextStart = wszLastSpace + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Break mid-word
|
||||
if ( wsz == wszStrStart )
|
||||
{
|
||||
// Even a single character doesn't fit, just force it
|
||||
wszBreak = wsz + 1;
|
||||
wszNextStart = wsz + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
wszBreak = wsz;
|
||||
wszNextStart = wsz;
|
||||
}
|
||||
}
|
||||
|
||||
if ( bDraw )
|
||||
{
|
||||
vgui::surface()->DrawSetTextPos(pX, pY);
|
||||
vgui::surface()->DrawPrintText(wszStrStart, (int)(intp)(wszNewStart - wszStrStart));
|
||||
vgui::surface()->DrawPrintText(wszStrStart, (int)(wszBreak - wszStrStart));
|
||||
}
|
||||
wszStrStart = wszNewStart + 1;
|
||||
wsz = wszStrStart;
|
||||
if ( ch == L'\n' )
|
||||
wsz--;
|
||||
|
||||
wszStrStart = wszNextStart;
|
||||
wsz = wszNextStart - 1; // loop increment will move it to wszNextStart
|
||||
wszLastSpace = NULL;
|
||||
x = 0;
|
||||
pY += nFontTall;
|
||||
extraY += nFontTall;
|
||||
}
|
||||
}
|
||||
|
||||
if (wszStrStart != wszEnd && bDraw)
|
||||
if (wszStrStart < wszEnd )
|
||||
{
|
||||
vgui::surface()->DrawSetTextPos(pX, pY);
|
||||
vgui::surface()->DrawPrintText(wszStrStart, (int)(intp)(wszEnd - wszStrStart));
|
||||
if ( bDraw )
|
||||
{
|
||||
vgui::surface()->DrawSetTextPos(pX, pY);
|
||||
vgui::surface()->DrawPrintText(wszStrStart, (int)(wszEnd - wszStrStart));
|
||||
}
|
||||
}
|
||||
|
||||
return extraY;
|
||||
|
||||
@ -507,7 +507,7 @@ void CGameUI::PlayGameStartupSound()
|
||||
engine->ClientCmd_Unrestricted( found );
|
||||
}
|
||||
|
||||
fileNames.PurgeAndDeleteElements();
|
||||
fileNames.PurgeAndDeleteElementsArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -461,6 +461,8 @@ public:
|
||||
int m_mouseRawAccumX, m_mouseRawAccumY;
|
||||
|
||||
float m_touchAccumX[TOUCH_FINGER_MAX_COUNT], m_touchAccumY[TOUCH_FINGER_MAX_COUNT];
|
||||
int m_touchFingerIds[TOUCH_FINGER_MAX_COUNT];
|
||||
int GetFingerIndex( int fingerId, bool bAdd );
|
||||
|
||||
// For the 'SleepUntilInput' feature
|
||||
HANDLE m_hEvent;
|
||||
|
||||
@ -50,8 +50,9 @@ void CInputSystem::InitializeTouch( void )
|
||||
|
||||
memset( m_touchAccumX, 0, sizeof(m_touchAccumX) );
|
||||
memset( m_touchAccumY, 0, sizeof(m_touchAccumY) );
|
||||
for( int i = 0; i < TOUCH_FINGER_MAX_COUNT; i++ ) m_touchFingerIds[i] = -1;
|
||||
|
||||
m_bJoystickInitialized = true;
|
||||
m_bTouchInitialized = true;
|
||||
SDL_AddEventWatch(TouchSDLWatcher, this);
|
||||
}
|
||||
|
||||
@ -64,35 +65,64 @@ void CInputSystem::ShutdownTouch()
|
||||
m_bTouchInitialized = false;
|
||||
}
|
||||
|
||||
bool CInputSystem::GetTouchAccumulators( int fingerId, float &dx, float &dy )
|
||||
int CInputSystem::GetFingerIndex( int fingerId, bool bAdd )
|
||||
{
|
||||
dx = m_touchAccumX[fingerId];
|
||||
dy = m_touchAccumY[fingerId];
|
||||
for( int i = 0; i < TOUCH_FINGER_MAX_COUNT; i++ )
|
||||
{
|
||||
if( m_touchFingerIds[i] == fingerId )
|
||||
return i;
|
||||
}
|
||||
|
||||
m_touchAccumX[fingerId] = m_touchAccumY[fingerId] = 0.f;
|
||||
if( bAdd )
|
||||
{
|
||||
for( int i = 0; i < TOUCH_FINGER_MAX_COUNT; i++ )
|
||||
{
|
||||
if( m_touchFingerIds[i] == -1 )
|
||||
{
|
||||
m_touchFingerIds[i] = fingerId;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool CInputSystem::GetTouchAccumulators( int index, float &dx, float &dy )
|
||||
{
|
||||
if( index < 0 || index >= TOUCH_FINGER_MAX_COUNT )
|
||||
return false;
|
||||
|
||||
dx = m_touchAccumX[index];
|
||||
dy = m_touchAccumY[index];
|
||||
|
||||
m_touchAccumX[index] = m_touchAccumY[index] = 0.f;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CInputSystem::FingerEvent(int eventType, int fingerId, float x, float y, float dx, float dy)
|
||||
{
|
||||
if( fingerId >= TOUCH_FINGER_MAX_COUNT )
|
||||
int index = GetFingerIndex( fingerId, eventType != IE_FingerUp );
|
||||
|
||||
if( index < 0 || index >= TOUCH_FINGER_MAX_COUNT )
|
||||
return;
|
||||
|
||||
if( eventType == IE_FingerUp )
|
||||
{
|
||||
m_touchAccumX[fingerId] = 0.f;
|
||||
m_touchAccumY[fingerId] = 0.f;
|
||||
m_touchAccumX[index] = 0.f;
|
||||
m_touchAccumY[index] = 0.f;
|
||||
m_touchFingerIds[index] = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_touchAccumX[fingerId] += dx;
|
||||
m_touchAccumY[fingerId] += dy;
|
||||
m_touchAccumX[index] += dx;
|
||||
m_touchAccumY[index] += dy;
|
||||
}
|
||||
|
||||
int _x,_y;
|
||||
memcpy( &_x, &x, sizeof(float) );
|
||||
memcpy( &_y, &y, sizeof(float) );
|
||||
PostEvent(eventType, m_nLastSampleTick, fingerId, _x, _y);
|
||||
PostEvent(eventType, m_nLastSampleTick, index, _x, _y);
|
||||
}
|
||||
|
||||
|
||||
@ -988,7 +988,7 @@ CUtlMemoryAligned<T, nAlignment>::CUtlMemoryAligned( T* pMemory, int numElements
|
||||
CUtlMemory<T>::m_nGrowSize = CUtlMemory<T>::EXTERNAL_BUFFER_MARKER;
|
||||
|
||||
CUtlMemory<T>::m_pMemory = (T*)Align( pMemory );
|
||||
CUtlMemory<T>::m_nAllocationCount = ( (int)(pMemory + numElements) - (int)CUtlMemory<T>::m_pMemory ) / sizeof(T);
|
||||
CUtlMemory<T>::m_nAllocationCount = ( (T*)pMemory + numElements ) - (T*)CUtlMemory<T>::m_pMemory;
|
||||
}
|
||||
|
||||
template< class T, int nAlignment >
|
||||
@ -998,7 +998,7 @@ CUtlMemoryAligned<T, nAlignment>::CUtlMemoryAligned( const T* pMemory, int numEl
|
||||
CUtlMemory<T>::m_nGrowSize = CUtlMemory<T>::EXTERNAL_CONST_BUFFER_MARKER;
|
||||
|
||||
CUtlMemory<T>::m_pMemory = (T*)Align( pMemory );
|
||||
CUtlMemory<T>::m_nAllocationCount = ( (int)(pMemory + numElements) - (int)CUtlMemory<T>::m_pMemory ) / sizeof(T);
|
||||
CUtlMemory<T>::m_nAllocationCount = ( (T*)pMemory + numElements ) - (T*)CUtlMemory<T>::m_pMemory;
|
||||
}
|
||||
|
||||
template< class T, int nAlignment >
|
||||
@ -1018,7 +1018,7 @@ void CUtlMemoryAligned<T, nAlignment>::SetExternalBuffer( T* pMemory, int numEle
|
||||
Purge();
|
||||
|
||||
CUtlMemory<T>::m_pMemory = (T*)Align( pMemory );
|
||||
CUtlMemory<T>::m_nAllocationCount = ( (int)(pMemory + numElements) - (int)CUtlMemory<T>::m_pMemory ) / sizeof(T);
|
||||
CUtlMemory<T>::m_nAllocationCount = ( (T*)pMemory + numElements ) - (T*)CUtlMemory<T>::m_pMemory;
|
||||
|
||||
// Indicate that we don't own the memory
|
||||
CUtlMemory<T>::m_nGrowSize = CUtlMemory<T>::EXTERNAL_BUFFER_MARKER;
|
||||
@ -1031,7 +1031,7 @@ void CUtlMemoryAligned<T, nAlignment>::SetExternalBuffer( const T* pMemory, int
|
||||
Purge();
|
||||
|
||||
CUtlMemory<T>::m_pMemory = (T*)Align( pMemory );
|
||||
CUtlMemory<T>::m_nAllocationCount = ( (int)(pMemory + numElements) - (int)CUtlMemory<T>::m_pMemory ) / sizeof(T);
|
||||
CUtlMemory<T>::m_nAllocationCount = ( (T*)pMemory + numElements ) - (T*)CUtlMemory<T>::m_pMemory;
|
||||
|
||||
// Indicate that we don't own the memory
|
||||
CUtlMemory<T>::m_nGrowSize = CUtlMemory<T>::EXTERNAL_CONST_BUFFER_MARKER;
|
||||
|
||||
@ -1433,7 +1433,7 @@ inline void CUtlVector<T, A>::PurgeAndDeleteElementsArray()
|
||||
{
|
||||
delete[] Element(i);
|
||||
}
|
||||
RemoveAll();
|
||||
Purge();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -67,7 +67,7 @@ GL_FUNC_VOID(OpenGL,true,glDeleteSync,(GLsync a),(a))
|
||||
GL_FUNC(OpenGL,true,GLsync,glFenceSync,(GLenum a, GLbitfield b),(a,b))
|
||||
|
||||
#if 1 //ifndef OSX // 10.6/GL 2.1 compatability
|
||||
GL_FUNC_VOID(OpenGL,true,glDrawRangeElementsBaseVertex,(GLenum a,GLuint b,GLuint c,GLsizei d,GLenum e,const GLvoid *f, GLenum g),(a,b,c,d,e,f,g))
|
||||
GL_FUNC_VOID(OpenGL,false,glDrawRangeElementsBaseVertex,(GLenum a,GLuint b,GLuint c,GLsizei d,GLenum e,const GLvoid *f, GLenum g),(a,b,c,d,e,f,g))
|
||||
#endif
|
||||
GL_FUNC_VOID(OpenGL,true,glEnable,(GLenum a),(a))
|
||||
GL_FUNC_VOID(OpenGL,true,glEnableVertexAttribArray,(GLuint a),(a))
|
||||
|
||||
@ -1900,8 +1900,22 @@ FORCEINLINE void GLMContext::DrawRangeElements( GLenum mode, GLuint start, GLuin
|
||||
#endif
|
||||
// do the drawing
|
||||
if (hasVP && hasFP)
|
||||
{
|
||||
if ( gGL->glDrawRangeElementsBaseVertex )
|
||||
{
|
||||
gGL->glDrawRangeElementsBaseVertex( mode, start, end, count, type, indicesActual, baseVertex );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( baseVertex == 0 )
|
||||
{
|
||||
gGL->glDrawRangeElements( mode, start, end, count, type, indicesActual );
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert( !"glDrawRangeElementsBaseVertex not supported but baseVertex != 0" );
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_slowCheckEnable )
|
||||
{
|
||||
@ -1916,7 +1930,21 @@ FORCEINLINE void GLMContext::DrawRangeElements( GLenum mode, GLuint start, GLuin
|
||||
|
||||
if ( m_pBoundPair )
|
||||
{
|
||||
gGL->glDrawRangeElementsBaseVertex( mode, start, end, count, type, indicesActual, baseVertex );
|
||||
if ( gGL->glDrawRangeElementsBaseVertex )
|
||||
{
|
||||
gGL->glDrawRangeElementsBaseVertex( mode, start, end, count, type, indicesActual, baseVertex );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( baseVertex == 0 )
|
||||
{
|
||||
gGL->glDrawRangeElements( mode, start, end, count, type, indicesActual );
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert( !"glDrawRangeElementsBaseVertex not supported but baseVertex != 0" );
|
||||
}
|
||||
}
|
||||
|
||||
#if GLMDEBUG
|
||||
if ( m_slowCheckEnable )
|
||||
|
||||
@ -540,6 +540,8 @@ DBG_INTERFACE bool DoNewAssertDialog( const tchar *pFilename, int line, const tc
|
||||
{
|
||||
#ifdef OSX
|
||||
void *ret = dlopen( "libSDL2-2.0.0.dylib", RTLD_LAZY );
|
||||
#elif defined( __ANDROID__ )
|
||||
void *ret = dlopen( "libSDL2.so", RTLD_LAZY );
|
||||
#else
|
||||
void *ret = dlopen( "libSDL2-2.0.so.0", RTLD_LAZY );
|
||||
#endif
|
||||
|
||||
@ -249,8 +249,13 @@ static int GetOpenGLVersionPatch()
|
||||
|
||||
static bool CheckBaseOpenGLVersion()
|
||||
{
|
||||
#ifdef __ANDROID__
|
||||
const int NEED_MAJOR = 3;
|
||||
const int NEED_MINOR = 0;
|
||||
#else
|
||||
const int NEED_MAJOR = 3;
|
||||
const int NEED_MINOR = 2;
|
||||
#endif
|
||||
const int NEED_PATCH = 0;
|
||||
|
||||
int major, minor, patch;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user